Пример #1
0
        /// <summary>
        /// DO NOT USE THIS CONSTRUCTOR FROM TESTS. Use ExecutionContext.CreateForTest method instead.
        /// </summary>
        internal ExecutionContext(string packagePath, string targetPath, string[] networkTargets, string sandboxPath, Manifest manifest, int currentPhase, int countOfPhases, PackageParameter[] packageParameters, TextWriter console)
        {
            this.PackagePath    = packagePath;
            this.TargetPath     = targetPath;
            this.NetworkTargets = networkTargets;
            this.SandboxPath    = sandboxPath;
            this.Manifest       = manifest;
            this.CurrentPhase   = currentPhase;
            this.CountOfPhases  = countOfPhases;
            this.Console        = console;

            if (manifest == null)
            {
                return;
            }

            foreach (var manifestParameter in manifest.Parameters)
            {
                var name         = manifestParameter.Key;
                var propertyName = name.TrimStart('@');
                var defaultValue = manifestParameter.Value;
                var value        = packageParameters.FirstOrDefault(p => p.PropertyName.ToLowerInvariant() == propertyName)?.Value;

                SetVariable(name, value ?? defaultValue);
            }
        }
Пример #2
0
        internal static void ParseHead(XmlDocument xml, Manifest manifest)
        {
            XmlElement   e;
            XmlAttribute attr;

            // root element inspection (required element name)
            e = xml.DocumentElement;
            if (e == null || e.Name != "Package")
            {
                throw new InvalidPackageException(SR.Errors.Manifest.WrongRootName,
                                                  PackagingExceptionType.WrongRootName);
            }

            // parsing type (required, one of the tool, patch, or install)
            attr = e.Attributes["type"];
            if (attr == null)
            {
                attr = e.Attributes["Type"];
            }
            if (attr == null)
            {
                throw new InvalidPackageException(SR.Errors.Manifest.MissingType,
                                                  PackagingExceptionType.MissingPackageType);
            }
            PackageType packageType;

            if (!Enum.TryParse <PackageType>(attr.Value, true, out packageType))
            {
                throw new InvalidPackageException(SR.Errors.Manifest.InvalidType,
                                                  PackagingExceptionType.InvalidPackageType);
            }
            manifest.PackageType = packageType;

            // parsing multiple execution switch
            var multipleAttr = e.Attributes.Cast <XmlAttribute>()
                               .SingleOrDefault(a =>
                                                string.Compare(a.Name, "multipleExecution", StringComparison.InvariantCultureIgnoreCase) == 0);
            var  multipleText = multipleAttr?.Value;
            bool multipleValue;

            if (!string.IsNullOrWhiteSpace(multipleText) && bool.TryParse(multipleText, out multipleValue))
            {
                manifest.MultipleExecutionAllowed = multipleValue;
            }

            // parsing ComponentId
            e = (XmlElement)xml.DocumentElement.SelectSingleNode("Id");
            if (e != null)
            {
                if (e.InnerText.Length == 0)
                {
                    throw new InvalidPackageException(SR.Errors.Manifest.InvalidComponentId,
                                                      PackagingExceptionType.InvalidComponentId);
                }
                manifest.ComponentId = e.InnerText;
            }
            else
            {
                throw new InvalidPackageException(SR.Errors.Manifest.MissingComponentId,
                                                  PackagingExceptionType.MissingComponentId);
            }

            // parsing system install
            manifest.SystemInstall = manifest.ComponentId == SystemComponentId &&
                                     manifest.PackageType == PackageType.Install;

            // parsing description (optional)
            e = (XmlElement)xml.DocumentElement.SelectSingleNode("Description");
            if (e != null)
            {
                manifest.Description = e.InnerText;
            }

            // parsing version
            e = (XmlElement)xml.DocumentElement.SelectSingleNode("Version");
            if (e == null)
            {
                throw new InvalidPackageException(SR.Errors.Manifest.MissingVersion,
                                                  PackagingExceptionType.MissingVersion);
            }
            manifest.Version = Dependency.ParseVersion(e.InnerText);

            // parsing release date (required)
            e = (XmlElement)xml.DocumentElement.SelectSingleNode("ReleaseDate");
            if (e == null)
            {
                throw new InvalidPackageException(SR.Errors.Manifest.MissingReleaseDate,
                                                  PackagingExceptionType.MissingReleaseDate);
            }
            DateTime releaseDate;

            if (!DateTime.TryParse(e.InnerText, out releaseDate))
            {
                throw new InvalidPackageException(SR.Errors.Manifest.InvalidReleaseDate,
                                                  PackagingExceptionType.InvalidReleaseDate);
            }
            if (releaseDate > DateTime.UtcNow)
            {
                throw new InvalidPackageException(SR.Errors.Manifest.TooBigReleaseDate,
                                                  PackagingExceptionType.TooBigReleaseDate);
            }
            manifest.ReleaseDate = releaseDate;

            // parsing dependencies
            var dependencies = new List <Dependency>();

            e = (XmlElement)xml.DocumentElement.SelectSingleNode("Dependencies");
            if (e != null)
            {
                foreach (XmlElement dependencyElement in e.SelectNodes("Dependency"))
                {
                    dependencies.Add(Dependency.Parse(dependencyElement));
                }
            }
            manifest.Dependencies = dependencies.ToArray();
        }
Пример #3
0
        public static PackagingResult Execute(string packagePath, string targetPath, int currentPhase,
                                              PackageParameter[] parameters, TextWriter console,
                                              RepositoryBuilder builder, bool editConnectionString = false)
        {
            var packageParameters = parameters ?? new PackageParameter[0];
            var forcedReinstall   = "true" == (packageParameters
                                               .FirstOrDefault(p => p.PropertyName.ToLowerInvariant() == "forcedreinstall")?
                                               .Value?.ToLowerInvariant() ?? "");

            var phaseCount = 1;

            var files = Directory.GetFiles(packagePath);

            Manifest  manifest = null;
            Exception manifestParsingException = null;

            if (files.Length == 1)
            {
                try
                {
                    manifest = Manifest.Parse(files[0], currentPhase, currentPhase == 0, packageParameters,
                                              forcedReinstall, editConnectionString);
                    phaseCount = manifest.CountOfPhases;
                }
                catch (Exception e)
                {
                    manifestParsingException = e;
                }
            }

            if (files.Length == 0)
            {
                throw new InvalidPackageException(SR.Errors.ManifestNotFound);
            }
            if (files.Length > 1)
            {
                throw new InvalidPackageException(SR.Errors.PackageCanContainOnlyOneFileInTheRoot);
            }
            if (manifestParsingException != null)
            {
                throw new PackagingException("Manifest parsing error. See inner exception.", manifestParsingException);
            }
            if (manifest == null)
            {
                throw new PackagingException("Manifest was not found.");
            }

            Logger.LogTitle(String.Format("Executing phase {0}/{1}", currentPhase + 1, phaseCount));

            var sandboxDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var executionContext = ExecutionContext.Create(packagePath, targetPath, Configuration.Packaging.NetworkTargets,
                                                           sandboxDirectory, manifest, currentPhase, manifest.CountOfPhases, packageParameters, console, builder);

            executionContext.LogVariables();

            PackagingResult result;

            try
            {
                result = ExecuteCurrentPhase(manifest, executionContext);
            }
            finally
            {
                if (Repository.Started())
                {
                    console?.WriteLine("-------------------------------------------------------------");
                    console?.Write("Stopping repository ... ");
                    Repository.Shutdown();
                    console?.WriteLine("Ok.");
                }
            }

            return(result);
        }
Пример #4
0
        internal static ExecutionContext CreateForTest(string packagePath, string targetPath, string[] networkTargets, string sandboxPath, Manifest manifest, int currentPhase, int countOfPhases, string[] parameters, TextWriter console)
        {
            var packageParameters = parameters?.Select(PackageParameter.Parse).ToArray() ?? new PackageParameter[0];

            return(new ExecutionContext(packagePath, targetPath, networkTargets, sandboxPath, manifest, currentPhase, countOfPhases, packageParameters, console)
            {
                Test = true
            });
        }
Пример #5
0
 internal static void SavePackage(Manifest manifest, ExecutionContext executionContext, bool successful, Exception execError)
 {
     SavePackage(manifest, successful ? ExecutionResult.Successful : ExecutionResult.Faulty, execError);
 }
Пример #6
0
        internal static PackagingResult ExecuteCurrentPhase(Manifest manifest, ExecutionContext executionContext)
        {
            var sysInstall   = manifest.SystemInstall;
            var currentPhase = executionContext.CurrentPhase;

            if (0 == currentPhase - (sysInstall ? 1 : 0))
            {
                SaveInitialPackage(manifest);
            }

            var stepElements = manifest.GetPhase(executionContext.CurrentPhase);

            var stopper = Stopwatch.StartNew();

            Logger.LogMessage("Executing steps");

            Exception phaseException = null;
            var       successful     = false;

            try
            {
                var maxStepId = stepElements.Count;
                for (int i = 0; i < maxStepId; i++)
                {
                    var stepElement = stepElements[i];
                    var step        = Step.Parse(stepElement, i, executionContext);

                    var stepStopper = Stopwatch.StartNew();
                    Logger.LogStep(step, maxStepId);
                    step.Execute(executionContext);
                    stepStopper.Stop();
                    Logger.LogMessage("-------------------------------------------------------------");
                    Logger.LogMessage("Time: " + stepStopper.Elapsed);
                    if (executionContext.Terminated)
                    {
                        LogTermination(executionContext);
                        break;
                    }
                }
                stopper.Stop();
                Logger.LogMessage("=============================================================");
                Logger.LogMessage("All steps were executed.");
                Logger.LogMessage("Aggregated time: " + stopper.Elapsed);
                Logger.LogMessage("Errors: " + Logger.Errors);
                successful = true;
            }
            catch (Exception e)
            {
                phaseException = e;
            }

            var finished = executionContext.Terminated || (executionContext.CurrentPhase == manifest.CountOfPhases - 1);

            if (successful && !finished)
            {
                return new PackagingResult {
                           NeedRestart = true, Successful = true, Errors = Logger.Errors
                }
            }
            ;

            if (executionContext.Terminated && executionContext.TerminationReason == TerminationReason.Warning)
            {
                successful = false;

                phaseException = new PackageTerminatedException(executionContext.TerminationMessage);
            }

            try
            {
                SavePackage(manifest, executionContext, successful, phaseException);
            }
            catch (Exception e)
            {
                if (phaseException != null)
                {
                    Logger.LogException(phaseException);
                }
                throw new PackagingException("Cannot save the package.", e);
            }
            finally
            {
                RepositoryVersionInfo.Reset();

                // we need to shut down messaging, because the line above uses it
                if (!executionContext.Test)
                {
                    DistributedApplication.ClusterChannel.ShutDownAsync(CancellationToken.None).GetAwaiter().GetResult();
                }
                else
                {
                    Diagnostics.SnTrace.Test.Write("DistributedApplication.ClusterChannel.ShutDown SKIPPED because it is a test context.");
                }
            }
            if (!successful && !executionContext.Terminated)
            {
                throw new ApplicationException(String.Format(SR.Errors.PhaseFinishedWithError_1, phaseException.Message), phaseException);
            }

            return(new PackagingResult {
                NeedRestart = false, Successful = successful, Terminated = executionContext.Terminated && !successful, Errors = Logger.Errors
            });
        }
Пример #7
0
 internal ExecutionContext(string packagePath, string targetPath, string[] networkTargets, string sandboxPath, Manifest manifest, int currentPhase, int countOfPhases, TextWriter console)
 {
     this.PackagePath    = packagePath;
     this.TargetPath     = targetPath;
     this.NetworkTargets = networkTargets;
     this.SandboxPath    = sandboxPath;
     this.Manifest       = manifest;
     this.CurrentPhase   = currentPhase;
     this.CountOfPhases  = countOfPhases;
     this.Console        = console;
 }
Пример #8
0
        private static PackagingResult ExecuteCurrentPhase(Manifest manifest, ExecutionContext executionContext)
        {
            if (executionContext.CurrentPhase == 0)
            {
                SaveInitialPackage(manifest);
            }

            var steps = manifest.GetPhase(executionContext.CurrentPhase);

            var stopper = Stopwatch.StartNew();

            Logger.LogMessage("Executing steps");

            Exception phaseException = null;
            var       successful     = false;

            try
            {
                var maxStepId = steps.Count();
                foreach (var step in steps)
                {
                    var stepStopper = Stopwatch.StartNew();
                    Logger.LogStep(step, maxStepId);
                    step.Execute(executionContext);
                    stepStopper.Stop();
                    Logger.LogMessage("-------------------------------------------------------------");
                    Logger.LogMessage("Time: " + stepStopper.Elapsed);
                }
                stopper.Stop();
                Logger.LogMessage("=============================================================");
                Logger.LogMessage("All steps were executed.");
                Logger.LogMessage("Aggregated time: " + stopper.Elapsed);
                Logger.LogMessage("Errors: " + Logger.Errors);
                successful = true;
            }
            catch (Exception e)
            {
                phaseException = e;
            }

            if (successful && (executionContext.CurrentPhase < manifest.CountOfPhases - 1))
            {
                return new PackagingResult {
                           NeedRestart = true, Successful = true, Errors = Logger.Errors
                }
            }
            ;

            try
            {
                if (Logger.Level <= LogLevel.Default)
                {
                    SavePackage(manifest, executionContext, successful, phaseException);
                }
            }
            finally
            {
                RepositoryVersionInfo.Reset();

                //we need to shut down messaging, because the line above uses it
                DistributedApplication.ClusterChannel.ShutDown();
            }
            if (!successful)
            {
                throw new ApplicationException(String.Format(SR.Errors.PhaseFinishedWithError_1, phaseException.Message), phaseException);
            }

            return(new PackagingResult {
                NeedRestart = false, Successful = true, Errors = Logger.Errors
            });
        }
Пример #9
0
        private static void SaveInitialPackage(Manifest manifest)
        {
            var newPack = CreatePackage(manifest, ExecutionResult.Unfinished, null);

            DataProvider.Current.SavePackage(newPack);
        }