summaryrefslogtreecommitdiff
path: root/worker
diff options
context:
space:
mode:
Diffstat (limited to 'worker')
-rw-r--r--worker/fs.ts29
-rw-r--r--worker/index.ts1
-rwxr-xr-xworker/jobs/ci_pipeline.run10
-rwxr-xr-xworker/scripts/build_docker_image.ts24
-rwxr-xr-xworker/scripts/checkout_ci.ts48
5 files changed, 52 insertions, 60 deletions
diff --git a/worker/fs.ts b/worker/fs.ts
new file mode 100644
index 0000000..2c02b34
--- /dev/null
+++ b/worker/fs.ts
@@ -0,0 +1,29 @@
+import { Either, getStdout, IEither, LogMetricTraceable } from '@emprespresso/pengueno';
+import { readFileSync } from 'node:fs';
+
+// the container which runs the pipeline synthesizer (A) might be spawned by another container
+// (B) ((which should be the one running this job)) by talking to the host's docker daemon
+// (mounting /var/run/docker.sock) and executing the {@link getPipelineGenerationCommand}.
+//
+// so mounting {@link getSrcDirectoryForCiJob} has no meaning as it doesn't exist on the host;
+// here we replace the path in (B) with the actual volume source on the host, where the src
+// exists.
+export async function getPathOnHost(path: string, home = '/var/lib/laminar'): Promise<IEither<Error, string>> {
+ const container = await Either.fromFailable<Error, string>(() =>
+ readFileSync('/etc/hostname', 'utf-8'),
+ ).flatMapAsync((hostname) =>
+ LogMetricTraceable.of(`docker inspect ${hostname}`.split(' '))
+ .map((tCmd) => getStdout(tCmd))
+ .get(),
+ );
+ if (container.left().present()) {
+ return Either.right(path);
+ }
+ return container
+ .flatMap((inspect) => Either.fromFailable(() => JSON.parse(inspect)))
+ .mapRight(
+ ([container]) =>
+ container.Mounts.find(({ Destination }: { Destination: string }) => Destination === home).Source,
+ )
+ .mapRight((source) => path.replace(home, source));
+}
diff --git a/worker/index.ts b/worker/index.ts
index 9ad32b9..9224e5d 100644
--- a/worker/index.ts
+++ b/worker/index.ts
@@ -1,2 +1,3 @@
+export * from './fs.js';
export * from './secret.js';
export * from './executor.js';
diff --git a/worker/jobs/ci_pipeline.run b/worker/jobs/ci_pipeline.run
index 6bee929..ff1efa7 100755
--- a/worker/jobs/ci_pipeline.run
+++ b/worker/jobs/ci_pipeline.run
@@ -3,14 +3,4 @@
# add scripts executed by the pipeline
export PATH=$PATH:$PIPELINE_PATH
-containerid=$(cat /etc/hostname)
-isindocker=$(docker ps -q -f "id=$containerid")
-if [ -n "$isindocker" ]; then
- executorLaminarPath=$(docker inspect "$containerid" | jq -r '.[0].Mounts[] | select(.Destination == "/var/lib/laminar") | .Source')
-else
- executorLaminarPath=$(pwd)
-fi
-
-export executorLaminarPath
-
checkout_ci.js
diff --git a/worker/scripts/build_docker_image.ts b/worker/scripts/build_docker_image.ts
index f29bd61..31bd260 100755
--- a/worker/scripts/build_docker_image.ts
+++ b/worker/scripts/build_docker_image.ts
@@ -10,7 +10,7 @@ import {
Command,
} from '@emprespresso/pengueno';
import type { BuildDockerImageJob, BuildDockerImageJobProps } from '@emprespresso/ci_model';
-import { Bitwarden, type LoginItem } from '@emprespresso/ci_worker';
+import { Bitwarden, getPathOnHost, type LoginItem } from '@emprespresso/ci_worker';
import path from 'path';
const job = getRequiredEnvVars([
@@ -78,9 +78,14 @@ await LogMetricTraceable.ofLogTraceable(_logJob)
.map(async (tEitherWithAuthdRegistryBuildJob) => {
const eitherWithAuthdRegistryBuildJob = await tEitherWithAuthdRegistryBuildJob.get();
tEitherWithAuthdRegistryBuildJob.trace.trace('finally building the image~ (◕ᴗ◕✿)');
- const eitherBuiltImage = await eitherWithAuthdRegistryBuildJob.flatMapAsync((job) =>
+ const context = await eitherWithAuthdRegistryBuildJob.flatMapAsync((j) => getPathOnHost(j.arguments.context));
+ const buildJobArgs = eitherWithAuthdRegistryBuildJob.joinRight(context, (context, job) => ({
+ ...job.arguments,
+ context,
+ }));
+ const eitherBuiltImage = await buildJobArgs.flatMapAsync((buildJobArgs) =>
tEitherWithAuthdRegistryBuildJob
- .move(getBuildCommand(job.arguments))
+ .move(getBuildCommand(buildJobArgs))
.map((tBuildCmd) =>
getStdout(tBuildCmd, {
env: {},
@@ -123,18 +128,7 @@ function getDockerLoginCommand(username: string, registry: string): Command {
}
function getBuildCommand({ buildTarget, imageTag, dockerfile, context }: BuildDockerImageJobProps): Command {
- return [
- 'cat',
- path.join(context, dockerfile),
- '|',
- 'docker',
- 'build',
- '--target',
- buildTarget,
- '-t',
- imageTag,
- '-',
- ];
+ return ['docker', 'build', '--target', buildTarget, '-t', imageTag, '-f', dockerfile, context];
}
function getPushCommand(tag: string): Command {
diff --git a/worker/scripts/checkout_ci.ts b/worker/scripts/checkout_ci.ts
index 65cbc2e..c4006e6 100755
--- a/worker/scripts/checkout_ci.ts
+++ b/worker/scripts/checkout_ci.ts
@@ -14,9 +14,9 @@ import {
IEither,
} from '@emprespresso/pengueno';
import { mkdir, readFile, rm } from 'fs/promises';
-import { join } from 'path';
+import path, { join } from 'path';
import { type CheckoutCiJob, type FetchCodeJob, Pipeline, PipelineImpl } from '@emprespresso/ci_model';
-import { executeJob, executePipeline } from '@emprespresso/ci_worker';
+import { executeJob, executePipeline, getPathOnHost } from '@emprespresso/ci_worker';
interface CiWorkflow {
workflow: string;
@@ -42,7 +42,7 @@ const READONLY_CREDENTIALS = { username: 'readonly', password: 'readonly' };
// -> checkout_ci (1000.uuidB)
const run = `${Date.now()}.${crypto.randomUUID().replaceAll('-', '')}`;
-const eitherJob = getRequiredEnvVars(['remote', 'refname', 'rev', 'executorLaminarPath']).mapRight(
+const eitherJob = getRequiredEnvVars(['remote', 'refname', 'rev']).mapRight(
(baseArgs) =>
<CheckoutCiJob>{
type: 'checkout_ci.js',
@@ -76,19 +76,13 @@ await LogMetricTraceable.ofLogTraceable(logTraceableJob)
mkdir(wd, { recursive: true })
.then(() => process.chdir(wd))
.then(() => tEitherJob.move(fetchPackageJob).map(executeJob).get())
- .then((e) =>
- e.fold(
- (err) => {
- throw err;
- },
- () => ciJob,
- ),
- ),
+ .then(() => ciJob),
);
}),
)
.map(async (tEitherCiJob) => {
const eitherCiJob = await tEitherCiJob.get();
+ const jobSrcOnHost = await eitherCiJob.flatMapAsync((job) => getPathOnHost(getSrcDirectoryForCiJob(job)));
const repoCiFileContents = await eitherCiJob.flatMapAsync((ciJob) =>
Either.fromFailableAsync<Error, string>(() =>
readFile(join(getSrcDirectoryForCiJob(ciJob), CI_WORKFLOW_FILE), 'utf-8'),
@@ -98,9 +92,13 @@ await LogMetricTraceable.ofLogTraceable(logTraceableJob)
.flatMap((fileText) =>
Either.fromFailable<Error, CiWorkflow>(() => JSON.parse(fileText)).filter((json) => isCiWorkflow(json)),
)
- .joinRight(eitherCiJob, (job: CheckoutCiJob, { workflow }) => ({
+ .joinRight(eitherCiJob, (job, { workflow }) => ({
job,
- commands: getPipelineGenerationCommand(job, workflow),
+ workflow,
+ }))
+ .joinRight(jobSrcOnHost, (src, { job, workflow }) => ({
+ job,
+ commands: getPipelineGenerationCommand(job, workflow, src),
}));
})
.map(
@@ -150,16 +148,6 @@ await LogMetricTraceable.ofLogTraceable(logTraceableJob)
() => afterJob,
);
})
- .map(
- TraceUtil.promiseify((e) =>
- e.get().fold(
- (err) => {
- throw err;
- },
- (ok) => ok,
- ),
- ),
- )
.get();
function getWorkingDirectoryForCiJob(job: CheckoutCiJob) {
@@ -170,20 +158,10 @@ function getSrcDirectoryForCiJob(job: CheckoutCiJob) {
return `${getWorkingDirectoryForCiJob(job)}/src`;
}
-function getSrcDirectoryForChildContainer(job: CheckoutCiJob) {
- // the container which runs the pipeline synthesizer (A) might be spawned by another container
- // (B) ((which should be the one running this job)) by talking to the host's docker daemon
- // (mounting /var/run/docker.sock) and executing the {@link getPipelineGenerationCommand}.
- //
- // so mounting {@link getSrcDirectoryForCiJob} has no meaning as it doesn't exist on the host;
- // here we replace the path in (B) with the actual volume source on the host, where the src
- // exists.
- return getSrcDirectoryForCiJob(job).replace('/var/lib/laminar', job.arguments.executorLaminarPath);
-}
-
function getPipelineGenerationCommand(
job: CheckoutCiJob,
pipelineGeneratorPath: string,
+ srcMount: string,
credentials = READONLY_CREDENTIALS,
registry = OCI_REGISTRY,
image = PIPELINE_IMAGE,
@@ -201,7 +179,7 @@ function getPipelineGenerationCommand(
'-e',
),
'-v',
- `${getSrcDirectoryForChildContainer(job)}:/src`,
+ `${srcMount}:/src`,
image,
`/src/${pipelineGeneratorPath}`,
],