Files
recipe-maintainer/sandbox/claude.py
autonomic-bot f283a371bb recipe-maintainer: public snapshot (secrets + deployment plans removed, single commit)
Sanitized single-commit public mirror of recipe-maintainer.
- Removed test-ssh/.testenv (live creds); added test-ssh/.testenv.example placeholders.
- Removed plans/ and planned-updates/ (deployment-planning docs) so no client/
  deployment domains appear in the public repo.
- All other secret stores were already gitignored.
- docs.coopcloud.tech retained as a submodule (public upstream).
2026-06-16 20:18:24 +00:00

105 lines
2.9 KiB
Python
Executable File

#!/usr/bin/env python3
import atexit
import os
import subprocess
import sys
import tempfile
SENSITIVE_NAMES = {".env", ".envrc", "secret.json", "secrets.json"}
SENSITIVE_DIRS = [
os.path.expanduser("~/.ssh"),
os.path.expanduser("~/.gnupg"),
]
OVERRIDE_HEADER = """\
services:
claude:
volumes:
"""
def find_sensitive_files(workspace):
"""Walk workspace and return paths to sensitive files."""
matches = []
for dirpath, _dirnames, filenames in os.walk(workspace):
for name in filenames:
if name in SENSITIVE_NAMES:
matches.append(os.path.join(dirpath, name))
return matches
def find_sensitive_dirs(workspace):
"""Return SENSITIVE_DIRS entries that exist and fall under workspace."""
workspace = os.path.realpath(workspace)
matches = []
for d in SENSITIVE_DIRS:
real = os.path.realpath(d)
if real.startswith(workspace + os.sep) and os.path.isdir(real):
matches.append(real)
return matches
def generate_override(workspace, sensitive_files, sensitive_dirs=None):
"""Write a compose override YAML that mounts /dev/null over each file
and tmpfs over each sensitive directory."""
fd, path = tempfile.mkstemp(prefix="claude-env-override-", suffix=".yml")
with os.fdopen(fd, "w") as f:
f.write(OVERRIDE_HEADER)
if sensitive_files:
for host_path in sensitive_files:
rel = os.path.relpath(host_path, workspace)
f.write(f" - /dev/null:/workspace/{rel}:ro\n")
else:
f.write(" []\n")
if sensitive_dirs:
f.write(" tmpfs:\n")
for dir_path in sensitive_dirs:
rel = os.path.relpath(dir_path, workspace)
f.write(f" - /workspace/{rel}:ro\n")
return path
def main():
script_dir = os.path.dirname(os.path.abspath(__file__))
workspace = os.getcwd()
sensitive_files = find_sensitive_files(workspace)
sensitive_dirs = find_sensitive_dirs(workspace)
override_file = generate_override(workspace, sensitive_files, sensitive_dirs)
atexit.register(lambda: os.unlink(override_file))
compose_file = os.path.join(script_dir, "docker-compose.yml")
uid = os.getuid()
gid = os.getgid()
print(f"++ loading {workspace}")
cmd = [
"docker", "compose",
"-f", compose_file,
"-f", override_file,
"run", "--rm",
]
# Allocate TTY only when a human is at the terminal
if not sys.stdin.isatty():
cmd.append("-T")
cmd.extend([
"-v", f"{workspace}:/workspace",
"-v", f"{workspace}/.container-abra:/home/claude/.abra",
"claude",
*sys.argv[1:],
])
env = {**os.environ, "HOST_UID": str(uid), "HOST_GID": str(gid)}
result = subprocess.run(cmd, env=env)
sys.exit(result.returncode)
if __name__ == "__main__":
main()