name: ecrou base: core26 adopt-info: ecrou title: ecrou summary: a small microVM runtime based on libkrun description: | ecrou boots disposable Linux environments as one-shot microVMs on libkrun: it resolves an image reference, boots the microVM, runs the command, and throws the machine away. Volume sharing `-v` and other features are available. ## Install ecrou is strictly confined. sudo snap install ecrou ## First run Connect the KVM interface: sudo snap connect ecrou:kvm Then run a microVM: ecrou run -it ubuntu ## Diagnostics `ecrou probe` reports what a run would find: KVM, libkrun, the cache directory. ## Configuration and cache - image cache: `~/snap/ecrou/common/cache/ecrou` license: MIT website: https://github.com/vhaudiquet/ecrou contact: https://github.com/vhaudiquet/ecrou/issues issues: https://github.com/vhaudiquet/ecrou/issues source-code: https://github.com/vhaudiquet/ecrou grade: stable confinement: strict platforms: amd64: arm64: riscv64: apps: ecrou: command: bin/ecrou command-chain: [command-chain/ecrou-env] plugs: - home - network - kvm parts: ecrou: plugin: rust source: . rust-channel: "1.98.1" rust-path: [crates/ecrou-cli] build-packages: [cmake, perl] # mkfs.ext4 builds the cache image and debugfs provisions it; both # ship in e2fsprogs and run as child processes of the binary. stage-packages: [e2fsprogs] override-pull: | craftctl default # [workspace.package] version — the single `version = "..."` at # the head of the workspace manifest. A missed match fails the # pack loudly instead of packing a versionless snap. craftctl set version="$(sed -n 's/^version = "\(.*\)"/\1/p' \ "$CRAFT_PART_SRC/Cargo.toml")" override-build: | craftctl default # The home interface stops at dotfiles, so ~/.cache is # unreachable under strict confinement. Point the XDG cache # lookup (the dirs crate honors the variable) into the snap's # durable area, shared across refreshes. mkdir -p "$CRAFT_PART_INSTALL/command-chain" cat > "$CRAFT_PART_INSTALL/command-chain/ecrou-env" <<'EOF' #!/bin/sh XDG_CACHE_HOME="$SNAP_USER_COMMON/cache" export XDG_CACHE_HOME mkdir -p "$XDG_CACHE_HOME" exec "$@" EOF chmod 755 "$CRAFT_PART_INSTALL/command-chain/ecrou-env" libkrun: plugin: rust source: https://github.com/containers/libkrun source-type: git source-tag: v1.19.7 source-depth: 1 rust-channel: "1.98.1" override-build: | # blk turns on the virtio-blk device: the rootfs crosses as a # raw ext4 image (krun_add_disk + krun_set_root_disk_remount), # which is what makes guest-side chown work. cargo build --release -p libkrun --features net,blk install -Dm755 target/release/libkrun.so \ "$CRAFT_PART_INSTALL/lib/libkrun.so.1.19.7" ln -s libkrun.so.1.19.7 "$CRAFT_PART_INSTALL/lib/libkrun.so.1" libkrunfw: plugin: nil # libkrunfw5 ships only in stonking universe today, not in any LTS # base, so the .deb comes straight from the Ubuntu archive — one # flavor per target arch. riscv64 lives on the ports archive # (archive.ubuntu.com carries amd64 and arm64 binaries only). The # library embeds its kernel and has no external symbols, so it # runs on the base's older glibc. build-packages: [curl] override-pull: | arch="$CRAFT_ARCH_BUILD_FOR" case "$arch" in amd64) digest="924cd545080aaf5da66740d12a51b7a5cbd9a5c0b502d21cbef9bc82bf1c8b6b" pool="https://archive.ubuntu.com/ubuntu/pool/universe/libk/libkrunfw" ;; arm64) digest="9570e82feac79fd41a6a9674cc02a9b2f09948ac30ad480d05fc73a957843e56" pool="https://archive.ubuntu.com/ubuntu/pool/universe/libk/libkrunfw" ;; riscv64) digest="1f8b52a00eafdf52d2295eeab7dd527736788ce4d3aa97aecc18e3f4b66f413f" pool="https://ports.ubuntu.com/ubuntu-ports/pool/universe/libk/libkrunfw" ;; *) echo "no libkrunfw5 .deb mapped for $arch" >&2; exit 1 ;; esac curl -fL -o libkrunfw5.deb "$pool/libkrunfw5_5.5.0+ds-1_${arch}.deb" echo "$digest libkrunfw5.deb" | sha256sum -c override-build: | dpkg -x libkrunfw5.deb unpack install -Dm755 "unpack/usr/lib/${CRAFT_ARCH_TRIPLET_BUILD_FOR}/libkrunfw.so.5.5.0" \ "$CRAFT_PART_INSTALL/lib/libkrunfw.so.5.5.0" ln -s libkrunfw.so.5.5.0 "$CRAFT_PART_INSTALL/lib/libkrunfw.so.5"