Compare commits
No commits in common. "eb0a9d937dbf39598d779e9bc6f53d5e084247eb" and "5502061f21585c02b75ad9ffd02fcbef78e861d0" have entirely different histories.
eb0a9d937d
...
5502061f21
6 changed files with 347 additions and 245 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,7 +1,4 @@
|
||||||
artifacts
|
artifacts
|
||||||
node_modules
|
node_modules
|
||||||
*.ext4
|
index.js
|
||||||
*.qcow2
|
index.js.map
|
||||||
.env
|
|
||||||
initramfs-virt
|
|
||||||
vmlinuz-virt
|
|
||||||
|
|
199
index.js
199
index.js
|
@ -1,199 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
import { nanoid } from "nanoid";
|
|
||||||
import { execFile as execFileCallback } from "node:child_process";
|
|
||||||
import {
|
|
||||||
constants,
|
|
||||||
copyFile,
|
|
||||||
mkdir,
|
|
||||||
opendir,
|
|
||||||
readdir,
|
|
||||||
rm,
|
|
||||||
symlink,
|
|
||||||
writeFile,
|
|
||||||
} from "node:fs/promises";
|
|
||||||
import { tmpdir } from "node:os";
|
|
||||||
import { basename, join } from "node:path";
|
|
||||||
import { promisify } from "node:util";
|
|
||||||
import * as dotenv from "dotenv";
|
|
||||||
dotenv.config();
|
|
||||||
|
|
||||||
const execFile = promisify(execFileCallback);
|
|
||||||
|
|
||||||
// TODO: configurar runsc
|
|
||||||
// TODO: cache de apk (robar de define-alpine-the-sequel)
|
|
||||||
|
|
||||||
const currRootPath = await setupRootfsDir();
|
|
||||||
await setupBasicApkEnvironment(currRootPath);
|
|
||||||
const packages = ["alpine-base", "fish", "docker", "linux-virt"];
|
|
||||||
await execFile("doas", [
|
|
||||||
"apk",
|
|
||||||
"--initdb",
|
|
||||||
"--clean-protected",
|
|
||||||
"--root",
|
|
||||||
currRootPath,
|
|
||||||
"add",
|
|
||||||
...packages,
|
|
||||||
]);
|
|
||||||
await chroot(currRootPath, ["rc-update", "add", "networking", "sysinit"]);
|
|
||||||
await chroot(currRootPath, ["rc-update", "add", "docker", "boot"]);
|
|
||||||
await chroot(currRootPath, ["rc-update", "add", "acpid", "default"]);
|
|
||||||
await chroot(currRootPath, ["rc-update", "add", "local", "default"]);
|
|
||||||
|
|
||||||
await writeFile(
|
|
||||||
"interfaces",
|
|
||||||
`auto lo
|
|
||||||
iface lo inet loopback
|
|
||||||
|
|
||||||
auto eth0
|
|
||||||
iface eth0
|
|
||||||
use dhcp`,
|
|
||||||
{ mode: 0o600 }
|
|
||||||
);
|
|
||||||
await execFile("doas", [
|
|
||||||
"mv",
|
|
||||||
"interfaces",
|
|
||||||
join(currRootPath, "/etc/network/interfaces"),
|
|
||||||
]);
|
|
||||||
await execFile("doas", [
|
|
||||||
"chown",
|
|
||||||
"0:0",
|
|
||||||
join(currRootPath, "/etc/network/interfaces"),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const woodpeckerSecret = getConfig("WOODPECKER_SECRET");
|
|
||||||
const woodpeckerServer = getConfig("WOODPECKER_SERVER");
|
|
||||||
|
|
||||||
await writeFile(
|
|
||||||
"woodpecker.start",
|
|
||||||
`#!/bin/sh
|
|
||||||
docker pull docker.io/woodpeckerci/woodpecker-agent:latest || exit $?
|
|
||||||
exec docker run --detach --rm \
|
|
||||||
--name=woodpecker-agent \
|
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
-e WOODPECKER_SERVER='${woodpeckerServer}' \
|
|
||||||
-e WOODPECKER_SECRET='${woodpeckerSecret}' \
|
|
||||||
-e WOODPECKER_MAX_PROCS=8 \
|
|
||||||
docker.io/woodpeckerci/woodpecker-agent:latest \
|
|
||||||
agent`,
|
|
||||||
{ mode: 0o700 }
|
|
||||||
);
|
|
||||||
await execFile("doas", [
|
|
||||||
"mv",
|
|
||||||
"woodpecker.start",
|
|
||||||
join(currRootPath, "/etc/local.d/woodpecker.start"),
|
|
||||||
]);
|
|
||||||
await execFile("doas", [
|
|
||||||
"chown",
|
|
||||||
"0:0",
|
|
||||||
join(currRootPath, "/etc/local.d/woodpecker.start"),
|
|
||||||
]);
|
|
||||||
|
|
||||||
await chroot(currRootPath, ["rc-update", "add", "localmount", "boot"]);
|
|
||||||
await writeFstab(currRootPath);
|
|
||||||
|
|
||||||
// make VM disk image
|
|
||||||
const ext4Path = "raw.ext4";
|
|
||||||
await execFile("qemu-img", ["create", "-f", "raw", ext4Path, "50G"]);
|
|
||||||
await execFile("mkfs.ext4", [ext4Path]);
|
|
||||||
|
|
||||||
const mntdir = join(tmpdir(), "woodpecker-in-a-vm-" + nanoid());
|
|
||||||
await mkdir(mntdir);
|
|
||||||
await execFile("doas", ["mount", ext4Path, mntdir]);
|
|
||||||
for (const path of await readdir(currRootPath))
|
|
||||||
await execFile("doas", ["cp", "-r", join(currRootPath, path), mntdir]);
|
|
||||||
await execFile("doas", ["umount", mntdir]);
|
|
||||||
await execFile("doas", [
|
|
||||||
"qemu-img",
|
|
||||||
"convert",
|
|
||||||
"-O",
|
|
||||||
"qcow2",
|
|
||||||
ext4Path,
|
|
||||||
"vm.qcow2",
|
|
||||||
]);
|
|
||||||
|
|
||||||
await copyFile(
|
|
||||||
join(currRootPath, "boot/vmlinuz-virt"),
|
|
||||||
"./vmlinuz-virt",
|
|
||||||
constants.COPYFILE_FICLONE
|
|
||||||
);
|
|
||||||
await copyFile(
|
|
||||||
join(currRootPath, "boot/initramfs-virt"),
|
|
||||||
"./initramfs-virt",
|
|
||||||
constants.COPYFILE_FICLONE
|
|
||||||
);
|
|
||||||
await execFile("doas", [
|
|
||||||
"chown",
|
|
||||||
"1000:1000",
|
|
||||||
"./vmlinuz-virt",
|
|
||||||
"./initramfs-virt",
|
|
||||||
"./vm.qcow2",
|
|
||||||
]);
|
|
||||||
|
|
||||||
async function setupRootfsDir() {
|
|
||||||
const artifactsPath = "./artifacts";
|
|
||||||
const currRootPath = join(artifactsPath, "rootfs" + nanoid());
|
|
||||||
await mkdir(currRootPath, { recursive: true });
|
|
||||||
|
|
||||||
{
|
|
||||||
const currentPath = join(artifactsPath, "current");
|
|
||||||
try {
|
|
||||||
await rm(currentPath);
|
|
||||||
} catch {}
|
|
||||||
await symlink(basename(currRootPath), currentPath);
|
|
||||||
}
|
|
||||||
return currRootPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} rootfs
|
|
||||||
*/
|
|
||||||
async function setupBasicApkEnvironment(rootfs) {
|
|
||||||
{
|
|
||||||
const apkKeysDir = join(rootfs, "/etc/apk/keys");
|
|
||||||
const keysSrcDir = "alpine/keys";
|
|
||||||
await mkdir(apkKeysDir, { recursive: true });
|
|
||||||
for await (const { name } of await opendir(keysSrcDir))
|
|
||||||
await copyFile(join(keysSrcDir, name), join(apkKeysDir, name));
|
|
||||||
}
|
|
||||||
|
|
||||||
await writeFile(
|
|
||||||
join(rootfs, "/etc/apk/repositories"),
|
|
||||||
[
|
|
||||||
// "https://dl-cdn.alpinelinux.org/alpine/v3.17/main",
|
|
||||||
// "https://dl-cdn.alpinelinux.org/alpine/v3.17/community",
|
|
||||||
"http://alpinelinux.c3sl.ufpr.br/v3.17/main",
|
|
||||||
"http://alpinelinux.c3sl.ufpr.br/v3.17/community",
|
|
||||||
].join("\n")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} rootfs
|
|
||||||
*/
|
|
||||||
async function writeFstab(rootfs) {
|
|
||||||
const virtualDiskName = "/dev/vda";
|
|
||||||
await writeFile(
|
|
||||||
"fstab",
|
|
||||||
`${virtualDiskName} / ext4 rw,relatime,discard 0 1
|
|
||||||
`
|
|
||||||
);
|
|
||||||
await execFile("doas", ["mv", "fstab", join(rootfs, "/etc/fstab")]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Corre comando en chroot
|
|
||||||
* @param {string} rootfs
|
|
||||||
* @param {string[]} cmd
|
|
||||||
*/
|
|
||||||
async function chroot(rootfs, cmd) {
|
|
||||||
await execFile("doas", ["chroot", rootfs, ...cmd]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} name
|
|
||||||
* @returns {string} la variable conseguida
|
|
||||||
*/
|
|
||||||
function getConfig(name) {
|
|
||||||
if (name in process.env) return process.env[name] || "";
|
|
||||||
else throw new Error(`Falta la variable ${name}`);
|
|
||||||
}
|
|
96
index.ts
Normal file
96
index.ts
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
|
import { execFile as execFileCallback } from "node:child_process";
|
||||||
|
import {
|
||||||
|
copyFile,
|
||||||
|
mkdir,
|
||||||
|
opendir,
|
||||||
|
readdir,
|
||||||
|
rm,
|
||||||
|
symlink,
|
||||||
|
writeFile,
|
||||||
|
} from "node:fs/promises";
|
||||||
|
import { tmpdir } from "node:os";
|
||||||
|
import { basename, join } from "node:path";
|
||||||
|
import { promisify } from "node:util";
|
||||||
|
|
||||||
|
const execFile = promisify(execFileCallback);
|
||||||
|
|
||||||
|
// TODO: configurar runsc
|
||||||
|
// TODO: cache de apk (robar de define-alpine-the-sequel)
|
||||||
|
|
||||||
|
const currRootPath = await setupRootfsDir();
|
||||||
|
await setupBasicApkEnvironment(currRootPath);
|
||||||
|
const packages = ["alpine-base", "fish", "docker", "linux-virt"];
|
||||||
|
await execFile("doas", [
|
||||||
|
"apk",
|
||||||
|
"--initdb",
|
||||||
|
"--clean-protected",
|
||||||
|
"--root",
|
||||||
|
currRootPath,
|
||||||
|
"add",
|
||||||
|
...packages,
|
||||||
|
]);
|
||||||
|
await chroot(currRootPath, ["rc-update", "add", "docker", "default"]);
|
||||||
|
|
||||||
|
await chroot(currRootPath, ["rc-update", "add", "localmount", "boot"]);
|
||||||
|
await writeFstab(currRootPath);
|
||||||
|
|
||||||
|
// make VM disk image
|
||||||
|
const ext4Path = "raw.ext4";
|
||||||
|
await execFile("qemu-img", ["create", "-f", "raw", ext4Path, "50G"]);
|
||||||
|
await execFile("mkfs.ext4", [ext4Path]);
|
||||||
|
|
||||||
|
const mntdir = join(tmpdir(), "woodpecker-in-a-vm-" + nanoid());
|
||||||
|
await mkdir(mntdir);
|
||||||
|
await execFile("doas", ["mount", ext4Path, mntdir]);
|
||||||
|
for (const path of await readdir(currRootPath))
|
||||||
|
await execFile("doas", ["cp", "-r", join(currRootPath, path), mntdir]);
|
||||||
|
await execFile("doas", ["umount", mntdir]);
|
||||||
|
await execFile("qemu-img", ["convert", "-O", "qcow2", ext4Path, "vm.qcow2"]);
|
||||||
|
|
||||||
|
async function setupRootfsDir() {
|
||||||
|
const artifactsPath = "./artifacts";
|
||||||
|
const currRootPath = join(artifactsPath, "rootfs" + nanoid());
|
||||||
|
await mkdir(currRootPath, { recursive: true });
|
||||||
|
|
||||||
|
{
|
||||||
|
const currentPath = join(artifactsPath, "current");
|
||||||
|
try {
|
||||||
|
await rm(currentPath);
|
||||||
|
} catch {}
|
||||||
|
await symlink(basename(currRootPath), currentPath);
|
||||||
|
}
|
||||||
|
return currRootPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setupBasicApkEnvironment(rootfs: string) {
|
||||||
|
{
|
||||||
|
const apkKeysDir = join(rootfs, "/etc/apk/keys");
|
||||||
|
const keysSrcDir = "alpine/keys";
|
||||||
|
await mkdir(apkKeysDir, { recursive: true });
|
||||||
|
for await (const { name } of await opendir(keysSrcDir))
|
||||||
|
await copyFile(join(keysSrcDir, name), join(apkKeysDir, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
await writeFile(
|
||||||
|
join(rootfs, "/etc/apk/repositories"),
|
||||||
|
[
|
||||||
|
"https://dl-cdn.alpinelinux.org/alpine/v3.17/main",
|
||||||
|
"https://dl-cdn.alpinelinux.org/alpine/v3.17/community",
|
||||||
|
].join("\n")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function writeFstab(rootfs: string) {
|
||||||
|
const virtualDiskName = "/dev/vda";
|
||||||
|
await writeFile(
|
||||||
|
"fstab",
|
||||||
|
`${virtualDiskName} / ext4 rw,relatime,discard 0 1
|
||||||
|
`
|
||||||
|
);
|
||||||
|
await execFile("doas", ["mv", "fstab", join(rootfs, "/etc/fstab")]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function chroot(rootfs: string, cmd: string[]) {
|
||||||
|
await execFile("doas", ["chroot", rootfs, ...cmd]);
|
||||||
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"run": "node index.js"
|
"run": "esbuild --log-level=warning --target=node18 --platform=node --sourcemap --outdir=. --format=esm --bundle index.ts && node --enable-source-maps index.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.15.5"
|
"@types/node": "^18.15.5",
|
||||||
|
"esbuild": "^0.17.12",
|
||||||
|
"typescript": "^5.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^16.0.3",
|
|
||||||
"nanoid": "^4.0.1"
|
"nanoid": "^4.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
260
pnpm-lock.yaml
260
pnpm-lock.yaml
|
@ -1,31 +1,261 @@
|
||||||
lockfileVersion: '6.0'
|
lockfileVersion: 5.4
|
||||||
|
|
||||||
|
specifiers:
|
||||||
|
'@types/node': ^18.15.5
|
||||||
|
esbuild: ^0.17.12
|
||||||
|
nanoid: ^4.0.1
|
||||||
|
typescript: ^5.0.2
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
dotenv:
|
nanoid: 4.0.1
|
||||||
specifier: ^16.0.3
|
|
||||||
version: 16.0.3
|
|
||||||
nanoid:
|
|
||||||
specifier: ^4.0.1
|
|
||||||
version: 4.0.1
|
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/node':
|
'@types/node': 18.15.5
|
||||||
specifier: ^18.15.5
|
esbuild: 0.17.12
|
||||||
version: 18.15.5
|
typescript: 5.0.2
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
/@types/node@18.15.5:
|
/@esbuild/android-arm/0.17.12:
|
||||||
|
resolution: {integrity: sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [android]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/android-arm64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-WQ9p5oiXXYJ33F2EkE3r0FRDFVpEdcDiwNX3u7Xaibxfx6vQE0Sb8ytrfQsA5WO6kDn6mDfKLh6KrPBjvkk7xA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [android]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/android-x64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [android]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/darwin-arm64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [darwin]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/darwin-x64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [darwin]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/freebsd-arm64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [freebsd]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/freebsd-x64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-A0Xg5CZv8MU9xh4a+7NUpi5VHBKh1RaGJKqjxe4KG87X+mTjDE6ZvlJqpWoeJxgfXHT7IMP9tDFu7IZ03OtJAw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [freebsd]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-arm/0.17.12:
|
||||||
|
resolution: {integrity: sha512-WsHyJ7b7vzHdJ1fv67Yf++2dz3D726oO3QCu8iNYik4fb5YuuReOI9OtA+n7Mk0xyQivNTPbl181s+5oZ38gyA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-arm64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-cK3AjkEc+8v8YG02hYLQIQlOznW+v9N+OI9BAFuyqkfQFR+DnDLhEM5N8QRxAUz99cJTo1rLNXqRrvY15gbQUg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-ia32/0.17.12:
|
||||||
|
resolution: {integrity: sha512-jdOBXJqcgHlah/nYHnj3Hrnl9l63RjtQ4vn9+bohjQPI2QafASB5MtHAoEv0JQHVb/xYQTFOeuHnNYE1zF7tYw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [ia32]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-loong64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-GTOEtj8h9qPKXCyiBBnHconSCV9LwFyx/gv3Phw0pa25qPYjVuuGZ4Dk14bGCfGX3qKF0+ceeQvwmtI+aYBbVA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [loong64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-mips64el/0.17.12:
|
||||||
|
resolution: {integrity: sha512-o8CIhfBwKcxmEENOH9RwmUejs5jFiNoDw7YgS0EJTF6kgPgcqLFjgoc5kDey5cMHRVCIWc6kK2ShUePOcc7RbA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [mips64el]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-ppc64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-biMLH6NR/GR4z+ap0oJYb877LdBpGac8KfZoEnDiBKd7MD/xt8eaw1SFfYRUeMVx519kVkAOL2GExdFmYnZx3A==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [ppc64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-riscv64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-jkphYUiO38wZGeWlfIBMB72auOllNA2sLfiZPGDtOBb1ELN8lmqBrlMiucgL8awBw1zBXN69PmZM6g4yTX84TA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [riscv64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-s390x/0.17.12:
|
||||||
|
resolution: {integrity: sha512-j3ucLdeY9HBcvODhCY4b+Ds3hWGO8t+SAidtmWu/ukfLLG/oYDMaA+dnugTVAg5fnUOGNbIYL9TOjhWgQB8W5g==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [s390x]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/linux-x64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-uo5JL3cgaEGotaqSaJdRfFNSCUJOIliKLnDGWaVCgIKkHxwhYMm95pfMbWZ9l7GeW9kDg0tSxcy9NYdEtjwwmA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [linux]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/netbsd-x64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-DNdoRg8JX+gGsbqt2gPgkgb00mqOgOO27KnrWZtdABl6yWTST30aibGJ6geBq3WM2TIeW6COs5AScnC7GwtGPg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [netbsd]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/openbsd-x64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-aVsENlr7B64w8I1lhHShND5o8cW6sB9n9MUtLumFlPhG3elhNWtE7M1TFpj3m7lT3sKQUMkGFjTQBrvDDO1YWA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [openbsd]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/sunos-x64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-qbHGVQdKSwi0JQJuZznS4SyY27tYXYF0mrgthbxXrZI3AHKuRvU+Eqbg/F0rmLDpW/jkIZBlCO1XfHUBMNJ1pg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [sunos]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/win32-arm64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-zsCp8Ql+96xXTVTmm6ffvoTSZSV2B/LzzkUXAY33F/76EajNw1m+jZ9zPfNJlJ3Rh4EzOszNDHsmG/fZOhtqDg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [arm64]
|
||||||
|
os: [win32]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/win32-ia32/0.17.12:
|
||||||
|
resolution: {integrity: sha512-FfrFjR4id7wcFYOdqbDfDET3tjxCozUgbqdkOABsSFzoZGFC92UK7mg4JKRc/B3NNEf1s2WHxJ7VfTdVDPN3ng==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [ia32]
|
||||||
|
os: [win32]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@esbuild/win32-x64/0.17.12:
|
||||||
|
resolution: {integrity: sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
cpu: [x64]
|
||||||
|
os: [win32]
|
||||||
|
requiresBuild: true
|
||||||
|
dev: true
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
/@types/node/18.15.5:
|
||||||
resolution: {integrity: sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==}
|
resolution: {integrity: sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/dotenv@16.0.3:
|
/esbuild/0.17.12:
|
||||||
resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
|
resolution: {integrity: sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
dev: false
|
hasBin: true
|
||||||
|
requiresBuild: true
|
||||||
|
optionalDependencies:
|
||||||
|
'@esbuild/android-arm': 0.17.12
|
||||||
|
'@esbuild/android-arm64': 0.17.12
|
||||||
|
'@esbuild/android-x64': 0.17.12
|
||||||
|
'@esbuild/darwin-arm64': 0.17.12
|
||||||
|
'@esbuild/darwin-x64': 0.17.12
|
||||||
|
'@esbuild/freebsd-arm64': 0.17.12
|
||||||
|
'@esbuild/freebsd-x64': 0.17.12
|
||||||
|
'@esbuild/linux-arm': 0.17.12
|
||||||
|
'@esbuild/linux-arm64': 0.17.12
|
||||||
|
'@esbuild/linux-ia32': 0.17.12
|
||||||
|
'@esbuild/linux-loong64': 0.17.12
|
||||||
|
'@esbuild/linux-mips64el': 0.17.12
|
||||||
|
'@esbuild/linux-ppc64': 0.17.12
|
||||||
|
'@esbuild/linux-riscv64': 0.17.12
|
||||||
|
'@esbuild/linux-s390x': 0.17.12
|
||||||
|
'@esbuild/linux-x64': 0.17.12
|
||||||
|
'@esbuild/netbsd-x64': 0.17.12
|
||||||
|
'@esbuild/openbsd-x64': 0.17.12
|
||||||
|
'@esbuild/sunos-x64': 0.17.12
|
||||||
|
'@esbuild/win32-arm64': 0.17.12
|
||||||
|
'@esbuild/win32-ia32': 0.17.12
|
||||||
|
'@esbuild/win32-x64': 0.17.12
|
||||||
|
dev: true
|
||||||
|
|
||||||
/nanoid@4.0.1:
|
/nanoid/4.0.1:
|
||||||
resolution: {integrity: sha512-udKGtCCUafD3nQtJg9wBhRP3KMbPglUsgV5JVsXhvyBs/oefqb4sqMEhKBBgqZncYowu58p1prsZQBYvAj/Gww==}
|
resolution: {integrity: sha512-udKGtCCUafD3nQtJg9wBhRP3KMbPglUsgV5JVsXhvyBs/oefqb4sqMEhKBBgqZncYowu58p1prsZQBYvAj/Gww==}
|
||||||
engines: {node: ^14 || ^16 || >=18}
|
engines: {node: ^14 || ^16 || >=18}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/typescript/5.0.2:
|
||||||
|
resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==}
|
||||||
|
engines: {node: '>=12.20'}
|
||||||
|
hasBin: true
|
||||||
|
dev: true
|
||||||
|
|
23
readme.md
23
readme.md
|
@ -4,26 +4,3 @@
|
||||||
1. lo configuré para que borre en el disco real si se borra algo dentro de la vm
|
1. lo configuré para que borre en el disco real si se borra algo dentro de la vm
|
||||||
1. como woodpecker-agent no tiene state, puedo regenerar la vm con el script las veces que quiera
|
1. como woodpecker-agent no tiene state, puedo regenerar la vm con el script las veces que quiera
|
||||||
1. no tengo que exponer mi docker real al agent porque está en una vm con el suyo
|
1. no tengo que exponer mi docker real al agent porque está en una vm con el suyo
|
||||||
|
|
||||||
|
|
||||||
## compilar imágen
|
|
||||||
|
|
||||||
```sh
|
|
||||||
node index.js
|
|
||||||
```
|
|
||||||
|
|
||||||
copiar `initramfs-virt vmlinuz-virt vm.qcow2` al servidor a `/var/lib/libvirt/images`
|
|
||||||
|
|
||||||
## definir vm
|
|
||||||
|
|
||||||
```sh
|
|
||||||
virsh shutdown woodpecker-in-a-vm
|
|
||||||
virsh undefine woodpecker-in-a-vm
|
|
||||||
virt-install --name woodpecker-in-a-vm \
|
|
||||||
--osinfo alpinelinux3.16 \
|
|
||||||
--memory 4096 --vcpus 4 \
|
|
||||||
--import \
|
|
||||||
--disk path=/var/lib/libvirt/images/vm.qcow2,format=qcow2 \
|
|
||||||
--boot kernel=/var/lib/libvirt/images/vmlinuz-virt,initrd=/var/lib/libvirt/images/initramfs-virt,kernel_args="console=/dev/ttyS0 quiet root=/dev/vda rw modules=ext4" \
|
|
||||||
--noautoconsole
|
|
||||||
```
|
|
||||||
|
|
Loading…
Reference in a new issue