Add "openssh" runroot method
Merges: https://pagure.io/pungi/pull-request/1166 Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
This commit is contained in:
parent
2f8717ec97
commit
959d6979d4
@ -867,6 +867,10 @@ Options
|
|||||||
Available methods are:
|
Available methods are:
|
||||||
* ``local`` -- runroot tasks are run locally
|
* ``local`` -- runroot tasks are run locally
|
||||||
* ``koji`` -- runroot tasks are run in Koji
|
* ``koji`` -- runroot tasks are run in Koji
|
||||||
|
* ``openssh`` -- runroot tasks are run on remote machine connected using OpenSSH.
|
||||||
|
The ``runroot_ssh_hostnames`` for each architecture must be set and the
|
||||||
|
user under which Pungi runs must be configured to login as ``runroot_ssh_username``
|
||||||
|
using the SSH key.
|
||||||
|
|
||||||
**runroot_channel**
|
**runroot_channel**
|
||||||
(*str*) -- name of koji channel
|
(*str*) -- name of koji channel
|
||||||
@ -885,6 +889,14 @@ Options
|
|||||||
* ``ostree``
|
* ``ostree``
|
||||||
* ``ostree_installer``
|
* ``ostree_installer``
|
||||||
|
|
||||||
|
**runroot_ssh_username**
|
||||||
|
(*str*) -- For ``openssh`` runroot method, configures the username used to login
|
||||||
|
the remote machine to run the runroot task. Defaults to "root".
|
||||||
|
|
||||||
|
**runroot_ssh_hostnames**
|
||||||
|
(*dict*) -- For ``openssh`` runroot method, defines the hostname for each
|
||||||
|
architecture on which the runroot task should be running. Format:
|
||||||
|
``{"x86_64": "runroot-x86-64.localhost.tld", ...}``
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
@ -562,7 +562,15 @@ def make_schema():
|
|||||||
},
|
},
|
||||||
"runroot_method": {
|
"runroot_method": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["local", "koji"],
|
"enum": ["local", "koji", "openssh"],
|
||||||
|
},
|
||||||
|
"runroot_ssh_username": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "root",
|
||||||
|
},
|
||||||
|
"runroot_ssh_hostnames": {
|
||||||
|
"type": "object",
|
||||||
|
"default": {},
|
||||||
},
|
},
|
||||||
"create_jigdo": {
|
"create_jigdo": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
@ -78,10 +78,36 @@ class Runroot(kobo.log.LoggingBase):
|
|||||||
|
|
||||||
output = koji_wrapper.run_runroot_cmd(koji_cmd, log_file=log_file)
|
output = koji_wrapper.run_runroot_cmd(koji_cmd, log_file=log_file)
|
||||||
if output["retcode"] != 0:
|
if output["retcode"] != 0:
|
||||||
raise RuntimeError("Runroot task failed: %s. See %s for more details."
|
raise RuntimeError(
|
||||||
% (output["task_id"], log_file))
|
"Runroot task failed: %s. See %s for more details."
|
||||||
|
% (output["task_id"], log_file)
|
||||||
|
)
|
||||||
self._result = output
|
self._result = output
|
||||||
|
|
||||||
|
def _run_openssh(self, command, log_file=None, arch=None, **kwargs):
|
||||||
|
"""
|
||||||
|
Runs the runroot command on remote machine using ssh.
|
||||||
|
"""
|
||||||
|
runroot_ssh_hostnames = self.compose.conf.get("runroot_ssh_hostnames", {})
|
||||||
|
if arch not in runroot_ssh_hostnames:
|
||||||
|
raise ValueError("The arch %r not in runroot_ssh_hostnames." % arch)
|
||||||
|
|
||||||
|
hostname = runroot_ssh_hostnames[arch]
|
||||||
|
user = self.compose.conf.get("runroot_ssh_username", "root")
|
||||||
|
|
||||||
|
ssh_cmd = ["ssh", "-oBatchMode=yes", "-n", "-l", user, hostname, command]
|
||||||
|
run(ssh_cmd, show_cmd=True, logfile=log_file)
|
||||||
|
|
||||||
|
# Get the buildroot RPMs.
|
||||||
|
ssh_cmd = ["ssh", "-oBatchMode=yes", "-n", "-l", user, hostname,
|
||||||
|
"rpm -qa --qf='%{name}-%{version}-%{release}.%{arch}\n'"]
|
||||||
|
output = run(ssh_cmd, show_cmd=True)[1]
|
||||||
|
self._result = []
|
||||||
|
for i in output.splitlines():
|
||||||
|
if not i:
|
||||||
|
continue
|
||||||
|
self._result.append(i)
|
||||||
|
|
||||||
def run(self, command, log_file=None, packages=None, arch=None,
|
def run(self, command, log_file=None, packages=None, arch=None,
|
||||||
output_dir=None, **kwargs):
|
output_dir=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -112,6 +138,10 @@ class Runroot(kobo.log.LoggingBase):
|
|||||||
self._run_koji(
|
self._run_koji(
|
||||||
command, log_file=log_file, packages=packages, arch=arch,
|
command, log_file=log_file, packages=packages, arch=arch,
|
||||||
output_dir=output_dir, **kwargs)
|
output_dir=output_dir, **kwargs)
|
||||||
|
elif self.runroot_method == "openssh":
|
||||||
|
self._run_openssh(
|
||||||
|
command, log_file=log_file, packages=packages, arch=arch,
|
||||||
|
output_dir=output_dir, **kwargs)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown runroot_method %r." % self.runroot_method)
|
raise ValueError("Unknown runroot_method %r." % self.runroot_method)
|
||||||
|
|
||||||
@ -127,12 +157,17 @@ class Runroot(kobo.log.LoggingBase):
|
|||||||
:return: List of RPMs in buildroot in which the runroot task run.
|
:return: List of RPMs in buildroot in which the runroot task run.
|
||||||
"""
|
"""
|
||||||
if not self._result:
|
if not self._result:
|
||||||
raise ValueError("Runroot.get_build_rpms before runroot task finished.")
|
raise ValueError(
|
||||||
|
"Runroot.get_buildroot_rpms called before runroot task "
|
||||||
|
"finished.")
|
||||||
if self.runroot_method in ["local", "koji"]:
|
if self.runroot_method in ["local", "koji"]:
|
||||||
if self.runroot_method == "local":
|
if self.runroot_method == "local":
|
||||||
task_id = None
|
task_id = None
|
||||||
else:
|
else:
|
||||||
task_id = self._result["task_id"]
|
task_id = self._result["task_id"]
|
||||||
return kojiwrapper.get_buildroot_rpms(self.compose, task_id)
|
return kojiwrapper.get_buildroot_rpms(self.compose, task_id)
|
||||||
|
elif self.runroot_method == "openssh":
|
||||||
|
# For openssh runroot_method, the result is list of buildroot_rpms.
|
||||||
|
return self._result
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unknown runroot_method %r." % self.runroot_method)
|
raise ValueError("Unknown runroot_method %r." % self.runroot_method)
|
||||||
|
52
tests/test_runroot.py
Normal file
52
tests/test_runroot.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import mock
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
||||||
|
|
||||||
|
from pungi.runroot import Runroot
|
||||||
|
from tests import helpers
|
||||||
|
|
||||||
|
|
||||||
|
class TestRunrootOpenSSH(helpers.PungiTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestRunrootOpenSSH, self).setUp()
|
||||||
|
self.compose = helpers.DummyCompose(self.topdir, {
|
||||||
|
"runroot": True,
|
||||||
|
"runroot_method": "openssh",
|
||||||
|
"runroot_ssh_user": "root",
|
||||||
|
"runroot_ssh_hostnames": {
|
||||||
|
"x86_64": "localhost"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
self.runroot = Runroot(self.compose)
|
||||||
|
|
||||||
|
def test_get_runroot_method(self):
|
||||||
|
method = self.runroot.get_runroot_method()
|
||||||
|
self.assertEqual(method, "openssh")
|
||||||
|
|
||||||
|
@mock.patch("pungi.runroot.run")
|
||||||
|
def test_run(self, run):
|
||||||
|
self.runroot.run("df -h", log_file="/foo/runroot.log", arch="x86_64")
|
||||||
|
run.assert_has_calls([
|
||||||
|
mock.call(
|
||||||
|
['ssh', '-oBatchMode=yes', '-n', '-l', 'root', 'localhost',
|
||||||
|
'df -h'], logfile='/foo/runroot.log', show_cmd=True),
|
||||||
|
mock.call(
|
||||||
|
['ssh', '-oBatchMode=yes', '-n', '-l', 'root', 'localhost',
|
||||||
|
"rpm -qa --qf='%{name}-%{version}-%{release}.%{arch}\n'"],
|
||||||
|
show_cmd=True)
|
||||||
|
])
|
||||||
|
|
||||||
|
@mock.patch("pungi.runroot.run")
|
||||||
|
def test_get_buildroot_rpms(self, run):
|
||||||
|
# Run the runroot task at first.
|
||||||
|
run.return_value = (0, "foo-1-1.fc29.noarch\nbar-1-1.fc29.noarch\n")
|
||||||
|
self.runroot.run("df -h", log_file="/foo/runroot.log", arch="x86_64")
|
||||||
|
|
||||||
|
rpms = self.runroot.get_buildroot_rpms()
|
||||||
|
self.assertEqual(
|
||||||
|
set(rpms), set(["foo-1-1.fc29.noarch", "bar-1-1.fc29.noarch"]))
|
Loading…
Reference in New Issue
Block a user