private async Task PublishPackage(string packageId, string packageDefinitionFilename, string assemblyVersion, CancellationToken token) { var versionList = await nugetCore.GetAllPackageVersions(packageId, token); var packageVersion = versionList.Any() ? versionList.Max() : null; if (!VersionTools.HasUpdates(packageVersion, assemblyVersion)) { Context.Output.WriteLine($"Package '{packageId}' is up-to-date. Version {packageVersion}", ConsoleColor.DarkCyan); return; } await nugetCmd.RunAsync(new NuGetPackArguments { Filename = packageDefinitionFilename, Version = assemblyVersion, OutputDirectory = nugetPackageDir, Properties = { ["Configuration"] = "Release", ["Platform"] = "AnyCPU", ["frameworkVersion"] = frameworkVersion, }, }, token); var packageFilename = Directory .GetFiles(nugetPackageDir, $"{packageId}.*.nupkg") .FirstOrDefault(); if (string.IsNullOrEmpty(packageFilename)) { throw new ApplicationException($"No package found matching package ID '{packageId}'!"); } await nugetCore.PushAsync(packageFilename, token); }
public async Task Run(CommandContext context) { ConsoleEx.Out .WriteLine($"Photon CLI {Configuration.Version}", ConsoleColor.DarkBlue) .WriteLine("Checking for updates...", ConsoleColor.DarkCyan); var index = await DownloadTools.GetLatestCliIndex(); var latestVersion = index.Version; if (!VersionTools.HasUpdates(Configuration.Version, latestVersion)) { ConsoleEx.Out.WriteLine("CLI is up-to-date.", ConsoleColor.DarkBlue); return; } ConsoleEx.Out.Write("Downloading CLI update ", ConsoleColor.DarkCyan) .Write(latestVersion, ConsoleColor.Cyan) .WriteLine("...", ConsoleColor.DarkCyan); updateDirectory = Path.Combine(Configuration.Directory, "Updates"); updateFilename = Path.Combine(updateDirectory, "Photon.Server.msi"); await DownloadUpdate(index); ConsoleEx.Out .WriteLine("Download Complete.", ConsoleColor.DarkGreen) .WriteLine("Launching installer...", ConsoleColor.DarkCyan); StartInstaller(); }
public async Task PublishAsync(CancellationToken token) { client.Output? .Append("Checking Package ", ConsoleColor.DarkCyan) .Append(PackageId, ConsoleColor.Cyan) .AppendLine(" for updates...", ConsoleColor.DarkCyan); var versionList = await client.GetAllPackageVersions(PackageId, token); var packageVersion = versionList.Any() ? versionList.Max() : null; if (!VersionTools.HasUpdates(packageVersion, Version)) { client.Output? .Append($"Package '{PackageId}' is up-to-date. Version ", ConsoleColor.DarkBlue) .AppendLine(packageVersion, ConsoleColor.Blue); return; } var cl = new NuGetCommandLine { ExeFilename = ExeFilename, ApiKey = client.ApiKey, Output = client.Output, }; cl.Pack(PackageDefinition, PackageDirectory); var packageFilename = Directory .GetFiles(PackageDirectory, $"{PackageId}.*.nupkg") .FirstOrDefault(); await client.PushAsync(packageFilename, token); }
private async Task Reconnect(PhotonServerDefinition server, string latestVersion, TimeSpan timeout) { using (var tokenSource = new CancellationTokenSource(timeout)) using (var client = new WebClient()) { var token = tokenSource.Token; while (true) { token.ThrowIfCancellationRequested(); try { var url = NetPath.Combine(server.Url, "api/version"); var version = await client.DownloadStringTaskAsync(url); if (!VersionTools.HasUpdates(version, latestVersion)) { break; } } catch (Exception error) when(error is SocketException || error is WebException) { await Task.Delay(1000, tokenSource.Token); } } } }
private async Task <MessageClient> Reconnect(ServerAgent agent, TimeSpan timeout) { var client = new MessageClient(PhotonServer.Instance.MessageRegistry); client.ThreadException += (o, e) => { var error = (Exception)e.ExceptionObject; Output.AppendLine("An error occurred while messaging the client!", ConsoleColor.DarkRed) .AppendLine(error.UnfoldMessages()); Log.Error("Message Client error after update!", error); }; var tokenSource = new CancellationTokenSource(timeout); var token = tokenSource.Token; while (true) { token.ThrowIfCancellationRequested(); try { await client.ConnectAsync(agent.TcpHost, agent.TcpPort, tokenSource.Token); var handshakeRequest = new HandshakeRequest { Key = Guid.NewGuid().ToString(), ServerVersion = Configuration.Version, }; var handshakeTimeout = TimeSpan.FromSeconds(HandshakeTimeoutSec); var handshakeResponse = await client.Handshake <HandshakeResponse>(handshakeRequest, handshakeTimeout, TokenSource.Token); if (!string.Equals(handshakeRequest.Key, handshakeResponse.Key, StringComparison.Ordinal)) { throw new ApplicationException("Handshake Failed! An invalid key was returned."); } if (!handshakeResponse.PasswordMatch) { throw new ApplicationException("Handshake Failed! Unauthorized."); } var versionRequest = new AgentGetVersionRequest(); var versionResponse = await client.Send(versionRequest) .GetResponseAsync <AgentGetVersionResponse>(token); if (!VersionTools.HasUpdates(versionResponse.Version, UpdateVersion)) { break; } } catch (SocketException) { await Task.Delay(1000, tokenSource.Token); } } return(client); }
private async Task <MessageClient> Reconnect(ServerAgent agent, TimeSpan timeout, CancellationToken token) { using (var timeoutTokenSource = new CancellationTokenSource(timeout)) using (var mergedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeoutTokenSource.Token, token)) { while (true) { mergedTokenSource.Token.ThrowIfCancellationRequested(); var client = new MessageClient(PhotonServer.Instance.MessageRegistry); try { using (var connectionTimeoutTokenSource = new CancellationTokenSource(20_000)) using (var connectTokenSource = CancellationTokenSource.CreateLinkedTokenSource(mergedTokenSource.Token, connectionTimeoutTokenSource.Token)) { await client.ConnectAsync(agent.TcpHost, agent.TcpPort, connectTokenSource.Token); await ClientHandshake.Verify(client, connectTokenSource.Token); var versionRequest = new AgentGetVersionRequest(); var versionResponse = await client.Send(versionRequest) .GetResponseAsync <AgentGetVersionResponse>(connectTokenSource.Token); if (string.IsNullOrEmpty(versionResponse.Version)) { Log.Warn("An empty version response was received!"); continue; } if (!VersionTools.HasUpdates(versionResponse.Version, UpdateVersion)) { return(client); } } } catch (SocketException) {} catch (OperationCanceledException) {} catch (Exception error) { Log.Warn("An unhandled exception occurred while attempting to reconnect to an updating agent.", error); } client.Dispose(); await Task.Delay(3_000, mergedTokenSource.Token); } } }
public async Task Run(CommandContext context) { var server = context.Servers.Get(ServerName); ConsoleEx.Out.WriteLine("Checking server version...", ConsoleColor.DarkCyan); string currentVersion = null; await AuthRetryAsync(async() => { currentVersion = await WebClient(server, async client => { return((await client.DownloadStringTaskAsync("api/version")).Trim()); }); }); ConsoleEx.Out .WriteLine($"Photon Server {currentVersion}", ConsoleColor.DarkBlue) .WriteLine("Checking for updates...", ConsoleColor.DarkCyan); var serverIndex = await DownloadTools.GetLatestServerIndex(); if (!VersionTools.HasUpdates(currentVersion, serverIndex.Version)) { ConsoleEx.Out.WriteLine("Server is up-to-date.", ConsoleColor.DarkBlue); return; } await BeginServerUpdate(server, serverIndex); ConsoleEx.Out.WriteLine("Server update started. Waiting for restart...", ConsoleColor.Cyan); await Task.Delay(3000); var timeout = TimeSpan.FromMinutes(2); try { await Reconnect(server, serverIndex.Version, timeout); ConsoleEx.Out.WriteLine("Update completed successfully.", ConsoleColor.DarkGreen); } catch (TaskCanceledException) { throw new ApplicationException($"Server failed to restart within timeout '{timeout}'."); } }
private async Task <bool> PreCheckUsingCore(CancellationToken token) { context.Output.WriteBlock() .Write("Checking Package ", ConsoleColor.DarkCyan) .Write(PackageId, ConsoleColor.Cyan) .WriteLine(" for updates...", ConsoleColor.DarkCyan) .Post(); var versionList = await Client.GetAllPackageVersions(PackageId, token); var packageVersion = versionList.Any() ? versionList.Max() : null; if (VersionTools.HasUpdates(packageVersion, Version)) { return(true); } context.Output.WriteBlock() .Write($"Package '{PackageId}' is up-to-date. Version ", ConsoleColor.DarkBlue) .WriteLine(packageVersion, ConsoleColor.Blue) .Post(); return(false); }
private async Task Reconnect(PhotonServerDefinition server, string latestVersion, TimeSpan timeout) { using (var tokenSource = new CancellationTokenSource(timeout)) using (var webClient = WebClientFactory.Create(server, Username, Password)) { var token = tokenSource.Token; while (true) { token.ThrowIfCancellationRequested(); try { var version = await webClient.DownloadStringTaskAsync("api/version"); if (!VersionTools.HasUpdates(version, latestVersion)) { break; } } catch (Exception error) when(error is SocketException || error is WebException) { await Task.Delay(1000, tokenSource.Token); } } } }
public async Task Run(CommandContext context) { var server = context.Servers.Get(ServerName); ConsoleEx.Out.WriteLine("Retrieving latest agent version...", ConsoleColor.DarkCyan); var agentIndex = await DownloadTools.GetLatestAgentIndex(); var latestVersion = agentIndex.Version; ConsoleEx.Out .Write("Found Latest Version ", ConsoleColor.DarkCyan) .WriteLine(latestVersion, ConsoleColor.Cyan) .WriteLine("Checking agent versions...", ConsoleColor.DarkCyan); HttpAgentVersionListResponse agentVersionResponse = null; await AuthRetryAsync(async() => { agentVersionResponse = await WebClient(server, async client => { var json = (await client.DownloadStringTaskAsync("api/agent/versions")).Trim(); return(JsonConvert.DeserializeObject <HttpAgentVersionListResponse>(json)); }); }); var updateAgents = new List <string>(); foreach (var agentVersion in agentVersionResponse.VersionList.OrderBy(x => x.AgentName)) { if (!string.IsNullOrEmpty(agentVersion.Exception)) { ConsoleEx.Out.Write("Failed to get version of agent ", ConsoleColor.DarkYellow) .Write(agentVersion.AgentName, ConsoleColor.Yellow) .WriteLine($"! {agentVersion.Exception}", ConsoleColor.DarkYellow); continue; } if (!VersionTools.HasUpdates(agentVersion.AgentVersion, latestVersion)) { ConsoleEx.Out.Write("Agent ", ConsoleColor.DarkBlue) .Write(agentVersion.AgentName, ConsoleColor.Blue) .WriteLine(" is up-to-date.", ConsoleColor.DarkBlue); continue; } ConsoleEx.Out.Write("Updating ", ConsoleColor.DarkCyan) .Write(agentVersion.AgentName, ConsoleColor.Cyan) .Write(" from version ", ConsoleColor.DarkCyan) .Write(agentVersion.AgentVersion, ConsoleColor.Cyan) .WriteLine(".", ConsoleColor.DarkCyan); updateAgents.Add(agentVersion.AgentId); } if (!updateAgents.Any()) { ConsoleEx.Out.WriteLine("All agents are up-to-date.", ConsoleColor.DarkGreen); return; } // Download update msi ConsoleEx.Out.Write("Downloading Agent update ", ConsoleColor.DarkCyan) .Write(agentIndex.Version, ConsoleColor.Cyan) .WriteLine("...", ConsoleColor.DarkCyan); var url = NetPath.Combine(Configuration.DownloadUrl, "agent", agentIndex.Version, agentIndex.MsiFilename); var updateDirectory = Path.Combine(Configuration.Directory, "Updates"); var updateFilename = Path.Combine(updateDirectory, "Photon.Agent.msi"); PathEx.CreatePath(updateDirectory); using (var client = new WebClient()) { await client.DownloadFileTaskAsync(url, updateFilename); } ConsoleEx.Out.WriteLine("Download Complete.", ConsoleColor.DarkBlue); // Perform updates var agentIdList = updateAgents.ToArray(); var startResult = await StartSession(server, agentIdList, updateFilename); var sessionId = startResult?.SessionId; if (string.IsNullOrEmpty(sessionId)) { throw new ApplicationException($"An invalid session-id was returned! [{sessionId}]"); } var position = 0; while (true) { var data = await UpdateOutput(server, sessionId, position); if (data == null) { throw new ApplicationException("An empty session-output response was returned!"); } if (data.IsComplete) { break; } if (!data.IsModified) { await Task.Delay(PollIntervalMs); continue; } position = data.NewLength; ConsoleEx.Out.WriteLine(data.NewText, ConsoleColor.Gray); } Result = await GetResult(server, sessionId); ConsoleEx.Out.WriteLine("Update completed successfully.", ConsoleColor.DarkGreen); }
public async Task PublishAsync(string packageName, string packageId, CancellationToken token = default(CancellationToken)) { context.Output.WriteBlock() .Write("Updating Application ", ConsoleColor.DarkCyan) .Write(packageName, ConsoleColor.Cyan) .WriteLine("...", ConsoleColor.DarkCyan) .Post(); var photonVars = context.ServerVariables["photon"]; if (photonVars == null) { throw new ApplicationException("Photon Variables were not found!"); } var assemblyVersion = AssemblyTools.GetVersion(AssemblyFilename); var webVersion = await GetWebVersion(); if (!VersionTools.HasUpdates(webVersion, assemblyVersion)) { context.Output.WriteBlock() .Write("Application ", ConsoleColor.DarkBlue) .Write(packageName, ConsoleColor.Blue) .Write(" is up-to-date. Version ", ConsoleColor.DarkBlue) .WriteLine(assemblyVersion, ConsoleColor.Blue) .Post(); return; } // Publish // Create ZIP PathEx.CreatePath(PackagePath); var zipFilename = Path.Combine(PackagePath, $"{packageId}.zip"); await CreateZip(BinPath, zipFilename); // Create Version Directory try { await CreateWebPath(assemblyVersion, token); } catch (WebException) { //... } var webMsiName = $"{packageId}.{assemblyVersion}.msi"; var webZipName = $"{packageId}.{assemblyVersion}.zip"; var msiWebUrl = NetPath.Combine(UploadPath, assemblyVersion, webMsiName); var zipWebUrl = NetPath.Combine(UploadPath, assemblyVersion, webZipName); await UploadFile(MsiFilename, msiWebUrl, token); await UploadFile(zipFilename, zipWebUrl, token); var index = new { version = assemblyVersion, msiFilename = webMsiName, zipFilename = webZipName, notes = "...", }; await UploadIndex(index, assemblyVersion, token); await UpdateLatest(assemblyVersion, token); context.Output.WriteBlock() .Write("Application ", ConsoleColor.DarkGreen) .Write(packageName, ConsoleColor.Green) .Write(" updated successfully. ", ConsoleColor.DarkGreen) .Write("Version ", ConsoleColor.DarkCyan) .WriteLine(assemblyVersion, ConsoleColor.Cyan) .Post(); }