private async Task <bool> GetComposeIsRunning(NodeCredentials credentials, ComposeVersion version, CancellationToken ct = default) { using var activity = Extensions.SuperComposeActivitySource.StartActivity("GetComposeNeedsToStop"); activity?.AddTag("supercompose.path", version.Directory); var cmd = await ComposeCmdPrefix(credentials, version.Directory, version.ServiceName, ct) + " ps --quiet"; var res = await proxyClient.RunCommand(credentials, cmd, ct); return(res.Code == 0 && res.Stdout != null && !string.IsNullOrEmpty(Encoding.UTF8.GetString(res.Stdout).Trim())); }
public async Task Update(Guid id, string?name, string?directory, bool?serviceEnabled, string?content) { var compose = await ctx.Composes .Include(x => x.Current) .Include(x => x.Deployments) .FirstOrDefaultAsync(x => x.Id == id); if (compose == null) { throw new ComposeNotFoundException(); } if (name != null) { compose.Name = name; } if (directory != null || serviceEnabled != null) { var version = new ComposeVersion { Id = Guid.NewGuid(), Content = content ?? compose.Current.Content, Directory = directory ?? compose.Current.Directory, ServiceEnabled = serviceEnabled ?? compose.Current.ServiceEnabled, ServiceName = name != null?ServiceNameFromCompose(name) : compose.Current.ServiceName, ComposeId = compose.Id }; await ctx.ComposeVersions.AddAsync(version); compose.CurrentId = version.Id; } await ctx.SaveChangesAsync(); foreach (var deployment in compose.Deployments) { await nodeUpdater.NotifyAboutNodeChange(deployment.NodeId); } }
private async Task <bool> UpdateSystemdFile(NodeCredentials credentials, ComposeVersion compose, CancellationToken ct) { using var activity = Extensions.SuperComposeActivitySource.StartActivity("UpdateSystemdFile"); var serviceFile = await GenerateSystemdServiceFile(credentials, compose, ct); var resp = await proxyClient.UpsertFile( credentials, compose.ServicePath, Encoding.UTF8.GetBytes(serviceFile), false, ct ); if (resp.Updated) { connectionLog.Info($"systemd service file has been updated"); } return(resp.Updated); }
public async Task Redeploy(Guid composeId) { var compose = await ctx.Composes .Include(x => x.Current) .Include(x => x.Deployments) .FirstOrDefaultAsync(x => x.Id == composeId); if (compose == null) { throw new ComposeNotFoundException(); } var version = new ComposeVersion { Id = Guid.NewGuid(), Content = compose.Current.Content, Directory = compose.Current.Directory, ServiceEnabled = compose.Current.ServiceEnabled, ServiceName = compose.Current.ServiceName, RedeploymentRequestedAt = DateTime.UtcNow, TenantId = compose.TenantId, ComposeId = compose.Id }; await ctx.ComposeVersions.AddAsync(version); compose.CurrentId = version.Id; foreach (var deployment in compose.Deployments) { deployment.ReconciliationFailed = false; } await ctx.SaveChangesAsync(); foreach (var deployment in compose.Deployments) { await nodeUpdater.NotifyAboutNodeChange(deployment.NodeId); } }
private async Task <string> GenerateSystemdServiceFile(NodeCredentials credentials, ComposeVersion composeVersion, CancellationToken ct) { return($@" [Unit] Description={composeVersion.Compose.Name} service with docker compose managed by supercompose Requires=docker.service After=docker.service [Service] Type=oneshot RemainAfterExit=true WorkingDirectory={composeVersion.Directory} ExecStart={await ComposeCmdPrefix(credentials, composeVersion.Directory, composeVersion.ServiceName, ct)} up -d --remove-orphans ExecStop={await ComposeCmdPrefix(credentials, composeVersion.Directory, composeVersion.ServiceName, ct)} down [Install] WantedBy=multi-user.target".Trim().Replace("\r\n", "\n")); }