#!/bin/bash # Efficient development container workflow - persistent container for debugging set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" # Container configuration CONTAINER_NAME="zero-os-dev" BUILDER_IMAGE="zero-os-builder:latest" # Source common functions source "${SCRIPT_DIR}/lib/common.sh" function show_usage() { cat << EOF Zero OS Development Container Manager Usage: $0 [COMMAND] Commands: start Start persistent development container stop Stop development container shell Enter development container shell build Run build in persistent container clean Clean and restart container status Show container status logs Show container logs Environment Variables: DEBUG Enable debug output (default: 1 for dev) Examples: $0 start # Start persistent container $0 shell # Enter container for debugging $0 build # Run build in persistent container EOF } function dev_container_start() { section_header "Starting Development Container" # Check if container already exists if podman container exists "$CONTAINER_NAME" 2>/dev/null; then if podman container inspect "$CONTAINER_NAME" --format '{{.State.Status}}' | grep -q "running"; then log_info "Development container already running" return 0 else log_info "Starting existing development container" safe_execute podman start "$CONTAINER_NAME" return 0 fi fi log_info "Creating new development container: ${CONTAINER_NAME}" # Create persistent container with all necessary mounts and environment safe_execute podman run -d \ --name "$CONTAINER_NAME" \ --privileged \ -v "${PROJECT_ROOT}:/workspace" \ -w /workspace \ -e DEBUG=1 \ -e ALPINE_VERSION=3.22 \ -e KERNEL_VERSION=6.12.44 \ -e RUST_TARGET=x86_64-unknown-linux-musl \ -e OPTIMIZATION_LEVEL=max \ "$BUILDER_IMAGE" \ sleep infinity log_info "Development container started successfully" log_info "Container name: ${CONTAINER_NAME}" log_info "Access with: $0 shell" } function dev_container_stop() { section_header "Stopping Development Container" if podman container exists "$CONTAINER_NAME" 2>/dev/null; then log_info "Stopping development container: ${CONTAINER_NAME}" safe_execute podman stop "$CONTAINER_NAME" log_info "Development container stopped" else log_info "Development container not found" fi } function dev_container_shell() { section_header "Entering Development Container Shell" if ! podman container exists "$CONTAINER_NAME" 2>/dev/null; then log_info "Development container not found, starting..." dev_container_start fi if ! podman container inspect "$CONTAINER_NAME" --format '{{.State.Status}}' | grep -q "running"; then log_info "Starting stopped development container" safe_execute podman start "$CONTAINER_NAME" fi log_info "Entering container shell (exit with 'exit' or Ctrl+D)" # Use direct execution for interactive shell (don't use safe_execute) exec podman exec -it "$CONTAINER_NAME" /bin/bash } function dev_container_build() { section_header "Running Build in Development Container" if ! podman container exists "$CONTAINER_NAME" 2>/dev/null; then log_info "Development container not found, starting..." dev_container_start fi if ! podman container inspect "$CONTAINER_NAME" --format '{{.State.Status}}' | grep -q "running"; then log_info "Starting stopped development container" safe_execute podman start "$CONTAINER_NAME" fi log_info "Running build in persistent container (real-time output)" log_info "Command: podman exec $CONTAINER_NAME ./scripts/build.sh $*" # Use direct execution to show real-time output (bypass safe_execute) podman exec "$CONTAINER_NAME" ./scripts/build.sh "$@" local exit_code=$? if [[ $exit_code -eq 0 ]]; then log_info "Build completed successfully in container" else log_error "Build failed in container with exit code: $exit_code" fi return $exit_code } function dev_container_clean() { section_header "Cleaning Development Container" if podman container exists "$CONTAINER_NAME" 2>/dev/null; then log_info "Removing existing development container" safe_execute podman rm -f "$CONTAINER_NAME" fi log_info "Starting fresh development container" dev_container_start } function dev_container_status() { section_header "Development Container Status" if podman container exists "$CONTAINER_NAME" 2>/dev/null; then local status=$(podman container inspect "$CONTAINER_NAME" --format '{{.State.Status}}') local created=$(podman container inspect "$CONTAINER_NAME" --format '{{.Created}}') log_info "Container: ${CONTAINER_NAME}" log_info "Status: ${status}" log_info "Created: ${created}" if [[ "$status" == "running" ]]; then log_info "✓ Ready for development" else log_info "⚠ Container stopped - use '$0 start' to start" fi else log_info "Development container not found" log_info "Use '$0 start' to create" fi } function dev_container_logs() { section_header "Development Container Logs" if podman container exists "$CONTAINER_NAME" 2>/dev/null; then safe_execute podman logs "$CONTAINER_NAME" else log_error "Development container not found" return 1 fi } # Main function function main() { local command="${1:-help}" case "$command" in start) dev_container_start ;; stop) dev_container_stop ;; shell) dev_container_shell ;; build) shift dev_container_build "$@" ;; clean) dev_container_clean ;; status) dev_container_status ;; logs) dev_container_logs ;; help|--help|-h) show_usage ;; *) log_error "Unknown command: $command" show_usage exit 1 ;; esac } main "$@"