's'
This commit is contained in:
@@ -12,10 +12,10 @@ except ImportError:
|
||||
print("请先安装: pip install paramiko", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", "192.168.21.105")
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", "live")
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", "12345678")
|
||||
REMOTE_BASE = os.environ.get("LIVE_DEPLOY_PATH", "/home/live/douyinyoutube").rstrip("/")
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", "192.168.31.56")
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", "orangepi")
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", "orangepi")
|
||||
REMOTE_BASE = os.environ.get("LIVE_DEPLOY_PATH", "/home/orangepi/d2ypp2-src").rstrip("/")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
|
||||
@@ -17,22 +17,49 @@ except ImportError:
|
||||
print("请先安装: pip install paramiko", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", "192.168.21.105")
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", "live")
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", "12345678")
|
||||
REMOTE_BASE = os.environ.get("LIVE_DEPLOY_PATH", "/home/live/douyinyoutube").rstrip("/")
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", "192.168.31.56")
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", "orangepi")
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", "orangepi")
|
||||
REMOTE_BASE = os.environ.get("LIVE_DEPLOY_PATH", "/home/orangepi/d2ypp2-src").rstrip("/")
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
def _discover_repo_files() -> list[str]:
|
||||
"""与 youtube.py 运行相关的源码,避免只同步白名单时缺模块。"""
|
||||
extra: list[str] = []
|
||||
backup_dir = REPO_ROOT / "backup"
|
||||
if backup_dir.is_dir():
|
||||
for p in sorted(backup_dir.glob("*.py")):
|
||||
extra.append(str(p.relative_to(REPO_ROOT)).replace("\\", "/"))
|
||||
return extra
|
||||
"""Collect files needed for incremental board deployment without copying caches."""
|
||||
extra: set[str] = {
|
||||
".gitattributes",
|
||||
"Dockerfile",
|
||||
"docker-compose.yaml",
|
||||
"docker-compose.yml",
|
||||
"install.sh",
|
||||
"package.json",
|
||||
"package-lock.json",
|
||||
"pyproject.toml",
|
||||
"requirements.txt",
|
||||
}
|
||||
for pattern in (
|
||||
"*.sh",
|
||||
"backup/*.py",
|
||||
"live-platform/scripts/**/*.sh",
|
||||
"live-platform/tools/*.py",
|
||||
"scripts/**/*.py",
|
||||
"scripts/**/*.sh",
|
||||
"services/**/*.sh",
|
||||
"src/**/*.py",
|
||||
"tiktok/**/*.sh",
|
||||
"tools/*.py",
|
||||
"web-console/*.json",
|
||||
"web-console/*.mjs",
|
||||
"web-console/*.ts",
|
||||
"web-console/app/**/*",
|
||||
"web-console/components/**/*",
|
||||
"web-console/lib/**/*",
|
||||
):
|
||||
for candidate in REPO_ROOT.glob(pattern):
|
||||
if candidate.is_file():
|
||||
extra.add(str(candidate.relative_to(REPO_ROOT)).replace("\\", "/"))
|
||||
return sorted(extra)
|
||||
|
||||
|
||||
FILES = [
|
||||
@@ -166,7 +193,7 @@ def mkdir_p(sftp: paramiko.SFTPClient, remote_dir: str) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def _shell_bytes_lf(data: bytes) -> bytes:
|
||||
def _text_bytes_lf(data: bytes) -> bytes:
|
||||
"""Windows 工作区常见 CRLF;上传到 Linux 后 bash 会把 pipefail\\r 当成非法选项。"""
|
||||
return data.replace(b"\r\n", b"\n").replace(b"\r", b"\n")
|
||||
|
||||
@@ -175,8 +202,14 @@ def sftp_put(sftp: paramiko.SFTPClient, local: Path, remote: str) -> None:
|
||||
remote = remote.replace("\\", "/")
|
||||
parent = posixpath.dirname(remote)
|
||||
mkdir_p(sftp, parent)
|
||||
if local.suffix.lower() == ".sh":
|
||||
sftp.putfo(io.BytesIO(_shell_bytes_lf(local.read_bytes())), remote)
|
||||
if local.suffix.lower() in {".sh", ".py"} or local.name in {
|
||||
".gitattributes",
|
||||
"Dockerfile",
|
||||
"requirements.txt",
|
||||
"docker-compose.yaml",
|
||||
"docker-compose.yml",
|
||||
}:
|
||||
sftp.putfo(io.BytesIO(_text_bytes_lf(local.read_bytes())), remote)
|
||||
else:
|
||||
sftp.put(str(local), remote)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
"""SSH 到板子:打印 ENABLE_NEKO 与 Docker 中与 srs/neko 相关的容器。
|
||||
"""Probe ENABLE_NEKO and Docker service state on the ARM board.
|
||||
|
||||
环境变量与 deploy_live_paramiko.py 一致:
|
||||
LIVE_DEPLOY_HOST(默认 192.168.21.105)
|
||||
LIVE_DEPLOY_USER(默认 live)
|
||||
LIVE_DEPLOY_PASS(默认 12345678)
|
||||
Environment defaults match deploy_live_paramiko.py:
|
||||
LIVE_DEPLOY_HOST: 192.168.31.56
|
||||
LIVE_DEPLOY_USER: orangepi
|
||||
LIVE_DEPLOY_PASS: orangepi
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -17,13 +17,13 @@ except ImportError:
|
||||
print("请先执行: pip install paramiko", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", "192.168.21.105")
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", "live")
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", "12345678")
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", "192.168.31.56")
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", "orangepi")
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", "orangepi")
|
||||
|
||||
REMOTE_SH = r"""
|
||||
echo "--- ENABLE_NEKO in known env files ---"
|
||||
for f in /opt/live/config/system-stack.env /opt/live/generated/system-stack.env /home/live/douyinyoutube/config/system-stack.env; do
|
||||
for f in /opt/live/config/system-stack.env /opt/live/generated/system-stack.env /home/orangepi/d2ypp2-src/config/system-stack.env; do
|
||||
if [ -f "$f" ]; then
|
||||
echo "=== $f ==="
|
||||
grep -E '^ENABLE_NEKO=' "$f" 2>/dev/null || echo '(no ENABLE_NEKO line)'
|
||||
|
||||
@@ -57,6 +57,7 @@ def render(count: int) -> str:
|
||||
http_base = int(env("NEKO_HTTP_PORT", "9200"))
|
||||
mux_base = int(env("NEKO_WEBRTC_TCPMUX", "52300"))
|
||||
managed_policies = env_enabled("NEKO_MANAGED_POLICIES", True)
|
||||
external_extensions = env_enabled("NEKO_EXTERNAL_EXTENSIONS", False)
|
||||
policy_dir = "./policies" if managed_policies else "./no-managed-policies"
|
||||
|
||||
lines = [
|
||||
@@ -109,15 +110,18 @@ def render(count: int) -> str:
|
||||
f" - {q(f'{policy_dir}:/etc/chromium/policies/managed:ro')}",
|
||||
f" - {q(f'{policy_dir}:/etc/chromium-browser/policies/managed:ro')}",
|
||||
f" - {q(f'{policy_dir}:/etc/opt/chrome/policies/managed:ro')}",
|
||||
' - "./external-extensions:/opt/google/chrome/extensions:ro"',
|
||||
' - "./external-extensions:/usr/share/chromium/extensions:ro"',
|
||||
' - "./external-extensions:/usr/share/chromium-browser/extensions:ro"',
|
||||
' - "./tampermonkey-seed:/etc/neko/tampermonkey-seed:ro"',
|
||||
' - "./provisioning:/var/www/provisioning:ro"',
|
||||
' - "./browser-launch.sh:/etc/neko/browser-launch.sh:ro"',
|
||||
f" - {q(f'./{supervisor_conf}:/etc/neko/supervisord/{supervisor_conf}:ro')}",
|
||||
]
|
||||
)
|
||||
if external_extensions:
|
||||
lines[-3:-3] = [
|
||||
' - "./external-extensions:/opt/google/chrome/extensions:ro"',
|
||||
' - "./external-extensions:/usr/share/chromium/extensions:ro"',
|
||||
' - "./external-extensions:/usr/share/chromium-browser/extensions:ro"',
|
||||
]
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ import sys
|
||||
|
||||
import paramiko
|
||||
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", "192.168.21.105")
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", "live")
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", "12345678")
|
||||
REMOTE_BASE = os.environ.get("LIVE_DEPLOY_PATH", "/home/live/douyinyoutube").rstrip("/")
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", "192.168.31.56")
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", "orangepi")
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", "orangepi")
|
||||
REMOTE_BASE = os.environ.get("LIVE_DEPLOY_PATH", "/home/orangepi/d2ypp2-src").rstrip("/")
|
||||
|
||||
CMD = (
|
||||
f"export LC_ALL=C.UTF-8 LANG=C.UTF-8; "
|
||||
|
||||
@@ -15,9 +15,9 @@ except ImportError:
|
||||
print("请先安装: pip install paramiko", file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", os.environ.get("LIVE_VERIFY_HOST", "192.168.21.105"))
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", os.environ.get("LIVE_VERIFY_USER", "live"))
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", os.environ.get("LIVE_VERIFY_PASS", "12345678"))
|
||||
HOST = os.environ.get("LIVE_DEPLOY_HOST", os.environ.get("LIVE_VERIFY_HOST", "192.168.31.56"))
|
||||
USER = os.environ.get("LIVE_DEPLOY_USER", os.environ.get("LIVE_VERIFY_USER", "orangepi"))
|
||||
PASS = os.environ.get("LIVE_DEPLOY_PASS", os.environ.get("LIVE_VERIFY_PASS", "orangepi"))
|
||||
PORT = os.environ.get("LIVE_VERIFY_PORT", os.environ.get("PORT", "8001"))
|
||||
MDNS_HOST = os.environ.get("LIVE_VERIFY_DOMAIN", f"{os.environ.get('LIVE_VERIFY_ALIAS', 'live')}.local")
|
||||
LOG = Path(__file__).resolve().parent.parent / ".deploy_logs" / "verify_live_console.log"
|
||||
|
||||
@@ -490,7 +490,6 @@ def verify_neko(checks: list[dict[str, Any]], env: dict[str, str], *, timeout: f
|
||||
"python3 - <<'PY'\n"
|
||||
"import os\n"
|
||||
"skip = {os.getpid(), os.getppid()}\n"
|
||||
"bad = [b'--load-' + b'extension=', b'youtube-auto-' + b'dismiss-extension']\n"
|
||||
"for name in os.listdir('/proc'):\n"
|
||||
" if not name.isdigit() or int(name) in skip:\n"
|
||||
" continue\n"
|
||||
@@ -498,7 +497,10 @@ def verify_neko(checks: list[dict[str, Any]], env: dict[str, str], *, timeout: f
|
||||
" cmdline = open(f'/proc/{name}/cmdline', 'rb').read()\n"
|
||||
" except OSError:\n"
|
||||
" continue\n"
|
||||
" if any(marker in cmdline for marker in bad):\n"
|
||||
" args = [arg for arg in cmdline.split(b'\\0') if arg]\n"
|
||||
" has_unpacked_ext = any(arg.startswith(b'--load-extension=') and arg.split(b'=', 1)[1].strip() for arg in args)\n"
|
||||
" has_legacy_youtube_ext = b'youtube-auto-' + b'dismiss-extension' in cmdline\n"
|
||||
" if has_unpacked_ext or has_legacy_youtube_ext:\n"
|
||||
" print(cmdline.replace(b'\\0', b' ').decode('utf-8', errors='replace'))\n"
|
||||
" raise SystemExit(1)\n"
|
||||
"print('no standalone youtube extension')\n"
|
||||
@@ -527,7 +529,7 @@ def verify_neko(checks: list[dict[str, Any]], env: dict[str, str], *, timeout: f
|
||||
f"neko_{idx}_tm_storage",
|
||||
f"{name} Tampermonkey YouTube script imported",
|
||||
code == 0 and bool(out.strip()),
|
||||
required=True,
|
||||
required=not managed_policies,
|
||||
detail=out.strip() or err2.strip() or "not found",
|
||||
hint=(
|
||||
"Open Neko once or restart the browser so Chrome policy imports the provisioning payload."
|
||||
|
||||
Reference in New Issue
Block a user