From eb0a9d937dbf39598d779e9bc6f53d5e084247eb Mon Sep 17 00:00:00 2001 From: Nulo Date: Wed, 5 Apr 2023 17:25:45 -0300 Subject: [PATCH] make it work --- .gitignore | 7 +- index.js | 199 +++++++++++++++++++++++++++++++++++++ index.ts | 96 ------------------ package.json | 7 +- pnpm-lock.yaml | 260 +++---------------------------------------------- readme.md | 23 +++++ vm.xml | 225 ------------------------------------------ 7 files changed, 244 insertions(+), 573 deletions(-) create mode 100644 index.js delete mode 100644 index.ts delete mode 100644 vm.xml diff --git a/.gitignore b/.gitignore index 13518c9..3820e82 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ artifacts node_modules -index.js -index.js.map *.ext4 -*.qcow2 \ No newline at end of file +*.qcow2 +.env +initramfs-virt +vmlinuz-virt diff --git a/index.js b/index.js new file mode 100644 index 0000000..56733c3 --- /dev/null +++ b/index.js @@ -0,0 +1,199 @@ +// @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}`); +} diff --git a/index.ts b/index.ts deleted file mode 100644 index 5a8a01a..0000000 --- a/index.ts +++ /dev/null @@ -1,96 +0,0 @@ -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]); -} diff --git a/package.json b/package.json index fc14b5e..eb142f1 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,13 @@ { "type": "module", "scripts": { - "run": "esbuild --log-level=warning --target=node18 --platform=node --sourcemap --outdir=. --format=esm --bundle index.ts && node --enable-source-maps index.js" + "run": "node index.js" }, "devDependencies": { - "@types/node": "^18.15.5", - "esbuild": "^0.17.12", - "typescript": "^5.0.2" + "@types/node": "^18.15.5" }, "dependencies": { + "dotenv": "^16.0.3", "nanoid": "^4.0.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c569b0..f7d0ba9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,261 +1,31 @@ -lockfileVersion: 5.4 - -specifiers: - '@types/node': ^18.15.5 - esbuild: ^0.17.12 - nanoid: ^4.0.1 - typescript: ^5.0.2 +lockfileVersion: '6.0' dependencies: - nanoid: 4.0.1 + dotenv: + specifier: ^16.0.3 + version: 16.0.3 + nanoid: + specifier: ^4.0.1 + version: 4.0.1 devDependencies: - '@types/node': 18.15.5 - esbuild: 0.17.12 - typescript: 5.0.2 + '@types/node': + specifier: ^18.15.5 + version: 18.15.5 packages: - /@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: + /@types/node@18.15.5: resolution: {integrity: sha512-Ark2WDjjZO7GmvsyFFf81MXuGTA/d6oP38anyxWOL6EREyBKAxKoFHwBhaZxCfLRLpO8JgVXwqOwSwa7jRcjew==} dev: true - /esbuild/0.17.12: - resolution: {integrity: sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==} + /dotenv@16.0.3: + resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} - 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 + dev: false - /nanoid/4.0.1: + /nanoid@4.0.1: resolution: {integrity: sha512-udKGtCCUafD3nQtJg9wBhRP3KMbPglUsgV5JVsXhvyBs/oefqb4sqMEhKBBgqZncYowu58p1prsZQBYvAj/Gww==} engines: {node: ^14 || ^16 || >=18} hasBin: true dev: false - - /typescript/5.0.2: - resolution: {integrity: sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==} - engines: {node: '>=12.20'} - hasBin: true - dev: true diff --git a/readme.md b/readme.md index a4db06a..1788946 100644 --- a/readme.md +++ b/readme.md @@ -4,3 +4,26 @@ 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. 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 +``` diff --git a/vm.xml b/vm.xml deleted file mode 100644 index dc87805..0000000 --- a/vm.xml +++ /dev/null @@ -1,225 +0,0 @@ - - woodpecker-in-a-vm - bdf26ac3-7eb1-41d7-9e29-846c60c85133 - - - - - - 4194304 - 4194304 - 2 - - /machine - - - hvm - /home/diablo/proy/woodpecker-in-a-vm/artifacts/current/boot/vmlinuz-virt - /home/diablo/proy/woodpecker-in-a-vm/artifacts/current/boot/initramfs-virt - quiet root=/dev/vda rw modules=ext4 - - - - - - - - - - - - - - destroy - restart - destroy - - - - - - /usr/bin/qemu-system-x86_64 - - - - - - -
- - - -
- - - - - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - - - -
- - - -
- - - -
- - - - - - - -
- - - - - - - - - - - - - - - - - -
- - - - -
- - - -
- - - - - - - - - - - -