ss
This commit is contained in:
0
d2ypp2/scripts/linux/install_all.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/install_all.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/install_business.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/install_business.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/install_hub.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/install_hub.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/install_stack.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/install_stack.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/launch_browser.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/launch_browser.sh
Normal file → Executable file
157
d2ypp2/scripts/linux/lib/common.sh
Normal file → Executable file
157
d2ypp2/scripts/linux/lib/common.sh
Normal file → Executable file
@@ -487,10 +487,15 @@ redroid_container_matches_host_support() {
|
||||
|
||||
resolve_neko_instance_count() {
|
||||
local requested="${NEKO_INSTANCE_COUNT:-2}"
|
||||
local cpu count
|
||||
local cpu count max_count
|
||||
max_count="${NEKO_MAX_INSTANCE_COUNT:-64}"
|
||||
case "$max_count" in
|
||||
''|*[!0-9]*) max_count=64 ;;
|
||||
esac
|
||||
[ "$max_count" -lt 2 ] && max_count=2
|
||||
[ "$max_count" -gt 64 ] && max_count=64
|
||||
cpu="$(nproc 2>/dev/null || echo 4)"
|
||||
case "$requested" in
|
||||
1|2|3) count="$requested" ;;
|
||||
auto|"")
|
||||
if [ "$cpu" -le 4 ]; then
|
||||
count=2
|
||||
@@ -498,15 +503,16 @@ resolve_neko_instance_count() {
|
||||
count=3
|
||||
fi
|
||||
;;
|
||||
*[!0-9]*) count=2 ;;
|
||||
*)
|
||||
count=2
|
||||
count="$requested"
|
||||
;;
|
||||
esac
|
||||
if [ "$count" -lt 1 ]; then
|
||||
count=1
|
||||
if [ "$count" -lt 2 ]; then
|
||||
count=2
|
||||
fi
|
||||
if [ "$count" -gt 3 ]; then
|
||||
count=3
|
||||
if [ "$count" -gt "$max_count" ]; then
|
||||
count="$max_count"
|
||||
fi
|
||||
printf '%s' "$count"
|
||||
}
|
||||
@@ -514,7 +520,7 @@ resolve_neko_instance_count() {
|
||||
resolve_neko_service_names() {
|
||||
local count name
|
||||
count="$(resolve_neko_instance_count)"
|
||||
for name in 1 2 3; do
|
||||
for name in $(seq 1 "$count"); do
|
||||
[ "$name" -le "$count" ] || break
|
||||
printf 'neko%s\n' "$name"
|
||||
done
|
||||
@@ -524,13 +530,85 @@ resolve_neko_instances_csv() {
|
||||
resolve_neko_service_names | paste -sd, -
|
||||
}
|
||||
|
||||
seed_neko_tampermonkey_profile() {
|
||||
local target="${1:-}" donor="${2:-}" rel src dst
|
||||
[ -n "$target" ] || return 0
|
||||
[ -n "$donor" ] || donor="$(resolve_neko_profile_dir_for_instance 1)"
|
||||
[ "$target" = "$donor" ] && return 0
|
||||
[ -d "$donor/Default" ] || return 0
|
||||
mkdir -p "$target/Default"
|
||||
for rel in \
|
||||
"Extensions/dhdgffkkebhmkfjojejmpbldmpobfkfo" \
|
||||
"Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo" \
|
||||
"Managed Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo"; do
|
||||
src="$donor/Default/$rel"
|
||||
dst="$target/Default/$rel"
|
||||
[ -e "$src" ] || continue
|
||||
[ ! -e "$dst" ] || continue
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
cp -a "$src" "$dst" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
|
||||
resolve_neko_http_port_for_instance() {
|
||||
case "${1:-1}" in
|
||||
1) printf '%s' "${NEKO_HTTP_PORT_1:-${NEKO_HTTP_PORT:-9200}}" ;;
|
||||
2) printf '%s' "${NEKO_HTTP_PORT_2:-9201}" ;;
|
||||
3) printf '%s' "${NEKO_HTTP_PORT_3:-9202}" ;;
|
||||
*) printf '%s' "${NEKO_HTTP_PORT_1:-${NEKO_HTTP_PORT:-9200}}" ;;
|
||||
local idx="${1:-1}" value base
|
||||
eval "value=\"\${NEKO_HTTP_PORT_${idx}:-}\""
|
||||
if [ -n "$value" ]; then
|
||||
printf '%s' "$value"
|
||||
return 0
|
||||
fi
|
||||
base="${NEKO_HTTP_PORT:-9200}"
|
||||
printf '%s' $((base + idx - 1))
|
||||
}
|
||||
|
||||
resolve_neko_tcpmux_for_instance() {
|
||||
local idx="${1:-1}" value base
|
||||
eval "value=\"\${NEKO_WEBRTC_TCPMUX_${idx}:-}\""
|
||||
if [ -n "$value" ]; then
|
||||
printf '%s' "$value"
|
||||
return 0
|
||||
fi
|
||||
base="${NEKO_WEBRTC_TCPMUX:-52300}"
|
||||
printf '%s' $((base + idx - 1))
|
||||
}
|
||||
|
||||
resolve_neko_udpmux_for_instance() {
|
||||
local idx="${1:-1}" value base
|
||||
eval "value=\"\${NEKO_WEBRTC_UDPMUX_${idx}:-}\""
|
||||
if [ -n "$value" ]; then
|
||||
printf '%s' "$value"
|
||||
return 0
|
||||
fi
|
||||
base="${NEKO_WEBRTC_UDPMUX:-52300}"
|
||||
printf '%s' $((base + idx - 1))
|
||||
}
|
||||
|
||||
resolve_neko_udp_range_for_instance() {
|
||||
local idx="${1:-1}" value start
|
||||
eval "value=\"\${NEKO_WEBRTC_UDP_RANGE_${idx}:-}\""
|
||||
if [ -n "$value" ]; then
|
||||
printf '%s' "$value"
|
||||
return 0
|
||||
fi
|
||||
if [ "$idx" -eq 1 ] && [ -n "${NEKO_WEBRTC_UDP_RANGE:-}" ]; then
|
||||
printf '%s' "$NEKO_WEBRTC_UDP_RANGE"
|
||||
return 0
|
||||
fi
|
||||
case "$idx" in
|
||||
2) start=52101 ;;
|
||||
3) start=52201 ;;
|
||||
*) start=$((52400 + ((idx - 4) * 100))) ;;
|
||||
esac
|
||||
[ "$idx" -eq 1 ] && start=52000
|
||||
printf '%s-%s' "$start" "$((start + 99))"
|
||||
}
|
||||
|
||||
render_neko_compose_file() {
|
||||
local count out
|
||||
count="$(resolve_neko_instance_count)"
|
||||
out="$ROOT_DIR/services/neko/docker-compose.generated.yml"
|
||||
python3 "$ROOT_DIR/tools/render_neko_compose.py" --count "$count" --output "$out"
|
||||
printf '%s' "$out"
|
||||
}
|
||||
|
||||
remove_legacy_neko_container() {
|
||||
@@ -1137,16 +1215,12 @@ install_neko_browser() {
|
||||
log "Neko skipped: docker compose unavailable"
|
||||
return 0
|
||||
fi
|
||||
log "Installing Neko browser desktops (Docker, 3 instances)"
|
||||
log "Installing Neko browser desktops (Docker, dynamic instances)"
|
||||
set -a
|
||||
[ -f "$STACK_ENV" ] && . "$STACK_ENV"
|
||||
set +a
|
||||
local neko_dir="$ROOT_DIR/services/neko"
|
||||
local idx neko_prof
|
||||
for idx in 1 2 3; do
|
||||
neko_prof="$(resolve_neko_profile_dir_for_instance "$idx")"
|
||||
prune_neko_profile "$neko_prof"
|
||||
done
|
||||
local idx neko_prof instance_count port mux udp range compose_file
|
||||
instance_count="$(resolve_neko_instance_count)"
|
||||
export NEKO_HTTP_PORT="${NEKO_HTTP_PORT:-9200}"
|
||||
export NEKO_HTTP_PORT_1="${NEKO_HTTP_PORT_1:-$NEKO_HTTP_PORT}"
|
||||
export NEKO_HTTP_PORT_2="${NEKO_HTTP_PORT_2:-9201}"
|
||||
@@ -1190,17 +1264,22 @@ install_neko_browser() {
|
||||
export NEKO_WEBRTC_NAT1TO1
|
||||
fi
|
||||
export NEKO_PLUGINS_ENABLED="${NEKO_PLUGINS_ENABLED:-true}"
|
||||
for port in "$NEKO_HTTP_PORT_1" "$NEKO_HTTP_PORT_2" "$NEKO_HTTP_PORT_3" "$NEKO_WEBRTC_TCPMUX_1" "$NEKO_WEBRTC_TCPMUX_2" "$NEKO_WEBRTC_TCPMUX_3"; do
|
||||
for idx in $(seq 1 "$instance_count"); do
|
||||
neko_prof="$(resolve_neko_profile_dir_for_instance "$idx")"
|
||||
seed_neko_tampermonkey_profile "$neko_prof" "$(resolve_neko_profile_dir_for_instance 1)"
|
||||
prune_neko_profile "$neko_prof"
|
||||
port="$(resolve_neko_http_port_for_instance "$idx")"
|
||||
mux="$(resolve_neko_tcpmux_for_instance "$idx")"
|
||||
udp="$(resolve_neko_udpmux_for_instance "$idx")"
|
||||
range="$(resolve_neko_udp_range_for_instance "$idx")"
|
||||
allow_tcp_port_if_firewall_active "$port"
|
||||
done
|
||||
for port in "$NEKO_WEBRTC_UDPMUX_1" "$NEKO_WEBRTC_UDPMUX_2" "$NEKO_WEBRTC_UDPMUX_3"; do
|
||||
allow_udp_port_if_firewall_active "$port"
|
||||
done
|
||||
for port_range in "$NEKO_WEBRTC_UDP_RANGE_1" "$NEKO_WEBRTC_UDP_RANGE_2" "$NEKO_WEBRTC_UDP_RANGE_3"; do
|
||||
allow_udp_range_if_firewall_active "$port_range"
|
||||
allow_tcp_port_if_firewall_active "$mux"
|
||||
allow_udp_port_if_firewall_active "$udp"
|
||||
allow_udp_range_if_firewall_active "$range"
|
||||
done
|
||||
remove_legacy_neko_container
|
||||
compose_in_service_dir "$neko_dir/docker-compose.yml" up -d
|
||||
compose_file="$(render_neko_compose_file)"
|
||||
compose_in_service_dir "$compose_file" up -d
|
||||
}
|
||||
|
||||
install_redroid() {
|
||||
@@ -1945,11 +2024,33 @@ ExecStart=$caddy_bin run --config /opt/live/generated/Caddyfile --adapter caddyf
|
||||
Restart=on-failure
|
||||
RestartSec=4
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
|
||||
chmod +x "$ROOT_DIR/scripts/linux/live_edge_watch.sh" 2>/dev/null || true
|
||||
cat >/etc/systemd/system/live-edge-watch.service <<UNIT
|
||||
[Unit]
|
||||
Description=Live edge proxy watchdog
|
||||
After=network-online.target live-console.service live-edge.service
|
||||
Wants=network-online.target live-edge.service
|
||||
Requires=live-console.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Environment=LIVE_STACK_ROOT=$ROOT_DIR
|
||||
Environment=LIVE_STACK_ENV=$STACK_ENV
|
||||
ExecStart=/bin/bash $ROOT_DIR/scripts/linux/live_edge_watch.sh
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
UNIT
|
||||
systemctl daemon-reload
|
||||
systemctl enable --now live-edge.service
|
||||
systemctl enable --now live-edge-watch.service
|
||||
log "Edge proxy live-edge.service enabled (http://${HOSTNAME_ALIAS}.local)"
|
||||
}
|
||||
|
||||
|
||||
53
d2ypp2/scripts/linux/live_edge_watch.sh
Executable file
53
d2ypp2/scripts/linux/live_edge_watch.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
# Keep the port-80 live.local edge proxy available after network/service drift.
|
||||
set -Eeuo pipefail
|
||||
|
||||
ROOT_DIR="${LIVE_STACK_ROOT:-/opt/live/d2ypp}"
|
||||
STACK_ENV="${LIVE_STACK_ENV:-$ROOT_DIR/config/system-stack.env}"
|
||||
if [ -f "$STACK_ENV" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
. "$STACK_ENV" || true
|
||||
fi
|
||||
|
||||
INTERVAL="${LIVE_EDGE_WATCH_INTERVAL:-15}"
|
||||
PORT="${PORT:-8001}"
|
||||
|
||||
log() {
|
||||
printf '[live-edge-watch] %s\n' "$*"
|
||||
}
|
||||
|
||||
positive_int() {
|
||||
case "${1:-}" in
|
||||
''|*[!0-9]*) return 1 ;;
|
||||
*) [ "$1" -gt 0 ] ;;
|
||||
esac
|
||||
}
|
||||
|
||||
positive_int "$INTERVAL" || INTERVAL=15
|
||||
|
||||
while true; do
|
||||
if [ "${ENABLE_LIVE_EDGE_PROXY:-1}" != "1" ]; then
|
||||
sleep "$INTERVAL"
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! systemctl is-active --quiet live-console.service 2>/dev/null; then
|
||||
log "live-console.service inactive; starting"
|
||||
systemctl start live-console.service >/dev/null 2>&1 || true
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
if ! systemctl is-active --quiet live-edge.service 2>/dev/null; then
|
||||
log "live-edge.service inactive; starting"
|
||||
systemctl start live-edge.service >/dev/null 2>&1 || true
|
||||
sleep "$INTERVAL"
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! curl -fsS -m 4 "http://127.0.0.1/health" >/dev/null 2>&1; then
|
||||
log "port 80 health failed; restarting live-edge.service for upstream :$PORT"
|
||||
systemctl restart live-edge.service >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
sleep "$INTERVAL"
|
||||
done
|
||||
8
d2ypp2/scripts/linux/neko_ip_watch.sh
Normal file → Executable file
8
d2ypp2/scripts/linux/neko_ip_watch.sh
Normal file → Executable file
@@ -31,10 +31,8 @@ normalize_interval() {
|
||||
|
||||
running_neko_nat1to1_values() {
|
||||
local name value
|
||||
for name in live-neko-1 live-neko-2 live-neko-3; do
|
||||
if ! docker ps --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
||||
continue
|
||||
fi
|
||||
docker ps --format '{{.Names}}' 2>/dev/null | grep -E '^live-neko-[0-9]+$' | sort -V | while read -r name; do
|
||||
[ -n "$name" ] || continue
|
||||
value="$(
|
||||
docker inspect "$name" --format '{{range .Config.Env}}{{println .}}{{end}}' 2>/dev/null |
|
||||
awk -F= '/^NEKO_WEBRTC_NAT1TO1=/{print $2; exit}'
|
||||
@@ -51,7 +49,7 @@ maybe_refresh_neko_for_ip_change() {
|
||||
if [ "${ENABLE_NEKO:-1}" != "1" ] || ! have docker; then
|
||||
return 0
|
||||
fi
|
||||
if ! docker ps --format '{{.Names}}' 2>/dev/null | grep -Eq '^live-neko-[123]$'; then
|
||||
if ! docker ps --format '{{.Names}}' 2>/dev/null | grep -Eq '^live-neko-[0-9]+$'; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
||||
0
d2ypp2/scripts/linux/probe_live_access.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/probe_live_access.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/refresh_live_console_unit.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/refresh_live_console_unit.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/reinstall_live_edge.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/reinstall_live_edge.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/run_kmscube.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/run_kmscube.sh
Normal file → Executable file
207
d2ypp2/scripts/linux/service_ctl.sh
Normal file → Executable file
207
d2ypp2/scripts/linux/service_ctl.sh
Normal file → Executable file
@@ -290,20 +290,50 @@ resolve_neko_profile_dir() {
|
||||
|
||||
resolve_neko_profile_dir_for_instance() {
|
||||
local idx="${1:-1}"
|
||||
local base
|
||||
local base override
|
||||
base="${NEKO_PROFILE_HOST_DIR:-$(resolve_neko_profile_dir)}"
|
||||
eval "override=\"\${NEKO_PROFILE_HOST_DIR_${idx}:-}\""
|
||||
if [ -n "$override" ]; then
|
||||
printf '%s' "$override"
|
||||
return 0
|
||||
fi
|
||||
case "$idx" in
|
||||
1) printf '%s' "$base" ;;
|
||||
*) printf '%s-%s' "$base" "$idx" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
seed_neko_tampermonkey_profile() {
|
||||
local target="${1:-}" donor="${2:-}" rel src dst
|
||||
[ -n "$target" ] || return 0
|
||||
[ -n "$donor" ] || donor="$(resolve_neko_profile_dir_for_instance 1)"
|
||||
[ "$target" = "$donor" ] && return 0
|
||||
[ -d "$donor/Default" ] || return 0
|
||||
mkdir -p "$target/Default"
|
||||
for rel in \
|
||||
"Extensions/dhdgffkkebhmkfjojejmpbldmpobfkfo" \
|
||||
"Local Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo" \
|
||||
"Managed Extension Settings/dhdgffkkebhmkfjojejmpbldmpobfkfo"; do
|
||||
src="$donor/Default/$rel"
|
||||
dst="$target/Default/$rel"
|
||||
[ -e "$src" ] || continue
|
||||
[ ! -e "$dst" ] || continue
|
||||
mkdir -p "$(dirname "$dst")"
|
||||
cp -a "$src" "$dst" 2>/dev/null || true
|
||||
done
|
||||
}
|
||||
|
||||
resolve_neko_instance_count() {
|
||||
local requested="${NEKO_INSTANCE_COUNT:-2}"
|
||||
local cpu count
|
||||
local cpu count max_count
|
||||
max_count="${NEKO_MAX_INSTANCE_COUNT:-64}"
|
||||
case "$max_count" in
|
||||
''|*[!0-9]*) max_count=64 ;;
|
||||
esac
|
||||
[ "$max_count" -lt 2 ] && max_count=2
|
||||
[ "$max_count" -gt 64 ] && max_count=64
|
||||
cpu="$(nproc 2>/dev/null || echo 4)"
|
||||
case "$requested" in
|
||||
1|2|3) count="$requested" ;;
|
||||
auto|"")
|
||||
if [ "$cpu" -le 4 ]; then
|
||||
count=2
|
||||
@@ -311,19 +341,81 @@ resolve_neko_instance_count() {
|
||||
count=3
|
||||
fi
|
||||
;;
|
||||
*[!0-9]*) count=2 ;;
|
||||
*)
|
||||
count=2
|
||||
count="$requested"
|
||||
;;
|
||||
esac
|
||||
if [ "$count" -lt 1 ]; then
|
||||
count=1
|
||||
if [ "$count" -lt 2 ]; then
|
||||
count=2
|
||||
fi
|
||||
if [ "$count" -gt 3 ]; then
|
||||
count=3
|
||||
if [ "$count" -gt "$max_count" ]; then
|
||||
count="$max_count"
|
||||
fi
|
||||
printf '%s' "$count"
|
||||
}
|
||||
|
||||
resolve_neko_http_port_for_instance() {
|
||||
local idx="${1:-1}" value base
|
||||
eval "value=\"\${NEKO_HTTP_PORT_${idx}:-}\""
|
||||
if [ -n "$value" ]; then
|
||||
printf '%s' "$value"
|
||||
return 0
|
||||
fi
|
||||
base="${NEKO_HTTP_PORT:-9200}"
|
||||
printf '%s' $((base + idx - 1))
|
||||
}
|
||||
|
||||
resolve_neko_tcpmux_for_instance() {
|
||||
local idx="${1:-1}" value base
|
||||
eval "value=\"\${NEKO_WEBRTC_TCPMUX_${idx}:-}\""
|
||||
if [ -n "$value" ]; then
|
||||
printf '%s' "$value"
|
||||
return 0
|
||||
fi
|
||||
base="${NEKO_WEBRTC_TCPMUX:-52300}"
|
||||
printf '%s' $((base + idx - 1))
|
||||
}
|
||||
|
||||
resolve_neko_udpmux_for_instance() {
|
||||
local idx="${1:-1}" value base
|
||||
eval "value=\"\${NEKO_WEBRTC_UDPMUX_${idx}:-}\""
|
||||
if [ -n "$value" ]; then
|
||||
printf '%s' "$value"
|
||||
return 0
|
||||
fi
|
||||
base="${NEKO_WEBRTC_UDPMUX:-52300}"
|
||||
printf '%s' $((base + idx - 1))
|
||||
}
|
||||
|
||||
resolve_neko_udp_range_for_instance() {
|
||||
local idx="${1:-1}" value start
|
||||
eval "value=\"\${NEKO_WEBRTC_UDP_RANGE_${idx}:-}\""
|
||||
if [ -n "$value" ]; then
|
||||
printf '%s' "$value"
|
||||
return 0
|
||||
fi
|
||||
if [ "$idx" -eq 1 ] && [ -n "${NEKO_WEBRTC_UDP_RANGE:-}" ]; then
|
||||
printf '%s' "$NEKO_WEBRTC_UDP_RANGE"
|
||||
return 0
|
||||
fi
|
||||
case "$idx" in
|
||||
2) start=52101 ;;
|
||||
3) start=52201 ;;
|
||||
*) start=$((52400 + ((idx - 4) * 100))) ;;
|
||||
esac
|
||||
[ "$idx" -eq 1 ] && start=52000
|
||||
printf '%s-%s' "$start" "$((start + 99))"
|
||||
}
|
||||
|
||||
render_neko_compose_file() {
|
||||
local count out
|
||||
count="$(resolve_neko_instance_count)"
|
||||
out="$ROOT_DIR/services/neko/docker-compose.generated.yml"
|
||||
python3 "$ROOT_DIR/tools/render_neko_compose.py" --count "$count" --output "$out"
|
||||
printf '%s' "$out"
|
||||
}
|
||||
|
||||
remove_legacy_neko_container() {
|
||||
if have docker && docker ps -a --format '{{.Names}}' 2>/dev/null | grep -qx 'live-neko-chromium'; then
|
||||
docker stop live-neko-chromium >/dev/null 2>&1 || true
|
||||
@@ -884,20 +976,18 @@ service_neko_status() {
|
||||
fi
|
||||
kv available 1
|
||||
local state
|
||||
local running_count=0 total_count=0 states="" name instance_count
|
||||
local running_count=0 total_count=0 states="" name instance_count idx ports="" profiles=""
|
||||
instance_count="$(resolve_neko_instance_count)"
|
||||
total_count="$instance_count"
|
||||
for name in live-neko-1 live-neko-2 live-neko-3; do
|
||||
case "$name" in
|
||||
live-neko-1) [ "$instance_count" -ge 1 ] || continue ;;
|
||||
live-neko-2) [ "$instance_count" -ge 2 ] || continue ;;
|
||||
live-neko-3) [ "$instance_count" -ge 3 ] || continue ;;
|
||||
esac
|
||||
for idx in $(seq 1 "$instance_count"); do
|
||||
name="live-neko-$idx"
|
||||
state="$(docker_container_status "$name" || true)"
|
||||
if echo "$state" | grep -qi running; then
|
||||
running_count=$((running_count + 1))
|
||||
fi
|
||||
states="${states}${name}:${state:-missing};"
|
||||
ports="${ports}$(resolve_neko_http_port_for_instance "$idx"),"
|
||||
profiles="${profiles}$(resolve_neko_profile_dir_for_instance "$idx"),"
|
||||
done
|
||||
if [ "$running_count" -eq 0 ]; then
|
||||
state="$(docker_container_status live-neko-chromium || true)"
|
||||
@@ -915,7 +1005,7 @@ service_neko_status() {
|
||||
if ! neko_nat1to1_is_usable "${NEKO_WEBRTC_NAT1TO1:-}"; then
|
||||
NEKO_WEBRTC_NAT1TO1="$(detect_preferred_lan_ip || true)"
|
||||
fi
|
||||
kv detail "image=$(resolve_neko_image); supervisor_conf=$(resolve_neko_supervisor_conf); start_url=${NEKO_START_URL}; nat1to1=${NEKO_WEBRTC_NAT1TO1:-unset}; instances=${running_count}/${total_count}; ports=${NEKO_HTTP_PORT_1},${NEKO_HTTP_PORT_2},${NEKO_HTTP_PORT_3}; profiles=$(resolve_neko_profile_dir_for_instance 1),$(resolve_neko_profile_dir_for_instance 2),$(resolve_neko_profile_dir_for_instance 3); screen=${NEKO_DESKTOP_SCREEN}; shm=${NEKO_SHM_SIZE}; fps=${NEKO_MAX_FPS}; bitrate=${NEKO_VIDEO_BITRATE}; render=${NEKO_BROWSER_RENDER_MODE}; udp_ranges=${NEKO_WEBRTC_UDP_RANGE_1},${NEKO_WEBRTC_UDP_RANGE_2},${NEKO_WEBRTC_UDP_RANGE_3}; tcpmux=${NEKO_WEBRTC_TCPMUX_1},${NEKO_WEBRTC_TCPMUX_2},${NEKO_WEBRTC_TCPMUX_3}; udpmux=${NEKO_WEBRTC_UDPMUX_1},${NEKO_WEBRTC_UDPMUX_2},${NEKO_WEBRTC_UDPMUX_3}; containers=${states}"
|
||||
kv detail "image=$(resolve_neko_image); supervisor_conf=$(resolve_neko_supervisor_conf); start_url=${NEKO_START_URL}; nat1to1=${NEKO_WEBRTC_NAT1TO1:-unset}; instances=${running_count}/${total_count}; ports=${ports%,}; profiles=${profiles%,}; screen=${NEKO_DESKTOP_SCREEN}; shm=${NEKO_SHM_SIZE}; fps=${NEKO_MAX_FPS}; bitrate=${NEKO_VIDEO_BITRATE}; render=${NEKO_BROWSER_RENDER_MODE}; containers=${states}"
|
||||
}
|
||||
|
||||
service_neko_start() {
|
||||
@@ -923,77 +1013,32 @@ service_neko_start() {
|
||||
kv message "请先在 config/system-stack.env 设置 ENABLE_NEKO=1"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f "$NEKO_COMPOSE" ]; then
|
||||
kv message "Neko compose missing"
|
||||
if [ ! -f "$ROOT_DIR/tools/render_neko_compose.py" ]; then
|
||||
kv message "Neko compose renderer missing"
|
||||
return 0
|
||||
fi
|
||||
local prof
|
||||
local prof idx port mux udp range compose_file service_names=""
|
||||
local instance_count
|
||||
local service_names="" extra_service_names="" idx_name
|
||||
instance_count="$(resolve_neko_instance_count)"
|
||||
for idx_name in 1 2 3; do
|
||||
case "$idx_name" in
|
||||
1)
|
||||
if [ "$instance_count" -ge 1 ]; then
|
||||
service_names="${service_names} neko1"
|
||||
else
|
||||
extra_service_names="${extra_service_names} neko1"
|
||||
fi
|
||||
;;
|
||||
2)
|
||||
if [ "$instance_count" -ge 2 ]; then
|
||||
service_names="${service_names} neko2"
|
||||
else
|
||||
extra_service_names="${extra_service_names} neko2"
|
||||
fi
|
||||
;;
|
||||
3)
|
||||
if [ "$instance_count" -ge 3 ]; then
|
||||
service_names="${service_names} neko3"
|
||||
else
|
||||
extra_service_names="${extra_service_names} neko3"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
for idx in 1 2 3; do
|
||||
[ "$idx" -le "$instance_count" ] || break
|
||||
prof="$(resolve_neko_profile_dir_for_instance "$idx")"
|
||||
prune_neko_profile "$prof"
|
||||
done
|
||||
export_neko_env
|
||||
for port in "$NEKO_HTTP_PORT_1" "$NEKO_HTTP_PORT_2" "$NEKO_HTTP_PORT_3" "$NEKO_WEBRTC_TCPMUX_1" "$NEKO_WEBRTC_TCPMUX_2" "$NEKO_WEBRTC_TCPMUX_3"; do
|
||||
case "$port" in
|
||||
"$NEKO_HTTP_PORT_1"|"$NEKO_WEBRTC_TCPMUX_1") [ "$instance_count" -ge 1 ] || continue ;;
|
||||
"$NEKO_HTTP_PORT_2"|"$NEKO_WEBRTC_TCPMUX_2") [ "$instance_count" -ge 2 ] || continue ;;
|
||||
"$NEKO_HTTP_PORT_3"|"$NEKO_WEBRTC_TCPMUX_3") [ "$instance_count" -ge 3 ] || continue ;;
|
||||
esac
|
||||
for idx in $(seq 1 "$instance_count"); do
|
||||
prof="$(resolve_neko_profile_dir_for_instance "$idx")"
|
||||
seed_neko_tampermonkey_profile "$prof" "$(resolve_neko_profile_dir_for_instance 1)"
|
||||
prune_neko_profile "$prof"
|
||||
port="$(resolve_neko_http_port_for_instance "$idx")"
|
||||
mux="$(resolve_neko_tcpmux_for_instance "$idx")"
|
||||
udp="$(resolve_neko_udpmux_for_instance "$idx")"
|
||||
range="$(resolve_neko_udp_range_for_instance "$idx")"
|
||||
allow_tcp_port_if_firewall_active "$port"
|
||||
done
|
||||
for port in "$NEKO_WEBRTC_UDPMUX_1" "$NEKO_WEBRTC_UDPMUX_2" "$NEKO_WEBRTC_UDPMUX_3"; do
|
||||
case "$port" in
|
||||
"$NEKO_WEBRTC_UDPMUX_1") [ "$instance_count" -ge 1 ] || continue ;;
|
||||
"$NEKO_WEBRTC_UDPMUX_2") [ "$instance_count" -ge 2 ] || continue ;;
|
||||
"$NEKO_WEBRTC_UDPMUX_3") [ "$instance_count" -ge 3 ] || continue ;;
|
||||
esac
|
||||
allow_udp_port_if_firewall_active "$port"
|
||||
done
|
||||
for port_range in "$NEKO_WEBRTC_UDP_RANGE_1" "$NEKO_WEBRTC_UDP_RANGE_2" "$NEKO_WEBRTC_UDP_RANGE_3"; do
|
||||
case "$port_range" in
|
||||
"$NEKO_WEBRTC_UDP_RANGE_1") [ "$instance_count" -ge 1 ] || continue ;;
|
||||
"$NEKO_WEBRTC_UDP_RANGE_2") [ "$instance_count" -ge 2 ] || continue ;;
|
||||
"$NEKO_WEBRTC_UDP_RANGE_3") [ "$instance_count" -ge 3 ] || continue ;;
|
||||
esac
|
||||
allow_udp_range_if_firewall_active "$port_range"
|
||||
allow_tcp_port_if_firewall_active "$mux"
|
||||
allow_udp_port_if_firewall_active "$udp"
|
||||
allow_udp_range_if_firewall_active "$range"
|
||||
service_names="${service_names} neko${idx}"
|
||||
done
|
||||
remove_legacy_neko_container
|
||||
# 只启动实际需要的实例,避免多余的 Chrome/Xorg 进程继续吃 CPU
|
||||
compose_file="$(render_neko_compose_file)"
|
||||
# shellcheck disable=SC2086
|
||||
compose_in_service_dir "$NEKO_COMPOSE" up -d $service_names
|
||||
if [ -n "${extra_service_names# }" ]; then
|
||||
# shellcheck disable=SC2086
|
||||
compose_in_service_dir "$NEKO_COMPOSE" stop $extra_service_names >/dev/null 2>&1 || true
|
||||
fi
|
||||
compose_in_service_dir "$compose_file" up -d $service_names
|
||||
kv message "Neko stack started (${instance_count} browser instances)"
|
||||
}
|
||||
|
||||
@@ -1049,12 +1094,14 @@ export_neko_env() {
|
||||
}
|
||||
|
||||
service_neko_stop() {
|
||||
if [ ! -f "$NEKO_COMPOSE" ]; then
|
||||
if [ ! -f "$ROOT_DIR/tools/render_neko_compose.py" ]; then
|
||||
kv message "Neko compose missing"
|
||||
return 0
|
||||
fi
|
||||
local compose_file
|
||||
export_neko_env
|
||||
compose_in_service_dir "$NEKO_COMPOSE" down
|
||||
compose_file="$(render_neko_compose_file)"
|
||||
compose_in_service_dir "$compose_file" down --remove-orphans
|
||||
kv message "Neko stack stopped"
|
||||
}
|
||||
|
||||
|
||||
3
d2ypp2/scripts/linux/uninstall_stack.sh
Normal file → Executable file
3
d2ypp2/scripts/linux/uninstall_stack.sh
Normal file → Executable file
@@ -9,7 +9,7 @@ ensure_root "$@"
|
||||
load_env
|
||||
|
||||
log "Stopping systemd services"
|
||||
for svc in live-edge.service live-console.service live-neko-ip-watch.service live-webtty.service live-android-panel.service live-pulseaudio.service live-kmscube.service live-redroid-host.service netdata cockpit.socket shellcrash.service avahi-daemon; do
|
||||
for svc in live-edge-watch.service live-edge.service live-console.service live-neko-ip-watch.service live-webtty.service live-android-panel.service live-pulseaudio.service live-kmscube.service live-redroid-host.service netdata cockpit.socket shellcrash.service avahi-daemon; do
|
||||
systemctl stop "$svc" >/dev/null 2>&1 || true
|
||||
systemctl disable "$svc" >/dev/null 2>&1 || true
|
||||
done
|
||||
@@ -41,6 +41,7 @@ fi
|
||||
|
||||
log "Removing systemd unit files"
|
||||
rm -f /etc/systemd/system/live-edge.service
|
||||
rm -f /etc/systemd/system/live-edge-watch.service
|
||||
rm -f /etc/systemd/system/live-console.service
|
||||
rm -f /etc/systemd/system/live-neko-ip-watch.service
|
||||
rm -f /etc/systemd/system/live-webtty.service
|
||||
|
||||
0
d2ypp2/scripts/linux/upgrade_ffmpeg_newer.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/upgrade_ffmpeg_newer.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/upgrade_live_console.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/upgrade_live_console.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/webtty_shell.sh
Normal file → Executable file
0
d2ypp2/scripts/linux/webtty_shell.sh
Normal file → Executable file
Reference in New Issue
Block a user