mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-07 10:46:57 +00:00
fix issue with mismatched scopes locally
This commit is contained in:
Executable
+432
@@ -0,0 +1,432 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# ATCR End-to-End Test Script
|
||||
# Tests single-arch and multi-arch image push/pull flows
|
||||
#
|
||||
# Usage:
|
||||
# ./test-e2e.sh # Run full test suite
|
||||
# ./test-e2e.sh --multi # Skip to multi-arch test only
|
||||
# REGISTRY=localhost:5000 ./test-e2e.sh # Custom registry
|
||||
# NAMESPACE=myuser ./test-e2e.sh # Custom namespace
|
||||
# VERBOSE=0 ./test-e2e.sh # Hide docker output
|
||||
#
|
||||
# To see bash command execution, edit this file and uncomment 'set -x' below
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Verbose mode - shows docker command output
|
||||
# Set VERBOSE=0 to hide docker output: VERBOSE=0 ./test-e2e.sh
|
||||
VERBOSE="${VERBOSE:-1}"
|
||||
|
||||
# Bash trace mode - shows every bash command as it executes
|
||||
# Uncomment the line below to see bash commands as they execute
|
||||
# set -x
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
REGISTRY="${REGISTRY:-127.0.0.1:5000}"
|
||||
NAMESPACE="${NAMESPACE:-evan.jarrett.net}"
|
||||
IMAGE_NAME="test-image"
|
||||
TAG="latest"
|
||||
MULTI_ARCH_TAG="multiarch"
|
||||
|
||||
# Full image references
|
||||
SINGLE_ARCH_IMAGE="${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${TAG}"
|
||||
MULTI_ARCH_IMAGE="${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${MULTI_ARCH_TAG}"
|
||||
AMD64_IMAGE="${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${TAG}-amd64"
|
||||
ARM64_IMAGE="${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${TAG}-arm64"
|
||||
|
||||
# Temporary directory for test images
|
||||
BUILD_DIR=$(mktemp -d)
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
log_info "Cleaning up..."
|
||||
rm -rf ${BUILD_DIR}
|
||||
|
||||
# Clean up any dangling manifest lists
|
||||
docker manifest rm ${MULTI_ARCH_IMAGE} 2>/dev/null || true
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
# Logging functions
|
||||
log_info() {
|
||||
echo -e "${GREEN}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[WARN]${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "\n${GREEN}==>${NC} $1"
|
||||
}
|
||||
|
||||
log_cmd() {
|
||||
echo -e "${BLUE}[CMD]${NC} $*"
|
||||
if [ "$VERBOSE" = "1" ]; then
|
||||
"$@"
|
||||
else
|
||||
"$@" > /dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if docker compose services are running
|
||||
check_compose_services() {
|
||||
log_step "Checking docker compose services..."
|
||||
|
||||
if ! docker compose ps | grep -q "Up"; then
|
||||
log_warn "Some services may not be running. Starting services..."
|
||||
docker compose up -d
|
||||
sleep 5
|
||||
fi
|
||||
|
||||
# Check for errors in logs
|
||||
log_info "Checking for errors in service logs..."
|
||||
if docker compose logs --tail=50 | grep -i "error" | grep -v "level=error msg=\"error processing" | grep -v "test"; then
|
||||
log_warn "Found some errors in logs (may be normal)"
|
||||
else
|
||||
log_info "No critical errors found in recent logs"
|
||||
fi
|
||||
}
|
||||
|
||||
# Build a simple test image
|
||||
build_single_arch_image() {
|
||||
log_step "Building single-arch test image..."
|
||||
|
||||
cat > ${BUILD_DIR}/Dockerfile <<EOF
|
||||
FROM alpine:latest
|
||||
|
||||
# Add some content to make the image non-trivial
|
||||
RUN apk add --no-cache curl bash
|
||||
|
||||
# Create a test file with some content
|
||||
RUN echo "This is a test image created at \$(date)" > /test.txt
|
||||
RUN echo "Architecture: \$(uname -m)" >> /test.txt
|
||||
|
||||
# Add a simple script
|
||||
RUN echo '#!/bin/sh' > /test.sh && \\
|
||||
echo 'echo "Test image running successfully!"' >> /test.sh && \\
|
||||
echo 'cat /test.txt' >> /test.sh && \\
|
||||
chmod +x /test.sh
|
||||
|
||||
CMD ["/test.sh"]
|
||||
EOF
|
||||
|
||||
log_cmd docker build -t ${SINGLE_ARCH_IMAGE} ${BUILD_DIR}
|
||||
log_info "Built single-arch image: ${SINGLE_ARCH_IMAGE}"
|
||||
}
|
||||
|
||||
# Build multi-arch images using docker manifest create (old school!)
|
||||
build_multi_arch_images() {
|
||||
log_step "Building multi-arch images (amd64 and arm64) using docker manifest..."
|
||||
|
||||
# Create Dockerfile for multi-arch builds
|
||||
cat > ${BUILD_DIR}/Dockerfile.multiarch <<EOF
|
||||
FROM alpine:latest
|
||||
|
||||
ARG TARGETARCH=unknown
|
||||
ARG TARGETOS=linux
|
||||
|
||||
# Add some content to make the image non-trivial
|
||||
RUN apk add --no-cache curl bash
|
||||
|
||||
# Create a test file with arch info
|
||||
RUN echo "This is a multi-arch test image" > /test.txt
|
||||
RUN echo "Target OS: \${TARGETOS}" >> /test.txt
|
||||
RUN echo "Target Architecture: \${TARGETARCH}" >> /test.txt
|
||||
RUN echo "Built at: \$(date)" >> /test.txt
|
||||
|
||||
# Add a simple script
|
||||
RUN echo '#!/bin/sh' > /test.sh && \\
|
||||
echo 'echo "Multi-arch test image running!"' >> /test.sh && \\
|
||||
echo 'cat /test.txt' >> /test.sh && \\
|
||||
chmod +x /test.sh
|
||||
|
||||
CMD ["/test.sh"]
|
||||
EOF
|
||||
|
||||
# Build amd64 image
|
||||
log_info "Building amd64 image..."
|
||||
log_cmd docker build \
|
||||
--platform linux/amd64 \
|
||||
--build-arg TARGETARCH=amd64 \
|
||||
--build-arg TARGETOS=linux \
|
||||
-t ${AMD64_IMAGE} \
|
||||
-f ${BUILD_DIR}/Dockerfile.multiarch \
|
||||
${BUILD_DIR}
|
||||
|
||||
# Push amd64 image
|
||||
log_info "Pushing amd64 image..."
|
||||
echo -e "${BLUE}[CMD]${NC} docker push ${AMD64_IMAGE}"
|
||||
if ! docker push ${AMD64_IMAGE}; then
|
||||
log_error "Failed to push amd64 image"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Build arm64 image
|
||||
log_info "Building arm64 image..."
|
||||
log_cmd docker build \
|
||||
--platform linux/arm64 \
|
||||
--build-arg TARGETARCH=arm64 \
|
||||
--build-arg TARGETOS=linux \
|
||||
-t ${ARM64_IMAGE} \
|
||||
-f ${BUILD_DIR}/Dockerfile.multiarch \
|
||||
${BUILD_DIR}
|
||||
|
||||
# Push arm64 image
|
||||
log_info "Pushing arm64 image..."
|
||||
echo -e "${BLUE}[CMD]${NC} docker push ${ARM64_IMAGE}"
|
||||
if ! docker push ${ARM64_IMAGE}; then
|
||||
log_error "Failed to push arm64 image"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create manifest list
|
||||
log_info "Creating multi-arch manifest list..."
|
||||
echo -e "${BLUE}[CMD]${NC} docker manifest create --insecure ${MULTI_ARCH_IMAGE} ${AMD64_IMAGE} ${ARM64_IMAGE}"
|
||||
docker manifest create --insecure ${MULTI_ARCH_IMAGE} \
|
||||
${AMD64_IMAGE} \
|
||||
${ARM64_IMAGE}
|
||||
|
||||
# Annotate manifests with platform info
|
||||
log_info "Annotating manifest with platform info..."
|
||||
docker manifest annotate ${MULTI_ARCH_IMAGE} ${AMD64_IMAGE} \
|
||||
--os linux --arch amd64
|
||||
docker manifest annotate ${MULTI_ARCH_IMAGE} ${ARM64_IMAGE} \
|
||||
--os linux --arch arm64
|
||||
|
||||
# Push the manifest list
|
||||
log_info "Pushing multi-arch manifest list..."
|
||||
echo -e "${BLUE}[CMD]${NC} docker manifest push --insecure ${MULTI_ARCH_IMAGE}"
|
||||
docker manifest push --insecure ${MULTI_ARCH_IMAGE}
|
||||
|
||||
log_info "Multi-arch manifest created and pushed: ${MULTI_ARCH_IMAGE}"
|
||||
}
|
||||
|
||||
# Push single-arch image and verify digest
|
||||
push_single_arch_image() {
|
||||
log_step "Pushing single-arch image..."
|
||||
|
||||
echo -e "${BLUE}[CMD]${NC} docker push ${SINGLE_ARCH_IMAGE}"
|
||||
local push_output
|
||||
push_output=$(docker push ${SINGLE_ARCH_IMAGE} 2>&1 | tee /dev/tty)
|
||||
|
||||
# Extract and verify digest
|
||||
local digest
|
||||
digest=$(echo "$push_output" | grep -oP 'digest: \K[a-z0-9:]+' | tail -1)
|
||||
|
||||
if [ -z "$digest" ]; then
|
||||
log_error "Failed to get digest from push output"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Pushed with digest: ${digest}"
|
||||
|
||||
# Verify we can reference by digest
|
||||
log_info "Verifying digest reference..."
|
||||
echo -e "${BLUE}[CMD]${NC} docker manifest inspect --insecure ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}@${digest}"
|
||||
docker manifest inspect --insecure "${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}@${digest}"
|
||||
log_info "Digest verification successful!"
|
||||
}
|
||||
|
||||
# Verify multi-arch manifest
|
||||
verify_multi_arch_manifest() {
|
||||
log_step "Verifying multi-arch manifest..."
|
||||
|
||||
echo -e "${BLUE}[CMD]${NC} docker manifest inspect --insecure ${MULTI_ARCH_IMAGE}"
|
||||
local manifest
|
||||
manifest=$(docker manifest inspect --insecure ${MULTI_ARCH_IMAGE} | tee /dev/tty)
|
||||
|
||||
# Check for both architectures (check for "amd64" and "arm64" in platform.architecture)
|
||||
if echo "$manifest" | grep -q '"architecture": "amd64"'; then
|
||||
log_info "Found linux/amd64 manifest"
|
||||
else
|
||||
log_error "Missing linux/amd64 manifest"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if echo "$manifest" | grep -q '"architecture": "arm64"'; then
|
||||
log_info "Found linux/arm64 manifest"
|
||||
else
|
||||
log_error "Missing linux/arm64 manifest"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract digest
|
||||
local digest
|
||||
digest=$(echo "$manifest" | jq -r '.manifests[0].digest' 2>/dev/null || echo "$manifest" | grep -oP 'sha256:[a-f0-9]+' | head -1)
|
||||
|
||||
if [ -n "$digest" ]; then
|
||||
log_info "Multi-arch manifest digest: ${digest}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Remove local images
|
||||
cleanup_local_images() {
|
||||
log_step "Removing local images..."
|
||||
|
||||
echo -e "${BLUE}[CMD]${NC} docker rmi ${SINGLE_ARCH_IMAGE}"
|
||||
docker rmi ${SINGLE_ARCH_IMAGE} || true
|
||||
|
||||
echo -e "${BLUE}[CMD]${NC} docker rmi ${AMD64_IMAGE}"
|
||||
docker rmi ${AMD64_IMAGE} || true
|
||||
|
||||
echo -e "${BLUE}[CMD]${NC} docker rmi ${ARM64_IMAGE}"
|
||||
docker rmi ${ARM64_IMAGE} || true
|
||||
|
||||
echo -e "${BLUE}[CMD]${NC} docker rmi ${MULTI_ARCH_IMAGE}"
|
||||
docker rmi ${MULTI_ARCH_IMAGE} || true
|
||||
|
||||
# Clean up manifest list
|
||||
docker manifest rm ${MULTI_ARCH_IMAGE} 2>/dev/null || true
|
||||
|
||||
# Also remove any cached layers
|
||||
log_info "Pruning dangling images..."
|
||||
log_cmd docker image prune -f
|
||||
|
||||
log_info "Local images removed"
|
||||
}
|
||||
|
||||
# Pull images back
|
||||
pull_images() {
|
||||
log_step "Pulling images back from registry..."
|
||||
|
||||
# Pull single-arch image
|
||||
log_info "Pulling single-arch image..."
|
||||
echo -e "${BLUE}[CMD]${NC} docker pull ${SINGLE_ARCH_IMAGE}"
|
||||
if docker pull ${SINGLE_ARCH_IMAGE}; then
|
||||
log_info "Successfully pulled: ${SINGLE_ARCH_IMAGE}"
|
||||
else
|
||||
log_error "Failed to pull single-arch image"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Pull multi-arch image
|
||||
log_info "Pulling multi-arch image..."
|
||||
echo -e "${BLUE}[CMD]${NC} docker pull ${MULTI_ARCH_IMAGE}"
|
||||
if docker pull ${MULTI_ARCH_IMAGE}; then
|
||||
log_info "Successfully pulled: ${MULTI_ARCH_IMAGE}"
|
||||
else
|
||||
log_error "Failed to pull multi-arch image"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Test running the images
|
||||
test_images() {
|
||||
log_step "Testing pulled images..."
|
||||
|
||||
# Test single-arch image
|
||||
log_info "Running single-arch image..."
|
||||
log_cmd docker run --rm ${SINGLE_ARCH_IMAGE}
|
||||
|
||||
# Test multi-arch image
|
||||
log_info "Running multi-arch image..."
|
||||
log_cmd docker run --rm ${MULTI_ARCH_IMAGE}
|
||||
|
||||
log_info "All images ran successfully!"
|
||||
}
|
||||
|
||||
# Check for errors in compose logs after operations
|
||||
check_compose_logs() {
|
||||
log_step "Checking compose logs for errors..."
|
||||
|
||||
local error_count
|
||||
error_count=$(docker compose logs --tail=100 | grep -i "error" | grep -v "level=error msg=\"error processing" | grep -v "test" | wc -l)
|
||||
|
||||
if [ "$error_count" -gt 0 ]; then
|
||||
log_warn "Found ${error_count} error messages in logs:"
|
||||
docker compose logs --tail=100 | grep -i "error" | grep -v "level=error msg=\"error processing" | grep -v "test" | tail -10
|
||||
else
|
||||
log_info "No errors found in compose logs"
|
||||
fi
|
||||
}
|
||||
|
||||
# Multi-arch only test flow
|
||||
multi_arch_only() {
|
||||
log_step "Starting ATCR multi-arch test (skipping single-arch)"
|
||||
log_info "Registry: ${REGISTRY}"
|
||||
log_info "Namespace: ${NAMESPACE}"
|
||||
log_info "Build directory: ${BUILD_DIR}"
|
||||
log_info "Verbose mode: ${VERBOSE} (set VERBOSE=0 to hide docker output)"
|
||||
|
||||
# Check prerequisites
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq &> /dev/null; then
|
||||
log_warn "jq is not installed - some checks may be limited"
|
||||
fi
|
||||
|
||||
# Run multi-arch test steps only
|
||||
check_compose_services
|
||||
build_multi_arch_images
|
||||
verify_multi_arch_manifest
|
||||
cleanup_local_images
|
||||
pull_images
|
||||
log_info "Running multi-arch image..."
|
||||
log_cmd docker run --rm ${MULTI_ARCH_IMAGE}
|
||||
check_compose_logs
|
||||
|
||||
log_step "Multi-arch test completed successfully!"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN}Multi-arch test passed!${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
}
|
||||
|
||||
# Main test flow
|
||||
main() {
|
||||
log_step "Starting ATCR end-to-end test"
|
||||
log_info "Registry: ${REGISTRY}"
|
||||
log_info "Namespace: ${NAMESPACE}"
|
||||
log_info "Build directory: ${BUILD_DIR}"
|
||||
log_info "Verbose mode: ${VERBOSE} (set VERBOSE=0 to hide docker output)"
|
||||
|
||||
# Check prerequisites
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker is not installed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v jq &> /dev/null; then
|
||||
log_warn "jq is not installed - some checks may be limited"
|
||||
fi
|
||||
|
||||
# Run test steps
|
||||
check_compose_services
|
||||
build_single_arch_image
|
||||
push_single_arch_image
|
||||
build_multi_arch_images
|
||||
verify_multi_arch_manifest
|
||||
cleanup_local_images
|
||||
pull_images
|
||||
test_images
|
||||
check_compose_logs
|
||||
|
||||
log_step "End-to-end test completed successfully!"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN}All tests passed!${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
if [ "$1" = "--multi" ]; then
|
||||
multi_arch_only
|
||||
else
|
||||
main "$@"
|
||||
fi
|
||||
Reference in New Issue
Block a user