Example #1
0
    def __get_k8s_containers(self, ajs):
        """Fills in all required for setting up the docker containers to be used, including setting a pull policy if
           this has been set.
           $GALAXY_VIRTUAL_ENV is set to None to avoid the galaxy virtualenv inside the tool container.
           $GALAXY_LIB is set to None to avoid changing the python path inside the container.
           Setting these variables changes the described behaviour in the job file shell script
           used to execute the tool inside the container.
        """
        k8s_container = {
            "name": self.__get_k8s_container_name(ajs.job_wrapper),
            "image": self._find_container(ajs.job_wrapper).container_id,
            # this form of command overrides the entrypoint and allows multi command
            # command line execution, separated by ;, which is what Galaxy does
            # to assemble the command.
            "command": [ajs.job_wrapper.shell],
            "args": ["-c", ajs.job_file],
            "workingDir": ajs.job_wrapper.working_directory,
            "volumeMounts": self.runner_params['k8s_volume_mounts']
        }

        resources = self.__get_resources(ajs.job_wrapper)
        if resources:
            envs = []
            if 'requests' in resources:
                requests = resources['requests']
                if 'memory' in requests:
                    envs.append({'name': 'GALAXY_MEMORY_MB', 'value': str(ByteSize(requests['memory']).to_unit('M', as_string=False))})
                if 'cpu' in requests:
                    envs.append({'name': 'GALAXY_SLOTS', 'value': str(int(math.ceil(float(requests['cpu']))))})
            elif 'limits' in resources:
                limits = resources['limits']
                if 'memory' in limits:
                    envs.append({'name': 'GALAXY_MEMORY_MB', 'value': str(ByteSize(limits['memory']).to_unit('M', as_string=False))})
                if 'cpu' in limits:
                    envs.append({'name': 'GALAXY_SLOTS', 'value': str(int(math.ceil(float(limits['cpu']))))})
            k8s_container['resources'] = resources
            k8s_container['env'] = envs

        if self._default_pull_policy:
            k8s_container["imagePullPolicy"] = self._default_pull_policy

        return [k8s_container]
Example #2
0
 def __transform_memory_value(self, mem_value):
     """
     Transforms valid kubernetes memory value to bytes
     """
     return ByteSize(mem_value).value
Example #3
0
    def __get_k8s_containers(self, ajs):
        """Fills in all required for setting up the docker containers to be used, including setting a pull policy if
           this has been set.
           $GALAXY_VIRTUAL_ENV is set to None to avoid the galaxy virtualenv inside the tool container.
           $GALAXY_LIB is set to None to avoid changing the python path inside the container.
           Setting these variables changes the described behaviour in the job file shell script
           used to execute the tool inside the container.
        """
        container = self._find_container(ajs.job_wrapper)
        k8s_container = {
            "name": self.__get_k8s_container_name(ajs.job_wrapper),
            "image": container.container_id,
            # this form of command overrides the entrypoint and allows multi command
            # command line execution, separated by ;, which is what Galaxy does
            # to assemble the command.
            "command": [ajs.job_wrapper.shell],
            "args": ["-c", ajs.job_file],
            "workingDir": ajs.job_wrapper.working_directory,
            "volumeMounts": self.runner_params['k8s_volume_mounts']
        }
        resources = self.__get_resources(ajs.job_wrapper)
        if resources:
            envs = []
            cpu_val = None
            if 'requests' in resources:
                requests = resources['requests']
                if 'cpu' in requests:
                    cpu_val = int(math.ceil(float(requests['cpu'])))
                    envs.append({
                        'name': 'GALAXY_SLOTS',
                        'value': str(cpu_val)
                    })
                if 'memory' in requests:
                    mem_val = ByteSize(requests['memory']).to_unit(
                        'M', as_string=False)
                    envs.append({
                        'name': 'GALAXY_MEMORY_MB',
                        'value': str(mem_val)
                    })
                    if cpu_val:
                        envs.append({
                            'name': 'GALAXY_MEMORY_MB_PER_SLOT',
                            'value': str(math.floor(mem_val / cpu_val))
                        })
            elif 'limits' in resources:
                limits = resources['limits']
                if 'cpu' in limits:
                    cpu_val = int(math.floor(float(limits['cpu'])))
                    cpu_val = cpu_val or 1
                    envs.append({
                        'name': 'GALAXY_SLOTS',
                        'value': str(cpu_val)
                    })
                if 'memory' in limits:
                    mem_val = ByteSize(limits['memory']).to_unit(
                        'M', as_string=False)
                    envs.append({
                        'name': 'GALAXY_MEMORY_MB',
                        'value': str(mem_val)
                    })
                    if cpu_val:
                        envs.append({
                            'name': 'GALAXY_MEMORY_MB_PER_SLOT',
                            'value': str(math.floor(mem_val / cpu_val))
                        })
            extra_envs = yaml.safe_load(
                self.__get_overridable_params(ajs.job_wrapper,
                                              'k8s_extra_job_envs') or "{}")
            for key in extra_envs:
                envs.append({'name': key, 'value': extra_envs[key]})
            if self.__has_guest_ports(ajs.job_wrapper):
                configured_eps = [
                    ep for ep in
                    ajs.job_wrapper.get_job().interactivetool_entry_points
                    if ep.configured
                ]
                for entry_point in configured_eps:
                    # sending in self.app as `trans` since it's only used for `.security` so seems to work
                    entry_point_path = self.app.interactivetool_manager.get_entry_point_path(
                        self.app, entry_point)
                    if '?' in entry_point_path:
                        # Removing all the parameters from the ingress path, but they will still be in the database
                        # so the link that the user clicks on will still have them
                        log.warning(
                            "IT urls including parameters (eg: /myit?mykey=myvalue) are only experimentally supported on K8S"
                        )
                        entry_point_path = entry_point_path.split('?')[0]
                    entry_point_domain = f'{self.app.config.interactivetools_proxy_host}'
                    if entry_point.requires_domain:
                        entry_point_subdomain = self.app.interactivetool_manager.get_entry_point_subdomain(
                            self.app, entry_point)
                        entry_point_domain = f'{entry_point_subdomain}.{entry_point_domain}'
                    envs.append({
                        'name': 'INTERACTIVETOOL_PORT',
                        'value': str(entry_point.tool_port)
                    })
                    envs.append({
                        'name': 'INTERACTIVETOOL_DOMAIN',
                        'value': str(entry_point_domain)
                    })
                    envs.append({
                        'name': 'INTERACTIVETOOL_PATH',
                        'value': str(entry_point_path)
                    })
            k8s_container['resources'] = resources
            k8s_container['env'] = envs

        if self._default_pull_policy:
            k8s_container["imagePullPolicy"] = self._default_pull_policy

        return [k8s_container]