s
This commit is contained in:
@@ -97,7 +97,7 @@ NEKO_WEBRTC_UDPMUX_3=52302
|
|||||||
NEKO_WEBRTC_NAT1TO1=
|
NEKO_WEBRTC_NAT1TO1=
|
||||||
NEKO_PLUGINS_ENABLED=true
|
NEKO_PLUGINS_ENABLED=true
|
||||||
|
|
||||||
# Redroid Android 13
|
# Redroid Android 13(需要 binderfs 或 /dev/binder*;安装脚本会在支持的内核上自动准备)
|
||||||
ENABLE_REDROID=1
|
ENABLE_REDROID=1
|
||||||
REDROID_DEFAULT_PORT=5555
|
REDROID_DEFAULT_PORT=5555
|
||||||
REDROID_PORT_STEP=1
|
REDROID_PORT_STEP=1
|
||||||
|
|||||||
0
d2ypp2/doctor.sh
Normal file → Executable file
0
d2ypp2/doctor.sh
Normal file → Executable file
0
d2ypp2/install-all.sh
Normal file → Executable file
0
d2ypp2/install-all.sh
Normal file → Executable file
0
d2ypp2/install-business.sh
Normal file → Executable file
0
d2ypp2/install-business.sh
Normal file → Executable file
0
d2ypp2/install-core.sh
Normal file → Executable file
0
d2ypp2/install-core.sh
Normal file → Executable file
0
d2ypp2/install-hub.sh
Normal file → Executable file
0
d2ypp2/install-hub.sh
Normal file → Executable file
0
d2ypp2/install-live.sh
Normal file → Executable file
0
d2ypp2/install-live.sh
Normal file → Executable file
11
d2ypp2/install-oneclick.sh
Normal file → Executable file
11
d2ypp2/install-oneclick.sh
Normal file → Executable file
@@ -34,9 +34,14 @@ esac
|
|||||||
log "ROOT_DIR=${ROOT_DIR}"
|
log "ROOT_DIR=${ROOT_DIR}"
|
||||||
log "架构=${ARCH} 系统=${PRETTY_NAME:-$ID}"
|
log "架构=${ARCH} 系统=${PRETTY_NAME:-$ID}"
|
||||||
|
|
||||||
if [ ! -x "${ROOT_DIR}/install-all.sh" ]; then
|
INSTALL_ALL="${ROOT_DIR}/install-all.sh"
|
||||||
log "缺少可执行的 install-all.sh"
|
if [ ! -f "${INSTALL_ALL}" ]; then
|
||||||
|
log "缺少 install-all.sh"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec bash "${ROOT_DIR}/install-all.sh" "$@"
|
if [ ! -x "${INSTALL_ALL}" ]; then
|
||||||
|
log "install-all.sh 未设置执行位,改用 bash 直接执行"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec bash "${INSTALL_ALL}" "$@"
|
||||||
|
|||||||
0
d2ypp2/install.sh
Normal file → Executable file
0
d2ypp2/install.sh
Normal file → Executable file
0
d2ypp2/probe-live.sh
Normal file → Executable file
0
d2ypp2/probe-live.sh
Normal file → Executable file
@@ -370,6 +370,121 @@ resolve_neko_profile_dir_for_instance() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redroid_binderfs_ready() {
|
||||||
|
[ -e /dev/binderfs/binder-control ]
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_legacy_binder_devices_ready() {
|
||||||
|
[ -e /dev/binder ] && [ -e /dev/hwbinder ] && [ -e /dev/vndbinder ]
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_binder_mode() {
|
||||||
|
if redroid_binderfs_ready; then
|
||||||
|
printf '%s\n' binderfs
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if redroid_legacy_binder_devices_ready; then
|
||||||
|
printf '%s\n' legacy
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_binder_is_provisionable() {
|
||||||
|
redroid_binder_mode >/dev/null 2>&1 && return 0
|
||||||
|
grep -qw binder /proc/filesystems 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_support_detail() {
|
||||||
|
if redroid_binderfs_ready; then
|
||||||
|
printf '%s' "binderfs mounted"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if redroid_legacy_binder_devices_ready; then
|
||||||
|
printf '%s' "legacy binder devices available"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if grep -qw binder /proc/filesystems 2>/dev/null; then
|
||||||
|
printf '%s' "binder filesystem supported but not mounted"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
printf '%s' "binder kernel support unavailable"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_redroid_host_support() {
|
||||||
|
if redroid_binder_mode >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if have modprobe; then
|
||||||
|
modprobe binder_linux devices=binder,hwbinder,vndbinder >/dev/null 2>&1 || \
|
||||||
|
modprobe binder_linux >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
if redroid_binder_mode >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if grep -qw binder /proc/filesystems 2>/dev/null; then
|
||||||
|
mkdir -p /dev/binderfs
|
||||||
|
if have mountpoint; then
|
||||||
|
if ! mountpoint -q /dev/binderfs 2>/dev/null; then
|
||||||
|
mount -t binder binder /dev/binderfs >/dev/null 2>&1 || \
|
||||||
|
mount -t binderfs binderfs /dev/binderfs >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
elif ! grep -qE '[[:space:]]/dev/binderfs[[:space:]]' /proc/mounts 2>/dev/null; then
|
||||||
|
mount -t binder binder /dev/binderfs >/dev/null 2>&1 || \
|
||||||
|
mount -t binderfs binderfs /dev/binderfs >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
redroid_binder_mode >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
install_redroid_host_service() {
|
||||||
|
mkdir -p /etc/modules-load.d /etc/modprobe.d
|
||||||
|
cat >/etc/modules-load.d/live-redroid.conf <<EOF
|
||||||
|
binder_linux
|
||||||
|
EOF
|
||||||
|
cat >/etc/modprobe.d/live-redroid.conf <<EOF
|
||||||
|
options binder_linux devices=binder,hwbinder,vndbinder
|
||||||
|
EOF
|
||||||
|
cat >/etc/systemd/system/live-redroid-host.service <<'UNIT'
|
||||||
|
[Unit]
|
||||||
|
Description=Live Redroid binder host preparation
|
||||||
|
After=systemd-modules-load.service local-fs.target
|
||||||
|
Wants=systemd-modules-load.service
|
||||||
|
Before=docker.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
ExecStart=/bin/bash -lc 'modprobe binder_linux devices=binder,hwbinder,vndbinder >/dev/null 2>&1 || modprobe binder_linux >/dev/null 2>&1 || true; mkdir -p /dev/binderfs; if command -v mountpoint >/dev/null 2>&1; then mountpoint -q /dev/binderfs || mount -t binder binder /dev/binderfs >/dev/null 2>&1 || mount -t binderfs binderfs /dev/binderfs >/dev/null 2>&1; else grep -qE "[[:space:]]/dev/binderfs[[:space:]]" /proc/mounts || mount -t binder binder /dev/binderfs >/dev/null 2>&1 || mount -t binderfs binderfs /dev/binderfs >/dev/null 2>&1; fi; test -e /dev/binderfs/binder-control || { test -e /dev/binder && test -e /dev/hwbinder && test -e /dev/vndbinder; }'
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
UNIT
|
||||||
|
systemctl daemon-reload
|
||||||
|
if systemctl enable --now live-redroid-host.service >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
log "WARN: live-redroid-host.service failed; Redroid will require preconfigured binder devices"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_container_matches_host_support() {
|
||||||
|
local name="$1"
|
||||||
|
case "$(redroid_binder_mode 2>/dev/null || true)" in
|
||||||
|
binderfs)
|
||||||
|
docker inspect -f '{{range .Mounts}}{{println .Destination}}{{end}}' "$name" 2>/dev/null | grep -qx '/dev/binderfs'
|
||||||
|
;;
|
||||||
|
legacy)
|
||||||
|
docker inspect -f '{{range .HostConfig.Devices}}{{println .PathOnHost}}{{end}}' "$name" 2>/dev/null | grep -qx '/dev/binder' && \
|
||||||
|
docker inspect -f '{{range .HostConfig.Devices}}{{println .PathOnHost}}{{end}}' "$name" 2>/dev/null | grep -qx '/dev/hwbinder' && \
|
||||||
|
docker inspect -f '{{range .HostConfig.Devices}}{{println .PathOnHost}}{{end}}' "$name" 2>/dev/null | grep -qx '/dev/vndbinder'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
resolve_neko_instance_count() {
|
resolve_neko_instance_count() {
|
||||||
local requested="${NEKO_INSTANCE_COUNT:-2}"
|
local requested="${NEKO_INSTANCE_COUNT:-2}"
|
||||||
local cpu count
|
local cpu count
|
||||||
@@ -568,8 +683,18 @@ install_docker_stack() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
log "Installing Docker"
|
log "Installing Docker"
|
||||||
apt_install docker.io docker-compose docker-compose-plugin
|
if ! apt_install docker.io docker-compose docker-compose-plugin; then
|
||||||
|
log "docker-compose-plugin package unavailable; retrying without it"
|
||||||
|
apt_install docker.io docker-compose || apt_install docker.io
|
||||||
|
fi
|
||||||
systemctl enable --now docker
|
systemctl enable --now docker
|
||||||
|
if ! docker compose version >/dev/null 2>&1; then
|
||||||
|
log "Docker installed without Compose v2 package; trying Compose v2 binary"
|
||||||
|
install_docker_compose_plugin_binary || true
|
||||||
|
fi
|
||||||
|
if ! docker compose version >/dev/null 2>&1 && have docker-compose; then
|
||||||
|
log "WARN: falling back to docker-compose v1; some stacks may need docker-compose-plugin"
|
||||||
|
fi
|
||||||
usermod -aG docker live || true
|
usermod -aG docker live || true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -761,27 +886,46 @@ configure_mdns() {
|
|||||||
log "Configuring hostname and mDNS"
|
log "Configuring hostname and mDNS"
|
||||||
hostnamectl set-hostname "$HOSTNAME_ALIAS"
|
hostnamectl set-hostname "$HOSTNAME_ALIAS"
|
||||||
|
|
||||||
local mdns_interfaces
|
local mdns_interfaces preferred_lan_ip
|
||||||
mdns_interfaces="$(detect_mdns_interfaces)"
|
mdns_interfaces="$(detect_mdns_interfaces)"
|
||||||
|
preferred_lan_ip="$(detect_preferred_lan_ip || true)"
|
||||||
|
|
||||||
python3 - <<PY
|
python3 - <<PY
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import re
|
import re
|
||||||
|
|
||||||
hosts = Path("/etc/hosts")
|
hosts = Path("/etc/hosts")
|
||||||
hosts_text = hosts.read_text(encoding="utf-8")
|
host_alias = "${HOSTNAME_ALIAS}"
|
||||||
if f"127.0.1.1\t${HOSTNAME_ALIAS}" not in hosts_text and f"127.0.1.1 ${HOSTNAME_ALIAS}" not in hosts_text:
|
preferred_lan_ip = "${preferred_lan_ip}".strip()
|
||||||
lines = []
|
host_lines = hosts.read_text(encoding="utf-8").splitlines()
|
||||||
replaced = False
|
next_host_lines = []
|
||||||
for raw in hosts_text.splitlines():
|
loopback_written = False
|
||||||
if raw.startswith("127.0.1.1"):
|
lan_written = False
|
||||||
lines.append(f"127.0.1.1\t${HOSTNAME_ALIAS}")
|
|
||||||
replaced = True
|
for raw in host_lines:
|
||||||
else:
|
stripped = raw.strip()
|
||||||
lines.append(raw)
|
if not stripped or stripped.startswith("#"):
|
||||||
if not replaced:
|
next_host_lines.append(raw)
|
||||||
lines.append(f"127.0.1.1\t${HOSTNAME_ALIAS}")
|
continue
|
||||||
hosts.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
parts = raw.split()
|
||||||
|
names = parts[1:]
|
||||||
|
if parts[0] == "127.0.1.1":
|
||||||
|
next_host_lines.append(f"127.0.1.1\t{host_alias}")
|
||||||
|
loopback_written = True
|
||||||
|
continue
|
||||||
|
if f"{host_alias}.local" in names:
|
||||||
|
if preferred_lan_ip and not lan_written:
|
||||||
|
next_host_lines.append(f"{preferred_lan_ip}\t{host_alias}.local")
|
||||||
|
lan_written = True
|
||||||
|
continue
|
||||||
|
next_host_lines.append(raw)
|
||||||
|
|
||||||
|
if not loopback_written:
|
||||||
|
next_host_lines.append(f"127.0.1.1\t{host_alias}")
|
||||||
|
if preferred_lan_ip and not lan_written:
|
||||||
|
next_host_lines.append(f"{preferred_lan_ip}\t{host_alias}.local")
|
||||||
|
|
||||||
|
hosts.write_text("\n".join(next_host_lines) + "\n", encoding="utf-8")
|
||||||
|
|
||||||
path = Path("/etc/avahi/avahi-daemon.conf")
|
path = Path("/etc/avahi/avahi-daemon.conf")
|
||||||
raw_lines = path.read_text(encoding="utf-8").splitlines()
|
raw_lines = path.read_text(encoding="utf-8").splitlines()
|
||||||
@@ -909,7 +1053,11 @@ install_browser_stack() {
|
|||||||
apt_install "$chrome_deb" || dpkg -i "$chrome_deb" || apt-get -f install -y || true
|
apt_install "$chrome_deb" || dpkg -i "$chrome_deb" || apt-get -f install -y || true
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
if have google-chrome || have google-chrome-stable; then
|
||||||
|
log "Google Chrome is available; skipping Chromium install on x86"
|
||||||
|
else
|
||||||
apt_install chromium || apt_install chromium-browser || true
|
apt_install chromium || apt_install chromium-browser || true
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
apt_install chromium || apt_install chromium-browser || true
|
apt_install chromium || apt_install chromium-browser || true
|
||||||
@@ -1024,17 +1172,35 @@ install_redroid() {
|
|||||||
esac
|
esac
|
||||||
name="${REDROID_INSTANCE_PREFIX}-1"
|
name="${REDROID_INSTANCE_PREFIX}-1"
|
||||||
data_dir="${REDROID_DATA_PREFIX}-${name}"
|
data_dir="${REDROID_DATA_PREFIX}-${name}"
|
||||||
|
install_redroid_host_service || true
|
||||||
|
if ! ensure_redroid_host_support; then
|
||||||
|
log "Redroid skipped: $(redroid_support_detail)"
|
||||||
|
if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
||||||
|
log "Removing incompatible Redroid container (${name})"
|
||||||
|
docker rm -f "$name" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
mkdir -p "$data_dir"
|
mkdir -p "$data_dir"
|
||||||
allow_tcp_port_if_firewall_active "$REDROID_DEFAULT_PORT"
|
allow_tcp_port_if_firewall_active "$REDROID_DEFAULT_PORT"
|
||||||
if docker ps --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
if docker ps --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
||||||
|
if redroid_container_matches_host_support "$name"; then
|
||||||
log "Redroid already running"
|
log "Redroid already running"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
log "Recreating running Redroid container to apply binder mounts"
|
||||||
|
docker rm -f "$name" >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
||||||
|
if ! redroid_container_matches_host_support "$name"; then
|
||||||
|
log "Recreating existing Redroid container to apply binder mounts"
|
||||||
|
docker rm -f "$name" >/dev/null 2>&1 || true
|
||||||
|
else
|
||||||
log "Starting existing Redroid container"
|
log "Starting existing Redroid container"
|
||||||
docker start "$name" >/dev/null 2>&1 || true
|
docker start "$name" >/dev/null 2>&1 || true
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
log "Installing Redroid container (${image})"
|
log "Installing Redroid container (${image})"
|
||||||
docker run -d \
|
docker run -d \
|
||||||
--name "$name" \
|
--name "$name" \
|
||||||
@@ -1045,9 +1211,12 @@ install_redroid() {
|
|||||||
-v "${data_dir}:/data" \
|
-v "${data_dir}:/data" \
|
||||||
-e "REDROID_GPU_MODE=${REDROID_GPU_MODE}" \
|
-e "REDROID_GPU_MODE=${REDROID_GPU_MODE}" \
|
||||||
-e "REDROID_DEVICE_PROFILE=${REDROID_DEVICE_PROFILE}" \
|
-e "REDROID_DEVICE_PROFILE=${REDROID_DEVICE_PROFILE}" \
|
||||||
|
$( [ "${REDROID_ADB_INSECURE:-1}" = "1" ] && printf '%s ' '-e' 'REDROID_ADB_INSECURE=1' ) \
|
||||||
|
$( [ -e /dev/kvm ] && printf '%s ' '--device' '/dev/kvm' ) \
|
||||||
$( [ -d /dev/dri ] && printf '%s ' '-v /dev/dri:/dev/dri' ) \
|
$( [ -d /dev/dri ] && printf '%s ' '-v /dev/dri:/dev/dri' ) \
|
||||||
$( [ -d /dev/dma_heap ] && printf '%s ' '-v /dev/dma_heap:/dev/dma_heap' ) \
|
$( [ -d /dev/dma_heap ] && printf '%s ' '-v /dev/dma_heap:/dev/dma_heap' ) \
|
||||||
$( [ -d /dev/binderfs ] && printf '%s ' '-v /dev/binderfs:/dev/binderfs' ) \
|
$( redroid_binderfs_ready && printf '%s ' '-v' '/dev/binderfs:/dev/binderfs' ) \
|
||||||
|
$( redroid_legacy_binder_devices_ready && printf '%s ' '--device' '/dev/binder' '--device' '/dev/hwbinder' '--device' '/dev/vndbinder' ) \
|
||||||
$( [ -e /dev/rga ] && printf '%s ' '--device /dev/rga' ) \
|
$( [ -e /dev/rga ] && printf '%s ' '--device /dev/rga' ) \
|
||||||
$( [ -e /dev/mpp_service ] && printf '%s ' '--device /dev/mpp_service' ) \
|
$( [ -e /dev/mpp_service ] && printf '%s ' '--device /dev/mpp_service' ) \
|
||||||
"$image" ${REDROID_BOOT_ARGS:-} >/dev/null 2>&1 || log "WARN: Redroid create failed; check /dev/kvm, binderfs, and image availability"
|
"$image" ${REDROID_BOOT_ARGS:-} >/dev/null 2>&1 || log "WARN: Redroid create failed; check /dev/kvm, binderfs, and image availability"
|
||||||
|
|||||||
@@ -367,6 +367,47 @@ detect_preferred_lan_ip() {
|
|||||||
hostname -I 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+\.' | grep -Ev '^(127\.|169\.254\.)' | head -n 1
|
hostname -I 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+\.' | grep -Ev '^(127\.|169\.254\.)' | head -n 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sync_mdns_hosts_entry() {
|
||||||
|
local preferred_lan_ip
|
||||||
|
preferred_lan_ip="$(detect_preferred_lan_ip || true)"
|
||||||
|
python3 - <<PY
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
hosts = Path("/etc/hosts")
|
||||||
|
host_alias = "${HOSTNAME_ALIAS}"
|
||||||
|
preferred_lan_ip = "${preferred_lan_ip}".strip()
|
||||||
|
host_lines = hosts.read_text(encoding="utf-8").splitlines()
|
||||||
|
next_host_lines = []
|
||||||
|
loopback_written = False
|
||||||
|
lan_written = False
|
||||||
|
|
||||||
|
for raw in host_lines:
|
||||||
|
stripped = raw.strip()
|
||||||
|
if not stripped or stripped.startswith("#"):
|
||||||
|
next_host_lines.append(raw)
|
||||||
|
continue
|
||||||
|
parts = raw.split()
|
||||||
|
names = parts[1:]
|
||||||
|
if parts[0] == "127.0.1.1":
|
||||||
|
next_host_lines.append(f"127.0.1.1\t{host_alias}")
|
||||||
|
loopback_written = True
|
||||||
|
continue
|
||||||
|
if f"{host_alias}.local" in names:
|
||||||
|
if preferred_lan_ip and not lan_written:
|
||||||
|
next_host_lines.append(f"{preferred_lan_ip}\t{host_alias}.local")
|
||||||
|
lan_written = True
|
||||||
|
continue
|
||||||
|
next_host_lines.append(raw)
|
||||||
|
|
||||||
|
if not loopback_written:
|
||||||
|
next_host_lines.append(f"127.0.1.1\t{host_alias}")
|
||||||
|
if preferred_lan_ip and not lan_written:
|
||||||
|
next_host_lines.append(f"{preferred_lan_ip}\t{host_alias}.local")
|
||||||
|
|
||||||
|
hosts.write_text("\\n".join(next_host_lines) + "\\n", encoding="utf-8")
|
||||||
|
PY
|
||||||
|
}
|
||||||
|
|
||||||
neko_nat1to1_is_usable() {
|
neko_nat1to1_is_usable() {
|
||||||
local candidate="$1"
|
local candidate="$1"
|
||||||
local iface
|
local iface
|
||||||
@@ -414,6 +455,7 @@ service_mdns_status() {
|
|||||||
|
|
||||||
service_mdns_start() {
|
service_mdns_start() {
|
||||||
hostnamectl set-hostname "$HOSTNAME_ALIAS"
|
hostnamectl set-hostname "$HOSTNAME_ALIAS"
|
||||||
|
sync_mdns_hosts_entry
|
||||||
systemctl restart avahi-daemon
|
systemctl restart avahi-daemon
|
||||||
kv message "mDNS hostname refreshed"
|
kv message "mDNS hostname refreshed"
|
||||||
}
|
}
|
||||||
@@ -1251,6 +1293,90 @@ redroid_resolved_image() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redroid_binderfs_ready() {
|
||||||
|
[ -e /dev/binderfs/binder-control ]
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_legacy_binder_devices_ready() {
|
||||||
|
[ -e /dev/binder ] && [ -e /dev/hwbinder ] && [ -e /dev/vndbinder ]
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_binder_mode() {
|
||||||
|
if redroid_binderfs_ready; then
|
||||||
|
printf '%s\n' binderfs
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if redroid_legacy_binder_devices_ready; then
|
||||||
|
printf '%s\n' legacy
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_binder_is_provisionable() {
|
||||||
|
redroid_binder_mode >/dev/null 2>&1 && return 0
|
||||||
|
grep -qw binder /proc/filesystems 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_support_detail() {
|
||||||
|
if redroid_binderfs_ready; then
|
||||||
|
printf '%s' "binderfs mounted"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if redroid_legacy_binder_devices_ready; then
|
||||||
|
printf '%s' "legacy binder devices available"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if grep -qw binder /proc/filesystems 2>/dev/null; then
|
||||||
|
printf '%s' "binder filesystem supported but not mounted"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
printf '%s' "binder kernel support unavailable"
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_redroid_host_support() {
|
||||||
|
if redroid_binder_mode >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if have modprobe; then
|
||||||
|
modprobe binder_linux devices=binder,hwbinder,vndbinder >/dev/null 2>&1 || \
|
||||||
|
modprobe binder_linux >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
if redroid_binder_mode >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
if grep -qw binder /proc/filesystems 2>/dev/null; then
|
||||||
|
mkdir -p /dev/binderfs
|
||||||
|
if have mountpoint; then
|
||||||
|
if ! mountpoint -q /dev/binderfs 2>/dev/null; then
|
||||||
|
mount -t binder binder /dev/binderfs >/dev/null 2>&1 || \
|
||||||
|
mount -t binderfs binderfs /dev/binderfs >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
elif ! grep -qE '[[:space:]]/dev/binderfs[[:space:]]' /proc/mounts 2>/dev/null; then
|
||||||
|
mount -t binder binder /dev/binderfs >/dev/null 2>&1 || \
|
||||||
|
mount -t binderfs binderfs /dev/binderfs >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
redroid_binder_mode >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
redroid_container_matches_host_support() {
|
||||||
|
local name="$1"
|
||||||
|
case "$(redroid_binder_mode 2>/dev/null || true)" in
|
||||||
|
binderfs)
|
||||||
|
docker inspect -f '{{range .Mounts}}{{println .Destination}}{{end}}' "$name" 2>/dev/null | grep -qx '/dev/binderfs'
|
||||||
|
;;
|
||||||
|
legacy)
|
||||||
|
docker inspect -f '{{range .HostConfig.Devices}}{{println .PathOnHost}}{{end}}' "$name" 2>/dev/null | grep -qx '/dev/binder' && \
|
||||||
|
docker inspect -f '{{range .HostConfig.Devices}}{{println .PathOnHost}}{{end}}' "$name" 2>/dev/null | grep -qx '/dev/hwbinder' && \
|
||||||
|
docker inspect -f '{{range .HostConfig.Devices}}{{println .PathOnHost}}{{end}}' "$name" 2>/dev/null | grep -qx '/dev/vndbinder'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
service_redroid_status() {
|
service_redroid_status() {
|
||||||
if [ "${ENABLE_REDROID:-1}" != "1" ]; then
|
if [ "${ENABLE_REDROID:-1}" != "1" ]; then
|
||||||
kv available 0
|
kv available 0
|
||||||
@@ -1266,17 +1392,28 @@ service_redroid_status() {
|
|||||||
kv detail "docker not installed"
|
kv detail "docker not installed"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
local default_name running_line all_lines
|
local default_name running_line all_lines binder_detail
|
||||||
default_name="$(redroid_default_name)"
|
default_name="$(redroid_default_name)"
|
||||||
|
binder_detail="$(redroid_support_detail)"
|
||||||
running_line="$(docker ps --format '{{.Names}} {{.Status}} {{.Ports}}' 2>/dev/null | grep -E "^${REDROID_INSTANCE_PREFIX}-|^${default_name} " | head -n1 || true)"
|
running_line="$(docker ps --format '{{.Names}} {{.Status}} {{.Ports}}' 2>/dev/null | grep -E "^${REDROID_INSTANCE_PREFIX}-|^${default_name} " | head -n1 || true)"
|
||||||
all_lines="$(docker ps -a --format '{{.Names}} {{.Image}} {{.Status}} {{.Ports}}' 2>/dev/null | grep -i redroid || true)"
|
all_lines="$(docker ps -a --format '{{.Names}} {{.Image}} {{.Status}} {{.Ports}}' 2>/dev/null | grep -i redroid || true)"
|
||||||
|
if ! redroid_binder_mode >/dev/null 2>&1 && ! redroid_binder_is_provisionable; then
|
||||||
|
kv available 0
|
||||||
|
kv running 0
|
||||||
|
kv status unavailable
|
||||||
|
kv host "${HOSTNAME_ALIAS}.local"
|
||||||
|
kv port "$REDROID_DEFAULT_PORT"
|
||||||
|
kv url ""
|
||||||
|
kv detail "${binder_detail}; image=$(redroid_resolved_image); default=${default_name}; adb=${HOSTNAME_ALIAS}.local:${REDROID_DEFAULT_PORT}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
kv available 1
|
kv available 1
|
||||||
kv running "$([ -n "$running_line" ] && echo 1 || echo 0)"
|
kv running "$([ -n "$running_line" ] && echo 1 || echo 0)"
|
||||||
kv status "$([ -n "$running_line" ] && echo online || echo stopped)"
|
kv status "$([ -n "$running_line" ] && echo online || echo stopped)"
|
||||||
kv host "${HOSTNAME_ALIAS}.local"
|
kv host "${HOSTNAME_ALIAS}.local"
|
||||||
kv port "$REDROID_DEFAULT_PORT"
|
kv port "$REDROID_DEFAULT_PORT"
|
||||||
kv url ""
|
kv url ""
|
||||||
kv detail "${all_lines:-image=$(redroid_resolved_image); default=${default_name}; adb=${HOSTNAME_ALIAS}.local:${REDROID_DEFAULT_PORT}; boot=${REDROID_BOOT_ARGS}; expect_gms=${REDROID_EXPECT_GMS}; expect_magisk=${REDROID_EXPECT_MAGISK}}"
|
kv detail "${all_lines:-binder=${binder_detail}; image=$(redroid_resolved_image); default=${default_name}; adb=${HOSTNAME_ALIAS}.local:${REDROID_DEFAULT_PORT}; boot=${REDROID_BOOT_ARGS}; expect_gms=${REDROID_EXPECT_GMS}; expect_magisk=${REDROID_EXPECT_MAGISK}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
service_redroid_start() {
|
service_redroid_start() {
|
||||||
@@ -1292,16 +1429,27 @@ service_redroid_start() {
|
|||||||
name="$(redroid_default_name)"
|
name="$(redroid_default_name)"
|
||||||
image="$(redroid_resolved_image)"
|
image="$(redroid_resolved_image)"
|
||||||
data_dir="${REDROID_DATA_PREFIX}-${name}"
|
data_dir="${REDROID_DATA_PREFIX}-${name}"
|
||||||
|
if ! ensure_redroid_host_support; then
|
||||||
|
kv message "Redroid host prerequisites unavailable: $(redroid_support_detail)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
mkdir -p "$data_dir"
|
mkdir -p "$data_dir"
|
||||||
if docker ps --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
if docker ps --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
||||||
|
if redroid_container_matches_host_support "$name"; then
|
||||||
kv message "Redroid already running"
|
kv message "Redroid already running"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
docker rm -f "$name" >/dev/null
|
||||||
|
fi
|
||||||
if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
if docker ps -a --format '{{.Names}}' 2>/dev/null | grep -qx "$name"; then
|
||||||
|
if ! redroid_container_matches_host_support "$name"; then
|
||||||
|
docker rm -f "$name" >/dev/null
|
||||||
|
else
|
||||||
docker start "$name" >/dev/null
|
docker start "$name" >/dev/null
|
||||||
kv message "Redroid container started"
|
kv message "Redroid container started"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
docker run -d \
|
docker run -d \
|
||||||
--name "$name" \
|
--name "$name" \
|
||||||
--privileged \
|
--privileged \
|
||||||
@@ -1311,9 +1459,12 @@ service_redroid_start() {
|
|||||||
-v "${data_dir}:/data" \
|
-v "${data_dir}:/data" \
|
||||||
-e "REDROID_GPU_MODE=${REDROID_GPU_MODE:-guest}" \
|
-e "REDROID_GPU_MODE=${REDROID_GPU_MODE:-guest}" \
|
||||||
-e "REDROID_DEVICE_PROFILE=${REDROID_DEVICE_PROFILE:-pixel-7-pro}" \
|
-e "REDROID_DEVICE_PROFILE=${REDROID_DEVICE_PROFILE:-pixel-7-pro}" \
|
||||||
|
$( [ "${REDROID_ADB_INSECURE:-1}" = "1" ] && printf '%s ' '-e' 'REDROID_ADB_INSECURE=1' ) \
|
||||||
|
$( [ -e /dev/kvm ] && printf '%s ' '--device' '/dev/kvm' ) \
|
||||||
$( [ -d /dev/dri ] && printf '%s ' '-v /dev/dri:/dev/dri' ) \
|
$( [ -d /dev/dri ] && printf '%s ' '-v /dev/dri:/dev/dri' ) \
|
||||||
$( [ -d /dev/dma_heap ] && printf '%s ' '-v /dev/dma_heap:/dev/dma_heap' ) \
|
$( [ -d /dev/dma_heap ] && printf '%s ' '-v /dev/dma_heap:/dev/dma_heap' ) \
|
||||||
$( [ -d /dev/binderfs ] && printf '%s ' '-v /dev/binderfs:/dev/binderfs' ) \
|
$( redroid_binderfs_ready && printf '%s ' '-v' '/dev/binderfs:/dev/binderfs' ) \
|
||||||
|
$( redroid_legacy_binder_devices_ready && printf '%s ' '--device' '/dev/binder' '--device' '/dev/hwbinder' '--device' '/dev/vndbinder' ) \
|
||||||
$( [ -e /dev/rga ] && printf '%s ' '--device /dev/rga' ) \
|
$( [ -e /dev/rga ] && printf '%s ' '--device /dev/rga' ) \
|
||||||
$( [ -e /dev/mpp_service ] && printf '%s ' '--device /dev/mpp_service' ) \
|
$( [ -e /dev/mpp_service ] && printf '%s ' '--device /dev/mpp_service' ) \
|
||||||
"$image" ${REDROID_BOOT_ARGS:-} >/dev/null
|
"$image" ${REDROID_BOOT_ARGS:-} >/dev/null
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ ensure_root "$@"
|
|||||||
load_env
|
load_env
|
||||||
|
|
||||||
log "Stopping systemd services"
|
log "Stopping systemd services"
|
||||||
for svc in live-edge.service live-console.service live-webtty.service live-android-panel.service live-pulseaudio.service live-kmscube.service netdata cockpit.socket shellcrash.service avahi-daemon; do
|
for svc in live-edge.service live-console.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 stop "$svc" >/dev/null 2>&1 || true
|
||||||
systemctl disable "$svc" >/dev/null 2>&1 || true
|
systemctl disable "$svc" >/dev/null 2>&1 || true
|
||||||
done
|
done
|
||||||
@@ -33,6 +33,11 @@ log "Stopping Redroid default instance"
|
|||||||
if command -v docker >/dev/null 2>&1; then
|
if command -v docker >/dev/null 2>&1; then
|
||||||
docker rm -f "${REDROID_INSTANCE_PREFIX:-redroid13}-1" >/dev/null 2>&1 || true
|
docker rm -f "${REDROID_INSTANCE_PREFIX:-redroid13}-1" >/dev/null 2>&1 || true
|
||||||
fi
|
fi
|
||||||
|
if command -v mountpoint >/dev/null 2>&1; then
|
||||||
|
mountpoint -q /dev/binderfs && umount /dev/binderfs >/dev/null 2>&1 || true
|
||||||
|
elif grep -qE '[[:space:]]/dev/binderfs[[:space:]]' /proc/mounts 2>/dev/null; then
|
||||||
|
umount /dev/binderfs >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
|
||||||
log "Removing systemd unit files"
|
log "Removing systemd unit files"
|
||||||
rm -f /etc/systemd/system/live-edge.service
|
rm -f /etc/systemd/system/live-edge.service
|
||||||
@@ -41,6 +46,9 @@ rm -f /etc/systemd/system/live-webtty.service
|
|||||||
rm -f /etc/systemd/system/live-android-panel.service
|
rm -f /etc/systemd/system/live-android-panel.service
|
||||||
rm -f /etc/systemd/system/live-pulseaudio.service
|
rm -f /etc/systemd/system/live-pulseaudio.service
|
||||||
rm -f /etc/systemd/system/live-kmscube.service
|
rm -f /etc/systemd/system/live-kmscube.service
|
||||||
|
rm -f /etc/systemd/system/live-redroid-host.service
|
||||||
|
rm -f /etc/modules-load.d/live-redroid.conf
|
||||||
|
rm -f /etc/modprobe.d/live-redroid.conf
|
||||||
rm -f /etc/sudoers.d/live-control-plane
|
rm -f /etc/sudoers.d/live-control-plane
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
version: "3.3"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
filebrowser:
|
filebrowser:
|
||||||
image: filebrowser/filebrowser:latest
|
image: filebrowser/filebrowser:latest
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
version: "3.3"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
homepage:
|
homepage:
|
||||||
image: ghcr.io/gethomepage/homepage:latest
|
image: ghcr.io/gethomepage/homepage:latest
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
version: "3.3"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
mitmproxy:
|
mitmproxy:
|
||||||
image: mitmproxy/mitmproxy:latest
|
image: mitmproxy/mitmproxy:latest
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
version: "3.3"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
openclaw-gateway:
|
openclaw-gateway:
|
||||||
image: "${OPENCLAW_IMAGE:-ghcr.io/openclaw/openclaw:latest}"
|
image: "${OPENCLAW_IMAGE:-ghcr.io/openclaw/openclaw:latest}"
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
version: "3.3"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
srs:
|
srs:
|
||||||
image: ossrs/srs:5
|
image: ossrs/srs:5
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
version: "3.3"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
uptime-kuma:
|
uptime-kuma:
|
||||||
image: louislam/uptime-kuma:1
|
image: louislam/uptime-kuma:1
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
version: "3.3"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
code-server:
|
code-server:
|
||||||
image: codercom/code-server:latest
|
image: codercom/code-server:latest
|
||||||
|
|||||||
Reference in New Issue
Block a user