如何執行 oc start-build

oc start-build 是 OpenShift 裡很方便的一個指令,事先建立好 build config 以後,就可以用 start-build 來指示 openshift 來幫忙建置,在建置完成以後,就自動完成佈署了。

等等,那 oc start-build 不是直接用 command/shell 模組就可以完成了嗎?為什麼還需要特別寫? 這是因為使用指令的話,在同時執行多個工作時,在後續的 oc get 會有些問題,所以才想去試試。

我在 Ansible 模組相關的文件裡去找,找了許久,都沒有找到適當的模組可以幫我完成這件事情。 後來不得已,才去看 oc 這個指令的原始碼,這才看到 oc 其實也是用 OpenShift 的 API 來進行這些事情。

原始碼網址:oc/buildinstantiatebinary.go at 4c2094c1d599734b770d74b2772651d5ff21fa1b · openshift/oc

func (c *buildInstatiateBinary) InstantiateBinary(name string, options *buildv1.BinaryBuildRequestOptions, r io.Reader) (*buildv1.Build, error) {
	result := &buildv1.Build{}
	err := c.client.Post().
		Namespace(c.ns).
		Resource("buildconfigs").
		Name(name).
		SubResource("instantiatebinary").
		Body(r).
		VersionedParams(options, scheme.ParameterCodec).
		Do(context.TODO()).
		Into(result)
	return result, err
}

從 go 的程式大致可以猜到網址是 buildconfigs ,也有 instantiatebinary

循線去找 OpenShift API ,就找到了:BuildConfig [build.openshift.io/v1] - Workloads APIs | API reference | OpenShift Container Platform 4.6

那接下來,使用 uri 模組就可以完成我想做的事情了。

---
- name: Test `oc start-build`
  hosts: localhost
  
  vars:
    openshift_api_host: "https://api.example.com:6443"
    openshift_username: "user"
    openshift_password: "pass"
    openshift_project_name: "example-project"
    openshift_app_name: "example-app"
    validate_certs: false
    artifact_path: "build/artifact.jar"

  tasks:
    - name: Log in (obtain access token)
      community.okd.openshift_auth:
        host: "{{ openshift_api_host }}"
        username: "{{ openshift_username }}"
        password: "{{ openshift_password }}"
        validate_certs: "{{ validate_certs }}"
      register: openshift_auth_results
      
    - name: Read file content
      slurp:
        path: "{{ artifact_path }}"
      register: bin_file

    - name: Run `oc start-build`
      uri:
        url: "{{ openshift_api_host }}/apis/build.openshift.io/v1/namespaces/{{ openshift_project_name }}/buildconfigs/build-{{ openshift_app_name }}/instantiatebinary?name=build-{{ openshift_app_name }}&namespace={{ openshift_project_name }}&asFile={{ artifact_path | basename }}"
        headers:
          Accept: "application/json"
          Content-Type: "application/octet-stream"
          Authorization: "Bearer {{ openshift_auth_results.openshift_auth.api_key }}"
        method: POST
        validate_certs: "{{ validate_certs }}"
        body: "{{ bin_file.content }}"
        status_code: 
          - 200
          - 201
        timeout: 900
      register: openshift_start_build_result

    - name: Display build name
      debug:
        msg: "build name={{ openshift_start_build_result.json.metadata.name }}"

第一個 task 先使用 community.okd.openshift_auth 進行登入,透過這個 task 的結果,可以取得 API token。

第二個 task 來使用 slurp 讀入檔案內容。

第三個 task 使用 uri 送出 HTTP POST

  • url: 填入的就是 API 的網址,比較需要注意的地方有兩個
    • 第一個是 path parameter,前面要帶入 Project name,後面要帶入 build config name
    • 第二個是 Query parameter,這邊依照文件,必須要再一次帶入 Project name 跟 build config name,然後再帶入文件裡所說的 guery 參數,這裡我就只填 asFile,值是 artifact 的檔名。
  • headers: HTTP 標頭,主要是要帶入前面所取得的 API token,並且用 Content-Type 指示這次是要上傳檔案。
  • body: 因為我使用的 oc start-build 主要帶入的參數是 –from-file,所以這邊就要帶入前面讀入的檔案內容。

這樣就可以順利呼叫到 start-build 了,請求的內容會是建立出來的 build 內容,所以可以用 openshift_start_build_result.json.metadata.name 來取得 build name

現在可以順利進行 start-build 了,那麼該怎麼取得 build 的狀況呢?下期待續。