/// <summary> /// Executes the post install steps /// </summary> /// <param name="postStepDetails"></param> internal static void ExecutePostSteps(InstallLogger installLogger, PostStepDetails postStepDetails) { try { SetInstallerState(InstallerState.InstallingPostSteps); //Load the metadata from the update package MetadataView metedateView = UpdateHelper.LoadMetadata(postStepDetails.PostStepPackageFilename); List <ContingencyEntry> logMessages = new List <ContingencyEntry>(); try { //Execute the post install steps DiffInstaller diffInstaller = new DiffInstaller(UpgradeAction.Upgrade); diffInstaller.ExecutePostInstallationInstructions(postStepDetails.PostStepPackageFilename, postStepDetails.HistoryPath, InstallMode.Update, metedateView, installLogger, ref logMessages); } finally { //Move the update package into the history folder File.Move(postStepDetails.PostStepPackageFilename, Path.Combine(postStepDetails.HistoryPath, Path.GetFileName(postStepDetails.PostStepPackageFilename))); } } catch (Exception ex) { Log.Fatal("Post step execution failed", ex, "InstallPackage"); installLogger.Fatal("Post step execution failed", ex); throw; } finally { SetInstallerState(InstallerState.Ready); } }
/// <summary> /// Initializes a new instance of the <see cref="WebManager"/> class. /// </summary> /// <param name="options">The install options.</param> /// <param name="variables">A cache of install variables.</param> /// <param name="installLogger">Logs installation results.</param> public WebManager(InstallOptions options, InstallVariables variables, InstallLogger installLogger) { this.installOptions = options; this.installVariables = variables; this.installLogger = installLogger; this.siteName = this.installOptions.RootSite != null ? string.Format("{0}/{1}", this.installOptions.HostName, this.installOptions.WebsiteName) : this.installOptions.WebsiteName; }
/// <summary> /// Main method that runs the install program. /// </summary> /// <param name="args">Command line arguments.</param> private static void Main(string[] args) { InstallOptions installOptions = new InstallOptions(); Environment.CurrentDirectory = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName; if (args.Contains("--help")) { Console.Write(installOptions.GetUsage()); Environment.Exit(0); } installLogger = new InstallLogger(installOptions.Quiet); Parser parser = new Parser(settings => { settings.MutuallyExclusive = true; }); if (!parser.ParseArguments(args, installOptions)) { installLogger.LogErrorLine("Invalid command line parameters"); Environment.Exit(1); } JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Formatting = Formatting.None, ContractResolver = new DiscretionalContractResolver(), Converters = new JsonConverter[] { new JsonKnownTypeConverter() } }; new Program().Run(installOptions); }
/// <summary> /// Initializes a new instance of the <see cref="DatabaseInitialiser"/> class. /// </summary> /// <param name="mongoConfiguration">The MongoDB configuration settings.</param> /// <param name="installOptions">The database install options.</param> /// <param name="variables">A cache of install variables.</param> /// <param name="installLogger">Logs installation results.</param> public DatabaseInitialiser(IMongoConfiguration mongoConfiguration, DatabaseInitialiserOptions installOptions, InstallVariables variables, InstallLogger installLogger) { this.mongoConfiguration = mongoConfiguration; this.installConfiguration = installOptions; this.installVariables = variables; this.installLogger = installLogger; this.ReadInput = delegate { return string.Empty; }; this.ReadPassword = delegate { return string.Empty; }; }
private void RunPostInitializeStepsIfNeeded() { string startupPostStepPackageFile = Path.Combine(_packageSource, InstallPackage.STARTUP_POST_STEP_PACKAGE_FILENAME); //remove post step flag file if it exists if (File.Exists(startupPostStepPackageFile)) { try { using (new SecurityDisabler()) { //Load the post step details XmlSerializer serializer = new XmlSerializer(typeof(PostStepDetails)); using (TextReader writer = new StreamReader(startupPostStepPackageFile)) { PostStepDetails details = serializer.Deserialize(writer) as PostStepDetails; if (details != null) { InstallLogger installLogger = new InstallLogger(new RootLogger(Level.ALL)); try { InstallPackage.ExecutePostSteps(installLogger, details, true); InstallPackage.NotifiyPackageComplete(InstallPackage.SUCCESS, details); } catch (Exception ex) { Log.Fatal("An error occured when running post steps", ex, this); InstallPackage.NotifiyPackageComplete(InstallPackage.FAIL, details); } finally { installLogger.WriteMessages(Path.Combine(details.HistoryPath, "Install.log")); } } } } } finally { //cleanup the post step File.Delete(startupPostStepPackageFile); } } }
/// <summary> /// Initializes a new instance of the <see cref="ScheduledTaskManager"/> class. /// </summary> /// <param name="options">The install options.</param> /// <param name="variables">A cache of install variables.</param> /// <param name="installLogger">Logs installation results.</param> public ScheduledTaskManager(InstallOptions options, InstallVariables variables, InstallLogger installLogger) { this.installOptions = options; this.installVariables = variables; this.installLogger = installLogger; }
/// <summary> /// Installs the packages found in the package source folder. /// </summary> private void InstallPackages() { //Check to see if there is a post-step pending, and skip package install if there is if (File.Exists(Path.Combine(_packageSource, STARTUP_POST_STEP_PACKAGE_FILENAME))) { Log.Info("Install packages skipped because there is a post step pending", this); return; } InstallLogger installLogger = new InstallLogger(new RootLogger(Level.ALL)); //Return if another installation is happening if (GetInstallerState() != InstallerState.Ready) { Log.Info(string.Format("Install packages skipped because install state is {0}. ", GetInstallerState()), this); return; } //Prevent shutdown using (new ShutdownGuard()) { //If Sitecore is shutting down, don't start the installer if (ShutdownDetected) { Log.Info("Skipping Install because shutdown is pending", this); return; } //Block further package installs SetInstallerState(InstallerState.InstallingPackage); using (new SecurityDisabler()) { //Find pending packages. This loop may not complete if there were binary/config changes foreach (string updatePackageFilename in Directory.GetFiles(_packageSource, "*.update", SearchOption.TopDirectoryOnly).OrderBy(f => f)) { string updatePackageFilenameStripped = updatePackageFilename.Split('\\').Last(); if (ShutdownDetected) { Log.Info("Install packages aborting due to shutdown", this); if (GetInstallerState() != InstallerState.WaitingForPostSteps) { SetInstallerState(InstallerState.Ready); } break; } Log.Info(String.Format("Begin Installation: {0}", updatePackageFilenameStripped), this); string installationHistoryRoot = null; List <ContingencyEntry> logMessages = new List <ContingencyEntry>(); PostStepDetails postStepDetails = new PostStepDetails { PostStepPackageFilename = updatePackageFilename, ResultFileName = Path.Combine(Path.GetDirectoryName(updatePackageFilename), Path.GetFileNameWithoutExtension(updatePackageFilename) + ".json") }; string installStatus = null; try { //Run the installer if (sitecoreUpdateVersionInfo.ProductMajorPart == 1) { logMessages = UpdateHelper.Install(BuildPackageInfo(updatePackageFilename), installLogger, out installationHistoryRoot); } else { object[] installationParamaters = new object[] { BuildReflectedPackageInfo(updatePackageFilename), installLogger, null }; logMessages = (List <ContingencyEntry>)updateHelperType.InvokeMember("Install", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public, null, null, installationParamaters, null); installationHistoryRoot = installationParamaters[2].ToString(); } postStepDetails.HistoryPath = installationHistoryRoot; if (_updateConfigurationFiles) { FindAndUpdateChangedConfigs(Path.GetFileNameWithoutExtension(updatePackageFilename)); } //Sleep for 4 seconds to see if there was a file change that could cause a problem Thread.Sleep(4000); //Abort if Sitecore is shutting down. The install post steps will have to be completed later if (ShutdownDetected) { SetInstallerState(InstallerState.WaitingForPostSteps); RunPostStepsAtStartup(updatePackageFilename, installationHistoryRoot, postStepDetails); RestartSitecoreServer(); break; } else { ExecutePostSteps(installLogger, postStepDetails, false); installStatus = SUCCESS; Log.Info(String.Format("Installation Complete: {0}", updatePackageFilenameStripped), this); SetInstallerState(InstallerState.InstallingPackage); } } catch (PostStepInstallerException ex) { installStatus = FAIL; logMessages = ex.Entries; installationHistoryRoot = ex.HistoryPath; installLogger.Fatal("Package install failed", ex); throw ex; } catch (Exception ex) { installStatus = FAIL; Log.Error(String.Format("Installation Failed: {0}", updatePackageFilenameStripped), ex, this); installLogger.Fatal("Package install failed", ex); ThreadPool.QueueUserWorkItem(new WaitCallback((ctx) => { try { //The update package may be locked because the file object hasn't been disposed. Wait for it. Thread.Sleep(100); //I really hate this, but I couldn't find another reliable way to ensure the locked file is closed before I move it. GC.Collect(2); GC.WaitForPendingFinalizers(); File.Move(updatePackageFilename, updatePackageFilename + ".error_" + DateTime.Now.ToString("yyyyMMdd.hhmmss")); } catch (Exception ex1) { Log.Error("Error moving broken package", ex1, this); } })); break; } finally { if (installationHistoryRoot != null) { //Write logs installLogger.WriteMessages(Path.Combine(installationHistoryRoot, "Install.log")); SaveInstallationMessages(installationHistoryRoot, logMessages); } //Send the status if there is one if (installStatus != null) { NotifiyPackageComplete(installStatus, postStepDetails); } } } if (!ShutdownDetected) { //Allow additional installs SetInstallerState(InstallerState.Ready); } } } }