Spaces:
Paused
Paused
feat: tao-shen user with sudo, hostname=huggingrun, ttyd login
Browse files- Create tao-shen user (sudo NOPASSWD) instead of generic 'user'
- Set hostname to 'huggingrun' for clean prompt
- ttyd uses 'login -f tao-shen' for proper login shell
- Copy root's authorized_keys to tao-shen on restore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Dockerfile +5 -1
- entrypoint.py +14 -3
Dockerfile
CHANGED
|
@@ -38,7 +38,11 @@ RUN dpkg-query -W -f='${Package}\n' | sort > /etc/base-packages.list
|
|
| 38 |
RUN ssh-keygen -A && mkdir -p /run/sshd
|
| 39 |
|
| 40 |
# User account (for SSH login); container runs as root for system persistence
|
| 41 |
-
RUN useradd -m -u 1000 -s /bin/bash -p "$(openssl passwd -6 huggingrun)"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
# Root password for SSH login as root
|
| 43 |
RUN usermod -p "$(openssl passwd -6 huggingrun)" root
|
| 44 |
RUN mkdir -p /data
|
|
|
|
| 38 |
RUN ssh-keygen -A && mkdir -p /run/sshd
|
| 39 |
|
| 40 |
# User account (for SSH login); container runs as root for system persistence
|
| 41 |
+
RUN useradd -m -u 1000 -s /bin/bash -p "$(openssl passwd -6 huggingrun)" tao-shen 2>/dev/null || true \
|
| 42 |
+
&& apt-get update && apt-get install -y --no-install-recommends sudo \
|
| 43 |
+
&& echo "tao-shen ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/tao-shen \
|
| 44 |
+
&& chmod 440 /etc/sudoers.d/tao-shen \
|
| 45 |
+
&& rm -rf /var/lib/apt/lists/*
|
| 46 |
# Root password for SSH login as root
|
| 47 |
RUN usermod -p "$(openssl passwd -6 huggingrun)" root
|
| 48 |
RUN mkdir -p /data
|
entrypoint.py
CHANGED
|
@@ -402,9 +402,18 @@ class LogSSEHandler(http.server.BaseHTTPRequestHandler):
|
|
| 402 |
|
| 403 |
# ββ Service Management ββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 404 |
def ensure_passwords():
|
| 405 |
-
sh("id
|
| 406 |
-
sh('echo "
|
| 407 |
sh('echo "root:huggingrun" | chpasswd')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 408 |
sh("ldconfig 2>/dev/null || true")
|
| 409 |
|
| 410 |
|
|
@@ -427,7 +436,7 @@ def start_sshd():
|
|
| 427 |
def start_ttyd():
|
| 428 |
proc = subprocess.Popen([
|
| 429 |
"ttyd", "--port", TTYD_PORT, "--writable", "--base-path", "/",
|
| 430 |
-
"
|
| 431 |
])
|
| 432 |
time.sleep(0.5)
|
| 433 |
log(f"[OK] ttyd PID={proc.pid}" if proc.poll() is None else "[FAIL] ttyd")
|
|
@@ -452,6 +461,8 @@ def main():
|
|
| 452 |
os.makedirs(PERSIST_PATH, exist_ok=True)
|
| 453 |
open(LOGFILE, "a").close()
|
| 454 |
|
|
|
|
|
|
|
| 455 |
resolve_config()
|
| 456 |
ensure_dataset_repo()
|
| 457 |
ensure_passwords()
|
|
|
|
| 402 |
|
| 403 |
# ββ Service Management ββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 404 |
def ensure_passwords():
|
| 405 |
+
sh("id tao-shen >/dev/null 2>&1 || useradd -m -s /bin/bash tao-shen")
|
| 406 |
+
sh('echo "tao-shen:huggingrun" | chpasswd')
|
| 407 |
sh('echo "root:huggingrun" | chpasswd')
|
| 408 |
+
sh("usermod -aG sudo tao-shen 2>/dev/null || true")
|
| 409 |
+
sh("echo 'tao-shen ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/tao-shen")
|
| 410 |
+
sh("chmod 440 /etc/sudoers.d/tao-shen")
|
| 411 |
+
# Copy root's SSH keys to tao-shen if needed
|
| 412 |
+
if os.path.exists("/root/.ssh/authorized_keys"):
|
| 413 |
+
sh("mkdir -p /home/tao-shen/.ssh")
|
| 414 |
+
sh("cp -n /root/.ssh/authorized_keys /home/tao-shen/.ssh/authorized_keys 2>/dev/null || true")
|
| 415 |
+
sh("chown -R tao-shen:tao-shen /home/tao-shen/.ssh")
|
| 416 |
+
sh("chmod 700 /home/tao-shen/.ssh && chmod 600 /home/tao-shen/.ssh/authorized_keys")
|
| 417 |
sh("ldconfig 2>/dev/null || true")
|
| 418 |
|
| 419 |
|
|
|
|
| 436 |
def start_ttyd():
|
| 437 |
proc = subprocess.Popen([
|
| 438 |
"ttyd", "--port", TTYD_PORT, "--writable", "--base-path", "/",
|
| 439 |
+
"login", "-f", "tao-shen",
|
| 440 |
])
|
| 441 |
time.sleep(0.5)
|
| 442 |
log(f"[OK] ttyd PID={proc.pid}" if proc.poll() is None else "[FAIL] ttyd")
|
|
|
|
| 461 |
os.makedirs(PERSIST_PATH, exist_ok=True)
|
| 462 |
open(LOGFILE, "a").close()
|
| 463 |
|
| 464 |
+
sh("hostname huggingrun")
|
| 465 |
+
|
| 466 |
resolve_config()
|
| 467 |
ensure_dataset_repo()
|
| 468 |
ensure_passwords()
|