mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-29 08:00:19 +01:00
Merge branch 'master' of https://github.com/tgstation/tgstation-server into 598-TestChatTagging
This commit is contained in:
@@ -35,77 +35,77 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
{
|
||||
logger.LogInformation("Host watchdog starting...");
|
||||
|
||||
var enviromentPath = Environment.GetEnvironmentVariable("PATH");
|
||||
var paths = enviromentPath.Split(';');
|
||||
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
|
||||
var exeName = "dotnet";
|
||||
IEnumerable<string> enumerator;
|
||||
if (isWindows)
|
||||
{
|
||||
exeName += ".exe";
|
||||
enumerator = paths;
|
||||
}
|
||||
else
|
||||
enumerator = paths.Select(x => x.Split(':')).SelectMany(x => x);
|
||||
|
||||
enumerator = enumerator.Select(x => Path.Combine(x, exeName));
|
||||
|
||||
var dotnetPath = enumerator
|
||||
.Where(x =>
|
||||
{
|
||||
logger.LogTrace("Checking for dotnet at {0}", x);
|
||||
return File.Exists(x);
|
||||
})
|
||||
.FirstOrDefault();
|
||||
|
||||
if (dotnetPath == default)
|
||||
{
|
||||
logger.LogCritical("Unable to locate dotnet executable in PATH! Please ensure the .NET Core runtime is installed and is in your PATH!");
|
||||
return;
|
||||
}
|
||||
logger.LogInformation("Detected dotnet executable at {0}", dotnetPath);
|
||||
|
||||
var rootLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
|
||||
var assemblyStoragePath = Path.Combine(rootLocation, "lib"); //always always next to watchdog
|
||||
var defaultAssemblyPath = Path.GetFullPath(Path.Combine(assemblyStoragePath, "Default"));
|
||||
#if DEBUG
|
||||
//just copy the shit where it belongs
|
||||
Directory.Delete(assemblyStoragePath, true);
|
||||
Directory.CreateDirectory(defaultAssemblyPath);
|
||||
|
||||
var sourcePath = "../../../../Tgstation.Server.Host/bin/Debug/netcoreapp2.1";
|
||||
foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
|
||||
Directory.CreateDirectory(dirPath.Replace(sourcePath, defaultAssemblyPath));
|
||||
|
||||
foreach (string newPath in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
|
||||
File.Copy(newPath, newPath.Replace(sourcePath, defaultAssemblyPath), true);
|
||||
|
||||
const string AppSettingsJson = "appsettings.json";
|
||||
var rootJson = Path.Combine(rootLocation, AppSettingsJson);
|
||||
File.Delete(rootJson);
|
||||
File.Move(Path.Combine(defaultAssemblyPath, AppSettingsJson), rootJson);
|
||||
#endif
|
||||
|
||||
var assemblyName = String.Join(".", nameof(Tgstation), nameof(Server), nameof(Host), "dll");
|
||||
var assemblyPath = Path.Combine(defaultAssemblyPath, assemblyName);
|
||||
|
||||
if (assemblyPath.Contains("\""))
|
||||
{
|
||||
logger.LogCritical("Running from paths with \"'s in the name is not supported!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!File.Exists(assemblyPath))
|
||||
{
|
||||
logger.LogCritical("Unable to locate host assembly!");
|
||||
return;
|
||||
}
|
||||
|
||||
string updateDirectory = null;
|
||||
try
|
||||
{
|
||||
var enviromentPath = Environment.GetEnvironmentVariable("PATH");
|
||||
var paths = enviromentPath.Split(';');
|
||||
var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
|
||||
var exeName = "dotnet";
|
||||
IEnumerable<string> enumerator;
|
||||
if (isWindows)
|
||||
{
|
||||
exeName += ".exe";
|
||||
enumerator = paths;
|
||||
}
|
||||
else
|
||||
enumerator = paths.Select(x => x.Split(':')).SelectMany(x => x);
|
||||
|
||||
enumerator = enumerator.Select(x => Path.Combine(x, exeName));
|
||||
|
||||
var dotnetPath = enumerator
|
||||
.Where(x =>
|
||||
{
|
||||
logger.LogTrace("Checking for dotnet at {0}", x);
|
||||
return File.Exists(x);
|
||||
})
|
||||
.FirstOrDefault();
|
||||
|
||||
if (dotnetPath == default)
|
||||
{
|
||||
logger.LogCritical("Unable to locate dotnet executable in PATH! Please ensure the .NET Core runtime is installed and is in your PATH!");
|
||||
return;
|
||||
}
|
||||
logger.LogInformation("Detected dotnet executable at {0}", dotnetPath);
|
||||
|
||||
var rootLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
|
||||
var assemblyStoragePath = Path.Combine(rootLocation, "lib"); //always always next to watchdog
|
||||
var defaultAssemblyPath = Path.GetFullPath(Path.Combine(assemblyStoragePath, "Default"));
|
||||
#if DEBUG
|
||||
//just copy the shit where it belongs
|
||||
Directory.Delete(assemblyStoragePath, true);
|
||||
Directory.CreateDirectory(defaultAssemblyPath);
|
||||
|
||||
var sourcePath = "../../../../Tgstation.Server.Host/bin/Debug/netcoreapp2.1";
|
||||
foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
|
||||
Directory.CreateDirectory(dirPath.Replace(sourcePath, defaultAssemblyPath));
|
||||
|
||||
foreach (string newPath in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
|
||||
File.Copy(newPath, newPath.Replace(sourcePath, defaultAssemblyPath), true);
|
||||
|
||||
const string AppSettingsJson = "appsettings.json";
|
||||
var rootJson = Path.Combine(rootLocation, AppSettingsJson);
|
||||
File.Delete(rootJson);
|
||||
File.Move(Path.Combine(defaultAssemblyPath, AppSettingsJson), rootJson);
|
||||
#endif
|
||||
|
||||
var assemblyName = String.Join(".", nameof(Tgstation), nameof(Server), nameof(Host), "dll");
|
||||
var assemblyPath = Path.Combine(defaultAssemblyPath, assemblyName);
|
||||
|
||||
if (assemblyPath.Contains("\""))
|
||||
{
|
||||
logger.LogCritical("Running from paths with \"'s in the name is not supported!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!File.Exists(assemblyPath))
|
||||
{
|
||||
logger.LogCritical("Unable to locate host assembly!");
|
||||
return;
|
||||
}
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
using (logger.BeginScope("Host invocation"))
|
||||
{
|
||||
@@ -119,7 +119,7 @@ namespace Tgstation.Server.Host.Watchdog
|
||||
var arguments = new List<string>
|
||||
{
|
||||
'"' + assemblyPath + '"',
|
||||
updateDirectory
|
||||
'"' + updateDirectory + '"'
|
||||
};
|
||||
if (Debugger.IsAttached)
|
||||
arguments.Add("--attach-debugger");
|
||||
|
||||
@@ -184,8 +184,8 @@ namespace Tgstation.Server.Host.Components
|
||||
while (true)
|
||||
try
|
||||
{
|
||||
await Task.Delay(new TimeSpan(0, minutes > Int32.MaxValue ? Int32.MaxValue : (int)minutes, 0), cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await Task.Delay(TimeSpan.FromMinutes(minutes > Int32.MaxValue ? Int32.MaxValue : (int)minutes), cancellationToken).ConfigureAwait(false);
|
||||
logger.LogDebug("Beginning auto update...");
|
||||
try
|
||||
{
|
||||
Models.User user = null;
|
||||
@@ -198,10 +198,11 @@ namespace Tgstation.Server.Host.Components
|
||||
},
|
||||
Description = "Scheduled repository update",
|
||||
CancelRightsType = RightsType.Repository,
|
||||
CancelRight = (ulong)RepositoryRights.CancelPendingChanges
|
||||
CancelRight = (ulong)RepositoryRights.CancelPendingChanges,
|
||||
StartedBy = user
|
||||
};
|
||||
|
||||
var noRepo = false;
|
||||
var repositoryUpdateSuccess = false;
|
||||
await jobManager.RegisterOperation(repositoryUpdateJob, async (paramJob, databaseContext, progressReporter, jobCancellationToken) =>
|
||||
{
|
||||
var repositorySettingsTask = databaseContext.RepositorySettings.Where(x => x.InstanceId == metadata.Id).FirstAsync(jobCancellationToken);
|
||||
@@ -225,8 +226,7 @@ namespace Tgstation.Server.Host.Components
|
||||
{
|
||||
if (repo == null)
|
||||
{
|
||||
//no repo, no auto updates
|
||||
noRepo = true;
|
||||
logger.LogTrace("Aborting repo update, no repository!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -241,13 +241,15 @@ namespace Tgstation.Server.Host.Components
|
||||
bool shouldSyncTracked;
|
||||
if (repositorySettings.AutoUpdatesKeepTestMerges.Value)
|
||||
{
|
||||
logger.LogTrace("Preserving test merges...");
|
||||
var result = await repo.MergeOrigin(repositorySettings.CommitterName, repositorySettings.CommitterEmail, NextProgressReporter(), jobCancellationToken).ConfigureAwait(false);
|
||||
if (!result.HasValue)
|
||||
return;
|
||||
throw new JobException("Merge conflict while preserving test merges!");
|
||||
shouldSyncTracked = result.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogTrace("Not preserving test merges...");
|
||||
await repo.ResetToOrigin(NextProgressReporter(), jobCancellationToken).ConfigureAwait(false);
|
||||
shouldSyncTracked = true;
|
||||
}
|
||||
@@ -258,12 +260,16 @@ namespace Tgstation.Server.Host.Components
|
||||
|
||||
progressReporter(5 * ProgressStep);
|
||||
}
|
||||
repositoryUpdateSuccess = true;
|
||||
}, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await jobManager.WaitForJobCompletion(repositoryUpdateJob, user, cancellationToken, default).ConfigureAwait(false);
|
||||
|
||||
if (noRepo)
|
||||
if (!repositoryUpdateSuccess)
|
||||
{
|
||||
logger.LogTrace("Aborting auto update, repository error!");
|
||||
continue;
|
||||
}
|
||||
|
||||
//finally set up the job
|
||||
var compileProcessJob = new Job
|
||||
|
||||
@@ -442,6 +442,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
Branch trackedBranch = null;
|
||||
|
||||
var oldHead = repository.Head;
|
||||
var oldTip = oldHead.Tip;
|
||||
|
||||
await Task.Factory.StartNew(() =>
|
||||
{
|
||||
@@ -468,7 +469,10 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
if (result.Status == MergeStatus.Conflicts)
|
||||
{
|
||||
logger.LogDebug("Merge conflict, aborting and reverting to {0}", oldHead.FriendlyName);
|
||||
RawCheckout(oldHead.CanonicalName, progressReporter, cancellationToken);
|
||||
repository.Reset(ResetMode.Hard, oldTip, new CheckoutOptions
|
||||
{
|
||||
OnCheckoutProgress = CheckoutProgressHandler(progressReporter)
|
||||
});
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
@@ -477,7 +481,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
|
||||
if (result.Status == MergeStatus.Conflicts)
|
||||
{
|
||||
await eventConsumer.HandleEvent(EventType.RepoMergeConflict, new List<string> { oldHead.Tip.Sha, trackedBranch.Tip.Sha, oldHead.FriendlyName ?? UnknownReference, trackedBranch.FriendlyName }, cancellationToken).ConfigureAwait(false);
|
||||
await eventConsumer.HandleEvent(EventType.RepoMergeConflict, new List<string> { oldTip.Sha, trackedBranch.Tip.Sha, oldHead.FriendlyName ?? UnknownReference, trackedBranch.FriendlyName }, cancellationToken).ConfigureAwait(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Tgstation.Server.Host.Components.StaticFiles
|
||||
/// <param name="data">The data to write. If <see langword="null"/>, the file is deleted</param>
|
||||
/// <param name="previousHash">The hash any existing file must match in order for the write to succeed</param>
|
||||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation. Usage may result in partial writes</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the updated <see cref="ConfigurationFile"/></returns>
|
||||
/// <returns>A <see cref="Task{TResult}"/> resulting in the updated <see cref="ConfigurationFile"/> or <see langword="null"/> if the write failed due to <see cref="ConfigurationFile.LastReadHash"/> conflicts</returns>
|
||||
Task<ConfigurationFile> Write(string configurationRelativePath, ISystemIdentity systemIdentity, byte[] data, string previousHash, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -68,7 +68,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
if (newFile == null)
|
||||
return Conflict(new ErrorMessage
|
||||
{
|
||||
Message = ""
|
||||
Message = "This file has been updated since you last viewed it!"
|
||||
});
|
||||
|
||||
newFile.Content = null;
|
||||
@@ -171,6 +171,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
|
||||
try
|
||||
{
|
||||
model.IsDirectory = true;
|
||||
return await instanceManager.GetInstance(Instance).Configuration.CreateDirectory(model.Path, AuthenticationContext.SystemIdentity, cancellationToken).ConfigureAwait(false) ? (IActionResult)Json(model) : StatusCode((int)HttpStatusCode.Created, model);
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
|
||||
@@ -295,6 +295,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
var oldAutoUpdateInterval = originalModel.AutoUpdateInterval.Value;
|
||||
var originalOnline = originalModel.Online.Value;
|
||||
var renamed = model.Name != null && originalModel.Name != model.Name;
|
||||
|
||||
@@ -356,6 +357,9 @@ namespace Tgstation.Server.Host.Controllers
|
||||
api.MoveJob = job.ToApi();
|
||||
}
|
||||
|
||||
if (originalModel.Online.Value && model.AutoUpdateInterval.HasValue && oldAutoUpdateInterval != model.AutoUpdateInterval)
|
||||
await instanceManager.GetInstance(originalModel).SetAutoUpdateInterval(model.AutoUpdateInterval.Value).ConfigureAwait(false);
|
||||
|
||||
return Json(api);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user