mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Recreate the opt-in/opt-out logic for deepcopy
This is the last piece of Clayton's #26179 to be implemented with file tags. All diffs are accounted for. Followup will use this to streamline some packages. Also add some V(5) debugging - it was helpful in diagnosing various issues, it may be helpful again.
This commit is contained in:
		@@ -31,6 +31,8 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/cmd/libs/go2idl/namer"
 | 
						"k8s.io/kubernetes/cmd/libs/go2idl/namer"
 | 
				
			||||||
	"k8s.io/kubernetes/cmd/libs/go2idl/parser"
 | 
						"k8s.io/kubernetes/cmd/libs/go2idl/parser"
 | 
				
			||||||
	"k8s.io/kubernetes/cmd/libs/go2idl/types"
 | 
						"k8s.io/kubernetes/cmd/libs/go2idl/types"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/util"
 | 
				
			||||||
 | 
						utilflag "k8s.io/kubernetes/pkg/util/flag"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/pflag"
 | 
						"github.com/spf13/pflag"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -147,7 +149,8 @@ func DefaultSourceTree() string {
 | 
				
			|||||||
// If you don't need any non-default behavior, use as:
 | 
					// If you don't need any non-default behavior, use as:
 | 
				
			||||||
// args.Default().Execute(...)
 | 
					// args.Default().Execute(...)
 | 
				
			||||||
func (g *GeneratorArgs) Execute(nameSystems namer.NameSystems, defaultSystem string, pkgs func(*generator.Context, *GeneratorArgs) generator.Packages) error {
 | 
					func (g *GeneratorArgs) Execute(nameSystems namer.NameSystems, defaultSystem string, pkgs func(*generator.Context, *GeneratorArgs) generator.Packages) error {
 | 
				
			||||||
	pflag.Parse()
 | 
						utilflag.InitFlags()
 | 
				
			||||||
 | 
						util.InitLogs()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b, err := g.NewBuilder()
 | 
						b, err := g.NewBuilder()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,59 @@ type CustomArgs struct {
 | 
				
			|||||||
	BoundingDirs []string // Only deal with types rooted under these dirs.
 | 
						BoundingDirs []string // Only deal with types rooted under these dirs.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This is the comment tag that carries parameters for deep-copy generation.
 | 
				
			||||||
 | 
					const tagName = "k8s:deepcopy-gen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Known values for the comment tag.
 | 
				
			||||||
 | 
					const tagValuePackage = "package"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// tagValue holds parameters from a tagName tag.
 | 
				
			||||||
 | 
					type tagValue struct {
 | 
				
			||||||
 | 
						value    string
 | 
				
			||||||
 | 
						register bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func extractTag(comments []string) *tagValue {
 | 
				
			||||||
 | 
						tagVals := types.ExtractCommentTags("+", comments)[tagName]
 | 
				
			||||||
 | 
						if tagVals == nil {
 | 
				
			||||||
 | 
							// No match for the tag.
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// If there are multiple values, abort.
 | 
				
			||||||
 | 
						if len(tagVals) > 1 {
 | 
				
			||||||
 | 
							glog.Fatalf("Found %d %s tags: %q", len(tagVals), tagName, tagVals)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// If we got here we are returning something.
 | 
				
			||||||
 | 
						tag := &tagValue{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get the primary value.
 | 
				
			||||||
 | 
						parts := strings.Split(tagVals[0], ",")
 | 
				
			||||||
 | 
						if len(parts) >= 1 {
 | 
				
			||||||
 | 
							tag.value = parts[0]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Parse extra arguments.
 | 
				
			||||||
 | 
						parts = parts[1:]
 | 
				
			||||||
 | 
						for i := range parts {
 | 
				
			||||||
 | 
							kv := strings.SplitN(parts[i], "=", 2)
 | 
				
			||||||
 | 
							k := kv[0]
 | 
				
			||||||
 | 
							v := ""
 | 
				
			||||||
 | 
							if len(kv) == 2 {
 | 
				
			||||||
 | 
								v = kv[1]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							switch k {
 | 
				
			||||||
 | 
							case "register":
 | 
				
			||||||
 | 
								if v != "false" {
 | 
				
			||||||
 | 
									tag.register = true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								glog.Fatalf("Unsupported %s param: %q", tagName, parts[i])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return tag
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO: This is created only to reduce number of changes in a single PR.
 | 
					// TODO: This is created only to reduce number of changes in a single PR.
 | 
				
			||||||
// Remove it and use PublicNamer instead.
 | 
					// Remove it and use PublicNamer instead.
 | 
				
			||||||
func deepCopyNamer() *namer.NameStrategy {
 | 
					func deepCopyNamer() *namer.NameStrategy {
 | 
				
			||||||
@@ -86,38 +139,61 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, p := range context.Universe {
 | 
						for i := range inputs {
 | 
				
			||||||
		// Short-circuit if this package has not opted in.
 | 
							glog.V(5).Infof("considering pkg %q", i)
 | 
				
			||||||
		if tagvals := types.ExtractCommentTags("+", p.Comments)["k8s:deepcopy-gen"]; tagvals == nil {
 | 
							pkg := context.Universe[i]
 | 
				
			||||||
			// No tag for this package.
 | 
							if pkg == nil {
 | 
				
			||||||
			continue
 | 
								// If the input had no Go files, for example.
 | 
				
			||||||
		} else if tagvals[0] != "generate" && tagvals[0] != "register" {
 | 
					 | 
				
			||||||
			// Unknown tag.
 | 
					 | 
				
			||||||
			glog.Errorf("Uknown tag value '+k8s:deepcopy-gen=%s'", tagvals[0])
 | 
					 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		needsGeneration := false
 | 
					
 | 
				
			||||||
		for _, t := range p.Types {
 | 
							ptag := extractTag(pkg.Comments)
 | 
				
			||||||
			if copyableWithinPackage(t, boundingDirs) && inputs.Has(t.Name.Package) {
 | 
							ptagValue := ""
 | 
				
			||||||
				needsGeneration = true
 | 
							ptagRegister := false
 | 
				
			||||||
				break
 | 
							if ptag != nil {
 | 
				
			||||||
 | 
								ptagValue = ptag.value
 | 
				
			||||||
 | 
								if ptagValue != tagValuePackage {
 | 
				
			||||||
 | 
									glog.Fatalf("Package %v: unsupported %s value: %q", i, tagName, ptagValue)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								ptagRegister = ptag.register
 | 
				
			||||||
 | 
								glog.V(5).Infof("  tag.value: %q, tag.register: %t", ptagValue, ptagRegister)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								glog.V(5).Infof("  no tag")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// If the pkg-scoped tag says to generate, we can skip scanning types.
 | 
				
			||||||
 | 
							pkgNeedsGeneration := (ptagValue == tagValuePackage)
 | 
				
			||||||
 | 
							if !pkgNeedsGeneration {
 | 
				
			||||||
 | 
								// If the pkg-scoped tag did not exist, scan all types for one that
 | 
				
			||||||
 | 
								// explicitly wants generation.
 | 
				
			||||||
 | 
								for _, t := range pkg.Types {
 | 
				
			||||||
 | 
									glog.V(5).Infof("  considering type %q", t.Name.String())
 | 
				
			||||||
 | 
									ttag := extractTag(t.CommentLines)
 | 
				
			||||||
 | 
									if ttag != nil && ttag.value == "true" {
 | 
				
			||||||
 | 
										glog.V(5).Infof("    tag=true")
 | 
				
			||||||
 | 
										if !copyableWithinPackage(t, boundingDirs) {
 | 
				
			||||||
 | 
											glog.Fatalf("Type %v requests deepcopy generation but is not copyable", t)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										pkgNeedsGeneration = true
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if needsGeneration {
 | 
					
 | 
				
			||||||
			path := p.Path
 | 
							if pkgNeedsGeneration {
 | 
				
			||||||
			packages = append(packages,
 | 
								packages = append(packages,
 | 
				
			||||||
				&generator.DefaultPackage{
 | 
									&generator.DefaultPackage{
 | 
				
			||||||
					PackageName: strings.Split(filepath.Base(path), ".")[0],
 | 
										PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0],
 | 
				
			||||||
					PackagePath: path,
 | 
										PackagePath: pkg.Path,
 | 
				
			||||||
					HeaderText:  header,
 | 
										HeaderText:  header,
 | 
				
			||||||
					GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
 | 
										GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
 | 
				
			||||||
						generators = []generator.Generator{}
 | 
											generators = []generator.Generator{}
 | 
				
			||||||
						generators = append(
 | 
											generators = append(
 | 
				
			||||||
							generators, NewGenDeepCopy(arguments.OutputFileBaseName, path, boundingDirs))
 | 
												generators, NewGenDeepCopy(arguments.OutputFileBaseName, pkg.Path, boundingDirs, (ptagValue == tagValuePackage), ptagRegister))
 | 
				
			||||||
						return generators
 | 
											return generators
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
					FilterFunc: func(c *generator.Context, t *types.Type) bool {
 | 
										FilterFunc: func(c *generator.Context, t *types.Type) bool {
 | 
				
			||||||
						return t.Name.Package == path
 | 
											return t.Name.Package == pkg.Path
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
				})
 | 
									})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -135,19 +211,23 @@ type genDeepCopy struct {
 | 
				
			|||||||
	generator.DefaultGen
 | 
						generator.DefaultGen
 | 
				
			||||||
	targetPackage string
 | 
						targetPackage string
 | 
				
			||||||
	boundingDirs  []string
 | 
						boundingDirs  []string
 | 
				
			||||||
 | 
						allTypes      bool
 | 
				
			||||||
 | 
						registerTypes bool
 | 
				
			||||||
	imports       namer.ImportTracker
 | 
						imports       namer.ImportTracker
 | 
				
			||||||
	typesForInit  []*types.Type
 | 
						typesForInit  []*types.Type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	globalVariables map[string]interface{}
 | 
						globalVariables map[string]interface{}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewGenDeepCopy(sanitizedName, targetPackage string, boundingDirs []string) generator.Generator {
 | 
					func NewGenDeepCopy(sanitizedName, targetPackage string, boundingDirs []string, allTypes, registerTypes bool) generator.Generator {
 | 
				
			||||||
	return &genDeepCopy{
 | 
						return &genDeepCopy{
 | 
				
			||||||
		DefaultGen: generator.DefaultGen{
 | 
							DefaultGen: generator.DefaultGen{
 | 
				
			||||||
			OptionalName: sanitizedName,
 | 
								OptionalName: sanitizedName,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		targetPackage: targetPackage,
 | 
							targetPackage: targetPackage,
 | 
				
			||||||
		boundingDirs:  boundingDirs,
 | 
							boundingDirs:  boundingDirs,
 | 
				
			||||||
 | 
							allTypes:      allTypes,
 | 
				
			||||||
 | 
							registerTypes: registerTypes,
 | 
				
			||||||
		imports:       generator.NewImportTracker(),
 | 
							imports:       generator.NewImportTracker(),
 | 
				
			||||||
		typesForInit:  make([]*types.Type, 0),
 | 
							typesForInit:  make([]*types.Type, 0),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -159,8 +239,15 @@ func (g *genDeepCopy) Namers(c *generator.Context) namer.NameSystems {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (g *genDeepCopy) Filter(c *generator.Context, t *types.Type) bool {
 | 
					func (g *genDeepCopy) Filter(c *generator.Context, t *types.Type) bool {
 | 
				
			||||||
	// Filter out all types not copyable within the package.
 | 
						// Filter out types not being processed or not copyable within the package.
 | 
				
			||||||
	copyable := g.copyableWithinPackage(t)
 | 
						enabled := g.allTypes
 | 
				
			||||||
 | 
						if !enabled {
 | 
				
			||||||
 | 
							ttag := extractTag(t.CommentLines)
 | 
				
			||||||
 | 
							if ttag != nil && ttag.value == "true" {
 | 
				
			||||||
 | 
								enabled = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						copyable := enabled && g.copyableWithinPackage(t)
 | 
				
			||||||
	if copyable {
 | 
						if copyable {
 | 
				
			||||||
		g.typesForInit = append(g.typesForInit, t)
 | 
							g.typesForInit = append(g.typesForInit, t)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -208,7 +295,8 @@ func isRootedUnder(pkg string, roots []string) bool {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func copyableWithinPackage(t *types.Type, boundingDirs []string) bool {
 | 
					func copyableWithinPackage(t *types.Type, boundingDirs []string) bool {
 | 
				
			||||||
	// If the type opts out of copy-generation, stop.
 | 
						// If the type opts out of copy-generation, stop.
 | 
				
			||||||
	if extractBoolTagOrDie("k8s:deepcopy-gen", true, t.CommentLines) == false {
 | 
						ttag := extractTag(t.CommentLines)
 | 
				
			||||||
 | 
						if ttag != nil && ttag.value == "false" {
 | 
				
			||||||
		return false
 | 
							return false
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Only packages within the restricted range can be processed.
 | 
						// Only packages within the restricted range can be processed.
 | 
				
			||||||
@@ -276,12 +364,14 @@ func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
 | 
				
			|||||||
	g.globalVariables = map[string]interface{}{
 | 
						g.globalVariables = map[string]interface{}{
 | 
				
			||||||
		"Cloner": cloner,
 | 
							"Cloner": cloner,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if tagvals := types.ExtractCommentTags("+", c.Universe[g.targetPackage].Comments)["k8s:deepcopy-gen"]; tagvals != nil && tagvals[0] != "register" {
 | 
						if !g.registerTypes {
 | 
				
			||||||
		// TODO: We should come up with a solution to register all generated
 | 
							// TODO: We should come up with a solution to register all generated
 | 
				
			||||||
		// deep-copy functions. However, for now, to avoid import cycles
 | 
							// deep-copy functions. However, for now, to avoid import cycles
 | 
				
			||||||
		// we register only those explicitly requested.
 | 
							// we register only those explicitly requested.
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						glog.V(5).Infof("registering types in pkg %q", g.targetPackage)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	scheme := c.Universe.Variable(types.Name{Package: apiPackagePath, Name: "Scheme"})
 | 
						scheme := c.Universe.Variable(types.Name{Package: apiPackagePath, Name: "Scheme"})
 | 
				
			||||||
	g.imports.AddType(scheme)
 | 
						g.imports.AddType(scheme)
 | 
				
			||||||
	g.globalVariables["scheme"] = scheme
 | 
						g.globalVariables["scheme"] = scheme
 | 
				
			||||||
@@ -302,7 +392,34 @@ func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
 | 
				
			|||||||
	return sw.Error()
 | 
						return sw.Error()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (g *genDeepCopy) needsGeneration(t *types.Type) bool {
 | 
				
			||||||
 | 
						tag := extractTag(t.CommentLines)
 | 
				
			||||||
 | 
						tv := ""
 | 
				
			||||||
 | 
						if tag != nil {
 | 
				
			||||||
 | 
							tv = tag.value
 | 
				
			||||||
 | 
							if tv != "true" && tv != "false" {
 | 
				
			||||||
 | 
								glog.Fatalf("Type %v: unsupported %s value: %q", t, tagName, tag.value)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if g.allTypes && tv == "false" {
 | 
				
			||||||
 | 
							// The whole package is being generated, but this type has opted out.
 | 
				
			||||||
 | 
							glog.V(5).Infof("not generating for type %v because type opted out", t)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if !g.allTypes && tv != "true" {
 | 
				
			||||||
 | 
							// The whole package is NOT being generated, and this type has NOT opted in.
 | 
				
			||||||
 | 
							glog.V(5).Infof("not generating for type %v because type did not opt in", t)
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
 | 
					func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
 | 
				
			||||||
 | 
						if !g.needsGeneration(t) {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						glog.V(5).Infof("generating for type %v", t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw := generator.NewSnippetWriter(w, c, "$", "$")
 | 
						sw := generator.NewSnippetWriter(w, c, "$", "$")
 | 
				
			||||||
	funcName := g.funcNameTmpl(t)
 | 
						funcName := g.funcNameTmpl(t)
 | 
				
			||||||
	sw.Do(fmt.Sprintf("func %s(in $.type|raw$, out *$.type|raw$, c *$.Cloner|raw$) error {\n", funcName), g.withGlobals(argsFromType(t)))
 | 
						sw.Do(fmt.Sprintf("func %s(in $.type|raw$, out *$.type|raw$, c *$.Cloner|raw$) error {\n", funcName), g.withGlobals(argsFromType(t)))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -265,3 +265,80 @@ func Test_hasDeepCopyMethod(t *testing.T) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Test_extractTagParams(t *testing.T) {
 | 
				
			||||||
 | 
						testCases := []struct {
 | 
				
			||||||
 | 
							comments []string
 | 
				
			||||||
 | 
							expect   *tagValue
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								comments: []string{
 | 
				
			||||||
 | 
									"Human comment",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expect: nil,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								comments: []string{
 | 
				
			||||||
 | 
									"Human comment",
 | 
				
			||||||
 | 
									"+k8s:deepcopy-gen",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expect: &tagValue{
 | 
				
			||||||
 | 
									value:    "",
 | 
				
			||||||
 | 
									register: false,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								comments: []string{
 | 
				
			||||||
 | 
									"Human comment",
 | 
				
			||||||
 | 
									"+k8s:deepcopy-gen=package",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expect: &tagValue{
 | 
				
			||||||
 | 
									value:    "package",
 | 
				
			||||||
 | 
									register: false,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								comments: []string{
 | 
				
			||||||
 | 
									"Human comment",
 | 
				
			||||||
 | 
									"+k8s:deepcopy-gen=package,register",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expect: &tagValue{
 | 
				
			||||||
 | 
									value:    "package",
 | 
				
			||||||
 | 
									register: true,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								comments: []string{
 | 
				
			||||||
 | 
									"Human comment",
 | 
				
			||||||
 | 
									"+k8s:deepcopy-gen=package,register=true",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expect: &tagValue{
 | 
				
			||||||
 | 
									value:    "package",
 | 
				
			||||||
 | 
									register: true,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								comments: []string{
 | 
				
			||||||
 | 
									"Human comment",
 | 
				
			||||||
 | 
									"+k8s:deepcopy-gen=package,register=false",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expect: &tagValue{
 | 
				
			||||||
 | 
									value:    "package",
 | 
				
			||||||
 | 
									register: false,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, tc := range testCases {
 | 
				
			||||||
 | 
							r := extractTag(tc.comments)
 | 
				
			||||||
 | 
							if r == nil && tc.expect != nil {
 | 
				
			||||||
 | 
								t.Errorf("case[%d]: expected non-nil", i)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if r != nil && tc.expect == nil {
 | 
				
			||||||
 | 
								t.Errorf("case[%d]: expected nil, got %v", i, *r)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if r != nil && *r != *tc.expect {
 | 
				
			||||||
 | 
								t.Errorf("case[%d]: expected %v, got %v", i, *tc.expect, *r)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,33 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2016 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
limitations under the License.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package generators
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"github.com/golang/glog"
 | 
					 | 
				
			||||||
	"k8s.io/kubernetes/cmd/libs/go2idl/types"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// extractBoolTagOrDie gets the comment-tags for the key and asserts that, if
 | 
					 | 
				
			||||||
// it exists, the value is boolean.  If the tag did not exist, it returns
 | 
					 | 
				
			||||||
// defaultVal.
 | 
					 | 
				
			||||||
func extractBoolTagOrDie(key string, defaultVal bool, lines []string) bool {
 | 
					 | 
				
			||||||
	val, err := types.ExtractSingleBoolCommentTag("+", key, defaultVal, lines)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Fatalf(err.Error())
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return val
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -28,18 +28,23 @@ limitations under the License.
 | 
				
			|||||||
// Generation is governed by comment tags in the source.  Any package may
 | 
					// Generation is governed by comment tags in the source.  Any package may
 | 
				
			||||||
// request DeepCopy generation by including a comment in the file-comments of
 | 
					// request DeepCopy generation by including a comment in the file-comments of
 | 
				
			||||||
// one file, of the form:
 | 
					// one file, of the form:
 | 
				
			||||||
//   // +k8s:deepcopy-gen=generate
 | 
					//   // +k8s:deepcopy-gen=package
 | 
				
			||||||
// or:
 | 
					 | 
				
			||||||
//   // +k8s:deepcopy-gen=register
 | 
					 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Packages which specify `=generate` will have DeepCopy functions generated
 | 
					// Packages can request that the generated DeepCopy functions be registered
 | 
				
			||||||
// into them.  Packages which specify `=register` will have DeepCopy functions
 | 
					// with an `init()` function call to `Scheme.AddGeneratedDeepCopyFuncs()` by
 | 
				
			||||||
// generated and registered with in `init()` function call to
 | 
					// changing the tag to:
 | 
				
			||||||
// `Scheme.AddGeneratedDeepCopyFuncs()`.
 | 
					//   // +k8s:deepcopy-gen=package,register
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Individual types may opt out of DeepCopy generation by specifying a comment
 | 
					// DeepCopy functions can be generated for individual types, rather than the
 | 
				
			||||||
// of the form:
 | 
					// entire package by specifying a comment on the type definion of the form:
 | 
				
			||||||
 | 
					//   // +k8s:deepcopy-gen=true
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// When generating for a whole package, individual types may opt out of
 | 
				
			||||||
 | 
					// DeepCopy generation by specifying a comment on the of the form:
 | 
				
			||||||
//   // +k8s:deepcopy-gen=false
 | 
					//   // +k8s:deepcopy-gen=false
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Note that registration is a whole-package option, and is not available for
 | 
				
			||||||
 | 
					// individual types.
 | 
				
			||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -77,8 +77,8 @@ cmd/libs/go2idl/ tool.
 | 
				
			|||||||
    1. Add your "group/" or "group/version" into
 | 
					    1. Add your "group/" or "group/version" into
 | 
				
			||||||
       cmd/libs/go2idl/conversion-gen/main.go;
 | 
					       cmd/libs/go2idl/conversion-gen/main.go;
 | 
				
			||||||
    2. Make sure your pkg/apis/`<group>`/`<version>` directory has a doc.go file
 | 
					    2. Make sure your pkg/apis/`<group>`/`<version>` directory has a doc.go file
 | 
				
			||||||
       with the comment `// +k8s:deepcopy-gen=register`, to catch the attention
 | 
					       with the comment `// +k8s:deepcopy-gen=package,register`, to catch the
 | 
				
			||||||
       of our generation tools.
 | 
					       attention of our generation tools.
 | 
				
			||||||
    3. Make sure your pkg/apis/`<group>`/`<version>` directory has a doc.go file
 | 
					    3. Make sure your pkg/apis/`<group>`/`<version>` directory has a doc.go file
 | 
				
			||||||
       with the comment `// +genconversion=true`, to catch the attention of our
 | 
					       with the comment `// +genconversion=true`, to catch the attention of our
 | 
				
			||||||
       gen-conversion script.
 | 
					       gen-conversion script.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package federation
 | 
					package federation
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1beta1
 | 
					package v1beta1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Package api contains the latest (or "internal") version of the
 | 
					// Package api contains the latest (or "internal") version of the
 | 
				
			||||||
// Kubernetes API objects. This is the API objects as represented in memory.
 | 
					// Kubernetes API objects. This is the API objects as represented in memory.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=generate
 | 
					// +k8s:deepcopy-gen=package
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package unversioned
 | 
					package unversioned
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Package v1 is the v1 version of the API.
 | 
					// Package v1 is the v1 version of the API.
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package apps
 | 
					package apps
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1alpha1
 | 
					package v1alpha1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package authentication
 | 
					package authentication
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1beta1
 | 
					package v1beta1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package authorization
 | 
					package authorization
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1beta1
 | 
					package v1beta1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package autoscaling
 | 
					package autoscaling
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1
 | 
					package v1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package batch
 | 
					package batch
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1
 | 
					package v1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v2alpha1
 | 
					package v2alpha1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package certificates
 | 
					package certificates
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1alpha1
 | 
					package v1alpha1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package componentconfig
 | 
					package componentconfig
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1alpha1
 | 
					package v1alpha1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package extensions
 | 
					package extensions
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1beta1
 | 
					package v1beta1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package policy
 | 
					package policy
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Package policy is for any kind of policy object.  Suitable examples, even if
 | 
					// Package policy is for any kind of policy object.  Suitable examples, even if
 | 
				
			||||||
// they aren't all here, are PodDisruptionBudget, PodSecurityPolicy,
 | 
					// they aren't all here, are PodDisruptionBudget, PodSecurityPolicy,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +groupName=rbac.authorization.k8s.io
 | 
					// +groupName=rbac.authorization.k8s.io
 | 
				
			||||||
package rbac
 | 
					package rbac
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ limitations under the License.
 | 
				
			|||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +groupName=rbac.authorization.k8s.io
 | 
					// +groupName=rbac.authorization.k8s.io
 | 
				
			||||||
// +k8s:deepcopy-gen=register
 | 
					// +k8s:deepcopy-gen=package,register
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +genconversion=true
 | 
					// +genconversion=true
 | 
				
			||||||
package v1alpha1
 | 
					package v1alpha1
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=generate
 | 
					// +k8s:deepcopy-gen=package
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Package conversion provides go object versioning.
 | 
					// Package conversion provides go object versioning.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,6 +42,6 @@ limitations under the License.
 | 
				
			|||||||
// As a bonus, a few common types useful from all api objects and versions
 | 
					// As a bonus, a few common types useful from all api objects and versions
 | 
				
			||||||
// are provided in types.go.
 | 
					// are provided in types.go.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// +k8s:deepcopy-gen=generate
 | 
					// +k8s:deepcopy-gen=package
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package runtime
 | 
					package runtime
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user