/// <inheritdoc /> public async Task <byte[]> DownloadVersion(Version version, CancellationToken cancellationToken) { var ourVersion = version; //lummox is annoying and doesn't like to post linux versions if nothing changed in DreamDaemon/DM //if this for's exit condition ever triggers, i get to say I told you so Exception lastException = null; for (var I = 0; I < 5 && ourVersion.Minor >= 1; ++I, ourVersion = new Version(ourVersion.Major, ourVersion.Minor)) { try { var url = String.Format(CultureInfo.InvariantCulture, ByondRevisionsURL, ourVersion.Major, ourVersion.Minor); return(await ioManager.DownloadFile(new Uri(url), cancellationToken).ConfigureAwait(false)); } catch (WebException e) { if (!(e.Status == WebExceptionStatus.ProtocolError && e.Response is HttpWebResponse response && response.StatusCode == HttpStatusCode.NotFound)) { throw; } lastException = e; } } throw lastException; }
/// <inheritdoc /> public async Task <byte[]> DownloadVersion(Version version, CancellationToken cancellationToken) { if (version == null) { throw new ArgumentNullException(nameof(version)); } var url = String.Format(CultureInfo.InvariantCulture, ByondRevisionsURLTemplate, version.Major, version.Minor); return(await ioManager.DownloadFile(new Uri(url), cancellationToken).ConfigureAwait(false)); }
/// <inheritdoc /> public bool ApplyUpdate(Version version, Uri updateZipUrl, IIOManager ioManager) { if (version == null) { throw new ArgumentNullException(nameof(version)); } if (updateZipUrl == null) { throw new ArgumentNullException(nameof(updateZipUrl)); } if (ioManager == null) { throw new ArgumentNullException(nameof(ioManager)); } CheckSanity(true); logger.LogTrace("Begin ApplyUpdate..."); lock (this) { if (updating || RestartRequested) { logger.LogTrace("Aborted due to concurrency conflict!"); return(false); } updating = true; } async void RunUpdate() { try { logger.LogInformation("Updating server to version {0} ({1})...", version, updateZipUrl); if (cancellationTokenSource == null) { throw new InvalidOperationException("Tried to update a non-running Server!"); } var cancellationToken = cancellationTokenSource.Token; logger.LogTrace("Downloading zip package..."); var updateZipData = await ioManager.DownloadFile(updateZipUrl, cancellationToken).ConfigureAwait(false); try { logger.LogTrace("Exctracting zip package to {0}...", updatePath); await ioManager.ZipToDirectory(updatePath, updateZipData, cancellationToken).ConfigureAwait(false); } catch (Exception e) { updating = false; try { // important to not leave this directory around if possible await ioManager.DeleteDirectory(updatePath, default).ConfigureAwait(false); } catch (Exception e2) { throw new AggregateException(e, e2); } throw; } await Restart(version, null).ConfigureAwait(false); } catch (OperationCanceledException) { logger.LogInformation("Server update cancelled!"); } catch (Exception e) { logger.LogError("Error updating server! Exception: {0}", e); } finally { updating = false; } } RunUpdate(); return(true); }
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)); }
/// <inheritdoc /> public Task <byte[]> DownloadVersion(Version version, CancellationToken cancellationToken) { var url = String.Format(CultureInfo.InvariantCulture, ByondRevisionsURLTemplate, version.Major, version.Minor); return(ioManager.DownloadFile(new Uri(url), cancellationToken)); }