/// <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); } }
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(); }
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); }
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 }); }
internal static void SavePackage(Manifest manifest, ExecutionContext executionContext, bool successful, Exception execError) { SavePackage(manifest, successful ? ExecutionResult.Successful : ExecutionResult.Faulty, execError); }
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 }); }
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; }
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 }); }
private static void SaveInitialPackage(Manifest manifest) { var newPack = CreatePackage(manifest, ExecutionResult.Unfinished, null); DataProvider.Current.SavePackage(newPack); }