From d4809686db2652ee09b983301747893d8be2c7da Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 18 Aug 2017 18:22:25 -0400 Subject: [PATCH] mssql image setup script, db up migrations with upgrade from setup --- src/Core/GlobalSettings.cs | 44 ++++++++++++++++++++++++++--- util/MsSql/.dockerignore | 1 + util/MsSql/Dockerfile | 2 ++ util/MsSql/entrypoint.sh | 2 +- util/MsSql/setup.sh | 4 +++ util/Setup/Dockerfile | 2 +- util/Setup/Helpers.cs | 28 ++++++++++++++++++ util/Setup/Program.cs | 58 +++++++++++++++++++++++++++++++++++--- util/Setup/Setup.csproj | 10 +++++++ 9 files changed, 141 insertions(+), 10 deletions(-) create mode 100644 util/MsSql/setup.sh diff --git a/src/Core/GlobalSettings.cs b/src/Core/GlobalSettings.cs index d89d8e5f61..194de26341 100644 --- a/src/Core/GlobalSettings.cs +++ b/src/Core/GlobalSettings.cs @@ -36,17 +36,44 @@ namespace Bit.Core public class SqlServerSettings { - public string ConnectionString { get; set; } + private string _connectionString; + + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value.Trim('"'); + } + } } public class StorageSettings { - public string ConnectionString { get; set; } + private string _connectionString; + + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value.Trim('"'); + } + } } public class AttachmentSettings { - public string ConnectionString { get; set; } + private string _connectionString; + + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value.Trim('"'); + } + } public string BaseDirectory { get; set; } public string BaseUrl { get; set; } } @@ -87,7 +114,16 @@ namespace Bit.Core public class NotificationHubSettings { - public string ConnectionString { get; set; } + private string _connectionString; + + public string ConnectionString + { + get => _connectionString; + set + { + _connectionString = value.Trim('"'); + } + } public string HubName { get; set; } } diff --git a/util/MsSql/.dockerignore b/util/MsSql/.dockerignore index 9dbc71be96..e46e7fae1c 100644 --- a/util/MsSql/.dockerignore +++ b/util/MsSql/.dockerignore @@ -1,3 +1,4 @@ * !entrypoint.sh !setup.sql +!setup.sh diff --git a/util/MsSql/Dockerfile b/util/MsSql/Dockerfile index d24112848a..aebc5f597b 100644 --- a/util/MsSql/Dockerfile +++ b/util/MsSql/Dockerfile @@ -1,6 +1,8 @@ FROM microsoft/mssql-server-linux COPY setup.sql / +COPY setup.sh / +RUN chmod +x /setup.sh COPY entrypoint.sh / RUN chmod +x /entrypoint.sh diff --git a/util/MsSql/entrypoint.sh b/util/MsSql/entrypoint.sh index a049275c73..31c85e404e 100644 --- a/util/MsSql/entrypoint.sh +++ b/util/MsSql/entrypoint.sh @@ -1,4 +1,4 @@ #!/bin/sh +/setup.sh & /opt/mssql/bin/sqlservr -/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P ${SA_PASSWORD} -i /setup.sql diff --git a/util/MsSql/setup.sh b/util/MsSql/setup.sh new file mode 100644 index 0000000000..447abfbf0a --- /dev/null +++ b/util/MsSql/setup.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +sleep 60s +/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P ${SA_PASSWORD} -i /setup.sql diff --git a/util/Setup/Dockerfile b/util/Setup/Dockerfile index 51cca202b4..48165c4aab 100644 --- a/util/Setup/Dockerfile +++ b/util/Setup/Dockerfile @@ -1,4 +1,4 @@ -FROM microsoft/dotnet:2.0.0-preview2-runtime +FROM microsoft/dotnet:2.0.0-runtime RUN apt-get update \ && apt-get install -y --no-install-recommends \ diff --git a/util/Setup/Helpers.cs b/util/Setup/Helpers.cs index 7e07acd093..211f4669b4 100644 --- a/util/Setup/Helpers.cs +++ b/util/Setup/Helpers.cs @@ -1,6 +1,8 @@ using System; +using System.IO; using System.Security.Cryptography; using System.Text; +using System.Threading.Tasks; namespace Setup { @@ -87,5 +89,31 @@ namespace Setup return characters; } + + public static string MakeSqlConnectionString(string server, string database, string username, string password) + { + return $"Server=tcp:{server},1433;Initial Catalog={database};Persist Security Info=False;User ID={username};" + + $"Password={password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;" + + "Connection Timeout=30;"; + } + + public static string GetDatabasePasswordFronEnvFile() + { + if(!File.Exists("/bitwarden/docker/mssql.override.env")) + { + return null; + } + + var lines = File.ReadAllLines("/bitwarden/docker/mssql.override.env"); + foreach(var line in lines) + { + if(line.StartsWith("SA_PASSWORD=")) + { + return line.Split(new char[] { '=' }, 2)[1]; + } + } + + return null; + } } } diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index 3e423e59bf..e0cb3d2144 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -1,7 +1,9 @@ -using System; +using DbUp; +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.Reflection; using System.Runtime.InteropServices; namespace Setup @@ -25,7 +27,22 @@ namespace Setup { _args = args; _parameters = ParseParameters(); + if(_parameters.ContainsKey("install")) + { + Install(); + } + else if(_parameters.ContainsKey("update")) + { + Update(); + } + else + { + Console.WriteLine("No top-level command detected. Exiting..."); + } + } + private static void Install() + { _installationId = _parameters.ContainsKey("install_id") ? _parameters["install_id"].ToLowerInvariant() : null; _installationKey = _parameters.ContainsKey("install_key") ? @@ -65,6 +82,41 @@ namespace Setup BuildAppSettingsFiles(); } + private static void Update() + { + if(_parameters.ContainsKey("db")) + { + MigrateDatabase(); + } + } + + private static void MigrateDatabase() + { + Console.WriteLine("Migrating database."); + + var dbPass = Helpers.GetDatabasePasswordFronEnvFile(); + var connectionString = Helpers.MakeSqlConnectionString("mssql", "vault", "sa", dbPass ?? string.Empty); + var upgrader = DeployChanges.To + .SqlDatabase(connectionString) + .JournalToSqlTable("dbo", "Migration") + .WithScriptsAndCodeEmbeddedInAssembly(Assembly.GetExecutingAssembly(), + s => s.Contains($".DbScripts.") && !s.Contains(".Archive.")) + .WithTransaction() + .WithExecutionTimeout(new TimeSpan(0, 5, 0)) + .LogToConsole() + .Build(); + + var result = upgrader.PerformUpgrade(); + if(result.Successful) + { + Console.WriteLine("Migration successful."); + } + else + { + Console.WriteLine("Migration failed."); + } + } + private static void MakeCerts() { if(!_ssl) @@ -255,9 +307,7 @@ server {{ Console.WriteLine("Building docker environment override files."); Directory.CreateDirectory("/bitwarden/docker/"); var dbPass = _parameters.ContainsKey("db_pass") ? _parameters["db_pass"].ToLowerInvariant() : "REPLACE"; - var dbConnectionString = "Server=tcp:mssql,1433;Initial Catalog=vault;Persist Security Info=False;User ID=sa;" + - $"Password={dbPass};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=True;" + - "Connection Timeout=30;"; + var dbConnectionString = Helpers.MakeSqlConnectionString("mssql", "vault", "sa", dbPass); using(var sw = File.CreateText("/bitwarden/docker/global.override.env")) { diff --git a/util/Setup/Setup.csproj b/util/Setup/Setup.csproj index ce1697ae88..bb1e3b662c 100644 --- a/util/Setup/Setup.csproj +++ b/util/Setup/Setup.csproj @@ -3,6 +3,16 @@ Exe netcoreapp2.0 + 1701;1702;1705;NU1701 + + + + + + + + +