def deploy_image(self, image_name, oc_new_app_args, project, name=None): """ Deploy image in OpenShift cluster using 'oc new-app' :param image_name: image name with tag :param oc_new_app_args: additional parameters for the `oc new-app`, env variables etc. :param project: project where app should be created :param name:str, name of application, if None random name is generated :return: str, name of the app """ self.project = project # app name is generated randomly name = name or 'app-{random_string}'.format( random_string=random_str(5)) oc_new_app_args = oc_new_app_args or [] new_image = self.import_image(image_name.split('/')[-1], image_name) c = self._oc_command(["new-app"] + oc_new_app_args + [new_image] + ["-n"] + [project] + ["--name=%s" % name]) logger.info("Creating new app in project %s", project) try: run_cmd(c) except subprocess.CalledProcessError as ex: raise ConuException("oc new-app failed: %s" % ex) return name
def run_via_binary(self, command=None, foreground=False, volumes=None, additional_opts=None, default_options=None, name=None, *args, **kwargs): """ Create new instance NspawnContianer in case of not running at foreground, in case foreground run, return process object :param command: list - command to run :param foreground: bool - run process at foreground :param volumes: list - put additional bind mounts :param additional_opts: list of more boot options for systemd-nspawn command :param default_options: default boot option (-b) :param name: str - name of running instance :param args: pass thru params to subprocess.Popen :param kwargs: pass thru params to subprocess.Popen :return: process or NspawnContianer instance """ command = deepcopy(command) or [] volumes = deepcopy(volumes) or [] additional_opts = deepcopy(additional_opts) or [] internalkw = deepcopy(kwargs) or {} inernalargs = deepcopy(args) or [] if default_options is None: default_options = ["-b"] # TODO: reconsile parameters (changed from API definition) logger.info("run container via binary in background") machine_name = constants.CONU_ARTIFACT_TAG if name: machine_name += name else: machine_name += random_str() if not foreground: # WARN: avoid to run boot without stderr and stdout to terminal, it breaks terminal, # it systemd-nspawn does some magic with console # TODO: is able to avoid this behaviour in better way? internalkw["stdout"] = subprocess.PIPE internalkw["stderr"] = subprocess.PIPE additional_opts += default_options if volumes: additional_opts += self.get_volume_options(volumes=volumes) logger.debug("starting NSPAWN") systemd_command = [ "systemd-nspawn", "--machine", machine_name, "-i", self.local_location] + additional_opts + command logger.debug("Start command: %s" % " ".join(systemd_command)) callback_method = (subprocess.Popen, systemd_command, inernalargs, internalkw) self.container_process = NspawnContainer.internal_run_container( name=machine_name, callback_method=callback_method, foreground=foreground ) if foreground: return self.container_process else: return NspawnContainer(self, None, name=machine_name, start_process=self.container_process, start_action=callback_method)
def create_new_app_from_source(self, image, project, source=None, oc_new_app_args=None): """ Deploy app using source-to-image in OpenShift cluster using 'oc new-app' :param image: image to be used as builder image :param project: project where app should be created :param source: source used to extend the image, can be path or url :param oc_new_app_args: additional parameters for the `oc new-app` :return: str, name of the app """ # app name is generated randomly name = 'app-{random_string}'.format(random_string=random_str(5)) oc_new_app_args = oc_new_app_args or [] new_image = push_to_registry(image, image.name.split('/')[-1], image.tag, project) c = self._oc_command(["new-app"] + [new_image.name + "~" + source] + oc_new_app_args + ["-n"] + [project] + ["--name=%s" % name]) logger.info("Creating new app in project %s", project) try: o = run_cmd(c, return_output=True) logger.debug(o) except subprocess.CalledProcessError as ex: raise ConuException("oc new-app failed: %s" % ex) # build from local source if os.path.isdir(source): self.start_build(name, ["-n", project, "--from-dir=%s" % source]) return name
def create_namespace(self): """ Create namespace with random name :return: name of new created namespace """ name = 'namespace-{random_string}'.format(random_string=random_str(5)) namespace = client.V1Namespace(metadata=client.V1ObjectMeta(name=name)) self.core_api.create_namespace(namespace) logger.info("Creating namespace: %s", name) # save all namespaces created with this backend self.managed_namespaces.append(name) # wait for namespace to be ready Probe(timeout=30, pause=5, expected_retval=True, fnc=self._namespace_ready, namespace=name).run() return name
def run_systemdrun(self, command, internal_background=False, return_full_dict=False, **kwargs): """ execute command via systemd-run inside container :param command: list of command params :param internal_background: not used now :param kwargs: pass params to subprocess :return: dict with result """ internalkw = deepcopy(kwargs) or {} original_ignore_st = internalkw.get("ignore_status", False) original_return_st = internalkw.get("return_output", False) internalkw["ignore_status"] = True internalkw["return_output"] = False unit_name = constants.CONU_ARTIFACT_TAG + "unit_" + random_str() opts = ["-M", self.name, "--unit", unit_name] lpath = "/var/tmp/{}".format(unit_name) comout = {} if self._run_systemdrun_decide(): add_wait_var = "--wait" else: # keep service exist after it finish, to be able to read exit code add_wait_var = "-r" if internal_background: add_wait_var = "" if add_wait_var: opts.append(add_wait_var) # TODO: behave move similar to run_cmd function, unable to work with clean subprocess objects because systemd-run # does not support return stderr, stdout, and return code directly # find way how to do this in better way, machinectl shell is not possible # https://github.com/systemd/systemd/issues/5879 # https://github.com/systemd/systemd/issues/5878 bashworkaround = [ "/bin/bash", "-c", "({comm})>{path}.stdout 2>{path}.stderr".format( comm=" ".join(command), path=lpath) ] whole_cmd = ["systemd-run"] + opts + bashworkaround comout['command'] = command comout['return_code'] = run_cmd(whole_cmd, **internalkw) or 0 if not internal_background: if not self._run_systemdrun_decide(): comout['return_code'] = self._systemctl_wait_until_finish( self.name, unit_name) if self.is_running(): self.copy_from("{pin}.stdout".format(pin=lpath), "{pin}.stdout".format(pin=lpath)) with open("{pin}.stdout".format(pin=lpath)) as f: comout['stdout'] = f.read() self.copy_from("{pin}.stderr".format(pin=lpath), "{pin}.stderr".format(pin=lpath)) with open("{pin}.stderr".format(pin=lpath)) as f: comout['stderr'] = f.read() logger.debug(comout) if not original_ignore_st and comout['return_code'] != 0: raise subprocess.CalledProcessError(comout['command'], comout) if return_full_dict: return comout if original_return_st: return comout['stdout'] else: return comout['return_code']