rootfs en js
This commit is contained in:
parent
08097035e4
commit
2599602d58
6 changed files with 174 additions and 57 deletions
|
@ -1,57 +0,0 @@
|
|||
#!/bin/sh -xe
|
||||
# https://github.com/firecracker-microvm/firecracker/blob/main/docs/rootfs-and-kernel-setup.md
|
||||
|
||||
dir="$(mktemp --tmpdir -d tmp.fireactions-rootfs.XXXXXXXXXX)"
|
||||
podman run -it --rm -v "$dir:/rootfs:Z" docker.io/alpine:3.18 sh -c "
|
||||
mkdir -p /rootfs/etc/apk
|
||||
cp -r /etc/apk/keys /rootfs/etc/apk/
|
||||
echo https://dl-cdn.alpinelinux.org/alpine/v3.18/main >> /rootfs/etc/apk/repositories
|
||||
echo https://dl-cdn.alpinelinux.org/alpine/v3.18/community >> /rootfs/etc/apk/repositories
|
||||
apk add --initdb --root /rootfs alpine-base dropbear util-linux dropbear-dbclient dhcpcd
|
||||
"
|
||||
|
||||
# gotta go fast
|
||||
echo 'rc_parallel="YES"' >> "$dir"/etc/rc.conf
|
||||
|
||||
mkdir -p "$dir"/usr/local/sbin
|
||||
go build -tags=netgo -o "$dir"/usr/local/sbin/fireactions-agent ./agent
|
||||
# https://github.com/OpenRC/openrc/blob/master/service-script-guide.md
|
||||
echo "#!/sbin/openrc-run
|
||||
pidfile=\"/run/\${RC_SVCNAME}.pid\"
|
||||
command_background=true
|
||||
command=/usr/local/sbin/fireactions-agent" > "$dir"/etc/init.d/fireactions-agent
|
||||
chmod +x "$dir"/etc/init.d/fireactions-agent
|
||||
ln -s /etc/init.d/fireactions-agent "$dir"/etc/runlevels/default/
|
||||
|
||||
ln -s /etc/init.d/devfs "$dir"/etc/runlevels/boot/
|
||||
ln -s /etc/init.d/procfs "$dir"/etc/runlevels/boot/
|
||||
ln -s /etc/init.d/sysfs "$dir"/etc/runlevels/boot/
|
||||
ln -s /etc/init.d/networking "$dir"/etc/runlevels/default/
|
||||
# ln -s /etc/init.d/dhcpcd "$dir"/etc/runlevels/default/
|
||||
ln -s /etc/init.d/dropbear "$dir"/etc/runlevels/default/
|
||||
|
||||
echo ttyS0 > "$dir"/etc/securetty
|
||||
ln -s agetty "$dir"/etc/init.d/agetty.ttyS0
|
||||
ln -s /etc/init.d/agetty.ttyS0 "$dir"/etc/runlevels/default/
|
||||
# ln -s /etc/init.d/local "$dir"/etc/runlevels/default/
|
||||
|
||||
mkdir -p "$dir"/etc/dropbear
|
||||
for t in rsa dss ed25519 ecdsa; do
|
||||
dropbearkey -t $t -f "$dir/etc/dropbear/dropbear_${t}_host_key"
|
||||
done
|
||||
|
||||
sudo mkdir -p "$dir"/root/.ssh
|
||||
echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEhrcTPMrhrOdwpgFkRFjTt8rdxt3gg16LJvBCZENRWa user@personal | sudo tee "$dir"/root/.ssh/authorized_keys
|
||||
echo "auto lo
|
||||
iface lo inet loopback" > "$dir"/etc/network/interfaces
|
||||
|
||||
rm rootfs.ext4
|
||||
fallocate --length 1G rootfs.ext4
|
||||
mkfs.ext4 rootfs.ext4
|
||||
|
||||
mkdir -p /tmp/rootfs
|
||||
sudo mount rootfs.ext4 /tmp/rootfs
|
||||
sudo cp -r "$dir"/* /tmp/rootfs/
|
||||
sudo umount /tmp/rootfs
|
||||
|
||||
# sudo rm -rf "$dir"
|
1
rootfs/.npmrc
Normal file
1
rootfs/.npmrc
Normal file
|
@ -0,0 +1 @@
|
|||
@nulo:registry=https://gitea.nulo.in/api/packages/nulo/npm/
|
126
rootfs/build.js
Normal file
126
rootfs/build.js
Normal file
|
@ -0,0 +1,126 @@
|
|||
import { init } from "@nulo/apkit";
|
||||
import { execFile as _execFile } from "node:child_process";
|
||||
import {
|
||||
chmod,
|
||||
mkdir,
|
||||
mkdtemp,
|
||||
readFile,
|
||||
readdir,
|
||||
rm,
|
||||
symlink,
|
||||
writeFile,
|
||||
} from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
const execFile = promisify(_execFile);
|
||||
|
||||
const root = await mkdtemp(join(tmpdir(), "tmp.fireactions-rootfs."));
|
||||
const alpine = await init(root);
|
||||
await alpine.install(["dropbear", "util-linux", "dropbear-dbclient", "dhcpcd"]);
|
||||
|
||||
// gotta go fast
|
||||
await append(r("/etc/rc.conf"), 'rc_parallel="YES"');
|
||||
|
||||
await mkdirp(r("/usr/local/sbin"));
|
||||
await execFile("go", [
|
||||
"build",
|
||||
"-tags=netgo",
|
||||
"-o",
|
||||
r("/usr/local/sbin/fireactions-agent"),
|
||||
"./agent",
|
||||
]);
|
||||
// https://github.com/OpenRC/openrc/blob/master/service-script-guide.md
|
||||
await writeFile(
|
||||
r("/etc/init.d/fireactions-agent"),
|
||||
`#!/sbin/openrc-run
|
||||
pidfile="/run/\${RC_SVCNAME}.pid"
|
||||
command_background=true
|
||||
command=/usr/local/sbin/fireactions-agent`
|
||||
);
|
||||
await chmod(r("/etc/init.d/fireactions-agent"), 0o700);
|
||||
await alpine.rcUpdate("default", "fireactions-agent");
|
||||
|
||||
await alpine.rcUpdate("boot", "devfs");
|
||||
await alpine.rcUpdate("boot", "procfs");
|
||||
await alpine.rcUpdate("boot", "sysfs");
|
||||
// alpine.rcUpdate('default', 'dhcpcd')
|
||||
await alpine.rcUpdate("default", "dropbear");
|
||||
|
||||
await writeFile(r("/etc/securetty"), "ttyS0");
|
||||
await symlink("agetty", r("/etc/init.d/agetty.ttyS0"));
|
||||
await alpine.rcUpdate("default", "agetty.ttyS0");
|
||||
|
||||
await mkdirp(r("/etc/dropbear"));
|
||||
for (const t of ["rsa", "dss", "ed25519", "ecdsa"]) {
|
||||
await execFile("dropbearkey", [
|
||||
"-t",
|
||||
t,
|
||||
"-f",
|
||||
r(`/etc/dropbear/dropbear_${t}_host_key`),
|
||||
]);
|
||||
}
|
||||
|
||||
await execFile("sudo", ["mkdir", "-p", r("/root/.ssh")]);
|
||||
await writeFile(
|
||||
"authorized_keys",
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEhrcTPMrhrOdwpgFkRFjTt8rdxt3gg16LJvBCZENRWa user@personal"
|
||||
);
|
||||
await execFile("sudo", [
|
||||
"mv",
|
||||
"authorized_keys",
|
||||
r("/root/.ssh/authorized_keys"),
|
||||
]);
|
||||
|
||||
await alpine.rcUpdate("default", "networking");
|
||||
await writeFile(
|
||||
r("/etc/network/interfaces"),
|
||||
`auto lo
|
||||
iface lo inet loopback`
|
||||
);
|
||||
|
||||
const ext4 = "rootfs.ext4";
|
||||
await rm(ext4);
|
||||
await execFile("fallocate", ["--length", "1G", ext4]);
|
||||
await execFile("mkfs.ext4", [ext4]);
|
||||
|
||||
const mountpoint = await mkdtemp(join(tmpdir(), "tmp.fireactions-mountpoint."));
|
||||
try {
|
||||
await mkdirp(mountpoint);
|
||||
await execFile("sudo", ["mount", ext4, mountpoint]);
|
||||
try {
|
||||
for (const dir of await readdir(root)) {
|
||||
await execFile("sudo", ["cp", "-r", r(dir), mountpoint]);
|
||||
}
|
||||
} finally {
|
||||
await execFile("sudo", ["umount", mountpoint]);
|
||||
}
|
||||
} finally {
|
||||
await rm(mountpoint, { recursive: true });
|
||||
}
|
||||
|
||||
// # sudo rm -rf "$dir"
|
||||
|
||||
// helpers
|
||||
/**
|
||||
* @param {import("node:fs").PathLike} path
|
||||
* @param {string} content
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function append(path, content) {
|
||||
const file = await readFile(path, "utf-8");
|
||||
await writeFile(path, file + "\n" + content);
|
||||
}
|
||||
/**
|
||||
* @param {import("node:fs").PathLike} path
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function mkdirp(path) {
|
||||
await mkdir(path, { recursive: true });
|
||||
}
|
||||
/**
|
||||
* @param {string} path
|
||||
*/
|
||||
function r(path) {
|
||||
return join(root, path);
|
||||
}
|
20
rootfs/package.json
Normal file
20
rootfs/package.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "fireactions-rootfs",
|
||||
"type": "module",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@nulo/apkit": "https://gitea.nulo.in/Nulo/apkit"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/node16": "^1.0.4",
|
||||
"@types/node": "^20.2.5"
|
||||
}
|
||||
}
|
19
rootfs/pnpm-lock.yaml
Normal file
19
rootfs/pnpm-lock.yaml
Normal file
|
@ -0,0 +1,19 @@
|
|||
lockfileVersion: '6.0'
|
||||
|
||||
devDependencies:
|
||||
'@tsconfig/node16':
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4
|
||||
'@types/node':
|
||||
specifier: ^20.2.5
|
||||
version: 20.2.5
|
||||
|
||||
packages:
|
||||
|
||||
/@tsconfig/node16@1.0.4:
|
||||
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
|
||||
dev: true
|
||||
|
||||
/@types/node@20.2.5:
|
||||
resolution: {integrity: sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==}
|
||||
dev: true
|
8
rootfs/tsconfig.json
Normal file
8
rootfs/tsconfig.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": "@tsconfig/node16/tsconfig.json",
|
||||
"exclude": ["build.js/", "build/"],
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue