Esempio n. 1
0
    def launch(self):
        """
        Launch a visualization-based Tool
        :returns:
            - <JsonResponse> w/ `tool_url` key corresponding to the
        launched container's url
            - <HttpResponseBadRequest>, <HttpServerError>
        """
        client = DockerClientWrapper(settings.DJANGO_DOCKER_ENGINE_DATA_DIR)
        max_containers = settings.DJANGO_DOCKER_ENGINE_MAX_CONTAINERS
        if len(client.list()) >= max_containers:
            raise VisualizationToolError('Max containers')
        container = DockerContainerSpec(
            image_name=self.tool_definition.image_name,
            container_name=self.container_name,
            labels={self.uuid: ToolDefinition.VISUALIZATION},
            container_input_path=(self.tool_definition.container_input_path),
            input={
                self.FILE_RELATIONSHIPS: self.get_file_relationships_urls()
            },
            extra_directories=self.tool_definition.get_extra_directories())

        client.run(container)

        return JsonResponse({Tool.TOOL_URL: self.get_relative_container_url()})
Esempio n. 2
0
def create_tool_definition(annotation_data):
    """
    :param annotation_data: dict of data that represents a ToolDefinition
    :returns: The created ToolDefinition object

    NOTE: Since we are within a `transaction` we aren't handling the
    usual `DoesNotExist` & `MultipleObjectsReturned` exceptions because
    we want them to propagate up the stack
    """
    tool_type = annotation_data["tool_type"]
    annotation = annotation_data["annotation"]
    common_tool_definition_params = {
        "name": annotation_data["name"],
        "description": annotation["description"],
        "tool_type": tool_type,
        "file_relationship": create_file_relationship_nesting(annotation),
    }

    if tool_type == ToolDefinition.WORKFLOW:
        workflow_engine = WorkflowEngine.objects.get(
            uuid=annotation_data["workflow_engine_uuid"])
        workflow = WorkflowFactory(
            uuid=str(uuid.uuid4()),
            name=annotation_data["name"],
            summary="Workflow for: {}".format(annotation_data["name"]),
            internal_id=annotation_data["galaxy_workflow_id"],
            workflow_engine=workflow_engine,
            is_active=True,
            type=Workflow.ANALYSIS_TYPE,
            graph=json.dumps(annotation_data["graph"]))
        workflow.set_manager_group(workflow_engine.get_manager_group())
        workflow.share(workflow_engine.get_manager_group().get_managed_group())

        tool_definition = ToolDefinitionFactory(
            workflow=workflow, **common_tool_definition_params)
    elif tool_type == ToolDefinition.VISUALIZATION:
        tool_definition = ToolDefinitionFactory(
            image_name=annotation["image_name"],
            **common_tool_definition_params)

        # If we've successfully created the ToolDefinition lets
        #  pull down its docker image
        try:
            image_name, version = tool_definition.image_name.split(":")
        except ValueError:
            raise RuntimeError(
                "Tool's Docker image: `{}` has no specified version".format(
                    tool_definition.image_name))
        else:
            logger.debug("Pulling Docker image: %s",
                         tool_definition.image_name)
            DockerClientWrapper().pull(image_name, version=version)

    tool_definition.annotation = json.dumps(annotation)
    tool_definition.save()

    create_and_associate_parameters(tool_definition,
                                    annotation[ToolDefinition.PARAMETERS])

    return tool_definition
Esempio n. 3
0
def django_docker_cleanup():
    # TODO: Specify manager, if not default
    DockerClientWrapper().purge_inactive(
        settings.DJANGO_DOCKER_ENGINE_SECONDS_INACTIVE)
    # Remove volumes not associated with a container.
    # NOTE: this functionality is provided by django-docker-engine >= 0.0.52
    client = docker.from_env()
    client.volumes.prune()
Esempio n. 4
0
def remove_tool_container(sender, instance, *args, **kwargs):
    """
    Remove the Docker container instance corresponding to a
    VisualizationTool's launch.
    """
    try:
        DockerClientWrapper(
            settings.DJANGO_DOCKER_ENGINE_DATA_DIR).purge_by_label(
                instance.uuid)
    except APIError as e:
        logger.error("Couldn't purge container for Tool with UUID: %s %s",
                     instance.uuid, e)
Esempio n. 5
0
    def test_visualiztion_running_status_in_response(self):
        self.create_tool(ToolDefinition.VISUALIZATION,
                         start_vis_container=True)

        self._make_tools_get_request()
        self.assertEqual(len(self.get_response.data), 1)

        self.assertTrue(self.get_response.data[0]["is_running"])

        DockerClientWrapper().purge_inactive(0)

        self._make_tools_get_request()
        self.assertEqual(len(self.get_response.data), 1)

        self.assertFalse(self.get_response.data[0]["is_running"])
Esempio n. 6
0
    def test_vis_tool_can_be_relaunched(self):
        self.create_tool(ToolDefinition.VISUALIZATION,
                         start_vis_container=True)
        assign_perm('core.read_dataset', self.user, self.tool.dataset)

        self._make_tools_get_request()
        self.assertTrue(self.tool.is_running())

        # Remove Container
        DockerClientWrapper().purge_inactive(0)
        self.assertFalse(self.tool.is_running())

        # Relaunch Tool
        get_request = self.factory.get(self.tool.relaunch_url)
        force_authenticate(get_request, self.user)
        with mock.patch("tool_manager.models.get_solr_response_json"):
            get_response = self.tool_relaunch_view(get_request,
                                                   uuid=self.tool.uuid)
        self.assertEqual(get_response.status_code, 200)
        self.assertEqual(
            json.loads(get_response.content)["container_url"],
            self.tool.get_relative_container_url())
        self.assertTrue(self.tool.is_running())
 def test_pull_missing_image(self):
     # Because all the image names are hardcoded, it's unlikely that the
     # image really doesn't exist... It's more likely that we got this
     # error because we ran out of disk space: hence the exception name.
     with self.assertRaises(PossiblyOutOfDiskSpace):
         DockerClientWrapper().pull('no-such-image')
Esempio n. 8
0
def django_docker_cleanup():
    # TODO: Specify manager, if not default
    client = DockerClientWrapper(settings.DJANGO_DOCKER_ENGINE_DATA_DIR)
    client.purge_inactive(settings.DJANGO_DOCKER_ENGINE_SECONDS_INACTIVE)