make it work
This commit is contained in:
parent
c6cd179efd
commit
eb0a9d937d
7 changed files with 244 additions and 573 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
||||||
artifacts
|
artifacts
|
||||||
node_modules
|
node_modules
|
||||||
index.js
|
|
||||||
index.js.map
|
|
||||||
*.ext4
|
*.ext4
|
||||||
*.qcow2
|
*.qcow2
|
||||||
|
.env
|
||||||
|
initramfs-virt
|
||||||
|
vmlinuz-virt
|
||||||
|
|
199
index.js
Normal file
199
index.js
Normal file
|
@ -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}`);
|
||||||
|
}
|
96
index.ts
96
index.ts
|
@ -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]);
|
|
||||||
}
|
|
|
@ -1,14 +1,13 @@
|
||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"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": {
|
"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,261 +1,31 @@
|
||||||
lockfileVersion: 5.4
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
specifiers:
|
|
||||||
'@types/node': ^18.15.5
|
|
||||||
esbuild: ^0.17.12
|
|
||||||
nanoid: ^4.0.1
|
|
||||||
typescript: ^5.0.2
|
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
nanoid: 4.0.1
|
dotenv:
|
||||||
|
specifier: ^16.0.3
|
||||||
|
version: 16.0.3
|
||||||
|
nanoid:
|
||||||
|
specifier: ^4.0.1
|
||||||
|
version: 4.0.1
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@types/node': 18.15.5
|
'@types/node':
|
||||||
esbuild: 0.17.12
|
specifier: ^18.15.5
|
||||||
typescript: 5.0.2
|
version: 18.15.5
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
/@esbuild/android-arm/0.17.12:
|
/@types/node@18.15.5:
|
||||||
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
|
||||||
|
|
||||||
/esbuild/0.17.12:
|
/dotenv@16.0.3:
|
||||||
resolution: {integrity: sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==}
|
resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
hasBin: true
|
dev: false
|
||||||
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,3 +4,26 @@
|
||||||
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
|
||||||
|
```
|
||||||
|
|
225
vm.xml
225
vm.xml
|
@ -1,225 +0,0 @@
|
||||||
<domain type='kvm' id='2'>
|
|
||||||
<name>woodpecker-in-a-vm</name>
|
|
||||||
<uuid>bdf26ac3-7eb1-41d7-9e29-846c60c85133</uuid>
|
|
||||||
<metadata>
|
|
||||||
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
|
|
||||||
<libosinfo:os id="http://alpinelinux.org/alpinelinux/3.17"/>
|
|
||||||
</libosinfo:libosinfo>
|
|
||||||
</metadata>
|
|
||||||
<memory unit='KiB'>4194304</memory>
|
|
||||||
<currentMemory unit='KiB'>4194304</currentMemory>
|
|
||||||
<vcpu placement='static'>2</vcpu>
|
|
||||||
<resource>
|
|
||||||
<partition>/machine</partition>
|
|
||||||
</resource>
|
|
||||||
<os>
|
|
||||||
<type arch='x86_64' machine='pc-q35-7.2'>hvm</type>
|
|
||||||
<kernel>/home/diablo/proy/woodpecker-in-a-vm/artifacts/current/boot/vmlinuz-virt</kernel>
|
|
||||||
<initrd>/home/diablo/proy/woodpecker-in-a-vm/artifacts/current/boot/initramfs-virt</initrd>
|
|
||||||
<cmdline>quiet root=/dev/vda rw modules=ext4</cmdline>
|
|
||||||
<boot dev='hd'/>
|
|
||||||
</os>
|
|
||||||
<features>
|
|
||||||
<acpi/>
|
|
||||||
<apic/>
|
|
||||||
<vmport state='off'/>
|
|
||||||
</features>
|
|
||||||
<cpu mode='host-passthrough' check='none' migratable='on'/>
|
|
||||||
<clock offset='utc'>
|
|
||||||
<timer name='rtc' tickpolicy='catchup'/>
|
|
||||||
<timer name='pit' tickpolicy='delay'/>
|
|
||||||
<timer name='hpet' present='no'/>
|
|
||||||
</clock>
|
|
||||||
<on_poweroff>destroy</on_poweroff>
|
|
||||||
<on_reboot>restart</on_reboot>
|
|
||||||
<on_crash>destroy</on_crash>
|
|
||||||
<pm>
|
|
||||||
<suspend-to-mem enabled='no'/>
|
|
||||||
<suspend-to-disk enabled='no'/>
|
|
||||||
</pm>
|
|
||||||
<devices>
|
|
||||||
<emulator>/usr/bin/qemu-system-x86_64</emulator>
|
|
||||||
<disk type='file' device='disk'>
|
|
||||||
<driver name='qemu' type='qcow2' discard='unmap'/>
|
|
||||||
<source file='/home/diablo/proy/woodpecker-in-a-vm/vm.qcow2' index='1'/>
|
|
||||||
<backingStore/>
|
|
||||||
<target dev='vda' bus='virtio'/>
|
|
||||||
<alias name='virtio-disk0'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/>
|
|
||||||
</disk>
|
|
||||||
<controller type='usb' index='0' model='qemu-xhci' ports='15'>
|
|
||||||
<alias name='usb'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x0'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='0' model='pcie-root'>
|
|
||||||
<alias name='pcie.0'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='1' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='1' port='0x10'/>
|
|
||||||
<alias name='pci.1'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0' multifunction='on'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='2' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='2' port='0x11'/>
|
|
||||||
<alias name='pci.2'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='3' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='3' port='0x12'/>
|
|
||||||
<alias name='pci.3'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x2'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='4' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='4' port='0x13'/>
|
|
||||||
<alias name='pci.4'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x3'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='5' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='5' port='0x14'/>
|
|
||||||
<alias name='pci.5'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x4'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='6' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='6' port='0x15'/>
|
|
||||||
<alias name='pci.6'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x5'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='7' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='7' port='0x16'/>
|
|
||||||
<alias name='pci.7'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x6'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='8' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='8' port='0x17'/>
|
|
||||||
<alias name='pci.8'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x7'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='9' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='9' port='0x18'/>
|
|
||||||
<alias name='pci.9'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='on'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='10' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='10' port='0x19'/>
|
|
||||||
<alias name='pci.10'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x1'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='11' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='11' port='0x1a'/>
|
|
||||||
<alias name='pci.11'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x2'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='12' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='12' port='0x1b'/>
|
|
||||||
<alias name='pci.12'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x3'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='13' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='13' port='0x1c'/>
|
|
||||||
<alias name='pci.13'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x4'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='pci' index='14' model='pcie-root-port'>
|
|
||||||
<model name='pcie-root-port'/>
|
|
||||||
<target chassis='14' port='0x1d'/>
|
|
||||||
<alias name='pci.14'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x5'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='sata' index='0'>
|
|
||||||
<alias name='ide'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
|
|
||||||
</controller>
|
|
||||||
<controller type='virtio-serial' index='0'>
|
|
||||||
<alias name='virtio-serial0'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
|
|
||||||
</controller>
|
|
||||||
<interface type='network'>
|
|
||||||
<mac address='52:54:00:08:f9:dc'/>
|
|
||||||
<source network='default' portid='82cc0c21-4cab-4010-ad3b-c66373e8beca' bridge='virbr0'/>
|
|
||||||
<target dev='vnet1'/>
|
|
||||||
<model type='virtio'/>
|
|
||||||
<alias name='net0'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
|
|
||||||
</interface>
|
|
||||||
<serial type='pty'>
|
|
||||||
<source path='/dev/pts/10'/>
|
|
||||||
<target type='isa-serial' port='0'>
|
|
||||||
<model name='isa-serial'/>
|
|
||||||
</target>
|
|
||||||
<alias name='serial0'/>
|
|
||||||
</serial>
|
|
||||||
<console type='pty' tty='/dev/pts/10'>
|
|
||||||
<source path='/dev/pts/10'/>
|
|
||||||
<target type='serial' port='0'/>
|
|
||||||
<alias name='serial0'/>
|
|
||||||
</console>
|
|
||||||
<channel type='unix'>
|
|
||||||
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-2-woodpecker-in-a-vm/org.qemu.guest_agent.0'/>
|
|
||||||
<target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/>
|
|
||||||
<alias name='channel0'/>
|
|
||||||
<address type='virtio-serial' controller='0' bus='0' port='1'/>
|
|
||||||
</channel>
|
|
||||||
<channel type='spicevmc'>
|
|
||||||
<target type='virtio' name='com.redhat.spice.0' state='disconnected'/>
|
|
||||||
<alias name='channel1'/>
|
|
||||||
<address type='virtio-serial' controller='0' bus='0' port='2'/>
|
|
||||||
</channel>
|
|
||||||
<input type='tablet' bus='usb'>
|
|
||||||
<alias name='input0'/>
|
|
||||||
<address type='usb' bus='0' port='1'/>
|
|
||||||
</input>
|
|
||||||
<input type='mouse' bus='ps2'>
|
|
||||||
<alias name='input1'/>
|
|
||||||
</input>
|
|
||||||
<input type='keyboard' bus='ps2'>
|
|
||||||
<alias name='input2'/>
|
|
||||||
</input>
|
|
||||||
<graphics type='spice' port='5901' autoport='yes' listen='127.0.0.1'>
|
|
||||||
<listen type='address' address='127.0.0.1'/>
|
|
||||||
<image compression='off'/>
|
|
||||||
</graphics>
|
|
||||||
<video>
|
|
||||||
<model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
|
|
||||||
<alias name='video0'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
|
|
||||||
</video>
|
|
||||||
<redirdev bus='usb' type='spicevmc'>
|
|
||||||
<alias name='redir0'/>
|
|
||||||
<address type='usb' bus='0' port='2'/>
|
|
||||||
</redirdev>
|
|
||||||
<redirdev bus='usb' type='spicevmc'>
|
|
||||||
<alias name='redir1'/>
|
|
||||||
<address type='usb' bus='0' port='3'/>
|
|
||||||
</redirdev>
|
|
||||||
<watchdog model='itco' action='reset'>
|
|
||||||
<alias name='watchdog0'/>
|
|
||||||
</watchdog>
|
|
||||||
<memballoon model='virtio'>
|
|
||||||
<alias name='balloon0'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/>
|
|
||||||
</memballoon>
|
|
||||||
<rng model='virtio'>
|
|
||||||
<backend model='random'>/dev/urandom</backend>
|
|
||||||
<alias name='rng0'/>
|
|
||||||
<address type='pci' domain='0x0000' bus='0x06' slot='0x00' function='0x0'/>
|
|
||||||
</rng>
|
|
||||||
</devices>
|
|
||||||
<seclabel type='dynamic' model='dac' relabel='yes'>
|
|
||||||
<label>+0:+0</label>
|
|
||||||
<imagelabel>+0:+0</imagelabel>
|
|
||||||
</seclabel>
|
|
||||||
</domain>
|
|
||||||
|
|
Loading…
Reference in a new issue