-
Notifications
You must be signed in to change notification settings - Fork 20
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
base: main
Are you sure you want to change the base?
Move merging of workflow section into webhook #168
Conversation
Skipping CI for Draft Pull Request. |
There was a problem hiding this 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.
controllers/tempest_controller.go
Outdated
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 | ||
} |
There was a problem hiding this comment.
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:).
controllers/tempest_controller.go
Outdated
return instance.Spec.TempestRun | ||
} | ||
|
||
func changeType(wtRun testv1beta1.WorkflowTempestRunSpec) testv1beta1.TempestRunSpec { |
There was a problem hiding this comment.
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.
func changeType(wtRun testv1beta1.WorkflowTempestRunSpec) testv1beta1.TempestRunSpec { | |
func changeType(instance interface{}) instance interface{} { |
e880a74
to
af17dde
Compare
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.
af17dde
to
6b1c12c
Compare
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. |
There was a problem hiding this 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:).
api/v1beta1/common_webhook.go
Outdated
tRunValue := src.Field(i) | ||
wtRunValue := dest.FieldByName(tRunName) | ||
|
||
if wtRunValue.IsZero() && !tRunValue.IsZero() { |
There was a problem hiding this comment.
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?
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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:
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?:)
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
} | ||
|
||
func changeType(instance interface{}, workflowStepNum int) interface{} { | ||
// TODO other types; else if typedInstance, ok := instance.(*v1beta1.HorizonTest); |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
api/v1beta1/common_webhook.go
Outdated
tRun := spec.TempestRun | ||
wtRun := &spec.Workflow[workflowStepNum].TempestRun |
There was a problem hiding this comment.
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, ...).
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
.
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.
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: kstrenkova 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 |
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. |
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. |
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