wip
This commit is contained in:
@@ -68,8 +68,8 @@ export const decrypt = (hashString: string) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
export function generateRangeArray(start, end) {
|
||||
return Array.from({ length: end - start }, (v, k) => k + start);
|
||||
export function generateRangeArray(start: number, end: number) {
|
||||
return Array.from({ length: end - start }, (_v, k) => k + start);
|
||||
}
|
||||
export function generateTimestamp(): string {
|
||||
return `${day().format('HH:mm:ss.SSS')}`;
|
||||
@@ -94,7 +94,7 @@ export async function getTemplates() {
|
||||
let data = await open.readFile({ encoding: 'utf-8' });
|
||||
let jsonData = JSON.parse(data);
|
||||
if (isARM(process.arch)) {
|
||||
jsonData = jsonData.filter((d) => d.arch !== 'amd64');
|
||||
jsonData = jsonData.filter((d: { arch: string }) => d.arch !== 'amd64');
|
||||
}
|
||||
return jsonData;
|
||||
} catch (error) {
|
||||
@@ -109,3 +109,26 @@ export function isARM(arch: string) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function removeService({ id }: { id: string }): Promise<void> {
|
||||
await prisma.serviceSecret.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.serviceSetting.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.servicePersistentStorage.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.meiliSearch.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.fider.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.ghost.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.umami.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.hasura.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.plausibleAnalytics.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.minio.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.vscodeserver.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.wordpress.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.glitchTip.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.moodle.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.appwrite.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.searxng.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.weblate.deleteMany({ where: { serviceId: id } });
|
||||
await prisma.taiga.deleteMany({ where: { serviceId: id } });
|
||||
|
||||
await prisma.service.delete({ where: { id } });
|
||||
}
|
||||
|
||||
@@ -1,31 +1,39 @@
|
||||
import { executeCommand } from "./executeCommand";
|
||||
import { executeCommand } from './executeCommand';
|
||||
|
||||
export async function checkContainer({ dockerId, container, remove = false }: { dockerId: string, container: string, remove?: boolean }): Promise<{ found: boolean, status?: { isExited: boolean, isRunning: boolean, isRestarting: boolean } }> {
|
||||
export async function checkContainer({
|
||||
dockerId,
|
||||
container,
|
||||
remove = false
|
||||
}: {
|
||||
dockerId: string;
|
||||
container: string;
|
||||
remove?: boolean;
|
||||
}): Promise<{
|
||||
found: boolean;
|
||||
status?: { isExited: boolean; isRunning: boolean; isRestarting: boolean };
|
||||
}> {
|
||||
let containerFound = false;
|
||||
try {
|
||||
const { stdout } = await executeCommand({
|
||||
dockerId,
|
||||
command:
|
||||
`docker inspect --format '{{json .State}}' ${container}`
|
||||
command: `docker inspect --format '{{json .State}}' ${container}`
|
||||
});
|
||||
containerFound = true
|
||||
containerFound = true;
|
||||
const parsedStdout = JSON.parse(stdout);
|
||||
const status = parsedStdout.Status;
|
||||
const isRunning = status === 'running';
|
||||
const isRestarting = status === 'restarting'
|
||||
const isExited = status === 'exited'
|
||||
const isRestarting = status === 'restarting';
|
||||
const isExited = status === 'exited';
|
||||
if (status === 'created') {
|
||||
await executeCommand({
|
||||
dockerId,
|
||||
command:
|
||||
`docker rm ${container}`
|
||||
command: `docker rm ${container}`
|
||||
});
|
||||
}
|
||||
if (remove && status === 'exited') {
|
||||
await executeCommand({
|
||||
dockerId,
|
||||
command:
|
||||
`docker rm ${container}`
|
||||
command: `docker rm ${container}`
|
||||
});
|
||||
}
|
||||
|
||||
@@ -43,5 +51,74 @@ export async function checkContainer({ dockerId, container, remove = false }: {
|
||||
return {
|
||||
found: false
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
export async function removeContainer({
|
||||
id,
|
||||
dockerId
|
||||
}: {
|
||||
id: string;
|
||||
dockerId: string;
|
||||
}): Promise<void> {
|
||||
try {
|
||||
const { stdout } = await executeCommand({
|
||||
dockerId,
|
||||
command: `docker inspect --format '{{json .State}}' ${id}`
|
||||
});
|
||||
if (JSON.parse(stdout).Running) {
|
||||
await executeCommand({ dockerId, command: `docker stop -t 0 ${id}` });
|
||||
await executeCommand({ dockerId, command: `docker rm ${id}` });
|
||||
}
|
||||
if (JSON.parse(stdout).Status === 'exited') {
|
||||
await executeCommand({ dockerId, command: `docker rm ${id}` });
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export async function stopDatabaseContainer(database: any): Promise<boolean> {
|
||||
let everStarted = false;
|
||||
const {
|
||||
id,
|
||||
destinationDockerId,
|
||||
destinationDocker: { engine, id: dockerId }
|
||||
} = database;
|
||||
if (destinationDockerId) {
|
||||
try {
|
||||
const { stdout } = await executeCommand({
|
||||
dockerId,
|
||||
command: `docker inspect --format '{{json .State}}' ${id}`
|
||||
});
|
||||
|
||||
if (stdout) {
|
||||
everStarted = true;
|
||||
await removeContainer({ id, dockerId });
|
||||
}
|
||||
} catch (error) {
|
||||
//
|
||||
}
|
||||
}
|
||||
return everStarted;
|
||||
}
|
||||
export async function stopTcpHttpProxy(
|
||||
id: string,
|
||||
destinationDocker: any,
|
||||
publicPort: number,
|
||||
forceName: string | null = null
|
||||
): Promise<{ stdout: string; stderr: string } | Error | unknown> {
|
||||
const { id: dockerId } = destinationDocker;
|
||||
let container = `${id}-${publicPort}`;
|
||||
if (forceName) container = forceName;
|
||||
const { found } = await checkContainer({ dockerId, container });
|
||||
try {
|
||||
if (!found) return true;
|
||||
return await executeCommand({
|
||||
dockerId,
|
||||
command: `docker stop -t 0 ${container} && docker rm ${container}`,
|
||||
shell: true
|
||||
});
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import sshConfig from 'ssh-config';
|
||||
|
||||
import { getFreeSSHLocalPort } from './ssh';
|
||||
import { env } from '../env';
|
||||
import { saveBuildLog } from './logging';
|
||||
import { BuildLog, saveBuildLog } from './logging';
|
||||
import { decrypt } from './common';
|
||||
|
||||
export async function executeCommand({
|
||||
@@ -31,23 +31,26 @@ export async function executeCommand({
|
||||
const { execa, execaCommand } = await import('execa');
|
||||
const { parse } = await import('shell-quote');
|
||||
const parsedCommand = parse(command);
|
||||
const dockerCommand = parsedCommand[0];
|
||||
const dockerArgs = parsedCommand.slice(1);
|
||||
const dockerCommand = parsedCommand[0]?.toString();
|
||||
const dockerArgs = parsedCommand.slice(1).toString();
|
||||
|
||||
if (dockerId) {
|
||||
if (dockerId && dockerCommand && dockerArgs) {
|
||||
const destinationDocker = await prisma.destinationDocker.findUnique({
|
||||
where: { id: dockerId }
|
||||
});
|
||||
if (!destinationDocker) {
|
||||
throw new Error('Destination docker not found');
|
||||
}
|
||||
let { remoteEngine, remoteIpAddress, engine } = destinationDocker;
|
||||
let {
|
||||
remoteEngine,
|
||||
remoteIpAddress,
|
||||
engine = 'unix:///var/run/docker.sock'
|
||||
} = destinationDocker;
|
||||
if (remoteEngine) {
|
||||
await createRemoteEngineConfiguration(dockerId);
|
||||
engine = `ssh://${remoteIpAddress}-remote`;
|
||||
} else {
|
||||
engine = 'unix:///var/run/docker.sock';
|
||||
}
|
||||
|
||||
if (env.CODESANDBOX_HOST) {
|
||||
if (command.startsWith('docker compose')) {
|
||||
command = command.replace(/docker compose/gi, 'docker-compose');
|
||||
@@ -73,12 +76,12 @@ export async function executeCommand({
|
||||
}
|
||||
const logs: any[] = [];
|
||||
if (subprocess && subprocess.stdout && subprocess.stderr) {
|
||||
subprocess.stdout.on('data', async (data) => {
|
||||
subprocess.stdout.on('data', async (data: string) => {
|
||||
const stdout = data.toString();
|
||||
const array = stdout.split('\n');
|
||||
for (const line of array) {
|
||||
if (line !== '\n' && line !== '') {
|
||||
const log = {
|
||||
const log: BuildLog = {
|
||||
line: `${line.replace('\n', '')}`,
|
||||
buildId,
|
||||
applicationId
|
||||
@@ -90,7 +93,7 @@ export async function executeCommand({
|
||||
}
|
||||
}
|
||||
});
|
||||
subprocess.stderr.on('data', async (data) => {
|
||||
subprocess.stderr.on('data', async (data: string) => {
|
||||
const stderr = data.toString();
|
||||
const array = stderr.split('\n');
|
||||
for (const line of array) {
|
||||
@@ -107,7 +110,7 @@ export async function executeCommand({
|
||||
}
|
||||
}
|
||||
});
|
||||
subprocess.on('exit', async (code) => {
|
||||
subprocess.on('exit', async (code: number) => {
|
||||
if (code === 0) {
|
||||
resolve('success');
|
||||
} else {
|
||||
|
||||
@@ -2,15 +2,13 @@ import { prisma } from '../prisma';
|
||||
import { encrypt, generateTimestamp, isDev } from './common';
|
||||
import { day } from './dayjs';
|
||||
|
||||
export const saveBuildLog = async ({
|
||||
line,
|
||||
buildId,
|
||||
applicationId
|
||||
}: {
|
||||
line: string;
|
||||
buildId: string;
|
||||
applicationId: string;
|
||||
}): Promise<any> => {
|
||||
export type Line = string | { shortMessage: string; stderr: string };
|
||||
export type BuildLog = {
|
||||
line: Line;
|
||||
buildId?: string;
|
||||
applicationId?: string;
|
||||
};
|
||||
export const saveBuildLog = async ({ line, buildId, applicationId }: BuildLog): Promise<any> => {
|
||||
if (buildId === 'undefined' || buildId === 'null' || !buildId) return;
|
||||
if (applicationId === 'undefined' || applicationId === 'null' || !applicationId) return;
|
||||
const { default: got } = await import('got');
|
||||
|
||||
Reference in New Issue
Block a user