Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Add command to update olmv1 operator #225

Merged

Conversation

azych
Copy link
Contributor

@azych azych commented Mar 5, 2025

Adds command to update an existing olmv1 operator (ClusterExtension).

Command has the following signature and flags:

Update an operator

Usage:
  operator olmv1 update operator <operator> [flags]

Flags:
      --channels stringArray               desired channels for operator versions. AND operation with version. Empty list means all available channels will be taken into consideration
  -h, --help                               help for operator
      --ignore-unset                       when enabled, any unset flag value will not be changed. Disabling means that for each unset value a default will be used instead (default true)
      --labels stringToString              labels that will be set on the operator (default [])
      --selector string                    filters the set of catalogs used in the bundle selection process. Empty means that all catalogs will be used in the bundle selection process
      --upgrade-constraint-policy string   controls whether the upgrade path(s) defined in the catalog are enforced. One of CatalogProvided|SelfCertified), Default: CatalogProvided
      --version string                     desired operator version (single or range) in semVer format. AND operation with channels

Example walkthrough:

➜ kubectl get clusterextensions
NAME        INSTALLED BUNDLE             VERSION   INSTALLED   PROGRESSING   AGE
zookeeper   zookeeper-operator.v0.17.8   0.17.8    True        True          44s
➜ go run *.go olmv1 update operator zookeeper
operator "zookeeper" updated
➜ kubectl get clusterextensions
NAME        INSTALLED BUNDLE              VERSION   INSTALLED   PROGRESSING   AGE
zookeeper   zookeeper-operator.v0.17.10   0.17.10   True        True          77s

➜ kubectl get clusterextensions
NAME        INSTALLED BUNDLE             VERSION   INSTALLED   PROGRESSING   AGE
zookeeper   zookeeper-operator.v0.17.8   0.17.8    True        True          8s
➜ go run *.go olmv1 update operator zookeeper --version=0.17.8
failed to update operator: no changes detected - operator already in desired state
exit status 1

➜ kubectl get clusterextensions zookeeper -o yaml
apiVersion: olm.operatorframework.io/v1
kind: ClusterExtension
metadata:
  creationTimestamp: "2025-03-05T10:21:08Z"
  finalizers:
  - olm.operatorframework.io/cleanup-unpack-cache
  - olm.operatorframework.io/cleanup-contentmanager-cache
  generation: 1
  name: zookeeper
  resourceVersion: "4087"
  uid: 7d808271-dffa-4395-a93c-12148959a6fe
spec:
  namespace: zookeeper
  serviceAccount:
    name: zookeeper
  source:
    catalog:
      packageName: zookeeper-operator
      upgradeConstraintPolicy: CatalogProvided
      version: 0.17.8
    sourceType: Catalog
➜ go run *.go olmv1 update operator zookeeper --version=0.17.8 --upgrade-constraint-policy=SelfCertified
operator "zookeeper" updated
➜ kubectl get clusterextensions zookeeper -o yaml
apiVersion: olm.operatorframework.io/v1
kind: ClusterExtension
metadata:
  creationTimestamp: "2025-03-05T10:21:08Z"
  finalizers:
  - olm.operatorframework.io/cleanup-unpack-cache
  - olm.operatorframework.io/cleanup-contentmanager-cache
  generation: 2
  name: zookeeper
  resourceVersion: "4328"
  uid: 7d808271-dffa-4395-a93c-12148959a6fe
spec:
  namespace: zookeeper
  serviceAccount:
    name: zookeeper
  source:
    catalog:
      packageName: zookeeper-operator
      upgradeConstraintPolicy: SelfCertified
      version: 0.17.8
    sourceType: Catalog
➜ go run *.go olmv1 update operator zookeeper --override-unset-with-current
failed to update operator: no changes detected - operator already in desired state
exit status 1
➜ go run *.go olmv1 update operator zookeeper --version=0.17.8 --override-unset-with-current
failed to update operator: no changes detected - operator already in desired state
exit status 1
➜ go run *.go olmv1 update operator zookeeper
operator "zookeeper" updated
➜ kubectl get clusterextensions zookeeper -o yaml
apiVersion: olm.operatorframework.io/v1
kind: ClusterExtension
metadata:
  creationTimestamp: "2025-03-05T10:21:08Z"
  finalizers:
  - olm.operatorframework.io/cleanup-unpack-cache
  - olm.operatorframework.io/cleanup-contentmanager-cache
  generation: 3
  name: zookeeper
  resourceVersion: "4642"
  uid: 7d808271-dffa-4395-a93c-12148959a6fe
spec:
  namespace: zookeeper
  serviceAccount:
    name: zookeeper
  source:
    catalog:
      packageName: zookeeper-operator
      upgradeConstraintPolicy: CatalogProvided
      version: 0.17.8
    sourceType: Catalog

➜ go run *.go olmv1 update operator zookeeper --version=0.17.10 --channels=alpha
operator "zookeeper" updated
➜ kubectl get clusterextensions zookeeper
NAME        INSTALLED BUNDLE              VERSION   INSTALLED   PROGRESSING   AGE
zookeeper   zookeeper-operator.v0.17.10   0.17.10   True        True          6m
➜ kubectl get clusterextensions zookeeper -o yaml
apiVersion: olm.operatorframework.io/v1
kind: ClusterExtension
metadata:
  creationTimestamp: "2025-03-05T10:21:08Z"
  finalizers:
  - olm.operatorframework.io/cleanup-unpack-cache
  - olm.operatorframework.io/cleanup-contentmanager-cache
  generation: 5
  name: zookeeper
  resourceVersion: "4973"
  uid: 7d808271-dffa-4395-a93c-12148959a6fe
spec:
  namespace: zookeeper
  serviceAccount:
    name: zookeeper
  source:
    catalog:
      channels:
      - alpha
      packageName: zookeeper-operator
      upgradeConstraintPolicy: CatalogProvided
      version: 0.17.10
    sourceType: Catalog
➜ go run *.go olmv1 update operator zookeeper --version=0.17.10
operator "zookeeper" updated
➜ kubectl get clusterextensions zookeeper -o yaml
apiVersion: olm.operatorframework.io/v1
kind: ClusterExtension
metadata:
  creationTimestamp: "2025-03-05T10:21:08Z"
  finalizers:
  - olm.operatorframework.io/cleanup-unpack-cache
  - olm.operatorframework.io/cleanup-contentmanager-cache
  generation: 6
  name: zookeeper
  resourceVersion: "5375"
  uid: 7d808271-dffa-4395-a93c-12148959a6fe
spec:
  namespace: zookeeper
  serviceAccount:
    name: zookeeper
  source:
    catalog:
      packageName: zookeeper-operator
      upgradeConstraintPolicy: CatalogProvided
      version: 0.17.10
    sourceType: Catalog

➜ go run *.go olmv1 update operator zookeeper --version="17-0-0"
failed to update operator: failed parsing version: Could not parse Range "17-0-0": Could not parse version "17-0-0" in "17-0-0": No Major.Minor.Patch elements found
exit status 1
➜ go run *.go olmv1 update operator zookeeper --version=">=0.17.9"
operator "zookeeper" updated
➜ kubectl get clusterextension zookeeper -o yaml
apiVersion: olm.operatorframework.io/v1
kind: ClusterExtension
metadata:
  creationTimestamp: "2025-03-05T10:21:08Z"
  finalizers:
  - olm.operatorframework.io/cleanup-unpack-cache
  - olm.operatorframework.io/cleanup-contentmanager-cache
  generation: 11
  name: zookeeper
  resourceVersion: "13986"
  uid: 7d808271-dffa-4395-a93c-12148959a6fe
spec:
  namespace: zookeeper
  serviceAccount:
    name: zookeeper
  source:
    catalog:
      packageName: zookeeper-operator
      upgradeConstraintPolicy: CatalogProvided
      version: '>=0.17.9'
    sourceType: Catalog

➜ go run *.go olmv1 update operator zookeeper --version="0.17.8" --selector="notfound,doesnotexist"
operator "zookeeper" updated
➜ kubectl get clusterextensions -o yaml
apiVersion: v1
items:
- apiVersion: olm.operatorframework.io/v1
  kind: ClusterExtension
  metadata:
    creationTimestamp: "2025-03-12T09:08:11Z"
    finalizers:
    - olm.operatorframework.io/cleanup-unpack-cache
    - olm.operatorframework.io/cleanup-contentmanager-cache
    generation: 2
    name: zookeeper
    resourceVersion: "11202"
    uid: 04f1a520-2d03-4c8e-b6c7-2aae43a5025c
  spec:
    namespace: zookeeper
    serviceAccount:
      name: zookeeper
    source:
      catalog:
        packageName: zookeeper-operator
        selector:
          matchExpressions:
          - key: doesnotexist
            operator: Exists
          - key: notfound
            operator: Exists
        upgradeConstraintPolicy: CatalogProvided
        version: 0.17.8
      sourceType: Catalog
➜ go run *.go olmv1 update operator zookeeper --version="0.17.8" --selector="notfound,doesnotexist"
failed to update operator: no changes detected - operator already in desired state
exit status 1
➜ go run *.go olmv1 update operator zookeeper --version="0.17.8" --selector="notfound,doesnotexist2"
operator "zookeeper" updated
➜ kubectl get clusterextensions -o yaml
apiVersion: v1
items:
- apiVersion: olm.operatorframework.io/v1
  kind: ClusterExtension
  metadata:
    creationTimestamp: "2025-03-12T09:08:11Z"
    finalizers:
    - olm.operatorframework.io/cleanup-unpack-cache
    - olm.operatorframework.io/cleanup-contentmanager-cache
    generation: 3
    name: zookeeper
    resourceVersion: "11250"
    uid: 04f1a520-2d03-4c8e-b6c7-2aae43a5025c
  spec:
    namespace: zookeeper
    serviceAccount:
      name: zookeeper
    source:
      catalog:
        packageName: zookeeper-operator
        selector:
          matchExpressions:
          - key: doesnotexist2
            operator: Exists
          - key: notfound
            operator: Exists
        upgradeConstraintPolicy: CatalogProvided
        version: 0.17.8
      sourceType: Catalog
➜ go run *.go olmv1 update operator zookeeper --version="0.17.8"
failed to update operator: no changes detected - operator already in desired state
exit status 1
➜ go run *.go olmv1 update operator zookeeper --version="0.17.8" --ignore-unset=false
operator "zookeeper" updated
➜ kubectl get clusterextensions -o yaml
apiVersion: v1
items:
- apiVersion: olm.operatorframework.io/v1
  kind: ClusterExtension
  metadata:
    creationTimestamp: "2025-03-12T09:08:11Z"
    finalizers:
    - olm.operatorframework.io/cleanup-unpack-cache
    - olm.operatorframework.io/cleanup-contentmanager-cache
    generation: 4
    name: zookeeper
    resourceVersion: "11299"
    uid: 04f1a520-2d03-4c8e-b6c7-2aae43a5025c
  spec:
    namespace: zookeeper
    serviceAccount:
      name: zookeeper
    source:
      catalog:
        packageName: zookeeper-operator
        upgradeConstraintPolicy: CatalogProvided
        version: 0.17.8
      sourceType: Catalog
➜ go run *.go olmv1 update operator zookeeper --version="0.17.8" --selector="<"
failed to update operator: failed parsing selector: couldn't parse the selector string "<": found '<', expected: !, identifier, or 'end of string'
exit status 1

Closes operator-framework/operator-controller#1772

@openshift-ci openshift-ci bot requested review from exdx and joelanford March 5, 2025 11:51
Copy link
Contributor Author

@azych azych left a comment

Choose a reason for hiding this comment

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

Like in #220, I'll hold off on unit tests for now

@azych azych force-pushed the olmv1-update-operator branch from c08c501 to 2e125d6 Compare March 5, 2025 12:01
@azych azych changed the title Add command to update olmv1 operator ✨ Add command to update olmv1 operator Mar 5, 2025
@azych azych force-pushed the olmv1-update-operator branch from 547d3be to fb856f8 Compare March 7, 2025 08:06
@azych azych force-pushed the olmv1-update-operator branch from fb856f8 to 1af1330 Compare March 7, 2025 14:30
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 7, 2025
@azych azych force-pushed the olmv1-update-operator branch from 1af1330 to b69e0e6 Compare March 7, 2025 14:34
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 7, 2025
@azych
Copy link
Contributor Author

azych commented Mar 7, 2025

There was an internal meeting yesterday regarding current CLI efforts in kubectl-operator. The gist of it was:

  • we focus on getting the core functionality in
  • detailed docs, potential syntax and terminology changes (such as operator -> extension (or anything else) will be deferred until this goes to dev preview

This is the epic that reflects the roadmap: operator-framework/operator-controller#1424

@azych azych force-pushed the olmv1-update-operator branch from b69e0e6 to df4c62c Compare March 7, 2025 15:11
@azych
Copy link
Contributor Author

azych commented Mar 10, 2025

@camilamacedo86 I'll group some of the responses to your comments to help with the organization at least a little.

Multiple Channels (raised in: #225 (comment), #225 (comment), #225 (comment))

  • As I mentioned in responses (eg. ✨ Add command to update olmv1 operator #225 (comment)), our CRD allows multiple channels to be set and the documentation does not mention any restrictions (that you can provide either no channels at all or a single one) - this is the first line of our docs (docs are fairly long, so I won't be pasting them here in full): channels <[]string> channels is an optional reference to a set of channels belonging to the package specified in the packageName field.
  • If you have a strong opinion about this (and I think you do, since you unresolved that comment) I would suggest maybe raising this an issue in the team/on the operator-controller, which owns the CRD. This way, if it needs fixing (should not be an array, but a single channel with empty value meaning 'all' channels) it will be fixed at the source first. Hopefully, this will unblock this PR from this discussion.

Documentation changes/questions (raised in: #225 (comment), #225 (comment), #225 (comment), #225 (comment))

  • flags documentation (help messages) are either taken from our CRD documentation (and shortened) or are created from scratch when there is no direct relation. Flags that you're raising issues about come mostly from our CRD docs.
  • patterns (like with One of: | come from current olmv0 commands that are defined in this repo
  • when it comes to improvements, the idea was to holistically review documentation and extend it to be user-facing at a later time, where we have all the commands ready and we have an RC (what I was trying to say here: ✨ Add command to update olmv1 operator #225 (comment), sorry if it wasn't too clear) to avoid lenghty discussions over things like:
  • Should One of CatalogProvided|SelfCertified), Default: CatalogProvided" be OPTIONS: 'CatalogProvided', 'SelfCertified'. Default: 'CatalogProvided'." up to the point of unresolving comments.

General comments/notes

In the (near) future (operator-framework/operator-controller#1851, operator-framework/operator-controller#1766, operator-framework/operator-controller#1850):

  • with olmv0 deprecation we have several options on how to approach the separation - new project, v1/, etc. This can (and most likely will come) with architecture changes
  • with that deprecation we will possibly be looking at getting rid/changing of the kubectl operator olmv1 prefix that currently needs to be used for the new commands
  • we agreed to review and extend documentation towards the end of the commands efforts
  • the commands we're adding right now are meant to provide a good base for extending with new features later
  • because of the last point, with things like 'how do we approach cleanup', 'how do we approach waiting for new object status (if at all) we agreed to defer those discussions and for now chose to go with whatever olmv0 was doing (✨ Add command to create a new olmv1 catalog #220 (comment))

The gist of those future plans is that with the new commands we look to come up with a good base functionality that we can later adjust and extend if we see fit (eg. someone makes a compelling argument why syntax should not follow kubectl behavior) and we wanted to avoid blocking this basic functionality over what could (would) be lengthy discussions and research.

Side note: sorry for this wall of text with multiple links, but I thought it was beneficial at this point to centralize some topics and provide a common background and reasoning for some of things we are doing now and have been doing in previous commands.

Copy link

@camilamacedo86 camilamacedo86 left a comment

Choose a reason for hiding this comment

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

Hi @azych,

Thank you for your time and explanations!
Regarding: Comment Reference,
I think it's best to discuss each point in its respective thread.

About UX/Flags

For all cases:

  • Can we avoid AND ... <other flag>? It feels unnecessary—AND is already implicit when multiple flags are used, right?
  • Can we ensure all flags document their default behavior?
    (e.g., for channels: if not set, search in all)

PS: I’m fine with improving this later, but a small tweak for clarity wouldn’t hurt. It might also help us during the review process. If we can ensure that, it’d be great! That said, it’s a NIT—I won’t block the PR over it.

Replacing "Operator" with "Cluster Extension"

Let’s leave this out for now.

Final Review Status

I did another pass, and I think the last open point is override-unset-with-current.
Its usage isn’t entirely clear to me—see comment.

Beyond that, everything else seems addressed or will be handled later.
So unless there’s more on this, Otherwise all fine lgtm

Thanks again for your time and input! 🚀

@LalatenduMohanty
Copy link
Member

For some reason I am not able to checkout the PR to test locally using github CLI

$ gh pr checkout 225
From https://github.com/operator-framework/kubectl-operator
 ! [rejected]        refs/pull/225/head -> olmv1-update-operator  (non-fast-forward)
failed to run git: exit status 1

May be re-basing it will help

@azych
Copy link
Contributor Author

azych commented Mar 11, 2025

For some reason I am not able to checkout the PR to test locally using github CLI

$ gh pr checkout 225
From https://github.com/operator-framework/kubectl-operator
 ! [rejected]        refs/pull/225/head -> olmv1-update-operator  (non-fast-forward)
failed to run git: exit status 1

May be re-basing it will help

This is already up to date with the main branch.

BTW. Wouldn't you say it would be better to keep issues like out of PR comments? We do have the team slack and IMO it would be best to keep the comments cleaner.

@azych azych force-pushed the olmv1-update-operator branch from 8261b24 to b2ccb7e Compare March 11, 2025 11:04
@LalatenduMohanty
Copy link
Member

BTW. Wouldn't you say it would be better to keep issues like out of PR comments? We do have the team slack and IMO it would be best to keep the comments cleaner.

I understand your sentiment, my intent is to keep all comment in public domain as much as possible. As we are a community project. I can use use #olm-dev channel for this if you prefer instead of PR comment. Personally I do not see an issue in PR comment vs slack message.

@azych
Copy link
Contributor Author

azych commented Mar 12, 2025

BTW. Wouldn't you say it would be better to keep issues like out of PR comments? We do have the team slack and IMO it would be best to keep the comments cleaner.

I understand your sentiment, my intent is to keep all comment in public domain as much as possible. As we are a community project. I can use use #olm-dev channel for this if you prefer instead of PR comment. Personally I do not see an issue in PR comment vs slack message.

yes, regardless of whether the project is open- or closed- source, in my opinion issues with arbitrary third party tools (like gh not being able to check out a branch) that have no real relation to the PR being reviewed should be kept outside of (root) comments for such PR.
Generally, I think we should take care with comments so they won't become messy and difficult to read and follow. To me that includes things like keeping them on topic and avoiding scattered discussions about the same issue for example.

@azych azych force-pushed the olmv1-update-operator branch from b2ccb7e to c675c45 Compare March 12, 2025 10:20
@azych
Copy link
Contributor Author

azych commented Mar 12, 2025

we now have full --selector support and the default behavior of --ignore-unset (new name) was reversed.
I've also introduced parsedSelector to the internal command structure and fixed the selector comparison issues I came across.

}
}

// nolint: unparam
Copy link
Member

Choose a reason for hiding this comment

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

Which lint error is this masking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

internal/pkg/v1/action/action_suite_test.go:83:27 unparam withConstraintPolicy - policy always receives string(olmv1.UpgradeConstraintPolicyCatalogProvided) ("CatalogProvided")

I don't think this needs to be 'fixed', hence nolint. withConstraintPolicy is used only to build test operators (extension) in tests. We do have test cases where we check setting a different value, but the base remains the same.

Copy link
Contributor

@ankitathomas ankitathomas left a comment

Choose a reason for hiding this comment

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

/lgtm

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Mar 12, 2025
@LalatenduMohanty LalatenduMohanty added this pull request to the merge queue Mar 12, 2025
Merged via the queue into operator-framework:main with commit 7794db4 Mar 12, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extend kubectl-operator plugin to upgrade a ClusterExtension
6 participants