commit 90249aad89cf40e34e1fe57d22e642e2a6ba8b9e Author: anthonyrawlins Date: Tue Sep 30 11:09:36 2025 +1000 Initial release of CHORUS Development Images This commit establishes the foundation for language-specific development container images used by CHORUS autonomous agents. Features: - Multi-stage Dockerfile with 7 layered images - Base Debian Bookworm image with common tools - Language-specific images: Rust, Go, Python, Node.js, Java, C/C++ - Standardized /workspace/{input,data,output} structure - Automated CI/CD pipeline for weekly security updates - Comprehensive test suite for all images - Full documentation (README, USAGE, MAINTENANCE) Images available: - chorus/base:1.0.0 (~200MB) - chorus/rust-dev:1.0.0 (~1.2GB) - chorus/go-dev:1.0.0 (~600MB) - chorus/python-dev:1.0.0 (~800MB) - chorus/node-dev:1.0.0 (~700MB) - chorus/java-dev:1.0.0 (~1.5GB) - chorus/cpp-dev:1.0.0 (~900MB) ๐Ÿค– Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude diff --git a/.gitea/workflows/build-and-push.yml b/.gitea/workflows/build-and-push.yml new file mode 100644 index 0000000..79572ff --- /dev/null +++ b/.gitea/workflows/build-and-push.yml @@ -0,0 +1,231 @@ +name: Build and Push Development Images + +on: + push: + branches: + - main + paths: + - 'images/**' + - 'VERSION' + pull_request: + branches: + - main + schedule: + # Weekly rebuild to get latest security updates (Mondays 2 AM UTC) + - cron: '0 2 * * 1' + workflow_dispatch: + inputs: + force_rebuild: + description: 'Force rebuild all images' + required: false + default: 'false' + +env: + REGISTRY: registry.home.deepblack.cloud + IMAGE_PREFIX: chorus + +jobs: + build-base: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.version.outputs.version }} + steps: + - uses: actions/checkout@v4 + + - name: Read version + id: version + run: echo "version=$(cat VERSION)" >> $GITHUB_OUTPUT + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Build and push base image + run: | + docker buildx build \ + --platform linux/amd64 \ + --target base \ + --push \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/base:latest \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/base:${{ steps.version.outputs.version }} \ + --cache-from type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/base:buildcache \ + --cache-to type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/base:buildcache,mode=max \ + -f images/base/Dockerfile \ + images/base + + build-rust: + needs: build-base + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Build and push rust-dev + run: | + docker buildx build \ + --platform linux/amd64 \ + --target rust-dev \ + --push \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/rust-dev:latest \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/rust-dev:${{ needs.build-base.outputs.version }} \ + --cache-from type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/rust-dev:buildcache \ + --cache-to type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/rust-dev:buildcache,mode=max \ + -f images/base/Dockerfile \ + images/base + + build-go: + needs: build-base + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Build and push go-dev + run: | + docker buildx build \ + --platform linux/amd64 \ + --target go-dev \ + --push \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/go-dev:latest \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/go-dev:${{ needs.build-base.outputs.version }} \ + --cache-from type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/go-dev:buildcache \ + --cache-to type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/go-dev:buildcache,mode=max \ + -f images/base/Dockerfile \ + images/base + + build-python: + needs: build-base + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Build and push python-dev + run: | + docker buildx build \ + --platform linux/amd64 \ + --target python-dev \ + --push \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/python-dev:latest \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/python-dev:${{ needs.build-base.outputs.version }} \ + --cache-from type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/python-dev:buildcache \ + --cache-to type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/python-dev:buildcache,mode=max \ + -f images/base/Dockerfile \ + images/base + + build-node: + needs: build-base + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Build and push node-dev + run: | + docker buildx build \ + --platform linux/amd64 \ + --target node-dev \ + --push \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/node-dev:latest \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/node-dev:${{ needs.build-base.outputs.version }} \ + --cache-from type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/node-dev:buildcache \ + --cache-to type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/node-dev:buildcache,mode=max \ + -f images/base/Dockerfile \ + images/base + + build-java: + needs: build-base + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Build and push java-dev + run: | + docker buildx build \ + --platform linux/amd64 \ + --target java-dev \ + --push \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/java-dev:latest \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/java-dev:${{ needs.build-base.outputs.version }} \ + --cache-from type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/java-dev:buildcache \ + --cache-to type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/java-dev:buildcache,mode=max \ + -f images/base/Dockerfile \ + images/base + + build-cpp: + needs: build-base + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Build and push cpp-dev + run: | + docker buildx build \ + --platform linux/amd64 \ + --target cpp-dev \ + --push \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/cpp-dev:latest \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/cpp-dev:${{ needs.build-base.outputs.version }} \ + --cache-from type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/cpp-dev:buildcache \ + --cache-to type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/cpp-dev:buildcache,mode=max \ + -f images/base/Dockerfile \ + images/base + + test-images: + needs: [build-rust, build-go, build-python, build-node, build-java, build-cpp] + runs-on: ubuntu-latest + strategy: + matrix: + image: [base, rust-dev, go-dev, python-dev, node-dev, java-dev, cpp-dev] + steps: + - uses: actions/checkout@v4 + + - name: Login to Registry + run: | + echo "${{ secrets.REGISTRY_PASSWORD }}" | docker login ${{ env.REGISTRY }} -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin + + - name: Test ${{ matrix.image }} + run: | + chmod +x tests/test-${{ matrix.image }}.sh + REGISTRY=${{ env.REGISTRY }}/chorus bash tests/test-${{ matrix.image }}.sh \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2a67d99 --- /dev/null +++ b/Makefile @@ -0,0 +1,191 @@ +# CHORUS Development Images Build System +# ======================================== + +.PHONY: help build-all build-base build-rust build-go build-python build-node build-java build-cpp \ + test-all test-base test-rust test-go test-python test-node test-java test-cpp \ + push-all clean version + +REGISTRY ?= registry.home.deepblack.cloud +IMAGE_PREFIX := chorus +VERSION := $(shell cat VERSION) + +# Colors for output +BLUE := \033[0;34m +GREEN := \033[0;32m +YELLOW := \033[0;33m +NC := \033[0m # No Color + +help: + @echo "$(BLUE)CHORUS Development Images Build System$(NC)" + @echo "" + @echo "$(GREEN)Build Targets:$(NC)" + @echo " build-all Build all images (base + 6 language images)" + @echo " build-base Build base image only" + @echo " build-rust Build Rust development image" + @echo " build-go Build Go development image" + @echo " build-python Build Python development image" + @echo " build-node Build Node.js development image" + @echo " build-java Build Java development image" + @echo " build-cpp Build C/C++ development image" + @echo "" + @echo "$(GREEN)Test Targets:$(NC)" + @echo " test-all Test all images" + @echo " test-base Test base image" + @echo " test-rust Test Rust image" + @echo " test-go Test Go image" + @echo " test-python Test Python image" + @echo " test-node Test Node.js image" + @echo " test-java Test Java image" + @echo " test-cpp Test C/C++ image" + @echo "" + @echo "$(GREEN)Registry Targets:$(NC)" + @echo " push-all Push all images to registry" + @echo " clean Remove local images" + @echo "" + @echo "$(YELLOW)Configuration:$(NC)" + @echo " Registry: $(REGISTRY)" + @echo " Image prefix: $(IMAGE_PREFIX)" + @echo " Version: $(VERSION)" + +build-all: build-base build-rust build-go build-python build-node build-java build-cpp + @echo "$(GREEN)โœ… All images built successfully$(NC)" + +build-base: + @echo "$(BLUE)Building base image...$(NC)" + docker build \ + --target base \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/base:latest \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/base:$(VERSION) \ + -f images/base/Dockerfile \ + images/base + @echo "$(GREEN)โœ… Base image built$(NC)" + +build-rust: build-base + @echo "$(BLUE)Building Rust development image...$(NC)" + docker build \ + --target rust-dev \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/rust-dev:latest \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/rust-dev:$(VERSION) \ + -f images/base/Dockerfile \ + images/base + @echo "$(GREEN)โœ… Rust image built$(NC)" + +build-go: build-base + @echo "$(BLUE)Building Go development image...$(NC)" + docker build \ + --target go-dev \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/go-dev:latest \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/go-dev:$(VERSION) \ + -f images/base/Dockerfile \ + images/base + @echo "$(GREEN)โœ… Go image built$(NC)" + +build-python: build-base + @echo "$(BLUE)Building Python development image...$(NC)" + docker build \ + --target python-dev \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/python-dev:latest \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/python-dev:$(VERSION) \ + -f images/base/Dockerfile \ + images/base + @echo "$(GREEN)โœ… Python image built$(NC)" + +build-node: build-base + @echo "$(BLUE)Building Node.js development image...$(NC)" + docker build \ + --target node-dev \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/node-dev:latest \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/node-dev:$(VERSION) \ + -f images/base/Dockerfile \ + images/base + @echo "$(GREEN)โœ… Node.js image built$(NC)" + +build-java: build-base + @echo "$(BLUE)Building Java development image...$(NC)" + docker build \ + --target java-dev \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/java-dev:latest \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/java-dev:$(VERSION) \ + -f images/base/Dockerfile \ + images/base + @echo "$(GREEN)โœ… Java image built$(NC)" + +build-cpp: build-base + @echo "$(BLUE)Building C/C++ development image...$(NC)" + docker build \ + --target cpp-dev \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/cpp-dev:latest \ + -t $(REGISTRY)/$(IMAGE_PREFIX)/cpp-dev:$(VERSION) \ + -f images/base/Dockerfile \ + images/base + @echo "$(GREEN)โœ… C/C++ image built$(NC)" + +test-all: test-base test-rust test-go test-python test-node test-java test-cpp + @echo "$(GREEN)โœ… All tests passed$(NC)" + +test-base: + @chmod +x tests/test-base.sh + @REGISTRY=$(REGISTRY)/$(IMAGE_PREFIX) bash tests/test-base.sh + +test-rust: + @chmod +x tests/test-rust-dev.sh + @REGISTRY=$(REGISTRY)/$(IMAGE_PREFIX) bash tests/test-rust-dev.sh + +test-go: + @chmod +x tests/test-go-dev.sh + @REGISTRY=$(REGISTRY)/$(IMAGE_PREFIX) bash tests/test-go-dev.sh + +test-python: + @chmod +x tests/test-python-dev.sh + @REGISTRY=$(REGISTRY)/$(IMAGE_PREFIX) bash tests/test-python-dev.sh + +test-node: + @chmod +x tests/test-node-dev.sh + @REGISTRY=$(REGISTRY)/$(IMAGE_PREFIX) bash tests/test-node-dev.sh + +test-java: + @chmod +x tests/test-java-dev.sh + @REGISTRY=$(REGISTRY)/$(IMAGE_PREFIX) bash tests/test-java-dev.sh + +test-cpp: + @chmod +x tests/test-cpp-dev.sh + @REGISTRY=$(REGISTRY)/$(IMAGE_PREFIX) bash tests/test-cpp-dev.sh + +push-all: build-all test-all + @echo "$(BLUE)Pushing all images to registry...$(NC)" + docker push $(REGISTRY)/$(IMAGE_PREFIX)/base:latest + docker push $(REGISTRY)/$(IMAGE_PREFIX)/base:$(VERSION) + docker push $(REGISTRY)/$(IMAGE_PREFIX)/rust-dev:latest + docker push $(REGISTRY)/$(IMAGE_PREFIX)/rust-dev:$(VERSION) + docker push $(REGISTRY)/$(IMAGE_PREFIX)/go-dev:latest + docker push $(REGISTRY)/$(IMAGE_PREFIX)/go-dev:$(VERSION) + docker push $(REGISTRY)/$(IMAGE_PREFIX)/python-dev:latest + docker push $(REGISTRY)/$(IMAGE_PREFIX)/python-dev:$(VERSION) + docker push $(REGISTRY)/$(IMAGE_PREFIX)/node-dev:latest + docker push $(REGISTRY)/$(IMAGE_PREFIX)/node-dev:$(VERSION) + docker push $(REGISTRY)/$(IMAGE_PREFIX)/java-dev:latest + docker push $(REGISTRY)/$(IMAGE_PREFIX)/java-dev:$(VERSION) + docker push $(REGISTRY)/$(IMAGE_PREFIX)/cpp-dev:latest + docker push $(REGISTRY)/$(IMAGE_PREFIX)/cpp-dev:$(VERSION) + @echo "$(GREEN)โœ… All images pushed to registry$(NC)" + +clean: + @echo "$(YELLOW)Removing local images...$(NC)" + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/base:latest 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/base:$(VERSION) 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/rust-dev:latest 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/rust-dev:$(VERSION) 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/go-dev:latest 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/go-dev:$(VERSION) 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/python-dev:latest 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/python-dev:$(VERSION) 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/node-dev:latest 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/node-dev:$(VERSION) 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/java-dev:latest 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/java-dev:$(VERSION) 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/cpp-dev:latest 2>/dev/null || true + -docker rmi $(REGISTRY)/$(IMAGE_PREFIX)/cpp-dev:$(VERSION) 2>/dev/null || true + @echo "$(GREEN)โœ… Local images removed$(NC)" + +version: + @echo "$(VERSION)" \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..bec6df4 --- /dev/null +++ b/README.md @@ -0,0 +1,207 @@ +# CHORUS Development Images + +Official Docker images for CHORUS autonomous agent development environments. + +[![Build Status](https://gitea.chorus.services/tony/chorus-dev-images/actions/workflows/build-and-push.yml/badge.svg)](https://gitea.chorus.services/tony/chorus-dev-images/actions) + +## Overview + +CHORUS Development Images provide standardized, pre-configured development environments for autonomous agents. Each image follows a consistent workspace structure and includes language-specific toolchains optimized for agent-driven software development. + +## Available Images + +| Image | Base | Approx Size | Key Tools | +|-------|------|-------------|-----------| +| `chorus/base` | Debian Bookworm | ~200MB | git, curl, build-essential, vim, jq | +| `chorus/rust-dev` | base | ~1.2GB | rustc 1.77+, cargo, clippy, rustfmt, ripgrep | +| `chorus/go-dev` | base | ~600MB | go1.22, gopls, delve, staticcheck, golangci-lint | +| `chorus/python-dev` | base | ~800MB | python3.11, uv, ruff, black, pytest, mypy | +| `chorus/node-dev` | base | ~700MB | node20, pnpm, yarn, typescript, eslint, prettier | +| `chorus/java-dev` | base | ~1.5GB | openjdk-17, maven, gradle | +| `chorus/cpp-dev` | base | ~900MB | gcc, g++, clang, cmake, ninja, gdb, valgrind | + +**Total storage:** ~5GB for all images (with layer sharing) + +## Quick Start + +### Pull an Image + +```bash +docker pull registry.home.deepblack.cloud/chorus/rust-dev:latest +``` + +### Run Interactive Shell + +```bash +docker run -it --rm \ + -v $(pwd):/workspace/input:ro \ + registry.home.deepblack.cloud/chorus/rust-dev:latest +``` + +### Execute Specific Command + +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v $(pwd)/output:/workspace/output \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + cargo build --release +``` + +## Workspace Structure + +All images use a standardized three-directory workspace layout: + +``` +/workspace/ +โ”œโ”€โ”€ input/ - Task requirements, repository checkout (typically read-only) +โ”œโ”€โ”€ data/ - Working directory for builds, compilation, temporary files +โ””โ”€โ”€ output/ - Deliverables, artifacts, reports, patches +``` + +**Environment Variables:** +- `WORKSPACE_ROOT=/workspace` +- `WORKSPACE_INPUT=/workspace/input` +- `WORKSPACE_DATA=/workspace/data` (default working directory) +- `WORKSPACE_OUTPUT=/workspace/output` + +## Image Details + +### Base Image (`chorus/base`) + +Foundation for all language-specific images with: +- Debian Bookworm (stable) +- Essential development tools +- Git with LFS support +- Standardized workspace structure +- Non-root `chorus` user (UID 1000) + +### Rust Development (`chorus/rust-dev`) + +- **Toolchain:** Stable Rust with rustup +- **Components:** rustfmt, clippy, rust-analyzer +- **Tools:** cargo-edit, cargo-audit, cargo-watch, ripgrep, fd-find +- **Libraries:** libssl-dev, libpq-dev, libsqlite3-dev + +### Go Development (`chorus/go-dev`) + +- **Version:** Go 1.22.2 +- **Tools:** gopls (LSP), delve (debugger), staticcheck, golangci-lint +- **Environment:** GOROOT, GOPATH pre-configured + +### Python Development (`chorus/python-dev`) + +- **Version:** Python 3.11 +- **Package Managers:** uv, pip-tools +- **Linters:** ruff, black, pylint, mypy +- **Testing:** pytest, pytest-cov, pytest-asyncio +- **REPL:** ipython + +### Node.js Development (`chorus/node-dev`) + +- **Version:** Node 20 LTS +- **Package Managers:** npm, pnpm, yarn +- **TypeScript:** Full TypeScript support +- **Tools:** eslint, prettier, nodemon, pm2 + +### Java Development (`chorus/java-dev`) + +- **JDK:** OpenJDK 17 +- **Build Tools:** Maven, Gradle +- **Pre-configured:** Maven local repository + +### C/C++ Development (`chorus/cpp-dev`) + +- **Compilers:** gcc, g++, clang +- **Build Systems:** cmake, ninja, autotools +- **Libraries:** boost +- **Debug Tools:** gdb, valgrind +- **Documentation:** doxygen + +## Building Locally + +### Prerequisites + +- Docker 20.10+ +- GNU Make + +### Build Commands + +```bash +# Build all images +make build-all + +# Build specific image +make build-rust +make build-go +make build-python +make build-node +make build-java +make build-cpp + +# Run tests +make test-all + +# Push to registry (after building and testing) +make push-all + +# Clean local images +make clean +``` + +## Versioning + +Images are tagged with: +- **`latest`** - Most recent stable build +- **``** - Semantic version (e.g., `1.0.0`) + +### Version History + +- **1.0.0** (2025-09-30) - Initial release + - Base Debian Bookworm image + - 6 language-specific development environments + - Standardized workspace structure + +## Automated Builds + +Images automatically rebuild: +- On changes to image source files (push to `main`) +- Weekly security update schedule (Mondays 2 AM UTC) +- Manual workflow dispatch + +## Integration with CHORUS + +The CHORUS execution engine automatically selects appropriate images based on task language: + +```go +// Example: CHORUS engine auto-selects image +task := &TaskExecutionRequest{ + Description: "Fix Rust compilation error", +} +// Engine detects "Rust" and uses chorus/rust-dev:latest +``` + +## Contributing + +### Adding a New Tool + +1. Edit `images/base/Dockerfile` +2. Add tool installation to appropriate image stage +3. Update tests in `tests/test-.sh` +4. Update this README +5. Submit pull request + +### Reporting Issues + +Please report issues at: https://gitea.chorus.services/tony/chorus-dev-images/issues + +## License + +Copyright ยฉ 2025 CHORUS Services. All rights reserved. + +## Links + +- **Source:** https://gitea.chorus.services/tony/chorus-dev-images +- **Registry:** registry.home.deepblack.cloud/chorus +- **Documentation:** [docs/](docs/) +- **Main Project:** https://gitea.chorus.services/tony/CHORUS \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..afaf360 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/docs/MAINTENANCE.md b/docs/MAINTENANCE.md new file mode 100644 index 0000000..2dbb685 --- /dev/null +++ b/docs/MAINTENANCE.md @@ -0,0 +1,317 @@ +# CHORUS Development Images - Maintenance Guide + +## Version Management + +### Semantic Versioning + +We follow [Semantic Versioning 2.0.0](https://semver.org/): + +- **MAJOR** (X.0.0): Breaking changes (base image OS upgrade, removed tools) +- **MINOR** (x.Y.0): New features (new tools added, new image variants) +- **PATCH** (x.y.Z): Bug fixes, security updates, tool version updates + +### Updating Version + +1. Edit the `VERSION` file: + ```bash + echo "1.1.0" > VERSION + ``` + +2. Commit the change: + ```bash + git add VERSION + git commit -m "Bump version to 1.1.0" + git push + ``` + +3. Automated build will create images tagged with new version + +## Updating Base Image + +### Debian Version Update + +When a new Debian stable release is available: + +1. Update `ARG DEBIAN_VERSION` in `images/base/Dockerfile`: + ```dockerfile + ARG DEBIAN_VERSION=bookworm-20240615 # Update date suffix + ``` + +2. Test all images: + ```bash + make build-all + make test-all + ``` + +3. If tests pass, increment MAJOR version + +## Updating Language Toolchains + +### Go Version Update + +1. Check latest Go version: https://go.dev/dl/ + +2. Update `ARG GO_VERSION` in Dockerfile: + ```dockerfile + ARG GO_VERSION=1.23.0 # Update version + ``` + +3. Build and test: + ```bash + make build-go + make test-go + ``` + +### Node.js Version Update + +1. Check LTS versions: https://nodejs.org/ + +2. Update `ARG NODE_VERSION` in Dockerfile: + ```dockerfile + ARG NODE_VERSION=22 # Update to new LTS + ``` + +3. Build and test: + ```bash + make build-node + make test-node + ``` + +### Rust Toolchain Update + +Rust auto-updates to stable via rustup. To pin a specific version: + +1. Modify Dockerfile rust-dev stage: + ```dockerfile + RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \ + --default-toolchain 1.78.0 \ # Pin version + --profile default \ + --no-modify-path + ``` + +### Python Version Update + +1. Check available versions: `apt-cache search python3.` + +2. Update Dockerfile: + ```dockerfile + RUN apt-get update && apt-get install -y --no-install-recommends \ + python3.12 \ # Update version + python3.12-dev \ # Update version + python3-pip \ + python3-venv + ``` + +## Adding New Tools + +### Adding Tool to Existing Image + +1. Edit `images/base/Dockerfile` in appropriate stage +2. Add installation command +3. Update README.md with new tool +4. Add test for new tool in `tests/test-.sh` +5. Increment MINOR version + +Example - Adding `tokei` to Rust image: + +```dockerfile +# In rust-dev stage +RUN cargo install \ + cargo-edit \ + cargo-audit \ + tokei \ # New tool + && rm -rf /home/chorus/.cargo/registry/cache +``` + +Add test: +```bash +# In tests/test-rust-dev.sh +docker run --rm "$IMAGE" which tokei > /dev/null || exit 1 +``` + +### Creating New Language Image + +1. Add new stage to `images/base/Dockerfile`: + ```dockerfile + FROM base AS ruby-dev + + USER root + RUN apt-get update && apt-get install -y --no-install-recommends \ + ruby-full \ + && rm -rf /var/lib/apt/lists/* + + USER chorus + RUN gem install bundler + + LABEL org.opencontainers.image.title="CHORUS Ruby Development Image" + ``` + +2. Create test script `tests/test-ruby-dev.sh` + +3. Add build target to `Makefile` + +4. Add to CI workflow `.gitea/workflows/build-and-push.yml` + +5. Update README.md with new image + +## Security Updates + +### Weekly Automated Rebuild + +Images automatically rebuild weekly (Mondays 2 AM UTC) to pull latest security updates. + +### Manual Security Update + +For critical CVEs: + +1. Trigger manual rebuild: + - Go to: https://gitea.chorus.services/tony/chorus-dev-images/actions + - Click "Build and Push Development Images" + - Click "Run workflow" + - Check "Force rebuild all images" + +2. Monitor build progress + +3. Increment PATCH version after successful build + +## Testing + +### Local Testing + +```bash +# Test all images +make test-all + +# Test specific image +make test-rust +``` + +### Adding New Tests + +Add assertions to appropriate test script: + +```bash +# tests/test-rust-dev.sh +echo " โœ“ Checking new feature..." +docker run --rm "$IMAGE" bash -c ' + # Test commands here + rustc --version | grep -q "1.77" +' || exit 1 +``` + +## Registry Management + +### Cleaning Old Tags + +Periodically remove old version tags to save space: + +```bash +# List all tags for an image +curl -u username:password \ + https://registry.home.deepblack.cloud/v2/chorus/rust-dev/tags/list + +# Delete specific tag (requires registry API v2) +curl -X DELETE -u username:password \ + https://registry.home.deepblack.cloud/v2/chorus/rust-dev/manifests/ +``` + +### Checking Image Sizes + +```bash +# Local sizes +docker images | grep chorus + +# Registry sizes (requires access to registry) +docker manifest inspect registry.home.deepblack.cloud/chorus/rust-dev:latest | \ + jq -r '.layers[].size' | awk '{s+=$1} END {print s/1024/1024 " MB"}' +``` + +## Build Optimization + +### Layer Caching + +Ensure frequently changing operations are at the end: + +```dockerfile +# โœ… Good - static dependencies first +RUN apt-get update && apt-get install -y build-essential +RUN cargo install cargo-edit # Changes infrequently + +# โŒ Bad - changing operation first +COPY requirements.txt /tmp/ +RUN pip install -r /tmp/requirements.txt +RUN apt-get update # Should be before pip +``` + +### Multi-Stage Build Size + +Check base layer is shared: + +```bash +docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.ID}}" | grep chorus +``` + +All images should share the same base layer ID. + +## Troubleshooting + +### Build Fails + +1. Check Docker build logs +2. Verify external dependencies (Go downloads, npm registry) +3. Test locally: `make build-` +4. Check network connectivity + +### Test Fails + +1. Run test manually: `bash tests/test-.sh` +2. Check tool availability in container +3. Verify tool versions +4. Check for breaking changes in tool updates + +### CI/CD Issues + +1. Check Gitea Actions logs +2. Verify registry credentials (secrets) +3. Check Docker buildx support +4. Verify network access to registry + +## Release Checklist + +Before releasing new version: + +- [ ] All tests pass locally (`make test-all`) +- [ ] README.md updated with new features/changes +- [ ] USAGE.md updated if usage patterns changed +- [ ] VERSION file updated +- [ ] Git tag created: `git tag v1.x.x && git push --tags` +- [ ] Registry contains new version tags +- [ ] CHANGELOG.md updated (if exists) +- [ ] CHORUS engine updated to use new images (if needed) + +## Monitoring + +### Build Status + +Check automated builds: https://gitea.chorus.services/tony/chorus-dev-images/actions + +### Registry Health + +```bash +# Check registry is accessible +curl -u username:password \ + https://registry.home.deepblack.cloud/v2/_catalog + +# Check image is pullable +docker pull registry.home.deepblack.cloud/chorus/base:latest +``` + +### Usage Metrics + +Track which images are most pulled (requires registry logging): + +```bash +# Check registry logs +docker service logs registry_registry | grep "GET /v2/chorus" | \ + awk '{print $10}' | sort | uniq -c | sort -rn +``` \ No newline at end of file diff --git a/docs/USAGE.md b/docs/USAGE.md new file mode 100644 index 0000000..bcc7569 --- /dev/null +++ b/docs/USAGE.md @@ -0,0 +1,297 @@ +# CHORUS Development Images - Usage Guide + +## Basic Usage Patterns + +### Pattern 1: Interactive Development + +Use when you need to explore a codebase or debug interactively: + +```bash +# Start interactive shell in Rust environment +docker run -it --rm \ + -v /path/to/repository:/workspace/input \ + -v /path/to/output:/workspace/output \ + registry.home.deepblack.cloud/chorus/rust-dev:latest +``` + +Inside the container: +```bash +cd /workspace/input +cargo build +cargo test +# Copy results to output +cp target/release/binary /workspace/output/ +``` + +### Pattern 2: Single Command Execution + +Use for automated agent tasks: + +```bash +# Build Rust project +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v $(pwd)/output:/workspace/output \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + bash -c "cd /workspace/input && cargo build --release && cp target/release/* /workspace/output/" +``` + +### Pattern 3: Multi-Step Workflow + +Use for complex build pipelines: + +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v $(pwd)/output:/workspace/output \ + registry.home.deepblack.cloud/chorus/python-dev:latest \ + bash -c " + cd /workspace/input + uv sync + uv run pytest + uv run ruff check + uv run mypy . + cp -r dist/* /workspace/output/ + " +``` + +## Language-Specific Examples + +### Rust + +**Build and Test:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + bash -c "cd /workspace/input && cargo build && cargo test" +``` + +**Format and Lint:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + bash -c "cd /workspace/input && cargo fmt && cargo clippy -- -D warnings" +``` + +### Go + +**Build Binary:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v $(pwd)/bin:/workspace/output \ + registry.home.deepblack.cloud/chorus/go-dev:latest \ + bash -c "cd /workspace/input && go build -o /workspace/output/app" +``` + +**Run Tests:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + registry.home.deepblack.cloud/chorus/go-dev:latest \ + bash -c "cd /workspace/input && go test ./..." +``` + +### Python + +**Install Dependencies and Test:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + registry.home.deepblack.cloud/chorus/python-dev:latest \ + bash -c "cd /workspace/input && uv sync && uv run pytest" +``` + +**Lint and Type Check:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + registry.home.deepblack.cloud/chorus/python-dev:latest \ + bash -c "cd /workspace/input && ruff check . && mypy ." +``` + +### Node.js + +**Install and Build:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v $(pwd)/dist:/workspace/output \ + registry.home.deepblack.cloud/chorus/node-dev:latest \ + bash -c "cd /workspace/input && npm install && npm run build && cp -r dist/* /workspace/output/" +``` + +**Run Tests:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + registry.home.deepblack.cloud/chorus/node-dev:latest \ + bash -c "cd /workspace/input && npm install && npm test" +``` + +### Java + +**Maven Build:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v $(pwd)/target:/workspace/output \ + registry.home.deepblack.cloud/chorus/java-dev:latest \ + bash -c "cd /workspace/input && mvn clean package && cp target/*.jar /workspace/output/" +``` + +**Gradle Build:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v $(pwd)/build:/workspace/output \ + registry.home.deepblack.cloud/chorus/java-dev:latest \ + bash -c "cd /workspace/input && gradle build && cp build/libs/*.jar /workspace/output/" +``` + +### C/C++ + +**CMake Build:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v $(pwd)/build:/workspace/output \ + registry.home.deepblack.cloud/chorus/cpp-dev:latest \ + bash -c " + cd /workspace/data + cmake /workspace/input + make + cp bin/* /workspace/output/ + " +``` + +## Advanced Usage + +### Preserving Build Cache + +Mount a volume for package caches to speed up subsequent builds: + +**Rust:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v cargo-cache:/home/chorus/.cargo/registry \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + bash -c "cd /workspace/input && cargo build" +``` + +**Python:** +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -v pip-cache:/home/chorus/.cache/pip \ + registry.home.deepblack.cloud/chorus/python-dev:latest \ + bash -c "cd /workspace/input && pip install -r requirements.txt" +``` + +### Setting Environment Variables + +```bash +docker run --rm \ + -v $(pwd):/workspace/input:ro \ + -e DATABASE_URL=postgres://localhost/db \ + -e API_KEY=secret \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + bash -c "cd /workspace/input && cargo test" +``` + +### Resource Limits + +```bash +docker run --rm \ + --memory="2g" \ + --cpus="2.0" \ + -v $(pwd):/workspace/input:ro \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + bash -c "cd /workspace/input && cargo build --release" +``` + +### Network Access Control + +```bash +# No network access +docker run --rm --network=none \ + -v $(pwd):/workspace/input:ro \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + bash -c "cd /workspace/input && cargo build --offline" + +# Custom network +docker run --rm --network=my-network \ + -v $(pwd):/workspace/input:ro \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + bash -c "cd /workspace/input && cargo test" +``` + +## Troubleshooting + +### Permission Issues + +If you encounter permission errors with output files: + +```bash +# Run with matching UID +docker run --rm \ + --user $(id -u):$(id -g) \ + -v $(pwd):/workspace/input \ + -v $(pwd)/output:/workspace/output \ + registry.home.deepblack.cloud/chorus/rust-dev:latest \ + bash -c "cd /workspace/input && cargo build" +``` + +### Image Not Found + +Ensure you're logged into the registry: + +```bash +docker login registry.home.deepblack.cloud +``` + +### Out of Disk Space + +Clean up old images and build cache: + +```bash +docker system prune -a +``` + +## Best Practices + +1. **Use Read-Only Input**: Mount source code as read-only (`:ro`) to prevent accidental modifications +2. **Separate Output**: Use dedicated output directory for build artifacts +3. **Cache Dependencies**: Mount package cache volumes for faster rebuilds +4. **Limit Resources**: Set memory and CPU limits for production use +5. **Version Pin**: Use specific version tags (e.g., `1.0.0`) in production, not `latest` + +## Integration with CI/CD + +### Example GitLab CI + +```yaml +test: + image: registry.home.deepblack.cloud/chorus/rust-dev:1.0.0 + script: + - cargo test + artifacts: + paths: + - target/release/ +``` + +### Example GitHub Actions + +```yaml +jobs: + test: + runs-on: ubuntu-latest + container: + image: registry.home.deepblack.cloud/chorus/rust-dev:1.0.0 + steps: + - uses: actions/checkout@v4 + - run: cargo test +``` \ No newline at end of file diff --git a/images/base/Dockerfile b/images/base/Dockerfile new file mode 100644 index 0000000..3e1baa7 --- /dev/null +++ b/images/base/Dockerfile @@ -0,0 +1,306 @@ +# ======================= +# CHORUS Development Images +# ======================= +# Multi-stage Dockerfile for language-specific development environments +# Maintained by CHORUS Services (https://chorus.services) + +# ======================= +# Base Image +# ======================= +ARG DEBIAN_VERSION=bookworm-20240408 +FROM debian:${DEBIAN_VERSION} AS base + +# Metadata +LABEL org.opencontainers.image.title="CHORUS Base Development Image" +LABEL org.opencontainers.image.description="Base image for CHORUS autonomous agent development environments" +LABEL org.opencontainers.image.vendor="CHORUS Services" +LABEL org.opencontainers.image.source="https://gitea.chorus.services/tony/chorus-dev-images" +LABEL org.opencontainers.image.documentation="https://gitea.chorus.services/tony/chorus-dev-images/src/branch/main/README.md" + +# Environment configuration +ENV DEBIAN_FRONTEND=noninteractive \ + LANG=C.UTF-8 \ + LC_ALL=C.UTF-8 \ + TZ=UTC \ + WORKSPACE_ROOT=/workspace \ + WORKSPACE_INPUT=/workspace/input \ + WORKSPACE_DATA=/workspace/data \ + WORKSPACE_OUTPUT=/workspace/output + +# Install base system packages +RUN apt-get update && apt-get install -y --no-install-recommends \ + # Core utilities + ca-certificates \ + curl \ + wget \ + git \ + vim \ + nano \ + less \ + jq \ + # Build essentials + build-essential \ + pkg-config \ + # Network tools + netcat-traditional \ + iputils-ping \ + dnsutils \ + # Process tools + procps \ + htop \ + # Compression + zip \ + unzip \ + tar \ + gzip \ + bzip2 \ + xz-utils \ + # SSL/TLS + openssl \ + # Version control + git-lfs \ + # Documentation + man-db \ + && rm -rf /var/lib/apt/lists/* + +# Create standardized workspace structure +RUN mkdir -p \ + ${WORKSPACE_INPUT} \ + ${WORKSPACE_DATA} \ + ${WORKSPACE_OUTPUT} \ + && chmod -R 755 ${WORKSPACE_ROOT} + +# Create non-root user for development +RUN useradd -m -s /bin/bash -u 1000 chorus && \ + chown -R chorus:chorus ${WORKSPACE_ROOT} + +# Add workspace helper scripts +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +WORKDIR ${WORKSPACE_DATA} +USER chorus + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +CMD ["/bin/bash"] + +# ======================= +# Rust Development Image +# ======================= +FROM base AS rust-dev + +USER root + +# Install Rust-specific system dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + # Rust compilation dependencies + libssl-dev \ + libc6-dev \ + # Database client libraries (common in Rust projects) + libpq-dev \ + libsqlite3-dev \ + # Additional build tools + cmake \ + && rm -rf /var/lib/apt/lists/* + +USER chorus + +# Install Rust toolchain +ENV RUSTUP_HOME=/home/chorus/.rustup \ + CARGO_HOME=/home/chorus/.cargo \ + PATH=/home/chorus/.cargo/bin:$PATH + +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \ + --default-toolchain stable \ + --profile default \ + --no-modify-path + +# Install common Rust development tools +RUN cargo install \ + cargo-edit \ + cargo-audit \ + cargo-watch \ + cargo-expand \ + cargo-outdated \ + ripgrep \ + fd-find \ + bat \ + && rm -rf /home/chorus/.cargo/registry/cache + +# Configure Rust toolchain +RUN rustup component add \ + rustfmt \ + clippy \ + rust-analyzer + +LABEL org.opencontainers.image.title="CHORUS Rust Development Image" + +# ======================= +# Go Development Image +# ======================= +FROM base AS go-dev + +USER root + +ARG GO_VERSION=1.22.2 + +# Install Go +RUN wget -O go.tar.gz "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" && \ + tar -C /usr/local -xzf go.tar.gz && \ + rm go.tar.gz + +USER chorus + +ENV GOROOT=/usr/local/go \ + GOPATH=/home/chorus/go \ + PATH=/usr/local/go/bin:/home/chorus/go/bin:$PATH + +# Install common Go development tools +RUN go install golang.org/x/tools/gopls@latest && \ + go install github.com/go-delve/delve/cmd/dlv@latest && \ + go install honnef.co/go/tools/cmd/staticcheck@latest && \ + go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest && \ + go clean -cache -modcache + +LABEL org.opencontainers.image.title="CHORUS Go Development Image" + +# ======================= +# Python Development Image +# ======================= +FROM base AS python-dev + +USER root + +# Install Python and development headers +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3.11 \ + python3.11-dev \ + python3-pip \ + python3-venv \ + # Python build dependencies + libffi-dev \ + libssl-dev \ + # Data science dependencies + libxml2-dev \ + libxslt1-dev \ + && rm -rf /var/lib/apt/lists/* + +USER chorus + +# Install modern Python tooling +ENV PATH=/home/chorus/.local/bin:$PATH + +RUN pip3 install --no-cache-dir --user \ + # Package management + uv \ + pip-tools \ + # Code quality + ruff \ + black \ + mypy \ + pylint \ + # Testing + pytest \ + pytest-cov \ + pytest-asyncio \ + # Development tools + ipython \ + # Documentation + sphinx \ + mkdocs + +LABEL org.opencontainers.image.title="CHORUS Python Development Image" + +# ======================= +# Node.js Development Image +# ======================= +FROM base AS node-dev + +USER root + +ARG NODE_VERSION=20 + +# Install Node.js from NodeSource +RUN curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | bash - && \ + apt-get install -y --no-install-recommends nodejs && \ + rm -rf /var/lib/apt/lists/* + +USER chorus + +# Install global development tools +RUN npm install -g \ + pnpm \ + yarn \ + typescript \ + ts-node \ + eslint \ + prettier \ + nodemon \ + pm2 \ + && npm cache clean --force + +LABEL org.opencontainers.image.title="CHORUS Node.js Development Image" + +# ======================= +# Java Development Image +# ======================= +FROM base AS java-dev + +USER root + +# Install OpenJDK, Maven, and Gradle +RUN apt-get update && apt-get install -y --no-install-recommends \ + openjdk-17-jdk \ + maven \ + gradle \ + && rm -rf /var/lib/apt/lists/* + +USER chorus + +ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \ + MAVEN_HOME=/usr/share/maven \ + GRADLE_HOME=/usr/share/gradle \ + PATH=/usr/lib/jvm/java-17-openjdk-amd64/bin:$PATH + +# Pre-create Maven local repository +RUN mkdir -p /home/chorus/.m2 && \ + echo '\n\ +\n\ +' > /home/chorus/.m2/settings.xml + +LABEL org.opencontainers.image.title="CHORUS Java Development Image" + +# ======================= +# C/C++ Development Image +# ======================= +FROM base AS cpp-dev + +USER root + +# Install C/C++ compilers and build systems +RUN apt-get update && apt-get install -y --no-install-recommends \ + # Compilers + gcc \ + g++ \ + clang \ + # Build systems + cmake \ + ninja-build \ + autoconf \ + automake \ + libtool \ + # Development libraries + libboost-all-dev \ + # Debugging tools + gdb \ + valgrind \ + # Documentation + doxygen \ + && rm -rf /var/lib/apt/lists/* + +USER chorus + +LABEL org.opencontainers.image.title="CHORUS C/C++ Development Image" \ No newline at end of file diff --git a/images/base/entrypoint.sh b/images/base/entrypoint.sh new file mode 100644 index 0000000..3c62c1c --- /dev/null +++ b/images/base/entrypoint.sh @@ -0,0 +1,27 @@ +#!/bin/bash +# CHORUS Development Environment Entrypoint +# Provides standardized initialization for development containers + +set -e + +# Display workspace structure on first run +if [ ! -f "${WORKSPACE_DATA}/.chorus-initialized" ]; then + cat << "EOF" +โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— +โ•‘ CHORUS Development Environment โ•‘ +โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• + +Workspace Structure: + ๐Ÿ“‚ /workspace/ + โ”œโ”€โ”€ input/ - Task requirements, repository checkout + โ”œโ”€โ”€ data/ - Working directory, build artifacts + โ””โ”€โ”€ output/ - Deliverables, patches, reports + +Current Directory: /workspace/data + +EOF + touch "${WORKSPACE_DATA}/.chorus-initialized" +fi + +# Execute provided command or shell +exec "$@" \ No newline at end of file diff --git a/tests/test-base.sh b/tests/test-base.sh new file mode 100644 index 0000000..20f9896 --- /dev/null +++ b/tests/test-base.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Test script for base image + +set -e + +IMAGE="${REGISTRY:-registry.home.deepblack.cloud/chorus}/base:latest" + +echo "๐Ÿงช Testing base image: $IMAGE" + +# Test workspace structure +echo " โœ“ Checking workspace directories..." +docker run --rm "$IMAGE" test -d /workspace/input || exit 1 +docker run --rm "$IMAGE" test -d /workspace/data || exit 1 +docker run --rm "$IMAGE" test -d /workspace/output || exit 1 + +# Test core utilities +echo " โœ“ Checking core utilities..." +docker run --rm "$IMAGE" git --version > /dev/null || exit 1 +docker run --rm "$IMAGE" curl --version > /dev/null || exit 1 +docker run --rm "$IMAGE" which vim > /dev/null || exit 1 +docker run --rm "$IMAGE" which jq > /dev/null || exit 1 + +# Test user permissions +echo " โœ“ Checking user permissions..." +docker run --rm "$IMAGE" whoami | grep -q chorus || exit 1 +docker run --rm "$IMAGE" sh -c 'echo "test" > /workspace/data/test.txt && rm /workspace/data/test.txt' || exit 1 + +# Test environment variables +echo " โœ“ Checking environment variables..." +docker run --rm "$IMAGE" sh -c 'test -n "$WORKSPACE_ROOT"' || exit 1 +docker run --rm "$IMAGE" sh -c 'test -n "$WORKSPACE_INPUT"' || exit 1 +docker run --rm "$IMAGE" sh -c 'test -n "$WORKSPACE_DATA"' || exit 1 +docker run --rm "$IMAGE" sh -c 'test -n "$WORKSPACE_OUTPUT"' || exit 1 + +echo "โœ… Base image tests passed" \ No newline at end of file diff --git a/tests/test-cpp-dev.sh b/tests/test-cpp-dev.sh new file mode 100644 index 0000000..8ca800c --- /dev/null +++ b/tests/test-cpp-dev.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Test script for C/C++ development image + +set -e + +IMAGE="${REGISTRY:-registry.home.deepblack.cloud/chorus}/cpp-dev:latest" + +echo "๐Ÿงช Testing C/C++ image: $IMAGE" + +# Test C/C++ toolchain +echo " โœ“ Checking C/C++ toolchain..." +docker run --rm "$IMAGE" gcc --version > /dev/null || exit 1 +docker run --rm "$IMAGE" g++ --version > /dev/null || exit 1 +docker run --rm "$IMAGE" clang --version > /dev/null || exit 1 + +# Test build systems +echo " โœ“ Checking build tools..." +docker run --rm "$IMAGE" cmake --version > /dev/null || exit 1 +docker run --rm "$IMAGE" ninja --version > /dev/null || exit 1 + +# Test compilation capability +echo " โœ“ Testing C++ compilation..." +docker run --rm "$IMAGE" bash -c ' + cd /tmp && \ + echo "#include \nint main() { std::cout << \"hello\" << std::endl; return 0; }" > test.cpp && \ + g++ -o test test.cpp && \ + ./test +' || exit 1 + +echo "โœ… C/C++ image tests passed" \ No newline at end of file diff --git a/tests/test-go-dev.sh b/tests/test-go-dev.sh new file mode 100644 index 0000000..569b1a4 --- /dev/null +++ b/tests/test-go-dev.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Test script for Go development image + +set -e + +IMAGE="${REGISTRY:-registry.home.deepblack.cloud/chorus}/go-dev:latest" + +echo "๐Ÿงช Testing Go image: $IMAGE" + +# Test Go toolchain +echo " โœ“ Checking Go toolchain..." +docker run --rm "$IMAGE" go version > /dev/null || exit 1 + +# Test development tools +echo " โœ“ Checking Go tools..." +docker run --rm "$IMAGE" which gopls > /dev/null || exit 1 +docker run --rm "$IMAGE" which dlv > /dev/null || exit 1 +docker run --rm "$IMAGE" which staticcheck > /dev/null || exit 1 + +# Test build capability +echo " โœ“ Testing Go build..." +docker run --rm "$IMAGE" bash -c ' + cd /tmp && \ + mkdir test-project && cd test-project && \ + echo "package main\nimport \"fmt\"\nfunc main() { fmt.Println(\"hello\") }" > main.go && \ + go mod init test && \ + go build && \ + ./test +' || exit 1 + +echo "โœ… Go image tests passed" \ No newline at end of file diff --git a/tests/test-java-dev.sh b/tests/test-java-dev.sh new file mode 100644 index 0000000..001bd43 --- /dev/null +++ b/tests/test-java-dev.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Test script for Java development image + +set -e + +IMAGE="${REGISTRY:-registry.home.deepblack.cloud/chorus}/java-dev:latest" + +echo "๐Ÿงช Testing Java image: $IMAGE" + +# Test Java toolchain +echo " โœ“ Checking Java toolchain..." +docker run --rm "$IMAGE" java -version 2>&1 | grep -q "openjdk" || exit 1 +docker run --rm "$IMAGE" javac -version > /dev/null 2>&1 || exit 1 +docker run --rm "$IMAGE" mvn --version > /dev/null || exit 1 +docker run --rm "$IMAGE" gradle --version > /dev/null || exit 1 + +# Test build capability +echo " โœ“ Testing Java compilation..." +docker run --rm "$IMAGE" bash -c ' + cd /tmp && \ + echo "public class HelloWorld { public static void main(String[] args) { System.out.println(\"hello\"); }}" > HelloWorld.java && \ + javac HelloWorld.java && \ + java HelloWorld +' || exit 1 + +echo "โœ… Java image tests passed" \ No newline at end of file diff --git a/tests/test-node-dev.sh b/tests/test-node-dev.sh new file mode 100644 index 0000000..e364f77 --- /dev/null +++ b/tests/test-node-dev.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Test script for Node.js development image + +set -e + +IMAGE="${REGISTRY:-registry.home.deepblack.cloud/chorus}/node-dev:latest" + +echo "๐Ÿงช Testing Node.js image: $IMAGE" + +# Test Node.js toolchain +echo " โœ“ Checking Node.js toolchain..." +docker run --rm "$IMAGE" node --version > /dev/null || exit 1 +docker run --rm "$IMAGE" npm --version > /dev/null || exit 1 + +# Test development tools +echo " โœ“ Checking Node.js tools..." +docker run --rm "$IMAGE" which pnpm > /dev/null || exit 1 +docker run --rm "$IMAGE" which yarn > /dev/null || exit 1 +docker run --rm "$IMAGE" which tsc > /dev/null || exit 1 +docker run --rm "$IMAGE" which eslint > /dev/null || exit 1 +docker run --rm "$IMAGE" which prettier > /dev/null || exit 1 + +# Test execution capability +echo " โœ“ Testing Node.js execution..." +docker run --rm "$IMAGE" node -e "console.log('hello')" || exit 1 + +# Test package installation +echo " โœ“ Testing npm install..." +docker run --rm "$IMAGE" bash -c ' + cd /tmp && \ + npm init -y --quiet && \ + npm install lodash --silent && \ + node -e "const _ = require(\"lodash\"); console.log(_.VERSION)" +' || exit 1 + +echo "โœ… Node.js image tests passed" \ No newline at end of file diff --git a/tests/test-python-dev.sh b/tests/test-python-dev.sh new file mode 100644 index 0000000..f2df199 --- /dev/null +++ b/tests/test-python-dev.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# Test script for Python development image + +set -e + +IMAGE="${REGISTRY:-registry.home.deepblack.cloud/chorus}/python-dev:latest" + +echo "๐Ÿงช Testing Python image: $IMAGE" + +# Test Python toolchain +echo " โœ“ Checking Python toolchain..." +docker run --rm "$IMAGE" python3 --version > /dev/null || exit 1 +docker run --rm "$IMAGE" pip3 --version > /dev/null || exit 1 + +# Test development tools +echo " โœ“ Checking Python tools..." +docker run --rm "$IMAGE" which uv > /dev/null || exit 1 +docker run --rm "$IMAGE" which ruff > /dev/null || exit 1 +docker run --rm "$IMAGE" which black > /dev/null || exit 1 +docker run --rm "$IMAGE" which pytest > /dev/null || exit 1 +docker run --rm "$IMAGE" which mypy > /dev/null || exit 1 + +# Test execution capability +echo " โœ“ Testing Python execution..." +docker run --rm "$IMAGE" python3 -c "print('hello')" || exit 1 + +# Test package installation +echo " โœ“ Testing pip install..." +docker run --rm "$IMAGE" bash -c ' + cd /tmp && \ + echo "requests" > requirements.txt && \ + pip3 install --user -r requirements.txt --quiet && \ + python3 -c "import requests; print(requests.__version__)" +' || exit 1 + +echo "โœ… Python image tests passed" \ No newline at end of file diff --git a/tests/test-rust-dev.sh b/tests/test-rust-dev.sh new file mode 100644 index 0000000..6699bbe --- /dev/null +++ b/tests/test-rust-dev.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Test script for Rust development image + +set -e + +IMAGE="${REGISTRY:-registry.home.deepblack.cloud/chorus}/rust-dev:latest" + +echo "๐Ÿงช Testing Rust image: $IMAGE" + +# Test Rust toolchain +echo " โœ“ Checking Rust toolchain..." +docker run --rm "$IMAGE" rustc --version > /dev/null || exit 1 +docker run --rm "$IMAGE" cargo --version > /dev/null || exit 1 +docker run --rm "$IMAGE" rustfmt --version > /dev/null || exit 1 +docker run --rm "$IMAGE" cargo clippy --version > /dev/null || exit 1 + +# Test development tools +echo " โœ“ Checking Rust tools..." +docker run --rm "$IMAGE" which ripgrep > /dev/null || exit 1 +docker run --rm "$IMAGE" which fd > /dev/null || exit 1 + +# Test build capability +echo " โœ“ Testing Rust build..." +docker run --rm "$IMAGE" bash -c ' + cd /tmp && \ + cargo init --name test-project --quiet && \ + cd test-project && \ + cargo build --release --quiet && \ + ./target/release/test-project +' || exit 1 + +echo "โœ… Rust image tests passed" \ No newline at end of file