public InstallerContext Build(string packageId, InstallInteractivityLevel interactivityLevel, PackageOperation operation)
 {
     return(new InstallerContext(packageId, interactivityLevel, _windowsInstallerClient, _nexClient)
     {
         InstallerRecords = _windowsInstallerClient.GetRecords(),
         Operation = operation
     });
 }
Beispiel #2
0
        public InstallerContext(string packageId, InstallInteractivityLevel interactivityLevel, WindowsInstallerClient installerClient, NexClient nexClient)
        {
            _packageId         = packageId;
            _installerClient   = installerClient;
            _nexClient         = nexClient;
            InteractivityLevel = interactivityLevel;


            _preOperationInstallRecords = installerClient.GetRecords();
            _stopWatch = Stopwatch.StartNew();
        }
Beispiel #3
0
        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.");
            }
        }
Beispiel #4
0
        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));
            }
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        public async Task UpdatePackage(string packageId, string tag, InstallInteractivityLevel interactivityLevel)
        {
            var manifest = await _packageRepository.GetAsync(packageId, tag);

            await _installService.Install(manifest, interactivityLevel);
        }