-
Notifications
You must be signed in to change notification settings - Fork 0
/
make_functions.sh
executable file
·146 lines (125 loc) · 5.23 KB
/
make_functions.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/usr/bin/env bash
set -euf
# Path variables
BASE_DIR=$(realpath $(dirname "$0"))
PROJECT_DIR=${PROJECT_DIR:-${BASE_DIR}}
BUILD_DIR=${BUILD_DIR:-${PROJECT_DIR}/_build}
JUJUD_BIN_DIR=${JUJUD_BIN_DIR:-${BUILD_DIR}/bin}
# Versioning variables
JUJU_BUILD_NUMBER=${JUJU_BUILD_NUMBER:-}
# Docker variables
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)}
readonly docker_staging_dir="docker-staging"
# _make_docker_staging_dir is responsible for ensuring that there exists a
# 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"
}
_juju_version() {
echo "$1" | grep -E -o "^[[:digit:]]{1,9}\.[[:digit:]]{1,9}(\.|-[[:alpha:]]+)[[:digit:]]{1,9}(\.[[:digit:]]{1,9})?"
}
_strip_build_version() {
echo "$1" | grep -E -o "^[[:digit:]]{1,9}\.[[:digit:]]{1,9}(\.|-[[:alpha:]]+)[[:digit:]]{1,9}"
}
_image_version() {
_strip_build_version "$(_juju_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 -
}
juju_version() {
(cd "${PROJECT_DIR}" && go run version/helper/main.go)
}
operator_image_release_path() {
juju_version=$(juju_version)
echo "${DOCKER_USERNAME}/jujud-operator:$(_image_version $juju_version)"
}
operator_image_path() {
juju_version=$(juju_version)
if [[ -z "${JUJU_BUILD_NUMBER}" ]] || [[ ${JUJU_BUILD_NUMBER} -eq 0 ]]; then
operator_image_release_path
else
echo "${DOCKER_USERNAME}/jujud-operator:$(_image_version "$juju_version").${JUJU_BUILD_NUMBER}"
fi
}
# build_push_operator_image is responsible for doing the heavy lifiting when it
# comes time to build the Juju oci operator image. This function can also build
# the operator image for multiple architectures at once. Takes 2 arguments that
# describe one or more platforms to build for and whether to push the image.
# - $1 space seperated list of os/arch to build the image for. Follow the GO
# idiom for naming. Example "linux/amd64 linux/arm64". The only supported OS
# is linux at the moment. If no argument is provided defaults to GOOS & GOARCH
# - $2 true or false value on if the resultant image(s) should be pushed to the
# registry
build_push_operator_image() {
build_multi_osarch=${1-""}
if [[ -z "$build_multi_osarch" ]]; then
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
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}/"
DOCKER_BUILDKIT=1 "$DOCKER_BIN" buildx build \
--builder "$DOCKER_BUILDX_CONTEXT" \
-f "${WORKDIR}/Dockerfile" \
-t "$(operator_image_path)" \
--platform="$build_multi_osarch" \
${output} \
"${BUILD_DIR}"
}
wait_for_dpkg() {
# Just in case, wait for cloud-init.
cloud-init status --wait 2> /dev/null || true
while sudo lsof /var/lib/dpkg/lock-frontend 2> /dev/null; do
echo "Waiting for dpkg lock..."
sleep 10
done
while sudo lsof /var/lib/apt/lists/lock 2> /dev/null; do
echo "Waiting for apt lock..."
sleep 10
done
}