Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/rust-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,16 @@ jobs:
matrix:
platform: [ public-ubuntu-24.04-32core, macos-14 ]
runs-on: ${{ matrix.platform }}
permissions:
id-token: write
contents: read
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: eu-central-1
role-to-assume: ${{ secrets.AWS_ROLE }}
role-duration-seconds: 7200
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # pin@v3
with:
token: ${{ secrets.ORB_GIT_HUB_TOKEN }}
Expand Down
23 changes: 19 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 6 additions & 3 deletions nix/shells/development.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{ fenix, system, instantiatedPkgs, seekSdk }:
let
p = instantiatedPkgs // {
native = p.${system};
native = instantiatedPkgs.${system};
};
seekSdkPath = seekSdk + "/Seek_Thermal_SDK_4.1.0.0";
# Gets the same rust toolchain that rustup would have used.
Expand Down Expand Up @@ -64,7 +64,6 @@ in
cargo-zigbuild # Used to cross compile rust
dpkg # Used to test outputs of cargo-deb
git-cliff # Conventional commit based release notes
sshpass # Non-interactive ssh password auth
mdbook # Generates site for docs
mdbook-mermaid # Adds mermaid support
nixpkgs-fmt # Nix autoformatter
Expand All @@ -73,6 +72,7 @@ in
(python3.withPackages (ps: with ps; [
requests
]))
qemu
squashfsTools # mksquashfs
sshpass # Needed for orb-software/scripts
taplo # toml autoformatter
Expand All @@ -87,7 +87,10 @@ in
# env variables ourselves and don't want nix overwriting them, so we
# use the unwrapped version.
pkg-config-unwrapped
]) ++ [
]) ++ p.native.lib.lists.optionals p.native.stdenv.isLinux [
p.native.guestfs-tools
p.native.passt
] ++ [
rustToolchain
rustPlatform.bindgenHook # Configures bindgen to use nix clang
] ++ p.native.lib.lists.optionals p.native.stdenv.isDarwin [
Expand Down
5 changes: 5 additions & 0 deletions test-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ rust-version.workspace = true
publish = false

[dependencies]
blake3 = "1.8.2"
cmd_lib.workspace = true
fs4 = "0.13.1"
nix = { workspace = true, features = ["socket"] }
regex = "1.11.2"
tempfile.workspace = true
testcontainers.workspace = true
tokio = { workspace = true, features = ["full"] }
uuid = { version = "1.18.1", features = ["v4"] }
1 change: 1 addition & 0 deletions test-utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod async_bag;
pub mod docker;
pub mod qemu;
51 changes: 51 additions & 0 deletions test-utils/src/qemu/base.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use super::img::QemuImg;

const NET_ENP0S3_SVC: &str = "
[Unit]
Description=Bring up enp0s3 static
Before=network.target

[Service]
Type=oneshot
ExecStart=/usr/sbin/ip link set enp0s3 up
ExecStart=/usr/sbin/ip addr add 10.0.2.15/24 dev enp0s3
ExecStart=/usr/sbin/ip route add default via 10.0.2.2
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
";

const RESOLVED_CONF: &str = "
[Resolve]
DNS=10.0.2.3 1.1.1.1
FallbackDNS=";

const SUDOERS: &str = "worldcoin ALL=(ALL) NOPASSWD:ALL";

const SSHD_CFG: &str = "
PasswordAuthentication yes
PermitEmptyPasswords yes
UsePAM yes
PubkeyAuthentication no
UseDNS no
GSSAPIAuthentication no
MaxStartups 100:30:200
";

pub fn bullseye() -> QemuImg {
QemuImg::from_base("debian-11-generic-amd64.qcow2")
.write("/etc/systemd/system/net-enp0s3.service", NET_ENP0S3_SVC)
.run("systemctl enable net-enp0s3.service")
.run("systemctl disable systemd-resolved")
.write("/etc/systemd/resolved.conf.d/99-qemu.conf", RESOLVED_CONF)
.run("ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf")
.run("systemctl enable systemd-resolved")
.write("/etc/sudoers.d/worldcoin", SUDOERS)
.write("/etc/ssh/sshd_config.d/99-local.conf", SSHD_CFG)
.run("useradd -m -s /bin/bash -G sudo worldcoin")
.run("passwd -d worldcoin")
.pkgs(&["openssh-server", "iproute2", "network-manager"])
.run("systemctl enable ssh")
.run("ssh-keygen -A")
}
95 changes: 95 additions & 0 deletions test-utils/src/qemu/fx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use super::{img::QemuImg, instance::QemuInstance};
use std::{
fs,
path::{Path, PathBuf},
};

pub fn run(workdir: impl AsRef<Path>, img: &QemuImg) -> QemuInstance {
if !s3::is_authed() {
panic!("\nplease authenticate with s3 before continuing\n");
}

let img_path = get_or_build_img(&workdir, img);
QemuInstance::start(workdir, img_path)
}

fn get_or_build_img(workdir: impl AsRef<Path>, qemu_img: &QemuImg) -> PathBuf {
let workdir = workdir.as_ref();
let workdir_str = workdir.to_str().unwrap();

let img = format!("{}.qcow2", qemu_img.to_hash());

let img_workdir_path = workdir.join(&img);
println!("checking for QemuImg in workdir: {img_workdir_path:?}");

if fs::exists(&img_workdir_path).unwrap() {
return img_workdir_path;
}

println!(
"QemuImg does not exist. Looking for it in {}",
s3::VM_S3_PATH
);

if s3::get_vm(workdir_str, &img) {
return img_workdir_path;
}

println!("QemuImg does not exist in S3, will build locally.");

let base_img_path = workdir.join(qemu_img.base());
println!("Looking for base image in workdir: {base_img_path:?}");

if !fs::exists(&base_img_path).unwrap() {
println!("Base image not found locally. Pulling from s3.");
if !s3::get_vm(workdir_str, qemu_img.base()) {
panic!(
"Could not find base image {} on S3. Nothing else to do.",
qemu_img.base()
);
}
}

println!("Building QemuImg.");
qemu_img.build(workdir)
}

mod s3 {
use std::{fs::OpenOptions, path::Path};

use cmd_lib::run_cmd;
use fs4::fs_std::FileExt;

pub const VM_S3_PATH: &str = "s3://worldcoin-orb-resources/virtual-machines";

pub fn is_authed() -> bool {
run_cmd!(aws sts get-caller-identity > /dev/null).is_ok()
}

pub fn get_vm(workdir: impl AsRef<Path>, filename: &str) -> bool {
let workdir = workdir.as_ref();
let workdir_str = workdir.to_str().unwrap();

let lock_path = workdir.join(format!("{filename}.lock"));
let file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(false)
.open(lock_path)
.unwrap();

file.lock_exclusive().unwrap();

if workdir.join(filename).exists() {
return true;
}

run_cmd!(aws s3 cp $VM_S3_PATH/$filename $workdir_str).is_ok()
}

#[allow(dead_code)]
pub fn upload_vm(workdir: &str, filename: &str) {
run_cmd!(aws s3 cp $workdir/$filename $VM_S3_PATH).unwrap();
}
}
Loading
Loading