def list(self, tool, group, options): """ List all tools from all groups, list tools from a specific group, or list which groups contain a specific tool :param tool: the registered tool name :param group: the group that the tool belongs too """ if tool is not None and group is not None: logger.error("You cannnot specifiy both --group and --name") sys.exit(1) if tool is None and group is None: for p in Path(self.config.rundir).glob("tools-v1-*/*"): # ignore empty directories if p.is_dir(): if next(os.scandir(p), False) is not False: print( "%s:" % str(p.parent).split("tools-v1-")[1], p.name, "[%s]" % ", ".join([x.name for x in Path(p).glob("*")]), ) elif tool: groups = [] for p in Path(self.config.rundir).rglob(f"tools-v1-*/*/{tool}"): group = str(p.parent.parent).split("tools-v1-")[1] if group not in groups: groups.append(group) if len(groups) != 0: print("tool name: %s, groups: %s" % (tool, " ".join(groups))) elif group: for p in Path(self.config.rundir).glob(f"tools-v1-{group}/*"): print(group, p.name, [x.name for x in Path(p).glob("*")])
def gen_tools_group_list(pbench_run): if isinstance(pbench_run, str): pbench_run = pathlib.Path(pbench_run) pbench_run = pathlib.Path(pbench_run) if not pbench_run.exists(): logger.error("pbench run directory %s does not exist", pbench_run) sys.exit(1) print(pbench_run)
def cleanup(config, debug): c = AgentConfig(config) try: initialize(c) (result, errors) = rmtree(c.rundir) if not result: logger.error("\n".join(errors)) sys.exit(result) except Exception as ex: logger.error("Failed to remove %s: %s", c.rundir, ex) sys.exit(1)
def activate(debug, config): c = AgentConfig(config) initialize(c) src = pathlib.Path(config) dest = pathlib.Path(c.installdir, "config", "pbench-agent.cfg") if not dest.exists(): try: shutil.copyfile(src, dest) except Exception as ex: logger.error("Failed to copy %s: %s", src, ex) sys.exit(1)
def ssh(debug, config, keyfile): c = AgentConfig(config) initialize(c) src = pathlib.Path(keyfile) dest = pathlib.Path(c.installdir, "id_rsa") if not dest.exists(): try: shutil.copyfile(src, dest) except Exception as ex: logger.error("Failed to copy ssh key file %s: %s", src, ex) sys.exit(1)
def init_wrapper(config): """Initialize agent envrionment before running a command :param config: a configparser object """ if six.PY2: logger.error("python3 is required, either directly or through SCL") sys.exit(1) pbench_run = pathlib.Path(config.rundir) if pbench_run.exists(): # Its possible to run pbench without root # but check to make sure that the rundir is writable # before we do anything else if os.access(pbench_run, os.W_OK) is not True: logger.error("%s is not writable", pbench_run) sys.exit(1) pbench_tmp = pathlib.Path(pbench_run, "tmp") if not pbench_run.exists(): # the pbench temporary directory is always relative to pbench run pbench_tmp.mkdir(parents=True, exists_ok=True) else: logger.error("the provided pbench run directory %s does not exist.", pbench_run) sys.exit(1) pbench_install_dir = pathlib.Path(config.installdir) if not pbench_install_dir.exists(): logger.error("pbench installation directory %s does not exist", pbench_install_dir) sys.exit(1)
def clear(self, tool, group, remote): """Remove tools that have been registered :param name: Tool that is registered :param goup: Group for the tool to be removed from :param remote: hostname associated with tool """ result = 0 tools_group_dir = verify_tool_group(self.rundir, group) if remote is None: # Look for all the hostnames remote = "*" if tool is None: # Remove all register tools tool = "*" remote_dir = Path(tools_group_dir, remote) tools = self._tools(tools_group_dir, tool, remote) for p in tools: if p.suffix and p.suffix == ".__noinstall__": try: os.unlink(p) except Exception as ex: logger.error("Failed to remove: %s", ex) result = 1 try: os.unlink(p) logger.info( "Removed %s from host, %s, in tools group %s", p.name, remote, tools_group_dir, ) except Exception as ex: logger.error("Failed to clear tool %s: %s", p, ex) result = 1 tool_files = self._tools(tools_group_dir, tool, remote) if "__label__" in tool_files: label = Path(tools_group_dir, f"{tool}/{remote}/__label__") try: os.unlink(label) except Exception as ex: logger.error( "Failed to remove label for remote %s: %s", Path(tools_group_dir, tool, remote), ex, ) result = 1 if len(tool_files) == 0: try: os.rmdir(remote_dir) logger.info("All tools removed from host %s", remote) except Exception as ex: logger.error("Failed to remove remote directory %s: %s", remote_dir, ex) result = 1 sys.exit(result)
def collect(self, name): if name is None: logger.error("Missing argument, need a name for this sysinfo" " collection, either 'beg' or 'end'") sys.exit(1) if name not in ["beg", "end"]: logger.error( "Invalid argument, collection names should be either" "'beg' or 'end' not %s", name, ) sys.exit(1) (sysnfo_path, tool_group_dir) = self._create_sysinfo_dir(name) for group in self.tools.groups: self.dump(name)
def dump(self, name): sysinfo_path = Path(self.sysinfo_dir, socket.gethostname(), name) for item in self.sysinfo.split(","): logger.debug("Collecting %s", item) if item == "kernel_config": self._collect_kernel_config(sysinfo_path) elif item == "security_mitigations": self._collect_mitigation_data(sysinfo_path) elif item == "libvirt": self._collect_libvirt(sysinfo_path) elif item == "topology": self._collect_topology(sysinfo_path) elif item == "block": self._collect_block(sysinfo_path) else: logger.error("bad sysinfo value: %s", item) sys.exit(1) sh.contrib.sudo.chown("-R", 775, sysinfo_path)
def clear(config, debug): c = AgentConfig(config) initialize(c) rundir = pathlib.Path(c.rundir) if rundir.exists(): for path in rundir.glob("*"): if not (path.name.startswith("tmp") or path.name.startswith("tools") or path.name == "pbench.log"): if path.is_file(): try: os.unlink(path) except Exception as ex: logger.error("Failed to remove %s: %s", path, ex) if path.is_dir(): try: shutil.rmtree(path) except Exception as ex: logger.error("Failed to remove %s: %s", path, ex)
def register(self, name, group, no_install, remotes, labels, args): if not name: logger.error("Missing required paramenter --name") sys.exit(1) tool = Path(self.toolsdir, name) if not tool.exists(): logger.error( "Could not find %s in %s: has this tool been " "integrated into pbench-agent?", name, self.toolsdir, ) sys.exit(1) if remotes: if "@" in remotes: # We are delaing with a file container the list of remotes remotes_file = Path(remotes.split("@")[1]) if not remotes_file.exists(): logger.error( "--remotes=@%s specifies a file that doesnt " "exist", remotes_file, ) sys.exit(1) remote = remotes_file.read_text().splitlines() else: remote = remotes.split(",") else: remote = [(socket.gethostname())] tg_dir = verify_tool_group(self.rundir, group) tg_dir.mkdir(parents=True, exist_ok=True) for r in remote: tg_r_dir = Path(tg_dir, r) tg_r_dir.mkdir(parents=True, exist_ok=True) tool_file = Path(tg_r_dir, name) if tool_file.exists(): tool_file.unlink() tool_file.touch() if args: tool_file.write_text(args) install_file = Path(tool_file, f"{name}.__noinstall__") if no_install: if not install_file.exists(): tool_file.symlink_to(install_file) else: if install_file.exists(): install_file.unlink() logger.info("%s is not registered for host(s) %s in %s", name, ",".join(remote), group)
def init_wrapper(config): if six.PY2: logger.error("python3 is not installed") pbench_run = pathlib.Path(config.rundir) if pbench_run.exists(): if os.access(pbench_run, os.W_OK) is not True: logger.error("%s is not writable", pbench_run) sys.exit(1) pbench_tmp = pathlib.Path(pbench_run, "tmp") if not pbench_run.exists(): # the pbench temporary directory is always relative to pbench run pbench_tmp.mkdir(parents=True, exists_ok=True) else: logger.error("the provided pbench run directory %s does not exist.", pbench_run) sys.exit(1) pbench_install_dir = pathlib.Path(config.installdir) if not pbench_install_dir.exists(): logger.error( "pbench installation directory %s does not exist", pbench_install_dir ) sys.exit(1) print(pbench_install_dir)
def register(self, group, start, stop): if not group: logger.error("A look group is required") sys.exit(1) if start is None or stop is None: logger.error("both --start-trigger and --stop-trigger is required") sys.exit(1) if ":" in start: logger.error("the start trigger cannot have a colon in it: %s", start) sys.exit(1) if ":" in stop: logger.error("the stop trigger cannot have a colon in it: %s", stop) sys.exit(1) tg_dir = Path(verify_tool_group(self.rundir, group), "__trigger__") tg_dir.write_text("%s: %s\n", start, stop) logger.info( "tool trigger strings for start: %s and for stop: %s are" "are not registered for tool group: %s", start, stop, group, )
def initialize(config): """Setup the pbench environment before executing a command""" if six.PY2: logger.error("python3 is not installed") sys.exit(1) pbench_run = pathlib.Path(config.rundir) if pbench_run.exists(): if os.access(pbench_run, os.W_OK) is not True: logger.error("%s is not writable", pbench_run) sys.exit(1) pbench_tmp = pathlib.Path(pbench_run, "tmp") if not pbench_tmp.exists(): # the pbench temporary directory is always relative to pbench # run pbench_tmp.mkdir(parents=True, exist_ok=True) else: logger.error("the provided pbench run directory %s does not exist", pbench_run) sys.exit(1)
def process(self, group, benchmark_dir, action): """ """ if group is None: logger.error("ERROR: required tool group paramanter missing") sys.exit(1) if benchmark_dir is None: logger.error("ERROR: required directory argument missing") sys.exit(1) rundir = verify_tool_group(group) if not rundir: sys.exit(1) if action == "kill": logger.error("kill-tools is a no-op and has been deprecated: " "pbench-stop-tools ensure tools are properly cleaned " "up.") sys.exit(1) sh.Command("pbench-tool-meister-client", group, benchmark_dir, action)()
def _create_sysinfo_dir(self, name): self.sysinfo_dir.mkdir(parents=True, exist_ok=True) if not self.sysinfo_dir.exists(): logger.debug("Unable to create working directory, %s", self.sysinfo_dir) if self.sysinfo in ["all", "default", "none"]: pass else: for item in self.sysinfo.split(","): if item in SYSINFO_OPTS_AVAILABLE: continue else: if item in ["all", "default", "none"]: pass else: logger.error("invalid sysinfo option: %s", item) sys.exit(1) sys.exit(1) logger.info("Collecting sysinfo information") tool_group_dir = Path(self.config.rundir, f"tools-{self.group}") if not tool_group_dir.exists(): logger.error("Unble to find defult tools group file: %s", tool_group_dir) sys.exit(1) sysinfo_path = Path(self.sysinfo_dir, socket.gethostname(), name) try: sysinfo_path.mkdir(parents=True) except FileExistsError: logger.error( "Already collection sysinfo-dump data, named: %s" " skipping...", name) sys.exit(0) return (sysinfo_path, tool_group_dir)
def _collect_kernel_config(self, sysinfo_path): try: shutil.copy(f"/boot/config-{os.uname().release}", sysinfo_path) except Exception as ex: logger.error("Failed to copy kernel config: %s", ex)