// Module included in the following assemblies:
//
// * operators/understanding/olm-packaging-format.adoc

:_mod-docs-content-type: CONCEPT
[id="olm-rukpak-bundle-immutability_{context}"]
= Bundle immutability

After a `Bundle` object is accepted by the API server, the bundle is considered an immutable artifact by the rest of the RukPak system. This behavior enforces the notion that a bundle represents some unique, static piece of content to source onto the cluster. A user can have confidence that a particular bundle is pointing to a specific set of manifests and cannot be updated without creating a new bundle. This property is true for both standalone bundles and dynamic bundles created by an embedded `BundleTemplate` object.

Bundle immutability is enforced by the core RukPak webhook. This webhook watches `Bundle` object events and, for any update to a bundle, checks whether the `spec` field of the existing bundle is semantically equal to that in the proposed updated bundle. If they are not equal, the update is rejected by the webhook. Other `Bundle` object fields, such as `metadata` or `status`, are updated during the bundle's lifecycle; it is only the `spec` field that is considered immutable.

Applying a `Bundle` object and then attempting to update its spec should fail. For example, the following example creates a bundle:

[source,terminal]
----
$ oc apply -f -<<EOF
apiVersion: core.rukpak.io/v1alpha1
kind: Bundle
metadata:
  name: combo-tag-ref
spec:
  source:
    type: git
    git:
      ref:
        tag: v0.0.2
      repository: https://github.com/operator-framework/combo
  provisionerClassName: core-rukpak-io-plain
EOF
----

.Example output
[source,terminal]
----
bundle.core.rukpak.io/combo-tag-ref created
----

Then, patching the bundle to point to a newer tag returns an error:

[source,terminal]
----
$ oc patch bundle combo-tag-ref --type='merge' -p '{"spec":{"source":{"git":{"ref":{"tag":"v0.0.3"}}}}}'
----

.Example output
[source,terminal]
----
Error from server (bundle.spec is immutable): admission webhook "vbundles.core.rukpak.io" denied the request: bundle.spec is immutable
----

The core RukPak admission webhook rejected the patch because the spec of the bundle is immutable. The recommended method to change the content of a bundle is by creating a new `Bundle` object instead of updating it in-place.

[discrete]
[id="olm-rukpak-bundle-immutability-considerations_{context}"]
== Further immutability considerations

While the `spec` field of the `Bundle` object is immutable, it is still possible for a `BundleDeployment` object to pivot to a newer version of bundle content without changing the underlying `spec` field. This unintentional pivoting could occur in the following scenario:

. A user sets an image tag, a Git branch, or a Git tag in the `spec.source` field of the `Bundle` object.
. The image tag moves to a new digest, a user pushes changes to a Git branch, or a user deletes and re-pushes a Git tag on a different commit.
. A user does something to cause the bundle unpack pod to be re-created, such as deleting the unpack pod.

If this scenario occurs, the new content from step 2 is unpacked as a result of step 3. The bundle deployment detects the changes and pivots to the newer version of the content.

This is similar to pod behavior, where one of the pod's container images uses a tag, the tag is moved to a different digest, and then at some point in the future the existing pod is rescheduled on a different node. At that point, the node pulls the new image at the new digest and runs something different without the user explicitly asking for it.

To be confident that the underlying `Bundle` spec content does not change, use a digest-based image or a Git commit reference when creating the bundle.
