diff --git a/api/swagger-spec/apps_v1alpha1.json b/api/swagger-spec/apps_v1alpha1.json index 34e122437da..13a1534e94a 100644 --- a/api/swagger-spec/apps_v1alpha1.json +++ b/api/swagger-spec/apps_v1alpha1.json @@ -1100,7 +1100,7 @@ "items": { "$ref": "v1.OwnerReference" }, - "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected." + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller." }, "finalizers": { "type": "array", @@ -1136,6 +1136,10 @@ "uid": { "type": "string", "description": "UID of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids" + }, + "controller": { + "type": "boolean", + "description": "If true, this reference points to the managing controller." } } }, diff --git a/api/swagger-spec/autoscaling_v1.json b/api/swagger-spec/autoscaling_v1.json index ffedf2692fa..12d1dbbac0b 100644 --- a/api/swagger-spec/autoscaling_v1.json +++ b/api/swagger-spec/autoscaling_v1.json @@ -1103,7 +1103,7 @@ "items": { "$ref": "v1.OwnerReference" }, - "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected." + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller." }, "finalizers": { "type": "array", @@ -1139,6 +1139,10 @@ "uid": { "type": "string", "description": "UID of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids" + }, + "controller": { + "type": "boolean", + "description": "If true, this reference points to the managing controller." } } }, diff --git a/api/swagger-spec/batch_v1.json b/api/swagger-spec/batch_v1.json index 87e3c426f62..a8824a1a220 100644 --- a/api/swagger-spec/batch_v1.json +++ b/api/swagger-spec/batch_v1.json @@ -1103,7 +1103,7 @@ "items": { "$ref": "v1.OwnerReference" }, - "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected." + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller." }, "finalizers": { "type": "array", @@ -1139,6 +1139,10 @@ "uid": { "type": "string", "description": "UID of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids" + }, + "controller": { + "type": "boolean", + "description": "If true, this reference points to the managing controller." } } }, diff --git a/api/swagger-spec/extensions_v1beta1.json b/api/swagger-spec/extensions_v1beta1.json index db44f2d56f2..623a1a8ca5d 100644 --- a/api/swagger-spec/extensions_v1beta1.json +++ b/api/swagger-spec/extensions_v1beta1.json @@ -6949,7 +6949,7 @@ "items": { "$ref": "v1.OwnerReference" }, - "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected." + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller." }, "finalizers": { "type": "array", @@ -6985,6 +6985,10 @@ "uid": { "type": "string", "description": "UID of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids" + }, + "controller": { + "type": "boolean", + "description": "If true, this reference points to the managing controller." } } }, diff --git a/api/swagger-spec/policy_v1alpha1.json b/api/swagger-spec/policy_v1alpha1.json index bdb64e0ac0a..3d10d7dc9cf 100644 --- a/api/swagger-spec/policy_v1alpha1.json +++ b/api/swagger-spec/policy_v1alpha1.json @@ -1100,7 +1100,7 @@ "items": { "$ref": "v1.OwnerReference" }, - "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected." + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller." }, "finalizers": { "type": "array", @@ -1136,6 +1136,10 @@ "uid": { "type": "string", "description": "UID of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids" + }, + "controller": { + "type": "boolean", + "description": "If true, this reference points to the managing controller." } } }, diff --git a/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json b/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json index 3d1aeea5582..efe783ae4a0 100644 --- a/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json +++ b/api/swagger-spec/rbac.authorization.k8s.io_v1alpha1.json @@ -2773,7 +2773,7 @@ "items": { "$ref": "v1.OwnerReference" }, - "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected." + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller." }, "finalizers": { "type": "array", @@ -2809,6 +2809,10 @@ "uid": { "type": "string", "description": "UID of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids" + }, + "controller": { + "type": "boolean", + "description": "If true, this reference points to the managing controller." } } }, diff --git a/api/swagger-spec/v1.json b/api/swagger-spec/v1.json index e637cf516a3..c32d962c951 100644 --- a/api/swagger-spec/v1.json +++ b/api/swagger-spec/v1.json @@ -15884,7 +15884,7 @@ "items": { "$ref": "v1.OwnerReference" }, - "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected." + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller." }, "finalizers": { "type": "array", @@ -15920,6 +15920,10 @@ "uid": { "type": "string", "description": "UID of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids" + }, + "controller": { + "type": "boolean", + "description": "If true, this reference points to the managing controller." } } }, diff --git a/docs/api-reference/autoscaling/v1/definitions.html b/docs/api-reference/autoscaling/v1/definitions.html index 68336b212bb..733b1bc67d6 100755 --- a/docs/api-reference/autoscaling/v1/definitions.html +++ b/docs/api-reference/autoscaling/v1/definitions.html @@ -1182,7 +1182,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

ownerReferences

-

List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected.

+

List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.

false

v1.OwnerReference array

@@ -1249,6 +1249,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

string

+ +

controller

+

If true, this reference points to the managing controller.

+

false

+

boolean

+

false

+ diff --git a/docs/api-reference/batch/v1/definitions.html b/docs/api-reference/batch/v1/definitions.html index ae27256e332..18754573de4 100755 --- a/docs/api-reference/batch/v1/definitions.html +++ b/docs/api-reference/batch/v1/definitions.html @@ -1737,7 +1737,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

ownerReferences

-

List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected.

+

List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.

false

v1.OwnerReference array

@@ -1804,6 +1804,13 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

string

+ +

controller

+

If true, this reference points to the managing controller.

+

false

+

boolean

+

false

+ diff --git a/docs/api-reference/extensions/v1beta1/definitions.html b/docs/api-reference/extensions/v1beta1/definitions.html index 28b4cd3e876..a38cf74d7ea 100755 --- a/docs/api-reference/extensions/v1beta1/definitions.html +++ b/docs/api-reference/extensions/v1beta1/definitions.html @@ -1644,7 +1644,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

ownerReferences

-

List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected.

+

List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.

false

v1.OwnerReference array

@@ -5010,6 +5010,13 @@ Both these may change in the future. Incoming requests are matched against the h

string

+ +

controller

+

If true, this reference points to the managing controller.

+

false

+

boolean

+

false

+ diff --git a/docs/api-reference/v1/definitions.html b/docs/api-reference/v1/definitions.html index 679687ab9db..31b5ed299bf 100755 --- a/docs/api-reference/v1/definitions.html +++ b/docs/api-reference/v1/definitions.html @@ -2000,7 +2000,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i

ownerReferences

-

List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected.

+

List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.

false

v1.OwnerReference array

@@ -6114,6 +6114,13 @@ The resulting set of endpoints can be viewed as:

string

+ +

controller

+

If true, this reference points to the managing controller.

+

false

+

boolean

+

false

+ diff --git a/pkg/api/deep_copy_generated.go b/pkg/api/deep_copy_generated.go index d7cd009ef04..a535f40a28c 100644 --- a/pkg/api/deep_copy_generated.go +++ b/pkg/api/deep_copy_generated.go @@ -1706,6 +1706,13 @@ func DeepCopy_api_OwnerReference(in OwnerReference, out *OwnerReference, c *conv out.Kind = in.Kind out.Name = in.Name out.UID = in.UID + if in.Controller != nil { + in, out := in.Controller, &out.Controller + *out = new(bool) + **out = *in + } else { + out.Controller = nil + } return nil } diff --git a/pkg/api/meta.go b/pkg/api/meta.go index f3f84063dd8..d715d58a116 100644 --- a/pkg/api/meta.go +++ b/pkg/api/meta.go @@ -100,6 +100,10 @@ func (meta *ObjectMeta) GetOwnerReferences() []metatypes.OwnerReference { ret[i].Name = meta.OwnerReferences[i].Name ret[i].UID = meta.OwnerReferences[i].UID ret[i].APIVersion = meta.OwnerReferences[i].APIVersion + if meta.OwnerReferences[i].Controller != nil { + value := *meta.OwnerReferences[i].Controller + ret[i].Controller = &value + } } return ret } @@ -111,6 +115,10 @@ func (meta *ObjectMeta) SetOwnerReferences(references []metatypes.OwnerReference newReferences[i].Name = references[i].Name newReferences[i].UID = references[i].UID newReferences[i].APIVersion = references[i].APIVersion + if references[i].Controller != nil { + value := *references[i].Controller + newReferences[i].Controller = &value + } } meta.OwnerReferences = newReferences } diff --git a/pkg/api/meta/meta.go b/pkg/api/meta/meta.go index b9c8d69d02c..3a3d1fc73d8 100644 --- a/pkg/api/meta/meta.go +++ b/pkg/api/meta/meta.go @@ -359,6 +359,14 @@ func extractFromOwnerReference(v reflect.Value, o *metatypes.OwnerReference) err if err := runtime.Field(v, "UID", &o.UID); err != nil { return err } + var controllerPtr *bool + if err := runtime.Field(v, "Controller", &controllerPtr); err != nil { + return err + } + if controllerPtr != nil { + controller := *controllerPtr + o.Controller = &controller + } return nil } @@ -376,6 +384,12 @@ func setOwnerReference(v reflect.Value, o *metatypes.OwnerReference) error { if err := runtime.SetField(o.UID, v, "UID"); err != nil { return err } + if o.Controller != nil { + controller := *(o.Controller) + if err := runtime.SetField(&controller, v, "Controller"); err != nil { + return err + } + } return nil } diff --git a/pkg/api/meta/meta_test.go b/pkg/api/meta/meta_test.go index 73eeffb98e2..cfcd724107f 100644 --- a/pkg/api/meta/meta_test.go +++ b/pkg/api/meta/meta_test.go @@ -781,6 +781,7 @@ func getObjectMetaAndOwnerRefereneces() (myAPIObject2 MyAPIObject2, metaOwnerRef Name: references[i].Name, UID: references[i].UID, APIVersion: references[i].APIVersion, + Controller: references[i].Controller, }) } if len(references) == 0 { diff --git a/pkg/api/meta/metatypes/deep_copy_generated.go b/pkg/api/meta/metatypes/deep_copy_generated.go index f06a194e54a..5033d2494cc 100644 --- a/pkg/api/meta/metatypes/deep_copy_generated.go +++ b/pkg/api/meta/metatypes/deep_copy_generated.go @@ -29,5 +29,9 @@ func DeepCopy_metatypes_OwnerReference(in OwnerReference, out *OwnerReference, c out.Kind = in.Kind out.UID = in.UID out.Name = in.Name + if in.Controller != nil { + value := *in.Controller + out.Controller = &value + } return nil } diff --git a/pkg/api/meta/metatypes/types.go b/pkg/api/meta/metatypes/types.go index ca4edf72e28..e7ac3e08d7f 100644 --- a/pkg/api/meta/metatypes/types.go +++ b/pkg/api/meta/metatypes/types.go @@ -26,4 +26,5 @@ type OwnerReference struct { Kind string UID types.UID Name string + Controller *bool } diff --git a/pkg/api/meta_test.go b/pkg/api/meta_test.go index cbac57e88ce..689e760e536 100644 --- a/pkg/api/meta_test.go +++ b/pkg/api/meta_test.go @@ -64,6 +64,7 @@ func getObjectMetaAndOwnerReferences() (objectMeta api.ObjectMeta, metaOwnerRefe Name: references[i].Name, UID: references[i].UID, APIVersion: references[i].APIVersion, + Controller: references[i].Controller, }) } if len(references) == 0 { diff --git a/pkg/api/types.generated.go b/pkg/api/types.generated.go index 4583d2150c1..6993ed34523 100644 --- a/pkg/api/types.generated.go +++ b/pkg/api/types.generated.go @@ -44098,12 +44098,13 @@ func (x *OwnerReference) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [4]bool + var yyq2 [5]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false + yyq2[4] = x.Controller != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(4) + r.EncodeArrayStart(5) } else { yynn2 = 4 for _, b := range yyq2 { @@ -44192,6 +44193,41 @@ func (x *OwnerReference) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeString(codecSelferC_UTF81234, string(x.UID)) } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[4] { + if x.Controller == nil { + r.EncodeNil() + } else { + yy16 := *x.Controller + yym17 := z.EncBinary() + _ = yym17 + if false { + } else { + r.EncodeBool(bool(yy16)) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[4] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("controller")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Controller == nil { + r.EncodeNil() + } else { + yy18 := *x.Controller + yym19 := z.EncBinary() + _ = yym19 + if false { + } else { + r.EncodeBool(bool(yy18)) + } + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -44277,6 +44313,22 @@ func (x *OwnerReference) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } else { x.UID = pkg1_types.UID(r.DecodeString()) } + case "controller": + if r.TryDecodeAsNil() { + if x.Controller != nil { + x.Controller = nil + } + } else { + if x.Controller == nil { + x.Controller = new(bool) + } + yym9 := z.DecBinary() + _ = yym9 + if false { + } else { + *((*bool)(x.Controller)) = r.DecodeBool() + } + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -44288,16 +44340,16 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj8 int - var yyb8 bool - var yyhl8 bool = l >= 0 - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + var yyj10 int + var yyb10 bool + var yyhl10 bool = l >= 0 + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l } else { - yyb8 = r.CheckBreak() + yyb10 = r.CheckBreak() } - if yyb8 { + if yyb10 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -44307,13 +44359,13 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.APIVersion = string(r.DecodeString()) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l } else { - yyb8 = r.CheckBreak() + yyb10 = r.CheckBreak() } - if yyb8 { + if yyb10 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -44323,13 +44375,13 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.Kind = string(r.DecodeString()) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l } else { - yyb8 = r.CheckBreak() + yyb10 = r.CheckBreak() } - if yyb8 { + if yyb10 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -44339,13 +44391,13 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.Name = string(r.DecodeString()) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l } else { - yyb8 = r.CheckBreak() + yyb10 = r.CheckBreak() } - if yyb8 { + if yyb10 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -44355,18 +44407,44 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.UID = pkg1_types.UID(r.DecodeString()) } - for { - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l - } else { - yyb8 = r.CheckBreak() + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.Controller != nil { + x.Controller = nil } - if yyb8 { + } else { + if x.Controller == nil { + x.Controller = new(bool) + } + yym16 := z.DecBinary() + _ = yym16 + if false { + } else { + *((*bool)(x.Controller)) = r.DecodeBool() + } + } + for { + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj8-1, "") + z.DecStructFieldNotFound(yyj10-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -52940,7 +53018,7 @@ func (x codecSelfer1234) decSliceOwnerReference(v *[]OwnerReference, d *codec197 yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 64) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 72) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/pkg/api/types.go b/pkg/api/types.go index 5022d3596a7..8a6288cc321 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -140,7 +140,9 @@ type ObjectMeta struct { Annotations map[string]string `json:"annotations,omitempty"` // List of objects depended by this object. If ALL objects in the list have - // been deleted, this object will be garbage collected. + // been deleted, this object will be garbage collected. If this object is managed by a controller, + // then an entry in this list will point to this controller, with the controller field set to true. + // There cannot be more than one managing controller. OwnerReferences []OwnerReference `json:"ownerReferences,omitempty"` // Must be empty before the object is deleted from the registry. Each entry @@ -2330,6 +2332,8 @@ type OwnerReference struct { // UID of the referent. // More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids UID types.UID `json:"uid"` + // If true, this reference points to the managing controller. + Controller *bool `json:"controller,omitempty"` } // ObjectReference contains enough information to let you inspect or modify the referred object. diff --git a/pkg/api/v1/conversion_generated.go b/pkg/api/v1/conversion_generated.go index e1ad00bfc28..492d0d5d8ae 100644 --- a/pkg/api/v1/conversion_generated.go +++ b/pkg/api/v1/conversion_generated.go @@ -3629,6 +3629,7 @@ func autoConvert_v1_OwnerReference_To_api_OwnerReference(in *OwnerReference, out out.Kind = in.Kind out.Name = in.Name out.UID = in.UID + out.Controller = in.Controller return nil } @@ -3641,6 +3642,7 @@ func autoConvert_api_OwnerReference_To_v1_OwnerReference(in *api.OwnerReference, out.Kind = in.Kind out.Name = in.Name out.UID = in.UID + out.Controller = in.Controller return nil } diff --git a/pkg/api/v1/deep_copy_generated.go b/pkg/api/v1/deep_copy_generated.go index f61e4961995..4018c58804b 100644 --- a/pkg/api/v1/deep_copy_generated.go +++ b/pkg/api/v1/deep_copy_generated.go @@ -1653,6 +1653,13 @@ func DeepCopy_v1_OwnerReference(in OwnerReference, out *OwnerReference, c *conve out.Kind = in.Kind out.Name = in.Name out.UID = in.UID + if in.Controller != nil { + in, out := in.Controller, &out.Controller + *out = new(bool) + **out = *in + } else { + out.Controller = nil + } return nil } diff --git a/pkg/api/v1/generated.pb.go b/pkg/api/v1/generated.pb.go index 06d343babab..be91812aeaa 100644 --- a/pkg/api/v1/generated.pb.go +++ b/pkg/api/v1/generated.pb.go @@ -4452,6 +4452,16 @@ func (m *OwnerReference) MarshalTo(data []byte) (int, error) { i++ i = encodeVarintGenerated(data, i, uint64(len(m.APIVersion))) i += copy(data[i:], m.APIVersion) + if m.Controller != nil { + data[i] = 0x30 + i++ + if *m.Controller { + data[i] = 1 + } else { + data[i] = 0 + } + i++ + } return i, nil } @@ -8982,6 +8992,9 @@ func (m *OwnerReference) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.APIVersion) n += 1 + l + sovGenerated(uint64(l)) + if m.Controller != nil { + n += 2 + } return n } @@ -23047,6 +23060,27 @@ func (m *OwnerReference) Unmarshal(data []byte) error { } m.APIVersion = string(data[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Controller", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + b := bool(v != 0) + m.Controller = &b default: iNdEx = preIndex skippy, err := skipGenerated(data[iNdEx:]) diff --git a/pkg/api/v1/generated.proto b/pkg/api/v1/generated.proto index 0d132d0aa15..f65d77154bc 100644 --- a/pkg/api/v1/generated.proto +++ b/pkg/api/v1/generated.proto @@ -1461,7 +1461,9 @@ message ObjectMeta { map annotations = 12; // List of objects depended by this object. If ALL objects in the list have - // been deleted, this object will be garbage collected. + // been deleted, this object will be garbage collected. If this object is managed by a controller, + // then an entry in this list will point to this controller, with the controller field set to true. + // There cannot be more than one managing controller. repeated OwnerReference ownerReferences = 13; // Must be empty before the object is deleted from the registry. Each entry @@ -1525,6 +1527,9 @@ message OwnerReference { // UID of the referent. // More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids optional string uid = 4; + + // If true, this reference points to the managing controller. + optional bool controller = 6; } // PersistentVolume (PV) is a storage resource provisioned by an administrator. diff --git a/pkg/api/v1/types.generated.go b/pkg/api/v1/types.generated.go index 95f8b2e6446..57ae2b3dde3 100644 --- a/pkg/api/v1/types.generated.go +++ b/pkg/api/v1/types.generated.go @@ -43840,12 +43840,13 @@ func (x *OwnerReference) CodecEncodeSelf(e *codec1978.Encoder) { } else { yysep2 := !z.EncBinary() yy2arr2 := z.EncBasicHandle().StructToArray - var yyq2 [4]bool + var yyq2 [5]bool _, _, _ = yysep2, yyq2, yy2arr2 const yyr2 bool = false + yyq2[4] = x.Controller != nil var yynn2 int if yyr2 || yy2arr2 { - r.EncodeArrayStart(4) + r.EncodeArrayStart(5) } else { yynn2 = 4 for _, b := range yyq2 { @@ -43934,6 +43935,41 @@ func (x *OwnerReference) CodecEncodeSelf(e *codec1978.Encoder) { r.EncodeString(codecSelferC_UTF81234, string(x.UID)) } } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1234) + if yyq2[4] { + if x.Controller == nil { + r.EncodeNil() + } else { + yy16 := *x.Controller + yym17 := z.EncBinary() + _ = yym17 + if false { + } else { + r.EncodeBool(bool(yy16)) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq2[4] { + z.EncSendContainerState(codecSelfer_containerMapKey1234) + r.EncodeString(codecSelferC_UTF81234, string("controller")) + z.EncSendContainerState(codecSelfer_containerMapValue1234) + if x.Controller == nil { + r.EncodeNil() + } else { + yy18 := *x.Controller + yym19 := z.EncBinary() + _ = yym19 + if false { + } else { + r.EncodeBool(bool(yy18)) + } + } + } + } if yyr2 || yy2arr2 { z.EncSendContainerState(codecSelfer_containerArrayEnd1234) } else { @@ -44019,6 +44055,22 @@ func (x *OwnerReference) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { } else { x.UID = pkg1_types.UID(r.DecodeString()) } + case "controller": + if r.TryDecodeAsNil() { + if x.Controller != nil { + x.Controller = nil + } + } else { + if x.Controller == nil { + x.Controller = new(bool) + } + yym9 := z.DecBinary() + _ = yym9 + if false { + } else { + *((*bool)(x.Controller)) = r.DecodeBool() + } + } default: z.DecStructFieldNotFound(-1, yys3) } // end switch yys3 @@ -44030,16 +44082,16 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1234 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj8 int - var yyb8 bool - var yyhl8 bool = l >= 0 - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + var yyj10 int + var yyb10 bool + var yyhl10 bool = l >= 0 + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l } else { - yyb8 = r.CheckBreak() + yyb10 = r.CheckBreak() } - if yyb8 { + if yyb10 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -44049,13 +44101,13 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.APIVersion = string(r.DecodeString()) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l } else { - yyb8 = r.CheckBreak() + yyb10 = r.CheckBreak() } - if yyb8 { + if yyb10 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -44065,13 +44117,13 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.Kind = string(r.DecodeString()) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l } else { - yyb8 = r.CheckBreak() + yyb10 = r.CheckBreak() } - if yyb8 { + if yyb10 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -44081,13 +44133,13 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.Name = string(r.DecodeString()) } - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l } else { - yyb8 = r.CheckBreak() + yyb10 = r.CheckBreak() } - if yyb8 { + if yyb10 { z.DecSendContainerState(codecSelfer_containerArrayEnd1234) return } @@ -44097,18 +44149,44 @@ func (x *OwnerReference) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } else { x.UID = pkg1_types.UID(r.DecodeString()) } - for { - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l - } else { - yyb8 = r.CheckBreak() + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1234) + return + } + z.DecSendContainerState(codecSelfer_containerArrayElem1234) + if r.TryDecodeAsNil() { + if x.Controller != nil { + x.Controller = nil } - if yyb8 { + } else { + if x.Controller == nil { + x.Controller = new(bool) + } + yym16 := z.DecBinary() + _ = yym16 + if false { + } else { + *((*bool)(x.Controller)) = r.DecodeBool() + } + } + for { + yyj10++ + if yyhl10 { + yyb10 = yyj10 > l + } else { + yyb10 = r.CheckBreak() + } + if yyb10 { break } z.DecSendContainerState(codecSelfer_containerArrayElem1234) - z.DecStructFieldNotFound(yyj8-1, "") + z.DecStructFieldNotFound(yyj10-1, "") } z.DecSendContainerState(codecSelfer_containerArrayEnd1234) } @@ -53112,7 +53190,7 @@ func (x codecSelfer1234) decSliceOwnerReference(v *[]OwnerReference, d *codec197 yyrg1 := len(yyv1) > 0 yyv21 := yyv1 - yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 64) + yyrl1, yyrt1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 72) if yyrt1 { if yyrl1 <= cap(yyv1) { yyv1 = yyv1[:yyrl1] diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index 643e667f481..75be2f93c33 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -177,7 +177,9 @@ type ObjectMeta struct { Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"` // List of objects depended by this object. If ALL objects in the list have - // been deleted, this object will be garbage collected. + // been deleted, this object will be garbage collected. If this object is managed by a controller, + // then an entry in this list will point to this controller, with the controller field set to true. + // There cannot be more than one managing controller. OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid" protobuf:"bytes,13,rep,name=ownerReferences"` // Must be empty before the object is deleted from the registry. Each entry @@ -2777,6 +2779,8 @@ type OwnerReference struct { // UID of the referent. // More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids UID types.UID `json:"uid" protobuf:"bytes,4,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"` + // If true, this reference points to the managing controller. + Controller *bool `json:"controller,omitempty" protobuf:"varint,6,opt,name=controller"` } // ObjectReference contains enough information to let you inspect or modify the referred object. diff --git a/pkg/api/v1/types_swagger_doc_generated.go b/pkg/api/v1/types_swagger_doc_generated.go index 014d608f690..4d28d9291ec 100644 --- a/pkg/api/v1/types_swagger_doc_generated.go +++ b/pkg/api/v1/types_swagger_doc_generated.go @@ -928,7 +928,7 @@ var map_ObjectMeta = map[string]string{ "deletionGracePeriodSeconds": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", "labels": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://releases.k8s.io/HEAD/docs/user-guide/labels.md", "annotations": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://releases.k8s.io/HEAD/docs/user-guide/annotations.md", - "ownerReferences": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected.", + "ownerReferences": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.", "finalizers": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed.", } @@ -957,6 +957,7 @@ var map_OwnerReference = map[string]string{ "kind": "Kind of the referent. More info: http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#types-kinds", "name": "Name of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#names", "uid": "UID of the referent. More info: http://releases.k8s.io/HEAD/docs/user-guide/identifiers.md#uids", + "controller": "If true, this reference points to the managing controller.", } func (OwnerReference) SwaggerDoc() map[string]string { diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 4ef99202f01..a24ef85ca36 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -160,8 +160,17 @@ func validateOwnerReference(ownerReference api.OwnerReference, fldPath *field.Pa func ValidateOwnerReferences(ownerReferences []api.OwnerReference, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} + controllerName := "" for _, ref := range ownerReferences { allErrs = append(allErrs, validateOwnerReference(ref, fldPath)...) + if ref.Controller != nil && *ref.Controller { + if controllerName != "" { + allErrs = append(allErrs, field.Invalid(fldPath, ownerReferences, + fmt.Sprintf("Only one reference can have Controller set to true. Found \"true\" in references for %v and %v", controllerName, ref.Name))) + } else { + controllerName = ref.Name + } + } } return allErrs } diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index e6d34577505..5ca2d8fa092 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -99,12 +99,17 @@ func TestValidateObjectMetaNamespaces(t *testing.T) { } func TestValidateObjectMetaOwnerReferences(t *testing.T) { + trueVar := true + falseVar := false testCases := []struct { - ownerReferences []api.OwnerReference - expectError bool + description string + ownerReferences []api.OwnerReference + expectError bool + expectedErrorMessage string }{ { - []api.OwnerReference{ + description: "simple success - third party extension.", + ownerReferences: []api.OwnerReference{ { APIVersion: "thirdpartyVersion", Kind: "thirdpartyKind", @@ -112,11 +117,12 @@ func TestValidateObjectMetaOwnerReferences(t *testing.T) { UID: "1", }, }, - false, + expectError: false, + expectedErrorMessage: "", }, { - // event shouldn't be set as an owner - []api.OwnerReference{ + description: "simple failures - event shouldn't be set as an owner", + ownerReferences: []api.OwnerReference{ { APIVersion: "v1", Kind: "Event", @@ -124,7 +130,76 @@ func TestValidateObjectMetaOwnerReferences(t *testing.T) { UID: "1", }, }, - true, + expectError: true, + expectedErrorMessage: "is disallowed from being an owner", + }, + { + description: "simple controller ref success - one reference with Controller set", + ownerReferences: []api.OwnerReference{ + { + APIVersion: "thirdpartyVersion", + Kind: "thirdpartyKind", + Name: "name", + UID: "1", + Controller: &falseVar, + }, + { + APIVersion: "thirdpartyVersion", + Kind: "thirdpartyKind", + Name: "name", + UID: "2", + Controller: &trueVar, + }, + { + APIVersion: "thirdpartyVersion", + Kind: "thirdpartyKind", + Name: "name", + UID: "3", + Controller: &falseVar, + }, + { + APIVersion: "thirdpartyVersion", + Kind: "thirdpartyKind", + Name: "name", + UID: "4", + }, + }, + expectError: false, + expectedErrorMessage: "", + }, + { + description: "simple controller ref failure - two references with Controller set", + ownerReferences: []api.OwnerReference{ + { + APIVersion: "thirdpartyVersion", + Kind: "thirdpartyKind", + Name: "name", + UID: "1", + Controller: &falseVar, + }, + { + APIVersion: "thirdpartyVersion", + Kind: "thirdpartyKind", + Name: "name", + UID: "2", + Controller: &trueVar, + }, + { + APIVersion: "thirdpartyVersion", + Kind: "thirdpartyKind", + Name: "name", + UID: "3", + Controller: &trueVar, + }, + { + APIVersion: "thirdpartyVersion", + Kind: "thirdpartyKind", + Name: "name", + UID: "4", + }, + }, + expectError: true, + expectedErrorMessage: "Only one reference can have Controller set to true", }, } @@ -137,13 +212,13 @@ func TestValidateObjectMetaOwnerReferences(t *testing.T) { }, field.NewPath("field")) if len(errs) != 0 && !tc.expectError { - t.Errorf("unexpected error: %v", errs) + t.Errorf("unexpected error: %v in test case %v", errs, tc.description) } if len(errs) == 0 && tc.expectError { - t.Errorf("expect error") + t.Errorf("expect error in test case %v", tc.description) } - if len(errs) != 0 && !strings.Contains(errs[0].Error(), "is disallowed from being an owner") { - t.Errorf("unexpected error message: %v", errs) + if len(errs) != 0 && !strings.Contains(errs[0].Error(), tc.expectedErrorMessage) { + t.Errorf("unexpected error message: %v in test case %v", errs, tc.description) } } } diff --git a/pkg/runtime/types.go b/pkg/runtime/types.go index 0c6d48afc4a..33f7c3630fa 100644 --- a/pkg/runtime/types.go +++ b/pkg/runtime/types.go @@ -231,20 +231,36 @@ func (u *Unstructured) setNestedMap(value map[string]string, fields ...string) { func extractOwnerReference(src interface{}) metatypes.OwnerReference { v := src.(map[string]interface{}) + controllerPtr, ok := (getNestedField(v, "controller")).(*bool) + if !ok { + controllerPtr = nil + } else { + if controllerPtr != nil { + controller := *controllerPtr + controllerPtr = &controller + } + } return metatypes.OwnerReference{ Kind: getNestedString(v, "kind"), Name: getNestedString(v, "name"), APIVersion: getNestedString(v, "apiVersion"), UID: (types.UID)(getNestedString(v, "uid")), + Controller: controllerPtr, } } func setOwnerReference(src metatypes.OwnerReference) map[string]interface{} { ret := make(map[string]interface{}) + controllerPtr := src.Controller + if controllerPtr != nil { + controller := *controllerPtr + controllerPtr = &controller + } setNestedField(ret, src.Kind, "kind") setNestedField(ret, src.Name, "name") setNestedField(ret, src.APIVersion, "apiVersion") setNestedField(ret, string(src.UID), "uid") + setNestedField(ret, controllerPtr, "controller") return ret } diff --git a/pkg/runtime/unstructured_test.go b/pkg/runtime/unstructured_test.go index db87f78420b..cf808185c63 100644 --- a/pkg/runtime/unstructured_test.go +++ b/pkg/runtime/unstructured_test.go @@ -236,6 +236,7 @@ func TestUnstructuredGetters(t *testing.T) { func TestUnstructuredSetters(t *testing.T) { unstruct := runtime.Unstructured{} + trueVar := true want := runtime.Unstructured{ Object: map[string]interface{}{ @@ -262,12 +263,14 @@ func TestUnstructuredSetters(t *testing.T) { "name": "poda", "apiVersion": "v1", "uid": "1", + "controller": (*bool)(nil), }, { "kind": "Pod", "name": "podb", "apiVersion": "v1", "uid": "2", + "controller": &trueVar, }, }, "finalizers": []interface{}{ @@ -303,6 +306,7 @@ func TestUnstructuredSetters(t *testing.T) { Name: "podb", APIVersion: "v1", UID: "2", + Controller: &trueVar, }, } unstruct.SetOwnerReferences(newOwnerReferences)