| # Image Customizer for Container-Optimized OS from Google | |
| Note: This is not an official Google product. | |
| The COS Customizer is a tool for creating customized Container-Optimized OS | |
| images. It uses | |
| [Daisy](https://github.com/GoogleCloudPlatform/compute-image-tools/tree/master/daisy) | |
| to create a COS VM instance, load data onto the instance, and create a disk | |
| image from the modified instance. | |
| Currently, the COS Customizer is intended to be run as part of a | |
| [Google Cloud Build](https://cloud.google.com/cloud-build/) workflow as a | |
| sequence of Google Cloud Build build steps. No other usage mode is currently | |
| supported. | |
| * [Accessing the cos-customizer container image](#accessing-the-cos_customizer-container-image) | |
| * [Quick Start](#quick-start) | |
| * [Minimal example](#minimal-example) | |
| * [Build Steps](#build-steps) | |
| * [Required build steps](#required-build-steps) | |
| * [The start-image-build step](#the-start_image_build-step) | |
| * [The finish-image-build step](#the-finish_image_build-step) | |
| * [Optional build steps](#optional-build-steps) | |
| * [run-script](#run_script) | |
| * [install-gpu](#install_gpu) | |
| * [seal-oem](#seal_oem) | |
| * [disable-auto-update](#disable_auto_update) | |
| ## Accessing the cos-customizer container image | |
| The container image is available at `gcr.io/cos-cloud/cos-customizer`. | |
| Alternatively, it can be built from source using [Bazel](https://bazel.build/). | |
| To build COS customizer and load the image into Docker, run: | |
| $ bazel run //:cos_customizer -- --norun | |
| The COS Customizer docker image will then be available in Docker as | |
| `bazel:cos_customizer`. | |
| ## Quick Start | |
| The COS Customizer is intended to be run as a sequence of steps in a Google | |
| Cloud Build workflow. It is implemented and distributed as a Docker container. | |
| Each subcommand of the COS Customizer implements a Google Cloud Build build | |
| step. Two of these steps need to be present for every image build, and the rest | |
| of the steps are optional steps that can be used for customizing a COS image. | |
| The required build steps are the `start-image-build` and `finish-image-build` | |
| steps. The `start-image-build` step initializes local state for the image build, | |
| and the `finish-image-build` step performs the image building operation with | |
| Daisy. | |
| Example optional build steps are `run-script`, `install-gpu`, `seal-oem` and | |
| `disable-auto-update`. | |
| `run-script`allows users to customize an image by running a script. | |
| `install-gpu` allows users to install GPU drivers using the | |
| [COS GPU installer](https://github.com/GoogleCloudPlatform/cos-gpu-installer). | |
| `seal-oem` allows users to setup a verified read-only OEM partition. It will be | |
| verified when the VM boots and when the data inside are accessed. | |
| `disable-auto-update` allows users to disable the auto-update service. And it | |
| will reclaim the disk space of the unused root partition. | |
| If you get permission denied error for getting/creating/deleting images, | |
| try granting your cloud build service account | |
| ([PROJECT_NUMBER]@cloudbuild.gserviceaccount.com) `Compute Admin` access. | |
| In some projects this role is not granted by default. | |
| ### COS Customizer Design | |
| See the `DESIGN.md` document for more information on the design particulars | |
| of the customizer. | |
| ### Minimal example | |
| Here is a minimal Google Cloud Build workflow demonstrating usage of the COS | |
| Customizer. It customizes the image `cos-stable-68-10718-86-0` by running the | |
| script `preload.sh`. This results in an image with the custom file | |
| `/var/lib/hello`. | |
| $ cat preload.sh | |
| echo "Hello, World!" > /var/lib/hello | |
| $ cat cloudbuild.yaml | |
| steps: | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['start-image-build', | |
| '-image-name=cos-stable-68-10718-86-0', | |
| '-image-project=cos-cloud', | |
| '-gcs-bucket=${PROJECT_ID}_cloudbuild', | |
| '-gcs-workdir=image-build-$BUILD_ID'] | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['run-script', | |
| '-script=preload.sh'] | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['finish-image-build', | |
| '-zone=us-west1-b', | |
| '-project=$PROJECT_ID', | |
| '-image-name=my-custom-image', | |
| '-image-project=$PROJECT_ID'] | |
| timeout: '1500s' | |
| $ gcloud builds submit --config=cloudbuild.yaml . | |
| ## Build Steps | |
| The COS Customizer is different from typical Google Cloud Build build steps. | |
| Most build steps, like the `gcr.io/cloud-builders/gcloud` build step, are | |
| single-purpose container images that are capable of being useful when run in | |
| isolation. The COS Customizer is not one of these build steps. | |
| The COS Customizer is a container image that provides a collection of Google | |
| Cloud Build build steps that are intended to be used together. When run in | |
| sequence as part of a Google Cloud Build workflow, these build steps create a | |
| Compute Engine disk image. | |
| Each build step is invoked as a subcommand of the COS Customizer container | |
| image; for example, usage of the `run-script` build step works as follows: | |
| ... | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['run-script', | |
| '-script=preload.sh'] | |
| ... | |
| ### Required build steps | |
| Two build steps are required for each image build operation; the | |
| `start-image-build` step and the `finish-image-build` step. | |
| #### The start-image-build step | |
| The primary purpose of this step is to initialize the image build process. It | |
| only initializes local state in the Google Cloud Build builder. It does not | |
| create any cloud resources. It must run before all of the other steps in the | |
| image build process, and it must only be run once. It takes the following flags: | |
| `-build-context`: A path to a file or directory that should be relative to the | |
| default Google Cloud Build working directory. Defaults to `.`. The contents of | |
| this path will be copied to the builder VM in a temporary directory. All scripts | |
| specified by a `run-script` step will execute with this directory as a working | |
| directory. For example, suppose that the source directory provided to Google | |
| Cloud Build looked like this: | |
| . | |
| ├── lib | |
| │ └── mylib.sh | |
| └── main.sh | |
| If `-build-context` is set to `.`, this directory structure will be copied to | |
| the builder VM and will be the working directory for all specified `run-script` | |
| steps. If a `run-script` step runs the script `main.sh`, `main.sh` will have | |
| access to `lib/mylib.sh`. However, suppose `-build-context` is set to `lib`; | |
| then, a `run-script` step that specifies `main.sh` will fail, since `main.sh` | |
| won't be included in the working directory on the builder VM. Specifying | |
| `mylib.sh` in a `run-script` step would be valid in this case though. | |
| `-gcs-bucket`: A GCS bucket to use for scratch space. Optional build steps are | |
| free to use this bucket for scratch space. Normally, it's expected that only | |
| `finish-image-build` will use this GCS bucket. `finish-image-build` uses this | |
| GCS bucket for transferring binary blobs to the builder VM. | |
| `-gcs-workdir`: A directory in the aforementioned GCS bucket that will be used | |
| for scratch space. | |
| `-image-project`: The Google Cloud Platform (GCP) project that contains the | |
| source image; that is, the image to customize. | |
| `-image-name`: The name of the source image. Mutually exclusive with | |
| `-image-milestone` and `-image-family`. | |
| `-image-milestone`: The milestone of the source image. If `-image-milestone` is | |
| specified and `-image-project` is set to `cos-cloud`, the `start-image-build` | |
| step will resolve the source image by finding the latest image in `cos-cloud` on | |
| the specified milestone. An example value for this field is `69`. Mutually | |
| exclusive with `-image-name` and `-image-family`. | |
| `-image-family`: The family of the source image. If `-image-family` is | |
| specified, the `start-image-build` step will resolve the source image by finding | |
| the latest active image in the specified image family. This is done using Google | |
| Compute Engine's `getFromFamily` API. Mutually exclusive with `-image-name` and | |
| `-image-milestone`. | |
| An example `start-image-build` step looks like the following: | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['start-image-build', | |
| '-image-name=cos-stable-68-10718-86-0', | |
| '-image-project=cos-cloud', | |
| '-gcs-bucket=${PROJECT_ID}_cloudbuild', | |
| '-gcs-workdir=image-build-$BUILD_ID'] | |
| #### The finish-image-build step | |
| The primary purpose of this step is to execute the steps specified in the image | |
| build process. This step creates a builder VM, runs configured scripts on it, | |
| and creates a disk image from the VM. It must run after all of the other steps | |
| in an image build process. This step will clean up the local state stored by | |
| previous COS Customizer steps; a new image build process can be started after a | |
| `finish-image-build` step. It takes the following flags: | |
| `-image-project`: The GCP project that should contain the output image. | |
| `-image-name`: The name of the output image. Mutually exclusive with | |
| `-image-suffix`. | |
| `-image-suffix`: Construct the name of the output image by appending the | |
| specified suffix to the name of the input image. Mutually exclusive with | |
| `-image-name`. | |
| `-image-family`: An image family to assign the output image to. | |
| `-deprecate-old-images`: If present, the image build process will deprecate all | |
| of the old images in the output image's image family. Can only be specified if | |
| `-image-family` is specified. | |
| `-old-image-ttl`: Time-to-live in seconds to apply to images deprecated by | |
| `-deprecate-old-images`. Configures the "deleted" field of the image's | |
| deprecation status to be this many seconds after the image is deprecated. Can | |
| only be used if `-deprecate-old-images` is also given. | |
| `-zone`: The GCE zone in which to perform the image building operation. This is | |
| an important consideration when installing GPU drivers on the image, since | |
| installing GPU drivers requires that GPU quota is available in this zone. | |
| `-project`: The GCP project to use for the image building operation. | |
| `-labels`: Key-value pairs to apply to the output image as image labels. | |
| Example: `-labels=cos_image=true,milestone=65` | |
| `-licenses`: A list of licenses to apply to the output image. License names must | |
| be formatted as `projects/{project}/global/licenses/{license}`. Example: | |
| `-licenses=projects/cos-cloud/global/licenses/cos` | |
| `-inherit-labels`: If present, the output image will be assigned the exact same | |
| image labels present on the source image. The labels specified by the `-labels` | |
| flag take precedence over labels assigned with this flag. | |
| `-disk-type`: The disk type for the preload VM to use when creating the image. | |
| Defaults to `pd-standard`. | |
| `-disk-size-gb`: The disk size in GB to use when creating the image. | |
| This value should never be smaller than 10 (the default size of a COS image). | |
| If `-oem-size` is set, the lower limit of `-disk-size-gb` is as shown in the | |
| following table. The larger one of the value in the table and 10 is | |
| effective. See section `-oem-size`, | |
| [seal-oem](#seal-oem) and [disable-auto-update](#disable-auto-update) for details. | |
| | disk-size-gb-lower-limit | no seal-oem | seal-oem | | |
| |:------------------------:|:------------------------:|:----------------------------:| | |
| | no disable-auto-update | 10GB + oem-size | 10GB + oem-size x 2 - 2046MB | | |
| | disable-auto-update | 10GB + oem-size - 2046MB | 10GB + oem-size x 2 - 2046MB | | |
| Note that if `seal-oem` is run without specifying `-oem-size`, the lower limit of | |
| `-disk-size-gb` will be 10. | |
| `-oem-size`: The file system size of the extended OEM partition with unit | |
| `G`,`M`,`K` or `B`. | |
| If no unit is provided, it will be parsed as the number of sectors of 512 Bytes. | |
| Since the default size of the OEM partition in a COS image is assumed to be 16MB, | |
| this value must be no smaller than 16MB, otherwise the build will fail. | |
| Make sure the disk size is large enough if this flag is used to extend the OEM partition. | |
| If the `seal-oem` or `disable-auto-update` is run, the OEM partition will firstly | |
| use the reclaimed space. | |
| See section `-disk-size-gb` for the limits of the disk size value. | |
| Example: `-oem-size=500M` | |
| Note that this feature is supported by COS versions higher than milestone 73 (included). | |
| `-timeout`: Timeout value of this step. Must be formatted according to Golang's | |
| time.Duration string format. Defaults to "1h0m0s". Keep in mind that this timeout | |
| value is different from the overall Cloud Build workflow timeout value, which is | |
| set at the Cloud Build workflow level. If this timeout value expires, resources | |
| created during the image build process will be properly cleaned up. If the | |
| overall Cloud Build workflow timeout expires, the task will be cancelled without | |
| any opportunity to clean up resources. | |
| `-machine-type`: The machine type to use for the COS Customizer preload VM. | |
| Defaults to `n1-standard-1`. Useful for optimizing costs. Note that this is | |
| separate from the Cloud Build machine type option, which sets the machine type | |
| of the Cloud Build VM, which is different from the COS Customizer preload VM. | |
| `-service-account`: The service account to be used by the COS Customizer preload VM. | |
| If not set, the default GCE service account will be used. | |
| `-gpu-type`: The GPU type attached to the COS Customizer preload VM e.g. | |
| `nvidia-tesla-t4`. Useful for installing GPU drivers via subcommand | |
| `run-script`. If this flag is set, it will overwrite the same flag set in | |
| step `install-gpu`. | |
| `-network`: The network/VPC to use for the COS Customizer preload VM. | |
| The network must have access to Google Cloud Storage. Defaults to | |
| default network `global/networks/default`. If -subnet is also specified subnet | |
| must be a subnetwork of network specified by -network. | |
| `-subnet`: The subnet to use for the COS Customizer preload VM. Defaults to | |
| default network `global/networks/default`. If the network is in auto subnet mode, | |
| the subnetwork is optional. If the network is in custom subnet mode, then this | |
| field should be specified. Zone should be specified if this field is specified. | |
| `-enable-cleanup`: If this flag is set, COS-Customizer will automatically delete old | |
| VMs created by previous invocations in the project and zone set by `-project` and `-zone`. | |
| `-use-scratch-disk`: If this flag is set, the preloading VM will have access to a 10GB scratch disk mounted at `/mnt/disks/scratch`. | |
| The disk type will be determined by the `-disk-type` flag, with the default being `pd-standard`. | |
| `-sbom-input-path`: Path to the input JSON file for SBOM generation. This path is relative to | |
| `-build-context` set in step `start-image-build`. Schema for the input: | |
| { | |
| "outputImageName": <Optional>"customized-image", | |
| "outputImageVersion": <Optional>"1.2.3", | |
| "creators": <Required>["Organization: Google LLC"], | |
| "supplier": <Optional>"Organization: Google LLC", | |
| "SPDXPackages": <Optional>[ | |
| { | |
| "name": <Required>"package-A", | |
| "SPDXID": <Required>"SPDXRef-package-A", | |
| "versionInfo": <Required>"1.2.3", | |
| "supplier": <Optional>"Organization: Google LLC", | |
| "filesAnalyzed": <Optional>false, | |
| "licenseDeclared": <Optional>"BSD-3-Clause AND Apache-2.0 AND LicenseRef-A", | |
| "licenseConcluded": <Optional>"BSD-3-Clause AND Apache-2.0 AND LicenseRef-A", | |
| "downloadLocation": <Optional>"https://package/download/url", | |
| "externalRefs": <Optional>[ | |
| { | |
| "referenceCategory": <Required>"SECURITY", | |
| "referenceLocator": <Required>"cpe:/a:vendor:package-A:1.2.3", | |
| "referenceType": <Required>"cpe23Type" | |
| } | |
| ], | |
| "checksums": <Optional>[ | |
| { | |
| "algorithm": <Required>"SHA1", | |
| "checksumValue": <Required>"11d7774ac38f40e009dcee453a760750aea75bbd" | |
| } | |
| ] | |
| } | |
| ], | |
| "SBOMPackages": <Optional>[ | |
| { | |
| "name": <Required>"package-B", | |
| "spdxDocument": <Required>"URL to package-B SBOM", | |
| "algorithm": <Required>"SHA1", | |
| "checksumValue": <Required>"11d7774ac38f40e009dcee453a760750aea75bbd" | |
| } | |
| ], | |
| "hasExtractedLicensingInfos": <Optional>[ | |
| { | |
| "licenseId": <Required>"LicenseRef-A", | |
| "extractedText": <Required>"extracted-license-text", | |
| "crossRefs": <Optional>["https://package/download/url/LICENSE.txt"] | |
| } | |
| ] | |
| } | |
| Note: `SPDXPackages` has the same schema as field `packages` in | |
| [SPDX JSON Schema](https://github.com/spdx/spdx-spec/blob/master/schemas/spdx-schema.json). | |
| Field `filesAnalyzed` in `SPDXPackages` can be ambiguous in JSON format so it should be set explicitly. | |
| If COS images from project `cos-cloud` is used as base image, cos-customizer will automatically | |
| fetch the public SBOM from GCS bucket `cos-tools` if available. | |
| `-sbom-output-path`: The GCS path for storing the output SBOM. The complete output file path is | |
| `<sbom-output-path>/<outputImageName>-<outputImageVersion>_sbom.json`. If `outputImageName` is not | |
| set in the input, the path will be `<sbom-output-path>/<actualOutputImageName>_sbom.json`. | |
| An example `finish-image-build` step looks like the following: | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['finish-image-build', | |
| '-zone=us-west1-b', | |
| '-project=$PROJECT_ID', | |
| '-image-name=my-custom-image', | |
| '-image-project=$PROJECT_ID'] | |
| An example `finish-image-build` step with `network` and `subnet` looks like the following: | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['finish-image-build', | |
| '-zone=us-west1-b', | |
| '-project=$PROJECT_ID', | |
| '-network=global/networks/auto-vpc', | |
| '-subnet=regions/us-west1/subnetworks/auto-vpc-subnet-us-west1', | |
| '-image-name=my-custom-image', | |
| '-image-project=$PROJECT_ID'] | |
| ### Optional build steps | |
| The rest of the build steps provided by COS Customizer are optional; if they are | |
| not included, the image build will run successfully, but will generate an image | |
| that is identical to the source image. Optional build steps are used to make | |
| meaningful changes to an image. | |
| #### run-script | |
| The `run-script` build step configures the image build to run a script on the | |
| builder VM. If multiple `run-script` steps are given, the scripts specified by | |
| each step will run in the same order in which the `run-script` steps were given. | |
| It takes the following flags: | |
| `-script`: A path to the script to run. The path should be relative to the root | |
| of the build context provided in `start-image-build`. | |
| `-env`: Key-value pairs indicating environment variables to provide to the | |
| script when it is run. Example: `-env=RELEASE=1,FOO=bar` | |
| An example `run-script` step looks like the following: | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['run-script', | |
| '-script=preload.sh'] | |
| #### install-gpu | |
| The `install-gpu` build step configures the image build to install GPU drivers | |
| on the builder VM. GPU drivers are installed using the | |
| [COS GPU installer](https://cos.googlesource.com/cos/tools/+/refs/heads/master/src/cmd/cos_gpu_installer_v1/). | |
| Currently, this installer gets pulled from GCR at runtime onto the preload VM meaning that | |
| the preload VM must have access to gcr. | |
| In addition to installing GPU drivers, the `install-gpu` step installs a script | |
| named `setup_gpu.sh` in the GPU driver install directory. _In order to use the | |
| installed GPU drivers, this script must be run every time the system boots_. It | |
| should be executed as part of a startup script or cloud config. `install-gpu` | |
| takes the following flags: | |
| `-version`: The GPU driver version to install. Currently, we only support | |
| installing Tesla drivers that are present in the | |
| [nvidia-drivers-us-public GCS bucket](https://console.cloud.google.com/storage/browser/nvidia-drivers-us-public). | |
| The set of supported drivers can be found by running the `install-gpu` step | |
| independently on your local machine with the `-get-driver-version` flag. | |
| Example: `-version=396.26` | |
| `-get-driver-version`: Prints out the list of supported driver versions to | |
| stdout and exits. If this flag is provided, the build step doesn't do anything | |
| meaningful; it only prints the list of supported driver versions. It is not | |
| intended to be used in a Google Cloud Build workflow; it is meant to be run | |
| independently for users to easily see the set of supported driver versions. | |
| `-md5sum`: If you have the md5sum of the driver you want to install, you can | |
| provide it here and the COS GPU installer will verify the driver with this | |
| md5sum. | |
| `-install-dir`: The directory on the image to install GPU drivers to. The | |
| `setup_gpu.sh` script will also be installed in this directory. Make sure to | |
| choose a directory that will persist across reboots; for the most part, this | |
| means a subdirectory of `/var` or `/home`. | |
| `-gpu-type`: This flag is deprecated, please use the same flag in step | |
| `finish-image-build`. | |
| `-installer-container`: (optional) The installer container to use. | |
| An example `install-gpu` step looks like the following: | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['install-gpu', | |
| '-version=396.26'] | |
| Note that when using an image customized with `install-gpu`, the hosted docker | |
| container should be set to run in privileged mode so that it has access to the | |
| GPU device on the host machine. | |
| #### seal-oem | |
| The `seal-oem` build step utilizes `dm-verity` to verify the data in the OEM | |
| partition when the system boots and when data are accessed. | |
| If the verification fails, the system will refuse to boot or will panic. | |
| This step takes no flags and needs to be run after any step | |
| that makes changes to the OEM partition (`/dev/sda8` or `/usr/share/oem`). | |
| If this step is run, the size of the OEM partition will be doubled to store | |
| the hash tree for verification in the second half of the partition. | |
| If `-oem-size` in `finish-image-build` step is not set, the file system | |
| size of the OEM partition will be assumed to be the same as the default size, | |
| 16MB. And the size of the OEM partition will be doubled to 32MB. | |
| The auto-update service is automatically disabled in this step. So it is not | |
| necessary to run the `disable-auto-update` step explicitly. This will reclaim | |
| the unused space and the OEM partition will firstly use the reclaimed space. | |
| See section `-disk-size-gb` for the limits of the disk size value. If the | |
| disk size is not large enough, the build will fail. | |
| After running this build step, the OEM partition will not be automatically | |
| mounted when the system boots. | |
| `sudo mount /dev/dm-1 /usr/share/oem` should be added to | |
| `startup script` or `cloud init` to mount the OEM partition. | |
| Note that this feature is supported by COS versions higher than milestone 73 (included). | |
| #### anthos-installer-install | |
| The `anthos-installer-install` build step installs the application binaries such as | |
| kubernetes, crictl and node-problem-detector on the builder VM based on the package | |
| spec in YAML format using the Anthos installer. Sample package spec is [here](https://cos.googlesource.com/cos/tools/+/refs/heads/master/testing/install_packages_test/pkgspec/kubernetes.yaml). | |
| This step takes one flag, `pkgspec-url`, path to the directory containing the pkgspec files. | |
| The pkgspec-url can point to the | |
| * Local directory | |
| * Archive file(.tar.gz) consisting of pkgspec files i.e. local or remote file in GCS(gs://), | |
| and http(http://)/https(https://) location. | |
| The Anthos Installer is limited to the fact that it doesn’t check the compatibility or | |
| the dependencies of the input packages on COS. The Anthos Installer works on the assumption | |
| that the dependencies are installed on the OS or fully specified by the YAML file. | |
| An example `anthos-installer-install` with input, a local directory step looks | |
| like the following: | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['anthos-installer-install', | |
| '-pkgspec-url=testing/install_packages_test/pkgspec'] | |
| An example with PkgSpec in GCS bucket. | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['anthos-installer-install', | |
| '-pkgspec-url=gs://test-bucket/pkgspec.tar.gz'] | |
| The `anthos-installer-install` step can also be used to preload the containers. | |
| One such example is implemented in [preload-container.yaml](https://cos.googlesource.com/cos/tools/+/refs/heads/master/testing/install_packages_test/pkgspec/preload-container.yaml). | |
| It supports different loader options such as docker, containerd and crictl. | |
| #### disable-auto-update | |
| The `disable-auto-update` build step modifies the kernel commandline to disable | |
| the auto-update serive. This step takes no flags. | |
| The root partition that is used by auto-update service will not be needed anymore, | |
| so the disk space (2046MB) of that partition will be reclaimed. The reclaimed | |
| space will be used by the OEM partition if extended and the stateful partition. | |
| Note that this feature is supported by COS versions higher than milestone 73 (included). | |
| ### sed-grub-config | |
| The `sed-grub-config` build step edits the grub configuration. This is helpful | |
| for making arbitrary edits to the kernel command line. | |
| An example to disable module signature verification: | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['sed-grub-config', | |
| '-sed-script=s|module.sig_enforce=1|module.sig_enforce=0|g'] | |
| An example to append a new kernel command line argument: | |
| - name: 'gcr.io/cos-cloud/cos-customizer' | |
| args: ['sed-grub-config', | |
| '-sed-script=s|cros_efi|cros_efi ima_appraise=off|g'] | |
| # Contributor Docs | |
| ## Releasing | |
| To release a new version of COS Customizer, tag the commit you want to release | |
| with the date in the form of `vYYYYMMDD`. This will trigger a Cloud Build job to | |
| build and release the container image. |