diff --git a/doc/configuration.rst b/doc/configuration.rst index b2bd809f..612fe41a 100644 --- a/doc/configuration.rst +++ b/doc/configuration.rst @@ -914,7 +914,7 @@ Options architecture on which the runroot task should be running. Format: ``{"x86_64": "runroot-x86-64.localhost.tld", ...}`` -**runroot_ssh_init_command** +**runroot_ssh_init_template** (*str*) [optional] -- For ``openssh`` runroot method, defines the command to initializes the runroot task on the remote machine. This command is executed as first command for each runroot task executed. @@ -927,6 +927,11 @@ Options commands. For example preparing the unique mock environment, mounting the desired file-systems, ... + The command string can contain following variables which are replaced by + the real values before executing the init command: + + * ``{runroot_tag}`` - Tag to initialize the runroot environment from. + When not set, no init command is executed. **runroot_ssh_install_packages_template** @@ -937,12 +942,12 @@ Options the real values before executing the install command: * ``{runroot_key}`` - Replaced with the string returned by - ``runroot_ssh_init_command`` if used. This can be used to keep the track + ``runroot_ssh_init_template`` if used. This can be used to keep the track of context of SSH commands beloging to single runroot task. * ``{packages}`` - White-list separated list of packages to install. Example (The ``{runroot_key}`` is expected to be set to mock config file - using the ``runroot_ssh_init_command`` command.): + using the ``runroot_ssh_init_template`` command.): ``"mock -r {runroot_key} --install {packages}"`` When not set, no command to install packages on remote machine is executed. @@ -955,12 +960,12 @@ Options the real values before executing the install command: * ``{runroot_key}`` - Replaced with the string returned by - ``runroot_ssh_init_command`` if used. This can be used to keep the track + ``runroot_ssh_init_template`` if used. This can be used to keep the track of context of SSH commands beloging to single runroot task. * ``{command}`` - Command to run. Example (The ``{runroot_key}`` is expected to be set to mock config file - using the ``runroot_ssh_init_command`` command.): + using the ``runroot_ssh_init_template`` command.): ``"mock -r {runroot_key} chroot -- {command}"`` When not set, the runroot command is run directly. diff --git a/pungi/checks.py b/pungi/checks.py index 2f9478de..521d71c6 100644 --- a/pungi/checks.py +++ b/pungi/checks.py @@ -573,6 +573,15 @@ def make_schema(): "type": "object", "default": {}, }, + "runroot_ssh_init_template": { + "type": "string", + }, + "runroot_ssh_install_packages_template": { + "type": "string", + }, + "runroot_ssh_run_template": { + "type": "string", + }, "create_jigdo": { "type": "boolean", "default": True, diff --git a/pungi/runroot.py b/pungi/runroot.py index 2b5f6292..25c804b7 100644 --- a/pungi/runroot.py +++ b/pungi/runroot.py @@ -13,7 +13,8 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, see . - +import os +from six.moves import shlex_quote import kobo.log from kobo.shortcuts import run @@ -100,7 +101,8 @@ class Runroot(kobo.log.LoggingBase): ssh_cmd = ["ssh", "-oBatchMode=yes", "-n", "-l", user, hostname, formatted_cmd] return run(ssh_cmd, show_cmd=True, logfile=log_file)[1] - def _run_openssh(self, command, log_file=None, arch=None, packages=None, **kwargs): + def _run_openssh(self, command, log_file=None, arch=None, packages=None, + output_dir=None, **kwargs): """ Runs the runroot command on remote machine using ssh. """ @@ -108,17 +110,28 @@ class Runroot(kobo.log.LoggingBase): if arch not in runroot_ssh_hostnames: raise ValueError("The arch %r not in runroot_ssh_hostnames." % arch) + # If the output dir is defined, change the permissions of files generated + # by the runroot task, so the Pungi user can access them. + if output_dir: + # Make the files world readable + command += " && chmod -R a+r %s" % shlex_quote(output_dir) + # and owned by the same user that is running the process + command += " && chown -R %d %s" % (os.getuid(), shlex_quote(output_dir)) + hostname = runroot_ssh_hostnames[arch] user = self.compose.conf.get("runroot_ssh_username", "root") - init_command = self.compose.conf.get("runroot_ssh_init_command") + runroot_tag = self.compose.conf["runroot_tag"] + init_template = self.compose.conf.get("runroot_ssh_init_template") install_packages_template = self.compose.conf.get( "runroot_ssh_install_packages_template" ) run_template = self.compose.conf.get("runroot_ssh_run_template") # Init the runroot on remote machine and get the runroot_key. - if init_command: - runroot_key = self._ssh_run(hostname, user, init_command, log_file=log_file) + if init_template: + fmt_dict = {"runroot_tag": runroot_tag} + runroot_key = self._ssh_run( + hostname, user, init_template, fmt_dict, log_file=log_file) runroot_key = runroot_key.rstrip("\n\r") else: runroot_key = None diff --git a/tests/test_runroot.py b/tests/test_runroot.py index b8016f24..6615419a 100644 --- a/tests/test_runroot.py +++ b/tests/test_runroot.py @@ -19,7 +19,8 @@ class TestRunrootOpenSSH(helpers.PungiTestCase): "runroot_ssh_user": "root", "runroot_ssh_hostnames": { "x86_64": "localhost" - } + }, + "runroot_tag": "f28-build", }) self.runroot = Runroot(self.compose) @@ -59,7 +60,7 @@ class TestRunrootOpenSSH(helpers.PungiTestCase): @mock.patch("pungi.runroot.run") def test_run_templates(self, run): - self.compose.conf["runroot_ssh_init_command"] = "/usr/sbin/init_runroot" + self.compose.conf["runroot_ssh_init_template"] = "/usr/sbin/init_runroot {runroot_tag}" self.compose.conf["runroot_ssh_install_packages_template"] = \ "install {runroot_key} {packages}" self.compose.conf["runroot_ssh_run_template"] = "run {runroot_key} {command}" @@ -68,7 +69,7 @@ class TestRunrootOpenSSH(helpers.PungiTestCase): self.runroot.run("df -h", log_file="/foo/runroot.log", arch="x86_64", packages=["lorax", "automake"]) run.assert_has_calls([ - self._ssh_call('/usr/sbin/init_runroot'), + self._ssh_call('/usr/sbin/init_runroot f28-build'), self._ssh_call('install key lorax automake'), self._ssh_call('run key df -h'), self._ssh_call("run key rpm -qa --qf='%{name}-%{version}-%{release}.%{arch}\n'"), @@ -113,3 +114,17 @@ class TestRunrootOpenSSH(helpers.PungiTestCase): self._ssh_call('run df -h'), self._ssh_call("run rpm -qa --qf='%{name}-%{version}-%{release}.%{arch}\n'"), ]) + + @mock.patch("pungi.runroot.run") + def test_run_templates_output_dir(self, run): + self.compose.conf["runroot_ssh_run_template"] = "run {command}" + + run.return_value = (0, "key\n") + self.runroot.run("df -h", log_file="/foo/runroot.log", arch="x86_64", + packages=["lorax", "automake"], output_dir="/mnt/foo/compose") + run.assert_has_calls([ + self._ssh_call( + 'run df -h && chmod -R a+r /mnt/foo/compose && ' + 'chown -R %d /mnt/foo/compose' % os.getuid()), + self._ssh_call("run rpm -qa --qf='%{name}-%{version}-%{release}.%{arch}\n'"), + ])