Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lima-vm
GitHub Repository: lima-vm/lima
Path: blob/master/pkg/cidata/cidata.TEMPLATE.d/boot.sh
2622 views
1
#!/bin/sh
2
3
# SPDX-FileCopyrightText: Copyright The Lima Authors
4
# SPDX-License-Identifier: Apache-2.0
5
6
set -eu
7
8
INFO() {
9
echo "LIMA $(date -Iseconds)| $*"
10
}
11
12
WARNING() {
13
echo "LIMA $(date -Iseconds)| WARNING: $*"
14
}
15
16
# shellcheck disable=SC2163
17
while read -r line; do [ -n "$line" ] && export "$line"; done <"${LIMA_CIDATA_MNT}"/lima.env
18
# shellcheck disable=SC2163
19
while read -r line; do [ -n "$line" ] && export "$line"; done <"${LIMA_CIDATA_MNT}"/param.env
20
21
# shellcheck disable=SC2163
22
while read -r line; do
23
# pam_env implementation:
24
# - '#' is treated the same as newline; terminates value
25
# - skip leading tabs and spaces
26
# - skip leading "export " prefix (only single space)
27
# - skip leading quote ('\'' or '"') on the value side
28
# - skip trailing quote only if leading quote has been skipped;
29
# quotes don't need to match; trailing quote may be omitted
30
line="$(echo "$line" | sed -E "s/^[ \\t]*(export )?//; s/#.*//; s/(^[^=]+=)[\"'](.*[^\"'])?[\"']?$/\1\2/")"
31
[ -n "$line" ] && export "$line"
32
done <"${LIMA_CIDATA_MNT}"/etc_environment
33
34
PATH="${LIMA_CIDATA_MNT}"/util:"${PATH}"
35
export PATH
36
37
CODE=0
38
39
# Don't make any changes to /etc or /var/lib until boot/04-persistent-data-volume.sh
40
# has run because it might move the directories to /mnt/data on first boot. In that
41
# case changes made on restart would be lost.
42
43
if [ "$LIMA_CIDATA_PLAIN" = "1" ]; then
44
INFO "Plain mode. Skipping to run boot scripts. Provisioning scripts will be still executed. Guest agent will not be running."
45
else
46
for f in "${LIMA_CIDATA_MNT}"/boot/*; do
47
INFO "Executing $f"
48
if ! "$f"; then
49
WARNING "Failed to execute $f"
50
CODE=1
51
fi
52
done
53
fi
54
55
# indirect variable lookup, like ${!var} in bash
56
deref() {
57
eval echo \$"$1"
58
}
59
60
if [ -d "${LIMA_CIDATA_MNT}"/provision.data ]; then
61
for f in "${LIMA_CIDATA_MNT}"/provision.data/*; do
62
filename=$(basename "$f")
63
overwrite=$(deref "LIMA_CIDATA_DATAFILE_${filename}_OVERWRITE")
64
owner=$(deref "LIMA_CIDATA_DATAFILE_${filename}_OWNER")
65
path=$(deref "LIMA_CIDATA_DATAFILE_${filename}_PATH")
66
permissions=$(deref "LIMA_CIDATA_DATAFILE_${filename}_PERMISSIONS")
67
user="${owner%%:*}"
68
if [ -e "$path" ] && [ "$overwrite" = "false" ]; then
69
INFO "Not overwriting $path"
70
else
71
INFO "Copying $f to $path"
72
if ! sudo -iu "${user}" mkdir -p "$(dirname "$path")"; then
73
WARNING "Failed to create directory for ${path} (as user ${user})"
74
WARNING "Falling back to creating directory as root to maintain compatibility"
75
mkdir -p "$(dirname "$path")"
76
fi
77
cp "$f" "$path"
78
chown "$owner" "$path"
79
chmod "$permissions" "$path"
80
fi
81
done
82
fi
83
84
if [ -d "${LIMA_CIDATA_MNT}"/provision.yq ]; then
85
yq="${LIMA_CIDATA_MNT}/lima-guestagent yq"
86
for f in "${LIMA_CIDATA_MNT}"/provision.yq/*; do
87
filename=$(basename "${f}")
88
format=$(deref "LIMA_CIDATA_YQ_PROVISION_${filename}_FORMAT")
89
owner=$(deref "LIMA_CIDATA_YQ_PROVISION_${filename}_OWNER")
90
path=$(deref "LIMA_CIDATA_YQ_PROVISION_${filename}_PATH")
91
permissions=$(deref "LIMA_CIDATA_YQ_PROVISION_${filename}_PERMISSIONS")
92
user="${owner%%:*}"
93
# Creating intermediate directories may fail if the user does not have permission.
94
# TODO: Create intermediate directories with the specified group ownership.
95
if ! sudo -iu "${user}" mkdir -p "$(dirname "${path}")"; then
96
WARNING "Failed to create directory for ${path} (as user ${user})"
97
CODE=1
98
continue
99
fi
100
# Since CIDATA is mounted with dmode=700,fmode=700,
101
# `lima-guestagent yq` cannot be executed by non-root users,
102
# and provision.yq/* files cannot be read by non-root users.
103
if [ -f "${path}" ]; then
104
INFO "Updating ${path}"
105
# If the user does not have write permission, it should fail.
106
# This avoids changes being made by the wrong user.
107
if ! sudo -iu "${user}" test -w "${path}"; then
108
WARNING "File ${path} is not writable by user ${user}"
109
CODE=1
110
continue
111
fi
112
# Relies on the fact that yq does not change the owner of the existing file.
113
if ! ${yq} --inplace --from-file "${f}" --input-format "${format}" --output-format "${format}" "${path}"; then
114
WARNING "Failed to update ${path} (as user ${user})"
115
CODE=1
116
continue
117
fi
118
else
119
if [ "${format}" = "auto" ]; then
120
# yq can't determine the output format from non-existing files
121
case "${path}" in
122
*.csv) format=csv ;;
123
*.ini) format=ini ;;
124
*.json) format=json ;;
125
*.properties) format=properties ;;
126
*.toml) format=toml ;;
127
*.tsv) format=tsv ;;
128
*.xml) format=xml ;;
129
*.yaml | *.yml) format=yaml ;;
130
*)
131
format=yaml
132
WARNING "Cannot determine file type for ${path}, using yaml format"
133
;;
134
esac
135
fi
136
INFO "Creating ${path}"
137
if ! ${yq} --null-input --from-file "${f}" --output-format "${format}" | sudo -iu "${user}" tee "${path}"; then
138
WARNING "Failed to create ${path} (as user ${user})"
139
CODE=1
140
continue
141
fi
142
fi
143
if ! sudo -iu "${user}" chown "${owner}" "${path}"; then
144
WARNING "Failed to set owner for ${path} (as user ${user})"
145
CODE=1
146
fi
147
if ! sudo -iu "${user}" chmod "${permissions}" "${path}"; then
148
WARNING "Failed to set permissions for ${path} (as user ${user})"
149
CODE=1
150
fi
151
done
152
fi
153
154
if [ -d "${LIMA_CIDATA_MNT}"/provision.system ]; then
155
for f in "${LIMA_CIDATA_MNT}"/provision.system/*; do
156
INFO "Executing $f"
157
if ! "$f"; then
158
WARNING "Failed to execute $f"
159
CODE=1
160
fi
161
done
162
fi
163
164
USER_SCRIPT="${LIMA_CIDATA_HOME}/.lima-user-script"
165
if [ -d "${LIMA_CIDATA_MNT}"/provision.user ]; then
166
if [ ! -f /sbin/openrc-run ]; then
167
until [ -e "/run/user/${LIMA_CIDATA_UID}/systemd/private" ]; do sleep 3; done
168
fi
169
params=$(grep -o '^PARAM_[^=]*' "${LIMA_CIDATA_MNT}"/param.env | paste -sd ,)
170
for f in "${LIMA_CIDATA_MNT}"/provision.user/*; do
171
INFO "Executing $f (as user ${LIMA_CIDATA_USER})"
172
cp "$f" "${USER_SCRIPT}"
173
chown "${LIMA_CIDATA_USER}" "${USER_SCRIPT}"
174
chmod 755 "${USER_SCRIPT}"
175
if ! sudo -iu "${LIMA_CIDATA_USER}" "--preserve-env=${params}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" "${USER_SCRIPT}"; then
176
WARNING "Failed to execute $f (as user ${LIMA_CIDATA_USER})"
177
CODE=1
178
fi
179
rm "${USER_SCRIPT}"
180
done
181
fi
182
183
# Signal that provisioning is done. The instance-id in the meta-data file changes on every boot,
184
# so any copy from a previous boot cycle will have different content.
185
cp "${LIMA_CIDATA_MNT}"/meta-data /run/lima-boot-done
186
187
INFO "Exiting with code $CODE"
188
exit "$CODE"
189
190