流水线模板组合思路

官方流水线示例中没有给出完整的流水线模板和完整的字段,只给出了一个大致的 schema [1],如下所示

json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
{
  "schema": "v2",
  "variables": [
    {
      "type": "<type>",
      "defaultValue": <value>,
      "description": "<description>",
      "name": "<varName>"
    }
  ],
  "id": "<templateName>",           # The pipeline instance references the template using this
  "protect": <true | false>,
  "metadata": {
    "name": "displayName",          # The display name shown in Deck
    "description": "<description>",
    "owner": "example@example.com",
    "scopes": ["global"]            # Not used
  },
  "pipeline": {                     # Contains the templatized pipeline itself
    "lastModifiedBy": "anonymous",  # Not used
    "updateTs": "0",                # Not used
    "parameterConfig": [],          # Same as in a regular pipeline
    "limitConcurrent": true,        # Same as in a regular pipeline
    "keepWaitingPipelines": false,  # Same as in a regular pipeline
    "description": "",              # Same as in a regular pipeline
    "triggers": [],                 # Same as in a regular pipeline
    "notifications": [],            # Same as in a regular pipeline
    "stages": [                     # Contains the templated stages
      {
        # This one is an example stage:
        "waitTime": "${ templateVariables.waitTime }",  # Templated field.
        "name": "My Wait Stage",
        "type": "wait",
        "refId": "wait1",
        "requisiteStageRefIds": []
      }
    ]
  }
}

这个流水线模板的 Schema 只包含了大的框架,但是 Spinnaker 的每种类型的 Stage 的 Schema 并没有包含里面,需要自行定义,最好的一个思路就是,先手动先创建一个 {ipeline,然后编辑这个 Pipeline 的 Json 复制出想要的 Stage 的内容,然后再根据 Pipeline Template 的模板进行填充。

例如,我们想顶一个选择 “多路分支” 的流水线,那么流水线类型如下

image-20240727212507497

图:spinnaker流水线结构

然后选择 “Edit stage as Json” 或者选择 “Pipeline Actions” 中 “Edit as JSON” 可以查看到该 Stage 或该 Pipelin 完整的 JSON 格式数据。

image-20240727212652058

图:Pipeline Stage JSON

image-20240727212803192

图:Pipeline JSON

最后将 Stage 的 JSON 复制 到 template Stage 的 数组中即可,下面是一个 Check Precondition 类型的 State 的 JSON

json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
  "completeOtherBranchesThenFail": false,
  "continuePipeline": false,
  "failPipeline": false,
  "name": "选择禁用是否启用配置注册",
  "notifications": [],
  "preconditions": [
    {
      "context": {
        "expression": "${ #judgment('check condition') == 'disable' }"
      },
      "failPipeline": true,
      "type": "expression"
    }
  ],
  "type": "checkPreconditions"
}

完整的基于分支判断的流水线模板示例

该模板是一个为 k8s deployment 启用/禁用 HPA 功能的流水线模板

yaml
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
{
  "id": "a422e02d0ab94ce23jk92a6d2bf8ff9c",
  "lastModifiedBy": "cylon",
  "metadata": {
    "description": "启用或停用 HPA",
    "name": "HPA Turn on or Turn off",
    "owner": "cylonchau@outlook.com",
    "scopes": [
      "global"
    ]
  },
  "pipeline": {
    "expectedArtifacts": [
      {
        "defaultArtifact": {
          "artifactAccount": "k8s-cluster-102",
          "reference": "https://git.chinamobile.cn/api/v4/projects/154/repository/files/hpa%2Fk8s-cluster-102%2F${ templateVariables.appName }.yaml/raw",
          "type": "gitlab/file",
          "version": "master"
        },
        "displayName": "${ templateVariables.appName }-hpa-file",
        "id": "${ templateVariables.appName }-hpa",
        "matchArtifact": {
          "artifactAccount": "k8s-cluster-102",
          "name": "https://git.chinamobile.cn/api/v4/projects/154/repository/files/hpa%2Fk8s-cluster-102%2F${ templateVariables.appName }.yaml/raw",
          "type": "gitlab/file"
        },
        "useDefaultArtifact": true,
        "usePriorArtifact": false
      }
    ],
    "keepWaitingPipelines": false,
    "limitConcurrent": true,
    "parameterConfig": [],
    "stages": [
      {
        "instructions": "请选择条件: \n\tenable 启用 ${ templateVariables.appName } HPA Autoscaler\n\tdisable 禁用HPA Autoscaler\n",
        "judgmentInputs": [
          {
            "value": "enable"
          },
          {
            "value": "disable"
          }
        ],
        "name": "Apply",
        "completeOtherBranchesThenFail": false,
        "continuePipeline": false,
        "failPipeline": false,
        "notifications": [],
        "propagateAuthenticationContext": false,
        "refId": "7",
        "requisiteStageRefIds": [],
        "type": "manualJudgment"
      },
      {
        "completeOtherBranchesThenFail": false,
        "continuePipeline": false,
        "failPipeline": false,
        "name": "选择禁用 ${ templateVariables.appName } HPA",
        "preconditions": [
          {
            "context": {
              "expression": "${ #judgment('Apply') == 'disable' }"
            },
            "failPipeline": true,
            "type": "expression"
          }
        ],
        "refId": "9",
        "requisiteStageRefIds": [
          "7"
        ],
        "type": "checkPreconditions"
      },
      {
        "name": "选择启用 ${ templateVariables.appName } HPA",
        "completeOtherBranchesThenFail": false,
        "continuePipeline": false,
        "failPipeline": false,
        "preconditions": [
          {
            "context": {
              "expression": "${ #judgment('Apply HPA') == 'enable' }"
            },
            "failPipeline": true,
            "type": "expression"
          }
        ],
        "refId": "10",
        "requisiteStageRefIds": [
          "7"
        ],
        "type": "checkPreconditions"
      },
      {
        "account": "${ templateVariables.dcName }",
        "app": "${ templateVariables.appName }",
        "cloudProvider": "kubernetes",
        "completeOtherBranchesThenFail": false,
        "continuePipeline": false,
        "failPipeline": false,
        "isNew": true,
        "location": " ${ templateVariables.appLocation }",
        "manifestName": "horizontalpodautoscaler ${ templateVariables.appName }-autoscaler",
        "mode": "static",
        "name": "禁用 ${ templateVariables.appName } HPA",
        "options": {
          "cascading": false,
          "gracePeriodSeconds": 300
        },
        "refId": "12",
        "requisiteStageRefIds": [
          "9"
        ],
        "type": "deleteManifest"
      },
      {
        "account": "${ templateVariables.dcName }",
        "cloudProvider": "kubernetes",
        "manifestArtifactAccount": "k8s-cluster-102",
        "manifestArtifactId": "${ templateVariables.appName }-hpa",
        "completeOtherBranchesThenFail": false,
        "continuePipeline": false,
        "failPipeline": false,
        "moniker": {
          "app": "${ templateVariables.appName }"
        },
        "name": "启用 ${ templateVariables.appName } HPA",
        "refId": "11",
        "requisiteStageRefIds": [
          "10"
        ],
        "skipExpressionEvaluation": false,
        "source": "artifact",
        "stageTimeoutMs": 500000,
        "trafficManagement": {
          "enabled": false,
          "options": {
            "enableTraffic": false,
            "services": []
          }
        },
        "type": "deployManifest"
      }
    ],
    "triggers": []
  },
  "protect": false,
  "schema": "v2",
  "tag": null,
  "updateTs": "1701832158029",
  "variables": [
    {
      "defaultValue": "k8s-cluster-102",
      "description": "要部署到的集群",
      "name": "dcName",
      "type": "string"
    },
    {
      "defaultValue": "",
      "description": "模块名称",
      "name": "appName",
      "type": "string"
    },
    {
      "defaultValue": "public",
      "description": "名称空间",
      "name": "appLocation",
      "type": "string"
    }
  ]
}

Reference

[1] Pipeline template JSON