/// <summary> /// Gets the available plugin updates. /// </summary> /// <param name="applicationVersion">The current server version.</param> /// <param name="withAutoUpdateEnabled">if set to <c>true</c> [with auto update enabled].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{IEnumerable{PackageVersionInfo}}.</returns> public async Task <IEnumerable <PackageVersionInfo> > GetAvailablePluginUpdates(Version applicationVersion, bool withAutoUpdateEnabled, CancellationToken cancellationToken) { var catalog = await GetAvailablePackagesWithoutRegistrationInfo(cancellationToken).ConfigureAwait(false); var plugins = _applicationHost.Plugins.ToList(); if (withAutoUpdateEnabled) { plugins = plugins .Where(p => _config.CommonConfiguration.EnableAutoUpdate) .ToList(); } var systemUpdateLevel = GetSystemUpdateLevel(); // Figure out what needs to be installed var packages = plugins.Select(p => { var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Id.ToString(), applicationVersion, systemUpdateLevel); return(latestPluginInfo != null && GetPackageVersion(latestPluginInfo) > p.Version ? latestPluginInfo : null); }).Where(i => i != null).ToList(); return(packages .Where(p => !string.IsNullOrWhiteSpace(p.sourceUrl) && !CompletedInstallations.Any(i => string.Equals(i.AssemblyGuid, p.guid, StringComparison.OrdinalIgnoreCase)))); }
protected IEnumerable <PackageVersionInfo> FilterCatalog(IEnumerable <PackageInfo> catalog, bool withAutoUpdateEnabled) { var plugins = ApplicationHost.Plugins; if (withAutoUpdateEnabled) { plugins = plugins.Where(p => p.Configuration.EnableAutoUpdate); } // Figure out what needs to be installed return(plugins.Select(p => { var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Configuration.UpdateClass); return latestPluginInfo != null && latestPluginInfo.version > p.Version ? latestPluginInfo : null; }).Where(p => !CompletedInstallations.Any(i => string.Equals(i.Name, p.name, StringComparison.OrdinalIgnoreCase))) .Where(p => p != null && !string.IsNullOrWhiteSpace(p.sourceUrl))); }
/// <summary> /// Gets the available plugin updates. /// </summary> /// <param name="withAutoUpdateEnabled">if set to <c>true</c> [with auto update enabled].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{IEnumerable{PackageVersionInfo}}.</returns> public async Task <IEnumerable <PackageVersionInfo> > GetAvailablePluginUpdates(bool withAutoUpdateEnabled, CancellationToken cancellationToken) { var catalog = await GetAvailablePackages(cancellationToken).ConfigureAwait(false); var plugins = ApplicationHost.Plugins; if (withAutoUpdateEnabled) { plugins = plugins.Where(p => p.Configuration.EnableAutoUpdate); } // Figure out what needs to be installed return(plugins.Select(p => { var latestPluginInfo = GetLatestCompatibleVersion(catalog, p.Name, p.Configuration.UpdateClass); return latestPluginInfo != null && latestPluginInfo.version > p.Version ? latestPluginInfo : null; }).Where(p => !CompletedInstallations.Any(i => i.Name.Equals(p.name, StringComparison.OrdinalIgnoreCase))) .Where(p => p != null && !string.IsNullOrWhiteSpace(p.sourceUrl))); }
/// <summary> /// Installs the package. /// </summary> /// <param name="package">The package.</param> /// <param name="isPlugin">if set to <c>true</c> [is plugin].</param> /// <param name="progress">The progress.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentNullException">package</exception> public async Task InstallPackage(PackageVersionInfo package, bool isPlugin, IProgress <double> progress, CancellationToken cancellationToken) { if (package == null) { throw new ArgumentNullException("package"); } if (progress == null) { throw new ArgumentNullException("progress"); } var installationInfo = new InstallationInfo { Id = Guid.NewGuid().ToString("N"), Name = package.name, AssemblyGuid = package.guid, UpdateClass = package.classification, Version = package.versionStr }; var innerCancellationTokenSource = new CancellationTokenSource(); var tuple = new Tuple <InstallationInfo, CancellationTokenSource>(installationInfo, innerCancellationTokenSource); // Add it to the in-progress list lock (CurrentInstallations) { CurrentInstallations.Add(tuple); } var innerProgress = new ActionableProgress <double>(); // Whenever the progress updates, update the outer progress object and InstallationInfo innerProgress.RegisterAction(percent => { progress.Report(percent); installationInfo.PercentComplete = percent; }); var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, innerCancellationTokenSource.Token).Token; var installationEventArgs = new InstallationEventArgs { InstallationInfo = installationInfo, PackageVersionInfo = package }; EventHelper.FireEventIfNotNull(PackageInstalling, this, installationEventArgs, _logger); try { await InstallPackageInternal(package, isPlugin, innerProgress, linkedToken).ConfigureAwait(false); lock (CurrentInstallations) { CurrentInstallations.Remove(tuple); } progress.Report(100); CompletedInstallations.Add(installationInfo); EventHelper.FireEventIfNotNull(PackageInstallationCompleted, this, installationEventArgs, _logger); } catch (OperationCanceledException) { lock (CurrentInstallations) { CurrentInstallations.Remove(tuple); } _logger.Info("Package installation cancelled: {0} {1}", package.name, package.versionStr); EventHelper.FireEventIfNotNull(PackageInstallationCancelled, this, installationEventArgs, _logger); throw; } catch (Exception ex) { _logger.ErrorException("Package installation failed", ex); lock (CurrentInstallations) { CurrentInstallations.Remove(tuple); } EventHelper.FireEventIfNotNull(PackageInstallationFailed, this, new InstallationFailedEventArgs { InstallationInfo = installationInfo, Exception = ex }, _logger); throw; } finally { // Dispose the progress object and remove the installation from the in-progress list innerProgress.Dispose(); tuple.Item2.Dispose(); } }