diff --git a/src/Tgstation.Server.Host/Components/IInstance.cs b/src/Tgstation.Server.Host/Components/IInstance.cs
index 8e5b2edf80..cf2c527a8a 100644
--- a/src/Tgstation.Server.Host/Components/IInstance.cs
+++ b/src/Tgstation.Server.Host/Components/IInstance.cs
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Hosting;
using System;
+using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Host.Components.Byond;
using Tgstation.Server.Host.Components.Chat;
@@ -75,5 +76,15 @@ namespace Tgstation.Server.Host.Components
/// The new auto update inteval
/// A representing the running operation
Task SetAutoUpdateInterval(uint newInterval);
+
+ ///
+ /// Run the compile job and insert it into the database. Meant to be called by a
+ ///
+ /// The running
+ /// The for the operation
+ /// The to report compilation progress
+ /// The for the operation
+ /// A representing the running operation
+ Task CompileProcess(Job job, IServiceProvider serviceProvider, Action progressReporter, CancellationToken cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs
index 46b5dc3541..1e99e0b49a 100644
--- a/src/Tgstation.Server.Host/Components/Instance.cs
+++ b/src/Tgstation.Server.Host/Components/Instance.cs
@@ -1,9 +1,11 @@
using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Tgstation.Server.Api.Rights;
using Tgstation.Server.Host.Components.Byond;
using Tgstation.Server.Host.Components.Chat;
using Tgstation.Server.Host.Components.Compiler;
@@ -114,6 +116,59 @@ namespace Tgstation.Server.Host.Components
RepositoryManager.Dispose();
}
+ ///
+ public async Task CompileProcess(Job job, IServiceProvider serviceProvider, Action progressReporter, CancellationToken cancellationToken)
+ {
+ var databaseContext = serviceProvider.GetRequiredService();
+
+ var ddSettingsTask = databaseContext.DreamDaemonSettings.Where(x => x.InstanceId == metadata.Id).Select(x => new DreamDaemonSettings
+ {
+ StartupTimeout = x.StartupTimeout,
+ SecurityLevel = x.SecurityLevel
+ }).FirstOrDefaultAsync(cancellationToken);
+
+ var dreamMakerSettings = await databaseContext.DreamMakerSettings.Where(x => x.InstanceId == metadata.Id).FirstAsync(cancellationToken).ConfigureAwait(false);
+ if (dreamMakerSettings == default)
+ throw new JobException("Missing DreamMakerSettings in DB!");
+ var ddSettings = await ddSettingsTask.ConfigureAwait(false);
+ if (ddSettings == default)
+ throw new JobException("Missing DreamDaemonSettings in DB!");
+
+ CompileJob compileJob;
+ RevisionInformation revInfo;
+ using (var repo = await RepositoryManager.LoadRepository(cancellationToken).ConfigureAwait(false))
+ {
+ if (repo == null)
+ throw new JobException("Missing Repository!");
+
+ var repoSha = repo.Head;
+ revInfo = await databaseContext.RevisionInformations.Where(x => x.CommitSha == repoSha).Include(x => x.ActiveTestMerges).ThenInclude(x => x.TestMerge).FirstOrDefaultAsync().ConfigureAwait(false);
+
+ if (revInfo == default)
+ {
+ revInfo = new RevisionInformation
+ {
+ CommitSha = repoSha,
+ OriginCommitSha = repoSha,
+ Instance = new Models.Instance
+ {
+ Id = metadata.Id
+ }
+ };
+ logger.LogWarning(Repository.Repository.OriginTrackingErrorTemplate, repoSha);
+ databaseContext.Instances.Attach(revInfo.Instance);
+ }
+
+ compileJob = await DreamMaker.Compile(revInfo, dreamMakerSettings, ddSettings.SecurityLevel.Value, ddSettings.StartupTimeout.Value, repo, cancellationToken).ConfigureAwait(false);
+ }
+
+ compileJob.Job = job;
+
+ databaseContext.CompileJobs.Add(compileJob); //will be saved by job context
+
+ job.PostComplete = ct => CompileJobConsumer.LoadCompileJob(compileJob, ct);
+ }
+
///
/// Pull the repository and compile for every set of given
///
@@ -129,33 +184,32 @@ namespace Tgstation.Server.Host.Components
try
{
- CompileJob job = null;
+ Job job = null;
+ Models.User user = null;
//need this the whole time
+ var noRepo = false;
await databaseContextFactory.UseContext(async (db) =>
{
- //start up queries we'll need in the future
- var instanceQuery = db.Instances.Where(x => x.Id == metadata.Id);
- var ddSettingsTask = instanceQuery.Select(x => x.DreamDaemonSettings).Select(x => new DreamDaemonSettings
- {
- StartupTimeout = x.StartupTimeout,
- SecurityLevel = x.SecurityLevel
- }).FirstAsync(cancellationToken);
- var dmSettingsTask = instanceQuery.Select(x => x.DreamMakerSettings).FirstAsync(cancellationToken);
- var repositorySettingsTask = instanceQuery.Select(x => x.RepositorySettings).FirstAsync(cancellationToken);
+ var userTask = db.Users.FirstAsync(cancellationToken);
+
+ var repositorySettingsTask = db.RepositorySettings.Where(x => x.InstanceId == metadata.Id).FirstAsync(cancellationToken);
using (var repo = await RepositoryManager.LoadRepository(cancellationToken).ConfigureAwait(false))
{
if (repo == null)
+ {
+ //no repo, no auto updates
+ noRepo = true;
return;
+ }
- //start the rev info query
- var startSha = repo.Head;
- var revInfoTask = instanceQuery.SelectMany(x => x.RevisionInformations).Where(x => x.CommitSha == startSha).FirstOrDefaultAsync(cancellationToken);
-
- //need repo setting to fetch
var repositorySettings = await repositorySettingsTask.ConfigureAwait(false);
+
+ //the main point of auto update is to pull the remote
await repo.FetchOrigin(repositorySettings.AccessUser, repositorySettings.AccessToken, null, cancellationToken).ConfigureAwait(false);
+ var startSha = repo.Head;
+
//take appropriate auto update actions
bool shouldSyncTracked;
if (repositorySettings.AutoUpdatesKeepTestMerges.Value)
@@ -174,38 +228,28 @@ namespace Tgstation.Server.Host.Components
//synch if necessary
if (repositorySettings.AutoUpdatesSynchronize.Value && startSha != repo.Head)
await repo.Sychronize(repositorySettings.AccessUser, repositorySettings.AccessToken, shouldSyncTracked, cancellationToken).ConfigureAwait(false);
-
- //finish other queries
- var dmSettings = await dmSettingsTask.ConfigureAwait(false);
- var ddSettings = await ddSettingsTask.ConfigureAwait(false);
- var revInfo = await revInfoTask.ConfigureAwait(false);
-
- //null rev info handling
- if (revInfo == default)
- {
- var currentSha = repo.Head;
- revInfo = new RevisionInformation
- {
- CommitSha = currentSha,
- OriginCommitSha = currentSha,
- Instance = new Models.Instance
- {
- Id = metadata.Id
- }
- };
- logger.LogWarning(Repository.Repository.OriginTrackingErrorTemplate, currentSha);
- db.Instances.Attach(revInfo.Instance);
- }
-
- //finally start compile
- job = await DreamMaker.Compile(revInfo, dmSettings, ddSettings.SecurityLevel.Value, ddSettings.StartupTimeout.Value, repo, cancellationToken).ConfigureAwait(false);
}
- db.CompileJobs.Add(job);
- await db.Save(cancellationToken).ConfigureAwait(false);
+ user = await userTask.ConfigureAwait(false);
+
+ //finally set up the job
+ job = new Job
+ {
+ StartedBy = user,
+ Instance = new Models.Instance
+ {
+ Id = metadata.Id
+ },
+ Description = "Scheduled code deployment",
+ CancelRightsType = RightsType.DreamMaker,
+ CancelRight = (ulong)DreamMakerRights.CancelCompile
+ };
+
+ await jobManager.RegisterOperation(job, CompileProcess, cancellationToken).ConfigureAwait(false);
}).ConfigureAwait(false);
- await CompileJobConsumer.LoadCompileJob(job, cancellationToken).ConfigureAwait(false);
+ if(!noRepo)
+ await jobManager.WaitForJobCompletion(job, user, cancellationToken, default).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
diff --git a/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs b/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs
index 746f04157b..3c12cdc2bf 100644
--- a/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs
+++ b/src/Tgstation.Server.Host/Controllers/DreamMakerController.cs
@@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
@@ -10,7 +9,6 @@ using System.Threading.Tasks;
using Tgstation.Server.Api;
using Tgstation.Server.Api.Rights;
using Tgstation.Server.Host.Components;
-using Tgstation.Server.Host.Components.Repository;
using Tgstation.Server.Host.Core;
using Tgstation.Server.Host.Models;
using Tgstation.Server.Host.Security;
@@ -97,7 +95,7 @@ namespace Tgstation.Server.Host.Controllers
CancelRight = (ulong)DreamMakerRights.CancelCompile,
Instance = Instance
};
- await jobManager.RegisterOperation(job, (paramJob, serviceProvider, progressReporter, ct) => RunCompile(paramJob, serviceProvider, Instance, ct), cancellationToken).ConfigureAwait(false);
+ await jobManager.RegisterOperation(job, instanceManager.GetInstance(Instance).CompileProcess, cancellationToken).ConfigureAwait(false);
return Accepted(job.ToApi());
}
@@ -129,69 +127,5 @@ namespace Tgstation.Server.Host.Controllers
await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
return await Read(cancellationToken).ConfigureAwait(false);
}
-
- ///
- /// Run the compile job and insert it into the database
- ///
- /// The running
- /// The for the operation
- /// The for the operation
- /// The for the operation
- /// A representing the running operation
- async Task RunCompile(Job job, IServiceProvider serviceProvider, Models.Instance instanceModel, CancellationToken cancellationToken)
- {
- var instanceManager = serviceProvider.GetRequiredService();
- var databaseContext = serviceProvider.GetRequiredService();
-
- var ddSettingsTask = databaseContext.DreamDaemonSettings.Where(x => x.InstanceId == instanceModel.Id).Select(x => new DreamDaemonSettings
- {
- StartupTimeout = x.StartupTimeout,
- SecurityLevel = x.SecurityLevel
- }).FirstOrDefaultAsync(cancellationToken);
-
-
- var dreamMakerSettings = await databaseContext.DreamMakerSettings.Where(x => x.InstanceId == instanceModel.Id).FirstAsync(cancellationToken).ConfigureAwait(false);
- if (dreamMakerSettings == default)
- throw new JobException("Missing DreamMakerSettings in DB!");
- var ddSettings = await ddSettingsTask.ConfigureAwait(false);
- if (ddSettings == default)
- throw new JobException("Missing DreamDaemonSettings in DB!");
-
- var instance = instanceManager.GetInstance(instanceModel);
-
- CompileJob compileJob;
- RevisionInformation revInfo;
- using (var repo = await instance.RepositoryManager.LoadRepository(cancellationToken).ConfigureAwait(false))
- {
- if (repo == null)
- throw new JobException("Missing Repository!");
-
- var repoSha = repo.Head;
- revInfo = await databaseContext.RevisionInformations.Where(x => x.CommitSha == repoSha).Include(x => x.ActiveTestMerges).ThenInclude(x => x.TestMerge).FirstOrDefaultAsync().ConfigureAwait(false);
-
- if (revInfo == default)
- {
- revInfo = new RevisionInformation
- {
- CommitSha = repoSha,
- OriginCommitSha = repoSha,
- Instance = new Models.Instance
- {
- Id = Instance.Id
- }
- };
- Logger.LogWarning(Repository.OriginTrackingErrorTemplate, repoSha);
- databaseContext.Instances.Attach(revInfo.Instance);
- }
-
- compileJob = await instance.DreamMaker.Compile(revInfo, dreamMakerSettings, ddSettings.SecurityLevel.Value, ddSettings.StartupTimeout.Value, repo, cancellationToken).ConfigureAwait(false);
- }
-
- compileJob.Job = job;
-
- databaseContext.CompileJobs.Add(compileJob); //will be saved by job context
-
- job.PostComplete = ct => instance.CompileJobConsumer.LoadCompileJob(compileJob, ct);
- }
}
}