name: "helm: lint and test charts" on: push: branches: [ master ] paths: ['k8s/**'] pull_request: branches: [ master ] paths: ['k8s/**'] permissions: contents: read jobs: lint-test: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 with: fetch-depth: 0 - name: Set up Helm uses: azure/setup-helm@v4 with: version: v3.18.4 - uses: actions/setup-python@v6 with: python-version: '3.9' check-latest: true - name: Set up chart-testing uses: helm/chart-testing-action@v2.8.0 - name: Run chart-testing (list-changed) id: list-changed run: | changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }} --chart-dirs k8s/charts) if [[ -n "$changed" ]]; then echo "::set-output name=changed::true" fi - name: Run chart-testing (lint) run: ct lint --target-branch ${{ github.event.repository.default_branch }} --all --validate-maintainers=false --chart-dirs k8s/charts - name: Verify template rendering run: | set -e CHART_DIR="k8s/charts/seaweedfs" echo "=== Testing default configuration ===" helm template test $CHART_DIR > /tmp/default.yaml echo "✓ Default configuration renders successfully" echo "=== Testing with S3 enabled ===" helm template test $CHART_DIR --set s3.enabled=true > /tmp/s3.yaml grep -q "kind: Deployment" /tmp/s3.yaml && grep -q "seaweedfs-s3" /tmp/s3.yaml echo "✓ S3 deployment renders correctly" echo "=== Testing with all-in-one mode ===" helm template test $CHART_DIR --set allInOne.enabled=true > /tmp/allinone.yaml grep -q "seaweedfs-all-in-one" /tmp/allinone.yaml echo "✓ All-in-one deployment renders correctly" echo "=== Testing with security enabled ===" helm template test $CHART_DIR --set global.enableSecurity=true > /tmp/security.yaml grep -q "security-config" /tmp/security.yaml echo "✓ Security configuration renders correctly" echo "=== Testing with monitoring enabled ===" helm template test $CHART_DIR \ --set global.monitoring.enabled=true \ --set global.monitoring.gatewayHost=prometheus \ --set global.monitoring.gatewayPort=9091 > /tmp/monitoring.yaml echo "✓ Monitoring configuration renders correctly" echo "=== Testing with PVC storage ===" helm template test $CHART_DIR \ --set master.data.type=persistentVolumeClaim \ --set master.data.size=10Gi \ --set master.data.storageClass=standard > /tmp/pvc.yaml grep -q "PersistentVolumeClaim" /tmp/pvc.yaml echo "✓ PVC configuration renders correctly" echo "=== Testing with custom replicas ===" helm template test $CHART_DIR \ --set master.replicas=3 \ --set filer.replicas=2 \ --set volume.replicas=3 > /tmp/replicas.yaml echo "✓ Custom replicas configuration renders correctly" echo "=== Testing filer with S3 gateway ===" helm template test $CHART_DIR \ --set filer.s3.enabled=true \ --set filer.s3.enableAuth=true > /tmp/filer-s3.yaml echo "✓ Filer S3 gateway renders correctly" echo "=== Testing SFTP enabled ===" helm template test $CHART_DIR --set sftp.enabled=true > /tmp/sftp.yaml grep -q "seaweedfs-sftp" /tmp/sftp.yaml echo "✓ SFTP deployment renders correctly" echo "=== Testing ingress configurations ===" helm template test $CHART_DIR \ --set master.ingress.enabled=true \ --set filer.ingress.enabled=true \ --set s3.enabled=true \ --set s3.ingress.enabled=true > /tmp/ingress.yaml grep -q "kind: Ingress" /tmp/ingress.yaml echo "✓ Ingress configurations render correctly" echo "=== Testing COSI driver ===" helm template test $CHART_DIR --set cosi.enabled=true > /tmp/cosi.yaml grep -q "seaweedfs-cosi" /tmp/cosi.yaml echo "✓ COSI driver renders correctly" echo "" echo "✅ All template rendering tests passed!" - name: Verify all-in-one template rendering run: | set -e CHART_DIR="k8s/charts/seaweedfs" echo "=== Testing all-in-one with custom replicas ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.replicas=2 > /tmp/allinone-replicas.yaml grep -q "replicas: 2" /tmp/allinone-replicas.yaml echo "✓ All-in-one replicas configuration works" echo "=== Testing all-in-one with S3 enabled ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.s3.enabled=true > /tmp/allinone-s3.yaml grep -q "\-s3" /tmp/allinone-s3.yaml grep -q "swfs-s3" /tmp/allinone-s3.yaml echo "✓ All-in-one S3 configuration works" echo "=== Testing all-in-one with custom S3 port ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.s3.enabled=true \ --set allInOne.s3.port=9000 > /tmp/allinone-s3-port.yaml grep -q "port: 9000" /tmp/allinone-s3-port.yaml echo "✓ All-in-one custom S3 port works" echo "=== Testing all-in-one with S3 auth ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.s3.enabled=true \ --set allInOne.s3.enableAuth=true > /tmp/allinone-s3-auth.yaml grep -q "config-s3-users" /tmp/allinone-s3-auth.yaml grep -q "s3.config=" /tmp/allinone-s3-auth.yaml echo "✓ All-in-one S3 auth configuration works" echo "=== Testing all-in-one with S3 domainName ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.s3.enabled=true \ --set allInOne.s3.domainName=s3.example.com > /tmp/allinone-s3-domain.yaml grep -q "s3.domainName=s3.example.com" /tmp/allinone-s3-domain.yaml echo "✓ All-in-one S3 domain name configuration works" echo "=== Testing all-in-one with SFTP enabled ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.sftp.enabled=true > /tmp/allinone-sftp.yaml grep -q "\-sftp" /tmp/allinone-sftp.yaml grep -q "swfs-sftp" /tmp/allinone-sftp.yaml echo "✓ All-in-one SFTP configuration works" echo "=== Testing all-in-one with custom SFTP port ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.sftp.enabled=true \ --set allInOne.sftp.port=2222 > /tmp/allinone-sftp-port.yaml grep -q "sftp.port=2222" /tmp/allinone-sftp-port.yaml echo "✓ All-in-one custom SFTP port works" echo "=== Testing all-in-one with extraArgs ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set 'allInOne.extraArgs[0]=-customFlag' \ --set 'allInOne.extraArgs[1]=customValue' > /tmp/allinone-extraargs.yaml grep -q "\-customFlag" /tmp/allinone-extraargs.yaml echo "✓ All-in-one extraArgs configuration works" echo "=== Testing all-in-one with RollingUpdate strategy ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.updateStrategy.type=RollingUpdate > /tmp/allinone-strategy.yaml grep -q "type: RollingUpdate" /tmp/allinone-strategy.yaml echo "✓ All-in-one update strategy configuration works" echo "=== Testing all-in-one with PVC storage ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.data.type=persistentVolumeClaim \ --set allInOne.data.size=50Gi \ --set allInOne.data.storageClass=fast > /tmp/allinone-pvc.yaml grep -q "PersistentVolumeClaim" /tmp/allinone-pvc.yaml grep -q "storage: 50Gi" /tmp/allinone-pvc.yaml grep -q "storageClassName: fast" /tmp/allinone-pvc.yaml echo "✓ All-in-one PVC configuration works" echo "=== Testing all-in-one with existing claim ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.data.type=existingClaim \ --set allInOne.data.claimName=my-existing-pvc > /tmp/allinone-existing-claim.yaml grep -q "claimName: my-existing-pvc" /tmp/allinone-existing-claim.yaml echo "✓ All-in-one existing claim configuration works" echo "=== Testing all-in-one with hostPath storage ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.data.type=hostPath \ --set allInOne.data.hostPathPrefix=/mnt/seaweedfs > /tmp/allinone-hostpath.yaml grep -q "hostPath:" /tmp/allinone-hostpath.yaml grep -q "/mnt/seaweedfs/seaweedfs-all-in-one-data" /tmp/allinone-hostpath.yaml echo "✓ All-in-one hostPath configuration works" echo "=== Testing all-in-one with ingress (S3) ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.s3.enabled=true \ --set allInOne.ingress.enabled=true \ --set allInOne.ingress.s3.enabled=true \ --set allInOne.ingress.host=seaweedfs.example.com > /tmp/allinone-ingress-s3.yaml grep -q "kind: Ingress" /tmp/allinone-ingress-s3.yaml grep -q "seaweedfs-all-in-one-s3" /tmp/allinone-ingress-s3.yaml echo "✓ All-in-one S3 ingress configuration works" echo "=== Testing all-in-one with ingress (filer) ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.ingress.enabled=true \ --set allInOne.ingress.filer.enabled=true > /tmp/allinone-ingress-filer.yaml grep -q "seaweedfs-all-in-one-filer" /tmp/allinone-ingress-filer.yaml echo "✓ All-in-one filer ingress configuration works" echo "=== Testing all-in-one with ingress (master) ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.ingress.enabled=true \ --set allInOne.ingress.master.enabled=true > /tmp/allinone-ingress-master.yaml grep -q "seaweedfs-all-in-one-master" /tmp/allinone-ingress-master.yaml echo "✓ All-in-one master ingress configuration works" echo "=== Testing all-in-one with secretExtraEnvironmentVars ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set 'allInOne.secretExtraEnvironmentVars.DB_PASSWORD.secretKeyRef.name=db-secret' \ --set 'allInOne.secretExtraEnvironmentVars.DB_PASSWORD.secretKeyRef.key=password' > /tmp/allinone-secret-env.yaml grep -q "DB_PASSWORD" /tmp/allinone-secret-env.yaml grep -q "secretKeyRef" /tmp/allinone-secret-env.yaml echo "✓ All-in-one secretExtraEnvironmentVars configuration works" echo "=== Testing all-in-one with security enabled ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set global.enableSecurity=true > /tmp/allinone-security.yaml grep -q "security-config" /tmp/allinone-security.yaml grep -q "ca-cert" /tmp/allinone-security.yaml echo "✓ All-in-one security configuration works" echo "=== Testing all-in-one combined configuration ===" helm template test $CHART_DIR \ --set allInOne.enabled=true \ --set allInOne.replicas=1 \ --set allInOne.s3.enabled=true \ --set allInOne.s3.port=9000 \ --set allInOne.s3.enableAuth=true \ --set allInOne.sftp.enabled=true \ --set allInOne.sftp.port=2222 \ --set allInOne.data.type=persistentVolumeClaim \ --set allInOne.data.size=100Gi \ --set allInOne.ingress.enabled=true \ --set allInOne.ingress.s3.enabled=true \ --set allInOne.ingress.filer.enabled=true > /tmp/allinone-combined.yaml grep -q "replicas: 1" /tmp/allinone-combined.yaml grep -q "s3.port=9000" /tmp/allinone-combined.yaml grep -q "sftp.port=2222" /tmp/allinone-combined.yaml grep -q "storage: 100Gi" /tmp/allinone-combined.yaml grep -q "kind: Ingress" /tmp/allinone-combined.yaml echo "✓ All-in-one combined configuration works" echo "" echo "✅ All all-in-one template rendering tests passed!" - name: Create kind cluster uses: helm/kind-action@v1.13.0 - name: Run chart-testing (install) run: ct install --target-branch ${{ github.event.repository.default_branch }} --all --chart-dirs k8s/charts - name: Deploy all-in-one cluster with S3 run: | set -e echo "=== Deploying SeaweedFS all-in-one cluster with S3 ===" # Install the all-in-one chart helm install seaweedfs-test k8s/charts/seaweedfs \ --set allInOne.enabled=true \ --set allInOne.s3.enabled=true \ --set allInOne.data.type=emptyDir \ --set master.enabled=false \ --set volume.enabled=false \ --set filer.enabled=false \ --set allInOne.resources.requests.cpu=100m \ --set allInOne.resources.requests.memory=256Mi \ --set allInOne.resources.limits.cpu=500m \ --set allInOne.resources.limits.memory=512Mi \ --wait \ --timeout 5m echo "✓ Helm install completed" - name: Wait for all-in-one pod to be ready run: | set -e echo "=== Waiting for all-in-one pod to be ready ===" kubectl wait --for=condition=ready pod \ -l app.kubernetes.io/component=seaweedfs-all-in-one \ --timeout=300s echo "✓ All-in-one pod is ready" # Show pod status kubectl get pods -l app.kubernetes.io/component=seaweedfs-all-in-one -o wide # Show logs echo "=== Pod logs ===" kubectl logs -l app.kubernetes.io/component=seaweedfs-all-in-one --tail=50 - name: Test Master API run: | set -e echo "=== Testing Master API ===" # Port-forward to master kubectl port-forward svc/seaweedfs-all-in-one 9333:9333 & PF_PID=$! sleep 5 # Test master cluster status echo "Testing /cluster/status endpoint..." RESPONSE=$(curl -s http://localhost:9333/cluster/status) echo "Response: $RESPONSE" if echo "$RESPONSE" | grep -q "IsLeader"; then echo "✓ Master API is responding correctly" else echo "✗ Master API test failed" kill $PF_PID 2>/dev/null || true exit 1 fi kill $PF_PID 2>/dev/null || true - name: Test Filer API run: | set -e echo "=== Testing Filer API ===" # Port-forward to filer kubectl port-forward svc/seaweedfs-all-in-one 8888:8888 & PF_PID=$! sleep 5 # Test filer root echo "Testing filer root endpoint..." RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8888/) echo "Response code: $RESPONSE" if [ "$RESPONSE" = "200" ]; then echo "✓ Filer API is responding correctly" else echo "✗ Filer API test failed with code: $RESPONSE" kill $PF_PID 2>/dev/null || true exit 1 fi # Test file upload and download echo "Testing file upload..." echo "Hello SeaweedFS" > /tmp/test-file.txt curl -s -F "file=@/tmp/test-file.txt" http://localhost:8888/test-file.txt echo "Testing file download..." CONTENT=$(curl -s http://localhost:8888/test-file.txt) if [ "$CONTENT" = "Hello SeaweedFS" ]; then echo "✓ File upload/download works correctly" else echo "✗ File content mismatch: $CONTENT" kill $PF_PID 2>/dev/null || true exit 1 fi # Cleanup curl -s -X DELETE http://localhost:8888/test-file.txt kill $PF_PID 2>/dev/null || true - name: Test S3 API run: | set -e echo "=== Testing S3 API ===" # Port-forward to S3 kubectl port-forward svc/seaweedfs-all-in-one 8333:8333 & PF_PID=$! sleep 5 # Test S3 status endpoint echo "Testing S3 /status endpoint..." RESPONSE=$(curl -s http://localhost:8333/status) echo "Response: $RESPONSE" if echo "$RESPONSE" | grep -q "version"; then echo "✓ S3 API is responding correctly" else echo "✗ S3 API test failed" kill $PF_PID 2>/dev/null || true exit 1 fi kill $PF_PID 2>/dev/null || true - name: Test S3 operations with AWS CLI run: | set -e echo "=== Testing S3 operations with AWS CLI ===" # Install AWS CLI pip install awscli # Port-forward to S3 kubectl port-forward svc/seaweedfs-all-in-one 8333:8333 & PF_PID=$! sleep 5 # Configure AWS CLI for local S3 export AWS_ACCESS_KEY_ID=any export AWS_SECRET_ACCESS_KEY=any export AWS_DEFAULT_REGION=us-east-1 S3_ENDPOINT="http://localhost:8333" # Create a bucket echo "Creating test bucket..." aws --endpoint-url $S3_ENDPOINT s3 mb s3://test-bucket || true echo "✓ Bucket created" # List buckets echo "Listing buckets..." aws --endpoint-url $S3_ENDPOINT s3 ls echo "✓ Bucket listing works" # Upload a file echo "Uploading test file..." echo "Hello from S3 test" > /tmp/s3-test-file.txt aws --endpoint-url $S3_ENDPOINT s3 cp /tmp/s3-test-file.txt s3://test-bucket/test-file.txt echo "✓ File uploaded" # List objects echo "Listing objects..." aws --endpoint-url $S3_ENDPOINT s3 ls s3://test-bucket/ echo "✓ Object listing works" # Download the file echo "Downloading test file..." aws --endpoint-url $S3_ENDPOINT s3 cp s3://test-bucket/test-file.txt /tmp/s3-downloaded.txt # Verify content CONTENT=$(cat /tmp/s3-downloaded.txt) if [ "$CONTENT" = "Hello from S3 test" ]; then echo "✓ File content matches" else echo "✗ File content mismatch: $CONTENT" kill $PF_PID 2>/dev/null || true exit 1 fi # Delete the file echo "Deleting test file..." aws --endpoint-url $S3_ENDPOINT s3 rm s3://test-bucket/test-file.txt echo "✓ File deleted" # Delete the bucket echo "Deleting test bucket..." aws --endpoint-url $S3_ENDPOINT s3 rb s3://test-bucket echo "✓ Bucket deleted" kill $PF_PID 2>/dev/null || true echo "" echo "✅ All S3 operations completed successfully!" - name: Cleanup if: always() run: | echo "=== Cleaning up ===" helm uninstall seaweedfs-test || true echo "✓ Cleanup completed"