Skip to content

[WIP] feat: add Gemini CLI image with fixed user/group handling #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

bouthilx
Copy link
Contributor

@bouthilx bouthilx commented Jun 26, 2025

User description

  • Add complete Gemini CLI container image for AI-powered development
  • Support Google Gemini models (1.5 Pro, Flash) with configurable settings
  • Include comprehensive plugin system for authentication and configuration
  • Fix user/group creation conflicts with existing base image users
  • Dynamic username handling for compatibility with node:20-slim base
  • Persistent configuration for .config/gemini and .cache/gemini
  • Test suite for Docker build, API key setup, and Cubbi integration

🤖 Generated with Claude Code


Not tested yet, need access to gemini.


PR Type

Enhancement


Description

  • Add Gemini CLI container image

  • Support Google Gemini models configuration

  • Fix user/group handling for node base

  • Implement persistent configuration directories


Changes walkthrough 📝

Relevant files
Enhancement
gemini_cli_plugin.py
Authentication and configuration plugin for Gemini CLI     

cubbi/images/gemini-cli/gemini_cli_plugin.py

  • Implements authentication setup for Google Gemini CLI
  • Handles API key configuration from environment variables
  • Creates configuration files with proper permissions
  • Supports various model settings (temperature, max tokens, etc.)
  • +237/-0 
    Dockerfile
    Dockerfile for Gemini CLI container image                               

    cubbi/images/gemini-cli/Dockerfile

  • Creates container based on node:20-slim
  • Installs system dependencies and Gemini CLI
  • Sets up initialization system with cubbi_init.py
  • Configures environment for proper operation
  • +68/-0   
    Tests
    test_gemini.py
    Test suite for Gemini CLI container image                               

    cubbi/images/gemini-cli/test_gemini.py

  • Comprehensive test suite for Gemini CLI image
  • Tests Docker build, API key configuration, and CLI integration
  • Verifies persistent configuration directories
  • Includes Cubbi CLI integration tests
  • +309/-0 
    Documentation
    README.md
    Documentation for Gemini CLI container image                         

    cubbi/images/gemini-cli/README.md

  • Comprehensive documentation for Gemini CLI image
  • Includes quick start guide, configuration options
  • Provides usage examples and troubleshooting tips
  • Details security considerations and API limits
  • +339/-0 
    Configuration changes
    cubbi_image.yaml
    Cubbi image configuration for Gemini CLI                                 

    cubbi/images/gemini-cli/cubbi_image.yaml

  • Defines image metadata and configuration
  • Specifies environment variables for customization
  • Configures persistent storage for settings
  • Sets up volume mappings for project integration
  • +80/-0   

    Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • - Add complete Gemini CLI container image for AI-powered development
    - Support Google Gemini models (1.5 Pro, Flash) with configurable settings
    - Include comprehensive plugin system for authentication and configuration
    - Fix user/group creation conflicts with existing base image users
    - Dynamic username handling for compatibility with node:20-slim base
    - Persistent configuration for .config/gemini and .cache/gemini
    - Test suite for Docker build, API key setup, and Cubbi integration
    
    🤖 Generated with [Claude Code](https://claude.ai/code)
    
    Co-Authored-By: Claude <[email protected]>
    @pr-agent-monadical
    Copy link
    Contributor

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🧪 PR contains tests
    🔒 Security concerns

    Sensitive information exposure:
    The plugin writes API keys to a .env file (lines 97-98) and while it does set permissions to be user-readable only (line 102), there's no validation of the API key content which could allow injection attacks if the key variable contains malicious content. Additionally, the test script (test_gemini.py) includes test API keys in plaintext which could be mistaken for real keys.

    ⚡ Recommended focus areas for review

    Error Handling

    The plugin catches exceptions in multiple places but continues execution. This could lead to silent failures where the container appears to work but authentication or configuration isn't properly set up.

    except Exception as e:
        self.status.log(f"Failed to create environment file: {e}", "ERROR")
        return False
    Hardcoded Path

    The test script contains a hardcoded path that will fail on other systems. This should be made relative or configurable.

    "cd /home/bouthilx/projects/cubbi/cubbi/images/gemini-cli && docker build -t monadical/cubbi-gemini-cli:latest .",
    Missing Files

    The Dockerfile copies files like cubbi_init.py and init-status.sh that aren't included in the PR. These dependencies should be included or documented.

    COPY cubbi_init.py /cubbi/cubbi_init.py
    COPY gemini_cli_plugin.py /cubbi/gemini_cli_plugin.py
    COPY cubbi_image.yaml /cubbi/cubbi_image.yaml
    COPY init-status.sh /cubbi/init-status.sh

    Comment on lines +45 to +60
    def _ensure_gemini_dirs(self) -> tuple[Path, Path]:
    """Ensure Gemini directories exist with correct ownership"""
    config_dir = self._get_gemini_config_dir()
    cache_dir = self._get_gemini_cache_dir()

    # Create directories
    for directory in [config_dir, cache_dir]:
    try:
    directory.mkdir(mode=0o755, parents=True, exist_ok=True)
    self._set_ownership(directory)
    except OSError as e:
    self.status.log(
    f"Failed to create Gemini directory {directory}: {e}", "ERROR"
    )

    return config_dir, cache_dir
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: The function should handle the case where it fails to create a directory by returning early or raising an exception. Currently, it continues execution even after logging an error, which could lead to issues when the directories don't exist. [possible issue, importance: 8]

    Suggested change
    def _ensure_gemini_dirs(self) -> tuple[Path, Path]:
    """Ensure Gemini directories exist with correct ownership"""
    config_dir = self._get_gemini_config_dir()
    cache_dir = self._get_gemini_cache_dir()
    # Create directories
    for directory in [config_dir, cache_dir]:
    try:
    directory.mkdir(mode=0o755, parents=True, exist_ok=True)
    self._set_ownership(directory)
    except OSError as e:
    self.status.log(
    f"Failed to create Gemini directory {directory}: {e}", "ERROR"
    )
    return config_dir, cache_dir
    def _ensure_gemini_dirs(self) -> tuple[Path, Path]:
    """Ensure Gemini directories exist with correct ownership"""
    config_dir = self._get_gemini_config_dir()
    cache_dir = self._get_gemini_cache_dir()
    # Create directories
    for directory in [config_dir, cache_dir]:
    try:
    directory.mkdir(mode=0o755, parents=True, exist_ok=True)
    self._set_ownership(directory)
    except OSError as e:
    self.status.log(
    f"Failed to create Gemini directory {directory}: {e}", "ERROR"
    )
    raise RuntimeError(f"Failed to create required directory: {directory}")
    return config_dir, cache_dir

    Comment on lines 44 to 60
    def test_docker_build():
    """Test Docker image build"""
    print("\n" + "=" * 60)
    print("🧪 Testing Docker Image Build")
    print("=" * 60)

    result = run_command(
    "cd /home/bouthilx/projects/cubbi/cubbi/images/gemini-cli && docker build -t monadical/cubbi-gemini-cli:latest .",
    "Building Gemini CLI Docker image",
    )

    if result.returncode == 0:
    print("✅ Gemini CLI Docker image built successfully")
    return True
    else:
    print("❌ Gemini CLI Docker image build failed")
    return False
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: The test function contains a hardcoded absolute path to a specific user's home directory (/home/bouthilx/projects/cubbi/...), which will fail when run on other systems. Use a relative path or environment variable instead. [possible issue, importance: 9]

    Suggested change
    def test_docker_build():
    """Test Docker image build"""
    print("\n" + "=" * 60)
    print("🧪 Testing Docker Image Build")
    print("=" * 60)
    result = run_command(
    "cd /home/bouthilx/projects/cubbi/cubbi/images/gemini-cli && docker build -t monadical/cubbi-gemini-cli:latest .",
    "Building Gemini CLI Docker image",
    )
    if result.returncode == 0:
    print("✅ Gemini CLI Docker image built successfully")
    return True
    else:
    print("❌ Gemini CLI Docker image build failed")
    return False
    def test_docker_build():
    """Test Docker image build"""
    print("\n" + "=" * 60)
    print("🧪 Testing Docker Image Build")
    print("=" * 60)
    result = run_command(
    "docker build -t monadical/cubbi-gemini-cli:latest .",
    "Building Gemini CLI Docker image",
    )
    if result.returncode == 0:
    print("✅ Gemini CLI Docker image built successfully")
    return True
    else:
    print("❌ Gemini CLI Docker image build failed")
    return False

    Your Name and others added 2 commits June 26, 2025 16:24
    - Fix hardcoded paths in tests to use dynamic path resolution
    - Update gemini-cli plugin to use actual username instead of hardcoded "cubbi"
    - Simplify persistent configuration test to use ~ instead of absolute paths
    - Remove unused imports and improve test reliability
    - Ensure configuration files are created in correct user directories
    
    🤖 Generated with [Claude Code](https://claude.ai/code)
    
    Co-Authored-By: Claude <[email protected]>
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    1 participant