Repository navigation
Expand file tree
/
Copy pathsysinfo.func
More file actions
248 lines (216 loc) · 9.44 KB
/
Copy pathsysinfo.func
File metadata and controls
248 lines (216 loc) · 9.44 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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#!/usr/bin/env bash
# Copyright (c) 2021-2026 community-scripts ORG
# License: MIT | https://raw.githubusercontent.com/community-scripts/core/main/LICENSE
# ==============================================================================
# API/SYSTEM AND ORIGIN DETECTION
# ==============================================================================
# Where the script came from and what it runs on. Loaded through api/api.func;
# read once per run.
# ==============================================================================
[[ -n "${_API_SYSINFO_LOADED:-}" ]] && return 0
_API_SYSINFO_LOADED=1
# ------------------------------------------------------------------------------
# detect_repo_source()
#
# - Dynamically detects which GitHub repo the scripts were loaded from
# - Inspects /proc/$$/cmdline and $0 to find the source URL
# - Maps detected repo to one of three canonical values:
# * "ProxmoxVE" — official community-scripts/ProxmoxVE (production)
# * "DevScripts" — official community-scripts/DevScripts (development,
# formerly ProxmoxVED)
# * "external" — any fork or unknown source
# - Additionally sets REPO_SLUG to the real "owner/repo" string
# - Fallback: "ProxmoxVE", the default scripts base
# - Skips detection if REPO_SOURCE is already set (e.g., exported by the host
# into the container environment)
# ------------------------------------------------------------------------------
detect_repo_source() {
# Allow explicit override via environment (also how the container inherits
# the host's attribution instead of re-detecting)
if [[ -n "${REPO_SOURCE:-}" ]]; then
[[ "$REPO_SOURCE" == "ProxmoxVED" ]] && REPO_SOURCE="DevScripts"
if [[ -z "${REPO_SLUG:-}" ]]; then
case "$REPO_SOURCE" in
ProxmoxVE) REPO_SLUG="community-scripts/ProxmoxVE" ;;
DevScripts) REPO_SLUG="community-scripts/DevScripts" ;;
esac
export REPO_SLUG
fi
return 0
fi
local content="" owner_repo=""
# Method 0: COMMUNITY_SCRIPTS_URL, already resolved by build.func. It IS the
# scripts base, so it answers directly instead of being inferred. Necessary,
# not merely better: the bootstrap line now names only the engine, so the
# scraping below read every modern script as "community-scripts/core" and
# attributed all of DevScripts and Incus as external.
if [[ -n "${COMMUNITY_SCRIPTS_URL:-}" ]]; then
owner_repo=$(echo "$COMMUNITY_SCRIPTS_URL" |
grep -oE 'raw\.githubusercontent\.com/[^/]+/[^/]+' |
head -1 | sed 's|raw\.githubusercontent\.com/||') || true
if [[ -z "$owner_repo" ]]; then
owner_repo=$(echo "$COMMUNITY_SCRIPTS_URL" |
grep -oE 'git\.community-scripts\.org/[^/]+/[^/]+' |
head -1 | sed 's|git\.community-scripts\.org/||') || true
fi
fi
# Method 1: Read from /proc/$$/cmdline
# When invoked via: bash -c "$(curl -fsSL https://.../ct/app.sh)"
if [[ -z "$owner_repo" && -r /proc/$$/cmdline ]]; then
content=$(tr '\0' ' ' </proc/$$/cmdline 2>/dev/null) || true
fi
# Method 2: Read from the original script file (bash ct/app.sh)
if [[ -z "$owner_repo" ]] &&
{ [[ -z "$content" ]] || ! echo "$content" | grep -qE 'githubusercontent\.com|community-scripts\.org' 2>/dev/null; }; then
if [[ -f "$0" ]] && [[ "$0" != *bash* ]]; then
content=$(head -10 "$0" 2>/dev/null) || true
fi
fi
# A script run through bash -c carries its own text here, not its URL, and the
# first URL in that text is the engine bootstrap. The license header names the
# repository it was published from.
if [[ -z "$owner_repo" && -n "$content" ]]; then
owner_repo=$(echo "$content" | grep -oE '(raw\.githubusercontent\.com|github\.com)/community-scripts/(ProxmoxVED?|DevScripts)/' | head -1 | sed -E 's#^[^/]+/##; s#/$##') || true
fi
if [[ -z "$owner_repo" && -n "$content" ]]; then
owner_repo=$(echo "$content" | grep -oE 'raw\.githubusercontent\.com/[^/]+/[^/]+' | sed 's|raw\.githubusercontent\.com/||' | grep -vx 'community-scripts/core' | head -1) || true
if [[ -z "$owner_repo" ]]; then
owner_repo=$(echo "$content" | grep -oE 'git\.community-scripts\.org/[^/]+/[^/]+' | head -1 | sed 's|git\.community-scripts\.org/||') || true
fi
fi
case "$owner_repo" in
community-scripts/ProxmoxVE)
REPO_SOURCE="ProxmoxVE"
REPO_SLUG="community-scripts/ProxmoxVE"
;;
community-scripts/DevScripts | community-scripts/ProxmoxVED)
REPO_SOURCE="DevScripts"
REPO_SLUG="community-scripts/DevScripts"
;;
"" | community-scripts/core)
# No script repo identified. ProxmoxVE, matching build.func's default base:
# DevScripts here would file every tool and add-on run from ProxmoxVE as a
# development build.
REPO_SOURCE="ProxmoxVE"
REPO_SLUG="community-scripts/ProxmoxVE"
;;
*)
REPO_SOURCE="external"
REPO_SLUG="$owner_repo"
;;
esac
export REPO_SOURCE REPO_SLUG
}
# Run detection immediately when api.func is sourced
detect_repo_source
# ------------------------------------------------------------------------------
# detect_gpu() - GPU vendor, model, passthrough type
# ------------------------------------------------------------------------------
detect_gpu() {
GPU_VENDOR="unknown"
GPU_MODEL=""
GPU_PASSTHROUGH="unknown"
local gpu_line
gpu_line=$(lspci 2>/dev/null | grep -iE "VGA|3D|Display" | head -1 || true)
if [[ -n "$gpu_line" ]]; then
GPU_MODEL=$(echo "$gpu_line" | sed 's/.*: //' | sed 's/ (rev .*)$//' | cut -c1-64)
if echo "$gpu_line" | grep -qi "Intel"; then
GPU_VENDOR="intel"
GPU_PASSTHROUGH="igpu"
elif echo "$gpu_line" | grep -qi "AMD\|ATI"; then
GPU_VENDOR="amd"
if echo "$gpu_line" | grep -qi "Radeon RX\|Radeon Pro"; then
GPU_PASSTHROUGH="dgpu"
else
GPU_PASSTHROUGH="igpu"
fi
elif echo "$gpu_line" | grep -qi "NVIDIA"; then
GPU_VENDOR="nvidia"
GPU_PASSTHROUGH="dgpu"
fi
fi
export GPU_VENDOR GPU_MODEL GPU_PASSTHROUGH
}
# ------------------------------------------------------------------------------
# detect_cpu() - CPU vendor and model
# ------------------------------------------------------------------------------
detect_cpu() {
CPU_VENDOR="unknown"
CPU_MODEL=""
if [[ -f /proc/cpuinfo ]]; then
local vendor_id
vendor_id=$(grep -m1 "vendor_id" /proc/cpuinfo 2>/dev/null | cut -d: -f2 | tr -d ' ' || true)
case "$vendor_id" in
GenuineIntel) CPU_VENDOR="intel" ;;
AuthenticAMD) CPU_VENDOR="amd" ;;
*)
if grep -qi "CPU implementer" /proc/cpuinfo 2>/dev/null; then
CPU_VENDOR="arm"
fi
;;
esac
CPU_MODEL=$(grep -m1 "model name" /proc/cpuinfo 2>/dev/null | cut -d: -f2 | sed 's/^ *//' | sed 's/(R)//g' | sed 's/(TM)//g' | sed 's/ */ /g' | cut -c1-64 || true)
fi
export CPU_VENDOR CPU_MODEL
}
# ------------------------------------------------------------------------------
# detect_ram() - RAM speed via dmidecode (empty in nested VMs)
# ------------------------------------------------------------------------------
detect_ram() {
RAM_SPEED=""
if command -v dmidecode &>/dev/null; then
RAM_SPEED=$(dmidecode -t memory 2>/dev/null | grep -m1 "Configured Memory Speed:" | grep -oE "[0-9]+" | head -1) || true
if [[ -z "$RAM_SPEED" ]]; then
RAM_SPEED=$(dmidecode -t memory 2>/dev/null | grep -m1 "Speed:" | grep -oE "[0-9]+" | head -1) || true
fi
fi
export RAM_SPEED
}
# ------------------------------------------------------------------------------
# detect_arm() - true when running on arm64 hardware
# ------------------------------------------------------------------------------
detect_arm() {
HAS_ARM="false"
case "$(dpkg --print-architecture 2>/dev/null || uname -m)" in
arm64 | aarch64) HAS_ARM="true" ;;
esac
export HAS_ARM
}
# ------------------------------------------------------------------------------
# telemetry_collect_sysinfo()
#
# - Collects ALL system metadata exactly once (cached via _TM_SYSINFO_DONE)
# - Sets: CPU_VENDOR, CPU_MODEL, GPU_VENDOR, GPU_MODEL, GPU_PASSTHROUGH,
# RAM_SPEED, HAS_ARM, TM_ARCH, TM_PVE_VERSION
# ------------------------------------------------------------------------------
telemetry_collect_sysinfo() {
[[ "${_TM_SYSINFO_DONE:-}" == "true" ]] && return 0
[[ -z "${GPU_VENDOR:-}" ]] && detect_gpu
[[ -z "${CPU_VENDOR:-}" ]] && detect_cpu
[[ -z "${RAM_SPEED+x}" ]] && detect_ram
[[ -z "${HAS_ARM:-}" ]] && detect_arm
[[ -z "${KERNEL_VERSION:-}" ]] && KERNEL_VERSION="$(uname -r 2>/dev/null)"
# One vocabulary: dpkg says amd64/arm64, uname says x86_64/aarch64, so which a
# run reported depended on whether dpkg existed. Normalised to dpkg's spelling,
# which var_arm64, the templates and the release assets already use.
TM_ARCH="$(dpkg --print-architecture 2>/dev/null || uname -m 2>/dev/null || echo unknown)"
case "$TM_ARCH" in
x86_64) TM_ARCH="amd64" ;;
aarch64) TM_ARCH="arm64" ;;
armv7* | armhf) TM_ARCH="armhf" ;;
i386 | i686) TM_ARCH="i386" ;;
esac
# Virtualization platform: pve (Proxmox VE) or incus.
# Containers inherit TELEMETRY_PLATFORM from the host environment.
TM_PLATFORM="${TELEMETRY_PLATFORM:-}"
TM_PVE_VERSION=""
if command -v pveversion &>/dev/null; then
TM_PVE_VERSION=$(pveversion 2>/dev/null | awk -F'[/ ]' '{print $2}') || true
TM_PLATFORM="${TM_PLATFORM:-pve}"
elif command -v incus &>/dev/null; then
TM_PVE_VERSION="incus-$(incus version 2>/dev/null | head -1 | awk '{print $NF}')" || true
TM_PLATFORM="${TM_PLATFORM:-incus}"
fi
_TM_SYSINFO_DONE=true
export TM_ARCH TM_PVE_VERSION TM_PLATFORM KERNEL_VERSION _TM_SYSINFO_DONE
}