diff --git a/.dockerignore b/.dockerignore deleted file mode 120000 index 3e4e48b0..00000000 --- a/.dockerignore +++ /dev/null @@ -1 +0,0 @@ -.gitignore \ No newline at end of file diff --git a/.gitignore b/.gitignore index 483e4b6e..2c11510d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ build/ +build.*/ mkosi/ env.json mkosi.packages/ @@ -8,4 +9,6 @@ mkosi.builddir/ .claudesync/ .claudeignore tmp/ +.temp NvVars +.vscode diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 82a8f514..77415a1e 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -15,6 +15,7 @@ This comprehensive guide covers everything you need to know about developing wit - [Freezing to Debian Archive Snapshots](#freezing-to-debian-archive-snapshots) - [Testing for Reproducibility](#testing-for-reproducibility) - [Creating Debian Packages](#creating-debian-packages) +- [Custom Developer Files](#custom-developer-files) - [Debugging and Troubleshooting](#debugging-and-troubleshooting) ## Project Structure @@ -276,8 +277,8 @@ systemd services are the primary way to run applications in Flashboxes. Here's h ```ini [Unit] Description=My Application -After=network.target network-setup.service -Requires=network-setup.service +After=network-online.target +Wants=network-online.target [Service] Type=simple @@ -354,8 +355,8 @@ Conflicts=apache2.service ```ini [Unit] # Network is available -After=network.target network-setup.service -Requires=network-setup.service +After=network-online.target +Wants=network-online.target # Persistent storage is mounted After=persistent-mount.service @@ -365,24 +366,14 @@ Requires=persistent-mount.service After=basic.target ``` -### Enabling Services +### Enabling Packaged Services -**In `mkosi.postinst` script**: -```bash -#!/bin/bash -set -euxo pipefail - -# Enable service -mkosi-chroot systemctl enable myapp.service +To enable a service installed with a Debian package, add the following to your `mkosi.postinst` script: -# Create symlink for minimal.target -mkdir -p "$BUILDROOT/etc/systemd/system/minimal.target.wants" -ln -sf "/etc/systemd/system/myapp.service" \ - "$BUILDROOT/etc/systemd/system/minimal.target.wants/" +```bash +mkosi-chroot systemctl add-wants minimal.target myapp.service ``` -For comprehensive systemd options, see: [systemd Service Documentation](https://www.freedesktop.org/software/systemd/man/systemd.service.html) - ## Extending Built-in systemd Services Sometimes you need to modify existing systemd services rather than creating new ones. @@ -543,8 +534,7 @@ chown myapp:myapp /etc/myapp/config.conf chmod 600 /etc/myapp/config.conf # Enable systemd service -systemctl enable myapp.service || true -systemctl start myapp.service || true +mkosi-chroot systemctl add-wants minimal.target myapp.service || true exit 0 ``` @@ -636,6 +626,30 @@ For systems without systemd v250+ or where Nix installation isn't feasible, you > Replace "btrfs" with your chosen storage driver 5. Run the desired `mkosi` command inside the shell Podman environment +## Custom Developer Files + +When building with the `devtools` profile, you can add your own custom files to the image without committing them to git. This is useful for adding personal SSH keys, configuration files, or debugging tools during development. + +### Adding Custom Files + +Place files in `mkosi.profiles/devtools/custom/` mirroring the filesystem structure you want: + +```bash +# Add your SSH authorized keys +mkdir -p mkosi.profiles/devtools/custom/root/.ssh +cp ~/.ssh/id_rsa.pub mkosi.profiles/devtools/custom/root/.ssh/authorized_keys + +# Add a custom configuration file +mkdir -p mkosi.profiles/devtools/custom/etc +echo "my_setting=value" > mkosi.profiles/devtools/custom/etc/myconfig.conf + +# Add a debugging script +mkdir -p mkosi.profiles/devtools/custom/usr/local/bin +cp my-debug-script.sh mkosi.profiles/devtools/custom/usr/local/bin/ +``` + +Files placed here will be copied into the image (like any other `ExtraTrees` directory) but will be ignored by git, so they won't be accidentally committed. + ## Debugging and Troubleshooting ### mkosi Debugging diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 57739de9..00000000 --- a/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM ubuntu:25.04 - -RUN apt-get update && apt-get install -y \ - curl git sudo qemu-system-x86 qemu-utils \ - debian-archive-keyring systemd-boot reprepro xz-utils - -RUN echo "ubuntu ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ubuntu && \ - chmod 0440 /etc/sudoers.d/ubuntu - -COPY --chown=ubuntu:ubuntu . /home/ubuntu/mkosi -RUN mkdir -p /home/ubuntu/mkosi/mkosi.packages /home/ubuntu/mkosi/mkosi.cache \ - /home/ubuntu/mkosi/mkosi.builddir /home/ubuntu/mkosi/build /nix && \ - chown -R ubuntu:ubuntu /home/ubuntu/mkosi /nix - -USER ubuntu -RUN curl -L https://nixos.org/nix/install | sh -s -- --no-daemon && \ - mkdir -p ~/.config/nix ~/.cache/mkosi/ && \ - echo 'experimental-features = nix-command flakes' > ~/.config/nix/nix.conf - -WORKDIR /home/ubuntu/mkosi -RUN /home/ubuntu/.nix-profile/bin/nix develop -c /bin/true -ENTRYPOINT ["/home/ubuntu/.nix-profile/bin/nix", "develop", "-c", "/bin/bash"] \ No newline at end of file diff --git a/base/add-backports.sh b/base/add-backports.sh deleted file mode 100755 index c14a8bfc..00000000 --- a/base/add-backports.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# The mkosi sandbox environment should have a debian backports source list -# that matches the archive timestamp of the main release. -# See https://github.com/systemd/mkosi/issues/1755 -MIRROR=$(jq -r .Mirror /work/config.json) -if [ "$MIRROR" = "null" ]; then - MIRROR="http://deb.debian.org/debian" -fi - -cat > "$SRCDIR/mkosi.builddir/debian-backports.sources" </dev/null +mkosi-chroot grpck --sort >/dev/null + # Remove all logs and cache, but keep directory structure intact find "$BUILDROOT/var/log" -type f -delete find "$BUILDROOT/var/cache" -type f -delete @@ -31,10 +36,9 @@ debloat_paths=( "/usr/lib/systemd/catalog" "/usr/lib/systemd/user" "/usr/lib/systemd/user-generators" - "/usr/lib/systemd/network" "/usr/lib/pcrlock.d" "/usr/lib/tmpfiles.d" - "/etc/systemd/network" + "/var/lib/ucf" "/etc/credstore" "/nix" ) diff --git a/base/efi-stub.sh b/base/mkosi.postinst.d/10-efi-stub.sh similarity index 100% rename from base/efi-stub.sh rename to base/mkosi.postinst.d/10-efi-stub.sh diff --git a/base/debloat-systemd.sh b/base/mkosi.postinst.d/90-debloat-systemd.sh similarity index 79% rename from base/debloat-systemd.sh rename to base/mkosi.postinst.d/90-debloat-systemd.sh index 81efba20..2cb8f4bb 100755 --- a/base/debloat-systemd.sh +++ b/base/mkosi.postinst.d/90-debloat-systemd.sh @@ -16,6 +16,9 @@ systemd_svc_whitelist=( "systemd-journald-dev-log.socket" "systemd-remount-fs.service" "systemd-sysctl.service" + "systemd-networkd.service" + "systemd-networkd.socket" + "systemd-networkd-wait-online.service" "chrony.service" ) @@ -42,10 +45,9 @@ mkosi-chroot dpkg-query -L systemd | grep -E '\.service$|\.socket$|\.timer$|\.ta fi done -# Set default target -ln -sf minimal.target "$SYSTEMD_DIR/default.target" - -# Enable chrony and link to minimal.target -mkdir -p "$BUILDROOT/etc/systemd/system/minimal.target.wants" -mkosi-chroot systemctl enable chrony.service -ln -sf /lib/systemd/system/chrony.service "$BUILDROOT/etc/systemd/system/minimal.target.wants/" +# Enable chrony service +mkosi-chroot systemctl add-wants minimal.target \ + chrony.service \ + systemd-resolved.service \ + systemd-networkd.service \ + systemd-networkd-wait-online.service diff --git a/base/mkosi.skeleton/etc/resolv.conf b/base/mkosi.skeleton/etc/resolv.conf deleted file mode 100644 index 0bb99396..00000000 --- a/base/mkosi.skeleton/etc/resolv.conf +++ /dev/null @@ -1,2 +0,0 @@ -nameserver 8.8.8.8 -nameserver 8.8.4.4 \ No newline at end of file diff --git a/base/mkosi.skeleton/etc/systemd/system/network-setup.service b/base/mkosi.skeleton/etc/systemd/system/network-setup.service deleted file mode 100644 index d980087b..00000000 --- a/base/mkosi.skeleton/etc/systemd/system/network-setup.service +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -Description=Basic Network Setup -DefaultDependencies=no -Before=network.target -Wants=network.target - -[Service] -Type=oneshot -ExecStart=ip link set lo up -ExecStart=ip link set eth0 up -ExecStart=chattr +i /etc/resolv.conf -ExecStart=/usr/sbin/udhcpc -i eth0 -n -RemainAfterExit=yes - -[Install] -WantedBy=sysinit.target \ No newline at end of file diff --git a/base/mkosi.sync.d/10-setup-apt.sh b/base/mkosi.sync.d/10-setup-apt.sh new file mode 100755 index 00000000..587875a9 --- /dev/null +++ b/base/mkosi.sync.d/10-setup-apt.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Adds mkosi sources. See https://github.com/systemd/mkosi/issues/1755 +SNAPSHOT=$(jq -r .Snapshot /work/config.json) +if [ "$SNAPSHOT" = "null" ]; then + MIRROR="http://deb.debian.org/debian" +else + MIRROR="http://snapshot.debian.org/archive/debian/${SNAPSHOT}" +fi + +cat > "$SRCDIR/mkosi.builddir/mkosi.sources" < "$output_path" - rm "$BUILDROOT/$rel_path" -done - -# Download rbuilder-bidding binary -export rbuilder_version="v0.4.2" -export github_token="$(jq -j ".bidding_service.github_token" env.json)" -export rbuilder_url="https://api.github.com/repos/flashbots/rbuilder-bidding-service/releases/tags/$rbuilder_version" -export headers="Authorization: token $github_token" -export asset_url=$(curl -s -H "$headers" "$rbuilder_url" | jq -j '.assets[] | select(.name == "bidding-service") | .url') -curl -s -H "$headers" -H "Accept: application/octet-stream" -L "$asset_url" -o "$BUILDROOT/usr/bin/bidding-service" -chmod +x "$BUILDROOT/usr/bin/bidding-service" - -# Set permissions of templated files -chmod 640 "$BUILDROOT/etc/rbuilder.config" -chmod 600 "$BUILDROOT/etc/rclone.conf" diff --git a/env.json.example b/env.json.example deleted file mode 100644 index 41278556..00000000 --- a/env.json.example +++ /dev/null @@ -1,23 +0,0 @@ -{ - "bidding_service_download": { - "github_token": "", - "config": "" - }, - "fluentbit": { - "aws_access_key_id": "", - "aws_secret_access_key": "" - }, - "rbuilder": { - "coinbase_secret_key": "", - "dry_run": "true", - "optimistic_relay_secret_key": "", - "relay_secret_key": "", - "top_bid_ws_basic_auth": "", - "top_bid_ws_url": "" - }, - "rclone": { - "access_key_id": "", - "bucket_endpoint": "", - "secret_access_key": "" - } -} \ No newline at end of file diff --git a/flake.lock b/flake.lock index 7dcb42b7..0c6ae986 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1746904237, - "narHash": "sha256-3e+AVBczosP5dCLQmMoMEogM57gmZ2qrVSrmq9aResQ=", + "lastModified": 1769170682, + "narHash": "sha256-oMmN1lVQU0F0W2k6OI3bgdzp2YOHWYUAw79qzDSjenU=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d89fc19e405cb2d55ce7cc114356846a0ee5e956", + "rev": "c5296fdd05cfa2c187990dd909864da9658df755", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 7e423ba3..80589616 100644 --- a/flake.nix +++ b/flake.nix @@ -44,14 +44,14 @@ src = pkgs.fetchFromGitHub { owner = "flashbots"; repo = "dstack-mr-gcp"; - rev = "ee95d36c8f18d159f6ada31474555e4a253b3897"; - sha256 = "sha256-vAYN4zFXHSxd86KP+Toqh1ZDa4+KGLNsQoOuTr45pGg="; + rev = "503e7c506f89f9d81be04025c90921778b26f0a4"; + sha256 = "sha256-z6STTgcOXatiqA2rlpzwRyvAwnXrK30oNDCJqtIp7/8="; }; vendorHash = "sha256-glOyRTrIF/zP78XGV+v58a1Bec6C3Fvc5c8G3PglzPM="; }; mkosi = system: let pkgsForSystem = import nixpkgs {inherit system;}; - mkosi-unwrapped = pkgsForSystem.mkosi.override { + mkosi-unwrapped = (pkgsForSystem.mkosi.override { extraDeps = with pkgsForSystem; [ apt @@ -74,7 +74,23 @@ jq ] ++ [reprepro]; - }; + }).overrideAttrs (old: { + src = pkgsForSystem.fetchFromGitHub { + owner = "systemd"; + repo = "mkosi"; + rev = "df51194bc2d890d4c267af644a1832d2d53339ac"; + hash = "sha256-rGGzE9xIR8WvK07GBnaAmeLpmnM3Uy51wqyrmuHuWXo="; + }; + # TODO: remove these patch hunks from upstream nixpkgs next time mkosi has a release + # The latest mkosi doesn't need them + patches = pkgs.lib.drop 2 old.patches; + postPatch = let fd = "${pkgs.patchutils}/bin/filterdiff"; in '' + { ${fd} -x '*/run.py' --hunks=x2 ${builtins.elemAt old.patches 0} + ${fd} -i '*/run.py' --hunks=x1-2 ${builtins.elemAt old.patches 0} + ${fd} --hunks=x1 ${builtins.elemAt old.patches 1} + } | patch -p1 + ''; + }); in # Create a wrapper script that runs mkosi with unshare # Unshare is needed to create files owned by multiple uids/gids @@ -90,14 +106,10 @@ devShells = builtins.listToAttrs (map (system: { name = system; value.default = pkgs.mkShell { - nativeBuildInputs = [ - (mkosi system) - measured-boot - measured-boot-gcp - ]; + nativeBuildInputs = [(mkosi system) measured-boot measured-boot-gcp]; shellHook = '' mkdir -p mkosi.packages mkosi.cache mkosi.builddir ~/.cache/mkosi - touch mkosi.builddir/debian-backports.sources + touch mkosi.builddir/mkosi.sources ''; }; }) ["x86_64-linux" "aarch64-linux"]); diff --git a/mkosi.profiles/azure/mkosi.conf b/mkosi.profiles/azure/mkosi.conf index b28c483a..9ec84e2e 100644 --- a/mkosi.profiles/azure/mkosi.conf +++ b/mkosi.profiles/azure/mkosi.conf @@ -1,4 +1 @@ [Content] -SkeletonTrees=azure-complete-provisioning.service:/etc/systemd/system/azure-complete-provisioning.service -SkeletonTrees=azure-complete-provisioning:/usr/bin/azure-complete-provisioning -Packages=dmidecode diff --git a/mkosi.profiles/azure/mkosi.extra/etc/systemd/network/99-azure-dns.network b/mkosi.profiles/azure/mkosi.extra/etc/systemd/network/99-azure-dns.network new file mode 100644 index 00000000..eae5e182 --- /dev/null +++ b/mkosi.profiles/azure/mkosi.extra/etc/systemd/network/99-azure-dns.network @@ -0,0 +1,8 @@ +[Match] +Name=eth* en* + +[Network] +# Azure internal DNS +DNS=168.63.129.16 +Domains=~internal.cloudapp.net +DNSOverTLS=no diff --git a/mkosi.profiles/azure/azure-complete-provisioning.service b/mkosi.profiles/azure/mkosi.extra/etc/systemd/system/azure-complete-provisioning.service similarity index 71% rename from mkosi.profiles/azure/azure-complete-provisioning.service rename to mkosi.profiles/azure/mkosi.extra/etc/systemd/system/azure-complete-provisioning.service index 4d8866dd..70fe33db 100644 --- a/mkosi.profiles/azure/azure-complete-provisioning.service +++ b/mkosi.profiles/azure/mkosi.extra/etc/systemd/system/azure-complete-provisioning.service @@ -1,7 +1,8 @@ [Unit] Description=Report VM is ready to Azure API -After=network.target network-setup.service -Requires=network-setup.service +ConditionVirtualization=microsoft +After=network-online.target +Wants=network-online.target [Service] Type=oneshot diff --git a/mkosi.profiles/azure/azure-complete-provisioning b/mkosi.profiles/azure/mkosi.extra/usr/bin/azure-complete-provisioning similarity index 93% rename from mkosi.profiles/azure/azure-complete-provisioning rename to mkosi.profiles/azure/mkosi.extra/usr/bin/azure-complete-provisioning index c4dce969..ca89c5b4 100755 --- a/mkosi.profiles/azure/azure-complete-provisioning +++ b/mkosi.profiles/azure/mkosi.extra/usr/bin/azure-complete-provisioning @@ -4,11 +4,6 @@ set -e -if ! dmidecode -s system-manufacturer 2>/dev/null | grep -q "Microsoft Corporation"; then - echo "Not running on Azure, skipping provisioning" - exit 0 -fi - attempts=1 retrieved_goal_state=false until [ "$attempts" -gt 5 ] diff --git a/mkosi.profiles/azure/mkosi.postinst b/mkosi.profiles/azure/mkosi.postinst deleted file mode 100755 index c1b3474f..00000000 --- a/mkosi.profiles/azure/mkosi.postinst +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -set -euxo pipefail - -mkosi-chroot systemctl enable "azure-complete-provisioning.service" -ln -sf "/etc/systemd/system/azure-complete-provisioning.service" "$BUILDROOT/etc/systemd/system/minimal.target.wants/" diff --git a/mkosi.profiles/devtools/custom.postinst.d/.gitignore b/mkosi.profiles/devtools/custom.postinst.d/.gitignore new file mode 100644 index 00000000..38e31890 --- /dev/null +++ b/mkosi.profiles/devtools/custom.postinst.d/.gitignore @@ -0,0 +1,3 @@ +# Ignore everything in this directory except .gitignore +* +!.gitignore diff --git a/mkosi.profiles/devtools/custom/.gitignore b/mkosi.profiles/devtools/custom/.gitignore new file mode 100644 index 00000000..38e31890 --- /dev/null +++ b/mkosi.profiles/devtools/custom/.gitignore @@ -0,0 +1,3 @@ +# Ignore everything in this directory except .gitignore +* +!.gitignore diff --git a/mkosi.profiles/devtools/mkosi.conf b/mkosi.profiles/devtools/mkosi.conf index c720603f..c7eb8d59 100644 --- a/mkosi.profiles/devtools/mkosi.conf +++ b/mkosi.profiles/devtools/mkosi.conf @@ -1,17 +1,25 @@ [Content] ExtraTrees=mkosi.extra + custom +PostInstallationScripts=custom.postinst.d/*.sh Packages=adjtimex apt bash-completion curl dnsutils + iftop + iotop iputils-ping + jq net-tools netcat-openbsd openssh-server + screen socat strace tcpdump tcpflow vim + wget + zstd diff --git a/mkosi.profiles/devtools/mkosi.extra/etc/systemd/system/serial-console.service b/mkosi.profiles/devtools/mkosi.extra/etc/systemd/system/serial-console.service index 04352634..bfcfdd63 100644 --- a/mkosi.profiles/devtools/mkosi.extra/etc/systemd/system/serial-console.service +++ b/mkosi.profiles/devtools/mkosi.extra/etc/systemd/system/serial-console.service @@ -13,5 +13,3 @@ Restart=always [Install] WantedBy=minimal.target -WantedBy=rescue.target -WantedBy=emergency.target diff --git a/mkosi.profiles/devtools/mkosi.postinst b/mkosi.profiles/devtools/mkosi.postinst index 5eca88d7..cc0db73b 100755 --- a/mkosi.profiles/devtools/mkosi.postinst +++ b/mkosi.profiles/devtools/mkosi.postinst @@ -7,12 +7,15 @@ HASH=$(mkosi-chroot openssl passwd -6 -salt salt "$PASSWORD") mkosi-chroot passwd -u root mkosi-chroot usermod -p "$HASH" root +# Remove git files in custom/ folder +mkosi-chroot rm /.gitignore /.gitkeep || true + if [ -f "$BUILDROOT/etc/default/dropbear" ]; then # Remove -s, -w, -g flags from dropbear args sed -i '/^DROPBEAR_EXTRA_ARGS=/s/-[swg] \?//g' "$BUILDROOT/etc/default/dropbear" else echo "PermitRootLogin yes" >> "$BUILDROOT/etc/ssh/sshd_config" echo "PasswordAuthentication yes" >> "$BUILDROOT/etc/ssh/sshd_config" - mkosi-chroot systemctl enable ssh.service mkosi-chroot systemctl unmask ssh.service ssh.socket + mkosi-chroot systemctl add-wants minimal.target ssh.service fi diff --git a/mkosi.profiles/gcp/mkosi.extra/etc/resolv.conf b/mkosi.profiles/gcp/mkosi.extra/etc/resolv.conf deleted file mode 100644 index 6c6486e6..00000000 --- a/mkosi.profiles/gcp/mkosi.extra/etc/resolv.conf +++ /dev/null @@ -1,2 +0,0 @@ -nameserver 169.254.169.254 -options edns0 trust-ad diff --git a/mkosi.profiles/gcp/mkosi.extra/etc/systemd/network/99-gcp-dns.network b/mkosi.profiles/gcp/mkosi.extra/etc/systemd/network/99-gcp-dns.network new file mode 100644 index 00000000..5bf197c1 --- /dev/null +++ b/mkosi.profiles/gcp/mkosi.extra/etc/systemd/network/99-gcp-dns.network @@ -0,0 +1,8 @@ +[Match] +Name=eth* en* + +[Network] +# GCP internal DNS +DNS=169.254.169.254 +Domains=~internal ~google.internal +DNSOverTLS=no diff --git a/mkosi.profiles/gcp/mkosi.extra/etc/systemd/system/set-hostname.service b/mkosi.profiles/gcp/mkosi.extra/etc/systemd/system/set-hostname.service index 209cd01f..eb16abf9 100644 --- a/mkosi.profiles/gcp/mkosi.extra/etc/systemd/system/set-hostname.service +++ b/mkosi.profiles/gcp/mkosi.extra/etc/systemd/system/set-hostname.service @@ -1,8 +1,8 @@ [Unit] Description=Set hostname ConditionFirstBoot=yes -After=network.target network-setup.service -Wants=network-setup.service +After=network-online.target +Wants=network-online.target [Service] User=root @@ -11,4 +11,4 @@ Type=oneshot ExecStart=/usr/bin/set-hostname.sh [Install] -WantedBy=default.target +WantedBy=minimal.target diff --git a/mkosi.profiles/gcp/mkosi.postinst b/mkosi.profiles/gcp/mkosi.postinst index c1ad20cc..bd8a5155 100755 --- a/mkosi.profiles/gcp/mkosi.postinst +++ b/mkosi.profiles/gcp/mkosi.postinst @@ -9,14 +9,9 @@ echo "/dev/disk/by-id/google-data" >> "$BUILDROOT/etc/tdx-init/disk-glob" # Enable systemd services mkdir "$BUILDROOT/etc/systemd/system/minimal.target.wants" || true + mkosi-chroot systemctl unmask sys-kernel-config.mount -for service in \ - sys-kernel-config.mount \ - set-hostname.service -do - mkosi-chroot systemctl enable "$service" - ln -sf "/etc/systemd/system/$service" "$BUILDROOT/etc/systemd/system/minimal.target.wants/" -done +mkosi-chroot systemctl add-wants minimal.target sys-kernel-config.mount if [ -f /etc/rsyslog.d/50-default.conf ]; then sed -i 's/^.*\/var\/log\/syslog.*$/# &/' /etc/rsyslog.d/50-default.conf diff --git a/mkosi.profiles/gcp/mkosi.postoutput b/mkosi.profiles/gcp/mkosi.postoutput index 83228a42..2d4dbe66 100755 --- a/mkosi.profiles/gcp/mkosi.postoutput +++ b/mkosi.profiles/gcp/mkosi.postoutput @@ -1,53 +1,30 @@ #!/bin/bash -set -euxo pipefail -EFI="${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.efi" -TAR="${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.tar.gz" -TMP="${OUTPUTDIR}/gcp-tmp" - -[ ! -f "$EFI" ] && echo "Error: $EFI not found" && exit 1 - -mkdir -p "$TMP" - -# Fixed GUIDs and IDs -DISK_GUID="12345678-1234-5678-1234-567812345678" -PARTITION_GUID="87654321-4321-8765-4321-876543218765" -FAT_SERIAL="12345678" - -# Create 500MB ESP -dd if=/dev/zero of="$TMP/esp.img" bs=1M count=500 - -# Format with fixed volume serial number and label -mformat -i "$TMP/esp.img" -F -v "ESP" -N "$FAT_SERIAL" :: - -# Create directory structure -mmd -i "$TMP/esp.img" ::EFI ::EFI/BOOT - -# Copy files with deterministic timestamps -# -D o sets file times to 1980-01-01 (DOS epoch) -mcopy -D o -i "$TMP/esp.img" "$EFI" ::EFI/BOOT/BOOTX64.EFI - -# Create 1GB disk with GPT -dd if=/dev/zero of="$TMP/disk.raw" bs=1M count=1024 -sgdisk --disk-guid="$DISK_GUID" "$TMP/disk.raw" - -# Create ESP partition -# -n creates partition (number:start:end) -# -t sets type (1:ef00 for ESP) -# -u sets partition GUID -# -c sets partition name -sgdisk -n 1:2048:1026047 \ - -t 1:ef00 \ - -u 1:"$PARTITION_GUID" \ - -c 1:"ESP" \ - -A 1:set:0 \ - "$TMP/disk.raw" - -# Write ESP image to partition area -dd if="$TMP/esp.img" of="$TMP/disk.raw" bs=512 seek=2048 conv=notrunc -touch -d "2024-01-01 00:00:00 UTC" "$TMP/disk.raw" 2>/dev/null || true - -# Create GCP tar.gz -tar --format=oldgnu -Sczf "$TAR" -C "$TMP" disk.raw - -rm -rf "$TMP" +set -eu -o pipefail + +export SOURCE_DATE_EPOCH=0 # not propagated from the main config, needed for mkfs.vfat +export SYSTEMD_REPART_MKFS_OPTIONS_VFAT="-i 12345678 --invariant" +mkdir -p ${OUTPUTDIR}/esp/EFI/BOOT +cp ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.efi ${OUTPUTDIR}/esp/EFI/BOOT/BOOTX64.EFI +# Set fixed timestamps for reproducibility (FAT uses file mtime for directory entries) +find ${OUTPUTDIR}/esp -exec touch -d "@${SOURCE_DATE_EPOCH}" {} + +rm -f ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.raw + +# Hack to use the newer systemd-repart from nix instead of mkosi.tools one +# TODO: remove after updating mkosi +PATH="${PATH#/usr/bin:/usr/sbin:}" systemd-repart --empty=create \ + --size=1G \ + --definitions=mkosi.profiles/gcp/repart.d \ + --copy-source=${OUTPUTDIR} \ + --seed=630b5f72-a36a-4e83-b23d-6ef47c82fd9c \ + --dry-run=no \ + ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.raw +sgdisk --disk-guid "12345678-1234-5678-1234-567812345678" ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.raw + +rm -rf ${OUTPUTDIR}/esp + +cd ${OUTPUTDIR} +ln -sf ${IMAGE_ID}_${IMAGE_VERSION}.raw disk.raw +tar --mtime="@${SOURCE_DATE_EPOCH}" --dereference --format=oldgnu -Sczf ${IMAGE_ID}_${IMAGE_VERSION}.tar.gz disk.raw +unlink disk.raw +rm -f ${OUTPUTDIR}/${IMAGE_ID}_${IMAGE_VERSION}.raw diff --git a/mkosi.profiles/gcp/repart.d/00-uki.conf b/mkosi.profiles/gcp/repart.d/00-uki.conf new file mode 100644 index 00000000..b161a108 --- /dev/null +++ b/mkosi.profiles/gcp/repart.d/00-uki.conf @@ -0,0 +1,8 @@ +[Partition] +Type=esp +Format=vfat +CopyFiles=/esp:/ +Minimize=off +UUID=87654321-4321-8765-4321-876543218765 +SizeMinBytes=524288000 +SizeMaxBytes=524288000 diff --git a/scripts/build_rust_package.sh b/scripts/build_rust_package.sh index e38f412a..7cbd08fa 100755 --- a/scripts/build_rust_package.sh +++ b/scripts/build_rust_package.sh @@ -7,6 +7,7 @@ build_rust_package() { local provided_binary="${4:-}" local extra_features="${5:-}" local extra_rustflags="${6:-}" + local cargo_package="${7:-$package}" local dest_path="$DESTDIR/usr/bin/$package" mkdir -p "$DESTDIR/usr/bin" @@ -19,7 +20,8 @@ build_rust_package() { fi # If binary is cached, skip compilation - local cached_binary="$BUILDDIR/${package}-${version}" + local safe_version="${version//\//_}" + local cached_binary="$BUILDDIR/${package}-${safe_version}" if [ -f "$cached_binary" ]; then echo "Using cached binary for $package version $version" cp "$cached_binary" "$dest_path" @@ -29,7 +31,14 @@ build_rust_package() { # Clone the repository local build_dir="$BUILDROOT/build/$package" mkdir -p "$build_dir" - git clone --depth 1 --branch "$version" "$git_url" "$build_dir" + if [ -f "$BUILDDIR/.ghtoken" ]; then + git_url="${git_url/#https:\/\/github.com/https:\/\/x-access-token:$(cat "$BUILDDIR/.ghtoken")@github.com}" + fi + git clone --depth 1 --branch "$version" "$git_url" "$build_dir" || ( + echo "Could not clone branch/tag, attempting to checkout the commit by sha" + git clone "$git_url" "$build_dir" && + git -C "$build_dir" checkout "$version" + ) # Define Rust flags for reproducibility local rustflags=( @@ -50,7 +59,7 @@ build_rust_package() { CARGO_TERM_COLOR='never' cd '/build/$package' cargo fetch - cargo build --release --frozen ${extra_features:+--features $extra_features} + cargo build --release --frozen ${extra_features:+--features $extra_features} --package $cargo_package " # Cache and install the built binary diff --git a/scripts/make_git_package.sh b/scripts/make_git_package.sh index 5771e162..f037bfa5 100644 --- a/scripts/make_git_package.sh +++ b/scripts/make_git_package.sh @@ -10,8 +10,9 @@ make_git_package() { # All remaining arguments are artifact mappings in src:dest format mkdir -p "$DESTDIR/usr/bin" - local cache_dir="$BUILDDIR/${package}-${version}" - + local safe_version="${version//\//_}" + local cache_dir="$BUILDDIR/${package}-${safe_version}" + # Use cached artifacts if available if [ -n "$cache_dir" ] && [ -d "$cache_dir" ] && [ "$(ls -A "$cache_dir" 2>/dev/null)" ]; then echo "Using cached artifacts for $package version $version" @@ -32,7 +33,14 @@ make_git_package() { # Build from source local build_dir="$BUILDROOT/build/$package" - git clone --depth 1 --branch "$version" "$git_url" "$build_dir" + if [ -f "$BUILDDIR/.ghtoken" ]; then + git_url="${git_url/#https:\/\/github.com/https:\/\/x-access-token:$(cat "$BUILDDIR/.ghtoken")@github.com}" + fi + git clone --depth 1 --branch "$version" "$git_url" "$build_dir" || ( + echo "Could not clone branch/tag, attempting to checkout the commit by sha" + git clone "$git_url" "$build_dir" && + git -C "$build_dir" checkout "$version" + ) mkosi-chroot bash -c "cd '/build/$package' && $build_cmd" # Copy artifacts to image and cache diff --git a/scripts/setup_deps.sh b/scripts/setup_deps.sh index d0e66987..66d7b23c 100755 --- a/scripts/setup_deps.sh +++ b/scripts/setup_deps.sh @@ -24,8 +24,6 @@ cmd_exists curl || missing+=("curl") cmd_exists qemu-img || missing+=("qemu-utils") cmd_exists newuidmap || missing+=("uidmap") -ls /usr/share/keyrings/debian-archive* &>/dev/null 2>&1 || missing+=("debian-archive-keyring") - if cmd_exists systemctl; then version=$(systemctl --version | head -1 | awk '{print $2}') [ "$version" -ge 250 ] || err "systemd 250+ required (current: $version). $LIMA_MSG" @@ -55,7 +53,7 @@ fi apt_pkgs=() for dep in "${missing[@]}"; do - [[ "$dep" == "curl" || "$dep" == "debian-archive-keyring" || "$dep" == "qemu-utils" || "$dep" == "uidmap" ]] && apt_pkgs+=("$dep") + [[ "$dep" == "curl" || "$dep" == "qemu-utils" || "$dep" == "uidmap" ]] && apt_pkgs+=("$dep") done if [ ${#apt_pkgs[@]} -gt 0 ]; then diff --git a/services/bin/rbuilder-init b/services/bin/rbuilder-init deleted file mode 100755 index 94e4ff29..00000000 --- a/services/bin/rbuilder-init +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -set -e - -# Create necessary directories -mkdir -p /var/run/rbuilder /persistent/rbuilder -chown -R rbuilder:eth /var/run/rbuilder /persistent/rbuilder /etc/rbuilder.config -chmod 640 /etc/rbuilder.config -chmod 770 /var/run/rbuilder - -# Create initial blocklist file -if [ ! -f /persistent/rbuilder/rbuilder.blocklist.json ]; then - echo '{}' > /persistent/rbuilder/rbuilder.blocklist.json - chmod 640 /persistent/rbuilder/rbuilder.blocklist.json - chown rbuilder:eth /persistent/rbuilder/rbuilder.blocklist.json -fi \ No newline at end of file diff --git a/services/bin/reth-sync b/services/bin/reth-sync deleted file mode 100755 index f7dbe8c9..00000000 --- a/services/bin/reth-sync +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -set -e - -# Set up directories -mkdir -p /persistent/reth -chown reth:eth /persistent/reth - -# Get latest version and sync -LATEST_META=$(rclone --config /etc/rclone.conf cat r2:chain-db-snapshots/reth-mainnet-full/latest_version.meta.txt) - -rclone sync --config /etc/rclone.conf -v -P \ - --transfers=20 --multi-thread-streams 30 \ - --contimeout=10m --retries 10 --retries-sleep 60s \ - --error-on-no-transfer --update --fast-list \ - --delete-during --disable-http2 --no-gzip-encoding \ - --exclude 'files.txt' \ - r2:chain-db-snapshots/reth-mainnet-full/$LATEST_META/ /persistent/reth \ No newline at end of file diff --git a/services/systemd/persistence-setup.service b/services/systemd/persistence-setup.service deleted file mode 100644 index d03b6a1f..00000000 --- a/services/systemd/persistence-setup.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description=Setup Persistent Storage -DefaultDependencies=no -After=local-fs-pre.target -Before=local-fs.target - -[Service] -Type=oneshot -ExecStart=/bin/sh -c "if [ -e /dev/vda ] && ! blkid /dev/vda | grep -q 'TYPE=\"ext4\"'; then mkfs.ext4 -F /dev/vda; fi" -ExecStart=/bin/sh -c "mkdir -p /persistent" -ExecStart=/bin/sh -c "mount /dev/vda /persistent || echo 'Failed to mount persistent storage'" -RemainAfterExit=yes - -[Install] -WantedBy=sysinit.target \ No newline at end of file diff --git a/services/systemd/rbuilder-bidding.service b/services/systemd/rbuilder-bidding.service deleted file mode 100644 index 8d039242..00000000 --- a/services/systemd/rbuilder-bidding.service +++ /dev/null @@ -1,30 +0,0 @@ -[Unit] -Description=RBuilder Bidding Service -After=network.target network-setup.service persistent-mount.service rbuilder.service -Requires=network-setup.service persistent-mount.service rbuilder.service - -[Service] -Type=exec -User=rbuilder -Group=eth -WorkingDirectory=/var/run/rbuilder -ExecStart=/usr/bin/bwrap \ - --ro-bind /usr /usr \ - --ro-bind /lib /lib \ - --ro-bind /lib64 /lib64 \ - --ro-bind /bin /bin \ - --ro-bind /sbin /sbin \ - --ro-bind /etc/bidding.toml /config.toml \ - --bind /var/run/rbuilder /var/run/rbuilder \ - --proc /proc \ - --dev /dev \ - --clearenv \ - --unshare-pid \ - bidding-service /config.toml -Restart=on-failure -RestartSec=10 -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=minimal.target \ No newline at end of file diff --git a/services/systemd/rbuilder.service b/services/systemd/rbuilder.service deleted file mode 100644 index 764d82b7..00000000 --- a/services/systemd/rbuilder.service +++ /dev/null @@ -1,30 +0,0 @@ -[Unit] -Description=RBuilder Bidding Service -After=network.target network-setup.service persistent-mount.service -Requires=network-setup.service persistent-mount.service - -[Service] -Type=exec -User=rbuilder -Group=eth -ExecStartPre=+/usr/bin/rbuilder-init -ExecStart=/usr/bin/bwrap \ - --ro-bind /usr /usr \ - --ro-bind /lib /lib \ - --ro-bind /lib64 /lib64 \ - --ro-bind /bin /bin \ - --ro-bind /sbin /sbin \ - --ro-bind /etc/bidding.toml /config.toml \ - --bind /var/run/rbuilder /var/run/rbuilder \ - --proc /proc \ - --dev /dev \ - --clearenv \ - --unshare-pid \ - bidding-service /config.toml -Restart=on-failure -RestartSec=10 -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=minimal.target \ No newline at end of file diff --git a/services/systemd/reth-sync.service b/services/systemd/reth-sync.service deleted file mode 100644 index e47c9c85..00000000 --- a/services/systemd/reth-sync.service +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -Description=Reth Chain Data Sync -After=network.target network-setup.service persistent-mount.service -Requires=network-setup.service persistent-mount.service - -[Service] -User=reth -Group=eth -Type=oneshot -ExecStart=/usr/bin/reth-sync -RemainAfterExit=yes -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=minimal.target \ No newline at end of file diff --git a/services/systemd/reth.service b/services/systemd/reth.service deleted file mode 100644 index 9d41f010..00000000 --- a/services/systemd/reth.service +++ /dev/null @@ -1,32 +0,0 @@ -[Unit] -Description=Reth Execution Client -After=network-setup.service reth-sync.service persistent-mount.service -Requires=network-setup.service reth-sync.service persistent-mount.service - -[Service] -User=reth -Group=eth -ExecStart=/usr/bin/reth node \ - --full \ - --datadir "/persistent/reth" \ - --authrpc.addr 127.0.0.1 \ - --authrpc.jwtsecret "/tmp/jwt.hex" \ - --authrpc.port 8551 \ - --http \ - --http.addr 127.0.0.1 \ - --http.port 8545 \ - --http.api "eth,net,web3,trace,rpc,debug,txpool" \ - --ws \ - --ws.addr 127.0.0.1 \ - --ws.port 8546 \ - --ws.api "eth,net,trace,web3,rpc,debug,txpool" \ - --log.stdout.format json \ - --log.file.max-files 0 \ - --metrics "127.0.0.1:9001" -Restart=on-failure -RestartSec=10 -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=minimal.target \ No newline at end of file diff --git a/tdx-dummy/dummy-tdx-dcap.service b/tdx-dummy/dummy-tdx-dcap.service index f3feae45..b71ab38b 100644 --- a/tdx-dummy/dummy-tdx-dcap.service +++ b/tdx-dummy/dummy-tdx-dcap.service @@ -1,7 +1,7 @@ [Unit] Description=Dummy TDX DCAP server -After=network-setup.service -Wants=network-setup.service +After=network-online.target +Wants=network-online.target [Service] Type=exec