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 nil interface{} checks #1459

Merged
merged 1 commit into from
Nov 6, 2023
Merged

Conversation

tpantelis
Copy link
Contributor

PR #1447 changed places where we check for nil interface{} in the callback functions for AwaitUntil to cast first. However this can result in an invalid type conversion panic depending on how the value is returned from the operation function. In Go, an interface var contains both a type and value so there are 2 cases for a nil:

  1. The type is non-nil and the value is nil
  2. The type and value are nil

For 1, the interface{} var is not actually nil so checking if result == nil yields false. Eg,

  var s *string
  var i interface{} = s

  if i == nil { // yields false b/c i is typed
  }

In this case, we can cast to the expected type and then check for nil.

s := i.(*string)
if s == nil {  // yields true
}

For 2, the interface{} var is untyped so nil check yields true:

var i interface{} = nil
 if i == nil { // yields true
 }

So in cases where we directly return nil from an operation function, the nil check in the result function is valid.

The actual reason for #1447 was b/c of a nil pointer panic in AwaitGatewaysWithStatus. This function was previously changed to call findGateway and return its values. However findGateway returns *unstructured.Unstructured so now the operation function returned a typed interface{} var. So if findGateway returns a nil *unstructured.Unstructured value, the result == nil check in the result function yields false. This resulted in the panic when result was later casted and accessed.

So we basically need to undo #1447. For AwaitGatewayWithStatus and AwaitGatewayFullyConnected, check the error from findGateway and return a nil interface{} value.

@tpantelis tpantelis self-assigned this Nov 6, 2023
@submariner-bot
Copy link

🤖 Created branch: z_pr1459/tpantelis/fix_nil_checks

PR submariner-io#1447 changed places
where we check for nil interface{} in the callback functions for
AwaitUntil to cast first. However this can result in an invalid type
conversion panic depending on how the value is returned from the
operation function. In Go, an interface var contains both a type and
value so there are 2 cases for a nil:

 1) The type is non-nil and the value is nil
 2) The type and value are nil

For #1, the interface{} var is not actually nil so checking
'if result == nil' yields false. Eg,

  var s *string
  var i interface{} = s

  if i == nil { // yields false b/c i is typed
  }

In this case, we can cast to the expected type and then check for nil.

  s := i.(*string)
  if s == nil {  // yields true
  }

For #2, the interface{} var is untyped so nil check yields true:

  var i interface{} = nil
  if i == nil { // yields true
  }

So in cases where we directly return nil from an operation function, the
nil check in the result function is valid.

The actual reason for submariner-io#1447 was b/c of a nil pointer panic in
AwaitGatewaysWithStatus. This function was previously changed to call
'findGateway' and return its values. However 'findGateway' returns
*unstructured.Unstructured so now the operation function returned
a typed interface{} var. So if 'findGateway' returns a nil
*unstructured.Unstructured value, the 'result == nil' check in the
result function yields false. This resulted in the panic when 'result'
was later casted and accessed.

So we basically need to undo submariner-io#1447. For AwaitGatewayWithStatus and
AwaitGatewayFullyConnected, check the error from 'findGateway' and
return a nil interface{} value.

Signed-off-by: Tom Pantelis <tompantelis@gmail.com>
@tpantelis tpantelis enabled auto-merge (rebase) November 6, 2023 16:04
@tpantelis tpantelis disabled auto-merge November 6, 2023 16:30
@tpantelis
Copy link
Contributor Author

tpantelis commented Nov 6, 2023

The globalnet w/ helm job is failing:

E1106 16:18:52.373476 1 leaderelection.go:327] error retrieving resource lock submariner-operator/submariner-globalnet-lock: leases.coordination.k8s.io "submariner-globalnet-lock" is forbidden: User "system:serviceaccount:submariner-operator:submariner-globalnet" cannot get resource "leases" in API group "coordination.k8s.io" in the namespace "submariner-operator"

Need to update the helm chart to add submariner-globalnet permissions. This issue is orthogonal so shouldn't block this PR so force merging.

@tpantelis tpantelis merged commit cc0d7db into submariner-io:devel Nov 6, 2023
45 of 46 checks passed
@submariner-bot
Copy link

🤖 Closed branches: [z_pr1459/tpantelis/fix_nil_checks]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants