213
|
1
|
#!/usr/bin/env sh |
|
2
|
set -eu |
|
3
|
main() { |
|
4
|
need_cmd uname |
|
5
|
need_cmd mktemp |
|
6
|
need_cmd chmod |
|
7
|
need_cmd mkdir |
|
8
|
need_cmd rm |
|
9
|
need_cmd rmdir |
|
10
|
need_cmd tar |
|
11
|
need_cmd zstd |
|
12
|
need_cmd hg |
|
13
|
need_cmd git |
219
|
14
|
# need_cmd clang |
213
|
15
|
need_cmd grep |
|
16
|
need_cmd awk |
|
17
|
need_cmd head |
|
18
|
need_cmd tail |
239
|
19
|
export INFRA_HOST_CONFIG=$(cat /proc/sys/kernel/hostname).sxp |
|
20
|
rm -f $INFRA_HOST_CONFIG |
213
|
21
|
check_mem |
218
|
22
|
local _mem_total="$RETVAL" |
213
|
23
|
check_disk |
|
24
|
check_mod kvm |
254
|
25
|
check_mod btrfs |
213
|
26
|
get_architecture || return 1 |
|
27
|
local _arch="$RETVAL" |
|
28
|
assert_nz "$_arch" "arch" |
251
|
29
|
_write ";;; $INFRA_HOST_CONFIG -*- mode:skel -*-" |
213
|
30
|
_write ":arch \"$_arch\"" |
|
31
|
kernel_version |
|
32
|
local _kernel_version="$RETVAL" |
|
33
|
_write ":kernel \"$_kernel_version\"" |
|
34
|
check_cpus |
|
35
|
local _num_cpus="$RETVAL" |
|
36
|
_write ":cpus $_num_cpus" |
218
|
37
|
_write ":mem $_mem_total" |
213
|
38
|
case "$_arch" in |
|
39
|
*windows*) |
|
40
|
_write ":ext \"exe\"" |
|
41
|
;; |
|
42
|
*) |
|
43
|
_write ":ext nil" |
|
44
|
esac |
254
|
45
|
say $INFRA_HOST_CONFIG |
213
|
46
|
} |
|
47
|
|
|
48
|
say() { |
|
49
|
printf '%s\n' "$1" |
|
50
|
} |
|
51
|
|
219
|
52
|
say_var() { |
|
53
|
say "$1=$(eval echo "\$$1" 2> /dev/null)" |
|
54
|
} |
|
55
|
|
213
|
56
|
_write() { |
239
|
57
|
say "$1" >> $INFRA_HOST_CONFIG |
213
|
58
|
} |
|
59
|
|
|
60
|
err() { |
|
61
|
say "$1" >&2 |
|
62
|
exit 1 |
|
63
|
} |
|
64
|
|
|
65
|
assert_nz() { |
|
66
|
if [ -z "$1" ]; then err "assert_nz $2"; fi |
|
67
|
} |
|
68
|
|
|
69
|
check_cmd() { |
|
70
|
command -v "$1" > /dev/null 2>&1 |
|
71
|
} |
|
72
|
|
|
73
|
need_cmd() { |
|
74
|
if ! check_cmd "$1"; then |
|
75
|
err "need '$1' (command not found)" |
|
76
|
fi |
|
77
|
} |
|
78
|
|
|
79
|
ensure() { |
|
80
|
if ! "$@"; then err "command failed: $*"; fi |
|
81
|
} |
|
82
|
|
|
83
|
check_proc() { |
|
84
|
# Check for /proc by looking for the /proc/self/exe link |
|
85
|
# This is only run on Linux |
|
86
|
if ! test -L /proc/self/exe ; then |
|
87
|
err "fatal: Unable to find /proc/self/exe. Is /proc mounted? Installation cannot proceed without /proc." |
|
88
|
fi |
|
89
|
} |
|
90
|
|
|
91
|
get_bitness() { |
|
92
|
# Architecture detection without dependencies beyond coreutils. |
|
93
|
# ELF files start out "\x7fELF", and the following byte is |
|
94
|
# 0x01 for 32-bit and |
|
95
|
# 0x02 for 64-bit. |
|
96
|
# The printf builtin on some shells like dash only supports octal |
|
97
|
# escape sequences, so we use those. |
|
98
|
local _current_exe_head |
|
99
|
_current_exe_head=$(head -c 5 /proc/self/exe ) |
|
100
|
if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then |
|
101
|
echo 32 |
|
102
|
elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then |
|
103
|
echo 64 |
|
104
|
else |
|
105
|
err "unknown platform bitness" |
|
106
|
fi |
|
107
|
} |
|
108
|
|
|
109
|
is_host_amd64_elf() { |
|
110
|
# ELF e_machine detection without dependencies beyond coreutils. |
|
111
|
# Two-byte field at offset 0x12 indicates the CPU, |
|
112
|
# but we're interested in it being 0x3E to indicate amd64, or not that. |
|
113
|
local _current_exe_machine |
|
114
|
_current_exe_machine=$(head -c 19 /proc/self/exe | tail -c 1) |
|
115
|
[ "$_current_exe_machine" = "$(printf '\076')" ] |
|
116
|
} |
|
117
|
|
|
118
|
get_endianness() { |
|
119
|
local cputype=$1 |
|
120
|
local suffix_eb=$2 |
|
121
|
local suffix_el=$3 |
|
122
|
|
|
123
|
# detect endianness without od/hexdump, like get_bitness() does. |
|
124
|
local _current_exe_endianness |
|
125
|
_current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)" |
|
126
|
if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then |
|
127
|
echo "${cputype}${suffix_el}" |
|
128
|
elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then |
|
129
|
echo "${cputype}${suffix_eb}" |
|
130
|
else |
|
131
|
err "unknown platform endianness" |
|
132
|
fi |
|
133
|
} |
|
134
|
|
|
135
|
get_architecture() { |
|
136
|
local _ostype _cputype _bitness _arch _clibtype |
|
137
|
_ostype="$(uname -s)" |
|
138
|
_cputype="$(uname -m)" |
|
139
|
_clibtype="gnu" |
|
140
|
|
|
141
|
if [ "$_ostype" = Linux ]; then |
|
142
|
if [ "$(uname -o)" = Android ]; then |
|
143
|
_ostype=Android |
|
144
|
fi |
|
145
|
if ldd --version 2>&1 | grep -q 'musl'; then |
|
146
|
_clibtype="musl" |
|
147
|
fi |
|
148
|
fi |
|
149
|
|
|
150
|
if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then |
|
151
|
# Darwin `uname -m` lies |
|
152
|
if sysctl hw.optional.x86_64 | grep -q ': 1'; then |
|
153
|
_cputype=x86_64 |
|
154
|
fi |
|
155
|
fi |
|
156
|
|
|
157
|
if [ "$_ostype" = SunOS ]; then |
|
158
|
# Both Solaris and illumos presently announce as "SunOS" in "uname -s" |
|
159
|
# so use "uname -o" to disambiguate. We use the full path to the |
|
160
|
# system uname in case the user has coreutils uname first in PATH, |
|
161
|
# which has historically sometimes printed the wrong value here. |
|
162
|
if [ "$(/usr/bin/uname -o)" = illumos ]; then |
|
163
|
_ostype=illumos |
|
164
|
fi |
|
165
|
|
|
166
|
# illumos systems have multi-arch userlands, and "uname -m" reports the |
|
167
|
# machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86 |
|
168
|
# systems. Check for the native (widest) instruction set on the |
|
169
|
# running kernel: |
|
170
|
if [ "$_cputype" = i86pc ]; then |
|
171
|
_cputype="$(isainfo -n)" |
|
172
|
fi |
|
173
|
fi |
|
174
|
|
|
175
|
case "$_ostype" in |
|
176
|
|
|
177
|
Android) |
|
178
|
_ostype=linux-android |
|
179
|
;; |
|
180
|
|
|
181
|
Linux) |
|
182
|
check_proc |
|
183
|
_ostype=unknown-linux-$_clibtype |
|
184
|
_bitness=$(get_bitness) |
|
185
|
;; |
|
186
|
|
|
187
|
FreeBSD) |
|
188
|
_ostype=unknown-freebsd |
|
189
|
;; |
|
190
|
|
|
191
|
NetBSD) |
|
192
|
_ostype=unknown-netbsd |
|
193
|
;; |
|
194
|
|
|
195
|
DragonFly) |
|
196
|
_ostype=unknown-dragonfly |
|
197
|
;; |
|
198
|
|
|
199
|
Darwin) |
|
200
|
_ostype=apple-darwin |
|
201
|
;; |
|
202
|
|
|
203
|
illumos) |
|
204
|
_ostype=unknown-illumos |
|
205
|
;; |
|
206
|
|
|
207
|
MINGW* | MSYS* | CYGWIN* | Windows_NT) |
|
208
|
_ostype=pc-windows-gnu |
|
209
|
;; |
|
210
|
|
|
211
|
*) |
|
212
|
err "unrecognized OS type: $_ostype" |
|
213
|
;; |
|
214
|
|
|
215
|
esac |
|
216
|
|
|
217
|
case "$_cputype" in |
|
218
|
|
|
219
|
i386 | i486 | i686 | i786 | x86) |
|
220
|
_cputype=i686 |
|
221
|
;; |
|
222
|
|
|
223
|
xscale | arm) |
|
224
|
_cputype=arm |
|
225
|
if [ "$_ostype" = "linux-android" ]; then |
|
226
|
_ostype=linux-androideabi |
|
227
|
fi |
|
228
|
;; |
|
229
|
|
|
230
|
armv6l) |
|
231
|
_cputype=arm |
|
232
|
if [ "$_ostype" = "linux-android" ]; then |
|
233
|
_ostype=linux-androideabi |
|
234
|
else |
|
235
|
_ostype="${_ostype}eabihf" |
|
236
|
fi |
|
237
|
;; |
|
238
|
|
|
239
|
armv7l | armv8l) |
|
240
|
_cputype=armv7 |
|
241
|
if [ "$_ostype" = "linux-android" ]; then |
|
242
|
_ostype=linux-androideabi |
|
243
|
else |
|
244
|
_ostype="${_ostype}eabihf" |
|
245
|
fi |
|
246
|
;; |
|
247
|
|
|
248
|
aarch64 | arm64) |
|
249
|
_cputype=aarch64 |
|
250
|
;; |
|
251
|
|
|
252
|
x86_64 | x86-64 | x64 | amd64) |
|
253
|
_cputype=x86_64 |
|
254
|
;; |
|
255
|
|
|
256
|
mips) |
|
257
|
_cputype=$(get_endianness mips '' el) |
|
258
|
;; |
|
259
|
|
|
260
|
mips64) |
|
261
|
if [ "$_bitness" -eq 64 ]; then |
|
262
|
# only n64 ABI is supported for now |
|
263
|
_ostype="${_ostype}abi64" |
|
264
|
_cputype=$(get_endianness mips64 '' el) |
|
265
|
fi |
|
266
|
;; |
|
267
|
|
|
268
|
ppc) |
|
269
|
_cputype=powerpc |
|
270
|
;; |
|
271
|
|
|
272
|
ppc64) |
|
273
|
_cputype=powerpc64 |
|
274
|
;; |
|
275
|
|
|
276
|
ppc64le) |
|
277
|
_cputype=powerpc64le |
|
278
|
;; |
|
279
|
|
|
280
|
s390x) |
|
281
|
_cputype=s390x |
|
282
|
;; |
|
283
|
riscv64) |
|
284
|
_cputype=riscv64gc |
|
285
|
;; |
|
286
|
loongarch64) |
|
287
|
_cputype=loongarch64 |
|
288
|
;; |
|
289
|
*) |
|
290
|
err "unknown CPU type: $_cputype" |
|
291
|
|
|
292
|
esac |
|
293
|
|
|
294
|
# Detect 64-bit linux with 32-bit userland |
|
295
|
if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then |
|
296
|
case $_cputype in |
|
297
|
x86_64) |
|
298
|
if [ -n "${CPUTYPE:-}" ]; then |
|
299
|
_cputype="$CPUTYPE" |
|
300
|
else { |
|
301
|
# 32-bit executable for amd64 = x32 |
|
302
|
if is_host_amd64_elf; then { |
|
303
|
echo "This host is running an x32 userland; as it stands, x32 support is poor," 1>&2 |
|
304
|
echo "and there isn't a native toolchain -- you will have to install" 1>&2 |
|
305
|
echo "multiarch compatibility with i686 and/or amd64, then select one" 1>&2 |
|
306
|
echo "by re-running this script with the CPUTYPE environment variable" 1>&2 |
|
307
|
echo "set to i686 or x86_64, respectively." 1>&2 |
|
308
|
exit 1 |
|
309
|
}; else |
|
310
|
_cputype=i686 |
|
311
|
fi |
|
312
|
}; fi |
|
313
|
;; |
|
314
|
mips64) |
|
315
|
_cputype=$(get_endianness mips '' el) |
|
316
|
;; |
|
317
|
powerpc64) |
|
318
|
_cputype=powerpc |
|
319
|
;; |
|
320
|
aarch64) |
|
321
|
_cputype=armv7 |
|
322
|
if [ "$_ostype" = "linux-android" ]; then |
|
323
|
_ostype=linux-androideabi |
|
324
|
else |
|
325
|
_ostype="${_ostype}eabihf" |
|
326
|
fi |
|
327
|
;; |
|
328
|
riscv64gc) |
|
329
|
err "riscv64 with 32-bit userland unsupported" |
|
330
|
;; |
|
331
|
esac |
|
332
|
fi |
|
333
|
|
|
334
|
if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then |
|
335
|
if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then |
|
336
|
# At least one processor does not have NEON. |
|
337
|
_cputype=arm |
|
338
|
fi |
|
339
|
fi |
|
340
|
|
|
341
|
_arch="${_cputype}-${_ostype}" |
|
342
|
|
|
343
|
RETVAL="$_arch" |
|
344
|
} |
|
345
|
|
|
346
|
mem_total () { |
|
347
|
local _mem_total |
|
348
|
_mem_total=$(awk '/MemTotal/ {print $2}' /proc/meminfo) |
|
349
|
RETVAL="$_mem_total" |
|
350
|
} |
|
351
|
|
|
352
|
check_mem () { |
|
353
|
mem_total |
|
354
|
local _mem_total="$RETVAL" |
|
355
|
local _mem_min=8388608 # 8Gb in kB |
|
356
|
if [ "$_mem_total" -lt "$_mem_min" ]; then |
|
357
|
err "not enough memory: $_mem_total < $_mem_min"; |
|
358
|
fi |
|
359
|
} |
|
360
|
|
|
361
|
disk_free () { |
|
362
|
local _disk_free |
217
|
363
|
_disk_free=$(df . | tail -n1 | awk '{print $4}') |
|
364
|
RETVAL="${_disk_free}" |
213
|
365
|
} |
|
366
|
|
|
367
|
check_disk () { |
|
368
|
disk_free |
|
369
|
local _disk_free="$RETVAL" |
217
|
370
|
local _disk_min=33554432 # in bytes |
213
|
371
|
if [ "$_disk_free" -lt "$_disk_min" ]; then |
|
372
|
err "not enough disk space: $_disk_free < $_disk_min" |
|
373
|
fi |
|
374
|
} |
|
375
|
|
|
376
|
kernel_version () { |
|
377
|
local _kernel_version |
|
378
|
_kernel_version=$(uname -r) |
|
379
|
RETVAL="$_kernel_version" |
|
380
|
} |
|
381
|
|
|
382
|
check_mod () { |
|
383
|
if ! lsmod | grep -wq "$1"; then |
|
384
|
err "kernel module $1 isn't loaded" |
|
385
|
fi |
|
386
|
} |
|
387
|
|
|
388
|
num_cpus () { |
|
389
|
local _num_cpus |
|
390
|
_num_cpus=$(grep -c '^processor' /proc/cpuinfo 2>/dev/null) |
|
391
|
RETVAL="$_num_cpus" |
|
392
|
# sysctl -n hw.ncpu # nproc --all |
|
393
|
} |
|
394
|
|
|
395
|
check_cpus () { |
|
396
|
num_cpus |
|
397
|
local _num_cpus="$RETVAL" |
|
398
|
local _min_cpus=8 |
|
399
|
if [ "$_num_cpus" -lt "$_min_cpus" ]; then |
|
400
|
err "not enough cpu threads ($_num_cpus < $_min_cpus)" |
|
401
|
fi |
|
402
|
} |
|
403
|
|
219
|
404
|
print_env () { |
|
405
|
say_var STASH |
|
406
|
say_var STORE |
|
407
|
say_var DIST |
|
408
|
say_var PACKY_URL |
|
409
|
say_var VC_URL |
|
410
|
say_var INSTALL_PREFIX |
|
411
|
say_var CC |
|
412
|
say_var AR |
|
413
|
say_var HG |
|
414
|
say_var GIT |
|
415
|
say_var LISP |
|
416
|
say_var RUST |
|
417
|
say_var LD |
|
418
|
say_var SHELL |
|
419
|
say_var DEV |
|
420
|
say_var DEV_HOME |
|
421
|
say_var ID |
|
422
|
say_var WORKER |
|
423
|
say_var WORKER_ID |
|
424
|
say_var WORKER_HOME |
|
425
|
say_var CARGO_HOME |
|
426
|
say_var RUSTUP_HOME |
|
427
|
} |
|
428
|
|
213
|
429
|
main "$@" || exit 1 |