mirror of
https://github.com/wekan/wekan.git
synced 2026-11-05 01:20:07 -05:00
Shell scripts on macOS: no /proc, so command lines and memory are asked another way.
macOS and the BSDs have no /proc. - releases/db-conformance.sh decided whether a container's run was still going from /proc/<pid>/cmdline. On a Mac every live run looked dead, so a second conformance run removed the first one's containers and networks. The command line comes from ps -o command= where there is no /proc (tests/dbConformanceStaleContainers.test.cjs passes on macOS now). - start-wekan.sh and releases/ferretdb/start-wekan.sh sized the Node.js and FerretDB heaps from /proc/meminfo, so on a Mac they assumed 2 GiB whatever the machine had. They ask sysctl hw.memsize (macOS) or hw.physmem (BSD) there, as build.sh already did. - releases/debug-speed-watch.sh shows the load average from sysctl vm.loadavg where there is no /proc/loadavg. tests/macosShellPortability.test.cjs fails on a /proc memory, load or command-line read without such a fallback (the Docker entrypoint, which runs only on Linux, excepted). releases/nextcloud-pack.sh is listed in tests/buildScriptParity.test.cjs as run by nextcloud.yml. Thanks to xet7 !
This commit is contained in:
1 parent
0ed8fb20f2
commit
1f9ada5599
6 files changed
+31
-4
No files matched your search
@@ -286,10 +286,20 @@ DB_HOST_PORT_BASE="${WEKAN_CONFORMANCE_DB_PORT:-35432}"
|
||||
# its queries ("connection refused"), and both of its results were lost.
|
||||
OWNER_LABEL_KEY="wekan.conformance.pid"
|
||||
OWNER_LABEL="$OWNER_LABEL_KEY=$$"
|
||||
# The command line comes from /proc on Linux; macOS and the BSDs have no /proc,
|
||||
# where every live run looked dead and a second run removed its containers.
|
||||
# ps -o command= gives the same line there.
|
||||
command_line_of() {
|
||||
if [ -r "/proc/$1/cmdline" ]; then
|
||||
tr '\0' ' ' < "/proc/$1/cmdline" 2>/dev/null
|
||||
else
|
||||
ps -o command= -p "$1" 2>/dev/null
|
||||
fi
|
||||
}
|
||||
run_still_going() {
|
||||
local pid="$1"
|
||||
[ -n "$pid" ] && [ "$pid" != "$$" ] && kill -0 "$pid" 2>/dev/null &&
|
||||
tr '\0' ' ' < "/proc/$pid/cmdline" 2>/dev/null | grep -q 'db-conformance\.sh'
|
||||
command_line_of "$pid" | grep -q 'db-conformance\.sh'
|
||||
}
|
||||
left_behind() {
|
||||
local kind="$1" id owner
|
||||
|
||||
@@ -13,7 +13,8 @@ WATCH_PATH="${DEBUGSPEED_WATCH_PATH:-.}"
|
||||
printf 'timestamp\tload\tmem_available_kb\tdisk_available_kb\n'
|
||||
while :; do
|
||||
timestamp="$(date --iso-8601=seconds 2>/dev/null || date)"
|
||||
load="$(cut -d' ' -f1-3 /proc/loadavg 2>/dev/null || echo unavailable)"
|
||||
# /proc is Linux; macOS and the BSDs answer sysctl vm.loadavg as "{ 1.2 1.1 1.0 }".
|
||||
load="$(cut -d' ' -f1-3 /proc/loadavg 2>/dev/null || sysctl -n vm.loadavg 2>/dev/null | tr -d '{}' | awk '{print $1, $2, $3}' || echo unavailable)"
|
||||
mem_available="$(awk '/^MemAvailable:/{print $2}' /proc/meminfo 2>/dev/null || true)"
|
||||
disk_available="$(df -Pk "$WATCH_PATH" 2>/dev/null | awk 'NR==2{print $4}')"
|
||||
printf '%s\t%s\t%s\t%s\n' \
|
||||
|
||||
@@ -46,7 +46,10 @@ NODE="$DIR/node"
|
||||
[ -n "$NODE" ] || { echo "ERROR: no bundled ./node and no node found on PATH" >&2; exit 1; }
|
||||
|
||||
# Bound the two bundled runtimes relative to available RAM; explicit overrides win.
|
||||
_memory_mb=$(awk '/^MemTotal:/{print int($2/1024)}' /proc/meminfo 2>/dev/null || echo 2048)
|
||||
_memory_mb=$(awk '/^MemTotal:/{print int($2/1024)}' /proc/meminfo 2>/dev/null)
|
||||
# macOS and the BSDs have no /proc; hw.memsize (macOS) and hw.physmem (BSD) are bytes.
|
||||
[ -n "$_memory_mb" ] || _memory_mb=$(( $(sysctl -n hw.memsize 2>/dev/null || sysctl -n hw.physmem 2>/dev/null || echo 0) / 1048576 ))
|
||||
[ "$_memory_mb" -gt 0 ] 2>/dev/null || _memory_mb=2048
|
||||
for _f in /sys/fs/cgroup/memory.max /sys/fs/cgroup/memory/memory.limit_in_bytes; do [ -r "$_f" ] || continue; _b=$(cat "$_f" 2>/dev/null || true); case "$_b" in ''|max|*[!0-9]*) continue;; esac; _m=$((_b/1048576)); [ "$_m" -gt 0 ] && [ "$_m" -lt "$_memory_mb" ] && _memory_mb=$_m; break; done
|
||||
_heap_mb=$((_memory_mb*3/5)); [ "$_heap_mb" -gt 4096 ] && _heap_mb=4096
|
||||
# A 32-bit Node has only a 4 GiB virtual address space for the executable,
|
||||
|
||||
+4
-1
@@ -927,7 +927,10 @@
|
||||
#-------------------- OPTIONAL SETTINGS END ----------------------
|
||||
#bash -c "ulimit -s 65500; exec node --stack-size=65500 --max-old-space-size=8192 main.js"
|
||||
if [ -z "${NODE_OPTIONS:-}" ]; then
|
||||
_memory_mb=$(awk '/^MemTotal:/{print int($2/1024)}' /proc/meminfo 2>/dev/null || echo 2048)
|
||||
_memory_mb=$(awk '/^MemTotal:/{print int($2/1024)}' /proc/meminfo 2>/dev/null)
|
||||
# macOS and the BSDs have no /proc; hw.memsize (macOS) and hw.physmem (BSD) are bytes.
|
||||
[ -n "$_memory_mb" ] || _memory_mb=$(( $(sysctl -n hw.memsize 2>/dev/null || sysctl -n hw.physmem 2>/dev/null || echo 0) / 1048576 ))
|
||||
[ "$_memory_mb" -gt 0 ] 2>/dev/null || _memory_mb=2048
|
||||
for _f in /sys/fs/cgroup/memory.max /sys/fs/cgroup/memory/memory.limit_in_bytes; do [ -r "$_f" ] || continue; _b=$(cat "$_f" 2>/dev/null || true); case "$_b" in ''|max|*[!0-9]*) continue;; esac; _m=$((_b/1048576)); [ "$_m" -gt 0 ] && [ "$_m" -lt "$_memory_mb" ] && _memory_mb=$_m; break; done
|
||||
_heap_mb=$((_memory_mb*3/5)); [ "$_heap_mb" -gt 4096 ] && _heap_mb=4096
|
||||
export NODE_OPTIONS="--max-old-space-size=$_heap_mb"
|
||||
|
||||
@@ -430,6 +430,7 @@ test('every script in releases/ is reachable from BOTH menus', () => {
|
||||
// container for musl, Termux-like Android builders, the Bun builders).
|
||||
SKIP['musl/build-bundle.sh'] = 'musl bundle build run by musl.yml inside Alpine';
|
||||
SKIP['android/build-bundle.sh'] = 'Android bundle build run by android.yml';
|
||||
SKIP['nextcloud-pack.sh'] = 'Nextcloud ExApp packer run by nextcloud.yml before signing; tested by tests/nextcloudRelease.test.py';
|
||||
SKIP['single-file/bun/build-and-check.sh'] = 'Bun single-file build run by bun-single-file.yml';
|
||||
SKIP['single-file/bun/build.mjs'] = 'Bun single-file builder run by bun-single-file.yml and releases/bun/build-target.sh';
|
||||
SKIP['single-file/bun/launcher.mjs'] = 'runs INSIDE the Bun single-file executable, embedded by single-file/bun/build.mjs';
|
||||
|
||||
@@ -75,6 +75,15 @@ test('sha256sum, nproc and ip only with a macOS fallback', () => {
|
||||
assert.deepStrictEqual(offenders(c => /^\s*ip (address|addr|a)\b/m.test(c) && !/ifconfig/.test(c)), []);
|
||||
});
|
||||
|
||||
test('/proc memory, load and command lines only with a macOS fallback', () => {
|
||||
// macOS and the BSDs have no /proc. db-conformance.sh read a run's command
|
||||
// line there, so on a Mac every live run looked dead and a second run
|
||||
// removed its containers. The Docker entrypoint only ever runs on Linux.
|
||||
const linuxOnly = new Set(['releases/ferretdb/wekan-entrypoint.sh']);
|
||||
assert.deepStrictEqual(offenders(c => /\/proc\/(meminfo|loadavg|\$[A-Za-z_{][^/]*\/cmdline)/.test(c)
|
||||
&& !/sysctl -n|ps -o command=/.test(c)).filter(rel => !linuxOnly.has(rel)), []);
|
||||
});
|
||||
|
||||
test('no GNU-only ln -T or stat -c', () => {
|
||||
assert.deepStrictEqual(offenders(c => /\bln -[a-zA-Z]*T\b|\bstat -c\b|\bstat --/.test(c)), []);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user