// Clean install requires machine be free of previous Fabric installations private static bool CheckForCleanInstall(StandAloneInstallerJsonModelBase config, MachineHealthContainer machineHealthContainer, bool isForcedRun = false) { SFDeployerTrace.WriteNoise(StringResources.Info_BPANoFabric); List <string> machineNamesTemp = StandaloneUtility.GetMachineNamesIncludingClient(machineHealthContainer.GetHealthyMachineNames()); var importantSettings = config.GetFabricSystemSettings(); string fabricDataRoot = importantSettings.ContainsKey(DMConstants.FabricDataRootString) ? importantSettings[DMConstants.FabricDataRootString] : null; bool localMachineFailed = false; Parallel.ForEach( machineNamesTemp, (string machineName) => { bool result = true; if (StandaloneUtility.IsFabricInstalled(machineName)) { SFDeployerTrace.WriteError(StringResources.Error_BPAPreviousFabricExists, machineName); result = false; } if (!isForcedRun) { if (fabricDataRoot != null) { IEnumerable <string> machineNodes = config.Nodes.Where(n => n.IPAddress == machineName).Select(n => n.NodeName); foreach (string node in machineNodes) { string nodeDirectory; if (StandaloneUtility.DataRootNodeExists(machineName, node, fabricDataRoot, out nodeDirectory)) { SFDeployerTrace.WriteError(StringResources.Error_BPADataRootNodeExists, node, machineName, nodeDirectory); result = false; } } } } if (!result) { if (Helpers.IsLocalIpAddress(machineName)) { localMachineFailed = true; } else { machineHealthContainer.MarkMachineAsUnhealthy(machineName); } } }); if (localMachineFailed) { return(false); } return(machineHealthContainer.EnoughHealthyMachines()); }
internal static AnalysisSummary AnalyzeClusterSetup( string configPath, string oldConfigPath, string cabPath, bool usingClusterManifest = false, FabricPackageType fabricPackageType = FabricPackageType.XCopyPackage, bool isForcedRun = false, int maxPercentFailedNodes = 0) { SFDeployerTrace.WriteInfo(StringResources.Info_BPAStart); var summary = new AnalysisSummary(); // Check user has local admin privilege summary.LocalAdminPrivilege = CheckLocalAdminPrivilege(); // Validate JSON config StandAloneInstallerJsonModelBase standAloneModel = null; StandAloneInstallerJsonModelBase oldStandAloneModel = null; if (!usingClusterManifest) { standAloneModel = StandAloneInstallerJsonModelBase.GetJsonConfigFromFile(configPath); if (!string.IsNullOrEmpty(oldConfigPath)) { oldStandAloneModel = StandAloneInstallerJsonModelBase.GetJsonConfigFromFile(oldConfigPath); } summary.IsJsonValid = IsJsonConfigModelValid(standAloneModel, oldStandAloneModel, validateDownNodes: true, throwIfError: false) && ValidateCodeVersionExists(standAloneModel); } // Deliberately not checking empty. Some invocations aren't intended to test cabPath. if (cabPath != null) { summary.IsCabValid = CheckIsCabFile(cabPath); } // Below depends on JSON being valid if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } // Get machine names from JSON config IEnumerable <string> healthyMachineNames = usingClusterManifest ? StandaloneUtility.GetMachineNamesFromClusterManifest(configPath) : standAloneModel.GetClusterTopology().Machines; MachineHealthContainer machineHealthContainer = new MachineHealthContainer(healthyMachineNames, maxPercentFailedNodes); // Validate machine FQDNs, Check SMB ports opened summary.RequiredPortsOpen = StandaloneUtility.CheckRequiredPorts(machineHealthContainer); // Below depends on machines being reachable if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } // Validate Remote Registry Service is not disabled on all machines summary.RemoteRegistryAvailable = CheckRemoteRegistryEnabled(machineHealthContainer); // Below depends on remote registry service if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } summary.FirewallAvailable = CheckFirewallEnabled(machineHealthContainer); // Below depends on firewall service if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } // Run RPC check to validate end-to-end registry access to all machines summary.RpcCheckPassed = CheckRPCAccess(machineHealthContainer); // Below depend on remote registry access if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } summary.NoDomainController = CheckNoMachineIsDomainController(machineHealthContainer); // Below depends on machines not being domain controller if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } if (fabricPackageType == FabricPackageType.XCopyPackage) { // Validate that Fabric runtime MSI is not installed since this will be conflicting with Standalone summary.NoConflictingInstallations = !StandaloneUtility.IsMsiInstalled(machineHealthContainer); } string fabricDataRoot = null; string fabricLogRoot = null; if (!usingClusterManifest) { if (string.IsNullOrEmpty(oldConfigPath)) { summary.FabricInstallable = CheckForCleanInstall(standAloneModel, machineHealthContainer, isForcedRun); // Fabric is not installed on target machines } var importantSettings = standAloneModel.GetFabricSystemSettings(); fabricDataRoot = importantSettings.ContainsKey(DMConstants.FabricDataRootString) ? importantSettings[DMConstants.FabricDataRootString] : null; fabricLogRoot = importantSettings.ContainsKey(DMConstants.FabricLogRootString) ? importantSettings[DMConstants.FabricLogRootString] : null; summary.DataDrivesAvailable = CheckDataSystemDrives(machineHealthContainer, fabricDataRoot, fabricLogRoot); // System drives for path-based settings, exist on target machines // Below depend on data system drives if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } } summary.DrivesEnoughAvailableSpace = CheckDrivesAvailableSpace(machineHealthContainer, fabricDataRoot, fabricLogRoot); // Below depend on root drives having enough space available if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } summary.IsAllOrNoneIOTDevice = CheckAllIOTDevices(machineHealthContainer); // Below depend on all or none machines being IOT Devices if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } // Check dotnet.exe exists in %Path% // Currently we only need to check for IOTCore environment. summary.DotNetExeInPath = IsDotNetExeInPath(machineHealthContainer); // Below depend on IOT Devices having dotnet.exe in path if (!summary.Passed) { SFDeployerTrace.WriteError(StringResources.Error_BPABailing); return(summary); } summary.MachineHealthContainer = machineHealthContainer; LogResult(summary); return(summary); }