diff --git a/README.md b/README.md index 0494507..2d633d0 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ - [Installation with helm](#installation-with-helm) - [Prerequisites for local runs](#prerequisites-for-local-runs) - [Jobs configuration](#jobs-configuration) + - [Examples](#examples) - [How does it look in practice?](#how-does-it-look-in-practice) - [Things to remember](#things-to-remember) - [Available params](#available-params) @@ -130,6 +131,16 @@ spec: parallel: true ``` +### Examples + +More example manifests are available in the [`config/samples/`](config/samples/) directory: + +| Example | Description | +|---------|-------------| +| [Quick Start](config/samples/managedjob_quickstart.yaml) | Simple "Hello World" with two sequential jobs | +| [Parallel Processing](config/samples/managedjob_parallel_example.yaml) | Fan-out/fan-in pattern with parallel job execution | +| [Comprehensive Demo](config/samples/managedjob_comprehensive_example.yaml) | Full-featured example showcasing all capabilities: ConfigMaps, Secrets, volumes, resource limits, multi-group dependencies, and parameter inheritance | + ### How does it look in practice? ```yaml @@ -335,6 +346,8 @@ Status colors in the visualization: - **Red**: failed - **Gray**: pending +![kubectl plugin screenshot](public/plugin-screenshot.png) + ## Observability ### Prometheus Metrics diff --git a/config/samples/managedjob_comprehensive_example.yaml b/config/samples/managedjob_comprehensive_example.yaml new file mode 100644 index 0000000..a29a389 --- /dev/null +++ b/config/samples/managedjob_comprehensive_example.yaml @@ -0,0 +1,253 @@ +# Comprehensive ManagedJob Example +# This example demonstrates all capabilities of the jobs-manager-operator +# +# Workflow Overview: +# 1. setup-group: Creates initial configuration (runs first, sequential) +# 2. parallel-workers: Multiple parallel jobs that process data +# 3. aggregation-group: Depends on parallel-workers completion +# 4. notification-group: Final notification job +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: job-config +data: + APP_NAME: "hello-world-demo" + LOG_LEVEL: "info" + greeting.txt: | + Hello from the jobs-manager-operator! + This file was mounted from a ConfigMap. +--- +apiVersion: v1 +kind: Secret +metadata: + name: job-secrets +type: Opaque +stringData: + API_KEY: "demo-secret-key-12345" + DATABASE_URL: "postgres://user:pass@localhost/demo" +--- +apiVersion: jobsmanager.raczylo.com/v1beta1 +kind: ManagedJob +metadata: + name: comprehensive-demo + labels: + app.kubernetes.io/name: comprehensive-demo + app.kubernetes.io/component: demo +spec: + # Retry failed jobs up to 3 times + retries: 3 + + # Spec-level parameters - applied to ALL jobs (can be overridden) + params: + # Environment variables applied globally + env: + - name: GLOBAL_ENV + value: "available-in-all-jobs" + - name: WORKFLOW_ID + value: "demo-workflow-001" + + # Environment variables from ConfigMap (applied to all jobs) + fromEnv: + - configMapRef: + name: job-config + + # Resource defaults for all jobs + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "128Mi" + cpu: "100m" + + # Labels and annotations for all job pods + labels: + managed-by: jobs-manager-operator + environment: demo + annotations: + prometheus.io/scrape: "false" + + # Default restart policy + restartPolicy: OnFailure + + # Default image pull policy + imagePullPolicy: IfNotPresent + + groups: + # ========================================================================= + # GROUP 1: Setup (Sequential, runs first) + # ========================================================================= + - name: setup-group + parallel: false # Jobs in this group run sequentially + jobs: + - name: init-job + image: busybox:1.36 + args: + - /bin/sh + - -c + - | + echo "=== Initialization Job ===" + echo "Workflow ID: $WORKFLOW_ID" + echo "Global Env: $GLOBAL_ENV" + echo "App Name from ConfigMap: $APP_NAME" + echo "Setup complete!" + + - name: validate-config + image: busybox:1.36 + args: + - /bin/sh + - -c + - | + echo "=== Validating Configuration ===" + echo "Checking environment variables..." + test -n "$APP_NAME" && echo "✓ APP_NAME is set" + test -n "$LOG_LEVEL" && echo "✓ LOG_LEVEL is set" + echo "Configuration validated!" + # This job depends on init-job completing successfully + dependencies: + - name: init-job + status: succeeded + + # ========================================================================= + # GROUP 2: Parallel Workers (runs after setup-group) + # ========================================================================= + - name: parallel-workers + parallel: true # Jobs in this group run in parallel + dependencies: + - name: setup-group + status: succeeded + + # Group-level params - override spec-level for this group + params: + env: + - name: GROUP_NAME + value: "parallel-workers" + - name: WORKER_MODE + value: "parallel" + + jobs: + - name: worker-alpha + image: busybox:1.36 + parallel: true + args: + - /bin/sh + - -c + - | + echo "=== Worker Alpha ===" + echo "Processing task A..." + echo "Group: $GROUP_NAME" + echo "Mode: $WORKER_MODE" + sleep 2 + echo "Worker Alpha completed!" + + - name: worker-beta + image: busybox:1.36 + parallel: true + args: + - /bin/sh + - -c + - | + echo "=== Worker Beta ===" + echo "Processing task B..." + sleep 2 + echo "Worker Beta completed!" + # Job-level params - override group and spec level + params: + env: + - name: BETA_SPECIFIC + value: "only-in-worker-beta" + # Custom resource requirements for this job + resources: + requests: + memory: "32Mi" + cpu: "25m" + limits: + memory: "64Mi" + cpu: "50m" + + - name: worker-gamma + image: busybox:1.36 + parallel: true + args: + - /bin/sh + - -c + - | + echo "=== Worker Gamma ===" + echo "Processing task C..." + sleep 2 + echo "Worker Gamma completed!" + + # ========================================================================= + # GROUP 3: Aggregation (depends on parallel-workers) + # ========================================================================= + - name: aggregation-group + parallel: false + dependencies: + - name: parallel-workers + status: succeeded + + # Group-level params with volume mounts + params: + env: + - name: AGGREGATION_MODE + value: "combine-results" + # Mount ConfigMap as a volume + volumes: + - name: config-volume + configMap: + name: job-config + volumeMounts: + - name: config-volume + mountPath: /config + readOnly: true + + jobs: + - name: aggregate-results + image: busybox:1.36 + args: + - /bin/sh + - -c + - | + echo "=== Aggregating Results ===" + echo "Mode: $AGGREGATION_MODE" + echo "" + echo "Reading mounted ConfigMap file:" + cat /config/greeting.txt + echo "" + echo "All worker results aggregated!" + + # ========================================================================= + # GROUP 4: Notification (final step) + # ========================================================================= + - name: notification-group + parallel: false + dependencies: + - name: aggregation-group + status: succeeded + + # Group-level params with secrets + params: + fromEnv: + - secretRef: + name: job-secrets + + jobs: + - name: send-notification + image: busybox:1.36 + args: + - /bin/sh + - -c + - | + echo "=== Sending Notification ===" + echo "Workflow completed successfully!" + echo "" + echo "API Key available: $(test -n "$API_KEY" && echo 'yes' || echo 'no')" + echo "Database URL available: $(test -n "$DATABASE_URL" && echo 'yes' || echo 'no')" + echo "" + echo "Final Summary:" + echo "- Workflow ID: $WORKFLOW_ID" + echo "- App Name: $APP_NAME" + echo "- All groups completed!" + echo "" + echo "🎉 Demo workflow finished successfully!" diff --git a/config/samples/managedjob_parallel_example.yaml b/config/samples/managedjob_parallel_example.yaml new file mode 100644 index 0000000..23f47bf --- /dev/null +++ b/config/samples/managedjob_parallel_example.yaml @@ -0,0 +1,86 @@ +# Parallel Execution ManagedJob Example +# Demonstrates fan-out/fan-in pattern with parallel jobs +# +# Workflow: +# 1. prepare (single job) +# 2. process-1, process-2, process-3 (run in parallel) +# 3. finalize (waits for all parallel jobs) +--- +apiVersion: jobsmanager.raczylo.com/v1beta1 +kind: ManagedJob +metadata: + name: parallel-demo +spec: + retries: 2 + params: + env: + - name: BATCH_ID + value: "batch-001" + + groups: + # Stage 1: Preparation + - name: preparation + jobs: + - name: prepare + image: busybox:1.36 + args: + - /bin/sh + - -c + - | + echo "Preparing batch: $BATCH_ID" + echo "Starting parallel processing..." + + # Stage 2: Parallel Processing (fan-out) + - name: processing + parallel: true + dependencies: + - name: preparation + status: succeeded + jobs: + - name: process-1 + image: busybox:1.36 + parallel: true + args: + - /bin/sh + - -c + - | + echo "Processing chunk 1..." + sleep 3 + echo "Chunk 1 done!" + + - name: process-2 + image: busybox:1.36 + parallel: true + args: + - /bin/sh + - -c + - | + echo "Processing chunk 2..." + sleep 2 + echo "Chunk 2 done!" + + - name: process-3 + image: busybox:1.36 + parallel: true + args: + - /bin/sh + - -c + - | + echo "Processing chunk 3..." + sleep 4 + echo "Chunk 3 done!" + + # Stage 3: Finalization (fan-in) + - name: finalization + dependencies: + - name: processing + status: succeeded + jobs: + - name: finalize + image: busybox:1.36 + args: + - /bin/sh + - -c + - | + echo "All parallel jobs completed!" + echo "Batch $BATCH_ID finished successfully." diff --git a/config/samples/managedjob_quickstart.yaml b/config/samples/managedjob_quickstart.yaml new file mode 100644 index 0000000..8580749 --- /dev/null +++ b/config/samples/managedjob_quickstart.yaml @@ -0,0 +1,32 @@ +# Quick Start ManagedJob Example +# A simple example to get started with the jobs-manager-operator +# +# This demonstrates: +# - Basic sequential job execution +# - Simple environment variables +# - Job dependencies within a group +--- +apiVersion: jobsmanager.raczylo.com/v1beta1 +kind: ManagedJob +metadata: + name: hello-world +spec: + retries: 1 + + groups: + - name: hello-group + jobs: + - name: say-hello + image: busybox:1.36 + args: + - echo + - "Hello, World!" + + - name: say-goodbye + image: busybox:1.36 + args: + - echo + - "Goodbye, World!" + dependencies: + - name: say-hello + status: succeeded diff --git a/public/plugin-screenshot.png b/public/plugin-screenshot.png new file mode 100644 index 0000000..f4f1f1b Binary files /dev/null and b/public/plugin-screenshot.png differ