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); } }
// 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); }