internal void ValidateAndEnsureDefaultImageStore()
        {
            try
            {
                fabricValidator = FabricValidator.Create(manifest, infrastructure == null ? null : infrastructure.InfrastructureNodes, new WindowsFabricSettings(this.manifest), parameters.Operation);
                fabricValidator.Validate();
            }
            catch (Exception e)
            {
                throw new ClusterManifestValidationException(
                          string.Format(StringResources.Error_FabricDeployer_InvalidClusterManifest_Formatted, e));
            }

            if (this.fabricValidator.IsSingleMachineDeployment)
            {
                this.EnsureImageStoreForSingleMachineDeployment(Path.Combine(parameters.DeploymentSpecification.GetDataRoot(), Constants.DefaultImageStoreRootFolderName));
                this.EnsureCorrectDiagnosticStore(Path.Combine(parameters.DeploymentSpecification.GetDataRoot(), Constants.DefaultDiagnosticsStoreRootFolderName));
            }
            else
            {
                this.EnsureCorrectDiagnosticStore(null);
            }
        }
        internal static void CompareAndAnalyze(ClusterManifestType currentClusterManifest, ClusterManifestType targetClusterManifest, Infrastructure infrastructure, DeploymentParameters parameters)
        {
            // If the infrastructure elements are different, the update cannot continue
            if (targetClusterManifest.Infrastructure.Item.GetType() != currentClusterManifest.Infrastructure.Item.GetType())
            {
                DeployerTrace.WriteError("Invalid Operation. Cannot update from 1 infrastructure type to another");
                throw new ClusterManifestValidationException(StringResources.Error_FabricDeployer_InvalidClusterManifest_Formatted);
            }

            // Validate that the new cluster manifest and the node list are valid
            try
            {
                var currentWindowsFabricSettings = new WindowsFabricSettings(currentClusterManifest);
                var targetWindowsFabricSettings  = new WindowsFabricSettings(targetClusterManifest);
                FabricValidator.Create(targetClusterManifest, infrastructure.InfrastructureNodes, targetWindowsFabricSettings, parameters.Operation).Validate();
                //Validate if the SeedNodeCount increases by one
                int           currentSeedNodes = 0, targetSeedNodes = 0;
                List <String> currentSeedNodesList = new List <String>();
                List <String> targetSeedNodesList  = new List <String>();
                if (currentClusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureWindowsAzure)
                {
                    ClusterManifestTypeInfrastructureWindowsAzure currentInfrastructure = currentClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsAzure;
                    ClusterManifestTypeInfrastructureWindowsAzure targetInfrastructure  = targetClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsAzure;
                    for (int i = 0; i < currentInfrastructure.Roles.Length; i++)
                    {
                        currentSeedNodes += currentInfrastructure.Roles[i].SeedNodeCount;
                    }
                    for (int j = 0; j < targetInfrastructure.Roles.Length; j++)
                    {
                        targetSeedNodes += targetInfrastructure.Roles[j].SeedNodeCount;
                    }
                }
                else if (currentClusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureWindowsAzureStaticTopology)
                {
                    ClusterManifestTypeInfrastructureWindowsAzureStaticTopology currentInfrastructure = currentClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsAzureStaticTopology;
                    ClusterManifestTypeInfrastructureWindowsAzureStaticTopology targetInfrastructure  = targetClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsAzureStaticTopology;
                    foreach (FabricNodeType nodelist in currentInfrastructure.NodeList)
                    {
                        if (nodelist.IsSeedNode)
                        {
                            currentSeedNodes++;
                        }
                    }
                    foreach (FabricNodeType nodelist in targetInfrastructure.NodeList)
                    {
                        if (nodelist.IsSeedNode)
                        {
                            targetSeedNodes++;
                        }
                    }
                }
#if DotNetCoreClrLinux
                else if (currentClusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureLinux)
                {
                    var currentInfrastructure = currentClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureLinux;
                    var targetInfrastructure  = targetClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureLinux;
#else
                else if (currentClusterManifest.Infrastructure.Item is ClusterManifestTypeInfrastructureWindowsServer)
                {
                    var currentInfrastructure = currentClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsServer;
                    var targetInfrastructure  = targetClusterManifest.Infrastructure.Item as ClusterManifestTypeInfrastructureWindowsServer;
#endif
                    foreach (FabricNodeType nodelist in currentInfrastructure.NodeList)
                    {
                        if (nodelist.IsSeedNode)
                        {
                            currentSeedNodes++;
                            currentSeedNodesList.Add(nodelist.NodeName);
                        }
                    }
                    foreach (FabricNodeType nodelist in targetInfrastructure.NodeList)
                    {
                        if (nodelist.IsSeedNode)
                        {
                            targetSeedNodes++;
                            targetSeedNodesList.Add(nodelist.NodeName);
                        }
                    }
                }
                if (System.Math.Abs(currentSeedNodes - targetSeedNodes) > 1)
                {
                    DeployerTrace.WriteError(StringResources.Warning_SeedNodeCountCanOnlyChangeByOne);
                    throw new ClusterManifestValidationException(StringResources.Warning_SeedNodeCountCanOnlyChangeByOne);
                }
                else if (currentSeedNodesList.Except(targetSeedNodesList).Union(targetSeedNodesList.Except(currentSeedNodesList)).Count() > 1)
                {
                    DeployerTrace.WriteError(StringResources.Warning_SeedNodeSetCannotHaveMultipleChanges);
                    throw new ClusterManifestValidationException(StringResources.Warning_SeedNodeSetCannotHaveMultipleChanges);
                }

                var fabricValidator = FabricValidator.Create(currentClusterManifest, null, currentWindowsFabricSettings, parameters.Operation);
                // Finally, compare the settings and decide if fabric must restart or not
                IEnumerable <KeyValuePair <string, string> > modifiedStaticSettings = fabricValidator.CompareAndAnalyze(targetClusterManifest, parameters.NodeTypeName);
                if (modifiedStaticSettings.Count() > 0)
                {
                    WriteModifiedStaticSettingsToFile(modifiedStaticSettings, targetClusterManifest.FabricSettings, parameters.OutputFile);
                    throw new FabricHostRestartRequiredException("Fabric host restart is required");
                }
                else
                {
                    throw new FabricHostRestartNotRequiredException("Fabric host restart is not required");
                }
            }
            catch (Exception e)
            {
                if (e is FabricHostRestartRequiredException || e is FabricHostRestartNotRequiredException)
                {
                    throw e;
                }
                else
                {
                    throw new ClusterManifestValidationException(
                              string.Format(StringResources.Error_FabricDeployer_InvalidClusterManifest_Formatted, e));
                }
            }
        }
        public void UpgradeFabric(
            string currentFabricVersion,
            string targetFabricVersion,
#if !DotNetCoreClrLinux && !DotNetCoreClrIOT
            string configurationCsvFilePath,
#endif
            TimeSpan timeout,
            out bool isConfigOnly)
        {
            isConfigOnly = false;

            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            ImageBuilder.TraceSource.WriteInfo(
                TraceType,
                "UpgradeFabric started: CurrentFabricVersion:{0}, TargetFabricVersion:{1}, Timeout:{2}",
                currentFabricVersion,
                targetFabricVersion,
                timeoutHelper.GetRemainingTime());

            // If the current version is invalid (ie. Cluster FabricVersion is not determined)
            // then do not validate
            if (ImageBuilderUtility.Equals(currentFabricVersion, FabricVersion.Invalid.ToString()))
            {
                return;
            }

            FabricVersion currentVersion, targetVersion;

            bool isValid = FabricVersion.TryParse(currentFabricVersion, out currentVersion);

            if (!isValid)
            {
                ImageBuilderUtility.TraceAndThrowValidationError(
                    TraceType,
                    StringResources.ImageBuilderError_InvalidValue,
                    "CurrentFabricVersion",
                    currentFabricVersion);
            }

            isValid = FabricVersion.TryParse(targetFabricVersion, out targetVersion);
            if (!isValid)
            {
                ImageBuilderUtility.TraceAndThrowValidationError(
                    TraceType,
                    StringResources.ImageBuilderError_InvalidValue,
                    "TargetFabricVersion",
                    targetFabricVersion);
            }

            WinFabStoreLayoutSpecification winFabLayout = WinFabStoreLayoutSpecification.Create();
            string currentClusterManifestPath           = winFabLayout.GetClusterManifestFile(currentVersion.ConfigVersion);
            string targetClusterManifestPath            = winFabLayout.GetClusterManifestFile(targetVersion.ConfigVersion);

            ClusterManifestType currentClusterManifest = this.imageStoreWrapper.GetFromStore <ClusterManifestType>(currentClusterManifestPath, timeoutHelper.GetRemainingTime());
            ClusterManifestType targetClusterManifest  = this.imageStoreWrapper.GetFromStore <ClusterManifestType>(targetClusterManifestPath, timeoutHelper.GetRemainingTime());

            timeoutHelper.ThrowIfExpired();

            try
            {
                // todo: Vaishnav to pass node list object loaded from the location
                FabricValidator fabricValidator = FabricValidator.Create(currentClusterManifest, null, new WindowsFabricSettings(currentClusterManifest), DeploymentOperations.Update);
                IEnumerable <KeyValuePair <string, string> > modifiedStaticSettings = fabricValidator.CompareAndAnalyze(targetClusterManifest, null /*Detect changes for any NodeType*/);
                isConfigOnly = !modifiedStaticSettings.Any();
            }
            catch (Exception e)
            {
                ImageBuilderUtility.TraceAndThrowValidationError(
                    TraceType,
                    StringResources.ImageBuilderError_InvalidConfigFabricUpgrade,
                    e.ToString(),
                    currentFabricVersion,
                    targetFabricVersion);
            }

            ImageBuilder.TraceSource.WriteInfo(
                TraceType,
                "UpgradeFabric completed: CurrentFabricVersion:{0}, TargetFabricVersion:{1}, ConfigOnly:{2}",
                currentFabricVersion,
                targetFabricVersion,
                isConfigOnly);
        }