mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-27 15:07:03 +01:00
ByondController
This commit is contained in:
@@ -14,5 +14,11 @@ namespace Tgstation.Server.Api.Models
|
||||
/// </summary>
|
||||
[Permissions(ReadRight = ByondRights.ReadActive, WriteRight = ByondRights.ChangeVersion)]
|
||||
public Version Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Job"/> being used to install a new <see cref="Version"/>
|
||||
/// </summary>
|
||||
[Permissions(DenyWrite = true)]
|
||||
public Job InstallJob { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,12 @@ namespace Tgstation.Server.Api.Models
|
||||
[Permissions(DenyWrite = true)]
|
||||
public bool? IsGitHub { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Job"/> started by the <see cref="Repository"/> if any
|
||||
/// </summary>
|
||||
[Permissions(DenyWrite = true)]
|
||||
public Job ActiveJob { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Do the equivalent of a git pull. Will attempt to merge unless <see cref="Reference"/> is also specified
|
||||
/// </summary>
|
||||
|
||||
@@ -17,8 +17,16 @@ namespace Tgstation.Server.Api.Rights
|
||||
/// </summary>
|
||||
ReadActive = 1,
|
||||
/// <summary>
|
||||
/// User may change to any BYOND version
|
||||
/// User may list all installed BYOND versions
|
||||
/// </summary>
|
||||
ChangeVersion = 4
|
||||
ListInstalled = 2,
|
||||
/// <summary>
|
||||
/// User may change the active BYOND version
|
||||
/// </summary>
|
||||
ChangeVersion = 4,
|
||||
/// <summary>
|
||||
/// User may cancel version installations
|
||||
/// </summary>
|
||||
CancelInstall = 8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,14 @@ namespace Tgstation.Server.Api.Rights
|
||||
/// <summary>
|
||||
/// User may delete the <see cref="Models.Repository"/>
|
||||
/// </summary>
|
||||
Delete = 2048
|
||||
Delete = 2048,
|
||||
/// <summary>
|
||||
/// User may cancel clone operations
|
||||
/// </summary>
|
||||
CancelClone = 4096,
|
||||
/// <summary>
|
||||
/// User may cancel synchronize operations
|
||||
/// </summary>
|
||||
CancelSynchronize = 8192
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.IO;
|
||||
|
||||
namespace Tgstation.Server.Host.Components.Byond
|
||||
@@ -20,6 +21,16 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
/// <inheritdoc />
|
||||
public Version ActiveVersion { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IReadOnlyList<Version> InstalledVersions
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (installedVersions)
|
||||
return installedVersions.Select(x => Version.Parse(x.Key)).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IIOManager"/> for the <see cref="ByondManager"/>
|
||||
/// </summary>
|
||||
@@ -40,6 +51,13 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
/// </summary>
|
||||
readonly Dictionary<string, Task> installedVersions;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="SemaphoreSlim"/> for the <see cref="ByondManager"/>
|
||||
/// </summary>
|
||||
readonly SemaphoreSlim semaphore;
|
||||
|
||||
static string VersionKey(Version version) => new Version(version.Major, version.Minor).ToString();
|
||||
|
||||
/// <summary>
|
||||
/// Construct a <see cref="ByondManager"/>
|
||||
/// </summary>
|
||||
@@ -53,9 +71,11 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
installedVersions = new Dictionary<string, Task>();
|
||||
semaphore = new SemaphoreSlim(1);
|
||||
}
|
||||
|
||||
static string VersionKey(Version version) => new Version(version.Major, version.Minor).ToString();
|
||||
/// <inheritdoc />
|
||||
public void Dispose() => semaphore.Dispose();
|
||||
|
||||
async Task InstallVersion(Version version, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -95,8 +115,11 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
public async Task ChangeVersion(Version version, CancellationToken cancellationToken)
|
||||
{
|
||||
await InstallVersion(version, cancellationToken).ConfigureAwait(false);
|
||||
await ioManager.WriteAllBytes(ActiveVersionFileName, Encoding.UTF8.GetBytes(version.ToString()), cancellationToken).ConfigureAwait(false);
|
||||
ActiveVersion = version;
|
||||
using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
await ioManager.WriteAllBytes(ActiveVersionFileName, Encoding.UTF8.GetBytes(version.ToString()), cancellationToken).ConfigureAwait(false);
|
||||
ActiveVersion = version;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -8,13 +9,18 @@ namespace Tgstation.Server.Host.Components.Byond
|
||||
/// <summary>
|
||||
/// For managing the BYOND installation
|
||||
/// </summary>
|
||||
public interface IByondManager : IHostedService
|
||||
public interface IByondManager : IHostedService, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The currently active BYOND version
|
||||
/// </summary>
|
||||
Version ActiveVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The installed BYOND versions
|
||||
/// </summary>
|
||||
IReadOnlyList<Version> InstalledVersions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Change the active BYOND version
|
||||
/// </summary>
|
||||
|
||||
@@ -12,6 +12,11 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
/// <inheritdoc />
|
||||
sealed class Repository : IRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Indication of a GitHub repository
|
||||
/// </summary>
|
||||
public const string GitHubUrl = "://github.com/";
|
||||
|
||||
const string UnknownReference = "<UNKNOWN>";
|
||||
|
||||
/// <summary>
|
||||
@@ -86,7 +91,7 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
this.ioMananger = ioMananger ?? throw new ArgumentNullException(nameof(ioMananger));
|
||||
this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
|
||||
this.onDispose = onDispose ?? throw new ArgumentNullException(nameof(onDispose));
|
||||
IsGitHubRepository = Origin.ToUpperInvariant().Contains("://GITHUB.COM/");
|
||||
IsGitHubRepository = Origin.ToUpperInvariant().Contains(GitHubUrl.ToUpperInvariant());
|
||||
if (IsGitHubRepository)
|
||||
{
|
||||
GetRepositoryOwnerName(Origin, out var owner, out var name);
|
||||
|
||||
@@ -53,28 +53,38 @@ namespace Tgstation.Server.Host.Components.Repository
|
||||
{
|
||||
using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken).ConfigureAwait(false))
|
||||
if (!await ioManager.DirectoryExists(".", cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
await DeleteRepository(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await Task.Factory.StartNew(() =>
|
||||
try
|
||||
{
|
||||
await DeleteRepository(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await Task.Factory.StartNew(() =>
|
||||
{
|
||||
string path = null;
|
||||
try
|
||||
{
|
||||
path = LibGit2Sharp.Repository.Clone(Repository.GenerateAuthUrl(url.ToString(), accessString), ioManager.ResolvePath("."), new CloneOptions
|
||||
{
|
||||
OnProgress = (a) => !cancellationToken.IsCancellationRequested,
|
||||
OnTransferProgress = (a) => !cancellationToken.IsCancellationRequested,
|
||||
RecurseSubmodules = true,
|
||||
OnUpdateTips = (a, b, c) => !cancellationToken.IsCancellationRequested,
|
||||
RepositoryOperationStarting = (a) => !cancellationToken.IsCancellationRequested,
|
||||
BranchName = initialBranch
|
||||
});
|
||||
}
|
||||
catch (UserCancelledException) { }
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
string path = null;
|
||||
try
|
||||
{
|
||||
path = LibGit2Sharp.Repository.Clone(Repository.GenerateAuthUrl(url.ToString(), accessString), ioManager.ResolvePath("."), new CloneOptions
|
||||
{
|
||||
OnProgress = (a) => !cancellationToken.IsCancellationRequested,
|
||||
OnTransferProgress = (a) => !cancellationToken.IsCancellationRequested,
|
||||
RecurseSubmodules = true,
|
||||
OnUpdateTips = (a, b, c) => !cancellationToken.IsCancellationRequested,
|
||||
RepositoryOperationStarting = (a) => !cancellationToken.IsCancellationRequested,
|
||||
BranchName = initialBranch
|
||||
});
|
||||
await ioManager.DeleteDirectory(".", default).ConfigureAwait(false);
|
||||
}
|
||||
catch (UserCancelledException) { }
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current).ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
throw;
|
||||
}
|
||||
return await LoadRepository(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Tgstation.Server.Api.Models;
|
||||
using Tgstation.Server.Api.Rights;
|
||||
using Tgstation.Server.Host.Components;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.Models;
|
||||
using Tgstation.Server.Host.Security;
|
||||
|
||||
namespace Tgstation.Server.Host.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Controller for managing <see cref="Api.Models.Byond.Version"/>s
|
||||
/// </summary>
|
||||
[Route("/" + nameof(Byond))]
|
||||
public sealed class ByondController : ModelController<Api.Models.Byond>
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="IInstanceManager"/> for the <see cref="ByondController"/>
|
||||
/// </summary>
|
||||
readonly IInstanceManager instanceManager;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IJobManager"/> for the <see cref="ByondController"/>
|
||||
/// </summary>
|
||||
readonly IJobManager jobManager;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILogger"/> for the <see cref="ByondController"/>
|
||||
/// </summary>
|
||||
readonly ILogger<ByondController> logger;
|
||||
|
||||
/// <summary>
|
||||
/// Construct a <see cref="ByondController"/>
|
||||
/// </summary>
|
||||
/// <param name="databaseContext">The <see cref="IDatabaseContext"/> for the <see cref="ApiController"/></param>
|
||||
/// <param name="authenticationContextFactory">The <see cref="IAuthenticationContextFactory"/> for the <see cref="ApiController"/></param>
|
||||
/// <param name="instanceManager">The value of <see cref="instanceManager"/></param>
|
||||
/// <param name="jobManager">The value of <see cref="jobManager"/></param>
|
||||
/// <param name="logger">The value of <see cref="logger"/></param>
|
||||
public ByondController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, IInstanceManager instanceManager, IJobManager jobManager, ILogger<ByondController> logger) : base(databaseContext, authenticationContextFactory, true)
|
||||
{
|
||||
this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager));
|
||||
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[TgsAuthorize(ByondRights.ReadActive)]
|
||||
public override Task<IActionResult> Read(CancellationToken cancellationToken) => Task.FromResult((IActionResult)
|
||||
Json(new Api.Models.Byond
|
||||
{
|
||||
Version = instanceManager.GetInstance(Instance).ByondManager.ActiveVersion
|
||||
}));
|
||||
|
||||
/// <inheritdoc />
|
||||
[TgsAuthorize(ByondRights.ListInstalled)]
|
||||
public override Task<IActionResult> List(CancellationToken cancellationToken) => Task.FromResult((IActionResult)
|
||||
Json(instanceManager.GetInstance(Instance).ByondManager.InstalledVersions.Select(x => new Api.Models.Byond
|
||||
{
|
||||
Version = x
|
||||
})));
|
||||
|
||||
/// <inheritdoc />
|
||||
[TgsAuthorize(ByondRights.ChangeVersion)]
|
||||
public override async Task<IActionResult> Update([FromBody] Api.Models.Byond model, CancellationToken cancellationToken)
|
||||
{
|
||||
if (model == null)
|
||||
return BadRequest(new { message = "Missing request model!" });
|
||||
|
||||
if(model.Version == null)
|
||||
return BadRequest(new { message = "Missing version!" });
|
||||
|
||||
var byondManager = instanceManager.GetInstance(Instance).ByondManager;
|
||||
|
||||
//remove cruff fields
|
||||
var installingVersion = new Version(model.Version.Major, model.Version.Major);
|
||||
|
||||
var result = new Api.Models.Byond();
|
||||
|
||||
if (byondManager.InstalledVersions.Any(x => x == model.Version))
|
||||
{
|
||||
logger.LogInformation("User ID {0} changing instance ID {1} BYOND version to {2}", AuthenticationContext.User.Id, Instance.Id, installingVersion);
|
||||
await byondManager.ChangeVersion(model.Version, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogInformation("User ID {0} installing BYOND version to {2} on instance ID {1}", AuthenticationContext.User.Id, Instance.Id, installingVersion);
|
||||
//run the install through the job manager
|
||||
var job = new Models.Job
|
||||
{
|
||||
StartedBy = AuthenticationContext.User,
|
||||
CancelRightsType = RightsType.Byond,
|
||||
CancelRight = (int)ByondRights.CancelInstall,
|
||||
Instance = Instance
|
||||
};
|
||||
await jobManager.RegisterOperation(job, (paramJob, serviceProvicer, ct) => byondManager.ChangeVersion(installingVersion, ct), cancellationToken).ConfigureAwait(false);
|
||||
result.InstallJob = job.ToApi();
|
||||
}
|
||||
result.Version = byondManager.ActiveVersion;
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,15 +55,16 @@ namespace Tgstation.Server.Host.Controllers
|
||||
if (instance.Watchdog.Running)
|
||||
return StatusCode((int)HttpStatusCode.Gone);
|
||||
|
||||
await jobManager.RegisterOperation(new Models.Job
|
||||
var job = new Models.Job
|
||||
{
|
||||
Description = "Launch DreamDaemon",
|
||||
CancelRight = (int)DreamDaemonRights.Shutdown,
|
||||
CancelRightsType = RightsType.DreamDaemon,
|
||||
Instance = Instance,
|
||||
StartedBy = AuthenticationContext.User
|
||||
},
|
||||
async (job, serviceProvider, innerCt) =>
|
||||
};
|
||||
await jobManager.RegisterOperation(job,
|
||||
async (paramJob, serviceProvider, innerCt) =>
|
||||
{
|
||||
var result = await instance.Watchdog.Launch(innerCt).ConfigureAwait(false);
|
||||
if (result == null)
|
||||
@@ -72,7 +73,7 @@ namespace Tgstation.Server.Host.Controllers
|
||||
throw new Exception("Failed to launch watchdog!");
|
||||
},
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
return Ok();
|
||||
return Json(job);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -38,6 +39,11 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// </summary>
|
||||
readonly IJobManager jobManager;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILogger"/> for the <see cref="RepositoryController"/>
|
||||
/// </summary>
|
||||
readonly ILogger<RepositoryController> logger;
|
||||
|
||||
/// <summary>
|
||||
/// Construct a <see cref="RepositoryController"/>
|
||||
/// </summary>
|
||||
@@ -46,11 +52,13 @@ namespace Tgstation.Server.Host.Controllers
|
||||
/// <param name="instanceManager">The value of <see cref="instanceManager"/></param>
|
||||
/// <param name="gitHubClient">The value of <see cref="gitHubClient"/></param>
|
||||
/// <param name="jobManager">The value of <see cref="jobManager"/></param>
|
||||
public RepositoryController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, IInstanceManager instanceManager, Octokit.IGitHubClient gitHubClient, IJobManager jobManager) : base(databaseContext, authenticationContextFactory, true)
|
||||
/// <param name="logger">The value of <see cref="logger"/></param>
|
||||
public RepositoryController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, IInstanceManager instanceManager, Octokit.IGitHubClient gitHubClient, IJobManager jobManager, ILogger<RepositoryController> logger) : base(databaseContext, authenticationContextFactory, true)
|
||||
{
|
||||
this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager));
|
||||
this.gitHubClient = gitHubClient ?? throw new ArgumentNullException(nameof(gitHubClient));
|
||||
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
static string GetAccessString(Api.Models.Internal.RepositorySettings repositorySettings) => repositorySettings.AccessUser != null ? String.Concat(repositorySettings.AccessUser, '@', repositorySettings.AccessToken) : null;
|
||||
@@ -115,6 +123,13 @@ namespace Tgstation.Server.Host.Controllers
|
||||
if (currentModel == default)
|
||||
return StatusCode((int)HttpStatusCode.Gone);
|
||||
|
||||
//normalize github urls
|
||||
const string BadGitHubUrl = "://www.github.com/";
|
||||
var uiOrigin = model.Origin.ToUpperInvariant();
|
||||
var uiBad = BadGitHubUrl.ToUpperInvariant();
|
||||
var uiGitHub = Components.Repository.Repository.GitHubUrl.ToUpperInvariant();
|
||||
if (uiOrigin.Contains(uiBad))
|
||||
model.Origin = uiOrigin.Replace(uiBad, uiGitHub);
|
||||
|
||||
currentModel.AccessToken = model.AccessToken;
|
||||
currentModel.AccessUser = model.AccessUser; //intentionally only these fields, user not allowed to change anything else atm
|
||||
@@ -122,15 +137,37 @@ namespace Tgstation.Server.Host.Controllers
|
||||
var origin = model.Origin;
|
||||
|
||||
var repoManager = instanceManager.GetInstance(Instance).RepositoryManager;
|
||||
using (var repo = await repoManager.CloneRepository(new Uri(origin), cloneBranch, GetAccessString(currentModel), cancellationToken).ConfigureAwait(false))
|
||||
|
||||
using (var repo = await repoManager.LoadRepository(cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
if (repo == null)
|
||||
//clone conflict
|
||||
return Conflict();
|
||||
|
||||
var job = new Models.Job
|
||||
{
|
||||
Description = "Clone repository",
|
||||
StartedBy = AuthenticationContext.User,
|
||||
CancelRightsType = RightsType.Repository,
|
||||
CancelRight = (int)RepositoryRights.CancelClone,
|
||||
Instance = Instance
|
||||
};
|
||||
var api = currentModel.ToApi();
|
||||
await PopulateApi(api, repo, null, null, cancellationToken).ConfigureAwait(false);
|
||||
currentModel.LastOriginCommitSha = repo.Head;
|
||||
await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
|
||||
await jobManager.RegisterOperation(job, async (paramJob, serviceProvider, ct) =>
|
||||
{
|
||||
using (var repos = await repoManager.CloneRepository(new Uri(origin), cloneBranch, GetAccessString(currentModel), cancellationToken).ConfigureAwait(false))
|
||||
{
|
||||
if (repos == null)
|
||||
throw new Exception("Filesystem conflict while cloning repository!");
|
||||
await PopulateApi(api, repo, null, null, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
api.Origin = model.Origin;
|
||||
api.Reference = model.Reference;
|
||||
api.IsGitHub = model.Origin.ToUpperInvariant().Contains(uiGitHub);
|
||||
api.ActiveJob = job.ToApi();
|
||||
|
||||
return Json(api);
|
||||
}
|
||||
}
|
||||
@@ -154,7 +191,17 @@ namespace Tgstation.Server.Host.Controllers
|
||||
|
||||
await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
await instanceManager.GetInstance(Instance).RepositoryManager.DeleteRepository(cancellationToken).ConfigureAwait(false);
|
||||
logger.LogInformation("Instance {0} repository delete initiated by user {1}", Instance.Id, AuthenticationContext.User.Id);
|
||||
|
||||
var job = new Models.Job
|
||||
{
|
||||
Description = "Delete repository",
|
||||
StartedBy = AuthenticationContext.User,
|
||||
Instance = Instance
|
||||
};
|
||||
var api = currentModel.ToApi();
|
||||
await jobManager.RegisterOperation(job, (paramJob, serviceProvider, ct) => instanceManager.GetInstance(Instance).RepositoryManager.DeleteRepository(cancellationToken), cancellationToken).ConfigureAwait(false);
|
||||
api.ActiveJob = job.ToApi();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
@@ -341,7 +388,9 @@ namespace Tgstation.Server.Host.Controllers
|
||||
{
|
||||
Description = "Synchronize repository changes",
|
||||
StartedBy = AuthenticationContext.User,
|
||||
Instance = Instance
|
||||
Instance = Instance,
|
||||
CancelRightsType = RightsType.Repository,
|
||||
CancelRight = (int)RepositoryRights.CancelSynchronize,
|
||||
};
|
||||
await jobManager.RegisterOperation(job, async (paramJob, serviceProvider, ct) =>
|
||||
{
|
||||
@@ -349,6 +398,8 @@ namespace Tgstation.Server.Host.Controllers
|
||||
if (repos != null)
|
||||
await repos.Sychronize(accessString, ct).ConfigureAwait(false);
|
||||
}, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
api.ActiveJob = job.ToApi();
|
||||
}
|
||||
|
||||
return Json(api);
|
||||
|
||||
@@ -104,6 +104,19 @@ namespace Tgstation.Server.Host.Core
|
||||
{
|
||||
var databaseContext = scope.ServiceProvider.GetRequiredService<IDatabaseContext>();
|
||||
job.StartedAt = DateTimeOffset.Now;
|
||||
job.Instance = new Instance
|
||||
{
|
||||
Id = job.Instance.Id
|
||||
};
|
||||
databaseContext.Instances.Attach(job.Instance);
|
||||
if (job.StartedBy != null)
|
||||
{
|
||||
job.StartedBy = new User
|
||||
{
|
||||
Id = job.StartedBy.Id
|
||||
};
|
||||
databaseContext.Users.Attach(job.StartedBy);
|
||||
}
|
||||
databaseContext.Jobs.Add(job);
|
||||
await databaseContext.Save(cancellationToken).ConfigureAwait(false);
|
||||
var jobHandler = JobHandler.Create(x => RunJob(job, operation, x));
|
||||
|
||||
Reference in New Issue
Block a user