mirror of
https://github.com/GoodOlClint/PSProxmoxVE.git
synced 2026-07-26 07:58:14 +00:00
feat: add dev container for local build, test, and provisioning
- Dockerfile.test: multi-stage build with dev (ARM+x86) and dev-infra (x86 only, adds Terraform + PVE provisioning tools) targets - docker-compose.test.yml: services for both targets, .env.test support - dev.sh: helper script wrapping container lifecycle and run-integration.sh - .env.test.example: template for integration test configuration - .gitignore: exclude .env.test, whitelist .env.*.example Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,3 +13,5 @@ nupkg/
|
||||
BenchmarkDotNet.Artifacts/
|
||||
.env
|
||||
.env.*
|
||||
!.env.*.example
|
||||
tests/.env.test
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# PSProxmoxVE integration test configuration.
|
||||
# Copy to .env.test and fill in values. This file is gitignored.
|
||||
|
||||
# ── For testing against a pre-existing PVE (./tests/dev.sh integration) ──
|
||||
PVETEST_HOST=pve.example.com
|
||||
PVETEST_PORT=8006
|
||||
PVETEST_APITOKEN=user@realm!tokenid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
PVETEST_NODE=pve1
|
||||
PVETEST_STORAGE=local
|
||||
PVETEST_PASSWORD=<your-test-password>
|
||||
|
||||
# ── For full provisioning (./tests/dev.sh provision, x86 only) ───────────
|
||||
# PVE_ENDPOINT=https://pve.example.com:8006
|
||||
# PVE_API_TOKEN=user@realm!tokenid=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
# PVE_TARGET_NODE=pve1
|
||||
# PVE_PASSWORD=<root-password-for-nested-pve>
|
||||
|
||||
# ── Optional overrides ──────────────────────────────────────────────────
|
||||
# CACHE_DIR=/opt/pve-isos
|
||||
# WORK_DIR=/tmp/pve-integration
|
||||
# PVE_VERSIONS=9 8
|
||||
+48
-31
@@ -1,36 +1,53 @@
|
||||
# Replicates the GitHub Actions CI environment for PS 7.x unit tests
|
||||
FROM mcr.microsoft.com/powershell:7.5-ubuntu-24.04
|
||||
# PSProxmoxVE development and integration testing container
|
||||
#
|
||||
# Two targets:
|
||||
# dev - .NET SDK + PowerShell + Pester (build & test, works on ARM/x86)
|
||||
# dev-infra - Adds Terraform + PVE provisioning tools (x86 only)
|
||||
#
|
||||
# Usage:
|
||||
# # For build + test (works on Mac M-series):
|
||||
# docker compose -f tests/docker-compose.test.yml up -d
|
||||
#
|
||||
# # For full CI flow including provisioning (x86 only):
|
||||
# docker compose -f tests/docker-compose.test.yml --profile infra up -d
|
||||
|
||||
# Install .NET SDK 9.0, build module, install Pester, copy to module path
|
||||
RUN apt-get update && apt-get install -y wget \
|
||||
&& wget https://dot.net/v1/dotnet-install.sh -O /tmp/dotnet-install.sh \
|
||||
&& chmod +x /tmp/dotnet-install.sh \
|
||||
&& /tmp/dotnet-install.sh --channel 9.0 --install-dir /usr/share/dotnet \
|
||||
&& ln -sf /usr/share/dotnet/dotnet /usr/local/bin/dotnet \
|
||||
&& rm /tmp/dotnet-install.sh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
# ── Base: .NET SDK + PowerShell + Pester ────────────────────────────
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0-noble AS dev
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl jq openssh-client ca-certificates apt-transport-https gnupg \
|
||||
&& curl -fsSL https://packages.microsoft.com/keys/microsoft.asc \
|
||||
| gpg --dearmor -o /usr/share/keyrings/microsoft-archive-keyring.gpg \
|
||||
&& echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft-archive-keyring.gpg] \
|
||||
https://packages.microsoft.com/ubuntu/24.04/prod noble main" \
|
||||
> /etc/apt/sources.list.d/microsoft-prod.list \
|
||||
&& apt-get update && apt-get install -y --no-install-recommends powershell \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& pwsh -NoProfile -Command \
|
||||
'Set-PSRepository -Name PSGallery -InstallationPolicy Trusted; \
|
||||
Install-Module -Name Pester -MinimumVersion 5.0 -Scope AllUsers -Force' \
|
||||
&& mkdir -p /usr/local/share/powershell/Modules/PSProxmoxVE
|
||||
|
||||
WORKDIR /repo
|
||||
COPY . .
|
||||
CMD ["pwsh", "-NoProfile"]
|
||||
|
||||
RUN dotnet publish src/PSProxmoxVE/PSProxmoxVE.csproj \
|
||||
--configuration Release --framework net9.0 --output ./publish/net9.0 \
|
||||
&& rm -f ./publish/net9.0/PSProxmoxVE.deps.json \
|
||||
&& pwsh -NoProfile -Command ' \
|
||||
Install-Module -Name Pester -MinimumVersion 5.0 -Force -Scope AllUsers; \
|
||||
$modulePath = "/usr/local/share/powershell/Modules/PSProxmoxVE"; \
|
||||
New-Item -ItemType Directory -Path $modulePath -Force | Out-Null; \
|
||||
Copy-Item -Path ./publish/net9.0/* -Destination $modulePath -Recurse -Force'
|
||||
# ── Full: adds Terraform + PVE provisioning tools (x86 only) ───────
|
||||
FROM dev AS dev-infra
|
||||
|
||||
# Unset DOTNET_ROOT so PS uses its own bundled runtime
|
||||
ENV DOTNET_ROOT=""
|
||||
ENV DOTNET_MULTILEVEL_LOOKUP=""
|
||||
|
||||
CMD ["pwsh", "-NoProfile", "-Command", " \
|
||||
Import-Module Pester -MinimumVersion 5.0; \
|
||||
$config = New-PesterConfiguration; \
|
||||
$config.Run.Path = 'tests/PSProxmoxVE.Tests'; \
|
||||
$config.Run.Exit = $true; \
|
||||
$config.Filter.ExcludeTag = @('Integration'); \
|
||||
$config.Output.Verbosity = 'Detailed'; \
|
||||
Invoke-Pester -Configuration $config"]
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
dosfstools mtools sshpass python3 xorriso gnupg \
|
||||
&& curl -fsSL https://apt.releases.hashicorp.com/gpg \
|
||||
| gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg \
|
||||
&& echo "deb [arch=amd64 signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
|
||||
https://apt.releases.hashicorp.com noble main" \
|
||||
> /etc/apt/sources.list.d/hashicorp.list \
|
||||
&& curl -fsSL https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg \
|
||||
-o /usr/share/keyrings/proxmox-release-bookworm.gpg \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/proxmox-release-bookworm.gpg] \
|
||||
http://download.proxmox.com/debian/pve bookworm pve-no-subscription" \
|
||||
> /etc/apt/sources.list.d/proxmox-pve.list \
|
||||
&& apt-get update && apt-get install -y --no-install-recommends \
|
||||
terraform proxmox-auto-install-assistant qemu-utils \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env bash
|
||||
# Helper script for the dev/test containers.
|
||||
#
|
||||
# Usage:
|
||||
# ./tests/dev.sh # Start dev container and open pwsh shell
|
||||
# ./tests/dev.sh build # Build the module inside the container
|
||||
# ./tests/dev.sh test # Run unit tests
|
||||
# ./tests/dev.sh integration # Run integration tests against existing PVE (needs .env.test)
|
||||
# ./tests/dev.sh provision # Full CI flow: provision → test → cleanup (x86 only)
|
||||
# ./tests/dev.sh cleanup # Destroy provisioned VMs (x86 only)
|
||||
# ./tests/dev.sh stop # Stop all containers
|
||||
# ./tests/dev.sh rebuild # Rebuild container image(s)
|
||||
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
COMPOSE="docker compose -f tests/docker-compose.test.yml"
|
||||
DEV_CONTAINER="psproxmoxve-dev"
|
||||
INFRA_CONTAINER="psproxmoxve-dev-infra"
|
||||
MODULE_PATH="/usr/local/share/powershell/Modules/PSProxmoxVE"
|
||||
RUN_INTEGRATION="tests/infrastructure/scripts/run-integration.sh"
|
||||
|
||||
ensure_dev() {
|
||||
if ! docker inspect "$DEV_CONTAINER" --format '{{.State.Running}}' 2>/dev/null | grep -q true; then
|
||||
echo "Starting dev container..."
|
||||
$COMPOSE up -d dev
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_infra() {
|
||||
if ! docker inspect "$INFRA_CONTAINER" --format '{{.State.Running}}' 2>/dev/null | grep -q true; then
|
||||
echo "Starting infra container (x86 only)..."
|
||||
$COMPOSE --profile infra up -d dev-infra
|
||||
fi
|
||||
}
|
||||
|
||||
build_module() {
|
||||
local container="$1"
|
||||
docker exec "$container" bash -c "
|
||||
dotnet publish src/PSProxmoxVE/PSProxmoxVE.csproj \
|
||||
-c Release -f netstandard2.0 -o /tmp/publish 2>&1 | tail -1 && \
|
||||
cp -r /tmp/publish/* $MODULE_PATH/ && \
|
||||
echo 'Module installed to $MODULE_PATH'
|
||||
"
|
||||
}
|
||||
|
||||
case "${1:-shell}" in
|
||||
shell)
|
||||
ensure_dev
|
||||
docker exec -it "$DEV_CONTAINER" pwsh -NoProfile
|
||||
;;
|
||||
|
||||
build)
|
||||
ensure_dev
|
||||
build_module "$DEV_CONTAINER"
|
||||
;;
|
||||
|
||||
test)
|
||||
ensure_dev
|
||||
build_module "$DEV_CONTAINER"
|
||||
docker exec "$DEV_CONTAINER" pwsh -NoProfile -Command "
|
||||
\$config = New-PesterConfiguration
|
||||
\$config.Run.Path = 'tests/PSProxmoxVE.Tests'
|
||||
\$config.Run.Exit = \$true
|
||||
\$config.Filter.ExcludeTag = @('Integration')
|
||||
\$config.Output.Verbosity = 'Detailed'
|
||||
Invoke-Pester -Configuration \$config
|
||||
"
|
||||
;;
|
||||
|
||||
integration)
|
||||
# Run integration tests against a pre-existing PVE (set via .env.test)
|
||||
ensure_dev
|
||||
build_module "$DEV_CONTAINER"
|
||||
docker exec "$DEV_CONTAINER" bash -c "
|
||||
SKIP_PROVISION=true bash $RUN_INTEGRATION test ${2:-all}
|
||||
"
|
||||
;;
|
||||
|
||||
provision)
|
||||
# Full CI lifecycle: provision → test → cleanup (x86 infra container)
|
||||
ensure_infra
|
||||
build_module "$INFRA_CONTAINER"
|
||||
docker exec "$INFRA_CONTAINER" bash "$RUN_INTEGRATION" all "${2:-all}"
|
||||
;;
|
||||
|
||||
cleanup)
|
||||
# Destroy provisioned VMs
|
||||
ensure_infra
|
||||
docker exec "$INFRA_CONTAINER" bash "$RUN_INTEGRATION" cleanup
|
||||
;;
|
||||
|
||||
stop)
|
||||
$COMPOSE --profile infra down
|
||||
;;
|
||||
|
||||
rebuild)
|
||||
$COMPOSE --profile infra down
|
||||
$COMPOSE build --no-cache dev
|
||||
$COMPOSE --profile infra build --no-cache dev-infra
|
||||
$COMPOSE up -d dev
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $0 {shell|build|test|integration|provision|cleanup|stop|rebuild}"
|
||||
echo ""
|
||||
echo " shell Open pwsh in the dev container"
|
||||
echo " build Build the module"
|
||||
echo " test Run unit tests"
|
||||
echo " integration Run integration tests against existing PVE (.env.test)"
|
||||
echo " provision Full CI flow: provision → test → cleanup (x86 only)"
|
||||
echo " cleanup Destroy provisioned VMs (x86 only)"
|
||||
echo " stop Stop all containers"
|
||||
echo " rebuild Rebuild container images"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,50 @@
|
||||
## PSProxmoxVE dev/test containers
|
||||
##
|
||||
## Default (works on ARM Macs + x86):
|
||||
## docker compose -f tests/docker-compose.test.yml up -d
|
||||
## docker exec -it psproxmoxve-dev pwsh
|
||||
##
|
||||
## Full CI infra (x86 only — adds Terraform + PVE provisioning tools):
|
||||
## docker compose -f tests/docker-compose.test.yml --profile infra up -d
|
||||
## docker exec -it psproxmoxve-dev-infra bash
|
||||
##
|
||||
## Stop:
|
||||
## docker compose -f tests/docker-compose.test.yml down
|
||||
|
||||
services:
|
||||
dev:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: tests/Dockerfile.test
|
||||
target: dev
|
||||
container_name: psproxmoxve-dev
|
||||
volumes:
|
||||
- ..:/repo
|
||||
working_dir: /repo
|
||||
stdin_open: true
|
||||
tty: true
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- path: .env.test
|
||||
required: false
|
||||
|
||||
dev-infra:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: tests/Dockerfile.test
|
||||
target: dev-infra
|
||||
container_name: psproxmoxve-dev-infra
|
||||
profiles: [infra]
|
||||
volumes:
|
||||
- ..:/repo
|
||||
- pve-isos:/opt/pve-isos
|
||||
working_dir: /repo
|
||||
stdin_open: true
|
||||
tty: true
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- path: .env.test
|
||||
required: false
|
||||
|
||||
volumes:
|
||||
pve-isos:
|
||||
Reference in New Issue
Block a user