refactor(multi-server): replace executeCommand with execAsyncRemote

This commit is contained in:
Mauricio Siu
2024-09-16 00:40:11 -06:00
parent 19295ba746
commit d8d0b60cb3
76 changed files with 622 additions and 19123 deletions

View File

@@ -13,8 +13,8 @@ import {
writeDomainsToComposeRemote,
} from "../docker/domain";
import { encodeBase64, prepareEnvironmentVariables } from "../docker/utils";
import { spawnAsync } from "../process/spawnAsync";
import { execAsyncRemote } from "../process/execAsync";
import { spawnAsync } from "../process/spawnAsync";
export type ComposeNested = InferResultType<
"compose",

View File

@@ -1,16 +1,16 @@
import fs from "node:fs/promises";
import path, { join } from "node:path";
import type { Application } from "@/server/api/services/application";
import { findServerById } from "@/server/api/services/server";
import { APPLICATIONS_PATH } from "@/server/constants";
import AdmZip from "adm-zip";
import { Client, type SFTPWrapper } from "ssh2";
import {
recreateDirectory,
recreateDirectoryRemote,
} from "../filesystem/directory";
import type { Application } from "@/server/api/services/application";
import { execAsyncRemote } from "../process/execAsync";
import { Client, type SFTPWrapper } from "ssh2";
import { findServerById } from "@/server/api/services/server";
import { readSSHKey } from "../filesystem/ssh";
import { execAsyncRemote } from "../process/execAsync";
export const unzipDrop = async (zipFile: File, application: Application) => {
let sftp: SFTPWrapper | null = null;

View File

@@ -1,9 +1,7 @@
import { createWriteStream } from "node:fs";
// import { docker } from "@/server/constants";
import type { InferResultType } from "@/server/types/with";
import type { CreateServiceOptions } from "dockerode";
import { uploadImage } from "../cluster/upload";
import Dockerode from "dockerode";
import {
calculateResources,
generateBindMounts,
@@ -12,14 +10,12 @@ import {
generateVolumeMounts,
prepareEnvironmentVariables,
} from "../docker/utils";
import { getRemoteDocker } from "../servers/remote-docker";
import { buildCustomDocker, getDockerCommand } from "./docker-file";
import { buildHeroku, getHerokuCommand } from "./heroku";
import { buildNixpacks, getNixpacksCommand } from "./nixpacks";
import { buildPaketo, getPaketoCommand } from "./paketo";
import { buildStatic, getStaticCommand } from "./static";
import { findServerById } from "@/server/api/services/server";
import { readSSHKey } from "../filesystem/ssh";
import { getRemoteDocker } from "../servers/remote-docker";
// NIXPACKS codeDirectory = where is the path of the code directory
// HEROKU codeDirectory = where is the path of the code directory

View File

@@ -5,6 +5,7 @@ import type { Compose } from "@/server/api/services/compose";
import type { Domain } from "@/server/api/services/domain";
import { COMPOSE_PATH } from "@/server/constants";
import { dump, load } from "js-yaml";
import { execAsyncRemote } from "../process/execAsync";
import {
cloneRawBitbucketRepository,
cloneRawBitbucketRepositoryRemote,
@@ -31,7 +32,6 @@ import type {
DefinitionsService,
PropertiesNetworks,
} from "./types";
import { execAsyncRemote } from "../process/execAsync";
import { encodeBase64 } from "./utils";
export const cloneCompose = async (compose: Compose) => {

View File

@@ -1,8 +1,8 @@
import { exec } from "node:child_process";
import util from "node:util";
import { findServerById } from "@/server/api/services/server";
import { readSSHKey } from "../filesystem/ssh";
import { Client } from "ssh2";
import { readSSHKey } from "../filesystem/ssh";
export const execAsync = util.promisify(exec);
export const execAsyncRemote = async (
@@ -25,7 +25,7 @@ export const execAsyncRemote = async (
conn.exec(command, (err, stream) => {
if (err) throw err;
stream
.on("close", (code, signal) => {
.on("close", (code: number, signal: string) => {
console.log(
`Stream :: close :: code: ${code}, signal: ${signal}`,
);
@@ -55,31 +55,5 @@ export const execAsyncRemote = async (
privateKey: keys.privateKey,
timeout: 99999,
});
// client.exec(command, (err, stream) => {
// if (err) {
// client.end();
// return reject(err);
// }
// let stdout = "";
// let stderr = "";
// stream
// .on("data", (data: string) => {
// stdout += data.toString();
// })
// .on("close", (code, signal) => {
// client.end();
// if (code === 0) {
// resolve({ stdout, stderr });
// } else {
// reject(new Error(`Command exited with code ${code}`));
// }
// })
// .stderr.on("data", (data) => {
// stderr += data.toString();
// });
// });
});
};

View File

@@ -10,8 +10,8 @@ import type {
import type { InferResultType } from "@/server/types/with";
import { TRPCError } from "@trpc/server";
import { recreateDirectory } from "../filesystem/directory";
import { spawnAsync } from "../process/spawnAsync";
import { execAsyncRemote } from "../process/execAsync";
import { spawnAsync } from "../process/spawnAsync";
export type ApplicationWithBitbucket = InferResultType<
"applications",

View File

@@ -1,12 +1,12 @@
import { createWriteStream } from "node:fs";
import path, { join } from "node:path";
import type { Compose } from "@/server/api/services/compose";
import { updateSSHKeyById } from "@/server/api/services/ssh-key";
import { APPLICATIONS_PATH, COMPOSE_PATH, SSH_PATH } from "@/server/constants";
import { TRPCError } from "@trpc/server";
import { recreateDirectory } from "../filesystem/directory";
import { execAsync, execAsyncRemote } from "../process/execAsync";
import { spawnAsync } from "../process/spawnAsync";
import type { Compose } from "@/server/api/services/compose";
export const cloneGitRepository = async (
entity: {

View File

@@ -11,7 +11,6 @@ import { spawnAsync } from "../process/spawnAsync";
import type { Compose } from "@/server/api/services/compose";
import { type Github, findGithubById } from "@/server/api/services/github";
import type { apiFindGithubBranches } from "@/server/db/schema";
import { executeCommand } from "../servers/command";
import { execAsyncRemote } from "../process/execAsync";
export const authGithub = (githubProvider: Github) => {
@@ -164,7 +163,7 @@ export const getGithubCloneCommand = async (
exit 1;
`;
await executeCommand(serverId, command);
await execAsyncRemote(serverId, command);
throw new TRPCError({
code: "NOT_FOUND",
message: "GitHub Provider not found",
@@ -189,7 +188,7 @@ export const getGithubCloneCommand = async (
exit 1; # Exit with error code
`;
await executeCommand(serverId, bashCommand);
await execAsyncRemote(serverId, bashCommand);
return;
}

View File

@@ -11,9 +11,8 @@ import type { apiGitlabTestConnection } from "@/server/db/schema";
import type { InferResultType } from "@/server/types/with";
import { TRPCError } from "@trpc/server";
import { recreateDirectory } from "../filesystem/directory";
import { spawnAsync } from "../process/spawnAsync";
import { executeCommand } from "../servers/command";
import { execAsyncRemote } from "../process/execAsync";
import { spawnAsync } from "../process/spawnAsync";
export const refreshGitlabToken = async (gitlabProviderId: string) => {
const gitlabProvider = await findGitlabById(gitlabProviderId);

View File

@@ -3,9 +3,9 @@ import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import type { Compose } from "@/server/api/services/compose";
import { COMPOSE_PATH } from "@/server/constants";
import { encodeBase64 } from "../docker/utils";
import { recreateDirectory } from "../filesystem/directory";
import { execAsyncRemote } from "../process/execAsync";
import { encodeBase64 } from "../docker/utils";
export const createComposeFile = async (compose: Compose, logPath: string) => {
const { appName, composeFile } = compose;

View File

@@ -1,10 +0,0 @@
import { execAsyncRemote } from "../process/execAsync";
export const executeCommand = async (serverId: string, command: string) => {
try {
await execAsyncRemote(serverId, command);
} catch (err) {
console.error("Execution error:", err);
throw err;
}
};

View File

@@ -1,7 +1,7 @@
import { findServerById } from "@/server/api/services/server";
import { readSSHKey } from "../filesystem/ssh";
import Dockerode from "dockerode";
import { docker } from "@/server/constants";
import Dockerode from "dockerode";
import { readSSHKey } from "../filesystem/ssh";
export const getRemoteDocker = async (serverId: string | null) => {
if (!serverId) return docker;

View File

@@ -1,30 +1,19 @@
import { findServerById } from "@/server/api/services/server";
import { recreateDirectory } from "../filesystem/directory";
import { slugify } from "@/lib/slug";
import { createWriteStream } from "node:fs";
import path from "node:path";
import {
APPLICATIONS_PATH,
BASE_PATH,
CERTIFICATES_PATH,
DYNAMIC_TRAEFIK_PATH,
getPaths,
LOGS_PATH,
MAIN_TRAEFIK_PATH,
MONITORING_PATH,
SSH_PATH,
} from "@/server/constants";
import { slugify } from "@/lib/slug";
import {
createServerDeployment,
updateDeploymentStatus,
} from "@/server/api/services/deployment";
import { createWriteStream } from "node:fs";
import { Client } from "ssh2";
import { readSSHKey } from "../filesystem/ssh";
import { findServerById } from "@/server/api/services/server";
import { LOGS_PATH, SSH_PATH, getPaths } from "@/server/constants";
import {
getDefaultMiddlewares,
getDefaultServerTraefikConfig,
getDefaultTraefikConfig,
} from "@/server/setup/traefik-setup";
import { Client } from "ssh2";
import { recreateDirectory } from "../filesystem/directory";
import { readSSHKey } from "../filesystem/ssh";
export const setupServer = async (serverId: string) => {
const server = await findServerById(serverId);
@@ -57,8 +46,6 @@ export const setupServer = async (serverId: string) => {
}
};
const setupTraefikInstance = async (serverId: string) => {};
const connectToServer = async (serverId: string, logPath: string) => {
const writeStream = createWriteStream(logPath, { flags: "a" });
const client = new Client();

View File

@@ -3,8 +3,8 @@ import path from "node:path";
import type { Domain } from "@/server/api/services/domain";
import { DYNAMIC_TRAEFIK_PATH } from "@/server/constants";
import { dump, load } from "js-yaml";
import type { FileConfig, HttpLoadBalancerService } from "./file-types";
import { execAsyncRemote } from "../process/execAsync";
import type { FileConfig, HttpLoadBalancerService } from "./file-types";
export const createTraefikConfig = (appName: string) => {
const defaultPort = 3000;

View File

@@ -3,9 +3,9 @@ import { join } from "node:path";
import { DYNAMIC_TRAEFIK_PATH } from "@/server/constants";
import { dump, load } from "js-yaml";
import type { ApplicationNested } from "../builders";
import type { FileConfig } from "./file-types";
import { execAsyncRemote } from "../process/execAsync";
import { writeTraefikConfigRemote } from "./application";
import type { FileConfig } from "./file-types";
export const addMiddleware = (config: FileConfig, middlewareName: string) => {
if (config.http?.routers) {

View File

@@ -1,4 +1,5 @@
import type { Redirect } from "@/server/api/services/redirect";
import type { ApplicationNested } from "../builders";
import {
loadOrCreateConfig,
loadOrCreateConfigRemote,
@@ -13,7 +14,6 @@ import {
loadRemoteMiddlewares,
writeMiddleware,
} from "./middleware";
import type { ApplicationNested } from "../builders";
export const updateRedirectMiddleware = async (
application: ApplicationNested,

View File

@@ -1,5 +1,6 @@
import type { Security } from "@/server/api/services/security";
import * as bcrypt from "bcrypt";
import type { ApplicationNested } from "../builders";
import {
loadOrCreateConfig,
loadOrCreateConfigRemote,
@@ -18,7 +19,6 @@ import {
loadRemoteMiddlewares,
writeMiddleware,
} from "./middleware";
import type { ApplicationNested } from "../builders";
export const createSecurityMiddleware = async (
application: ApplicationNested,