diff --git a/packaging/arch/.SRCINFO b/packaging/arch/.SRCINFO new file mode 100644 index 0000000..f61074e --- /dev/null +++ b/packaging/arch/.SRCINFO @@ -0,0 +1,30 @@ +pkgbase = forkd-bin + pkgdesc = Fork microVMs the way you fork processes (prebuilt binaries) + pkgver = 0.5.3 + pkgrel = 1 + url = https://github.com/deeplethe/forkd + arch = x86_64 + license = Apache-2.0 + depends = firecracker>=1.10 + depends = gcc-libs + depends = glibc + depends = iproute2 + depends = which + optdepends = curl: download the guest kernel during quickstart + optdepends = docker: build rootfs images; parent and from-image also need build-rootfs.sh + optdepends = e2fsprogs: build ext4 rootfs images + optdepends = iptables: configure NAT during quickstart and netns setup + optdepends = logrotate: rotate the controller audit log + provides = forkd=0.5.3 + conflicts = forkd + backup = etc/logrotate.d/forkd + source = LICENSE-0.5.3::https://raw.githubusercontent.com/deeplethe/forkd/v0.5.3/LICENSE + source = forkd-controller-0.5.3.service::https://raw.githubusercontent.com/deeplethe/forkd/v0.5.3/packaging/systemd/forkd-controller.service + source = forkd.logrotate + sha256sums = 86f7b7013dff87a69534190a231c8b3545c7365d123728002089e2b91eb8f7b4 + sha256sums = 2aab38bae2a1d975281806a3f9bdb86fc1b59e40664438f238887e7b9e888cae + sha256sums = 55aeede89ec62af51910487d7c9d583632b3a1973f36c53680fe7febb5320271 + source_x86_64 = forkd-0.5.3-x86_64-linux.tar.gz::https://github.com/deeplethe/forkd/releases/download/v0.5.3/forkd-v0.5.3-x86_64-linux.tar.gz + sha256sums_x86_64 = 417865e0d9bb3fcaf6bd0308dfe8d40a4bd282adefb62459dd76585d6bede7e4 + +pkgname = forkd-bin diff --git a/packaging/arch/PKGBUILD b/packaging/arch/PKGBUILD new file mode 100644 index 0000000..00387a5 --- /dev/null +++ b/packaging/arch/PKGBUILD @@ -0,0 +1,104 @@ +# Contributor: Deeplethe + +pkgname=forkd-bin +pkgver=0.5.3 +pkgrel=1 +pkgdesc='Fork microVMs the way you fork processes (prebuilt binaries)' +arch=('x86_64') +url='https://github.com/deeplethe/forkd' +license=('Apache-2.0') +depends=( + 'firecracker>=1.10' + 'gcc-libs' + 'glibc' + 'iproute2' + 'which' +) +optdepends=( + 'curl: download the guest kernel during quickstart' + 'docker: build rootfs images; parent and from-image also need build-rootfs.sh' + 'e2fsprogs: build ext4 rootfs images' + 'iptables: configure NAT during quickstart and netns setup' + 'logrotate: rotate the controller audit log' +) +provides=("forkd=${pkgver}") +conflicts=('forkd') +backup=('etc/logrotate.d/forkd') +source=( + "LICENSE-${pkgver}::https://raw.githubusercontent.com/deeplethe/forkd/v${pkgver}/LICENSE" + "forkd-controller-${pkgver}.service::https://raw.githubusercontent.com/deeplethe/forkd/v${pkgver}/packaging/systemd/forkd-controller.service" + 'forkd.logrotate' +) +source_x86_64=( + "forkd-${pkgver}-x86_64-linux.tar.gz::https://github.com/deeplethe/forkd/releases/download/v${pkgver}/forkd-v${pkgver}-x86_64-linux.tar.gz" +) +sha256sums=( + '86f7b7013dff87a69534190a231c8b3545c7365d123728002089e2b91eb8f7b4' + '2aab38bae2a1d975281806a3f9bdb86fc1b59e40664438f238887e7b9e888cae' + '55aeede89ec62af51910487d7c9d583632b3a1973f36c53680fe7febb5320271' +) +sha256sums_x86_64=( + '417865e0d9bb3fcaf6bd0308dfe8d40a4bd282adefb62459dd76585d6bede7e4' +) + +prepare() { + sed \ + -e 's|/usr/local/bin/forkd-controller|/usr/bin/forkd-controller|' \ + -e '/--state \/var\/lib\/forkd\/state.json \\/a\ --snapshot-root /var/lib/forkd/snapshots \\' \ + -e '/^StateDirectory=forkd$/a\# Rootfs sidecars in /var/cache/forkd are reopened on restore.\nCacheDirectory=forkd' \ + -e '/^RuntimeDirectory=forkd$/a\StateDirectoryMode=0700\nCacheDirectoryMode=0700\nLogsDirectoryMode=0700\nRuntimeDirectoryMode=0700\nUMask=0077' \ + -e 's|^ReadWritePaths=/var/lib/forkd /var/log/forkd /sys/fs/cgroup$|ReadWritePaths=/var/lib/forkd /var/cache/forkd /var/log/forkd /sys/fs/cgroup|' \ + -e 's|^SystemCallFilter=@system-service$|# ip netns exec needs mount(2), umount2(2), and capset(2).\n# Keep @system-service as the allowlist; do not expose the rest of @mount.\n# A ~@privileged group deny would override the required capset allow, so the\n# following deny list mirrors @privileged except for capset.\nSystemCallFilter=@system-service mount umount2 capset|' \ + -e 's|^SystemCallFilter=~@privileged @resources$|SystemCallFilter=~@chown @clock @module @raw-io @reboot @swap @resources\nSystemCallFilter=~_sysctl acct bpf chroot fanotify_init fanotify_mark nfsservctl open_by_handle_at pivot_root quotactl quotactl_fd setdomainname setfsuid setfsuid32 setgroups setgroups32 sethostname setresuid setresuid32 setreuid setreuid32 setuid setuid32 vhangup|' \ + "$srcdir/forkd-controller-${pkgver}.service" \ + > "$srcdir/forkd-controller.service" +} + +check() { + "$srcdir/forkd" --version + "$srcdir/forkd-controller" --version + grep -Fq 'ExecStart=/usr/bin/forkd-controller serve' \ + "$srcdir/forkd-controller.service" + grep -Fq -- '--snapshot-root /var/lib/forkd/snapshots' \ + "$srcdir/forkd-controller.service" + grep -Fqx 'StateDirectoryMode=0700' "$srcdir/forkd-controller.service" + grep -Fqx 'CacheDirectory=forkd' "$srcdir/forkd-controller.service" + grep -Fqx 'CacheDirectoryMode=0700' "$srcdir/forkd-controller.service" + grep -Fqx 'LogsDirectoryMode=0700' "$srcdir/forkd-controller.service" + grep -Fqx 'RuntimeDirectoryMode=0700' "$srcdir/forkd-controller.service" + grep -Fqx 'UMask=0077' "$srcdir/forkd-controller.service" + grep -Fqx 'ReadWritePaths=/var/lib/forkd /var/cache/forkd /var/log/forkd /sys/fs/cgroup' \ + "$srcdir/forkd-controller.service" + grep -Fqx 'SystemCallFilter=@system-service mount umount2 capset' \ + "$srcdir/forkd-controller.service" + grep -Fqx 'SystemCallFilter=~@chown @clock @module @raw-io @reboot @swap @resources' \ + "$srcdir/forkd-controller.service" + ! grep -Fq 'SystemCallFilter=~@privileged' \ + "$srcdir/forkd-controller.service" + ! grep -Fq 'SystemCallFilter=@system-service @mount' \ + "$srcdir/forkd-controller.service" + ! grep -Fq '/usr/local/bin/forkd-controller' \ + "$srcdir/forkd-controller.service" + grep -Fqx '/var/log/forkd/audit.log {' "$srcdir/forkd.logrotate" + grep -Fqx ' weekly' "$srcdir/forkd.logrotate" + grep -Fqx ' rotate 8' "$srcdir/forkd.logrotate" + grep -Fqx ' compress' "$srcdir/forkd.logrotate" + grep -Fqx ' delaycompress' "$srcdir/forkd.logrotate" + grep -Fqx ' missingok' "$srcdir/forkd.logrotate" + grep -Fqx ' notifempty' "$srcdir/forkd.logrotate" + grep -Fqx ' copytruncate' "$srcdir/forkd.logrotate" + grep -Fqx ' su root root' "$srcdir/forkd.logrotate" + grep -Fqx ' create 0600 root root' "$srcdir/forkd.logrotate" +} + +package() { + install -Dm755 "$srcdir/forkd" "$pkgdir/usr/bin/forkd" + install -Dm755 "$srcdir/forkd-controller" \ + "$pkgdir/usr/bin/forkd-controller" + install -Dm644 "$srcdir/forkd-controller.service" \ + "$pkgdir/usr/lib/systemd/system/forkd-controller.service" + install -Dm644 "$srcdir/forkd.logrotate" \ + "$pkgdir/etc/logrotate.d/forkd" + install -Dm644 "$srcdir/LICENSE-${pkgver}" \ + "$pkgdir/usr/share/licenses/$pkgname/LICENSE" +} diff --git a/packaging/arch/README.md b/packaging/arch/README.md new file mode 100644 index 0000000..2b45fbc --- /dev/null +++ b/packaging/arch/README.md @@ -0,0 +1,40 @@ +# Arch Linux package + +`forkd-bin` installs the official prebuilt forkd release and depends on the +distribution `firecracker` package. It never downloads or replaces +Firecracker. + +Build locally: + +```bash +cd packaging/arch +makepkg --cleanbuild +sudo pacman -U forkd-bin-*.pkg.tar.zst +``` + +Before enabling the controller, create a bearer token: + +```bash +sudo install -d -m 0755 /etc/forkd +sudo sh -c 'umask 077; head -c 32 /dev/urandom | base64 > /etc/forkd/token' +sudo systemctl enable --now forkd-controller +``` + +The service stores snapshots in `/var/lib/forkd/snapshots`. + +In v0.5.3, `quickstart` can stage its embedded helper scripts, but +`parent build` and `from-image` still require `scripts/build-rootfs.sh` from a +forkd source checkout. Point `FORKD_SCRIPTS_DIR` at `/scripts` +before running either command. In fish: + +```fish +set -gx FORKD_SCRIPTS_DIR /path/to/forkd/scripts +``` + +Snapshots are not portable across Firecracker versions. Recreate them after a +Firecracker upgrade. The standard Arch Firecracker supports normal fork, +full branch, and diff branch. It does not include forkd's experimental patches +for `live_fork=true` or `mode="live"`. + +Publishing the recipe to AUR requires a separate AUR Git repository and a +maintainer identity. This directory is the upstream source of that recipe. diff --git a/packaging/arch/forkd.logrotate b/packaging/arch/forkd.logrotate new file mode 100644 index 0000000..4683b3c --- /dev/null +++ b/packaging/arch/forkd.logrotate @@ -0,0 +1,11 @@ +/var/log/forkd/audit.log { + weekly + rotate 8 + compress + delaycompress + missingok + notifempty + copytruncate + su root root + create 0600 root root +}