Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ Once OLM has been deployed, use the following command to install the latest oper
$ kubectl apply -f https://operatorhub.io/install/shipwright-operator.yaml
```

## OLM Dependencies
When installed via OLM using the provided Shipwright Operator Bundle, the Shipwright operator will ask OLM to deploy the following operators:
- The [Tekton operator](https://tekton.dev/docs/operator/) to deploy and manage Tekton Pipelines.
- The [Cert-Manager operator](https://cert-manager.io/docs/installation/operator-lifecycle-manager/) to provision certificates for admission/conversion webhooks.
For this to work, the Shipwright operator must be included in a catalog that includes these other operators.
## Prerequisites

Before installing the Shipwright operator, you must have the following components installed in your cluster:

- **Tekton**: The Shipwright operator requires Tekton Pipelines to be installed. Follow the [Tekton installation instructions](https://tekton.dev/docs/setup/) to install Tekton in your cluster.
- **cert-manager**: The Shipwright operator uses cert-manager to provision certificates for admission/conversion webhooks. Follow the [cert-manager installation instructions](https://cert-manager.io/docs/installation/) to install cert-manager in your cluster.

**Note**: The cert-manager operator has been deprecated. Please install cert-manager directly using the recommended installation method from the [cert-manager documentation](https://cert-manager.io/docs/installation/).

## Usage

Expand Down
13 changes: 6 additions & 7 deletions bundle/manifests/shipwright-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,17 @@ spec:
kind: ShipwrightBuild
name: shipwrightbuilds.operator.shipwright.io
version: v1alpha1
required:
- kind: TektonConfig
name: tektonconfigs.operator.tekton.dev
version: v1alpha1
- kind: Certificate
name: certificates.cert-manager.io
version: v1
description: |
Shipwright is a framework for building container images on Kubernetes.

Read more: [https://shipwright.io](https://shipwright.io)

## Prerequisites

Before installing the Shipwright operator, ensure the following components are installed:
- **Tekton**: Follow the [Tekton installation instructions](https://tekton.dev/docs/setup/) to install Tekton Pipelines.
- **cert-manager**: Follow the [cert-manager installation instructions](https://cert-manager.io/docs/installation/) to install cert-manager for webhook certificate provisioning.

Comment on lines +44 to +49
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 - we can't rely on Operator Lifecycle Manager to install these with this change.

We will also need to update the "Getting Started" instructions once we get the release working on OperatorHub.

## Usage

To deploy and manage [Shipwright Builds](https://github.com/shipwright-io/build) in your cluster,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,17 @@ spec:
kind: ShipwrightBuild
name: shipwrightbuilds.operator.shipwright.io
version: v1alpha1
required:
- kind: TektonConfig
name: tektonconfigs.operator.tekton.dev
version: v1alpha1
- kind: Certificate
name: certificates.cert-manager.io
version: v1
description: |
Shipwright is a framework for building container images on Kubernetes.

Read more: [https://shipwright.io](https://shipwright.io)

## Prerequisites

Before installing the Shipwright operator, ensure the following components are installed:
- **Tekton**: Follow the [Tekton installation instructions](https://tekton.dev/docs/setup/) to install Tekton Pipelines.
- **cert-manager**: Follow the [cert-manager installation instructions](https://cert-manager.io/docs/installation/) to install cert-manager for webhook certificate provisioning.

## Usage

To deploy and manage [Shipwright Builds](https://github.com/shipwright-io/build) in your cluster,
Expand Down
40 changes: 31 additions & 9 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,20 @@ func setupTektonCRDs(ctx context.Context) {
tektonOpCRD.Status.StoredVersions = []string{"v1alpha1"}
err = k8sClient.Create(ctx, tektonOpCRD, &client.CreateOptions{})
Expect(err).NotTo(HaveOccurred())

// Wait for the CRD to be established before proceeding
Eventually(func() bool {
crd := &crdv1.CustomResourceDefinition{}
if err := k8sClient.Get(ctx, types.NamespacedName{Name: "tektonconfigs.operator.tekton.dev"}, crd); err != nil {
return false
}
for _, condition := range crd.Status.Conditions {
if condition.Type == crdv1.Established && condition.Status == crdv1.ConditionTrue {
return true
}
}
return false
}).Should(BeTrue(), "TektonConfig CRD should be established")
Comment on lines +129 to +142
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also do this for the cert-manager Issuer or Certificate CRDs? I think we can address this in a follow-up PR if needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good looking out. I’ll look into this in a future pr

}
Expect(err).NotTo(HaveOccurred())
}
Expand Down Expand Up @@ -191,31 +205,39 @@ func createTektonConfig(ctx context.Context) *tektonoperatorv1alpha1.TektonConfi
},
},
}
_, err := tektonOpClient.TektonConfigs().Create(ctx, tektonConfig, metav1.CreateOptions{})
// Use controller-runtime client instead of REST client for better compatibility with envtest
err := k8sClient.Create(ctx, tektonConfig, &client.CreateOptions{})
Comment on lines +208 to +209
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 - thank you for this! Much needed payoff for old tech debt.

if errors.IsAlreadyExists(err) {
// If it already exists, that's fine
err = nil
// If it already exists, fetch it
err = k8sClient.Get(ctx, types.NamespacedName{Name: "config"}, tektonConfig)
Expect(err).NotTo(HaveOccurred())
} else {
Expect(err).NotTo(HaveOccurred())
}
Expect(err).To(BeNil())

return tektonConfig
}

// deleteTektonConfig tears down the given TektonConfig instance.
func deleteTektonConfig(ctx context.Context) {
By("deleting the TektonConfig instance")
err := tektonOpClient.TektonConfigs().Delete(ctx, "config", metav1.DeleteOptions{})
tektonConfig := &tektonoperatorv1alpha1.TektonConfig{
ObjectMeta: metav1.ObjectMeta{
Name: "config",
},
}
err := k8sClient.Delete(ctx, tektonConfig, &client.DeleteOptions{})
// the delete e2e's can delete this object before this AfterEach runs
if errors.IsNotFound(err) {
return
}
Expect(err).NotTo(HaveOccurred())

By("waiting for TektonConfig instance to be completely removed")
Eventually(func() error {
_, err := tektonOpClient.TektonConfigs().Get(ctx, "config", metav1.GetOptions{})
return err
}, "30s", "5s").Should(WithTransform(errors.IsNotFound, BeTrue()))
Eventually(func() bool {
err := k8sClient.Get(ctx, types.NamespacedName{Name: "config"}, tektonConfig)
return errors.IsNotFound(err)
}, "30s", "5s").Should(BeTrue(), "TektonConfig should be deleted")
}

var _ = BeforeSuite(func() {
Expand Down
90 changes: 90 additions & 0 deletions hack/run-operator-catalog.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
# - SUBSCRIPTION_NAMESPACE: Namespace to install the operator via an OLM subscription. Defaults to
# shipwright-operator.
# - NAME_PREFIX: prefix to use for all resource names. Defaults to "shipwright-"
# - TEKTON_OPERATOR_VERSION: Tekton Operator version to install. Defaults to v0.77.0 (matches go.mod).
# - CERT_MANAGER_VERSION: cert-manager version to install. Defaults to v1.13.0.

set -eu -o pipefail

Expand Down Expand Up @@ -81,6 +83,90 @@ function wait_for_pod() {
${KUBECTL_BIN} wait --for=condition=Ready pod -l "${label}" -n "${namespace}" --timeout "${timeout}"
}

function install_tekton() {
echo "Installing Tekton Operator"
# Install Tekton Operator using the official installation method (https://github.com/tektoncd/operator/releases)
# Minimum supported version is v0.50.0 (see pkg/common/const.go)
# Default version matches the dependency in go.mod (v0.77.0) for stability
# Can be overridden via TEKTON_OPERATOR_VERSION env var
TEKTON_OPERATOR_VERSION=${TEKTON_OPERATOR_VERSION:-v0.77.0}
echo "Installing Tekton Operator version ${TEKTON_OPERATOR_VERSION}"
if ! ${KUBECTL_BIN} apply -f "https://storage.googleapis.com/tekton-releases/operator/previous/${TEKTON_OPERATOR_VERSION}/release.yaml"; then
echo "Warning: Failed to install Tekton Operator ${TEKTON_OPERATOR_VERSION}, falling back to latest"
${KUBECTL_BIN} apply -f "https://storage.googleapis.com/tekton-releases/operator/latest/release.yaml"
fi

echo "Waiting for Tekton Operator to be ready"
# Wait for the operator namespace to exist first
for i in {1..30}; do
if ${KUBECTL_BIN} get namespace tekton-operator &>/dev/null; then
break
fi
sleep 2
done

if ! wait_for_pod "app=tekton-operator" "tekton-operator" 5m; then
echo "Failed to deploy Tekton Operator"
${KUBECTL_BIN} get pods -n tekton-operator
exit 1
fi

echo "Creating TektonConfig instance"
# Check if TektonConfig already exists, delete it if it does to avoid annotation warnings
if ${KUBECTL_BIN} get tektonconfigs.operator.tekton.dev/config &>/dev/null; then
echo "TektonConfig already exists, deleting it to recreate cleanly"
${KUBECTL_BIN} delete tektonconfigs.operator.tekton.dev/config --ignore-not-found=true
# Wait a moment for deletion to complete
sleep 2
fi

${KUBECTL_BIN} apply -f - <<EOF
apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
name: config
spec:
profile: lite
targetNamespace: tekton-pipelines
EOF

echo "Waiting for TektonConfig to be ready"
if ! ${KUBECTL_BIN} wait --for=condition=Ready tektonconfigs.operator.tekton.dev/config --timeout=5m; then
echo "Failed to deploy TektonConfig"
${KUBECTL_BIN} get tektonconfigs -o yaml
${KUBECTL_BIN} get tektonconfigs config -o yaml
exit 1
fi
}

function install_cert_manager() {
echo "Installing cert-manager"
# Install cert-manager using the official installation method (https://github.com/cert-manager/cert-manager/releases)
# Default version is v1.13.0 (stable release)
# Can be overridden via CERT_MANAGER_VERSION env var
CERT_MANAGER_VERSION=${CERT_MANAGER_VERSION:-v1.13.0}
echo "Installing cert-manager version ${CERT_MANAGER_VERSION}"
${KUBECTL_BIN} apply -f "https://github.com/cert-manager/cert-manager/releases/download/${CERT_MANAGER_VERSION}/cert-manager.yaml"

echo "Waiting for cert-manager pods to be ready"
if ! wait_for_pod "app.kubernetes.io/instance=cert-manager" "cert-manager" 5m; then
echo "Failed to deploy cert-manager"
${KUBECTL_BIN} get pods -n cert-manager
exit 1
fi

echo "Waiting for cert-manager webhook to be ready"
# Wait for the webhook to be ready by checking if it can validate certificates
for i in {1..30}; do
if ${KUBECTL_BIN} get validatingwebhookconfigurations cert-manager-webhook &>/dev/null; then
echo "cert-manager webhook is ready"
return 0
fi
sleep 2
done
echo "Warning: cert-manager webhook may not be fully ready, continuing anyway"
}

add_kustomizations

echo "Deploying catalog source"
Expand Down Expand Up @@ -108,6 +194,10 @@ if ! wait_for_pod "app=shipwright-operator" "${SUBSCRIPTION_NAMESPACE}" 5m; then
exit 1
fi

echo "Installing prerequisites"
install_cert_manager
install_tekton

echo "Deploying Shipwright build controller"

${KUBECTL_BIN} apply -f - <<EOF
Expand Down
Loading