Browse code

Rebase OpenShift code onto latest

Clayton Coleman authored on 2014/10/03 11:05:55
Showing 22 changed files
... ...
@@ -34,14 +34,30 @@ var Codec = v1beta1.Codec
34 34
 // TODO: when versioning changes, make this part of each API definition.
35 35
 var ResourceVersioner = runtime.NewJSONBaseResourceVersioner()
36 36
 
37
+// SelfLinker can set or get the SelfLink field of all API types.
38
+// TODO: when versioning changes, make this part of each API definition.
39
+// TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses
40
+// to go through the InterfacesFor method below.
41
+var SelfLinker = runtime.NewJSONBaseSelfLinker()
42
+
43
+// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
44
+type VersionInterfaces struct {
45
+	runtime.Codec
46
+	runtime.ResourceVersioner
47
+	runtime.SelfLinker
48
+}
49
+
37 50
 // InterfacesFor returns the default Codec and ResourceVersioner for a given version
38 51
 // string, or an error if the version is not known.
39
-func InterfacesFor(version string) (codec runtime.Codec, versioner runtime.ResourceVersioner, err error) {
52
+func InterfacesFor(version string) (*VersionInterfaces, error) {
40 53
 	switch version {
41 54
 	case "v1beta1":
42
-		codec, versioner = v1beta1.Codec, ResourceVersioner
55
+		return &VersionInterfaces{
56
+			Codec:             v1beta1.Codec,
57
+			ResourceVersioner: ResourceVersioner,
58
+			SelfLinker:        SelfLinker,
59
+		}, nil
43 60
 	default:
44
-		err = fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", "))
61
+		return nil, fmt.Errorf("unsupported storage version: %s (valid: %s)", version, strings.Join(Versions, ", "))
45 62
 	}
46
-	return
47 63
 }
... ...
@@ -110,7 +110,7 @@ func (bc *BuildController) synchronize(build *api.Build) (api.BuildStatus, error
110 110
 		}
111 111
 
112 112
 		glog.Infof("Attempting to create pod: %#v", podSpec)
113
-		_, err = bc.kubeClient.CreatePod(podSpec)
113
+		_, err = bc.kubeClient.CreatePod(kubeapi.NewContext(), podSpec)
114 114
 
115 115
 		// TODO: strongly typed error checking
116 116
 		if err != nil {
... ...
@@ -127,7 +127,7 @@ func (bc *BuildController) synchronize(build *api.Build) (api.BuildStatus, error
127 127
 			return api.BuildFailed, fmt.Errorf("Build timed out")
128 128
 		}
129 129
 
130
-		pod, err := bc.kubeClient.GetPod(build.PodID)
130
+		pod, err := bc.kubeClient.GetPod(kubeapi.NewContext(), build.PodID)
131 131
 		if err != nil {
132 132
 			return build.Status, fmt.Errorf("Error retrieving pod for build ID %v: %#v", build.ID, err)
133 133
 		}
... ...
@@ -141,7 +141,7 @@ func (bc *BuildController) synchronize(build *api.Build) (api.BuildStatus, error
141 141
 
142 142
 		// check the exit codes of all the containers in the pod
143 143
 		for _, info := range pod.CurrentState.Info {
144
-			if info.State.ExitCode != 0 {
144
+			if info.State.Termination != nil && info.State.Termination.ExitCode != 0 {
145 145
 				nextStatus = api.BuildFailed
146 146
 			}
147 147
 		}
... ...
@@ -31,7 +31,7 @@ func (r *REST) New() runtime.Object {
31 31
 }
32 32
 
33 33
 // List obtains a list of Builds that match selector.
34
-func (r *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
34
+func (r *REST) List(ctx kubeapi.Context, selector, fields labels.Selector) (runtime.Object, error) {
35 35
 	builds, err := r.registry.ListBuilds(selector)
36 36
 	if err != nil {
37 37
 		return nil, err
... ...
@@ -41,7 +41,7 @@ func (r *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
41 41
 }
42 42
 
43 43
 // Get obtains the build specified by its id.
44
-func (r *REST) Get(id string) (runtime.Object, error) {
44
+func (r *REST) Get(ctx kubeapi.Context, id string) (runtime.Object, error) {
45 45
 	build, err := r.registry.GetBuild(id)
46 46
 	if err != nil {
47 47
 		return nil, err
... ...
@@ -50,14 +50,14 @@ func (r *REST) Get(id string) (runtime.Object, error) {
50 50
 }
51 51
 
52 52
 // Delete asynchronously deletes the Build specified by its id.
53
-func (r *REST) Delete(id string) (<-chan runtime.Object, error) {
53
+func (r *REST) Delete(ctx kubeapi.Context, id string) (<-chan runtime.Object, error) {
54 54
 	return apiserver.MakeAsync(func() (runtime.Object, error) {
55 55
 		return &kubeapi.Status{Status: kubeapi.StatusSuccess}, r.registry.DeleteBuild(id)
56 56
 	}), nil
57 57
 }
58 58
 
59 59
 // Create registers a given new Build instance to r.registry.
60
-func (r *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
60
+func (r *REST) Create(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
61 61
 	build, ok := obj.(*api.Build)
62 62
 	if !ok {
63 63
 		return nil, fmt.Errorf("not a build: %#v", obj)
... ...
@@ -82,7 +82,7 @@ func (r *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
82 82
 }
83 83
 
84 84
 // Update replaces a given Build instance with an existing instance in r.registry.
85
-func (r *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
85
+func (r *REST) Update(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
86 86
 	build, ok := obj.(*api.Build)
87 87
 	if !ok {
88 88
 		return nil, fmt.Errorf("not a build: %#v", obj)
... ...
@@ -31,7 +31,7 @@ func (r *REST) New() runtime.Object {
31 31
 }
32 32
 
33 33
 // List obtains a list of BuildConfigs that match selector.
34
-func (r *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
34
+func (r *REST) List(ctx kubeapi.Context, selector, fields labels.Selector) (runtime.Object, error) {
35 35
 	builds, err := r.registry.ListBuildConfigs(selector)
36 36
 	if err != nil {
37 37
 		return nil, err
... ...
@@ -40,7 +40,7 @@ func (r *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
40 40
 }
41 41
 
42 42
 // Get obtains the BuildConfig specified by its id.
43
-func (r *REST) Get(id string) (runtime.Object, error) {
43
+func (r *REST) Get(ctx kubeapi.Context, id string) (runtime.Object, error) {
44 44
 	buildConfig, err := r.registry.GetBuildConfig(id)
45 45
 	if err != nil {
46 46
 		return nil, err
... ...
@@ -49,14 +49,14 @@ func (r *REST) Get(id string) (runtime.Object, error) {
49 49
 }
50 50
 
51 51
 // Delete asynchronously deletes the BuildConfig specified by its id.
52
-func (r *REST) Delete(id string) (<-chan runtime.Object, error) {
52
+func (r *REST) Delete(ctx kubeapi.Context, id string) (<-chan runtime.Object, error) {
53 53
 	return apiserver.MakeAsync(func() (runtime.Object, error) {
54 54
 		return &kubeapi.Status{Status: kubeapi.StatusSuccess}, r.registry.DeleteBuildConfig(id)
55 55
 	}), nil
56 56
 }
57 57
 
58 58
 // Create registers a given new BuildConfig instance to r.registry.
59
-func (r *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
59
+func (r *REST) Create(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
60 60
 	buildConfig, ok := obj.(*api.BuildConfig)
61 61
 	if !ok {
62 62
 		return nil, fmt.Errorf("not a buildConfig: %#v", obj)
... ...
@@ -78,7 +78,7 @@ func (r *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
78 78
 }
79 79
 
80 80
 // Update replaces a given BuildConfig instance with an existing instance in r.registry.
81
-func (r *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
81
+func (r *REST) Update(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
82 82
 	buildConfig, ok := obj.(*api.BuildConfig)
83 83
 	if !ok {
84 84
 		return nil, fmt.Errorf("not a buildConfig: %#v", obj)
... ...
@@ -53,7 +53,7 @@ func (r *Etcd) GetBuild(id string) (*api.Build, error) {
53 53
 
54 54
 // CreateBuild creates a new Build.
55 55
 func (r *Etcd) CreateBuild(build *api.Build) error {
56
-	err := r.CreateObj(makeBuildKey(build.ID), build)
56
+	err := r.CreateObj(makeBuildKey(build.ID), build, 0)
57 57
 	return etcderr.InterpretCreateError(err, "build", build.ID)
58 58
 }
59 59
 
... ...
@@ -103,7 +103,7 @@ func (r *Etcd) GetBuildConfig(id string) (*api.BuildConfig, error) {
103 103
 
104 104
 // CreateBuildConfig creates a new BuildConfig.
105 105
 func (r *Etcd) CreateBuildConfig(config *api.BuildConfig) error {
106
-	err := r.CreateObj(makeBuildConfigKey(config.ID), config)
106
+	err := r.CreateObj(makeBuildConfigKey(config.ID), config, 0)
107 107
 	return etcderr.InterpretCreateError(err, "buildConfig", config.ID)
108 108
 }
109 109
 
... ...
@@ -78,7 +78,7 @@ func (bs *STIBuildStrategy) setupTempVolume(pod *api.Pod) error {
78 78
 	tmpVolume := api.Volume{
79 79
 		Name: "tmp",
80 80
 		Source: &api.VolumeSource{
81
-			HostDirectory: &api.HostDirectory{
81
+			HostDir: &api.HostDir{
82 82
 				Path: tempDir,
83 83
 			},
84 84
 		},
... ...
@@ -12,7 +12,7 @@ func setupDockerSocket(podSpec *api.Pod) {
12 12
 	dockerSocketVolume := api.Volume{
13 13
 		Name: "docker-socket",
14 14
 		Source: &api.VolumeSource{
15
-			HostDirectory: &api.HostDirectory{
15
+			HostDir: &api.HostDir{
16 16
 				Path: "/var/run/docker.sock",
17 17
 			},
18 18
 		},
... ...
@@ -39,7 +39,7 @@ func setupDockerConfig(podSpec *api.Pod) {
39 39
 	dockerConfigVolume := api.Volume{
40 40
 		Name: "docker-cfg",
41 41
 		Source: &api.VolumeSource{
42
-			HostDirectory: &api.HostDirectory{
42
+			HostDir: &api.HostDir{
43 43
 				Path: dockerConfig,
44 44
 			},
45 45
 		},
... ...
@@ -1,9 +1,6 @@
1 1
 package client
2 2
 
3 3
 import (
4
-	"fmt"
5
-	"strings"
6
-
7 4
 	kubeclient "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
8 5
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
9 6
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/watch"
... ...
@@ -98,23 +95,33 @@ type Client struct {
98 98
 	*kubeclient.RESTClient
99 99
 }
100 100
 
101
-// New creates and returns a new Client.
102
-func New(host, version string, auth *kubeclient.AuthInfo) (*Client, error) {
103
-	if version == "" {
101
+// New creates an OpenShift client for the given config. This client works with builds, deployments,
102
+// templates, routes, and images. It allows operations such as list, get, update and delete on these
103
+// objects. An error is returned if the provided configuration is not valid.
104
+func New(c *kubeclient.Config) (*Client, error) {
105
+	config := *c
106
+	if config.Prefix == "" {
107
+		config.Prefix = "/osapi"
108
+	}
109
+	if config.Version == "" {
104 110
 		// Clients default to the preferred code API version
105
-		// TODO: implement version negotation (highest version supported by server)
106
-		version = latest.Version
111
+		// TODO: implement version negotiation (highest version supported by server)
112
+		config.Version = latest.Version
107 113
 	}
108
-	serverCodec, _, err := latest.InterfacesFor(version)
114
+	client, err := kubeclient.RESTClientFor(&config)
109 115
 	if err != nil {
110
-		return nil, fmt.Errorf("API version '%s' is not recognized (valid values: %s)", version, strings.Join(latest.Versions, ", "))
116
+		return nil, err
111 117
 	}
112
-	prefix := fmt.Sprintf("/osapi/%s/", version)
113
-	restClient, err := kubeclient.NewRESTClient(host, auth, prefix, serverCodec)
118
+	return &Client{client}, nil
119
+}
120
+
121
+// NewOrDie creates an OpenShift client and panics if the provided API version is not recognized.
122
+func NewOrDie(c *kubeclient.Config) *Client {
123
+	client, err := New(c)
114 124
 	if err != nil {
115
-		return nil, fmt.Errorf("API URL '%s' is not valid: %v", host, err)
125
+		panic(err)
116 126
 	}
117
-	return &Client{restClient}, nil
127
+	return client
118 128
 }
119 129
 
120 130
 // CreateBuild creates new build. Returns the server's representation of the build and error if one occurs.
... ...
@@ -31,7 +31,7 @@ func NewCommandKubecfg(name string) *cobra.Command {
31 31
 	flag := cmd.Flags()
32 32
 	flag.BoolVar(&cfg.ServerVersion, "server_version", false, "Print the server's version number.")
33 33
 	flag.BoolVar(&cfg.PreventSkew, "expect_version_match", false, "Fail if server's version doesn't match own version.")
34
-	flag.StringVarP(&cfg.HttpServer, "host", "h", "", "The host to connect to.")
34
+	flag.StringVarP(&cfg.ClientConfig.Host, "host", "h", "", "The host to connect to.")
35 35
 	flag.StringVarP(&cfg.Config, "config", "c", "", "Path or URL to the config file, or '-' to read from STDIN")
36 36
 	flag.StringVarP(&cfg.Selector, "label", "l", "", "Selector (label query) to use for listing")
37 37
 	flag.DurationVarP(&cfg.UpdatePeriod, "update", "u", 60*time.Second, "Update interval period")
... ...
@@ -45,9 +45,10 @@ func NewCommandKubecfg(name string) *cobra.Command {
45 45
 	flag.StringVar(&cfg.WWW, "www", "", "If -proxy is true, use this directory to serve static files")
46 46
 	flag.StringVar(&cfg.TemplateFile, "template_file", "", "If present, load this file as a golang template and use it for output printing")
47 47
 	flag.StringVar(&cfg.TemplateStr, "template", "", "If present, parse this string as a golang template and use it for output printing")
48
-	flag.StringVar(&cfg.CAFile, "certificate_authority", "", "Path to a cert. file for the certificate authority")
49
-	flag.StringVar(&cfg.CertFile, "client_certificate", "", "Path to a client certificate for TLS.")
50
-	flag.StringVar(&cfg.KeyFile, "client_key", "", "Path to a client key file for TLS.")
48
+	flag.StringVar(&cfg.ClientConfig.CAFile, "certificate_authority", "", "Path to a cert. file for the certificate authority")
49
+	flag.StringVar(&cfg.ClientConfig.CertFile, "client_certificate", "", "Path to a client certificate for TLS.")
50
+	flag.StringVar(&cfg.ClientConfig.KeyFile, "client_key", "", "Path to a client key file for TLS.")
51
+	flag.BoolVar(&cfg.ClientConfig.Insecure, "insecure_skip_tls_verify", false, "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.")
51 52
 	flag.StringVar(&cfg.ImageName, "image", "", "Image used when updating a replicationController.  Will apply to the first container in the pod template.")
52 53
 
53 54
 	return cmd
... ...
@@ -54,9 +54,9 @@ import (
54 54
 )
55 55
 
56 56
 type KubeConfig struct {
57
+	ClientConfig   kubeclient.Config
57 58
 	ServerVersion  bool
58 59
 	PreventSkew    bool
59
-	HttpServer     string
60 60
 	Config         string
61 61
 	TemplateConfig string
62 62
 	Selector       string
... ...
@@ -74,10 +74,6 @@ type KubeConfig struct {
74 74
 
75 75
 	ImageName string
76 76
 
77
-	CAFile   string
78
-	CertFile string
79
-	KeyFile  string
80
-
81 77
 	APIVersion   string
82 78
 	OSAPIVersion string
83 79
 
... ...
@@ -193,48 +189,47 @@ func (c *KubeConfig) Run() {
193 193
 	util.InitLogs()
194 194
 	defer util.FlushLogs()
195 195
 
196
-	var masterServer string
197
-	if len(c.HttpServer) > 0 {
198
-		masterServer = c.HttpServer
199
-	} else if len(os.Getenv("KUBERNETES_MASTER")) > 0 {
200
-		masterServer = os.Getenv("KUBERNETES_MASTER")
201
-	} else {
202
-		masterServer = "http://localhost:8080"
203
-	}
204
-	kubeClient, err := kubeclient.New(masterServer, c.APIVersion, nil)
205
-	if err != nil {
206
-		glog.Fatalf("Unable to parse %s as a URL: %v", masterServer, err)
196
+	clientConfig := &c.ClientConfig
197
+	// Initialize the client
198
+	if clientConfig.Host == "" {
199
+		clientConfig.Host = os.Getenv("KUBERNETES_MASTER")
207 200
 	}
208
-	client, err := osclient.New(masterServer, c.OSAPIVersion, nil)
209
-	if err != nil {
210
-		glog.Fatalf("Unable to parse %s as a URL: %v", masterServer, err)
201
+	if clientConfig.Host == "" {
202
+		// TODO: eventually apiserver should start on 443 and be secure by default
203
+		clientConfig.Host = "http://localhost:8080"
211 204
 	}
212 205
 
213
-	// TODO: this won't work if TLS is enabled with client cert auth, but no
214
-	// passwords are required. Refactor when we address client auth abstraction.
215
-	if kubeClient.Secure() {
206
+	if kubeclient.IsConfigTransportSecure(clientConfig) {
216 207
 		auth, err := kubecfg.LoadAuthInfo(c.AuthConfig, os.Stdin)
217 208
 		if err != nil {
218 209
 			glog.Fatalf("Error loading auth: %v", err)
219 210
 		}
220
-		if c.CAFile != "" {
221
-			auth.CAFile = c.CAFile
222
-		}
223
-		if c.CertFile != "" {
224
-			auth.CertFile = c.CertFile
211
+		clientConfig.Username = auth.User
212
+		clientConfig.Password = auth.Password
213
+		if auth.CAFile != "" {
214
+			clientConfig.CAFile = auth.CAFile
225 215
 		}
226
-		if c.KeyFile != "" {
227
-			auth.KeyFile = c.KeyFile
216
+		if auth.CertFile != "" {
217
+			clientConfig.CertFile = auth.CertFile
228 218
 		}
229
-		kubeClient, err = kubeclient.New(masterServer, c.APIVersion, auth)
230
-		if err != nil {
231
-			glog.Fatalf("Unable to parse %s as a URL: %v", masterServer, err)
219
+		if auth.KeyFile != "" {
220
+			clientConfig.KeyFile = auth.KeyFile
232 221
 		}
233
-		client, err = osclient.New(masterServer, c.OSAPIVersion, auth)
234
-		if err != nil {
235
-			glog.Fatalf("Unable to parse %s as a URL: %v", masterServer, err)
222
+		if auth.Insecure != nil {
223
+			clientConfig.Insecure = *auth.Insecure
236 224
 		}
237 225
 	}
226
+	clientConfig.Version = c.APIVersion
227
+	kubeClient, err := kubeclient.New(clientConfig)
228
+	if err != nil {
229
+		glog.Fatalf("Unable to set up the Kubernetes API client: %v", err)
230
+	}
231
+
232
+	clientConfig.Version = c.OSAPIVersion
233
+	client, err := osclient.New(clientConfig)
234
+	if err != nil {
235
+		glog.Fatalf("Unable to set up the OpenShift API client: %v", err)
236
+	}
238 237
 
239 238
 	// check the kubernetes server version
240 239
 	if c.ServerVersion {
... ...
@@ -438,14 +433,15 @@ func (c *KubeConfig) executeControllerRequest(method string, client *kubeclient.
438 438
 		return c.Arg(1)
439 439
 	}
440 440
 
441
+	ctx := api.NewContext()
441 442
 	var err error
442 443
 	switch method {
443 444
 	case "stop":
444
-		err = kubecfg.StopController(parseController(), client)
445
+		err = kubecfg.StopController(ctx, parseController(), client)
445 446
 	case "rm":
446
-		err = kubecfg.DeleteController(parseController(), client)
447
+		err = kubecfg.DeleteController(ctx, parseController(), client)
447 448
 	case "rollingupdate":
448
-		err = kubecfg.Update(parseController(), client, c.UpdatePeriod, c.ImageName)
449
+		err = kubecfg.Update(ctx, parseController(), client, c.UpdatePeriod, c.ImageName)
449 450
 	case "run":
450 451
 		if len(c.Args) != 4 {
451 452
 			glog.Fatal("usage: kubecfg [OPTIONS] run <image> <replicas> <controller>")
... ...
@@ -456,7 +452,7 @@ func (c *KubeConfig) executeControllerRequest(method string, client *kubeclient.
456 456
 		if err != nil {
457 457
 			glog.Fatalf("Error parsing replicas: %v", err)
458 458
 		}
459
-		err = kubecfg.RunController(image, name, replicas, client, c.PortSpec, c.ServicePort)
459
+		err = kubecfg.RunController(ctx, image, name, replicas, client, c.PortSpec, c.ServicePort)
460 460
 	case "resize":
461 461
 		args := c.Args
462 462
 		if len(args) < 3 {
... ...
@@ -467,7 +463,7 @@ func (c *KubeConfig) executeControllerRequest(method string, client *kubeclient.
467 467
 		if err != nil {
468 468
 			glog.Fatalf("Error parsing replicas: %v", err)
469 469
 		}
470
-		err = kubecfg.ResizeController(name, replicas, client)
470
+		err = kubecfg.ResizeController(ctx, name, replicas, client)
471 471
 	default:
472 472
 		return false
473 473
 	}
... ...
@@ -50,16 +50,16 @@ import (
50 50
 	"github.com/openshift/origin/pkg/image/registry/image"
51 51
 	"github.com/openshift/origin/pkg/image/registry/imagerepository"
52 52
 	"github.com/openshift/origin/pkg/image/registry/imagerepositorymapping"
53
-	routeregistry "github.com/openshift/origin/pkg/route/registry/route"
54 53
 	routeetcd "github.com/openshift/origin/pkg/route/registry/etcd"
54
+	routeregistry "github.com/openshift/origin/pkg/route/registry/route"
55 55
 	"github.com/openshift/origin/pkg/template"
56 56
 	"github.com/openshift/origin/pkg/version"
57 57
 
58 58
 	// Register versioned api types
59 59
 	_ "github.com/openshift/origin/pkg/config/api/v1beta1"
60 60
 	_ "github.com/openshift/origin/pkg/image/api/v1beta1"
61
-	_ "github.com/openshift/origin/pkg/template/api/v1beta1"
62 61
 	_ "github.com/openshift/origin/pkg/route/api/v1beta1"
62
+	_ "github.com/openshift/origin/pkg/template/api/v1beta1"
63 63
 )
64 64
 
65 65
 func NewCommandStartAllInOne(name string) *cobra.Command {
... ...
@@ -73,6 +73,7 @@ func NewCommandStartAllInOne(name string) *cobra.Command {
73 73
 			cfg.masterHost = env("OPENSHIFT_MASTER", "127.0.0.1")
74 74
 			cfg.bindAddr = env("OPENSHIFT_BIND_ADDR", "127.0.0.1")
75 75
 			cfg.nodeHosts = []string{"127.0.0.1"}
76
+			cfg.networkContainerImage = env("KUBERNETES_NETWORK_CONTAINER_IMAGE", kubelet.NetworkContainerImage)
76 77
 
77 78
 			if len(os.Getenv("OPENSHIFT_MASTER")) > 0 {
78 79
 				if cfg.masterHost == cfg.bindAddr {
... ...
@@ -106,10 +107,13 @@ type config struct {
106 106
 	VolumeDir  string
107 107
 	EtcdDir    string
108 108
 	Docker     docker.Helper
109
+
109 110
 	masterHost string
110 111
 	nodeHosts  []string
111 112
 	bindAddr   string
112 113
 
114
+	networkContainerImage string
115
+
113 116
 	storageVersion string
114 117
 }
115 118
 
... ...
@@ -121,15 +125,15 @@ func (c *config) newEtcdHelper() (helper tools.EtcdHelper, err error) {
121 121
 	if version == "" {
122 122
 		version = latest.Version
123 123
 	}
124
-	codec, versioner, err := latest.InterfacesFor(version)
124
+	interfaces, err := latest.InterfacesFor(version)
125 125
 	if err != nil {
126 126
 		return helper, err
127 127
 	}
128
-	return tools.EtcdHelper{client, codec, versioner}, nil
128
+	return tools.EtcdHelper{client, interfaces.Codec, interfaces.ResourceVersioner}, nil
129 129
 }
130 130
 
131 131
 func (c *config) getKubeClient() *kubeclient.Client {
132
-	kubeClient, err := kubeclient.New("http://"+c.ListenAddr, klatest.Version, nil)
132
+	kubeClient, err := kubeclient.New(&kubeclient.Config{Host: c.ListenAddr, Version: klatest.Version})
133 133
 	if err != nil {
134 134
 		glog.Fatalf("Unable to configure client - bad URL: %v", err)
135 135
 	}
... ...
@@ -137,7 +141,7 @@ func (c *config) getKubeClient() *kubeclient.Client {
137 137
 }
138 138
 
139 139
 func (c *config) getOsClient() *osclient.Client {
140
-	osClient, err := osclient.New("http://"+c.ListenAddr, latest.Version, nil)
140
+	osClient, err := osclient.New(&kubeclient.Config{Host: c.ListenAddr, Version: latest.Version})
141 141
 	if err != nil {
142 142
 		glog.Fatalf("Unable to configure client - bad URL: %v", err)
143 143
 	}
... ...
@@ -257,7 +261,7 @@ func (c *config) runApiserver() {
257 257
 
258 258
 	apiserver.NewAPIGroup(m.API_v1beta1()).InstallREST(osMux, kubePrefix)
259 259
 	apiserver.NewAPIGroup(m.API_v1beta2()).InstallREST(osMux, kube2Prefix)
260
-	apiserver.NewAPIGroup(storage, v1beta1.Codec).InstallREST(osMux, osPrefix)
260
+	apiserver.NewAPIGroup(storage, v1beta1.Codec, osPrefix, latest.SelfLinker).InstallREST(osMux, osPrefix)
261 261
 	apiserver.InstallSupport(osMux)
262 262
 
263 263
 	osApi := &http.Server{
... ...
@@ -342,7 +346,10 @@ func (c *config) runKubelet() {
342 342
 		cadvisorClient,
343 343
 		etcdClient,
344 344
 		rootDirectory,
345
-		30*time.Second)
345
+		c.networkContainerImage,
346
+		30*time.Second,
347
+		0.0,
348
+		10)
346 349
 	go util.Forever(func() { k.Run(cfg.Updates()) }, 0)
347 350
 	go util.Forever(func() {
348 351
 		kubelet.ListenAndServeKubeletServer(k, cfg.Channel("http"), minionHost, uint(minionPort))
... ...
@@ -3,7 +3,7 @@ package deploy
3 3
 import (
4 4
 	"time"
5 5
 
6
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
6
+	kubeapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
7 7
 	kubeclient "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
8 8
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
9 9
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
... ...
@@ -31,11 +31,11 @@ type DeploymentStateHandler interface {
31 31
 type DefaultDeploymentHandler struct {
32 32
 	osClient    osclient.Interface
33 33
 	kubeClient  kubeclient.Interface
34
-	environment []api.EnvVar
34
+	environment []kubeapi.EnvVar
35 35
 }
36 36
 
37 37
 // NewDeploymentController creates a new DeploymentController.
38
-func NewDeploymentController(kubeClient kubeclient.Interface, osClient osclient.Interface, initialEnvironment []api.EnvVar) *DeploymentController {
38
+func NewDeploymentController(kubeClient kubeclient.Interface, osClient osclient.Interface, initialEnvironment []kubeapi.EnvVar) *DeploymentController {
39 39
 	dc := &DeploymentController{
40 40
 		kubeClient: kubeClient,
41 41
 		osClient:   osClient,
... ...
@@ -101,31 +101,31 @@ func (dh *DefaultDeploymentHandler) saveDeployment(deployment *deployapi.Deploym
101 101
 	return err
102 102
 }
103 103
 
104
-func (dh *DefaultDeploymentHandler) makeDeploymentPod(deployment *deployapi.Deployment) *api.Pod {
104
+func (dh *DefaultDeploymentHandler) makeDeploymentPod(deployment *deployapi.Deployment) *kubeapi.Pod {
105 105
 	podID := deploymentPodID(deployment)
106 106
 
107 107
 	envVars := deployment.Strategy.CustomPod.Environment
108
-	envVars = append(envVars, api.EnvVar{Name: "KUBERNETES_DEPLOYMENT_ID", Value: deployment.ID})
108
+	envVars = append(envVars, kubeapi.EnvVar{Name: "KUBERNETES_DEPLOYMENT_ID", Value: deployment.ID})
109 109
 	for _, env := range dh.environment {
110 110
 		envVars = append(envVars, env)
111 111
 	}
112 112
 
113
-	return &api.Pod{
114
-		JSONBase: api.JSONBase{
113
+	return &kubeapi.Pod{
114
+		JSONBase: kubeapi.JSONBase{
115 115
 			ID: podID,
116 116
 		},
117
-		DesiredState: api.PodState{
118
-			Manifest: api.ContainerManifest{
117
+		DesiredState: kubeapi.PodState{
118
+			Manifest: kubeapi.ContainerManifest{
119 119
 				Version: "v1beta1",
120
-				Containers: []api.Container{
120
+				Containers: []kubeapi.Container{
121 121
 					{
122 122
 						Name:  "deployment",
123 123
 						Image: deployment.Strategy.CustomPod.Image,
124 124
 						Env:   envVars,
125 125
 					},
126 126
 				},
127
-				RestartPolicy: api.RestartPolicy{
128
-					Never: &api.RestartPolicyNever{},
127
+				RestartPolicy: kubeapi.RestartPolicy{
128
+					Never: &kubeapi.RestartPolicyNever{},
129 129
 				},
130 130
 			},
131 131
 		},
... ...
@@ -140,7 +140,7 @@ func deploymentPodID(deployment *deployapi.Deployment) string {
140 140
 func (dh *DefaultDeploymentHandler) HandleNew(deployment *deployapi.Deployment) error {
141 141
 	deploymentPod := dh.makeDeploymentPod(deployment)
142 142
 	glog.Infof("Attempting to create deployment pod: %+v", deploymentPod)
143
-	if pod, err := dh.kubeClient.CreatePod(deploymentPod); err != nil {
143
+	if pod, err := dh.kubeClient.CreatePod(kubeapi.NewContext(), deploymentPod); err != nil {
144 144
 		glog.Warningf("Received error creating pod: %v", err)
145 145
 		deployment.State = deployapi.DeploymentFailed
146 146
 	} else {
... ...
@@ -155,7 +155,7 @@ func (dh *DefaultDeploymentHandler) HandleNew(deployment *deployapi.Deployment)
155 155
 func (dh *DefaultDeploymentHandler) HandlePending(deployment *deployapi.Deployment) error {
156 156
 	podID := deploymentPodID(deployment)
157 157
 	glog.Infof("Retrieving deployment pod id %s", podID)
158
-	pod, err := dh.kubeClient.GetPod(podID)
158
+	pod, err := dh.kubeClient.GetPod(kubeapi.NewContext(), podID)
159 159
 	if err != nil {
160 160
 		glog.Errorf("Error retrieving pod for deployment ID %v: %#v", deployment.ID, err)
161 161
 		deployment.State = deployapi.DeploymentFailed
... ...
@@ -163,9 +163,9 @@ func (dh *DefaultDeploymentHandler) HandlePending(deployment *deployapi.Deployme
163 163
 		glog.Infof("Deployment pod is %+v", pod)
164 164
 
165 165
 		switch pod.CurrentState.Status {
166
-		case api.PodRunning:
166
+		case kubeapi.PodRunning:
167 167
 			deployment.State = deployapi.DeploymentRunning
168
-		case api.PodTerminated:
168
+		case kubeapi.PodTerminated:
169 169
 			dh.checkForTerminatedDeploymentPod(deployment, pod)
170 170
 		}
171 171
 	}
... ...
@@ -177,7 +177,7 @@ func (dh *DefaultDeploymentHandler) HandlePending(deployment *deployapi.Deployme
177 177
 func (dh *DefaultDeploymentHandler) HandleRunning(deployment *deployapi.Deployment) error {
178 178
 	podID := deploymentPodID(deployment)
179 179
 	glog.Infof("Retrieving deployment pod id %s", podID)
180
-	pod, err := dh.kubeClient.GetPod(podID)
180
+	pod, err := dh.kubeClient.GetPod(kubeapi.NewContext(), podID)
181 181
 	if err != nil {
182 182
 		glog.Errorf("Error retrieving pod for deployment ID %v: %#v", deployment.ID, err)
183 183
 		deployment.State = deployapi.DeploymentFailed
... ...
@@ -189,15 +189,15 @@ func (dh *DefaultDeploymentHandler) HandleRunning(deployment *deployapi.Deployme
189 189
 	return dh.saveDeployment(deployment)
190 190
 }
191 191
 
192
-func (dh *DefaultDeploymentHandler) checkForTerminatedDeploymentPod(deployment *deployapi.Deployment, pod *api.Pod) {
193
-	if pod.CurrentState.Status != api.PodTerminated {
192
+func (dh *DefaultDeploymentHandler) checkForTerminatedDeploymentPod(deployment *deployapi.Deployment, pod *kubeapi.Pod) {
193
+	if pod.CurrentState.Status != kubeapi.PodTerminated {
194 194
 		glog.Infof("The deployment has not yet finished. Pod status is %s. Continuing", pod.CurrentState.Status)
195 195
 		return
196 196
 	}
197 197
 
198 198
 	deployment.State = deployapi.DeploymentComplete
199 199
 	for _, info := range pod.CurrentState.Info {
200
-		if info.State.ExitCode != 0 {
200
+		if info.State.Termination != nil && info.State.Termination.ExitCode != 0 {
201 201
 			deployment.State = deployapi.DeploymentFailed
202 202
 		}
203 203
 	}
... ...
@@ -205,7 +205,7 @@ func (dh *DefaultDeploymentHandler) checkForTerminatedDeploymentPod(deployment *
205 205
 	if deployment.State == deployapi.DeploymentComplete {
206 206
 		podID := deploymentPodID(deployment)
207 207
 		glog.Infof("Removing deployment pod for ID %v", podID)
208
-		dh.kubeClient.DeletePod(podID)
208
+		dh.kubeClient.DeletePod(kubeapi.NewContext(), podID)
209 209
 	}
210 210
 
211 211
 	glog.Infof("The deployment pod has finished. Setting deployment state to %s", deployment.State)
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"fmt"
5 5
 
6 6
 	"code.google.com/p/go-uuid/uuid"
7
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
7
+	kubeapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
8 8
 	kubeerrors "github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
9 9
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
10 10
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
... ...
@@ -26,8 +26,13 @@ func NewREST(registry Registry) apiserver.RESTStorage {
26 26
 	}
27 27
 }
28 28
 
29
+// New creates a new Deployment for use with Create and Update
30
+func (s *REST) New() runtime.Object {
31
+	return &deployapi.Deployment{}
32
+}
33
+
29 34
 // List obtains a list of Deployments that match selector.
30
-func (s *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
35
+func (s *REST) List(ctx kubeapi.Context, selector, fields labels.Selector) (runtime.Object, error) {
31 36
 	deployments, err := s.registry.ListDeployments(selector)
32 37
 	if err != nil {
33 38
 		return nil, err
... ...
@@ -36,13 +41,8 @@ func (s *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
36 36
 	return deployments, nil
37 37
 }
38 38
 
39
-// New creates a new Deployment for use with Create and Update
40
-func (s *REST) New() runtime.Object {
41
-	return &deployapi.Deployment{}
42
-}
43
-
44 39
 // Get obtains the Deployment specified by its id.
45
-func (s *REST) Get(id string) (runtime.Object, error) {
40
+func (s *REST) Get(ctx kubeapi.Context, id string) (runtime.Object, error) {
46 41
 	deployment, err := s.registry.GetDeployment(id)
47 42
 	if err != nil {
48 43
 		return nil, err
... ...
@@ -51,14 +51,14 @@ func (s *REST) Get(id string) (runtime.Object, error) {
51 51
 }
52 52
 
53 53
 // Delete asynchronously deletes the Deployment specified by its id.
54
-func (s *REST) Delete(id string) (<-chan runtime.Object, error) {
54
+func (s *REST) Delete(ctx kubeapi.Context, id string) (<-chan runtime.Object, error) {
55 55
 	return apiserver.MakeAsync(func() (runtime.Object, error) {
56
-		return &api.Status{Status: api.StatusSuccess}, s.registry.DeleteDeployment(id)
56
+		return &kubeapi.Status{Status: kubeapi.StatusSuccess}, s.registry.DeleteDeployment(id)
57 57
 	}), nil
58 58
 }
59 59
 
60 60
 // Create registers a given new Deployment instance to s.registry.
61
-func (s *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
61
+func (s *REST) Create(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
62 62
 	deployment, ok := obj.(*deployapi.Deployment)
63 63
 	if !ok {
64 64
 		return nil, fmt.Errorf("not a deployment: %#v", obj)
... ...
@@ -85,7 +85,7 @@ func (s *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
85 85
 }
86 86
 
87 87
 // Update replaces a given Deployment instance with an existing instance in s.registry.
88
-func (s *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
88
+func (s *REST) Update(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
89 89
 	deployment, ok := obj.(*deployapi.Deployment)
90 90
 	if !ok {
91 91
 		return nil, fmt.Errorf("not a deployment: %#v", obj)
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"fmt"
5 5
 
6 6
 	"code.google.com/p/go-uuid/uuid"
7
-	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
7
+	kubeapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
8 8
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
9 9
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
10 10
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
... ...
@@ -23,8 +23,13 @@ func NewREST(registry Registry) apiserver.RESTStorage {
23 23
 	}
24 24
 }
25 25
 
26
+// New creates a new DeploymentConfig for use with Create and Update
27
+func (s *REST) New() runtime.Object {
28
+	return &deployapi.DeploymentConfig{}
29
+}
30
+
26 31
 // List obtains a list of DeploymentConfigs that match selector.
27
-func (s *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
32
+func (s *REST) List(ctx kubeapi.Context, selector, fields labels.Selector) (runtime.Object, error) {
28 33
 	deploymentConfigs, err := s.registry.ListDeploymentConfigs(selector)
29 34
 	if err != nil {
30 35
 		return nil, err
... ...
@@ -34,7 +39,7 @@ func (s *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
34 34
 }
35 35
 
36 36
 // Get obtains the DeploymentConfig specified by its id.
37
-func (s *REST) Get(id string) (runtime.Object, error) {
37
+func (s *REST) Get(ctx kubeapi.Context, id string) (runtime.Object, error) {
38 38
 	deploymentConfig, err := s.registry.GetDeploymentConfig(id)
39 39
 	if err != nil {
40 40
 		return nil, err
... ...
@@ -43,19 +48,14 @@ func (s *REST) Get(id string) (runtime.Object, error) {
43 43
 }
44 44
 
45 45
 // Delete asynchronously deletes the DeploymentConfig specified by its id.
46
-func (s *REST) Delete(id string) (<-chan runtime.Object, error) {
46
+func (s *REST) Delete(ctx kubeapi.Context, id string) (<-chan runtime.Object, error) {
47 47
 	return apiserver.MakeAsync(func() (runtime.Object, error) {
48
-		return &api.Status{Status: api.StatusSuccess}, s.registry.DeleteDeploymentConfig(id)
48
+		return &kubeapi.Status{Status: kubeapi.StatusSuccess}, s.registry.DeleteDeploymentConfig(id)
49 49
 	}), nil
50 50
 }
51 51
 
52
-// New creates a new DeploymentConfig for use with Create and Update
53
-func (s *REST) New() runtime.Object {
54
-	return &deployapi.DeploymentConfig{}
55
-}
56
-
57 52
 // Create registers a given new DeploymentConfig instance to s.registry.
58
-func (s *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
53
+func (s *REST) Create(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
59 54
 	deploymentConfig, ok := obj.(*deployapi.DeploymentConfig)
60 55
 	if !ok {
61 56
 		return nil, fmt.Errorf("not a deploymentConfig: %#v", obj)
... ...
@@ -76,7 +76,7 @@ func (s *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
76 76
 }
77 77
 
78 78
 // Update replaces a given DeploymentConfig instance with an existing instance in s.registry.
79
-func (s *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
79
+func (s *REST) Update(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
80 80
 	deploymentConfig, ok := obj.(*deployapi.DeploymentConfig)
81 81
 	if !ok {
82 82
 		return nil, fmt.Errorf("not a deploymentConfig: %#v", obj)
... ...
@@ -55,7 +55,7 @@ func (r *Etcd) GetDeployment(id string) (*api.Deployment, error) {
55 55
 
56 56
 // CreateDeployment creates a new Deployment.
57 57
 func (r *Etcd) CreateDeployment(deployment *api.Deployment) error {
58
-	err := r.CreateObj(makeDeploymentKey(deployment.ID), deployment)
58
+	err := r.CreateObj(makeDeploymentKey(deployment.ID), deployment, 0)
59 59
 	return etcderr.InterpretCreateError(err, "deployment", deployment.ID)
60 60
 }
61 61
 
... ...
@@ -107,7 +107,7 @@ func (r *Etcd) GetDeploymentConfig(id string) (*api.DeploymentConfig, error) {
107 107
 
108 108
 // CreateDeploymentConfig creates a new DeploymentConfig.
109 109
 func (r *Etcd) CreateDeploymentConfig(deploymentConfig *api.DeploymentConfig) error {
110
-	err := r.CreateObj(makeDeploymentConfigKey(deploymentConfig.ID), deploymentConfig)
110
+	err := r.CreateObj(makeDeploymentConfigKey(deploymentConfig.ID), deploymentConfig, 0)
111 111
 	return etcderr.InterpretCreateError(err, "deploymentConfig", deploymentConfig.ID)
112 112
 }
113 113
 
... ...
@@ -57,7 +57,7 @@ func (r *Etcd) GetImage(id string) (*api.Image, error) {
57 57
 
58 58
 // CreateImage creates a new image
59 59
 func (r *Etcd) CreateImage(image *api.Image) error {
60
-	err := r.CreateObj(makeImageKey(image.ID), image)
60
+	err := r.CreateObj(makeImageKey(image.ID), image, 0)
61 61
 	return etcderr.InterpretCreateError(err, "image", image.ID)
62 62
 }
63 63
 
... ...
@@ -117,7 +117,7 @@ func (r *Etcd) WatchImageRepositories(resourceVersion uint64, filter func(repo *
117 117
 
118 118
 // CreateImageRepository registers the given ImageRepository.
119 119
 func (r *Etcd) CreateImageRepository(repo *api.ImageRepository) error {
120
-	err := r.CreateObj(makeImageRepositoryKey(repo.ID), repo)
120
+	err := r.CreateObj(makeImageRepositoryKey(repo.ID), repo, 0)
121 121
 	return etcderr.InterpretCreateError(err, "imageRepository", repo.ID)
122 122
 }
123 123
 
... ...
@@ -29,27 +29,27 @@ func (s *REST) New() runtime.Object {
29 29
 	return &api.Image{}
30 30
 }
31 31
 
32
-// Get retrieves an Image by id.
33
-func (s *REST) Get(id string) (runtime.Object, error) {
34
-	image, err := s.registry.GetImage(id)
32
+// List retrieves a list of Images that match selector.
33
+func (s *REST) List(ctx kubeapi.Context, selector, fields labels.Selector) (runtime.Object, error) {
34
+	images, err := s.registry.ListImages(selector)
35 35
 	if err != nil {
36 36
 		return nil, err
37 37
 	}
38
-	return image, nil
38
+
39
+	return images, nil
39 40
 }
40 41
 
41
-// List retrieves a list of Images that match selector.
42
-func (s *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
43
-	images, err := s.registry.ListImages(selector)
42
+// Get retrieves an Image by id.
43
+func (s *REST) Get(ctx kubeapi.Context, id string) (runtime.Object, error) {
44
+	image, err := s.registry.GetImage(id)
44 45
 	if err != nil {
45 46
 		return nil, err
46 47
 	}
47
-
48
-	return images, nil
48
+	return image, nil
49 49
 }
50 50
 
51 51
 // Create registers the given Image.
52
-func (s *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
52
+func (s *REST) Create(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
53 53
 	image, ok := obj.(*api.Image)
54 54
 	if !ok {
55 55
 		return nil, fmt.Errorf("not an image: %#v", obj)
... ...
@@ -65,17 +65,17 @@ func (s *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
65 65
 		if err := s.registry.CreateImage(image); err != nil {
66 66
 			return nil, err
67 67
 		}
68
-		return s.Get(image.ID)
68
+		return s.Get(ctx, image.ID)
69 69
 	}), nil
70 70
 }
71 71
 
72 72
 // Update is not supported for Images, as they are immutable.
73
-func (s *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
73
+func (s *REST) Update(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
74 74
 	return nil, fmt.Errorf("Images may not be changed.")
75 75
 }
76 76
 
77 77
 // Delete asynchronously deletes an Image specified by its id.
78
-func (s *REST) Delete(id string) (<-chan runtime.Object, error) {
78
+func (s *REST) Delete(ctx kubeapi.Context, id string) (<-chan runtime.Object, error) {
79 79
 	return apiserver.MakeAsync(func() (runtime.Object, error) {
80 80
 		return &kubeapi.Status{Status: kubeapi.StatusSuccess}, s.registry.DeleteImage(id)
81 81
 	}), nil
... ...
@@ -5,7 +5,7 @@ import (
5 5
 
6 6
 	"code.google.com/p/go-uuid/uuid"
7 7
 
8
-	baseapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
8
+	kubeapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
9 9
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
10 10
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
11 11
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
... ...
@@ -30,26 +30,26 @@ func (s *REST) New() runtime.Object {
30 30
 	return &api.ImageRepository{}
31 31
 }
32 32
 
33
-// Get retrieves an ImageRepository by id.
34
-func (s *REST) Get(id string) (runtime.Object, error) {
35
-	repo, err := s.registry.GetImageRepository(id)
33
+// List retrieves a list of ImageRepositories that match selector.
34
+func (s *REST) List(ctx kubeapi.Context, selector, fields labels.Selector) (runtime.Object, error) {
35
+	imageRepositories, err := s.registry.ListImageRepositories(selector)
36 36
 	if err != nil {
37 37
 		return nil, err
38 38
 	}
39
-	return repo, nil
39
+	return imageRepositories, err
40 40
 }
41 41
 
42
-// List retrieves a list of ImageRepositories that match selector.
43
-func (s *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
44
-	imageRepositories, err := s.registry.ListImageRepositories(selector)
42
+// Get retrieves an ImageRepository by id.
43
+func (s *REST) Get(ctx kubeapi.Context, id string) (runtime.Object, error) {
44
+	repo, err := s.registry.GetImageRepository(id)
45 45
 	if err != nil {
46 46
 		return nil, err
47 47
 	}
48
-	return imageRepositories, err
48
+	return repo, nil
49 49
 }
50 50
 
51 51
 // Watch begins watching for new, changed, or deleted ImageRepositories.
52
-func (s *REST) Watch(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
52
+func (s *REST) Watch(ctx kubeapi.Context, label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
53 53
 	return s.registry.WatchImageRepositories(resourceVersion, func(repo *api.ImageRepository) bool {
54 54
 		fields := labels.Set{
55 55
 			"ID": repo.ID,
... ...
@@ -60,7 +60,7 @@ func (s *REST) Watch(label, field labels.Selector, resourceVersion uint64) (watc
60 60
 }
61 61
 
62 62
 // Create registers the given ImageRepository.
63
-func (s *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
63
+func (s *REST) Create(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
64 64
 	repo, ok := obj.(*api.ImageRepository)
65 65
 	if !ok {
66 66
 		return nil, fmt.Errorf("not an image repository: %#v", obj)
... ...
@@ -80,12 +80,12 @@ func (s *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
80 80
 		if err := s.registry.CreateImageRepository(repo); err != nil {
81 81
 			return nil, err
82 82
 		}
83
-		return s.Get(repo.ID)
83
+		return s.Get(ctx, repo.ID)
84 84
 	}), nil
85 85
 }
86 86
 
87 87
 // Update replaces an existing ImageRepository in the registry with the given ImageRepository.
88
-func (s *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
88
+func (s *REST) Update(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
89 89
 	repo, ok := obj.(*api.ImageRepository)
90 90
 	if !ok {
91 91
 		return nil, fmt.Errorf("not an image repository: %#v", obj)
... ...
@@ -99,13 +99,13 @@ func (s *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
99 99
 		if err != nil {
100 100
 			return nil, err
101 101
 		}
102
-		return s.Get(repo.ID)
102
+		return s.Get(ctx, repo.ID)
103 103
 	}), nil
104 104
 }
105 105
 
106 106
 // Delete asynchronously deletes an ImageRepository specified by its id.
107
-func (s *REST) Delete(id string) (<-chan runtime.Object, error) {
107
+func (s *REST) Delete(ctx kubeapi.Context, id string) (<-chan runtime.Object, error) {
108 108
 	return apiserver.MakeAsync(func() (runtime.Object, error) {
109
-		return &baseapi.Status{Status: baseapi.StatusSuccess}, s.registry.DeleteImageRepository(id)
109
+		return &kubeapi.Status{Status: kubeapi.StatusSuccess}, s.registry.DeleteImageRepository(id)
110 110
 	}), nil
111 111
 }
... ...
@@ -33,18 +33,18 @@ func (s *REST) New() runtime.Object {
33 33
 	return &api.ImageRepositoryMapping{}
34 34
 }
35 35
 
36
-// Get is not supported.
37
-func (s *REST) Get(id string) (runtime.Object, error) {
38
-	return nil, errors.NewNotFound("imageRepositoryMapping", id)
39
-}
40
-
41 36
 // List is not supported.
42
-func (s *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
37
+func (s *REST) List(ctx kubeapi.Context, selector, fields labels.Selector) (runtime.Object, error) {
43 38
 	return nil, errors.NewNotFound("imageRepositoryMapping", "list")
44 39
 }
45 40
 
41
+// Get is not supported.
42
+func (s *REST) Get(ctx kubeapi.Context, id string) (runtime.Object, error) {
43
+	return nil, errors.NewNotFound("imageRepositoryMapping", id)
44
+}
45
+
46 46
 // Create registers a new image (if it doesn't exist) and updates the specified ImageRepository's tags.
47
-func (s *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
47
+func (s *REST) Create(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
48 48
 	mapping, ok := obj.(*api.ImageRepositoryMapping)
49 49
 	if !ok {
50 50
 		return nil, fmt.Errorf("not an image repository mapping: %#v", obj)
... ...
@@ -110,11 +110,11 @@ func (s *REST) findImageRepository(dockerRepo string) (*api.ImageRepository, err
110 110
 }
111 111
 
112 112
 // Update is not supported.
113
-func (s *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
113
+func (s *REST) Update(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
114 114
 	return nil, fmt.Errorf("ImageRepositoryMappings may not be changed.")
115 115
 }
116 116
 
117 117
 // Delete is not supported.
118
-func (s *REST) Delete(id string) (<-chan runtime.Object, error) {
118
+func (s *REST) Delete(ctx kubeapi.Context, id string) (<-chan runtime.Object, error) {
119 119
 	return nil, errors.NewNotFound("imageRepositoryMapping", id)
120 120
 }
... ...
@@ -57,7 +57,7 @@ func (registry *Etcd) GetRoute(routeID string) (*api.Route, error) {
57 57
 
58 58
 // CreateRoute creates a new Route.
59 59
 func (registry *Etcd) CreateRoute(route *api.Route) error {
60
-	err := registry.CreateObj(makeRouteKey(route.ID), route)
60
+	err := registry.CreateObj(makeRouteKey(route.ID), route, 0)
61 61
 	return etcderr.InterpretCreateError(err, "route", route.ID)
62 62
 }
63 63
 
... ...
@@ -80,7 +80,7 @@ func (registry *Etcd) WatchRoutes(label, field labels.Selector, resourceVersion
80 80
 		return nil, fmt.Errorf("label selectors are not supported on routes yet")
81 81
 	}
82 82
 	if value, found := field.RequiresExactMatch("ID"); found {
83
-		return registry.Watch(makeRouteKey(value), resourceVersion)
83
+		return registry.Watch(makeRouteKey(value), resourceVersion), nil
84 84
 	}
85 85
 	if field.Empty() {
86 86
 		return registry.WatchList("/routes", resourceVersion, tools.Everything)
... ...
@@ -32,7 +32,7 @@ func (rs *REST) New() runtime.Object {
32 32
 }
33 33
 
34 34
 // List obtains a list of Routes that match selector.
35
-func (rs *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
35
+func (rs *REST) List(ctx kubeapi.Context, selector, fields labels.Selector) (runtime.Object, error) {
36 36
 	list, err := rs.registry.ListRoutes(selector)
37 37
 	if err != nil {
38 38
 		return nil, err
... ...
@@ -41,7 +41,7 @@ func (rs *REST) List(selector, fields labels.Selector) (runtime.Object, error) {
41 41
 }
42 42
 
43 43
 // Get obtains the route specified by its id.
44
-func (rs *REST) Get(id string) (runtime.Object, error) {
44
+func (rs *REST) Get(ctx kubeapi.Context, id string) (runtime.Object, error) {
45 45
 	route, err := rs.registry.GetRoute(id)
46 46
 	if err != nil {
47 47
 		return nil, err
... ...
@@ -50,7 +50,7 @@ func (rs *REST) Get(id string) (runtime.Object, error) {
50 50
 }
51 51
 
52 52
 // Delete asynchronously deletes the Route specified by its id.
53
-func (rs *REST) Delete(id string) (<-chan runtime.Object, error) {
53
+func (rs *REST) Delete(ctx kubeapi.Context, id string) (<-chan runtime.Object, error) {
54 54
 	_, err := rs.registry.GetRoute(id)
55 55
 	if err != nil {
56 56
 		return nil, err
... ...
@@ -61,12 +61,12 @@ func (rs *REST) Delete(id string) (<-chan runtime.Object, error) {
61 61
 }
62 62
 
63 63
 // Create registers a given new Route instance to rs.registry.
64
-func (rs *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
64
+func (rs *REST) Create(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
65 65
 	route, ok := obj.(*api.Route)
66 66
 	if !ok {
67 67
 		return nil, fmt.Errorf("not a route: %#v", obj)
68 68
 	}
69
-	
69
+
70 70
 	if errs := validation.ValidateRoute(route); len(errs) > 0 {
71 71
 		return nil, errors.NewInvalid("route", route.ID, errs)
72 72
 	}
... ...
@@ -86,7 +86,7 @@ func (rs *REST) Create(obj runtime.Object) (<-chan runtime.Object, error) {
86 86
 }
87 87
 
88 88
 // Update replaces a given Route instance with an existing instance in rs.registry.
89
-func (rs *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
89
+func (rs *REST) Update(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
90 90
 	route, ok := obj.(*api.Route)
91 91
 	if !ok {
92 92
 		return nil, fmt.Errorf("not a route: %#v", obj)
... ...
@@ -109,6 +109,6 @@ func (rs *REST) Update(obj runtime.Object) (<-chan runtime.Object, error) {
109 109
 
110 110
 // Watch returns Routes events via a watch.Interface.
111 111
 // It implements apiserver.ResourceWatcher.
112
-func (rs *REST) Watch(label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
112
+func (rs *REST) Watch(ctx kubeapi.Context, label, field labels.Selector, resourceVersion uint64) (watch.Interface, error) {
113 113
 	return rs.registry.WatchRoutes(label, field, resourceVersion)
114 114
 }
... ...
@@ -6,6 +6,7 @@ import (
6 6
 	"math/rand"
7 7
 	"time"
8 8
 
9
+	kubeapi "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
9 10
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/apiserver"
10 11
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
11 12
 	"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
... ...
@@ -19,33 +20,23 @@ import (
19 19
 type Storage struct{}
20 20
 
21 21
 // NewStorage creates new RESTStorage for the Template objects.
22
-func NewStorage() apiserver.RESTStorage {
22
+func NewStorage() *Storage {
23 23
 	return &Storage{}
24 24
 }
25 25
 
26
-func (s *Storage) List(selector, fields labels.Selector) (runtime.Object, error) {
27
-	return nil, errors.New("template.Storage.List() is not implemented.")
28
-}
29
-
30
-func (s *Storage) Get(id string) (runtime.Object, error) {
31
-	return nil, errors.New("template.Storage.Get() is not implemented.")
32
-}
33
-
34 26
 func (s *Storage) New() runtime.Object {
35 27
 	return &api.Template{}
36 28
 }
37 29
 
38
-func (s *Storage) Delete(id string) (<-chan runtime.Object, error) {
39
-	return apiserver.MakeAsync(func() (runtime.Object, error) {
40
-		return nil, errors.New("template.Storage.Delete() is not implemented.")
41
-	}), nil
30
+func (s *Storage) List(ctx kubeapi.Context, selector, fields labels.Selector) (runtime.Object, error) {
31
+	return nil, errors.New("template.Storage.List() is not implemented.")
42 32
 }
43 33
 
44
-func (s *Storage) Update(minion runtime.Object) (<-chan runtime.Object, error) {
45
-	return nil, errors.New("template.Storage.Update() is not implemented.")
34
+func (s *Storage) Get(ctx kubeapi.Context, id string) (runtime.Object, error) {
35
+	return nil, errors.New("template.Storage.Get() is not implemented.")
46 36
 }
47 37
 
48
-func (s *Storage) Create(obj runtime.Object) (<-chan runtime.Object, error) {
38
+func (s *Storage) Create(ctx kubeapi.Context, obj runtime.Object) (<-chan runtime.Object, error) {
49 39
 	template, ok := obj.(*api.Template)
50 40
 	if !ok {
51 41
 		return nil, errors.New("Not a template config.")
... ...
@@ -62,3 +53,13 @@ func (s *Storage) Create(obj runtime.Object) (<-chan runtime.Object, error) {
62 62
 		return config, err
63 63
 	}), nil
64 64
 }
65
+
66
+func (s *Storage) Update(ctx kubeapi.Context, template runtime.Object) (<-chan runtime.Object, error) {
67
+	return nil, errors.New("template.Storage.Update() is not implemented.")
68
+}
69
+
70
+func (s *Storage) Delete(ctx kubeapi.Context, id string) (<-chan runtime.Object, error) {
71
+	return apiserver.MakeAsync(func() (runtime.Object, error) {
72
+		return nil, errors.New("template.Storage.Delete() is not implemented.")
73
+	}), nil
74
+}