diff --git a/Makefile b/Makefile index baf81073530..3dcaa884a4a 100644 --- a/Makefile +++ b/Makefile @@ -453,6 +453,7 @@ check-deps: # CAAS related targets +export OCI_BUILDER ?= docker DOCKER_USERNAME ?= jujusolutions DOCKER_BUILDX_CONTEXT ?= juju-make DOCKER_STAGING_DIR ?= ${BUILD_DIR}/docker-staging @@ -487,7 +488,9 @@ image-check-build-skip: docker-builder: ## docker-builder: Makes sure that there is a buildx context for building the ## oci images +ifeq ($(OCI_BUILDER),docker) -@docker buildx create --name ${DOCKER_BUILDX_CONTEXT} +endif .PHONY: image-check operator-image: image-check docker-builder @@ -526,7 +529,7 @@ host-install: .PHONY: minikube-operator-update minikube-operator-update: host-install operator-image ## minikube-operator-update: Push up the newly built operator image for use with minikube - docker save "$(shell ${OPERATOR_IMAGE_PATH})" | minikube image load --overwrite=true - + $(OCI_BUILDER) save "$(shell ${OPERATOR_IMAGE_PATH})" | minikube image load --overwrite=true - .PHONY: microk8s-operator-update microk8s-operator-update: host-install operator-image @@ -536,7 +539,7 @@ microk8s-operator-update: host-install operator-image .PHONY: k3s-operator-update k3s-operator-update: host-install operator-image ## k3s-operator-update: Push up the newly built operator image for use with k3s - docker save "$(shell ${OPERATOR_IMAGE_PATH})" | sudo k3s ctr images import - + $(OCI_BUILDER) save "$(shell ${OPERATOR_IMAGE_PATH})" | sudo k3s ctr images import - .PHONY: check-k8s-model check-k8s-model: @@ -548,7 +551,7 @@ check-k8s-model: local-operator-update: check-k8s-model operator-image ## local-operator-update: Build then update local operator image $(eval kubeworkers != juju status -m ${JUJU_K8S_MODEL} kubernetes-worker --format json | jq -c '.machines | keys' | tr -c '[:digit:]' ' ' 2>&1) - docker save "$(shell ${OPERATOR_IMAGE_PATH})" | gzip > ${DOCKER_STAGING_DIR}/jujud-operator-image.tar.gz + $(OCI_BUILDER) save "$(shell ${OPERATOR_IMAGE_PATH})" | gzip > ${DOCKER_STAGING_DIR}/jujud-operator-image.tar.gz $(foreach wm,$(kubeworkers), juju scp -m ${JUJU_K8S_MODEL} ${DOCKER_STAGING_DIR}/jujud-operator-image.tar.gz $(wm):/tmp/jujud-operator-image.tar.gz ; ) $(foreach wm,$(kubeworkers), juju ssh -m ${JUJU_K8S_MODEL} $(wm) -- "zcat /tmp/jujud-operator-image.tar.gz | docker load" ; ) diff --git a/caas/Dockerfile b/caas/Dockerfile index b8dee2e2a09..b64a2383d87 100644 --- a/caas/Dockerfile +++ b/caas/Dockerfile @@ -1,7 +1,6 @@ FROM public.ecr.aws/ubuntu/ubuntu:20.04 ARG TARGETOS ARG TARGETARCH -ARG BUILDOS # Add the syslog user for audit logging. RUN useradd --system -M syslog diff --git a/make_functions.sh b/make_functions.sh index a69c163a4a8..29accabc458 100755 --- a/make_functions.sh +++ b/make_functions.sh @@ -11,10 +11,11 @@ JUJUD_BIN_DIR=${JUJUD_BIN_DIR:-${BUILD_DIR}/bin} JUJU_BUILD_NUMBER=${JUJU_BUILD_NUMBER:-} # Docker variables +OCI_BUILDER=${OCI_BUILDER:-docker} DOCKER_USERNAME=${DOCKER_USERNAME:-jujusolutions} DOCKER_BUILDX_CONTEXT=${DOCKER_BUILDX_CONTEXT:-juju-make} DOCKER_STAGING_DIR="${BUILD_DIR}/docker-staging" -DOCKER_BIN=${DOCKER_BIN:-$(which docker || true)} +DOCKER_BIN=${DOCKER_BIN:-$(which ${OCI_BUILDER} || true)} readonly docker_staging_dir="docker-staging" @@ -22,10 +23,10 @@ readonly docker_staging_dir="docker-staging" # Docker staging directory under the build path. The staging directory's path # is returned as the output of this function. _make_docker_staging_dir() { - dir="${BUILD_DIR}/${docker_staging_dir}" - rm -rf "$dir" - mkdir -p "$dir" - echo "$dir" + dir="${BUILD_DIR}/${docker_staging_dir}" + rm -rf "$dir" + mkdir -p "$dir" + echo "$dir" } _juju_version() { @@ -39,23 +40,23 @@ _image_version() { } microk8s_operator_update() { - echo "Uploading image $(operator_image_path) to microk8s" - # For macos we have to push the image into the microk8s multipass vm because - # we can't use the ctr to stream off the local machine. - if [[ $(uname) = "Darwin" ]]; then - tmp_docker_image="/tmp/juju-operator-image-${RANDOM}.image" - docker save $(operator_image_path) | multipass transfer - microk8s-vm:${tmp_docker_image} - microk8s ctr --namespace k8s.io image import ${tmp_docker_image} - multipass exec microk8s-vm rm "${tmp_docker_image}" - return - fi - - # Linux we can stream the file like normal. - docker save "$(operator_image_path)" | microk8s.ctr --namespace k8s.io image import - + echo "Uploading image $(operator_image_path) to microk8s" + # For macos we have to push the image into the microk8s multipass vm because + # we can't use the ctr to stream off the local machine. + if [[ $(uname) = "Darwin" ]]; then + tmp_docker_image="/tmp/juju-operator-image-${RANDOM}.image" + "${DOCKER_BIN}" save $(operator_image_path) | multipass transfer - microk8s-vm:${tmp_docker_image} + microk8s ctr --namespace k8s.io image import ${tmp_docker_image} + multipass exec microk8s-vm rm "${tmp_docker_image}" + return + fi + + # Linux we can stream the file like normal. + "${DOCKER_BIN}" save "$(operator_image_path)" | microk8s.ctr --namespace k8s.io image import - } juju_version() { - (cd "${PROJECT_DIR}" && go run version/helper/main.go) + (cd "${PROJECT_DIR}" && go run version/helper/main.go) } operator_image_release_path() { @@ -85,52 +86,67 @@ operator_image_path() { build_push_operator_image() { build_multi_osarch=${1-""} if [[ -z "$build_multi_osarch" ]]; then - build_multi_osarch="$(go env GOOS)/$(go env GOARCH)" + build_multi_osarch="$(go env GOOS)/$(go env GOARCH)" fi # We need to find any ppc64el references and move the build artefacts over # to ppc64le so that it works with Docker. for platform in $build_multi_osarch; do - if [[ "$platform" = *"ppc64el"* ]]; then - echo "detected operator image build for ppc64el \"${platform}\"" - new_platform=$(echo "$platform" | sed 's/ppc64el/ppc64le/g') - echo "changing platform \"${platform}\" to platform \"${new_platform}\"" - - platform_dir="${BUILD_DIR}/$(echo "$platform" | sed 's/\//_/g')" - new_platform_dir="${BUILD_DIR}/$(echo "$new_platform" | sed 's/\//_/g')" - if ! [[ -d "$platform_dir" ]]; then - echo "platform build directory \"${platform_dir}\" does not exist" - exit 1 + if [[ "$platform" = *"ppc64el"* ]]; then + echo "detected operator image build for ppc64el \"${platform}\"" + new_platform=$(echo "$platform" | sed 's/ppc64el/ppc64le/g') + echo "changing platform \"${platform}\" to platform \"${new_platform}\"" + + platform_dir="${BUILD_DIR}/$(echo "$platform" | sed 's/\//_/g')" + new_platform_dir="${BUILD_DIR}/$(echo "$new_platform" | sed 's/\//_/g')" + if ! [[ -d "$platform_dir" ]]; then + echo "platform build directory \"${platform_dir}\" does not exist" + exit 1 + fi + + echo "copying platform build directory \"${platform_dir}\" to \"${new_platform_dir}\"" + cp -r "$platform_dir" "$new_platform_dir" fi - - echo "copying platform build directory \"${platform_dir}\" to \"${new_platform_dir}\"" - cp -r "$platform_dir" "$new_platform_dir" - fi done build_multi_osarch=$(echo "$build_multi_osarch" | sed 's/ppc64el/ppc64le/g') push_image=${2:-"false"} - output="-o type=oci,dest=${BUILD_DIR}/oci.tar.gz" - if [[ "$push_image" = true ]]; then - output="-o type=image,push=true" - elif [[ $(echo "$build_multi_osarch" | wc -w) -eq 1 ]]; then - output="-o type=docker" - fi build_multi_osarch=$(echo $build_multi_osarch | sed 's/ /,/g') WORKDIR=$(_make_docker_staging_dir) cp "${PROJECT_DIR}/caas/Dockerfile" "${WORKDIR}/" cp "${PROJECT_DIR}/caas/requirements.txt" "${WORKDIR}/" - BUILDX_NO_DEFAULT_ATTESTATIONS=true DOCKER_BUILDKIT=1 "$DOCKER_BIN" buildx build \ - --builder "$DOCKER_BUILDX_CONTEXT" \ - -f "${WORKDIR}/Dockerfile" \ - -t "$(operator_image_path)" \ - --platform="$build_multi_osarch" \ - --provenance=false \ - ${output} \ - "${BUILD_DIR}" + if [[ "${OCI_BUILDER}" = "docker" ]]; then + output="-o type=oci,dest=${BUILD_DIR}/oci.tar.gz" + if [[ "$push_image" = true ]]; then + output="-o type=image,push=true" + elif [[ $(echo "$build_multi_osarch" | wc -w) -eq 1 ]]; then + output="-o type=docker" + fi + BUILDX_NO_DEFAULT_ATTESTATIONS=true DOCKER_BUILDKIT=1 "$DOCKER_BIN" buildx build \ + --builder "$DOCKER_BUILDX_CONTEXT" \ + -f "${WORKDIR}/Dockerfile" \ + -t "$(operator_image_path)" \ + --platform="$build_multi_osarch" \ + --provenance=false \ + ${output} \ + "${BUILD_DIR}" + elif [[ "${OCI_BUILDER}" = "podman" ]]; then + "$DOCKER_BIN" build \ + --jobs "4" \ + -f "${WORKDIR}/Dockerfile" \ + -t "$(operator_image_path)" \ + --platform="$build_multi_osarch" \ + "${BUILD_DIR}" + if [[ "$push_image" = true ]]; then + "$DOCKER_BIN" push "$(operator_image_path)" + fi + else + echo "unknown OCI_BUILDER=${OCI_BUILDER} expected docker or podman" + exit 1 + fi } wait_for_dpkg() {