Skill v1.0.1
currentAutomated scan100/100+3 new
version: "1.0.1" name: preflight-check-operator description: Guide users running preflight check operator for Red Hat OpenShift Operator Certification. Use when users want to validate operator bundles, debug check failures, understand OLM deployment issues, build index images, or work with operator certification requirements. Trigger on mentions of preflight operator, operator bundle, OLM, DeployableByOLM, operator certification, or index images.
Preflight Operator Check Skill
Help end users run preflight check operator to validate their operator bundles for Red Hat OpenShift Operator Certification. This skill assists with running checks, building index images, debugging failures, results, and understanding operator certification requirements.
When to Use This Skill
Use this skill when users:
- Want to validate an operator bundle for Red Hat OpenShift certification
- Need help building or configuring index images with
opm - Need to understand check failures or errors (especially DeployableByOLM)
- Ask about specific operator checks (DeployableByOLM, ValidateOperatorBundle, CertifiedImages, etc.)
- Need to interpret results, artifacts, or log files from operator validation
- Have issues with KUBECONFIG, cluster access, or OLM deployment
- Are working in disconnected/air-gapped environments with operator bundles
- Need to configure operator channels, namespaces, or service accounts
Core Command Structure
The basic command structure is:
preflight check operator <bundle-image-reference> [flags]
Critical Prerequisites:
- A running OpenShift 4.5+ cluster with Operator Lifecycle Manager (OLM)
- KUBECONFIG environment variable pointing to cluster with cluster-admin privileges
- An index image containing your operator bundle
- Your operator bundle published to a container registry
Common Usage Patterns
Basic operator validation:
export KUBECONFIG=/path/to/your/kubeconfigexport PFLT_INDEXIMAGE=registry.example.org/your-namespace/your-index:v1.0preflight check operator registry.example.org/your-namespace/your-bundle:v1.0
With authentication for private registries:
export KUBECONFIG=/path/to/your/kubeconfigexport PFLT_INDEXIMAGE=registry.example.org/your-namespace/your-index:v1.0preflight check operator registry.example.org/your-namespace/your-bundle:v1.0 \--docker-config=/path/to/config.json
Specifying operator channel:
export KUBECONFIG=/path/to/your/kubeconfigexport PFLT_INDEXIMAGE=registry.example.org/your-namespace/your-index:v1.0preflight check operator registry.example.org/your-namespace/your-bundle:v1.0 \--channel=beta
Custom namespace and service account:
export KUBECONFIG=/path/to/your/kubeconfigexport PFLT_INDEXIMAGE=registry.example.org/your-namespace/your-index:v1.0preflight check operator registry.example.org/your-namespace/your-bundle:v1.0 \--namespace=preflight-testing \--serviceaccount=preflight-sa
Important Flags and Environment Variables
Required
KUBECONFIG(env): Path to kubeconfig with cluster-admin access to OpenShift 4.5+ clusterPFLT_INDEXIMAGE(env): Index image containing your operator bundle
Authentication
--docker-config/PFLT_DOCKERCONFIG: Path to docker config.json (for private registries or to avoid rate limits)
Operator Configuration
--channel/PFLT_CHANNEL: Operator channel name for DeployableByOLM check (uses default channel from bundle annotations if empty)
Output and Logging
--artifacts/PFLT_ARTIFACTS: Where artifacts are written (default:artifacts/)--logfile/PFLT_LOGFILE: Execution log location (default:preflight.log)--loglevel/PFLT_LOGLEVEL: Verbosity (warn, info, debug, trace, error)
Building an Index Image
Before running operator checks, you must build an index image containing your bundle. This is required for the DeployableByOLM check.
Prerequisites
- Install the
opmCLI tool from operator-framework/operator-registry releases - Your operator bundle must already be published to a registry
Building the Index
# Build index image with your bundleopm index add \--bundles registry.example.org/your-namespace/your-bundle:v1.0 \--tag registry.example.org/your-namespace/your-index:v1.0# Push the index to your registrypodman push registry.example.org/your-namespace/your-index:v1.0# Set the index image for preflightexport PFLT_INDEXIMAGE=registry.example.org/your-namespace/your-index:v1.0
Docker users: Add --container-tool=docker to the opm index add command.
Private registries: If your index image is in a private repository, provide docker config:
export PFLT_DOCKERCONFIG=/path/to/docker/config.json
Index Image Requirements
- Must be accessible from both preflight and your target OpenShift cluster
- Must contain the operator bundle you're testing
- Registry must be reachable from the cluster (important for DeployableByOLM)
Understanding Check Results
Results Location
After running preflight, check these locations:
- Results JSON:
artifacts/results.json- detailed pass/fail for each check - Log file:
preflight.log(or custom location) - execution details - Artifacts:
artifacts/directory - check-specific evidence
Common Operator Checks
When debugging failures, understand what each check validates:
| Check Name | Purpose | Common Failures | |
|---|---|---|---|
| DeployableByOLM | Validates operator can be deployed via OLM | Index image not accessible, CSV issues, missing dependencies, cluster connectivity | |
| ValidateOperatorBundle | Runs operator-sdk bundle validate | Invalid bundle structure, missing required files, annotation errors | |
| CertifiedImages | Verifies all container images are Red Hat certified | Using non-certified base images or dependencies | |
| RequiredAnnotations | Checks for required bundle annotations | Missing annotations in metadata/annotations.yaml | |
| RelatedImages | Validates relatedImages in CSV | Missing or incorrect relatedImages section in ClusterServiceVersion | |
| RestrictedNetworkAware | Checks for disconnected environment support | RelatedImages not properly declared, external image references |
Interpreting Failures
When a check fails:
- Read the result message: The
results.jsoncontains amessagefield with details - Check artifacts: Look in
artifacts/for check-specific evidence (output, logs) - Review cluster logs: For DeployableByOLM failures, check cluster events and pod logs
- Use debug logging: Run with
--loglevel=debugor--loglevel=trace - Verify prerequisites: Confirm KUBECONFIG, PFLT_INDEXIMAGE, and cluster access
Debugging Common Failures
DeployableByOLM Failures
This is the most common failure point. The check deploys your operator on the cluster using OLM.
Common issues:
- Index image not accessible from cluster
`` Error: Failed to create CatalogSource ` **Fix:** Ensure the index image is in a registry accessible from the cluster. For private registries, create an image pull secret: `bash # Provide docker config to preflight preflight check operator <bundle> --docker-config=/path/to/config.json ``
- ClusterServiceVersion (CSV) issues
`` Error: CSV did not reach succeeded phase `` Fix: Check the CSV definition in your bundle. Common problems:
- Missing or incorrect install modes
- Invalid deployment specifications
- Resource requirements too high for test cluster
- Missing RBAC permissions
- Missing dependencies
`` Error: Required CRDs not found `` Fix: Ensure all CRD dependencies are declared in the CSV and available in the cluster.
- Channel configuration
``text Error: Channel not found in bundle ` **Fix:** Either specify --channel=<channel-name> or ensure your bundle has a default channel in metadata/annotations.yaml`.
Debugging steps:
# Run with debug loggingpreflight check operator <bundle> --loglevel=debug# Check the operator pod logs in the clusteroc get pods -n <namespace>oc logs <operator-pod> -n <namespace># Check the subscription and CSVoc get subscription -n <namespace>oc get csv -n <namespace>oc describe csv <csv-name> -n <namespace>
ValidateOperatorBundle Failures
This check validates bundle structure using operator-sdk bundle validate.
Common issues:
- Missing required files
`` Error: Missing manifests directory ` **Fix:** Ensure bundle has proper structure: ` bundle/ ├── manifests/ │ ├── <operator>.clusterserviceversion.yaml │ └── <crd-files>.yaml └── metadata/ └── annotations.yaml ``
- Invalid annotations
`` Error: Required annotation missing ` **Fix:** Verify metadata/annotations.yaml contains required fields: `yaml annotations: operators.operatorframework.io.bundle.manifests.v1: manifests/ operators.operatorframework.io.bundle.metadata.v1: metadata/ operators.operatorframework.io.bundle.package.v1: <package-name> operators.operatorframework.io.bundle.channels.v1: <channel-list> operators.operatorframework.io.bundle.channel.default.v1: <default-channel> ``
CertifiedImages Failures
Validates all images used by the operator are Red Hat certified.
Error: Image <image-name> is not certified
Fix: All images referenced in your CSV must be from the Red Hat certified catalog. Check:
- Base images in Dockerfiles
- Images in CSV's relatedImages section
- Container images in deployment specs
Where to find certified images:
- Red Hat Container Catalog: https://catalog.redhat.com/
- Use Red Hat Universal Base Images (UBI) as base images
- Ensure all sidecar/init containers use certified images
RelatedImages / RestrictedNetworkAware Failures
These checks ensure operator works in disconnected environments.
Error: RelatedImages section is incomplete
Fix: The CSV must have a complete relatedImages section listing all images:
spec:relatedImages:- name: operatorimage: registry.example.org/operator:v1.0.0- name: operandimage: registry.example.org/operand:v1.0.0# Include ALL images referenced by the operator
Important: Every image used must be in relatedImages, including:
- Operator image itself
- All operand images
- Init containers
- Sidecar containers
- Any images referenced in the operator's code
Configuration File
Use a config file to avoid exposing values in the console:
# config.yamldockerConfig: /path/to/config.jsonloglevel: debuglogfile: artifacts/preflight.logartifacts: artifactschannel: stable
Then set environment variables and run:
export KUBECONFIG=/path/to/kubeconfigexport PFLT_INDEXIMAGE=registry.example.org/your-namespace/your-index:v1.0preflight check operator registry.example.org/your-namespace/your-bundle:v1.0
Common Workflows
Iterative Development Workflow
# 1. Build and push your operator bundleoperator-sdk bundle build quay.io/myrepo/my-operator-bundle:v1.0podman push quay.io/myrepo/my-operator-bundle:v1.0# 2. Build and push index imageopm index add --bundles quay.io/myrepo/my-operator-bundle:v1.0 \--tag quay.io/myrepo/my-operator-index:v1.0podman push quay.io/myrepo/my-operator-index:v1.0# 3. Set up environmentexport KUBECONFIG=/path/to/kubeconfigexport PFLT_INDEXIMAGE=quay.io/myrepo/my-operator-index:v1.0# 4. Run preflight (iterative - no submission for operators)preflight check operator quay.io/myrepo/my-operator-bundle:v1.0 --loglevel=debug# 5. Fix failures, rebuild bundle and index, repeat until all checks pass# 6. Review resultscat artifacts/results.json | jq '.passed'
Testing with Different Channels
# Test the stable channelexport PFLT_INDEXIMAGE=quay.io/myrepo/my-operator-index:v1.0preflight check operator quay.io/myrepo/my-operator-bundle:v1.0 --channel=stable# Test the beta channelpreflight check operator quay.io/myrepo/my-operator-bundle:v1.0 --channel=beta
Podman Container Workflow
Running preflight in a container for operator checks:
CONTAINER_TOOL=podman$CONTAINER_TOOL run \-it \--rm \--security-opt=label=disable \--env KUBECONFIG=/kubeconfig \--env PFLT_LOGLEVEL=debug \--env PFLT_INDEXIMAGE=registry.example.org/your-namespace/your-index:v1.0 \--env PFLT_ARTIFACTS=/artifacts \--env PFLT_CHANNEL=stable \--env PFLT_LOGFILE=/artifacts/preflight.log \-v /path/on/host/artifacts:/artifacts \-v /path/on/host/kubeconfig:/kubeconfig:ro \quay.io/opdev/preflight:stable check operator registry.example.org/your-namespace/your-bundle:v1.0
Cluster Requirements
Minimum Requirements
- OpenShift 4.5 or later
- Operator Lifecycle Manager (OLM) installed and running
- Cluster-admin privileges via KUBECONFIG
- Sufficient resources to deploy the operator
Verifying Cluster Access
# Verify KUBECONFIG is set and validecho $KUBECONFIGoc cluster-info# Verify OLM is runningoc get csv -Aoc get catalogsources -n openshift-marketplace# Verify you have cluster-admin privilegesoc auth can-i '*' '*' --all-namespaces
Namespace and RBAC Considerations
By default, preflight uses the default namespace and default service account. For isolated testing:
# Create dedicated namespaceoc create namespace preflight-testing# Create service accountoc create serviceaccount preflight-sa -n preflight-testing# Grant necessary permissionsoc create rolebinding preflight-admin \--clusterrole=admin \--serviceaccount=preflight-testing:preflight-sa \-n preflight-testing# Run preflight with custom namespace/SApreflight check operator <bundle> \--namespace=preflight-testing \--serviceaccount=preflight-sa
Tips for Success
- Build index image first: Don't forget this critical step - PFLT_INDEXIMAGE is required
- Verify cluster access: Test KUBECONFIG and cluster connectivity before running checks
- Use debug logging: For DeployableByOLM failures,
--loglevel=debugshows cluster interaction - Check cluster resources: Ensure cluster has enough resources for operator deployment
- Test channels: If your operator supports multiple channels, test each one
- Monitor cluster: Watch pods/events in the cluster while DeployableByOLM runs
- Disconnected prep: For air-gapped environments, use
preflight runtime-assetsto identify all required images - Clean between runs: If re-running checks, clean up operator resources from previous runs
- Review CSV carefully: Most failures trace back to CSV configuration issues
- Complete relatedImages: Ensure ALL images are listed for disconnected environment support
Differences from Container Checks
Operator checks differ from container checks:
- No submission: Operator results are not submitted to Red Hat (submits to Partner Connect portal separately)
- Requires cluster: Must have access to OpenShift cluster with OLM
- Requires index image: Must build index image containing bundle
- Tests deployment: DeployableByOLM actually deploys the operator on the cluster
- More complex: Operator certification has more moving parts than container certification
When to Escalate
If users encounter issues beyond this skill's scope:
- OLM/Cluster issues: Direct to OpenShift documentation or support
- Operator SDK problems: Reference operator-framework documentation
- Preflight bugs: Report at https://github.com/redhat-openshift-ecosystem/openshift-preflight/issues
- Certification policy questions: Direct to Red Hat certification documentation or Partner Connect support at https://connect.redhat.com/support/partner-acceleration-desk/#/case/new
- API/Pyxis issues: Contact Red Hat Partner Connect support at https://connect.redhat.com/support/partner-acceleration-desk/#/case/new
Example: Complete Validation Workflow
# Prerequisites checkecho "Checking prerequisites..."which opm || echo "ERROR: opm not found"oc cluster-info || echo "ERROR: Cluster not accessible"echo $PFLT_INDEXIMAGE || echo "ERROR: PFLT_INDEXIMAGE not set"# Build index imageecho "Building index image..."opm index add \--bundles quay.io/myrepo/my-operator-bundle:v1.0.0 \--tag quay.io/myrepo/my-operator-index:v1.0.0podman push quay.io/myrepo/my-operator-index:v1.0.0# Set environmentexport KUBECONFIG=/path/to/kubeconfigexport PFLT_INDEXIMAGE=quay.io/myrepo/my-operator-index:v1.0.0# Run preflight with debug loggingecho "Running preflight operator checks..."preflight check operator quay.io/myrepo/my-operator-bundle:v1.0.0 \--loglevel=debug \--channel=stable \--namespace=preflight-testing# Review resultsecho "Checking results..."cat artifacts/results.json | jq '.passed'if [ $(cat artifacts/results.json | jq '.passed') = "true" ]; thenecho "SUCCESS: All operator checks passed!"echo "Next: Submit to Partner Connect portal for certification"elseecho "FAILED: Review artifacts/results.json for failures"cat artifacts/results.json | jq '.results[] | select(.passed == false)'fi