diff --git a/pkg/api/deep_copy_generated.go b/pkg/api/deep_copy_generated.go index 4021137fc1d..9898e2dc70e 100644 --- a/pkg/api/deep_copy_generated.go +++ b/pkg/api/deep_copy_generated.go @@ -737,6 +737,8 @@ func deepCopy_api_List(in List, out *List, c *conversion.Cloner) error { for i := range in.Items { if newVal, err := c.DeepCopy(in.Items[i]); err != nil { return err + } else if newVal == nil { + out.Items[i] = nil } else { out.Items[i] = newVal.(runtime.Object) } @@ -759,11 +761,15 @@ func deepCopy_api_ListOptions(in ListOptions, out *ListOptions, c *conversion.Cl } if newVal, err := c.DeepCopy(in.LabelSelector); err != nil { return err + } else if newVal == nil { + out.LabelSelector = nil } else { out.LabelSelector = newVal.(labels.Selector) } if newVal, err := c.DeepCopy(in.FieldSelector); err != nil { return err + } else if newVal == nil { + out.FieldSelector = nil } else { out.FieldSelector = newVal.(fields.Selector) } @@ -2125,6 +2131,8 @@ func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c if in.Amount != nil { if newVal, err := c.DeepCopy(in.Amount); err != nil { return err + } else if newVal == nil { + out.Amount = nil } else { out.Amount = newVal.(*inf.Dec) } diff --git a/pkg/api/v1/deep_copy_generated.go b/pkg/api/v1/deep_copy_generated.go index cd710336ed6..2d6f64c6ae9 100644 --- a/pkg/api/v1/deep_copy_generated.go +++ b/pkg/api/v1/deep_copy_generated.go @@ -32,6 +32,8 @@ func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c if in.Amount != nil { if newVal, err := c.DeepCopy(in.Amount); err != nil { return err + } else if newVal == nil { + out.Amount = nil } else { out.Amount = newVal.(*inf.Dec) } diff --git a/pkg/conversion/cloner.go b/pkg/conversion/cloner.go index 43ed27007ed..a8c57471327 100644 --- a/pkg/conversion/cloner.go +++ b/pkg/conversion/cloner.go @@ -117,6 +117,13 @@ func (c *Cloner) RegisterGeneratedDeepCopyFunc(deepCopyFunc interface{}) error { // DeepCopy will perform a deep copy of a given object. func (c *Cloner) DeepCopy(in interface{}) (interface{}, error) { + // Can be invalid if we run DeepCopy(X) where X is a nil interface type. + // For example, we get an invalid value when someone tries to deep-copy + // a nil labels.Selector. + // This does not occur if X is nil and is a pointer to a concrete type. + if in == nil { + return nil, nil + } inValue := reflect.ValueOf(in) outValue, err := c.deepCopy(inValue) if err != nil { diff --git a/pkg/runtime/deep_copy_generator.go b/pkg/runtime/deep_copy_generator.go index 0b05d1470f3..45fe3a01926 100644 --- a/pkg/runtime/deep_copy_generator.go +++ b/pkg/runtime/deep_copy_generator.go @@ -420,6 +420,8 @@ func (g *deepCopyGenerator) writeDeepCopyForPtr(b *buffer, inField reflect.Struc ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent+1) b.addLine("return err\n", indent+2) + b.addLine("} else if newVal == nil {\n", indent+1) + b.addLine(fmt.Sprintf("out.%s = nil\n", inField.Name), indent+2) b.addLine("} else {\n", indent+1) assignFormat := "out.%s = newVal.(%s)\n" assignStmt := fmt.Sprintf(assignFormat, inField.Name, g.typeName(inField.Type)) @@ -467,6 +469,8 @@ func (g *deepCopyGenerator) writeDeepCopyForSlice(b *buffer, inField reflect.Str ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent+2) b.addLine("return err\n", indent+3) + b.addLine("} else if newVal == nil {\n", indent+2) + b.addLine(fmt.Sprintf("out.%s[i] = nil\n", inField.Name), indent+3) b.addLine("} else {\n", indent+2) assignFormat := "out.%s[i] = newVal.(%s)\n" assignStmt := fmt.Sprintf(assignFormat, inField.Name, g.typeName(inField.Type.Elem())) @@ -508,6 +512,8 @@ func (g *deepCopyGenerator) writeDeepCopyForStruct(b *buffer, inType reflect.Typ ifStmt := fmt.Sprintf(ifFormat, inField.Name) b.addLine(ifStmt, indent) b.addLine("return err\n", indent+1) + b.addLine("} else if newVal == nil {\n", indent) + b.addLine(fmt.Sprintf("out.%s = nil\n", inField.Name), indent+1) b.addLine("} else {\n", indent) copyFormat := "out.%s = newVal.(%s)\n" copyStmt := fmt.Sprintf(copyFormat, inField.Name, g.typeName(inField.Type))