Fix issues in OpenSSH Runroot method found by real tests.

- Pass the runroot_tag to init command in OpenSSH Runroot method.
  This is needed for the init command as a source for initial packages
  for the buildroot.
- Rename the "runroot_ssh_init_command" to "runroot_ssh_init_template"
  to make it consistent with the rest of "runroot_ssh_*" options.
- Add missing "runroot_ssh_*" options to checks.py.
- Use chmod/chown to `output_dir` in OpenSSH Runroot method the same way
  as it is used in Koji runroot method to make the runroot output readable
  for Pungi user.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
This commit is contained in:
Jan Kaluza 2019-05-03 10:16:46 +02:00
parent 2dd30008ae
commit cfb7b71fca
4 changed files with 55 additions and 13 deletions

View File

@ -914,7 +914,7 @@ Options
architecture on which the runroot task should be running. Format: architecture on which the runroot task should be running. Format:
``{"x86_64": "runroot-x86-64.localhost.tld", ...}`` ``{"x86_64": "runroot-x86-64.localhost.tld", ...}``
**runroot_ssh_init_command** **runroot_ssh_init_template**
(*str*) [optional] -- For ``openssh`` runroot method, defines the command (*str*) [optional] -- For ``openssh`` runroot method, defines the command
to initializes the runroot task on the remote machine. This command is to initializes the runroot task on the remote machine. This command is
executed as first command for each runroot task executed. executed as first command for each runroot task executed.
@ -927,6 +927,11 @@ Options
commands. For example preparing the unique mock environment, mounting the commands. For example preparing the unique mock environment, mounting the
desired file-systems, ... 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. When not set, no init command is executed.
**runroot_ssh_install_packages_template** **runroot_ssh_install_packages_template**
@ -937,12 +942,12 @@ Options
the real values before executing the install command: the real values before executing the install command:
* ``{runroot_key}`` - Replaced with the string returned by * ``{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. of context of SSH commands beloging to single runroot task.
* ``{packages}`` - White-list separated list of packages to install. * ``{packages}`` - White-list separated list of packages to install.
Example (The ``{runroot_key}`` is expected to be set to mock config file 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}"`` ``"mock -r {runroot_key} --install {packages}"``
When not set, no command to install packages on remote machine is executed. 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: the real values before executing the install command:
* ``{runroot_key}`` - Replaced with the string returned by * ``{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. of context of SSH commands beloging to single runroot task.
* ``{command}`` - Command to run. * ``{command}`` - Command to run.
Example (The ``{runroot_key}`` is expected to be set to mock config file 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}"`` ``"mock -r {runroot_key} chroot -- {command}"``
When not set, the runroot command is run directly. When not set, the runroot command is run directly.

View File

@ -573,6 +573,15 @@ def make_schema():
"type": "object", "type": "object",
"default": {}, "default": {},
}, },
"runroot_ssh_init_template": {
"type": "string",
},
"runroot_ssh_install_packages_template": {
"type": "string",
},
"runroot_ssh_run_template": {
"type": "string",
},
"create_jigdo": { "create_jigdo": {
"type": "boolean", "type": "boolean",
"default": True, "default": True,

View File

@ -13,7 +13,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, see <https://gnu.org/licenses/>. # along with this program; if not, see <https://gnu.org/licenses/>.
import os
from six.moves import shlex_quote
import kobo.log import kobo.log
from kobo.shortcuts import run 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] ssh_cmd = ["ssh", "-oBatchMode=yes", "-n", "-l", user, hostname, formatted_cmd]
return run(ssh_cmd, show_cmd=True, logfile=log_file)[1] 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. 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: if arch not in runroot_ssh_hostnames:
raise ValueError("The arch %r not in runroot_ssh_hostnames." % arch) 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] hostname = runroot_ssh_hostnames[arch]
user = self.compose.conf.get("runroot_ssh_username", "root") 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( install_packages_template = self.compose.conf.get(
"runroot_ssh_install_packages_template" "runroot_ssh_install_packages_template"
) )
run_template = self.compose.conf.get("runroot_ssh_run_template") run_template = self.compose.conf.get("runroot_ssh_run_template")
# Init the runroot on remote machine and get the runroot_key. # Init the runroot on remote machine and get the runroot_key.
if init_command: if init_template:
runroot_key = self._ssh_run(hostname, user, init_command, log_file=log_file) 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") runroot_key = runroot_key.rstrip("\n\r")
else: else:
runroot_key = None runroot_key = None

View File

@ -19,7 +19,8 @@ class TestRunrootOpenSSH(helpers.PungiTestCase):
"runroot_ssh_user": "root", "runroot_ssh_user": "root",
"runroot_ssh_hostnames": { "runroot_ssh_hostnames": {
"x86_64": "localhost" "x86_64": "localhost"
} },
"runroot_tag": "f28-build",
}) })
self.runroot = Runroot(self.compose) self.runroot = Runroot(self.compose)
@ -59,7 +60,7 @@ class TestRunrootOpenSSH(helpers.PungiTestCase):
@mock.patch("pungi.runroot.run") @mock.patch("pungi.runroot.run")
def test_run_templates(self, 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"] = \ self.compose.conf["runroot_ssh_install_packages_template"] = \
"install {runroot_key} {packages}" "install {runroot_key} {packages}"
self.compose.conf["runroot_ssh_run_template"] = "run {runroot_key} {command}" 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", self.runroot.run("df -h", log_file="/foo/runroot.log", arch="x86_64",
packages=["lorax", "automake"]) packages=["lorax", "automake"])
run.assert_has_calls([ 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('install key lorax automake'),
self._ssh_call('run key df -h'), self._ssh_call('run key df -h'),
self._ssh_call("run key rpm -qa --qf='%{name}-%{version}-%{release}.%{arch}\n'"), 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 df -h'),
self._ssh_call("run rpm -qa --qf='%{name}-%{version}-%{release}.%{arch}\n'"), 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'"),
])