IF YOU WOULD LIKE TO GET AN ACCOUNT, please write an email to s dot adaszewski at gmail dot com. User accounts are meant only to report issues and/or generate pull requests. This is a purpose-specific Git hosting for ADARED projects. Thank you for your understanding!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
5.1KB

  1. //
  2. // Copyright (C) Stanislaw Adaszewski, 2020
  3. // Contact: s.adaszewski@gmail.com
  4. // Website: https://adared.ch/wba
  5. // License: GNU Affero General Public License, Version 3
  6. //
  7. import makeArvadosRequest from 'make-arvados-request';
  8. import wbUuidsToCwl from 'wb-uuids-to-cwl';
  9. function wbParseWorkflowInputs(workflowDefinition, userInputs, errors) {
  10. // first see if all inputs are parseable
  11. const inputs = {};
  12. const main = workflowDefinition['$graph'].find(a => (a.id === '#main'));
  13. for (let k in userInputs) {
  14. try {
  15. let val = jsyaml.safeLoad(userInputs[k]);
  16. val = wbUuidsToCwl(val);
  17. k = k.split('/').slice(1).join('/');
  18. inputs[k] = (val === undefined ? null : val);
  19. } catch (exc) {
  20. errors.push('Error parsing ' + k + ': ' + exc.message);
  21. }
  22. }
  23. return inputs;
  24. }
  25. function ensureSubProject(arvHost, arvToken, projectUuid) {
  26. const filters = [
  27. [ 'group_class', '=', 'project' ],
  28. [ 'owner_uuid', '=', projectUuid ],
  29. [ 'properties.type', '=', 'daily_process_subproject_container' ]
  30. ];
  31. let prom = makeArvadosRequest(arvHost, arvToken,
  32. '/arvados/v1/groups?filters=' + encodeURIComponent(JSON.stringify(filters)));
  33. prom = prom.then(xhr => {
  34. if (xhr.response.items.length === 0) {
  35. let prom_1 = new Promise(accept => accept());
  36. prom_1 = prom_1.then(() => makeArvadosRequest(arvHost, arvToken,
  37. '/arvados/v1/groups', { method: 'POST',
  38. data: JSON.stringify({ owner_uuid: projectUuid,
  39. group_class: 'project',
  40. name: 'Container for daily sub-projects for processes',
  41. properties: { type: 'daily_process_subproject_container' } }) }));
  42. prom_1 = prom_1.then(xhr_1 => xhr_1.response.uuid);
  43. return prom_1;
  44. }
  45. return xhr.response.items[0].uuid;
  46. });
  47. let date = new Date();
  48. date = (date.getYear() + 1900) + '-' +
  49. ('00' + (date.getMonth() + 1)).slice(-2) + '-' +
  50. ('00' + date.getDate()).slice(-2);
  51. let containerUuid;
  52. prom = prom.then(uuid => {
  53. containerUuid = uuid;
  54. const filters_1 = [
  55. [ 'group_class', '=', 'project'],
  56. [ 'owner_uuid', '=', containerUuid ],
  57. [ 'properties.type', '=', 'daily_process_subproject' ],
  58. [ 'properties.date', '=', date ]
  59. ];
  60. return makeArvadosRequest(arvHost, arvToken,
  61. '/arvados/v1/groups?filters=' + encodeURIComponent(JSON.stringify(filters_1)));
  62. });
  63. prom = prom.then(xhr => {
  64. if (xhr.response.items.length === 0) {
  65. let prom_1 = new Promise(accept => accept());
  66. prom_1 = prom_1.then(() => makeArvadosRequest(arvHost, arvToken,
  67. '/arvados/v1/groups', { method: 'POST',
  68. data: JSON.stringify({ owner_uuid: containerUuid,
  69. group_class: 'project',
  70. name: 'Daily processes sub-project for ' + date,
  71. properties: { type: 'daily_process_subproject', date } }) }));
  72. prom_1 = prom_1.then(xhr => xhr.response.uuid);
  73. return prom_1;
  74. }
  75. return xhr.response.items[0].uuid;
  76. });
  77. return prom;
  78. }
  79. // params:
  80. // arvHost, arvToken, inputs,
  81. // projectUuid, workflowDefinition, workflowUuid
  82. // processName, processDescription, placeInSubProject
  83. function wbSubmitContainerRequest(params) {
  84. const { workflowDefinition, workflowUuid,
  85. processName, processDescription, inputs,
  86. arvHost, arvToken,
  87. placeInSubProject } = params;
  88. let { projectUuid } = params;
  89. let prom = new Promise(accept => accept());
  90. if (placeInSubProject) {
  91. prom = prom.then(() => ensureSubProject(arvHost, arvToken, projectUuid));
  92. prom = prom.then(subProjUuid => (projectUuid = subProjUuid));
  93. }
  94. prom = prom.then(() => {
  95. // prepare a request
  96. const req = {
  97. name: processName,
  98. description: processDescription,
  99. owner_uuid: projectUuid,
  100. container_image: 'arvados/jobs',
  101. properties: {
  102. template_uuid: workflowUuid
  103. },
  104. runtime_constraints: {
  105. API: true,
  106. vcpus: 1,
  107. ram: 1073741824
  108. },
  109. cwd: '/var/spool/cwl',
  110. command: [
  111. 'arvados-cwl-runner',
  112. '--local',
  113. '--api=containers',
  114. '--project-uuid=' + projectUuid,
  115. '--collection-cache-size=256',
  116. '/var/lib/cwl/workflow.json#main',
  117. '/var/lib/cwl/cwl.input.json'],
  118. output_path: '/var/spool/cwl',
  119. priority: 1,
  120. state: 'Committed',
  121. mounts: {
  122. 'stdout': {
  123. kind: 'file',
  124. path: '/var/spool/cwl/cwl.output.json'
  125. },
  126. '/var/spool/cwl': {
  127. kind: 'collection',
  128. writable: true
  129. },
  130. '/var/lib/cwl/workflow.json': {
  131. kind: 'json',
  132. content: workflowDefinition
  133. },
  134. '/var/lib/cwl/cwl.input.json': {
  135. kind: 'json',
  136. content: inputs
  137. }
  138. }
  139. };
  140. return makeArvadosRequest(arvHost, arvToken,
  141. '/arvados/v1/container_requests',
  142. { method: 'POST', data: JSON.stringify(req) });
  143. });
  144. return prom;
  145. }
  146. export { wbParseWorkflowInputs, wbSubmitContainerRequest };