diff --git a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
index 1ccca2d0fb..96b02fd263 100644
--- a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
+++ b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
@@ -33,9 +33,9 @@
-
+
-
+
diff --git a/src/Tgstation.Server.Host.Watchdog/IsolatedServerFactory.cs b/src/Tgstation.Server.Host.Watchdog/IsolatedServerFactory.cs
index 2545747721..b51de730e9 100644
--- a/src/Tgstation.Server.Host.Watchdog/IsolatedServerFactory.cs
+++ b/src/Tgstation.Server.Host.Watchdog/IsolatedServerFactory.cs
@@ -25,9 +25,10 @@ namespace Tgstation.Server.Host.Watchdog
///
/// Loads the at and creates an from it
///
- /// The arguments for the
+ /// The arguments for the
+ /// The updatePath for the
/// A new
- public IServer CreateServer(string[] args)
+ public IServer CreateServer(string[] args, string updatePath)
{
var assembly = LoadFromAssemblyPath(assemblyPath);
//find the IServerFactory implementation
@@ -36,7 +37,7 @@ namespace Tgstation.Server.Host.Watchdog
var serverFactoryImplementationType = assembly.GetTypes().Where(x => serverFactoryInterfaceType.IsAssignableFrom(x)).First();
var serverFactory = (IServerFactory)Activator.CreateInstance(serverFactoryImplementationType);
- return serverFactory.CreateServer(args);
+ return serverFactory.CreateServer(args, updatePath);
}
//honestly have no idea what this is for, but the examples i see just return null and it seems to work just fine
diff --git a/src/Tgstation.Server.Host.Watchdog/Watchdog.cs b/src/Tgstation.Server.Host.Watchdog/Watchdog.cs
index 23f4a8968d..07372198e5 100644
--- a/src/Tgstation.Server.Host.Watchdog/Watchdog.cs
+++ b/src/Tgstation.Server.Host.Watchdog/Watchdog.cs
@@ -57,27 +57,36 @@ namespace Tgstation.Server.Host.Watchdog
logger.LogTrace("Determining location of host assembly...");
var assemblyPath = serverFactory.GetType().Assembly.Location;
logger.LogDebug("Path to initial host assembly: {0}", assemblyPath);
+ var assemblyName = Path.GetFileName(assemblyPath);
+ const string UpdatePath = "Updates";
+ var newAssemblyDirectory = Path.Combine(Path.GetDirectoryName(assemblyPath), UpdatePath);
var firstIteration = true;
do
using (logger.BeginScope("Host invocation"))
{
- var server = serverFactory.CreateServer(args);
- logger.LogTrace("Running server...");
- await server.RunAsync(cancellationToken).ConfigureAwait(false);
- logger.LogInformation("Active host exited.");
+ Guid updateGuid;
+ using (var server = serverFactory.CreateServer(args, newAssemblyDirectory))
+ {
+ logger.LogTrace("Running server...");
+ await server.RunAsync(cancellationToken).ConfigureAwait(false);
+ logger.LogInformation("Active host exited.");
- if (server.UpdatePath == null)
- break;
+ if (!server.UpdateGuid.HasValue)
+ break;
+ updateGuid = server.UpdateGuid.Value;
+ }
- logger.LogInformation("Update path is set to \"{0}\", attempting host assembly hotswap...", server.UpdatePath);
+ logger.LogInformation("Update path is set to \"{0}\", attempting host assembly hotswap...", updateGuid);
GC.Collect(Int32.MaxValue, GCCollectionMode.Forced, true, true);
- logger.LogTrace("Deleting old host assembly");
- activeAssemblyDeleter.DeleteActiveAssembly(assemblyPath);
- logger.LogTrace("Moving new host assembly in place...");
- File.Move(server.UpdatePath, assemblyPath);
+ if (!firstIteration)
+ {
+ logger.LogTrace("Deleting old host assembly");
+ //TODO: make this use directories
+ //activeAssemblyDeleter.DeleteActiveAssembly(newAssemblyDirectory);
+ }
logger.LogTrace("Atttempting to create new server factory...");
- serverFactory = isolatedAssemblyLoader.CreateIsolatedServerFactory(assemblyPath);
+ serverFactory = isolatedAssemblyLoader.CreateIsolatedServerFactory(Path.Combine(newAssemblyDirectory, updateGuid.ToString(), assemblyName));
firstIteration = false;
}
while (!cancellationToken.IsCancellationRequested);
diff --git a/src/Tgstation.Server.Host/IO/DefaultIOManager.cs b/src/Tgstation.Server.Host/IO/DefaultIOManager.cs
index b24653f8fe..a5f2b122c7 100644
--- a/src/Tgstation.Server.Host/IO/DefaultIOManager.cs
+++ b/src/Tgstation.Server.Host/IO/DefaultIOManager.cs
@@ -272,7 +272,7 @@ namespace Tgstation.Server.Host.IO
zipFileBytes = null;
using (var archive = new ZipArchive(ms))
{
- string GetEntryName(ZipArchiveEntry entry) => ConcatPath(path, GetDirectoryName(entry.FullName));
+ string GetEntryName(ZipArchiveEntry entry) => ConcatPath(path, entry.FullName);
//create directories first
await Task.WhenAll(archive.Entries.Where(x => x.Name.Length == 0).Select(x => CreateDirectory(GetEntryName(x), cancellationToken))).ConfigureAwait(false);
//extract files
diff --git a/src/Tgstation.Server.Host/ServerFactory.cs b/src/Tgstation.Server.Host/ServerFactory.cs
index 810ef924e2..ffe440055d 100644
--- a/src/Tgstation.Server.Host/ServerFactory.cs
+++ b/src/Tgstation.Server.Host/ServerFactory.cs
@@ -7,6 +7,6 @@ namespace Tgstation.Server.Host
public sealed class ServerFactory : IServerFactory
{
///
- public IServer CreateServer(string[] args) => new Server(WebHost.CreateDefaultBuilder(args));
+ public IServer CreateServer(string[] args, string updatePath) => new Server(WebHost.CreateDefaultBuilder(args), updatePath);
}
}
diff --git a/tests/Tgstation.Server.Host.Tests/Core/TestApplication.cs b/tests/Tgstation.Server.Host.Tests/Core/TestApplication.cs
index 22833bacdb..6a8eb5d68a 100644
--- a/tests/Tgstation.Server.Host.Tests/Core/TestApplication.cs
+++ b/tests/Tgstation.Server.Host.Tests/Core/TestApplication.cs
@@ -4,14 +4,16 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.IO;
+using System.Threading;
using System.Threading.Tasks;
+using Tgstation.Server.Host.IO;
namespace Tgstation.Server.Host.Core.Tests
{
[TestClass]
public sealed class TestApplication : IServerUpdater
{
- public void ApplyUpdate(string updatePath) => throw new NotImplementedException();
+ public Task ApplyUpdate(byte[] updateZipData, IIOManager ioManager, CancellationToken cancellationToken) => throw new NotImplementedException();
public void RegisterForUpdate(Action action) => throw new NotImplementedException();
diff --git a/tests/Tgstation.Server.Host.Watchdog.Tests/TestIsolatedServerFactory.cs b/tests/Tgstation.Server.Host.Watchdog.Tests/TestIsolatedServerFactory.cs
index ab382bff97..384139308b 100644
--- a/tests/Tgstation.Server.Host.Watchdog.Tests/TestIsolatedServerFactory.cs
+++ b/tests/Tgstation.Server.Host.Watchdog.Tests/TestIsolatedServerFactory.cs
@@ -20,7 +20,7 @@ namespace Tgstation.Server.Host.Watchdog.Tests
public void TestLoading()
{
var isf = new IsolatedServerFactory(typeof(ServerFactory).Assembly.Location);
- Assert.IsNotNull(isf.CreateServer(Array.Empty()));
+ Assert.IsNotNull(isf.CreateServer(Array.Empty(), String.Empty));
}
}
}
diff --git a/tests/Tgstation.Server.Host.Watchdog.Tests/TestWatchdog.cs b/tests/Tgstation.Server.Host.Watchdog.Tests/TestWatchdog.cs
index 56ec75351a..8f233120d5 100644
--- a/tests/Tgstation.Server.Host.Watchdog.Tests/TestWatchdog.cs
+++ b/tests/Tgstation.Server.Host.Watchdog.Tests/TestWatchdog.cs
@@ -29,7 +29,7 @@ namespace Tgstation.Server.Host.Watchdog.Tests
{
readonly IServer server;
public MockServerFactory(IServer server) => this.server = server;
- public IServer CreateServer(string[] args) => server;
+ public IServer CreateServer(string[] args, string updatePath) => server;
}
[TestMethod]
@@ -50,34 +50,5 @@ namespace Tgstation.Server.Host.Watchdog.Tests
mockServer.VerifyAll();
}
}
-
- [TestMethod]
- public async Task TestRunAsyncWithUpdate()
- {
- var mockServer = new Mock();
- mockServer.Setup(x => x.UpdatePath).Returns(GetType().Assembly.Location).Verifiable();
- var mockServerFactory = new MockServerFactory(mockServer.Object);
- var mockActiveAssemblyDeleter = new Mock();
- var mockIsolatedServerContextFactory = new Mock();
- mockIsolatedServerContextFactory.Setup(x => x.CreateIsolatedServerFactory(GetType().Assembly.Location)).Returns(mockServerFactory).Verifiable();
- var mockLogger = new LoggerFactory().CreateLogger();
-
- var wd = new Watchdog(mockServerFactory, mockActiveAssemblyDeleter.Object, mockIsolatedServerContextFactory.Object, mockLogger);
-
- using (var cts = new CancellationTokenSource())
- {
- int count = 0;
- mockServer.Setup(x => x.RunAsync(cts.Token)).Callback(() =>
- {
- if (++count > 1)
- cts.Cancel();
- }).Returns(Task.CompletedTask).Verifiable();
- await wd.RunAsync(Array.Empty(), cts.Token).ConfigureAwait(false);
-
- mockServer.VerifyAll();
- mockActiveAssemblyDeleter.Verify(x => x.DeleteActiveAssembly(GetType().Assembly.Location), Times.Exactly(2));
- mockIsolatedServerContextFactory.VerifyAll();
- }
- }
}
}