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]
def __transform_memory_value(self, mem_value): """ Transforms valid kubernetes memory value to bytes """ return ByteSize(mem_value).value
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]