Merge branch 'master' of https://github.com/tgstation/tgstation-server into 598-TestChatTagging

This commit is contained in:
Jordan Brown
2018-09-22 11:39:57 -04:00
6 changed files with 96 additions and 81 deletions
+69 -69
View File
@@ -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);
}