Beispiel #1
0
 def temp_file(self, prefix, contents, suffix=".txt"):
     # type: (Union[Text, Iterable[Text]], Iterable[Text], Text) -> Text
     """
     Write contents to a temporary file, yielding its path. Finally, delete it.
     :param prefix: file name prefix
     :param contents: text lines to write
     :param suffix: file name suffix
     """
     f, temp_path = mkstemp(suffix=suffix, prefix=prefix)
     with f:
         f.write(contents if isinstance(contents, six.text_type
                                        ) else join_lines(contents))
     try:
         yield temp_path
     finally:
         if not self.session.debug_mode:
             safe_remove_file(temp_path)
Beispiel #2
0
    def _kubectl_apply(self, create_clearml_conf, docker_image, docker_args, labels, queue, task_id, queue_name):
        template = deepcopy(self.template_dict)
        template.setdefault('apiVersion', 'v1')
        template['kind'] = 'Pod'
        template.setdefault('metadata', {})
        name = 'clearml-{queue}-id-{task_id}'.format(queue=queue_name, task_id=task_id)
        template['metadata']['name'] = name
        template.setdefault('spec', {})
        template['spec'].setdefault('containers', [])
        if labels:
            labels_dict = dict(pair.split('=', 1) for pair in labels)
            template['metadata'].setdefault('labels', {})
            template['metadata']['labels'].update(labels_dict)
        container = self._parse_docker_args(docker_args)

        container_bash_script = [self.container_bash_script] if isinstance(self.container_bash_script, str) \
            else self.container_bash_script

        script_encoded = '\n'.join(
            ['#!/bin/bash', ] +
            [line.format(extra_bash_init_cmd=self.extra_bash_init_script or '', task_id=task_id)
             for line in container_bash_script])

        create_init_script = \
            "echo '{}' | base64 --decode >> ~/__start_agent__.sh ; " \
            "/bin/bash ~/__start_agent__.sh".format(
                base64.b64encode(
                    script_encoded.encode('ascii')
                ).decode('ascii'))

        container = merge_dicts(
            container,
            dict(name=name, image=docker_image,
                 command=['/bin/bash'],
                 args=['-c', '{} ; {}'.format(create_clearml_conf, create_init_script)])
        )

        if template['spec']['containers']:
            template['spec']['containers'][0] = merge_dicts(template['spec']['containers'][0], container)
        else:
            template['spec']['containers'].append(container)

        fp, yaml_file = tempfile.mkstemp(prefix='clearml_k8stmpl_', suffix='.yml')
        os.close(fp)
        with open(yaml_file, 'wt') as f:
            yaml.dump(template, f)

        kubectl_cmd = self.KUBECTL_APPLY_CMD.format(
            task_id=task_id,
            docker_image=docker_image,
            queue_id=queue,
            namespace=self.namespace
        )
        # make sure we provide a list
        if isinstance(kubectl_cmd, str):
            kubectl_cmd = kubectl_cmd.split()

        # add the template file at the end
        kubectl_cmd += [yaml_file]
        try:
            process = subprocess.Popen(kubectl_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            output, error = process.communicate()
        except Exception as ex:
            return None, str(ex)
        finally:
            safe_remove_file(yaml_file)

        return output, error
Beispiel #3
0
 def close_pid_file(cls):
     if cls._pid_file:
         cls._pid_file.close()
         safe_remove_file(cls._pid_file.name)
     cls._pid_file = None