tgstation-server 6.11.3
The /tg/station 13 server suite
Loading...
Searching...
No Matches
InstanceController.cs
Go to the documentation of this file.
1using System;
4using System.IO;
5using System.Linq;
10
15
16using NCrontab;
17
34
36{
41#pragma warning disable CA1506 // TODO: Decomplexify
43 {
47 public const string InstanceAttachFileName = "TGS4_ALLOW_INSTANCE_ATTACH";
48
53
58
63
68
73
78
83
129
138 [HttpPut]
143 {
144 ArgumentNullException.ThrowIfNull(model);
145
146 if (String.IsNullOrWhiteSpace(model.Name) || String.IsNullOrWhiteSpace(model.Path))
147 return BadRequest(new ErrorMessageResponse(ErrorCode.InstanceWhitespaceNameOrPath));
148
150 if (earlyOut != null)
151 return earlyOut;
152
155
158 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceAtConflictingPath));
159
160 // Validate it's not a child of any other instance
162 .Instances
163 .AsQueryable()
164 .Where(x => x.SwarmIdentifer == swarmConfiguration.Identifier)
165 .Select(x => new Models.Instance
166 {
167 Path = x.Path,
168 })
169 .ToListAsync(cancellationToken);
170
172 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceLimitReached));
173
176 .ToArray();
177
178 await Task.WhenAll(instancePathChecks);
179
180 if (instancePathChecks.Any(task => task.Result))
181 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceAtConflictingPath));
182
183 // Last test, ensure it's in the list of valid paths
186 .ToArray()
187 ?? Enumerable.Empty<Task<bool>>();
188 await Task.WhenAll(pathChecks);
189 if (!pathChecks.All(task => task.Result))
190 return BadRequest(new ErrorMessageResponse(ErrorCode.InstanceNotAtWhitelistedPath));
191
193 {
195 return false;
196
199
202
203 return files.Concat(dirs).Any();
204 }
205
207 bool attached = false;
210 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceAtExistingPath));
211 else
212 attached = true;
213
215 if (newInstance == null)
216 return Conflict(new ErrorMessageResponse(ErrorCode.NoPortsAvailable));
217
219 try
220 {
222
223 try
224 {
225 // actually reserve it now
228 }
229 catch
230 {
231 // oh shit delete the model
233
234 // DCT: Operation must always run
235 await DatabaseContext.Save(CancellationToken.None);
236 throw;
237 }
238 }
239 catch (IOException e)
240 {
241 return Conflict(new ErrorMessageResponse(ErrorCode.IOError)
242 {
243 AdditionalData = e.Message,
244 });
245 }
246
247 Logger.LogInformation(
248 "{userName} {attachedOrCreated} instance {instanceName}: {instanceId} ({instancePath})",
250 attached ? "attached" : "created",
251 newInstance.Name,
252 newInstance.Id,
253 newInstance.Path);
254
256 newInstance.InstancePermissionSets.First(),
258
259 var api = newInstance.ToApi();
260 api.Accessible = true; // instances are always accessible by their creator
261 return attached ? Json(api) : this.Created(api);
262 }
263
272 [HttpDelete("{id}")]
276 public async ValueTask<IActionResult> Delete(long id, CancellationToken cancellationToken)
277 {
279 .Instances
280 .AsQueryable()
281 .Where(x => x.Id == id && x.SwarmIdentifer == swarmConfiguration.Identifier)
282 .FirstOrDefaultAsync(cancellationToken);
283 if (originalModel == default)
284 return this.Gone();
285 if (originalModel.Online!.Value)
286 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceDetachOnline));
287
290 try
291 {
294 }
296 {
297 // DCT: Operation must always run
298 await ioManager.DeleteFile(attachFileName, CancellationToken.None);
299 throw;
300 }
301
302 try
303 {
304 // yes this is racy af. I hate it
305 // there's a bug where removing the root instance doesn't work sometimes
308 .AsQueryable()
309 .Where(x => x.Job!.Instance!.Id == id)
310 .ExecuteDeleteAsync(cancellationToken);
313 .AsQueryable()
314 .Where(x => x.RevisionInformation.InstanceId == id)
315 .ExecuteDeleteAsync(cancellationToken);
318 .AsQueryable()
319 .Where(x => x.InstanceId == id)
320 .ExecuteDeleteAsync(cancellationToken);
321
323 await DatabaseContext.Save(cancellationToken); // cascades everything else
324 }
325 catch
326 {
327 await ioManager.DeleteFile(attachFileName, CancellationToken.None); // DCT: Shouldn't be cancelled
328 throw;
329 }
330
331 return NoContent();
332 }
333
343 [HttpPost]
344 [TgsAuthorize(InstanceManagerRights.Relocate | InstanceManagerRights.Rename | InstanceManagerRights.SetAutoUpdate | InstanceManagerRights.SetConfiguration | InstanceManagerRights.SetOnline | InstanceManagerRights.SetChatBotLimit)]
348#pragma warning disable CA1502 // TODO: Decomplexify
350 {
351 ArgumentNullException.ThrowIfNull(model);
352
353 IQueryable<Models.Instance> InstanceQuery() => DatabaseContext
354 .Instances
355 .AsQueryable()
356 .Where(x => x.Id == model.Id && x.SwarmIdentifer == swarmConfiguration.Identifier);
357
359 .SelectMany(x => x.Jobs)
360 .Where(x => !x.StoppedAt.HasValue && x.JobCode == JobCode.Move)
361 .Select(x => new Job(x.Id!.Value))
362 .FirstOrDefaultAsync(cancellationToken);
363
364 if (moveJob != null)
365 {
366 // don't allow them to cancel it if they can't start it.
368 return Forbid();
370 }
371
373 .Include(x => x.RepositorySettings)
374 .Include(x => x.ChatSettings)
375 .ThenInclude(x => x.Channels)
376 .Include(x => x.DreamDaemonSettings) // need these for onlining
377 .FirstOrDefaultAsync(cancellationToken);
378 if (originalModel == default(Models.Instance))
379 return this.Gone();
380
383
386 {
388 var property = (PropertyInfo)memberSelectorExpression.Member;
389
390 var newVal = property.GetValue(model);
391 if (newVal == null)
392 return false;
393 if (!userRights.HasFlag(requiredRight) && property.GetValue(originalModel) != newVal)
394 return true;
395
396 property.SetValue(originalModel, newVal);
397 return false;
398 }
399
400 string? originalModelPath = null;
401 string? normalizedPath = null;
402 var originalOnline = originalModel.Online!.Value;
403 if (model.Path != null)
404 {
406
407 if (normalizedPath != originalModel.Path)
408 {
409 if (!userRights.HasFlag(InstanceManagerRights.Relocate))
410 return Forbid();
411 if (originalOnline && model.Online != true)
412 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceRelocateOnline));
413
416 return Conflict(new ErrorMessageResponse(ErrorCode.InstanceAtExistingPath));
417
420 }
421 }
422
423 var oldAutoUpdateInterval = originalModel.AutoUpdateInterval!.Value;
424 var oldAutoUpdateCron = originalModel.AutoUpdateCron;
425
427 if (earlyOut != null)
428 return earlyOut;
429
431 var changedAutoCron = model.AutoUpdateCron != null && oldAutoUpdateCron != model.AutoUpdateCron;
432
433 var renamed = model.Name != null && originalModel.Name != model.Name;
434
435 if (CheckModified(x => x.AutoUpdateInterval, InstanceManagerRights.SetAutoUpdate)
436 || CheckModified(x => x.AutoUpdateCron, InstanceManagerRights.SetAutoUpdate)
437 || CheckModified(x => x.ConfigurationType, InstanceManagerRights.SetConfiguration)
438 || CheckModified(x => x.Name, InstanceManagerRights.Rename)
439 || CheckModified(x => x.Online, InstanceManagerRights.SetOnline)
440 || CheckModified(x => x.ChatBotLimit, InstanceManagerRights.SetChatBotLimit))
441 return Forbid();
442
443 if (model.ChatBotLimit.HasValue)
444 {
446 .ChatBots
447 .AsQueryable()
448 .Where(x => x.InstanceId == originalModel.Id)
449 .CountAsync(cancellationToken);
450
451 if (countOfExistingChatBots > model.ChatBotLimit.Value)
452 return Conflict(new ErrorMessageResponse(ErrorCode.ChatBotMax));
453 }
454
455 if (changedAutoCron)
457 else if (changedAutoInterval)
459
461
462 if (renamed)
463 {
464 // ignoring retval because we don't care if it's offline
467 {
469 return null;
470 },
472 }
473
474 var oldAutoStart = originalModel.DreamDaemonSettings!.AutoStart;
475 try
476 {
477 if (originalOnline && model.Online == false)
479 else if (!originalOnline && model.Online == true)
480 {
481 // force autostart false here because we don't want any long running jobs right now
482 // remember to document this
485 }
486 }
487 catch (Exception e)
488 {
490 Logger.LogError(e, "Error changing instance online state!");
493 if (originalModelPath != null)
495
496 // DCT: Operation must always run
497 await DatabaseContext.Save(CancellationToken.None);
498 throw;
499 }
500
501 var api = (AuthenticationContext.GetRight(RightsType.InstanceManager) & (ulong)InstanceManagerRights.Read) != 0 ? originalModel.ToApi() : new InstanceResponse
502 {
503 Id = originalModel.Id,
504 };
505
506 var moving = originalModelPath != null;
507 if (moving)
508 {
509 var description = $"Move instance ID {originalModel.Id} from {originalModelPath} to {normalizedPath}";
512
514 job,
515 (core, databaseContextFactory, paramJob, progressHandler, ct) // core will be null here since the instance is offline
518 api.MoveJob = job.ToApi();
519 }
520
522 {
523 // ignoring retval because we don't care if it's offline
526 {
527 await componentInstance.ScheduleAutoUpdate(model.AutoUpdateInterval!.Value, model.AutoUpdateCron);
528 return null;
529 },
531 }
532
534 return moving ? Accepted(api) : Json(api);
535 }
536#pragma warning restore CA1502
537
550 [FromQuery] int? page,
551 [FromQuery] int? pageSize,
552 CancellationToken cancellationToken)
553 {
554 IQueryable<Models.Instance> GetBaseQuery()
555 {
557 .Instances
558 .AsQueryable()
559 .Where(x => x.SwarmIdentifer == swarmConfiguration.Identifier);
561 query = query
562 .Where(x => x.InstancePermissionSets.Any(y => y.PermissionSetId == AuthenticationContext.PermissionSet.Id))
563 .Where(x => x.InstancePermissionSets.Any(instanceUser =>
564 instanceUser.EngineRights != EngineRights.None ||
565 instanceUser.ChatBotRights != ChatBotRights.None ||
566 instanceUser.ConfigurationRights != ConfigurationRights.None ||
567 instanceUser.DreamDaemonRights != DreamDaemonRights.None ||
568 instanceUser.DreamMakerRights != DreamMakerRights.None ||
569 instanceUser.InstancePermissionSetRights != InstancePermissionSetRights.None));
570
571 // Hack for EF IAsyncEnumerable BS
572 return query.Select(x => x);
573 }
574
576 .SelectMany(x => x.Jobs)
577 .Where(x => !x.StoppedAt.HasValue && x.JobCode == JobCode.Move)
578 .Include(x => x.StartedBy!)
579 .ThenInclude(x => x.CreatedBy)
580 .Include(x => x.Instance)
581 .ToListAsync(cancellationToken);
582
583 var needsUpdate = false;
584 var result = await Paginated<Models.Instance, InstanceResponse>(
585 () => ValueTask.FromResult(
588 .OrderBy(x => x.Id))),
589 async instance =>
590 {
592 instance.MoveJob = moveJobs.FirstOrDefault(x => x.Instance!.Id == instance.Id)?.ToApi();
594 },
595 page,
596 pageSize,
598
599 if (needsUpdate)
601
602 return result;
603 }
604
613 [HttpGet("{id}")]
617 public async ValueTask<IActionResult> GetId(long id, CancellationToken cancellationToken)
618 {
620 IQueryable<Models.Instance> QueryForUser()
621 {
623 .Instances
624 .AsQueryable()
625 .Where(x => x.Id == id && x.SwarmIdentifer == swarmConfiguration.Identifier);
626
627 if (cantList)
628 query = query.Include(x => x.InstancePermissionSets);
629 return query;
630 }
631
632 var instance = await QueryForUser().FirstOrDefaultAsync(cancellationToken);
633
634 if (instance == null)
635 return this.Gone();
636
637 if (ValidateInstanceOnlineStatus(instance))
639
640 if (cantList && !instance.InstancePermissionSets.Any(instanceUser => instanceUser.PermissionSetId == AuthenticationContext.PermissionSet.Require(x => x.Id)
641 && (instanceUser.RepositoryRights != RepositoryRights.None ||
642 instanceUser.EngineRights != EngineRights.None ||
643 instanceUser.ChatBotRights != ChatBotRights.None ||
644 instanceUser.ConfigurationRights != ConfigurationRights.None ||
645 instanceUser.DreamDaemonRights != DreamDaemonRights.None ||
646 instanceUser.DreamMakerRights != DreamMakerRights.None ||
647 instanceUser.InstancePermissionSetRights != InstancePermissionSetRights.None)))
648 return Forbid();
649
650 var api = instance.ToApi();
651
653 .SelectMany(x => x.Jobs)
654 .Where(x => !x.StoppedAt.HasValue && x.JobCode == JobCode.Move)
655 .Include(x => x.StartedBy!)
656 .ThenInclude(x => x.CreatedBy)
657 .Include(x => x.Instance)
658 .FirstOrDefaultAsync(cancellationToken);
659 api.MoveJob = moveJob?.ToApi();
661 return Json(api);
662 }
663
671 [HttpPatch("{id}")]
672 [TgsAuthorize(InstanceManagerRights.GrantPermissions)]
676 {
677 IQueryable<Models.Instance> BaseQuery() => DatabaseContext
678 .Instances
679 .AsQueryable()
680 .Where(x => x.Id == id && x.SwarmIdentifer == swarmConfiguration.Identifier);
681
682 // ensure the current user has write privilege on the instance
684 .SelectMany(x => x.InstancePermissionSets)
685 .Where(x => x.PermissionSetId == AuthenticationContext.PermissionSet.Id)
686 .FirstOrDefaultAsync(cancellationToken);
687 if (usersInstancePermissionSet == default)
688 {
689 // does the instance actually exist?
691 .AnyAsync(cancellationToken);
692
693 if (!instanceExists)
694 return this.Gone();
695
699 }
700 else
702
704
705 return NoContent();
706 }
707
715 {
717 if (!ddPort.HasValue)
718 return null;
719
720 // try to use the old default if possible
721 const ushort DefaultDreamDaemonPort = 1337;
722 if (ddPort.Value < DefaultDreamDaemonPort)
724
725 const ushort DefaultApiValidationPort = 1339;
728 Math.Min((ushort)(ddPort.Value + 1), DefaultApiValidationPort),
729 false,
731 if (!dmPort.HasValue)
732 return null;
733
734 // try to use the old default if possible
737
738 return new Models.Instance
739 {
742 {
743 AllowWebClient = false,
744 AutoStart = false,
745 Port = ddPort,
746 OpenDreamTopicPort = 0,
747 SecurityLevel = DreamDaemonSecurity.Safe,
748 Visibility = DreamDaemonVisibility.Public,
749 StartupTimeout = 60,
750 HealthCheckSeconds = 60,
751 DumpOnHealthCheckRestart = false,
752 TopicRequestTimeout = generalConfiguration.ByondTopicTimeout,
753 AdditionalParameters = String.Empty,
754 StartProfiler = false,
755 LogOutput = false,
756 MapThreads = 0,
757 Minidumps = true,
758 },
760 {
761 ApiValidationPort = dmPort,
762 ApiValidationSecurityLevel = DreamDaemonSecurity.Safe,
764 Timeout = TimeSpan.FromHours(1),
765 CompilerAdditionalArguments = null,
766 },
767 Name = initialSettings.Name,
768 Online = false,
769 Path = initialSettings.Path,
770 AutoUpdateInterval = initialSettings.AutoUpdateInterval ?? 0,
771 AutoUpdateCron = initialSettings.AutoUpdateCron ?? String.Empty,
774 {
775 CommitterEmail = Components.Repository.Repository.DefaultCommitterEmail,
776 CommitterName = Components.Repository.Repository.DefaultCommitterName,
777 PushTestMergeCommits = false,
778 ShowTestMergeCommitters = false,
779 AutoUpdatesKeepTestMerges = false,
780 AutoUpdatesSynchronize = false,
781 PostTestMergeComment = false,
782 CreateGitHubDeployments = false,
783 UpdateSubmodules = true,
784 },
785 InstancePermissionSets = new List<InstancePermissionSet> // give this user full privileges on the instance
786 {
788 },
789 SwarmIdentifer = swarmConfiguration.Identifier,
790 };
791 }
792
814
820 [return: NotNullIfNotNull(nameof(path))]
821 string? NormalizePath(string? path)
822 {
823 if (path == null)
824 return null;
825
828
829 return path;
830 }
831
839 {
842 .AsQueryable()
843 .Where(x => x.InstanceId == instanceResponse.Id && x.PermissionSetId == AuthenticationContext.PermissionSet.Id)
844 .AnyAsync(cancellationToken);
845 }
846
853 {
854 if (!String.IsNullOrWhiteSpace(instance.AutoUpdateCron))
855 {
856 if ((instance.AutoUpdateInterval.HasValue && instance.AutoUpdateInterval.Value != 0)
857 || (CrontabSchedule.TryParse(
858 instance.AutoUpdateCron,
859 new CrontabSchedule.ParseOptions
860 {
861 IncludingSeconds = true,
862 }) == null))
863 return BadRequest(new ErrorMessageResponse(ErrorCode.ModelValidationFailure));
864
866 }
867 else
869
870 return null;
871 }
872 }
873}
List< string >? ValidInstancePaths
Limits the locations instances may be created or attached from.
uint InstanceLimit
The maximum number of Instances allowed.
string? Identifier
The server's identifier.
Represents a set of server permissions.
InstanceManagerRights? InstanceManagerRights
The Rights.InstanceManagerRights for the user.
Represents configurable settings for a git repository.
Represents an error message returned by the server.
Routes to a server actions.
Definition Routes.cs:9
const string InstanceManager
The Models.Instance controller.
Definition Routes.cs:48
const string List
The postfix for list operations.
Definition Routes.cs:113
uint ByondTopicTimeout
The timeout in milliseconds for sending and receiving topics to/from DreamDaemon. Note that a single ...
Configuration for the server swarm system.
ILogger< ApiController > Logger
The ILogger for the ApiController.
async ValueTask< IActionResult?> WithComponentInstanceNullable(Func< IInstanceCore, ValueTask< IActionResult?> > action, Models.Instance? instance=null)
Run a given action with the relevant IInstance.
IInstanceOperations InstanceOperations
Access the IInstanceOperations instance.
readonly IInstanceManager instanceManager
The IInstanceManager for the ComponentInterfacingController.
bool ValidateInstanceOnlineStatus(Api.Models.Instance metadata)
Corrects discrepencies between the Api.Models.Instance.Online status of IInstances in the database vs...
ApiController for managing Components.Instances.
async ValueTask< Models.Instance?> CreateDefaultInstance(InstanceCreateRequest initialSettings, CancellationToken cancellationToken)
Creates a default Models.Instance from initialSettings .
async ValueTask< IActionResult > GetId(long id, CancellationToken cancellationToken)
Get a specific Api.Models.Instance.
InstanceController(IDatabaseContext databaseContext, IAuthenticationContext authenticationContext, ILogger< InstanceController > logger, IInstanceManager instanceManager, IJobManager jobManager, IIOManager ioManager, IPlatformIdentifier platformIdentifier, IPortAllocator portAllocator, IPermissionsUpdateNotifyee permissionsUpdateNotifyee, IOptions< GeneralConfiguration > generalConfigurationOptions, IOptions< SwarmConfiguration > swarmConfigurationOptions, IApiHeadersProvider apiHeaders)
Initializes a new instance of the InstanceController class.
readonly IJobManager jobManager
The IJobManager for the InstanceController.
readonly GeneralConfiguration generalConfiguration
The GeneralConfiguration for the InstanceController.
BadRequestObjectResult? ValidateCronSetting(Api.Models.Instance instance)
Validates a given instance 's Api.Models.Instance.AutoUpdateCron setting.
string? NormalizePath(string? path)
Normalize a given path for an instance.
readonly IPortAllocator portAllocator
The IPortAllocator for the InstanceController.
async ValueTask< IActionResult > Update([FromBody] InstanceUpdateRequest model, CancellationToken cancellationToken)
Modify an Api.Models.Instance's settings.
InstancePermissionSet InstanceAdminPermissionSet(InstancePermissionSet? permissionSetToModify)
Generate an InstancePermissionSet with full rights.
readonly SwarmConfiguration swarmConfiguration
The SwarmConfiguration for the InstanceController.
async ValueTask< IActionResult > List([FromQuery] int? page, [FromQuery] int? pageSize, CancellationToken cancellationToken)
List Api.Models.Instances.
const string InstanceAttachFileName
File name to allow attaching instances.
async ValueTask< IActionResult > Create([FromBody] InstanceCreateRequest model, CancellationToken cancellationToken)
Create or attach an Api.Models.Instance.
readonly IPlatformIdentifier platformIdentifier
The IPlatformIdentifier for the InstanceController.
readonly IPermissionsUpdateNotifyee permissionsUpdateNotifyee
The IPermissionsUpdateNotifyee for the InstanceController.
async ValueTask< IActionResult > Delete(long id, CancellationToken cancellationToken)
Detach an Api.Models.Instance with the given id .
async ValueTask CheckAccessible(InstanceResponse instanceResponse, CancellationToken cancellationToken)
Populate the InstanceResponse.Accessible property of a given instanceResponse .
readonly IIOManager ioManager
The IIOManager for the InstanceController.
async ValueTask< IActionResult > GrantPermissions(long id, CancellationToken cancellationToken)
Gives the current user full permissions on a given instance id .
Backend abstract implementation of IDatabaseContext.
DbSet< Instance > Instances
The Instances in the DatabaseContext.
DbSet< InstancePermissionSet > InstancePermissionSets
The InstancePermissionSets in the DatabaseContext.
DbSet< CompileJob > CompileJobs
The CompileJobs in the DatabaseContext.
Task Save(CancellationToken cancellationToken)
Saves changes made to the IDatabaseContext.A Task representing the running operation.
DbSet< ChatBot > ChatBots
The ChatBots in the DatabaseContext.
DbSet< RevInfoTestMerge > RevInfoTestMerges
The RevInfoTestMerges in the DatabaseContext.
DbSet< RevisionInformation > RevisionInformations
The RevisionInformations in the DatabaseContext.
IIOManager that resolves paths to Environment.CurrentDirectory.
const string CurrentDirectory
Path to the current working directory for the IIOManager.
Instance? Instance
The parent Models.Instance.
Represents an Api.Models.Instance in the database.
Definition Instance.cs:11
const ushort DefaultChatBotLimit
Default for Api.Models.Instance.ChatBotLimit.
Definition Instance.cs:15
static Job Create(JobCode code, User? startedBy, Api.Models.Instance instance)
Creates a new job for registering in the Jobs.IJobService.
PermissionSet PermissionSet
The User's effective PermissionSet.
ulong GetRight(RightsType rightsType)
Get the value of a given rightsType .The value of rightsType . Note that if InstancePermissionSet is ...
ValueTask OnlineInstance(Models.Instance metadata, CancellationToken cancellationToken)
Online an IInstance.
ValueTask MoveInstance(Models.Instance metadata, string oldPath, CancellationToken cancellationToken)
Move an IInstance.
ValueTask OfflineInstance(Models.Instance metadata, User user, CancellationToken cancellationToken)
Offline an IInstance.
Interface for using filesystems.
Definition IIOManager.cs:13
Task< IReadOnlyList< string > > GetFiles(string path, CancellationToken cancellationToken)
Returns full file names in a given path .
Task< bool > PathIsChildOf(string parentPath, string childPath, CancellationToken cancellationToken)
Check if a given parentPath is a parent of a given parentPath .
string ResolvePath()
Retrieve the full path of the current working directory.
string ConcatPath(params string[] paths)
Combines an array of strings into a path.
Task< IReadOnlyList< string > > GetDirectories(string path, CancellationToken cancellationToken)
Returns full directory names in a given path .
Task CreateDirectory(string path, CancellationToken cancellationToken)
Create a directory at path .
Task DeleteFile(string path, CancellationToken cancellationToken)
Deletes a file at path .
ValueTask WriteAllBytes(string path, byte[] contents, CancellationToken cancellationToken)
Writes some contents to a file at path overwriting previous content.
Task< bool > FileExists(string path, CancellationToken cancellationToken)
Check that the file at path exists.
Task< bool > DirectoryExists(string path, CancellationToken cancellationToken)
Check that the directory at path exists.
Manages the runtime of Jobs.
ValueTask< Job?> CancelJob(Job job, User? user, bool blocking, CancellationToken cancellationToken)
Cancels a give job .
ValueTask RegisterOperation(Job job, JobEntrypoint operation, CancellationToken cancellationToken)
Registers a given Job and begins running it.
For creating and accessing authentication contexts.
Receives notifications about permissions updates.
ValueTask InstancePermissionSetCreated(InstancePermissionSet instancePermissionSet, CancellationToken cancellationToken)
Called when a given instancePermissionSet is successfully created.
For identifying the current platform.
string NormalizePath(string path)
Normalize a path for consistency.
Gets unassigned ports for use by TGS.
ValueTask< ushort?> GetAvailablePort(ushort basePort, bool checkOne, CancellationToken cancellationToken)
Gets a port not currently in use by TGS.
ErrorCode
Types of Response.ErrorMessageResponses that the API may return.
Definition ErrorCode.cs:12
DreamDaemonVisibility
The visibility setting for DreamDaemon.
JobCode
The different types of Response.JobResponse.
Definition JobCode.cs:9
ConfigurationType
The type of configuration allowed on an Instance.
@ Online
The watchdog is online and DreamDaemon is running.
DreamDaemonSecurity
DreamDaemon's security level.
DMApiValidationMode
The DMAPI validation setting for deployments.
ChatBotRights
Rights for chat bots.
ConfigurationRights
Rights for Models.IConfigurationFiles.
@ List
User may list files if the Models.Instance allows it.
DreamMakerRights
Rights for deployment.
RightsType
The type of rights a model uses.
Definition RightsType.cs:7
EngineRights
Rights for engine version management.
RepositoryRights
Rights for the git repository.
InstancePermissionSetRights
Rights for an Models.Instance.
DreamDaemonRights
Rights for managing DreamDaemon.
InstanceManagerRights
Rights for managing Models.Instances.
@ Api
The ApiHeaders.ApiVersionHeader header is missing or invalid.