

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

# 提交挂钩
<a name="submission-hooks"></a>

提交挂钩允许您在 Deadline Cloud 作业提交工作流程中运行自定义脚本。在作业到达 Deadline Cloud 服务之前，挂钩将在提交作业的工作站上本地运行。Hook 不会在工作人员或 AWS 云端运行。由于挂钩在您的计算机上执行，因此它们可以访问本地文件、环境变量以及提交用户可用的网络资源。

您可以使用挂钩来验证作业配置、发现其他资产、修改提交参数或与外部系统（例如生产跟踪软件）集成。有关在工作线程或云端运行的其他集成点，请参阅[作业的挂钩、事件和集成点](integration-points.md)。

有两种配置挂钩的方法：
+ **捆绑挂钩** — 将一个`hooks.yaml`（或`hooks.json`）文件放在任务包目录旁边`template.yaml`。捆绑包挂钩非常适合在提交之前已经存在捆绑包的 CLI 工作流程。
+ **环境挂钩** — 将`DEADLINE_HOOKS_DIR`环境变量指向包含的目录`hooks.yaml`。环境挂钩对于想要在不修改任务捆绑包的情况下对所有提交内容强制执行挂钩的工作室非常有用。

两个源可以同时处于活动状态。当两者都存在时，首先运行环境挂钩，然后运行捆绑挂钩。

**注意**  
In-application (DCC) 提交者（例如 Maya、Nuke 或 Blender）仅在提交前和提交后阶段运行环境挂钩。GUI 之前的阶段不适用于 DCC 提交者。有关更多信息，请参阅 [Pre-GUI 钩子](#submission-hooks-pre-gui)。

## 挂钩类型
<a name="submission-hooks-types"></a>

Deadline Cloud 支持三种挂钩类型，它们对应于提交工作流程中的不同点。

### Pre-GUI 钩子
<a name="submission-hooks-pre-gui"></a>

Pre-GUI 挂钩在提交对话框打开之前运行。你可以使用 GUI 之前的挂钩来完成以下任务：

**重要**  
Pre-GUI 挂钩只能在独立 GUI 提交器 (`deadline bundle gui-submit`) 上运行。它们不会在应用程序内 (DCC) 提交器（例如 Maya、Nuke 或 Blender）中运行，因为这些应用程序直接构建其提交对话框，并且不会调用 GUI 之前的阶段。 Pre-GUI 挂钩也不适用于 CLI 提交 (`deadline bundle submit`)，它没有 GUI 阶段。 Pre-submission 而且，提交后挂钩适用于所有提交方法。
+ Pre-populate 工作名称、描述和优先级
+ 根据当前场景或管道上下文设置参数默认值
+ 向项目管理系统查询任务元数据

Pre-GUI 如果失败（非零退出代码或超时），挂钩会阻止对话框打开。

将 JSON 输出到 stdout 以修改初始对话框状态。以下示例显示了输出格式：

```
import json

output = {
    "name": "My Render - v042",
    "description": "Submitted via pipeline",
    "parameters": {
        "SceneFile": "/resolved/path/to/scene.ma",
        "OutputPath": "/shots/sh010/renders/",
        "deadline:priority": 75,
        "deadline:maxFailedTasksCount": 5,
        "deadline:maxRetriesPerTask": 3,
        "deadline:maxWorkerCount": 10,
        "deadline:targetTaskRunStatus": "READY"
    }
}
print(json.dumps(output))
```

下表描述了 GUI 之前的挂钩的输出字段。


| 字段 | Type | 说明 | 
| --- | --- | --- | 
| `name` | 字符串 | Pre-fills 工作名称字段。 | 
| `description` | 字符串 | Pre-fills 职位描述字段。 | 
| `parameters` | 对象 | Pre-fills 按名称排列的参数值。Job 模板参数直接使用其名称。共享作业属性使用前`deadline:`缀。 | 

下表描述了可以在`parameters`对象中使用`deadline:`前缀设置的共享作业属性。


| Key | Type | 说明 | 
| --- | --- | --- | 
| `deadline:priority` | 整数 | 优先级 (0—100)。 | 
| `deadline:maxFailedTasksCount` | 整数 | 任务失败前的最大失败任务数。 | 
| `deadline:maxRetriesPerTask` | 整数 | 每个失败的任务的最大重试次数。 | 
| `deadline:maxWorkerCount` | 整数 | 并发工作人员的最大数量。 | 
| `deadline:targetTaskRunStatus` | 字符串 | 初始任务状态：`READY`或`SUSPENDED`。 | 

**注意**  
CLI-supplied `--parameter`值优先于挂钩`parameters`提供的值。

### Pre-submission 钩子
<a name="submission-hooks-pre-submission"></a>

Pre-submission hooks 在对作业附件进行哈希处理和上传之前运行。您可以使用提交前的挂钩来完成以下任务：
+ 验证作业配置
+ 发现并添加其他输入文件
+ 修改任务参数，例如优先级
+ 强制执行工作室政策

Pre-submission 如果失败（非零退出代码或超时），hooks 将阻止提交。

将 JSON 输出到标准输出以修改提交。挂钩输出取代了嵌套键级别的资产引用。如果您的挂钩输出`inputFilenames`，则挂钩输出将替换整个`inputFilenames`列表。Deadline Cloud 会保留您未包含在输出中的密钥。

以下示例将发现的纹理文件添加到提交中：

```
import json
import os
import sys

metadata = json.load(sys.stdin)
bundle_dir = metadata["jobBundleDir"]

textures = []
for root, _, files in os.walk(bundle_dir):
    for f in files:
        if f.endswith(('.exr', '.png', '.jpg', '.tx')):
            textures.append(os.path.join(root, f))

if textures:
    print(json.dumps({
        "attachments": {
            "assetReferences": {
                "inputFilenames": textures
            }
        }
    }))
```

Pre-submission hooks 还可以通过在 stdout 上发出`parameters`映射来修改作业模板的参数值：

```
print(json.dumps({"parameters": {"SceneFile": "/resolved/scene.ma", "Quality": "high"}}))
```

参数键是作业模板的参数名称。钩子中的值应用于捆绑包的参数值之上，但 CLI-supplied `--parameter`值仍然优先于钩子提供的值。

**重要**  
`PATH`stdout 上发出的参数必须是绝对的。钩子不是从提交的 shell 的工作目录中运行的，因此 stdout 上的相对`PATH`值是不明确的，会因错误而被拒绝。发出绝对路径（例如，join with`DEADLINE_JOB_BUNDLE_DIR`），或者改为将值写入磁盘`parameter_values.json`上`PATH`的`parameter_values.yaml`/，其中根据作业捆绑包目录解析相对路径。

### Post-submission 钩子
<a name="submission-hooks-post-submission"></a>

Post-submission 挂钩在 `CreateJob` API 调用成功返回后运行。目前，Deadline Cloud 已接受这份工作。您可以使用提交后挂钩来完成以下任务：
+ 发送通知（Slack、电子邮件）
+ 更新跟踪系统
+ 日志提交详情

Post-submission 挂接失败会记录为警告，但不会影响已提交的作业。

## 配置提交挂钩
<a name="submission-hooks-configuration"></a>

在`hooks.yaml`或`hooks.json`文件中定义挂钩。将文件放在作业捆绑包目录旁边`template.yaml`，或者放在指定的目录中`DEADLINE_HOOKS_DIR`。如果两种格式都存在于同一个目录中，则提交者会报告错误。

该`version`字段为必填字段，且必须为必填字段`"1.0"`。

以下示例显示了`hooks.yaml`配置：

```
version: "1.0"
preGUI:
  - command: python3
    args: [scripts/prefill_from_shotgrid.py]
    timeout: 10

preSubmission:
  - command: python3
    args: [scripts/validate_assets.py]
    timeout: 60
    env:
      VALIDATION_LEVEL: strict

  - command: python3
    args: [scripts/discover_textures.py]

postSubmission:
  - command: python3
    args: [scripts/notify_slack.py]
    timeout: 15
    env:
      SLACK_WEBHOOK: https://hooks.slack.com/...
```

### 挂钩定义字段
<a name="submission-hooks-definition-fields"></a>

每个挂钩条目都接受以下字段。


| 字段 | 必填 | 默认值 | Description | 
| --- | --- | --- | --- | 
| `command` | 是 | – | 可执行文件或解释器（例如，`python3`或`bash`）。 | 
| `args` | 否 | `[]` | Command-line 争论。 | 
| `timeout` | 否 | `60` | 以秒为单位的最大执行时间。 | 
| `env` | 否 | `{}` | 其他环境变量。Hooks 继承了提交者的完整环境。`DEADLINE_*`变量和任何特定于挂钩的`env`值都位于顶部。 | 

### 路径解决方案
<a name="submission-hooks-path-resolution"></a>

Hook 脚本是根据以下规则解析的：
+ **绝对路径**-按原样使用。
+ **相对路径**-相对于作业捆绑包目录进行解析。
+ **命令名**-在系统路径中搜索。

## 挂钩输入
<a name="submission-hooks-input"></a>

Hooks 通过 stdin 上的 JSON 和便捷环境变量接收任务元数据。

### 环境变量
<a name="submission-hooks-env-vars"></a>

以下环境变量适用于所有挂钩。


| 变量 | 说明 | 
| --- | --- | 
| `DEADLINE_JOB_NAME` | 作业名称。 | 
| `DEADLINE_PRIORITY` | Job 优先级。 | 
| `DEADLINE_FARM_ID` | 农场编号。 | 
| `DEADLINE_QUEUE_ID` | 队列 ID。 | 
| `DEADLINE_JOB_BUNDLE_DIR` | 作业捆绑包目录的路径。 | 
| `DEADLINE_STORAGE_PROFILE_ID` | 存储配置文件 ID（如果已设置）。 | 
| `DEADLINE_JOB_ID` | Job ID（仅限提交后的挂钩）。 | 

### 标准输入上的 JSON
<a name="submission-hooks-json-stdin"></a>

完整的元数据在 stdin 上以 JSON 形式提供。以下示例显示了结构：

```
{
  "jobName": "My Render Job",
  "priority": 50,
  "farmId": "farm-abc123",
  "queueId": "queue-def456",
  "jobBundleDir": "/path/to/bundle",
  "parameters": {"SceneFile": "/path/to/scene.ma"},
  "submitterName": "Maya",
  "assetReferences": {
    "inputFilenames": ["/path/to/texture.exr"],
    "inputDirectories": [],
    "outputDirectories": ["/path/to/output"],
    "referencedPaths": []
  },
  "submissionPayload": {}
}
```

## 安全性
<a name="submission-hooks-security"></a>

默认情况下，挂钩处于禁用状态。每个挂钩源都有自己的设置，您必须启用该设置。

### 启用捆绑挂钩
<a name="submission-hooks-enable-bundle"></a>

要允许在任务捆绑包`hooks.yaml`中定义挂钩，请启用捆绑挂钩设置。

**启用捆绑挂钩**
+ 运行以下命令：

  ```
  deadline config set settings.allow_bundle_hooks true
  ```

### 启用环境挂钩
<a name="submission-hooks-enable-environment"></a>

要允许从指定的目录进行挂钩`DEADLINE_HOOKS_DIR`，请启用环境挂钩设置并设置目录路径。

**启用环境挂钩**

1. 启用设置：

   ```
   deadline config set settings.allow_environment_hooks true
   ```

1. 通常在应用程序启动器脚本中设置环境变量：

   ```
   export DEADLINE_HOOKS_DIR=/studio/pipeline/hooks/blender
   ```

### 确认提示
<a name="submission-hooks-confirmation"></a>

启用挂钩后，提交者会在挂钩运行之前提示您进行确认。 Pre-GUI hooks 会在对话框打开之前显示提示。 Pre-submission 当你选择 Submit 时，提交后的挂钩会显示提示。

提示符显示将运行哪些命令，允许您在继续操作之前进行查看：

```
This job bundle contains submission hooks that will execute on your machine:

  Pre-GUI hooks:
    [1] python3 prefill_from_shotgrid.py

  Pre-submission hooks:
    [1] python3 validate_assets.py

  Post-submission hooks:
    [1] python3 notify.py

  Bundle: /path/to/bundle

Do you want to run these hooks? [Y/n]
```

要跳过 CI/automation 工作流程的确认提示，请运行以下命令：

```
deadline config set settings.auto_accept true
```

### 配置设置摘要
<a name="submission-hooks-config-summary"></a>


| 设置 | 默认值 | 说明 | 
| --- | --- | --- | 
| `settings.allow_bundle_hooks` | `false` | 指定是否允许使用作业捆绑包`hooks.yaml`文件进行挂接。 | 
| `settings.allow_environment_hooks` | `false` | 指定是否允许来自`DEADLINE_HOOKS_DIR`目录的挂钩。 | 
| `settings.auto_accept` | `false` | 指定是否跳过确认提示。在 CI/automation 环境中谨慎使用。 | 

## 工作室部署
<a name="submission-hooks-studio-deployment"></a>

Pipeline 技术主管可以通过跨工作站部署环境挂钩，将挂钩配置为自动为所有艺术家运行。当您的工作室拥有用于挂钩脚本的共享网络位置，并且您拥有配置艺术家工作站的管理权限时，请使用此过程。

**为工作室部署环境挂钩**

1. 配置工作站以允许环境挂钩：

   ```
   deadline config set settings.allow_environment_hooks true
   ```

1. `DEADLINE_HOOKS_DIR`在每个应用程序的启动器脚本中设置：

   ```
   # blender_launcher.sh
   export DEADLINE_HOOKS_DIR=/studio/pipeline/hooks/blender
   exec blender "$@"
   ```

1. 在指定位置创建挂钩：

   ```
   /studio/pipeline/hooks/blender/
   ├── hooks.yaml
   └── validate_scene.py
   ```

## 错误处理
<a name="submission-hooks-error-handling"></a>

当提交前或 GUI 之前的挂钩失败时，错误输出将包含以下信息：
+ 哪个挂钩失败了
+ 退出代码
+ stdout 和 stderr 输出
+ 超时持续时间（如果挂钩超时）

在您解决问题之前，提交者会阻止提交。 Post-submission 挂接失败会记录为警告，但不会影响已提交的作业。

## 最佳实践
<a name="submission-hooks-best-practices"></a>
+ **保持快速挂钩。**设置适当的超时时间，避免在挂钩中长时间运行操作。
+ **登录到 stderr。**为 GUI 前和提交前挂钩中的 JSON 输出保留标准输出。
+ **优雅地处理错误。**在 stderr 上提供清晰的错误消息，以便用户可以识别出问题所在。
+ **首先使用 CLI 进行测试。**CLI 提交比 GUI 提交更容易调试。
+ **在输出中使用绝对路径。**将文件添加到资源引用时，请始终使用绝对路径。
+ **使用环境挂钩制定工作室范围的策略。**环境挂钩比捆绑挂钩更安全，因为它们是由工作室而不是捆绑包作者控制的。
+ **启用之前请查看捆绑包挂钩。**`hooks.yaml`在允许包挂钩运行之前，请先检查来自不受信任来源的捆绑包。

## 提交方法
<a name="submission-hooks-cli-gui"></a>

Hooks 可使用以下提交方法：
+ `deadline bundle submit`(CLI) — Pre-submission 然后运行提交后的挂钩。CLI 没有 GUI 阶段，因此 GUI 之前的挂钩不适用。
+ `deadline bundle gui-submit`（独立 GUI）— 所有阶段都运行，包括 GUI 之前的挂钩。
+ In-application (DCC) 提交者——提交后挂 Pre-submission 钩会运行。DCC 提交者不会调用 GUI 之前的阶段。

独立 GUI 会复制`hooks.yaml`到作业历史包中，并将脚本路径解析回原始包目录。

## 其他资源
<a name="submission-hooks-related"></a>

有关集成点和相关主题的更多信息，请参阅以下内容：
+ [作业的挂钩、事件和集成点](integration-points.md)
+ [如何向 Deadline Cloud 提交工作](submit-jobs-how.md)
+ [创建要提交到截止日期云的作业](building-jobs.md)
+ 网站上的 d@@ [eadline-cloud](https://github.com/aws-deadline/deadline-cloud) 存储库 GitHub 