changelog shortlog graph tags branches changeset files revisions annotate raw help

Mercurial > infra / check.sh

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