diff --git a/docs/build.md b/docs/build.md index 110748371..fe1016455 100644 --- a/docs/build.md +++ b/docs/build.md @@ -80,7 +80,7 @@ The `Build` definition supports the following fields: - `spec.output.credentials.name`- Reference an existing secret to get access to the container registry. - Optional: - - `spec.paramValues` - Refers to a list of `key/value` that could be used to loosely type `parameters` in the `BuildStrategy`. + - `spec.paramValues` - Refers to a name-value(s) list to specify values for `parameters` defined in the `BuildStrategy`. - `spec.dockerfile` - Path to a Dockerfile to be used for building an image. (_Use this path for strategies that require a Dockerfile_) - `spec.sources` - [Sources](#Sources) describes a slice of artifacts that will be imported into project context, before the actual build process starts. - `spec.timeout` - Defines a custom timeout. The value needs to be parsable by [ParseDuration](https://golang.org/pkg/time/#ParseDuration), for example `5m`. The default is ten minutes. The value can be overwritten in the `BuildRun`. @@ -240,60 +240,167 @@ spec: ### Defining ParamValues -A `Build` resource can specify _params_, these allow users to modify the behaviour of the referenced `BuildStrategy` steps. +A `Build` resource can specify _paramValues_ for parameters that are defined in the referenced `BuildStrategy`. This allows one to control how the steps of the build strategy behave. Values can be overwritten in the `BuildRun` resource. See the related [documentation](./buildrun.md#defining-params) for more information. -When using _params_, users should avoid: +The build strategy author can define a parameter to be either a simple string, or an array. Depending on that, you must specify the value accordingly. The build strategy parameter can be specified with a default value. For parameters without a default, a value must be specified in the `Build` or `BuildRun`. + +You can either specify values directly, or reference keys from [ConfigMaps](https://kubernetes.io/docs/concepts/configuration/configmap/) and [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/). **Note**: the usage of ConfigMaps and Secrets is limited by the usage of the parameter in the build strategy steps. You can only use them if the parameter is used in the command, arguments, or as environment variable values. + +When using _paramValues_, users should avoid: - Defining a `spec.paramValues` name that doesn't match one of the `spec.parameters` defined in the `BuildStrategy`. -- Defining a `spec.paramValues` name that collides with the Shipwright reserved parameters. These are _BUILDER_IMAGE_,_DOCKERFILE_,_CONTEXT_DIR_ and any name starting with _shp-_. +- Defining a `spec.paramValues` name that collides with the Shipwright reserved parameters. These are _BUILDER\_IMAGE_, _DOCKERFILE_, _CONTEXT\_DIR_ and any name starting with _shp-_. -In general, _params_ are tighly bound to Strategy _parameters_, please make sure you understand the contents of your strategy of choice, before defining _params_ in the _Build_. `BuildRun` resources allow users to override `Build` _params_, see the related [docs](./buildrun.md#defining-params) for more information. +In general, _paramValues_ are tightly bound to Strategy _parameters_, please make sure you understand the contents of your strategy of choice, before defining _paramValues_ in the _Build_. #### Example -The following `BuildStrategy` contains a single step ( _a-strategy-step_ ) with a command and arguments. The strategy defines a parameter( _sleep-time_ ) with a reasonable default, that is used in the step arguments, see _$(params.sleep-time)_. +The [BuildKit sample `BuildStrategy`](../samples/buildstrategy/buildkit/buildstrategy_buildkit_cr.yaml) contains various parameters. Two of them are outlined here: ```yaml ---- apiVersion: shipwright.io/v1alpha1 -kind: BuildStrategy +kind: ClusterBuildStrategy metadata: - name: sleepy-strategy + name: buildkit + ... spec: parameters: - - name: sleep-time - description: "time in seconds for sleeping" - default: "1" + - name: build-args + description: "The values for the ARGs in the Dockerfile. Values must be in the format KEY=VALUE." + type: array + defaults: [] + - name: cache + description: "Configure BuildKit's cache usage. Allowed values are 'disabled' and 'registry'. The default is 'registry'." + type: string + default: registry + ... buildSteps: - - name: a-strategy-step - image: alpine:latest - command: - - sleep - args: - - $(params.sleep-time) + ... ``` -If users would like the above strategy to change its behaviour, e.g. _allow the step to trigger a sleep cmd longer than 1 second_, then users can modify the default behaviour, via their `Build` `spec.paramValues` definition. For example: +The `cache` parameter is a simple string. You can provide it like this in your Build: ```yaml ---- apiVersion: shipwright.io/v1alpha1 kind: Build metadata: name: a-build + namespace: a-namespace spec: + paramValues: + - name: cache + value: disabled + strategy: + name: buildkit + kind: ClusterBuildStrategy source: - url: https://github.com/shipwright-io/sample-go - contextDir: docker-build/ + ... + output: + ... +``` + +If you have multiple Builds and want to centrally control this parameter, then you can create a ConfigMap: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: buildkit-configuration + namespace: a-namespace +data: + cache: disabled +``` + +You reference the ConfigMap as a parameter value like this: + +```yaml +apiVersion: shipwright.io/v1alpha1 +kind: Build +metadata: + name: a-build + namespace: a-namespace +spec: + paramValues: + - name: cache + configMapValue: + name: buildkit-configuration + key: cache + strategy: + name: buildkit + kind: ClusterBuildStrategy + source: + ... + output: + ... +``` + +The `build-args` parameter is defined as an array. In the BuildKit strategy, it is used to set the values of [`ARG`s in the Dockerfile](https://docs.docker.com/engine/reference/builder/#arg), specified as key-value pairs separated by an equals sign, for example `NODE_VERSION=16`. Your Build then looks like this (the value for `cache` is retained to outline how multiple _paramValue_ can be set): + +```yaml +apiVersion: shipwright.io/v1alpha1 +kind: Build +metadata: + name: a-build + namespace: a-namespace +spec: paramValues: - - name: sleep-time - value: "60" + - name: cache + configMapValue: + name: buildkit-configuration + key: cache + - name: build-args + values: + - value: NODE_VERSION=16 strategy: - name: sleepy-strategy - kind: BuildStrategy + name: buildkit + kind: ClusterBuildStrategy + source: + ... + output: + ... ``` -The above `Build` definition uses _sleep-time_ param, a well-defined _parameter_ under its referenced `BuildStrategy`. By doing this, the user signalizes to the referenced sleepy-strategy, the usage of a different value for its _sleep-time_ parameter. +Similar to simple values, you can also reference ConfigMaps and Secrets for every item in the array. Example: + +```yaml +apiVersion: shipwright.io/v1alpha1 +kind: Build +metadata: + name: a-build + namespace: a-namespace +spec: + paramValues: + - name: cache + configMapValue: + name: buildkit-configuration + key: cache + - name: build-args + values: + - configMapValue: + name: project-configuration + key: node-version + format: NODE_VERSION=${CONFIGMAP_VALUE} + - value: DEBUG_MODE=true + - secretValue: + name: npm-registry-access + key: npm-auth-token + format: NPM_AUTH_TOKEN=${SECRET_VALUE} + strategy: + name: buildkit + kind: ClusterBuildStrategy + source: + ... + output: + ... +``` + +Here, we pass three items in the `build-args` array: + +1. The first item references a ConfigMap. As the ConfigMap just contains the value (for example `"16"`) as the data of the `node-version` key, the `format` setting is used to prepend `NODE_VERSION=` to make it a complete key-value pair. +2. The second item is just a hard-coded value. +3. The third item references a Secret. This works in the same way as with ConfigMaps. + +**NOTE**: the logging output of BuildKit contains expanded `ARG`s in `RUN` commands. Also, such information ends up in the final container image if you use such args in the [final stage of your Dockerfile](https://docs.docker.com/develop/develop-images/multistage-build/). An alternative approach to pass secrets is using [secret mounts](https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information). The BuildKit sample strategy supports them using the `secrets` parameter. ### Defining the Builder or Dockerfile diff --git a/docs/buildrun.md b/docs/buildrun.md index 41be66ce9..7eacf5bb2 100644 --- a/docs/buildrun.md +++ b/docs/buildrun.md @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 - [Defining ParamValues](#defining-paramvalues) - [Defining the ServiceAccount](#defining-the-serviceaccount) - [Canceling a `BuildRun`](#canceling-a-buildrun) - - [Specifying Environment Variables](#specifying-environment-variables) +- [Specifying Environment Variables](#specifying-environment-variables) - [BuildRun Status](#buildrun-status) - [Understanding the state of a BuildRun](#understanding-the-state-of-a-buildrun) - [Understanding failed BuildRuns](#understanding-failed-buildruns) @@ -61,7 +61,7 @@ The `BuildRun` definition supports the following fields: - Optional: - `spec.serviceAccount` - Refers to the SA to use when building the image. (_defaults to the `default` SA_) - `spec.timeout` - Defines a custom timeout. The value needs to be parsable by [ParseDuration](https://golang.org/pkg/time/#ParseDuration), for example `5m`. The value overwrites the value that is defined in the `Build`. - - `spec.paramValues` - Override any _params_ defined in the referenced `Build`, as long as their name matches. + - `spec.paramValues` - Refers to a name-value(s) list to specify values for `parameters` defined in the `BuildStrategy`. This overwrites values defined with the same name in the Build. - `spec.output.image` - Refers to a custom location where the generated image would be pushed. The value will overwrite the `output.image` value which is defined in `Build`. ( Note: other properties of the output, for example, the credentials cannot be specified in the buildRun spec. ) - `spec.output.credentials.name` - Reference an existing secret to get access to the container registry. This secret will be added to the service account along with the ones requested by the `Build`. - `spec.env` - Specifies additional environment variables that should be passed to the build container. Overrides any environment variables that are specified in the `Build` resource. The available variables depend on the tool that is being used by the chosen build strategy. @@ -82,41 +82,44 @@ spec: ### Defining ParamValues -A `BuildRun` resource can override _paramValues_ defined in its referenced `Build`, as long as the `Build` defines the same _params_ name. +A `BuildRun` resource can define _paramValues_ for parameters specified in the build strategy. If a value has been provided for a parameter with the same name in the `Build` already, then the value from the `BuildRun` will have precedence. For example, the following `BuildRun` overrides the value for _sleep-time_ param, that is defined in the _a-build_ `Build` resource. ```yaml --- apiVersion: shipwright.io/v1alpha1 -kind: BuildRun +kind: Build metadata: - name: a-buildrun + name: a-build + namespace: a-namespace spec: - buildRef: - name: a-build paramValues: - - name: sleep-time - value: "30" + - name: cache + value: disabled + strategy: + name: buildkit + kind: ClusterBuildStrategy + source: + ... + output: + ... --- apiVersion: shipwright.io/v1alpha1 -kind: Build +kind: BuildRun metadata: - name: a-build + name: a-buildrun + namespace: a-namespace spec: - source: - url: https://github.com/shipwright-io/sample-go - contextDir: docker-build/ + buildRef: + name: a-build paramValues: - - name: sleep-time - value: "60" - strategy: - name: sleepy-strategy - kind: BuildStrategy + - name: cache + value: registry ``` -See more about `paramValues` usage in the related [Build](./build.md#defining-paramvalues) resource docs. +See more about _paramValues_ usage in the related [Build](./build.md#defining-paramvalues) resource docs. ### Defining the ServiceAccount @@ -156,7 +159,7 @@ spec: state: "BuildRunCanceled" ``` -### Specifying Environment Variables +## Specifying Environment Variables An example of a `BuildRun` that specifies environment variables: @@ -246,25 +249,33 @@ The following table illustrates the different states a BuildRun can have under i | Status | Reason | CompletionTime is set | Description | | --- | --- | --- | --- | -| Unknown | Pending | No | The BuildRun is waiting on a Pod in status Pending. | -| Unknown | Running | No | The BuildRun has been validate and started to perform its work. |l -| Unknown | Running | No | The BuildRun has been validate and started to perform its work. | -| Unknown | BuildRunCanceled | No | The user requested the BuildRun to be canceled. This results in the BuildRun controller requesting the TaskRun be canceled. Cancellation has not been done yet. | -| True | Succeeded | Yes | The BuildRun Pod is done. | -| False | Failed | Yes | The BuildRun failed in one of the steps. | -| False | BuildRunTimeout | Yes | The BuildRun timed out. | -| False | UnknownStrategyKind | Yes | The Build specified strategy Kind is unknown. (_options: ClusterBuildStrategy or BuildStrategy_) | -| False | ClusterBuildStrategyNotFound | Yes | The referenced cluster strategy was not found in the cluster. | -| False | BuildStrategyNotFound | Yes | The referenced namespaced strategy was not found in the cluster. | -| False | SetOwnerReferenceFailed | Yes | Setting ownerreferences from the BuildRun to the related TaskRun failed. | -| False | TaskRunIsMissing | Yes | The BuildRun related TaskRun was not found. | -| False | TaskRunGenerationFailed | Yes | The generation of a TaskRun spec failed. | -| False | ServiceAccountNotFound | Yes | The referenced service account was not found in the cluster. | -| False | BuildRegistrationFailed | Yes | The related Build in the BuildRun is on a Failed state. | -| False | BuildNotFound | Yes | The related Build in the BuildRun was not found. | -| False | BuildRunCanceled | Yes | The BuildRun and underlying TaskRun were canceled successfully. | -| False | BuildRunNameInvalid | Yes | The defined `BuildRun` name (`metadata.name`) is invalid. The `BuildRun` name should be a [valid label value](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set). | -| False | PodEvicted | Yes | The BuildRun Pod was evicted from the node it was running on. See [API-initiated Eviction](https://kubernetes.io/docs/concepts/scheduling-eviction/api-eviction/) and [Node-pressure Eviction](https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/) for more information. | +| Unknown | Pending | No | The BuildRun is waiting on a Pod in status Pending. | +| Unknown | Running | No | The BuildRun has been validate and started to perform its work. |l +| Unknown | Running | No | The BuildRun has been validate and started to perform its work. | +| Unknown | BuildRunCanceled | No | The user requested the BuildRun to be canceled. This results in the BuildRun controller requesting the TaskRun be canceled. Cancellation has not been done yet. | +| True | Succeeded | Yes | The BuildRun Pod is done. | +| False | Failed | Yes | The BuildRun failed in one of the steps. | +| False | BuildRunTimeout | Yes | The BuildRun timed out. | +| False | UnknownStrategyKind | Yes | The Build specified strategy Kind is unknown. (_options: ClusterBuildStrategy or BuildStrategy_) | +| False | ClusterBuildStrategyNotFound | Yes | The referenced cluster strategy was not found in the cluster. | +| False | BuildStrategyNotFound | Yes | The referenced namespaced strategy was not found in the cluster. | +| False | SetOwnerReferenceFailed | Yes | Setting ownerreferences from the BuildRun to the related TaskRun failed. | +| False | TaskRunIsMissing | Yes | The BuildRun related TaskRun was not found. | +| False | TaskRunGenerationFailed | Yes | The generation of a TaskRun spec failed. | +| False | MissingParameterValues | Yes | No value has been provided for some parameters that are defined in the build strategy without any default. Values for those parameters must be provided through the Build or the BuildRun. | +| False | RestrictedParametersInUse | Yes | A value for a system parameter was provided. This is not allowed. | +| False | UndefinedParameter | Yes | A value for a parameter was provided that is not defined in the build strategy. | +| False | WrongParameterValueType | Yes | A value was provided for a build strategy parameter using the wrong type. The parameter is defined as `array` or `string` in the build strategy. Depending on that you must provide `values` or a direct value. | +| False | InconsistentParameterValues | Yes | A value for a parameter contained more than one of `value`, `configMapValue`, and `secretValue`. Any values including array items must only provide one of them. | +| False | EmptyArrayItemParameterValues | Yes | An item inside the `values` of an array parameter contained none of `value`, `configMapValue`, and `secretValue`. Exactly one of them must be provided. Null array items are not allowed. | +| False | IncompleteConfigMapValueParameterValues | Yes | A value for a parameter contained a `configMapValue` where the `name` or the `value` were empty. You must specify them to point to an existing ConfigMap key in your namespace. | +| False | IncompleteSecretValueParameterValues | Yes | A value for a parameter contained a `secretValue` where the `name` or the `value` were empty. You must specify them to point to an existing Secret key in your namespace. | +| False | ServiceAccountNotFound | Yes | The referenced service account was not found in the cluster. | +| False | BuildRegistrationFailed | Yes | The related Build in the BuildRun is on a Failed state. | +| False | BuildNotFound | Yes | The related Build in the BuildRun was not found. | +| False | BuildRunCanceled | Yes | The BuildRun and underlying TaskRun were canceled successfully. | +| False | BuildRunNameInvalid | Yes | The defined `BuildRun` name (`metadata.name`) is invalid. The `BuildRun` name should be a [valid label value](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set). | +| False | PodEvicted | Yes | The BuildRun Pod was evicted from the node it was running on. See [API-initiated Eviction](https://kubernetes.io/docs/concepts/scheduling-eviction/api-eviction/) and [Node-pressure Eviction](https://kubernetes.io/docs/concepts/scheduling-eviction/node-pressure-eviction/) for more information. | _Note_: We heavily rely on the Tekton TaskRun [Conditions](https://github.com/tektoncd/pipeline/blob/main/docs/taskruns.md#monitoring-execution-status) for populating the BuildRun ones, with some exceptions. @@ -274,13 +285,13 @@ _Note_: We heavily rely on the Tekton TaskRun [Conditions](https://github.com/te In addition, the `Status.Conditions` will host under the `Message` field a compacted message containing the `kubectl` command to trigger, in order to retrieve the logs. -Lastly, users can check `Status.FailureDetails` field, which includes the same information available in the `Status.FailedAt` field, +Lastly, users can check `Status.FailureDetails` field, which includes the same information available in the `Status.FailedAt` field, as well as a humanly-readable error message and reason. The message and reason are only included if the build strategy provides them. Example of failed BuildRun: -```yaml +```yaml # [...] status: # [...] @@ -313,7 +324,7 @@ error reasons: ### Step Results in BuildRun Status After the successful completion of a `BuildRun`, the `.status` field contains the results (`.status.taskResults`) emitted from the `TaskRun` steps generate by the `BuildRun` controller as part of processing the `BuildRun`. These results contain valuable metadata for users, like the _image digest_ or the _commit sha_ of the source code used for building. -The results from the source step will be surfaced to the `.status.sources` and the results from +The results from the source step will be surfaced to the `.status.sources` and the results from the [output step](buildstrategies.md#system-results) will be surfaced to the `.status.output` field of a `BuildRun`. Example of a `BuildRun` with surfaced results for `git` source (note that the `branchName` is only included if the Build does not specify any `revision`): diff --git a/docs/buildstrategies.md b/docs/buildstrategies.md index 3e86120ec..d89736fbf 100644 --- a/docs/buildstrategies.md +++ b/docs/buildstrategies.md @@ -140,13 +140,16 @@ kubectl apply -f samples/buildstrategy/kaniko/buildstrategy_kaniko-trivy_cr.yaml ### Cache Exporters -By default, the `buildkit` ClusterBuildStrategy will use caching to optimize the build times. When pushing an image to a registry, it will use the `inline` export cache, which pushes the image and cache together. Please refer to [export-cache docs](https://github.com/moby/buildkit#export-cache) for more information. +By default, the `buildkit` ClusterBuildStrategy will use caching to optimize the build times. When pushing an image to a registry, it will use the inline export cache, which appends cache information to the image that is built. Please refer to [export-cache docs](https://github.com/moby/buildkit#export-cache) for more information. Caching can be disabled by setting the `cache` parameter to disabled. See [Defining ParamValues](build.md#defining-paramvalues) for more information. + +### Build-args and secrets + +The sample build strategy contains array parameters to set values for [`ARG`s in your Dockerfile](https://docs.docker.com/engine/reference/builder/#arg), and for [mounts with type=secret](https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information). The parameter names are `build-args` and `secrets`. [Defining ParamValues](build.md#defining-paramvalues) contains example usage. ### Known Limitations The `buildkit` ClusterBuildStrategy currently locks the following parameters: -- A `Dockerfile` name needs to be `Dockerfile`, this is currently not configurable. - Exporter caches are enabled by default, this is currently not configurable. - To allow running rootless, it requires both [AppArmor](https://kubernetes.io/docs/tutorials/clusters/apparmor/) as well as [SecComp](https://kubernetes.io/docs/tutorials/clusters/seccomp/) to be disabled using the `unconfined` profile. @@ -230,33 +233,161 @@ Strategy parameters allow users to parameterize their strategy definition, by al Users defining _parameters_ under their strategies require to understand the following: -- **Definition**: A list of parameters should be defined under `spec.parameters`. Each list item should consist of a _name_, a _description_ and a reasonable _default_ value (_type string_). Note that a default value is not mandatory. -- **Usage**: In order to use a parameter in the strategy steps, users should follow the following syntax: `$(params.your-parameter-name)` +- **Definition**: A list of parameters should be defined under `spec.parameters`. Each list item should consist of a _name_, a _description_, a _type_ (either `"array"` or `"string"`) and optionally a _default_ value (for type=string), or _defaults_ values (for type=array). If no default(s) are provided, then the user must define a value in the Build or BuildRun. +- **Usage**: In order to use a parameter in the strategy steps, use the following syntax for type=string: `$(params.your-parameter-name)`. String parameters can be used in all places in the `buildSteps`. Some example scenarios are: + - `image`: to use a custom tag, for example `golang:$(params.go-version)` as it is done in the [ko sample build strategy](../samples/buildstrategy/ko/buildstrategy_ko_cr.yaml)) + - `args`: to pass data into your builder command + - `env`: to force a user to provide a value for an environment variable. + + Arrays are referenced using `$(params.your-array-parameter-name[*])`, and can only be used in as the value for `args` or `command` because the defined as arrays by Kubernetes. For every item in the array, an arg will be set. For example, if you specify this in your build strategy step: + + ```yaml + spec: + parameteres: + - name: tool-args + description: Parameters for the tool + type: array + buildSteps: + - name: a-step + command: + - some-tool + args: + - $(params.tool-args[*]) + ``` + + If the build user sets the value of tool-args to ["--some-arg", "some-value"], then the Pod will contain these args: + + ```yaml + spec: + containers: + - name: a-step + args: + ... + - --some-arg + - some-value + ``` + - **Parameterize**: Any `Build` or `BuildRun` referencing your strategy, can set a value for _your-parameter-name_ parameter if needed. -The following is an example of a strategy that defines and uses the `sleep-time` parameter: +**Note**: Users can provide parameter values as simple strings or as references to keys in [ConfigMaps](https://kubernetes.io/docs/concepts/configuration/configmap/) and [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/). If they use a ConfigMap or Secret, then the value can only be used if the parameter is used in the `command`, `args`, or `env` section of the `buildSteps`. For example, the above mentioned scenario to set a step's `image` to `golang:$(params.go-version)` does not allow the usage of ConfigMaps or Secrets. + +The following example is from the [BuildKit sample build strategy](../samples/buildstrategy/buildkit/buildstrategy_buildkit_cr.yaml). It defines and uses several parameters: ```yaml --- apiVersion: shipwright.io/v1alpha1 -kind: BuildStrategy +kind: ClusterBuildStrategy metadata: - name: sleepy-strategy + name: buildkit + ... spec: parameters: - - name: sleep-time - description: "time in seconds for sleeping" - default: "1" + - name: build-args + description: "The values for the ARGs in the Dockerfile. Values must be in the format KEY=VALUE." + type: array + defaults: [] + - name: cache + description: "Configure BuildKit's cache usage. Allowed values are 'disabled' and 'registry'. The default is 'registry'." + type: string + default: registry + - name: insecure-registry + type: string + description: "enables the push to an insecure registry" + default: "false" + - name: secrets + description: "The secrets to pass to the build. Values must be in the format ID=FILE_CONTENT." + type: array + defaults: [] buildSteps: - - name: a-strategy-step - image: alpine:latest - command: - - sleep - args: - - $(params.sleep-time) + ... + - name: build-and-push + image: moby/buildkit:nightly-rootless + imagePullPolicy: Always + workingDir: $(params.shp-source-root) + ... + command: + - /bin/ash + args: + - -c + - | + set -euo pipefail + + # Prepare the file arguments + DOCKERFILE_PATH='$(params.shp-source-context)/$(build.dockerfile)' + DOCKERFILE_DIR="$(dirname "${DOCKERFILE_PATH}")" + DOCKERFILE_NAME="$(basename "${DOCKERFILE_PATH}")" + + # We only have ash here and therefore no bash arrays to help add dynamic arguments (the build-args) to the build command. + + echo "#!/bin/ash" > /tmp/run.sh + echo "set -euo pipefail" >> /tmp/run.sh + echo "buildctl-daemonless.sh \\" >> /tmp/run.sh + echo "build \\" >> /tmp/run.sh + echo "--progress=plain \\" >> /tmp/run.sh + echo "--frontend=dockerfile.v0 \\" >> /tmp/run.sh + echo "--opt=filename=\"${DOCKERFILE_NAME}\" \\" >> /tmp/run.sh + echo "--local=context='$(params.shp-source-context)' \\" >> /tmp/run.sh + echo "--local=dockerfile=\"${DOCKERFILE_DIR}\" \\" >> /tmp/run.sh + echo "--output=type=image,name='$(params.shp-output-image)',push=true,registry.insecure=$(params.insecure-registry) \\" >> /tmp/run.sh + if [ "$(params.cache)" == "registry" ]; then + echo "--export-cache=type=inline \\" >> /tmp/run.sh + echo "--import-cache=type=registry,ref='$(params.shp-output-image)' \\" >> /tmp/run.sh + elif [ "$(params.cache)" == "disabled" ]; then + echo "--no-cache \\" >> /tmp/run.sh + else + echo -e "An invalid value for the parameter 'cache' has been provided: '$(params.cache)'. Allowed values are 'disabled' and 'registry'." + echo -n "InvalidParameterValue" > '$(results.shp-error-reason.path)' + echo -n "An invalid value for the parameter 'cache' has been provided: '$(params.cache)'. Allowed values are 'disabled' and 'registry'." > '$(results.shp-error-message.path)' + exit 1 + fi + + stage="" + for a in "$@" + do + if [ "${a}" == "--build-args" ]; then + stage=build-args + elif [ "${a}" == "--secrets" ]; then + stage=secrets + elif [ "${stage}" == "build-args" ]; then + echo "--opt=\"build-arg:${a}\" \\" >> /tmp/run.sh + elif [ "${stage}" == "secrets" ]; then + # Split ID=FILE_CONTENT into variables id and data + + # using head because the data could be multiline + id="$(echo "${a}" | head -1 | sed 's/=.*//')" + + # This is hacky, we remove the suffix ${id}= from all lines of the data. + # If the data would be multiple lines and a line would start with ${id}= + # then we would remove it. We could force users to give us the secret + # base64 encoded. But ultimately, the best solution might be if the user + # mounts the secret and just gives us the path here. + data="$(echo "${a}" | sed "s/^${id}=//")" + + # Write the secret data into a temporary file, once we have volume support + # in the build strategy, we should use a memory based emptyDir for this. + echo -n "${data}" > "/tmp/secret_${id}" + + # Add the secret argument + echo "--secret id=${id},src="/tmp/secret_${id}" \\" >> /tmp/run.sh + fi + done + + echo "--metadata-file /tmp/image-metadata.json" >> /tmp/run.sh + + chmod +x /tmp/run.sh + /tmp/run.sh + + # Store the image digest + sed -E 's/.*containerimage.digest":"([^"]*).*/\1/' < /tmp/image-metadata.json > '$(results.shp-image-digest.path)' + # That's the separator between the shell script and its args + - -- + - --build-args + - $(params.build-args[*]) + - --secrets + - $(params.secrets[*]) ``` -See more information on how to use this parameter in a `Build` or `BuildRun` in the related [docs](./build.md#defining-paramvalues). +See more information on how to use these parameters in a `Build` or `BuildRun` in the related [documentation](./build.md#defining-paramvalues). ## System parameters diff --git a/docs/proposals/parameterize-strategies.md b/docs/proposals/parameterize-strategies.md index 57fb4258e..e29da3c87 100644 --- a/docs/proposals/parameterize-strategies.md +++ b/docs/proposals/parameterize-strategies.md @@ -315,7 +315,7 @@ spec: output: #Content omitted for this example paramValues: - name: INSECURE_REGISTRY - value: false + value: "false" ``` ```yaml @@ -328,7 +328,7 @@ spec: name: a-build paramValues: - name: INSECURE_REGISTRY - value: true + value: "true" ``` The above allows a user to opt-in for pushing to an insecure registry, although the referenced Build disables this behaviour. diff --git a/docs/tutorials/building_with_buildkit.md b/docs/tutorials/building_with_buildkit.md index 8cfa8448f..69a5d5d49 100644 --- a/docs/tutorials/building_with_buildkit.md +++ b/docs/tutorials/building_with_buildkit.md @@ -61,8 +61,7 @@ metadata: spec: source: url: https://github.com/shipwright-io/sample-go - contextDir: docker-build/ - dockerfile: docker-build/ + contextDir: docker-build strategy: name: buildkit kind: ClusterBuildStrategy @@ -73,8 +72,6 @@ spec: EOF ``` -_Note_: Pay attention to the definition under `spec.source.dockerfile`. The `buildkit` expects a path to where your `Dockerfile` is located. - Verify that the `go-tutorial` Build was created successfully: ```sh