forked from juju/juju
-
Notifications
You must be signed in to change notification settings - Fork 0
/
make_functions.sh
executable file
·183 lines (160 loc) · 6.92 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!/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:-}
JUJU_DB_VERSION=${JUJU_DB_VERSION:-}
# Docker variables
OCI_BUILDER=${OCI_BUILDER:-docker}
DOCKER_USERNAME=${DOCKER_USERNAME:-docker.io/jujusolutions}
DOCKER_BUILDX_CONTEXT=${DOCKER_BUILDX_CONTEXT:-juju-make}
DOCKER_STAGING_DIR="${BUILD_DIR}/docker-staging"
DOCKER_BIN=${DOCKER_BIN:-$(which ${OCI_BUILDER} || 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_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)
}
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 lifting 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"}
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}/"
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" manifest rm "$(operator_image_path)" || true
"$DOCKER_BIN" manifest create "$(operator_image_path)"
"$DOCKER_BIN" build \
--jobs "4" \
-f "${WORKDIR}/Dockerfile" \
--manifest "$(operator_image_path)" \
--platform="$build_multi_osarch" \
"${BUILD_DIR}"
if [[ "$push_image" = true ]]; then
"$DOCKER_BIN" manifest push -f v2s2 "$(operator_image_path)" "docker://$(operator_image_path)"
fi
else
echo "unknown OCI_BUILDER=${OCI_BUILDER} expected docker or podman"
exit 1
fi
}
seed_repository() {
set -x
"$DOCKER_BIN" pull "docker.io/jujusolutions/juju-db:${JUJU_DB_VERSION}"
"$DOCKER_BIN" tag "docker.io/jujusolutions/juju-db:${JUJU_DB_VERSION}" "${DOCKER_USERNAME}/juju-db:${JUJU_DB_VERSION}"
"$DOCKER_BIN" push "${DOCKER_USERNAME}/juju-db:${JUJU_DB_VERSION}"
# copy all the lts that are available
for (( i = 18; ; i += 2 )); do
if "$DOCKER_BIN" pull "docker.io/jujusolutions/charm-base:ubuntu-$i.04" ; then
"$DOCKER_BIN" tag "docker.io/jujusolutions/charm-base:ubuntu-$i.04" "${DOCKER_USERNAME}/charm-base:ubuntu-$i.04"
"$DOCKER_BIN" push "${DOCKER_USERNAME}/charm-base:ubuntu-$i.04"
else
break
fi
done
}
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
}