-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupdate.sh
More file actions
executable file
·230 lines (204 loc) · 8.19 KB
/
Copy pathupdate.sh
File metadata and controls
executable file
·230 lines (204 loc) · 8.19 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
#!/bin/bash
# Isabelle project
# This script updates existing installation in place.
TOP_DIR="$(cd "$(dirname "$(which "$0")")" ; pwd -P)"
cd "${TOP_DIR}"
. ./lib_header.sh
user=""
password=""
coreenv=""
no_verify=""
# An already-downloaded release to install instead of fetching one.
#
# The platform fetches releases on its own machine and copies the bytes over,
# so that the credentials for the release server never land on a customer's
# host — where anyone who gets root on their own box would find them. Without
# this the only way to update was to hand those credentials to every instance.
archive=""
# The version name this install is known by on the release server, e.g.
# `main-288`. Recorded in the distribution directory once the install has
# succeeded, so an installation can say what it is running — until now nothing
# in the tree named the release it came from, and the only answer to "which
# build is this?" was a component commit hash.
version=""
while test -n "$1" ; do
case $1 in
--user)
user="$2"
shift 1
;;
--password)
password="$2"
shift 1
;;
--coreenv)
coreenv="y"
;;
--no-verify)
no_verify="y"
;;
--archive)
archive="$2"
shift 1
;;
--version)
version="$2"
shift 1
;;
*)
fail "Unknown argument: $1"
;;
esac
shift 1
done
if [ "${archive}" != "" ] ; then
[ -f "${archive}" ] || fail "No such archive: ${archive}"
elif [ "${coreenv}" == "y" ]; then
if [ "${user}" == "" ] && [ -f "${DISTR_DIR}/.releases_user" ]; then
user="$(cat "${DISTR_DIR}/.releases_user")"
fi
if [ "${password}" == "" ] && [ -f "${DISTR_DIR}/.releases_password" ]; then
password="$(cat "${DISTR_DIR}/.releases_password")"
fi
if [ "${user}" == "" ] || [ "${password}" == "" ]; then
fail "Releases credentials not found in core environment"
fi
fi
if [ "${archive}" == "" ] && { [ "${user}" == "" ] || [ "${password}" == "" ] ; } ; then
read -p "Releases user: " user
read -p "Releases password: " password
fi
# Check the release's detached OpenPGP signature. Called before the service
# is stopped and before anything is unpacked, so a tampered or truncated
# download leaves the running installation exactly as it was.
#
# The trusted key is isabelle-release-pubkey.asc shipped alongside these
# scripts — that is, it comes from the previous, already verified release,
# not from the tarball we are about to install. Trusting a key carried
# inside the new tarball would verify nothing.
function verify_release() {
local file="$1"
local sig="$2"
if [ "${no_verify}" == "y" ] ; then
echo "WARNING: --no-verify given, installing an UNVERIFIED release" >&2
return 0
fi
local pubkey="${TOP_DIR}/isabelle-release-pubkey.asc"
[ -f "${pubkey}" ] || fail "Release signing key not found: ${pubkey}"
which gpg > /dev/null 2>&1 || fail "gpg is not installed, cannot verify the release"
# Throwaway keyring holding exactly one trusted key: the host's own
# keyring is never touched, and no other key can satisfy the check.
# Kept in TMPDIR because gpg-agent's socket lives inside GNUPGHOME and
# unix socket paths are capped at ~104 characters.
local gnupg_home
gnupg_home="$(mktemp -d "${TMPDIR:-/tmp}/isabelle-verify.XXXXXX")" \
|| fail "Failed to create a temporary keyring"
chmod 700 "${gnupg_home}"
local rc=0
GNUPGHOME="${gnupg_home}" gpg --batch --quiet --import "${pubkey}" || rc=1
if [ ${rc} -eq 0 ] ; then
GNUPGHOME="${gnupg_home}" gpg --batch --verify "${sig}" "${file}" || rc=2
fi
GNUPGHOME="${gnupg_home}" gpgconf --kill gpg-agent > /dev/null 2>&1 || true
rm -rf "${gnupg_home}"
[ ${rc} -eq 0 ] \
|| fail "Release signature verification FAILED — installation left untouched"
echo "Release signature verified"
}
url_release_equestrian="https://releases.interpretica.io/isabelle-equestrian-release/main-latest/equestrian-main-latest.tar.xz"
url_release_sample="https://releases.interpretica.io/isabelle-sample-release/main-latest/sample-main-latest.tar.xz"
url_release_intranet="https://releases.interpretica.io/isabelle-intranet-release/main-latest/intranet-main-latest.tar.xz"
url_release_cloudcpe="https://releases.interpretica.io/isabelle-cloudcpe-release/main-latest/cloudcpe-main-latest.tar.xz"
url_release_didactist="https://releases.interpretica.io/isabelle-didactist-release/main-latest/didactist-main-latest.tar.xz"
url_release_midair="https://releases.interpretica.io/isabelle-midair-release/main-latest/midair-main-latest.tar.xz"
url_release_proteos="https://releases.interpretica.io/isabelle-proteos-release/main-latest/proteos-main-latest.tar.xz"
url_release_zine="https://releases.interpretica.io/isabelle-zine-release/main-latest/zine-main-latest.tar.xz"
case "$flavour" in
equestrian)
target_release="$url_release_equestrian"
;;
sample)
target_release="$url_release_sample"
;;
intranet)
target_release="$url_release_intranet"
;;
cloudcpe)
target_release="$url_release_cloudcpe"
;;
didactist)
target_release="$url_release_didactist"
;;
midair)
target_release="$url_release_midair"
;;
proteos)
target_release="$url_release_proteos"
;;
zine)
target_release="$url_release_zine"
;;
*)
echo "Unknown flavour: $flavour" >&2
exit 1
esac
# Fall back to the name the archive carries: releases are published as
# `<flavour>-<version>.tar.xz`, so `midair-main-288.tar.xz` is `main-288`.
if [ "${version}" == "" ] ; then
if [ "${archive}" != "" ] ; then
version="$(basename "${archive}")"
else
version="$(basename "${target_release}")"
fi
version="${version#${flavour}-}"
version="${version%.tar.xz}"
fi
pushd "${DISTR_DIR}" > /dev/null
# Get the release and its detached signature side by side, whether they come
# off the release server or were handed to us already downloaded.
if [ "${archive}" != "" ] ; then
cp "${archive}" release.tar.xz || fail "Failed to take the supplied archive"
if [ "${no_verify}" != "y" ] ; then
[ -f "${archive}.asc" ] \
|| fail "No signature next to the supplied archive: ${archive}.asc"
cp "${archive}.asc" release.tar.xz.asc \
|| fail "Failed to take the supplied archive's signature"
fi
else
touch wget_tmp
chmod 600 wget_tmp
echo "user=$user" > wget_tmp
echo "password=$password" >> wget_tmp
WGETRC=./wget_tmp wget "${target_release}" -O release.tar.xz || fail "Failed to download release"
if [ "${no_verify}" != "y" ] ; then
WGETRC=./wget_tmp wget "${target_release}.asc" -O release.tar.xz.asc \
|| fail "Failed to download release signature"
fi
rm wget_tmp
fi
# Everything below this line modifies the live installation, so the
# signature has to be good before we reach it.
verify_release release.tar.xz release.tar.xz.asc
rm distr/core/isabelle-gc/.installed > /dev/null 2> /dev/null
${TOP_DIR}/service.sh stop || fail "Failed to stop service"
rm -rf distr/ui
tar xvf release.tar.xz
rm -f release.tar.xz release.tar.xz.asc
# Written last: a half-finished install must not claim to be the new version.
echo "${version}" > .version
popd > /dev/null
chown -R www-data:www-data "${DISTR_DIR}"
# The tarball may carry its own data/raw; whatever this installation was
# configured to be allowed to do is re-asserted over it, exactly as at deploy
# time. Before the hooks, for the same reason as there.
install_features
# Re-apply install-time extras hooks: the tarball just overwrote distr/ and
# data/raw/, so any data the hooks injected (e.g. bublik_ui_url, SSH creds in
# data/raw/settings.js) needs to be re-applied before the core starts and
# snapshots its data again.
if [ -d "${TOP_DIR}/extras/deploy" ] ; then
for file in $(ls "${TOP_DIR}/extras/deploy"/*.sh 2> /dev/null) ; do
TOP_DIR="${TOP_DIR}" "$file" || fail "Extras deploy hook failed: $file"
done
fi
${TOP_DIR}/service.sh start || fail "Failed to start service"