blob: 98f58ed0833c67a9533950975d11e8a5373a8d93 [file] [log] [blame]
#!/bin/bash
# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
readonly current_dir="$(dirname "$(realpath -e "${BASH_SOURCE[0]}")")"
readonly chroot_default="${current_dir}/../../../../../chroot"
validate () {
# @FUNCTION: validate
# @USAGE: validates inputs to build_*
# @DESCRIPTION:
#
# Args:
# $1: Server name (as built/installed into /usr/bin on the chroot)
# $2: Dockerfile path for the build
# $3: (optional) chroot path
# $4: (optional) tags
# $5: (optional) output file for metadata
# $6: (optional) host
# $7: (optional) project
# $8+: (optional) labels
server_name=""
docker_file=""
chroot_arg=""
tags=""
output_path=""
registry_name=""
cloud_project=""
while [[ $# -gt 0 ]]; do
case $1 in
--service| -s)
server_name="$2"
shift 2
;;
--docker_file| -d)
docker_file="$2"
shift 2
;;
--chroot| -c)
chroot_arg="$2"
shift 2
;;
--tags| -t)
tags="$2"
shift 2
;;
--output| -o)
output_path="$2"
shift 2
;;
--host| -h)
registry_name="$2"
shift 2
;;
--project| -p)
cloud_project="$2"
shift 2
;;
*)
break
;;
esac
done
if [[ "${server_name}" == "" || "${docker_file}" == "" ]]; then
die "${FUNCNAME[0]}: Server name and Dockerfile path required"
fi
# Aggregate rest of CLI arguments as labels into an array
labels=( "$@" )
# shellcheck source=/dev/null
if [[ -e ${CHROOT_VERSION_FILE} ]]; then
echo "Script must run outside the chroot since this depends on docker"
exit 1
fi
chroot="${chroot_arg}"
if [ -z "${chroot}" ]; then
echo "No chroot specified, so defaulting to: ${chroot_default}"
chroot="${chroot_default}"
fi
if [ ! -d "${chroot}" ]; then
echo "chroot path does not exist: ${chroot}"
exit 1
fi
readonly default_tag="local-${USER}"
if [[ "${tags}" == "" ]]; then
echo "No tags specified, defaulting to: ${default_tag}"
tags="${default_tag}"
fi
readonly default_registry_name="us-docker.pkg.dev"
if [[ "${registry_name}" == "" ]]; then
echo "No host specified, defaulting to: ${default_registry_name}"
registry_name="${default_registry_name}"
fi
readonly default_cloud_project="cros-registry/test-services"
if [[ "${cloud_project}" == "" ]]; then
echo "No project specified, defaulting to: ${default_cloud_project}"
cloud_project="${default_cloud_project}"
fi
readonly image_name="${server_name}"
readonly image_path="${registry_name}/${cloud_project}/${image_name}"
readonly server_name docker_file chroot_arg tags
}
build_image() {
# @FUNCTION: build_image
# @USAGE: Docker builds + uploads to the registry.
# @DESCRIPTION:
# Construct and execute build command
args=(-f "${docker_file}")
# Map tags into -t options
ntag=0
IFS=,
for tag in ${tags}; do
ntag="$((ntag+1))"
args+=(-t "${image_path}:${tag}")
done
# Map labels into --label options
for label in "${labels[@]}"; do
args+=(--label "${label:Q}")
done
args+=("${build_context}")
echo sudo docker build "${args[@]}"
sudo docker build "${args[@]}"
# Push image to register
sudo docker login -u oauth2accesstoken -p "$(gcloud auth print-access-token)" "https://${registry_name}"
sudo docker push --all-tags "${image_path}"
# write output if requested
if [[ -n "${output_path}" ]]; then
local digest
digest=$(docker inspect --format='{{index .RepoDigests 0}}' "${image_path}:${tag[0]}" | cut -d@ -f2)
cat <<EOF > "${output_path}"
{
"repository" : {
"hostname": "${registry_name}",
"project" : "${cloud_project}"
},
"name" : "${image_name}",
"digest" : "${digest}",
"tags" : [
EOF
ii=0
local tag_block=""
IFS=,
for tag in ${tags}; do
tag_block+=" \"${tag}\""
ii="$((ii+1))"
if [[ $ii -lt ${ntag} ]]; then
tag_block+=",\n"
fi
done
echo -e "${tag_block}" >> "${output_path}"
cat <<EOF >> "${output_path}"
]
}
EOF
fi
}
build_container_image(){
# @FUNCTION: build_container_image
# @USAGE: [server_name]
# @DESCRIPTION:
#
# Args:
# $1: Server name (as built/installed into /usr/bin on the chroot)
# $2: Dockerfile path for the build
# $3: (optional) chroot path
# $4: (optional) tags
# $5: (optional) output file for metadata
# $6: (optional) host
# $7: (optional) project
# $8+: (optional) labels
validate "$@"
readonly build_context=$(dirname "${docker_file}")
build_image
trap 'rm -rf "${build_context}"' EXIT
}
build_server_image() {
# @FUNCTION: build_server_image
# @USAGE: [server_name]
# @DESCRIPTION:
#
# Args:
# $1: Server name (as built/installed into /usr/bin on the chroot)
# $2: Dockerfile path for the build
# $3: (optional) chroot path
# $4: (optional) tags
# $5: (optional) output file for metadata
# $6: (optional) host
# $7: (optional) project
# $8+: (optional) labels
validate "$@"
readonly tmpdir=$(mktemp -d)
trap 'rm -rf "${tmpdir}"' EXIT
cp "${chroot}/usr/bin/${server_name}" "${tmpdir}"
readonly build_context="${tmpdir}"
build_image
}