Skip to content

Commit a07b348

Browse files
committed
Test system manager deployment triggered by Ansible
1 parent a394449 commit a07b348

File tree

8 files changed

+116
-103
lines changed

8 files changed

+116
-103
lines changed

ansible/tasks/setup-nix.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
- name: Check if nix is installed
3+
ansible.builtin.command: which nix
4+
register: nix_installed
5+
failed_when: nix_installed.rc != 0
6+
ignore_errors: true
7+
8+
- name: Install nix
9+
ansible.builtin.shell: curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install --no-confirm --extra-conf 'substituters = https://cache.nixos.org https://nix-postgres-artifacts.s3.amazonaws.com' --extra-conf 'trusted-public-keys = nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI=% cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY='
10+
when: nix_installed.rc != 0
11+
become: true
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
- name: Deploy system manager
3+
ansible.builtin.shell: |
4+
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
5+
cd /tmp
6+
nix run /flake#system-manager -- switch --flake /flake
7+
become: true

ansible/tests/conftest.py

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,76 @@
1+
import pytest
2+
import subprocess
3+
import testinfra
4+
from rich.console import Console
5+
6+
console = Console()
7+
8+
19
def pytest_addoption(parser):
210
parser.addoption(
3-
"--ansible-dir",
11+
"--flake-dir",
412
action="store",
5-
help="Directory containing Ansible playbooks and roles",
13+
help="Directory containing the current flake",
614
)
715

816
parser.addoption(
917
"--docker-image",
1018
action="store",
1119
help="Docker image and tag to use for testing",
1220
)
21+
22+
23+
@pytest.fixture(scope="module")
24+
def host(request):
25+
flake_dir = request.config.getoption("--flake-dir")
26+
docker_id = (
27+
subprocess.check_output(
28+
[
29+
"docker",
30+
"run",
31+
"--privileged",
32+
"--cap-add",
33+
"SYS_ADMIN",
34+
"--security-opt",
35+
"seccomp=unconfined",
36+
"--cgroup-parent=docker.slice",
37+
"--cgroupns",
38+
"private",
39+
"-v",
40+
f"{flake_dir}:/flake",
41+
"-d",
42+
"ubuntu-cloudimg-with-tools:0.1",
43+
]
44+
)
45+
.decode()
46+
.strip()
47+
)
48+
yield testinfra.get_host("docker://" + docker_id)
49+
subprocess.check_call(["docker", "rm", "-f", docker_id], stdout=subprocess.DEVNULL)
50+
51+
52+
@pytest.fixture(scope="module")
53+
def run_ansible_playbook(host):
54+
def _run_playbook(playbook_name, verbose=False):
55+
cmd = [
56+
"ANSIBLE_HOST_KEY_CHECKING=False",
57+
"ansible-playbook",
58+
"--connection=local",
59+
]
60+
if verbose:
61+
cmd.append("-vvv")
62+
cmd.extend([
63+
"-i",
64+
"localhost,",
65+
"--extra-vars",
66+
"@/flake/ansible/vars.yml",
67+
f"/flake/ansible/tests/{playbook_name}",
68+
])
69+
result = host.run(" ".join(cmd))
70+
if result.failed:
71+
console.log(result.stdout)
72+
console.log(result.stderr)
73+
raise pytest.fail(
74+
f"Ansible playbook {playbook_name} failed with return code {result.rc}"
75+
)
76+
return _run_playbook

ansible/tests/nix.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
- hosts: localhost
3+
tasks:
4+
- import_tasks: ../tasks/setup-nix.yml
5+
- import_tasks: ../tasks/setup-system-manager.yml

ansible/tests/test_nginx.py

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,9 @@
11
import pytest
2-
import subprocess
3-
import testinfra
4-
from rich.console import Console
52

6-
console = Console()
73

8-
9-
@pytest.fixture(scope="session")
10-
def host(request):
11-
ansible_dir = request.config.getoption("--ansible-dir")
12-
docker_id = (
13-
subprocess.check_output(
14-
[
15-
"docker",
16-
"run",
17-
"--privileged",
18-
"--cap-add",
19-
"SYS_ADMIN",
20-
"--security-opt",
21-
"seccomp=unconfined",
22-
"--cgroup-parent=docker.slice",
23-
"--cgroupns",
24-
"private",
25-
"-v",
26-
f"{ansible_dir}/:/ansible/",
27-
"-d",
28-
"ubuntu-cloudimg-with-tools:0.1",
29-
]
30-
)
31-
.decode()
32-
.strip()
33-
)
34-
yield testinfra.get_host("docker://" + docker_id)
35-
subprocess.check_call(["docker", "rm", "-f", docker_id], stdout=subprocess.DEVNULL)
36-
37-
38-
@pytest.fixture(scope="session", autouse=True)
39-
def run_ansible(host):
40-
cmd = [
41-
"ANSIBLE_HOST_KEY_CHECKING=False",
42-
"ansible-playbook",
43-
"--connection=local",
44-
"-i",
45-
"localhost,",
46-
"--extra-vars",
47-
"@/ansible/vars.yml",
48-
"/ansible/tests/nginx.yaml",
49-
]
50-
result = host.run(" ".join(cmd))
51-
if result.failed:
52-
console.log(result.stdout)
53-
console.log(result.stderr)
54-
raise pytest.fail(
55-
"Ansible playbook nginx.yaml failed with return code {}".format(result.rc)
56-
)
4+
@pytest.fixture(scope="module", autouse=True)
5+
def run_ansible(run_ansible_playbook):
6+
run_ansible_playbook("nginx.yaml")
577

588

599
def test_nginx_service(host):

ansible/tests/test_nix.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import pytest
2+
3+
4+
@pytest.fixture(scope="module", autouse=True)
5+
def run_ansible(run_ansible_playbook):
6+
run_ansible_playbook("nix.yaml", verbose=True)
7+
8+
9+
def test_nix_service(host):
10+
assert host.service("nix-daemon.service").is_running
11+
12+
def test_envoy_service(host):
13+
assert host.service("envoy.service").is_running

nix/packages/ansible-test.nix

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,9 @@
11
{
22
pkgs,
33
lib,
4+
docker-image-ubuntu,
45
}:
56
let
6-
ubuntu-cloudimg =
7-
let
8-
cloudImg = builtins.fetchurl {
9-
url = "http://cloud-images-archive.ubuntu.com/releases/noble/release-20250430/ubuntu-24.04-server-cloudimg-amd64-root.tar.xz";
10-
sha256 = "sha256:0rfi3qqs0sqarixfic7pzjpx7d4vldv2d98c5zjv7b90mirznvf9";
11-
};
12-
in
13-
pkgs.runCommand "ubuntu-cloudimg" { nativeBuildInputs = [ pkgs.xz ]; } ''
14-
mkdir -p $out
15-
tar --exclude='dev/*' \
16-
--exclude='etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service' \
17-
--exclude='etc/systemd/system/multi-user.target.wants/systemd-resolved.service' \
18-
--exclude='usr/lib/systemd/system/tpm-udev.service' \
19-
--exclude='usr/lib/systemd/system/systemd-remount-fs.service' \
20-
--exclude='usr/lib/systemd/system/systemd-resolved.service' \
21-
--exclude='var/lib/apt/lists/*' \
22-
-xJf ${cloudImg} -C $out
23-
rm $out/bin $out/lib $out/lib64 $out/sbin
24-
mkdir -p $out/run/systemd && echo 'docker' > $out/run/systemd/container
25-
mkdir $out/var/lib/apt/lists/partial
26-
'';
27-
28-
dockerImageUbuntu = pkgs.dockerTools.buildImage {
29-
name = "ubuntu-cloudimg";
30-
tag = "0.1";
31-
created = "now";
32-
extraCommands = ''
33-
ln -s usr/bin
34-
ln -s usr/lib
35-
ln -s usr/lib64
36-
ln -s usr/sbin
37-
'';
38-
copyToRoot = pkgs.buildEnv {
39-
name = "image-root";
40-
pathsToLink = [ "/" ];
41-
paths = [ ubuntu-cloudimg ];
42-
};
43-
config.Cmd = [ "/lib/systemd/systemd" ];
44-
};
45-
467
dockerImageUbuntuWithTools =
478
let
489
tools = [ pkgs.ansible ];
@@ -52,7 +13,8 @@ let
5213
tag = "0.1";
5314
created = "now";
5415
maxLayers = 30;
55-
fromImage = dockerImageUbuntu;
16+
fromImage = docker-image-ubuntu;
17+
compressor = "zstd";
5618
config = {
5719
Env = [
5820
"PATH=${lib.makeBinPath tools}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
@@ -69,19 +31,18 @@ pkgs.writeShellApplication {
6931
requests
7032
pytest
7133
pytest-testinfra
34+
pytest-xdist
7235
rich
7336
]
7437
))
7538
];
7639
text = ''
7740
echo "Running Ansible tests..."
7841
export DOCKER_IMAGE=${dockerImageUbuntuWithTools.imageName}:${dockerImageUbuntuWithTools.imageTag}
79-
if ! docker image inspect $DOCKER_IMAGE > /dev/null; then
80-
echo "Loading Docker image..."
81-
docker load < ${dockerImageUbuntuWithTools}
82-
fi
83-
ANSIBLE_DIR=${../../ansible}
84-
pytest -p no:cacheprovider -s -v "$@" $ANSIBLE_DIR/tests --ansible-dir=$ANSIBLE_DIR --docker-image=$DOCKER_IMAGE
42+
echo "Loading Docker image..."
43+
docker load < ${dockerImageUbuntuWithTools}
44+
FLAKE_DIR=${../..}
45+
pytest -x -p no:cacheprovider -s -v "$@" $FLAKE_DIR/ansible/tests --flake-dir=$FLAKE_DIR --docker-image=$DOCKER_IMAGE
8546
'';
8647
meta = with pkgs.lib; {
8748
description = "Ansible test runner";

nix/packages/default.nix

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
packages = (
3232
{
3333
build-test-ami = pkgs.callPackage ./build-test-ami.nix { };
34-
ansible-test = pkgs.callPackage ./ansible-test.nix { };
34+
ansible-test = pkgs.callPackage ./ansible-test.nix {
35+
inherit (self'.packages) docker-image-ubuntu;
36+
};
3537
cleanup-ami = pkgs.callPackage ./cleanup-ami.nix { };
3638
dbmate-tool = pkgs.callPackage ./dbmate-tool.nix { inherit (self.supabase) defaults; };
3739
docker-image-ubuntu = pkgs.callPackage ./docker-ubuntu.nix { };

0 commit comments

Comments
 (0)