]> git.apps.os.sepia.ceph.com Git - teuthology.git/commitdiff
task/kernel: parallelize per-role work 1692/head
authorSage Weil <sage@newdream.net>
Mon, 8 Nov 2021 19:39:00 +0000 (13:39 -0600)
committerSage Weil <sage@newdream.net>
Fri, 12 Nov 2021 23:06:09 +0000 (17:06 -0600)
Signed-off-by: Sage Weil <sage@newdream.net>
teuthology/task/kernel.py

index fdc902ba7c0405f4ed69385600aee4f31b6fdd23..65fdaca7d85b1751c702309ce3cf95eec868a986 100644 (file)
@@ -694,14 +694,14 @@ def wait_for_reboot(ctx, need_install, timeout, config, distro=False):
     time.sleep(30)
     starttime = time.time()
     while need_install:
-        teuthology.reconnect(ctx, timeout)
         for client in list(need_install.keys()):
             if 'distro' in str(need_install[client]):
                  distro = True
             log.info('Checking client {client} for new kernel version...'.format(client=client))
             try:
+                (remote,) = ctx.cluster.only(client).remotes.keys()
+                remote.reconnect(timeout=timeout)
                 if distro:
-                    (remote,) = ctx.cluster.only(client).remotes.keys()
                     assert not need_to_install_distro(remote, config[client]), \
                             'failed to install new distro kernel version within timeout'
 
@@ -1230,105 +1230,109 @@ def task(ctx, config):
     validate_config(ctx, config)
     log.info('config %s, timeout %d' % (config, timeout))
 
-    need_install = {}  # sha1 to dl, or path to rpm or deb
-    need_version = {}  # utsrelease or sha1
-    kdb = {}
-
-    for role, role_config in config.items():
-        # gather information about this remote
-        (role_remote,) = ctx.cluster.only(role).remotes.keys()
-        system_type = role_remote.os.name
-        if role_config.get('rpm') or role_config.get('deb'):
-            # We only care about path - deb: vs rpm: is meaningless,
-            # rpm: just happens to be parsed first.  Nothing is stopping
-            # 'deb: /path/to/foo.rpm' and it will work provided remote's
-            # os.package_type is 'rpm' and vice versa.
-            path = role_config.get('rpm')
-            if not path:
-                path = role_config.get('deb')
-            sha1 = get_sha1_from_pkg_name(path)
-            assert sha1, "failed to extract commit hash from path %s" % path
-            if need_to_install(ctx, role, sha1):
-                need_install[role] = path
-                need_version[role] = sha1
-        elif role_config.get('sha1') == 'distro':
-            version = need_to_install_distro(role_remote, role_config)
-            if version:
-                need_install[role] = 'distro'
-                need_version[role] = version
-        elif role_config.get("koji") or role_config.get('koji_task'):
-            # installing a kernel from koji
-            build_id = role_config.get("koji")
-            task_id = role_config.get("koji_task")
-            if role_remote.os.package_type != "rpm":
-                msg = (
-                    "Installing a kernel from koji is only supported "
-                    "on rpm based systems. System type is {system_type}."
-                )
-                msg = msg.format(system_type=system_type)
-                log.error(msg)
-                ctx.summary["failure_reason"] = msg
-                ctx.summary["status"] = "dead"
-                raise ConfigError(msg)
-
-            # FIXME: this install should probably happen somewhere else
-            # but I'm not sure where, so we'll leave it here for now.
-            install_package('koji', role_remote)
-
-            if build_id:
-                # get information about this build from koji
-                build_info = get_koji_build_info(build_id, role_remote, ctx)
-                version = "{ver}-{rel}.x86_64".format(
-                    ver=build_info["version"],
-                    rel=build_info["release"]
-                )
-            elif task_id:
-                # get information about results of this task from koji
-                task_result = get_koji_task_result(task_id, role_remote, ctx)
-                # this is not really 'build_info', it's a dict of information
-                # about the kernel rpm from the task results, but for the sake
-                # of reusing the code below I'll still call it that.
-                build_info = get_koji_task_rpm_info(
-                    'kernel',
-                    task_result['rpms']
-                )
-                # add task_id so we can know later that we're installing
-                # from a task and not a build.
-                build_info["task_id"] = task_id
-                version = build_info["version"]
-
-            if need_to_install(ctx, role, version):
-                need_install[role] = build_info
-                need_version[role] = version
-        else:
-            builder = get_builder_project()(
-                "kernel",
-                role_config,
-                ctx=ctx,
-                remote=role_remote,
+    with parallel() as p:
+        for role, role_config in config.items():
+            p.spawn(process_role, ctx, config, timeout, role, role_config)
+
+
+def process_role(ctx, config, timeout, role, role_config):
+    need_install = None  # sha1 to dl, or path to rpm or deb
+    need_version = None  # utsrelease or sha1
+
+    # gather information about this remote
+    (role_remote,) = ctx.cluster.only(role).remotes.keys()
+    system_type = role_remote.os.name
+    if role_config.get('rpm') or role_config.get('deb'):
+        # We only care about path - deb: vs rpm: is meaningless,
+        # rpm: just happens to be parsed first.  Nothing is stopping
+        # 'deb: /path/to/foo.rpm' and it will work provided remote's
+        # os.package_type is 'rpm' and vice versa.
+        path = role_config.get('rpm')
+        if not path:
+            path = role_config.get('deb')
+        sha1 = get_sha1_from_pkg_name(path)
+        assert sha1, "failed to extract commit hash from path %s" % path
+        if need_to_install(ctx, role, sha1):
+            need_install = path
+            need_version = sha1
+    elif role_config.get('sha1') == 'distro':
+        version = need_to_install_distro(role_remote, role_config)
+        if version:
+            need_install = 'distro'
+            need_version = version
+    elif role_config.get("koji") or role_config.get('koji_task'):
+        # installing a kernel from koji
+        build_id = role_config.get("koji")
+        task_id = role_config.get("koji_task")
+        if role_remote.os.package_type != "rpm":
+            msg = (
+                "Installing a kernel from koji is only supported "
+                "on rpm based systems. System type is {system_type}."
             )
-            sha1 = builder.sha1
-            log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
-            ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1
-
-            if need_to_install(ctx, role, sha1):
-                if teuth_config.use_shaman:
-                    version = builder.scm_version
-                else:
-                    version = builder.version
-                if not version:
-                    raise VersionNotFoundError(builder.base_url)
-                need_install[role] = sha1
-                need_version[role] = version
+            msg = msg.format(system_type=system_type)
+            log.error(msg)
+            ctx.summary["failure_reason"] = msg
+            ctx.summary["status"] = "dead"
+            raise ConfigError(msg)
+
+        # FIXME: this install should probably happen somewhere else
+        # but I'm not sure where, so we'll leave it here for now.
+        install_package('koji', role_remote)
+
+        if build_id:
+            # get information about this build from koji
+            build_info = get_koji_build_info(build_id, role_remote, ctx)
+            version = "{ver}-{rel}.x86_64".format(
+                ver=build_info["version"],
+                rel=build_info["release"]
+            )
+        elif task_id:
+            # get information about results of this task from koji
+            task_result = get_koji_task_result(task_id, role_remote, ctx)
+            # this is not really 'build_info', it's a dict of information
+            # about the kernel rpm from the task results, but for the sake
+            # of reusing the code below I'll still call it that.
+            build_info = get_koji_task_rpm_info(
+                'kernel',
+                task_result['rpms']
+            )
+            # add task_id so we can know later that we're installing
+            # from a task and not a build.
+            build_info["task_id"] = task_id
+            version = build_info["version"]
+
+        if need_to_install(ctx, role, version):
+            need_install = build_info
+            need_version = version
+    else:
+        builder = get_builder_project()(
+            "kernel",
+            role_config,
+            ctx=ctx,
+            remote=role_remote,
+        )
+        sha1 = builder.sha1
+        log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
+        ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1
 
-        # enable or disable kdb if specified, otherwise do not touch
-        if role_config.get('kdb') is not None:
-            kdb[role] = role_config.get('kdb')
+        if need_to_install(ctx, role, sha1):
+            if teuth_config.use_shaman:
+                version = builder.scm_version
+            else:
+                version = builder.version
+            if not version:
+                raise VersionNotFoundError(builder.base_url)
+            need_install = sha1
+            need_version = version
 
     if need_install:
-        install_firmware(ctx, need_install)
-        download_kernel(ctx, need_install)
-        install_and_reboot(ctx, need_install, config)
-        wait_for_reboot(ctx, need_version, timeout, config)
-
-    enable_disable_kdb(ctx, kdb)
+        install_firmware(ctx, {role: need_install})
+        download_kernel(ctx, {role: need_install})
+        install_and_reboot(ctx, {role: need_install}, config)
+        wait_for_reboot(ctx, {role: need_version}, timeout, config)
+
+    # enable or disable kdb if specified, otherwise do not touch
+    if role_config.get('kdb') is not None:
+        kdb = role_config.get('kdb')
+        enable_disable_kdb(ctx, {role: kdb})
+