Skip to content

Commit

Permalink
Add --determinate container and VM tests (#1103)
Browse files Browse the repository at this point in the history
* Add --determinate container tests

* Add --determinate VM tests

* fixup: actually show journalctl logs when something fails

* fixup: trace logging container and VM tests

This makes it easier to see what's going on, and aids debugging
failures.

* fixup: add Determinate SELinux policy

* Skip --determinate in RHEL v7 VM tests

* Fixup fmt

---------

Co-authored-by: Graham Christensen <graham@grahamc.com>
  • Loading branch information
cole-h and grahamc committed Aug 19, 2024
1 parent 21da280 commit d6240cf
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 31 deletions.
31 changes: 31 additions & 0 deletions nix/tests/container-test/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,37 @@ let
system = "x86_64-linux";
};

# Found via https://hub.docker.com/_/ubuntu/ under "How is the rootfs build?"
# Jammy (--determinate)
"ubuntu-v22_04-determinate" = {
tarball = builtins.fetchurl {
url = "http://cdimage.ubuntu.com/ubuntu-base/releases/22.04/release/ubuntu-base-22.04-base-amd64.tar.gz";
sha256 = "01sbpjb32x1z1yr9q78zrk0a6kfw5c4fxw1jqmm23g8ixryffvyz";
};
tester = ./default/Dockerfile.determinate;
system = "x86_64-linux";
};

# focal (--determinate)
"ubuntu-v20_04-determinate" = {
tarball = builtins.fetchurl {
url = "http://cdimage.ubuntu.com/ubuntu-base/releases/20.04/release/ubuntu-base-20.04.1-base-amd64.tar.gz";
sha256 = "0ryn38csmx41a415g9b3wk30csaxxlkgkdij9v4754pk877wpxlp";
};
tester = ./default/Dockerfile.determinate;
system = "x86_64-linux";
};

# bionic (--determinate)
"ubuntu-v18_04-determinate" = {
tarball = builtins.fetchurl {
url = "http://cdimage.ubuntu.com/ubuntu-base/releases/18.04/release/ubuntu-base-18.04.5-base-amd64.tar.gz";
sha256 = "1sh73pqwgyzkyssv3ngpxa2ynnkbdvjpxdw1v9ql4ghjpd3hpwlg";
};
tester = ./default/Dockerfile.determinate;
system = "x86_64-linux";
};

};

makeTest = containerTool: imageName:
Expand Down
4 changes: 2 additions & 2 deletions nix/tests/container-test/default/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ COPY nix-installer /nix-installer
RUN chmod +x /nix-installer
COPY binary-tarball /binary-tarball
RUN mv /binary-tarball/nix-*.tar.xz nix.tar.xz
RUN /nix-installer/bin/nix-installer install linux --logger pretty --log-directive nix_installer=debug --nix-package-url file:///nix.tar.xz --init none --extra-conf "sandbox = false" --no-confirm -vvv
RUN /nix-installer/bin/nix-installer install linux --logger pretty --log-directive nix_installer=trace --nix-package-url file:///nix.tar.xz --init none --extra-conf "sandbox = false" --no-confirm -vvv
ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"
RUN nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }'
RUN /nix/nix-installer uninstall --no-confirm
RUN /nix/nix-installer uninstall --no-confirm
9 changes: 9 additions & 0 deletions nix/tests/container-test/default/Dockerfile.determinate
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM default
COPY nix-installer /nix-installer
RUN chmod +x /nix-installer
COPY binary-tarball /binary-tarball
RUN mv /binary-tarball/nix-*.tar.xz nix.tar.xz
RUN /nix-installer/bin/nix-installer install linux --logger pretty --log-directive nix_installer=trace --nix-package-url file:///nix.tar.xz --init none --extra-conf "sandbox = false" --determinate --no-confirm -vvv
ENV PATH="${PATH}:/nix/var/nix/profiles/default/bin"
RUN nix-build --no-substitute -E 'derivation { name = "foo"; system = "x86_64-linux"; builder = "/bin/sh"; args = ["-c" "echo foobar > $out"]; }'
RUN /nix/nix-installer uninstall --no-confirm
38 changes: 30 additions & 8 deletions nix/tests/vm-test/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
let
nix-installer-install = ''
NIX_PATH=$(readlink -f nix.tar.xz)
RUST_BACKTRACE="full" ./nix-installer install --nix-package-url "file://$NIX_PATH" --no-confirm --logger pretty --log-directive nix_installer=info
RUST_BACKTRACE="full" ./nix-installer install --nix-package-url "file://$NIX_PATH" --no-confirm --logger pretty --log-directive nix_installer=trace
'';
nix-installer-install-quiet = ''
NIX_PATH=$(readlink -f nix.tar.xz)
RUST_BACKTRACE="full" ./nix-installer install --nix-package-url "file://$NIX_PATH" --no-confirm
'';
nix-installer-install-determinate = ''
NIX_PATH=$(readlink -f nix.tar.xz)
RUST_BACKTRACE="full" ./nix-installer install --nix-package-url "file://$NIX_PATH" --no-confirm --logger pretty --log-directive nix_installer=trace --determinate
'';
cure-script-multi-user = ''
tar xvf nix.tar.xz
./nix-*/install --no-channel-add --yes --daemon
Expand Down Expand Up @@ -38,25 +42,25 @@ let
fi
if systemctl is-failed nix-daemon.socket; then
echo "nix-daemon.socket is failed"
systemctl status nix-daemon.socket
sudo journalctl -eu nix-daemon.socket
exit 1
fi
if !(sudo systemctl start nix-daemon.service); then
echo "nix-daemon.service failed to start"
systemctl status nix-daemon.service
sudo journalctl -eu nix-daemon.service
exit 1
fi
if systemctl is-failed nix-daemon.service; then
echo "nix-daemon.service is failed"
systemctl status nix-daemon.service
sudo journalctl -eu nix-daemon.service
exit 1
fi
if !(sudo systemctl stop nix-daemon.service); then
echo "nix-daemon.service failed to stop"
systemctl status nix-daemon.service
sudo journalctl -eu nix-daemon.service
exit 1
fi
Expand Down Expand Up @@ -188,6 +192,18 @@ let
uninstall = installCases.install-default.uninstall;
uninstallCheck = installCases.install-default.uninstallCheck;
};
install-determinate = {
install = nix-installer-install-determinate;
check = installCases.install-default.check + ''
if systemctl is-failed determinate-nixd.socket; then
echo "determinate-nixd.socket is failed"
sudo journalctl -eu determinate-nixd.socket
exit 1
fi
'';
uninstall = installCases.install-default.uninstall;
uninstallCheck = installCases.install-default.uninstallCheck;
};
};
cureSelfCases = {
cure-self-linux-working = {
Expand Down Expand Up @@ -475,6 +491,9 @@ let
rootDisk = "box.img";
upstreamScriptsWork = false; # SELinux!
system = "x86_64-linux";
skip = [
"install-determinate" # RHEL v7 has systemd 219 (2015-02-16); determinate-nixd requires at least 227 (2015-10-07)
];
};

"rhel-v8" = {
Expand Down Expand Up @@ -602,20 +621,23 @@ let

makeTests = name: tests: builtins.mapAttrs
(imageName: image:
let
doTests = builtins.removeAttrs tests (image.skip or [ ]);
in
rec {
${image.system} = (builtins.mapAttrs
(testName: test:
makeTest imageName testName test
)
tests) // {
doTests) // {
"${name}" = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.releaseTools.aggregate {
name = name;
constituents = (
pkgs.lib.mapAttrsToList
(testName: test:
makeTest imageName testName test
)
tests
doTests
);
});
};
Expand Down Expand Up @@ -653,7 +675,7 @@ lib.recursiveUpdate joined-tests {
all."x86_64-linux" = (with (forSystem "x86_64-linux" ({ system, pkgs, ... }: pkgs)); pkgs.lib.mapAttrs (caseName: case:
pkgs.releaseTools.aggregate {
name = caseName;
constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux"."${caseName}") joined-tests;
constituents = pkgs.lib.mapAttrsToList (name: value: value."x86_64-linux"."${caseName}" or "") joined-tests;
}
)) (allCases // { "cure-self" = { }; "cure-script" = { }; "install" = { }; "uninstall" = { }; "all" = { }; });
}
17 changes: 13 additions & 4 deletions src/action/linux/provision_selinux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use crate::execute_command;

use crate::action::{Action, ActionDescription, StatefulAction};

const SE_LINUX_POLICY_PP_CONTENT: &[u8] = include_bytes!("selinux/nix.pp");
pub const SELINUX_POLICY_PP_CONTENT: &[u8] = include_bytes!("selinux/nix.pp");
pub const DETERMINATE_SELINUX_POLICY_PP_CONTENT: &[u8] =
include_bytes!("selinux/determinate-nix.pp");

/**
Provision the selinux/nix.pp for SELinux compatibility
Expand All @@ -18,12 +20,19 @@ Provision the selinux/nix.pp for SELinux compatibility
#[serde(tag = "action_name", rename = "provision_selinux")]
pub struct ProvisionSelinux {
policy_path: PathBuf,
policy_content: Vec<u8>,
}

impl ProvisionSelinux {
#[tracing::instrument(level = "debug", skip_all)]
pub async fn plan(policy_path: PathBuf) -> Result<StatefulAction<Self>, ActionError> {
let this = Self { policy_path };
pub async fn plan(
policy_path: PathBuf,
policy_content: &[u8],
) -> Result<StatefulAction<Self>, ActionError> {
let this = Self {
policy_path,
policy_content: policy_content.to_vec(),
};

// Note: `restorecon` requires us to not just skip this, even if everything is in place.

Expand Down Expand Up @@ -74,7 +83,7 @@ impl Action for ProvisionSelinux {
.map_err(Self::error)?;
}

tokio::fs::write(&self.policy_path, SE_LINUX_POLICY_PP_CONTENT)
tokio::fs::write(&self.policy_path, &self.policy_content)
.await
.map_err(|e| ActionErrorKind::Write(self.policy_path.clone(), e))
.map_err(Self::error)?;
Expand Down
8 changes: 5 additions & 3 deletions src/action/linux/selinux/build.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash ../../../../shell.nix
#!/usr/bin/env bash

checkmodule -M -m -c 5 -o nix.mod nix.te
semodule_package -o nix.pp -m nix.mod -f nix.fc
semodule_package -o nix.pp -m nix.mod -f nix.fc

checkmodule -M -m -c 5 -o nix.mod nix.te
semodule_package -o determinate-nix.pp -m nix.mod -f determinate-nix.fc
14 changes: 14 additions & 0 deletions src/action/linux/selinux/determinate-nix.fc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/nix/store/[^/]+/s?bin(/.*)? system_u:object_r:bin_t:s0
/nix/store/[^/]+/lib/systemd/system(/.*)? system_u:object_r:systemd_unit_file_t:s0
/nix/store/[^/]+/lib(/.*)? system_u:object_r:lib_t:s0
/nix/store/[^/]+/man(/.*)? system_u:object_r:man_t:s0
/nix/store/[^/]+/etc(/.*)? system_u:object_r:etc_t:s0
/nix/store/[^/]+/share(/.*)? system_u:object_r:usr_t:s0
/nix/var/nix/daemon-socket(/.*)? system_u:object_r:var_run_t:s0
/nix/var/nix/profiles(/per-user/[^/]+)?/[^/]+ system_u:object_r:usr_t:s0

/nix/determinate/determinate-nixd system_u:object_r:bin_t:s0
/nix/var/determinate/determinate-nixd.socket system_u:object_r:var_run_t:s0
/nix/var/determinate/intake.pipe system_u:object_r:var_run_t:s0
/nix/var/determinate/post-build-hook.sh system_u:object_r:bin_t:s0
/nix/var/determinate/netrc system_u:object_r:etc_t:s0
Binary file added src/action/linux/selinux/determinate-nix.pp
Binary file not shown.
24 changes: 17 additions & 7 deletions src/planner/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ use crate::{
ConfigureDeterminateNixdInitService, ConfigureNix, ConfigureUpstreamInitService,
CreateUsersAndGroups, ProvisionDeterminateNixd, ProvisionNix,
},
linux::ProvisionSelinux,
linux::{
provision_selinux::{DETERMINATE_SELINUX_POLICY_PP_CONTENT, SELINUX_POLICY_PP_CONTENT},
ProvisionSelinux,
},
StatefulAction,
},
error::HasExpectedErrors,
planner::{Planner, PlannerError},
settings::CommonSettings,
settings::{determinate_nix_settings, InitSettings, InitSystem, InstallSettingsError},
settings::{
determinate_nix_settings, CommonSettings, InitSettings, InitSystem, InstallSettingsError,
},
Action, BuiltinPlanner,
};

Expand Down Expand Up @@ -87,10 +91,16 @@ impl Planner for Linux {

if has_selinux {
plan.push(
ProvisionSelinux::plan("/usr/share/selinux/packages/nix.pp".into())
.await
.map_err(PlannerError::Action)?
.boxed(),
ProvisionSelinux::plan(
"/usr/share/selinux/packages/nix.pp".into(),
self.settings
.determinate_nix
.then_some(DETERMINATE_SELINUX_POLICY_PP_CONTENT)
.unwrap_or(SELINUX_POLICY_PP_CONTENT),
)
.await
.map_err(PlannerError::Action)?
.boxed(),
);
}

Expand Down
22 changes: 15 additions & 7 deletions src/planner/ostree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ use crate::{
ConfigureNix, ConfigureUpstreamInitService, CreateUsersAndGroups,
ProvisionDeterminateNixd, ProvisionNix,
},
linux::{ProvisionSelinux, StartSystemdUnit, SystemctlDaemonReload},
linux::{
provision_selinux::{DETERMINATE_SELINUX_POLICY_PP_CONTENT, SELINUX_POLICY_PP_CONTENT},
ProvisionSelinux, StartSystemdUnit, SystemctlDaemonReload,
},
StatefulAction,
},
error::HasExpectedErrors,
planner::{Planner, PlannerError},
settings::CommonSettings,
settings::{determinate_nix_settings, InitSystem, InstallSettingsError},
settings::{determinate_nix_settings, CommonSettings, InitSystem, InstallSettingsError},
Action, BuiltinPlanner,
};
use std::{collections::HashMap, path::PathBuf};
Expand Down Expand Up @@ -208,10 +210,16 @@ impl Planner for Ostree {

if has_selinux {
plan.push(
ProvisionSelinux::plan("/etc/nix-installer/selinux/packages/nix.pp".into())
.await
.map_err(PlannerError::Action)?
.boxed(),
ProvisionSelinux::plan(
"/etc/nix-installer/selinux/packages/nix.pp".into(),
self.settings
.determinate_nix
.then_some(DETERMINATE_SELINUX_POLICY_PP_CONTENT)
.unwrap_or(SELINUX_POLICY_PP_CONTENT),
)
.await
.map_err(PlannerError::Action)?
.boxed(),
);
}

Expand Down

0 comments on commit d6240cf

Please sign in to comment.