Chapter 2. Configuring build strategies In a BuildStrategy or ClusterBuildStrategy custom resource (CR), you can define strategy parameters, system parameters, step resources definitions, annotations, and volumes to configure a build strategy. A BuildStrategy resource is available for use within a namespace, and a ClusterBuildStrategy resource is available for use throughout the cluster. To configure a build strategy, create a BuildStrategy or ClusterBuildStrategy resource YAML file and apply it to the OpenShift Container Platform cluster. 2.1. Strategy parameters definition You can define strategy parameters in a BuildStrategy or ClusterBuildStrategy custom resource (CR) and set, or modify, the values of those parameters in your Build or BuildRun CR. You can also configure or modify strategy parameters at build time when creating your build strategy. Consider the following points before defining parameters for your strategy: Define a list of parameters in the spec.parameters field of your build strategy CR. Each list item contains a name, a description, a type, and an optional default value, or values, for an array type. If no default value is set, you must define a value in the Build or BuildRun CR. Define parameters of string or array type in the spec.steps field of your build strategy. Specify a parameter of string type by using the USD(params.your-parameter-name) syntax. You can set a value for the your-parameter-name parameter in your Build or BuildRun CR that references your strategy. You can define the following string parameters based on your needs: Table 2.1. String parameters Parameter Description image Use this parameter to define a custom tag, such as golang:USD(params.go-version) args Use this parameter to pass data into your builder commands env Use this parameter to provide a value for an environment variable Specify a parameter of array type by using the USD(params.your-array-parameter-name[*]) syntax. After specifying the array, you can use it in an argument or a command. For each item in the array, an argument will be set. The following example uses an array parameter in the spec.steps field of the build strategy: apiVersion: shipwright.io/v1beta1 kind: ClusterBuildStrategy metadata: name: <cluster_build_strategy_name> # ... spec: parameters: - name: tool-args description: Parameters for the tool type: array steps: - name: a-step command: - some-tool args: - --tool-args - USD(params.tool-args[*]) Provide parameter values as simple strings or as references to keys in config maps or secrets. For a parameter, you can use a config map or secret value only if it is defined in the command , args , or env section of the spec.steps field. 2.2. System parameters definition You can use system parameters when defining the steps of a build strategy to access system information, or user-defined information in a Build or BuildRun custom resource (CR). You cannot configure or modify system parameters as they are defined at runtime by the build run controller. You can define the following system parameters in your build strategy definition: Table 2.2. System parameters Parameter Description USD(params.shp-source-root) Denotes the absolute path to the directory that contains the source code. USD(params.shp-source-context) Denotes the absolute path to the context directory of the source code. If you do not specify any value for spec.source.contextDir in the Build CR, this parameter uses the value of the USD(params.shp-source-root) system parameter. USD(params.shp-output-image) Denotes the URL of the image to push as defined in the spec.output.image field of your Build or BuildRun CR. 2.3. Step resources definition You can include a definition of resources, such as the limit imposed on CPU, memory, and disk usage for all steps in a build strategy. For strategies with multiple steps, a step might require more resources than others. As a strategy administrator, you can define the resource values that are optimal for each step. For example, you can install strategies with the same steps, but different names and step resources on the cluster so that users can create a build with smaller or larger resource requirements. 2.3.1. Strategies with different resources Define multiple types of the same strategy with varying limits on the resources. The following examples use the same buildah strategy with small and medium limits defined for the resources. These examples provide a strategy administrator more control over the step resources definition. 2.3.1.1. Buildah strategy with small limit Define the spec.steps[].resources field with a small resource limit for the buildah strategy, as shown in the following example: Example: buildah strategy with small limit apiVersion: shipwright.io/v1beta1 kind: ClusterBuildStrategy metadata: name: buildah-small spec: steps: - name: build-and-push image: quay.io/containers/buildah:v1.31.0 workingDir: USD(params.shp-source-root) securityContext: capabilities: add: - "SETFCAP" command: - /bin/bash args: - -c - | set -euo pipefail # Parse parameters # ... # That's the separator between the shell script and its args - -- - --context - USD(params.shp-source-context) - --dockerfile - USD(build.dockerfile) - --image - USD(params.shp-output-image) - --build-args - USD(params.build-args[*]) - --registries-block - USD(params.registries-block[*]) - --registries-insecure - USD(params.registries-insecure[*]) - --registries-search - USD(params.registries-search[*]) resources: limits: cpu: 250m memory: 65Mi requests: cpu: 250m memory: 65Mi parameters: - name: build-args description: "The values for the args in the Dockerfile. Values must be in the format KEY=VALUE." type: array defaults: [] # ... 2.3.1.2. Buildah strategy with medium limit Define the spec.steps[].resources field with a medium resource limit for the buildah strategy, as shown in the following example: Example: buildah strategy with medium limit apiVersion: shipwright.io/v1beta1 kind: ClusterBuildStrategy metadata: name: buildah-medium spec: steps: - name: build-and-push image: quay.io/containers/buildah:v1.31.0 workingDir: USD(params.shp-source-root) securityContext: capabilities: add: - "SETFCAP" command: - /bin/bash args: - -c - | set -euo pipefail # Parse parameters # ... # That's the separator between the shell script and its args - -- - --context - USD(params.shp-source-context) - --dockerfile - USD(build.dockerfile) - --image - USD(params.shp-output-image) - --build-args - USD(params.build-args[*]) - --registries-block - USD(params.registries-block[*]) - --registries-insecure - USD(params.registries-insecure[*]) - --registries-search - USD(params.registries-search[*]) resources: limits: cpu: 500m memory: 1Gi requests: cpu: 500m memory: 1Gi parameters: - name: build-args description: "The values for the args in the Dockerfile. Values must be in the format KEY=VALUE." type: array defaults: [] # ... After configuring the resource definition for a strategy, you must reference the strategy in your Build CR, as shown in the following example: apiVersion: shipwright.io/v1beta1 kind: Build metadata: name: buildah-medium spec: source: git: url: https://github.com/shipwright-io/sample-go contextDir: docker-build strategy: name: buildah-medium kind: ClusterBuildStrategy # ... 2.3.2. Resource management in Tekton pipelines The build controller works with the Tekton pipeline controller so that it can schedule pods for executing the strategy steps. At runtime, the build controller creates a Tekton TaskRun resource, and the TaskRun resource creates a new pod in the specific namespace. This pod then sequentially executes all of the strategy steps to build an image. 2.4. Annotations definition You can define annotations for a build strategy or a cluster build strategy like for any other Kubernetes object. The build strategy first propagates annotations to the TaskRun resource. Then, Tekton propagates them to the pod. You can use annotations for the following purposes: To limit the network bandwidth the pod is allowed to use, the kubernetes.io/ingress-bandwidth and kubernetes.io/egress-bandwidth annotations are defined in the Kubernetes network traffic shaping feature. To define the AppArmor profile of a container, the container.apparmor.security.beta.kubernetes.io/<container_name> annotation is used. The following example shows the usage of annotations in a build strategy: apiVersion: shipwright.io/v1beta1 kind: ClusterBuildStrategy metadata: name: <cluster_build_strategy_name> annotations: container.apparmor.security.beta.kubernetes.io/step-build-and-push: unconfined container.seccomp.security.alpha.kubernetes.io/step-build-and-push: unconfined spec: # ... The following annotations are not propagated: kubectl.kubernetes.io/last-applied-configuration clusterbuildstrategy.shipwright.io/* buildstrategy.shipwright.io/* build.shipwright.io/* buildrun.shipwright.io/* A strategy administrator can further restrict the usage of annotations by using policy engines. 2.5. Secure referencing of string parameters String parameters are used when you define environment variables, arguments, or images in a BuildStrategy or ClusterBuildStrategy custom resource (CR). In your build strategy steps, you can reference string parameters by using the USD(params.your-parameter-name) syntax. Note You can also reference system parameters and strategy parameters by using the USD(params.your-parameter-name) syntax in your build strategy steps. In the pod, all USD(params.your-parameter-name) variables are replaced by actual strings. However, you must pay attention when you reference a string parameter in an argument by using an inline script. For example, to securely pass a parameter value into an argument defined with a script, you can choose one of the following approaches: Use environment variables Use arguments Example: Referencing a string parameter into an environment variable You can pass the string parameter into an environment variable, instead of directly using it inside the script. By using quoting around the environment variable, you can avoid the command injection vulnerability. You can use this approach for strategies, such as buildah . The following example uses an environment variable inside the script to reference a string parameter: apiVersion: shipwright.io/v1beta1 kind: BuildStrategy metadata: name: sample-strategy spec: parameters: - name: sample-parameter description: A sample parameter type: string steps: - name: sample-step env: - name: PARAM_SAMPLE_PARAMETER value: USD(params.sample-parameter) command: - /bin/bash args: - -c - | set -euo pipefail some-tool --sample-argument "USD{PARAM_SAMPLE_PARAMETER}" Example: Referencing a string parameter into an argument You can pass the string parameter into an argument defined within your script. Appropriate shell quoting guards against command injection. You can use this approach for strategies, such as buildah . The following example uses an argument defined within your script to reference a string parameter: apiVersion: shipwright.io/v1beta1 kind: BuildStrategy metadata: name: sample-strategy spec: parameters: - name: sample-parameter description: A sample parameter type: string steps: - name: sample-step command: - /bin/bash args: - -c - | set -euo pipefail SAMPLE_PARAMETER="USD1" some-tool --sample-argument "USD{SAMPLE_PARAMETER}" - -- - USD(params.sample-parameter) 2.6. System results definition You can store the size and digest of the image that is created by your build strategy to a set of result files. You can also store error details for debugging purposes when a BuildRun resource fails. You can define the following result parameters in your BuildStrategy or ClusterBuildStrategy CR: Table 2.3. Result parameters Parameter Description USD(results.shp-image-digest.path) Denotes the path to the file that stores the digest of the image. USD(results.shp-image-size.path) Denotes the path to the file that stores the compressed size of the image. USD(results.shp-error-reason.path) Denotes the path to the file that stores the error reason. USD(results.shp-error-message.path) Denotes the path to the file that stores the error message. The following example shows the size and digest of the image in the .status.output field of the BuildRun CR: apiVersion: shipwright.io/v1beta1 kind: BuildRun # ... status: # ... output: digest: sha256:07626e3c7fdd28d5328a8d6df8d29cd3da760c7f5e2070b534f9b880ed093a53 size: 1989004 # ... The following example shows the error reason and message in the .status.failureDetails field of the BuildRun CR: apiVersion: shipwright.io/v1beta1 kind: BuildRun # ... status: # ... failureDetails: location: container: step-source-default pod: baran-build-buildrun-gzmv5-b7wbf-pod-bbpqr message: The source repository does not exist, or you have insufficient permission to access it. reason: GitRemotePrivate 2.7. Volumes and volume mounts definition A build strategy includes the definition of volumes and volume mounts. The volumes defined in a build strategy support all of the usual volumeSource types. The build steps refer to the volumes by creating a volume mount. Note The volume mount defined in build steps allows you to access volumes defined in a BuildStrategy , Build or BuildRun resource. Volumes in build strategy use an overridable boolean flag, which is set to false by default. If a Build or BuildRun resource tries to override the volumes defined in a BuildStrategy resource, it will fail because the default value of the overridable flag is false . The following example shows a BuildStrategy resource that defines the volumes and volumeMounts fields: apiVersion: shipwright.io/v1beta1 kind: BuildStrategy metadata: name: buildah spec: steps: - name: build image: quay.io/containers/buildah:v1.23.3 # ... volumeMounts: - name: varlibcontainers mountPath: /var/lib/containers volumes: - name: varlibcontainers overridable: true emptyDir: {}

Commands:
apiVersion: shipwright.io/v1beta1 kind: ClusterBuildStrategy metadata: name: <cluster_build_strategy_name> # spec: parameters: - name: tool-args description: Parameters for the tool type: array steps: - name: a-step command: - some-tool args: - --tool-args - USD(params.tool-args[*])
apiVersion: shipwright.io/v1beta1 kind: ClusterBuildStrategy metadata: name: buildah-small spec: steps: - name: build-and-push image: quay.io/containers/buildah:v1.31.0 workingDir: USD(params.shp-source-root) securityContext: capabilities: add: - "SETFCAP" command: - /bin/bash args: - -c - | set -euo pipefail # Parse parameters # # That's the separator between the shell script and its args - -- - --context - USD(params.shp-source-context) - --dockerfile - USD(build.dockerfile) - --image - USD(params.shp-output-image) - --build-args - USD(params.build-args[*]) - --registries-block - USD(params.registries-block[*]) - --registries-insecure - USD(params.registries-insecure[*]) - --registries-search - USD(params.registries-search[*]) resources: limits: cpu: 250m memory: 65Mi requests: cpu: 250m memory: 65Mi parameters: - name: build-args description: "The values for the args in the Dockerfile. Values must be in the format KEY=VALUE." type: array defaults: [] #
apiVersion: shipwright.io/v1beta1 kind: ClusterBuildStrategy metadata: name: buildah-medium spec: steps: - name: build-and-push image: quay.io/containers/buildah:v1.31.0 workingDir: USD(params.shp-source-root) securityContext: capabilities: add: - "SETFCAP" command: - /bin/bash args: - -c - | set -euo pipefail # Parse parameters # # That's the separator between the shell script and its args - -- - --context - USD(params.shp-source-context) - --dockerfile - USD(build.dockerfile) - --image - USD(params.shp-output-image) - --build-args - USD(params.build-args[*]) - --registries-block - USD(params.registries-block[*]) - --registries-insecure - USD(params.registries-insecure[*]) - --registries-search - USD(params.registries-search[*]) resources: limits: cpu: 500m memory: 1Gi requests: cpu: 500m memory: 1Gi parameters: - name: build-args description: "The values for the args in the Dockerfile. Values must be in the format KEY=VALUE." type: array defaults: [] #
apiVersion: shipwright.io/v1beta1 kind: Build metadata: name: buildah-medium spec: source: git: url: https://github.com/shipwright-io/sample-go contextDir: docker-build strategy: name: buildah-medium kind: ClusterBuildStrategy #
apiVersion: shipwright.io/v1beta1 kind: ClusterBuildStrategy metadata: name: <cluster_build_strategy_name> annotations: container.apparmor.security.beta.kubernetes.io/step-build-and-push: unconfined container.seccomp.security.alpha.kubernetes.io/step-build-and-push: unconfined spec: #
apiVersion: shipwright.io/v1beta1 kind: BuildStrategy metadata: name: sample-strategy spec: parameters: - name: sample-parameter description: A sample parameter type: string steps: - name: sample-step env: - name: PARAM_SAMPLE_PARAMETER value: USD(params.sample-parameter) command: - /bin/bash args: - -c - | set -euo pipefail some-tool --sample-argument "USD{PARAM_SAMPLE_PARAMETER}"
apiVersion: shipwright.io/v1beta1 kind: BuildStrategy metadata: name: sample-strategy spec: parameters: - name: sample-parameter description: A sample parameter type: string steps: - name: sample-step command: - /bin/bash args: - -c - | set -euo pipefail SAMPLE_PARAMETER="USD1" some-tool --sample-argument "USD{SAMPLE_PARAMETER}" - -- - USD(params.sample-parameter)
apiVersion: shipwright.io/v1beta1 kind: BuildRun status: # output: digest: sha256:07626e3c7fdd28d5328a8d6df8d29cd3da760c7f5e2070b534f9b880ed093a53 size: 1989004 #
apiVersion: shipwright.io/v1beta1 kind: BuildRun status: # failureDetails: location: container: step-source-default pod: baran-build-buildrun-gzmv5-b7wbf-pod-bbpqr message: The source repository does not exist, or you have insufficient permission to access it. reason: GitRemotePrivate
apiVersion: shipwright.io/v1beta1 kind: BuildStrategy metadata: name: buildah spec: steps: - name: build image: quay.io/containers/buildah:v1.23.3 # volumeMounts: - name: varlibcontainers mountPath: /var/lib/containers volumes: - name: varlibcontainers overridable: true emptyDir: {}