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

Fix a bug that out-of-tree plugin is misplaced when using scheduler v1beta3 config #108613

Merged
merged 1 commit into from
Mar 22, 2022

Conversation

Huang-Wei
Copy link
Member

What type of PR is this?

/kind bug
/sig scheduling

What this PR does / why we need it:

When custom plugins are specified via regular extension points in v1beta3, the current logic places them at the head,, and then appends internal default plugins (in expandMultiPointPlugins()).

However, the eventual order should be like this:

  • part 1: plugins that are explicitly re-configured in multipoint (i.e., specified in both regular extension point and multipoint). Note their order should be intact as how they're configured in the regular extension point.
  • part 2: plugins enabled in multipoint excluding the ones in part 1. These plugins can be:
    • defaulted in-tree plugin
    • out-of-tree plugin
  • part 3: other plugins (excluded by part 1 & 2) in regular extension point. The category contains:
    • non-defaulted in-tree plugin
    • out-of-tree plugin

This PR changes the logic of expandMultiPointPlugins() to order the plugins when necessary.

Which issue(s) this PR fixes:

Fixes #108083

Special notes for your reviewer:

Does this PR introduce a user-facing change?

Fix a bug that out-of-tree plugin is misplaced when using scheduler v1beta3 config

@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. kind/bug Categorizes issue or PR as related to a bug. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. sig/scheduling Categorizes an issue or PR as relevant to SIG Scheduling. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Mar 9, 2022
@k8s-ci-robot
Copy link
Contributor

@Huang-Wei: This issue is currently awaiting triage.

If a SIG or subproject determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

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/test-infra repository.

@k8s-ci-robot k8s-ci-robot added needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Mar 9, 2022
@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Mar 9, 2022
@Huang-Wei
Copy link
Member Author

/retest

@Huang-Wei
Copy link
Member Author

With this PR, any testing plugin will be appended (not prepend) to the default plugins, that caused an integration test failure cuz DefaultBind would fail (due to the testing context), that failed the pod's scheduling as well as further TestBind plugin's execution.

@Huang-Wei
Copy link
Member Author

/retest

newPlugins := reflect.New(reflect.TypeOf(e.slicePtr).Elem()).Elem()
// part 1
deletionCnt := 0
for i, name := range enabledSet.list {
Copy link
Member Author

Choose a reason for hiding this comment

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

In Golang, the iteration order of a map is uncertain, and thus this PR introduces an orderedSet.

Another alternative is to use slice to replace enabledSet, but in that case, we need extra logic to deal with duplicated plugins.

@Huang-Wei
Copy link
Member Author

@damemi This PR is ready for review.


newPlugins := reflect.Append(plugins, reflect.ValueOf(pg))
plugins.Set(newPlugins)
}

// Reorder plugins if needed. Here is the expected order:
Copy link
Member

Choose a reason for hiding this comment

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

It seems like we rearrange all the plugin orders here. So when len(profile.Plugins.MultiPoint.Enabled) > 0, we no longer need above updatePluginList process anymore, right? If this makes sense, we should merge them together.

for _, e := range f.getExtensionPoints(profile.Plugins) {
if err := updatePluginList(e.slicePtr, *e.plugins, pluginsMap); err != nil {
return nil, err
}
}

Copy link
Member Author

@Huang-Wei Huang-Wei Mar 10, 2022

Choose a reason for hiding this comment

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

I still prefer to keep them separate. When len(profile.Plugins.MultiPoint.Enabled) > 0, it's not necessarily going to rearrange the plugins - e.g., all plugins defined in multipoint has been specified (say reconfigured) in the regular extension point.

@damemi
Copy link
Contributor

damemi commented Mar 10, 2022

Thanks for working on this @Huang-Wei, I will take add some review soon when I have a moment

enabledSet.delete(name)
}
}
// enabledSet.isEmpty() implies part 3 is empty, so don't need to continue
Copy link
Member

Choose a reason for hiding this comment

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

If I understood correctly, we can harmless remove https://github.com/kubernetes/kubernetes/blob/8ef5ccdad6bba8b664b51a8b29fd1a5ce396a59d/pkg/scheduler/framework/runtime/framework.go#L532-L535 and

newPlugins := reflect.Append(plugins, reflect.ValueOf(pg))
plugins.Set(newPlugins)

After removal, program still behaves the same but more clearly to read. Separate the reading and writing process.

Copy link
Member Author

Choose a reason for hiding this comment

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

SG. It reads better.

@Huang-Wei Huang-Wei force-pushed the fix-v1beta3-order branch 2 times, most recently from c856910 to 912f320 Compare March 11, 2022 20:26
@Huang-Wei
Copy link
Member Author

/retest

t.Fatal(err)
}

// plugin config
Copy link
Member

Choose a reason for hiding this comment

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

nit: replace with out-of-tree plugin config v1beta2

Copy link
Member Author

Choose a reason for hiding this comment

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

will update along with other comments.

plugins.Set(newPlugins)
// Reorder plugins. Here is the expected order:
// - part 1: overridePlugins. Their order stay intact as how they're specified in regular extension point.
// - part 2: multiPointEnabled - i.e., plugin defined in multipoint but not overriding regular extension point.
Copy link
Member

Choose a reason for hiding this comment

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

s/not overriding/not overrided by/

Copy link
Member Author

Choose a reason for hiding this comment

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

not really, it's the multi-point plugin overriding others instead of the other way around.

Copy link
Contributor

Choose a reason for hiding this comment

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

Aren't both correct? This is the set of multipoint plugins that aren't overriding (ie, not in part 1) but also they aren't being overridden (otherwise, they would be in part 1 as their overridden config). Part 1 includes explicitly reconfigured multiPoint plugins right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct, it's bi-directional. This may lead to less ambiguity?

// - part 2: multiPointEnabled - i.e., plugins defined in multipoint but not in regular extension point.

@kerthcet
Copy link
Member

Some nits, then LGTM. Left for @damemi for a further review.

@kerthcet
Copy link
Member

/retest

Copy link
Contributor

@damemi damemi left a comment

Choose a reason for hiding this comment

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

Looks good to me overall. I think breaking the logic out into 3 distinct sets makes it a bit clearer how the precedence works
/approve

}

func newOrderedSet() *orderedSet {
return &orderedSet{set: make(map[string]int)}
Copy link
Contributor

Choose a reason for hiding this comment

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

do you need to initialize the list too?

Copy link
Member

Choose a reason for hiding this comment

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

A nil slice is functionally equivalent to a zero-length slice. If we won't gone to use Marshal and reflect. DeepEqual with this field, freely to us. So I think we can omit it here.

Copy link
Member Author

Choose a reason for hiding this comment

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

yup, we usually don't need to initialize a slice. And in terms of using a slice: var s []string are in favor of s := []string.

@@ -656,6 +656,44 @@ func TestNewFrameworkMultiPointExpansion(t *testing.T) {
PostBind: config.PluginSet{Enabled: []config.Plugin{{Name: testPlugin}}},
},
},
{
name: "Reorder MultiPoint plugins (specified extension only takes precedence when it exists in MultiPoint)",
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this test covers the mix of use cases well

plugins.Set(newPlugins)
// Reorder plugins. Here is the expected order:
// - part 1: overridePlugins. Their order stay intact as how they're specified in regular extension point.
// - part 2: multiPointEnabled - i.e., plugin defined in multipoint but not overriding regular extension point.
Copy link
Contributor

Choose a reason for hiding this comment

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

Aren't both correct? This is the set of multipoint plugins that aren't overriding (ie, not in part 1) but also they aren't being overridden (otherwise, they would be in part 1 as their overridden config). Part 1 includes explicitly reconfigured multiPoint plugins right?

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: damemi, Huang-Wei

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

The pull request process is described 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

@Huang-Wei
Copy link
Member Author

Commits squashed.

@damemi please take a another look when you get a chance.

@Huang-Wei
Copy link
Member Author

@damemi could you please take another look?

@damemi
Copy link
Contributor

damemi commented Mar 21, 2022

Sorry @Huang-Wei, I only had those 2 nits. The rest looks good, thanks for fixing this
/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 21, 2022
@kerthcet
Copy link
Member

/retest

@kerthcet
Copy link
Member

We should rebase the code as we changed the PreFilterPlugin interface days before.

@k8s-triage-robot
Copy link

The Kubernetes project has merge-blocking tests that are currently too flaky to consistently pass.

This bot retests PRs for certain kubernetes repos according to the following rules:

  • The PR does have any do-not-merge/* labels
  • The PR does not have the needs-ok-to-test label
  • The PR is mergeable (does not have a needs-rebase label)
  • The PR is approved (has cncf-cla: yes, lgtm, approved labels)
  • The PR is failing tests required for merge

You can:

/retest

@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 21, 2022
@Huang-Wei
Copy link
Member Author

@kerthcet @damemi could you please re-/lgtm?

@denkensk
Copy link
Member

/lgtm

Thanks. @Huang-Wei

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 22, 2022
@kerthcet
Copy link
Member

/retest

@k8s-ci-robot k8s-ci-robot merged commit 0b8a665 into kubernetes:master Mar 22, 2022
@k8s-ci-robot k8s-ci-robot added this to the v1.24 milestone Mar 22, 2022
@Huang-Wei Huang-Wei deleted the fix-v1beta3-order branch March 22, 2022 18:21
k8s-ci-robot added a commit that referenced this pull request Apr 28, 2022
…08613-upstream-release-1.23

Automated cherry pick of #108613: Fix a bug that out-of-tree plugin is misplaced when using
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. area/test cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/scheduling Categorizes an issue or PR as relevant to SIG Scheduling. sig/testing Categorizes an issue or PR as relevant to SIG Testing. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

scheduler v1beta3 pre-appends an out-of-tree plugin instead of append
6 participants