// 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());
        }
        private static bool CheckNoMachineIsDomainController(MachineHealthContainer machineHealthContainer)
        {
            Parallel.ForEach(
                machineHealthContainer.GetHealthyMachineNames(),
                (string machineName) =>
            {
                bool result = true;
                try
                {
                    if (StandaloneUtility.IsMachineDomainController(machineName))
                    {
                        SFDeployerTrace.WriteError(StringResources.Error_BPAMachineIsDomainController, machineName);
                        result = false;
                    }
                }
                catch (System.ComponentModel.Win32Exception ex)
                {
                    SFDeployerTrace.WriteError(StringResources.Error_BPADomainControllerQueryException, machineName, ex.NativeErrorCode, ex.Message);
                    result = false;
                }

                if (!result)
                {
                    machineHealthContainer.MarkMachineAsUnhealthy(machineName);
                }
            });

            return(machineHealthContainer.EnoughHealthyMachines());
        }
        private static bool CheckFirewallEnabled(MachineHealthContainer machineHealthContainer)
        {
            SFDeployerTrace.WriteNoise(StringResources.Info_BPAWindowsFirewall);
            Parallel.ForEach(
                machineHealthContainer.GetHealthyMachineNames(),
                (string machineName) =>
            {
                bool result = true;
                try
                {
                    FabricDeployerServiceController.ServiceStartupType type =
                        FabricDeployerServiceController.GetServiceStartupType(machineName, DMConstants.FirewallServiceName);
                    if (type == FabricDeployerServiceController.ServiceStartupType.Disabled)
                    {
                        SFDeployerTrace.WriteError(StringResources.Error_BPAFirewallServiceDisabled, machineName);
                        result = false;
                    }
                }
                catch (Exception ex)
                {
                    SFDeployerTrace.WriteError(StringResources.Error_BPAFirewallServiceQueryException, machineName, ex.Message);
                    result = false;
                }

                try
                {
                    ServiceController firewallSvc  = FabricDeployerServiceController.GetService(DMConstants.FirewallServiceName, machineName);
                    ServiceControllerStatus status = firewallSvc.Status;
                    if (status == ServiceControllerStatus.Stopped || status == ServiceControllerStatus.StopPending)
                    {
                        SFDeployerTrace.WriteError(StringResources.Error_BPAFirewallServiceNotRunning, machineName, status.ToString());
                        result = false;
                    }
                }
                catch (Exception ex)
                {
                    SFDeployerTrace.WriteError(StringResources.Error_BPAFirewallServiceStatusException, machineName, ex.Message);
                    result = false;
                }

                if (!result)
                {
                    machineHealthContainer.MarkMachineAsUnhealthy(machineName);
                }
            });

            return(machineHealthContainer.EnoughHealthyMachines());
        }
        private static bool CheckRemoteRegistryEnabled(MachineHealthContainer machineHealthContainer)
        {
            SFDeployerTrace.WriteNoise(StringResources.Info_BPARemoteRegistry);
            Parallel.ForEach(
                machineHealthContainer.GetHealthyMachineNames(),
                (string machineName) =>
            {
                bool result    = true;
                int retryCount = 5;
                for (int i = 0; i < retryCount; i++)
                {
                    try
                    {
                        FabricDeployerServiceController.ServiceStartupType type =
                            FabricDeployerServiceController.GetServiceStartupType(machineName, DMConstants.RemoteRegistryServiceName);
                        if (type == FabricDeployerServiceController.ServiceStartupType.Disabled)
                        {
                            SFDeployerTrace.WriteError(StringResources.Error_BPARemoteRegistryServiceDisabled, machineName);
                            result = false;
                        }

                        break;
                    }
                    catch (Exception ex)
                    {
                        SFDeployerTrace.WriteError(StringResources.Error_BPARemoteRegistryQueryException, machineName, ex.Message, i);

                        if (i < retryCount - 1)
                        {
                            Thread.Sleep(TimeSpan.FromSeconds(10));
                        }
                        else
                        {
                            result = false;
                        }
                    }
                }

                if (!result)
                {
                    machineHealthContainer.MarkMachineAsUnhealthy(machineName);
                }
            });

            return(machineHealthContainer.EnoughHealthyMachines());
        }
        private static bool CheckDrivesAvailableSpace(MachineHealthContainer machineHealthContainer, string fabricDataRoot, string fabricLogRoot)
        {
            List <string> drives                       = new List <string>();
            string        candidateMachine             = machineHealthContainer.GetHealthyMachineNames().ElementAt(0);
            string        fabricPackageDestinationPath = Utility.GetDefaultPackageDestination(candidateMachine);
            string        fabricRootDrive              = Path.GetPathRoot(fabricPackageDestinationPath);

            drives.Add(fabricRootDrive);

            if (fabricDataRoot != null)
            {
                drives.Add(Path.GetPathRoot(fabricDataRoot));
            }

            if (fabricLogRoot != null)
            {
                drives.Add(Path.GetPathRoot(fabricLogRoot));
            }

            foreach (string drive in drives.Distinct())
            {
                Parallel.ForEach(
                    machineHealthContainer.GetHealthyMachineNames(),
                    (string machineName) =>
                {
                    string remoteRootDrive = Helpers.GetRemotePathIfNotLocalMachine(drive, machineName);
                    if (!StandaloneUtility.EnoughAvailableSpaceOnDrive(remoteRootDrive))
                    {
                        SFDeployerTrace.WriteError(StringResources.Error_BPANotEnoughSpaceOnDrive, drive, machineName);
                        machineHealthContainer.MarkMachineAsUnhealthy(machineName);
                    }
                });
            }

            return(machineHealthContainer.EnoughHealthyMachines());
        }
        private static bool CheckDataSystemDrives(MachineHealthContainer machineHealthContainer, string fabricDataRoot, string fabricLogRoot)
        {
            bool systemDataDriveExists = true;
            bool systemLogDriveExists  = true;

            if (fabricDataRoot != null)
            {
                // Verify path system drive exists on each machine to be deployed
                Parallel.ForEach(
                    machineHealthContainer.GetHealthyMachineNames(),
                    (string machineName) =>
                {
                    try
                    {
                        string remotePath = Helpers.GetRemotePathIfNotLocalMachine(fabricDataRoot, machineName);
                        var info          = new DirectoryInfo(remotePath);

                        if (!info.Root.Exists)
                        {
                            SFDeployerTrace.WriteError(StringResources.Error_BPAJsonDataRootRootDriveDoesNotExist, DMConstants.FabricDataRootString, machineName);
                            systemDataDriveExists = false;
                            machineHealthContainer.MarkMachineAsUnhealthy(machineName);
                        }
                    }
                    catch (Exception ex)
                    {
                        SFDeployerTrace.WriteNoise(StringResources.Error_BPAJsonDataRootRootDriveQueryException, DMConstants.FabricDataRootString, ex);
                        systemDataDriveExists = false;
                        machineHealthContainer.MarkMachineAsUnhealthy(machineName);
                    }
                });

                if (!systemDataDriveExists)
                {
                    SFDeployerTrace.WriteError(StringResources.Error_BPAJsonDataRootRootDriveDoesNotExistGeneric, DMConstants.FabricDataRootString);
                }
            }

            if (fabricLogRoot != null)
            {
                Parallel.ForEach(
                    machineHealthContainer.GetHealthyMachineNames(),
                    (string machineName) =>
                {
                    try
                    {
                        string remotePath = Helpers.GetRemotePathIfNotLocalMachine(fabricLogRoot, machineName);
                        var info          = new DirectoryInfo(remotePath);
                        if (!info.Root.Exists)
                        {
                            SFDeployerTrace.WriteError(StringResources.Error_BPAJsonDataRootRootDriveDoesNotExist, DMConstants.FabricLogRootString, machineName);
                            systemLogDriveExists = false;
                            machineHealthContainer.MarkMachineAsUnhealthy(machineName);
                        }
                    }
                    catch (Exception ex)
                    {
                        SFDeployerTrace.WriteError(StringResources.Error_BPAJsonDataRootRootDriveQueryException, DMConstants.FabricLogRootString, ex);
                        systemLogDriveExists = false;
                        machineHealthContainer.MarkMachineAsUnhealthy(machineName);
                    }
                });

                if (!systemLogDriveExists)
                {
                    SFDeployerTrace.WriteError(StringResources.Error_BPAJsonDataRootRootDriveDoesNotExistGeneric, DMConstants.FabricLogRootString);
                }
            }

            return(machineHealthContainer.EnoughHealthyMachines());
        }
        private static bool CheckRPCAccess(MachineHealthContainer machineHealthContainer)
        {
            var retryTimeout = new System.Fabric.Common.TimeoutHelper(DMConstants.BpaRpcRetryTimeout);

            SFDeployerTrace.WriteNoise(StringResources.Info_SFRpcInfo);

            Parallel.ForEach <string>(
                machineHealthContainer.GetHealthyMachineNames(),
                (string machine) =>
            {
                bool result = true;
                bool willRetry;

                do
                {
                    willRetry = false;

                    try
                    {
                        Utility.GetTempPath(machine);
                    }
                    catch (Exception ex)
                    {
                        string message;
                        if (ex is System.IO.IOException)
                        {
                            switch (ex.HResult)
                            {
                            // If new failures are discovered: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
                            case 53:         // ERROR_BAD_NETPATH
                                message   = string.Format(StringResources.Error_SFRpcIoNetpath, machine, ex.HResult);
                                willRetry = true;
                                break;

                            case 1723:         // RPC_S_SERVER_TOO_BUSY
                                message   = string.Format(StringResources.Error_SFRpcIoTooBusy, machine, ex.HResult);
                                willRetry = true;
                                break;

                            case 1727:         // RPC_S_CALL_FAILED_DNE
                                message = string.Format(StringResources.Error_SFRpcIoFailedDne, machine, ex.HResult);
                                break;

                            default:
                                message = string.Format(StringResources.Error_SFRpcIoGeneric, machine, ex.HResult);
                                break;
                            }
                        }
                        else if (ex is System.Security.SecurityException)
                        {
                            switch (ex.HResult)
                            {
                            case -2146233078:         // COR_E_SECURITY
                                message = string.Format(StringResources.Error_SFRpcSecAccess, machine, ex.HResult);
                                break;

                            default:
                                message = string.Format(StringResources.Error_SFRpcSecGeneric, machine, ex.HResult);
                                break;
                            }
                        }
                        else if (ex is NullReferenceException)
                        {
                            switch (ex.HResult)
                            {
                            case -2146232828:         // COR_E_TARGETINVOCATION
                                message = string.Format(StringResources.Error_SFRpcNullRegAccess, machine, ex.HResult);
                                break;

                            default:
                                message = string.Format(StringResources.Error_SFRpcNullGeneric, machine, ex.HResult);
                                break;
                            }
                        }
                        else
                        {
                            // This is to catch coding errors.
                            message = string.Format(StringResources.Error_SFRpcGeneric, machine, ex.HResult);
                        }

                        willRetry &= !System.Fabric.Common.TimeoutHelper.HasExpired(retryTimeout);

                        if (willRetry)
                        {
                            SFDeployerTrace.WriteWarning(message);

                            StandaloneUtility.OpenRemoteRegistryNamedPipe(machine, retryTimeout.GetRemainingTime());

                            Thread.Sleep(TimeSpan.FromSeconds(5));
                        }
                        else
                        {
                            SFDeployerTrace.WriteError(message);

                            result = false;
                        }
                    }
                }while (willRetry);

                if (!result)
                {
                    machineHealthContainer.MarkMachineAsUnhealthy(machine);
                }
            });

            return(machineHealthContainer.EnoughHealthyMachines());
        }