Beispiel #1
0
        /// <summary>
        /// Try to download and apply an update with a given <paramref name="newVersion"/>.
        /// </summary>
        /// <param name="newVersion">The version of the server to update to.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
        /// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> of the operation.</returns>
        async Task <IActionResult> CheckReleasesAndApplyUpdate(Version newVersion, CancellationToken cancellationToken)
        {
            Logger.LogDebug("Looking for GitHub releases version {0}...", newVersion);
            IEnumerable <Release> releases;

            try
            {
                var gitHubClient = GetGitHubClient();
                releases = await gitHubClient
                           .Repository
                           .Release
                           .GetAll(updatesConfiguration.GitHubRepositoryId)
                           .WithToken(cancellationToken)
                           .ConfigureAwait(false);
            }
            catch (RateLimitExceededException e)
            {
                return(RateLimit(e));
            }
            catch (ApiException e)
            {
                Logger.LogWarning(e, OctokitException);
                return(StatusCode(HttpStatusCode.FailedDependency));
            }

            releases = releases.Where(x => x.TagName.StartsWith(updatesConfiguration.GitTagPrefix, StringComparison.InvariantCulture));

            Logger.LogTrace("Release query complete!");

            foreach (var release in releases)
            {
                if (Version.TryParse(
                        release.TagName.Replace(
                            updatesConfiguration.GitTagPrefix, String.Empty, StringComparison.Ordinal),
                        out var version) &&
                    version == newVersion)
                {
                    var asset = release.Assets.Where(x => x.Name.Equals(updatesConfiguration.UpdatePackageAssetName, StringComparison.Ordinal)).FirstOrDefault();
                    if (asset == default)
                    {
                        continue;
                    }

                    if (!serverUpdater.ApplyUpdate(version, new Uri(asset.BrowserDownloadUrl), ioManager))
                    {
                        return(Conflict(new ErrorMessage(ErrorCode.ServerUpdateInProgress)));
                    }
                    return(Accepted(new Administration
                    {
                        WindowsHost = platformIdentifier.IsWindows,
                        NewVersion = newVersion
                    }));                    // gtfo of here before all the cancellation tokens fire
                }
            }

            return(Gone());
        }
Beispiel #2
0
        /// <inheritdoc />
        public async Task <ServerUpdateResult> BeginUpdate(Version newVersion, CancellationToken cancellationToken)
        {
            logger.LogDebug("Looking for GitHub releases version {0}...", newVersion);
            IEnumerable <Release> releases;
            var gitHubClient = gitHubClientFactory.CreateClient();

            releases = await gitHubClient
                       .Repository
                       .Release
                       .GetAll(updatesConfiguration.GitHubRepositoryId)
                       .WithToken(cancellationToken)
                       .ConfigureAwait(false);

            releases = releases.Where(x => x.TagName.StartsWith(updatesConfiguration.GitTagPrefix, StringComparison.InvariantCulture));

            logger.LogTrace("Release query complete!");

            foreach (var release in releases)
            {
                if (Version.TryParse(
                        release.TagName.Replace(
                            updatesConfiguration.GitTagPrefix, String.Empty, StringComparison.Ordinal),
                        out var version) &&
                    version == newVersion)
                {
                    var asset = release.Assets.Where(x => x.Name.Equals(updatesConfiguration.UpdatePackageAssetName, StringComparison.Ordinal)).FirstOrDefault();
                    if (asset == default)
                    {
                        continue;
                    }

                    if (!serverControl.ApplyUpdate(version, new Uri(asset.BrowserDownloadUrl), ioManager))
                    {
                        return(ServerUpdateResult.UpdateInProgress);
                    }
                    return(ServerUpdateResult.Started);
                }
            }

            return(ServerUpdateResult.ReleaseMissing);
        }
        public override async Task <IActionResult> Update([FromBody] Administration model, CancellationToken cancellationToken)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            if (model.NewVersion == null)
            {
                return(BadRequest(new ErrorMessage {
                    Message = "Missing new version!"
                }));
            }

            if (model.NewVersion.Major != application.Version.Major)
            {
                return(BadRequest(new ErrorMessage {
                    Message = "Cannot update to a different suite version!"
                }));
            }

            IEnumerable <Release> releases;

            try
            {
                releases = (await gitHubClient.Repository.Release.GetAll(updatesConfiguration.GitHubRepositoryId).ConfigureAwait(false)).Where(x => x.TagName.StartsWith(updatesConfiguration.GitTagPrefix, StringComparison.InvariantCulture));
            }
            catch (RateLimitExceededException e)
            {
                return(RateLimit(e));
            }

            foreach (var release in releases)
            {
                if (Version.TryParse(release.TagName.Replace(updatesConfiguration.GitTagPrefix, String.Empty, StringComparison.Ordinal), out var version) && version == model.NewVersion)
                {
                    var asset = release.Assets.Where(x => x.Name == updatesConfiguration.UpdatePackageAssetName).FirstOrDefault();
                    if (asset == default)
                    {
                        continue;
                    }

                    var assetBytes = await ioManager.DownloadFile(new Uri(asset.BrowserDownloadUrl), cancellationToken).ConfigureAwait(false);

                    try
                    {
                        if (!await serverUpdater.ApplyUpdate(assetBytes, ioManager, cancellationToken).ConfigureAwait(false))
                        {
                            return(UnprocessableEntity(new ErrorMessage
                            {
                                Message = RestartNotSupportedException
                            }));                                //unprocessable entity
                        }
                    }
                    catch (InvalidOperationException)
                    {
                        return(StatusCode((int)HttpStatusCode.ServiceUnavailable)); //we were beat to the punch, really shouldn't happen but heat death of the universe and what not
                    }
                    return(Accepted());                                             //gtfo of here before all the cancellation tokens fire
                }
            }

            return(StatusCode((int)HttpStatusCode.Gone));
        }
Beispiel #4
0
        public override async Task <IActionResult> Update([FromBody] Administration model, CancellationToken cancellationToken)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            if (model.NewVersion == null)
            {
                return(BadRequest(new ErrorMessage {
                    Message = "Missing new version!"
                }));
            }

            if (model.NewVersion.Major != application.Version.Major)
            {
                return(BadRequest(new ErrorMessage {
                    Message = "Cannot update to a different suite version!"
                }));
            }

            if (!serverUpdater.WatchdogPresent)
            {
                return(UnprocessableEntity(new ErrorMessage
                {
                    Message = RestartNotSupportedException
                }));
            }

            Logger.LogDebug("Looking for GitHub releases version {0}...", model.NewVersion);
            IEnumerable <Release> releases;

            try
            {
                var gitHubClient = GetGitHubClient();
                releases = (await gitHubClient.Repository.Release.GetAll(updatesConfiguration.GitHubRepositoryId).ConfigureAwait(false)).Where(x => x.TagName.StartsWith(updatesConfiguration.GitTagPrefix, StringComparison.InvariantCulture));
                cancellationToken.ThrowIfCancellationRequested();
            }
            catch (RateLimitExceededException e)
            {
                return(RateLimit(e));
            }
            catch (ApiException e)
            {
                Logger.LogWarning(OctokitException, e);
                return(StatusCode((int)HttpStatusCode.FailedDependency));
            }

            Logger.LogTrace("Release query complete!");
            foreach (var release in releases)
            {
                if (Version.TryParse(release.TagName.Replace(updatesConfiguration.GitTagPrefix, String.Empty, StringComparison.Ordinal), out var version) && version == model.NewVersion)
                {
                    var asset = release.Assets.Where(x => x.Name == updatesConfiguration.UpdatePackageAssetName).FirstOrDefault();
                    if (asset == default)
                    {
                        continue;
                    }

                    if (!serverUpdater.ApplyUpdate(version, new Uri(asset.BrowserDownloadUrl), ioManager))
                    {
                        return(Conflict(new ErrorMessage
                        {
                            Message = "An update operation is already in progress!"
                        }));
                    }
                    return(Accepted());                     //gtfo of here before all the cancellation tokens fire
                }
            }

            return(StatusCode((int)HttpStatusCode.Gone));
        }