public bool ConfigureLocalNode(ClusterTopology topologyToDeploy)
        {
            try
            {
                TextLogger.LogInfo("Configuring local Service Fabric node based on bootstrap cluster manifest.");

                if (!this.InvokeFabricDeployer(topologyToDeploy, DeploymentType.Create, false))
                {
                    TextLogger.LogError("Failed to configure local Service Fabric node based on bootstrap cluster manifest.");

                    return(false);
                }

                Utilities.SetWindowsFabricNodeConfigurationCompleted(false);

                TextLogger.LogInfo("Successfully configured local Service Fabric node based on bootstrap cluster manifest.");

                return(true);
            }
            catch (Exception e)
            {
                TextLogger.LogError("Failed to configure local Service Fabric node based on bootstrap cluster manifest : {0}", e);

                return(false);
            }
        }
Exemple #2
0
        // Whether topology of the cluster has changed.
        // Topology is defined as the set of nodes. Each node is defined by name, UD, FD, IP, role, etc.
        internal bool IsClusterTopologyChanged(ClusterTopology clusterTopology)
        {
            if (clusterTopology == null || ServiceFabricNodes.Count != clusterTopology.ServiceFabricNodes.Count)
            {
                return(true);
            }

            // note that node list is always ordered by node name(role.nodeID), which uniquely identifies a node
            for (int i = 0; i < clusterTopology.ServiceFabricNodes.Count; i++)
            {
                if (!NodeEquals(clusterTopology.ServiceFabricNodes[i], ServiceFabricNodes[i]))
                {
                    return(true);
                }
            }

            return(false);
        }
        private bool InvokeFabricDeployer(ClusterTopology topologyToDeploy, DeploymentType deploymentType, bool toUseCurrentClusterManifestForDeployment)
        {
            TextLogger.LogInfo("Invoking FabricDeployer with deployment type = {0} and toUseCurrentClusterManifestForDeployment = {1}.", deploymentType, toUseCurrentClusterManifestForDeployment);

            string clusterManifestFileToDeploy;

            if (toUseCurrentClusterManifestForDeployment)
            {
                string currentClusterManifestFile = this.GetCurrentClusterManifestFile(topologyToDeploy.CurrentNodeName);

                if (File.Exists(currentClusterManifestFile))
                {
                    TextLogger.LogInfo("Using current cluster manifest file {0} for deployment.", currentClusterManifestFile);

                    clusterManifestFileToDeploy = currentClusterManifestFile;
                }
                else
                {
                    TextLogger.LogError("Current cluster manifest file does not exist as {0} when toUseCurrentClusterManifestForDeployment = true.", currentClusterManifestFile);

                    return(false);
                }
            }
            else
            {
                clusterManifestFileToDeploy = this.GetBootstrapClusterManifestFile();
            }

            if (!this.FabricDeploy(deploymentType, clusterManifestFileToDeploy, this.DataRootDirectory, topologyToDeploy.ServiceFabricNodes, true))
            {
                TextLogger.LogError(
                    "Failed to invoke FabricDeployer with deployment type = {0}, cluster manifest file = {1}, data root directory = {2}.",
                    deploymentType,
                    clusterManifestFileToDeploy,
                    this.DataRootDirectory);

                return(false);
            }

            return(true);
        }
        public bool DiscoverTopology(out ClusterTopology expectedTopology)
        {
            expectedTopology = null;

            try
            {
                TextLogger.LogInfo("Discovering cluster topology from bootstrap cluster manifest file.");

                if (ConfigurationManager.BootstrapClusterManifestLocation == BootstrapClusterManifestLocationType.NotReady)
                {
                    TextLogger.LogWarning("Bootstrap cluster manifest is not ready. Cluster topology would not be discovered until bootstrap cluster manifest is ready.");

                    return(false);
                }

                ClusterManifestType bootstrapClusterManifest;
                if (!this.ReadBootstrapClusterManifestFile(out bootstrapClusterManifest))
                {
                    return(false);
                }

                TopologyProviderType topologyProviderType = TopologyProvider.GetTopologyProviderTypeFromClusterManifest(bootstrapClusterManifest);

                TextLogger.LogInfo("Topology provider type : {0}.", topologyProviderType);

                if (topologyProviderType != TopologyProviderType.StaticTopologyProvider)
                {
                    TextLogger.LogInfo("Topology provider type {0} is not supported to provide static topology.", topologyProviderType);

                    return(false);
                }
                else
                {
                    /*
                     * Static topology provider defines the authoritative cluster topology in the cluster manifest.
                     * If the local machine (physical or virtual) is not part of the cluster topology specified in static topology provider section, a Service Fabric node will not be started locally.
                     * During scale-up, bootstrap cluster manifest has to be upgraded to allow new Service Fabric nodes to be started on the new machines and join the ring.
                     * A scale-up is normally a two-phase process with allocation of new machines (and their IPs) and generation of a new bootstrap cluster manifest with updated topology.
                     */
                    ClusterManifestTypeInfrastructureWindowsAzureStaticTopology staticTopologyProviderElement = TopologyProvider.GetStaticTopologyProviderElementFromClusterManifest(bootstrapClusterManifest);

                    if (staticTopologyProviderElement.NodeList == null || staticTopologyProviderElement.NodeList.Length == 0)
                    {
                        TextLogger.LogError("Static topology provider section of bootstrap cluster manifest does not specify topology of the Service Fabric cluster.");

                        return(false);
                    }

                    LogClusterTopology(staticTopologyProviderElement);

                    ClusterTopology staticTopologyProviderClusterTopology = ClusterTopology.GetClusterTopology();

                    staticTopologyProviderClusterTopology.LogTopology();

                    expectedTopology = staticTopologyProviderClusterTopology;

                    TextLogger.LogInfo("Successfully discovered cluster topology.");

                    return(true);
                }
            }
            catch (Exception e)
            {
                TextLogger.LogError("Failed to discover cluster topology : {0}", e);

                return(false);
            }
        }
        private bool RunStateMachineCore(ServiceFabricAutopilotAgentState currentState)
        {
            TextLogger.LogInfo("Starting RunStateMachineCore. Current state : {0}.", currentState);

            switch (currentState)
            {
            case ServiceFabricAutopilotAgentState.ManagingNetworkConfiguration:
            {
                if (!this.localNodeManager.ManageNetworkConfiguration())
                {
                    return(false);
                }

                ServiceFabricAutopilotAgentState nextState;
                if (!this.ComputeNextStateFromManagingNetworkConfigurationState(out nextState))
                {
                    return(false);
                }

                this.agentStatus.SetNextState(nextState);

                break;
            }

            case ServiceFabricAutopilotAgentState.InstallingProduct:
            {
                if (!this.localNodeManager.InstallProduct())
                {
                    return(false);
                }

                // For now, we assume the topology is static.
                // TODO: when adding dynamic topology support, change state machine transition here.
                this.agentStatus.SetNextState(ServiceFabricAutopilotAgentState.DiscoveringTopology);

                break;
            }

            case ServiceFabricAutopilotAgentState.DiscoveringTopology:
            {
                ClusterTopology expectedTopology;
                if (!this.localNodeManager.DiscoverTopology(out expectedTopology))
                {
                    return(false);
                }

                lock (this.agentStatus.StatusLock)
                {
                    this.agentStatus.ExpectedTopology = expectedTopology;

                    this.agentStatus.ExpectedTopologyRunning = false;
                }

                this.agentStatus.SetNextState(ServiceFabricAutopilotAgentState.ConfiguringNode);

                break;
            }

            case ServiceFabricAutopilotAgentState.ConfiguringNode:
            {
                ClusterTopology topologyToDeploy = this.agentStatus.GetTopologyToDeploy();

                if (!this.localNodeManager.ConfigureLocalNode(topologyToDeploy))
                {
                    return(false);
                }

                lock (this.agentStatus.StatusLock)
                {
                    this.agentStatus.DeployedTopology = topologyToDeploy;

                    this.agentStatus.ExpectedTopologyRunning = !this.agentStatus.DeployedTopology.IsClusterTopologyChanged(this.agentStatus.ExpectedTopology);
                }

                this.agentStatus.SetNextState(ServiceFabricAutopilotAgentState.StartingNode);

                break;
            }

            case ServiceFabricAutopilotAgentState.StartingNode:
            {
                if (!this.localNodeManager.StartLocalNode())
                {
                    return(false);
                }

                this.agentStatus.SetNextState(ServiceFabricAutopilotAgentState.NodeStarted);

                break;
            }

            case ServiceFabricAutopilotAgentState.NodeStarted:
            {
                // TODO: this only applies when DynamicTopologyUpdateMode == None or OnNodeConfigurationOnly.
                // When we want to update topology whenever topology changes, this needs to change.
                lock (this.agentStatus.StatusLock)
                {
                    this.agentStatus.ExpectedTopologyRunning = true;
                    this.agentStatus.ExpectedTopology        = ClusterTopology.GetClusterTopology();
                    this.agentStatus.DeployedTopology        = this.agentStatus.ExpectedTopology;
                }

                break;
            }
            }

            return(true);
        }