Break the cos-customizer dependency on snapshot.debian.org

snapshot.debian.org is unreliable, and its unreliability sometimes
blocks cos-customizer presubmits and releases for days. It also makes
blocking on cos-customizer integration tests impractical. We need to
break the dependency on snapshot.debian.org.

Unfortunately, the dependency on snapshot.debian.org is pretty tightly
integrated into the cos-customizer build, which is based on bazel and
the distroless package manager. The distroless package manager has since
been deprecated, and the old software is immutable (it depends on an
opaque executable in a GCS bucket that we don't own). To move away from
snapshot.debian.org, we need to move away from the bazel+distroless
build system for cos-customizer.

cos-customizer unfortunately depended on bazel+distroless at a deep
level. The provisioner program, which is used by cos-customizer to
execute preloading logic on the preload VM, bundles a few helper
programs and container images with it. We used bazel+distroless to also
build these bundled container images, and we used bazel+`go embed` to
bundle these other artifacts with the provisioner program.

The most natural alternative for building cos-customizer is a
Dockerfile, since that's what we use for our other container images and
it's a pretty widespread tool for building container images. This change
switches the cos-customizer container build to a Dockerfile from bazel.
Go programs are still compiled with bazel, but the container images are
built with a Dockerfile.

In order to separate the container image build into a different build
system from the Go program builds, I needed to change the way
cos-customizer behaves at runtime. In particular, executable data
dependencies could no longer reasonably be packaged with `go embed`
technology, and instead needed to be passed in to these programs at
runtime.

The following are cos-customizer data dependencies that needed
to be extracted out:
- The cidata file system image
- the scratch file system image

The following are provisioner data dependencies that needed to be
extracted out:
- The docker-credential-gcr executable
- The veritysetup container image
- The handle_disk_layout executable

The Dockerfile orchestrates the build of all these components and
arranges them in the right way so that startup.yaml can correctly pass
their locations in at runtime.

I also needed to update some tests to test against a newer version of
COS - I moved the tests from M69 to M93. The docker version on M69 is
now sufficiently old that it can no longer pull
docker.io/library/ubuntu:latest. As far as I can tell this is completely
independent of the cos-customizer changes, but perhaps the issue was
exposed since these changes make ./run_tests.sh much more reliable.

I tried to split this CL up into smaller CLs, but snapshot.debian.org
unreliability made testing intermediate CLs pretty hard. The tests can
only pass on the full set of changes.

BUG=b/293196753
TEST=./run_tests, `bazel test -- ... -//src/pkg/tools/...`

Change-Id: I0f1c3a329cfca38479c9d58745d251d2fe0778ce
Reviewed-on: https://cos-review.googlesource.com/c/cos/tools/+/56387
Cloud-Build: GCB Service account <228075978874@cloudbuild.gserviceaccount.com>
Tested-by: Robert Kolchmeyer <rkolchmeyer@google.com>
Reviewed-by: Nandhini Rengaraj <nrengaraj@google.com>
diff --git a/BUILD.bazel b/BUILD.bazel
index 93e78a0..f0cdbe3 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -13,120 +13,6 @@
 # limitations under the License.
 
 load("@bazel_gazelle//:def.bzl", "gazelle")
-load("@io_bazel_rules_docker//go:image.bzl", "go_image")
-load("@io_bazel_rules_docker//container:container.bzl", "container_image")
-load("@package_bundle_amd64//file:packages.bzl", packages_amd64 = "packages")
-load("@package_bundle_arm64//file:packages.bzl", packages_arm64 = "packages")
-load("@rules_pkg//:pkg.bzl", "pkg_deb", "pkg_tar")
 
 # gazelle:prefix cos.googlesource.com/cos/tools.git
 gazelle(name = "gazelle")
-
-exports_files(glob(["src/data/**"]))
-
-genrule(
-    name = "workspace_dir",
-    outs = ["workspace"],
-    cmd = "mkdir $@",
-)
-
-genrule(
-    name = "tmp_dir",
-    outs = ["tmp"],
-    cmd = "mkdir $@",
-)
-
-container_image(
-    name = "veritysetup_amd64",
-    architecture = "amd64",
-    debs = [
-        packages_amd64["coreutils"],
-        packages_amd64["tar"],
-        packages_amd64["libacl1"],
-        packages_amd64["libattr1"],
-        packages_amd64["libc6"],
-        packages_amd64["libselinux1"],
-        packages_amd64["libpcre3"],
-        packages_amd64["cryptsetup-bin"],
-        packages_amd64["libcryptsetup4"],
-        packages_amd64["libpopt0"],
-        packages_amd64["libuuid1"],
-        packages_amd64["libdevmapper1.02.1"],
-        packages_amd64["libgcrypt20"],
-        packages_amd64["libargon2-0"],
-        packages_amd64["libjson-c3"],
-        packages_amd64["libudev1"],
-        packages_amd64["libpthread-stubs0-dev"],
-        packages_amd64["libm17n-0"],
-        packages_amd64["libgpg-error0"],
-    ],
-    repository = "veritysetup",
-    visibility = ["//visibility:public"],
-)
-
-container_image(
-    name = "veritysetup_arm64",
-    architecture = "arm64",
-    debs = [
-        packages_arm64["coreutils"],
-        packages_arm64["tar"],
-        packages_arm64["libacl1"],
-        packages_arm64["libattr1"],
-        packages_arm64["libc6"],
-        packages_arm64["libselinux1"],
-        packages_arm64["libpcre3"],
-        packages_arm64["cryptsetup-bin"],
-        packages_arm64["libcryptsetup4"],
-        packages_arm64["libpopt0"],
-        packages_arm64["libuuid1"],
-        packages_arm64["libdevmapper1.02.1"],
-        packages_arm64["libgcrypt20"],
-        packages_arm64["libargon2-0"],
-        packages_arm64["libjson-c3"],
-        packages_arm64["libudev1"],
-        packages_arm64["libpthread-stubs0-dev"],
-        packages_arm64["libm17n-0"],
-        packages_arm64["libgpg-error0"],
-    ],
-    repository = "veritysetup",
-    visibility = ["//visibility:public"],
-)
-
-pkg_tar(
-    name = "data_tar",
-    srcs = glob(["src/data/**"]),
-    strip_prefix = "src/",
-)
-
-container_image(
-    name = "cos_customizer_base",
-    base = "@daisy//image",
-    data_path = ".",
-    debs = [
-        packages_amd64["coreutils"],
-        packages_amd64["tar"],
-        packages_amd64["libacl1"],
-        packages_amd64["libattr1"],
-        packages_amd64["libc6"],
-        packages_amd64["libselinux1"],
-        packages_amd64["libpcre3"],
-        packages_amd64["mtools"],
-    ],
-    files = [
-        ":tmp_dir",
-        ":workspace_dir",
-    ],
-    tars = [
-        ":data_tar",
-    ],
-)
-
-go_image(
-    name = "cos_customizer",
-    base = ":cos_customizer_base",
-    embed = ["//src/cmd/cos_customizer:cos_customizer_lib"],
-    goarch = "amd64",
-    goos = "linux",
-    pure = "on",
-    visibility = ["//visibility:public"],
-)
diff --git a/WORKSPACE b/WORKSPACE
index 8b5ffbc..e914758 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -35,32 +35,11 @@
 )
 
 http_archive(
-    name = "io_bazel_rules_docker",
-    sha256 = "07ee8ca536080f5ebab6377fc6e8920e9a761d2ee4e64f0f6d919612f6ab56aa",
-    strip_prefix = "rules_docker-0.25.0",
-    urls = ["https://github.com/bazelbuild/rules_docker/archive/v0.25.0.tar.gz"],
-)
-
-http_archive(
-    name = "distroless",
-    sha256 = "14834aaf9e005b9175de2cfa2b420c80778880ee4d9f9a9f7f385d3b177abff7",
-    strip_prefix = "distroless-fa0765cc86064801e42a3b35f50ff2242aca9998",
-    urls = ["https://github.com/GoogleContainerTools/distroless/archive/fa0765cc86064801e42a3b35f50ff2242aca9998.tar.gz"],
-)
-
-http_archive(
     name = "rules_pkg",
     sha256 = "aeca78988341a2ee1ba097641056d168320ecc51372ef7ff8e64b139516a4937",
     urls = ["https://github.com/bazelbuild/rules_pkg/releases/download/0.2.6-1/rules_pkg-0.2.6.tar.gz"],
 )
 
-http_archive(
-    name = "rules_foreign_cc",
-    sha256 = "ab805b9e00747ba9b184790cbe2d4d19b672770fcac437f01d8c101ae60df996",
-    strip_prefix = "rules_foreign_cc-c309ec13192f69a46aaaba39587c3d7ff684eb35",
-    urls = ["https://github.com/bazelbuild/rules_foreign_cc/archive/c309ec13192f69a46aaaba39587c3d7ff684eb35.zip"],
-)
-
 git_repository(
     name = "com_google_protobuf",
     commit = "31ebe2ac71400344a5db91ffc13c4ddfb7589f92",
@@ -100,131 +79,3 @@
 load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
 
 gazelle_dependencies()
-
-load(
-    "@io_bazel_rules_docker//repositories:repositories.bzl",
-    container_repositories = "repositories",
-)
-
-container_repositories()
-
-load("@io_bazel_rules_docker//repositories:deps.bzl", container_deps = "deps")
-
-container_deps()
-
-load(
-    "@io_bazel_rules_docker//container:container.bzl",
-    "container_pull",
-)
-
-container_pull(
-    name = "daisy",
-    digest = "sha256:a23774074d5941ed9e25f64ee7e02f96d2f8e09a4d7cee7131b49664267c33c7",
-    registry = "gcr.io",
-    repository = "compute-image-tools/daisy",
-)
-
-load(
-    "@io_bazel_rules_docker//go:image.bzl",
-    _go_image_repos = "repositories",
-)
-
-_go_image_repos()
-
-load(
-    "@distroless//package_manager:package_manager.bzl",
-    "package_manager_repositories",
-)
-
-package_manager_repositories()
-
-load(
-    "@distroless//package_manager:dpkg.bzl",
-    "dpkg_src",
-    "dpkg_list",
-)
-
-dpkg_src(
-    name = "debian_stretch_amd64",
-    arch = "amd64",
-    distro = "stretch",
-    sha256 = "79a66cd92ba9096fce679e15d0b5feb9effcf618b0a6d065eb32684dbffd0311",
-    snapshot = "20190328T105444Z",
-    url = "http://snapshot.debian.org/archive",
-)
-
-dpkg_src(
-    name = "debian_stretch_arm64",
-    arch = "arm64",
-    distro = "stretch",
-    sha256 = "ec05c9109c0a6aef4509091b9ccf10939583e56b7ce53be9d8ef38ec5e0ce9d2",
-    snapshot = "20190328T105444Z",
-    url = "http://snapshot.debian.org/archive",
-)
-
-dpkg_list(
-    name = "package_bundle_amd64",
-    packages = [
-        "coreutils",
-        "libacl1",
-        "libattr1",
-        "libc6",
-        "libpcre3",
-        "libselinux1",
-        "tar",
-        "cryptsetup-bin",
-        "libcryptsetup4",
-        "libpopt0",
-        "libuuid1",
-        "libdevmapper1.02.1",
-        "libgcrypt20",
-        "libargon2-0",
-        "libjson-c3",
-        "libudev1",
-        "libpthread-stubs0-dev",
-        "libm17n-0",
-        "libgpg-error0",
-        "mtools",
-    ],
-    sources = [
-        "@debian_stretch_amd64//file:Packages.json",
-    ],
-)
-
-dpkg_list(
-    name = "package_bundle_arm64",
-    packages = [
-        "coreutils",
-        "libacl1",
-        "libattr1",
-        "libc6",
-        "libpcre3",
-        "libselinux1",
-        "tar",
-        "cryptsetup-bin",
-        "libcryptsetup4",
-        "libpopt0",
-        "libuuid1",
-        "libdevmapper1.02.1",
-        "libgcrypt20",
-        "libargon2-0",
-        "libjson-c3",
-        "libudev1",
-        "libpthread-stubs0-dev",
-        "libm17n-0",
-        "libgpg-error0",
-        "mtools",
-    ],
-    sources = [
-        "@debian_stretch_arm64//file:Packages.json",
-    ],
-)
-
-load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependencies")
-rules_foreign_cc_dependencies()
-
-load("//src/third_party/dosfstools:dosfstools_repositories.bzl", "dosfstools_repositories")
-dosfstools_repositories()
-
-load("//src/third_party/mtools:mtools_repositories.bzl", "mtools_repositories")
-mtools_repositories()
diff --git a/deps.bzl b/deps.bzl
index 0e4bb16..77e1fc0 100644
--- a/deps.bzl
+++ b/deps.bzl
@@ -451,3 +451,9 @@
         sum = "h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=",
         version = "v0.0.0-20200804184101-5ec99f83aff1",
     )
+    go_repository(
+        name = "com_github_pkg_errors",
+        importpath = "github.com/pkg/errors",
+        sum = "h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=",
+        version = "v0.9.1",
+    )
diff --git a/src/cmd/cos_customizer/Dockerfile b/src/cmd/cos_customizer/Dockerfile
new file mode 100644
index 0000000..7e73347
--- /dev/null
+++ b/src/cmd/cos_customizer/Dockerfile
@@ -0,0 +1,137 @@
+# Step 1: build all bundled programs built with Bazel
+FROM gcr.io/cloud-builders/bazel AS bazel_builder
+ARG _BUILD_TOOLS_CACHE
+
+ADD . /workspace
+WORKDIR /workspace
+RUN bazel build \
+  --remote_cache=$_BUILD_TOOLS_CACHE \
+  //src/cmd/cos_customizer:cos_customizer \
+  //src/cmd/provisioner:provisioner_amd64 \
+  //src/cmd/provisioner:provisioner_arm64 \
+  //src/cmd/metadata_watcher:metadata_watcher_amd64 \
+  //src/cmd/metadata_watcher:metadata_watcher_arm64 \
+  //src/cmd/handle_disk_layout:handle_disk_layout_bin_amd64 \
+  //src/cmd/handle_disk_layout:handle_disk_layout_bin_arm64 \
+  @com_github_googlecloudplatform_docker_credential_gcr//:docker-credential-gcr_amd64 \
+  @com_github_googlecloudplatform_docker_credential_gcr//:docker-credential-gcr_arm64; \
+  mkdir -p _out/amd64; \
+  cp \
+    $(bazel cquery --output=files //src/cmd/cos_customizer:cos_customizer) \
+    $(bazel cquery --output=files //src/cmd/provisioner:provisioner_amd64) \
+    $(bazel cquery --output=files //src/cmd/metadata_watcher:metadata_watcher_amd64) \
+    $(bazel cquery --output=files //src/cmd/handle_disk_layout:handle_disk_layout_bin_amd64) \
+    $(bazel cquery --output=files @com_github_googlecloudplatform_docker_credential_gcr//:docker-credential-gcr_amd64) \
+    _out/amd64; \
+  mkdir -p _out/arm64; \
+  cp \
+    $(bazel cquery --output=files //src/cmd/provisioner:provisioner_arm64) \
+    $(bazel cquery --output=files //src/cmd/metadata_watcher:metadata_watcher_arm64) \
+    $(bazel cquery --output=files //src/cmd/handle_disk_layout:handle_disk_layout_bin_arm64) \
+    $(bazel cquery --output=files @com_github_googlecloudplatform_docker_credential_gcr//:docker-credential-gcr_arm64) \
+    _out/arm64
+
+# Step 2: build CIDATA and SCRATCH images
+FROM debian:bookworm AS cidata_builder
+
+RUN dpkg --add-architecture arm64; apt-get update; \
+  apt-get install -y --no-install-recommends dosfstools mtools
+
+# Output in /opt/veritysetup_amd64/veritysetup_amd64.tar.gz
+RUN mkdir -p /opt/veritysetup_amd64/{root,debs}
+WORKDIR /opt/veritysetup_amd64/debs
+RUN apt-get download \
+  coreutils:amd64 \
+  tar:amd64 \
+  libacl1:amd64 \
+  libattr1:amd64 \
+  libc6:amd64 \
+  libselinux1:amd64 \
+  libpcre3:amd64 \
+  cryptsetup-bin:amd64 \
+  libblkid1:amd64 \
+  libcryptsetup12:amd64 \
+  libpopt0:amd64 \
+  libuuid1:amd64 \
+  libdevmapper1.02.1:amd64 \
+  libgcrypt20:amd64 \
+  libargon2-1:amd64 \
+  libjson-c5:amd64 \
+  libudev1:amd64 \
+  libssl3:amd64 \
+  libpcre2-8-0:amd64
+WORKDIR /opt/veritysetup_amd64
+RUN for f in debs/*.deb; do dpkg-deb --extract $f root; done; \
+  tar czf veritysetup_amd64.tar.gz -C root .
+
+# Output in /opt/veritysetup_arm64/veritysetup_arm64.tar.gz
+RUN mkdir -p /opt/veritysetup_arm64/{root,debs}
+WORKDIR /opt/veritysetup_arm64/debs
+RUN apt-get download \
+  coreutils:arm64 \
+  tar:arm64 \
+  libacl1:arm64 \
+  libattr1:arm64 \
+  libc6:arm64 \
+  libselinux1:arm64 \
+  libpcre3:arm64 \
+  cryptsetup-bin:arm64 \
+  libblkid1:arm64 \
+  libcryptsetup12:arm64 \
+  libpopt0:arm64 \
+  libuuid1:arm64 \
+  libdevmapper1.02.1:arm64 \
+  libgcrypt20:arm64 \
+  libargon2-1:arm64 \
+  libjson-c5:arm64 \
+  libudev1:arm64 \
+  libssl3:arm64 \
+  libpcre2-8-0:arm64
+WORKDIR /opt/veritysetup_arm64
+RUN for f in debs/*.deb; do dpkg-deb --extract $f root; done; \
+  tar czf veritysetup_arm64.tar.gz -C root .
+
+# Output in /opt/cidata/cidata.img
+RUN mkdir -p /opt/cidata/deps
+WORKDIR /opt/cidata
+COPY --from=bazel_builder /workspace/src/data/startup.yaml deps/user-data
+COPY --from=bazel_builder /workspace/_out/amd64 deps/amd64
+COPY --from=bazel_builder /workspace/_out/arm64 deps/arm64
+RUN mkfs.fat -n CIDATA -S 512 -s 8 -C cidata.img 131072; \
+  touch meta-data; \
+  mcopy -i cidata.img deps/user-data ::/user-data; \
+  mcopy -i cidata.img meta-data ::/meta-data; \
+  mcopy -i cidata.img deps/amd64/provisioner_amd64 ::/provisioner_amd64; \
+  mcopy -i cidata.img deps/arm64/provisioner_arm64 ::/provisioner_arm64; \
+  mcopy -i cidata.img deps/amd64/metadata_watcher_amd64 ::/metadata_watcher_amd64; \
+  mcopy -i cidata.img deps/arm64/metadata_watcher_arm64 ::/metadata_watcher_arm64; \
+  mcopy -i cidata.img deps/amd64/docker-credential-gcr_amd64 ::/docker-credential-gcr_amd64; \
+  mcopy -i cidata.img deps/arm64/docker-credential-gcr_arm64 ::/docker-credential-gcr_arm64; \
+  mcopy -i cidata.img deps/amd64/handle_disk_layout_bin_amd64 ::/handle_disk_layout_bin_amd64; \
+  mcopy -i cidata.img deps/arm64/handle_disk_layout_bin_arm64 ::/handle_disk_layout_bin_arm64; \
+  mcopy -i cidata.img /opt/veritysetup_amd64/veritysetup_amd64.tar.gz ::/veritysetup_amd64.tar.gz; \
+  mcopy -i cidata.img /opt/veritysetup_arm64/veritysetup_arm64.tar.gz ::/veritysetup_arm64.tar.gz
+
+# Output in /opt/scratch/scratch.img
+RUN mkdir -p /opt/scratch
+WORKDIR /opt/scratch
+RUN fallocate -l 512M scratch.img; \
+  mkfs.ext4 scratch.img; \
+  tune2fs -c0 -i0 scratch.img; \
+  e2label scratch.img SCRATCH
+
+# Step 3: build the cos-customizer container image
+FROM gcr.io/compute-image-tools/daisy@sha256:a23774074d5941ed9e25f64ee7e02f96d2f8e09a4d7cee7131b49664267c33c7 AS daisy
+FROM debian:bookworm-slim
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+  tar \
+  mtools \
+  ca-certificates
+RUN mkdir -p /tmp; mkdir -p /workspace
+COPY --from=bazel_builder /workspace/src/data /data
+COPY --from=bazel_builder /workspace/_out/amd64/cos_customizer /cos_customizer
+COPY --from=daisy /daisy /daisy
+COPY --from=cidata_builder /opt/cidata/cidata.img /cidata.img
+COPY --from=cidata_builder /opt/scratch/scratch.img /scratch.img
+ENTRYPOINT ["/cos_customizer"]
diff --git a/src/cmd/cos_customizer/cloudbuild.yaml b/src/cmd/cos_customizer/cloudbuild.yaml
index b13cb0e..9de1966 100644
--- a/src/cmd/cos_customizer/cloudbuild.yaml
+++ b/src/cmd/cos_customizer/cloudbuild.yaml
@@ -20,16 +20,17 @@
   - |
     cat <<EOF | docker build -t bazel -
     FROM gcr.io/cloud-builders/bazel
-    RUN apt-get update && apt-get install -y mtools
+    RUN apt-get update && apt-get install -y mtools dosfstools
     EOF
 - name: 'bazel'
   args: ['test', '--remote_cache=${_BUILD_TOOLS_CACHE}', '--google_default_credentials', '--spawn_strategy=standalone','--','...','-//src/pkg/tools/...']
-- name: 'bazel'
-  args: ['run', '--remote_cache=${_BUILD_TOOLS_CACHE}', '--google_default_credentials', '--spawn_strategy=standalone', ':cos_customizer', '--', '--norun']
 - name: 'gcr.io/cloud-builders/docker'
-  args: ['tag', 'bazel:cos_customizer', 'gcr.io/${_OUTPUT_PROJECT}/cos-customizer:${TAG_NAME}']
-- name: 'gcr.io/cloud-builders/docker'
-  args: ['tag', 'bazel:cos_customizer', 'gcr.io/${_OUTPUT_PROJECT}/cos-customizer:latest']
+  args: ['build',
+         '-t', 'gcr.io/${_OUTPUT_PROJECT}/cos-customizer:${TAG_NAME}',
+         '-t', 'gcr.io/${_OUTPUT_PROJECT}/cos-customizer:latest',
+         '-f', 'src/cmd/cos_customizer/Dockerfile',
+         '--build-arg', '_BUILD_TOOLS_CACHE=${_BUILD_TOOLS_CACHE}',
+         '.']
 options:
   machineType: 'N1_HIGHCPU_8'
   substitutionOption: 'MUST_MATCH'
diff --git a/src/cmd/cos_customizer/finish_image_build_test.go b/src/cmd/cos_customizer/finish_image_build_test.go
index c812062..71cafc9 100644
--- a/src/cmd/cos_customizer/finish_image_build_test.go
+++ b/src/cmd/cos_customizer/finish_image_build_test.go
@@ -20,11 +20,13 @@
 	"fmt"
 	"io/ioutil"
 	"os"
+	"path/filepath"
 	"testing"
 
 	"cos.googlesource.com/cos/tools.git/src/pkg/config"
 	"cos.googlesource.com/cos/tools.git/src/pkg/fakes"
 	"cos.googlesource.com/cos/tools.git/src/pkg/fs"
+	"cos.googlesource.com/cos/tools.git/src/pkg/utils"
 
 	"cloud.google.com/go/storage"
 	"github.com/google/subcommands"
@@ -104,6 +106,16 @@
 		os.RemoveAll(tmpDir)
 		return "", nil, err
 	}
+	files.CIDataImg = filepath.Join(tmpDir, "cidata.img")
+	if err := utils.RunCommand([]string{"mkfs.fat", "-n", "CIDATA", "-S", "512", "-s", "8", "-C", files.CIDataImg, "131072"}, tmpDir, nil); err != nil {
+		os.RemoveAll(tmpDir)
+		return "", nil, err
+	}
+	files.ScratchImg, err = createTempFile(tmpDir)
+	if err != nil {
+		os.RemoveAll(tmpDir)
+		return "", nil, err
+	}
 	return tmpDir, files, nil
 }
 
diff --git a/src/cmd/provisioner/BUILD.bazel b/src/cmd/provisioner/BUILD.bazel
index 3c2c3be..3f0a0d0 100644
--- a/src/cmd/provisioner/BUILD.bazel
+++ b/src/cmd/provisioner/BUILD.bazel
@@ -13,53 +13,6 @@
 # limitations under the License.
 
 load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
-load("@io_bazel_rules_go//extras:embed_data.bzl", "go_embed_data")
-
-# Our goal is for this program to be embedded into this Go package. Go embed
-# only allows files in the same package directory to be embedded. So we need to
-# use a "no-op" genrule to place this binary in the same directory as the
-# package source.
-genrule(
-    name = "handle_disk_layout_amd64.bin",
-    srcs = ["//src/cmd/handle_disk_layout:handle_disk_layout_bin_amd64"],
-    outs = ["_handle_disk_layout_amd64.bin"],
-    cmd = "cp $< $@",
-)
-
-genrule(
-    name = "handle_disk_layout_arm64.bin",
-    srcs = ["//src/cmd/handle_disk_layout:handle_disk_layout_bin_arm64"],
-    outs = ["_handle_disk_layout_arm64.bin"],
-    cmd = "cp $< $@",
-)
-
-genrule(
-    name = "veritysetup_amd64.img",
-    srcs = ["//:veritysetup_amd64.tar"],
-    outs = ["_veritysetup_amd64.img"],
-    cmd = "cp $< $@",
-)
-
-genrule(
-    name = "veritysetup_arm64.img",
-    srcs = ["//:veritysetup_arm64.tar"],
-    outs = ["_veritysetup_arm64.img"],
-    cmd = "cp $< $@",
-)
-
-genrule(
-    name = "docker_credential_gcr_amd64",
-    srcs = ["@com_github_googlecloudplatform_docker_credential_gcr//:docker-credential-gcr_amd64"],
-    outs = ["docker-credential-gcr_amd64"],
-    cmd = "cp $< $@",
-)
-
-genrule(
-    name = "docker_credential_gcr_arm64",
-    srcs = ["@com_github_googlecloudplatform_docker_credential_gcr//:docker-credential-gcr_arm64"],
-    outs = ["docker-credential-gcr_arm64"],
-    cmd = "cp $< $@",
-)
 
 go_library(
     name = "provisioner_lib",
@@ -67,21 +20,7 @@
         "main.go",
         "resume.go",
         "run.go",
-        "embeds_linux_amd64.go",
-        "embeds_linux_arm64.go",
     ],
-    embedsrcs = select({
-        "@io_bazel_rules_go//go/toolchain:amd64": [
-            ":handle_disk_layout_amd64.bin",
-            ":veritysetup_amd64.img",
-            ":docker_credential_gcr_amd64",
-        ],
-        "@io_bazel_rules_go//go/toolchain:arm64": [
-            ":handle_disk_layout_arm64.bin",
-            ":veritysetup_arm64.img",
-            ":docker_credential_gcr_arm64",
-        ],
-    }),
     importpath = "cos.googlesource.com/cos/tools.git/src/cmd/provisioner",
     visibility = ["//visibility:private"],
     deps = [
diff --git a/src/cmd/provisioner/embeds_linux_amd64.go b/src/cmd/provisioner/embeds_linux_amd64.go
deleted file mode 100644
index 427f337..0000000
--- a/src/cmd/provisioner/embeds_linux_amd64.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import _ "embed"
-
-//go:embed _handle_disk_layout_amd64.bin
-var handleDiskLayoutBin []byte
-
-//go:embed _veritysetup_amd64.img
-var veritySetupImage []byte
-
-//go:embed docker-credential-gcr_amd64
-var dockerCredentialGCR []byte
diff --git a/src/cmd/provisioner/embeds_linux_arm64.go b/src/cmd/provisioner/embeds_linux_arm64.go
deleted file mode 100644
index b3c56b2..0000000
--- a/src/cmd/provisioner/embeds_linux_arm64.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import _ "embed"
-
-//go:embed _handle_disk_layout_arm64.bin
-var handleDiskLayoutBin []byte
-
-//go:embed _veritysetup_arm64.img
-var veritySetupImage []byte
-
-//go:embed docker-credential-gcr_arm64
-var dockerCredentialGCR []byte
diff --git a/src/cmd/provisioner/main.go b/src/cmd/provisioner/main.go
index ef889b2..966ebfb 100644
--- a/src/cmd/provisioner/main.go
+++ b/src/cmd/provisioner/main.go
@@ -32,6 +32,9 @@
 	stateDir = flag.String("state-dir", "/var/lib/.cos-customizer", "Absolute path to the directory to use for provisioner state. "+
 		"This directory is used for persisting internal state across reboots, unpacking inputs, and running provisioning scripts. "+
 		"The size of the directory scales with the size of the inputs.")
+	dockerCredentialGCR = flag.String("docker-credential-gcr", "", "Path to the docker-credential-gcr executable to use during provisioning.")
+	veritySetupImage    = flag.String("veritysetup-image", "", "Path to the veritysetup file system tarball to use as a Docker container during provisioning.")
+	handleDiskLayoutBin = flag.String("handle-disk-layout-bin", "", "Path to the handle_disk_layout executable to use during provisioning.")
 )
 
 func main() {
@@ -56,9 +59,9 @@
 		Resize2fsCmd:        "resize2fs",
 		E2fsckCmd:           "e2fsck",
 		RootDir:             "/",
-		DockerCredentialGCR: dockerCredentialGCR,
-		VeritySetupImage:    veritySetupImage,
-		HandleDiskLayoutBin: handleDiskLayoutBin,
+		DockerCredentialGCR: *dockerCredentialGCR,
+		VeritySetupImage:    *veritySetupImage,
+		HandleDiskLayoutBin: *handleDiskLayoutBin,
 	}
 	var exitCode int
 	ret := subcommands.Execute(ctx, deps, &exitCode)
diff --git a/src/data/startup.yaml b/src/data/startup.yaml
index 20b8958..9f55be1 100644
--- a/src/data/startup.yaml
+++ b/src/data/startup.yaml
@@ -101,9 +101,17 @@
       status mkdir -p /mnt/disks/cidata
       status mount /dev/disk/by-label/CIDATA /mnt/disks/cidata
       if [[ ! -d /var/lib/.cos-customizer ]]; then
-        run_provisioner /mnt/disks/cidata/provisioner_${ARCH} run --config=/mnt/disks/cidata/config.json
+        run_provisioner /mnt/disks/cidata/provisioner_${ARCH} \
+          --docker-credential-gcr=/mnt/disks/cidata/docker-credential-gcr_${ARCH} \
+          --veritysetup-image=/mnt/disks/cidata/veritysetup_${ARCH}.tar.gz \
+          --handle-disk-layout-bin=/mnt/disks/cidata/handle_disk_layout_bin_${ARCH} \
+          run --config=/mnt/disks/cidata/config.json
       else
-        run_provisioner /mnt/disks/cidata/provisioner_${ARCH} resume
+        run_provisioner /mnt/disks/cidata/provisioner_${ARCH} \
+          --docker-credential-gcr=/mnt/disks/cidata/docker-credential-gcr_${ARCH} \
+          --veritysetup-image=/mnt/disks/cidata/veritysetup_${ARCH}.tar.gz \
+          --handle-disk-layout-bin=/mnt/disks/cidata/handle_disk_layout_bin_${ARCH} \
+          resume
       fi
     }
 
diff --git a/src/pkg/fs/file_system.go b/src/pkg/fs/file_system.go
index e9139b7..d7dd49f 100644
--- a/src/pkg/fs/file_system.go
+++ b/src/pkg/fs/file_system.go
@@ -61,6 +61,12 @@
 	DaisyWorkflow string
 	// DaisyBin points to the Daisy binary.
 	DaisyBin string
+	// CIDataImg points to the vfat image that delivers the provisioner and its
+	// dependencies to the build VM.
+	CIDataImg string
+	// ScratchImg points to an empty ext4 file system image that is used by the
+	// provisioner for scratch space.
+	ScratchImg string
 }
 
 // DefaultFiles builds a Files struct with a default file layout.
@@ -74,6 +80,8 @@
 		ProvConfig:              filepath.Join(persistentDir, provConfig),
 		DaisyWorkflow:           filepath.Join(volatileDir, daisyWorkflow),
 		DaisyBin:                daisyBin,
+		CIDataImg:               "/cidata.img",
+		ScratchImg:              "/scratch.img",
 	}
 }
 
diff --git a/src/pkg/preloader/BUILD.bazel b/src/pkg/preloader/BUILD.bazel
index 021204a..3fb01ca 100644
--- a/src/pkg/preloader/BUILD.bazel
+++ b/src/pkg/preloader/BUILD.bazel
@@ -14,51 +14,12 @@
 
 load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
 
-genrule(
-    name = "scratch",
-    outs = ["scratch.img"],
-    cmd = "\
-fallocate -l 512M $@;\
-mkfs.ext4 $@;\
-tune2fs -c0 -i0 $@;\
-e2label $@ SCRATCH",
-)
-
-genrule(
-    name = "cidata",
-    srcs = [
-        "//:src/data/startup.yaml",
-        "//src/cmd/provisioner:provisioner_amd64",
-        "//src/cmd/provisioner:provisioner_arm64",
-        "//src/cmd/metadata_watcher:metadata_watcher_amd64",
-        "//src/cmd/metadata_watcher:metadata_watcher_arm64",
-    ],
-    outs = ["cidata.img"],
-    cmd = "\
-$(location @dosfstools//:mkfs.fat) -n CIDATA -S 512 -s 8 -C $@ 131072;\
-touch meta-data;\
-$(location @mtools//:mcopy) -i $@ $(location //:src/data/startup.yaml) ::/user-data;\
-$(location @mtools//:mcopy) -i $@ meta-data ::/meta-data;\
-$(location @mtools//:mcopy) -i $@ $(location //src/cmd/provisioner:provisioner_amd64) ::/provisioner_amd64;\
-$(location @mtools//:mcopy) -i $@ $(location //src/cmd/provisioner:provisioner_arm64) ::/provisioner_arm64;\
-$(location @mtools//:mcopy) -i $@ $(location //src/cmd/metadata_watcher:metadata_watcher_amd64) ::/metadata_watcher_amd64;\
-$(location @mtools//:mcopy) -i $@ $(location //src/cmd/metadata_watcher:metadata_watcher_arm64) ::/metadata_watcher_arm64;",
-    tools = [
-        "@dosfstools//:mkfs.fat",
-        "@mtools//:mcopy",
-    ],
-)
-
 go_library(
     name = "preloader",
     srcs = [
         "gcs.go",
         "preload.go",
     ],
-    embedsrcs = [
-        ":cidata",
-	":scratch"
-    ],
     importpath = "cos.googlesource.com/cos/tools.git/src/pkg/preloader",
     visibility = ["//visibility:public"],
     deps = [
diff --git a/src/pkg/preloader/preload.go b/src/pkg/preloader/preload.go
index 23dccbf..dba5e9e 100644
--- a/src/pkg/preloader/preload.go
+++ b/src/pkg/preloader/preload.go
@@ -18,7 +18,6 @@
 
 import (
 	"context"
-	_ "embed"
 	"encoding/json"
 	"fmt"
 	"io/ioutil"
@@ -40,12 +39,6 @@
 	"cloud.google.com/go/storage"
 )
 
-//go:embed cidata.img
-var ciDataImg []byte
-
-//go:embed scratch.img
-var scratchImg []byte
-
 // storeInGCS stores the given files in GCS using the given gcsManager.
 // Files to store are provided in a map where each key is a file on the local
 // file system and each value is the relative path in GCS at which to store the
@@ -203,18 +196,16 @@
 	return utils.RunCommand([]string{"mcopy", "-i", path, files.ProvConfig, "::/config.json"}, "", nil)
 }
 
-func writeImage(imgData *[]byte) (path string, err error) {
+func writeImage(fileName string) (path string, err error) {
 	img, err := ioutil.TempFile(fs.ScratchDir, "img-")
 	if err != nil {
 		return "", err
 	}
-	_, writeErr := img.Write(*imgData)
-	closeErr := img.Close()
-	if writeErr != nil {
-		return "", writeErr
+	if err := img.Close(); err != nil {
+		return "", err
 	}
-	if closeErr != nil {
-		return "", closeErr
+	if err := utils.CopyFile(fileName, img.Name()); err != nil {
+		return "", err
 	}
 	return img.Name(), err
 }
@@ -305,7 +296,7 @@
 	if err := updateProvConfig(provConfig, buildSpec, buildContexts, gcs, files); err != nil {
 		return nil, err
 	}
-	ciDataFile, err := writeImage(&ciDataImg)
+	ciDataFile, err := writeImage(files.CIDataImg)
 	if err != nil {
 		return nil, err
 	}
@@ -316,11 +307,7 @@
 	if err != nil {
 		return nil, err
 	}
-	scratchImgFile, err := writeImage(&scratchImg)
-	if err != nil {
-		return nil, err
-	}
-	scratchImgFileTar, err := tarImage(scratchImgFile)
+	scratchImgFileTar, err := tarImage(files.ScratchImg)
 	if err != nil {
 		return nil, err
 	}
diff --git a/src/pkg/preloader/preload_test.go b/src/pkg/preloader/preload_test.go
index 045a8bc..bd14663 100644
--- a/src/pkg/preloader/preload_test.go
+++ b/src/pkg/preloader/preload_test.go
@@ -28,6 +28,7 @@
 	"cos.googlesource.com/cos/tools.git/src/pkg/fakes"
 	"cos.googlesource.com/cos/tools.git/src/pkg/fs"
 	"cos.googlesource.com/cos/tools.git/src/pkg/provisioner"
+	"cos.googlesource.com/cos/tools.git/src/pkg/utils"
 
 	"github.com/google/go-cmp/cmp"
 	compute "google.golang.org/api/compute/v1"
@@ -65,6 +66,16 @@
 		os.RemoveAll(tmpDir)
 		return "", nil, err
 	}
+	files.CIDataImg = filepath.Join(tmpDir, "cidata.img")
+	if err := utils.RunCommand([]string{"mkfs.fat", "-n", "CIDATA", "-S", "512", "-s", "8", "-C", files.CIDataImg, "131072"}, tmpDir, nil); err != nil {
+		os.RemoveAll(tmpDir)
+		return "", nil, err
+	}
+	files.ScratchImg, err = createTempFile(tmpDir)
+	if err != nil {
+		os.RemoveAll(tmpDir)
+		return "", nil, err
+	}
 	return tmpDir, files, nil
 }
 
diff --git a/src/pkg/provisioner/config.go b/src/pkg/provisioner/config.go
index a0ccf09..adb1191 100644
--- a/src/pkg/provisioner/config.go
+++ b/src/pkg/provisioner/config.go
@@ -94,9 +94,9 @@
 type stepDeps struct {
 	// GCSClient is used to access Google Cloud Storage.
 	GCSClient *storage.Client
-	// VeritySetupImage is an embedded Docker image that contains the
-	// "veritysetup" tool.
-	VeritySetupImage []byte
+	// VeritySetupImage is a path to a file system tarball (can be imported as a
+	// Docker image) that contains the "veritysetup" tool.
+	VeritySetupImage string
 }
 
 type step interface {
diff --git a/src/pkg/provisioner/disk_layout.go b/src/pkg/provisioner/disk_layout.go
index 5cb418a..7950700 100644
--- a/src/pkg/provisioner/disk_layout.go
+++ b/src/pkg/provisioner/disk_layout.go
@@ -101,7 +101,11 @@
 	if err := mountFunc("", filepath.Join(deps.RootDir, "tmp"), "", unix.MS_REMOUNT|unix.MS_NOSUID|unix.MS_NODEV, ""); err != nil {
 		return fmt.Errorf("error remounting /tmp as exec: %v", err)
 	}
-	if err := ioutil.WriteFile(filepath.Join(deps.RootDir, "tmp", "handle_disk_layout.bin"), deps.HandleDiskLayoutBin, 0744); err != nil {
+	out := filepath.Join(deps.RootDir, "tmp", "handle_disk_layout.bin")
+	if err := utils.CopyFile(deps.HandleDiskLayoutBin, out); err != nil {
+		return err
+	}
+	if err := os.Chmod(out, 755); err != nil {
 		return err
 	}
 	data := fmt.Sprintf(`[Unit]
diff --git a/src/pkg/provisioner/provisioner.go b/src/pkg/provisioner/provisioner.go
index 954a5eb..48f9f28 100644
--- a/src/pkg/provisioner/provisioner.go
+++ b/src/pkg/provisioner/provisioner.go
@@ -115,7 +115,10 @@
 		}
 	}
 	if _, err := os.Stat(dockerCredentialGCRPath); os.IsNotExist(err) {
-		if err := ioutil.WriteFile(dockerCredentialGCRPath, deps.DockerCredentialGCR, 0744); err != nil {
+		if err := utils.CopyFile(deps.DockerCredentialGCR, dockerCredentialGCRPath); err != nil {
+			return err
+		}
+		if err := os.Chmod(dockerCredentialGCRPath, 0755); err != nil {
 			return err
 		}
 	}
@@ -334,15 +337,15 @@
 	// RootDir is the path to the root file system. Should be "/" in all real
 	// runtime situations.
 	RootDir string
-	// DockerCredentialGCR is an embedded docker-credential-gcr program to use as a Docker
+	// DockerCredentialGCR is a path to a docker-credential-gcr program to use as a Docker
 	// credential helper.
-	DockerCredentialGCR []byte
-	// VeritySetupImage is an embedded Docker image that contains the
-	// "veritysetup" tool.
-	VeritySetupImage []byte
-	// HandleDiskLayoutBin is an embedded program for reformatting a COS disk
+	DockerCredentialGCR string
+	// VeritySetupImage is a path to a file system tarball (which can be imported
+	// as a Docker image) that contains the "veritysetup" tool.
+	VeritySetupImage string
+	// HandleDiskLayoutBin is a path to a program for reformatting a COS disk
 	// image.
-	HandleDiskLayoutBin []byte
+	HandleDiskLayoutBin string
 }
 
 func run(ctx context.Context, deps Deps, runState *state) (err error) {
diff --git a/src/pkg/provisioner/provisioner_test.go b/src/pkg/provisioner/provisioner_test.go
index 92af977..a4172c2 100644
--- a/src/pkg/provisioner/provisioner_test.go
+++ b/src/pkg/provisioner/provisioner_test.go
@@ -27,8 +27,6 @@
 	"golang.org/x/sys/unix"
 )
 
-const trueExecutable = "#!/bin/bash\ntrue"
-
 func testDataDir(t *testing.T) string {
 	t.Helper()
 	path, err := filepath.Abs("testdata")
@@ -73,9 +71,9 @@
 		GCSClient:           nil,
 		TarCmd:              "",
 		SystemctlCmd:        "",
-		DockerCredentialGCR: []byte(trueExecutable),
-		VeritySetupImage:    []byte(trueExecutable),
-		HandleDiskLayoutBin: []byte(trueExecutable),
+		DockerCredentialGCR: "/bin/true",
+		VeritySetupImage:    "/bin/true",
+		HandleDiskLayoutBin: "/bin/true",
 	}
 	config := Config{}
 	if err := Run(ctx, deps, dir, config); err != errStateAlreadyExists {
@@ -118,9 +116,9 @@
 				TarCmd:              "tar",
 				SystemctlCmd:        "/bin/true",
 				RootDir:             tempDir,
-				DockerCredentialGCR: []byte(trueExecutable),
-				VeritySetupImage:    []byte(trueExecutable),
-				HandleDiskLayoutBin: []byte(trueExecutable),
+				DockerCredentialGCR: "/bin/true",
+				VeritySetupImage:    "/bin/true",
+				HandleDiskLayoutBin: "/bin/true",
 			}
 			stateDir := filepath.Join(tempDir, "var", "lib", ".cos-customizer")
 			if err := stubMountInfo(filepath.Join(tempDir, "proc", "self", "mountinfo"), filepath.Join(stateDir, "bin")); err != nil {
@@ -193,9 +191,9 @@
 				TarCmd:              "tar",
 				SystemctlCmd:        "/bin/true",
 				RootDir:             tempDir,
-				DockerCredentialGCR: []byte(trueExecutable),
-				VeritySetupImage:    []byte(trueExecutable),
-				HandleDiskLayoutBin: []byte(trueExecutable),
+				DockerCredentialGCR: "/bin/true",
+				VeritySetupImage:    "/bin/true",
+				HandleDiskLayoutBin: "/bin/true",
 			}
 			stateDir := filepath.Join(tempDir, "var", "lib", ".cos-customizer")
 			if err := stubMountInfo(filepath.Join(tempDir, "proc", "self", "mountinfo"), filepath.Join(stateDir, "bin")); err != nil {
@@ -276,9 +274,9 @@
 				TarCmd:              "tar",
 				SystemctlCmd:        "/bin/true",
 				RootDir:             tempDir,
-				DockerCredentialGCR: []byte(trueExecutable),
-				VeritySetupImage:    []byte(trueExecutable),
-				HandleDiskLayoutBin: []byte(trueExecutable),
+				DockerCredentialGCR: "/bin/true",
+				VeritySetupImage:    "/bin/true",
+				HandleDiskLayoutBin: "/bin/true",
 			}
 			stateDir := filepath.Join(tempDir, "var", "lib", ".cos-customizer")
 			if err := stubMountInfo(filepath.Join(tempDir, "proc", "self", "mountinfo"), filepath.Join(stateDir, "bin")); err != nil {
diff --git a/src/pkg/provisioner/seal_oem_step.go b/src/pkg/provisioner/seal_oem_step.go
index 9c1415e..22e8795 100644
--- a/src/pkg/provisioner/seal_oem_step.go
+++ b/src/pkg/provisioner/seal_oem_step.go
@@ -16,12 +16,12 @@
 
 import (
 	"context"
-	"io/ioutil"
 	"log"
 	"os"
 	"path/filepath"
 
 	"cos.googlesource.com/cos/tools.git/src/pkg/tools"
+	"cos.googlesource.com/cos/tools.git/src/pkg/utils"
 )
 
 type SealOEMStep struct{}
@@ -30,7 +30,7 @@
 	log.Println("Sealing the OEM partition with dm-verity")
 	veritysetupImgPath := filepath.Join(runState.dir, "veritysetup.img")
 	if _, err := os.Stat(veritysetupImgPath); os.IsNotExist(err) {
-		if err := ioutil.WriteFile(veritysetupImgPath, deps.VeritySetupImage, 0644); err != nil {
+		if err := utils.CopyFile(deps.VeritySetupImage, veritysetupImgPath); err != nil {
 			return err
 		}
 	}
diff --git a/src/pkg/tools/seal_oem_partition.go b/src/pkg/tools/seal_oem_partition.go
index cd86cf6..604bc75 100644
--- a/src/pkg/tools/seal_oem_partition.go
+++ b/src/pkg/tools/seal_oem_partition.go
@@ -73,13 +73,14 @@
 // loadVeritysetupImage loads the docker image of veritysetup.
 // return the image ID.
 func loadVeritysetupImage(imgPath string) (string, error) {
-	cmd := exec.Command("sudo", "docker", "load", "-i", imgPath)
+	tag := "veritysetup:veritysetup_" + runtime.GOARCH
+	cmd := exec.Command("sudo", "docker", "import", imgPath, tag)
 	if err := cmd.Run(); err != nil {
 		return "", fmt.Errorf("error in loading docker image, "+
 			"input: imgPath=%q, error msg: (%v)", imgPath, err)
 	}
 	var idBuf bytes.Buffer
-	cmd = exec.Command("sudo", "docker", "images", "veritysetup:veritysetup_"+runtime.GOARCH, "-q")
+	cmd = exec.Command("sudo", "docker", "images", tag, "-q")
 	cmd.Stdout = &idBuf
 	cmd.Stderr = os.Stderr
 	if err := cmd.Run(); err != nil {
@@ -199,7 +200,7 @@
 	dmVersion := 0
 	for idx, line := range lines {
 		if !strings.Contains(line, "dm=") &&
-		   !strings.Contains(line, "dm-mod.create=") {
+			!strings.Contains(line, "dm-mod.create=") {
 			continue
 		}
 		var startPos = strings.Index(line, "dm=")
@@ -214,7 +215,7 @@
 			lineBuf[startPos+4] = '2'
 			lines[idx] = strings.Join(append(strings.Split(string(lineBuf), ","), entryStringV0), ",")
 		} else {
-			configs := []string {string(lineBuf), entryStringV1}
+			configs := []string{string(lineBuf), entryStringV1}
 			lines[idx] = strings.Join(configs, ";")
 		}
 	}
diff --git a/src/third_party/dosfstools/BUILD.bazel b/src/third_party/dosfstools/BUILD.bazel
deleted file mode 100644
index 8e71575..0000000
--- a/src/third_party/dosfstools/BUILD.bazel
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the License);
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an AS IS BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
diff --git a/src/third_party/dosfstools/BUILD.dosfstools.bazel b/src/third_party/dosfstools/BUILD.dosfstools.bazel
deleted file mode 100644
index 98ee6e8..0000000
--- a/src/third_party/dosfstools/BUILD.dosfstools.bazel
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the License);
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an AS IS BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("@rules_foreign_cc//tools/build_defs:configure.bzl", "configure_make")
-
-package(default_visibility = ["//visibility:public"])
-
-filegroup(
-    name = "all_srcs",
-    srcs = glob(["**"]),
-)
-
-configure_make(
-    name = "dosfstools_pkg",
-    lib_source = ":all_srcs",
-    configure_options = ["--disable-dependency-tracking"],
-    make_commands = [
-        # dosfstools requires the path to 'make' be present in the MAKE
-        # variable. Since the configure_make() rule doesn't do this for us, some
-        # magic is needed.
-        # 1. Set MAKE to the output of a 'shell' function that reads the path of
-        # the parent process. The parent process of the 'shell' function is the
-        # make process, run by configure_make() using the correct make program.
-        # 2. Write "$$PID" as "$$$PID$$". We do this because the
-        # configure_make() rule has a substitution that does "$$PID$$" ->
-        # "$PID".
-        "make MAKE='$(shell realpath /proc/$$$PPID$$/exe)'",
-        "make MAKE='$(shell realpath /proc/$$$PPID$$/exe)' install",
-    ],
-    out_bin_dir = "sbin",
-    binaries = ["mkfs.fat"],
-)
-
-filegroup(
-    name = "mkfs.fat",
-    srcs = [":dosfstools_pkg"],
-    output_group = "mkfs.fat",
-)
diff --git a/src/third_party/dosfstools/dosfstools_repositories.bzl b/src/third_party/dosfstools/dosfstools_repositories.bzl
deleted file mode 100644
index 1c839ca..0000000
--- a/src/third_party/dosfstools/dosfstools_repositories.bzl
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the License);
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an AS IS BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
-
-def dosfstools_repositories():
-    """Load all repositories needed for dosfstools."""
-
-    maybe(
-        http_archive,
-        name = "dosfstools",
-        build_file = Label("//src/third_party/dosfstools:BUILD.dosfstools.bazel"),
-        strip_prefix = "dosfstools-4.2",
-        urls = ["https://github.com/dosfstools/dosfstools/releases/download/v4.2/dosfstools-4.2.tar.gz"],
-        sha256 = "64926eebf90092dca21b14259a5301b7b98e7b1943e8a201c7d726084809b527",
-    )
diff --git a/src/third_party/mtools/BUILD.bazel b/src/third_party/mtools/BUILD.bazel
deleted file mode 100644
index 8e71575..0000000
--- a/src/third_party/mtools/BUILD.bazel
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the License);
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an AS IS BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
diff --git a/src/third_party/mtools/BUILD.mtools.bazel b/src/third_party/mtools/BUILD.mtools.bazel
deleted file mode 100644
index 9b0f74d..0000000
--- a/src/third_party/mtools/BUILD.mtools.bazel
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the License);
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an AS IS BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("@rules_foreign_cc//tools/build_defs:configure.bzl", "configure_make")
-
-package(default_visibility = ["//visibility:public"])
-
-filegroup(
-    name = "all_srcs",
-    srcs = glob(["**"]),
-)
-
-configure_make(
-    name = "mtools_pkg",
-    lib_source = ":all_srcs",
-    binaries = ["mcopy"],
-)
-
-filegroup(
-    name = "mcopy",
-    srcs = [":mtools_pkg"],
-    output_group = "mcopy",
-)
diff --git a/src/third_party/mtools/mtools_repositories.bzl b/src/third_party/mtools/mtools_repositories.bzl
deleted file mode 100644
index 79064d9..0000000
--- a/src/third_party/mtools/mtools_repositories.bzl
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the License);
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an AS IS BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
-load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
-
-def mtools_repositories():
-    """Load all repositories needed for mtools."""
-
-    maybe(
-        http_archive,
-        name = "mtools",
-        build_file = Label("//src/third_party/mtools:BUILD.mtools.bazel"),
-        strip_prefix = "mtools-4.0.26",
-        urls = [
-            "https://mirror.bazel.build/ftp.gnu.org/gnu/mtools/mtools-4.0.26.tar.gz",
-            "http://ftp.gnu.org/gnu/mtools/mtools-4.0.26.tar.gz",
-        ],
-        sha256 = "b1adb6973d52b3b70b16047e682f96ef1b669d6b16894c9056a55f407e71cd0f",
-    )
diff --git a/testing/deprecate_test.yaml b/testing/deprecate_test.yaml
index 93dfa34..572cd18 100644
--- a/testing/deprecate_test.yaml
+++ b/testing/deprecate_test.yaml
@@ -13,38 +13,38 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "deprecate_test"
-  "_INPUT_IMAGE": "cos-dev-69-10895-0-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'deprecate_test'
+  '_INPUT_IMAGE': 'cos-93-16623-461-15'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
 - name: 'gcr.io/cloud-builders/gcloud'
-  args: ["compute", "images", "create", "preload-test-$BUILD_ID-old",
-         "--source-image=${_INPUT_IMAGE}", "--source-image-project=${_INPUT_PROJECT}",
-         "--family=test-family"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-family=test-family",
-         "-deprecate-old-images",
-         "-image-project=$PROJECT_ID"]
+  args: ['compute', 'images', 'create', 'preload-test-$BUILD_ID-old',
+         '--source-image=${_INPUT_IMAGE}', '--source-image-project=${_INPUT_PROJECT}',
+         '--family=test-family']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-family=test-family',
+         '-deprecate-old-images',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/cloud-builders/gcloud'
   entrypoint: '/bin/bash'
   env:
-  - "OLD_IMAGE=preload-test-$BUILD_ID-old"
-  - "IMAGE=preload-test-$BUILD_ID"
-  - "PROJECT=$PROJECT_ID"
-  args: ["/workspace/testing/${_TEST}/run_test.sh"]
+  - 'OLD_IMAGE=preload-test-$BUILD_ID-old'
+  - 'IMAGE=preload-test-$BUILD_ID'
+  - 'PROJECT=$PROJECT_ID'
+  args: ['/workspace/testing/${_TEST}/run_test.sh']
 options:
   machineType: 'N1_HIGHCPU_8'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/disable_auto_update_test.yaml b/testing/disable_auto_update_test.yaml
index 4231a0e..5a724b5 100644
--- a/testing/disable_auto_update_test.yaml
+++ b/testing/disable_auto_update_test.yaml
@@ -13,34 +13,34 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "disable_auto_update_test"
-  "_INPUT_IMAGE": "cos-81-12871-148-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'disable_auto_update_test'
+  '_INPUT_IMAGE': 'cos-81-12871-148-0'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["disable-auto-update"]        
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['disable-auto-update']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_32'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/env_test.yaml b/testing/env_test.yaml
index dad5b19..11b1a8e 100644
--- a/testing/env_test.yaml
+++ b/testing/env_test.yaml
@@ -13,33 +13,33 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "env_test"
-  "_INPUT_IMAGE": "cos-dev-69-10895-0-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'env_test'
+  '_INPUT_IMAGE': 'cos-93-16623-461-15'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh",
-         "-env=HELLO=hello"]
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh',
+         '-env=HELLO=hello']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_8'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/extend_oem_test/extend_oem_test.yaml b/testing/extend_oem_test/extend_oem_test.yaml
index 5516179..dea2b5a 100644
--- a/testing/extend_oem_test/extend_oem_test.yaml
+++ b/testing/extend_oem_test/extend_oem_test.yaml
@@ -13,40 +13,40 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "extend_oem_test"
-  "_INPUT_IMAGE": "cos-81-12871-148-0"
-  "_INPUT_PROJECT": "cos-cloud"
-  "_OEM_SIZE": ""
-  "_DISK_SIZE": ""
-  "_OEM_SIZE_TH": ""
+  '_TEST': 'extend_oem_test'
+  '_INPUT_IMAGE': 'cos-81-12871-148-0'
+  '_INPUT_PROJECT': 'cos-cloud'
+  '_OEM_SIZE': ''
+  '_DISK_SIZE': ''
+  '_OEM_SIZE_TH': ''
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
 - name: 'busybox'
-  args: ["sed", "-i", "-e", "s|%s|'${_OEM_SIZE_TH}'|",
-         "testing/${_TEST}/preload_test.cfg"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID",
-         "-disk-size-gb=${_DISK_SIZE}",
-         "-oem-size=${_OEM_SIZE}"]
+  args: ['sed', '-i', '-e', 's|%s|"${_OEM_SIZE_TH}"|',
+         'testing/${_TEST}/preload_test.cfg']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID',
+         '-disk-size-gb=${_DISK_SIZE}',
+         '-oem-size=${_OEM_SIZE}']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_32'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/gpu_test/gpu_test.yaml b/testing/gpu_test/gpu_test.yaml
index c9f49de..d97fe5c 100644
--- a/testing/gpu_test/gpu_test.yaml
+++ b/testing/gpu_test/gpu_test.yaml
@@ -13,16 +13,16 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "gpu_test"
-  "_INPUT_IMAGE": "cos-89-16108-798-1"
-  "_INPUT_PROJECT": "cos-cloud"
-  "_DRIVER_VERSION": ""
-  "_DEPS_DIR": ""
+  '_TEST': 'gpu_test'
+  '_INPUT_IMAGE': 'cos-89-16108-798-1'
+  '_INPUT_PROJECT': 'cos-cloud'
+  '_DRIVER_VERSION': ''
+  '_DEPS_DIR': ''
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
 - name: 'ubuntu'
-  args: 
+  args:
   - bash
   - -c
   - |
@@ -33,32 +33,32 @@
       sub="${ver}"
     fi
     sed -i -e "s|%s|'${sub}'|" testing/${_TEST}/preload_test.cfg
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["install-gpu",
-         "-version=${_DRIVER_VERSION}",
-         "-gpu-type=nvidia-tesla-t4",
-         "-deps-dir=${_DEPS_DIR}"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['install-gpu',
+         '-version=${_DRIVER_VERSION}',
+         '-gpu-type=nvidia-tesla-t4',
+         '-deps-dir=${_DEPS_DIR}']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "-var:vm_workflow",
-         "./gpu_vm.wf.json", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', '-var:vm_workflow',
+         './gpu_vm.wf.json', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_32'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/image_test.yaml b/testing/image_test.yaml
index 6eaeb9e..cb82e30 100644
--- a/testing/image_test.yaml
+++ b/testing/image_test.yaml
@@ -13,39 +13,39 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "image_test"
-  "_INPUT_IMAGE": "cos-dev-69-10895-0-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'image_test'
+  '_INPUT_IMAGE': 'cos-93-16623-461-15'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-labels=hello=world,test_key=test_value",
-         "-licenses=projects/cos-cloud/global/licenses/cos-gpu",
-         "-disk-size-gb=50",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-family=test-family",
-         "-image-project=$PROJECT_ID"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-labels=hello=world,test_key=test_value',
+         '-licenses=projects/cos-cloud/global/licenses/cos-gpu',
+         '-disk-size-gb=50',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-family=test-family',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/cloud-builders/gcloud'
   entrypoint: '/bin/bash'
   env:
-  - "IMAGE=preload-test-$BUILD_ID"
-  - "PROJECT=$PROJECT_ID"
-  - "LABELS=hello=world;test_key=test_value"
-  - "FAMILY=test-family"
-  - "DISK_SIZE_GB=50"
-  - "LICENSES=https://www.googleapis.com/compute/v1/projects/cos-cloud/global/licenses/cos-gpu;https://www.googleapis.com/compute/v1/projects/cos-cloud/global/licenses/cos"
-  args: ["/workspace/testing/${_TEST}/run_test.sh"]
+  - 'IMAGE=preload-test-$BUILD_ID'
+  - 'PROJECT=$PROJECT_ID'
+  - 'LABELS=hello=world;test_key=test_value'
+  - 'FAMILY=test-family'
+  - 'DISK_SIZE_GB=50'
+  - 'LICENSES=https://www.googleapis.com/compute/v1/projects/cos-cloud-shielded/global/licenses/shielded-cos;https://www.googleapis.com/compute/v1/projects/cos-cloud/global/licenses/cos-pcid;https://www.googleapis.com/compute/v1/projects/cos-cloud/global/licenses/cos;https://www.googleapis.com/compute/v1/projects/cos-cloud/global/licenses/cos-gpu'
+  args: ['/workspace/testing/${_TEST}/run_test.sh']
 options:
   machineType: 'N1_HIGHCPU_8'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/install_packages_remote_pkgspec_test.yaml b/testing/install_packages_remote_pkgspec_test.yaml
index 04a7ea6..66bcfac 100644
--- a/testing/install_packages_remote_pkgspec_test.yaml
+++ b/testing/install_packages_remote_pkgspec_test.yaml
@@ -20,21 +20,21 @@
   '_INPUT_PKGSPEC': 'testing/install_packages_remote_pkgspec_test/kubernetes_pkg_spec.tar.gz'
 
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ['run', '--spawn_strategy=standalone', ':cos_customizer', '--', '--norun']
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
 - name: 'gcr.io/cloud-builders/gsutil'
-  args: [ "-m", "cp", "${_INPUT_PKGSPEC}", "gs://${PROJECT_ID}_cloudbuild/" ]
-- name: 'bazel:cos_customizer'
+  args: [ '-m', 'cp', '${_INPUT_PKGSPEC}', 'gs://${PROJECT_ID}_cloudbuild/' ]
+- name: 'cos_customizer'
   args: ['start-image-build',
          '-build-context=testing/${_TEST}',
          '-image-name=${_INPUT_IMAGE}',
          '-image-project=${_INPUT_PROJECT}',
          '-gcs-bucket=${PROJECT_ID}_cloudbuild',
          '-gcs-workdir=customizer-$BUILD_ID']
-- name: 'bazel:cos_customizer'
+- name: 'cos_customizer'
   args: ['anthos-installer-install',
          '-pkgspec-url=gs://${PROJECT_ID}_cloudbuild/${_INPUT_PKGSPEC_FILE}']
-- name: 'bazel:cos_customizer'
+- name: 'cos_customizer'
   args: ['finish-image-build',
          '-zone=us-west1-b',
          '-project=$PROJECT_ID',
@@ -42,11 +42,11 @@
          '-image-project=$PROJECT_ID',
          '-timeout=5m']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 - name: 'gcr.io/cloud-builders/gsutil'
-  args: ["rm", "gs://${PROJECT_ID}_cloudbuild/kubernetes_pkg_spec.tar.gz" ]
+  args: ['rm', 'gs://${PROJECT_ID}_cloudbuild/kubernetes_pkg_spec.tar.gz' ]
 options:
   machineType: 'N1_HIGHCPU_32'
 timeout: '7200s'
diff --git a/testing/install_packages_test.yaml b/testing/install_packages_test.yaml
index bc52b33..20e4535 100644
--- a/testing/install_packages_test.yaml
+++ b/testing/install_packages_test.yaml
@@ -17,19 +17,19 @@
   '_INPUT_IMAGE': 'cos-85-13310-1260-8'
   '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ['run', '--spawn_strategy=standalone', ':cos_customizer', '--', '--norun']
-- name: 'bazel:cos_customizer'
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
   args: ['start-image-build',
          '-build-context=testing/${_TEST}',
          '-image-name=${_INPUT_IMAGE}',
          '-image-project=${_INPUT_PROJECT}',
          '-gcs-bucket=${PROJECT_ID}_cloudbuild',
          '-gcs-workdir=customizer-$BUILD_ID']
-- name: 'bazel:cos_customizer'
+- name: 'cos_customizer'
   args: ['anthos-installer-install',
          '-pkgspec-url=pkgspec']
-- name: 'bazel:cos_customizer'
+- name: 'cos_customizer'
   args: ['finish-image-build',
          '-zone=us-west1-b',
          '-project=$PROJECT_ID',
@@ -37,9 +37,9 @@
          '-image-project=$PROJECT_ID',
          '-timeout=5m']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_32'
 timeout: '7200s'
diff --git a/testing/machine_type_test.yaml b/testing/machine_type_test.yaml
index a230666..0ea2322 100644
--- a/testing/machine_type_test.yaml
+++ b/testing/machine_type_test.yaml
@@ -13,33 +13,33 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "machine_type_test"
-  "_INPUT_IMAGE": "cos-dev-69-10895-0-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'machine_type_test'
+  '_INPUT_IMAGE': 'cos-93-16623-461-15'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: "gcr.io/cloud-builders/bazel"
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: "bazel:cos_customizer"
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: "bazel:cos_customizer"
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: "bazel:cos_customizer"
-  args: ["finish-image-build",
-         "-machine-type=n1-standard-8",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
-- name: "gcr.io/compute-image-tools/daisy"
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-machine-type=n1-standard-8',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
+- name: 'gcr.io/compute-image-tools/daisy'
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
-  machineType: "N1_HIGHCPU_8"
-timeout: "7200s"
+  machineType: 'N1_HIGHCPU_8'
+timeout: '7200s'
diff --git a/testing/milestone_test.yaml b/testing/milestone_test.yaml
index c1e4dbf..e74e31e 100644
--- a/testing/milestone_test.yaml
+++ b/testing/milestone_test.yaml
@@ -13,29 +13,29 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "milestone_test"
-  "_INPUT_IMAGE": "69"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'milestone_test'
+  '_INPUT_IMAGE': '69'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-milestone=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-milestone=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_8'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/multi_script/preload_test.cfg b/testing/multi_script/preload_test.cfg
index 203cd15..602f265 100644
--- a/testing/multi_script/preload_test.cfg
+++ b/testing/multi_script/preload_test.cfg
@@ -60,7 +60,7 @@
       }
 
       testVersion() {
-        expected="10895.0.0"
+        expected="16623.461.15"
         actual=$(. /etc/os-release; echo "${BUILD_ID}")
         if [[ "${expected}" != "${actual}" ]]; then
           echo "expected version: ${expected}"
diff --git a/testing/multi_script_test.yaml b/testing/multi_script_test.yaml
index 10afdeb..9f30632 100644
--- a/testing/multi_script_test.yaml
+++ b/testing/multi_script_test.yaml
@@ -13,35 +13,35 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "multi_script"
-  "_INPUT_IMAGE": "cos-dev-69-10895-0-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'multi_script'
+  '_INPUT_IMAGE': 'cos-93-16623-461-15'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload_1.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload_2.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload_1.sh']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload_2.sh']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_8'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/network_subnet_test.yaml b/testing/network_subnet_test.yaml
index 4c39fc6..1304232 100644
--- a/testing/network_subnet_test.yaml
+++ b/testing/network_subnet_test.yaml
@@ -16,45 +16,43 @@
 # This test uses subnetwork `cos-customizer-test` in default VPC for the preload VM.
 
 substitutions:
-  "_TEST": "network_subnet_test"
-  "_INPUT_IMAGE": "cos-85-13310-1260-8"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'network_subnet_test'
+  '_INPUT_IMAGE': 'cos-85-13310-1260-8'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: "gcr.io/cloud-builders/bazel"
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
 - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
   args: [ 'gcloud', 'compute', 'networks', 'subnets',
           'create', 'cos-customizer-test',
           '--project', '${PROJECT_ID}', '--network', 'default', '--region', 'us-central1',
-          '--range', '10.124.0.0/20'
-  ]
-- name: "bazel:cos_customizer"
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: "bazel:cos_customizer"
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: "bazel:cos_customizer"
-  args: ["finish-image-build",
-         "-machine-type=n1-standard-8",
-         "-zone=us-central1-a",
-         "-project=$PROJECT_ID",
-         "-subnet=regions/us-central1/subnetworks/cos-customizer-test",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
-- name: "gcr.io/compute-image-tools/daisy"
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+          '--range', '10.124.0.0/20']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-machine-type=n1-standard-8',
+         '-zone=us-central1-a',
+         '-project=$PROJECT_ID',
+         '-subnet=regions/us-central1/subnetworks/cos-customizer-test',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
+- name: 'gcr.io/compute-image-tools/daisy'
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
   args: [ 'gcloud', 'compute', 'networks', 'subnets',
           'delete', 'cos-customizer-test',
-          '--project', '${PROJECT_ID}', '--region', 'us-central1',
-  ]
+          '--project', '${PROJECT_ID}', '--region', 'us-central1']
 options:
-  machineType: "N1_HIGHCPU_8"
-timeout: "7200s"
+  machineType: 'N1_HIGHCPU_8'
+timeout: '7200s'
diff --git a/testing/parallel_test.yaml b/testing/parallel_test.yaml
index 598a901..5620f4e 100644
--- a/testing/parallel_test.yaml
+++ b/testing/parallel_test.yaml
@@ -13,90 +13,90 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST_1": "smoke_test"
-  "_INPUT_IMAGE_1": "cos-dev-69-10895-0-0"
-  "_TEST_2": "gpu_test"
-  "_INPUT_IMAGE_2": "cos-89-16108-798-1"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST_1': 'smoke_test'
+  '_INPUT_IMAGE_1': 'cos-93-16623-461-15'
+  '_TEST_2': 'gpu_test'
+  '_INPUT_IMAGE_2': 'cos-89-16108-798-1'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  id: "docker-build"
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
+- name: 'gcr.io/cloud-builders/docker'
+  id: 'docker-build'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
 # TEST_1 workflow
-- name: 'bazel:cos_customizer'
-  waitFor: "docker-build"
-  id: "test-1-start-build"
-  args: ["-local-state-workdir=.${_TEST_1}",
-         "start-image-build",
-         "-build-context=testing/${_TEST_1}",
-         "-image-name=${_INPUT_IMAGE_1}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-${_TEST_1}-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  waitFor: "test-1-start-build"
-  id: "test-1-run-script"
-  args: ["-local-state-workdir=.${_TEST_1}",
-         "run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  waitFor: "test-1-run-script"
-  id: "test-1-finish-build"
-  args: ["-local-state-workdir=.${_TEST_1}",
-         "finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-t1-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+- name: 'cos_customizer'
+  waitFor: 'docker-build'
+  id: 'test-1-start-build'
+  args: ['-local-state-workdir=.${_TEST_1}',
+         'start-image-build',
+         '-build-context=testing/${_TEST_1}',
+         '-image-name=${_INPUT_IMAGE_1}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-${_TEST_1}-$BUILD_ID']
+- name: 'cos_customizer'
+  waitFor: 'test-1-start-build'
+  id: 'test-1-run-script'
+  args: ['-local-state-workdir=.${_TEST_1}',
+         'run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  waitFor: 'test-1-run-script'
+  id: 'test-1-finish-build'
+  args: ['-local-state-workdir=.${_TEST_1}',
+         'finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-t1-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  waitFor: "test-1-finish-build"
-  id: "test-1-test-build"
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-t1-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST_1}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  waitFor: 'test-1-finish-build'
+  id: 'test-1-test-build'
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-t1-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST_1}/preload_test.cfg', 'testing/util/run_test.wf.json']
 # TEST_2 workflow
 - name: 'busybox'
-  args: ["sed", "-i", "-e", "s|%s|'450.216.04'|",
-         "testing/${_TEST_2}/preload_test.cfg"]
-- name: 'bazel:cos_customizer'
-  waitFor: "docker-build"
-  id: "test-2-start-build"
-  args: ["-local-state-workdir=.${_TEST_2}",
-         "start-image-build",
-         "-build-context=testing/${_TEST_2}",
-         "-image-name=${_INPUT_IMAGE_2}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-${_TEST_2}-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  waitFor: "test-2-start-build"
-  id: "test-2-install-gpu"
-  args: ["-local-state-workdir=.${_TEST_2}",
-         "install-gpu",
-         "-version=450.216.04",
-         "-gpu-type=nvidia-tesla-t4"]
-- name: 'bazel:cos_customizer'
-  waitFor: "test-2-install-gpu"
-  id: "test-2-run-script"
-  args: ["-local-state-workdir=.${_TEST_2}",
-         "run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  waitFor: "test-2-run-script"
-  id: "test-2-finish-build"
-  args: ["-local-state-workdir=.${_TEST_2}",
-         "finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-t2-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+  args: ['sed', '-i', '-e', 's|%s|"450.216.04"|',
+         'testing/${_TEST_2}/preload_test.cfg']
+- name: 'cos_customizer'
+  waitFor: 'docker-build'
+  id: 'test-2-start-build'
+  args: ['-local-state-workdir=.${_TEST_2}',
+         'start-image-build',
+         '-build-context=testing/${_TEST_2}',
+         '-image-name=${_INPUT_IMAGE_2}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-${_TEST_2}-$BUILD_ID']
+- name: 'cos_customizer'
+  waitFor: 'test-2-start-build'
+  id: 'test-2-install-gpu'
+  args: ['-local-state-workdir=.${_TEST_2}',
+         'install-gpu',
+         '-version=450.216.04',
+         '-gpu-type=nvidia-tesla-t4']
+- name: 'cos_customizer'
+  waitFor: 'test-2-install-gpu'
+  id: 'test-2-run-script'
+  args: ['-local-state-workdir=.${_TEST_2}',
+         'run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  waitFor: 'test-2-run-script'
+  id: 'test-2-finish-build'
+  args: ['-local-state-workdir=.${_TEST_2}',
+         'finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-t2-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  waitFor: "test-2-finish-build"
-  id: "test-2-test-build"
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-t2-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST_2}/preload_test.cfg", "-var:vm_workflow",
-         "./gpu_vm.wf.json", "testing/util/run_test.wf.json"]
+  waitFor: 'test-2-finish-build'
+  id: 'test-2-test-build'
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-t2-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST_2}/preload_test.cfg', '-var:vm_workflow',
+         './gpu_vm.wf.json', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_32'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/seal_oem_test/seal_oem_test.yaml b/testing/seal_oem_test/seal_oem_test.yaml
index 373f90c..7989337 100644
--- a/testing/seal_oem_test/seal_oem_test.yaml
+++ b/testing/seal_oem_test/seal_oem_test.yaml
@@ -13,42 +13,42 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "seal_oem_test"
-  "_INPUT_IMAGE": "cos-81-12871-148-0"
-  "_INPUT_PROJECT": "cos-cloud"
-  "_OEM_SIZE": ""
-  "_DISK_SIZE": ""
-  "_OEM_SIZE_TH": ""
+  '_TEST': 'seal_oem_test'
+  '_INPUT_IMAGE': 'cos-81-12871-148-0'
+  '_INPUT_PROJECT': 'cos-cloud'
+  '_OEM_SIZE': ''
+  '_DISK_SIZE': ''
+  '_OEM_SIZE_TH': ''
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
 - name: 'busybox'
-  args: ["sed", "-i", "-e", "s|%s|'${_OEM_SIZE_TH}'|",
-         "testing/${_TEST}/preload_test.cfg"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["seal-oem"]        
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID",
-         "-disk-size-gb=${_DISK_SIZE}",
-         "-oem-size=${_OEM_SIZE}"]
+  args: ['sed', '-i', '-e', 's|%s|"${_OEM_SIZE_TH}"|',
+         'testing/${_TEST}/preload_test.cfg']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['seal-oem']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID',
+         '-disk-size-gb=${_DISK_SIZE}',
+         '-oem-size=${_OEM_SIZE}']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-default_timeout=15m", "-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-default_timeout=15m', '-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_32'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/seal_oem_test_no_oem_size.yaml b/testing/seal_oem_test_no_oem_size.yaml
index 1974487..e209a39 100644
--- a/testing/seal_oem_test_no_oem_size.yaml
+++ b/testing/seal_oem_test_no_oem_size.yaml
@@ -13,34 +13,34 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "seal_oem_test"
-  "_INPUT_IMAGE": "cos-81-12871-148-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'seal_oem_test'
+  '_INPUT_IMAGE': 'cos-81-12871-148-0'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["seal-oem"]        
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['seal-oem']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-default_timeout=15m", "-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-default_timeout=15m', '-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_32'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/seal_oem_test_no_size.yaml b/testing/seal_oem_test_no_size.yaml
index 051180b..0f73214 100644
--- a/testing/seal_oem_test_no_size.yaml
+++ b/testing/seal_oem_test_no_size.yaml
@@ -13,35 +13,35 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "seal_oem_test"
-  "_INPUT_IMAGE": "cos-81-12871-148-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'seal_oem_test'
+  '_INPUT_IMAGE': 'cos-81-12871-148-0'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["seal-oem"]        
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID",
-         "-disk-size-gb=11"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['seal-oem']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID',
+         '-disk-size-gb=11']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-default_timeout=15m", "-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-default_timeout=15m', '-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_32'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/seal_oem_test_timeout.yaml b/testing/seal_oem_test_timeout.yaml
index 2b6dcca..4235840 100644
--- a/testing/seal_oem_test_timeout.yaml
+++ b/testing/seal_oem_test_timeout.yaml
@@ -13,46 +13,46 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "seal_oem_test"
-  "_INPUT_IMAGE": "cos-81-12871-148-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'seal_oem_test'
+  '_INPUT_IMAGE': 'cos-81-12871-148-0'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["seal-oem"]   
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=modify_oem.sh"]       
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID",
-         "-disk-size-gb=11"]
-- name: 'gcr.io/cloud-builders/docker'    
-  args: [ 'build', '-t', 'seal-oem-test-timeout-image', 'testing/${_TEST}' ]    
-- name: 'seal-oem-test-timeout-image'     
-  entrypoint: '/bin/bash'    
-  args:    
-  - '-c'    
-  - |    
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['seal-oem']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=modify_oem.sh']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID',
+         '-disk-size-gb=11']
+- name: 'gcr.io/cloud-builders/docker'
+  args: [ 'build', '-t', 'seal-oem-test-timeout-image', 'testing/${_TEST}' ]
+- name: 'seal-oem-test-timeout-image'
+  entrypoint: '/bin/bash'
+  args:
+  - '-c'
+  - |
     /daisy -default_timeout=5m -project=$PROJECT_ID -zone=us-west1-b \
     -var:image_name preload-test-$BUILD_ID -var:image_project $PROJECT_ID \
-    -var:test_cfg /preload_test.cfg /run_test.wf.json | tee /build.log 
+    -var:test_cfg /preload_test.cfg /run_test.wf.json | tee /build.log
     if ( grep "did not complete within the specified timeout" /build.log > /dev/null ); \
     then exit 0; else echo "error: timemout expected"; exit 1; fi
 options:
   machineType: 'N1_HIGHCPU_32'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/smoke_test.yaml b/testing/smoke_test.yaml
index 59950c6..d412432 100644
--- a/testing/smoke_test.yaml
+++ b/testing/smoke_test.yaml
@@ -13,32 +13,32 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "smoke_test"
-  "_INPUT_IMAGE": "cos-dev-69-10895-0-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'smoke_test'
+  '_INPUT_IMAGE': 'cos-93-16623-461-15'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_8'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/smoke_test/preload_test.cfg b/testing/smoke_test/preload_test.cfg
index c943032..207717f 100644
--- a/testing/smoke_test/preload_test.cfg
+++ b/testing/smoke_test/preload_test.cfg
@@ -60,7 +60,7 @@
       }
 
       testVersion() {
-        expected="10895.0.0"
+        expected="16623.461.15"
         actual=$(. /etc/os-release; echo "${BUILD_ID}")
         if [[ "${expected}" != "${actual}" ]]; then
           echo "expected version: ${expected}"
diff --git a/testing/timeout_test/timeout_test.yaml b/testing/timeout_test/timeout_test.yaml
index 0c5bc3f..94be555 100644
--- a/testing/timeout_test/timeout_test.yaml
+++ b/testing/timeout_test/timeout_test.yaml
@@ -14,22 +14,22 @@
 
 substitutions:
   '_TEST': 'timeout_test'
-  '_INPUT_IMAGE': 'cos-dev-69-10895-0-0'
+  '_INPUT_IMAGE': 'cos-93-16623-461-15'
   '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ['run', '--spawn_strategy=standalone', ':cos_customizer', '--', '--norun']
-- name: 'bazel:cos_customizer'
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
   args: ['start-image-build',
          '-build-context=testing/${_TEST}',
          '-image-name=${_INPUT_IMAGE}',
          '-image-project=${_INPUT_PROJECT}',
          '-gcs-bucket=${PROJECT_ID}_cloudbuild',
          '-gcs-workdir=customizer-$BUILD_ID']
-- name: 'bazel:cos_customizer'
+- name: 'cos_customizer'
   args: ['run-script',
          '-script=preload.sh']
-- name: 'bazel:cos_customizer'
+- name: 'cos_customizer'
   args: ['finish-image-build',
          '-zone=us-west1-b',
          '-project=$PROJECT_ID',
diff --git a/testing/toolbox_test.yaml b/testing/toolbox_test.yaml
index 0b89950..f489204 100644
--- a/testing/toolbox_test.yaml
+++ b/testing/toolbox_test.yaml
@@ -13,32 +13,32 @@
 # limitations under the License.
 
 substitutions:
-  "_TEST": "toolbox_test"
-  "_INPUT_IMAGE": "cos-dev-69-10895-0-0"
-  "_INPUT_PROJECT": "cos-cloud"
+  '_TEST': 'toolbox_test'
+  '_INPUT_IMAGE': 'cos-93-16623-461-15'
+  '_INPUT_PROJECT': 'cos-cloud'
 steps:
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ["run", "--spawn_strategy=standalone", ":cos_customizer", "--", "--norun"]
-- name: 'bazel:cos_customizer'
-  args: ["start-image-build",
-         "-build-context=testing/${_TEST}",
-         "-image-name=${_INPUT_IMAGE}",
-         "-image-project=${_INPUT_PROJECT}",
-         "-gcs-bucket=${PROJECT_ID}_cloudbuild",
-         "-gcs-workdir=customizer-$BUILD_ID"]
-- name: 'bazel:cos_customizer'
-  args: ["run-script",
-         "-script=preload.sh"]
-- name: 'bazel:cos_customizer'
-  args: ["finish-image-build",
-         "-zone=us-west1-b",
-         "-project=$PROJECT_ID",
-         "-image-name=preload-test-$BUILD_ID",
-         "-image-project=$PROJECT_ID"]
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
+- name: 'cos_customizer'
+  args: ['start-image-build',
+         '-build-context=testing/${_TEST}',
+         '-image-name=${_INPUT_IMAGE}',
+         '-image-project=${_INPUT_PROJECT}',
+         '-gcs-bucket=${PROJECT_ID}_cloudbuild',
+         '-gcs-workdir=customizer-$BUILD_ID']
+- name: 'cos_customizer'
+  args: ['run-script',
+         '-script=preload.sh']
+- name: 'cos_customizer'
+  args: ['finish-image-build',
+         '-zone=us-west1-b',
+         '-project=$PROJECT_ID',
+         '-image-name=preload-test-$BUILD_ID',
+         '-image-project=$PROJECT_ID']
 - name: 'gcr.io/compute-image-tools/daisy'
-  args: ["-project=$PROJECT_ID", "-zone=us-west1-b", "-var:image_name",
-         "preload-test-$BUILD_ID", "-var:image_project", "$PROJECT_ID",
-         "-var:test_cfg", "../${_TEST}/preload_test.cfg", "testing/util/run_test.wf.json"]
+  args: ['-project=$PROJECT_ID', '-zone=us-west1-b', '-var:image_name',
+         'preload-test-$BUILD_ID', '-var:image_project', '$PROJECT_ID',
+         '-var:test_cfg', '../${_TEST}/preload_test.cfg', 'testing/util/run_test.wf.json']
 options:
   machineType: 'N1_HIGHCPU_8'
-timeout: "7200s"
+timeout: '7200s'
diff --git a/testing/toolbox_test/preload.sh b/testing/toolbox_test/preload.sh
index fee0210..0eece3c 100644
--- a/testing/toolbox_test/preload.sh
+++ b/testing/toolbox_test/preload.sh
@@ -14,4 +14,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-toolbox
+toolbox echo
diff --git a/testing/toolbox_test/preload_test.cfg b/testing/toolbox_test/preload_test.cfg
index da3f4f6..32094d3 100644
--- a/testing/toolbox_test/preload_test.cfg
+++ b/testing/toolbox_test/preload_test.cfg
@@ -30,8 +30,8 @@
       }
 
       testToolbox() {
-        expected="gcr.io/google-containers/toolbox"
-        actual=$(docker images --format {{.Repository}})
+        expected="gcr.io/cos-cloud/toolbox:v20230615"
+        actual=$(ctr images ls -q)
         if [[ "${expected}" != "${actual}" ]]; then
           echo "expected: ${expected}"
           echo "actual: ${actual}"
diff --git a/testing/ubuntu_ova_test.yaml b/testing/ubuntu_ova_test.yaml
index 06d5230..bf7a0d7 100644
--- a/testing/ubuntu_ova_test.yaml
+++ b/testing/ubuntu_ova_test.yaml
@@ -17,8 +17,8 @@
   '_INPUT_IMAGE': 'https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.ova'
 steps:
 # Build cos-customizer and tools container
-- name: 'gcr.io/cloud-builders/bazel'
-  args: ['run', '--spawn_strategy=standalone', ':cos_customizer', '--', '--norun']
+- name: 'gcr.io/cloud-builders/docker'
+  args: ['build', '-f', 'src/cmd/cos_customizer/Dockerfile', '-t', 'cos_customizer', '.']
 - name: 'gcr.io/cloud-builders/docker'
   entrypoint: 'bash'
   args:
@@ -56,17 +56,17 @@
   args: ['rm', 'gs://${PROJECT_ID}_cloudbuild/build-ova-${BUILD_ID}/ubuntu_gce.tar.gz']
 
 # Run cos-customizer
-- name: 'bazel:cos_customizer'
+- name: 'cos_customizer'
   args: ['start-image-build',
          '-build-context=testing/${_TEST}',
          '-image-name=input-${BUILD_ID}',
          '-image-project=${PROJECT_ID}',
          '-gcs-bucket=${PROJECT_ID}_cloudbuild',
          '-gcs-workdir=customizer-$BUILD_ID']
-- name: 'bazel:cos_customizer'
+- name: 'cos_customizer'
   args: ['run-script',
          '-script=preload.sh']
-- name: 'bazel:cos_customizer'
+- name: 'cos_customizer'
   args: ['finish-image-build',
          '-zone=us-west1-b',
          '-project=${PROJECT_ID}',