Skip to content
This repository was archived by the owner on Feb 8, 2021. It is now read-only.

Commit 61e3ce7

Browse files
Make runtime less global for Codec
* Make Codec separate from Scheme * Move EncodeOrDie off Scheme to take a Codec * Make Copy work without a Codec * Create a "latest" package that imports all versions and sets global defaults for "most recent encoding" * v1beta1 is the current "latest", v1beta2 exists * Kill DefaultCodec, replace it with "latest.Codec" * This updates the client and etcd to store the latest known version * EmbeddedObject is per schema and per package now * Move runtime.DefaultScheme to api.Scheme * Split out WatchEvent since it's not an API object today, treat it like a special object in api * Kill DefaultResourceVersioner, instead place it on "latest" (as the package that understands all packages) * Move objDiff to runtime.ObjectDiff
1 parent 154a91c commit 61e3ce7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+944
-389
lines changed

cmd/integration/integration.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"time"
3030

3131
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
32+
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
3233
"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
3334
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
3435
"github.com/GoogleCloudPlatform/kubernetes/pkg/controller"
@@ -206,7 +207,7 @@ func runAtomicPutTest(c *client.Client) {
206207
var svc api.Service
207208
err := c.Post().Path("services").Body(
208209
&api.Service{
209-
JSONBase: api.JSONBase{ID: "atomicservice", APIVersion: "v1beta1"},
210+
JSONBase: api.JSONBase{ID: "atomicservice", APIVersion: latest.Version},
210211
Port: 12345,
211212
Labels: map[string]string{
212213
"name": "atomicService",

cmd/kubecfg/kubecfg.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"time"
3131

3232
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
33+
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
3334
"github.com/GoogleCloudPlatform/kubernetes/pkg/client"
3435
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubecfg"
3536
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"

examples/examples_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
"testing"
2626

2727
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
28-
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
28+
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/latest"
2929
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
3030
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
3131
"github.com/golang/glog"

pkg/api/conversion.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
Copyright 2014 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package api
18+
19+
import (
20+
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
21+
)
22+
23+
// Codec is the identity codec for this package - it can only convert itself
24+
// to itself.
25+
var Codec = runtime.CodecFor(Scheme, "")
26+
27+
// EmbeddedObject implements a Codec specific version of an
28+
// embedded object.
29+
type EmbeddedObject struct {
30+
runtime.Object
31+
}
32+
33+
// UnmarshalJSON implements the json.Unmarshaler interface.
34+
func (a *EmbeddedObject) UnmarshalJSON(b []byte) error {
35+
obj, err := runtime.CodecUnmarshalJSON(Codec, b)
36+
a.Object = obj
37+
return err
38+
}
39+
40+
// MarshalJSON implements the json.Marshaler interface.
41+
func (a EmbeddedObject) MarshalJSON() ([]byte, error) {
42+
return runtime.CodecMarshalJSON(Codec, a.Object)
43+
}
44+
45+
// SetYAML implements the yaml.Setter interface.
46+
func (a *EmbeddedObject) SetYAML(tag string, value interface{}) bool {
47+
obj, ok := runtime.CodecSetYAML(Codec, tag, value)
48+
a.Object = obj
49+
return ok
50+
}
51+
52+
// GetYAML implements the yaml.Getter interface.
53+
func (a EmbeddedObject) GetYAML() (tag string, value interface{}) {
54+
return runtime.CodecGetYAML(Codec, a.Object)
55+
}

pkg/api/latest/doc.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
Copyright 2014 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package latest defines the default output serializations that code should
18+
// use and imports the required schemas. It also ensures all previously known
19+
// and supported API versions are available for conversion.
20+
package latest

pkg/api/latest/latest.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
Copyright 2014 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package latest
18+
19+
import (
20+
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
21+
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
22+
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
23+
)
24+
25+
// Version is the string that represents the current external default version
26+
var Version = "v1beta1"
27+
28+
// Codec is the default codec for serializing output that should use
29+
// the latest supported version. Use this Codec when writing to
30+
// disk, a data store that is not dynamically versioned, or in tests.
31+
// This codec can decode any object that Kubernetes is aware of.
32+
var Codec = v1beta1.Codec
33+
34+
// ResourceVersioner describes a default versioner that can handle all types
35+
// of versioning.
36+
// TODO: when versioning changes, make this part of each API definition.
37+
var ResourceVersioner = runtime.NewJSONBaseResourceVersioner()

pkg/api/latest/latest_test.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
Copyright 2014 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package latest
18+
19+
import (
20+
"encoding/json"
21+
"reflect"
22+
"testing"
23+
24+
internal "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
25+
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta1"
26+
_ "github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta2"
27+
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
28+
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
29+
"github.com/fsouza/go-dockerclient"
30+
"github.com/google/gofuzz"
31+
)
32+
33+
// apiObjectFuzzer can randomly populate api objects.
34+
var apiObjectFuzzer = fuzz.New().NilChance(.5).NumElements(1, 1).Funcs(
35+
func(j *internal.JSONBase, c fuzz.Continue) {
36+
// We have to customize the randomization of JSONBases because their
37+
// APIVersion and Kind must remain blank in memory.
38+
j.APIVersion = ""
39+
j.Kind = ""
40+
j.ID = c.RandString()
41+
// TODO: Fix JSON/YAML packages and/or write custom encoding
42+
// for uint64's. Somehow the LS *byte* of this is lost, but
43+
// only when all 8 bytes are set.
44+
j.ResourceVersion = c.RandUint64() >> 8
45+
j.SelfLink = c.RandString()
46+
47+
var sec, nsec int64
48+
c.Fuzz(&sec)
49+
c.Fuzz(&nsec)
50+
j.CreationTimestamp = util.Unix(sec, nsec).Rfc3339Copy()
51+
},
52+
func(intstr *util.IntOrString, c fuzz.Continue) {
53+
// util.IntOrString will panic if its kind is set wrong.
54+
if c.RandBool() {
55+
intstr.Kind = util.IntstrInt
56+
intstr.IntVal = int(c.RandUint64())
57+
intstr.StrVal = ""
58+
} else {
59+
intstr.Kind = util.IntstrString
60+
intstr.IntVal = 0
61+
intstr.StrVal = c.RandString()
62+
}
63+
},
64+
func(u64 *uint64, c fuzz.Continue) {
65+
// TODO: uint64's are NOT handled right.
66+
*u64 = c.RandUint64() >> 8
67+
},
68+
func(pb map[docker.Port][]docker.PortBinding, c fuzz.Continue) {
69+
// This is necessary because keys with nil values get omitted.
70+
// TODO: Is this a bug?
71+
pb[docker.Port(c.RandString())] = []docker.PortBinding{
72+
{c.RandString(), c.RandString()},
73+
{c.RandString(), c.RandString()},
74+
}
75+
},
76+
func(pm map[string]docker.PortMapping, c fuzz.Continue) {
77+
// This is necessary because keys with nil values get omitted.
78+
// TODO: Is this a bug?
79+
pm[c.RandString()] = docker.PortMapping{
80+
c.RandString(): c.RandString(),
81+
}
82+
},
83+
)
84+
85+
func TestInternalRoundTrip(t *testing.T) {
86+
latest := "v1beta2"
87+
88+
for k, _ := range internal.Scheme.KnownTypes("") {
89+
obj, err := internal.Scheme.New("", k)
90+
if err != nil {
91+
t.Errorf("%s: unexpected error: %v", k, err)
92+
continue
93+
}
94+
apiObjectFuzzer.Fuzz(obj)
95+
96+
newer, err := internal.Scheme.New(latest, k)
97+
if err != nil {
98+
t.Errorf("%s: unexpected error: %v", k, err)
99+
continue
100+
}
101+
102+
if err := internal.Scheme.Convert(obj, newer); err != nil {
103+
t.Errorf("unable to convert %#v to %#v: %v", obj, newer, err)
104+
}
105+
106+
actual, err := internal.Scheme.New("", k)
107+
if err != nil {
108+
t.Errorf("%s: unexpected error: %v", k, err)
109+
continue
110+
}
111+
112+
if err := internal.Scheme.Convert(newer, actual); err != nil {
113+
t.Errorf("unable to convert %#v to %#v: %v", newer, actual, err)
114+
}
115+
116+
if !reflect.DeepEqual(obj, actual) {
117+
t.Errorf("%s: diff %s", k, runtime.ObjectDiff(obj, actual))
118+
}
119+
}
120+
}
121+
122+
func TestResourceVersioner(t *testing.T) {
123+
pod := internal.Pod{JSONBase: internal.JSONBase{ResourceVersion: 10}}
124+
version, err := ResourceVersioner.ResourceVersion(&pod)
125+
if err != nil {
126+
t.Fatalf("unexpected error: %v", err)
127+
}
128+
if version != 10 {
129+
t.Errorf("unexpected version %d", version)
130+
}
131+
}
132+
133+
func TestCodec(t *testing.T) {
134+
pod := internal.Pod{}
135+
data, err := Codec.Encode(&pod)
136+
if err != nil {
137+
t.Fatalf("unexpected error: %v", err)
138+
}
139+
other := internal.Pod{}
140+
if err := json.Unmarshal(data, &other); err != nil {
141+
t.Fatalf("unexpected error: %v", err)
142+
}
143+
if other.APIVersion != Version || other.Kind != "Pod" {
144+
t.Errorf("unexpected unmarshalled object %#v", other)
145+
}
146+
}

pkg/api/register.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ import (
2020
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
2121
)
2222

23+
var Scheme = runtime.NewScheme()
24+
2325
func init() {
24-
runtime.DefaultScheme.AddKnownTypes("",
26+
Scheme.AddKnownTypes("",
2527
&PodList{},
2628
&Pod{},
2729
&ReplicationControllerList{},

0 commit comments

Comments
 (0)