From b1320b18ff97cb37e5402e6075b548b0a87eb139 Mon Sep 17 00:00:00 2001 From: Jakub Kadlcik Date: Thu, 26 Sep 2024 06:23:06 +0200 Subject: [PATCH] rpmbuild, frontend: activate Red Hat subscription on demand Fix #2132 --- .../coprs/views/backend_ns/backend_general.py | 6 ++- rpmbuild/copr_rpmbuild/helpers.py | 5 ++- rpmbuild/copr_rpmbuild/rhsm.py | 41 +++++++++++++++++++ rpmbuild/main.py | 4 ++ 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 rpmbuild/copr_rpmbuild/rhsm.py diff --git a/frontend/coprs_frontend/coprs/views/backend_ns/backend_general.py b/frontend/coprs_frontend/coprs/views/backend_ns/backend_general.py index 0cd94058a..cf6ad7c52 100755 --- a/frontend/coprs_frontend/coprs/views/backend_ns/backend_general.py +++ b/frontend/coprs_frontend/coprs/views/backend_ns/backend_general.py @@ -143,7 +143,11 @@ def get_build_record(task, for_backend=False): "sandbox": task.build.sandbox, "background": bool(task.build.is_background), "chroot": task.mock_chroot.name, - "tags": task.mock_chroot.tags + task.tags, + "tags": task.mock_chroot.tags + task.tags + ( + # TODO just for testing purposes, add a boolean + # `models.MockChroot.subscription` column to the database? + ["subscription"] if task.mock_chroot.name == "rhel-9-x86_64" else [] + ), "allow_user_ssh": bool(task.build.ssh_public_keys), } diff --git a/rpmbuild/copr_rpmbuild/helpers.py b/rpmbuild/copr_rpmbuild/helpers.py index 8ff30b0b9..af207c041 100644 --- a/rpmbuild/copr_rpmbuild/helpers.py +++ b/rpmbuild/copr_rpmbuild/helpers.py @@ -38,7 +38,7 @@ def cmd_readable(cmd): return ' '.join([shlex.quote(part) for part in cmd]) -def run_cmd(cmd, cwd=".", preexec_fn=None, env=None): +def run_cmd(cmd, cwd=".", preexec_fn=None, env=None, timeout=None): """ Runs given command in a subprocess. @@ -46,6 +46,7 @@ def run_cmd(cmd, cwd=".", preexec_fn=None, env=None): :param str cwd: In which directory to execute the command :param func preexec_fn: a callback invoked before exec in subprocess :param dict env: environment variables to set for process + :param int timeout: passed down to Popen.communicate() :raises RuntimeError :returns munch.Munch(cmd, stdout, stderr, returncode) @@ -55,7 +56,7 @@ def run_cmd(cmd, cwd=".", preexec_fn=None, env=None): try: process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd, preexec_fn=preexec_fn, env=env) - (stdout, stderr) = process.communicate() + (stdout, stderr) = process.communicate(timeout=timeout) except OSError as e: if e.errno == errno.ENOENT: raise RuntimeError( diff --git a/rpmbuild/copr_rpmbuild/rhsm.py b/rpmbuild/copr_rpmbuild/rhsm.py new file mode 100644 index 000000000..0cde9c4ac --- /dev/null +++ b/rpmbuild/copr_rpmbuild/rhsm.py @@ -0,0 +1,41 @@ +""" +Red Hat Subscription Management + +Activating Red Hat subscription may take a lot of time and historically, the +subscription service used to be unreliable, so we should activate the +subscription only when necessary. +""" + +import os +import shlex +from copr_rpmbuild.helpers import run_cmd + + +def activate_subscription(): + """ + Activate Red Hat Subscription. + """ + pool = "8a85f9a17c71102f017ce611251c770f" + user = "copr-team" + # TODO Not sure where to store this password so that it is not readable from + # the builder (we give SSH access to users, so it cannot be in ENV) + password = "TODO" + name = os.environ.get("RESALLOC_NAME", "unknown-builder") + system = name.replace("_", "-") + timeout = 200 + + cmd = [ + "/usr/local/bin/copr-rh-subscribe.sh", + "--pool-id", pool, + "--user", user, + "--pass", shlex.quote(password), + "--system", shlex.quote(system), + ] + run_cmd(cmd, timeout=timeout) + + +def subscription_required(task): + """ + Is subscription required for this task? + """ + return "subscription" in task["tags"] diff --git a/rpmbuild/main.py b/rpmbuild/main.py index ab4edb2d3..d00bd95c1 100755 --- a/rpmbuild/main.py +++ b/rpmbuild/main.py @@ -25,6 +25,7 @@ locate_srpm, package_version, ) +from copr_rpmbuild.rhsm import subscription_required, activate_subscription from six.moves.urllib.parse import urlparse, urljoin, urlencode log = logging.getLogger(__name__) @@ -256,6 +257,9 @@ def build_rpm(args, config): task = get_task(args, config, build_config_url_path, task_id) log_task(task) + if subscription_required(task): + activate_subscription() + try: source_json = { "clone_url": task["git_repo"],