def ps(self): if self.ctx.current() != Ctx.CONTAINER: raise k8shError("ps can only be used within a container") remote_host, id = self._container_info() r = RemoteCommand(remote_host) res = r.run_sync(["sudo", "docker", "top", id]) if res != 0: raise k8shError( "Executing docker top on {} exited with error code {}".format( remote_host, res))
def json(self, command: str, admin: bool = False): command += " -o=json" outcome = self.run(command, admin) if outcome.returncode != 0: raise k8shError( "Error running {}: process returned with retcode: {}, error: {}" .format(command, outcome.returncode, outcome.stderr.decode())) try: return json.loads(outcome.stdout.decode()) except Exception as e: raise k8shError("Error decoding json output: {}".format(str(e)))
def tail(self, arg): if self.ctx.current() != Ctx.CONTAINER: raise k8shError("nsenter can only be used within a container") ctl = self._from_ctx() rc = ctl.run_sync("logs {} {} {}".format( arg, self.ctx.get(Ctx.POD), self.ctx.get(Ctx.CONTAINER), )) if rc != 0: raise k8shError("Could not read the logs")
def _cd(self, val: str): if val == "..": try: self.ctx.pop() except k8shError: pass else: cur = self.ctx.current() available = self.context_ls() if val in available: self.ctx.push(val) else: raise k8shError("Could not find {} in {} {}".format( val, cur.name.lower(), self.ctx.get(cur)))
def containers(self) -> Dict[str, Any]: if self.ctx.current().value < Ctx.POD: raise k8shError("Containers can only be listed at pod level.") ctl = self._from_ctx() res = ctl.json("get pods " + self.ctx.get(Ctx.POD)) hostname = res["spec"]["nodeName"] return { "containers": [{ "name": r["name"], "ID": r["containerID"] } for r in res["status"]["containerStatuses"]], "host": hostname, }
def nsenter(self, arg): """ Allows you to execute command from the kubernetes worker inside the container's namespace. You will have to pass the namespaces you want to enter, and the command to execute. """ if self.ctx.current() != Ctx.CONTAINER: raise k8shError("nsenter can only be used within a container") remote_host, id = self._container_info() r = RemoteCommand(remote_host) res = r.run( ["sudo", "docker", "inspect", "-f", "'{{.State.Pid}}'", id]) if res.returncode != 0: raise k8shError( "Error finding the PID of the container: exitcode {}: {}". format(res.returncode, res.stderr.decode())) else: pid = res.stdout.decode().rstrip() cmd = ["sudo", "nsenter", "-t", pid] + shlex.split(arg) res = r.run_sync(cmd) if res != 0: raise k8shError("Command {} exited with return code {}".format( cmd, res))
def do_exec(self, arg): """ Usage: exec <command> Context: container Runs a command **within** the container """ if self.ctx.current() != Ctx.CONTAINER: raise k8shError("nsenter can only be used within a container") ctl = self._from_ctx() # This needs to run with admin privileges. ctl.run_sync( "exec {} -c {} -- {}".format(self.ctx.get(Ctx.POD), self.ctx.get(Ctx.CONTAINER), arg), True, )