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 patches to virt-operator #3612

Merged
merged 4 commits into from Sep 7, 2020

Conversation

ashleyschuett
Copy link
Contributor

@ashleyschuett ashleyschuett commented Jun 19, 2020

What this PR does / why we need it:

  1. Adds the CustomizeComponents field to the KubeVirt CR
  2. Allows for optional Patches to be specified

This PR will allow users to customize the virt-controller, virt-handler, virt-api, and all other resources that are created by the virt-operator.

We need this to allow users to be able to customize the way kubevirt is ran in each of their environments. This gives users the power to specify where components can be scheduled, customizing flags and other use cases. If a user defines an invalid patch the operator will fail to deploy.

This current draft PR only adds this logic for the virt-controller. An example KubeVirt CR is as follows:

---
apiVersion: kubevirt.io/v1alpha3
kind: KubeVirt
metadata:
  name: kubevirt
  namespace: kubevirt
spec:
  certificateRotateStrategy: {}
  configuration: {}
  customizeComponents: 
    patches:
    - resourceType: Deployment
      resourceName: virt-controller
      patch: '[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'
      type: json
    - resourceType: Deployment
      resourecName: virt-controller
      patch: '{"metadata":{"annotations":{"patch": "true"}}}'
      type: strategic
  imagePullPolicy: IfNotPresent

Which issue(s) this PR fixes:
Fixes #3365

Special notes for your reviewer:

  1. How do we feel able the name customizeComponents? I also ended up using the name ComponentsCustomization in the config struct. I think these two should be consistent, but would like opinions on what naming makes more sense?

  2. Is there any reason to continue passing individual arguments to functions such as NewControllerDeployment instead of passing the who config object?

Release note:

Adds `customizeComponents` to the kubevirt api

@openshift-ci-robot
Copy link
Collaborator

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@kubevirt-bot kubevirt-bot added release-note Denotes a PR that will be considered when it comes time to generate release notes. do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. dco-signoff: yes Indicates the PR's author has DCO signed all their commits. size/L kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API labels Jun 19, 2020
@ashleyschuett
Copy link
Contributor Author

@davidvossel @rmohr does this approach look correct to implement for all components?

Copy link
Member

@davidvossel davidvossel left a comment

Choose a reason for hiding this comment

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

i left one comment about code structure. The other kind of high level comment I have is how do we detect when a new patch has been added which should result in rollling out a new install strategy.

So for example, if someone installs kubevirt, then mutates the kubevirt spec to include a patch, how does our controller know to roll out that change. Right now it's only keying off image name/registry. We

if err != nil {
return nil, fmt.Errorf("error generating virt-apiserver deployment %v", err)
}
strategy.deployments = append(strategy.deployments, apiDeployment)

controller, err := components.NewControllerDeployment(config.GetNamespace(), config.GetImageRegistry(), config.GetImagePrefix(), config.GetControllerVersion(), config.GetLauncherVersion(), config.GetImagePullPolicy(), config.GetVerbosity(), config.GetExtraEnv())
controller, err := components.NewControllerDeployment(config.GetNamespace(), config.GetImageRegistry(), config.GetImagePrefix(), config.GetControllerVersion(), config.GetLauncherVersion(), config.GetImagePullPolicy(), config.GetVerbosity(), config.GetExtraEnv(), config.GetPatchesForResource("Deployment", components.ControllerDeploymentName))
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if instead of passing in the patches to each create function (like deployments, api, daemonset, etc...) if we could just loop over all the objects at the of this GenerateCurrentInstallStrategy instead.

Something like

// services
for i, entry := range strategy.services {
    strategy.services[i], err = applyPatches(entry, getPatchesForResource(.....))
    if err != nil {
        return nil, err
    }
}
// deployments
for i, entry := range strategy.deployments {
    strategy.deployments[i], err = applyPatches(entry, getPatchesForResource(.....))
    if err != nil {
        return nil, err
    }
}

maybe there's even a generic function that can be used to do this so it would be as simple as

genericApplyPatches(strategy.Services, config)
genericApplyPatches(strategy.Deployments, config)
.
.
.

I'm just trying to think if there's a way to consolidate all the patching logic to this generate function rather than spreading it around.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I think that makes sense, I have updated apply patches to be more generic so it only needs to be called for each resource type that we want to allow patches on

@timstoop
Copy link

Don't want to creep in additional features, but I wonder if this would be applicable to virt-launchers as well? As we would like to add a sidecart with the libvirt_exporter (https://github.com/kumina/libvirt_exporter/), for example.

@rmohr
Copy link
Member

rmohr commented Jun 30, 2020

Don't want to creep in additional features, but I wonder if this would be applicable to virt-launchers as well? As we would like to add a sidecart with the libvirt_exporter (https://github.com/kumina/libvirt_exporter/), for example.

Independent if that makes sense (probably does): We are exposing metrics for all VMIs through virt-handler, in case you are not aware of it. Let us know if you are missing something there. Have a look at https://kubevirt.io/user-guide/#/installation/monitoring?id=monitoring-kubevirt-components

@kubevirt-bot kubevirt-bot added dco-signoff: no Indicates the PR's author has not DCO signed all their commits. and removed dco-signoff: yes Indicates the PR's author has DCO signed all their commits. labels Jul 3, 2020
@ashleyschuett
Copy link
Contributor Author

So for example, if someone installs kubevirt, then mutates the kubevirt spec to include a patch, how does our controller know to roll out that change. Right now it's only keying off image name/registry.

It gets updated from this function since the correct install strategy will no longer exist
https://github.com/kubevirt/kubevirt/pull/3612/files#diff-bd81c399ded8070883a8f861d513f5e8R442

@ashleyschuett ashleyschuett marked this pull request as ready for review July 21, 2020 13:41
@kubevirt-bot kubevirt-bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 21, 2020
@kubevirt-bot kubevirt-bot added dco-signoff: yes Indicates the PR's author has DCO signed all their commits. and removed dco-signoff: no Indicates the PR's author has not DCO signed all their commits. labels Jul 21, 2020
s := "CustomizeComponentsPatches"

for _, p := range c.Patches {
s += fmt.Sprintf("Resource%sName%sPatch%sType%s", p.ResourceType, p.ResourceName, p.Patch, string(p.Type))

Choose a reason for hiding this comment

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

I think that in this case using strings.StringBuilder will be much more efficient.
Strings are immutable and for every patch we actually reallocate a new memory chunk and reference s to the new location.

Copy link
Member

@davidvossel davidvossel left a comment

Choose a reason for hiding this comment

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

code quality so far looks great! I have a couple of top level comments.

  1. what happens (or should happen) if someone modifies the KubeVirt CR with a patch after install? It looks like we might ignore those changes today until the KubeVirt version is updated, then the patches would kick in?

  2. i think this logic deserves a functional test case in tests/operator_test.go

@@ -335,6 +335,7 @@ func NewControllerDeployment(namespace string, repository string, imagePrefix st
}

attachCertificateSecret(pod, VirtControllerCertSecretName, "/etc/virt-controller/certificates")

Copy link
Member

Choose a reason for hiding this comment

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

super minor, there's a random line added here to a file that otherwise has no changes.

@rmohr
Copy link
Member

rmohr commented Jul 31, 2020

  1. what happens (or should happen) if someone modifies the KubeVirt CR with a patch after install? It looks like we might ignore those changes today until the KubeVirt version is updated, then the patches would kick in?

To make everything react fast and easy to grasp I am still for doing the patches always when we load the install strategy and always just dump the plain shipped install strategy. That makes is absolutely clear and understandable what will happen: If patches are provided in the CR they are applied, if they are not there they are not. Of course that can be done by dumping the proper install strategy over and over, but it is mentally much more difficult to grasp and no questions like this will arise: If I roll back to the previous version which had patches and I don't provide the patches, will it still have them? You simply always get what we release + your patches on the CR. No exception.

@rmohr
Copy link
Member

rmohr commented Jul 31, 2020

One additional note, after we merge the subresource PR, the generation metadata field will only be bumped on the kubevirt cr, if the spec changes. Like on e.g. Deployments I would suggest to add the generation as a metadata annotation to all our artifacts. This will make it pretty easy to detect changes then.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

12 similar comments
@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-commenter-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs.
Silence the bot with an /lgtm cancel or /hold comment for consistent failures.

@kubevirt-bot kubevirt-bot merged commit 78f37c8 into kubevirt:master Sep 7, 2020
EdDev added a commit to EdDev/kubevirt that referenced this pull request Sep 9, 2020
…figuration"

The change causes constant failure when running focused tests [1],
failing on [2].

Another issue the PR introduced has a proposed fix [3].

1. https://github.com/kubevirt/kubevirt/blob/
   bfe9df0/tests/vmi_networking_test.go#L677
2. https://github.com/kubevirt/kubevirt/blob/master/tests/utils.go#L2687
3. kubevirt#4143

This reverts commit 78f37c8, reversing
changes made to 7b70b99.
EdDev added a commit to EdDev/kubevirt that referenced this pull request Sep 9, 2020
…figuration"

The change causes constant failure when running focused tests [1],
failing on [2].

Another issue the PR introduced has a proposed fix [3].

1. https://github.com/kubevirt/kubevirt/blob/
   bfe9df0/tests/vmi_networking_test.go#L677
2. https://github.com/kubevirt/kubevirt/blob/master/tests/utils.go#L2687
3. kubevirt#4143

This reverts commit 78f37c8, reversing
changes made to 7b70b99.

Signed-off-by: Edward Haas <edwardh@redhat.com>
@ashleyschuett ashleyschuett deleted the patch-configuration branch October 5, 2020 11:42
@rmohr rmohr changed the title add patches to virt-controller add patches to virt-operator Jul 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. dco-signoff: yes Indicates the PR's author has DCO signed all their commits. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API lgtm Indicates that a PR is ready to be merged. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow for customization of virt-operator created deployments, daemonset
10 participants