-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathshared.bash
More file actions
executable file
·305 lines (271 loc) · 14.8 KB
/
shared.bash
File metadata and controls
executable file
·305 lines (271 loc) · 14.8 KB
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
[[ $DEBUG == true ]] && set -x
[[ $DEBUG == true ]] && ANKA_DEBUG="--debug"
capitalize() {
printf '%s' "$1" | head -c 1 | tr [:lower:] [:upper:]
printf '%s' "$1" | tail -c '+2'
}
export ANKA_LOG_LEVEL="debug"
STORAGE_LOCATION=${STORAGE_LOCATION:-"/tmp"}
URL_PROTOCOL=${URL_PROTOCOL:-"http://"}
ARCH_EXTENSION=""
ARCH="$(arch)"
if [[ "${ARCH}" != "arm64" ]]; then
SUDO="sudo" # Can't open the anka viewer to install macos and addons as ${SUDO} anka.
ARCH="amd64"
else
ARCH_EXTENSION="-arm64"
SUDO=""
fi
# ARCH_CAPITALIZED="$(capitalize ${ARCH})"
if [[ "$(uname)" == "Darwin" ]]; then
if tty -s; then # Disable if the shell isn't interactive (avoids: tput: No value for $TERM and no -T specified)
export COLOR_NC=$(tput sgr0) # No Color
export COLOR_RED=$(tput setaf 1)
export COLOR_GREEN=$(tput setaf 2)
export COLOR_YELLOW=$(tput setaf 3)
export COLOR_BLUE=$(tput setaf 4)
export COLOR_MAGENTA=$(tput setaf 5)
export COLOR_CYAN=$(tput setaf 6)
export COLOR_WHITE=$(tput setaf 7)
fi
fi
error() {
echo "${COLOR_RED}ERROR: $* ${COLOR_NC}"
exit 50
}
warning() {
echo "${COLOR_YELLOW}WARNING: $* ${COLOR_NC}"
}
obtain_anka_license() {
if [[ -z "${ANKA_LICENSE}" ]]; then
while true; do
read -p "Input your Anka license (type \"skip\" to skip this): " ANKA_LICENSE
case "${ANKA_LICENSE}" in
"" ) echo "Want to type something?";;
"skip" ) echo "skipping license activate"; break;;
* ) break;;
esac
done
fi
}
JENKINS_PLUGIN_VERSION="2.13.0"
JENKINS_PIPELINE_PLUGIN_VERSION="1.8.4"
CREDENTIALS_PLUGIN_VERSION="2.5"
GITHUB_PLUGIN_VERSION="1.33.1"
# Minimum versions required by anka-build DependencyVerifier (install before anka-build).
NODE_ITERATOR_API_PLUGIN_VERSION="${NODE_ITERATOR_API_PLUGIN_VERSION:-72.vc90e81737df1}"
SSH_SLAVES_PLUGIN_VERSION="${SSH_SLAVES_PLUGIN_VERSION:-3.1031.v72c6b_883b_869}"
WORKFLOW_BASIC_STEPS_PLUGIN_VERSION="${WORKFLOW_BASIC_STEPS_PLUGIN_VERSION:-1079.vce64b_a_929c5a_}"
WORKFLOW_DURABLE_TASK_STEP_PLUGIN_VERSION="${WORKFLOW_DURABLE_TASK_STEP_PLUGIN_VERSION:-1434.v1b_595c29ddd7}"
GITLAB_ANKA_RUNNER_VERSION=${GITLAB_ANKA_RUNNER_VERSION:-"1.6.1"}
GITLAB_RELEASE_TYPE=${GITLAB_RELEASE_TYPE:-"ce"}
GITLAB_DOCKER_TAG_VERSION=${GITLAB_DOCKER_TAG_VERSION:-"18.0.2-$GITLAB_RELEASE_TYPE.0"}
CLOUD_VERSION="1.50.0-5908cc18"
# CLOUD_NATIVE_PACKAGE=${CLOUD_NATIVE_PACKAGE:-"AnkaControllerRegistry${ARCH_CAPITALIZED}-${CONTROLLER_VERSION}.pkg"}
CLOUD_NATIVE_MACOS_CONTROLLER_PACKAGE=${CLOUD_NATIVE_MACOS_CONTROLLER_PACKAGE:-"anka-controller-${ARCH}-${CLOUD_VERSION}.pkg"}
CLOUD_NATIVE_MACOS_REGISTRY_PACKAGE=${CLOUD_NATIVE_MACOS_REGISTRY_PACKAGE:-"anka-registry-${ARCH}-${CLOUD_VERSION}.pkg"}
CLOUD_DOCKER_TAR=${CLOUD_DOCKER_TAR:-"anka-controller-registry-amd64-${CLOUD_VERSION}.tar.gz"}
ANKA_VIRTUALIZATION_PACKAGE=${ANKA_VIRTUALIZATION_PACKAGE:-"Anka-3.8.5.211.pkg"}
# [[ "$(arch)" == "arm64" ]] && ANKA_VIRTUALIZATION_PACKAGE="${ANKA_VIRTUALIZATION_PACKAGE:-"Anka-3.3.2.166.pkg"}"
TEAMCITY_VERSION="2025.11"
PROMETHEUS_BINARY_VERSION=${PROMETHEUS_BINARY_VERSION:-"2.2.2"}
GITLAB_RUNNER_CUSTOM_EXECUTOR_VERSION="v1.4.1"
CLOUDFRONT_URL="https://downloads.veertu.com/anka"
DOCKER_HOST_ADDRESS=${DOCKER_HOST_ADDRESS:-"host.docker.internal"}
ANKA_VIRTUALIZATION_DOWNLOAD_URL="$CLOUDFRONT_URL/$ANKA_VIRTUALIZATION_PACKAGE"
ANKA_VM_USER=${ANKA_VM_USER:-"anka"}
ANKA_VM_PASSWORD=${ANKA_VM_PASSWORD:-"admin"}
ANKA_BASE_VM_TEMPLATE_UUID_INTEL="${ANKA_BASE_VM_TEMPLATE_UUID_INTEL:-"c12ccfa5-8757-411e-9505-128190e9854e"}" # Used in cloud_tests
ANKA_BASE_VM_TEMPLATE_UUID_APPLE="${ANKA_BASE_VM_TEMPLATE_UUID_APPLE:-"d792c6f6-198c-470f-9526-9c998efe7ab4"}" # Used in cloud_tests
[[ "$(arch)" == "arm64" ]] && ANKA_BASE_VM_TEMPLATE_UUID="${ANKA_BASE_VM_TEMPLATE_UUID_APPLE}" || ANKA_BASE_VM_TEMPLATE_UUID="${ANKA_BASE_VM_TEMPLATE_UUID_INTEL}"
CLOUD_CONTROLLER_ADDRESS=${CLOUD_CONTROLLER_ADDRESS:-"anka.controller"}
CLOUD_REGISTRY_ADDRESS=${CLOUD_REGISTRY_ADDRESS:-"anka.registry"}
CLOUD_ETCD_ADDRESS=${CLOUD_ETCD_ADDRESS:-"anka.etcd"}
CLOUD_CONTROLLER_PORT=${CLOUD_CONTROLLER_PORT:-"8090"}
CLOUD_CONTROLLER_DATA_DIR="/Library/Application Support/Veertu/Anka/anka-controller"
CLOUD_CONTROLLER_LOG_DIR="/Library/Logs/Veertu/AnkaController"
CLOUD_REGISTRY_PORT=${CLOUD_REGISTRY_PORT:-"8089"} # 8089 is the default
CLOUD_REGISTRY_REPO_NAME=${CLOUD_REGISTRY_REPO_NAME:-"local-demo"}
CLOUD_REGISTRY_STORAGE_LOCATION=${CLOUD_REGISTRY_STORAGE_LOCATION:-"/Library/Application Support/Veertu/Anka/registry"}
[[ "$(uname)" == "Linux" ]] && CLOUD_REGISTRY_STORAGE_LOCATION="${HOME}/anka-docker-registry-data"
CLOUD_DOCKER_FOLDER="$(echo $CLOUD_DOCKER_TAR | awk -F'.tar.gz' '{print $1}')"
GITHUB_ACTIONS_ANKA_VM_TEMPLATE_TAG="v1"
GITHUB_ACTIONS_VM_TEMPLATE_UUID_INTEL="${GITHUB_ACTIONS_VM_TEMPLATE_UUID_INTEL:-"9690461a-02b5-412d-8778-dab4167743db"}" # This is used in CI/CD; change screwdriver runner-setup script if you change the name of the var
GITHUB_ACTIONS_VM_TEMPLATE_UUID_APPLE="${GITHUB_ACTIONS_VM_TEMPLATE_UUID_APPLE:-"63bd43f0-9e7a-49e6-b1cd-ab9ed2ed021b"}" # This is used in CI/CD; change screwdriver runner-setup script if you change the name of the var
[[ "$(arch)" == "arm64" ]] && GITHUB_ACTIONS_VM_TEMPLATE_UUID="${GITHUB_ACTIONS_VM_TEMPLATE_UUID_APPLE}" || GITHUB_ACTIONS_VM_TEMPLATE_UUID="${GITHUB_ACTIONS_VM_TEMPLATE_UUID_INTEL}"
JENKINS_PORT="${JENKINS_PORT:-"9092"}"
JENKINS_SERVICE_PORT="8080"
JENKINS_DOCKER_CONTAINER_NAME="anka.jenkins"
JENKINS_TAG_VERSION=${JENKINS_TAG_VERSION:-"lts"}
JENKINS_DATA_DIR="$HOME/$JENKINS_DOCKER_CONTAINER_NAME-data"
JENKINS_VM_TEMPLATE_UUID_INTEL="${JENKINS_VM_TEMPLATE_UUID_INTEL:-"c0847bc9-5d2d-4dbc-ba6a-240f7ff08032"}" # Used in https://github.com/veertuinc/jenkins-dynamic-label-example
JENKINS_VM_TEMPLATE_UUID_APPLE="${JENKINS_VM_TEMPLATE_UUID_APPLE:-"9bf0318f-5c58-4142-b544-cf743a087a41"}" # Used in https://github.com/veertuinc/jenkins-dynamic-label-example
JENKINS_VM_TEMPLATE_UUID="${JENKINS_VM_TEMPLATE_UUID:-"${JENKINS_VM_TEMPLATE_UUID_INTEL}"}"
JENKINS_TEMPLATE_ARCH="${JENKINS_TEMPLATE_ARCH:-"x86_64_mac"}"
if [[ "$(arch)" == "arm64" || "${JENKINS_TEMPLATE_ARCH}" == "arm64_mac" ]]; then
JENKINS_VM_TEMPLATE_UUID="${JENKINS_VM_TEMPLATE_UUID:-"${JENKINS_VM_TEMPLATE_UUID_APPLE}"}"
fi
GITLAB_PORT="${GITLAB_PORT:-"9093"}"
GITLAB_DOCKER_CONTAINER_NAME="anka.gitlab"
GITLAB_DOCKER_DATA_DIR="$HOME/$GITLAB_DOCKER_CONTAINER_NAME-data"
GITLAB_ROOT_PASSWORD="kLF2Cx2XmaWdBwcKAmWRD/Ew9eifMCnyPUFnUPlk6Lw="
GITLAB_ACCESS_TOKEN="token-string-here1234"
GITLAB_EXAMPLE_PROJECT_NAME="gitlab-examples"
GITLAB_ANKA_VM_TEMPLATE_TAG="v1"
GITLAB_RUNNER_PROJECT_RUNNER_NAME="${GITLAB_RUNNER_PROJECT_RUNNER_NAME:-"gitlab-runner-project-specific"}"
GITLAB_RUNNER_SHARED_RUNNER_NAME="${GITLAB_RUNNER_SHARED_RUNNER_NAME:-"gitlab-runner-shared"}"
GITLAB_RUNNER_LOCATION="/tmp/anka-gitlab-runner"
GITLAB_RUNNER_DESTINATION="/usr/local/bin/"
GITLAB_RUNNER_DOCKER_IMAGE="gitlab/gitlab-runner:latest"
[[ "${ARCH}" == "amd64" ]] && RUNNER_ARCH="x86_64" || RUNNER_ARCH="arm64"
GITLAB_RUNNER_CUSTOM_EXECUTOR_FILE_NAME="anka-cloud-gitlab-executor_linux_${RUNNER_ARCH}"
GITLAB_VM_TEMPLATE_UUID_INTEL="${GITLAB_VM_TEMPLATE_UUID_INTEL:-"e69281a5-260e-47c2-bfb3-0d0027eb780c"}"
GITLAB_VM_TEMPLATE_UUID_APPLE="${GITLAB_VM_TEMPLATE_UUID_APPLE:-"304db393-37a5-4e1c-aee5-82ffe32d87ea"}"
GITLAB_VM_TEMPLATE_UUID="${GITLAB_VM_TEMPLATE_UUID_INTEL}"
GITLAB_TEMPLATE_ARCH="${GITLAB_TEMPLATE_ARCH:-"x86_64_mac"}"
if [[ "$(arch)" == "arm64" || "${GITLAB_TEMPLATE_ARCH}" == "arm64_mac" ]]; then
GITLAB_VM_TEMPLATE_UUID="${GITLAB_VM_TEMPLATE_UUID_APPLE}"
fi
PROMETHEUS_PORT="9095"
PROMETHEUS_DOCKER_CONTAINER_NAME="anka.prometheus"
PROMETHEUS_DOCKER_TAG_VERSION=${PROMETHEUS_DOCKER_TAG_VERSION:-"2.21.0"}
PROMETHEUS_DOCKER_DATA_DIR="$HOME/$PROMETHEUS_DOCKER_CONTAINER_NAME-data"
PROMETHEUS_BINARY_NAME="anka-prometheus-exporter"
TEAMCITY_PORT="9094"
TEAMCITY_DOCKER_TAG_VERSION=${TEAMCITY_DOCKER_TAG_VERSION:-"$TEAMCITY_VERSION-linux"}
TEAMCITY_DOCKER_CONTAINER_NAME="anka.teamcity"
TEAMCITY_DOCKER_DATA_DIR="$HOME/$TEAMCITY_DOCKER_CONTAINER_NAME-data"
USE_CERTS=${USE_CERTS:-false}
CERT_DIRECTORY=${CERT_DIRECTORY:-"$HOME/local-build-cloud-certs"}
[[ "$USE_CERTS" == true ]] && CERTS="--cacert $CERT_DIRECTORY/anka-ca-crt.pem --cert $CERT_DIRECTORY/anka-node-$(hostname)-crt.pem --key $CERT_DIRECTORY/anka-node-$(hostname)-key.pem"
dump_jenkins_logs() {
local jenkins_log_tail_lines="${JENKINS_LOG_TAIL_LINES:-200}"
if [[ -n "$JENKINS_BINARY_LOG_FILE" && -e "$JENKINS_BINARY_LOG_FILE" ]]; then
echo "]] Recent Jenkins binary logs (tail -n $jenkins_log_tail_lines $JENKINS_BINARY_LOG_FILE):"
tail -n "$jenkins_log_tail_lines" "$JENKINS_BINARY_LOG_FILE" || true
elif command -v docker >/dev/null && docker ps -a --format '{{.Names}}' | grep -q "^${JENKINS_DOCKER_CONTAINER_NAME}$"; then
echo "]] Recent Jenkins docker logs (docker logs --tail $jenkins_log_tail_lines $JENKINS_DOCKER_CONTAINER_NAME):"
docker logs --tail "$jenkins_log_tail_lines" "$JENKINS_DOCKER_CONTAINER_NAME" 2>&1 || true
else
warning "No Jenkins log source found to dump (checked \$JENKINS_BINARY_LOG_FILE and docker container '$JENKINS_DOCKER_CONTAINER_NAME')."
fi
}
wait_for_jenkins_config_file() {
local jenkins_config_file_path="$JENKINS_DATA_DIR/config.xml"
local jenkins_config_wait_max_attempts="${JENKINS_CONFIG_WAIT_MAX_ATTEMPTS:-30}"
local jenkins_config_wait_delay_seconds="${JENKINS_CONFIG_WAIT_DELAY_SECONDS:-10}"
local jenkins_config_wait_attempt=1
while [[ ! -e "$jenkins_config_file_path" ]]; do
if [[ "$jenkins_config_wait_attempt" -gt "$jenkins_config_wait_max_attempts" ]]; then
echo "Jenkins config file '$jenkins_config_file_path' was not created after $((jenkins_config_wait_max_attempts * jenkins_config_wait_delay_seconds)) seconds."
dump_jenkins_logs
error "Jenkins did not create '$jenkins_config_file_path' in time."
fi
echo "waiting for config file to be created... (${jenkins_config_wait_attempt}/${jenkins_config_wait_max_attempts})"
sleep "$jenkins_config_wait_delay_seconds"
jenkins_config_wait_attempt=$((jenkins_config_wait_attempt + 1))
done
}
modify_hosts() {
[[ -z $1 ]] && echo "ARG 1 missing" && exit 1
if [[ $(uname) == "Darwin" ]]; then
SED="sudo sed -i ''"
else
SED="sudo sed -i"
fi
HOSTS_LOCATION="/etc/hosts"
echo "]] Adding $1 to $HOSTS_LOCATION (requires root)"
$SED "/$1/d" $HOSTS_LOCATION
( echo "127.0.0.1 $1" | sudo tee -a $HOSTS_LOCATION ) &>/dev/null
}
jenkins_obtain_crumb() {
COOKIEJAR="$(mktemp)"
CRUMB=$(jenkins_curl_or_warn "Obtaining Jenkins CSRF crumb" -u "admin: admin" --cookie-jar "$COOKIEJAR" -s "http://$JENKINS_DOCKER_CONTAINER_NAME:$JENKINS_PORT/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,\":\",//crumb)") || return 1
if [[ -z "$CRUMB" ]]; then
warning "Obtaining Jenkins CSRF crumb returned an empty response." >&2
return 1
fi
}
jenkins_curl() {
local jenkins_curl_connect_timeout_seconds="${JENKINS_CURL_CONNECT_TIMEOUT_SECONDS:-10}"
local jenkins_curl_max_time_seconds="${JENKINS_CURL_MAX_TIME_SECONDS:-60}"
curl --fail --show-error --connect-timeout "$jenkins_curl_connect_timeout_seconds" --max-time "$jenkins_curl_max_time_seconds" "$@"
}
jenkins_curl_or_warn() {
local jenkins_request_description="$1"
shift
echo "]] $jenkins_request_description" >&2
local jenkins_curl_exit_code=0
if jenkins_curl "$@"; then
return 0
else
jenkins_curl_exit_code=$?
fi
if [[ "$jenkins_curl_exit_code" == "28" ]]; then
warning "$jenkins_request_description timed out after ${JENKINS_CURL_MAX_TIME_SECONDS:-60}s." >&2
elif [[ "$jenkins_curl_exit_code" == "7" ]]; then
warning "$jenkins_request_description could not connect to Jenkins." >&2
elif [[ "$jenkins_curl_exit_code" == "22" ]]; then
warning "$jenkins_request_description returned a non-success HTTP status." >&2
else
warning "$jenkins_request_description failed with curl exit code $jenkins_curl_exit_code." >&2
fi
return "$jenkins_curl_exit_code"
}
jenkins_plugin_install() {
PLUGIN_NAME=$(echo $1 | cut -d@ -f1)
PLUGIN_VERSION=$(echo $1 | cut -d@ -f2)
jenkins_obtain_crumb
jenkins_curl_or_warn "Requesting Jenkins plugin installation for ${PLUGIN_NAME}@${PLUGIN_VERSION}" -X POST -H "$CRUMB" --cookie "$COOKIEJAR" -d "<jenkins><install plugin=\"${PLUGIN_NAME}@${PLUGIN_VERSION}\" /></jenkins>" --header 'Content-Type: text/xml' http://$JENKINS_DOCKER_CONTAINER_NAME:$JENKINS_PORT/pluginManager/installNecessaryPlugins || return 1
TRIES=0
while [[ "$(docker logs --tail 500 $JENKINS_DOCKER_CONTAINER_NAME 2>&1 | grep "INFO: Installation successful: ${PLUGIN_NAME}$" | head -1)" != "INFO: Installation successful: $PLUGIN_NAME" ]]; do
echo "Installation of $PLUGIN_NAME plugin still pending..."
sleep 10
[[ $TRIES == 100 ]] && echo "Something is wrong with the Jenkins $PLUGIN_NAME installation..." && docker logs --tail 500 $JENKINS_DOCKER_CONTAINER_NAME && exit 1
TRIES=$(($TRIES + 1))
done
true
}
replace_text_in_file() {
local destination_file_path="$1"
local text_to_replace="$2"
local replacement_text="$3"
if [[ "$(uname)" == "Darwin" ]]; then
sed -i '' "s|${text_to_replace}|${replacement_text}|g" "$destination_file_path"
else
sed -i "s|${text_to_replace}|${replacement_text}|g" "$destination_file_path"
fi
}
configure_jenkins_cloud_config() {
local jenkins_config_file_path="$1"
local jenkins_vm_template_uuid_value="$2"
local jenkins_anka_mgmt_host_value="$3"
local jenkins_anka_mgmt_port_value="$4"
replace_text_in_file "$jenkins_config_file_path" "$JENKINS_VM_TEMPLATE_UUID_INTEL" "$jenkins_vm_template_uuid_value"
replace_text_in_file "$jenkins_config_file_path" "JENKINS_ANKA_MGMT_HOST_PLACEHOLDER" "$jenkins_anka_mgmt_host_value"
replace_text_in_file "$jenkins_config_file_path" "JENKINS_ANKA_MGMT_PORT_PLACEHOLDER" "$jenkins_anka_mgmt_port_value"
}
modify_uuid() {
# Modify UUID (don't use in production; for getting-started demo only)
[[ -z "$1" ]] && echo "no arguments... Please provide TEMPLATE_NAME as ARG1" && exit 1
[[ -z "$2" ]] && echo "Please provided the new UUID as ARG2" && exit 2
TEMPLATE_NAME=$1
DEST_UUID=$2
CUR_UUID=$(${SUDO} anka --machine-readable list | jq -r ".body[] | select(.name==\"$TEMPLATE_NAME\") | .uuid")
if [[ -z "$(${SUDO} anka --machine-readable registry list | jq ".body[] | select(.id == \"${DEST_UUID}\") | .name")" && "${CUR_UUID}" != "${DEST_UUID}" ]]; then
${SUDO} mv "$(${SUDO} anka config vm_lib_dir)/$CUR_UUID" "$(${SUDO} anka config vm_lib_dir)/$DEST_UUID"
${SUDO} sed -i '' "s/$CUR_UUID/$DEST_UUID/" "$(${SUDO} anka config vm_lib_dir)/$DEST_UUID/config.yaml"
fi
}
execute-docker-compose() {
PATH="/usr/local/bin:$PATH" # Fix for CI/CD
if [[ ! -z "$(docker compose --help | grep "Usage: docker compose \[OPTIONS\] COMMAND")" ]]; then
docker compose "$@"
elif [[ ! -z "$(command -v docker-compose)" ]]; then
docker-compose "$@"
else
echo "No docker compose/docker-compose found, please install it!"
exit 1
fi
}
function timeout() { perl -e 'alarm shift; exec @ARGV' "$@"; }