WIP shit, waiting on the other PR

This commit is contained in:
Cyberboss
2018-05-28 13:05:12 -04:00
parent 4cc817055a
commit 5cdaba7ae0
7 changed files with 166 additions and 21 deletions
@@ -1,11 +1,11 @@
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Tgstation.Server.Api.Rights;
using Tgstation.Server.Host.Components;
using Tgstation.Server.Host.Core;
@@ -30,7 +30,7 @@ namespace Tgstation.Server.Host.Controllers
readonly IInstanceManager instanceManager;
/// <summary>
/// Construct a <see cref="HomeController"/>
/// Construct a <see cref="DreamMakerController"/>
/// </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>
@@ -86,7 +86,7 @@ namespace Tgstation.Server.Host.Controllers
/// <inheritdoc />
[TgsAuthorize(DreamMakerRights.SetDme)]
public override async Task<IActionResult> Update([FromBody] Api.Models.DreamMaker model, CancellationToken cancellationToken)
public override async Task<IActionResult> UpdateAsync([FromBody] Api.Models.DreamMaker model, CancellationToken cancellationToken)
{
var hostModel = new DreamMakerSettings
{
@@ -0,0 +1,116 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
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="Components.Instance"/>s
/// </summary>
[Route("/Instance")]
public sealed class InstanceController : ModelController<Api.Models.Instance>
{
/// <summary>
/// The <see cref="IJobManager"/> for the <see cref="InstanceController"/>
/// </summary>
readonly IJobManager jobManager;
/// <summary>
/// The <see cref="IInstanceManager"/> for the <see cref="InstanceController"/>
/// </summary>
readonly IInstanceManager instanceManager;
/// <summary>
/// The <see cref="IIOManager"/> for the <see cref="InstanceController"/>
/// </summary>
readonly IIOManager ioManager;
/// <summary>
/// Construct a <see cref="InstanceController"/>
/// </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="jobManager">The value of <see cref="jobManager"/></param>
/// <param name="instanceManager">The value of <see cref="instanceManager"/></param>
/// <param name="ioManager">The value of <see cref="ioManager"/></param>
public InstanceController(IDatabaseContext databaseContext, IAuthenticationContextFactory authenticationContextFactory, IJobManager jobManager, IInstanceManager instanceManager, IIOManager ioManager) : base(databaseContext, authenticationContextFactory)
{
this.jobManager = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
this.instanceManager = instanceManager ?? throw new ArgumentNullException(nameof(instanceManager));
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
}
/// <inheritdoc />
[TgsAuthorize(InstanceManagerRights.Create)]
public override async Task<IActionResult> Create([FromBody] Api.Models.Instance model, CancellationToken cancellationToken)
{
var dirExistsTask = ioManager.DirectoryExists(model.Path, cancellationToken);
if (await ioManager.FileExists(model.Path, cancellationToken).ConfigureAwait(false) || await dirExistsTask.ConfigureAwait(false))
return Conflict(new { message = "Path not empty!" });
var newInstance = new Models.Instance
{
ChatSettings = new ChatSettings(),
ConfigurationAllowed = model.ConfigurationAllowed,
DreamDaemonSettings = new DreamDaemonSettings(),
DreamMakerSettings = new DreamMakerSettings(),
Name = model.Name,
Online = false,
Path = model.Path,
RepositorySettings = new RepositorySettings()
};
DatabaseContext.Instances.Add(newInstance);
try
{
await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);
try
{
//actually reserve it now
await ioManager.CreateDirectory(model.Path, default).ConfigureAwait(false);
}
catch
{
//oh shit delete the model
DatabaseContext.Instances.Remove(newInstance);
DatabaseContext.DreamMakerSettings.Remove(newInstance.DreamMakerSettings);
DatabaseContext.ChatSettings.Remove(newInstance.ChatSettings);
DatabaseContext.RepositorySettings.Remove(newInstance.RepositorySettings);
DatabaseContext.DreamDaemonSettings.Remove(newInstance.DreamDaemonSettings);
await DatabaseContext.Save(default).ConfigureAwait(false);
throw;
}
}
catch (Exception e)
{
return Conflict(new { message = e.Message });
}
model.Online = newInstance.Online;
model.Id = newInstance.Id;
return Json(model);
}
/// <inheritdoc />
[TgsAuthorize(InstanceManagerRights.Relocate | InstanceManagerRights.Rename | InstanceManagerRights.SetAutoUpdate | InstanceManagerRights.SetConfiguration | InstanceManagerRights.SetOnline)]
public override async Task<IActionResult> UpdateAsync([FromBody] Api.Models.Instance model, CancellationToken cancellationToken)
{
var originalModel = await DatabaseContext.Instances.Where(x => x.Id == model.Id).FirstAsync(cancellationToken).ConfigureAwait(false);
if (originalModel == default(Models.Instance))
return StatusCode(HttpStatusCode.Gone);
throw new NotImplementedException();
}
}
}
@@ -50,7 +50,7 @@ namespace Tgstation.Server.Host.Controllers
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the <see cref="IActionResult"/> of the operation</returns>
[HttpPost]
public virtual Task<IActionResult> Update([FromBody]TModel model, CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound());
public virtual Task<IActionResult> UpdateAsync([FromBody]TModel model, CancellationToken cancellationToken) => Task.FromResult((IActionResult)NotFound());
/// <summary>
/// Attempt to delete a <paramref name="model"/>
@@ -144,8 +144,12 @@ namespace Tgstation.Server.Host.Core
/// <inheritdoc />
public Task DeleteFile(string path, CancellationToken cancellationToken) => Task.Factory.StartNew(() => File.Delete(ResolvePath(path)), cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
/// <inheritdoc />
public Task<bool> FileExists(string path, CancellationToken cancellationToken) => Task.Factory.StartNew(() => File.Exists(ResolvePath(path)), cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
/// <inheritdoc />
public Task<bool> DirectoryExists(string path, CancellationToken cancellationToken) => Task.Factory.StartNew(() => Directory.Exists(ResolvePath(path)), cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
/// <inheritdoc />
public string GetDirectoryName(string path) => Path.GetDirectoryName(path ?? throw new ArgumentNullException(nameof(path)));
+9 -1
View File
@@ -7,7 +7,7 @@ namespace Tgstation.Server.Host.Core
/// <summary>
/// Interface for using filesystems
/// </summary>
interface IIOManager
public interface IIOManager
{
/// <summary>
/// Retrieve the full path of some <paramref name="path"/> given a relative path. Must be used before passing relative paths to other APIs. All other operations in this <see langword="interface"/> call this internally on given paths
@@ -48,6 +48,14 @@ namespace Tgstation.Server.Host.Core
/// <returns>A <see cref="Task"/> resulting in <see langword="true"/> if the file at <paramref name="path"/> exists, <see langword="false"/> otherwise</returns>
Task<bool> FileExists(string path, CancellationToken cancellationToken);
/// <summary>
/// Check that the directory at <paramref name="path"/> exists
/// </summary>
/// <param name="path">The directory to check for existence</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param>
/// <returns>A <see cref="Task"/> resulting in <see langword="true"/> if the directory at <paramref name="path"/> exists, <see langword="false"/> otherwise</returns>
Task<bool> DirectoryExists(string path, CancellationToken cancellationToken);
/// <summary>
/// Returns all the contents of a file at <paramref name="path"/> as a <see cref="byte"/> array
/// </summary>
@@ -2,7 +2,9 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
#if !DEBUG
using System.Linq;
#endif
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Host.Configuration;
@@ -31,6 +33,15 @@ namespace Tgstation.Server.Host.Models
/// <inheritdoc />
public DbSet<DreamMakerSettings> DreamMakerSettings { get; set; }
/// <inheritdoc />
public DbSet<ChatSettings> ChatSettings { get; set; }
/// <inheritdoc />
public DbSet<DreamDaemonSettings> DreamDaemonSettings { get; set; }
/// <inheritdoc />
public DbSet<RepositorySettings> RepositorySettings { get; set; }
/// <summary>
/// The <see cref="DbSet{TEntity}"/> for <see cref="Log"/>s
/// </summary>
@@ -40,30 +51,21 @@ namespace Tgstation.Server.Host.Models
/// The <see cref="InstanceUser"/>s in the <see cref="DatabaseContext{TParentContext}"/>
/// </summary>
public DbSet<InstanceUser> InstanceUsers { get; set; }
/// <summary>
/// The <see cref="ChatChannel"/>s in the <see cref="DatabaseContext{TParentContext}"/>
/// </summary>
public DbSet<ChatChannel> ChatChannels { get; set; }
/// <summary>
/// The <see cref="ChatSettings"/>s in the <see cref="DatabaseContext{TParentContext}"/>
/// </summary>
public DbSet<ChatSettings> ChatSettings { get; set; }
/// <summary>
/// The <see cref="Models.DreamDaemonSettings"/> in the <see cref="DatabaseContext{TParentContext}"/>
/// </summary>
public DbSet<DreamDaemonSettings> DreamDaemonSettings { get; set; }
/// <summary>
/// The <see cref="Job"/>s in the <see cref="DatabaseContext{TParentContext}"/>
/// </summary>
public DbSet<Job> Jobs { get; set; }
/// <summary>
/// The <see cref="TestMerge"/>s in the <see cref="DatabaseContext{TParentContext}"/>
/// </summary>
public DbSet<TestMerge> TestMerges { get; set; }
/// <summary>
/// The <see cref="Models.RepositorySettings"/> in the <see cref="DatabaseContext{TParentContext}"/>
/// </summary>
public DbSet<RepositorySettings> RepositorySettings { get; set; }
/// <summary>
/// The connection string for the <see cref="DatabaseContext{TParentContext}"/>
@@ -35,10 +35,25 @@ namespace Tgstation.Server.Host.Models
DbSet<RevisionInformation> RevisionInformations { get; }
/// <summary>
/// The <see cref="DreamMakerSettings"/> in the <see cref="IDatabaseContext"/>
/// The <see cref="Models.DreamMakerSettings"/> in the <see cref="IDatabaseContext"/>
/// </summary>
DbSet<DreamMakerSettings> DreamMakerSettings { get; set; }
/// <summary>
/// The <see cref="Models.DreamDaemonSettings"/> in the <see cref="IDatabaseContext"/>
/// </summary>
DbSet<DreamDaemonSettings> DreamDaemonSettings { get; set; }
/// <summary>
/// The <see cref="Models.ChatSettings"/> in the <see cref="IDatabaseContext"/>
/// </summary>
DbSet<ChatSettings> ChatSettings { get; set; }
/// <summary>
/// The <see cref="Models.RepositorySettings"/> in the <see cref="IDatabaseContext"/>
/// </summary>
DbSet<RepositorySettings> RepositorySettings { get; set; }
/// <summary>
/// Get the <see cref="ServerSettings"/> in the <see cref="IDatabaseContext"/>
/// </summary>