diff --git a/.gitignore b/.gitignore index e69de29..5781c7c 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,2 @@ +container-home/* +!container-home/.gitkeep diff --git a/README.md b/README.md index d1ca75f..8983696 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ the host. - Arch Linux–based image - Runs as the host user (same username, UID, GID) - Mounts only the current project directory (same absolute path inside container) -- Persists OpenCode state in XDG_DATA_HOME/opencode-container/container-home directory +- Persists OpenCode state in ./container-home directory - No access to SSH keys, passwords, or full `$HOME` - Simple shell function (`opencode`) to launch interactively @@ -24,14 +24,10 @@ git clone https://git.jeena.net/jeena/opencode-container.git Source the helper file `opencode.aliases` in your shell configuration (`.bashrc` or `.zshrc`) so the `opencode` function is available in new sessions. -We set up the XDG_DATA_HOME/opencode-container/container-home directory as a central $HOME inside of the +We set up the ./container-home directory as a central $HOME inside of the container, independent of the session or project directory we start in. This -persists the whole $HOME from inside the container so everything OpenCode -writes into config files, etc. persists there. - -## Environment Variables - -- `XDG_DATA_HOME`: Override default data directory (default: ~/.local/share) +presists the whole $HOME from inside the container so everything opencode +writes into config files, etc. presists there. ## Usage diff --git a/container-home/.gitkeep b/container-home/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/force-cleanup.sh b/force-cleanup.sh deleted file mode 100755 index 1a0d9a5..0000000 --- a/force-cleanup.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# opencode-container-cleanup.sh - Complete cleanup script for OpenCode container - -set -e - -# Stop and remove all opencode containers -echo "Stopping and removing opencode containers..." -docker ps -q --filter "name=oc-" | xargs -r docker stop -docker ps -a -q --filter "name=oc-" | xargs -r docker rm -f - -# Remove the Docker image -echo "Removing opencode-container image..." -docker rmi opencode-container:latest 2>/dev/null || true - -# Remove entire opencode-container directory -CONTAINER_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/opencode-container" -if [ -d "$CONTAINER_DIR" ]; then - echo "Removing ~/.local/share/opencode-container directory..." - rm -rf "$CONTAINER_DIR" -fi - -echo "Complete cleanup finished!" diff --git a/opencode-container.py b/opencode-container.py index 84a7919..6f95659 100755 --- a/opencode-container.py +++ b/opencode-container.py @@ -16,43 +16,14 @@ class OpenCodeContainer: def __init__(self): self.project_path = Path.cwd().resolve() self.project_id = self._project_id(self.project_path) - - # Store host user info once - self.host_username = os.environ.get('USER', 'dev') - self.host_uid = os.getuid() - self.host_gid = os.getgid() - self.container_name = f"oc-{self.project_path.name}-{self.project_id}" self.docker_context_dir = Path(__file__).resolve().parent - def _get_xdg_data_home(self) -> Path: - """Get XDG_DATA_HOME with fallback to ~/.local/share""" - xdg_data = os.environ.get('XDG_DATA_HOME') - if xdg_data: - return Path(xdg_data) - return Path.home() / '.local' / 'share' - - @property - def container_home_path(self) -> Path: - """Container home directory in XDG_DATA_HOME""" - return self._get_xdg_data_home() / 'opencode-container' / 'container-home' - # ========================= # Public entrypoint # ========================= def run(self, args: list[str]) -> None: - # Ensure container home directory exists - self.container_home_path.mkdir(parents=True, exist_ok=True) - - # Pre-create project directory structure to prevent root-owned directories - try: - relative_path = self.project_path.relative_to(Path.home()) - (self.container_home_path / relative_path).mkdir(parents=True, exist_ok=True) - except ValueError: - # Project is outside home directory - no action needed - pass - if not self.image_exists(): self.build_image() @@ -83,12 +54,9 @@ class OpenCodeContainer: ).returncode == 0 def build_image(self) -> None: - print(f"Building image '{self.IMAGE}' with user {self.host_username} ({self.host_uid}:{self.host_gid})") + print(f"Building image '{self.IMAGE}'") self._run([ "docker", "build", - "--build-arg", f"USERNAME={self.host_username}", - "--build-arg", f"UID={self.host_uid}", - "--build-arg", f"GID={self.host_gid}", "-t", self.IMAGE, str(self.docker_context_dir), ]) @@ -98,14 +66,16 @@ class OpenCodeContainer: # ========================= def create_container(self) -> None: + uid = os.getuid() + gid = os.getgid() + print(f"Creating container '{self.container_name}'") self._run([ "docker", "create", "--name", self.container_name, - "--user", f"{self.host_uid}:{self.host_gid}", + "--user", f"{uid}:{gid}", "--volume", f"{self.project_path}:{self.project_path}", - "--volume", f"{self.container_home_path}:/home/{self.host_username}", self.IMAGE, "sh", "-c", "sleep infinity", ])