def run(self, connection, max_end_time): # obtain lava overlay # start container # create USB device mapping to container # connect to container, and run lava-test-shell over it location = self.get_namespace_data(action="test", label="shared", key="location") overlay = self.get_namespace_data( action="test", label="results", key="lava_test_results_dir").strip("/") image = self.parameters["docker"]["image"] container = "lava-docker-test-shell-%s-%s" % (self.job.job_id, self.level) board_id = self.get_board_id() device_info = {"board_id": board_id} add_device_container_mapping( job_id=self.job.job_id, device_info=device_info, container=container, container_type="docker", logging_info=self.get_logging_info(), ) docker = DockerRun(image) docker.bind_mount(os.path.join(location, overlay), "/" + overlay) docker.interactive() docker.hostname("lava") docker.name(container) docker.environment("PS1", "docker-test-shell:$ ") if self.wait_for_device: devices = get_udev_devices(device_info=[device_info]) for dev in devices: docker.add_device(dev) docker_cmd = docker.cmdline("bash", "--norc", "-i") cmd = " ".join([shlex.quote(s) for s in docker_cmd]) self.logger.debug("Starting docker test shell container: %s" % cmd) shell = ShellCommand(cmd, self.timeout, logger=self.logger) shell_connection = ShellSession(self.job, shell) shell_connection.prompt_str = "docker-test-shell:" self.__set_connection__(shell_connection) super().run(shell_connection, max_end_time) # finish the container shell_connection.finalise() # return the original connection untouched self.__set_connection__(connection) return connection
def run(self, connection, max_end_time, args=None): connection = super(LxcAddStaticDevices, self).run(connection, max_end_time, args) lxc_name = self.get_namespace_data(action='lxc-create-action', label='lxc', key='name') # If there are no USB devices under static_info then this action should be idempotent. if not self.get_usb_devices(): return connection device_list = get_udev_devices( job=self.job, logger=self.logger, device_info=self.get_usb_devices()) for link in device_list: lxc_cmd = ['lxc-device', '-n', lxc_name, 'add', link] cmd_out = self.run_command(lxc_cmd, allow_silent=True) if not isinstance(cmd_out, bool) and cmd_out: self.logger.debug(cmd_out) return connection
def run(self, connection, max_end_time): connection = super().run(connection, max_end_time) lxc_name = self.get_namespace_data(action='lxc-create-action', label='lxc', key='name') # If there are no USB devices under static_info then this action should be idempotent. if not self.get_usb_devices(): return connection device_list = get_udev_devices(job=self.job, logger=self.logger, device_info=self.get_usb_devices()) for link in device_list: lxc_cmd = ['lxc-device', '-n', lxc_name, 'add', link] cmd_out = self.run_command(lxc_cmd, allow_silent=True) if not isinstance(cmd_out, bool) and cmd_out: self.logger.debug(cmd_out) return connection
def __get_device_nodes__(self): device_info = self.action.job.device.get("device_info", {}) if device_info: return get_udev_devices(device_info=device_info) else: return []
def run(self, connection, max_end_time): # obtain lava overlay # start container # create USB device mapping to container # connect to container, and run lava-test-shell over it location = self.get_namespace_data(action="test", label="shared", key="location") overlay = self.get_namespace_data( action="test", label="results", key="lava_test_results_dir").strip("/") container = "lava-docker-test-shell-%s-%s" % (self.job.job_id, self.level) docker = DockerRun.from_parameters(self.parameters["docker"]) docker.prepare() docker.bind_mount(os.path.join(location, overlay), "/" + overlay) namespace = self.parameters.get("downloads-namespace", self.parameters.get("namespace")) if namespace: downloads_dir = pathlib.Path( self.job.tmp_dir) / "downloads" / namespace if downloads_dir.exists(): docker.bind_mount(downloads_dir, LAVA_DOWNLOADS) for bind_mount in self.test_docker_bind_mounts: read_only = True if len(bind_mount) == 2 else False docker.bind_mount(bind_mount[0], bind_mount[1], read_only) docker.interactive() docker.tty() docker.hostname("lava") docker.name(container) docker.environment("PS1", "docker-test-shell:$ ") docker_cmd = docker.cmdline("bash", "--norc", "-i") cmd = " ".join([shlex.quote(s) for s in docker_cmd]) self.logger.debug("Starting docker test shell container: %s" % cmd) shell = ShellCommand(cmd, self.timeout, logger=self.logger) shell_connection = ShellSession(self.job, shell) shell_connection.prompt_str = "docker-test-shell:" self.__set_connection__(shell_connection) self.add_device_container_mappings(container, "docker") devices = get_udev_devices(device_info=self.device_info, logger=self.logger, required=False) docker.wait() # share all the devices as there isn't a 1:1 relationship between # the trigger and actual sharing of the devices for dev in devices: if not os.path.islink(dev): self.trigger_share_device_with_container(dev) for dev in devices: docker.wait_file(dev) try: super().run(shell_connection, max_end_time) finally: # finish the container shell_connection.finalise() docker.destroy() # return the original connection untouched self.__set_connection__(connection) return connection
def run(self, connection, max_end_time): # obtain lava overlay # start container # create USB device mapping to container # connect to container, and run lava-test-shell over it location = self.get_namespace_data(action="test", label="shared", key="location") overlay = self.get_namespace_data( action="test", label="results", key="lava_test_results_dir").strip("/") container = "lava-docker-test-shell-%s-%s" % (self.job.job_id, self.level) docker = DockerRun.from_parameters(self.parameters["docker"], self.job) docker.prepare() docker.bind_mount(os.path.join(location, overlay), "/" + overlay) docker_method_conf = (self.job.device["actions"].get("test", {}).get( "methods", {}).get("docker", {})) # Preprocess docker option list, to better support partial # overriding of them via device dict: # 1. Filter out None, to make it easier to template # YAML syntactic lists with Jinja2: # '- {{ some_opt_from_device_dict }}' # (if not default, will be set to None). # 2. Flatten sublists, `- ['--opt1', '--opt2']`. def preproc_opts(opts): res = [] for o in opts: if o is None: continue elif isinstance(o, list): res += o else: res.append(o) return res if "global_options" in docker_method_conf: docker.add_docker_options( *preproc_opts(docker_method_conf["global_options"])) if "options" in docker_method_conf: docker.add_docker_run_options( *preproc_opts(docker_method_conf["options"])) namespace = self.parameters.get("downloads-namespace", self.parameters.get("namespace")) if namespace: downloads_dir = pathlib.Path( self.job.tmp_dir) / "downloads" / namespace if downloads_dir.exists(): docker.bind_mount(downloads_dir, LAVA_DOWNLOADS) for bind_mount in self.test_docker_bind_mounts: read_only = True if len(bind_mount) == 2 else False docker.bind_mount(bind_mount[0], bind_mount[1], read_only) docker.interactive() docker.tty() docker.name(container) docker.environment("PS1", "docker-test-shell:$ ") docker_cmd = docker.cmdline("bash", "--norc", "-i") cmd = " ".join([shlex.quote(s) for s in docker_cmd]) self.logger.debug("Starting docker test shell container: %s" % cmd) shell = ShellCommand(cmd, self.timeout, logger=self.logger) shell_connection = ShellSession(self.job, shell) shell_connection.prompt_str = "docker-test-shell:" self.__set_connection__(shell_connection) self.add_device_container_mappings(container, "docker") devices = get_udev_devices(device_info=self.device_info, logger=self.logger, required=False) docker.wait(shell) # share all the devices as there isn't a 1:1 relationship between # the trigger and actual sharing of the devices for dev in devices: if not os.path.islink(dev): self.trigger_share_device_with_container(dev) for dev in devices: docker.wait_file(dev) try: super().run(shell_connection, max_end_time) finally: # finish the container shell_connection.finalise() docker.destroy() # return the original connection untouched self.__set_connection__(connection) return connection