From bc24067636687313a55757196e83527c4687ff9d Mon Sep 17 00:00:00 2001 From: coconut-bunch Date: Wed, 20 Sep 2023 22:48:48 +0200 Subject: [PATCH 01/11] feat: added drogon start and stop with DIVE --- src/core/dependencies.ts | 8 ++++- src/gradle/index.ts | 64 ++++++++++++++++++++++------------------ src/helpers/index.ts | 5 ++++ 3 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/core/dependencies.ts b/src/core/dependencies.ts index ae0ce65..4ac5136 100644 --- a/src/core/dependencies.ts +++ b/src/core/dependencies.ts @@ -70,8 +70,14 @@ const unzipTarGz = async(source: string, destination: string): Promise => }); } +const ensureKurtosisClean = () => { + shell.exec(`${DROGON_CONFIG_FOLDER}/kurtosis engine clean`, { silent: true }); +} +const ensureDiveStopped = () => { + shell.exec(`${DROGON_CONFIG_FOLDER}/dive clean`, { silent: true }); +} const ensureKurtosisRunning = () => { shell.exec(`${DROGON_CONFIG_FOLDER}/kurtosis engine start`, { silent: true }); } -export { ensureKurtosisCli, ensureDIVECli, ensureDrogonConfigFolder, ensureKurtosisRunning }; +export { ensureKurtosisCli, ensureDIVECli,ensureDiveStopped, ensureDrogonConfigFolder,ensureKurtosisClean, ensureKurtosisRunning }; diff --git a/src/gradle/index.ts b/src/gradle/index.ts index 8bbd6cc..0c471d6 100644 --- a/src/gradle/index.ts +++ b/src/gradle/index.ts @@ -1,13 +1,13 @@ import signale from 'signale'; -import {ensureCWDDrogonProject, getContainerNameForProject} from '../helpers'; +import { ensureCWDDrogonProject, wait, getContainerNameForProject } from '../helpers'; import { mountAndRunCommandInContainer, runAContainerInBackground, stopContainerWithName, } from '../helpers/docker'; var shell = require('shelljs'); -import {DROGON_CONFIG_FOLDER} from '../constants'; -import { ensureDIVECli, ensureKurtosisCli, ensureKurtosisRunning} from '../core/dependencies'; +import { DROGON_CONFIG_FOLDER } from '../constants'; +import { ensureDIVECli, ensureKurtosisCli, ensureKurtosisRunning } from '../core/dependencies'; export const startDiveDaemon = (projectPath: string, args: any) => { ensureCWDDrogonProject(projectPath); @@ -16,44 +16,50 @@ export const startDiveDaemon = (projectPath: string, args: any) => { ensureDIVECli(); ensureKurtosisRunning(); - - const command = `${DROGON_CONFIG_FOLDER}/dive chain icon -d` signale.pending('Starting Drogon daemon'); + // wait for 10 seconds for the engine to be active + wait(10).then(() => { + const command = `${DROGON_CONFIG_FOLDER}/dive chain icon` //TODO: add support for the -d argument. currently it is failing at the first run + shell.exec(command, (code: any, stdout: any, stderr: any) => { + if (code !== 0) { + signale.error('Failed to start Drogon daemon'); + console.log(stderr.toString()) + process.exit(code); + } + else { + signale.success('Started Drogon daemon'); + process.exit(code); + } + }) + }); - shell.exec(command,(code: any, stdout: any, stderr: any) => { - if (code !== 0) { - signale.error('Failed to start Drogon daemon'); - console.log(stderr.toString()) - process.exit(code); - } - else { - signale.success('Started Drogon daemon'); - process.exit(code); - } - }) }; export const stopDrogonDaemon = async (projectPath: string, args: any) => { ensureCWDDrogonProject(projectPath); - - const diveStop = `${DROGON_CONFIG_FOLDER}/dive clean` - signale.pending('Stopping Drogon daemon'); - await stopTheService(diveStop); - - const kurtosisStop = `${DROGON_CONFIG_FOLDER}/kurtosis engine stop` - await stopTheService(kurtosisStop); - signale.success('Stopped Drogon daemon'); + try { + const diveStop = `${DROGON_CONFIG_FOLDER}/dive clean` + signale.pending('Stopping Drogon daemon'); + await stopTheService(diveStop); + await wait(5) + const kurtosisStop = `${DROGON_CONFIG_FOLDER}/kurtosis engine stop` + await stopTheService(kurtosisStop); + await wait(5) + signale.success('Stopped Drogon daemon'); + } catch (error) { + console.log(error) + signale.fatal('error stopping Drogon daemon'); + } }; const stopTheService = async (command: string) => { - shell.exec(command,(code: any, stdout: any, stderr: any) => { + shell.exec(command, (code: any, stdout: any, stderr: any) => { + // console.log(stdout.toString()) + console.log(stderr.toString()) if (code !== 0) { - process.exit(code); - } - else { - process.exit(code); + throw stderr } }) } \ No newline at end of file diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 889ba5e..04e416e 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -175,3 +175,8 @@ export const getContainerNameForProject = ( const containerName = `${containerNamePrefix}-${projectName}-${hash}`; return containerName; }; + +// introduce an artificial wait in seconds +export const wait = (seconds: number) => { + return new Promise(resolve => setTimeout(resolve, seconds * 1000)); +}; \ No newline at end of file From c073a57f161c18a55c912a2685f97393514e6fa1 Mon Sep 17 00:00:00 2001 From: coconut-bunch Date: Thu, 21 Sep 2023 00:14:34 +0200 Subject: [PATCH 02/11] feat: adding gradle to the dive container at runtime --- package-lock.json | 2 +- src/compile/index.ts | 1 - src/core/dependencies.ts | 22 ++++++++++++++++++++-- src/core/index.ts | 17 ++--------------- src/deploy/index.ts | 1 - src/deploy/optimize.ts | 1 - src/goloop/index.ts | 1 - src/gradle/index.ts | 35 ++++++++++++++++++++--------------- src/helpers/docker.ts | 37 ++++++++++++++++++++++++++++++++----- src/helpers/index.ts | 13 ++++++++++++- src/sandbox/index.ts | 1 - src/test/index.ts | 1 - 12 files changed, 87 insertions(+), 45 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1aef8ef..2577d32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "@icon-community/drogon", - "version": "1.1.19", + "version": "1.1.20", "dependencies": { "axios": "^0.27.2", "chalk": "^4.1.2", diff --git a/src/compile/index.ts b/src/compile/index.ts index 5b90339..9108c06 100644 --- a/src/compile/index.ts +++ b/src/compile/index.ts @@ -31,7 +31,6 @@ export const mountAndCompile = (projectPath: string, args: any, cb: any) => { mountAndRunCommandInContainer( container, - projectPath, args, command, cb, diff --git a/src/core/dependencies.ts b/src/core/dependencies.ts index 4ac5136..3821e3c 100644 --- a/src/core/dependencies.ts +++ b/src/core/dependencies.ts @@ -7,6 +7,7 @@ var tar = require('tar'); import signale from 'signale'; import { DROGON_CONFIG_FOLDER, KURTOSIS_RELEASES_VERSION, DIVE_RELEASES_VERSION, DIVE_CLI, DIVE_CLI_REPO, KURTOSIS_CLI, KURTOSIS_CLI_REPO } from '../constants'; +import { getDIVEContainerId, mountAndRunCommandInContainerAsync } from '../helpers/docker'; async function downloadAndExtractLatestRelease(repo: string, toolName: string, version: string): Promise { @@ -79,5 +80,22 @@ const ensureDiveStopped = () => { const ensureKurtosisRunning = () => { shell.exec(`${DROGON_CONFIG_FOLDER}/kurtosis engine start`, { silent: true }); } - -export { ensureKurtosisCli, ensureDIVECli,ensureDiveStopped, ensureDrogonConfigFolder,ensureKurtosisClean, ensureKurtosisRunning }; +const ensureGradleInDIVEContainer = async () => { + const container_id = await getDIVEContainerId() + if(container_id == null) { + throw new Error("DIVE container not found"); + } + const command = `mkdir -p /gradle && \ + wget -O gradle-5.5.1-all.zip https://services.gradle.org/distributions/gradle-5.5.1-all.zip && \ + unzip gradle-5.5.1-all.zip && \ + mv gradle-5.5.1 /gradle` + try { + await mountAndRunCommandInContainerAsync(container_id, [], command, true); + } catch (error) { + console.error("Command failed with exit code:", error); + throw error + } + +} +export { ensureKurtosisCli, ensureDIVECli,ensureDiveStopped, ensureDrogonConfigFolder,ensureKurtosisClean, ensureKurtosisRunning, + ensureGradleInDIVEContainer }; diff --git a/src/core/index.ts b/src/core/index.ts index 6ba4b02..7bf69e6 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -14,7 +14,7 @@ import { mountAndRunCommand, pullImage, } from '../helpers/docker'; -import { ensureKurtosisCli, ensureDIVECli, ensureDrogonConfigFolder } from './dependencies'; +import { ensureKurtosisCli, ensureDIVECli, ensureDrogonConfigFolder, ensureKurtosisRunning } from './dependencies'; import {DROGON_CONFIG_FOLDER, DROGON_IMAGE, ICON_TEMPLATES_REPO} from '../constants'; import {mainBuildGradle, gradleSettings, gitignore} from './contents'; import {Config} from './config'; @@ -35,7 +35,7 @@ export const install = async () => { await ensureKurtosisCli(); await ensureDIVECli() // await fetch_drogon(); - await initializeKurtosis(); + await ensureKurtosisRunning(); // await fetch_score_image(); // progressBar.stopWithMessage('Drogon ready for use.'); @@ -43,19 +43,6 @@ export const install = async () => { // process.exit(); }; -export const initializeKurtosis = async () => { - const command = `${DROGON_CONFIG_FOLDER}/kurtosis engine start` - signale.pending('Initializing Kurtosis'); - shell.exec(command, {async:true}, (code: any) => { - if (code !== 0) { - signale.error('Failed to initialize Kurtosis'); - } - else { - signale.success('Initialized Kurtosis'); - } - }) -} - export const fetch_drogon = async () => { const localImage = await localDrogonImageId(DROGON_IMAGE); if (localImage) { diff --git a/src/deploy/index.ts b/src/deploy/index.ts index ca9b1fe..6f9503c 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -95,7 +95,6 @@ export const deployContracts = async ( mountAndRunCommandInContainer( container, - projectPath, args, command, async (exitCode: any, output: string) => { diff --git a/src/deploy/optimize.ts b/src/deploy/optimize.ts index 08c29ee..563252d 100644 --- a/src/deploy/optimize.ts +++ b/src/deploy/optimize.ts @@ -39,7 +39,6 @@ export const mountAndOptimize = ( ); mountAndRunCommandInContainer( container, - projectPath, args, command, cb, diff --git a/src/goloop/index.ts b/src/goloop/index.ts index e47665f..dfa6e3b 100644 --- a/src/goloop/index.ts +++ b/src/goloop/index.ts @@ -54,7 +54,6 @@ export const runGoloopCmd = async (projectPath: any, command: any, cb: any) => { await mountAndRunCommandInContainer( container, - '/goloop/app', [], command, (exitCode: any, output: string) => { diff --git a/src/gradle/index.ts b/src/gradle/index.ts index 0c471d6..66f10c9 100644 --- a/src/gradle/index.ts +++ b/src/gradle/index.ts @@ -1,5 +1,5 @@ import signale from 'signale'; -import { ensureCWDDrogonProject, wait, getContainerNameForProject } from '../helpers'; +import { ensureCWDDrogonProject, wait, getContainerNameForProject, executeShellCommand } from '../helpers'; import { mountAndRunCommandInContainer, runAContainerInBackground, @@ -7,7 +7,7 @@ import { } from '../helpers/docker'; var shell = require('shelljs'); import { DROGON_CONFIG_FOLDER } from '../constants'; -import { ensureDIVECli, ensureKurtosisCli, ensureKurtosisRunning } from '../core/dependencies'; +import { ensureDIVECli, ensureGradleInDIVEContainer, ensureKurtosisCli, ensureKurtosisRunning } from '../core/dependencies'; export const startDiveDaemon = (projectPath: string, args: any) => { ensureCWDDrogonProject(projectPath); @@ -18,20 +18,25 @@ export const startDiveDaemon = (projectPath: string, args: any) => { ensureKurtosisRunning(); signale.pending('Starting Drogon daemon'); // wait for 10 seconds for the engine to be active - wait(10).then(() => { - const command = `${DROGON_CONFIG_FOLDER}/dive chain icon` //TODO: add support for the -d argument. currently it is failing at the first run - shell.exec(command, (code: any, stdout: any, stderr: any) => { - if (code !== 0) { - signale.error('Failed to start Drogon daemon'); - console.log(stderr.toString()) - process.exit(code); - } - else { - signale.success('Started Drogon daemon'); - process.exit(code); - } + + wait(10) + .then(() => { + const command = `${DROGON_CONFIG_FOLDER}/dive chain icon`; + return executeShellCommand(command); + }) + .then(() => { + return wait(10); }) - }); + .then(ensureGradleInDIVEContainer) + .then(() => { + signale.success('Started Drogon daemon'); + process.exit(0); + }) + .catch(error => { + signale.error('Error during Drogon daemon start:', error); + process.exit(1); + }); + }; diff --git a/src/helpers/docker.ts b/src/helpers/docker.ts index d9ee2e7..acdaf48 100644 --- a/src/helpers/docker.ts +++ b/src/helpers/docker.ts @@ -50,6 +50,19 @@ export const localDrogonImageId = async ( } return null; }; +export const getContainerIdFromNamePattern = async ( + namePattern: string +): Promise => { + const docker = dockerInit(); + const containers = await docker.listContainers(); + const matchedContainer = containers.find(container => + container.Names.some(name => name.includes(namePattern)) + ); + return matchedContainer ? matchedContainer.Id : null; +}; +export const getDIVEContainerId = async (): Promise => { + return await getContainerIdFromNamePattern('icon-node-0xacbc4e'); +} export const removeImage = async (imageId: string): Promise => { const docker = dockerInit(); @@ -132,9 +145,20 @@ export const mountAndRunCommand = async ( ); }; +export const mountAndRunCommandInContainerAsync = (containerName: string, args: any, command: string, logToStdout: boolean): Promise => { + return new Promise((resolve, reject) => { + mountAndRunCommandInContainer(containerName, args, command, (exitCode: number, output: any) => { + if (exitCode) { + reject({ exitCode, output }); + } else { + resolve(output); + } + }, logToStdout); + }); +}; + export const mountAndRunCommandInContainer = async ( containerName: string, - projectPath: string, args: any, command: string, cb: any, @@ -155,7 +179,7 @@ export const mountAndRunCommandInContainer = async ( AttachStderr: true, AttachStdin: true, Tty: true, - WorkingDir: '/goloop/app', + WorkingDir: '/', Cmd: ['sh', '-c', command], }, (err: any, exec: any) => { @@ -188,7 +212,8 @@ export const mountAndRunCommandInContainer = async ( export async function interactWithDockerContainer( containerName: string, destination: string, - command: string + command: string, + shoudStartContainer: boolean = true ) { const docker = new Docker(); const container = await docker.getContainer(containerName); @@ -201,8 +226,10 @@ export async function interactWithDockerContainer( hijack: true, }); - // Start the container - await container.start(); + if(shoudStartContainer === true){ + // Start the container + await container.start(); + } // Execute a command in the container container.exec( diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 04e416e..db52ae5 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -5,7 +5,7 @@ import chalk from 'chalk'; import signale from 'signale'; import path from 'path'; import crypto from 'crypto'; - +var shell = require('shelljs'); export const banner = function () { const banner = textSync('Drogon!', { font: 'Ghost', @@ -179,4 +179,15 @@ export const getContainerNameForProject = ( // introduce an artificial wait in seconds export const wait = (seconds: number) => { return new Promise(resolve => setTimeout(resolve, seconds * 1000)); +}; +export const executeShellCommand = (command:string) => { + return new Promise((resolve, reject) => { + shell.exec(command, (code:any, stdout:any, stderr:any) => { + if (code !== 0) { + reject(new Error(stderr.toString())); + } else { + resolve(stdout); + } + }); + }); }; \ No newline at end of file diff --git a/src/sandbox/index.ts b/src/sandbox/index.ts index 9d1f0ca..9165e45 100644 --- a/src/sandbox/index.ts +++ b/src/sandbox/index.ts @@ -229,7 +229,6 @@ export const startSandbox = (projectPath: string, args: any) => { mountAndRunCommandInContainer( container, - projectPath, args, command, (exitCode: number, output: any) => { diff --git a/src/test/index.ts b/src/test/index.ts index 403f59e..dda6b1e 100644 --- a/src/test/index.ts +++ b/src/test/index.ts @@ -15,7 +15,6 @@ export const testContracts = (projectPath: string, args: any) => { ); mountAndRunCommandInContainer( container, - projectPath, args, command, (exitCode: any) => { From 1c8372d006413b454fa9a9d1373db73b119ae91a Mon Sep 17 00:00:00 2001 From: coconut-bunch Date: Thu, 21 Sep 2023 00:20:42 +0200 Subject: [PATCH 03/11] feat: adds ability to copy folder into the container --- package-lock.json | 405 +++++++++++++++++++++++++++++++++--------- package.json | 4 +- src/helpers/docker.ts | 12 +- 3 files changed, 337 insertions(+), 84 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2577d32..595cba6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,8 @@ "prompts": "^2.4.2", "shelljs": "^0.8.5", "signale": "^1.4.0", - "tar": "^6.1.15" + "tar": "^6.1.15", + "tar-fs": "^3.0.4" }, "bin": { "drogon": ".build/src/index.js" @@ -33,6 +34,7 @@ "@types/node": "^14.11.2", "@types/prompts": "^2.0.14", "@types/signale": "^1.4.4", + "@types/tar-fs": "^2.0.2", "gts": "^3.1.1", "pkg": "^5.8.0", "prettier": "^2.8.0", @@ -770,6 +772,25 @@ "@types/node": "*" } }, + "node_modules/@types/tar-fs": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/tar-fs/-/tar-fs-2.0.2.tgz", + "integrity": "sha512-XuZRAvdo7FbDfgQCNkc8NOdSae5XtG+of2mTSgJ85G4OG0miN4E8BTGT+JBTLO87RQ7iCwsIDCqCsHnf2IaSXA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tar-stream": "*" + } + }, + "node_modules/@types/tar-stream": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/tar-stream/-/tar-stream-2.2.3.tgz", + "integrity": "sha512-if3mugZfjVkXOMZdFjIHySxY13r6GXPpyOlsDmLffvyI7tLz9wXE8BFjNivXsvUeyJ1KNlOpfLnag+ISmxgxPw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", @@ -1261,6 +1282,11 @@ "form-data": "^4.0.0" } }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2264,6 +2290,65 @@ "node": ">= 8.0" } }, + "node_modules/dockerode/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/dockerode/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/dockerode/node_modules/tar-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", + "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "node_modules/dockerode/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -3085,6 +3170,11 @@ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -6617,6 +6707,69 @@ "node": ">=6" } }, + "node_modules/prebuild-install/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/prebuild-install/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6824,6 +6977,11 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -8083,6 +8241,15 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/streamx": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", + "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "node_modules/strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -8347,62 +8514,23 @@ } }, "node_modules/tar-fs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", - "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "dependencies": { - "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.0.0" - } - }, - "node_modules/tar-fs/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/tar-fs/node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "tar-stream": "^3.1.5" } }, "node_modules/tar-fs/node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "node_modules/tar-stream": { @@ -9938,6 +10066,25 @@ "@types/node": "*" } }, + "@types/tar-fs": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/tar-fs/-/tar-fs-2.0.2.tgz", + "integrity": "sha512-XuZRAvdo7FbDfgQCNkc8NOdSae5XtG+of2mTSgJ85G4OG0miN4E8BTGT+JBTLO87RQ7iCwsIDCqCsHnf2IaSXA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/tar-stream": "*" + } + }, + "@types/tar-stream": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/tar-stream/-/tar-stream-2.2.3.tgz", + "integrity": "sha512-if3mugZfjVkXOMZdFjIHySxY13r6GXPpyOlsDmLffvyI7tLz9wXE8BFjNivXsvUeyJ1KNlOpfLnag+ISmxgxPw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", @@ -10285,6 +10432,11 @@ "form-data": "^4.0.0" } }, + "b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -11021,6 +11173,50 @@ "requires": { "docker-modem": "^3.0.0", "tar-fs": "~2.0.1" + }, + "dependencies": { + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "tar-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", + "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } } }, "doctrine": { @@ -11627,6 +11823,11 @@ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "dev": true }, + "fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -14164,6 +14365,54 @@ "simple-get": "^3.0.3", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } } }, "prelude-ls": { @@ -14316,6 +14565,11 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -15226,6 +15480,15 @@ } } }, + "streamx": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", + "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", + "requires": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -15427,45 +15690,23 @@ } }, "tar-fs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", - "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "requires": { - "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.0.0" + "tar-stream": "^3.1.5" }, "dependencies": { - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } } } diff --git a/package.json b/package.json index 5d3d721..3d9bb46 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "@types/node": "^14.11.2", "@types/prompts": "^2.0.14", "@types/signale": "^1.4.4", + "@types/tar-fs": "^2.0.2", "gts": "^3.1.1", "pkg": "^5.8.0", "prettier": "^2.8.0", @@ -70,7 +71,8 @@ "prompts": "^2.4.2", "shelljs": "^0.8.5", "signale": "^1.4.0", - "tar": "^6.1.15" + "tar": "^6.1.15", + "tar-fs": "^3.0.4" }, "npm": { "versionArgs": [ diff --git a/src/helpers/docker.ts b/src/helpers/docker.ts index acdaf48..e83f347 100644 --- a/src/helpers/docker.ts +++ b/src/helpers/docker.ts @@ -1,7 +1,7 @@ import Docker from 'dockerode'; import {DROGON_IMAGE} from '../constants'; import {getContainerNameForProject, panic} from '../helpers'; -import {PassThrough} from 'stream'; +import tar from 'tar-fs'; export const dockerInit = () => { return new Docker(); //defaults to above if env variables are not used @@ -282,3 +282,13 @@ export const stopContainerWithName = async (containerName: string) => { const container = await docker.getContainer(containerName); await container.stop(); }; +export async function copyToContainer( + containerName: string, + sourcePath: string, + destinationPath: string +): Promise { + const docker = new Docker(); + const container = docker.getContainer(containerName); + const tarStream = tar.pack(sourcePath); + await container.putArchive(tarStream, { path: destinationPath }); +} \ No newline at end of file From 32d4146c98f8136321bfdc72c68e1a1fcc762d93 Mon Sep 17 00:00:00 2001 From: coconut-bunch Date: Wed, 27 Sep 2023 10:09:44 +0200 Subject: [PATCH 04/11] feat: adds drogon start and stop --- src/core/dependencies.ts | 55 +++++++++++++++++++++++++++++++++------- src/gradle/index.ts | 26 ++++++------------- src/index.ts | 6 ++--- 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/core/dependencies.ts b/src/core/dependencies.ts index 3821e3c..82cf1ad 100644 --- a/src/core/dependencies.ts +++ b/src/core/dependencies.ts @@ -6,8 +6,9 @@ import * as zlib from 'zlib'; var tar = require('tar'); import signale from 'signale'; -import { DROGON_CONFIG_FOLDER, KURTOSIS_RELEASES_VERSION, DIVE_RELEASES_VERSION, DIVE_CLI, DIVE_CLI_REPO, KURTOSIS_CLI, KURTOSIS_CLI_REPO } from '../constants'; -import { getDIVEContainerId, mountAndRunCommandInContainerAsync } from '../helpers/docker'; +import { DROGON_CONFIG_FOLDER, KURTOSIS_RELEASES_VERSION, DIVE_RELEASES_VERSION, DIVE_CLI, DIVE_CLI_REPO, KURTOSIS_CLI, KURTOSIS_CLI_REPO, DROGON_IMAGE } from '../constants'; +import { getDIVEContainerId, mountAndRunCommandInContainer, mountAndRunCommandInContainerAsync, runAContainerInBackground, stopContainerWithName } from '../helpers/docker'; +import { getContainerNameForProject } from '../helpers'; async function downloadAndExtractLatestRelease(repo: string, toolName: string, version: string): Promise { @@ -43,7 +44,7 @@ async function downloadAndExtractLatestRelease(repo: string, toolName: string, v signale.success(`Downloaded ${toolName}!`); } -const ensureCLI =async (toolName: string, repo: string, version: string): Promise => { +const ensureCLI = async (toolName: string, repo: string, version: string): Promise => { const result = shell.which(`${DROGON_CONFIG_FOLDER}/${toolName}`); if (!result) { @@ -53,7 +54,7 @@ const ensureCLI =async (toolName: string, repo: string, version: string): Promis } const ensureKurtosisCli = () => ensureCLI(KURTOSIS_CLI, KURTOSIS_CLI_REPO, KURTOSIS_RELEASES_VERSION); -const ensureDIVECli = () => ensureCLI(DIVE_CLI,DIVE_CLI_REPO ,DIVE_RELEASES_VERSION); +const ensureDIVECli = () => ensureCLI(DIVE_CLI, DIVE_CLI_REPO, DIVE_RELEASES_VERSION); const ensureDrogonConfigFolder = async () => { if (!fs.existsSync(DROGON_CONFIG_FOLDER)) { @@ -61,7 +62,7 @@ const ensureDrogonConfigFolder = async () => { } } -const unzipTarGz = async(source: string, destination: string): Promise => { +const unzipTarGz = async (source: string, destination: string): Promise => { return new Promise((resolve, reject) => { fs.createReadStream(source) .pipe(zlib.createGunzip()) @@ -82,7 +83,7 @@ const ensureKurtosisRunning = () => { } const ensureGradleInDIVEContainer = async () => { const container_id = await getDIVEContainerId() - if(container_id == null) { + if (container_id == null) { throw new Error("DIVE container not found"); } const command = `mkdir -p /gradle && \ @@ -95,7 +96,43 @@ const ensureGradleInDIVEContainer = async () => { console.error("Command failed with exit code:", error); throw error } - + +} +const ensureGradleDaemon = async (projectPath: string, args: any) => { + const command = 'tail -f /dev/null'; + await runAContainerInBackground( + projectPath, + DROGON_IMAGE, + args, + command, + 'drogon' + ) + +} +const stopGradleDaemon = async (projectPath: string, args: any) => { + const container = getContainerNameForProject( + projectPath, + DROGON_IMAGE, + 'drogon' + ); + const command = 'gradle --stop'; + signale.pending('Stopping Drogon daemon'); + try { + await mountAndRunCommandInContainerAsync(container, [], command, true); + await stopContainerWithName(container); + } catch (error) { + console.error("Command failed with exit code:", error); + throw error + } } -export { ensureKurtosisCli, ensureDIVECli,ensureDiveStopped, ensureDrogonConfigFolder,ensureKurtosisClean, ensureKurtosisRunning, - ensureGradleInDIVEContainer }; +export { + ensureKurtosisCli, + ensureDIVECli, + ensureDiveStopped, + ensureDrogonConfigFolder, + ensureKurtosisClean, + ensureKurtosisRunning, + ensureGradleInDIVEContainer, + ensureGradleDaemon, + stopGradleDaemon +}; diff --git a/src/gradle/index.ts b/src/gradle/index.ts index 66f10c9..5ed9b0c 100644 --- a/src/gradle/index.ts +++ b/src/gradle/index.ts @@ -1,15 +1,10 @@ import signale from 'signale'; -import { ensureCWDDrogonProject, wait, getContainerNameForProject, executeShellCommand } from '../helpers'; -import { - mountAndRunCommandInContainer, - runAContainerInBackground, - stopContainerWithName, -} from '../helpers/docker'; +import { ensureCWDDrogonProject, wait } from '../helpers'; var shell = require('shelljs'); import { DROGON_CONFIG_FOLDER } from '../constants'; -import { ensureDIVECli, ensureGradleInDIVEContainer, ensureKurtosisCli, ensureKurtosisRunning } from '../core/dependencies'; +import { ensureDIVECli, ensureKurtosisCli, ensureKurtosisRunning, ensureGradleDaemon, stopGradleDaemon } from '../core/dependencies'; -export const startDiveDaemon = (projectPath: string, args: any) => { +export const startDaemons = (projectPath: string, args: any) => { ensureCWDDrogonProject(projectPath); ensureKurtosisCli(); @@ -17,17 +12,11 @@ export const startDiveDaemon = (projectPath: string, args: any) => { ensureKurtosisRunning(); signale.pending('Starting Drogon daemon'); - // wait for 10 seconds for the engine to be active - wait(10) + wait(5) .then(() => { - const command = `${DROGON_CONFIG_FOLDER}/dive chain icon`; - return executeShellCommand(command); + return ensureGradleDaemon(projectPath, args) }) - .then(() => { - return wait(10); - }) - .then(ensureGradleInDIVEContainer) .then(() => { signale.success('Started Drogon daemon'); process.exit(0); @@ -40,7 +29,7 @@ export const startDiveDaemon = (projectPath: string, args: any) => { }; -export const stopDrogonDaemon = async (projectPath: string, args: any) => { +export const stopDaemons = async (projectPath: string, args: any) => { ensureCWDDrogonProject(projectPath); try { @@ -50,7 +39,8 @@ export const stopDrogonDaemon = async (projectPath: string, args: any) => { await wait(5) const kurtosisStop = `${DROGON_CONFIG_FOLDER}/kurtosis engine stop` await stopTheService(kurtosisStop); - await wait(5) + await wait(2) + await stopGradleDaemon(projectPath, args); signale.success('Stopped Drogon daemon'); } catch (error) { console.log(error) diff --git a/src/index.ts b/src/index.ts index ab3be5e..bd6a677 100644 --- a/src/index.ts +++ b/src/index.ts @@ -19,7 +19,7 @@ import {generateKeystore, goloop} from './goloop'; import {initSandbox, startSandbox, stopSandbox} from './sandbox'; import {localDrogonImageId} from './helpers/docker'; import {DROGON_IMAGE} from './constants'; -import {startDiveDaemon, stopDrogonDaemon} from './gradle'; +import {startDaemons, stopDaemons} from './gradle'; const main = async () => { banner(); @@ -59,7 +59,7 @@ const main = async () => { .option('-p, --path [string]', 'Path of your Drogon Project', './') .action(function (this: any) { const path = resolve(this.opts().path); - startDiveDaemon(path, this.args); + startDaemons(path, this.args); }); program @@ -68,7 +68,7 @@ const main = async () => { .option('-p, --path [string]', 'Path of your Drogon Project', './') .action(function (this: any) { const path = resolve(this.opts().path); - stopDrogonDaemon(path, this.args).then(() => { + stopDaemons(path, this.args).then(() => { process.exit(0); }); }); From 7ec63aa1c426cf268f822f07bfbf8b5981cd4379 Mon Sep 17 00:00:00 2001 From: coconut-bunch Date: Mon, 2 Oct 2023 14:29:34 +0200 Subject: [PATCH 05/11] feat: idempotent sandbox initialization --- src/constants.ts | 2 +- src/core/dependencies.ts | 25 +++++++++++++++--- src/core/index.ts | 5 ++-- src/sandbox/index.ts | 55 ++++++++++++++++++++-------------------- 4 files changed, 53 insertions(+), 34 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 4630174..0b79861 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -39,7 +39,7 @@ export const ICON_CONFIG = `{ "p2p": "127.0.0.1:8080", "p2p_listen": "", "role": 1, - "rpc_addr": ":9082", + "rpc_addr": ":9080", "rpc_debug": true, "rpc_dump": false, "log_level": "trace", diff --git a/src/core/dependencies.ts b/src/core/dependencies.ts index 82cf1ad..7c05a29 100644 --- a/src/core/dependencies.ts +++ b/src/core/dependencies.ts @@ -7,7 +7,7 @@ var tar = require('tar'); import signale from 'signale'; import { DROGON_CONFIG_FOLDER, KURTOSIS_RELEASES_VERSION, DIVE_RELEASES_VERSION, DIVE_CLI, DIVE_CLI_REPO, KURTOSIS_CLI, KURTOSIS_CLI_REPO, DROGON_IMAGE } from '../constants'; -import { getDIVEContainerId, mountAndRunCommandInContainer, mountAndRunCommandInContainerAsync, runAContainerInBackground, stopContainerWithName } from '../helpers/docker'; +import { getDIVEContainerId, mountAndRunCommandInContainerAsync, runAContainerInBackground, stopContainerWithName } from '../helpers/docker'; import { getContainerNameForProject } from '../helpers'; async function downloadAndExtractLatestRelease(repo: string, toolName: string, version: string): Promise { @@ -75,11 +75,17 @@ const unzipTarGz = async (source: string, destination: string): Promise => const ensureKurtosisClean = () => { shell.exec(`${DROGON_CONFIG_FOLDER}/kurtosis engine clean`, { silent: true }); } +const ensureKurtosisRunning = () => { + shell.exec(`${DROGON_CONFIG_FOLDER}/kurtosis engine start`, { silent: true }); +} const ensureDiveStopped = () => { shell.exec(`${DROGON_CONFIG_FOLDER}/dive clean`, { silent: true }); } -const ensureKurtosisRunning = () => { - shell.exec(`${DROGON_CONFIG_FOLDER}/kurtosis engine start`, { silent: true }); +const ensureDiveRunning = async () => { + const container_id = await getDIVEContainerId() + if(container_id == null){ + shell.exec(`${DROGON_CONFIG_FOLDER}/dive chain icon`, { silent: false }) + } } const ensureGradleInDIVEContainer = async () => { const container_id = await getDIVEContainerId() @@ -98,6 +104,17 @@ const ensureGradleInDIVEContainer = async () => { } } +const ensureGradleDaemonIsRunning = async (projectPath: string, args:any) => { + const container = getContainerNameForProject( + projectPath, + DROGON_IMAGE, + 'drogon' + ); + if (container == null) { + await ensureGradleDaemon(projectPath, args) + } +} + const ensureGradleDaemon = async (projectPath: string, args: any) => { const command = 'tail -f /dev/null'; await runAContainerInBackground( @@ -128,11 +145,13 @@ const stopGradleDaemon = async (projectPath: string, args: any) => { export { ensureKurtosisCli, ensureDIVECli, + ensureDiveRunning, ensureDiveStopped, ensureDrogonConfigFolder, ensureKurtosisClean, ensureKurtosisRunning, ensureGradleInDIVEContainer, ensureGradleDaemon, + ensureGradleDaemonIsRunning, stopGradleDaemon }; diff --git a/src/core/index.ts b/src/core/index.ts index 7bf69e6..6be8097 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -5,7 +5,6 @@ import { checkIfFileExists, ensureCWDDrogonProject, panic, - ProgressBar, safeexit, } from '../helpers'; import { @@ -15,7 +14,7 @@ import { pullImage, } from '../helpers/docker'; import { ensureKurtosisCli, ensureDIVECli, ensureDrogonConfigFolder, ensureKurtosisRunning } from './dependencies'; -import {DROGON_CONFIG_FOLDER, DROGON_IMAGE, ICON_TEMPLATES_REPO} from '../constants'; +import {DROGON_IMAGE, ICON_TEMPLATES_REPO} from '../constants'; import {mainBuildGradle, gradleSettings, gitignore} from './contents'; import {Config} from './config'; import {runTackle, scaffoldProject} from './scaffold'; @@ -34,7 +33,7 @@ export const install = async () => { await ensureDrogonConfigFolder(); await ensureKurtosisCli(); await ensureDIVECli() - // await fetch_drogon(); + await fetch_drogon(); await ensureKurtosisRunning(); // await fetch_score_image(); diff --git a/src/sandbox/index.ts b/src/sandbox/index.ts index 9165e45..270e2c3 100644 --- a/src/sandbox/index.ts +++ b/src/sandbox/index.ts @@ -9,16 +9,16 @@ import { importJson, panic, ProgressBar, + wait, } from '../helpers'; import { dockerInit, mountAndRunCommandInContainer, - stopContainerWithName, } from '../helpers/docker'; -import signale from 'signale'; -import {exitCode} from 'process'; import {generateKeystore, runGoloopCmd} from '../goloop'; import Wallet from '../core/keystore'; +import { ensureKurtosisCli, ensureDIVECli, ensureKurtosisRunning, ensureGradleDaemon, ensureGradleDaemonIsRunning, ensureDiveRunning } from '../core/dependencies'; +import signale from 'signale'; const sandbox_folder = '.drogon/sandbox'; @@ -156,12 +156,10 @@ const setupIconConfig = async (projectPath: string, password: string) => { if (!config) panic('Please run the command inside the Drogon Project'); - let address = ''; // get configured keystore from config let keystoreFile = config.keystore; if (!checkIfFileExists(`${projectPath}/` + keystoreFile)) { - // await generateKeystore(`${projectPath}/.drogon/sandbox`, "gochain", []) const command = 'goloop ks gen --out /goloop/app/.drogon/sandbox/keystore.json'; await runGoloopCmd(`${projectPath}`, command, (output: any) => { @@ -182,34 +180,37 @@ const setupIconConfig = async (projectPath: string, password: string) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars export const initSandbox = (projectPath: string, opts: any, args: any) => { - // TODO: - // - add config initializations - // - god wallet configuration - // - genesis ensureCWDDrogonProject(projectPath); - + ensureKurtosisCli(); + ensureDIVECli(); + ensureKurtosisRunning(); fs.mkdirSync(`${projectPath}/.drogon/sandbox`, {recursive: true}); - - // setup ICON config - setupIconConfig(projectPath, opts.password) - .then(() => {}) - .catch(e => { - console.log(e); - panic('failed to init sandbox'); - }); - - scaffoldSandboxData( - 'data/single', - projectPath, - ICON_SANDBOX_DATA_REPO, - `${projectPath}/.drogon/sandbox` - ) + wait(1) + .then(() => { + return ensureGradleDaemonIsRunning(projectPath, args) + }) + .then(() => { + return ensureDiveRunning() + }) + .then(() => { + return setupIconConfig(projectPath, opts.password) + }) + .then(() => { + return scaffoldSandboxData( + 'data/single', + projectPath, + ICON_SANDBOX_DATA_REPO, + `${projectPath}/.drogon/sandbox` + ) + }) .then(() => { - console.log('Sandbox initialised'); + signale.success('Initialized sandbox'); + }) .catch(error => { - console.log(error); + signale.error('Failed to initialize the sandbox:', error); + process.exit(1); }); }; From 7d6c58832b6009fd2fe7b63c46d5803ab775dd22 Mon Sep 17 00:00:00 2001 From: coconut-bunch Date: Mon, 2 Oct 2023 15:51:54 +0200 Subject: [PATCH 06/11] drogon sandbox commands (init/start/stop) implementation --- src/core/dependencies.ts | 42 +++++++++++----- src/gradle/index.ts | 4 +- src/helpers/docker.ts | 33 ++++++++----- src/sandbox/index.ts | 102 +++++++++++++++++++++++++-------------- 4 files changed, 120 insertions(+), 61 deletions(-) diff --git a/src/core/dependencies.ts b/src/core/dependencies.ts index 7c05a29..47cd0ee 100644 --- a/src/core/dependencies.ts +++ b/src/core/dependencies.ts @@ -7,7 +7,7 @@ var tar = require('tar'); import signale from 'signale'; import { DROGON_CONFIG_FOLDER, KURTOSIS_RELEASES_VERSION, DIVE_RELEASES_VERSION, DIVE_CLI, DIVE_CLI_REPO, KURTOSIS_CLI, KURTOSIS_CLI_REPO, DROGON_IMAGE } from '../constants'; -import { getDIVEContainerId, mountAndRunCommandInContainerAsync, runAContainerInBackground, stopContainerWithName } from '../helpers/docker'; +import { getContainerIdsFromNamePattern, getDIVEContainerId, getKurtosisContainerIds, mountAndRunCommandInContainerAsync, runAContainerInBackground, stopContainerWithName } from '../helpers/docker'; import { getContainerNameForProject } from '../helpers'; async function downloadAndExtractLatestRelease(repo: string, toolName: string, version: string): Promise { @@ -72,14 +72,25 @@ const unzipTarGz = async (source: string, destination: string): Promise => }); } -const ensureKurtosisClean = () => { +const ensureKurtosisStopped = async () => { shell.exec(`${DROGON_CONFIG_FOLDER}/kurtosis engine clean`, { silent: true }); + shell.exec(`${DROGON_CONFIG_FOLDER}/kurtosis engine stop`, { silent: true }); + const kurtosis_containers = await getKurtosisContainerIds() + if(kurtosis_containers != null && kurtosis_containers.length > 0){ + for(const container_id of kurtosis_containers){ + await stopContainerWithName(container_id) + } + } } const ensureKurtosisRunning = () => { shell.exec(`${DROGON_CONFIG_FOLDER}/kurtosis engine start`, { silent: true }); } -const ensureDiveStopped = () => { +const ensureDiveStopped = async () => { shell.exec(`${DROGON_CONFIG_FOLDER}/dive clean`, { silent: true }); + const container_id = await getDIVEContainerId() + if (container_id != null) { + await stopContainerWithName(container_id) + } } const ensureDiveRunning = async () => { const container_id = await getDIVEContainerId() @@ -104,12 +115,20 @@ const ensureGradleInDIVEContainer = async () => { } } -const ensureGradleDaemonIsRunning = async (projectPath: string, args:any) => { - const container = getContainerNameForProject( +const getGradeDaemeonContainerId = async (projectPath: string) => { + const container_name = getContainerNameForProject( projectPath, DROGON_IMAGE, 'drogon' ); + const container = await getContainerIdsFromNamePattern(container_name) + if (container == null || container.length == 0) { + return null + } + return container[0] +} +const ensureGradleDaemonIsRunning = async (projectPath: string, args:any) => { + const container = await getGradeDaemeonContainerId(projectPath) if (container == null) { await ensureGradleDaemon(projectPath, args) } @@ -127,11 +146,10 @@ const ensureGradleDaemon = async (projectPath: string, args: any) => { } const stopGradleDaemon = async (projectPath: string, args: any) => { - const container = getContainerNameForProject( - projectPath, - DROGON_IMAGE, - 'drogon' - ); + const container = await getGradeDaemeonContainerId(projectPath) + if (container == null) { + return + } const command = 'gradle --stop'; signale.pending('Stopping Drogon daemon'); try { @@ -148,10 +166,10 @@ export { ensureDiveRunning, ensureDiveStopped, ensureDrogonConfigFolder, - ensureKurtosisClean, + ensureKurtosisStopped, ensureKurtosisRunning, ensureGradleInDIVEContainer, - ensureGradleDaemon, + getGradeDaemeonContainerId, ensureGradleDaemonIsRunning, stopGradleDaemon }; diff --git a/src/gradle/index.ts b/src/gradle/index.ts index 5ed9b0c..3114f46 100644 --- a/src/gradle/index.ts +++ b/src/gradle/index.ts @@ -2,7 +2,7 @@ import signale from 'signale'; import { ensureCWDDrogonProject, wait } from '../helpers'; var shell = require('shelljs'); import { DROGON_CONFIG_FOLDER } from '../constants'; -import { ensureDIVECli, ensureKurtosisCli, ensureKurtosisRunning, ensureGradleDaemon, stopGradleDaemon } from '../core/dependencies'; +import { ensureDIVECli, ensureGradleDaemonIsRunning, ensureKurtosisCli, ensureKurtosisRunning, stopGradleDaemon } from '../core/dependencies'; export const startDaemons = (projectPath: string, args: any) => { ensureCWDDrogonProject(projectPath); @@ -15,7 +15,7 @@ export const startDaemons = (projectPath: string, args: any) => { wait(5) .then(() => { - return ensureGradleDaemon(projectPath, args) + return ensureGradleDaemonIsRunning(projectPath, args) }) .then(() => { signale.success('Started Drogon daemon'); diff --git a/src/helpers/docker.ts b/src/helpers/docker.ts index e83f347..0092a58 100644 --- a/src/helpers/docker.ts +++ b/src/helpers/docker.ts @@ -50,20 +50,31 @@ export const localDrogonImageId = async ( } return null; }; -export const getContainerIdFromNamePattern = async ( +export const getContainerIdsFromNamePattern = async ( namePattern: string -): Promise => { - const docker = dockerInit(); - const containers = await docker.listContainers(); - const matchedContainer = containers.find(container => - container.Names.some(name => name.includes(namePattern)) - ); - return matchedContainer ? matchedContainer.Id : null; -}; +): Promise => { + try { + const docker = dockerInit(); + const containers = await docker.listContainers(); + const matchedContainers = containers.filter(container => + container.Names.some(name => name.includes(namePattern)) + ); + return matchedContainers.map(container => container.Id); + } catch (error) { + console.error(error); + return null; + } +} export const getDIVEContainerId = async (): Promise => { - return await getContainerIdFromNamePattern('icon-node-0xacbc4e'); + const containers = await getContainerIdsFromNamePattern('icon-node-0xacbc4e'); + if (containers != null && containers?.length > 0) { + return containers[0]; + } + return null +} +export const getKurtosisContainerIds = async () => { + return await getContainerIdsFromNamePattern('kurtosis'); } - export const removeImage = async (imageId: string): Promise => { const docker = dockerInit(); const image = await docker.getImage(imageId); diff --git a/src/sandbox/index.ts b/src/sandbox/index.ts index 270e2c3..3fe0641 100644 --- a/src/sandbox/index.ts +++ b/src/sandbox/index.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; -import {basename} from 'path'; -import {DROGON_IMAGE, ICON_CONFIG, ICON_SANDBOX_DATA_REPO} from '../constants'; -import {verifySourcePath} from '../core/scaffold'; +import { basename } from 'path'; +import { DROGON_IMAGE, ICON_CONFIG, ICON_SANDBOX_DATA_REPO } from '../constants'; +import { verifySourcePath } from '../core/scaffold'; import { checkIfFileExists, ensureCWDDrogonProject, @@ -15,9 +15,9 @@ import { dockerInit, mountAndRunCommandInContainer, } from '../helpers/docker'; -import {generateKeystore, runGoloopCmd} from '../goloop'; +import { generateKeystore, runGoloopCmd } from '../goloop'; import Wallet from '../core/keystore'; -import { ensureKurtosisCli, ensureDIVECli, ensureKurtosisRunning, ensureGradleDaemon, ensureGradleDaemonIsRunning, ensureDiveRunning } from '../core/dependencies'; +import { ensureKurtosisCli, ensureDIVECli, ensureKurtosisRunning, ensureGradleDaemonIsRunning, ensureDiveRunning, stopGradleDaemon, ensureDiveStopped, ensureKurtosisStopped, getGradeDaemeonContainerId } from '../core/dependencies'; import signale from 'signale'; const sandbox_folder = '.drogon/sandbox'; @@ -76,8 +76,8 @@ const fetchProjectWithInContainer = async ( (err: any, exec: any) => { if (err) panic(`Failed to start container. ${err}`); - exec.start({stream: true, hijack: true}, (err: any, stream: any) => { - stream.on('end', async () => {}); + exec.start({ stream: true, hijack: true }, (err: any, stream: any) => { + stream.on('end', async () => { }); stream.on('data', async (chunk: any) => { output += chunk.toString(); @@ -185,13 +185,13 @@ export const initSandbox = (projectPath: string, opts: any, args: any) => { ensureKurtosisCli(); ensureDIVECli(); ensureKurtosisRunning(); - fs.mkdirSync(`${projectPath}/.drogon/sandbox`, {recursive: true}); + fs.mkdirSync(`${projectPath}/.drogon/sandbox`, { recursive: true }); wait(1) .then(() => { return ensureGradleDaemonIsRunning(projectPath, args) }) .then(() => { - return ensureDiveRunning() + return wait(2) }) .then(() => { return setupIconConfig(projectPath, opts.password) @@ -216,40 +216,70 @@ export const initSandbox = (projectPath: string, opts: any, args: any) => { // eslint-disable-next-line @typescript-eslint/no-unused-vars export const startSandbox = (projectPath: string, args: any) => { - console.log(`${projectPath}./${sandbox_folder}/single`); - ensureCWDDrogonProject(projectPath); - - const container = getContainerNameForProject( - projectPath, - DROGON_IMAGE, - 'drogon' - ); - const command = - 'GOCHAIN_KEYSTORE=/goloop/app/.drogon/sandbox/keystore.json GOCHAIN_CONFIG=/goloop/app/.drogon/sandbox/config.json GOCHAIN_DATA=/goloop/app/.drogon/sandbox/ /goloop/run.sh'; + ensureCWDDrogonProject(projectPath); + ensureKurtosisCli(); + ensureDIVECli(); + ensureKurtosisRunning(); + wait(1) + .then(() => { + return ensureGradleDaemonIsRunning(projectPath, args) + }) + .then(() => { + return ensureDiveRunning() + }) + .then(() => { + return getGradeDaemeonContainerId(projectPath) + }) + .then((container) => { + const command = `GOCHAIN_KEYSTORE=/goloop/app/.drogon/sandbox/keystore.json \ + GOCHAIN_CONFIG=/goloop/app/.drogon/sandbox/config.json \ + GOCHAIN_DATA=/goloop/app/.drogon/sandbox/ \ + /goloop/run.sh`; + if(container == null) { + throw new Error('Gradle daemon is not running') + } + mountAndRunCommandInContainer( + container, + args, + command, + (exitCode: number, output: any) => { + console.log(output); + }, + true + ); + signale.success('Started sandbox'); + }) + .catch(error => { + signale.error('Failed to start the sandbox:', error); + process.exit(1); + }); - mountAndRunCommandInContainer( - container, - args, - command, - (exitCode: number, output: any) => { - console.log(output); - }, - true - ); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars export const stopSandbox = (projectPath: string, args: any) => { - ensureCWDDrogonProject(projectPath); - - const container = getContainerNameForProject( - projectPath, - DROGON_IMAGE, - 'sandbox' - ); - throw 'Not implemented!'; + ensureCWDDrogonProject(projectPath); + ensureKurtosisCli(); + ensureDIVECli(); + wait(1) + .then(() => { + return stopGradleDaemon(projectPath, args) + }) + .then(() => { + return ensureDiveStopped() + }) + .then(() => { + return ensureKurtosisStopped() + }) + .then(() => { + signale.success('Stopped sandbox'); + }) + .catch(error => { + signale.error('Failed to stop the sandbox:', error); + process.exit(1); + }); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars From 46ad861ffc53db63a0c37f3707e8d4c565abcd2a Mon Sep 17 00:00:00 2001 From: coconut-bunch Date: Mon, 2 Oct 2023 15:55:14 +0200 Subject: [PATCH 07/11] revers to old rpc addr --- src/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants.ts b/src/constants.ts index 0b79861..4630174 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -39,7 +39,7 @@ export const ICON_CONFIG = `{ "p2p": "127.0.0.1:8080", "p2p_listen": "", "role": 1, - "rpc_addr": ":9080", + "rpc_addr": ":9082", "rpc_debug": true, "rpc_dump": false, "log_level": "trace", From 0363b43b17d7da75c934e7b6cf396b0aba119fd4 Mon Sep 17 00:00:00 2001 From: ant4g0nist Date: Mon, 2 Oct 2023 16:40:25 +0200 Subject: [PATCH 08/11] fix: resets working dir to /goloop/app --- src/helpers/docker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/docker.ts b/src/helpers/docker.ts index 0092a58..5522eea 100644 --- a/src/helpers/docker.ts +++ b/src/helpers/docker.ts @@ -190,7 +190,7 @@ export const mountAndRunCommandInContainer = async ( AttachStderr: true, AttachStdin: true, Tty: true, - WorkingDir: '/', + WorkingDir: '/goloop/app/', Cmd: ['sh', '-c', command], }, (err: any, exec: any) => { From 960637c3a86b0c0948e62f8a21e0afd7ff442547 Mon Sep 17 00:00:00 2001 From: ant4g0nist Date: Tue, 3 Oct 2023 09:14:41 +0200 Subject: [PATCH 09/11] feat: WIP deploy to DIVE changes: - adds support to compile on Drogon and deploy on DIVE notes: - requires tests to ensure artifacts such as build locations - should add support to use gradle on host machine --- src/deploy/index.ts | 92 ++++++++++++++++++++++++++++++++++++------- src/helpers/docker.ts | 18 ++++++--- src/sandbox/index.ts | 36 +++++++---------- 3 files changed, 105 insertions(+), 41 deletions(-) diff --git a/src/deploy/index.ts b/src/deploy/index.ts index 6f9503c..e87d2fb 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -8,10 +8,11 @@ import { listOptmizedContracts, panic, } from '../helpers'; -import {mountAndRunCommandInContainer} from '../helpers/docker'; +import {getDIVEContainerId, mountAndRunCommandInContainer, dockerInit} from '../helpers/docker'; import {DROGON_IMAGE} from '../constants'; import Wallet from '../core/keystore'; import chalk from 'chalk'; +var shell = require('shelljs'); export const deployContracts = async ( projectPath: string, @@ -65,34 +66,97 @@ export const deployContracts = async ( ); console.log(`Loaded wallet ${chalk.green(wallet.getAddress())}`); - await wallet.showBalances(); + // await wallet.showBalances(); signale.pending('Deploying contracts'); - const container = getContainerNameForProject( - projectPath, - DROGON_IMAGE, - 'drogon' - ); + // const container = getContainerNameForProject( + // projectPath, + // DROGON_IMAGE, + // 'drogon' + // ); + + const docker = dockerInit(); + const containerId = await getDIVEContainerId(); + + if (!containerId) { + signale.fatal('DIVE container not found'); + process.exit(1); + } + + console.log("Discovered DIVE container: " + containerId) + const container = docker.getContainer(containerId); const projects = await listAvailableContracts(projectPath); + const optimized = await listOptmizedContracts(projectPath); const keys = Object.keys(projects); const numProjects = keys.length; let tasks: any = {}; - for (var i = 0; i < numProjects; i++) { - let project = keys[i]; + mountAndRunCommandInContainer( + container, + args, + "mkdir -p /goloop/app", + async (exitCode: any, output: string) => { + if (exitCode) { + signale.fatal('Failed to deploy contracts'); + process.exit(exitCode); + } else { + } + }, + true, + "/goloop/" + ); + + let j = 0 + for(var i in optimized) { + console.log("Deploying optimized contract: " + i) + const path = optimized[i] + + // Copy the optimized contract from host to container + signale.pending(`Copying optimized contract ${path} to container`) + + // path without file name + const basePath = path.substring(0, path.lastIndexOf("/")) + const fileName = path.substring(path.lastIndexOf("/")+1) + + console.log("Copying file " + fileName + " to /goloop/app/" + fileName) + console.log("Creating directory " + basePath) + let mkdir = `mkdir -p /goloop/app/${basePath}` + + mountAndRunCommandInContainer( + container, + args, + mkdir, + async (exitCode: any, output: string) => { + if (exitCode) { + signale.fatal('Failed to deploy contracts'); + process.exit(exitCode); + } + }, + true + ); + + const basePath2 = path.split("/").slice(0, 2).join("/") + "/"; + + shell.exec(`docker cp ${projectPath}/${path} ${containerId}:/goloop/app/${path}`, { silent: false }) + shell.exec(`docker cp ${projectPath}/${basePath2}/build.gradle ${containerId}:/goloop/app/${basePath2}/build.gradle`, { silent: false }) + shell.exec(`docker cp ${projectPath}/build.gradle ${containerId}:/goloop/app/build.gradle`, { silent: false }) + shell.exec(`docker cp ${projectPath}/settings.gradle ${containerId}:/goloop/app/settings.gradle`, { silent: false }) - let command = `gradle src:${project}:${destination} -PkeystoreName=/goloop/app/${keystoreFile}`; + // Deploy the contract + let initialWalletBalance = 0 + let project = keys[j]; + j = j + 1 + let command = `/gradle/gradle-5.5.1/bin/gradle src:${project}:${destination} -PkeystoreName=/goloop/app/${keystoreFile}`; if (password) { command += ` -PkeystorePass=${password}`; } - let initialWalletBalance = await wallet.getBalance(); - + console.log("Running command: " + command) mountAndRunCommandInContainer( container, args, @@ -102,10 +166,10 @@ export const deployContracts = async ( signale.fatal('Failed to deploy contracts'); process.exit(exitCode); } else { - signale.success(`Done deploying ${project} contract`); + signale.success(`Done deploying ${i} contract`); let currentBalance = await wallet.getBalance(); - tasks[project] = { + tasks[i] = { current: currentBalance, initial: initialWalletBalance, }; diff --git a/src/helpers/docker.ts b/src/helpers/docker.ts index 5522eea..d251dde 100644 --- a/src/helpers/docker.ts +++ b/src/helpers/docker.ts @@ -72,9 +72,11 @@ export const getDIVEContainerId = async (): Promise => { } return null } + export const getKurtosisContainerIds = async () => { return await getContainerIdsFromNamePattern('kurtosis'); } + export const removeImage = async (imageId: string): Promise => { const docker = dockerInit(); const image = await docker.getImage(imageId); @@ -164,22 +166,28 @@ export const mountAndRunCommandInContainerAsync = (containerName: string, args: } else { resolve(output); } - }, logToStdout); + }, logToStdout, "/"); }); }; export const mountAndRunCommandInContainer = async ( - containerName: string, + containerName: string|Docker.Container, args: any, command: string, cb: any, - logToStdout: boolean + logToStdout: boolean, + workingDir: string = '/goloop/app' ) => { const docker = dockerInit(); if (args) command = `${command} ${args.join(' ')}`; - const container = docker.getContainer(containerName); + let container: Docker.Container; + if (typeof containerName === 'string') { + container = await docker.getContainer(containerName); + } else { + container = containerName; + } let output = ''; @@ -190,7 +198,7 @@ export const mountAndRunCommandInContainer = async ( AttachStderr: true, AttachStdin: true, Tty: true, - WorkingDir: '/goloop/app/', + WorkingDir: workingDir, Cmd: ['sh', '-c', command], }, (err: any, exec: any) => { diff --git a/src/sandbox/index.ts b/src/sandbox/index.ts index 3fe0641..8182d06 100644 --- a/src/sandbox/index.ts +++ b/src/sandbox/index.ts @@ -14,10 +14,11 @@ import { import { dockerInit, mountAndRunCommandInContainer, + getDIVEContainerId, } from '../helpers/docker'; import { generateKeystore, runGoloopCmd } from '../goloop'; import Wallet from '../core/keystore'; -import { ensureKurtosisCli, ensureDIVECli, ensureKurtosisRunning, ensureGradleDaemonIsRunning, ensureDiveRunning, stopGradleDaemon, ensureDiveStopped, ensureKurtosisStopped, getGradeDaemeonContainerId } from '../core/dependencies'; +import { ensureKurtosisCli, ensureDIVECli, ensureKurtosisRunning, ensureGradleDaemonIsRunning, ensureDiveRunning, stopGradleDaemon, ensureDiveStopped, ensureKurtosisStopped, ensureGradleInDIVEContainer } from '../core/dependencies'; import signale from 'signale'; const sandbox_folder = '.drogon/sandbox'; @@ -228,28 +229,19 @@ export const startSandbox = (projectPath: string, args: any) => { .then(() => { return ensureDiveRunning() }) - .then(() => { - return getGradeDaemeonContainerId(projectPath) - }) - .then((container) => { - const command = `GOCHAIN_KEYSTORE=/goloop/app/.drogon/sandbox/keystore.json \ - GOCHAIN_CONFIG=/goloop/app/.drogon/sandbox/config.json \ - GOCHAIN_DATA=/goloop/app/.drogon/sandbox/ \ - /goloop/run.sh`; - if(container == null) { - throw new Error('Gradle daemon is not running') + .then(() => { + return ensureGradleInDIVEContainer() + }) + .then(async () => { + // docker exec container rsync -avP /temp-test/ /test/ + const containerId = await getDIVEContainerId() + if (!containerId) { + signale.fatal('DIVE container not found'); + process.exit(1); } - mountAndRunCommandInContainer( - container, - args, - command, - (exitCode: number, output: any) => { - console.log(output); - }, - true - ); - signale.success('Started sandbox'); - }) + const command = `docker exec container rsync -avP /goloop/app/.drogon/sandbox/ /goloop/app/data/single/`; + + }) .catch(error => { signale.error('Failed to start the sandbox:', error); process.exit(1); From 7a7681c8c3069d30b8f53aca81076cfbb2a09dc0 Mon Sep 17 00:00:00 2001 From: ant4g0nist Date: Tue, 3 Oct 2023 09:18:39 +0200 Subject: [PATCH 10/11] chore: removes unused .then block --- src/sandbox/index.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/sandbox/index.ts b/src/sandbox/index.ts index 8182d06..bdc58b9 100644 --- a/src/sandbox/index.ts +++ b/src/sandbox/index.ts @@ -231,16 +231,6 @@ export const startSandbox = (projectPath: string, args: any) => { }) .then(() => { return ensureGradleInDIVEContainer() - }) - .then(async () => { - // docker exec container rsync -avP /temp-test/ /test/ - const containerId = await getDIVEContainerId() - if (!containerId) { - signale.fatal('DIVE container not found'); - process.exit(1); - } - const command = `docker exec container rsync -avP /goloop/app/.drogon/sandbox/ /goloop/app/data/single/`; - }) .catch(error => { signale.error('Failed to start the sandbox:', error); From 9bfa36ce384c04ff74d2737174c61873469dbfe7 Mon Sep 17 00:00:00 2001 From: ant4g0nist Date: Tue, 3 Oct 2023 09:19:58 +0200 Subject: [PATCH 11/11] chore: make codeql happy --- src/deploy/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/deploy/index.ts b/src/deploy/index.ts index e87d2fb..b3e2bda 100644 --- a/src/deploy/index.ts +++ b/src/deploy/index.ts @@ -156,7 +156,6 @@ export const deployContracts = async ( command += ` -PkeystorePass=${password}`; } - console.log("Running command: " + command) mountAndRunCommandInContainer( container, args,