X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/e3064da256b0c0f78e97bfe53825a5c0bf11a4cb..03731a3886079e7056c84b963602a6a57ad1d7ce:/src/store/processes/processes-actions.ts diff --git a/src/store/processes/processes-actions.ts b/src/store/processes/processes-actions.ts index 213e292bfe..f7822e06ee 100644 --- a/src/store/processes/processes-actions.ts +++ b/src/store/processes/processes-actions.ts @@ -17,30 +17,83 @@ import { initialize } from "redux-form"; import { RUN_PROCESS_BASIC_FORM, RunProcessBasicFormData } from "views/run-process-panel/run-process-basic-form"; import { RunProcessAdvancedFormData, RUN_PROCESS_ADVANCED_FORM } from "views/run-process-panel/run-process-advanced-form"; import { MOUNT_PATH_CWL_WORKFLOW, MOUNT_PATH_CWL_INPUT } from 'models/process'; -import { getWorkflow, getWorkflowInputs } from "models/workflow"; +import { CommandInputParameter, getWorkflow, getWorkflowInputs, getWorkflowOutputs } from "models/workflow"; import { ProjectResource } from "models/project"; import { UserResource } from "models/user"; +import { CommandOutputParameter } from "cwlts/mappings/v1.0/CommandOutputParameter"; export const loadProcess = (containerRequestUuid: string) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Promise => { const containerRequest = await services.containerRequestService.get(containerRequestUuid); dispatch(updateResources([containerRequest])); + if (containerRequest.outputUuid) { + const collection = await services.collectionService.get(containerRequest.outputUuid); + dispatch(updateResources([collection])); + } + if (containerRequest.containerUuid) { const container = await services.containerService.get(containerRequest.containerUuid); dispatch(updateResources([container])); + if (container.runtimeUserUuid) { + const runtimeUser = await services.userService.get(container.runtimeUserUuid); + dispatch(updateResources([runtimeUser])); + } return { containerRequest, container }; } return { containerRequest }; }; -export const loadContainers = (filters: string) => +export const loadContainers = (filters: string, loadMounts: boolean = true) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - const { items } = await services.containerService.list({ filters }); + let args: any = { filters }; + if (!loadMounts) { + args.select = containerFieldsNoMounts; + } + const { items } = await services.containerService.list(args); dispatch(updateResources(items)); return items; }; +// Until the api supports unselecting fields, we need a list of all other fields to omit mounts +const containerFieldsNoMounts = [ + "auth_uuid", + "command", + "container_image", + "cost", + "created_at", + "cwd", + "environment", + "etag", + "exit_code", + "finished_at", + "gateway_address", + "href", + "interactive_session_started", + "kind", + "lock_count", + "locked_by_uuid", + "log", + "modified_at", + "modified_by_client_uuid", + "modified_by_user_uuid", + "output_path", + "output_properties", + "output_storage_classes", + "output", + "owner_uuid", + "priority", + "progress", + "runtime_auth_scopes", + "runtime_constraints", + "runtime_status", + "runtime_user_uuid", + "scheduling_parameters", + "started_at", + "state", + "uuid", +] + export const cancelRunningWorkflow = (uuid: string) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { try { @@ -85,8 +138,25 @@ export const reRunProcess = (processUuid: string, workflowUuid: string) => } }; -const getInputs = (data: any) => { +/* + * Fetches raw inputs from containerRequest mounts with fallback to properties + * Returns undefined if containerRequest not loaded + * Returns [] if inputs not found in mounts or props + */ +export const getRawInputs = (data: any): CommandInputParameter[] | undefined => { + if (!data) { return undefined; } + const mountInput = data.mounts?.[MOUNT_PATH_CWL_INPUT]?.content; + const propsInput = data.properties?.cwl_input; + if (!mountInput && !propsInput) { return []; } + return (mountInput || propsInput); +} + +export const getInputs = (data: any): CommandInputParameter[] => { + // Definitions from mounts are needed so we return early if missing if (!data || !data.mounts || !data.mounts[MOUNT_PATH_CWL_WORKFLOW]) { return []; } + const content = getRawInputs(data) as any; + if (!content) { return []; } + const inputs = getWorkflowInputs(data.mounts[MOUNT_PATH_CWL_WORKFLOW].content); return inputs ? inputs.map( (it: any) => ( @@ -94,7 +164,53 @@ const getInputs = (data: any) => { type: it.type, id: it.id, label: it.label, - default: data.mounts[MOUNT_PATH_CWL_INPUT].content[it.id], + default: content[it.id], + value: content[it.id.split('/').pop()] || [], + doc: it.doc + } + ) + ) : []; +}; + +/* + * Fetches raw outputs from containerRequest properties + * Assumes containerRequest is loaded + */ +export const getRawOutputs = (data: any): CommandInputParameter[] | undefined => { + if (!data || !data.properties || !data.properties.cwl_output) { return undefined; } + return (data.properties.cwl_output); +} + +export type InputCollectionMount = { + path: string; + pdh: string; +} + +export const getInputCollectionMounts = (data: any): InputCollectionMount[] => { + if (!data || !data.mounts) { return []; } + return Object.keys(data.mounts) + .map(key => ({ + ...data.mounts[key], + path: key, + })) + .filter(mount => mount.kind === 'collection' && + mount.portable_data_hash && + mount.path) + .map(mount => ({ + path: mount.path, + pdh: mount.portable_data_hash, + })); +}; + +export const getOutputParameters = (data: any): CommandOutputParameter[] => { + if (!data || !data.mounts || !data.mounts[MOUNT_PATH_CWL_WORKFLOW]) { return []; } + const outputs = getWorkflowOutputs(data.mounts[MOUNT_PATH_CWL_WORKFLOW].content); + return outputs ? outputs.map( + (it: any) => ( + { + type: it.type, + id: it.id, + label: it.label, doc: it.doc } )