client-gen: create private registry for fake clientset

pull/6/head
Dr. Stefan Schimanski 2017-02-25 09:52:11 +01:00
parent 49d1814b3a
commit ee8ce696d6
6 changed files with 124 additions and 68 deletions

View File

@ -28,6 +28,7 @@ import (
"k8s.io/gengo/types"
clientgenargs "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/args"
"k8s.io/kubernetes/cmd/libs/go2idl/client-gen/generators/fake"
"k8s.io/kubernetes/cmd/libs/go2idl/client-gen/generators/scheme"
clientgentypes "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/types"
"github.com/golang/glog"
@ -158,6 +159,19 @@ func packageForClientset(customArgs clientgenargs.Args, clientsetPackage string,
func packageForScheme(customArgs clientgenargs.Args, clientsetPackage string, srcTreePath string, boilerplate []byte, generatedBy string) generator.Package {
schemePackage := filepath.Join(clientsetPackage, "scheme")
// create runtime.Registry for internal client because it has to know about group versions
internalClient := false
NextGroup:
for _, group := range customArgs.Groups {
for _, v := range group.Versions {
if v == "" {
internalClient = true
break NextGroup
}
}
}
return &generator.DefaultPackage{
PackageName: "scheme",
PackagePath: schemePackage,
@ -173,15 +187,16 @@ func packageForScheme(customArgs clientgenargs.Args, clientsetPackage string, sr
// Always generate a "doc.go" file.
generator.DefaultGen{OptionalName: "doc"},
&genScheme{
&scheme.GenScheme{
DefaultGen: generator.DefaultGen{
OptionalName: "register",
},
inputPackages: customArgs.GroupVersionToInputPath,
outputPackage: schemePackage,
outputPath: filepath.Join(srcTreePath, schemePackage),
groups: customArgs.Groups,
imports: generator.NewImportTracker(),
InputPackages: customArgs.GroupVersionToInputPath,
OutputPackage: schemePackage,
OutputPath: filepath.Join(srcTreePath, schemePackage),
Groups: customArgs.Groups,
ImportTracker: generator.NewImportTracker(),
CreateRegistry: internalClient,
},
}
return generators

View File

@ -25,6 +25,7 @@ import (
"k8s.io/gengo/generator"
"k8s.io/gengo/types"
clientgenargs "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/args"
scheme "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/generators/scheme"
clientgentypes "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/types"
)
@ -118,6 +119,17 @@ func PackageForClientset(customArgs clientgenargs.Args, fakeClientsetPackage str
imports: generator.NewImportTracker(),
realClientsetPackage: filepath.Join(customArgs.ClientsetOutputPath, customArgs.ClientsetName),
},
&scheme.GenScheme{
DefaultGen: generator.DefaultGen{
OptionalName: "register",
},
InputPackages: customArgs.GroupVersionToInputPath,
OutputPackage: fakeClientsetPackage,
Groups: customArgs.Groups,
ImportTracker: generator.NewImportTracker(),
PrivateScheme: true,
CreateRegistry: true, // needed to know about root resources and for RESTMapper
},
}
return generators
},

View File

@ -70,7 +70,6 @@ func (g *genClientset) Imports(c *generator.Context) (imports []string) {
imports = append(imports, fmt.Sprintf("clientset \"%s\"", g.realClientsetPackage))
// imports for the code in commonTemplate
imports = append(imports,
"k8s.io/kubernetes/pkg/api",
"k8s.io/client-go/testing",
"k8s.io/client-go/discovery",
"fakediscovery \"k8s.io/client-go/discovery/fake\"",
@ -109,7 +108,7 @@ var common = `
// without applying any validations and/or defaults. It shouldn't be considered a replacement
// for a real clientset and is mostly useful in simple unit tests.
func NewSimpleClientset(objects ...runtime.Object) *Clientset {
o := testing.NewObjectTracker(api.Registry, api.Scheme, api.Codecs.UniversalDecoder())
o := testing.NewObjectTracker(registry, scheme, codecs.UniversalDecoder())
for _, obj := range objects {
if err := o.Add(obj); err != nil {
panic(err)
@ -117,7 +116,7 @@ func NewSimpleClientset(objects ...runtime.Object) *Clientset {
}
fakePtr := testing.Fake{}
fakePtr.AddReactor("*", "*", testing.ObjectReaction(o, api.Registry.RESTMapper()))
fakePtr.AddReactor("*", "*", testing.ObjectReaction(o, registry.RESTMapper()))
fakePtr.AddWatchReactor("*", testing.DefaultWatchReactor(watch.NewFake(), nil))

View File

@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["generator_for_scheme.go"],
tags = ["automanaged"],
deps = [
"//cmd/libs/go2idl/client-gen/types:go_default_library",
"//vendor:k8s.io/gengo/generator",
"//vendor:k8s.io/gengo/namer",
"//vendor:k8s.io/gengo/types",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package generators
package scheme
import (
"fmt"
@ -29,37 +29,38 @@ import (
clientgentypes "k8s.io/kubernetes/cmd/libs/go2idl/client-gen/types"
)
// genScheme produces a package for a clientset with the scheme, codecs and parameter codecs.
type genScheme struct {
// GenScheme produces a package for a clientset with the scheme, codecs and parameter codecs.
type GenScheme struct {
generator.DefaultGen
outputPackage string
groups []clientgentypes.GroupVersions
inputPackages map[clientgentypes.GroupVersion]string
outputPath string
imports namer.ImportTracker
OutputPackage string
Groups []clientgentypes.GroupVersions
InputPackages map[clientgentypes.GroupVersion]string
OutputPath string
ImportTracker namer.ImportTracker
PrivateScheme bool
CreateRegistry bool
schemeGenerated bool
}
func (g *genScheme) Namers(c *generator.Context) namer.NameSystems {
func (g *GenScheme) Namers(c *generator.Context) namer.NameSystems {
return namer.NameSystems{
"raw": namer.NewRawNamer(g.outputPackage, g.imports),
"raw": namer.NewRawNamer(g.OutputPackage, g.ImportTracker),
}
}
// We only want to call GenerateType() once.
func (g *genScheme) Filter(c *generator.Context, t *types.Type) bool {
func (g *GenScheme) Filter(c *generator.Context, t *types.Type) bool {
ret := !g.schemeGenerated
g.schemeGenerated = true
return ret
}
func (g *genScheme) Imports(c *generator.Context) (imports []string) {
imports = append(imports, g.imports.ImportLines()...)
internal := g.internalClientset()
for _, group := range g.groups {
func (g *GenScheme) Imports(c *generator.Context) (imports []string) {
imports = append(imports, g.ImportTracker.ImportLines()...)
for _, group := range g.Groups {
for _, version := range group.Versions {
packagePath := g.inputPackages[clientgentypes.GroupVersion{Group: group.Group, Version: version}]
if internal {
packagePath := g.InputPackages[clientgentypes.GroupVersion{Group: group.Group, Version: version}]
if g.CreateRegistry {
// import the install package for internal clientsets instead of the type package with register.go
if version != "" {
packagePath = filepath.Dir(packagePath)
@ -75,11 +76,11 @@ func (g *genScheme) Imports(c *generator.Context) (imports []string) {
return
}
func (g *genScheme) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
func (g *GenScheme) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
sw := generator.NewSnippetWriter(w, c, "$", "$")
allGroupVersions := clientgentypes.ToGroupVersionPackages(g.groups)
allInstallGroups := clientgentypes.ToGroupInstallPackages(g.groups)
allGroupVersions := clientgentypes.ToGroupVersionPackages(g.Groups)
allInstallGroups := clientgentypes.ToGroupInstallPackages(g.Groups)
m := map[string]interface{}{
"allGroupVersions": allGroupVersions,
@ -96,45 +97,51 @@ func (g *genScheme) GenerateType(c *generator.Context, t *types.Type, w io.Write
"registeredNewOrDie": c.Universe.Function(types.Name{Package: "k8s.io/apimachinery/pkg/apimachinery/registered", Name: "NewOrDie"}),
"registeredAPIRegistrationManager": c.Universe.Type(types.Name{Package: "k8s.io/apimachinery/pkg/apimachinery/registered", Name: "APIRegistrationManager"}),
}
sw.Do(globalsTemplate, m)
if _, err := os.Stat(filepath.Join(g.outputPath, strings.ToLower("register_custom.go"))); err == nil {
m["customRegister"] = true
globals := map[string]string{
"Scheme": "Scheme",
"Codecs": "Codecs",
"ParameterCodec": "ParameterCodec",
"Registry": "Registry",
"GroupFactoryRegistry": "GroupFactoryRegistry",
}
for k, v := range globals {
if g.PrivateScheme {
m[k] = strings.ToLower(v[0:1]) + v[1:]
} else {
m[k] = v
}
}
if g.internalClientset() {
sw.Do(internalRegistration, m)
sw.Do(globalsTemplate, m)
if g.OutputPath != "" {
if _, err := os.Stat(filepath.Join(g.OutputPath, strings.ToLower("register_custom.go"))); err == nil {
m["customRegister"] = true
}
}
if g.CreateRegistry {
sw.Do(registryRegistration, m)
} else {
sw.Do(registration, m)
sw.Do(simpleRegistration, m)
}
return sw.Error()
}
func (g *genScheme) internalClientset() bool {
for _, group := range g.groups {
for _, v := range group.Versions {
if v == "" {
return true
}
}
}
return false
}
var globalsTemplate = `
var Scheme = $.runtimeNewScheme|raw$()
var Codecs = $.serializerNewCodecFactory|raw$(Scheme)
var ParameterCodec = $.runtimeNewParameterCodec|raw$(Scheme)
var $.Scheme$ = $.runtimeNewScheme|raw$()
var $.Codecs$ = $.serializerNewCodecFactory|raw$($.Scheme$)
var $.ParameterCodec$ = $.runtimeNewParameterCodec|raw$($.Scheme$)
`
var internalRegistration = `
var Registry = $.registeredNewOrDie|raw$($.osGetenv|raw$("KUBE_API_VERSIONS"))
var GroupFactoryRegistry = make($.announcedAPIGroupFactoryRegistry|raw$)
var registryRegistration = `
var $.Registry$ = $.registeredNewOrDie|raw$($.osGetenv|raw$("KUBE_API_VERSIONS"))
var $.GroupFactoryRegistry$ = make($.announcedAPIGroupFactoryRegistry|raw$)
func init() {
$.metav1AddToGroupVersion|raw$(Scheme, $.schemaGroupVersion|raw${Version: "v1"})
Install(GroupFactoryRegistry, Registry, Scheme)
$.metav1AddToGroupVersion|raw$($.Scheme$, $.schemaGroupVersion|raw${Version: "v1"})
Install($.GroupFactoryRegistry$, $.Registry$, $.Scheme$)
}
// Install registers the API group and adds types to a scheme
@ -145,12 +152,12 @@ func Install(groupFactoryRegistry $.announcedAPIGroupFactoryRegistry|raw$, regis
}
`
var registration = `
var simpleRegistration = `
func init() {
$.metav1AddToGroupVersion|raw$(Scheme, $.schemaGroupVersion|raw${Version: "v1"})
AddToScheme(Scheme)
$.metav1AddToGroupVersion|raw$($.Scheme$, $.schemaGroupVersion|raw${Version: "v1"})
AddToScheme($.Scheme$)
}
// AddToScheme adds all types of this clientset into the given scheme. This allows composition

View File

@ -77,13 +77,3 @@ ${informergen} \
--listers-package k8s.io/kube-aggregator/pkg/client/listers \
--output-package k8s.io/kube-aggregator/pkg/client/informers
"$@"
# this is a temporary hack until we manage to update codegen to accept a scheme instead of hardcoding it
echo "rewriting imports"
grep -R -H "\"k8s.io/kubernetes/pkg" "${KUBE_ROOT}/vendor/k8s.io/kube-aggregator/pkg/client" | cut -d: -f1 | sort | uniq | \
grep "\.go" | \
xargs ${SED} -i "s|\"k8s.io/kubernetes/pkg|\"k8s.io/client-go/pkg|g"
echo "running gofmt"
find "${KUBE_ROOT}/vendor/k8s.io/kube-aggregator/pkg/client" -type f -name "*.go" -print0 | xargs -0 gofmt -w