From eb137addeea0d277c9b3b511462e967d1a0d3f36 Mon Sep 17 00:00:00 2001 From: Jordan Dominion Date: Sat, 16 Nov 2024 18:43:28 -0500 Subject: [PATCH] Remove the TGS3 migrator --- build/Version.props | 1 - .../InstallationExtensions.cs | 21 +- ....Server.Host.Service.Wix.Extensions.csproj | 1 + .../Extensions/ValueTaskExtensions.cs | 4 +- .../Extensions/VersionExtensions.cs | 4 +- .../Http/CachedResponseStream.cs | 4 +- .../Http/HttpClient.cs | 4 +- .../Http/HttpClientFactory.cs | 4 +- .../Http/IAbstractHttpClientFactory.cs | 4 +- .../Http/IHttpClient.cs | 4 +- .../Tgstation.Server.Common.csproj | 11 +- tgstation-server.sln | 33 -- .../Program.cs | 389 ------------- .../Tgstation.Server.Migrator.Comms.csproj | 24 - tools/Tgstation.Server.Migrator/Program.cs | 544 ------------------ .../RuntimeDistributableAttribute.cs | 34 -- .../Tgstation.Server.Migrator.csproj | 37 -- 17 files changed, 39 insertions(+), 1084 deletions(-) delete mode 100644 tools/Tgstation.Server.Migrator.Comms/Program.cs delete mode 100644 tools/Tgstation.Server.Migrator.Comms/Tgstation.Server.Migrator.Comms.csproj delete mode 100644 tools/Tgstation.Server.Migrator/Program.cs delete mode 100644 tools/Tgstation.Server.Migrator/Properties/RuntimeDistributableAttribute.cs delete mode 100644 tools/Tgstation.Server.Migrator/Tgstation.Server.Migrator.csproj diff --git a/build/Version.props b/build/Version.props index 02bbc0e30a4..2058d65952e 100644 --- a/build/Version.props +++ b/build/Version.props @@ -15,7 +15,6 @@ 1.6.0 8.0.0 1.2.1 - 2.0.0 netstandard2.0 8 diff --git a/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/InstallationExtensions.cs b/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/InstallationExtensions.cs index d6a46b77006..6747b1c764e 100644 --- a/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/InstallationExtensions.cs +++ b/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/InstallationExtensions.cs @@ -4,6 +4,7 @@ using System.IO; using System.ServiceProcess; + using Tgstation.Server.Common; using Tgstation.Server.Host.Common; using WixToolset.Dtf.WindowsInstaller; @@ -13,12 +14,6 @@ /// public static class InstallationExtensions { - /// - /// Package name - /// - /// As much as I'd like to use Tgstation.Server.Common.Constants.CanonicalPackageName here, attempting to reference it makes Tgstation.Server.Migrator.Comms fail due to referencing the net2.0 version of that library. EVEN THOUGH IT'S A TRANSITIVE DEPENDENCY OF Tgstation.Server.Client!!!!! If that dead-ass tool has been removed, feel free to do this. - const string CanonicalPackageName = "tgstation-server"; - /// /// Attempts to detach stop the existing tgstation-server service if it exists. /// @@ -35,18 +30,18 @@ public static ActionResult DetachStopTgsServiceIfRunning(Session session) session.Log("Begin DetachStopTgsServiceIfRunning"); ServiceController serviceController = null; - session.Log($"Searching for {CanonicalPackageName} service..."); + session.Log($"Searching for {Constants.CanonicalPackageName} service..."); try { foreach (var controller in ServiceController.GetServices()) - if (controller.ServiceName == CanonicalPackageName) + if (controller.ServiceName == Constants.CanonicalPackageName) serviceController = controller; else controller.Dispose(); if (serviceController == null || serviceController.Status != ServiceControllerStatus.Running) { - session.Log($"{CanonicalPackageName} service not found. Continuing."); + session.Log($"{Constants.CanonicalPackageName} service not found. Continuing."); return ActionResult.Success; } @@ -54,16 +49,16 @@ public static ActionResult DetachStopTgsServiceIfRunning(Session session) PipeCommands.CommandDetachingShutdown) .Value; - session.Log($"{CanonicalPackageName} service found. Sending command \"{PipeCommands.CommandDetachingShutdown}\" ({commandId})..."); + session.Log($"{Constants.CanonicalPackageName} service found. Sending command \"{PipeCommands.CommandDetachingShutdown}\" ({commandId})..."); serviceController.ExecuteCommand(commandId); - session.Log($"Command sent. Waiting for {CanonicalPackageName} service to stop..."); + session.Log($"Command sent. Waiting for {Constants.CanonicalPackageName} service to stop..."); serviceController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMinutes(1)); var stopped = serviceController.Status == ServiceControllerStatus.Stopped; - session.Log($"{CanonicalPackageName} stopped {(stopped ? String.Empty : "un")}successfully."); + session.Log($"{Constants.CanonicalPackageName} stopped {(stopped ? String.Empty : "un")}successfully."); return stopped ? ActionResult.Success @@ -97,7 +92,7 @@ public static ActionResult ApplyProductionAppsettingsIfNonExistant(Session sessi session.Log("Begin ApplyProductionAppsettingsIfNonExistant"); var programDataDirectory = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), - CanonicalPackageName); + Constants.CanonicalPackageName); var initialAppSettingsPath = Path.Combine(programDataDirectory, "appsettings.Initial.yml"); var productionAppSettingsPath = Path.Combine(programDataDirectory, "appsettings.Production.yml"); diff --git a/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/Tgstation.Server.Host.Service.Wix.Extensions.csproj b/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/Tgstation.Server.Host.Service.Wix.Extensions.csproj index fcdbd512a62..ad57e5fbd50 100644 --- a/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/Tgstation.Server.Host.Service.Wix.Extensions.csproj +++ b/build/package/winget/Tgstation.Server.Host.Service.Wix.Extensions/Tgstation.Server.Host.Service.Wix.Extensions.csproj @@ -11,6 +11,7 @@ + True diff --git a/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs b/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs index 1dead09d935..a01da554c0f 100644 --- a/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs +++ b/src/Tgstation.Server.Common/Extensions/ValueTaskExtensions.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0_OR_GREATER +using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; @@ -155,3 +156,4 @@ public static async ValueTask WhenAll(IReadOnlyList tasks) public static ValueTask WhenAll(params ValueTask[] tasks) => WhenAll((IReadOnlyList)tasks); } } +#endif diff --git a/src/Tgstation.Server.Common/Extensions/VersionExtensions.cs b/src/Tgstation.Server.Common/Extensions/VersionExtensions.cs index 3e6b3102bd1..c67a4a096d3 100644 --- a/src/Tgstation.Server.Common/Extensions/VersionExtensions.cs +++ b/src/Tgstation.Server.Common/Extensions/VersionExtensions.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0_OR_GREATER +using System; namespace Tgstation.Server.Common.Extensions { @@ -24,3 +25,4 @@ public static Version Semver(this Version version) } } } +#endif diff --git a/src/Tgstation.Server.Common/Http/CachedResponseStream.cs b/src/Tgstation.Server.Common/Http/CachedResponseStream.cs index eb007b54a5b..77dd7b1ccb9 100644 --- a/src/Tgstation.Server.Common/Http/CachedResponseStream.cs +++ b/src/Tgstation.Server.Common/Http/CachedResponseStream.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0_OR_GREATER +using System; using System.IO; using System.Net.Http; using System.Threading.Tasks; @@ -105,3 +106,4 @@ protected override void Dispose(bool disposing) } } } +#endif diff --git a/src/Tgstation.Server.Common/Http/HttpClient.cs b/src/Tgstation.Server.Common/Http/HttpClient.cs index 692c10a304b..67431fef9dc 100644 --- a/src/Tgstation.Server.Common/Http/HttpClient.cs +++ b/src/Tgstation.Server.Common/Http/HttpClient.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0_OR_GREATER +using System; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; @@ -49,3 +50,4 @@ public Task SendAsync(HttpRequestMessage request, HttpCompl => httpClient.SendAsync(request, completionOption, cancellationToken); } } +#endif diff --git a/src/Tgstation.Server.Common/Http/HttpClientFactory.cs b/src/Tgstation.Server.Common/Http/HttpClientFactory.cs index 93659471b5b..02ab8cc00b9 100644 --- a/src/Tgstation.Server.Common/Http/HttpClientFactory.cs +++ b/src/Tgstation.Server.Common/Http/HttpClientFactory.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0_OR_GREATER +using System; using System.Net.Http.Headers; namespace Tgstation.Server.Common.Http @@ -39,3 +40,4 @@ public HttpClientFactory(ProductInfoHeaderValue userAgent) } } } +#endif diff --git a/src/Tgstation.Server.Common/Http/IAbstractHttpClientFactory.cs b/src/Tgstation.Server.Common/Http/IAbstractHttpClientFactory.cs index 120712f2bb7..8bff723798c 100644 --- a/src/Tgstation.Server.Common/Http/IAbstractHttpClientFactory.cs +++ b/src/Tgstation.Server.Common/Http/IAbstractHttpClientFactory.cs @@ -1,4 +1,5 @@ -namespace Tgstation.Server.Common.Http +#if NETSTANDARD2_0_OR_GREATER +namespace Tgstation.Server.Common.Http { /// /// Creates s. @@ -12,3 +13,4 @@ public interface IAbstractHttpClientFactory IHttpClient CreateClient(); } } +#endif diff --git a/src/Tgstation.Server.Common/Http/IHttpClient.cs b/src/Tgstation.Server.Common/Http/IHttpClient.cs index d0ade7050dd..537a7bcd778 100644 --- a/src/Tgstation.Server.Common/Http/IHttpClient.cs +++ b/src/Tgstation.Server.Common/Http/IHttpClient.cs @@ -1,4 +1,5 @@ -using System; +#if NETSTANDARD2_0_OR_GREATER +using System; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; @@ -31,3 +32,4 @@ public interface IHttpClient : IDisposable Task SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken); } } +#endif diff --git a/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj b/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj index 4b119caf8b1..4ec30e8da0c 100644 --- a/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj +++ b/src/Tgstation.Server.Common/Tgstation.Server.Common.csproj @@ -2,7 +2,7 @@ - $(TgsNugetNetFramework) + $(TgsNugetNetFramework);net2.0 $(TgsCommonLibraryVersion) enable Common functions for tgstation-server. @@ -10,7 +10,7 @@ $(TGS_NUGET_RELEASE_NOTES_COMMON) - + @@ -24,4 +24,11 @@ + + + + + + + diff --git a/tgstation-server.sln b/tgstation-server.sln index 31d15d01590..2f8261c9d5b 100644 --- a/tgstation-server.sln +++ b/tgstation-server.sln @@ -197,13 +197,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ISSUE_TEMPLATE", "ISSUE_TEM EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tgstation.Server.Host.Tests.Signals", "tests\Tgstation.Server.Host.Tests.Signals\Tgstation.Server.Host.Tests.Signals.csproj", "{5813CC33-B16C-485D-A74D-20204DDF6542}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tgstation.Server.Migrator", "tools\Tgstation.Server.Migrator\Tgstation.Server.Migrator.csproj", "{CE499888-B22B-457C-891E-0EA9DC317228}" - ProjectSection(ProjectDependencies) = postProject - {07ED0FD5-E46B-4841-931D-BA2B673E16B2} = {07ED0FD5-E46B-4841-931D-BA2B673E16B2} - EndProjectSection -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tgstation.Server.Migrator.Comms", "tools\Tgstation.Server.Migrator.Comms\Tgstation.Server.Migrator.Comms.csproj", "{07ED0FD5-E46B-4841-931D-BA2B673E16B2}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tgstation.Server.Host.Common", "src\Tgstation.Server.Host.Common\Tgstation.Server.Host.Common.csproj", "{CF3968A0-EA81-4464-B2D4-C7D40F6B5BCB}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tgstation.Server.Common", "src\Tgstation.Server.Common\Tgstation.Server.Common.csproj", "{70CD9A98-D31A-44A4-81D1-D02764CEEEFD}" @@ -448,30 +441,6 @@ Global {5813CC33-B16C-485D-A74D-20204DDF6542}.ReleaseNoWindows|Any CPU.Build.0 = Release|Any CPU {5813CC33-B16C-485D-A74D-20204DDF6542}.ReleaseNoWix|Any CPU.ActiveCfg = Release|Any CPU {5813CC33-B16C-485D-A74D-20204DDF6542}.ReleaseNoWix|Any CPU.Build.0 = Release|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.DebugNoWindows|Any CPU.ActiveCfg = Debug|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.DebugNoWindows|Any CPU.Build.0 = Debug|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.DebugNoWix|Any CPU.ActiveCfg = Debug|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.DebugNoWix|Any CPU.Build.0 = Debug|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.Release|Any CPU.Build.0 = Release|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.ReleaseNoWindows|Any CPU.ActiveCfg = Release|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.ReleaseNoWindows|Any CPU.Build.0 = Release|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.ReleaseNoWix|Any CPU.ActiveCfg = Release|Any CPU - {CE499888-B22B-457C-891E-0EA9DC317228}.ReleaseNoWix|Any CPU.Build.0 = Release|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.DebugNoWindows|Any CPU.ActiveCfg = Debug|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.DebugNoWindows|Any CPU.Build.0 = Debug|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.DebugNoWix|Any CPU.ActiveCfg = Debug|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.DebugNoWix|Any CPU.Build.0 = Debug|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.Release|Any CPU.Build.0 = Release|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.ReleaseNoWindows|Any CPU.ActiveCfg = Release|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.ReleaseNoWindows|Any CPU.Build.0 = Release|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.ReleaseNoWix|Any CPU.ActiveCfg = Release|Any CPU - {07ED0FD5-E46B-4841-931D-BA2B673E16B2}.ReleaseNoWix|Any CPU.Build.0 = Release|Any CPU {CF3968A0-EA81-4464-B2D4-C7D40F6B5BCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CF3968A0-EA81-4464-B2D4-C7D40F6B5BCB}.Debug|Any CPU.Build.0 = Debug|Any CPU {CF3968A0-EA81-4464-B2D4-C7D40F6B5BCB}.DebugNoWindows|Any CPU.ActiveCfg = Debug|Any CPU @@ -605,8 +574,6 @@ Global {103C61AB-67D6-46FE-AA47-CC633B88EE0F} = {82066812-6C73-4360-943B-B23F2F491261} {CFFD7992-E73A-4D1F-9D7A-C817C07B7BEB} = {E82104F4-F5C4-4786-ACD4-B635166CDB21} {5813CC33-B16C-485D-A74D-20204DDF6542} = {316141B0-CD21-4769-A013-D53DA9B9EC09} - {CE499888-B22B-457C-891E-0EA9DC317228} = {A55C1117-5808-4AB2-BEA6-4D4A3E66A2F2} - {07ED0FD5-E46B-4841-931D-BA2B673E16B2} = {A55C1117-5808-4AB2-BEA6-4D4A3E66A2F2} {2648A85F-61AE-428E-95E1-66D06C7A3768} = {6FF654E6-3E2C-46D4-872D-D528F77D6973} {457A1F89-6201-4430-BCC6-2F4438A54B9E} = {2648A85F-61AE-428E-95E1-66D06C7A3768} {08E7C650-A447-4DE2-974E-ED123B50F8D6} = {457A1F89-6201-4430-BCC6-2F4438A54B9E} diff --git a/tools/Tgstation.Server.Migrator.Comms/Program.cs b/tools/Tgstation.Server.Migrator.Comms/Program.cs deleted file mode 100644 index 3c46d8a1cca..00000000000 --- a/tools/Tgstation.Server.Migrator.Comms/Program.cs +++ /dev/null @@ -1,389 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Net.Http.Headers; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -using TGS.Interface; - -using Tgstation.Server.Api; -using Tgstation.Server.Api.Models; -using Tgstation.Server.Api.Models.Internal; -using Tgstation.Server.Api.Models.Request; -using Tgstation.Server.Client; -using Tgstation.Server.Common.Extensions; - -static class Program -{ - static async Task Main(string[] args) - { - try - { - var tgs3Client = new Client(); - - switch (args[0]) - { - case "--verify-connection": - var status = tgs3Client.ConnectionStatus(out var error); - if (status != ConnectivityLevel.Administrator) - { - Console.WriteLine($"Connection Error: {error}"); - return 3; - } - return 0; - case "--migrate": - ushort apiPort = ushort.Parse(args[1]); - return await Migrate(tgs3Client, apiPort); - default: - return 2; - } - } - catch (Exception ex) - { - Console.WriteLine(ex); - return 1; - } - } - - static async Task Migrate(IClient tgs3Client, ushort apiPort) - { -#if DEBUG - Console.WriteLine("Test log line..."); - System.Diagnostics.Debugger.Launch(); -#endif - Console.WriteLine("Connecting to TGS3..."); - var status = tgs3Client.ConnectionStatus(out var tgs3Error); - if (status != ConnectivityLevel.Administrator) - { - Console.WriteLine($"Connection Error: {tgs3Client}"); - return 13; - } - - Console.WriteLine("Connected!"); - - Console.WriteLine("Connecting to TGS6..."); - var assemblyName = Assembly.GetExecutingAssembly().GetName(); - var productInfoHeaderValue = - new ProductInfoHeaderValue( - assemblyName.Name!, - assemblyName.Version!.Semver().ToString()); - - var serverUrl = new Uri($"http://localhost:{apiPort}"); - var clientFactory = new RestServerClientFactory(productInfoHeaderValue.Product); - var TGS6Client = await clientFactory.CreateFromLogin( - serverUrl, - DefaultCredentials.AdminUserName, - DefaultCredentials.DefaultAdminUserPassword); - - Console.WriteLine("Connected!"); - - // we do this synchronously and patiently because we aren't chumbii and this is delicate - // We need clear logs - var tgs3Instances = tgs3Client.Server.Instances.ToList(); - foreach (var tgs3Instance in tgs3Instances) - { - var instanceName = tgs3Instance.Metadata.Name; - var instancePath = tgs3Instance.Metadata.Path; - - if (!tgs3Instance.Metadata.Enabled) - { - Console.WriteLine($"Skipping instance {instanceName} at {instancePath}. Disabled."); - continue; - } - - Console.WriteLine($"Migrating instance {instanceName} at {instancePath}"); - - RepositoryUpdateRequest? repositoryUpdateRequest = null; - if (tgs3Instance.Repository.Exists()) - { - Console.WriteLine("Gathering instance repository data..."); - repositoryUpdateRequest = new RepositoryUpdateRequest - { - CommitterEmail = tgs3Instance.Repository.GetCommitterEmail(), - CommitterName = tgs3Instance.Repository.GetCommitterName(), - UpdateSubmodules = true, // default in 3 - Reference = tgs3Instance.Repository.GetBranch(out tgs3Error), - }; - - if (tgs3Error != null) - { - Console.WriteLine($"Error retrieving current branch: {tgs3Error}"); - } - } - else - Console.WriteLine("Instance has no repository, that's fine."); - - Console.WriteLine("Gather DreamDaemon and DreamMaker data..."); - var dreamDaemonRequest = new DreamDaemonRequest - { - AllowWebClient = tgs3Instance.DreamDaemon.Webclient(), - AutoStart = tgs3Instance.DreamDaemon.Autostart(), - Port = tgs3Instance.DreamDaemon.Port(), - SecurityLevel = tgs3Instance.DreamDaemon.SecurityLevel() switch - { - TGS.Interface.DreamDaemonSecurity.Safe => Tgstation.Server.Api.Models.DreamDaemonSecurity.Safe, - TGS.Interface.DreamDaemonSecurity.Ultrasafe => Tgstation.Server.Api.Models.DreamDaemonSecurity.Ultrasafe, - _ => Tgstation.Server.Api.Models.DreamDaemonSecurity.Trusted, - } - }; - - var dreamMakerRequest = new DreamMakerRequest - { - ApiValidationSecurityLevel = dreamDaemonRequest.SecurityLevel, - ApiValidationPort = (ushort)(dreamDaemonRequest.Port + 111) // Best rotation we can do... - }; - - Console.WriteLine("Gathering chat data..."); - var providerInfos = tgs3Instance.Chat.ProviderInfos(); - var chatBotCreateRequests = new List(); - foreach(var providerInfo in providerInfos) - { - if (!providerInfo.Enabled) - continue; - - var createRequest = new ChatBotCreateRequest() - { - Provider = providerInfo.Provider switch - { - TGS.Interface.ChatProvider.Discord => Tgstation.Server.Api.Models.ChatProvider.Discord, - _ => Tgstation.Server.Api.Models.ChatProvider.Irc, - }, - Enabled = true, - ReconnectionInterval = 5, - }; - - var isDiscordProvider = createRequest.Provider == Tgstation.Server.Api.Models.ChatProvider.Discord; - createRequest.Name = isDiscordProvider - ? "Discord Bot" - : "IRC Bot"; - - Console.WriteLine($"Gathering data for {createRequest.Name}..."); - - ChatConnectionStringBuilder csb; - if (createRequest.Provider == Tgstation.Server.Api.Models.ChatProvider.Discord) - { - var discordSetupInfo = new DiscordSetupInfo(providerInfo); - csb = new DiscordConnectionStringBuilder - { - DMOutputDisplay = DiscordDMOutputDisplayType.Always, - BotToken = discordSetupInfo.BotToken - }; - - } - else - { - var ircSetupInfo = new IRCSetupInfo(providerInfo); - csb = new IrcConnectionStringBuilder - { - Address = ircSetupInfo.URL, - Nickname = ircSetupInfo.Nickname, - Port = ircSetupInfo.Port - }; - } - createRequest.ConnectionString = csb.ToString(); - - createRequest.Channels = new List(); - - static string NormalizeChannelId(string channelId) => channelId.ToLowerInvariant().Trim(); - - var distinctChannels = providerInfo.WatchdogChannels - .Union(providerInfo.DevChannels) - .Union(providerInfo.AdminChannels) - .Union(providerInfo.GameChannels) - .Select(NormalizeChannelId) - .Distinct(); - - foreach(var channelIdentifier in distinctChannels) - { - var newChatChannel = new ChatChannel - { - IsWatchdogChannel = providerInfo.WatchdogChannels.Any(x => NormalizeChannelId(x) == channelIdentifier), - IsAdminChannel = providerInfo.AdminChannels.Any(x => NormalizeChannelId(x) == channelIdentifier), - IsUpdatesChannel = providerInfo.DevChannels.Any(x => NormalizeChannelId(x) == channelIdentifier), - // system channels are too new a feature to target - ChannelData = channelIdentifier, - }; - - createRequest.Channels.Add(newChatChannel); - } - - chatBotCreateRequests.Add(createRequest); - } - - Console.WriteLine("Detaching TGS3 instance..."); - tgs3Client.Server.InstanceManager.DetachInstance(instanceName); - - Console.WriteLine("Creating TGS6 attach file..."); - File.WriteAllText(Path.Combine(instancePath, "TGS4_ALLOW_INSTANCE_ATTACH"), String.Empty); - - Console.WriteLine("Checking BYOND install..."); - var byondDirectory = Path.Combine(instancePath, "BYOND"); - var byondVersionFile = Path.Combine(byondDirectory, "byond_version.dat"); - - EngineVersionRequest? byondVersionRequest = null; - if (Directory.Exists(byondDirectory) && File.Exists(byondVersionFile)) - { - var byondVersion = Version.Parse(File.ReadAllText(byondVersionFile).Trim()); - Console.WriteLine($"Found installed BYOND version: {byondVersion.Major}.{byondVersion.Minor}"); - byondVersionRequest = new EngineVersionRequest - { - EngineVersion = new EngineVersion - { - Version = byondVersion - } - }; - } - - var oldStaticDirectory = Path.Combine(instancePath, "Static"); - var newConfigurationDirectory = Path.Combine(instancePath, "Configuration"); - if (Directory.Exists(oldStaticDirectory)) - { - Console.WriteLine("Migrating Static to Configuration/GameStaticFiles"); - var gameStaticFilesDirectory = Path.Combine(newConfigurationDirectory, "GameStaticFiles"); - Directory.CreateDirectory(newConfigurationDirectory); - Directory.Move(oldStaticDirectory, gameStaticFilesDirectory); - - Console.WriteLine("Moving code modifications..."); - var codeModsDirectory = Path.Combine(newConfigurationDirectory, "CodeModifications"); - Directory.CreateDirectory(codeModsDirectory); - - var allDmFiles = Directory.EnumerateFiles(gameStaticFilesDirectory, "*.dm", SearchOption.TopDirectoryOnly).ToList(); - foreach (var dmFile in allDmFiles) - { - File.Move(Path.Combine(gameStaticFilesDirectory, dmFile), Path.Combine(codeModsDirectory, Path.GetFileName(dmFile))); - } - - var allDmeFiles = Directory.EnumerateFiles(gameStaticFilesDirectory, "*.dme", SearchOption.TopDirectoryOnly).ToList(); - if (allDmeFiles.Any()) - { - foreach (var dmeFile in allDmeFiles) - { - File.Move(Path.Combine(gameStaticFilesDirectory, dmeFile), Path.Combine(codeModsDirectory, Path.GetFileName(dmeFile))); - } - } - else if (allDmFiles.Any()) - { - Console.WriteLine("Generating HeadInclude.dm..."); - var headIncludeBuilder = new StringBuilder(); - foreach (var dmFile in allDmFiles.OrderBy(fileName => fileName.ToUpperInvariant())) - { - headIncludeBuilder.Append("#include \""); - headIncludeBuilder.Append(Path.GetFileName(dmFile)); - headIncludeBuilder.Append("\""); - headIncludeBuilder.Append(Environment.NewLine); - } - - File.WriteAllText(Path.Combine(codeModsDirectory, "HeadInclude.dm"), headIncludeBuilder.ToString()); - } - } - - var eventHandlersDirectory = Path.Combine(instancePath, "EventHandlers"); - if (Directory.Exists(eventHandlersDirectory)) - { - Console.WriteLine("Moving event scripts..."); - Directory.CreateDirectory(newConfigurationDirectory); - Directory.Move(eventHandlersDirectory, Path.Combine(newConfigurationDirectory, "EventScripts")); - } - - var diagnosticsDirectory = Path.Combine(instancePath, "Diagnostics"); - var minidumpsDirectory = Path.Combine(diagnosticsDirectory, "Minidumps"); - if (Directory.Exists(minidumpsDirectory)) - { - Console.WriteLine("Renaming Minidumps folder to ProcessDumps..."); - Directory.Move(minidumpsDirectory, Path.Combine(diagnosticsDirectory, "ProcessDumps")); - } - - Console.WriteLine("Deleting BYOND folder..."); - await RecursivelyDeleteDirectory(new DirectoryInfo(byondDirectory)); - Console.WriteLine("Deleting RepoKey folder..."); - await RecursivelyDeleteDirectory(new DirectoryInfo(Path.Combine(instancePath, "RepoKey"))); - Console.WriteLine("Deleting Game folder..."); - await RecursivelyDeleteDirectory(new DirectoryInfo(Path.Combine(instancePath, "Game"))); - Console.WriteLine("Deleting Instance.json..."); - File.Delete(Path.Combine(instancePath, "Instance.json")); - Console.WriteLine("Deleting prtestjob.json..."); - File.Delete(Path.Combine(instancePath, "prtestjob.json")); - Console.WriteLine("Deleting TGS3.json..."); - File.Delete(Path.Combine(instancePath, "TGS3.json")); - Console.WriteLine("Deleting TGDreamDaemonBridge.dll..."); - File.Delete(Path.Combine(instancePath, "TGDreamDaemonBridge.dll")); - - Console.WriteLine("Attaching TGS6 instance..."); - var TGS6Instance = await TGS6Client.Instances.CreateOrAttach(new InstanceCreateRequest - { - ConfigurationType = ConfigurationType.Disallowed, - Name = instanceName, - Path = instancePath, - }, default); - - Console.WriteLine($"Onlining TGS6 instance ID {TGS6Instance.Id}..."); - TGS6Instance = await TGS6Client.Instances.Update(new InstanceUpdateRequest - { - Online = true, - Id = TGS6Instance.Id - }, default); - - var v5InstanceClient = TGS6Client.Instances.CreateClient(TGS6Instance); - - if (byondVersionRequest != null) - { - Console.WriteLine("Triggering BYOND install job..."); - await v5InstanceClient.Engine.SetActiveVersion(byondVersionRequest, null, default); - } - - if (repositoryUpdateRequest != null) - { - Console.WriteLine("Updating repository settings..."); - await v5InstanceClient.Repository.Update(repositoryUpdateRequest, default); - } - - Console.WriteLine("Updating deployment settings..."); - await v5InstanceClient.DreamMaker.Update(dreamMakerRequest, default); - - Console.WriteLine("Updating DreamDaemon settings..."); - await v5InstanceClient.DreamDaemon.Update(dreamDaemonRequest, default); - - foreach(var chatBotCreateRequest in chatBotCreateRequests) - { - Console.WriteLine($"Creating chat bot {chatBotCreateRequest.Name}..."); - await v5InstanceClient.ChatBots.Create(chatBotCreateRequest, default); - } - - Console.WriteLine($"Instance {instanceName} (TGS6 ID: {TGS6Instance.Id}) successfully migrated!"); - } - - Console.WriteLine("All enabled V3 instances migrated into V5 and detached from V3!"); - - return 0; - } - - static async Task RecursivelyDeleteDirectory(DirectoryInfo dir) - { - var tasks = new List(); - - if (!dir.Exists) - return; - - // check if we are a symbolic link - if (!dir.Attributes.HasFlag(FileAttributes.Directory) || dir.Attributes.HasFlag(FileAttributes.ReparsePoint)) - { - dir.Delete(); - return; - } - - foreach (var subDir in dir.EnumerateDirectories()) - tasks.Add(RecursivelyDeleteDirectory(subDir)); - - foreach (var file in dir.EnumerateFiles()) - { - file.Attributes = FileAttributes.Normal; - file.Delete(); - } - - await Task.WhenAll(tasks); - dir.Delete(true); - } -} diff --git a/tools/Tgstation.Server.Migrator.Comms/Tgstation.Server.Migrator.Comms.csproj b/tools/Tgstation.Server.Migrator.Comms/Tgstation.Server.Migrator.Comms.csproj deleted file mode 100644 index e43af6ce0f6..00000000000 --- a/tools/Tgstation.Server.Migrator.Comms/Tgstation.Server.Migrator.Comms.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - - Exe - net472 - win-x86 - $(TgsMigratorVersion) - enable - - - - - - - - - - - - - - - diff --git a/tools/Tgstation.Server.Migrator/Program.cs b/tools/Tgstation.Server.Migrator/Program.cs deleted file mode 100644 index 86cabd419e5..00000000000 --- a/tools/Tgstation.Server.Migrator/Program.cs +++ /dev/null @@ -1,544 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Configuration.Install; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Management; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Reflection; -using System.Security.Principal; -using System.ServiceProcess; -using System.Text.RegularExpressions; -using System.Threading.Tasks; - -using Microsoft.Extensions.Logging; - -using Octokit; - -using Tgstation.Server.Api; -using Tgstation.Server.Client; -using Tgstation.Server.Common; -using Tgstation.Server.Common.Extensions; -using Tgstation.Server.Common.Http; -using Tgstation.Server.Host.IO; -using Tgstation.Server.Host.Setup; -using Tgstation.Server.Migrator.Properties; - -using FileMode = System.IO.FileMode; - -[DoesNotReturn] -static void ExitPause(int exitCode) -{ - Console.WriteLine("Consider saving the console text to report issues. Press any key to exit..."); - Console.ReadKey(); - Environment.Exit(exitCode); -} - -try -{ - var commandLine = Environment.GetCommandLineArgs(); - var commandLineArguments = commandLine.Skip(1); - var skipPreamble = commandLineArguments.Any(x => x.Equals("--skip-preamble", StringComparison.OrdinalIgnoreCase)); - - Console.WriteLine("This is a very straightfoward script to migrate the instances of a TGS3 install into a new TGS6 install"); - - static bool PromptYesOrNo(string question) - { - Console.Write($"{question} (y/n):"); - var character = Console.ReadKey(); - Console.WriteLine(); - return character.KeyChar.ToString().ToUpperInvariant() == "Y"; - } - - // WORKING DIRECTORY CHECK - var currentAssembly = Assembly.GetExecutingAssembly(); - if(Path.GetDirectoryName(Path.GetFullPath(currentAssembly.Location))!.Replace("\\", "/").ToUpperInvariant() - != Path.GetFullPath(Environment.CurrentDirectory).Replace("\\", "/").ToUpperInvariant()) - { - Console.WriteLine("Please keep the working directory equivalent to the program directory for this migration!"); - ExitPause(8); - } - - // PREREQUISITE CHECK - if (!skipPreamble) - { - Console.WriteLine("We need to ensure you're running this program as Administrator because there are several operations we'll do that require it."); - Console.WriteLine("If not, you will be prompted to elevate this process."); - } - - // ADMINISTRATOR CHECK - static bool IsAdministrator() - { - using var identity = WindowsIdentity.GetCurrent(); - var principal = new WindowsPrincipal(identity); - return principal.IsInRole(WindowsBuiltInRole.Administrator); - } - - if (!IsAdministrator()) - { - Console.WriteLine("Not running as admin. Elevating process..."); - var selfExecutable = commandLine.First().Replace(".dll", ".exe"); - var selfArguments = String.Join(" ", commandLineArguments) + " --skip-preamble"; - using var elevatedProcess = new Process(); - elevatedProcess.StartInfo.UseShellExecute = true; - elevatedProcess.StartInfo.FileName = selfExecutable; - elevatedProcess.StartInfo.Arguments = selfArguments; - elevatedProcess.StartInfo.Verb = "runas"; - - elevatedProcess.Start(); - return; - } - - Console.WriteLine("Administrative privileges confirmed."); - - // TGS3 SERVICE CHECK - - const string PathToCommsBinary = -#if DEBUG - "../../../../../Tgstation.Server.Migrator.Comms/bin/Debug/net472/win-x86/" + -#else - "Comms/" + -#endif - "Tgstation.Server.Migrator.Comms.exe"; - - Console.WriteLine($"Checking {PathToCommsBinary} exists..."); - if (!File.Exists(PathToCommsBinary)) - { - Console.WriteLine("Could not find WCF comms binary!"); - ExitPause(7); - } - - static int RunComms(string command) - { - using var commsProcess = new Process(); - commsProcess.StartInfo.FileName = PathToCommsBinary; - commsProcess.StartInfo.Arguments = command; - commsProcess.Start(); - commsProcess.WaitForExit(); - return commsProcess.ExitCode; - } - - Console.WriteLine("Checking for TGS3 service..."); - const string OldServiceName = "TG Station Server"; - const string NewServiceName = Constants.CanonicalPackageName; - - static ServiceController GetTgs3Service(bool checkNewOneIsntInstalled) - { - var allServices = ServiceController.GetServices(); - var tgs3Service = allServices.FirstOrDefault(service => service.ServiceName == OldServiceName); - foreach (var service in allServices) - { - if (service == tgs3Service) - continue; - - using (service) - if (checkNewOneIsntInstalled && (service.ServiceName == NewServiceName || service.ServiceName == "tgstation-server-4")) - { - Console.WriteLine("Detected existing TGS4+ install! Cannot continue. Please uninstall any versions of TGS4+ before continuing."); - ExitPause(10); - } - } - - if (checkNewOneIsntInstalled) - Console.WriteLine("TGS4+ service install not detected."); - - if (tgs3Service == null) - { - Console.WriteLine("TGS3 is not installed on this machine!"); - ExitPause(5); - } - - return tgs3Service; - } - - using var tgs3Service = GetTgs3Service(true); - - if (tgs3Service.Status != ServiceControllerStatus.Running) - { - Console.WriteLine("TGS3 service is installed but not running! Please start the service before continuing."); - ExitPause(9); - } - - // TGS3 CONNECTION CHECK - Console.WriteLine("Checking TGS3 connection..."); - var commsExitCode = RunComms("--verify-connection"); - if(commsExitCode != 0) - { - Console.WriteLine("Could not connect to TGS3 as administrator!"); - ExitPause(6); - } - - // USER INPUT - Console.WriteLine("We've confirmed you have have both TGS3 installed and TGS4+ service UNinstalled on THIS machine."); - Console.WriteLine(); - Console.WriteLine("Please read all of the following CAREFULLY before proceeding:"); - Console.WriteLine("Confirm you want to migrate to the latest version installing the necessary prerequisite .NET version along the way."); - Console.WriteLine("Please note that this is a one way upgrade and will not keep your DreamDaemon servers running throughout it."); - Console.WriteLine("All TGS3 instances will be migrated in place. The following components will be preserved:"); - Console.WriteLine("- Repository (No test merge data or SSH key)"); - Console.WriteLine("- BYOND version (redownloaded from byond.com)"); - Console.WriteLine("- A FEW server configuration settings (Committer info, Autostart, Webclient, Game Port, Security Level)"); - Console.WriteLine("- EventHandlers"); - Console.WriteLine("- Chat Bots, if enabled"); - Console.WriteLine(" - TGS4+ doesn't support individual user/group identification. Admin channels will be used instead"); - Console.WriteLine(" - IRC authentication information cannot be copied and must be manually adjusted"); - Console.WriteLine("- Static Files"); - Console.WriteLine("- Code Modifications"); - Console.WriteLine("Remaining components such as logins, game builds, etc. can be recreated once the migration is complete."); - Console.WriteLine("IMPORTANT NOTES:"); - Console.WriteLine("- INSTANCES CANNOT HAVE GAME PORTS OFFSET 111 UNITS FROM EACH OTHER OR HIGHER THAN 65423! WE AREN'T CORRECTING FOR THIS WHILE MIGRATING!"); - Console.WriteLine("- DISABLED INSTANCES WILL NOT BE MIGRATED! PLEASE ENABLE ALL INSTANCES YOU WISH TO MIGRATE BEFORE CONTINUING!"); - Console.WriteLine("- INSTANCE AUTO UPDATE CAN INTERFERE WITH THE MIGRATION! PLEASE DISABLE IT ON ALL INSTANCES BEING MIGRATED BEFORE CONTINUING!"); - Console.WriteLine("- DO NOT ATTEMPT TO USE TGS3 VIA NORMAL METHODS WHILE THIS MIGRATION IS TAKING PLACE OR YOU COULD CORRUPT YOUR DATA!"); - Console.WriteLine("Side note: You can skip the TGS6 setup wizard step by copying your premade appsettings.Production.yml file next to this .exe NOW."); - if (!PromptYesOrNo("Proceed with upgrade?")) - { - Console.WriteLine("Prerequisite not met."); - ExitPause(0); - } - - string? tgsInstallPath = null; - do - { - Console.WriteLine("Please enter the directory where you would like the TGS binaries installed."); - Console.Write("This may be anywhere but should be empty: "); - tgsInstallPath = Console.ReadLine(); - if (!String.IsNullOrWhiteSpace(tgsInstallPath)) - { - if (!Path.IsPathRooted(tgsInstallPath)) - { - Console.WriteLine("Please do not use a relative path for this. Enter the full path including the drive letter."); - tgsInstallPath = null; - } - else if (Path.GetInvalidPathChars().Any(invalidChar => tgsInstallPath.Contains(invalidChar))) - { - Console.WriteLine("Invalid characters detected!"); - tgsInstallPath = null; - } - } - } - while (String.IsNullOrWhiteSpace(tgsInstallPath)); - - Console.WriteLine("Attempting to create TGS install directory..."); - Directory.CreateDirectory(tgsInstallPath); - - // ASP.NET 8.0 RUNTIME CHECK - Console.WriteLine("Next step, we need to ensure the ASP.NET Core 6 runtime is installed on your machine."); - Console.WriteLine("We're going to download it for you."); - Console.WriteLine("Yes, this program runs .NET 6, but it contains the entire runtime embedded into it. You will need a system-wide install for TGS."); - - var runtimeInstalled = true; // assume for now - using (var dotnetRuntimeCheck = new Process()) - { - dotnetRuntimeCheck.StartInfo.FileName = "C:/Program Files/dotnet/dotnet.exe"; - dotnetRuntimeCheck.StartInfo.Arguments = "--list-runtimes"; - dotnetRuntimeCheck.StartInfo.RedirectStandardOutput = true; - - try - { - dotnetRuntimeCheck.Start(); - - dotnetRuntimeCheck.WaitForExit(); - } - catch (Win32Exception ex) when (ex.NativeErrorCode == 2) - { - Console.WriteLine("Dotnet does not appear to be installed at all."); - runtimeInstalled = false; - } - - if (runtimeInstalled) - { - var versions = await dotnetRuntimeCheck.StandardOutput.ReadToEndAsync(); - var regex = new Regex("Microsoft\\.AspNetCore\\.App 8\\.0\\.[0-9]+"); - - if (!regex.IsMatch(versions)) - runtimeInstalled = false; - } - } - - // ASP.NET 8.0 RUNTIME SETUP - var assemblyName = currentAssembly.GetName(); - var productInfoHeaderValue = - new ProductInfoHeaderValue( - assemblyName.Name!, - assemblyName.Version!.Semver().ToString()); - var httpClientFactory = new HttpClientFactory(productInfoHeaderValue); - if (!runtimeInstalled) - { - // RUNTIME DONWLOAD - Console.WriteLine("The version we are installing is the latest circa 26-09-2022, feel free to update it later if you want but that is not necessary."); - - var x64 = Environment.Is64BitOperatingSystem; - var xSubstitution = x64 ? "64" : "86"; - Console.WriteLine($"Running on an x{xSubstitution} system."); - - var downloadUri = RuntimeDistributableAttribute.Instance.RuntimeDistributableUrl; - - var dotnetDownloadFilePath = $"dotnet-hosting-bundle-installer.exe"; - - Console.WriteLine($"Downloading {downloadUri} to {Path.GetFullPath(dotnetDownloadFilePath)}..."); - - using var httpClient = httpClientFactory.CreateClient(); - using var request = new HttpRequestMessage(HttpMethod.Get, downloadUri); - var webRequestTask = httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, default); - using var response = await webRequestTask; - response.EnsureSuccessStatusCode(); - await using (var responseStream = await response.Content.ReadAsStreamAsync()) - { - await using var fileStream = new FileStream( - dotnetDownloadFilePath, - FileMode.Create, - FileAccess.Write, - FileShare.ReadWrite | FileShare.Delete, - 4096, - FileOptions.Asynchronous | FileOptions.SequentialScan); - await responseStream.CopyToAsync(fileStream); - } - - // RUNTIME INSTALLATION - Console.WriteLine("Runtime downloaded. Running silent installation..."); - bool silentInstallSuccess = true; - using var silentInstallProcess = new Process(); - { - silentInstallProcess.StartInfo.UseShellExecute = false; - silentInstallProcess.StartInfo.FileName = dotnetDownloadFilePath; - silentInstallProcess.StartInfo.Arguments = "/install /quiet /norestart"; - silentInstallProcess.Start(); - silentInstallProcess.WaitForExit(); - - if (silentInstallProcess.ExitCode != 0) - { - Console.WriteLine("Silent installation failed! Please install the runtime interactively."); - Console.WriteLine("Launching install dialog"); - silentInstallSuccess = false; - } - } - - if (!silentInstallSuccess) - { - using var installProcess = new Process(); - installProcess.StartInfo.FileName = dotnetDownloadFilePath; - installProcess.Start(); - installProcess.WaitForExit(); - - if (!PromptYesOrNo("Was the installation successful?")) - { - Console.WriteLine("Cannot continue without ASP.NET 8.0 runtime installed."); - ExitPause(2); - } - } - } - else - { - Console.WriteLine("Runtime detected successfully. Continuing..."); - } - - - // TGS6 ONLINE LOCATING - Console.WriteLine("Now we're going to locate the latest version of the TGS service."); - Console.WriteLine("(This migrator does not support the console runner, but you may switch the installation to it after completion)"); - - Console.WriteLine("Determining latest version of TGS 5.X.X..."); - - var gitHubClient = new GitHubClient(new Octokit.ProductHeaderValue(productInfoHeaderValue.Product!.Name, productInfoHeaderValue.Product.Version)); - - string? gitHubPat = Environment.GetEnvironmentVariable("TGS_MIGRATOR_GITHUB_PAT"); - if (gitHubPat != null) - gitHubClient.Credentials = new Credentials(gitHubPat); - - const int TgstationServerRepoId = 92952846; - - var allReleases = await gitHubClient.Repository.Release.GetAll(TgstationServerRepoId); - - const string VersionFiveTagPrefix = "tgstation-server-v5."; - var allVersionFiveReleases = allReleases - .Where(release => release.TagName.StartsWith(VersionFiveTagPrefix)); - var latestVersionFiveRelease = allVersionFiveReleases - .OrderByDescending(release => Version.Parse(release.TagName[(VersionFiveTagPrefix.Length - 2)..])) - .FirstOrDefault(); - - if (latestVersionFiveRelease == null) - { - Console.WriteLine("Unable to determine latest version 5 release!"); - ExitPause(3); - } - - Console.WriteLine($"Latest V5 version: {latestVersionFiveRelease.TagName}"); - - var serverServiceAsset = latestVersionFiveRelease.Assets.FirstOrDefault(asset => asset.Name == "ServerService.zip"); - if (serverServiceAsset == null) - { - Console.WriteLine("Unable to determine ServerService.zip release asset!"); - ExitPause(4); - } - - // TGS6 SETUP WIZARD - Console.WriteLine("We are now going to run the TGS setup wizard to generate your new server configuration file."); - - var serverFactory = Tgstation.Server.Host.Core.Application.CreateDefaultServerFactory(); - _ = await serverFactory.CreateServer(new[] { $"General:SetupWizardMode={SetupWizardMode.Only}" }, null, default); // This is where the wizard actually runs - - // TGS6 DOWNLOAD AND UNZIP - Console.WriteLine("Downloading TGS6..."); - - using (var loggerFactory = LoggerFactory.Create(builder => { })) - { - BufferedFileStreamProvider tgsFiveZipBuffer; - { - var fileDownloader = new FileDownloader(httpClientFactory, loggerFactory.CreateLogger()); - await using var tgsFiveZipDownload = fileDownloader.DownloadFile(new Uri(serverServiceAsset.BrowserDownloadUrl), null); - tgsFiveZipBuffer = new BufferedFileStreamProvider( - await tgsFiveZipDownload.GetResult(default)); - } - - await using (tgsFiveZipBuffer) - { - Console.WriteLine("Unzipping TGS6..."); - await serverFactory.IOManager.ZipToDirectory( - tgsInstallPath, - await tgsFiveZipBuffer.GetResult(default), - default); - } - } - - // TGS6 CONFIG SETUP - const string ConfigurationFileName = "appsettings.Production.yml"; - Console.WriteLine("Extracting API port from configuration..."); - ushort configuredApiPort; - { - var configFileContents = await File.ReadAllTextAsync(ConfigurationFileName); - var match = Regex.Match(configFileContents, "ApiPort: ([0-9]+)"); - if (!match.Success) - { - Console.WriteLine("Unable to extract ApiPort setting!"); - ExitPause(12); - } - - configuredApiPort = ushort.Parse(match.Groups[1].Value); - } - - Console.WriteLine("Moving configuration file from setup wizard to installation folder..."); - File.Copy(ConfigurationFileName, Path.Combine(tgsInstallPath, ConfigurationFileName)); - - // TGS6 SERVICE SETUP - Console.WriteLine("Installing TGS6 service..."); - using (var processInstaller = new ServiceProcessInstaller()) - using (var installer = new ServiceInstaller()) - { - processInstaller.Account = ServiceAccount.LocalSystem; - - installer.Context = new InstallContext( - "tgs-migrate-install.log", - new string[] - { - $"assemblypath={Path.Combine(tgsInstallPath, "Tgstation.Server.Host.Service.exe")}" - }); - installer.Description = "/tg/station 13 server running as a windows service"; - installer.DisplayName = "tgstation-server"; - installer.StartType = ServiceStartMode.Automatic; - installer.ServicesDependedOn = new string[] { "Tcpip", "Dhcp", "Dnscache" }; - installer.ServiceName = NewServiceName; - installer.Parent = processInstaller; - - var state = new ListDictionary(); - installer.Install(state); - } - - Console.WriteLine("Starting TGS6 service..."); - var allServices = ServiceController.GetServices(); - using (var TGS6Service = allServices.FirstOrDefault(service => service.ServiceName == NewServiceName)) - { - if (TGS6Service == null) - { - Console.WriteLine("Unable to locate newly installed TGS6 service!"); - ExitPause(11); - } - - foreach (var service in allServices) - { - if (service == TGS6Service) - continue; - - service.Dispose(); - } - - TGS6Service.Start(); - TGS6Service.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromMinutes(2)); - } - - // TGS6 CLIENT CONNECTION - const int MaxWaitMinutes = 5; - Console.WriteLine($"Connecting to TGS6 (Max {MaxWaitMinutes} minute wait)..."); - var giveUpAt = DateTimeOffset.UtcNow.AddMinutes(MaxWaitMinutes); - - var serverUrl = new Uri($"http://localhost:{configuredApiPort}"); - var clientFactory = new RestServerClientFactory(productInfoHeaderValue.Product); - IRestServerClient TGS6Client; - for (var I = 1; ; ++I) - { - try - { - Console.WriteLine($"Attempt {I}..."); - TGS6Client = await clientFactory.CreateFromLogin( - serverUrl, - DefaultCredentials.AdminUserName, - DefaultCredentials.DefaultAdminUserPassword); - break; - } - catch (HttpRequestException) - { - //migrating, to be expected - if (DateTimeOffset.UtcNow > giveUpAt) - throw; - await Task.Delay(TimeSpan.FromSeconds(1)); - } - catch (ServiceUnavailableException) - { - // migrating, to be expected - if (DateTimeOffset.UtcNow > giveUpAt) - throw; - await Task.Delay(TimeSpan.FromSeconds(1)); - } - } - - Console.WriteLine("Successfully connected to TGS6!"); - - // COMMS MIGRATION - Console.WriteLine("Deferring to Comms binary to migrate instances..."); - - commsExitCode = RunComms($"--migrate {configuredApiPort}"); - if (commsExitCode != 0) - { - Console.WriteLine("Could not connect to TGS3 as administrator!"); - ExitPause(commsExitCode); - } - - // TGS3 SHUTDOWN - Console.WriteLine("Shutting down TGS3 service..."); - tgs3Service.Stop(); - tgs3Service.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromMinutes(2)); - tgs3Service.Dispose(); - - Console.WriteLine("Disabling TGS3 service..."); - using (var managementObject = new ManagementObject(string.Format("Win32_Service.Name=\"{0}\"", OldServiceName))) - { - managementObject.InvokeMethod("ChangeStartMode", new object[] { "Disabled" }); - } - - if(tgs3Service.StartType != ServiceStartMode.Disabled) - Console.WriteLine("Failed to disable TGS3 service! This isn't critical, however."); - - Console.WriteLine("Migration complete! Please continue uninstall TGS3 using Add/Remove Programs."); - Console.WriteLine("Then configure TGS6 using an interactive client to build and start your server."); - ExitPause(0); -} -catch (Exception ex) -{ - Console.WriteLine("An error occurred in the migration!"); - Console.WriteLine(ex); - ExitPause(1); -} diff --git a/tools/Tgstation.Server.Migrator/Properties/RuntimeDistributableAttribute.cs b/tools/Tgstation.Server.Migrator/Properties/RuntimeDistributableAttribute.cs deleted file mode 100644 index d4434c61bb6..00000000000 --- a/tools/Tgstation.Server.Migrator/Properties/RuntimeDistributableAttribute.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Reflection; - -namespace Tgstation.Server.Migrator.Properties -{ - /// - /// Attribute for bringing in the runtime redistributable download link - /// - [AttributeUsage(AttributeTargets.Assembly)] - sealed class RuntimeDistributableAttribute : Attribute - { - /// - /// Return the 's instance of the . - /// - public static RuntimeDistributableAttribute Instance => Assembly - .GetExecutingAssembly() - .GetCustomAttribute()!; - - /// - /// The of the current runtime distributable. - /// - public Uri RuntimeDistributableUrl { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The value of . - public RuntimeDistributableAttribute( - string runtimeDistributableUrl) - { - RuntimeDistributableUrl = new Uri(runtimeDistributableUrl ?? throw new ArgumentNullException(nameof(runtimeDistributableUrl))); - } - } -} diff --git a/tools/Tgstation.Server.Migrator/Tgstation.Server.Migrator.csproj b/tools/Tgstation.Server.Migrator/Tgstation.Server.Migrator.csproj deleted file mode 100644 index b1f6920d3fb..00000000000 --- a/tools/Tgstation.Server.Migrator/Tgstation.Server.Migrator.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - - Exe - $(TgsFrameworkVersion) - win-x86 - true - $(TgsMigratorVersion) - enable - CA1416 - false - - - - - - - - - - - <_Parameter1>$(TgsDotnetRedistUrl) - - - - - - - - - - - - - -