mirror of
https://github.com/johndoe6345789/SparkOS.git
synced 2026-04-24 13:34:56 +00:00
Merge pull request #6 from johndoe6345789/copilot/add-docker-version-for-testing
Add Docker containerization and GHCR publishing via GitHub Actions
This commit is contained in:
49
.dockerignore
Normal file
49
.dockerignore
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.github
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
*.md
|
||||||
|
!README.md
|
||||||
|
ARCHITECTURE.md
|
||||||
|
CONTRIBUTING.md
|
||||||
|
LICENSE
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
init
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
*.img
|
||||||
|
*.iso
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Generated rootfs contents (we build our own in Docker)
|
||||||
|
rootfs/bin/*
|
||||||
|
rootfs/sbin/init
|
||||||
|
rootfs/usr/
|
||||||
|
rootfs/lib/
|
||||||
|
rootfs/lib64/
|
||||||
|
rootfs/boot/
|
||||||
|
|
||||||
|
# Keep rootfs structure
|
||||||
|
!rootfs/etc/
|
||||||
|
!rootfs/root/
|
||||||
|
!rootfs/home/
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
/tmp/
|
||||||
|
|
||||||
|
# IDE and editor files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
105
.github/workflows/docker-publish.yml
vendored
Normal file
105
.github/workflows/docker-publish.yml
vendored
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
name: Docker Build and Publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- develop
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- develop
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=pr
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=semver,pattern={{major}}
|
||||||
|
type=sha,prefix={{branch}}-
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- name: Build Docker image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
load: ${{ github.event_name == 'pull_request' }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Test Docker image
|
||||||
|
run: |
|
||||||
|
echo "Testing SparkOS Docker image..."
|
||||||
|
# Get the first tag from the metadata output
|
||||||
|
IMAGE_TAG=$(echo "${{ steps.meta.outputs.tags }}" | head -n1)
|
||||||
|
echo "Using image: $IMAGE_TAG"
|
||||||
|
|
||||||
|
# For PRs, image is loaded locally; for branches, pull from GHCR
|
||||||
|
if [ "${{ github.event_name }}" != "pull_request" ]; then
|
||||||
|
echo "Pulling image from GHCR for testing..."
|
||||||
|
docker pull "$IMAGE_TAG"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run the container and check output
|
||||||
|
docker run --rm "$IMAGE_TAG"
|
||||||
|
|
||||||
|
# Verify init binary exists and is executable
|
||||||
|
docker run --rm "$IMAGE_TAG" sh -c "test -x /sparkos/rootfs/sbin/init && echo 'Init binary is executable'"
|
||||||
|
|
||||||
|
echo "Docker image test completed successfully!"
|
||||||
|
|
||||||
|
- name: Output image details
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
run: |
|
||||||
|
echo "### Docker Image Published! 🐳" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Registry:** ${{ env.REGISTRY }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Repository:** ${{ env.IMAGE_NAME }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Tags:**" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "**Pull command:**" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo '```bash' >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY
|
||||||
|
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||||
93
Dockerfile
Normal file
93
Dockerfile
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# SparkOS Docker Image
|
||||||
|
# Multi-stage build for minimal final image size
|
||||||
|
|
||||||
|
# Build stage - use gcc image which has all build tools pre-installed
|
||||||
|
FROM gcc:13-bookworm AS builder
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
# Copy source files
|
||||||
|
COPY src/ ./src/
|
||||||
|
COPY Makefile .
|
||||||
|
COPY scripts/ ./scripts/
|
||||||
|
|
||||||
|
# Build the init system
|
||||||
|
RUN make init
|
||||||
|
|
||||||
|
# Runtime stage - use Alpine for minimal size
|
||||||
|
FROM alpine:3.19
|
||||||
|
|
||||||
|
# Note: Alpine includes busybox by default
|
||||||
|
|
||||||
|
# Create minimal rootfs structure
|
||||||
|
RUN mkdir -p /sparkos/rootfs/bin \
|
||||||
|
/sparkos/rootfs/sbin \
|
||||||
|
/sparkos/rootfs/etc \
|
||||||
|
/sparkos/rootfs/proc \
|
||||||
|
/sparkos/rootfs/sys \
|
||||||
|
/sparkos/rootfs/dev \
|
||||||
|
/sparkos/rootfs/tmp \
|
||||||
|
/sparkos/rootfs/usr/bin \
|
||||||
|
/sparkos/rootfs/usr/sbin \
|
||||||
|
/sparkos/rootfs/usr/lib \
|
||||||
|
/sparkos/rootfs/var/log \
|
||||||
|
/sparkos/rootfs/var/run \
|
||||||
|
/sparkos/rootfs/root \
|
||||||
|
/sparkos/rootfs/home/spark && \
|
||||||
|
chmod 1777 /sparkos/rootfs/tmp && \
|
||||||
|
chmod 700 /sparkos/rootfs/root && \
|
||||||
|
chmod 755 /sparkos/rootfs/home/spark
|
||||||
|
|
||||||
|
# Copy built init binary from builder
|
||||||
|
COPY --from=builder /build/init /sparkos/rootfs/sbin/init
|
||||||
|
|
||||||
|
# Set up basic configuration files
|
||||||
|
RUN echo "sparkos" > /sparkos/rootfs/etc/hostname && \
|
||||||
|
echo "127.0.0.1 localhost" > /sparkos/rootfs/etc/hosts && \
|
||||||
|
echo "127.0.1.1 sparkos" >> /sparkos/rootfs/etc/hosts && \
|
||||||
|
echo "root:x:0:0:root:/root:/bin/sh" > /sparkos/rootfs/etc/passwd && \
|
||||||
|
echo "spark:x:1000:1000:SparkOS User:/home/spark:/bin/sh" >> /sparkos/rootfs/etc/passwd && \
|
||||||
|
echo "root:x:0:" > /sparkos/rootfs/etc/group && \
|
||||||
|
echo "spark:x:1000:" >> /sparkos/rootfs/etc/group
|
||||||
|
|
||||||
|
# Create a test entrypoint
|
||||||
|
COPY <<'EOF' /sparkos/test.sh
|
||||||
|
#!/bin/sh
|
||||||
|
echo "SparkOS Docker Test Environment"
|
||||||
|
echo "================================"
|
||||||
|
echo ""
|
||||||
|
echo "SparkOS init binary: /sparkos/rootfs/sbin/init"
|
||||||
|
echo ""
|
||||||
|
echo "Verifying init binary..."
|
||||||
|
if [ -f /sparkos/rootfs/sbin/init ]; then
|
||||||
|
echo "✓ Init binary exists"
|
||||||
|
ls -lh /sparkos/rootfs/sbin/init
|
||||||
|
echo ""
|
||||||
|
echo "File type:"
|
||||||
|
file /sparkos/rootfs/sbin/init
|
||||||
|
echo ""
|
||||||
|
echo "Dependencies:"
|
||||||
|
ldd /sparkos/rootfs/sbin/init 2>&1 || echo " Static binary (no dependencies)"
|
||||||
|
else
|
||||||
|
echo "✗ Init binary not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
echo "Root filesystem structure:"
|
||||||
|
ls -la /sparkos/rootfs/
|
||||||
|
echo ""
|
||||||
|
echo "SparkOS is ready for testing!"
|
||||||
|
echo ""
|
||||||
|
echo "To test the init system:"
|
||||||
|
echo " docker run --rm <image> /sparkos/rootfs/sbin/init --help"
|
||||||
|
echo ""
|
||||||
|
exec /bin/sh
|
||||||
|
EOF
|
||||||
|
|
||||||
|
RUN chmod +x /sparkos/test.sh
|
||||||
|
|
||||||
|
WORKDIR /sparkos
|
||||||
|
|
||||||
|
# Set entrypoint
|
||||||
|
ENTRYPOINT ["/sparkos/test.sh"]
|
||||||
53
README.md
53
README.md
@@ -24,6 +24,8 @@ The current MVP provides:
|
|||||||
- ✅ Build system (Makefile)
|
- ✅ Build system (Makefile)
|
||||||
- ✅ Wired networking configuration with DHCP
|
- ✅ Wired networking configuration with DHCP
|
||||||
- ✅ DNS configuration with public fallback servers
|
- ✅ DNS configuration with public fallback servers
|
||||||
|
- ✅ Docker container for testing
|
||||||
|
- ✅ Automated builds and publishing to GHCR
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -42,6 +44,27 @@ To create bootable images (optional):
|
|||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
|
### Using Docker (Recommended for Testing)
|
||||||
|
|
||||||
|
The easiest way to test SparkOS is using the pre-built Docker image from GitHub Container Registry:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Pull and run the latest image
|
||||||
|
docker pull ghcr.io/johndoe6345789/sparkos:latest
|
||||||
|
docker run --rm ghcr.io/johndoe6345789/sparkos:latest
|
||||||
|
|
||||||
|
# Or build locally
|
||||||
|
docker build -t sparkos:local .
|
||||||
|
docker run --rm sparkos:local
|
||||||
|
```
|
||||||
|
|
||||||
|
The Docker image includes:
|
||||||
|
- Pre-built init system binary
|
||||||
|
- Minimal root filesystem structure
|
||||||
|
- Test environment for validation
|
||||||
|
|
||||||
|
Images are automatically built and published to [GitHub Container Registry](https://github.com/johndoe6345789/SparkOS/pkgs/container/sparkos) on every push to main branch.
|
||||||
|
|
||||||
### Building the Init System
|
### Building the Init System
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -84,6 +107,9 @@ Replace `/dev/sdX` with your actual USB device (e.g., `/dev/sdb`).
|
|||||||
|
|
||||||
```
|
```
|
||||||
SparkOS/
|
SparkOS/
|
||||||
|
├── .github/ # GitHub Actions workflows
|
||||||
|
│ └── workflows/
|
||||||
|
│ └── docker-publish.yml # Docker build and publish workflow
|
||||||
├── config/ # Build configuration files
|
├── config/ # Build configuration files
|
||||||
│ └── build.conf # Build parameters
|
│ └── build.conf # Build parameters
|
||||||
├── scripts/ # Build and setup scripts
|
├── scripts/ # Build and setup scripts
|
||||||
@@ -97,6 +123,7 @@ SparkOS/
|
|||||||
│ ├── sbin/ # System binaries
|
│ ├── sbin/ # System binaries
|
||||||
│ ├── etc/ # Configuration files
|
│ ├── etc/ # Configuration files
|
||||||
│ └── ... # Standard FHS directories
|
│ └── ... # Standard FHS directories
|
||||||
|
├── Dockerfile # Docker image definition
|
||||||
├── Makefile # Build system
|
├── Makefile # Build system
|
||||||
└── README.md # This file
|
└── README.md # This file
|
||||||
```
|
```
|
||||||
@@ -134,6 +161,32 @@ SparkOS provides wired networking for initial bootstrap:
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
|
### CI/CD and Docker
|
||||||
|
|
||||||
|
SparkOS uses GitHub Actions for continuous integration and delivery:
|
||||||
|
|
||||||
|
**Automated Builds:**
|
||||||
|
- Docker images are automatically built on every push to main/develop branches
|
||||||
|
- Images are also built for pull requests (testing only, not published)
|
||||||
|
- Tagged releases automatically create versioned Docker images
|
||||||
|
|
||||||
|
**Container Registry:**
|
||||||
|
- Images are published to GitHub Container Registry (GHCR)
|
||||||
|
- Pull images: `docker pull ghcr.io/johndoe6345789/sparkos:latest`
|
||||||
|
- Available tags: `latest`, `main`, `develop`, version tags (e.g., `v1.0.0`)
|
||||||
|
|
||||||
|
**Docker Development:**
|
||||||
|
```bash
|
||||||
|
# Build Docker image locally
|
||||||
|
docker build -t sparkos:dev .
|
||||||
|
|
||||||
|
# Test the image
|
||||||
|
docker run --rm sparkos:dev
|
||||||
|
|
||||||
|
# Inspect the init binary
|
||||||
|
docker run --rm sparkos:dev sh -c "ls -lh /sparkos/rootfs/sbin/init"
|
||||||
|
```
|
||||||
|
|
||||||
### Building Components
|
### Building Components
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
Reference in New Issue
Block a user