diff --git a/cmd/libs/go2idl/conversion-gen/generators/conversion.go b/cmd/libs/go2idl/conversion-gen/generators/conversion.go index cfa62128b69..a9c93c52fb0 100644 --- a/cmd/libs/go2idl/conversion-gen/generators/conversion.go +++ b/cmd/libs/go2idl/conversion-gen/generators/conversion.go @@ -573,12 +573,27 @@ func (g *genConversion) GenerateType(c *generator.Context, t *types.Type, w io.W glog.V(5).Infof("generating for type %v", t) sw := generator.NewSnippetWriter(w, c, "$", "$") peerType := getPeerTypeFor(c, t, g.peerPackages) + didForward, didBackward := false, false if isDirectlyConvertible(t, peerType, g.manualConversions) { + didForward = true g.generateConversion(t, peerType, sw) } if isDirectlyConvertible(peerType, t, g.manualConversions) { + didBackward = true g.generateConversion(peerType, t, sw) } + if didForward != didBackward { + glog.Fatalf("Could only generate one direction of conversion for %v <-> %v", t, peerType) + } + if !didForward && !didBackward { + // TODO: This should be fatal but we have at least 8 types that + // currently fail this. The right thing to do is to figure out why they + // can't be generated and mark those fields as + // +k8s:conversion-gen=false, and ONLY do manual conversions for those + // fields, with the manual Convert_...() calling autoConvert_...() + // first. + glog.Errorf("Warning: could not generate autoConvert functions for %v <-> %v", t, peerType) + } return sw.Error() } diff --git a/pkg/api/types.go b/pkg/api/types.go index 1c038d0dc11..7225e8fa893 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -1479,12 +1479,15 @@ type PodSecurityContext struct { // Use the host's network namespace. If this option is set, the ports that will be // used must be specified. // Optional: Default to false + // +k8s:conversion-gen=false HostNetwork bool `json:"hostNetwork,omitempty"` // Use the host's pid namespace. // Optional: Default to false. + // +k8s:conversion-gen=false HostPID bool `json:"hostPID,omitempty"` // Use the host's ipc namespace. // Optional: Default to false. + // +k8s:conversion-gen=false HostIPC bool `json:"hostIPC,omitempty"` // The SELinux context to be applied to all containers. // If unspecified, the container runtime will allocate a random SELinux context for each diff --git a/pkg/api/v1/conversion.go b/pkg/api/v1/conversion.go index 7e760a49daf..642b1bc5e58 100644 --- a/pkg/api/v1/conversion.go +++ b/pkg/api/v1/conversion.go @@ -360,124 +360,34 @@ func Convert_v1_PodTemplateSpec_To_api_PodTemplateSpec(in *PodTemplateSpec, out // The following two PodSpec conversions are done here to support ServiceAccount // as an alias for ServiceAccountName. func Convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error { - if in.Volumes != nil { - out.Volumes = make([]Volume, len(in.Volumes)) - for i := range in.Volumes { - if err := Convert_api_Volume_To_v1_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { - return err - } - } - } else { - out.Volumes = nil - } - if in.InitContainers != nil { - out.InitContainers = make([]Container, len(in.InitContainers)) - for i := range in.InitContainers { - if err := Convert_api_Container_To_v1_Container(&in.InitContainers[i], &out.InitContainers[i], s); err != nil { - return err - } - } - } else { - out.InitContainers = nil - } - if in.Containers != nil { - out.Containers = make([]Container, len(in.Containers)) - for i := range in.Containers { - if err := Convert_api_Container_To_v1_Container(&in.Containers[i], &out.Containers[i], s); err != nil { - return err - } - } - } else { - out.Containers = nil + if err := autoConvert_api_PodSpec_To_v1_PodSpec(in, out, s); err != nil { + return err } - out.RestartPolicy = RestartPolicy(in.RestartPolicy) - out.TerminationGracePeriodSeconds = in.TerminationGracePeriodSeconds - out.ActiveDeadlineSeconds = in.ActiveDeadlineSeconds - out.DNSPolicy = DNSPolicy(in.DNSPolicy) - out.NodeSelector = in.NodeSelector - - out.ServiceAccountName = in.ServiceAccountName // DeprecatedServiceAccount is an alias for ServiceAccountName. out.DeprecatedServiceAccount = in.ServiceAccountName - out.NodeName = in.NodeName - if in.SecurityContext != nil { - out.SecurityContext = new(PodSecurityContext) - if err := Convert_api_PodSecurityContext_To_v1_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { - return err - } + if in.SecurityContext != nil { // the host namespace fields have to be handled here for backward compatibility // with v1.0.0 out.HostPID = in.SecurityContext.HostPID out.HostNetwork = in.SecurityContext.HostNetwork out.HostIPC = in.SecurityContext.HostIPC } - if in.ImagePullSecrets != nil { - out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets)) - for i := range in.ImagePullSecrets { - if err := Convert_api_LocalObjectReference_To_v1_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { - return err - } - } - } else { - out.ImagePullSecrets = nil - } - out.Hostname = in.Hostname - out.Subdomain = in.Subdomain + return nil } func Convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error { - SetDefaults_PodSpec(in) - if in.Volumes != nil { - out.Volumes = make([]api.Volume, len(in.Volumes)) - for i := range in.Volumes { - if err := Convert_v1_Volume_To_api_Volume(&in.Volumes[i], &out.Volumes[i], s); err != nil { - return err - } - } - } else { - out.Volumes = nil + if err := autoConvert_v1_PodSpec_To_api_PodSpec(in, out, s); err != nil { + return err } - if in.InitContainers != nil { - out.InitContainers = make([]api.Container, len(in.InitContainers)) - for i := range in.InitContainers { - if err := Convert_v1_Container_To_api_Container(&in.InitContainers[i], &out.InitContainers[i], s); err != nil { - return err - } - } - } else { - out.InitContainers = nil - } - if in.Containers != nil { - out.Containers = make([]api.Container, len(in.Containers)) - for i := range in.Containers { - if err := Convert_v1_Container_To_api_Container(&in.Containers[i], &out.Containers[i], s); err != nil { - return err - } - } - } else { - out.Containers = nil - } - out.RestartPolicy = api.RestartPolicy(in.RestartPolicy) - out.TerminationGracePeriodSeconds = in.TerminationGracePeriodSeconds - out.ActiveDeadlineSeconds = in.ActiveDeadlineSeconds - out.DNSPolicy = api.DNSPolicy(in.DNSPolicy) - out.NodeSelector = in.NodeSelector + // We support DeprecatedServiceAccount as an alias for ServiceAccountName. // If both are specified, ServiceAccountName (the new field) wins. - out.ServiceAccountName = in.ServiceAccountName if in.ServiceAccountName == "" { out.ServiceAccountName = in.DeprecatedServiceAccount } - out.NodeName = in.NodeName - if in.SecurityContext != nil { - out.SecurityContext = new(api.PodSecurityContext) - if err := Convert_v1_PodSecurityContext_To_api_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil { - return err - } - } // the host namespace fields have to be handled specially for backward compatibility // with v1.0.0 @@ -487,18 +397,7 @@ func Convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversi out.SecurityContext.HostNetwork = in.HostNetwork out.SecurityContext.HostPID = in.HostPID out.SecurityContext.HostIPC = in.HostIPC - if in.ImagePullSecrets != nil { - out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets)) - for i := range in.ImagePullSecrets { - if err := Convert_v1_LocalObjectReference_To_api_LocalObjectReference(&in.ImagePullSecrets[i], &out.ImagePullSecrets[i], s); err != nil { - return err - } - } - } else { - out.ImagePullSecrets = nil - } - out.Hostname = in.Hostname - out.Subdomain = in.Subdomain + return nil } diff --git a/pkg/api/v1/conversion_generated.go b/pkg/api/v1/conversion_generated.go index 6c2516fe008..a9cb349c0d3 100644 --- a/pkg/api/v1/conversion_generated.go +++ b/pkg/api/v1/conversion_generated.go @@ -4785,6 +4785,90 @@ func autoConvert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurity return nil } +func autoConvert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *PodSecurityContext, s conversion.Scope) error { + if in.SELinuxOptions != nil { + in, out := &in.SELinuxOptions, &out.SELinuxOptions + *out = new(SELinuxOptions) + if err := Convert_api_SELinuxOptions_To_v1_SELinuxOptions(*in, *out, s); err != nil { + return err + } + } else { + out.SELinuxOptions = nil + } + out.RunAsUser = in.RunAsUser + out.RunAsNonRoot = in.RunAsNonRoot + out.SupplementalGroups = in.SupplementalGroups + out.FSGroup = in.FSGroup + return nil +} + +func autoConvert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversion.Scope) error { + SetDefaults_PodSpec(in) + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]api.Volume, len(*in)) + for i := range *in { + if err := Convert_v1_Volume_To_api_Volume(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Volumes = nil + } + if in.InitContainers != nil { + in, out := &in.InitContainers, &out.InitContainers + *out = make([]api.Container, len(*in)) + for i := range *in { + if err := Convert_v1_Container_To_api_Container(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.InitContainers = nil + } + if in.Containers != nil { + in, out := &in.Containers, &out.Containers + *out = make([]api.Container, len(*in)) + for i := range *in { + if err := Convert_v1_Container_To_api_Container(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Containers = nil + } + out.RestartPolicy = api.RestartPolicy(in.RestartPolicy) + out.TerminationGracePeriodSeconds = in.TerminationGracePeriodSeconds + out.ActiveDeadlineSeconds = in.ActiveDeadlineSeconds + out.DNSPolicy = api.DNSPolicy(in.DNSPolicy) + out.NodeSelector = in.NodeSelector + out.ServiceAccountName = in.ServiceAccountName + out.NodeName = in.NodeName + if in.SecurityContext != nil { + in, out := &in.SecurityContext, &out.SecurityContext + *out = new(api.PodSecurityContext) + if err := Convert_v1_PodSecurityContext_To_api_PodSecurityContext(*in, *out, s); err != nil { + return err + } + } else { + out.SecurityContext = nil + } + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make([]api.LocalObjectReference, len(*in)) + for i := range *in { + if err := Convert_v1_LocalObjectReference_To_api_LocalObjectReference(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.ImagePullSecrets = nil + } + out.Hostname = in.Hostname + out.Subdomain = in.Subdomain + return nil +} + func autoConvert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversion.Scope) error { if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes diff --git a/pkg/api/v1/generated.proto b/pkg/api/v1/generated.proto index 1aef723d98d..f2101dfc9ac 100644 --- a/pkg/api/v1/generated.proto +++ b/pkg/api/v1/generated.proto @@ -2089,6 +2089,7 @@ message PodSpec { // DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. // Deprecated: Use serviceAccountName instead. + // +k8s:conversion-gen=false optional string serviceAccount = 9; // NodeName is a request to schedule this pod onto a specific node. If it is non-empty, @@ -2099,14 +2100,17 @@ message PodSpec { // Host networking requested for this pod. Use the host's network namespace. // If this option is set, the ports that will be used must be specified. // Default to false. + // +k8s:conversion-gen=false optional bool hostNetwork = 11; // Use the host's pid namespace. // Optional: Default to false. + // +k8s:conversion-gen=false optional bool hostPID = 12; // Use the host's ipc namespace. // Optional: Default to false. + // +k8s:conversion-gen=false optional bool hostIPC = 13; // SecurityContext holds pod-level security attributes and common container settings. diff --git a/pkg/api/v1/types.go b/pkg/api/v1/types.go index d09101b8bde..5dc3afceb50 100644 --- a/pkg/api/v1/types.go +++ b/pkg/api/v1/types.go @@ -1719,6 +1719,7 @@ type PodSpec struct { ServiceAccountName string `json:"serviceAccountName,omitempty" protobuf:"bytes,8,opt,name=serviceAccountName"` // DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. // Deprecated: Use serviceAccountName instead. + // +k8s:conversion-gen=false DeprecatedServiceAccount string `json:"serviceAccount,omitempty" protobuf:"bytes,9,opt,name=serviceAccount"` // NodeName is a request to schedule this pod onto a specific node. If it is non-empty, @@ -1728,12 +1729,15 @@ type PodSpec struct { // Host networking requested for this pod. Use the host's network namespace. // If this option is set, the ports that will be used must be specified. // Default to false. + // +k8s:conversion-gen=false HostNetwork bool `json:"hostNetwork,omitempty" protobuf:"varint,11,opt,name=hostNetwork"` // Use the host's pid namespace. // Optional: Default to false. + // +k8s:conversion-gen=false HostPID bool `json:"hostPID,omitempty" protobuf:"varint,12,opt,name=hostPID"` // Use the host's ipc namespace. // Optional: Default to false. + // +k8s:conversion-gen=false HostIPC bool `json:"hostIPC,omitempty" protobuf:"varint,13,opt,name=hostIPC"` // SecurityContext holds pod-level security attributes and common container settings. // Optional: Defaults to empty. See type description for default values of each field.