diff --git a/nix/tests/container-test/default.nix b/nix/tests/container-test/default.nix index 27d448ea..73fd316f 100644 --- a/nix/tests/container-test/default.nix +++ b/nix/tests/container-test/default.nix @@ -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: diff --git a/nix/tests/container-test/default/Dockerfile b/nix/tests/container-test/default/Dockerfile index fe2ba75d..6ee69422 100644 --- a/nix/tests/container-test/default/Dockerfile +++ b/nix/tests/container-test/default/Dockerfile @@ -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 \ No newline at end of file +RUN /nix/nix-installer uninstall --no-confirm diff --git a/nix/tests/container-test/default/Dockerfile.determinate b/nix/tests/container-test/default/Dockerfile.determinate new file mode 100644 index 00000000..cb45fe1c --- /dev/null +++ b/nix/tests/container-test/default/Dockerfile.determinate @@ -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 diff --git a/nix/tests/vm-test/default.nix b/nix/tests/vm-test/default.nix index 63eb2a54..5c2e0a72 100644 --- a/nix/tests/vm-test/default.nix +++ b/nix/tests/vm-test/default.nix @@ -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 @@ -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 @@ -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 = { @@ -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" = { @@ -602,12 +621,15 @@ 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 = ( @@ -615,7 +637,7 @@ let (testName: test: makeTest imageName testName test ) - tests + doTests ); }); }; @@ -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" = { }; }); } diff --git a/src/action/linux/provision_selinux.rs b/src/action/linux/provision_selinux.rs index 2d5defdd..756177e2 100644 --- a/src/action/linux/provision_selinux.rs +++ b/src/action/linux/provision_selinux.rs @@ -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 @@ -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, } impl ProvisionSelinux { #[tracing::instrument(level = "debug", skip_all)] - pub async fn plan(policy_path: PathBuf) -> Result, ActionError> { - let this = Self { policy_path }; + pub async fn plan( + policy_path: PathBuf, + policy_content: &[u8], + ) -> Result, 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. @@ -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)?; diff --git a/src/action/linux/selinux/build.sh b/src/action/linux/selinux/build.sh index b44b15f9..ef38fec8 100755 --- a/src/action/linux/selinux/build.sh +++ b/src/action/linux/selinux/build.sh @@ -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 \ No newline at end of file +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 diff --git a/src/action/linux/selinux/determinate-nix.fc b/src/action/linux/selinux/determinate-nix.fc new file mode 100644 index 00000000..bd1c8087 --- /dev/null +++ b/src/action/linux/selinux/determinate-nix.fc @@ -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 diff --git a/src/action/linux/selinux/determinate-nix.pp b/src/action/linux/selinux/determinate-nix.pp new file mode 100644 index 00000000..b1d42e66 Binary files /dev/null and b/src/action/linux/selinux/determinate-nix.pp differ diff --git a/src/planner/linux.rs b/src/planner/linux.rs index 20e06119..878e0ebe 100644 --- a/src/planner/linux.rs +++ b/src/planner/linux.rs @@ -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, }; @@ -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(), ); } diff --git a/src/planner/ostree.rs b/src/planner/ostree.rs index a01a22e3..32375b93 100644 --- a/src/planner/ostree.rs +++ b/src/planner/ostree.rs @@ -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}; @@ -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(), ); }