【问题标题】:How to pass result of script template as an input parameter to another task in dag in argo workflows如何将脚本模板的结果作为输入参数传递给 argo 工作流中 dag 中的另一个任务
【发布时间】:2021-12-14 15:06:01
【问题描述】:

我创建了一个WorkflowTemplate,我想在其中将脚本模板的结果作为输入参数传递给另一个任务

这是我的WorkflowTemplate

apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: dag-wft
spec:
  entrypoint: whalesay
  templates:
  - name: whalesay
    inputs:
      parameters:
        - name: message
          default: '["tests/hello", "templates/hello", "manifests/hello"]'
    dag:
      tasks:
        - name: prepare-lst
          template: prepare-list-script
          arguments:
            parameters:
              - name: message
                value: "{{inputs.parameters.message}}"

        - name: templates
          depends: prepare-lst
          templateRef:
            name: final-dag-wft
            template: whalesay-final
          arguments:
            parameters:
            - name: fnl_message
              value: "{{item}}"
          withParam: "{{tasks.prepare-lst.outputs.parameters.templates_lst}}"

        - name: manifests
          depends: prepare-lst && (templates.Succeeded || templates.Skipped)
          templateRef:
            name: final-dag-wft
            template: whalesay-final
          arguments:
            parameters:
            - name: fnl_message
              value: "{{item}}"
          withParam: "{{tasks.prepare-lst.outputs.parameters.manifests_lst}}"

  - name: prepare-list-script
    inputs:
      parameters:
        - name: message
    script:
      image: python
      command: [python]
      source: |
        manifests_lst = []
        # templates list preparation
        templates_lst = ['templates/' for template in "{{inputs.parameters.message}}" if 'templates/' in template]
        
        print(templates_lst)

        # manifests list preparation
        for i in "{{inputs.parameters.message}}":
          if 'templates/' not in i:
            manifests_lst.append(i)

        print(manifests_lst)

    outputs:
      parameters:
        - name: templates_lst
        - name: manifests_lst

在上面的脚本模板中,我添加了两个变量templates_lstmanifests_lst 的打印语句。我想将这两个变量结果作为输入传递给 dag 中的其他两个任务。另外两个任务是templatesmanifests

我访问输出值的方式是"{{tasks.prepare-lst.outputs.parameters.templates_lst}}""{{tasks.prepare-lst.outputs.parameters.manifests_lst}}"。它不工作

我们该怎么做?

【问题讨论】:

    标签: kubernetes argo-workflows


    【解决方案1】:

    1.完全定义您的输出参数

    您的输出参数规范不完整。您需要指定哪里输出参数的来源。

    由于您有多个输出参数,您不能只使用标准输出 ({{tasks.prepare-lst.outputs.parameters.result}})。您必须编写两个文件并从中派生一个输出参数。

    2。加载 JSON 数组,使其可迭代

    如果你遍历数组的字符串表示,你一次只会得到一个字符。

    3.使用环境变量将输入传递给 Python

    虽然这不是绝对必要的,但我认为这是最佳实践。如果恶意行为者能够设置 message 参数,他们可以将 Python 注入您的工作流程。将参数作为环境变量传递,因此字符串仍然是字符串。

    变化:

       - name: prepare-list-script
         inputs:
           parameters:
             - name: message
         script:
           image: python
           command: [python]
    +      env:
    +      - name: MESSAGE
    +        value: "{{inputs.parameters.message}}"
           source: |
    +        import json
    +        import os
    +        message = json.loads(os.environ["MESSAGE"])
             manifests_lst = []
             # templates list preparation
    -        templates_lst = ['templates/' for template in "{{inputs.parameters.message}}" if 'templates/' in template]
    +        templates_lst = ['templates/' for template in message if 'templates/' in template]
             
    -        print(templates_lst)
    +        with open('/mnt/out/templates_lst.txt', 'w') as outfile:
    +          outfile.write(str(json.dumps(templates_lst)))
     
             # manifests list preparation
             for i in "{{inputs.parameters.message}}":
               if 'templates/' not in i:
                 manifests_lst.append(i)
     
    -        print(manifests_lst)
    +        with open('/mnt/out/manifests_lst.txt', 'w') as outfile:
    +          outfile.write(str(json.dumps(manifests_lst)))
    +      volumeMounts:
    +      - name: out
    +        mountPath: /mnt/out
    +    volumes:
    +    - name: out
    +      emptyDir: { }
     
         outputs:
           parameters:
             - name: templates_lst
    +          valueFrom:
    +            path: /mnt/out/templates_lst.txt
             - name: manifests_lst
    +          valueFrom:
    +            path: /mnt/out/manifests_lst.txt
    
    

    【讨论】:

    • 是的,我最初尝试过同样的方法,但它给出了这个错误Failed: invalid spec: templates.whalesay-wf.tasks.templates-wf templates.whalesay.tasks.prepare-lst templates.prepare-list-script.outputs.parameters.templates_lst: k8sapi executor does not support outputs from base image layer. Use an emptyDir: https://argoproj.github.io/argo-workflows/empty-dir/。我也尝试添加 VolumeMountsvolumes 但没有运气
    • @Biru 我已经使用错误消息链接的分页中建议的更改更新了示例。
    • @Biru 如果在检查示例后仍然无法正常工作,您能否使用失败的 WorkflowTemplate 发布一个新问题?
    • @Biru 您能否发布指向您正在运行的完整规范的链接?看起来 YAML 与 Workflow 规范不匹配,但如果没有完整的 YAML,我看不出有什么问题。
    • 我修好了。问题是列表未正确存储在文件中。我使用json.dumps 将列表中字符串的单引号替换为双引号,这适用于withParam @Michael Crenshaw - 我更新了您的答案并接受它作为工作解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    相关资源
    最近更新 更多