summaryrefslogtreecommitdiff
path: root/worker/scripts
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2025-07-26 21:07:36 -0700
committerElizabeth Hunt <me@liz.coffee>2025-07-27 00:00:12 -0700
commitdf76fa3c266f7f9b22d2bfaf98ad5accebcabd35 (patch)
tree8aaef9f227e385b8e31bd6c69fc6a8231326f361 /worker/scripts
parent9ee3bf3345b006a745b2ee28fee3613819011796 (diff)
downloadci-df76fa3c266f7f9b22d2bfaf98ad5accebcabd35.tar.gz
ci-df76fa3c266f7f9b22d2bfaf98ad5accebcabd35.zip
Fixes type inference for Either.joinRightAsync. Regarding ansible-docker. Will it ever be okay to trust docs?!!
Diffstat (limited to 'worker/scripts')
-rwxr-xr-xworker/scripts/ansible_playbook.ts99
-rwxr-xr-xworker/scripts/fetch_code10
2 files changed, 64 insertions, 45 deletions
diff --git a/worker/scripts/ansible_playbook.ts b/worker/scripts/ansible_playbook.ts
index 20f85d8..2048d44 100755
--- a/worker/scripts/ansible_playbook.ts
+++ b/worker/scripts/ansible_playbook.ts
@@ -12,10 +12,10 @@ import {
TraceUtil,
} from '@emprespresso/pengueno';
import type { AnsiblePlaybookJob } from '@emprespresso/ci_model';
-import { Bitwarden, type SecureNote } from '@emprespresso/ci_worker';
-import { writeFile, mkdtemp } from 'fs/promises';
+import { Bitwarden, BitwardenKey, getPathOnHost, type SecureNote } from '@emprespresso/ci_worker';
+import { writeFile, mkdir } from 'fs/promises';
import { join } from 'path';
-import { tmpdir } from 'os';
+import { rmSync } from 'fs';
const eitherJob = getRequiredEnvVars(['path', 'playbooks']).mapRight(
(baseArgs) =>
@@ -41,51 +41,69 @@ await LogMetricTraceable.ofLogTraceable(_logJob)
}),
),
)
- .map(async (tEitherJobVault) => {
- const eitherJobVault = await tEitherJobVault.get();
-
- const eitherSshKey = await eitherJobVault.flatMapAsync(({ key, vault }) =>
- vault.fetchSecret<SecureNote>(tEitherJobVault, key, 'ssh_key'),
- );
- const eitherSshKeyFile = await eitherSshKey.mapRight(({ notes }) => notes).flatMapAsync(saveToTempFile);
- const eitherAnsibleSecrets = await eitherJobVault.flatMapAsync(({ key, vault }) =>
- vault.fetchSecret<SecureNote>(tEitherJobVault, key, 'ansible_secrets'),
- );
- const eitherAnsibleSecretsFile = await eitherAnsibleSecrets
- .mapRight(({ notes }) => notes)
- .flatMapAsync(saveToTempFile);
-
- return eitherJobVault.flatMapAsync(async ({ job, vault, key }) => {
- const eitherLocked = await vault.lock(tEitherJobVault, key);
- return eitherLocked.flatMap((_locked) =>
- eitherSshKeyFile.flatMap((sshKeyFile) =>
- eitherAnsibleSecretsFile.mapRight((secretsFile) => ({
- job,
- sshKeyFile,
- secretsFile,
- })),
- ),
- );
- });
- })
+ .map(
+ async (
+ tEitherJobVault,
+ ): Promise<
+ IEither<
+ Error,
+ {
+ secretFiles: { ssh_key: string; ansible_secrets: string };
+ key: BitwardenKey;
+ vault: Bitwarden;
+ job: AnsiblePlaybookJob;
+ }
+ >
+ > =>
+ ['ssh_key', 'ansible_secrets'].reduce(
+ async (_result, secret) => {
+ const result = await _result;
+ return result.joinRightAsync(
+ result.flatMapAsync(({ key, vault, job }) =>
+ vault
+ .fetchSecret<SecureNote>(tEitherJobVault, key, secret)
+ .then((eSecret) => eSecret.flatMapAsync(({ notes }) => saveToTempFile(job, notes))),
+ ),
+ (file, prev) => ({ ...prev, secretFiles: { ...prev.secretFiles, [secret]: file } }),
+ );
+ },
+ tEitherJobVault.get().then((e) => e.mapRight((r) => ({ ...r, secretFiles: <any>{} }))),
+ ),
+ )
.map(async (tEitherJobAndSecrets) => {
const eitherJobAndSecrets = await tEitherJobAndSecrets.get();
- return eitherJobAndSecrets.flatMapAsync(({ job, sshKeyFile, secretsFile }) => {
+ return eitherJobAndSecrets.flatMapAsync(async ({ job, secretFiles }) => {
+ const [src, sshKey, ansibleSecrets] = (
+ await Promise.all(
+ [join(process.cwd(), job.arguments.path), secretFiles.ssh_key, secretFiles.ansible_secrets].map(
+ (x) => getPathOnHost(x),
+ ),
+ )
+ ).map((x) => x.right().get());
const volumes = [
- `${job.arguments.path}:/ansible`,
- `${sshKeyFile}:/root/id_rsa`,
- `${secretsFile}:/ansible/secrets.yml`,
+ `${src}:/ansible`,
+ `${sshKey}:/root/.ssh/id_ed25519`,
+ `${ansibleSecrets}:/ansible/secrets.yml`,
];
const playbookCmd = `ansible-playbook -e @secrets.yml ${job.arguments.playbooks}`;
const deployCmd = [
'docker',
'run',
...prependWith(volumes, '-v'),
+ '--workdir=/ansible',
'willhallonline/ansible:latest',
...playbookCmd.split(' '),
];
tEitherJobAndSecrets.trace.trace(`running ansible magic~ (◕ᴗ◕✿) ${deployCmd}`);
- return tEitherJobAndSecrets.move(deployCmd).map(getStdout).get();
+ return tEitherJobAndSecrets
+ .move(deployCmd)
+ .map((c) =>
+ getStdout(c, { streamTraceable: ['stdout', 'stderr'] }).then((e) => {
+ Object.values(secretFiles).forEach((f) => rmSync(f));
+ return e;
+ }),
+ )
+ .get();
});
})
.map(async (tEitherJob) => {
@@ -97,12 +115,13 @@ await LogMetricTraceable.ofLogTraceable(_logJob)
})
.get();
-function saveToTempFile(text: string): Promise<IEither<Error, string>> {
+async function saveToTempFile(job: AnsiblePlaybookJob, text: string): Promise<IEither<Error, string>> {
+ const dir = join(process.cwd(), '.secrets', crypto.randomUUID());
+ const file = join(dir, 'secret');
return Either.fromFailableAsync(() =>
- mkdtemp(join(tmpdir(), 'ci-')).then(async (dir) => {
- const filePath = join(dir, 'temp-file');
- await writeFile(filePath, text);
- return filePath;
+ mkdir(dir, { recursive: true }).then(async () => {
+ await writeFile(file, text, { encoding: 'utf-8' });
+ return file;
}),
);
}
diff --git a/worker/scripts/fetch_code b/worker/scripts/fetch_code
index 2691832..d711f82 100755
--- a/worker/scripts/fetch_code
+++ b/worker/scripts/fetch_code
@@ -1,10 +1,10 @@
#!/bin/bash
-export LOG_PREFIX="[fetch_code $remote @ $checkout -> $path]"
+export LOG_PREFIX="[fetch_code $remoteUrl @ $checkout -> $path]"
-if [[ "$remote" == ssh://* ]]; then
- host=$(echo "$remote" | sed -E 's#ssh://([^:]+):[0-9]+/.*#\1#')
- port=$(echo "$remote" | sed -E 's#ssh://[^:]+:([0-9]+)/.*#\1#')
+if [[ "$remoteUrl" == ssh://* ]]; then
+ host=$(echo "$remoteUrl" | sed -E 's#ssh://([^:]+):[0-9]+/.*#\1#')
+ port=$(echo "$remoteUrl" | sed -E 's#ssh://[^:]+:([0-9]+)/.*#\1#')
log "populating host keyz~ $host:$port"
ssh-keyscan -p "$port" "$host" > ./cur_known_hosts
@@ -14,7 +14,7 @@ if [[ "$remote" == ssh://* ]]; then
fi
log "getting the codez~ time to fetch!"
-git clone "$remote" "$path"
+git clone "$remoteUrl" "$path"
if [ ! $? -eq 0 ]; then
log "D: oh nyo! couldn't clone the repo"
exit 1