From 4ab9a2a7d9c03c754928f13f1c2664b36df91aab Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 29 May 2020 09:26:17 -0400 Subject: [PATCH 01/17] Re-enable PostgresSQL - Update nuget package to 3.1.4 --- .travis.yml | 42 +++++++++---------- .../Database/PostgresSqlDatabaseContext.cs | 4 -- .../Setup/SetupWizard.cs | 6 +-- .../Tgstation.Server.Host.csproj | 2 +- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/.travis.yml b/.travis.yml index b5de2be669..7bad55861f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,27 +51,27 @@ jobs: packages: - libc6-i386 - libstdc++6:i386 -# - env: -# - DoxGeneration=false -# - DockerBuild=false -# - DMAPI=false -# - CONFIG=Release -# - TGS4_TEST_DATABASE_TYPE=PostgresSql -# - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" -# name: "PostgresSql Integration Test" -# language: csharp -# mono: none -# dotnet: 3.1 -# services: -# - postgresql -# cache: -# directories: -# - $HOME/.nuget/packages: -# addons: -# apt: -# packages: -# - libc6-i386 -# - libstdc++6:i386 + - env: + - DoxGeneration=false + - DockerBuild=false + - DMAPI=false + - CONFIG=Release + - TGS4_TEST_DATABASE_TYPE=PostgresSql + - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" + name: "PostgresSql Integration Test" + language: csharp + mono: none + dotnet: 3.1 + services: + - postgresql + cache: + directories: + - $HOME/.nuget/packages: + addons: + apt: + packages: + - libc6-i386 + - libstdc++6:i386 - env: - DoxGeneration=false - DockerBuild=false diff --git a/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs b/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs index 111f3918ed..bac19c1165 100644 --- a/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs +++ b/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs @@ -2,7 +2,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; -using System.Diagnostics; using Tgstation.Server.Host.Configuration; namespace Tgstation.Server.Host.Database @@ -37,9 +36,6 @@ namespace Tgstation.Server.Host.Database /// protected override void ValidateDatabaseType() { - if (!Debugger.IsAttached) - throw new NotImplementedException("PostgresSQL implementation is not complete yet!"); - if (DatabaseType != DatabaseType.PostgresSql) throw new InvalidOperationException("Invalid DatabaseType for PostgresSqlDatabaseContext!"); } diff --git a/src/Tgstation.Server.Host/Setup/SetupWizard.cs b/src/Tgstation.Server.Host/Setup/SetupWizard.cs index 9e54ac8f00..ad4a38e492 100644 --- a/src/Tgstation.Server.Host/Setup/SetupWizard.cs +++ b/src/Tgstation.Server.Host/Setup/SetupWizard.cs @@ -319,13 +319,11 @@ namespace Tgstation.Server.Host.Setup await console.WriteAsync( String.Format( CultureInfo.InvariantCulture, - "Please enter one of {0}, {1}, {2}, or {3}: ", + "Please enter one of {0}, {1}, {2}, {3} or {4}: ", DatabaseType.MariaDB, DatabaseType.MySql, -#pragma warning disable SA1515 // Single-line comment should be preceded by blank line - // DatabaseType.PostgresSql, + DatabaseType.PostgresSql, DatabaseType.SqlServer, -#pragma warning restore SA1515 // Single-line comment should be preceded by blank line DatabaseType.Sqlite), false, cancellationToken) diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj index 4382558c26..35ad0a92ef 100644 --- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj +++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj @@ -67,7 +67,7 @@ - + From 8383f21524ce52421228928c0e0fad46a7075f09 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 29 May 2020 09:40:37 -0400 Subject: [PATCH 02/17] Version bump to 4.3.1 --- build/Version.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Version.props b/build/Version.props index bda24b2315..c032b61ed9 100644 --- a/build/Version.props +++ b/build/Version.props @@ -2,7 +2,7 @@ - 4.3.0 + 4.3.1 6.5.0 7.1.0 5.2.2 From 179cd394687f1affed09e43b6af293001c0c8e24 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 29 May 2020 10:31:42 -0400 Subject: [PATCH 03/17] Assert Inconclusive on update test --- tests/Tgstation.Server.Tests/IntegrationTest.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Tgstation.Server.Tests/IntegrationTest.cs b/tests/Tgstation.Server.Tests/IntegrationTest.cs index aeff0bfffa..bc00450368 100644 --- a/tests/Tgstation.Server.Tests/IntegrationTest.cs +++ b/tests/Tgstation.Server.Tests/IntegrationTest.cs @@ -91,6 +91,10 @@ namespace Tgstation.Server.Tests await serverTask.ConfigureAwait(false); } catch (OperationCanceledException) { } + catch (NotSupportedException ex) + { + Assert.Inconclusive(ex.Message); + } } Assert.IsTrue(server.RestartRequested, "Server not requesting restart!"); } From a12a5dbeffebecdf6c65873d479b1fe747d6accf Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 29 May 2020 10:39:39 -0400 Subject: [PATCH 04/17] Fix a typo in an error code --- build/Version.props | 4 ++-- src/Tgstation.Server.Api/Models/ErrorCode.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/Version.props b/build/Version.props index c032b61ed9..264b6860ac 100644 --- a/build/Version.props +++ b/build/Version.props @@ -3,8 +3,8 @@ 4.3.1 - 6.5.0 - 7.1.0 + 6.5.1 + 7.1.1 5.2.2 0.4.0 1.1.0 diff --git a/src/Tgstation.Server.Api/Models/ErrorCode.cs b/src/Tgstation.Server.Api/Models/ErrorCode.cs index 1f8141301d..c62e41d04a 100644 --- a/src/Tgstation.Server.Api/Models/ErrorCode.cs +++ b/src/Tgstation.Server.Api/Models/ErrorCode.cs @@ -325,7 +325,7 @@ namespace Tgstation.Server.Api.Models /// /// The DMAPI never validated itself /// - [Description("DreamDaemon exited without validating the DMAPI@")] + [Description("DreamDaemon exited without validating the DMAPI!")] DreamMakerNeverValidated, /// From 82060a1ade317131e4b69f50ef56ab3d60e0c8cb Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 29 May 2020 12:44:42 -0400 Subject: [PATCH 05/17] Minor code cleanup --- src/Tgstation.Server.Host/Models/Instance.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tgstation.Server.Host/Models/Instance.cs b/src/Tgstation.Server.Host/Models/Instance.cs index c272b00324..0356bf0f2e 100644 --- a/src/Tgstation.Server.Host/Models/Instance.cs +++ b/src/Tgstation.Server.Host/Models/Instance.cs @@ -28,7 +28,7 @@ namespace Tgstation.Server.Host.Models public RepositorySettings RepositorySettings { get; set; } /// - /// The for the + /// The for the /// public DualReattachInformation WatchdogReattachInformation { get; set; } @@ -48,7 +48,7 @@ namespace Tgstation.Server.Host.Models public List RevisionInformations { get; set; } /// - /// The in the + /// The s in the /// public List Jobs { get; set; } From 3220d2aeec9584a7f72bfdd36a45ee624c125bae Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 29 May 2020 12:47:57 -0400 Subject: [PATCH 06/17] Fix Postgres Update test again --- tests/Tgstation.Server.Tests/IntegrationTest.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Tgstation.Server.Tests/IntegrationTest.cs b/tests/Tgstation.Server.Tests/IntegrationTest.cs index bc00450368..eeb4562a50 100644 --- a/tests/Tgstation.Server.Tests/IntegrationTest.cs +++ b/tests/Tgstation.Server.Tests/IntegrationTest.cs @@ -91,9 +91,10 @@ namespace Tgstation.Server.Tests await serverTask.ConfigureAwait(false); } catch (OperationCanceledException) { } - catch (NotSupportedException ex) + catch (AggregateException ex) { - Assert.Inconclusive(ex.Message); + if (ex.InnerException is NotSupportedException notSupportedException) + Assert.Inconclusive(notSupportedException.Message); } } Assert.IsTrue(server.RestartRequested, "Server not requesting restart!"); From b2d90239d98fadabda598e184087e75100622664 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Fri, 29 May 2020 13:28:56 -0400 Subject: [PATCH 07/17] Update the migrations to handle issues with FK_RevisionInformations_CompileJobs - Only on Postgres and MySql, others seem to work fine. --- .../Database/DatabaseContext.cs | 8 +- .../20200516111712_PGCreate.Designer.cs | 2 +- .../Migrations/20200516111712_PGCreate.cs | 3 +- ...20200529171541_MYFixForeignKey.Designer.cs | 808 ++++++++++++++++++ .../20200529171541_MYFixForeignKey.cs | 48 ++ .../MySqlDatabaseContextModelSnapshot.cs | 98 +-- ...PostgresSqlDatabaseContextModelSnapshot.cs | 2 +- .../Database/MySqlDatabaseContext.cs | 3 + .../Database/PostgresSqlDatabaseContext.cs | 3 + 9 files changed, 922 insertions(+), 53 deletions(-) create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200529171541_MYFixForeignKey.Designer.cs create mode 100644 src/Tgstation.Server.Host/Database/Migrations/20200529171541_MYFixForeignKey.cs diff --git a/src/Tgstation.Server.Host/Database/DatabaseContext.cs b/src/Tgstation.Server.Host/Database/DatabaseContext.cs index 10dddb039d..b75baf3e09 100644 --- a/src/Tgstation.Server.Host/Database/DatabaseContext.cs +++ b/src/Tgstation.Server.Host/Database/DatabaseContext.cs @@ -109,6 +109,11 @@ namespace Tgstation.Server.Host.Database /// protected DatabaseConfiguration DatabaseConfiguration { get; } + /// + /// The for the / foreign key. + /// + protected virtual DeleteBehavior RevInfoCompileJobDeleteBehavior => DeleteBehavior.ClientNoAction; + /// IDatabaseCollection IDatabaseContext.Users => usersCollection; @@ -271,7 +276,8 @@ namespace Tgstation.Server.Host.Database // rev info takes care of the rest // Break the link here so the db doesn't shit itself complaining about cascading deletes // EF will handle making the right query to destroy everything - revInfo.HasMany(x => x.CompileJobs).WithOne(x => x.RevisionInformation).OnDelete(DeleteBehavior.ClientNoAction); + // UPDATE: I fuck with this constantly in hopes of eliminating FK issues on instance detack + revInfo.HasMany(x => x.CompileJobs).WithOne(x => x.RevisionInformation).OnDelete(RevInfoCompileJobDeleteBehavior); // Also break the link between ritm and testmerge so it doesn't cycle in a triangle with rev info modelBuilder.Entity().HasMany(x => x.RevisonInformations).WithOne(x => x.TestMerge).OnDelete(DeleteBehavior.ClientNoAction); diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200516111712_PGCreate.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20200516111712_PGCreate.Designer.cs index 36d63b62c3..e2e75c64e2 100644 --- a/src/Tgstation.Server.Host/Database/Migrations/20200516111712_PGCreate.Designer.cs +++ b/src/Tgstation.Server.Host/Database/Migrations/20200516111712_PGCreate.Designer.cs @@ -674,7 +674,7 @@ namespace Tgstation.Server.Host.Database.Migrations b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") .WithMany("CompileJobs") .HasForeignKey("RevisionInformationId") - .OnDelete(DeleteBehavior.ClientNoAction) + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200516111712_PGCreate.cs b/src/Tgstation.Server.Host/Database/Migrations/20200516111712_PGCreate.cs index af77ee5d60..d76ef1939f 100644 --- a/src/Tgstation.Server.Host/Database/Migrations/20200516111712_PGCreate.cs +++ b/src/Tgstation.Server.Host/Database/Migrations/20200516111712_PGCreate.cs @@ -346,7 +346,8 @@ namespace Tgstation.Server.Host.Database.Migrations name: "FK_CompileJobs_RevisionInformations_RevisionInformationId", column: x => x.RevisionInformationId, principalTable: "RevisionInformations", - principalColumn: "Id"); + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateTable( diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200529171541_MYFixForeignKey.Designer.cs b/src/Tgstation.Server.Host/Database/Migrations/20200529171541_MYFixForeignKey.Designer.cs new file mode 100644 index 0000000000..9302a18764 --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200529171541_MYFixForeignKey.Designer.cs @@ -0,0 +1,808 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Tgstation.Server.Host.Database.Migrations +{ + [DbContext(typeof(MySqlDatabaseContext))] + [Migration("20200529171541_MYFixForeignKey")] + partial class MYFixForeignKey + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.4") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ChannelLimit") + .IsRequired() + .HasColumnType("smallint unsigned"); + + b.Property("ConnectionString") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("Provider") + .HasColumnType("int"); + + b.Property("ReconnectionInterval") + .IsRequired() + .HasColumnType("int unsigned"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "Name") + .IsUnique(); + + b.ToTable("ChatBots"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ChatSettingsId") + .HasColumnType("bigint"); + + b.Property("DiscordChannelId") + .HasColumnType("bigint unsigned"); + + b.Property("IrcChannel") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("IsAdminChannel") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("IsUpdatesChannel") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("IsWatchdogChannel") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("Tag") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.HasKey("Id"); + + b.HasIndex("ChatSettingsId", "DiscordChannelId") + .IsUnique(); + + b.HasIndex("ChatSettingsId", "IrcChannel") + .IsUnique(); + + b.ToTable("ChatChannels"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ByondVersion") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("DMApiMajorVersion") + .HasColumnType("int"); + + b.Property("DMApiMinorVersion") + .HasColumnType("int"); + + b.Property("DMApiPatchVersion") + .HasColumnType("int"); + + b.Property("DirectoryName") + .IsRequired() + .HasColumnType("char(36)"); + + b.Property("DmeName") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("JobId") + .HasColumnType("bigint"); + + b.Property("MinimumSecurityLevel") + .HasColumnType("int"); + + b.Property("Output") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("RevisionInformationId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("DirectoryName"); + + b.HasIndex("JobId") + .IsUnique(); + + b.HasIndex("RevisionInformationId"); + + b.ToTable("CompileJobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AllowWebClient") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("AutoStart") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("HeartbeatSeconds") + .IsRequired() + .HasColumnType("int unsigned"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("PrimaryPort") + .IsRequired() + .HasColumnType("smallint unsigned"); + + b.Property("SecondaryPort") + .IsRequired() + .HasColumnType("smallint unsigned"); + + b.Property("SecurityLevel") + .HasColumnType("int"); + + b.Property("StartupTimeout") + .IsRequired() + .HasColumnType("int unsigned"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamDaemonSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ApiValidationPort") + .IsRequired() + .HasColumnType("smallint unsigned"); + + b.Property("ApiValidationSecurityLevel") + .HasColumnType("int"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("ProjectName") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("DreamMakerSettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DualReattachInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AlphaId") + .HasColumnType("bigint"); + + b.Property("AlphaIsActive") + .HasColumnType("tinyint(1)"); + + b.Property("BravoId") + .HasColumnType("bigint"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AlphaId"); + + b.HasIndex("BravoId"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("WatchdogReattachInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AutoUpdateInterval") + .IsRequired() + .HasColumnType("int unsigned"); + + b.Property("ChatBotLimit") + .IsRequired() + .HasColumnType("smallint unsigned"); + + b.Property("ConfigurationType") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("Online") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("Path") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("Path") + .IsUnique(); + + b.ToTable("Instances"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("ByondRights") + .HasColumnType("bigint unsigned"); + + b.Property("ChatBotRights") + .HasColumnType("bigint unsigned"); + + b.Property("ConfigurationRights") + .HasColumnType("bigint unsigned"); + + b.Property("DreamDaemonRights") + .HasColumnType("bigint unsigned"); + + b.Property("DreamMakerRights") + .HasColumnType("bigint unsigned"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("InstanceUserRights") + .HasColumnType("bigint unsigned"); + + b.Property("RepositoryRights") + .HasColumnType("bigint unsigned"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId"); + + b.HasIndex("UserId", "InstanceId") + .IsUnique(); + + b.ToTable("InstanceUsers"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CancelRight") + .HasColumnType("bigint unsigned"); + + b.Property("CancelRightsType") + .HasColumnType("bigint unsigned"); + + b.Property("Cancelled") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("CancelledById") + .HasColumnType("bigint"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ErrorCode") + .HasColumnType("int unsigned"); + + b.Property("ExceptionDetails") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("StartedAt") + .IsRequired() + .HasColumnType("datetime(6)"); + + b.Property("StartedById") + .HasColumnType("bigint"); + + b.Property("StoppedAt") + .HasColumnType("datetime(6)"); + + b.HasKey("Id"); + + b.HasIndex("CancelledById"); + + b.HasIndex("InstanceId"); + + b.HasIndex("StartedById"); + + b.ToTable("Jobs"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AccessIdentifier") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CompileJobId") + .HasColumnType("bigint"); + + b.Property("IsPrimary") + .HasColumnType("tinyint(1)"); + + b.Property("LaunchSecurityLevel") + .HasColumnType("int"); + + b.Property("Port") + .HasColumnType("smallint unsigned"); + + b.Property("ProcessId") + .HasColumnType("int"); + + b.Property("RebootState") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CompileJobId"); + + b.ToTable("ReattachInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AccessToken") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("AccessUser") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("AutoUpdatesKeepTestMerges") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("AutoUpdatesSynchronize") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("CommitterEmail") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("CommitterName") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("PostTestMergeComment") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("PushTestMergeCommits") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("ShowTestMergeCommitters") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("RepositorySettings"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("RevisionInformationId") + .HasColumnType("bigint"); + + b.Property("TestMergeId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("RevisionInformationId"); + + b.HasIndex("TestMergeId"); + + b.ToTable("RevInfoTestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("CommitSha") + .IsRequired() + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.Property("OriginCommitSha") + .IsRequired() + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.HasKey("Id"); + + b.HasIndex("InstanceId", "CommitSha") + .IsUnique(); + + b.ToTable("RevisionInformations"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("Author") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("BodyAtMerge") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Comment") + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("MergedAt") + .HasColumnType("datetime(6)"); + + b.Property("MergedById") + .HasColumnType("bigint"); + + b.Property("Number") + .HasColumnType("int"); + + b.Property("PrimaryRevisionInformationId") + .IsRequired() + .HasColumnType("bigint"); + + b.Property("PullRequestRevision") + .IsRequired() + .HasColumnType("varchar(40) CHARACTER SET utf8mb4") + .HasMaxLength(40); + + b.Property("TitleAtMerge") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Url") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("MergedById"); + + b.HasIndex("PrimaryRevisionInformationId") + .IsUnique(); + + b.ToTable("TestMerges"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AdministrationRights") + .HasColumnType("bigint unsigned"); + + b.Property("CanonicalName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("CreatedAt") + .IsRequired() + .HasColumnType("datetime(6)"); + + b.Property("CreatedById") + .HasColumnType("bigint"); + + b.Property("Enabled") + .IsRequired() + .HasColumnType("tinyint(1)"); + + b.Property("InstanceManagerRights") + .HasColumnType("bigint unsigned"); + + b.Property("LastPasswordUpdate") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext CHARACTER SET utf8mb4") + .HasMaxLength(10000); + + b.Property("PasswordHash") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("SystemIdentifier") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("CanonicalName") + .IsUnique(); + + b.HasIndex("CreatedById"); + + b.HasIndex("SystemIdentifier") + .IsUnique(); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("ChatSettings") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ChatChannel", b => + { + b.HasOne("Tgstation.Server.Host.Models.ChatBot", "ChatSettings") + .WithMany("Channels") + .HasForeignKey("ChatSettingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.CompileJob", b => + { + b.HasOne("Tgstation.Server.Host.Models.Job", "Job") + .WithOne() + .HasForeignKey("Tgstation.Server.Host.Models.CompileJob", "JobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("CompileJobs") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamDaemonSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamDaemonSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamDaemonSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DreamMakerSettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("DreamMakerSettings") + .HasForeignKey("Tgstation.Server.Host.Models.DreamMakerSettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.DualReattachInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Alpha") + .WithMany() + .HasForeignKey("AlphaId"); + + b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Bravo") + .WithMany() + .HasForeignKey("BravoId"); + + b.HasOne("Tgstation.Server.Host.Models.Instance", null) + .WithOne("WatchdogReattachInformation") + .HasForeignKey("Tgstation.Server.Host.Models.DualReattachInformation", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("InstanceUsers") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", null) + .WithMany("InstanceUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.Job", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CancelledBy") + .WithMany() + .HasForeignKey("CancelledById"); + + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("Jobs") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.User", "StartedBy") + .WithMany() + .HasForeignKey("StartedById") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.ReattachInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.CompileJob", "CompileJob") + .WithMany() + .HasForeignKey("CompileJobId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RepositorySettings", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithOne("RepositorySettings") + .HasForeignKey("Tgstation.Server.Host.Models.RepositorySettings", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevInfoTestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") + .WithMany("ActiveTestMerges") + .HasForeignKey("RevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.TestMerge", "TestMerge") + .WithMany("RevisonInformations") + .HasForeignKey("TestMergeId") + .OnDelete(DeleteBehavior.ClientNoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.RevisionInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") + .WithMany("RevisionInformations") + .HasForeignKey("InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.TestMerge", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "MergedBy") + .WithMany("TestMerges") + .HasForeignKey("MergedById") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "PrimaryRevisionInformation") + .WithOne("PrimaryTestMerge") + .HasForeignKey("Tgstation.Server.Host.Models.TestMerge", "PrimaryRevisionInformationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Tgstation.Server.Host.Models.User", b => + { + b.HasOne("Tgstation.Server.Host.Models.User", "CreatedBy") + .WithMany("CreatedUsers") + .HasForeignKey("CreatedById"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/20200529171541_MYFixForeignKey.cs b/src/Tgstation.Server.Host/Database/Migrations/20200529171541_MYFixForeignKey.cs new file mode 100644 index 0000000000..3f2e2c658f --- /dev/null +++ b/src/Tgstation.Server.Host/Database/Migrations/20200529171541_MYFixForeignKey.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; + +namespace Tgstation.Server.Host.Database.Migrations +{ + /// + /// Fix the CompileJob/RevisionInformation foreign key for MySQL. + /// + public partial class MYFixForeignKey : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.DropForeignKey( + name: "FK_CompileJobs_RevisionInformations_RevisionInformationId", + table: "CompileJobs"); + + migrationBuilder.AddForeignKey( + name: "FK_CompileJobs_RevisionInformations_RevisionInformationId", + table: "CompileJobs", + column: "RevisionInformationId", + principalTable: "RevisionInformations", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + if (migrationBuilder == null) + throw new ArgumentNullException(nameof(migrationBuilder)); + + migrationBuilder.DropForeignKey( + name: "FK_CompileJobs_RevisionInformations_RevisionInformationId", + table: "CompileJobs"); + + migrationBuilder.AddForeignKey( + name: "FK_CompileJobs_RevisionInformations_RevisionInformationId", + table: "CompileJobs", + column: "RevisionInformationId", + principalTable: "RevisionInformations", + principalColumn: "Id"); + } + } +} diff --git a/src/Tgstation.Server.Host/Database/Migrations/MySqlDatabaseContextModelSnapshot.cs b/src/Tgstation.Server.Host/Database/Migrations/MySqlDatabaseContextModelSnapshot.cs index 27515b7376..d098601eed 100644 --- a/src/Tgstation.Server.Host/Database/Migrations/MySqlDatabaseContextModelSnapshot.cs +++ b/src/Tgstation.Server.Host/Database/Migrations/MySqlDatabaseContextModelSnapshot.cs @@ -12,7 +12,7 @@ namespace Tgstation.Server.Host.Database.Migrations { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.3") + .HasAnnotation("ProductVersion", "3.1.4") .HasAnnotation("Relational:MaxIdentifierLength", 64); modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => @@ -223,6 +223,36 @@ namespace Tgstation.Server.Host.Database.Migrations b.ToTable("DreamMakerSettings"); }); + modelBuilder.Entity("Tgstation.Server.Host.Models.DualReattachInformation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + b.Property("AlphaId") + .HasColumnType("bigint"); + + b.Property("AlphaIsActive") + .HasColumnType("tinyint(1)"); + + b.Property("BravoId") + .HasColumnType("bigint"); + + b.Property("InstanceId") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AlphaId"); + + b.HasIndex("BravoId"); + + b.HasIndex("InstanceId") + .IsUnique(); + + b.ToTable("WatchdogReattachInformations"); + }); + modelBuilder.Entity("Tgstation.Server.Host.Models.Instance", b => { b.Property("Id") @@ -604,36 +634,6 @@ namespace Tgstation.Server.Host.Database.Migrations b.ToTable("Users"); }); - modelBuilder.Entity("Tgstation.Server.Host.Models.WatchdogReattachInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AlphaId") - .HasColumnType("bigint"); - - b.Property("AlphaIsActive") - .HasColumnType("tinyint(1)"); - - b.Property("BravoId") - .HasColumnType("bigint"); - - b.Property("InstanceId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("AlphaId"); - - b.HasIndex("BravoId"); - - b.HasIndex("InstanceId") - .IsUnique(); - - b.ToTable("WatchdogReattachInformations"); - }); - modelBuilder.Entity("Tgstation.Server.Host.Models.ChatBot", b => { b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") @@ -663,7 +663,7 @@ namespace Tgstation.Server.Host.Database.Migrations b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") .WithMany("CompileJobs") .HasForeignKey("RevisionInformationId") - .OnDelete(DeleteBehavior.ClientNoAction) + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); @@ -685,6 +685,23 @@ namespace Tgstation.Server.Host.Database.Migrations .IsRequired(); }); + modelBuilder.Entity("Tgstation.Server.Host.Models.DualReattachInformation", b => + { + b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Alpha") + .WithMany() + .HasForeignKey("AlphaId"); + + b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Bravo") + .WithMany() + .HasForeignKey("BravoId"); + + b.HasOne("Tgstation.Server.Host.Models.Instance", null) + .WithOne("WatchdogReattachInformation") + .HasForeignKey("Tgstation.Server.Host.Models.DualReattachInformation", "InstanceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Tgstation.Server.Host.Models.InstanceUser", b => { b.HasOne("Tgstation.Server.Host.Models.Instance", "Instance") @@ -782,23 +799,6 @@ namespace Tgstation.Server.Host.Database.Migrations .WithMany("CreatedUsers") .HasForeignKey("CreatedById"); }); - - modelBuilder.Entity("Tgstation.Server.Host.Models.WatchdogReattachInformation", b => - { - b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Alpha") - .WithMany() - .HasForeignKey("AlphaId"); - - b.HasOne("Tgstation.Server.Host.Models.ReattachInformation", "Bravo") - .WithMany() - .HasForeignKey("BravoId"); - - b.HasOne("Tgstation.Server.Host.Models.Instance", null) - .WithOne("WatchdogReattachInformation") - .HasForeignKey("Tgstation.Server.Host.Models.WatchdogReattachInformation", "InstanceId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); #pragma warning restore 612, 618 } } diff --git a/src/Tgstation.Server.Host/Database/Migrations/PostgresSqlDatabaseContextModelSnapshot.cs b/src/Tgstation.Server.Host/Database/Migrations/PostgresSqlDatabaseContextModelSnapshot.cs index fd44242293..1cf3d0ce67 100644 --- a/src/Tgstation.Server.Host/Database/Migrations/PostgresSqlDatabaseContextModelSnapshot.cs +++ b/src/Tgstation.Server.Host/Database/Migrations/PostgresSqlDatabaseContextModelSnapshot.cs @@ -672,7 +672,7 @@ namespace Tgstation.Server.Host.Migrations b.HasOne("Tgstation.Server.Host.Models.RevisionInformation", "RevisionInformation") .WithMany("CompileJobs") .HasForeignKey("RevisionInformationId") - .OnDelete(DeleteBehavior.ClientNoAction) + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); }); diff --git a/src/Tgstation.Server.Host/Database/MySqlDatabaseContext.cs b/src/Tgstation.Server.Host/Database/MySqlDatabaseContext.cs index c18d4e723e..3bd351dd00 100644 --- a/src/Tgstation.Server.Host/Database/MySqlDatabaseContext.cs +++ b/src/Tgstation.Server.Host/Database/MySqlDatabaseContext.cs @@ -13,6 +13,9 @@ namespace Tgstation.Server.Host.Database /// sealed class MySqlDatabaseContext : DatabaseContext { + /// + protected override DeleteBehavior RevInfoCompileJobDeleteBehavior => DeleteBehavior.Cascade; + /// /// Construct a /// diff --git a/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs b/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs index bac19c1165..1f5d77b803 100644 --- a/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs +++ b/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs @@ -11,6 +11,9 @@ namespace Tgstation.Server.Host.Database /// sealed class PostgresSqlDatabaseContext : DatabaseContext { + /// + protected override DeleteBehavior RevInfoCompileJobDeleteBehavior => DeleteBehavior.Cascade; + /// /// Construct a /// From 1a205d67f4a725c4317e868ef64df195162b79b9 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 11:27:08 -0400 Subject: [PATCH 08/17] Add Postgres version specification --- README.md | 2 +- .../Configuration/DatabaseConfiguration.cs | 4 ++-- .../Database/MySqlDatabaseContext.cs | 4 ++-- .../Database/PostgresSqlDatabaseContext.cs | 9 ++++++++- src/Tgstation.Server.Host/Setup/SetupWizard.cs | 18 ++++++++++++++---- src/Tgstation.Server.Host/appsettings.json | 2 +- 6 files changed, 28 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index cd2898ed40..16bf6e737d 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ Create an `appsettings.Production.json` file next to `appsettings.json`. This wi - `Database:DatabaseType`: Can be one of `SqlServer`, `MariaDB`, `MySql`, or `Sqlite`. -- `Database:MySqlServerVersion`: The version of MySql/MariaDB the database resides on, can be left as null for attempted auto detection. Used by the MySQL/MariaDB provider for selection of [certain features](https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/blob/2.2.6/src/EFCore.MySql/Storage/Internal/ServerVersion.cs) ignore at your own risk. A string in the form `..` +- `Database:ServerVersion`: The version of the database server. Used by the MySQL/MariaDB and Postgres providers for selection of certain features, ignore at your own risk. A string in the form `..` for MySQL/MariaDB or `.` for Postgres. - `Database:ConnectionString`: Connection string for your database. Click [here](https://www.developerfusion.com/tools/sql-connection-string/) for an SQL Server generator or see [here](https://www.connectionstrings.com/mysql/) for a MySQL guide ([You should probably use '127.0.0.1' instead of 'localhost'](https://stackoverflow.com/questions/19712307/mysql-localhost-127-0-0-1)). diff --git a/src/Tgstation.Server.Host/Configuration/DatabaseConfiguration.cs b/src/Tgstation.Server.Host/Configuration/DatabaseConfiguration.cs index abe1a6d5df..92fd68237d 100644 --- a/src/Tgstation.Server.Host/Configuration/DatabaseConfiguration.cs +++ b/src/Tgstation.Server.Host/Configuration/DatabaseConfiguration.cs @@ -40,8 +40,8 @@ namespace Tgstation.Server.Host.Configuration public bool DesignTime { get; set; } /// - /// The form of the of a target MySQL/MariaDB server + /// The form of the of the target server /// - public string MySqlServerVersion { get; set; } + public string ServerVersion { get; set; } } } diff --git a/src/Tgstation.Server.Host/Database/MySqlDatabaseContext.cs b/src/Tgstation.Server.Host/Database/MySqlDatabaseContext.cs index 3bd351dd00..78e936352c 100644 --- a/src/Tgstation.Server.Host/Database/MySqlDatabaseContext.cs +++ b/src/Tgstation.Server.Host/Database/MySqlDatabaseContext.cs @@ -42,9 +42,9 @@ namespace Tgstation.Server.Host.Database { mySqlOptions.EnableRetryOnFailure(); - if (!String.IsNullOrEmpty(DatabaseConfiguration.MySqlServerVersion)) + if (!String.IsNullOrEmpty(DatabaseConfiguration.ServerVersion)) mySqlOptions.ServerVersion( - Version.Parse(DatabaseConfiguration.MySqlServerVersion), + Version.Parse(DatabaseConfiguration.ServerVersion), DatabaseConfiguration.DatabaseType == DatabaseType.MariaDB ? ServerType.MariaDb : ServerType.MySql); diff --git a/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs b/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs index 1f5d77b803..6514bc5333 100644 --- a/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs +++ b/src/Tgstation.Server.Host/Database/PostgresSqlDatabaseContext.cs @@ -33,7 +33,14 @@ namespace Tgstation.Server.Host.Database protected override void OnConfiguring(DbContextOptionsBuilder options) { base.OnConfiguring(options); - options.UseNpgsql(DatabaseConfiguration.ConnectionString, x => x.EnableRetryOnFailure()); + options.UseNpgsql(DatabaseConfiguration.ConnectionString, options => + { + options.EnableRetryOnFailure(); + + if (!String.IsNullOrEmpty(DatabaseConfiguration.ServerVersion)) + options.SetPostgresVersion( + Version.Parse(DatabaseConfiguration.ServerVersion)); + }); } /// diff --git a/src/Tgstation.Server.Host/Setup/SetupWizard.cs b/src/Tgstation.Server.Host/Setup/SetupWizard.cs index ad4a38e492..89c0a2eacb 100644 --- a/src/Tgstation.Server.Host/Setup/SetupWizard.cs +++ b/src/Tgstation.Server.Host/Setup/SetupWizard.cs @@ -180,15 +180,25 @@ namespace Tgstation.Server.Host.Setup await console.WriteAsync("Connection successful!", true, cancellationToken).ConfigureAwait(false); if (databaseConfiguration.DatabaseType == DatabaseType.MariaDB - || databaseConfiguration.DatabaseType == DatabaseType.MySql) + || databaseConfiguration.DatabaseType == DatabaseType.MySql + || databaseConfiguration.DatabaseType == DatabaseType.PostgresSql) { - await console.WriteAsync("Checking MySQL/MariaDB version...", true, cancellationToken).ConfigureAwait(false); + await console.WriteAsync($"Checking {databaseConfiguration.DatabaseType} version...", true, cancellationToken).ConfigureAwait(false); using var command = testConnection.CreateCommand(); command.CommandText = "SELECT VERSION()"; var fullVersion = (string)await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false); await console.WriteAsync(String.Format(CultureInfo.InvariantCulture, "Found {0}", fullVersion), true, cancellationToken).ConfigureAwait(false); - var splits = fullVersion.Split('-'); - databaseConfiguration.MySqlServerVersion = splits.First(); + + if (databaseConfiguration.DatabaseType == DatabaseType.PostgresSql) + { + var splits = fullVersion.Split(' '); + databaseConfiguration.ServerVersion = splits[1].TrimEnd(','); + } + else + { + var splits = fullVersion.Split('-'); + databaseConfiguration.ServerVersion = splits.First(); + } } if (!isSqliteDB && !dbExists) diff --git a/src/Tgstation.Server.Host/appsettings.json b/src/Tgstation.Server.Host/appsettings.json index 55786ab050..2a2d1c3b41 100644 --- a/src/Tgstation.Server.Host/appsettings.json +++ b/src/Tgstation.Server.Host/appsettings.json @@ -47,7 +47,7 @@ "DropDatabase": false, "DatabaseType": "SqlServer", "ResetAdminPassword": false, - "MySqlServerVersion": null, + "ServerVersion": null, "ConnectionString": "Data Source=(local);Initial Catalog=TGS;Integrated Security=True" } } From 8c42e6bce6534577dec2b43e9340259fb16646e9 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 11:28:08 -0400 Subject: [PATCH 09/17] Set postgres version for travis --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 7bad55861f..96d20ac5c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,6 +58,7 @@ jobs: - CONFIG=Release - TGS4_TEST_DATABASE_TYPE=PostgresSql - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" + - Database__ServerVersion="9.2" name: "PostgresSql Integration Test" language: csharp mono: none From 8860c3929288216414af9eb7f73da3c9433db8b3 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 11:29:15 -0400 Subject: [PATCH 10/17] It's 9.6 on xenial --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 96d20ac5c0..2c9906121c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,7 +58,7 @@ jobs: - CONFIG=Release - TGS4_TEST_DATABASE_TYPE=PostgresSql - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" - - Database__ServerVersion="9.2" + - Database__ServerVersion="9.6" name: "PostgresSql Integration Test" language: csharp mono: none From e129513d1c5d2b617cbecff68cecc5ca00a49f2c Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 13:54:11 -0400 Subject: [PATCH 11/17] Try 12 --- .travis.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c9906121c..a7e1c2c85e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,7 +58,6 @@ jobs: - CONFIG=Release - TGS4_TEST_DATABASE_TYPE=PostgresSql - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" - - Database__ServerVersion="9.6" name: "PostgresSql Integration Test" language: csharp mono: none @@ -67,12 +66,13 @@ jobs: - postgresql cache: directories: - - $HOME/.nuget/packages: - addons: - apt: - packages: - - libc6-i386 - - libstdc++6:i386 + - $HOME/.nuget/packages:addons: + postgresql: "12" + apt: + packages: + - postgresql-12 + - libc6-i386 + - libstdc++6:i386 - env: - DoxGeneration=false - DockerBuild=false From cc6262dde878ec25936dec5aab7baec8e47fc75e Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 14:06:28 -0400 Subject: [PATCH 12/17] Remove this? --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a7e1c2c85e..afc12c5ef0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,8 +62,6 @@ jobs: language: csharp mono: none dotnet: 3.1 - services: - - postgresql cache: directories: - $HOME/.nuget/packages:addons: From 963d914570721d65a54a2394ff20917e40be12b3 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 15:02:19 -0400 Subject: [PATCH 13/17] Fix postgres port --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index afc12c5ef0..08c4861b0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -57,7 +57,9 @@ jobs: - DMAPI=false - CONFIG=Release - TGS4_TEST_DATABASE_TYPE=PostgresSql - - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" + - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Port=5433;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" + global: + PGPORT=5433 name: "PostgresSql Integration Test" language: csharp mono: none From 4da1073409a623234a99661bff19ccb406a35a08 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 15:15:13 -0400 Subject: [PATCH 14/17] Fix shutdown timeout not being respected - Added more logging --- .../Components/Session/ReattachInfoHandler.cs | 7 +++---- src/Tgstation.Server.Host/Core/Application.cs | 6 +++++- src/Tgstation.Server.Host/ServerFactory.cs | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Tgstation.Server.Host/Components/Session/ReattachInfoHandler.cs b/src/Tgstation.Server.Host/Components/Session/ReattachInfoHandler.cs index 001f0a1087..b7d377ef8a 100644 --- a/src/Tgstation.Server.Host/Components/Session/ReattachInfoHandler.cs +++ b/src/Tgstation.Server.Host/Components/Session/ReattachInfoHandler.cs @@ -56,11 +56,12 @@ namespace Tgstation.Server.Host.Components.Session logger.LogDebug("Saving reattach information: {0}...", reattachInformation); - var deleteTask = db + await db .WatchdogReattachInformations .AsQueryable() .Where(x => x.InstanceId == metadata.Id) - .DeleteAsync(cancellationToken); + .DeleteAsync(cancellationToken) + .ConfigureAwait(false); Models.ReattachInformation ConvertReattachInfo(ReattachInformation wdInfo) { @@ -79,8 +80,6 @@ namespace Tgstation.Server.Host.Components.Session }; } - await deleteTask.ConfigureAwait(false); - db.WatchdogReattachInformations.Add(new Models.DualReattachInformation { Alpha = ConvertReattachInfo(reattachInformation.Alpha), diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs index edfddae43f..8bc5133bc8 100644 --- a/src/Tgstation.Server.Host/Core/Application.cs +++ b/src/Tgstation.Server.Host/Core/Application.cs @@ -354,7 +354,11 @@ namespace Tgstation.Server.Host.Core // attempt to restart the server if the configuration changes if (serverControl.WatchdogPresent) - ChangeToken.OnChange(Configuration.GetReloadToken, () => serverControl.Restart()); + ChangeToken.OnChange(Configuration.GetReloadToken, () => + { + logger.LogInformation("Configuration change detected"); + serverControl.Restart(); + }); // setup the HTTP request pipeline // Final point where we wrap exceptions in a 500 (ErrorMessage) response diff --git a/src/Tgstation.Server.Host/ServerFactory.cs b/src/Tgstation.Server.Host/ServerFactory.cs index 6bb31a8948..9be5679521 100644 --- a/src/Tgstation.Server.Host/ServerFactory.cs +++ b/src/Tgstation.Server.Host/ServerFactory.cs @@ -73,7 +73,7 @@ namespace Tgstation.Server.Host .UseIISIntegration() .UseApplication(postSetupServices) .SuppressStatusMessages(true) - .UseShutdownTimeout(TimeSpan.FromMinutes(1))); + .UseShutdownTimeout(TimeSpan.FromMilliseconds(postSetupServices.GeneralConfiguration.RestartTimeout))); if (updatePath != null) hostBuilder.UseContentRoot( From 45c9bd2c00344f1e94859e25b3fc73b767c3b129 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 15:17:24 -0400 Subject: [PATCH 15/17] Fix build --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 08c4861b0e..3abc6da6a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,21 +58,21 @@ jobs: - CONFIG=Release - TGS4_TEST_DATABASE_TYPE=PostgresSql - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Port=5433;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" - global: - PGPORT=5433 + - PGPORT=5433 name: "PostgresSql Integration Test" language: csharp mono: none dotnet: 3.1 cache: directories: - - $HOME/.nuget/packages:addons: - postgresql: "12" - apt: - packages: - - postgresql-12 - - libc6-i386 - - libstdc++6:i386 + - $HOME/.nuget/packages: + addons: + postgresql: "12" + apt: + packages: + - postgresql-12 + - libc6-i386 + - libstdc++6:i386 - env: - DoxGeneration=false - DockerBuild=false From 23e8a09f5a9067dd053f7a4e706977c10b2cffc8 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 16:47:45 -0400 Subject: [PATCH 16/17] Try this --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3abc6da6a3..65216b8e0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -55,6 +55,7 @@ jobs: - DoxGeneration=false - DockerBuild=false - DMAPI=false + - POSTGRESFIX=true - CONFIG=Release - TGS4_TEST_DATABASE_TYPE=PostgresSql - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Port=5433;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" @@ -128,6 +129,11 @@ jobs: - libc6-i386 - libstdc++6:i386 +before_install: + - if [ $POSTGRESFIX = true ]; then sudo sed -i -e '/local.*peer/s/postgres/all/' -e 's/peer\|md5/trust/g' /etc/postgresql/*/main/pg_hba.conf; fi + - if [ $POSTGRESFIX = true ]; then sudo service postgresql restart; fi + - if [ $POSTGRESFIX = true ]; then sleep 1; fi + install: - if [ $DoxGeneration = false ] && [ $DockerBuild = false ] && [ $DMAPI = true ]; then build/install_byond.sh; fi - if [ $DoxGeneration = false ] && [ $DockerBuild = false ] && [ $DMAPI = false ]; then dotnet restore tgstation-server.sln; fi From 447f00849a69461497a1cabc274936da7b3ce363 Mon Sep 17 00:00:00 2001 From: Jordan Brown Date: Mon, 8 Jun 2020 21:39:33 -0400 Subject: [PATCH 17/17] Try this --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 65216b8e0e..d5196bdd03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,7 +58,7 @@ jobs: - POSTGRESFIX=true - CONFIG=Release - TGS4_TEST_DATABASE_TYPE=PostgresSql - - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Port=5433;Host=127.0.0.1;Username=postgres;Password=;Database=TGS_Test" + - TGS4_TEST_CONNECTION_STRING="Application Name=tgstation-server;Port=5433;Host=127.0.0.1;Username=testuser;Password=password;Database=TGS_Test" - PGPORT=5433 name: "PostgresSql Integration Test" language: csharp @@ -130,9 +130,8 @@ jobs: - libstdc++6:i386 before_install: - - if [ $POSTGRESFIX = true ]; then sudo sed -i -e '/local.*peer/s/postgres/all/' -e 's/peer\|md5/trust/g' /etc/postgresql/*/main/pg_hba.conf; fi - - if [ $POSTGRESFIX = true ]; then sudo service postgresql restart; fi - - if [ $POSTGRESFIX = true ]; then sleep 1; fi + - if [ $POSTGRESFIX = true ]; then sudo -u postgres psql -c "CREATE USER testuser WITH PASSWORD 'password'"; fi + - if [ $POSTGRESFIX = true ]; then sudo -u postgres psql -c "ALTER ROLE testuser SUPERUSER"; fi install: - if [ $DoxGeneration = false ] && [ $DockerBuild = false ] && [ $DMAPI = true ]; then build/install_byond.sh; fi