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

Move merging of workflow section into webhook #168

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

kstrenkova
Copy link
Contributor

Currently, the merging of workflow section is done in controllers of related CRs. We want to move the merging logic into webhooks to make the process cleaner.

Depends on: #160

Copy link

openshift-ci bot commented Aug 12, 2024

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

Copy link
Collaborator

@lpiwowar lpiwowar left a comment

Choose a reason for hiding this comment

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

@kstrenkova, this is really nice progress! 🎉 I say we schedule a call and discuss details but generally speaking I think we can make this work. I've just tried to test this locally. I had to make some minor tweaks (see comments) for the merging to work on the TempestRun section on my machine.

Anyway, really good job! 👍 Even when you do not manage to finish this task and somebody will be working on it instead of you then you still laid a really good foundation here!

From our last conversation I was under the impression that this won't work. I think this will still require 2 - 3 PR updates and reviews but it is on a good path.

api/v1beta1/tempest_webhook.go Outdated Show resolved Hide resolved
api/v1beta1/tempest_webhook.go Outdated Show resolved Hide resolved
api/v1beta1/tempest_webhook.go Outdated Show resolved Hide resolved
api/v1beta1/tempest_webhook.go Outdated Show resolved Hide resolved
api/v1beta1/tempest_webhook.go Outdated Show resolved Hide resolved
api/v1beta1/tempest_webhook.go Outdated Show resolved Hide resolved
Comment on lines 515 to 541
func getTempestRun(instance *testv1beta1.Tempest, workflowStepNum int) testv1beta1.TempestRunSpec {
if workflowStepNum < len(instance.Spec.Workflow) {
wtRun := instance.Spec.Workflow[workflowStepNum].TempestRun
tRun := changeType(wtRun)
return tRun
}
return instance.Spec.TempestRun
}

func changeType(wtRun testv1beta1.WorkflowTempestRunSpec) testv1beta1.TempestRunSpec {
var tRun testv1beta1.TempestRunSpec

wtReflected := reflect.ValueOf(wtRun)
tReflected := reflect.ValueOf(&tRun).Elem()

for i := 0; i < wtReflected.NumField(); i++ {
tName := tReflected.Type().Field(i).Name
tValue := tReflected.Field(i)

wtValue := wtReflected.FieldByName(tName)
if !wtValue.IsNil() {
wtValue = wtValue.Elem()
tValue.Set(wtValue)
}
}
return tRun
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice solution! 🥳

I'm wondering whether we can bypass this somehow. I'm thinking about getting rid of the pointers entirely. But this can be a little bit tricky.

But even if we do not make the workflows work without the pointers then I think that calling a slight modification of this function at the beginning of the reconcile loop won't hurt.

Again, we can make this little bit more generic:).

return instance.Spec.TempestRun
}

func changeType(wtRun testv1beta1.WorkflowTempestRunSpec) testv1beta1.TempestRunSpec {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should aim at making this function more generic by replacing the types with interface{}. The caller of the function will be responsible of casting the result to a correct type.

Suggested change
func changeType(wtRun testv1beta1.WorkflowTempestRunSpec) testv1beta1.TempestRunSpec {
func changeType(instance interface{}) instance interface{} {

controllers/tempest_controller.go Outdated Show resolved Hide resolved
@kstrenkova kstrenkova force-pushed the merge-workflow-section-in-webhook branch from e880a74 to af17dde Compare September 30, 2024 19:24
Currently, the merging of workflow section is done in controllers
of related CRs. We want to move the merging logic into webhooks
to make the process cleaner.
@kstrenkova kstrenkova force-pushed the merge-workflow-section-in-webhook branch from af17dde to 6b1c12c Compare October 22, 2024 12:43
@kstrenkova
Copy link
Contributor Author

I have added a new version of this patch that can also work with structures by calling the function for adding values from TempestRun section recursively. There is maybe needed a bit more generalization to get the functions working for all resources, but for Tempest this version should work.

Copy link
Collaborator

@lpiwowar lpiwowar left a comment

Choose a reason for hiding this comment

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

I think the PR is moving in the right direction. Nice work! 👍

I've added couple of comments @kstrenkova. Let me know what you think:).

tRunValue := src.Field(i)
wtRunValue := dest.FieldByName(tRunName)

if wtRunValue.IsZero() && !tRunValue.IsZero() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

The use of IsZero() function is not 100 % accurate here because IsZero() returns true when variable e.g. concurrency is set to 0 [1].

What do you think @kstrenkova about this? Would it be a problem?

Suggested change
if wtRunValue.IsZero() && !tRunValue.IsZero() {
if wtRunValue.IsNil() {

You can also use wtRunValue.IsZero() it is an equivalent to wtRunValue.IsNil() when wtRunValue is a pointer.

[1] https://cs.opensource.google/go/go/+/refs/tags/go1.23.2:src/reflect/value.go;l=1572

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch, I think the need for !tRunValue.IsNil is still there though 🤔 The problem was that if the value in tempestRun was nil, it would create an error.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, you are right:

The Tempest "tempest-tests" is invalid:
* spec.workflow[0].tempestRun.extraImagesType: Invalid value: "null": spec.workflow[0].tempestRun.extraImagesType in body must be of type array: "null"
* spec.workflow[0].tempestRun.externalPlugin: Invalid value: "null": spec.workflow[0].tempestRun.externalPlugin in body must be of type array: "null"
* spec.workflow[0].tempestRun.extraRPMs: Invalid value: "null": spec.workflow[0].tempestRun.extraRPMs in body must be of type array: "null"

Notice that the error only impacts arrays. We are trying to assign null to what should be a pointer to an array. Is there a way how to fix this? What about checking whether the array is empty in the tRun section and if it is then do not perform the assignment?

@@ -28,3 +33,42 @@ const (
"ensures that the copying of the logs to the PV is completed without any " +
"complications."
)

// merge non-workflow section into workflow
func mergeSectionIntoWorkflow(instance interface{}, workflowStepNum int) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would modify the interface of this function like this:

Suggested change
func mergeSectionIntoWorkflow(instance interface{}, workflowStepNum int) {
func mergeSectionIntoWorkflow(instance interface{}, instanceWorkflowSection {}interface) {

It would be a responsibility of the webhook to pass the correct values. Wdyt?:)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I looked into it and I don't understand why this would be needed 😄 Could you please explain your thought behind it a bit more?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ok, so the idea for this function is to be generic because it is inside of the commonw_webhook.go . It should work for Tempest, Tobiko, HorizonTest and AnsibleTest CR. Yet you have a code which is specific to Tempest CR inside the function [1].

The idea is that inside the webhook you would call this function like this:

if len(spec.Workflow) > 0 {
	for _, workflowStepSpec := range spec.Workflow {
		mergeSectionIntoWorkflow(spec, workflowStepSpec)
	}
}

This would allow you to avoid the need to cast the instance variable to TempestSpec before you can grab the workflow section.

[1] here

api/v1beta1/common_webhook.go Show resolved Hide resolved
api/v1beta1/common_webhook.go Outdated Show resolved Hide resolved
}

func changeType(instance interface{}, workflowStepNum int) interface{} {
// TODO other types; else if typedInstance, ok := instance.(*v1beta1.HorizonTest);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, I agree:)

@@ -550,3 +550,38 @@ func GetCommonRbacRules(privileged bool) []rbacv1.PolicyRule {

return []rbacv1.PolicyRule{rbacPolicyRule}
}

// TODO make general for all resources
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

Comment on lines 45 to 46
tRun := spec.TempestRun
wtRun := &spec.Workflow[workflowStepNum].TempestRun
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can start the copying of the non-workflow values directly from Spec.. I know it was not done like so up until now for Tempest CR. The long term goal is to unify the behavior of the CRs so it would be nice to keep it consistent with the rest of them (like tobiko, ansibletest, ...).

Suggested change
tRun := spec.TempestRun
wtRun := &spec.Workflow[workflowStepNum].TempestRun
tRun := spec
wtRun := &spec.Workflow[workflowStepNum]

It might require some changes here:) [1].

Also, we should add similar behavior for the TempestconfRunSpec.

[1] here
[2] here

lpiwowar and others added 16 commits December 3, 2024 04:56
This patch adds reviewers who would be capable of adding /lgtm on
test-operator PRs.
When a workflow is set without ExtraConfigMap in ansible controller the
pod won't be able to start because the pointer won't be pointing at
nothing. Changed the condition to allow avoiding this issue.

not tested, waiting for a test enviornment to work on this

Jira: https://issues.redhat.com/browse/OSPRH-11191
This patch fixes the issue when ExtraConfigmapsMounts is empty.
Dereferencing a nil pointer leads to a panic.

We now first check whether the pointer is nil and then move to
dereferencing it.
For BGP setup there is the need to set the default gateway
to the additional interface defined via the multus annotations.
To allow this a user can configure `ipam.gateway` in the NAD.
EnsureNetworksAnnotation() will override the pod network default
route by reading the NAD. If `ipam.gateway` is defined and not "",
it gets set on the networks annotation as the `default-route`.

Jira: https://issues.redhat.com/browse/OSPRH-8680

Depends-On: openstack-k8s-operators/lib-common#579

Signed-off-by: Martin Schuppert <mschuppert@redhat.com>
The Expected Failures List parameter will help with specifying set
of tests whose failures we want to ignore. By adding test to this
list, its failure will not have impact on the jobs pass/fail. It
can help with not having to re-run long running jobs and save
time and resources in specific cases, for example when dealing
with flaky tests.

Depends-On: openstack-k8s-operators/ci-framework#2513
The Ensure[Horizon|Tobiko]CloudsYAML function was failing when
the CM containing the modified clouds.yaml already existed:

  Object openstack/horizontest-clouds-config is already owned
  by another HorizonTest controller horizontest-tests

This patch does two things:

  - Ensures that we do not create the modified clouds.yaml when it
    already exists.

  - Removes the duplicate implementation of of the Ensure*CloudsYAML
    function and replaces it with EnsureCloudsConfigMapExists.
Usually directories are ordered alphabetically when we access to them
via CLI or UI.
With this change the alphabetical order corresponds with the workflow
order.
There was a race condition in the previous implementation of the
workflows that was caused by the dependency of the workflow feature
on a ConfigMap that served as counter.

This commit simplifies the logic of the Reconcile loop in two ways:

  1. Removes the dependency for an external workflow counter

  2. Introduces NextAction function which decides what next action
     should be performed by the Reconcile loop based on the current
     state of the OpenShift cluster. The input of this function is the
     instance which is currently being processed and a workflowLength.
     Using these two arguments it then tells the Reconcile loop which
     actions it should perform: Wait, CreateFirstJob, CreateNextJob,
     EndTesting, Failure.

This approach should simplify the reconcile logic and move the
test-operator towards a unified Reconcile loop.
This patch enables the Tempest cleanup feature that cleans all
resources created during the Tempest test execution.

Depends-On: openstack-k8s-operators/ci-framework#2381
Currently, the merging of workflow section is done in controllers
of related CRs. We want to move the merging logic into webhooks
to make the process cleaner.
Copy link

openshift-ci bot commented Dec 3, 2024

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: kstrenkova
Once this PR has been reviewed and has the lgtm label, please ask for approval from lpiwowar. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot removed the approved label Dec 3, 2024
Copy link

Merge Failed.

This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset.
Warning:
Error merging github.com/openstack-k8s-operators/test-operator for 168,acf536c9054f5be35f0179a5d34578f8977aa19c

@openshift-merge-robot
Copy link
Collaborator

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants