def run_via_binary(self, run_command_instance=None, command=None, volumes=None, additional_opts=None, *args, **kwargs): """ create a container using this image and run it in background; this method is useful to test real user scenarios when users invoke containers using binary :param run_command_instance: instance of DockerRunBuilder :param command: list of str, command to run in the container, examples: - ["ls", "/"] - ["bash", "-c", "ls / | grep bin"] :param volumes: tuple or list of tuples in the form: * `("/path/to/directory", )` * `("/host/path", "/container/path")` * `("/host/path", "/container/path", "mode")` * `(conu.Directory('/host/path'), "/container/path")` (source can be also Directory instance) :param additional_opts: list of str, additional options for `docker run` :return: instance of DockerContainer """ logger.info("run container via binary in background") if (command is not None or additional_opts is not None) and run_command_instance is not None: raise ConuException("run_command_instance and command parameters cannot be passed into method at same time") if run_command_instance is None: command = command or [] additional_opts = additional_opts or [] if (isinstance(command, list) or isinstance(command, tuple) and isinstance(additional_opts, list) or isinstance(additional_opts, tuple)): run_command_instance = DockerRunBuilder(command=command, additional_opts=additional_opts) else: raise ConuException("command and additional_opts needs to be list of str or None") else: run_command_instance = run_command_instance or DockerRunBuilder() if not isinstance(run_command_instance, DockerRunBuilder): raise ConuException("run_command_instance needs to be an instance of DockerRunBuilder") run_command_instance.image_name = self.get_id() run_command_instance.options += ["-d"] if volumes: run_command_instance.options += self.get_volume_options(volumes=volumes) def callback(): try: # FIXME: catch std{out,err}, print stdout to logger.debug, stderr to logger.error run_cmd(run_command_instance.build()) except subprocess.CalledProcessError as ex: raise ConuException("Container exited with an error: %s" % ex.returncode) container_id, _ = self._run_container(run_command_instance, callback) container_name = self.d.inspect_container(container_id)['Name'][1:] return DockerContainer(self, container_id, name=container_name)
def run_via_binary(self, run_command_instance=None, *args, **kwargs): """ create a container using this image and run it in background; this method is useful to test real user scenarios when users invoke containers using binary :param image: instance of Image :param run_command_instance: instance of DockerRunBuilder :return: instance of DockerContainer """ logger.info("run container via binary in background") run_command_instance = run_command_instance or DockerRunBuilder() if not isinstance(run_command_instance, DockerRunBuilder): raise ConuException( "run_command_instance needs to be an instance of DockerRunBuilder" ) run_command_instance.image_name = self.get_id() run_command_instance.options += ["-d"] popen_instance = subprocess.Popen(run_command_instance.build(), stdout=subprocess.PIPE) stdout = popen_instance.communicate()[0].strip().decode("utf-8") if popen_instance.returncode > 0: raise ConuException("Container exited with an error: %s" % popen_instance.returncode) # no error, stdout is the container id return DockerContainer(self, stdout)
def run_via_binary(self, run_command_instance=None, *args, **kwargs): """ create a container using this image and run it in background; this method is useful to test real user scenarios when users invoke containers using binary :param run_command_instance: instance of DockerRunBuilder :return: instance of DockerContainer """ logger.info("run container via binary in background") run_command_instance = run_command_instance or DockerRunBuilder() if not isinstance(run_command_instance, DockerRunBuilder): raise ConuException( "run_command_instance needs to be an instance of DockerRunBuilder" ) run_command_instance.image_name = self.get_id() run_command_instance.options += ["-d"] def callback(): try: # FIXME: catch std{out,err}, print stdout to logger.debug, stderr to logger.error run_cmd(run_command_instance.build()) except subprocess.CalledProcessError as ex: raise ConuException("Container exited with an error: %s" % ex.returncode) container_id, _ = self._run_container(run_command_instance, callback) container_name = self.d.inspect_container(container_id)['Name'][1:] return DockerContainer(self, container_id, name=container_name)
def run_via_binary_in_foreground(self, run_command_instance=None, popen_params=None, container_name=None): """ Create a container using this image and run it in foreground; this method is useful to test real user scenarios when users invoke containers using binary and pass input into the container via STDIN. You are also responsible for: * redirecting STDIN when intending to use container.write_to_stdin afterwards by setting popen_params={"stdin": subprocess.PIPE} during run_via_binary_in_foreground * checking whether the container exited successfully via: container.popen_instance.returncode Please consult the documentation for subprocess python module for best practices on how you should work with instance of Popen :param run_command_instance: instance of DockerRunBuilder :param popen_params: dict, keyword arguments passed to Popen constructor :param container_name: str, pretty container identifier :return: instance of DockerContainer """ logger.info("run container via binary in foreground") run_command_instance = run_command_instance or DockerRunBuilder() if not isinstance(run_command_instance, DockerRunBuilder): raise ConuException( "run_command_instance needs to be an instance of DockerRunBuilder" ) popen_params = popen_params or {} run_command_instance.image_name = self.get_id() if container_name: run_command_instance.options += ["--name", container_name] def callback(): return subprocess.Popen(run_command_instance.build(), **popen_params) container_id, popen_instance = self._run_container( run_command_instance, callback) actual_name = self.d.inspect_container(container_id)['Name'][1:] if container_name and container_name != actual_name: raise ConuException( "Unexpected container name value. Expected = " + str(container_name) + " Actual = " + str(actual_name)) if not container_name: container_name = actual_name return DockerContainer(self, container_id, popen_instance=popen_instance, name=container_name)
def run_via_binary_in_foreground(self, run_command_instance=None, popen_params=None, container_name=None): """ Create a container using this image and run it in foreground; this method is useful to test real user scenarios when users invoke containers using binary and pass input into the container via STDIN. Please bear in mind that conu doesn't know the ID of the container when created like this, so it's highly recommended to name your container. You are also responsible for checking whether the container exited successfully via: container.popen_instance.returncode Please consult the documentation for subprocess python module for best practices on how you should work with instance of Popen :param run_command_instance: instance of DockerRunBuilder :param popen_params: dict, keyword arguments passed to Popen constructor :param container_name: str, pretty container identifier :return: instance of DockerContainer """ logger.info("run container via binary in foreground") run_command_instance = run_command_instance or DockerRunBuilder() if not isinstance(run_command_instance, DockerRunBuilder): raise ConuException( "run_command_instance needs to be an instance of DockerRunBuilder" ) popen_params = popen_params or {} run_command_instance.image_name = self.get_id() if container_name: run_command_instance.options += ["--name", container_name] logger.debug("command = %s", str(run_command_instance)) popen_instance = subprocess.Popen(run_command_instance.build(), **popen_params) container_id = None return DockerContainer(self, container_id, popen_instance=popen_instance, name=container_name)
def has_pkgs_signed_with(self, allowed_keys): """ Check signature of packages installed in image. Raises exception when * rpm binary is not installed in image * parsing of rpm fails * there are packages in image that are not signed with one of allowed keys :param allowed_keys: list of allowed keys :return: bool """ if not allowed_keys or not isinstance(allowed_keys, list): raise ConuException("allowed_keys must be a list") drb = DockerRunBuilder( command=['rpm', '-qa', '--qf', '%{name} %{SIGPGP:pgpsig}\n']) cont = self.run_via_binary(drb) try: out = cont.logs_unicode()[:-1].split('\n') check_signatures(out, allowed_keys) finally: cont.stop() cont.delete() return True
def run_via_binary_in_foreground( self, run_command_instance=None, command=None, volumes=None, additional_opts=None, popen_params=None, container_name=None): """ Create a container using this image and run it in foreground; this method is useful to test real user scenarios when users invoke containers using binary and pass input into the container via STDIN. You are also responsible for: * redirecting STDIN when intending to use container.write_to_stdin afterwards by setting popen_params={"stdin": subprocess.PIPE} during run_via_binary_in_foreground * checking whether the container exited successfully via: container.popen_instance.returncode Please consult the documentation for subprocess python module for best practices on how you should work with instance of Popen :param run_command_instance: instance of DockerRunBuilder :param command: list of str, command to run in the container, examples: - ["ls", "/"] - ["bash", "-c", "ls / | grep bin"] :param volumes: tuple or list of tuples in the form: * `("/path/to/directory", )` * `("/host/path", "/container/path")` * `("/host/path", "/container/path", "mode")` * `(conu.Directory('/host/path'), "/container/path")` (source can be also Directory instance) :param additional_opts: list of str, additional options for `docker run` :param popen_params: dict, keyword arguments passed to Popen constructor :param container_name: str, pretty container identifier :return: instance of DockerContainer """ logger.info("run container via binary in foreground") if (command is not None or additional_opts is not None) \ and run_command_instance is not None: raise ConuException( "run_command_instance and command parameters cannot be " "passed into method at same time") if run_command_instance is None: command = command or [] additional_opts = additional_opts or [] if (isinstance(command, list) or isinstance(command, tuple) and isinstance(additional_opts, list) or isinstance(additional_opts, tuple)): run_command_instance = DockerRunBuilder( command=command, additional_opts=additional_opts) else: raise ConuException("command and additional_opts needs to be list of str or None") else: run_command_instance = run_command_instance or DockerRunBuilder() if not isinstance(run_command_instance, DockerRunBuilder): raise ConuException("run_command_instance needs to be an " "instance of DockerRunBuilder") popen_params = popen_params or {} run_command_instance.image_name = self.get_id() if container_name: run_command_instance.options += ["--name", container_name] if volumes: run_command_instance.options += self.get_volume_options(volumes=volumes) def callback(): return subprocess.Popen(run_command_instance.build(), **popen_params) container_id, popen_instance = self._run_container(run_command_instance, callback) actual_name = self.d.inspect_container(container_id)['Name'][1:] if container_name and container_name != actual_name: raise ConuException( "Unexpected container name value. Expected = " + str(container_name) + " Actual = " + str(actual_name)) if not container_name: container_name = actual_name return DockerContainer( self, container_id, popen_instance=popen_instance, name=container_name)
def setup_class(cls): cls.backend = DockerBackend().__enter__() cls.image = cls.backend.ImageClass(FEDORA_MINIMAL_REPOSITORY, tag=FEDORA_MINIMAL_REPOSITORY_TAG) cls.container = cls.image.run_via_binary( DockerRunBuilder(command=["sleep", "infinity"]))
def setup_class(cls): cls.image = DockerImage(FEDORA_MINIMAL_REPOSITORY, tag=FEDORA_MINIMAL_REPOSITORY_TAG) cls.container = cls.image.run_via_binary( DockerRunBuilder(command=["sleep", "infinity"])) cls.containers_to_remove.append(cls.container.get_id())