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 findOpenPorts portAllocator function #1725

Merged
merged 3 commits into from
Aug 6, 2020

Conversation

aLekSer
Copy link
Collaborator

@aLekSer aLekSer commented Jul 29, 2020

There could be the possible case when we set PortPolicy as an empty
string on update of GameServer.

What type of PR is this?

/kind bug

What this PR does / Why we need it:

There is a way to cause infinite loop (recursion) in Allocate() function using kubectl edit gameservers, if you update the PortPolicy to an empty string "" and one more field. Then you would receive the state when Agones controller could not allocate any ports and got stuck in this state:

kubectl get gs
NAME                     STATE            ADDRESS         PORT   NODE                                     AGE
simple-udp-2skbm-657tc   PortAllocation                                                                   18m
simple-udp-2skbm-894s9   PortAllocation                                                                   18m
simple-udp-7xxfz         PortAllocation   35.230.21.139          gke-test-cluster-default-5847533f-6z66   73m

Which issue(s) this PR fixes:
none

Special notes for your reviewer:
This is not expected scenario of editing GameServer but I assume that restarting agones controller with deleting bad GameServer would recover from this situation.

@agones-bot
Copy link
Collaborator

Build Succeeded 👏

Build Id: d5bc282d-f118-475a-9e97-c872153beb12

The following development artifacts have been built, and will exist for the next 30 days:

A preview of the website (the last 30 builds are retained):

To install this version:

  • git fetch https://github.com/googleforgames/agones.git pull/1725/head:pr_1725 && git checkout pr_1725
  • helm install ./install/helm/agones --namespace agones-system --name agones --set agones.image.tag=1.8.0-fabc044

@aLekSer
Copy link
Collaborator Author

aLekSer commented Jul 29, 2020

Note that in that case of amount=0 we never return from the recursion as if condition in line https://github.com/googleforgames/agones/blob/master/pkg/gameservers/portallocator.go#L146 would always be false.

@agones-bot
Copy link
Collaborator

Build Failed 😱

Build Id: 1c8aa1ec-e06a-4a63-ad29-2f241ee39617

To get permission to view the Cloud Build view, join the agones-discuss Google Group.

// single port empty
fd := fixture.DeepCopy()
fd.Spec.Ports[0].PortPolicy = ""
pa.Allocate(fd)
Copy link
Contributor

Choose a reason for hiding this comment

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

Allocate returns GameServer pointer, so it is worth checking it for nil.

fd := fixture.DeepCopy()
fd.Spec.Ports[0].PortPolicy = ""
pa.Allocate(fd)
assert.Nil(t, err)
Copy link
Contributor

Choose a reason for hiding this comment

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

Which error do you check here? Seems this assert is redundant.

assert.True(t, cache.WaitForCacheSync(stop, pa.nodeSynced))

err := pa.syncAll()
assert.Nil(t, err)
Copy link
Contributor

Choose a reason for hiding this comment

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

Use require here, please. If an error happens here there is no point 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.

Also use NoError over Nil - that way if it fails, we get a better error message.

@@ -39,6 +39,37 @@ var (
n3 = corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: "node3", UID: "node3"}}
)

func TestEmptyPortPolicy(t *testing.T) {
Copy link
Contributor

@akremsa akremsa Jul 31, 2020

Choose a reason for hiding this comment

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

I think this test name is not accurate. It should describe which function do you test.
There is a test function TestPortAllocatorAllocate, so you can put this scenario there as a separate t.Run("empty port policy") statement.

Copy link
Member

Choose a reason for hiding this comment

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

"TestPortAllocatorAllocateWithEmptyPolicy" ?

Copy link
Contributor

@akremsa akremsa left a comment

Choose a reason for hiding this comment

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

several changes have been requested

@google-oss-robot
Copy link

@akremsa: changing LGTM is restricted to collaborators

In response to this:

several changes have been requested

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.

Copy link
Member

@markmandel markmandel left a comment

Choose a reason for hiding this comment

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

Doh! I never submitted this review!

fd := fixture.DeepCopy()
fd.Spec.Ports[0].PortPolicy = ""
pa.Allocate(fd)
assert.Nil(t, err)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
assert.Nil(t, err)
assert.NoError(t, err)

(gives a better message on failure)

assert.True(t, cache.WaitForCacheSync(stop, pa.nodeSynced))

err := pa.syncAll()
assert.Nil(t, err)
Copy link
Member

Choose a reason for hiding this comment

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

Also use NoError over Nil - that way if it fails, we get a better error message.

@@ -39,6 +39,37 @@ var (
n3 = corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: "node3", UID: "node3"}}
)

func TestEmptyPortPolicy(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

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

"TestPortAllocatorAllocateWithEmptyPolicy" ?

@@ -121,6 +121,9 @@ func (pa *PortAllocator) Allocate(gs *agonesv1.GameServer) *agonesv1.GameServer
// Also the return gives an escape from the double loop
findOpenPorts := func(amount int) []pn {
var ports []pn
if amount <= 0 {
Copy link
Member

Choose a reason for hiding this comment

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

Excellent short circuit! 👍

@aLekSer
Copy link
Collaborator Author

aLekSer commented Aug 4, 2020

Thanks for the review, I have applied both series of comments.

@agones-bot
Copy link
Collaborator

Build Succeeded 👏

Build Id: 5bcf26fb-3fc7-409e-9441-37a1e70e72c8

The following development artifacts have been built, and will exist for the next 30 days:

A preview of the website (the last 30 builds are retained):

To install this version:

  • git fetch https://github.com/googleforgames/agones.git pull/1725/head:pr_1725 && git checkout pr_1725
  • helm install ./install/helm/agones --namespace agones-system --name agones --set agones.image.tag=1.8.0-5296de6

@google-oss-robot
Copy link

@akremsa: changing LGTM is restricted to collaborators

In response to this:

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.

aLekSer added 3 commits August 6, 2020 10:59
There could be the possible case when we set PortPolicy as an empty
string on update of GameServer.
@aLekSer aLekSer force-pushed the fix/findOpenPorts branch from 5296de6 to fc49377 Compare August 6, 2020 08:00
@agones-bot
Copy link
Collaborator

Build Succeeded 👏

Build Id: 2eb288d6-4d54-42d9-9b69-fd37ba14576f

The following development artifacts have been built, and will exist for the next 30 days:

A preview of the website (the last 30 builds are retained):

To install this version:

  • git fetch https://github.com/googleforgames/agones.git pull/1725/head:pr_1725 && git checkout pr_1725
  • helm install ./install/helm/agones --namespace agones-system --name agones --set agones.image.tag=1.8.0-fc49377

Copy link
Member

@markmandel markmandel left a comment

Choose a reason for hiding this comment

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

Love it!

This also ties nicely into #749

@google-oss-robot
Copy link

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: akremsa, aLekSer, markmandel

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

@markmandel markmandel merged commit c28848a into googleforgames:master Aug 6, 2020
@markmandel markmandel added area/user-experience Pertaining to developers trying to use Agones, e.g. SDK, installation, etc kind/bug These are bugs. and removed area/user-experience Pertaining to developers trying to use Agones, e.g. SDK, installation, etc labels Aug 6, 2020
@markmandel markmandel added this to the 1.8.0 milestone Aug 6, 2020
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this pull request Oct 23, 2020
* Fix findOpenPorts portAllocator function

There could be the possible case when we set PortPolicy as an empty
string on update of GameServer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved area/user-experience Pertaining to developers trying to use Agones, e.g. SDK, installation, etc cla: yes kind/bug These are bugs. lgtm size/S
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants