-
Notifications
You must be signed in to change notification settings - Fork 2
Improve test VM workflow. #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| on: | ||
| pull_request: | ||
| push: | ||
|
|
||
| jobs: | ||
| build: | ||
| name: Build | ||
| runs-on: ubuntu-22.04 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: DeterminateSystems/nix-installer-action@main | ||
| - uses: DeterminateSystems/magic-nix-cache-action@main | ||
| - run: nix build -L | ||
| - run: nix flake check -L |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,6 +34,7 @@ let | |
| nativeBuildInputs = [ perl ]; | ||
| installPhase = '' | ||
| find $GRADLE_USER_HOME/caches/modules-2 -type f -regex '.*\.\(jar\|pom\|module\)' \ | ||
| | LC_ALL=C sort \ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not just this line but i have no clue what youre doing here, this is definitely bside the point of this PR but could you leave a comment about this or something just briefly explaining this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ahah yes, this line is dark magic stolen from occurrences I found in So Nix builds are either sandboxes with no network, or they have network access but need to have an exact hash output. If we wanted to build a package that fetches external dependencies using stuff gradle, cargo, npm, we'd have to set the hash of the output of the build, which is tedious since that would check any time our source changes just a tiny bit, or we change the build process a little. The compromise in Nix is to split the build process in two, fetch the dependencies out of the sandbox and set a fixed hash, and then run the actual build in the sandbox and not have to set the output hash. This is fine for sensible package managers, but gradle is not one of them. It doesn't really have a proper way of just fetching the dependencies. What we do here is build packit-api twice. After the first build, we throw away the build output but keep the cache in Now the actual sort I added is because the same artifact might appear multiple times in the cache, with slightly different contents, eg. one was published to maven central and one to the gradle plugin repository. Absolute madness but here we are. Thanfully from what I could tell, the differences were very minor. We can only have a single copy in our fake maven repo.
I hate all of this, but it's the best I could find for now. nixpkgs has actually improved this quite a bit in the current master, but we need to wait until November for a stable release: NixOS/nixpkgs#272380
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that was actually fucked up |
||
| | perl -pe 's#(.*/([^/]+)/([^/]+)/([^/]+)/[0-9a-f]{30,40}/([^/\s]+))$# ($x = $2) =~ tr|\.|/|; "install -Dm444 $1 \$out/$x/$3/$4/$5" #e' \ | ||
| | sh | ||
| rm -rf $out/tmp | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| #!/usr/bin/env bash | ||
| set -eu | ||
|
|
||
| export VAULT_ADDR="https://vault.dide.ic.ac.uk:8200" | ||
|
|
||
| VAULT_TOKEN=$(cat /sys/firmware/qemu_fw_cfg/by_name/opt/vault-token/raw) | ||
| export VAULT_TOKEN | ||
|
|
||
| PACKIT_GITHUB_CLIENT_ID=$(vault kv get -mount=secret -field=id packit/githubauth/auth/githubclient) | ||
| PACKIT_GITHUB_CLIENT_SECRET=$(vault kv get -mount=secret -field=secret packit/githubauth/auth/githubclient) | ||
|
|
||
| cat > /var/secrets/github-oauth <<EOF | ||
| PACKIT_GITHUB_CLIENT_ID=$PACKIT_GITHUB_CLIENT_ID | ||
| PACKIT_GITHUB_CLIENT_SECRET=$PACKIT_GITHUB_CLIENT_SECRET | ||
| EOF |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| { pkgs, inputs }: | ||
| pkgs.testers.runNixOSTest { | ||
| name = "boot"; | ||
| node.specialArgs = { | ||
| inherit inputs; | ||
| }; | ||
| nodes.machine = { lib, config, ... }: { | ||
| imports = [ | ||
| ../configuration.nix | ||
|
|
||
| # The `virtualisation.vmVariant` setting we use to import VM-specific | ||
| # settings doesn't work for the test VMs, so re-import the vm module here. | ||
| # https://github.com/NixOS/nixpkgs/pull/339511#issuecomment-2328611982 | ||
| ../vm.nix | ||
| ]; | ||
|
|
||
| services.packit-api.instances = | ||
| let | ||
| f = name: lib.nameValuePair name { | ||
| authentication.method = lib.mkForce "basic"; | ||
| }; | ||
| in | ||
| lib.listToAttrs (map f config.services.multi-packit.instances); | ||
|
|
||
| # It's suprisingly easy to run qemu without hardware acceleration and not | ||
| # notice it, which makes the VM so slow the tests tend to fail. This forces | ||
| # KVM acceleration and will fail to start if missing. | ||
| virtualisation.qemu.options = [ "-machine" "accel=kvm" ]; | ||
|
Comment on lines
+25
to
+28
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. okay been reading up about kvm and qemu, i get the general gist but couldnt find exactly how kvm acceleration works, is it because qemu simulates a full machine and kvm hardware acceleration brings that abstraction closer to the metal of the actual machine the vm is running on?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not an expert, but here's my attempt: QEMU is a general virtual machine framework. It has multiple backends, mostly TCG and KVM. Regardless of the backend, it needs to emulate lots of peripherals, eg. the network card and file storage. TCG is an actual emulator, implemented as a JIT. It reads instructions from the guest machine and translates them into host machine instructions. It also needs to emulate a whole bunch of low level stuff (eg. the memory managment, interrupts, ...). Emulating stuff this way is super slow. Fine if you want to emulate a 90s video game console on a modern fast CPU, less fine if you want to emulate a modern fast CPU on a modern fast CPU. KVM is the linux API for hardware accelerated VM. It's the Linux equivalent of Hyper-V I guess. It uses whatever the underlying CPU's acceleration is, on intel that's Intel VT. In that mode, guest instructions are run directly on the host CPU. The CPU has special settings to run in VM mode, and these instructions are correctly isolated from the host and each other. The performance of this is close to native (there's usually a small overhead, but not much). It's what everyone does these days (either via Hyper-V or KVM), cloud VMs would just be too slow without hardware acceleration. Because KVM needs special hardware access, some linux distros, including Ubuntu, restrict the permissions a little bit. Not all though, from my reading it seems some of them have I spent way too long figuring out why the tests were slow but |
||
| }; | ||
|
|
||
| testScript = builtins.readFile ./script.py; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import json | ||
| from shlex import quote | ||
|
|
||
| machine.wait_for_unit("multi-user.target") | ||
|
|
||
| api_url = "https://localhost/reside/packit/api" | ||
| response = machine.wait_until_succeeds(f"curl -sfk {api_url}/auth/config") | ||
| data = json.loads(response) | ||
| assert data == { | ||
| "enableAuth": True, | ||
| "enableBasicLogin": True, | ||
| "enableGithubLogin": False, | ||
| } | ||
|
|
||
| machine.succeed( | ||
| "create-basic-user reside admin@localhost.com password", | ||
| "grant-role reside admin@localhost.com ADMIN") | ||
|
|
||
| payload = json.dumps({ "email": "admin@localhost.com", "password": "password"}) | ||
| response = machine.succeed(f"curl -sfk --json {quote(payload)} {api_url}/auth/login/basic") | ||
| token = json.loads(response)["token"] | ||
|
|
||
| response = machine.succeed(f"curl -sfk --oauth2-bearer {quote(token)} {api_url}/outpack/") | ||
| data = json.loads(response) | ||
| assert data["status"] == "success" |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry for the questions, just trying to work out how this is equivalent, the
/bin/setfacl -m g:nixbld:rwis fine and then we want/dev/kvmthe$env{DEVNAME}gives the/devbit but then how does the/kvmcome into play, youve doneKERNEL=="kvm"but couldnt find anything related to kernel onsetfaclman pageThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a udev rule, which is how modern (last 10-15 years) Linux distros manage devices in
/dev./devis now a temporary in-memory filesystem, and any changes to it don't persist reboot.The rule says, for a device that has the label
KERNEL=="kvm", run the following command.DEVNAMEis set to/dev/kvm. This is more a udev thing than it is asetfaclone.