##// END OF EJS Templates
contrib: update PyOxidizer to 0.10.3...
Gregory Szorc -
r47091:a6c5ec6b stable
parent child Browse files
Show More
@@ -1,597 +1,597 b''
1 1 # linux.py - Linux specific automation functionality
2 2 #
3 3 # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 # no-check-code because Python 3 native.
9 9
10 10 import os
11 11 import pathlib
12 12 import shlex
13 13 import subprocess
14 14 import tempfile
15 15
16 16 from .ssh import exec_command
17 17
18 18
19 19 # Linux distributions that are supported.
20 20 DISTROS = {
21 21 'debian9',
22 22 'debian10',
23 23 'ubuntu18.04',
24 24 'ubuntu19.04',
25 25 }
26 26
27 27 INSTALL_PYTHONS = r'''
28 28 PYENV2_VERSIONS="2.7.17 pypy2.7-7.2.0"
29 29 PYENV3_VERSIONS="3.5.10 3.6.12 3.7.9 3.8.6 3.9.0 pypy3.5-7.0.0 pypy3.6-7.3.0"
30 30
31 31 git clone https://github.com/pyenv/pyenv.git /hgdev/pyenv
32 32 pushd /hgdev/pyenv
33 33 git checkout 8ac91b4fd678a8c04356f5ec85cfcd565c265e9a
34 34 popd
35 35
36 36 export PYENV_ROOT="/hgdev/pyenv"
37 37 export PATH="$PYENV_ROOT/bin:$PATH"
38 38
39 39 # pip 19.2.3.
40 40 PIP_SHA256=57e3643ff19f018f8a00dfaa6b7e4620e3c1a7a2171fd218425366ec006b3bfe
41 41 wget -O get-pip.py --progress dot:mega https://github.com/pypa/get-pip/raw/309a56c5fd94bd1134053a541cb4657a4e47e09d/get-pip.py
42 42 echo "${PIP_SHA256} get-pip.py" | sha256sum --check -
43 43
44 44 VIRTUALENV_SHA256=f78d81b62d3147396ac33fc9d77579ddc42cc2a98dd9ea38886f616b33bc7fb2
45 45 VIRTUALENV_TARBALL=virtualenv-16.7.5.tar.gz
46 46 wget -O ${VIRTUALENV_TARBALL} --progress dot:mega https://files.pythonhosted.org/packages/66/f0/6867af06d2e2f511e4e1d7094ff663acdebc4f15d4a0cb0fed1007395124/${VIRTUALENV_TARBALL}
47 47 echo "${VIRTUALENV_SHA256} ${VIRTUALENV_TARBALL}" | sha256sum --check -
48 48
49 49 for v in ${PYENV2_VERSIONS}; do
50 50 pyenv install -v ${v}
51 51 ${PYENV_ROOT}/versions/${v}/bin/python get-pip.py
52 52 ${PYENV_ROOT}/versions/${v}/bin/pip install ${VIRTUALENV_TARBALL}
53 53 ${PYENV_ROOT}/versions/${v}/bin/pip install -r /hgdev/requirements-py2.txt
54 54 done
55 55
56 56 for v in ${PYENV3_VERSIONS}; do
57 57 pyenv install -v ${v}
58 58 ${PYENV_ROOT}/versions/${v}/bin/python get-pip.py
59 59 ${PYENV_ROOT}/versions/${v}/bin/pip install -r /hgdev/requirements-py3.txt
60 60 done
61 61
62 62 pyenv global ${PYENV2_VERSIONS} ${PYENV3_VERSIONS} system
63 63 '''.lstrip().replace(
64 64 '\r\n', '\n'
65 65 )
66 66
67 67
68 68 INSTALL_RUST = r'''
69 69 RUSTUP_INIT_SHA256=a46fe67199b7bcbbde2dcbc23ae08db6f29883e260e23899a88b9073effc9076
70 70 wget -O rustup-init --progress dot:mega https://static.rust-lang.org/rustup/archive/1.18.3/x86_64-unknown-linux-gnu/rustup-init
71 71 echo "${RUSTUP_INIT_SHA256} rustup-init" | sha256sum --check -
72 72
73 73 chmod +x rustup-init
74 74 sudo -H -u hg -g hg ./rustup-init -y
75 75 sudo -H -u hg -g hg /home/hg/.cargo/bin/rustup install 1.31.1 1.46.0
76 76 sudo -H -u hg -g hg /home/hg/.cargo/bin/rustup component add clippy
77 77
78 sudo -H -u hg -g hg /home/hg/.cargo/bin/cargo install --version 0.9.0 pyoxidizer
78 sudo -H -u hg -g hg /home/hg/.cargo/bin/cargo install --version 0.10.3 pyoxidizer
79 79 '''
80 80
81 81
82 82 BOOTSTRAP_VIRTUALENV = r'''
83 83 /usr/bin/virtualenv /hgdev/venv-bootstrap
84 84
85 85 HG_SHA256=35fc8ba5e0379c1b3affa2757e83fb0509e8ac314cbd9f1fd133cf265d16e49f
86 86 HG_TARBALL=mercurial-5.1.1.tar.gz
87 87
88 88 wget -O ${HG_TARBALL} --progress dot:mega https://www.mercurial-scm.org/release/${HG_TARBALL}
89 89 echo "${HG_SHA256} ${HG_TARBALL}" | sha256sum --check -
90 90
91 91 /hgdev/venv-bootstrap/bin/pip install ${HG_TARBALL}
92 92 '''.lstrip().replace(
93 93 '\r\n', '\n'
94 94 )
95 95
96 96
97 97 BOOTSTRAP_DEBIAN = (
98 98 r'''
99 99 #!/bin/bash
100 100
101 101 set -ex
102 102
103 103 DISTRO=`grep DISTRIB_ID /etc/lsb-release | awk -F= '{{print $2}}'`
104 104 DEBIAN_VERSION=`cat /etc/debian_version`
105 105 LSB_RELEASE=`lsb_release -cs`
106 106
107 107 sudo /usr/sbin/groupadd hg
108 108 sudo /usr/sbin/groupadd docker
109 109 sudo /usr/sbin/useradd -g hg -G sudo,docker -d /home/hg -m -s /bin/bash hg
110 110 sudo mkdir /home/hg/.ssh
111 111 sudo cp ~/.ssh/authorized_keys /home/hg/.ssh/authorized_keys
112 112 sudo chown -R hg:hg /home/hg/.ssh
113 113 sudo chmod 700 /home/hg/.ssh
114 114 sudo chmod 600 /home/hg/.ssh/authorized_keys
115 115
116 116 cat << EOF | sudo tee /etc/sudoers.d/90-hg
117 117 hg ALL=(ALL) NOPASSWD:ALL
118 118 EOF
119 119
120 120 sudo apt-get update
121 121 sudo DEBIAN_FRONTEND=noninteractive apt-get -yq dist-upgrade
122 122
123 123 # Install packages necessary to set up Docker Apt repo.
124 124 sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install --no-install-recommends \
125 125 apt-transport-https \
126 126 gnupg
127 127
128 128 cat > docker-apt-key << EOF
129 129 -----BEGIN PGP PUBLIC KEY BLOCK-----
130 130
131 131 mQINBFit2ioBEADhWpZ8/wvZ6hUTiXOwQHXMAlaFHcPH9hAtr4F1y2+OYdbtMuth
132 132 lqqwp028AqyY+PRfVMtSYMbjuQuu5byyKR01BbqYhuS3jtqQmljZ/bJvXqnmiVXh
133 133 38UuLa+z077PxyxQhu5BbqntTPQMfiyqEiU+BKbq2WmANUKQf+1AmZY/IruOXbnq
134 134 L4C1+gJ8vfmXQt99npCaxEjaNRVYfOS8QcixNzHUYnb6emjlANyEVlZzeqo7XKl7
135 135 UrwV5inawTSzWNvtjEjj4nJL8NsLwscpLPQUhTQ+7BbQXAwAmeHCUTQIvvWXqw0N
136 136 cmhh4HgeQscQHYgOJjjDVfoY5MucvglbIgCqfzAHW9jxmRL4qbMZj+b1XoePEtht
137 137 ku4bIQN1X5P07fNWzlgaRL5Z4POXDDZTlIQ/El58j9kp4bnWRCJW0lya+f8ocodo
138 138 vZZ+Doi+fy4D5ZGrL4XEcIQP/Lv5uFyf+kQtl/94VFYVJOleAv8W92KdgDkhTcTD
139 139 G7c0tIkVEKNUq48b3aQ64NOZQW7fVjfoKwEZdOqPE72Pa45jrZzvUFxSpdiNk2tZ
140 140 XYukHjlxxEgBdC/J3cMMNRE1F4NCA3ApfV1Y7/hTeOnmDuDYwr9/obA8t016Yljj
141 141 q5rdkywPf4JF8mXUW5eCN1vAFHxeg9ZWemhBtQmGxXnw9M+z6hWwc6ahmwARAQAB
142 142 tCtEb2NrZXIgUmVsZWFzZSAoQ0UgZGViKSA8ZG9ja2VyQGRvY2tlci5jb20+iQI3
143 143 BBMBCgAhBQJYrefAAhsvBQsJCAcDBRUKCQgLBRYCAwEAAh4BAheAAAoJEI2BgDwO
144 144 v82IsskP/iQZo68flDQmNvn8X5XTd6RRaUH33kXYXquT6NkHJciS7E2gTJmqvMqd
145 145 tI4mNYHCSEYxI5qrcYV5YqX9P6+Ko+vozo4nseUQLPH/ATQ4qL0Zok+1jkag3Lgk
146 146 jonyUf9bwtWxFp05HC3GMHPhhcUSexCxQLQvnFWXD2sWLKivHp2fT8QbRGeZ+d3m
147 147 6fqcd5Fu7pxsqm0EUDK5NL+nPIgYhN+auTrhgzhK1CShfGccM/wfRlei9Utz6p9P
148 148 XRKIlWnXtT4qNGZNTN0tR+NLG/6Bqd8OYBaFAUcue/w1VW6JQ2VGYZHnZu9S8LMc
149 149 FYBa5Ig9PxwGQOgq6RDKDbV+PqTQT5EFMeR1mrjckk4DQJjbxeMZbiNMG5kGECA8
150 150 g383P3elhn03WGbEEa4MNc3Z4+7c236QI3xWJfNPdUbXRaAwhy/6rTSFbzwKB0Jm
151 151 ebwzQfwjQY6f55MiI/RqDCyuPj3r3jyVRkK86pQKBAJwFHyqj9KaKXMZjfVnowLh
152 152 9svIGfNbGHpucATqREvUHuQbNnqkCx8VVhtYkhDb9fEP2xBu5VvHbR+3nfVhMut5
153 153 G34Ct5RS7Jt6LIfFdtcn8CaSas/l1HbiGeRgc70X/9aYx/V/CEJv0lIe8gP6uDoW
154 154 FPIZ7d6vH+Vro6xuWEGiuMaiznap2KhZmpkgfupyFmplh0s6knymuQINBFit2ioB
155 155 EADneL9S9m4vhU3blaRjVUUyJ7b/qTjcSylvCH5XUE6R2k+ckEZjfAMZPLpO+/tF
156 156 M2JIJMD4SifKuS3xck9KtZGCufGmcwiLQRzeHF7vJUKrLD5RTkNi23ydvWZgPjtx
157 157 Q+DTT1Zcn7BrQFY6FgnRoUVIxwtdw1bMY/89rsFgS5wwuMESd3Q2RYgb7EOFOpnu
158 158 w6da7WakWf4IhnF5nsNYGDVaIHzpiqCl+uTbf1epCjrOlIzkZ3Z3Yk5CM/TiFzPk
159 159 z2lLz89cpD8U+NtCsfagWWfjd2U3jDapgH+7nQnCEWpROtzaKHG6lA3pXdix5zG8
160 160 eRc6/0IbUSWvfjKxLLPfNeCS2pCL3IeEI5nothEEYdQH6szpLog79xB9dVnJyKJb
161 161 VfxXnseoYqVrRz2VVbUI5Blwm6B40E3eGVfUQWiux54DspyVMMk41Mx7QJ3iynIa
162 162 1N4ZAqVMAEruyXTRTxc9XW0tYhDMA/1GYvz0EmFpm8LzTHA6sFVtPm/ZlNCX6P1X
163 163 zJwrv7DSQKD6GGlBQUX+OeEJ8tTkkf8QTJSPUdh8P8YxDFS5EOGAvhhpMBYD42kQ
164 164 pqXjEC+XcycTvGI7impgv9PDY1RCC1zkBjKPa120rNhv/hkVk/YhuGoajoHyy4h7
165 165 ZQopdcMtpN2dgmhEegny9JCSwxfQmQ0zK0g7m6SHiKMwjwARAQABiQQ+BBgBCAAJ
166 166 BQJYrdoqAhsCAikJEI2BgDwOv82IwV0gBBkBCAAGBQJYrdoqAAoJEH6gqcPyc/zY
167 167 1WAP/2wJ+R0gE6qsce3rjaIz58PJmc8goKrir5hnElWhPgbq7cYIsW5qiFyLhkdp
168 168 YcMmhD9mRiPpQn6Ya2w3e3B8zfIVKipbMBnke/ytZ9M7qHmDCcjoiSmwEXN3wKYI
169 169 mD9VHONsl/CG1rU9Isw1jtB5g1YxuBA7M/m36XN6x2u+NtNMDB9P56yc4gfsZVES
170 170 KA9v+yY2/l45L8d/WUkUi0YXomn6hyBGI7JrBLq0CX37GEYP6O9rrKipfz73XfO7
171 171 JIGzOKZlljb/D9RX/g7nRbCn+3EtH7xnk+TK/50euEKw8SMUg147sJTcpQmv6UzZ
172 172 cM4JgL0HbHVCojV4C/plELwMddALOFeYQzTif6sMRPf+3DSj8frbInjChC3yOLy0
173 173 6br92KFom17EIj2CAcoeq7UPhi2oouYBwPxh5ytdehJkoo+sN7RIWua6P2WSmon5
174 174 U888cSylXC0+ADFdgLX9K2zrDVYUG1vo8CX0vzxFBaHwN6Px26fhIT1/hYUHQR1z
175 175 VfNDcyQmXqkOnZvvoMfz/Q0s9BhFJ/zU6AgQbIZE/hm1spsfgvtsD1frZfygXJ9f
176 176 irP+MSAI80xHSf91qSRZOj4Pl3ZJNbq4yYxv0b1pkMqeGdjdCYhLU+LZ4wbQmpCk
177 177 SVe2prlLureigXtmZfkqevRz7FrIZiu9ky8wnCAPwC7/zmS18rgP/17bOtL4/iIz
178 178 QhxAAoAMWVrGyJivSkjhSGx1uCojsWfsTAm11P7jsruIL61ZzMUVE2aM3Pmj5G+W
179 179 9AcZ58Em+1WsVnAXdUR//bMmhyr8wL/G1YO1V3JEJTRdxsSxdYa4deGBBY/Adpsw
180 180 24jxhOJR+lsJpqIUeb999+R8euDhRHG9eFO7DRu6weatUJ6suupoDTRWtr/4yGqe
181 181 dKxV3qQhNLSnaAzqW/1nA3iUB4k7kCaKZxhdhDbClf9P37qaRW467BLCVO/coL3y
182 182 Vm50dwdrNtKpMBh3ZpbB1uJvgi9mXtyBOMJ3v8RZeDzFiG8HdCtg9RvIt/AIFoHR
183 183 H3S+U79NT6i0KPzLImDfs8T7RlpyuMc4Ufs8ggyg9v3Ae6cN3eQyxcK3w0cbBwsh
184 184 /nQNfsA6uu+9H7NhbehBMhYnpNZyrHzCmzyXkauwRAqoCbGCNykTRwsur9gS41TQ
185 185 M8ssD1jFheOJf3hODnkKU+HKjvMROl1DK7zdmLdNzA1cvtZH/nCC9KPj1z8QC47S
186 186 xx+dTZSx4ONAhwbS/LN3PoKtn8LPjY9NP9uDWI+TWYquS2U+KHDrBDlsgozDbs/O
187 187 jCxcpDzNmXpWQHEtHU7649OXHP7UeNST1mCUCH5qdank0V1iejF6/CfTFU4MfcrG
188 188 YT90qFF93M3v01BbxP+EIY2/9tiIPbrd
189 189 =0YYh
190 190 -----END PGP PUBLIC KEY BLOCK-----
191 191 EOF
192 192
193 193 sudo apt-key add docker-apt-key
194 194
195 195 if [ "$LSB_RELEASE" = "stretch" ]; then
196 196 cat << EOF | sudo tee -a /etc/apt/sources.list
197 197 # Need backports for clang-format-6.0
198 198 deb http://deb.debian.org/debian stretch-backports main
199 199 EOF
200 200 fi
201 201
202 202 if [ "$LSB_RELEASE" = "stretch" -o "$LSB_RELEASE" = "buster" ]; then
203 203 cat << EOF | sudo tee -a /etc/apt/sources.list
204 204 # Sources are useful if we want to compile things locally.
205 205 deb-src http://deb.debian.org/debian $LSB_RELEASE main
206 206 deb-src http://security.debian.org/debian-security $LSB_RELEASE/updates main
207 207 deb-src http://deb.debian.org/debian $LSB_RELEASE-updates main
208 208 deb-src http://deb.debian.org/debian $LSB_RELEASE-backports main
209 209
210 210 deb [arch=amd64] https://download.docker.com/linux/debian $LSB_RELEASE stable
211 211 EOF
212 212
213 213 elif [ "$DISTRO" = "Ubuntu" ]; then
214 214 cat << EOF | sudo tee -a /etc/apt/sources.list
215 215 deb [arch=amd64] https://download.docker.com/linux/ubuntu $LSB_RELEASE stable
216 216 EOF
217 217
218 218 fi
219 219
220 220 sudo apt-get update
221 221
222 222 PACKAGES="\
223 223 awscli \
224 224 btrfs-progs \
225 225 build-essential \
226 226 bzr \
227 227 clang-format-6.0 \
228 228 cvs \
229 229 darcs \
230 230 debhelper \
231 231 devscripts \
232 232 docker-ce \
233 233 dpkg-dev \
234 234 dstat \
235 235 emacs \
236 236 gettext \
237 237 git \
238 238 htop \
239 239 iotop \
240 240 jfsutils \
241 241 libbz2-dev \
242 242 libexpat1-dev \
243 243 libffi-dev \
244 244 libgdbm-dev \
245 245 liblzma-dev \
246 246 libncurses5-dev \
247 247 libnss3-dev \
248 248 libreadline-dev \
249 249 libsqlite3-dev \
250 250 libssl-dev \
251 251 netbase \
252 252 ntfs-3g \
253 253 nvme-cli \
254 254 pyflakes \
255 255 pyflakes3 \
256 256 pylint \
257 257 pylint3 \
258 258 python-all-dev \
259 259 python-dev \
260 260 python-docutils \
261 261 python-fuzzywuzzy \
262 262 python-pygments \
263 263 python-subversion \
264 264 python-vcr \
265 265 python3-boto3 \
266 266 python3-dev \
267 267 python3-docutils \
268 268 python3-fuzzywuzzy \
269 269 python3-pygments \
270 270 python3-vcr \
271 271 python3-venv \
272 272 rsync \
273 273 sqlite3 \
274 274 subversion \
275 275 tcl-dev \
276 276 tk-dev \
277 277 tla \
278 278 unzip \
279 279 uuid-dev \
280 280 vim \
281 281 virtualenv \
282 282 wget \
283 283 xfsprogs \
284 284 zip \
285 285 zlib1g-dev"
286 286
287 287 if [ "LSB_RELEASE" = "stretch" ]; then
288 288 PACKAGES="$PACKAGES linux-perf"
289 289 elif [ "$DISTRO" = "Ubuntu" ]; then
290 290 PACKAGES="$PACKAGES linux-tools-common"
291 291 fi
292 292
293 293 # Monotone only available in older releases.
294 294 if [ "$LSB_RELEASE" = "stretch" -o "$LSB_RELEASE" = "xenial" ]; then
295 295 PACKAGES="$PACKAGES monotone"
296 296 fi
297 297
298 298 sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install --no-install-recommends $PACKAGES
299 299
300 300 # Create clang-format symlink so test harness finds it.
301 301 sudo update-alternatives --install /usr/bin/clang-format clang-format \
302 302 /usr/bin/clang-format-6.0 1000
303 303
304 304 sudo mkdir /hgdev
305 305 # Will be normalized to hg:hg later.
306 306 sudo chown `whoami` /hgdev
307 307
308 308 {install_rust}
309 309
310 310 cp requirements-py2.txt /hgdev/requirements-py2.txt
311 311 cp requirements-py3.txt /hgdev/requirements-py3.txt
312 312
313 313 # Disable the pip version check because it uses the network and can
314 314 # be annoying.
315 315 cat << EOF | sudo tee -a /etc/pip.conf
316 316 [global]
317 317 disable-pip-version-check = True
318 318 EOF
319 319
320 320 {install_pythons}
321 321 {bootstrap_virtualenv}
322 322
323 323 /hgdev/venv-bootstrap/bin/hg clone https://www.mercurial-scm.org/repo/hg /hgdev/src
324 324
325 325 # Mark the repo as non-publishing.
326 326 cat >> /hgdev/src/.hg/hgrc << EOF
327 327 [phases]
328 328 publish = false
329 329 EOF
330 330
331 331 sudo chown -R hg:hg /hgdev
332 332 '''.lstrip()
333 333 .format(
334 334 install_rust=INSTALL_RUST,
335 335 install_pythons=INSTALL_PYTHONS,
336 336 bootstrap_virtualenv=BOOTSTRAP_VIRTUALENV,
337 337 )
338 338 .replace('\r\n', '\n')
339 339 )
340 340
341 341
342 342 # Prepares /hgdev for operations.
343 343 PREPARE_HGDEV = '''
344 344 #!/bin/bash
345 345
346 346 set -e
347 347
348 348 FS=$1
349 349
350 350 ensure_device() {
351 351 if [ -z "${DEVICE}" ]; then
352 352 echo "could not find block device to format"
353 353 exit 1
354 354 fi
355 355 }
356 356
357 357 # Determine device to partition for extra filesystem.
358 358 # If only 1 volume is present, it will be the root volume and
359 359 # should be /dev/nvme0. If multiple volumes are present, the
360 360 # root volume could be nvme0 or nvme1. Use whichever one doesn't have
361 361 # a partition.
362 362 if [ -e /dev/nvme1n1 ]; then
363 363 if [ -e /dev/nvme0n1p1 ]; then
364 364 DEVICE=/dev/nvme1n1
365 365 else
366 366 DEVICE=/dev/nvme0n1
367 367 fi
368 368 else
369 369 DEVICE=
370 370 fi
371 371
372 372 sudo mkdir /hgwork
373 373
374 374 if [ "${FS}" != "default" -a "${FS}" != "tmpfs" ]; then
375 375 ensure_device
376 376 echo "creating ${FS} filesystem on ${DEVICE}"
377 377 fi
378 378
379 379 if [ "${FS}" = "default" ]; then
380 380 :
381 381
382 382 elif [ "${FS}" = "btrfs" ]; then
383 383 sudo mkfs.btrfs ${DEVICE}
384 384 sudo mount ${DEVICE} /hgwork
385 385
386 386 elif [ "${FS}" = "ext3" ]; then
387 387 # lazy_journal_init speeds up filesystem creation at the expense of
388 388 # integrity if things crash. We are an ephemeral instance, so we don't
389 389 # care about integrity.
390 390 sudo mkfs.ext3 -E lazy_journal_init=1 ${DEVICE}
391 391 sudo mount ${DEVICE} /hgwork
392 392
393 393 elif [ "${FS}" = "ext4" ]; then
394 394 sudo mkfs.ext4 -E lazy_journal_init=1 ${DEVICE}
395 395 sudo mount ${DEVICE} /hgwork
396 396
397 397 elif [ "${FS}" = "jfs" ]; then
398 398 sudo mkfs.jfs ${DEVICE}
399 399 sudo mount ${DEVICE} /hgwork
400 400
401 401 elif [ "${FS}" = "tmpfs" ]; then
402 402 echo "creating tmpfs volume in /hgwork"
403 403 sudo mount -t tmpfs -o size=1024M tmpfs /hgwork
404 404
405 405 elif [ "${FS}" = "xfs" ]; then
406 406 sudo mkfs.xfs ${DEVICE}
407 407 sudo mount ${DEVICE} /hgwork
408 408
409 409 else
410 410 echo "unsupported filesystem: ${FS}"
411 411 exit 1
412 412 fi
413 413
414 414 echo "/hgwork ready"
415 415
416 416 sudo chown hg:hg /hgwork
417 417 mkdir /hgwork/tmp
418 418 chown hg:hg /hgwork/tmp
419 419
420 420 rsync -a /hgdev/src /hgwork/
421 421 '''.lstrip().replace(
422 422 '\r\n', '\n'
423 423 )
424 424
425 425
426 426 HG_UPDATE_CLEAN = '''
427 427 set -ex
428 428
429 429 HG=/hgdev/venv-bootstrap/bin/hg
430 430
431 431 cd /hgwork/src
432 432 ${HG} --config extensions.purge= purge --all
433 433 ${HG} update -C $1
434 434 ${HG} log -r .
435 435 '''.lstrip().replace(
436 436 '\r\n', '\n'
437 437 )
438 438
439 439
440 440 def prepare_exec_environment(ssh_client, filesystem='default'):
441 441 """Prepare an EC2 instance to execute things.
442 442
443 443 The AMI has an ``/hgdev`` bootstrapped with various Python installs
444 444 and a clone of the Mercurial repo.
445 445
446 446 In EC2, EBS volumes launched from snapshots have wonky performance behavior.
447 447 Notably, blocks have to be copied on first access, which makes volume
448 448 I/O extremely slow on fresh volumes.
449 449
450 450 Furthermore, we may want to run operations, tests, etc on alternative
451 451 filesystems so we examine behavior on different filesystems.
452 452
453 453 This function is used to facilitate executing operations on alternate
454 454 volumes.
455 455 """
456 456 sftp = ssh_client.open_sftp()
457 457
458 458 with sftp.open('/hgdev/prepare-hgdev', 'wb') as fh:
459 459 fh.write(PREPARE_HGDEV)
460 460 fh.chmod(0o0777)
461 461
462 462 command = 'sudo /hgdev/prepare-hgdev %s' % filesystem
463 463 chan, stdin, stdout = exec_command(ssh_client, command)
464 464 stdin.close()
465 465
466 466 for line in stdout:
467 467 print(line, end='')
468 468
469 469 res = chan.recv_exit_status()
470 470
471 471 if res:
472 472 raise Exception('non-0 exit code updating working directory; %d' % res)
473 473
474 474
475 475 def synchronize_hg(
476 476 source_path: pathlib.Path, ec2_instance, revision: str = None
477 477 ):
478 478 """Synchronize a local Mercurial source path to remote EC2 instance."""
479 479
480 480 with tempfile.TemporaryDirectory() as temp_dir:
481 481 temp_dir = pathlib.Path(temp_dir)
482 482
483 483 ssh_dir = temp_dir / '.ssh'
484 484 ssh_dir.mkdir()
485 485 ssh_dir.chmod(0o0700)
486 486
487 487 public_ip = ec2_instance.public_ip_address
488 488
489 489 ssh_config = ssh_dir / 'config'
490 490
491 491 with ssh_config.open('w', encoding='utf-8') as fh:
492 492 fh.write('Host %s\n' % public_ip)
493 493 fh.write(' User hg\n')
494 494 fh.write(' StrictHostKeyChecking no\n')
495 495 fh.write(' UserKnownHostsFile %s\n' % (ssh_dir / 'known_hosts'))
496 496 fh.write(' IdentityFile %s\n' % ec2_instance.ssh_private_key_path)
497 497
498 498 if not (source_path / '.hg').is_dir():
499 499 raise Exception(
500 500 '%s is not a Mercurial repository; synchronization '
501 501 'not yet supported' % source_path
502 502 )
503 503
504 504 env = dict(os.environ)
505 505 env['HGPLAIN'] = '1'
506 506 env['HGENCODING'] = 'utf-8'
507 507
508 508 hg_bin = source_path / 'hg'
509 509
510 510 res = subprocess.run(
511 511 ['python2.7', str(hg_bin), 'log', '-r', revision, '-T', '{node}'],
512 512 cwd=str(source_path),
513 513 env=env,
514 514 check=True,
515 515 capture_output=True,
516 516 )
517 517
518 518 full_revision = res.stdout.decode('ascii')
519 519
520 520 args = [
521 521 'python2.7',
522 522 str(hg_bin),
523 523 '--config',
524 524 'ui.ssh=ssh -F %s' % ssh_config,
525 525 '--config',
526 526 'ui.remotecmd=/hgdev/venv-bootstrap/bin/hg',
527 527 # Also ensure .hgtags changes are present so auto version
528 528 # calculation works.
529 529 'push',
530 530 '-f',
531 531 '-r',
532 532 full_revision,
533 533 '-r',
534 534 'file(.hgtags)',
535 535 'ssh://%s//hgwork/src' % public_ip,
536 536 ]
537 537
538 538 res = subprocess.run(args, cwd=str(source_path), env=env)
539 539
540 540 # Allow 1 (no-op) to not trigger error.
541 541 if res.returncode not in (0, 1):
542 542 res.check_returncode()
543 543
544 544 # TODO support synchronizing dirty working directory.
545 545
546 546 sftp = ec2_instance.ssh_client.open_sftp()
547 547
548 548 with sftp.open('/hgdev/hgup', 'wb') as fh:
549 549 fh.write(HG_UPDATE_CLEAN)
550 550 fh.chmod(0o0700)
551 551
552 552 chan, stdin, stdout = exec_command(
553 553 ec2_instance.ssh_client, '/hgdev/hgup %s' % full_revision
554 554 )
555 555 stdin.close()
556 556
557 557 for line in stdout:
558 558 print(line, end='')
559 559
560 560 res = chan.recv_exit_status()
561 561
562 562 if res:
563 563 raise Exception(
564 564 'non-0 exit code updating working directory; %d' % res
565 565 )
566 566
567 567
568 568 def run_tests(ssh_client, python_version, test_flags=None):
569 569 """Run tests on a remote Linux machine via an SSH client."""
570 570 test_flags = test_flags or []
571 571
572 572 print('running tests')
573 573
574 574 if python_version == 'system2':
575 575 python = '/usr/bin/python2'
576 576 elif python_version == 'system3':
577 577 python = '/usr/bin/python3'
578 578 elif python_version.startswith('pypy'):
579 579 python = '/hgdev/pyenv/shims/%s' % python_version
580 580 else:
581 581 python = '/hgdev/pyenv/shims/python%s' % python_version
582 582
583 583 test_flags = ' '.join(shlex.quote(a) for a in test_flags)
584 584
585 585 command = (
586 586 '/bin/sh -c "export TMPDIR=/hgwork/tmp; '
587 587 'cd /hgwork/src/tests && %s run-tests.py %s"' % (python, test_flags)
588 588 )
589 589
590 590 chan, stdin, stdout = exec_command(ssh_client, command)
591 591
592 592 stdin.close()
593 593
594 594 for line in stdout:
595 595 print(line, end='')
596 596
597 597 return chan.recv_exit_status()
@@ -1,211 +1,211 b''
1 1 # install-dependencies.ps1 - Install Windows dependencies for building Mercurial
2 2 #
3 3 # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 # This script can be used to bootstrap a Mercurial build environment on
9 9 # Windows.
10 10 #
11 11 # The script makes a lot of assumptions about how things should work.
12 12 # For example, the install location of Python is hardcoded to c:\hgdev\*.
13 13 #
14 14 # The script should be executed from a PowerShell with elevated privileges
15 15 # if you don't want to see a UAC prompt for various installers.
16 16 #
17 17 # The script is tested on Windows 10 and Windows Server 2019 (in EC2).
18 18
19 19 $VS_BUILD_TOOLS_URL = "https://download.visualstudio.microsoft.com/download/pr/a1603c02-8a66-4b83-b821-811e3610a7c4/aa2db8bb39e0cbd23e9940d8951e0bc3/vs_buildtools.exe"
20 20 $VS_BUILD_TOOLS_SHA256 = "911E292B8E6E5F46CBC17003BDCD2D27A70E616E8D5E6E69D5D489A605CAA139"
21 21
22 22 $VC9_PYTHON_URL = "https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28-B59FBF6D907B/VCForPython27.msi"
23 23 $VC9_PYTHON_SHA256 = "070474db76a2e625513a5835df4595df9324d820f9cc97eab2a596dcbc2f5cbf"
24 24
25 25 $PYTHON27_x64_URL = "https://www.python.org/ftp/python/2.7.18/python-2.7.18.amd64.msi"
26 26 $PYTHON27_x64_SHA256 = "b74a3afa1e0bf2a6fc566a7b70d15c9bfabba3756fb077797d16fffa27800c05"
27 27 $PYTHON27_X86_URL = "https://www.python.org/ftp/python/2.7.18/python-2.7.18.msi"
28 28 $PYTHON27_X86_SHA256 = "d901802e90026e9bad76b8a81f8dd7e43c7d7e8269d9281c9e9df7a9c40480a9"
29 29
30 30 $PYTHON37_x86_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9.exe"
31 31 $PYTHON37_x86_SHA256 = "769bb7c74ad1df6d7d74071cc16a984ff6182e4016e11b8949b93db487977220"
32 32 $PYTHON37_X64_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-amd64.exe"
33 33 $PYTHON37_x64_SHA256 = "e69ed52afb5a722e5c56f6c21d594e85c17cb29f12f18bb69751cf1714e0f987"
34 34
35 35 $PYTHON38_x86_URL = "https://www.python.org/ftp/python/3.8.6/python-3.8.6.exe"
36 36 $PYTHON38_x86_SHA256 = "287d5df01ff22ff09e6a487ae018603ee19eade71d462ec703850c96f1d5e8a0"
37 37 $PYTHON38_x64_URL = "https://www.python.org/ftp/python/3.8.6/python-3.8.6-amd64.exe"
38 38 $PYTHON38_x64_SHA256 = "328a257f189cb500606bb26ab0fbdd298ed0e05d8c36540a322a1744f489a0a0"
39 39
40 40 $PYTHON39_x86_URL = "https://www.python.org/ftp/python/3.9.0/python-3.9.0.exe"
41 41 $PYTHON39_x86_SHA256 = "a4c65917f4225d1543959342f0615c813a4e9e7ff1137c4394ff6a5290ac1913"
42 42 $PYTHON39_x64_URL = "https://www.python.org/ftp/python/3.9.0/python-3.9.0-amd64.exe"
43 43 $PYTHON39_x64_SHA256 = "fd2e2c6612d43bb6b213b72fc53f07d73d99059fa72c96e44bde12e7815073ae"
44 44
45 45 # PIP 19.2.3.
46 46 $PIP_URL = "https://github.com/pypa/get-pip/raw/309a56c5fd94bd1134053a541cb4657a4e47e09d/get-pip.py"
47 47 $PIP_SHA256 = "57e3643ff19f018f8a00dfaa6b7e4620e3c1a7a2171fd218425366ec006b3bfe"
48 48
49 49 $VIRTUALENV_URL = "https://files.pythonhosted.org/packages/66/f0/6867af06d2e2f511e4e1d7094ff663acdebc4f15d4a0cb0fed1007395124/virtualenv-16.7.5.tar.gz"
50 50 $VIRTUALENV_SHA256 = "f78d81b62d3147396ac33fc9d77579ddc42cc2a98dd9ea38886f616b33bc7fb2"
51 51
52 52 $INNO_SETUP_URL = "http://files.jrsoftware.org/is/5/innosetup-5.6.1-unicode.exe"
53 53 $INNO_SETUP_SHA256 = "27D49E9BC769E9D1B214C153011978DB90DC01C2ACD1DDCD9ED7B3FE3B96B538"
54 54
55 55 $MINGW_BIN_URL = "https://osdn.net/frs/redir.php?m=constant&f=mingw%2F68260%2Fmingw-get-0.6.3-mingw32-pre-20170905-1-bin.zip"
56 56 $MINGW_BIN_SHA256 = "2AB8EFD7C7D1FC8EAF8B2FA4DA4EEF8F3E47768284C021599BC7435839A046DF"
57 57
58 58 $MERCURIAL_WHEEL_FILENAME = "mercurial-5.1.2-cp27-cp27m-win_amd64.whl"
59 59 $MERCURIAL_WHEEL_URL = "https://files.pythonhosted.org/packages/6d/47/e031e47f7fe9b16e4e3383da47e2b0a7eae6e603996bc67a03ec4fa1b3f4/$MERCURIAL_WHEEL_FILENAME"
60 60 $MERCURIAL_WHEEL_SHA256 = "1d18c7f6ca1456f0f62ee65c9a50c14cbba48ce6e924930cdb10537f5c9eaf5f"
61 61
62 62 $RUSTUP_INIT_URL = "https://static.rust-lang.org/rustup/archive/1.21.1/x86_64-pc-windows-gnu/rustup-init.exe"
63 63 $RUSTUP_INIT_SHA256 = "d17df34ba974b9b19cf5c75883a95475aa22ddc364591d75d174090d55711c72"
64 64
65 65 # Writing progress slows down downloads substantially. So disable it.
66 66 $progressPreference = 'silentlyContinue'
67 67
68 68 function Secure-Download($url, $path, $sha256) {
69 69 if (Test-Path -Path $path) {
70 70 Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash
71 71
72 72 if ($hash.Hash -eq $sha256) {
73 73 Write-Output "SHA256 of $path verified as $sha256"
74 74 return
75 75 }
76 76
77 77 Write-Output "hash mismatch on $path; downloading again"
78 78 }
79 79
80 80 Write-Output "downloading $url to $path"
81 81 Invoke-WebRequest -Uri $url -OutFile $path
82 82 Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash
83 83
84 84 if ($hash.Hash -ne $sha256) {
85 85 Remove-Item -Path $path
86 86 throw "hash mismatch when downloading $url; got $($hash.Hash), expected $sha256"
87 87 }
88 88 }
89 89
90 90 function Invoke-Process($path, $arguments) {
91 91 $p = Start-Process -FilePath $path -ArgumentList $arguments -Wait -PassThru -WindowStyle Hidden
92 92
93 93 if ($p.ExitCode -ne 0) {
94 94 throw "process exited non-0: $($p.ExitCode)"
95 95 }
96 96 }
97 97
98 98 function Install-Python3($name, $installer, $dest, $pip) {
99 99 Write-Output "installing $name"
100 100
101 101 # We hit this when running the script as part of Simple Systems Manager in
102 102 # EC2. The Python 3 installer doesn't seem to like per-user installs
103 103 # when running as the SYSTEM user. So enable global installs if executed in
104 104 # this mode.
105 105 if ($env:USERPROFILE -eq "C:\Windows\system32\config\systemprofile") {
106 106 Write-Output "running with SYSTEM account; installing for all users"
107 107 $allusers = "1"
108 108 }
109 109 else {
110 110 $allusers = "0"
111 111 }
112 112
113 113 Invoke-Process $installer "/quiet TargetDir=${dest} InstallAllUsers=${allusers} AssociateFiles=0 CompileAll=0 PrependPath=0 Include_doc=0 Include_launcher=0 InstallLauncherAllUsers=0 Include_pip=0 Include_test=0"
114 114 Invoke-Process ${dest}\python.exe $pip
115 115 }
116 116
117 117 function Install-Rust($prefix) {
118 118 Write-Output "installing Rust"
119 119 $Env:RUSTUP_HOME = "${prefix}\rustup"
120 120 $Env:CARGO_HOME = "${prefix}\cargo"
121 121
122 122 Invoke-Process "${prefix}\assets\rustup-init.exe" "-y --default-host x86_64-pc-windows-msvc"
123 123 Invoke-Process "${prefix}\cargo\bin\rustup.exe" "target add i686-pc-windows-msvc"
124 124 Invoke-Process "${prefix}\cargo\bin\rustup.exe" "install 1.46.0"
125 125 Invoke-Process "${prefix}\cargo\bin\rustup.exe" "component add clippy"
126 126
127 127 # Install PyOxidizer for packaging.
128 Invoke-Process "${prefix}\cargo\bin\cargo.exe" "install --version 0.9.0 pyoxidizer"
128 Invoke-Process "${prefix}\cargo\bin\cargo.exe" "install --version 0.10.3 pyoxidizer"
129 129 }
130 130
131 131 function Install-Dependencies($prefix) {
132 132 if (!(Test-Path -Path $prefix\assets)) {
133 133 New-Item -Path $prefix\assets -ItemType Directory
134 134 }
135 135
136 136 $pip = "${prefix}\assets\get-pip.py"
137 137
138 138 Secure-Download $VC9_PYTHON_URL ${prefix}\assets\VCForPython27.msi $VC9_PYTHON_SHA256
139 139 Secure-Download $PYTHON27_x86_URL ${prefix}\assets\python27-x86.msi $PYTHON27_x86_SHA256
140 140 Secure-Download $PYTHON27_x64_URL ${prefix}\assets\python27-x64.msi $PYTHON27_x64_SHA256
141 141 Secure-Download $PYTHON37_x86_URL ${prefix}\assets\python37-x86.exe $PYTHON37_x86_SHA256
142 142 Secure-Download $PYTHON37_x64_URL ${prefix}\assets\python37-x64.exe $PYTHON37_x64_SHA256
143 143 Secure-Download $PYTHON38_x86_URL ${prefix}\assets\python38-x86.exe $PYTHON38_x86_SHA256
144 144 Secure-Download $PYTHON38_x64_URL ${prefix}\assets\python38-x64.exe $PYTHON38_x64_SHA256
145 145 Secure-Download $PYTHON39_x86_URL ${prefix}\assets\python39-x86.exe $PYTHON39_x86_SHA256
146 146 Secure-Download $PYTHON39_x64_URL ${prefix}\assets\python39-x64.exe $PYTHON39_x64_SHA256
147 147 Secure-Download $PIP_URL ${pip} $PIP_SHA256
148 148 Secure-Download $VIRTUALENV_URL ${prefix}\assets\virtualenv.tar.gz $VIRTUALENV_SHA256
149 149 Secure-Download $VS_BUILD_TOOLS_URL ${prefix}\assets\vs_buildtools.exe $VS_BUILD_TOOLS_SHA256
150 150 Secure-Download $INNO_SETUP_URL ${prefix}\assets\InnoSetup.exe $INNO_SETUP_SHA256
151 151 Secure-Download $MINGW_BIN_URL ${prefix}\assets\mingw-get-bin.zip $MINGW_BIN_SHA256
152 152 Secure-Download $MERCURIAL_WHEEL_URL ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME} $MERCURIAL_WHEEL_SHA256
153 153 Secure-Download $RUSTUP_INIT_URL ${prefix}\assets\rustup-init.exe $RUSTUP_INIT_SHA256
154 154
155 155 Write-Output "installing Python 2.7 32-bit"
156 156 Invoke-Process msiexec.exe "/i ${prefix}\assets\python27-x86.msi /l* ${prefix}\assets\python27-x86.log /q TARGETDIR=${prefix}\python27-x86 ALLUSERS="
157 157 Invoke-Process ${prefix}\python27-x86\python.exe ${prefix}\assets\get-pip.py
158 158 Invoke-Process ${prefix}\python27-x86\Scripts\pip.exe "install ${prefix}\assets\virtualenv.tar.gz"
159 159
160 160 Write-Output "installing Python 2.7 64-bit"
161 161 Invoke-Process msiexec.exe "/i ${prefix}\assets\python27-x64.msi /l* ${prefix}\assets\python27-x64.log /q TARGETDIR=${prefix}\python27-x64 ALLUSERS="
162 162 Invoke-Process ${prefix}\python27-x64\python.exe ${prefix}\assets\get-pip.py
163 163 Invoke-Process ${prefix}\python27-x64\Scripts\pip.exe "install ${prefix}\assets\virtualenv.tar.gz"
164 164
165 165 Install-Python3 "Python 3.7 32-bit" ${prefix}\assets\python37-x86.exe ${prefix}\python37-x86 ${pip}
166 166 Install-Python3 "Python 3.7 64-bit" ${prefix}\assets\python37-x64.exe ${prefix}\python37-x64 ${pip}
167 167 Install-Python3 "Python 3.8 32-bit" ${prefix}\assets\python38-x86.exe ${prefix}\python38-x86 ${pip}
168 168 Install-Python3 "Python 3.8 64-bit" ${prefix}\assets\python38-x64.exe ${prefix}\python38-x64 ${pip}
169 169 Install-Python3 "Python 3.9 32-bit" ${prefix}\assets\python39-x86.exe ${prefix}\python39-x86 ${pip}
170 170 Install-Python3 "Python 3.9 64-bit" ${prefix}\assets\python39-x64.exe ${prefix}\python39-x64 ${pip}
171 171
172 172 Write-Output "installing Visual Studio 2017 Build Tools and SDKs"
173 173 Invoke-Process ${prefix}\assets\vs_buildtools.exe "--quiet --wait --norestart --nocache --channelUri https://aka.ms/vs/15/release/channel --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Component.Windows10SDK.17763 --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.Windows10SDK --add Microsoft.VisualStudio.Component.VC.140"
174 174
175 175 Install-Rust ${prefix}
176 176
177 177 Write-Output "installing Visual C++ 9.0 for Python 2.7"
178 178 Invoke-Process msiexec.exe "/i ${prefix}\assets\VCForPython27.msi /l* ${prefix}\assets\VCForPython27.log /q"
179 179
180 180 Write-Output "installing Inno Setup"
181 181 Invoke-Process ${prefix}\assets\InnoSetup.exe "/SP- /VERYSILENT /SUPPRESSMSGBOXES"
182 182
183 183 Write-Output "extracting MinGW base archive"
184 184 Expand-Archive -Path ${prefix}\assets\mingw-get-bin.zip -DestinationPath "${prefix}\MinGW" -Force
185 185
186 186 Write-Output "updating MinGW package catalogs"
187 187 Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "update"
188 188
189 189 Write-Output "installing MinGW packages"
190 190 Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "install msys-base msys-coreutils msys-diffutils msys-unzip"
191 191
192 192 # Construct a virtualenv useful for bootstrapping. It conveniently contains a
193 193 # Mercurial install.
194 194 Write-Output "creating bootstrap virtualenv with Mercurial"
195 195 Invoke-Process "$prefix\python27-x64\Scripts\virtualenv.exe" "${prefix}\venv-bootstrap"
196 196 Invoke-Process "${prefix}\venv-bootstrap\Scripts\pip.exe" "install ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME}"
197 197 }
198 198
199 199 function Clone-Mercurial-Repo($prefix, $repo_url, $dest) {
200 200 Write-Output "cloning $repo_url to $dest"
201 201 # TODO Figure out why CA verification isn't working in EC2 and remove
202 202 # --insecure.
203 203 Invoke-Process "${prefix}\venv-bootstrap\Scripts\hg.exe" "clone --insecure $repo_url $dest"
204 204
205 205 # Mark repo as non-publishing by default for convenience.
206 206 Add-Content -Path "$dest\.hg\hgrc" -Value "`n[phases]`npublish = false"
207 207 }
208 208
209 209 $prefix = "c:\hgdev"
210 210 Install-Dependencies $prefix
211 211 Clone-Mercurial-Repo $prefix "https://www.mercurial-scm.org/repo/hg" $prefix\src
General Comments 0
You need to be logged in to leave comments. Login now