public InstallerContext Build(string packageId, InstallInteractivityLevel interactivityLevel, PackageOperation operation) { return(new InstallerContext(packageId, interactivityLevel, _windowsInstallerClient, _nexClient) { InstallerRecords = _windowsInstallerClient.GetRecords(), Operation = operation }); }
public InstallerContext(string packageId, InstallInteractivityLevel interactivityLevel, WindowsInstallerClient installerClient, NexClient nexClient) { _packageId = packageId; _installerClient = installerClient; _nexClient = nexClient; InteractivityLevel = interactivityLevel; _preOperationInstallRecords = installerClient.GetRecords(); _stopWatch = Stopwatch.StartNew(); }
public async Task UpdateAllPackages(InstallInteractivityLevel interactivityLevel) { if (!_envInfo.IsAdministrator) { Console.WriteLine(); _logger.Warn("Running as administrator is recommended to allow uninterrupted batch updates."); Console.WriteLine(); } var updates = await GetUpdates(); var toInstall = updates.Where(c => c.Status == UpdateStatus.Available).ToList(); var updated = 0; var failed = 0; var restartRequired = false; for (var index = 0; index < toInstall.Count; index++) { var update = toInstall[index]; SentryTarget.AddTag("packageid", update.PackageId); try { _logger.Info("Installing update {0} of {1}", index + 1, toInstall.Count); Console.WriteLine(); await UpdatePackage(update.PackageId, PackageManifest.LATEST_TAG, interactivityLevel); updated++; } catch (InstallerException e) when(e.ExitReason?.Category == ExitCodeTypes.RestartRequired) { restartRequired = true; } catch (Exception e) { _logger.Fatal(e, "An error occurred while updating {0}", update.PackageId); failed++; } finally { SentryTarget.AddTag("packageid", null); } } Console.WriteLine(); _logger.Info("Updates Applied Successfully: {0:n0} Updates failed to apply: {1:n0}", updated, failed); if (restartRequired) { _logger.Warn("One or more installers have requested a system restart to complete the installation."); } }
public async Task Install(PackageManifest packageManifest, InstallInteractivityLevel interactivityLevel) { using (var context = _installerContextFactory.Build(packageManifest, interactivityLevel, PackageOperation.Install)) { _logger.Info("Beginning installation of '{0}'", packageManifest); _hub.Publish(new InstallationInitializedEvent(packageManifest)); var installer = _findInstaller.GetBestInstaller(packageManifest.Installers); var installerPath = await _fileTransferService.TransferFile(installer.Location, installer.Sha256); _logger.Debug("Getting list of installed application"); var updates = await _novoClient.GetUpdate(context.InstallerRecords, packageManifest.Id); var availableUpdates = updates.Where(c => c.Status == UpdateStatus.Available); if (availableUpdates.Any()) { _logger.Info("Updating {0} to {1}. Currently Installed: {2}", packageManifest.Name, packageManifest.Version, updates.First().InstalledVersion); } var whisperer = _installWhisperers().First(c => c.InstallMethod == packageManifest.InstallMethod); context.Whisperer = whisperer; whisperer.Initialize(packageManifest, installerPath); foreach (var update in updates) { _unlocker.UnlockFolder(update.InstallationPath, packageManifest.InstallMethod); } try { context.Process = RunInstaller(interactivityLevel, packageManifest, whisperer); } catch (InstallerException ex) { context.Exception = ex; throw; } _logger.Info("Installation completed successfully for '{0}'", packageManifest); _hub.Publish(new InstallationSuccessfulEvent(packageManifest)); } }
private Process RunInstaller(InstallInteractivityLevel interactivity, PackageManifest packageManifest, IInstaller whisperer) { _hub.Publish(new ExecutingInstallerEvent(packageManifest)); var installArgs = _argFactory.GetInstallerArguments(interactivity, packageManifest, whisperer); var process = _processController.Start(whisperer.GetProcessPath(), installArgs.Arguments); _logger.Info("Waiting for installation to complete ..."); _processController.WaitForExit(process); if (process.ExitCode != 0) { whisperer.ExitCodes.TryGetValue(process.ExitCode, out var exitReason); throw new InstallerException(process.ExitCode, packageManifest, exitReason, installArgs.LogFile); } return(process); }
public InstallerArguments GetInstallerArguments(InstallInteractivityLevel interactivity, PackageManifest manifest, IInstaller installer) { var result = new InstallerArguments { LogFile = _pathResolver.GetInstallerLogFile(manifest.Id) }; var effectiveInteractivity = GetInteractivelyLevel(interactivity, manifest.Args, installer); switch (effectiveInteractivity) { case InstallInteractivityLevel.Silent: result.Arguments = $"{installer.SilentArgs} {manifest.Args?.Silent}"; break; case InstallInteractivityLevel.Interactive: result.Arguments = $"{installer.InteractiveArgs} {manifest.Args?.Interactive}"; break; case InstallInteractivityLevel.Passive: result.Arguments = $"{installer.PassiveArgs} {manifest.Args?.Passive}"; break; default: throw new ArgumentOutOfRangeException(nameof(effectiveInteractivity)); } var logArg = GetLoggingArgs(result.LogFile, manifest.Args, installer); if (string.IsNullOrWhiteSpace(logArg)) { result.LogFile = null; } else { _logger.Info($"Writing installer log files to {result.LogFile}"); result.Arguments = $"{result.Arguments.Trim()} {logArg.Trim()}"; } return(result); }
private InstallInteractivityLevel GetInteractivelyLevel(InstallInteractivityLevel interactivity, InstallArgs args, IInstaller installer) { bool SupportsSilent() { return(args?.Silent != null || installer.SilentArgs != null); } bool SupportsPassive() { return(args?.Passive != null || installer.PassiveArgs != null); } if (interactivity == InstallInteractivityLevel.Silent && !SupportsSilent()) { if (SupportsPassive()) { _logger.Info("Silent install is not supported by installer. Switching to Passive"); return(InstallInteractivityLevel.Passive); } _logger.Warn("Silent or Passive install is not supported by installer. Switching to Interactive"); return(InstallInteractivityLevel.Interactive); } if (interactivity == InstallInteractivityLevel.Passive && !SupportsPassive()) { if (SupportsSilent()) { _logger.Info("Passive install is not supported by installer. Switching to Silent."); return(InstallInteractivityLevel.Silent); } _logger.Warn("Silent or Passive install is not supported by installer. Switching to Interactive"); return(InstallInteractivityLevel.Interactive); } return(interactivity); }
public async Task UpdatePackage(string packageId, string tag, InstallInteractivityLevel interactivityLevel) { var manifest = await _packageRepository.GetAsync(packageId, tag); await _installService.Install(manifest, interactivityLevel); }