Ejemplo n.º 1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BasicWatchdog"/> <see langword="class"/>.
 /// </summary>
 /// <param name="chat">The <see cref="IChatManager"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="sessionControllerFactory">The <see cref="ISessionControllerFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="dmbFactory">The <see cref="IDmbFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="sessionPersistor">The <see cref="ISessionPersistor"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="jobManager">The <see cref="IJobManager"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="serverControl">The <see cref="IServerControl"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="diagnosticsIOManager">The <see cref="IIOManager"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="eventConsumer">The <see cref="IEventConsumer"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="remoteDeploymentManagerFactory">The <see cref="IRemoteDeploymentManagerFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="logger">The <see cref="ILogger"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="initialLaunchParameters">The <see cref="DreamDaemonLaunchParameters"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="instance">The <see cref="Api.Models.Instance"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="autoStart">The autostart value for the <see cref="WatchdogBase"/>.</param>
 public BasicWatchdog(
     IChatManager chat,
     ISessionControllerFactory sessionControllerFactory,
     IDmbFactory dmbFactory,
     ISessionPersistor sessionPersistor,
     IJobManager jobManager,
     IServerControl serverControl,
     IAsyncDelayer asyncDelayer,
     IIOManager diagnosticsIOManager,
     IEventConsumer eventConsumer,
     IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
     ILogger <BasicWatchdog> logger,
     DreamDaemonLaunchParameters initialLaunchParameters,
     Api.Models.Instance instance,
     bool autoStart)
     : base(
         chat,
         sessionControllerFactory,
         dmbFactory,
         sessionPersistor,
         jobManager,
         serverControl,
         asyncDelayer,
         diagnosticsIOManager,
         eventConsumer,
         remoteDeploymentManagerFactory,
         logger,
         initialLaunchParameters,
         instance,
         autoStart)
 {
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BasicWatchdog"/> <see langword="class"/>.
 /// </summary>
 /// <param name="chat">The <see cref="IChatManager"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="sessionControllerFactory">The <see cref="ISessionControllerFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="dmbFactory">The <see cref="IDmbFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="reattachInfoHandler">The <see cref="IReattachInfoHandler"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="databaseContextFactory">The <see cref="IDatabaseContextFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="jobManager">The <see cref="IJobManager"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="serverControl">The <see cref="IServerControl"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="logger">The <see cref="ILogger"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="initialLaunchParameters">The <see cref="DreamDaemonLaunchParameters"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="instance">The <see cref="Api.Models.Instance"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="autoStart">The autostart value for the <see cref="WatchdogBase"/>.</param>
 public BasicWatchdog(
     IChatManager chat,
     ISessionControllerFactory sessionControllerFactory,
     IDmbFactory dmbFactory,
     IReattachInfoHandler reattachInfoHandler,
     IDatabaseContextFactory databaseContextFactory,
     IJobManager jobManager,
     IServerControl serverControl,
     IAsyncDelayer asyncDelayer,
     ILogger <BasicWatchdog> logger,
     DreamDaemonLaunchParameters initialLaunchParameters,
     Api.Models.Instance instance,
     bool autoStart)
     : base(
         chat,
         sessionControllerFactory,
         dmbFactory,
         reattachInfoHandler,
         databaseContextFactory,
         jobManager,
         serverControl,
         asyncDelayer,
         logger,
         initialLaunchParameters,
         instance,
         autoStart)
 {
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DreamMaker"/> class.
        /// </summary>
        /// <param name="byond">The value of <see cref="byond"/>.</param>
        /// <param name="ioManager">The value of <see cref="ioManager"/>.</param>
        /// <param name="configuration">The value of <see cref="configuration"/>.</param>
        /// <param name="sessionControllerFactory">The value of <see cref="sessionControllerFactory"/>.</param>
        /// <param name="eventConsumer">The value of <see cref="eventConsumer"/>.</param>
        /// <param name="chatManager">The value of <see cref="chatManager"/>.</param>
        /// <param name="processExecutor">The value of <see cref="processExecutor"/>.</param>
        /// <param name="compileJobConsumer">The value of <see cref="compileJobConsumer"/>.</param>
        /// <param name="repositoryManager">The value of <see cref="repositoryManager"/>.</param>
        /// <param name="remoteDeploymentManagerFactory">The value of <see cref="remoteDeploymentManagerFactory"/>.</param>
        /// <param name="logger">The value of <see cref="logger"/>.</param>
        /// <param name="metadata">The value of <see cref="metadata"/>.</param>
        public DreamMaker(
            IByondManager byond,
            IIOManager ioManager,
            StaticFiles.IConfiguration configuration,
            ISessionControllerFactory sessionControllerFactory,
            IEventConsumer eventConsumer,
            IChatManager chatManager,
            IProcessExecutor processExecutor,
            ICompileJobSink compileJobConsumer,
            IRepositoryManager repositoryManager,
            IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
            ILogger <DreamMaker> logger,
            Api.Models.Instance metadata)
        {
            this.byond                          = byond ?? throw new ArgumentNullException(nameof(byond));
            this.ioManager                      = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
            this.configuration                  = configuration ?? throw new ArgumentNullException(nameof(configuration));
            this.sessionControllerFactory       = sessionControllerFactory ?? throw new ArgumentNullException(nameof(sessionControllerFactory));
            this.eventConsumer                  = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
            this.chatManager                    = chatManager ?? throw new ArgumentNullException(nameof(chatManager));
            this.processExecutor                = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
            this.compileJobConsumer             = compileJobConsumer ?? throw new ArgumentNullException(nameof(compileJobConsumer));
            this.repositoryManager              = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager));
            this.remoteDeploymentManagerFactory = remoteDeploymentManagerFactory ?? throw new ArgumentNullException(nameof(remoteDeploymentManagerFactory));
            this.logger                         = logger ?? throw new ArgumentNullException(nameof(logger));
            this.metadata                       = metadata ?? throw new ArgumentNullException(nameof(metadata));

            deploymentLock = new object();
        }
 /// <inheritdoc />
 protected override IWatchdog CreateNonExperimentalWatchdog(
     IChat chat,
     IDmbFactory dmbFactory,
     IReattachInfoHandler reattachInfoHandler,
     IEventConsumer eventConsumer,
     ISessionControllerFactory sessionControllerFactory,
     IIOManager ioManager,
     Api.Models.Instance instance,
     DreamDaemonSettings settings)
 => new WindowsWatchdog(
     chat,
     sessionControllerFactory,
     dmbFactory,
     reattachInfoHandler,
     DatabaseContextFactory,
     ByondTopicSender,
     eventConsumer,
     JobManager,
     ServerControl,
     AsyncDelayer,
     ioManager,
     symlinkFactory,
     LoggerFactory.CreateLogger <WindowsWatchdog>(),
     settings,
     instance,
     settings.AutoStart.Value);
 /// <summary>
 /// Construct a <see cref="ReattachInfoHandler"/>
 /// </summary>
 /// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/></param>
 /// <param name="dmbFactory">The value of <see cref="dmbFactory"/></param>
 /// <param name="logger">The value of <see cref="logger"/></param>
 /// <param name="metadata">The value of <see cref="metadata"/></param>
 public ReattachInfoHandler(IDatabaseContextFactory databaseContextFactory, IDmbFactory dmbFactory, ILogger <ReattachInfoHandler> logger, Api.Models.Instance metadata)
 {
     this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
     this.dmbFactory             = dmbFactory ?? throw new ArgumentNullException(nameof(dmbFactory));
     this.logger   = logger ?? throw new ArgumentNullException(nameof(logger));
     this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Construct a <see cref="SessionControllerFactory"/>
 /// </summary>
 /// <param name="processExecutor">The value of <see cref="processExecutor"/></param>
 /// <param name="byond">The value of <see cref="byond"/></param>
 /// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
 /// <param name="cryptographySuite">The value of <see cref="cryptographySuite"/></param>
 /// <param name="application">The value of <see cref="application"/></param>
 /// <param name="instance">The value of <see cref="instance"/></param>
 /// <param name="ioManager">The value of <see cref="ioManager"/></param>
 /// <param name="chat">The value of <see cref="chat"/></param>
 /// <param name="networkPromptReaper">The value of <see cref="networkPromptReaper"/></param>
 /// <param name="platformIdentifier">The value of <see cref="platformIdentifier"/></param>
 /// <param name="loggerFactory">The value of <see cref="loggerFactory"/></param>
 public SessionControllerFactory(
     IProcessExecutor processExecutor,
     IByondManager byond,
     IByondTopicSender byondTopicSender,
     ICryptographySuite cryptographySuite,
     IApplication application,
     IIOManager ioManager,
     IChat chat,
     INetworkPromptReaper networkPromptReaper,
     IPlatformIdentifier platformIdentifier,
     ILoggerFactory loggerFactory,
     Api.Models.Instance instance)
 {
     this.processExecutor   = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
     this.byond             = byond ?? throw new ArgumentNullException(nameof(byond));
     this.byondTopicSender  = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
     this.cryptographySuite = cryptographySuite ?? throw new ArgumentNullException(nameof(cryptographySuite));
     this.application       = application ?? throw new ArgumentNullException(nameof(application));
     this.instance          = instance ?? throw new ArgumentNullException(nameof(instance));
     this.ioManager         = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
     this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
     this.networkPromptReaper = networkPromptReaper ?? throw new ArgumentNullException(nameof(networkPromptReaper));
     this.platformIdentifier  = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier));
     this.loggerFactory       = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Construct a <see cref="IWatchdog"/>
        /// </summary>
        /// <param name="chat">The value of <see cref="chat"/></param>
        /// <param name="sessionControllerFactory">The value of <see cref="sessionControllerFactory"/></param>
        /// <param name="dmbFactory">The value of <see cref="dmbFactory"/></param>
        /// <param name="serverUpdater">The <see cref="IServerControl"/> for the <see cref="Watchdog"/></param>
        /// <param name="logger">The value of <see cref="logger"/></param>
        /// <param name="reattachInfoHandler">The value of <see cref="reattachInfoHandler"/></param>
        /// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/></param>
        /// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
        /// <param name="initialLaunchParameters">The initial value of <see cref="ActiveLaunchParameters"/></param>
        /// <param name="instance">The value of <see cref="instance"/></param>
        /// <param name="autoStart">The value of <see cref="autoStart"/></param>
        /// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
        public Watchdog(IChat chat, ISessionControllerFactory sessionControllerFactory, IDmbFactory dmbFactory, IServerControl serverUpdater, ILogger <Watchdog> logger, IReattachInfoHandler reattachInfoHandler, IDatabaseContextFactory databaseContextFactory, IByondTopicSender byondTopicSender, IEventConsumer eventConsumer, DreamDaemonLaunchParameters initialLaunchParameters, Api.Models.Instance instance, bool autoStart)
        {
            this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
            this.sessionControllerFactory = sessionControllerFactory ?? throw new ArgumentNullException(nameof(sessionControllerFactory));
            this.dmbFactory             = dmbFactory ?? throw new ArgumentNullException(nameof(dmbFactory));
            this.logger                 = logger ?? throw new ArgumentNullException(nameof(logger));
            this.reattachInfoHandler    = reattachInfoHandler ?? throw new ArgumentNullException(nameof(reattachInfoHandler));
            this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
            this.byondTopicSender       = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
            this.eventConsumer          = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
            this.instance               = instance ?? throw new ArgumentNullException(nameof(instance));
            this.autoStart              = autoStart;

            if (serverUpdater == null)
            {
                throw new ArgumentNullException(nameof(serverUpdater));
            }

            serverUpdater.RegisterForRestart(() => releaseServers = true);

            chat.RegisterCommandHandler(this);

            AlphaIsActive          = true;
            ActiveLaunchParameters = initialLaunchParameters;
            releaseServers         = false;
            semaphore = new SemaphoreSlim(1);
            activeParametersUpdated = new TaskCompletionSource <object>();
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Construct an <see cref="Instance"/>
 /// </summary>
 /// <param name="metadata">The value of <see cref="metadata"/></param>
 /// <param name="repositoryManager">The value of <see cref="RepositoryManager"/></param>
 /// <param name="byondManager">The value of <see cref="ByondManager"/></param>
 /// <param name="dreamMaker">The value of <see cref="dreamMaker"/></param>
 /// <param name="watchdog">The value of <see cref="Watchdog"/></param>
 /// <param name="chat">The value of <see cref="Chat"/></param>
 /// <param name="configuration">The value of <see cref="Configuration"/></param>
 /// <param name="compileJobConsumer">The value of <see cref="compileJobConsumer"/></param>
 /// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/></param>
 /// <param name="dmbFactory">The value of <see cref="dmbFactory"/></param>
 /// <param name="jobManager">The value of <see cref="jobManager"/></param>
 /// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
 /// <param name="gitHubClientFactory">The value of <see cref="gitHubClientFactory"/></param>
 /// <param name="logger">The value of <see cref="logger"/></param>
 public Instance(
     Api.Models.Instance metadata,
     IRepositoryManager repositoryManager,
     IByondManager byondManager,
     IDreamMaker dreamMaker,
     IWatchdog watchdog,
     IChat chat,
     StaticFiles.IConfiguration
     configuration,
     ICompileJobConsumer compileJobConsumer,
     IDatabaseContextFactory databaseContextFactory,
     IDmbFactory dmbFactory,
     IJobManager jobManager,
     IEventConsumer eventConsumer,
     IGitHubClientFactory gitHubClientFactory,
     ILogger <Instance> logger)
 {
     this.metadata     = metadata ?? throw new ArgumentNullException(nameof(metadata));
     RepositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager));
     ByondManager      = byondManager ?? throw new ArgumentNullException(nameof(byondManager));
     this.dreamMaker   = dreamMaker ?? throw new ArgumentNullException(nameof(dreamMaker));
     Watchdog          = watchdog ?? throw new ArgumentNullException(nameof(watchdog));
     Chat                        = chat ?? throw new ArgumentNullException(nameof(chat));
     Configuration               = configuration ?? throw new ArgumentNullException(nameof(configuration));
     this.compileJobConsumer     = compileJobConsumer ?? throw new ArgumentNullException(nameof(compileJobConsumer));
     this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
     this.dmbFactory             = dmbFactory ?? throw new ArgumentNullException(nameof(dmbFactory));
     this.jobManager             = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
     this.eventConsumer          = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
     this.gitHubClientFactory    = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory));
     this.logger                 = logger ?? throw new ArgumentNullException(nameof(logger));
 }
        /// <inheritdoc />
        public IWatchdog CreateWatchdog(
            IChat chat,
            IDmbFactory dmbFactory,
            IReattachInfoHandler reattachInfoHandler,
            IEventConsumer eventConsumer,
            ISessionControllerFactory sessionControllerFactory,
            IIOManager ioManager,
            Api.Models.Instance instance,
            DreamDaemonSettings settings)
        {
            if (GeneralConfiguration.UseExperimentalWatchdog)
            {
                return(new ExperimentalWatchdog(
                           chat,
                           sessionControllerFactory,
                           dmbFactory,
                           reattachInfoHandler,
                           DatabaseContextFactory,
                           ByondTopicSender,
                           eventConsumer,
                           JobManager,
                           ServerControl,
                           AsyncDelayer,
                           LoggerFactory.CreateLogger <ExperimentalWatchdog>(),
                           settings,
                           instance,
                           settings.AutoStart.Value));
            }

            return(CreateNonExperimentalWatchdog(chat, dmbFactory, reattachInfoHandler, eventConsumer, sessionControllerFactory, ioManager, instance, settings));
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Construct an <see cref="Instance"/>
        /// </summary>
        /// <param name="metadata">The value of <see cref="metadata"/></param>
        /// <param name="repositoryManager">The value of <see cref="RepositoryManager"/></param>
        /// <param name="byondManager">The value of <see cref="ByondManager"/></param>
        /// <param name="dreamMaker">The value of <see cref="DreamMaker"/></param>
        /// <param name="watchdog">The value of <see cref="Watchdog"/></param>
        /// <param name="chat">The value of <see cref="Chat"/></param>
        /// <param name="configuration">The value of <see cref="Configuration"/></param>
        /// <param name="dmbFactory">The value of <see cref="dmbFactory"/></param>
        /// <param name="jobManager">The value of <see cref="jobManager"/></param>
        /// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
        /// <param name="remoteDeploymentManagerFactory">The value of <see cref="remoteDeploymentManagerFactory"/>.</param>
        /// <param name="logger">The value of <see cref="logger"/></param>
        public Instance(
            Api.Models.Instance metadata,
            IRepositoryManager repositoryManager,
            IByondManager byondManager,
            IDreamMaker dreamMaker,
            IWatchdog watchdog,
            IChatManager chat,
            StaticFiles.IConfiguration
            configuration,
            IDmbFactory dmbFactory,
            IJobManager jobManager,
            IEventConsumer eventConsumer,
            IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
            ILogger <Instance> logger)
        {
            this.metadata     = metadata ?? throw new ArgumentNullException(nameof(metadata));
            RepositoryManager = repositoryManager ?? throw new ArgumentNullException(nameof(repositoryManager));
            ByondManager      = byondManager ?? throw new ArgumentNullException(nameof(byondManager));
            DreamMaker        = dreamMaker ?? throw new ArgumentNullException(nameof(dreamMaker));
            Watchdog          = watchdog ?? throw new ArgumentNullException(nameof(watchdog));
            Chat               = chat ?? throw new ArgumentNullException(nameof(chat));
            Configuration      = configuration ?? throw new ArgumentNullException(nameof(configuration));
            this.dmbFactory    = dmbFactory ?? throw new ArgumentNullException(nameof(dmbFactory));
            this.jobManager    = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
            this.eventConsumer = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
            this.remoteDeploymentManagerFactory = remoteDeploymentManagerFactory ?? throw new ArgumentNullException(nameof(remoteDeploymentManagerFactory));
            this.logger = logger ?? throw new ArgumentNullException(nameof(logger));

            timerLock = new object();
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GitHubRemoteDeploymentManager"/> <see langword="class"/>.
 /// </summary>
 /// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/>.</param>
 /// <param name="gitHubClientFactory">The value of <see cref="gitHubClientFactory"/>.</param>
 /// <param name="logger">The <see cref="ILogger"/> for the <see cref="BaseRemoteDeploymentManager"/>.</param>
 /// <param name="metadata">The <see cref="Api.Models.Instance"/> for the <see cref="BaseRemoteDeploymentManager"/>.</param>
 public GitHubRemoteDeploymentManager(
     IDatabaseContextFactory databaseContextFactory,
     IGitHubClientFactory gitHubClientFactory,
     ILogger <GitHubRemoteDeploymentManager> logger,
     Api.Models.Instance metadata)
     : base(logger, metadata)
 {
     this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
     this.gitHubClientFactory    = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory));
 }
Ejemplo n.º 12
0
 /// <inheritdoc />
 public virtual IWatchdog CreateWatchdog(
     IChatManager chat,
     IDmbFactory dmbFactory,
     ISessionPersistor sessionPersistor,
     ISessionControllerFactory sessionControllerFactory,
     IIOManager gameIOManager,
     IIOManager diagnosticsIOManager,
     IEventConsumer eventConsumer,
     Api.Models.Instance instance,
     DreamDaemonSettings settings)
 => new BasicWatchdog(
Ejemplo n.º 13
0
        /// <summary>
        /// Construct a <see cref="DmbFactory"/>
        /// </summary>
        /// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/></param>
        /// <param name="ioManager">The value of <see cref="ioManager"/></param>
        /// <param name="logger">The value of <see cref="logger"/></param>
        /// <param name="instance">The value of <see cref="instance"/></param>
        public DmbFactory(IDatabaseContextFactory databaseContextFactory, IIOManager ioManager, ILogger <DmbFactory> logger, Api.Models.Instance instance)
        {
            this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
            this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
            this.logger    = logger ?? throw new ArgumentNullException(nameof(logger));
            this.instance  = instance ?? throw new ArgumentNullException(nameof(instance));

            cleanupTask   = Task.CompletedTask;
            newerDmbTcs   = new TaskCompletionSource <object>();
            cleanupCts    = new CancellationTokenSource();
            jobLockCounts = new Dictionary <long, int>();
        }
Ejemplo n.º 14
0
 /// <inheritdoc />
 public override IWatchdog CreateWatchdog(
     IChatManager chat,
     IDmbFactory dmbFactory,
     ISessionPersistor sessionPersistor,
     ISessionControllerFactory sessionControllerFactory,
     IIOManager gameIOManager,
     IIOManager diagnosticsIOManager,
     IEventConsumer eventConsumer,
     IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
     Api.Models.Instance instance,
     DreamDaemonSettings settings)
 => new WindowsWatchdog(
Ejemplo n.º 15
0
 /// <summary>
 /// Construct a <see cref="WatchdogFactory"/>
 /// </summary>
 /// <param name="chat">The value of <see cref="chat"/></param>
 /// <param name="sessionControllerFactory">The value of <see cref="sessionControllerFactory"/></param>
 /// <param name="serverUpdater">The value of <see cref="serverUpdater"/></param>
 /// <param name="loggerFactory">The value of <see cref="loggerFactory"/></param>
 /// <param name="reattachInfoHandler">The value of <see cref="reattachInfoHandler"/></param>
 /// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/></param>
 /// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
 /// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
 /// <param name="instance">The value of <see cref="instance"/></param>
 public WatchdogFactory(IChat chat, ISessionControllerFactory sessionControllerFactory, IServerControl serverUpdater, ILoggerFactory loggerFactory, IReattachInfoHandler reattachInfoHandler, IDatabaseContextFactory databaseContextFactory, IByondTopicSender byondTopicSender, IEventConsumer eventConsumer, Api.Models.Instance instance)
 {
     this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
     this.sessionControllerFactory = sessionControllerFactory ?? throw new ArgumentNullException(nameof(sessionControllerFactory));
     this.serverUpdater            = serverUpdater ?? throw new ArgumentNullException(nameof(serverUpdater));
     this.loggerFactory            = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
     this.reattachInfoHandler      = reattachInfoHandler ?? throw new ArgumentNullException(nameof(reattachInfoHandler));
     this.databaseContextFactory   = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
     this.byondTopicSender         = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
     this.eventConsumer            = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
     this.instance = instance ?? throw new ArgumentNullException(nameof(instance));
 }
Ejemplo n.º 16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WatchdogBase"/> <see langword="class"/>.
        /// </summary>
        /// <param name="chat">The value of <see cref="Chat"/></param>
        /// <param name="sessionControllerFactory">The value of <see cref="SessionControllerFactory"/></param>
        /// <param name="dmbFactory">The value of <see cref="DmbFactory"/></param>
        /// <param name="reattachInfoHandler">The value of <see cref="reattachInfoHandler"/></param>
        /// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/></param>
        /// <param name="byondTopicSender">The value of <see cref="byondTopicSender"/></param>
        /// <param name="eventConsumer">The value of <see cref="eventConsumer"/></param>
        /// <param name="jobManager">The value of <see cref="jobManager"/></param>
        /// <param name="serverControl">The <see cref="IServerControl"/> to populate <see cref="restartRegistration"/> with</param>
        /// <param name="asyncDelayer">The value of <see cref="AsyncDelayer"/>.</param>
        /// <param name="logger">The value of <see cref="Logger"/></param>
        /// <param name="initialLaunchParameters">The initial value of <see cref="ActiveLaunchParameters"/>. May be modified</param>
        /// <param name="instance">The value of <see cref="instance"/></param>
        /// <param name="autoStart">The value of <see cref="autoStart"/></param>
        protected WatchdogBase(
            IChat chat,
            ISessionControllerFactory sessionControllerFactory,
            IDmbFactory dmbFactory,
            IReattachInfoHandler reattachInfoHandler,
            IDatabaseContextFactory databaseContextFactory,
            IByondTopicSender byondTopicSender,
            IEventConsumer eventConsumer,
            IJobManager jobManager,
            IServerControl serverControl,
            IAsyncDelayer asyncDelayer,
            ILogger logger,
            DreamDaemonLaunchParameters initialLaunchParameters,
            Api.Models.Instance instance,
            bool autoStart)
        {
            Chat = chat ?? throw new ArgumentNullException(nameof(chat));
            SessionControllerFactory = sessionControllerFactory ?? throw new ArgumentNullException(nameof(sessionControllerFactory));
            DmbFactory                  = dmbFactory ?? throw new ArgumentNullException(nameof(dmbFactory));
            AsyncDelayer                = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
            this.reattachInfoHandler    = reattachInfoHandler ?? throw new ArgumentNullException(nameof(reattachInfoHandler));
            this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
            this.byondTopicSender       = byondTopicSender ?? throw new ArgumentNullException(nameof(byondTopicSender));
            this.eventConsumer          = eventConsumer ?? throw new ArgumentNullException(nameof(eventConsumer));
            this.jobManager             = jobManager ?? throw new ArgumentNullException(nameof(jobManager));
            Logger = logger ?? throw new ArgumentNullException(nameof(logger));
            ActiveLaunchParameters = initialLaunchParameters ?? throw new ArgumentNullException(nameof(initialLaunchParameters));
            this.instance          = instance ?? throw new ArgumentNullException(nameof(instance));
            this.autoStart         = autoStart;

            if (serverControl == null)
            {
                throw new ArgumentNullException(nameof(serverControl));
            }

            chat.RegisterCommandHandler(this);

            ActiveLaunchParameters  = initialLaunchParameters;
            releaseServers          = false;
            ActiveParametersUpdated = new TaskCompletionSource <object>();

            restartRegistration = serverControl.RegisterForRestart(this);
            try
            {
                Semaphore = new SemaphoreSlim(1);
            }
            catch
            {
                restartRegistration.Dispose();
                throw;
            }
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Construct a <see cref="SessionPersistor"/>
 /// </summary>
 /// <param name="databaseContextFactory">The value of <see cref="databaseContextFactory"/></param>
 /// <param name="dmbFactory">The value of <see cref="dmbFactory"/></param>
 /// <param name="processExecutor">The value of <see cref="processExecutor"/></param>
 /// <param name="logger">The value of <see cref="logger"/></param>
 /// <param name="metadata">The value of <see cref="metadata"/></param>
 public SessionPersistor(
     IDatabaseContextFactory databaseContextFactory,
     IDmbFactory dmbFactory,
     IProcessExecutor processExecutor,
     ILogger <SessionPersistor> logger,
     Api.Models.Instance metadata)
 {
     this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
     this.dmbFactory             = dmbFactory ?? throw new ArgumentNullException(nameof(dmbFactory));
     this.processExecutor        = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
     this.logger   = logger ?? throw new ArgumentNullException(nameof(logger));
     this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
 }
        /// <summary>
        /// Get the most recent <see cref="CompileJob"/> for a given <paramref name="instance"/> from a given <paramref name="databaseContext"/>.
        /// </summary>
        /// <param name="databaseContext">The <see cref="IDatabaseContext"/>.</param>
        /// <param name="instance">The <see cref="Instance"/> to search for <see cref="CompileJob"/>s.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
        /// <returns>A <see cref="Task{TResult}"/> resulting in the most recent <see cref="CompileJob"/> associated with the given <paramref name="instance"/> from the <paramref name="databaseContext"/>.</returns>
        public static Task <CompileJob> MostRecentCompletedCompileJobOrDefault(
            this IDatabaseContext databaseContext,
            Api.Models.Instance instance,
            CancellationToken cancellationToken)
        {
            if (databaseContext == null)
            {
                throw new ArgumentNullException(nameof(databaseContext));
            }

            return(databaseContext
                   .CompileJobs
                   .AsQueryable()
                   .Where(x => x.Job.Instance.Id == instance.Id)
                   .OrderByDescending(x => x.Job.StoppedAt)
                   .FirstOrDefaultAsync(cancellationToken));
        }
Ejemplo n.º 19
0
        /// <inheritdoc />
        public IInstanceReference GetInstanceReference(Api.Models.Instance metadata)
        {
            if (metadata == null)
            {
                throw new ArgumentNullException(nameof(metadata));
            }

            lock (instances)
            {
                if (!instances.TryGetValue(metadata.Id.Value, out var instance))
                {
                    logger.LogTrace("Cannot reference instance {0} as it is not online or on this node!", metadata.Id);
                    return(null);
                }

                return(instance.AddReference());
            }
        }
        void NormalizeModelPath(Api.Models.Instance model, out string absolutePath)
        {
            if (model.Path == null)
            {
                absolutePath = null;
                return;
            }

            absolutePath = ioManager.ResolvePath(model.Path);
            if (platformIdentifier.IsWindows)
            {
                model.Path = absolutePath.ToUpperInvariant();
            }
            else
            {
                model.Path = absolutePath;
            }
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WindowsWatchdog"/> class.
 /// </summary>
 /// <param name="chat">The <see cref="IChatManager"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="sessionControllerFactory">The <see cref="ISessionControllerFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="dmbFactory">The <see cref="IDmbFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="sessionPersistor">The <see cref="ISessionPersistor"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="jobManager">The <see cref="IJobManager"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="serverControl">The <see cref="IServerControl"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="diagnosticsIOManager">The <see cref="IIOManager"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="eventConsumer">The <see cref="IEventConsumer"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="remoteDeploymentManagerFactory">The <see cref="IRemoteDeploymentManagerFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="gameIOManager">The value of <see cref="GameIOManager"/>.</param>
 /// <param name="symlinkFactory">The value of <see cref="symlinkFactory"/>.</param>
 /// <param name="logger">The <see cref="ILogger"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="initialLaunchParameters">The <see cref="DreamDaemonLaunchParameters"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="instance">The <see cref="Api.Models.Instance"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="autoStart">The autostart value for the <see cref="WatchdogBase"/>.</param>
 public WindowsWatchdog(
     IChatManager chat,
     ISessionControllerFactory sessionControllerFactory,
     IDmbFactory dmbFactory,
     ISessionPersistor sessionPersistor,
     IJobManager jobManager,
     IServerControl serverControl,
     IAsyncDelayer asyncDelayer,
     IIOManager diagnosticsIOManager,
     IEventConsumer eventConsumer,
     IRemoteDeploymentManagerFactory remoteDeploymentManagerFactory,
     IIOManager gameIOManager,
     ISymlinkFactory symlinkFactory,
     ILogger <WindowsWatchdog> logger,
     DreamDaemonLaunchParameters initialLaunchParameters,
     Api.Models.Instance instance,
     bool autoStart)
     : base(
         chat,
         sessionControllerFactory,
         dmbFactory,
         sessionPersistor,
         jobManager,
         serverControl,
         asyncDelayer,
         diagnosticsIOManager,
         eventConsumer,
         remoteDeploymentManagerFactory,
         logger,
         initialLaunchParameters,
         instance,
         autoStart)
 {
     try
     {
         GameIOManager       = gameIOManager ?? throw new ArgumentNullException(nameof(gameIOManager));
         this.symlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory));
     }
     catch
     {
         _ = DisposeAsync();
         throw;
     }
 }
Ejemplo n.º 22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RuntimeInformation"/> <see langword="class"/>.
 /// </summary>
 /// <param name="assemblyInformationProvider">The <see cref="IAssemblyInformationProvider"/> to use.</param>
 /// <param name="serverPortProvider">The <see cref="IServerPortProvider"/> used to set the value of <see cref="ServerPort"/>.</param>
 /// <param name="testMerges">An <see cref="IEnumerable{T}"/> used to construct the value of <see cref="TestMerges"/>.</param>
 /// <param name="chatChannels">The <see cref="Chat.ChannelRepresentation"/>s for the <see cref="ChatUpdate"/>.</param>
 /// <param name="instance">The <see cref="Instance"/> used to set <see cref="InstanceName"/>.</param>
 /// <param name="revision">The value of <see cref="RevisionInformation"/>.</param>
 /// <param name="securityLevel">The value of <see cref="SecurityLevel"/>.</param>
 /// <param name="apiValidateOnly">The value of <see cref="ApiValidateOnly"/>.</param>
 public RuntimeInformation(
     IAssemblyInformationProvider assemblyInformationProvider,
     IServerPortProvider serverPortProvider,
     IEnumerable <TestMergeInformation> testMerges,
     IEnumerable <Chat.ChannelRepresentation> chatChannels,
     Api.Models.Instance instance,
     Api.Models.Internal.RevisionInformation revision,
     DreamDaemonSecurity?securityLevel,
     bool apiValidateOnly)
     : base(chatChannels)
 {
     ServerVersion   = assemblyInformationProvider?.Version ?? throw new ArgumentNullException(nameof(assemblyInformationProvider));
     ServerPort      = serverPortProvider?.HttpApiPort ?? throw new ArgumentNullException(nameof(serverPortProvider));
     TestMerges      = testMerges?.ToList() ?? throw new ArgumentNullException(nameof(testMerges));
     InstanceName    = instance?.Name ?? throw new ArgumentNullException(nameof(instance));
     Revision        = revision ?? throw new ArgumentNullException(nameof(revision));
     SecurityLevel   = securityLevel;
     ApiValidateOnly = apiValidateOnly;
 }
Ejemplo n.º 23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="WindowsWatchdog"/> <see langword="class"/>.
 /// </summary>
 /// <param name="chat">The <see cref="IChat"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="sessionControllerFactory">The <see cref="ISessionControllerFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="dmbFactory">The <see cref="IDmbFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="reattachInfoHandler">The <see cref="IReattachInfoHandler"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="databaseContextFactory">The <see cref="IDatabaseContextFactory"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="byondTopicSender">The <see cref="IByondTopicSender"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="eventConsumer">The <see cref="IEventConsumer"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="jobManager">The <see cref="IJobManager"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="serverControl">The <see cref="IServerControl"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="asyncDelayer">The <see cref="IAsyncDelayer"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="ioManager">The value of <see cref="ioManager"/>.</param>
 /// <param name="symlinkFactory">The value of <see cref="symlinkFactory"/>.</param>
 /// <param name="logger">The <see cref="ILogger"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="initialLaunchParameters">The <see cref="DreamDaemonLaunchParameters"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="instance">The <see cref="Api.Models.Instance"/> for the <see cref="WatchdogBase"/>.</param>
 /// <param name="autoStart">The autostart value for the <see cref="WatchdogBase"/>.</param>
 public WindowsWatchdog(
     IChat chat,
     ISessionControllerFactory sessionControllerFactory,
     IDmbFactory dmbFactory,
     IReattachInfoHandler reattachInfoHandler,
     IDatabaseContextFactory databaseContextFactory,
     IByondTopicSender byondTopicSender,
     IEventConsumer eventConsumer,
     IJobManager jobManager,
     IServerControl serverControl,
     IAsyncDelayer asyncDelayer,
     IIOManager ioManager,
     ISymlinkFactory symlinkFactory,
     ILogger <WindowsWatchdog> logger,
     DreamDaemonLaunchParameters initialLaunchParameters,
     Api.Models.Instance instance, bool autoStart)
     : base(
         chat,
         sessionControllerFactory,
         dmbFactory,
         reattachInfoHandler,
         databaseContextFactory,
         byondTopicSender,
         eventConsumer,
         jobManager,
         serverControl,
         asyncDelayer,
         logger,
         initialLaunchParameters,
         instance,
         autoStart)
 {
     try
     {
         this.ioManager      = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
         this.symlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory));
     }
     catch
     {
         Dispose();
         throw;
     }
 }
Ejemplo n.º 24
0
 Models.Instance CreateDefaultInstance(Api.Models.Instance initialSettings)
 => new Models.Instance
 {
     ConfigurationType   = initialSettings.ConfigurationType ?? ConfigurationType.Disallowed,
     DreamDaemonSettings = new DreamDaemonSettings
     {
         AllowWebClient      = false,
         AutoStart           = false,
         Port                = 1337,
         SecurityLevel       = DreamDaemonSecurity.Safe,
         StartupTimeout      = 60,
         HeartbeatSeconds    = 60,
         TopicRequestTimeout = generalConfiguration.ByondTopicTimeout
     },
     DreamMakerSettings = new DreamMakerSettings
     {
         ApiValidationPort          = 1339,
         ApiValidationSecurityLevel = DreamDaemonSecurity.Safe,
         RequireDMApiValidation     = true
     },
     Name               = initialSettings.Name,
     Online             = false,
     Path               = initialSettings.Path,
     AutoUpdateInterval = initialSettings.AutoUpdateInterval ?? 0,
     ChatBotLimit       = initialSettings.ChatBotLimit ?? Models.Instance.DefaultChatBotLimit,
     RepositorySettings = new RepositorySettings
     {
         CommitterEmail            = Components.Repository.Repository.DefaultCommitterEmail,
         CommitterName             = Components.Repository.Repository.DefaultCommitterName,
         PushTestMergeCommits      = false,
         ShowTestMergeCommitters   = false,
         AutoUpdatesKeepTestMerges = false,
         AutoUpdatesSynchronize    = false,
         PostTestMergeComment      = false,
         CreateGitHubDeployments   = false
     },
     InstanceUsers = new List <Models.InstanceUser>                    // give this user full privileges on the instance
     {
         InstanceAdminUser(null)
     }
 };
Ejemplo n.º 25
0
 /// <summary>
 /// Create a <see cref="IWatchdog"/> that isn't the <see cref="ExperimentalWatchdog"/>.
 /// </summary>
 /// <param name="chat">The <see cref="IChatManager"/> for the <see cref="IWatchdog"/></param>
 /// <param name="dmbFactory">The <see cref="IDmbFactory"/> for the <see cref="IWatchdog"/> with</param>
 /// <param name="reattachInfoHandler">The <see cref="IReattachInfoHandler"/> for the <see cref="IWatchdog"/></param>
 /// <param name="sessionControllerFactory">The <see cref="ISessionControllerFactory"/> for the <see cref="IWatchdog"/></param>
 /// <param name="ioManager">The <see cref="IIOManager"/> for the <see cref="IWatchdog"/>.</param>
 /// <param name="instance">The <see cref="Instance"/> for the <see cref="IWatchdog"/></param>
 /// <param name="settings">The initial <see cref="DreamDaemonSettings"/> for the <see cref="IWatchdog"/></param>
 /// <returns>A new <see cref="IWatchdog"/></returns>
 protected virtual IWatchdog CreateNonExperimentalWatchdog(
     IChatManager chat,
     IDmbFactory dmbFactory,
     IReattachInfoHandler reattachInfoHandler,
     ISessionControllerFactory sessionControllerFactory,
     IIOManager ioManager,
     Api.Models.Instance instance,
     DreamDaemonSettings settings)
 => new BasicWatchdog(
     chat,
     sessionControllerFactory,
     dmbFactory,
     reattachInfoHandler,
     DatabaseContextFactory,
     JobManager,
     ServerControl,
     AsyncDelayer,
     LoggerFactory.CreateLogger <BasicWatchdog>(),
     settings,
     instance,
     settings.AutoStart.Value);
Ejemplo n.º 26
0
        /// <inheritdoc />
        public IRemoteDeploymentManager CreateRemoteDeploymentManager(Api.Models.Instance metadata, RemoteGitProvider remoteGitProvider)
        {
            if (metadata == null)
            {
                throw new ArgumentNullException(nameof(metadata));
            }

            logger.LogTrace("Creating remote deployment manager for remote git provider {0}...", remoteGitProvider);
            return(remoteGitProvider switch
            {
                RemoteGitProvider.GitHub => new GitHubRemoteDeploymentManager(
                    databaseContextFactory,
                    gitHubClientFactory,
                    loggerFactory.CreateLogger <GitHubRemoteDeploymentManager>(),
                    metadata),
                RemoteGitProvider.GitLab => new GitLabRemoteDeploymentManager(
                    loggerFactory.CreateLogger <GitLabRemoteDeploymentManager>(),
                    metadata),
                RemoteGitProvider.Unknown => new NoOpRemoteDeploymentManager(),
                _ => throw new InvalidOperationException($"Invalid RemoteGitProvider: {remoteGitProvider}!"),
            });
Ejemplo n.º 27
0
        /// <summary>
        /// Corrects discrepencies between the <see cref="Api.Models.Instance.Online"/> status of <see cref="IInstance"/>s in the database vs the service.
        /// </summary>
        /// <param name="instanceManager">The <see cref="IInstanceManager"/> to use.</param>
        /// <param name="logger">The <see cref="ILogger"/> to use.</param>
        /// <param name="metadata">The <see cref="Api.Models.Instance"/> to check.</param>
        /// <returns><see langword="true"/> if an unsaved DB update was made, <see langword="false"/> otherwise.</returns>
        public static bool ValidateInstanceOnlineStatus(IInstanceManager instanceManager, ILogger logger, Api.Models.Instance metadata)
        {
            if (instanceManager == null)
            {
                throw new ArgumentNullException(nameof(instanceManager));
            }
            if (metadata == null)
            {
                throw new ArgumentNullException(nameof(metadata));
            }

            bool online;

            using (var instanceReferenceCheck = instanceManager.GetInstanceReference(metadata))
                online = instanceReferenceCheck != null;

            if (metadata.Online.Value == online)
            {
                return(false);
            }

            const string OfflineWord = "offline";
            const string OnlineWord  = "online";

            logger.LogWarning(
                "Instance {0} is says it's {1} in the database, but it is actually {2} in the service. Updating the database to reflect this...",
                metadata.Id,
                online ? OfflineWord : OnlineWord,
                online ? OnlineWord : OfflineWord);

            metadata.Online = online;
            return(true);
        }
Ejemplo n.º 28
0
        public async Task RunPostTest(CancellationToken cancellationToken)
        {
            var instances = await instanceManagerClient.List(cancellationToken);

            var firstTest      = instances.Single(x => x.Name == TestInstanceName);
            var instanceClient = instanceManagerClient.CreateClient(firstTest);

            //can regain permissions on instance without instance user
            var ourInstanceUser = await instanceClient.Users.Read(cancellationToken).ConfigureAwait(false);

            await instanceClient.Users.Delete(ourInstanceUser, cancellationToken).ConfigureAwait(false);

            await Assert.ThrowsExceptionAsync <InsufficientPermissionsException>(() => instanceClient.Users.Read(cancellationToken)).ConfigureAwait(false);

            await instanceManagerClient.GrantPermissions(new Api.Models.Instance
            {
                Id = firstTest.Id
            }, cancellationToken).ConfigureAwait(false);

            ourInstanceUser = await instanceClient.Users.Read(cancellationToken).ConfigureAwait(false);

            Assert.AreEqual(RightsHelper.AllRights <DreamDaemonRights>(), ourInstanceUser.DreamDaemonRights.Value);

            //can't detach online instance
            await ApiAssert.ThrowsException <ConflictException>(() => instanceManagerClient.Detach(firstTest, cancellationToken), ErrorCode.InstanceDetachOnline).ConfigureAwait(false);

            firstTest.Online = false;
            firstTest        = await instanceManagerClient.Update(firstTest, cancellationToken).ConfigureAwait(false);

            await instanceManagerClient.Detach(firstTest, cancellationToken).ConfigureAwait(false);

            var attachPath = Path.Combine(firstTest.Path, InstanceController.InstanceAttachFileName);

            Assert.IsTrue(File.Exists(attachPath));

            //can recreate detached instance
            firstTest = await instanceManagerClient.CreateOrAttach(firstTest, cancellationToken).ConfigureAwait(false);

            // Test updating only with SetChatBotLimit works
            var current = await usersClient.Read(cancellationToken);

            var update = new UserUpdate
            {
                Id = current.Id,
                InstanceManagerRights = InstanceManagerRights.SetChatBotLimit
            };
            await usersClient.Update(update, cancellationToken);

            var update2 = new Api.Models.Instance
            {
                Id           = firstTest.Id,
                ChatBotLimit = 77
            };
            var newThing = await instanceManagerClient.Update(update2, cancellationToken);

            update.InstanceManagerRights |= InstanceManagerRights.Delete | InstanceManagerRights.Create | InstanceManagerRights.List;
            await usersClient.Update(update, cancellationToken);

            //but only if the attach file exists
            await instanceManagerClient.Detach(firstTest, cancellationToken).ConfigureAwait(false);

            File.Delete(attachPath);
            await ApiAssert.ThrowsException <ConflictException>(() => instanceManagerClient.CreateOrAttach(firstTest, cancellationToken), ErrorCode.InstanceAtExistingPath).ConfigureAwait(false);
        }
Ejemplo n.º 29
0
        public async Task <IActionResult> Create([FromBody] Api.Models.Instance model, CancellationToken cancellationToken)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            if (String.IsNullOrWhiteSpace(model.Name))
            {
                return(BadRequest(new ErrorMessage(ErrorCode.InstanceWhitespaceName)));
            }

            var unNormalizedPath   = model.Path;
            var targetInstancePath = NormalizePath(unNormalizedPath);

            model.Path = targetInstancePath;

            var installationDirectoryPath = NormalizePath(DefaultIOManager.CurrentDirectory);

            bool InstanceIsChildOf(string otherPath)
            {
                if (!targetInstancePath.StartsWith(otherPath, StringComparison.Ordinal))
                {
                    return(false);
                }

                bool sameLength       = targetInstancePath.Length == otherPath.Length;
                char dirSeparatorChar = targetInstancePath.ToCharArray()[Math.Min(otherPath.Length, targetInstancePath.Length - 1)];

                return(sameLength ||
                       dirSeparatorChar == Path.DirectorySeparatorChar ||
                       dirSeparatorChar == Path.AltDirectorySeparatorChar);
            }

            if (InstanceIsChildOf(installationDirectoryPath))
            {
                return(Conflict(new ErrorMessage(ErrorCode.InstanceAtConflictingPath)));
            }

            // Validate it's not a child of any other instance
            IActionResult earlyOut = null;
            ulong         countOfOtherInstances = 0;

            using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
            {
                var newCancellationToken = cts.Token;
                try
                {
                    await DatabaseContext
                    .Instances
                    .AsQueryable()
                    .Select(x => new Models.Instance
                    {
                        Path = x.Path
                    })
                    .ForEachAsync(
                        otherInstance =>
                    {
                        if (++countOfOtherInstances >= generalConfiguration.InstanceLimit)
                        {
                            earlyOut ??= Conflict(new ErrorMessage(ErrorCode.InstanceLimitReached));
                        }
                        else if (InstanceIsChildOf(otherInstance.Path))
                        {
                            earlyOut ??= Conflict(new ErrorMessage(ErrorCode.InstanceAtConflictingPath));
                        }

                        if (earlyOut != null && !newCancellationToken.IsCancellationRequested)
                        {
                            cts.Cancel();
                        }
                    },
                        newCancellationToken)
                    .ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                }
            }

            if (earlyOut != null)
            {
                return(earlyOut);
            }

            // Last test, ensure it's in the list of valid paths
            if (!(generalConfiguration.ValidInstancePaths?
                  .Select(path => NormalizePath(path))
                  .Any(path => InstanceIsChildOf(path)) ?? true))
            {
                return(BadRequest(new ErrorMessage(ErrorCode.InstanceNotAtWhitelistedPath)));
            }

            async Task <bool> DirExistsAndIsNotEmpty()
            {
                if (!await ioManager.DirectoryExists(model.Path, cancellationToken).ConfigureAwait(false))
                {
                    return(false);
                }

                var filesTask = ioManager.GetFiles(model.Path, cancellationToken);
                var dirsTask  = ioManager.GetDirectories(model.Path, cancellationToken);

                var files = await filesTask.ConfigureAwait(false);

                var dirs = await dirsTask.ConfigureAwait(false);

                return(files.Concat(dirs).Any());
            }

            var  dirExistsTask = DirExistsAndIsNotEmpty();
            bool attached      = false;

            if (await ioManager.FileExists(model.Path, cancellationToken).ConfigureAwait(false) || await dirExistsTask.ConfigureAwait(false))
            {
                if (!await ioManager.FileExists(ioManager.ConcatPath(model.Path, InstanceAttachFileName), cancellationToken).ConfigureAwait(false))
                {
                    return(Conflict(new ErrorMessage(ErrorCode.InstanceAtExistingPath)));
                }
                else
                {
                    attached = true;
                }
            }

            var newInstance = CreateDefaultInstance(model);

            DatabaseContext.Instances.Add(newInstance);
            try
            {
                await DatabaseContext.Save(cancellationToken).ConfigureAwait(false);

                try
                {
                    // actually reserve it now
                    await ioManager.CreateDirectory(unNormalizedPath, cancellationToken).ConfigureAwait(false);

                    await ioManager.DeleteFile(ioManager.ConcatPath(targetInstancePath, InstanceAttachFileName), cancellationToken).ConfigureAwait(false);
                }
                catch
                {
                    // oh shit delete the model
                    DatabaseContext.Instances.Remove(newInstance);

                    // DCT: Operation must always run
                    await DatabaseContext.Save(default).ConfigureAwait(false);
Ejemplo n.º 30
0
 public ByondTest(IByondClient byondClient, IJobsClient jobsClient, Api.Models.Instance metadata)
     : base(jobsClient)
 {
     this.byondClient = byondClient ?? throw new ArgumentNullException(nameof(byondClient));
     this.metadata    = metadata ?? throw new ArgumentNullException(nameof(metadata));
 }