An xml file that keeps track of deployment status
Inheritance: IDeploymentStatusFile
コード例 #1
0
ファイル: DeploymentManager.cs プロジェクト: ashbrener/kudu
        private DeploymentStatusFile CreateStatusFile(string id)
        {
            DeploymentStatusFile deploymentStatusFile = DeploymentStatusFile.Create(GetStatusFilePath(id));

            deploymentStatusFile.Id = id;
            return(deploymentStatusFile);
        }
コード例 #2
0
ファイル: DeploymentManager.cs プロジェクト: JamesTryand/kudu
        /// <summary>
        /// Ensure the deployment is in a valid state.
        /// </summary>
        private DeploymentStatusFile VerifyDeployment(string id, bool isDeploying)
        {
            DeploymentStatusFile statusFile = OpenStatusFile(id);

            if (statusFile == null)
            {
                return(null);
            }

            if (statusFile.Complete)
            {
                return(statusFile);
            }

            // There's an incomplete deployment, yet nothing is going on, mark this deployment as failed
            // since it probably means something died
            if (!isDeploying)
            {
                MarkFailed(statusFile);

                ILogger logger = GetLogger(id);
                logger.LogUnexpetedError();
            }

            return(statusFile);
        }
コード例 #3
0
        public static DeploymentStatusFile Open(string id, IEnvironment environment, IAnalytics analytics, IOperationLock statusLock)
        {
            // status complete file is created infrequently at deployment completion time
            // once deployment is completed, it is highly unlikely its status will change
            // this helps optimize status read operation avoid taking status lock
            DeploymentStatusFile statusComplete = null;

            OperationManager.SafeExecute(() =>
            {
                string path = Path.Combine(environment.DeploymentsPath, id, StatusCompleteFile);
                if (FileSystemHelpers.FileExists(path))
                {
                    if (ScmHostingConfigurations.DeploymentStatusCompleteFileEnabled)
                    {
                        statusComplete = new DeploymentStatusFile(id, environment, statusLock, FileSystemCache.ReadXml(path));
                    }
                    else
                    {
                        FileSystemHelpers.DeleteFile(path);
                    }
                }
            });

            return(statusComplete ?? statusLock.LockOperation(() =>
            {
                string path = Path.Combine(environment.DeploymentsPath, id, StatusFile);

                if (!FileSystemHelpers.FileExists(path))
                {
                    return null;
                }

                try
                {
                    XDocument document = null;
                    using (var stream = FileSystemHelpers.OpenRead(path))
                    {
                        document = XDocument.Load(stream);
                    }
                    return new DeploymentStatusFile(id, environment, statusLock, document);
                }
                catch (Exception ex)
                {
                    // in the scenario where w3wp is abruptly terminated while xml is being written,
                    // we may end up with corrupted xml.  we will handle the error and remove the problematic directory.
                    analytics.UnexpectedException(ex);

                    FileSystemHelpers.DeleteDirectorySafe(Path.GetDirectoryName(path), ignoreErrors: true);

                    // it is ok to return null as callers already handle null.
                    return null;
                }
            }, "Getting deployment status", DeploymentStatusManager.LockTimeout));
        }
コード例 #4
0
ファイル: DeploymentManager.cs プロジェクト: JamesTryand/kudu
        private void MarkFailed(DeploymentStatusFile currentStatus)
        {
            if (currentStatus == null)
            {
                return;
            }

            currentStatus.Complete   = true;
            currentStatus.Status     = DeployStatus.Failed;
            currentStatus.StatusText = String.Empty;
            currentStatus.EndTime    = DateTime.Now;
            currentStatus.Save(_fileSystem);
        }
コード例 #5
0
ファイル: DeploymentManager.cs プロジェクト: ashbrener/kudu
        public IDisposable CreateTemporaryDeployment(string statusText)
        {
            var    tracer = _traceFactory.GetTracer();
            string id     = TemporaryDeploymentId;

            using (tracer.Step("Creating temporary deployment"))
            {
                DeploymentStatusFile statusFile = CreateStatusFile(id);
                statusFile.Status     = DeployStatus.Pending;
                statusFile.StatusText = statusText;
                statusFile.Save(_fileSystem);
            }

            // Return a handle that deletes the deployment on dispose.
            return(new DisposableAction(DeleteTemporaryDeployment));
        }
コード例 #6
0
ファイル: DeploymentManager.cs プロジェクト: JamesTryand/kudu
        /// <summary>
        /// Runs post deployment steps.
        /// - Marks the active deployment
        /// - Sets the complete flag
        /// </summary>
        private void FinishDeployment(string id, ITracer tracer, IDisposable deployStep)
        {
            DeploymentStatusFile currentStatus = null;
            ILogger logger = null;

            try
            {
                currentStatus = OpenStatusFile(id);
                logger        = GetLogger(id);

                // Write the active deployment file
                MarkActive(id);

                logger.Log(Resources.Log_DeploymentSuccessful);

                currentStatus.Status             = DeployStatus.Success;
                currentStatus.StatusText         = String.Empty;
                currentStatus.EndTime            = DateTime.Now;
                currentStatus.LastSuccessEndTime = currentStatus.EndTime;
                currentStatus.Save(_fileSystem);
            }
            catch (Exception ex)
            {
                tracer.TraceError(ex);

                MarkFailed(currentStatus);

                logger.LogUnexpetedError();
            }
            finally
            {
                // Set the deployment as complete
                currentStatus.Complete = true;
                currentStatus.Save(_fileSystem);

                ReportStatus(id);

                // End the deployment step
                deployStep.Dispose();
            }
        }
コード例 #7
0
ファイル: DeploymentManager.cs プロジェクト: JamesTryand/kudu
        private ILogger CreateAndPopulateStatusFile(ITracer tracer, string id, string deployer)
        {
            ILogger logger = GetLogger(id);

            using (tracer.Step("Collecting changeset information"))
            {
                // Create the status file and store information about the commit
                DeploymentStatusFile statusFile = CreateStatusFile(id);
                statusFile.Id = id;
                ChangeSet changeSet = _serverRepository.GetChangeSet(id);
                statusFile.Message     = changeSet.Message;
                statusFile.Author      = changeSet.AuthorName;
                statusFile.Deployer    = deployer;
                statusFile.AuthorEmail = changeSet.AuthorEmail;
                statusFile.Save(_fileSystem);

                logger.Log(Resources.Log_NewDeploymentReceived);
            }

            return(logger);
        }
コード例 #8
0
 public IDeploymentStatusFile Open(string id)
 {
     return(DeploymentStatusFile.Open(id, _environment, _analytics, _statusLock));
 }
コード例 #9
0
 public IDeploymentStatusFile Create(string id)
 {
     return(DeploymentStatusFile.Create(id, _environment, _statusLock));
 }
コード例 #10
0
ファイル: DeploymentManager.cs プロジェクト: JamesTryand/kudu
 private DeploymentStatusFile CreateStatusFile(string id)
 {
     return(DeploymentStatusFile.Create(GetStatusFilePath(id)));
 }
コード例 #11
0
ファイル: DeploymentManager.cs プロジェクト: JamesTryand/kudu
 private DeploymentStatusFile OpenStatusFile(string id)
 {
     return(DeploymentStatusFile.Open(_fileSystem, GetStatusFilePath(id, ensureDirectory: false)));
 }
コード例 #12
0
ファイル: DeploymentManager.cs プロジェクト: JamesTryand/kudu
        /// <summary>
        /// Builds and deploys a particular changeset. Puts all build artifacts in a deployments/{id}
        /// </summary>
        private void Build(string id, ITracer tracer, IDisposable deployStep)
        {
            if (String.IsNullOrEmpty(id))
            {
                throw new ArgumentException();
            }

            ILogger logger = null;
            DeploymentStatusFile currentStatus = null;
            IDisposable          buildStep     = null;

            try
            {
                logger = GetLogger(id);
                ILogger innerLogger = logger.Log(Resources.Log_PreparingDeployment, TrimId(id));

                currentStatus            = OpenStatusFile(id);
                currentStatus.Complete   = false;
                currentStatus.StartTime  = DateTime.Now;
                currentStatus.Status     = DeployStatus.Building;
                currentStatus.StatusText = String.Format(CultureInfo.CurrentCulture, Resources.Status_BuildingAndDeploying, id);
                currentStatus.Save(_fileSystem);

                ReportStatus(id);

                ISiteBuilder builder = null;

                try
                {
                    builder = _builderFactory.CreateBuilder(tracer, innerLogger);
                }
                catch (Exception ex)
                {
                    _globalLogger.Log(ex);

                    tracer.TraceError(ex);

                    innerLogger.Log(ex);

                    MarkFailed(currentStatus);

                    ReportStatus(id);

                    deployStep.Dispose();

                    return;
                }

                buildStep = tracer.Step("Building");

                var context = new DeploymentContext
                {
                    ManifestWriter   = GetDeploymentManifestWriter(id),
                    PreviousMainfest = GetActiveDeploymentManifestReader(),
                    Tracer           = tracer,
                    Logger           = logger,
                    GlobalLogger     = _globalLogger,
                    OutputPath       = _environment.DeploymentTargetPath,
                };

                builder.Build(context)
                .Then(() =>
                {
                    // End the build step
                    buildStep.Dispose();

                    // Run post deployment steps
                    FinishDeployment(id, tracer, deployStep);
                })
                .Catch(ex =>
                {
                    // End the build step
                    buildStep.Dispose();

                    MarkFailed(currentStatus);

                    ReportStatus(id);

                    // End the deploy step
                    deployStep.Dispose();
                });
            }
            catch (Exception ex)
            {
                tracer.TraceError(ex);

                logger.LogUnexpetedError();

                if (buildStep != null)
                {
                    buildStep.Dispose();
                }

                deployStep.Dispose();
            }
        }
コード例 #13
0
        private void NotifyError(ILogger logger, DeploymentStatusFile trackingFile, Exception exception)
        {
            logger.Log("Deployment failed.", LogEntryType.Error);

            // Failed to deploy
            trackingFile.Percentage = 100;
            trackingFile.Status = DeployStatus.Failed;
            trackingFile.StatusText = String.Empty;
            trackingFile.DeploymentEndTime = DateTime.Now;
            trackingFile.Save(_fileSystem);
        }
コード例 #14
0
        // Temporary dirty code to install node packages. Switch to real NPM when available
        private void DownloadNodePackages(string id, DeploymentStatusFile trackingFile, ILogger logger)
        {
            var p = new nji.Program();
            p.ModulesDir = Path.Combine(_environment.DeploymentTargetPath, "node_modules");
            p.TempDir = Path.Combine(p.ModulesDir, ".tmp");
            p.Logger = logger;
            p.UpdateStatusText = (statusText) => {
                trackingFile.StatusText = statusText;
                trackingFile.Save(_fileSystem);
                NotifyStatus(id);
            };

            p.InstallDependencies(_environment.DeploymentTargetPath);
        }
コード例 #15
0
        public void Deploy(string id, string deployer, bool clean)
        {
            ITracer     tracer     = _traceFactory.GetTracer();
            IDisposable deployStep = null;

            try
            {
                deployStep = tracer.Step("DeploymentManager.Deploy(id)");

                // Check to see if we have a deployment with this id already
                string trackingFilePath = GetStatusFilePath(id, ensureDirectory: false);

                if (!_fileSystem.File.Exists(trackingFilePath))
                {
                    // If we don't then throw
                    throw new FileNotFoundException(String.Format(CultureInfo.CurrentCulture, Resources.Error_DeployNotFound, id));
                }

                // Remove the old log file for this deployment id
                string logPath = GetLogPath(id);
                FileSystemHelpers.DeleteFileSafe(logPath);

                ILogger logger = GetLogger(id);

                using (tracer.Step("Updating to specific changeset"))
                {
                    // Update to the the specific changeset
                    _serverRepository.Update(id);
                }

                if (clean)
                {
                    tracer.Trace("Cleaning git repository");

                    logger.Log(Resources.Log_CleaningGitRepository);

                    _serverRepository.Clean();
                }

                if (!String.IsNullOrEmpty(deployer))
                {
                    // Update the deployer
                    DeploymentStatusFile statusFile = OpenStatusFile(id);
                    statusFile.Deployer = deployer;
                    statusFile.Save(_fileSystem);
                }

                // Perform the build deployment of this changeset
                Build(id, tracer, deployStep);
            }
            catch (Exception ex)
            {
                tracer.TraceError(ex);

                if (deployStep != null)
                {
                    deployStep.Dispose();
                }

                throw;
            }
        }
コード例 #16
0
 public IDeploymentStatusFile Open(string id)
 {
     return(DeploymentStatusFile.Open(id, _fileSystem, _environment, _statusLock));
 }
コード例 #17
0
ファイル: DeploymentManager.cs プロジェクト: cburgdorf/kudu
        private void MarkFailed(DeploymentStatusFile currentStatus)
        {
            if (currentStatus == null)
            {
                return;
            }

            currentStatus.Complete = true;
            currentStatus.Status = DeployStatus.Failed;
            currentStatus.StatusText = String.Empty;
            currentStatus.EndTime = DateTime.Now;
            currentStatus.Save(_fileSystem);
        }
コード例 #18
0
        private void NotifyError(ILogger logger, DeploymentStatusFile trackingFile, Exception exception)
        {
            logger.Log("Deployment failed.", LogEntryType.Error);

            if (trackingFile != null)
            {
                // Failed to deploy
                trackingFile.Percentage = 100;
                trackingFile.Complete = true;
                trackingFile.Status = DeployStatus.Failed;
                trackingFile.StatusText = trackingFile.Status == DeployStatus.Failed ? logger.GetTopLevelError() : String.Empty;
                trackingFile.DeploymentEndTime = DateTime.Now;
                trackingFile.Save(_fileSystem);
            }
        }