diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fbb628f..188edafc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed +- The configuration files for the SSH hook and the Slurm sync hook are no longer generated automatically as part of the CMake installation process. + In other words, the aforementioned hooks are no longer configured and enabled by default. - Updated recommended runc version to 1.1.9 - ### Fixed - Fixed support for image manifests which are provided by registries as multi-line, not indented JSON diff --git a/CI/src/integration_tests/test_command_hooks.py b/CI/src/integration_tests/test_command_hooks.py index 3f6ef3f5..5a6c9d8a 100755 --- a/CI/src/integration_tests/test_command_hooks.py +++ b/CI/src/integration_tests/test_command_hooks.py @@ -7,69 +7,83 @@ import unittest import os -import subprocess - import common.util as util class TestCommandHooks(unittest.TestCase): """ - These tests verify the outputs "hooks" command + These tests verify the outputs of the "hooks" command """ def test_command_hooks(self): expected_header = ["NAME", "PATH", "STAGES"] - actual_header = self._header_in_output_of_hooks_command() + actual_header = header_in_output_of_hooks_command() self.assertEqual(actual_header, expected_header) - hook_output = self._hook_in_output_of_hooks_command("07-ssh-hook") - self.assertEqual(hook_output[1], "/opt/sarus/default/bin/ssh_hook") - self.assertEqual(hook_output[2], "prestart") - - hook_output = self._hook_in_output_of_hooks_command("09-slurm-global-sync-hook") - self.assertEqual(hook_output[1], "/opt/sarus/default/bin/slurm_global_sync_hook") - self.assertEqual(hook_output[2], "prestart") + with util.temporary_hook_files((generate_dummy_hook_config(), + os.environ["CMAKE_INSTALL_PREFIX"] + "/etc/hooks.d/01-dummy-hook.json")): + hook_output = hook_in_output_of_hooks_command("01-dummy-hook") + self.assertEqual(hook_output[1], "/opt/sarus/default/bin/dummy_hook") + self.assertEqual(hook_output[2], "prestart") def test_command_hooks_mpi(self): expected_header = ["NAME", "MPI", "TYPE"] - actual_header = self._header_in_output_of_hooks_command(print_mpi_hooks=True) + actual_header = header_in_output_of_hooks_command(print_mpi_hooks=True) self.assertEqual(actual_header, expected_header) hook_config_paths = [os.environ["CMAKE_INSTALL_PREFIX"] + "/etc/hooks.d/050-mpi0-hook.json", os.environ["CMAKE_INSTALL_PREFIX"] + "/etc/hooks.d/051-mpi1-hook.json"] - with util.temporary_hook_files((self._generate_mpi_hook_config("mpi0"), hook_config_paths[0]), - (self._generate_mpi_hook_config("mpi1"), hook_config_paths[1])): + with util.temporary_hook_files((generate_mpi_hook_config("mpi0"), hook_config_paths[0]), + (generate_mpi_hook_config("mpi1"), hook_config_paths[1])): with util.custom_sarus_json({"defaultMPIType": "mpi0"}): - hook_output = self._hook_in_output_of_hooks_command("050-mpi0-hook", print_mpi_hooks=True) + hook_output = hook_in_output_of_hooks_command("050-mpi0-hook", print_mpi_hooks=True) self.assertEqual(hook_output, ['050-mpi0-hook', '^mpi0$', '(default)']) - hook_output = self._hook_in_output_of_hooks_command("051-mpi1-hook", print_mpi_hooks=True) + hook_output = hook_in_output_of_hooks_command("051-mpi1-hook", print_mpi_hooks=True) self.assertEqual(hook_output, ['051-mpi1-hook', '^mpi1$']) - def _header_in_output_of_hooks_command(self, print_mpi_hooks=False): - return util.get_hooks_command_output(print_mpi_hooks)[0] - - def _hook_in_output_of_hooks_command(self, hook_name, print_mpi_hooks=False): - output = util.get_hooks_command_output(print_mpi_hooks=print_mpi_hooks) - for line in output: - if line[0] == hook_name: - return line - - def _generate_mpi_hook_config(self, mpi_type): - config = { - "version": "1.0.0", - "hook": { - "path": os.environ["CMAKE_INSTALL_PREFIX"] + "/bin/mpi_hook", - "env": [] - }, - "when": { - "annotations": { - "^com.hooks.mpi.enabled$": "^true$", - "^com.hooks.mpi.type": f"^{mpi_type}$" - } - }, - "stages": ["prestart"] - } - return config + +def header_in_output_of_hooks_command(print_mpi_hooks=False): + return util.get_hooks_command_output(print_mpi_hooks)[0] + + +def hook_in_output_of_hooks_command(hook_name, print_mpi_hooks=False): + output = util.get_hooks_command_output(print_mpi_hooks=print_mpi_hooks) + for line in output: + if line[0] == hook_name: + return line + + +def generate_dummy_hook_config(): + config = { + "version": "1.0.0", + "hook": { + "path": os.environ["CMAKE_INSTALL_PREFIX"] + "/bin/dummy_hook", + "env": [] + }, + "when": { + "always": True + }, + "stages": ["prestart"] + } + return config + + +def generate_mpi_hook_config(mpi_type): + config = { + "version": "1.0.0", + "hook": { + "path": os.environ["CMAKE_INSTALL_PREFIX"] + "/bin/mpi_hook", + "env": [] + }, + "when": { + "annotations": { + "^com.hooks.mpi.enabled$": "^true$", + "^com.hooks.mpi.type": f"^{mpi_type}$" + } + }, + "stages": ["prestart"] + } + return config diff --git a/CI/src/integration_tests/test_security_checks.py b/CI/src/integration_tests/test_security_checks.py index 11953c90..0e3d91ab 100644 --- a/CI/src/integration_tests/test_security_checks.py +++ b/CI/src/integration_tests/test_security_checks.py @@ -40,73 +40,87 @@ class TestSecurityChecks(unittest.TestCase): def setUp(self): # To make sure these tests start from a sane default state - self._sarus_foo() + sarus_foo() def tearDown(self): # To make sure these tests are not altering config files permissions - self._sarus_foo() + sarus_foo() def test_untamperable_config(self): - self._check_untamperable(CONFIG_FILENAME) + check_untamperable(CONFIG_FILENAME) def test_untamperable_config_schema(self): - self._check_untamperable(SCHEMA_FILENAME) + check_untamperable(SCHEMA_FILENAME) def test_disabled_security_checks(self): with util.custom_sarus_json({"securityChecks": False}): # some tamperable locations are OK... with changed_owner("/opt/sarus/default/bin/", NONROOT_ID, NONROOT_ID): - self._sarus_foo() + sarus_foo() # but not these two... - self._check_untamperable(CONFIG_FILENAME) - self._check_untamperable(SCHEMA_FILENAME) + check_untamperable(CONFIG_FILENAME) + check_untamperable(SCHEMA_FILENAME) def test_untamperable_binaries(self): - INIT_PATH = self._get_parameter_from_config_file("initPath") - RUNC_PATH = self._get_parameter_from_config_file("runcPath") + init_path = get_parameter_from_config_file("initPath") + runc_path = get_parameter_from_config_file("runcPath") - self._check_untamperable(INIT_PATH) - self._check_untamperable(RUNC_PATH) + check_untamperable(init_path) + check_untamperable(runc_path) - self._check_untamperable("/opt/sarus/default/bin/") + check_untamperable("/opt/sarus/default/bin/") def test_untamperable_hooks_and_deps(self): - # ssh is only default hook enabled - self._check_untamperable("/opt/sarus/default/etc/hooks.d/07-ssh-hook.json") - self._check_untamperable("/opt/sarus/default/bin/ssh_hook") - self._check_untamperable("/opt/sarus/default/dropbear") - - def _get_parameter_from_config_file(self, parameter): - with open(CONFIG_FILENAME) as conf_file: - conf = json.load(conf_file) - return conf[parameter] - - def _sarus_foo(self): - """ - Performs the simplest Sarus action so Security Checks are run. - """ - with open(os.devnull, 'wb') as devnull: - res = subprocess.run(SARUS_FOO_CMD, stdout=devnull, check=True) - assert res.returncode == 0 - - def _check_untamperable(self, path): - if os.path.isdir(path): - entry = path if path[-1] != '/' else path[:-1] - else: - entry = os.path.basename(path) - - with changed_owner(path, NONROOT_ID, NONROOT_ID): - util.assert_sarus_raises_error_containing_text(SARUS_FOO_CMD, - '{}" must be owned by root'.format(entry)) - - with changed_permissions(path, stat.S_IWGRP): - util.assert_sarus_raises_error_containing_text(SARUS_FOO_CMD, - '{}" cannot be group- or world-writable'.format(entry)) - - with changed_permissions(path, stat.S_IWOTH): - util.assert_sarus_raises_error_containing_text(SARUS_FOO_CMD, - '{}" cannot be group- or world-writable'.format(entry)) + hook_config = { + "version": "1.0.0", + "hook": { + "path": os.environ["CMAKE_INSTALL_PREFIX"] + "/bin/timestamp_hook" + }, + "when": { + "always": True + }, + "stages": ["prestart"] + } + hook_config_file = "/opt/sarus/default/etc/hooks.d/00-timestamp-hook.json" + with util.temporary_hook_files((hook_config, hook_config_file)): + check_untamperable(hook_config_file) + check_untamperable("/opt/sarus/default/bin/timestamp_hook") + check_untamperable("/opt/sarus/default/dropbear") + + +def get_parameter_from_config_file(parameter): + with open(CONFIG_FILENAME) as conf_file: + conf = json.load(conf_file) + return conf[parameter] + + +def sarus_foo(): + """ + Performs the simplest Sarus action so Security Checks are run. + """ + with open(os.devnull, 'wb') as devnull: + res = subprocess.run(SARUS_FOO_CMD, stdout=devnull, check=True) + assert res.returncode == 0 + + +def check_untamperable(path): + if os.path.isdir(path): + entry = path if path[-1] != '/' else path[:-1] + else: + entry = os.path.basename(path) + + with changed_owner(path, NONROOT_ID, NONROOT_ID): + util.assert_sarus_raises_error_containing_text(SARUS_FOO_CMD, + '{}" must be owned by root'.format(entry)) + + with changed_permissions(path, stat.S_IWGRP): + util.assert_sarus_raises_error_containing_text(SARUS_FOO_CMD, + '{}" cannot be group- or world-writable'.format(entry)) + + with changed_permissions(path, stat.S_IWOTH): + util.assert_sarus_raises_error_containing_text(SARUS_FOO_CMD, + '{}" cannot be group- or world-writable'.format(entry)) @contextmanager diff --git a/CI/src/integration_tests_for_virtual_cluster/test_ssh_hook.py b/CI/src/integration_tests_for_virtual_cluster/test_ssh_hook.py index 6354c79b..3bf26c83 100755 --- a/CI/src/integration_tests_for_virtual_cluster/test_ssh_hook.py +++ b/CI/src/integration_tests_for_virtual_cluster/test_ssh_hook.py @@ -10,49 +10,119 @@ import os import shutil import subprocess +from contextlib import contextmanager import common.util as util + class TestSshHook(unittest.TestCase): # Run tests in musl-only containers as well as glibc-only containers, in order to make - # sure that the custom OpenSSH injected into the container is standalone (as expected) + # sure that the SSH software injected into the container is standalone (as expected) # and doesn't have any dependency on musl or glibc. It happened in the past that the # custom sshd depended on the NSS dynamic libraries of glibc. image_with_musl = "quay.io/ethcscs/alpine:3.14" image_with_glibc = "quay.io/ethcscs/debian:buster" + SARUS_INSTALL_PATH = os.environ["CMAKE_INSTALL_PREFIX"] + + OCI_HOOKS_CONFIG_FILES = { + "ssh": SARUS_INSTALL_PATH + "/etc/hooks.d/ssh_hook.json", + "slurm_sync": SARUS_INSTALL_PATH + "/etc/hooks.d/slurm_sync_hook.json" + } + + @classmethod + def setUpClass(cls): + cls._pull_docker_images() + cls._get_hooks_base_dir() + + @classmethod + def _pull_docker_images(cls): + util.pull_image_if_necessary(is_centralized_repository=False, image=cls.image_with_musl) + util.pull_image_if_necessary(is_centralized_repository=False, image=cls.image_with_glibc) + + @classmethod + def _get_hooks_base_dir(cls): + import json + with open(util.sarus_json_filename, 'r') as f: + config = json.load(f) + cls.OCI_HOOKS_BASE_DIR = config["localRepositoryBaseDir"] + + @classmethod + def _generate_ssh_hook_config(cls): + hook_config = { + "version": "1.0.0", + "hook": { + "path": f"{cls.SARUS_INSTALL_PATH}/bin/ssh_hook", + "env": [ + f"HOOK_BASE_DIR={cls.OCI_HOOKS_BASE_DIR}", + f"PASSWD_FILE={cls.SARUS_INSTALL_PATH}/etc/passwd", + f"DROPBEAR_DIR={cls.SARUS_INSTALL_PATH}/dropbear", + "SERVER_PORT=15263" + ], + "args": [ + "ssh_hook", + "start-ssh-daemon" + ] + }, + "when": { + "annotations": { + "^com.hooks.ssh.enabled$": "^true$" + } + }, + "stages": ["prestart"] + } + return hook_config + + @classmethod + def _generate_slurm_sync_hook_config(cls): + hook_config = { + "version": "1.0.0", + "hook": { + "path": f"{cls.SARUS_INSTALL_PATH}/bin/slurm_global_sync_hook", + "env": [ + f"HOOK_BASE_DIR={cls.OCI_HOOKS_BASE_DIR}", + f"PASSWD_FILE={cls.SARUS_INSTALL_PATH}/etc/passwd" + ] + }, + "when": { + "annotations": { + "^com.hooks.slurm-global-sync.enabled$": "^true$" + } + }, + "stages": ["prestart"] + } + return hook_config + def test_ssh_hook(self): - util.pull_image_if_necessary(is_centralized_repository=False, image=self.image_with_musl) - util.pull_image_if_necessary(is_centralized_repository=False, image=self.image_with_glibc) - - self._check_ssh_keys_generation() - - # check SSH from node0 to node1 - hostname_node1 = self._get_hostname_of_node1(self.image_with_musl) - hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh(self.image_with_musl, hostname_node1) - self.assertEqual(hostname_node1, hostname_node1_through_ssh) - hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh(self.image_with_glibc, hostname_node1) - self.assertEqual(hostname_node1, hostname_node1_through_ssh) - - # check SSH from node0 to node1 with non-standard $HOME - # in some systems the home from the passwd file (copied from the host) - # might not be present in the container. The hook has to deduce it from - # the passwd file and create it. - self._set_home_in_sarus_passwd_file("/users/test") - hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh(self.image_with_musl, hostname_node1) - self.assertEqual(hostname_node1, hostname_node1_through_ssh) - hostname_node1_through_ssh = self._get_hostname_of_node1_though_ssh(self.image_with_glibc, hostname_node1) - self.assertEqual(hostname_node1, hostname_node1_through_ssh) - self._restore_sarus_passwd_file() - - # check SSH goes into container (not host) - prettyname = self._get_prettyname_of_node1_through_ssh(self.image_with_musl, hostname_node1) - self.assertEqual(prettyname, "Alpine Linux v3.14") - prettyname = self._get_prettyname_of_node1_through_ssh(self.image_with_glibc, hostname_node1) - self.assertEqual(prettyname, "Debian GNU/Linux 10 (buster)") - - def _check_ssh_keys_generation(self): + with util.temporary_hook_files((self._generate_ssh_hook_config(), self.OCI_HOOKS_CONFIG_FILES["ssh"]), + (self._generate_slurm_sync_hook_config(), self.OCI_HOOKS_CONFIG_FILES["slurm_sync"])): + util.generate_ssh_keys() + + # check SSH from node0 to node1 + hostname_node1 = get_hostname_of_node1(self.image_with_musl) + hostname_node1_through_ssh = get_hostname_of_node1_though_ssh(self.image_with_musl, hostname_node1) + self.assertEqual(hostname_node1, hostname_node1_through_ssh) + hostname_node1_through_ssh = get_hostname_of_node1_though_ssh(self.image_with_glibc, hostname_node1) + self.assertEqual(hostname_node1, hostname_node1_through_ssh) + + # check SSH from node0 to node1 with non-standard $HOME + # in some systems the home from the passwd file (copied from the host) + # might not be present in the container. The hook has to deduce it from + # the passwd file and create it. + with custom_home_in_sarus_passwd_file("/users/test"): + hostname_node1_through_ssh = get_hostname_of_node1_though_ssh(self.image_with_musl, hostname_node1) + self.assertEqual(hostname_node1, hostname_node1_through_ssh) + hostname_node1_through_ssh = get_hostname_of_node1_though_ssh(self.image_with_glibc, hostname_node1) + self.assertEqual(hostname_node1, hostname_node1_through_ssh) + + # check SSH goes into container (not host) + prettyname = get_prettyname_of_node1_through_ssh(self.image_with_musl, hostname_node1) + self.assertEqual(prettyname, "Alpine Linux v3.14") + prettyname = get_prettyname_of_node1_through_ssh(self.image_with_glibc, hostname_node1) + self.assertEqual(prettyname, "Debian GNU/Linux 10 (buster)") + + def test_ssh_keys_generation(self): ssh_dir = os.environ['HOME'] + "/.oci-hooks/ssh" fingerprint_command = ["bash", "-c", "find " + ssh_dir + r" -type f -exec sum {} \; | sum"] @@ -73,66 +143,72 @@ def _check_ssh_keys_generation(self): fingerprint_changed = subprocess.check_output(fingerprint_command).decode() self.assertNotEqual(fingerprint, fingerprint_changed) - def _get_hostname_of_node1(self, image): - command = [ - "sh", - "-c", - "[ $SLURM_NODEID -eq 1 ] && echo $(hostname); exit 0" - ] - out = util.run_command_in_container_with_slurm(image=image, - command=command, - options_of_srun_command=["-N2"], - options_of_run_command=["--ssh"]) - assert len(out) == 1 # expect one single line of output - return out[0] - - def _get_hostname_of_node1_though_ssh(self, image, hostname_node1): - command = [ - "sh", - "-c", - "if [ $SLURM_NODEID -eq 0 ]; then" - " echo $(ssh {} hostname);" - " ssh {} touch /done;" - "else" - " while [ ! -e /done ]; do" - " sleep 1;" - " done;" - "fi".format(hostname_node1, hostname_node1) - ] - out = util.run_command_in_container_with_slurm(image=image, - command=command, - options_of_srun_command=["-N2"], - options_of_run_command=["--ssh"]) - assert len(out) == 1 # expect one single line of output - return out[0] - - def _get_prettyname_of_node1_through_ssh(self, image, hostname_node1): - command = [ - "sh", - "-c", - "if [ $SLURM_NODEID -eq 0 ]; then" - " echo $(ssh {} cat /etc/os-release);" - " ssh {} touch /done;" - "else" - " while [ ! -e /done ]; do" - " sleep 1;" - " done;" - "fi".format(hostname_node1, hostname_node1) - ] - out = util.run_command_in_container_with_slurm(image=image, - command=command, - options_of_srun_command=["-N2"], - options_of_run_command=["--ssh"]) - assert len(out) == 1 # expect one single line of output - return re.match(r".*PRETTY_NAME=\"([^\"]+)\" .*", out[0]).group(1) - - def _set_home_in_sarus_passwd_file(self, new_home_directory): + +def get_hostname_of_node1(image): + command = [ + "sh", + "-c", + "[ $SLURM_NODEID -eq 1 ] && echo $(hostname); exit 0" + ] + out = util.run_command_in_container_with_slurm(image=image, + command=command, + options_of_srun_command=["-N2"], + options_of_run_command=["--ssh"]) + assert len(out) == 1 # expect one single line of output + return out[0] + + +def get_hostname_of_node1_though_ssh(image, hostname_node1): + command = [ + "sh", + "-c", + "if [ $SLURM_NODEID -eq 0 ]; then" + " echo $(ssh {} hostname);" + " ssh {} touch /done;" + "else" + " while [ ! -e /done ]; do" + " sleep 1;" + " done;" + "fi".format(hostname_node1, hostname_node1) + ] + out = util.run_command_in_container_with_slurm(image=image, + command=command, + options_of_srun_command=["-N2"], + options_of_run_command=["--ssh"]) + assert len(out) == 1 # expect one single line of output + return out[0] + + +def get_prettyname_of_node1_through_ssh(image, hostname_node1): + command = [ + "sh", + "-c", + "if [ $SLURM_NODEID -eq 0 ]; then" + " echo $(ssh {} cat /etc/os-release);" + " ssh {} touch /done;" + "else" + " while [ ! -e /done ]; do" + " sleep 1;" + " done;" + "fi".format(hostname_node1, hostname_node1) + ] + out = util.run_command_in_container_with_slurm(image=image, + command=command, + options_of_srun_command=["-N2"], + options_of_run_command=["--ssh"]) + assert len(out) == 1 # expect one single line of output + return re.match(r".*PRETTY_NAME=\"([^\"]+)\" .*", out[0]).group(1) + + +@contextmanager +def custom_home_in_sarus_passwd_file(new_home_directory): + try: import getpass - self.saruspwd_filename = os.environ["CMAKE_INSTALL_PREFIX"] + "/etc/passwd" + saruspwd_filename = os.environ["CMAKE_INSTALL_PREFIX"] + "/etc/passwd" # Create backup - subprocess.check_output(["sudo", "cp", self.saruspwd_filename, - self.saruspwd_filename + '.bak']) + subprocess.check_output(["sudo", "cp", saruspwd_filename, + saruspwd_filename + '.bak']) with open('/etc/passwd', 'r') as f: pwdlines = f.readlines() @@ -146,8 +222,9 @@ def _set_home_in_sarus_passwd_file(self, new_home_directory): with open("passwd.dummy", 'w') as f: f.writelines(pwdlines) - subprocess.check_output(["sudo", "cp", "passwd.dummy", self.saruspwd_filename]) + subprocess.check_output(["sudo", "cp", "passwd.dummy", saruspwd_filename]) os.remove("passwd.dummy") + yield - def _restore_sarus_passwd_file(self): - subprocess.check_output(["sudo", "cp", self.saruspwd_filename + '.bak', self.saruspwd_filename]) + finally: + subprocess.check_output(["sudo", "cp", saruspwd_filename + '.bak', saruspwd_filename]) diff --git a/CI/utility_docker_functions.bash b/CI/utility_docker_functions.bash index ae66c45d..43e9ee25 100644 --- a/CI/utility_docker_functions.bash +++ b/CI/utility_docker_functions.bash @@ -131,7 +131,7 @@ sarus-itest-standalone() { _run_cmd_in_container ${image_run} root \ ". /sarus-source/CI/utility_functions.bash && \ install_sarus_from_archive /opt/sarus ${sarus_archive} && \ - run_integration_tests $(_build_dir_container)" + run_integration_tests /opt/sarus/default" fail_on_error "${FUNCNAME}: failed" } @@ -140,6 +140,8 @@ sarus-itest-from-scratch() { echo "${FUNCNAME^^} with:" _print_parameters + local install_dir="/opt/sarus/default" + if [ ${toolchain_file} = "gcc-asan.cmake" ]; then echo "${FUNCNAME}: skipping integration tests (Sarus doesn't work when built with ASan)" return @@ -147,8 +149,8 @@ sarus-itest-from-scratch() { _run_cmd_in_container ${image_run} root \ ". /sarus-source/CI/utility_functions.bash && \ - install_sarus $(_build_dir_container) /opt/sarus/default && \ - run_integration_tests $(_build_dir_container)" + install_sarus $(_build_dir_container) ${install_dir} && \ + run_integration_tests ${install_dir}" fail_on_error "${FUNCNAME}: failed" } @@ -157,6 +159,8 @@ sarus-itest-from-scratch-debug() { echo "${FUNCNAME^^} with:" _print_parameters + local install_dir="/opt/sarus/default" + if [ ${toolchain_file} = "gcc-asan.cmake" ]; then echo "${FUNCNAME}: skipping integration tests (Sarus doesn't work when built with ASan)" return @@ -164,7 +168,7 @@ sarus-itest-from-scratch-debug() { _run_cmd_in_interactive_container ${image_run} root \ ". /sarus-source/CI/utility_functions.bash && \ - install_sarus $(_build_dir_container) /opt/sarus/default && \ + install_sarus $(_build_dir_container) ${install_dir} && \ bash" fail_on_error "${FUNCNAME}: failed" diff --git a/CI/utility_functions.bash b/CI/utility_functions.bash index b9001da5..e7e0ff15 100644 --- a/CI/utility_functions.bash +++ b/CI/utility_functions.bash @@ -159,12 +159,12 @@ install_sarus_from_archive() { sudo ln -s ${sarus_version} default fail_on_error "Failed to install Sarus" - export PATH=/opt/sarus/default/bin:${PATH} - sudo /opt/sarus/default/configure_installation.sh + export PATH=${root_dir}/default/bin:${PATH} + sudo ${root_dir}/default/configure_installation.sh fail_on_error "Failed to install Sarus" - echo "Successfully installed Sarus" + echo "Successfully installed Sarus ${sarus_version} in ${root_dir}/default" cd ${pwd_backup} } @@ -199,20 +199,20 @@ run_unit_tests() { } run_integration_tests() { - local build_dir=$1; shift || error "${FUNCNAME}: missing build_dir argument" + local install_dir=$1; shift || error "${FUNCNAME}: missing install_dir argument" echo "Running integration tests with user=docker" sudo -u docker --login bash -c " - PATH=/opt/sarus/default/bin:\${PATH} PYTHONPATH=/sarus-source/CI/src:\${PYTHONPATH} \ - CMAKE_INSTALL_PREFIX=/opt/sarus/default HOME=/home/docker \ + PATH=${install_dir}/bin:\${PATH} PYTHONPATH=/sarus-source/CI/src:\${PYTHONPATH} \ + CMAKE_INSTALL_PREFIX=${install_dir} HOME=/home/docker \ pytest -v -m 'not asroot' /sarus-source/CI/src/integration_tests/" # TIP: Add -s --last-failed to pytest to get more output from failed tests. fail_on_error "Python integration tests failed" echo "Successfully run integration tests with user=docker" echo "Running integration tests with user=root" sudo --login bash -c " - PATH=/opt/sarus/default/bin:\$PATH PYTHONPATH=/sarus-source/CI/src:\$PYTHONPATH \ - CMAKE_INSTALL_PREFIX=/opt/sarus/default HOME=/home/docker \ + PATH=${install_dir}/bin:\$PATH PYTHONPATH=/sarus-source/CI/src:\$PYTHONPATH \ + CMAKE_INSTALL_PREFIX=${install_dir} HOME=/home/docker \ pytest -v -m asroot /sarus-source/CI/src/integration_tests/" fail_on_error "Python integration tests as root failed" echo "Successfully run integration tests with user=root" diff --git a/etc/CMakeLists.txt b/etc/CMakeLists.txt index 2ef7c767..ff9d94e3 100644 --- a/etc/CMakeLists.txt +++ b/etc/CMakeLists.txt @@ -4,6 +4,5 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/container/nsswitch.conf DESTINATION ${ install(FILES sarus.schema.json hook.schema.json definitions.schema.json DESTINATION ${CMAKE_INSTALL_PREFIX}/etc) install(FILES policy.json DESTINATION ${CMAKE_INSTALL_PREFIX}/etc) install(DIRECTORY templates DESTINATION ${CMAKE_INSTALL_PREFIX}/etc) +install(DIRECTORY DESTINATION ${CMAKE_INSTALL_PREFIX}/etc/hooks.d) -install(FILES templates/hooks.d/07-ssh-hook.json.in DESTINATION ${CMAKE_INSTALL_PREFIX}/etc/hooks.d) -install(FILES templates/hooks.d/09-slurm-global-sync-hook.json.in DESTINATION ${CMAKE_INSTALL_PREFIX}/etc/hooks.d)