在 AWSTOE中使用循环结构 - EC2Image Builder

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 AWSTOE中使用循环结构

本部分提供了有助于您在 AWSTOE中创建循环结构的信息。循环结构定义了重复的指令序列。您可以在 AWSTOE中使用以下类型的循环结构:

  • for 结构 – 在有界的整数序列上迭代。

  • forEach 结构

    • forEach 使用输入列表循环 – 迭代有限的字符串集合。

    • forEach 带分隔列表的循环 – 迭代由分隔符连接的有限字符串集合。

注意

循环结构仅支持字符串数据类型。

引用迭代变量

要引用当前迭代变量的索引和值,必须在包含循环结构的步骤的输入主体中使用引用表达式 {{ loop.* }}。此表达式不能用于引用另一个步骤的循环结构的迭代变量。

引用表达式由以下成员组成:

  • {{ loop.index }} – 当前迭代的序数位置,索引为 0

  • {{ loop.value }} – 与当前迭代变量关联的值。

循环名称

所有循环结构都有一个用于标识的可选名称字段。如果提供了循环名称,则可以使用它来引用步骤输入主体中的迭代变量。要引用命名循环的迭代索引和值,请在步骤的输入主体中使用带 {{ loop.* }}{{ <loop_name>.* }}。此表达式不能用于引用另一个步骤的命名循环结构。

引用表达式由以下成员组成:

  • {{ <loop_name>.index }} – 命名循环当前迭代的序数位置,其索引位于 0

  • {{ <loop_name>.value }} – 与命名循环的当前迭代变量关联的值。

解析引用表达式

解 AWSTOE 析引用表达式如下:

  • {{ <loop_name>.* }}— 使用以下逻辑 AWSTOE 解析此表达式:

    • 如果当前正在运行的步骤的循环与 <loop_name> 值匹配,则引用表达式将解析为当前正在运行的步骤的循环结构。

    • 如果命名的循环结构出现在当前运行的步骤内,则 <loop_name> 解析为该结构。

  • {{ loop.* }}— 使用在当前运行的步骤中定义的循环结构 AWSTOE 解析表达式。

如果在不包含循环的步骤中使用引用表达式,则 AWSTOE 不会解析这些表达式,并且它们出现在步骤中而不进行替换。

注意

引用表达式必须用双引号括起来,以便YAML编译器正确解释。

循环结构的类型

本节提供有关可在 AWSTOE中使用的循环结构类型的信息和示例。

for 循环

for 循环迭代处于由变量开头和结尾勾勒的边界内指定的整数范围。迭代值在集合 [start, end] 中,包括边界值。

AWSTOE 验证startend、和updateBy值,以确保组合不会导致无限循环。

for 循环架构

- name: "StepName" action: "ActionModule" loop: name: "string" for: start: int end: int updateBy: int inputs: ...
for 循环输入
字段 描述 类型 必需 默认

name

循环的唯一名称。与同一阶段的其他循环名称相比,它必须是唯一的。

String

""

start

迭代的起始值。不接受链接表达式。

整数

不适用

end

迭代的结束值。不接受链接表达式。 整数 不适用

updateBy

通过加法更新迭代值的差异。它必须是非零负值或正值。不接受链接表达式。 整数 不适用

for 循环输入示例

- name: "CalculateFileUploadLatencies" action: "ExecutePowerShell" loop: for: start: 100000 end: 1000000 updateBy: 100000 inputs: commands: - | $f = new-object System.IO.FileStream c:\temp\test{{ loop.index }}.txt, Create, ReadWrite $f.SetLength({{ loop.value }}MB) $f.Close() - c:\users\administrator\downloads\latencyTest.exe --file c:\temp\test{{ loop.index }}.txt - AWS s3 cp c:\users\administrator\downloads\latencyMetrics.json s3://bucket/latencyMetrics.json - | Remove-Item -Path c:\temp\test{{ loop.index }}.txt Remove-Item -Path c:\users\administrator\downloads\latencyMetrics.json

forEach 使用输入列表循环

forEach 循环迭代一个显式的值列表,该列表可以是字符串和链式表达式。

forEach 使用输入列表架构进行循环

- name: "StepName" action: "ActionModule" loop: name: "string" forEach: - "string" inputs: ...
forEach 使用输入列表输入进行循环
字段 描述 类型 必需 默认

name

循环的唯一名称。与同一阶段的其他循环名称相比,它必须是唯一的。

String

""

forEach 循环字符串列表

用于迭代的字符串列表。接受链式表达式作为列表中的字符串。链式表达式必须用双引号括起来,YAML编译器才能正确解释它们。

字符串列表

不适用

forEach 使用输入列表循环示例 1

- name: "ExecuteCustomScripts" action: "ExecuteBash" loop: name: BatchExecLoop forEach: - /tmp/script1.sh - /tmp/script2.sh - /tmp/script3.sh inputs: commands: - echo "Count {{ BatchExecLoop.index }}" - sh "{{ loop.value }}" - | retVal=$? if [ $retVal -ne 0 ]; then echo "Failed" else echo "Passed" fi

forEach 使用输入列表循环示例 2

- name: "RunMSIWithDifferentArgs" action: "ExecuteBinary" loop: name: MultiArgLoop forEach: - "ARG1=C:\Users ARG2=1" - "ARG1=C:\Users" - "ARG1=C:\Users ARG3=C:\Users\Administrator\Documents\f1.txt" inputs: commands: path: "c:\users\administrator\downloads\runner.exe" args: - "{{ MultiArgLoop.value }}"

forEach 使用输入列表循环示例 3

- name: "DownloadAllBinaries" action: "S3Download" loop: name: MultiArgLoop forEach: - "bin1.exe" - "bin10.exe" - "bin5.exe" inputs: - source: "s3://bucket/{{ loop.value }}" destination: "c:\temp\{{ loop.value }}"

forEach 使用带分隔列表的循环

该循环遍历包含由分隔符分隔的值的字符串。要遍历字符串的组成部分,请 AWSTOE 使用分隔符将字符串拆分为适合迭代的数组。

forEach 使用分隔列表架构的循环

- name: "StepName" action: "ActionModule" loop: name: "string" forEach: list: "string" delimiter: ".,;:\n\t -_" inputs: ...
forEach 使用分隔列表输入的循环
字段 描述 类型 必需 默认

name

赋予循环的唯一名称。与同一阶段的其他循环名称相比,它应该是唯一的。

String

""

list

由组成字符串组成的字符串,这些字符串由一个通用分隔符连接在一起。也接受链式表达式。如果是链式表达式,请确保用双引号将它们括起来,以便YAML编译器正确解释。 String

不适用

delimiter

用于在区块中分隔字符串的字符。默认为逗号字符。在给定的列表中只允许使用一个分隔符:
  • 圆点:"."

  • 逗号:","

  • 分号:";"

  • 冒号:":"

  • 新建行:"\n"

  • 选项卡:"\t"

  • 空格:" "

  • 连字符:"-"

  • 下划线:"_"

不能使用链接表达式。

String 逗号:","
注意

list 的值被视为不可变的字符串。如果在运行时更改了 list 的源,则它在运行期间不会反映出来。

forEach 使用分隔列表循环示例 1

此示例使用以下链接表达式模式来引用另一个步骤的输出:<phase_name>.<step_name>.[inputs | outputs].<var_name>.

- name: "RunMSIs" action: "ExecuteBinary" loop: forEach: list: "{{ build.GetAllMSIPathsForInstallation.outputs.stdout }}" delimiter: "\n" inputs: commands: path: "{{ loop.value }}"

forEach 使用分隔列表循环示例 2

- name: "UploadMetricFiles" action: "S3Upload" loop: forEach: list: "/tmp/m1.txt,/tmp/m2.txt,/tmp/m3.txt,..." inputs: commands: - source: "{{ loop.value }}" destination: "s3://bucket/key/{{ loop.value }}"

步骤字段

循环是步骤的一部分。任何与步骤运行相关的字段都不会应用于单个迭代。步骤字段仅应用于步骤级别,如下所示:

  • timeoutSeconds— 循环的所有迭代都必须在此字段指定的时间段内运行。如果循环运行超时,则 AWSTOE 运行该步骤的重试策略,并为每次新的尝试重置超时参数。如果循环运行在达到最大重试次数后超过超时值,则该步骤的失败消息将表明循环运行已超时。

  • onFailure— 故障处理应用于该步骤,如下所示:

    • 如果设置onFailureAbort,则 AWSTOE 退出循环并根据重试策略重试该步骤。在达到最大重试次数后,将当前步骤 AWSTOE 标记为失败,并停止运行该进程。

      AWSTOE 将父阶段和文档的状态码设置为Failed

      注意

      在失败的步骤之后,不再运行任何其他步骤。

    • 如果设置onFailureContinue,则 AWSTOE 退出循环并根据重试策略重试该步骤。在达到最大重试次数后,将当前步骤 AWSTOE 标记为失败,然后继续运行下一个步骤。

      AWSTOE 将父阶段和文档的状态码设置为Failed

    • 如果设置onFailureIgnore,则 AWSTOE 退出循环并根据重试策略重试该步骤。在达到最大重试次数后,将当前步骤 AWSTOE 标记为IgnoredFailure,然后继续运行下一步。

      AWSTOE 将父阶段和文档的状态码设置为SuccessWithIgnoredFailure

      注意

      这仍被视为成功运行,但包含一些信息,可让您知道一个或多个步骤失败并被忽略。

  • maxAttempts — 每次重试,整个步骤和所有迭代都是从头开始运行的。

  • 状态 – 步骤运行的总体状态。status 不代表各个迭代的状态。包含循环的步骤状态确定如下:

    • 如果单个迭代运行失败,则步骤的状态指向失败。

    • 如果所有迭代都成功,则步骤的状态指向成功。

  • startTime — 步骤运行的总开始时间。不代表各个迭代的开始时间。

  • endTime — 步骤运行的总结束时间。不代表单个迭代的结束时间。

  • failureMessage — 包括在出现非超时错误时失败的迭代索引。如果出现超时错误,消息指出该循环运行失败。为了最大限度地减少失败消息的大小,不为每次迭代提供单独的错误消息。

步骤和迭代输出

每次迭代都包含一个输出。在循环运行结束时, AWSTOE 将所有成功的迭代输出合并到中。detailedOutput.json合并输出是属于相应输出键的值的排序规则,这些值在操作模块的输出架构中定义。下面的示例说明如何合并输出:

迭代 1 的 ExecuteBash 的输出

{ "stdout":"Hello" }

迭代 2 的 ExecuteBash 的输出

{ "stdout":"World" }

步骤的 ExecuteBash 的输出

{ "stdout":"Hello\nWorld" }

例如,ExecuteBashExecutePowerShellExecuteBinary 是操作模块,其返回 STDOUT 作为操作模块输出。STDOUT 消息与换行符连接以在 detailedOutput.json 中生成步骤的总体输出。

AWSTOE 不会合并失败迭代的输出。