Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
10c2ace6
Commit
10c2ace6
authored
Mar 03, 2015
by
Clayton Coleman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Pod Templates
parent
8b04e7f7
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
443 additions
and
18 deletions
+443
-18
examples_test.go
examples/examples_test.go
+9
-4
podtemplate.json
examples/walkthrough/podtemplate.json
+22
-0
test-cmd.sh
hack/test-cmd.sh
+28
-0
latest_test.go
pkg/api/latest/latest_test.go
+4
-0
register.go
pkg/api/register.go
+4
-0
resttest.go
pkg/api/rest/resttest/resttest.go
+25
-2
serialization_test.go
pkg/api/serialization_test.go
+17
-6
validation.go
pkg/api/validation/validation.go
+18
-0
resource_printer.go
pkg/kubectl/resource_printer.go
+37
-5
master.go
pkg/master/master.go
+18
-0
rest.go
pkg/registry/pod/rest.go
+0
-1
doc.go
pkg/registry/podtemplate/doc.go
+18
-0
etcd.go
pkg/registry/podtemplate/etcd/etcd.go
+63
-0
etcd_test.go
pkg/registry/podtemplate/etcd/etcd_test.go
+99
-0
rest.go
pkg/registry/podtemplate/rest.go
+81
-0
No files found.
examples/examples_test.go
View file @
10c2ace6
...
@@ -34,7 +34,6 @@ import (
...
@@ -34,7 +34,6 @@ import (
)
)
func
validateObject
(
obj
runtime
.
Object
)
(
errors
[]
error
)
{
func
validateObject
(
obj
runtime
.
Object
)
(
errors
[]
error
)
{
ctx
:=
api
.
NewDefaultContext
()
switch
t
:=
obj
.
(
type
)
{
switch
t
:=
obj
.
(
type
)
{
case
*
api
.
ReplicationController
:
case
*
api
.
ReplicationController
:
if
t
.
Namespace
==
""
{
if
t
.
Namespace
==
""
{
...
@@ -49,7 +48,6 @@ func validateObject(obj runtime.Object) (errors []error) {
...
@@ -49,7 +48,6 @@ func validateObject(obj runtime.Object) (errors []error) {
if
t
.
Namespace
==
""
{
if
t
.
Namespace
==
""
{
t
.
Namespace
=
api
.
NamespaceDefault
t
.
Namespace
=
api
.
NamespaceDefault
}
}
api
.
ValidNamespace
(
ctx
,
&
t
.
ObjectMeta
)
errors
=
validation
.
ValidateService
(
t
)
errors
=
validation
.
ValidateService
(
t
)
case
*
api
.
ServiceList
:
case
*
api
.
ServiceList
:
for
i
:=
range
t
.
Items
{
for
i
:=
range
t
.
Items
{
...
@@ -59,7 +57,6 @@ func validateObject(obj runtime.Object) (errors []error) {
...
@@ -59,7 +57,6 @@ func validateObject(obj runtime.Object) (errors []error) {
if
t
.
Namespace
==
""
{
if
t
.
Namespace
==
""
{
t
.
Namespace
=
api
.
NamespaceDefault
t
.
Namespace
=
api
.
NamespaceDefault
}
}
api
.
ValidNamespace
(
ctx
,
&
t
.
ObjectMeta
)
errors
=
validation
.
ValidatePod
(
t
)
errors
=
validation
.
ValidatePod
(
t
)
case
*
api
.
PodList
:
case
*
api
.
PodList
:
for
i
:=
range
t
.
Items
{
for
i
:=
range
t
.
Items
{
...
@@ -68,8 +65,15 @@ func validateObject(obj runtime.Object) (errors []error) {
...
@@ -68,8 +65,15 @@ func validateObject(obj runtime.Object) (errors []error) {
case
*
api
.
PersistentVolume
:
case
*
api
.
PersistentVolume
:
errors
=
validation
.
ValidatePersistentVolume
(
t
)
errors
=
validation
.
ValidatePersistentVolume
(
t
)
case
*
api
.
PersistentVolumeClaim
:
case
*
api
.
PersistentVolumeClaim
:
api
.
ValidNamespace
(
ctx
,
&
t
.
ObjectMeta
)
if
t
.
Namespace
==
""
{
t
.
Namespace
=
api
.
NamespaceDefault
}
errors
=
validation
.
ValidatePersistentVolumeClaim
(
t
)
errors
=
validation
.
ValidatePersistentVolumeClaim
(
t
)
case
*
api
.
PodTemplate
:
if
t
.
Namespace
==
""
{
t
.
Namespace
=
api
.
NamespaceDefault
}
errors
=
validation
.
ValidatePodTemplate
(
t
)
default
:
default
:
return
[]
error
{
fmt
.
Errorf
(
"no validation defined for %#v"
,
obj
)}
return
[]
error
{
fmt
.
Errorf
(
"no validation defined for %#v"
,
obj
)}
}
}
...
@@ -156,6 +160,7 @@ func TestExampleObjectSchemas(t *testing.T) {
...
@@ -156,6 +160,7 @@ func TestExampleObjectSchemas(t *testing.T) {
"pod-with-http-healthcheck"
:
&
api
.
Pod
{},
"pod-with-http-healthcheck"
:
&
api
.
Pod
{},
"service"
:
&
api
.
Service
{},
"service"
:
&
api
.
Service
{},
"replication-controller"
:
&
api
.
ReplicationController
{},
"replication-controller"
:
&
api
.
ReplicationController
{},
"podtemplate"
:
&
api
.
PodTemplate
{},
},
},
"../examples/update-demo"
:
{
"../examples/update-demo"
:
{
"kitten-rc"
:
&
api
.
ReplicationController
{},
"kitten-rc"
:
&
api
.
ReplicationController
{},
...
...
examples/walkthrough/podtemplate.json
0 → 100644
View file @
10c2ace6
{
"apiVersion"
:
"v1beta3"
,
"kind"
:
"PodTemplate"
,
"metadata"
:
{
"name"
:
"nginx"
},
"spec"
:
{
"metadata"
:
{
"labels"
:
{
"name"
:
"nginx"
},
"generateName"
:
"nginx-"
},
"spec"
:
{
"containers"
:
[{
"name"
:
"nginx"
,
"image"
:
"dockerfile/nginx"
,
"ports"
:
[{
"containerPort"
:
80
}]
}]
}
}
}
hack/test-cmd.sh
View file @
10c2ace6
...
@@ -358,6 +358,34 @@ for version in "${kube_api_versions[@]}"; do
...
@@ -358,6 +358,34 @@ for version in "${kube_api_versions[@]}"; do
kube::test::get_object_assert
'pods --namespace=other'
"{{range.items}}{{
$id_field
}}:{{end}}"
''
kube::test::get_object_assert
'pods --namespace=other'
"{{range.items}}{{
$id_field
}}:{{end}}"
''
#################
# Pod templates #
#################
# Note: pod templates exist only in v1beta3 and above, so output will always be in that form
### Create PODTEMPLATE
# Pre-condition: no PODTEMPLATE
kube::test::get_object_assert podtemplates
"{{range.items}}{{.metadata.name}}:{{end}}"
''
# Command
kubectl create
-f
examples/walkthrough/podtemplate.json
"
${
kube_flags
[@]
}
"
# Post-condition: nginx PODTEMPLATE is available
kube::test::get_object_assert podtemplates
"{{range.items}}{{.metadata.name}}:{{end}}"
'nginx:'
### Printing pod templates works
kubectl get podtemplates
"
${
kube_flags
[@]
}
"
### Display of an object which doesn't existing in v1beta1 and v1beta2 works
[[
"
$(
kubectl get podtemplates
-o
yaml
"
${
kube_flags
[@]
}
"
|
grep
nginx
)
"
]]
### Delete nginx pod template by name
# Pre-condition: nginx pod template is available
kube::test::get_object_assert podtemplates
"{{range.items}}{{.metadata.name}}:{{end}}"
'nginx:'
# Command
kubectl delete podtemplate nginx
"
${
kube_flags
[@]
}
"
# Post-condition: No templates exist
kube::test::get_object_assert podtemplate
"{{range.items}}{{.metadata.name}}:{{end}}"
''
############
############
# Services #
# Services #
############
############
...
...
pkg/api/latest/latest_test.go
View file @
10c2ace6
...
@@ -80,6 +80,10 @@ func TestRESTMapper(t *testing.T) {
...
@@ -80,6 +80,10 @@ func TestRESTMapper(t *testing.T) {
t
.
Errorf
(
"unexpected version mapping: %s %s %v"
,
v
,
k
,
err
)
t
.
Errorf
(
"unexpected version mapping: %s %s %v"
,
v
,
k
,
err
)
}
}
if
m
,
err
:=
RESTMapper
.
RESTMapping
(
"PodTemplate"
,
""
);
err
!=
nil
||
m
.
APIVersion
!=
"v1beta3"
||
m
.
Resource
!=
"podtemplates"
{
t
.
Errorf
(
"unexpected version mapping: %#v %v"
,
m
,
err
)
}
for
_
,
version
:=
range
Versions
{
for
_
,
version
:=
range
Versions
{
mapping
,
err
:=
RESTMapper
.
RESTMapping
(
"ReplicationController"
,
version
)
mapping
,
err
:=
RESTMapper
.
RESTMapping
(
"ReplicationController"
,
version
)
if
err
!=
nil
{
if
err
!=
nil
{
...
...
pkg/api/register.go
View file @
10c2ace6
...
@@ -28,6 +28,8 @@ func init() {
...
@@ -28,6 +28,8 @@ func init() {
&
Pod
{},
&
Pod
{},
&
PodList
{},
&
PodList
{},
&
PodStatusResult
{},
&
PodStatusResult
{},
&
PodTemplate
{},
&
PodTemplateList
{},
&
ReplicationControllerList
{},
&
ReplicationControllerList
{},
&
ReplicationController
{},
&
ReplicationController
{},
&
ServiceList
{},
&
ServiceList
{},
...
@@ -71,6 +73,8 @@ func init() {
...
@@ -71,6 +73,8 @@ func init() {
func
(
*
Pod
)
IsAnAPIObject
()
{}
func
(
*
Pod
)
IsAnAPIObject
()
{}
func
(
*
PodList
)
IsAnAPIObject
()
{}
func
(
*
PodList
)
IsAnAPIObject
()
{}
func
(
*
PodStatusResult
)
IsAnAPIObject
()
{}
func
(
*
PodStatusResult
)
IsAnAPIObject
()
{}
func
(
*
PodTemplate
)
IsAnAPIObject
()
{}
func
(
*
PodTemplateList
)
IsAnAPIObject
()
{}
func
(
*
ReplicationController
)
IsAnAPIObject
()
{}
func
(
*
ReplicationController
)
IsAnAPIObject
()
{}
func
(
*
ReplicationControllerList
)
IsAnAPIObject
()
{}
func
(
*
ReplicationControllerList
)
IsAnAPIObject
()
{}
func
(
*
Service
)
IsAnAPIObject
()
{}
func
(
*
Service
)
IsAnAPIObject
()
{}
...
...
pkg/api/rest/resttest/resttest.go
View file @
10c2ace6
...
@@ -179,7 +179,7 @@ func (t *Tester) TestCreateRejectsMismatchedNamespace(valid runtime.Object) {
...
@@ -179,7 +179,7 @@ func (t *Tester) TestCreateRejectsMismatchedNamespace(valid runtime.Object) {
if
err
==
nil
{
if
err
==
nil
{
t
.
Errorf
(
"Expected an error, but we didn't get one"
)
t
.
Errorf
(
"Expected an error, but we didn't get one"
)
}
else
if
strings
.
Contains
(
err
.
Error
(),
"Controller.Namespace does not match the provided context"
)
{
}
else
if
strings
.
Contains
(
err
.
Error
(),
"Controller.Namespace does not match the provided context"
)
{
t
.
Errorf
(
"Expected 'Controller.Namespace does not match the provided context' error, got '%v'"
,
err
.
Error
()
)
t
.
Errorf
(
"Expected 'Controller.Namespace does not match the provided context' error, got '%v'"
,
err
)
}
}
}
}
...
@@ -195,7 +195,30 @@ func (t *Tester) TestCreateRejectsNamespace(valid runtime.Object) {
...
@@ -195,7 +195,30 @@ func (t *Tester) TestCreateRejectsNamespace(valid runtime.Object) {
if
err
==
nil
{
if
err
==
nil
{
t
.
Errorf
(
"Expected an error, but we didn't get one"
)
t
.
Errorf
(
"Expected an error, but we didn't get one"
)
}
else
if
strings
.
Contains
(
err
.
Error
(),
"Controller.Namespace does not match the provided context"
)
{
}
else
if
strings
.
Contains
(
err
.
Error
(),
"Controller.Namespace does not match the provided context"
)
{
t
.
Errorf
(
"Expected 'Controller.Namespace does not match the provided context' error, got '%v'"
,
err
.
Error
())
t
.
Errorf
(
"Expected 'Controller.Namespace does not match the provided context' error, got '%v'"
,
err
)
}
}
func
(
t
*
Tester
)
TestUpdate
(
valid
runtime
.
Object
,
existing
,
older
runtime
.
Object
)
{
t
.
TestUpdateFailsOnNotFound
(
copyOrDie
(
valid
))
t
.
TestUpdateFailsOnVersion
(
copyOrDie
(
older
))
}
func
(
t
*
Tester
)
TestUpdateFailsOnNotFound
(
valid
runtime
.
Object
)
{
_
,
_
,
err
:=
t
.
storage
.
(
rest
.
Updater
)
.
Update
(
api
.
NewDefaultContext
(),
valid
)
if
err
==
nil
{
t
.
Errorf
(
"Expected an error, but we didn't get one"
)
}
else
if
!
errors
.
IsNotFound
(
err
)
{
t
.
Errorf
(
"Expected NotFound error, got '%v'"
,
err
)
}
}
func
(
t
*
Tester
)
TestUpdateFailsOnVersion
(
older
runtime
.
Object
)
{
_
,
_
,
err
:=
t
.
storage
.
(
rest
.
Updater
)
.
Update
(
api
.
NewDefaultContext
(),
older
)
if
err
==
nil
{
t
.
Errorf
(
"Expected an error, but we didn't get one"
)
}
else
if
!
errors
.
IsConflict
(
err
)
{
t
.
Errorf
(
"Expected Conflict error, got '%v'"
,
err
)
}
}
}
}
...
...
pkg/api/serialization_test.go
View file @
10c2ace6
...
@@ -85,13 +85,20 @@ func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) {
...
@@ -85,13 +85,20 @@ func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) {
}
}
// roundTripSame verifies the same source object is tested in all API versions.
// roundTripSame verifies the same source object is tested in all API versions.
func
roundTripSame
(
t
*
testing
.
T
,
item
runtime
.
Object
)
{
func
roundTripSame
(
t
*
testing
.
T
,
item
runtime
.
Object
,
except
...
string
)
{
set
:=
util
.
NewStringSet
(
except
...
)
seed
:=
rand
.
Int63
()
seed
:=
rand
.
Int63
()
fuzzInternalObject
(
t
,
""
,
item
,
seed
)
fuzzInternalObject
(
t
,
""
,
item
,
seed
)
roundTrip
(
t
,
v1beta1
.
Codec
,
item
)
if
!
set
.
Has
(
"v1beta1"
)
{
roundTrip
(
t
,
v1beta2
.
Codec
,
item
)
roundTrip
(
t
,
v1beta1
.
Codec
,
item
)
fuzzInternalObject
(
t
,
"v1beta3"
,
item
,
seed
)
}
roundTrip
(
t
,
v1beta3
.
Codec
,
item
)
if
!
set
.
Has
(
"v1beta2"
)
{
roundTrip
(
t
,
v1beta2
.
Codec
,
item
)
}
if
!
set
.
Has
(
"v1beta3"
)
{
fuzzInternalObject
(
t
,
"v1beta3"
,
item
,
seed
)
roundTrip
(
t
,
v1beta3
.
Codec
,
item
)
}
}
}
func
roundTripAll
(
t
*
testing
.
T
,
item
runtime
.
Object
)
{
func
roundTripAll
(
t
*
testing
.
T
,
item
runtime
.
Object
)
{
...
@@ -130,6 +137,10 @@ func TestList(t *testing.T) {
...
@@ -130,6 +137,10 @@ func TestList(t *testing.T) {
var
nonRoundTrippableTypes
=
util
.
NewStringSet
(
"ContainerManifest"
,
"ContainerManifestList"
)
var
nonRoundTrippableTypes
=
util
.
NewStringSet
(
"ContainerManifest"
,
"ContainerManifestList"
)
var
nonInternalRoundTrippableTypes
=
util
.
NewStringSet
(
"List"
,
"ListOptions"
,
"PodExecOptions"
)
var
nonInternalRoundTrippableTypes
=
util
.
NewStringSet
(
"List"
,
"ListOptions"
,
"PodExecOptions"
)
var
nonRoundTrippableTypesByVersion
=
map
[
string
][]
string
{
"PodTemplate"
:
{
"v1beta1"
,
"v1beta2"
},
"PodTemplateList"
:
{
"v1beta1"
,
"v1beta2"
},
}
func
TestRoundTripTypes
(
t
*
testing
.
T
)
{
func
TestRoundTripTypes
(
t
*
testing
.
T
)
{
// api.Scheme.Log(t)
// api.Scheme.Log(t)
...
@@ -148,7 +159,7 @@ func TestRoundTripTypes(t *testing.T) {
...
@@ -148,7 +159,7 @@ func TestRoundTripTypes(t *testing.T) {
if
_
,
err
:=
meta
.
TypeAccessor
(
item
);
err
!=
nil
{
if
_
,
err
:=
meta
.
TypeAccessor
(
item
);
err
!=
nil
{
t
.
Fatalf
(
"%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v"
,
kind
,
err
)
t
.
Fatalf
(
"%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v"
,
kind
,
err
)
}
}
roundTripSame
(
t
,
item
)
roundTripSame
(
t
,
item
,
nonRoundTrippableTypesByVersion
[
kind
]
...
)
if
!
nonInternalRoundTrippableTypes
.
Has
(
kind
)
{
if
!
nonInternalRoundTrippableTypes
.
Has
(
kind
)
{
roundTrip
(
t
,
api
.
Codec
,
fuzzInternalObject
(
t
,
""
,
item
,
rand
.
Int63
()))
roundTrip
(
t
,
api
.
Codec
,
fuzzInternalObject
(
t
,
""
,
item
,
rand
.
Int63
()))
}
}
...
...
pkg/api/validation/validation.go
View file @
10c2ace6
...
@@ -888,6 +888,24 @@ func ValidatePodStatusUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList {
...
@@ -888,6 +888,24 @@ func ValidatePodStatusUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList {
return
allErrs
return
allErrs
}
}
// ValidatePodTemplate tests if required fields in the pod template are set.
func
ValidatePodTemplate
(
pod
*
api
.
PodTemplate
)
errs
.
ValidationErrorList
{
allErrs
:=
errs
.
ValidationErrorList
{}
allErrs
=
append
(
allErrs
,
ValidateObjectMeta
(
&
pod
.
ObjectMeta
,
true
,
ValidatePodName
)
.
Prefix
(
"metadata"
)
...
)
allErrs
=
append
(
allErrs
,
ValidatePodTemplateSpec
(
&
pod
.
Spec
,
0
)
.
Prefix
(
"spec"
)
...
)
return
allErrs
}
// ValidatePodTemplateUpdate tests to see if the update is legal for an end user to make. newPod is updated with fields
// that cannot be changed.
func
ValidatePodTemplateUpdate
(
newPod
,
oldPod
*
api
.
PodTemplate
)
errs
.
ValidationErrorList
{
allErrs
:=
errs
.
ValidationErrorList
{}
allErrs
=
append
(
allErrs
,
ValidateObjectMetaUpdate
(
&
oldPod
.
ObjectMeta
,
&
newPod
.
ObjectMeta
)
.
Prefix
(
"metadata"
)
...
)
allErrs
=
append
(
allErrs
,
ValidatePodTemplateSpec
(
&
newPod
.
Spec
,
0
)
.
Prefix
(
"spec"
)
...
)
return
allErrs
}
var
supportedSessionAffinityType
=
util
.
NewStringSet
(
string
(
api
.
AffinityTypeClientIP
),
string
(
api
.
AffinityTypeNone
))
var
supportedSessionAffinityType
=
util
.
NewStringSet
(
string
(
api
.
AffinityTypeClientIP
),
string
(
api
.
AffinityTypeNone
))
// ValidateService tests if required fields in the service are set.
// ValidateService tests if required fields in the service are set.
...
...
pkg/kubectl/resource_printer.go
View file @
10c2ace6
...
@@ -245,6 +245,7 @@ func (h *HumanReadablePrinter) HandledResources() []string {
...
@@ -245,6 +245,7 @@ func (h *HumanReadablePrinter) HandledResources() []string {
}
}
var
podColumns
=
[]
string
{
"POD"
,
"IP"
,
"CONTAINER(S)"
,
"IMAGE(S)"
,
"HOST"
,
"LABELS"
,
"STATUS"
,
"CREATED"
,
"MESSAGE"
}
var
podColumns
=
[]
string
{
"POD"
,
"IP"
,
"CONTAINER(S)"
,
"IMAGE(S)"
,
"HOST"
,
"LABELS"
,
"STATUS"
,
"CREATED"
,
"MESSAGE"
}
var
podTemplateColumns
=
[]
string
{
"TEMPLATE"
,
"CONTAINER(S)"
,
"IMAGE(S)"
,
"PODLABELS"
}
var
replicationControllerColumns
=
[]
string
{
"CONTROLLER"
,
"CONTAINER(S)"
,
"IMAGE(S)"
,
"SELECTOR"
,
"REPLICAS"
}
var
replicationControllerColumns
=
[]
string
{
"CONTROLLER"
,
"CONTAINER(S)"
,
"IMAGE(S)"
,
"SELECTOR"
,
"REPLICAS"
}
var
serviceColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"SELECTOR"
,
"IP"
,
"PORT(S)"
}
var
serviceColumns
=
[]
string
{
"NAME"
,
"LABELS"
,
"SELECTOR"
,
"IP"
,
"PORT(S)"
}
var
endpointColumns
=
[]
string
{
"NAME"
,
"ENDPOINTS"
}
var
endpointColumns
=
[]
string
{
"NAME"
,
"ENDPOINTS"
}
...
@@ -263,6 +264,8 @@ var componentStatusColumns = []string{"NAME", "STATUS", "MESSAGE", "ERROR"}
...
@@ -263,6 +264,8 @@ var componentStatusColumns = []string{"NAME", "STATUS", "MESSAGE", "ERROR"}
func
(
h
*
HumanReadablePrinter
)
addDefaultHandlers
()
{
func
(
h
*
HumanReadablePrinter
)
addDefaultHandlers
()
{
h
.
Handler
(
podColumns
,
printPod
)
h
.
Handler
(
podColumns
,
printPod
)
h
.
Handler
(
podColumns
,
printPodList
)
h
.
Handler
(
podColumns
,
printPodList
)
h
.
Handler
(
podTemplateColumns
,
printPodTemplate
)
h
.
Handler
(
podTemplateColumns
,
printPodTemplateList
)
h
.
Handler
(
replicationControllerColumns
,
printReplicationController
)
h
.
Handler
(
replicationControllerColumns
,
printReplicationController
)
h
.
Handler
(
replicationControllerColumns
,
printReplicationControllerList
)
h
.
Handler
(
replicationControllerColumns
,
printReplicationControllerList
)
h
.
Handler
(
serviceColumns
,
printService
)
h
.
Handler
(
serviceColumns
,
printService
)
...
@@ -383,11 +386,6 @@ func interpretContainerStatus(status *api.ContainerStatus) (string, string, stri
...
@@ -383,11 +386,6 @@ func interpretContainerStatus(status *api.ContainerStatus) (string, string, stri
}
}
func
printPod
(
pod
*
api
.
Pod
,
w
io
.
Writer
)
error
{
func
printPod
(
pod
*
api
.
Pod
,
w
io
.
Writer
)
error
{
// TODO: remove me when pods are converted
spec
:=
&
api
.
PodSpec
{}
if
err
:=
api
.
Scheme
.
Convert
(
&
pod
.
Spec
,
spec
);
err
!=
nil
{
glog
.
Errorf
(
"Unable to convert pod manifest: %v"
,
err
)
}
_
,
err
:=
fmt
.
Fprintf
(
w
,
"%s
\t
%s
\t
%s
\t
%s
\t
%s
\t
%s
\t
%s
\t
%s
\t
%s
\n
"
,
_
,
err
:=
fmt
.
Fprintf
(
w
,
"%s
\t
%s
\t
%s
\t
%s
\t
%s
\t
%s
\t
%s
\t
%s
\t
%s
\n
"
,
pod
.
Name
,
pod
.
Name
,
pod
.
Status
.
PodIP
,
pod
.
Status
.
PodIP
,
...
@@ -447,6 +445,40 @@ func printPodList(podList *api.PodList, w io.Writer) error {
...
@@ -447,6 +445,40 @@ func printPodList(podList *api.PodList, w io.Writer) error {
return
nil
return
nil
}
}
func
printPodTemplate
(
pod
*
api
.
PodTemplate
,
w
io
.
Writer
)
error
{
containers
:=
pod
.
Spec
.
Spec
.
Containers
var
firstContainer
api
.
Container
if
len
(
containers
)
>
0
{
firstContainer
,
containers
=
containers
[
0
],
containers
[
1
:
]
}
_
,
err
:=
fmt
.
Fprintf
(
w
,
"%s
\t
%s
\t
%s
\t
%s
\n
"
,
pod
.
Name
,
firstContainer
.
Name
,
firstContainer
.
Image
,
formatLabels
(
pod
.
Spec
.
Labels
),
)
if
err
!=
nil
{
return
err
}
// Lay out all the other containers on separate lines.
for
_
,
container
:=
range
containers
{
_
,
err
:=
fmt
.
Fprintf
(
w
,
"%s
\t
%s
\t
%s
\t
%s
\n
"
,
""
,
container
.
Name
,
container
.
Image
,
""
)
if
err
!=
nil
{
return
err
}
}
return
nil
}
func
printPodTemplateList
(
podList
*
api
.
PodTemplateList
,
w
io
.
Writer
)
error
{
for
_
,
pod
:=
range
podList
.
Items
{
if
err
:=
printPodTemplate
(
&
pod
,
w
);
err
!=
nil
{
return
err
}
}
return
nil
}
func
printReplicationController
(
controller
*
api
.
ReplicationController
,
w
io
.
Writer
)
error
{
func
printReplicationController
(
controller
*
api
.
ReplicationController
,
w
io
.
Writer
)
error
{
containers
:=
controller
.
Spec
.
Template
.
Spec
.
Containers
containers
:=
controller
.
Spec
.
Template
.
Spec
.
Containers
var
firstContainer
api
.
Container
var
firstContainer
api
.
Container
...
...
pkg/master/master.go
View file @
10c2ace6
...
@@ -58,6 +58,7 @@ import (
...
@@ -58,6 +58,7 @@ import (
pvcetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/persistentvolumeclaim/etcd"
pvcetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/persistentvolumeclaim/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod"
podetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/etcd"
podetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/pod/etcd"
podtemplateetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/podtemplate/etcd"
resourcequotaetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/etcd"
resourcequotaetcd
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/resourcequota/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/secret"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/secret"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/service"
...
@@ -360,9 +361,18 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter)
...
@@ -360,9 +361,18 @@ func logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter)
// init initializes master.
// init initializes master.
func
(
m
*
Master
)
init
(
c
*
Config
)
{
func
(
m
*
Master
)
init
(
c
*
Config
)
{
// TODO: make initialization of the helper part of the Master, and allow some storage
// objects to have a newer storage version than the user's default.
newerHelper
,
err
:=
NewEtcdHelper
(
c
.
EtcdHelper
.
Client
,
"v1beta3"
)
if
err
!=
nil
{
glog
.
Fatalf
(
"Unable to setup storage for v1beta3: %v"
,
err
)
}
podStorage
:=
podetcd
.
NewStorage
(
c
.
EtcdHelper
,
c
.
KubeletClient
)
podStorage
:=
podetcd
.
NewStorage
(
c
.
EtcdHelper
,
c
.
KubeletClient
)
podRegistry
:=
pod
.
NewRegistry
(
podStorage
.
Pod
)
podRegistry
:=
pod
.
NewRegistry
(
podStorage
.
Pod
)
podTemplateStorage
:=
podtemplateetcd
.
NewREST
(
newerHelper
)
eventRegistry
:=
event
.
NewEtcdRegistry
(
c
.
EtcdHelper
,
uint64
(
c
.
EventTTL
.
Seconds
()))
eventRegistry
:=
event
.
NewEtcdRegistry
(
c
.
EtcdHelper
,
uint64
(
c
.
EventTTL
.
Seconds
()))
limitRangeRegistry
:=
limitrange
.
NewEtcdRegistry
(
c
.
EtcdHelper
)
limitRangeRegistry
:=
limitrange
.
NewEtcdRegistry
(
c
.
EtcdHelper
)
...
@@ -397,6 +407,8 @@ func (m *Master) init(c *Config) {
...
@@ -397,6 +407,8 @@ func (m *Master) init(c *Config) {
"pods/binding"
:
podStorage
.
Binding
,
"pods/binding"
:
podStorage
.
Binding
,
"bindings"
:
podStorage
.
Binding
,
"bindings"
:
podStorage
.
Binding
,
"podTemplates"
:
podTemplateStorage
,
"replicationControllers"
:
controllerStorage
,
"replicationControllers"
:
controllerStorage
,
"services"
:
service
.
NewStorage
(
m
.
serviceRegistry
,
m
.
nodeRegistry
,
m
.
endpointRegistry
,
m
.
portalNet
,
c
.
ClusterName
),
"services"
:
service
.
NewStorage
(
m
.
serviceRegistry
,
m
.
nodeRegistry
,
m
.
endpointRegistry
,
m
.
portalNet
,
c
.
ClusterName
),
"endpoints"
:
endpointsStorage
,
"endpoints"
:
endpointsStorage
,
...
@@ -606,6 +618,9 @@ func (m *Master) defaultAPIGroupVersion() *apiserver.APIGroupVersion {
...
@@ -606,6 +618,9 @@ func (m *Master) defaultAPIGroupVersion() *apiserver.APIGroupVersion {
func
(
m
*
Master
)
api_v1beta1
()
*
apiserver
.
APIGroupVersion
{
func
(
m
*
Master
)
api_v1beta1
()
*
apiserver
.
APIGroupVersion
{
storage
:=
make
(
map
[
string
]
rest
.
Storage
)
storage
:=
make
(
map
[
string
]
rest
.
Storage
)
for
k
,
v
:=
range
m
.
storage
{
for
k
,
v
:=
range
m
.
storage
{
if
k
==
"podTemplates"
{
continue
}
storage
[
k
]
=
v
storage
[
k
]
=
v
}
}
version
:=
m
.
defaultAPIGroupVersion
()
version
:=
m
.
defaultAPIGroupVersion
()
...
@@ -619,6 +634,9 @@ func (m *Master) api_v1beta1() *apiserver.APIGroupVersion {
...
@@ -619,6 +634,9 @@ func (m *Master) api_v1beta1() *apiserver.APIGroupVersion {
func
(
m
*
Master
)
api_v1beta2
()
*
apiserver
.
APIGroupVersion
{
func
(
m
*
Master
)
api_v1beta2
()
*
apiserver
.
APIGroupVersion
{
storage
:=
make
(
map
[
string
]
rest
.
Storage
)
storage
:=
make
(
map
[
string
]
rest
.
Storage
)
for
k
,
v
:=
range
m
.
storage
{
for
k
,
v
:=
range
m
.
storage
{
if
k
==
"podTemplates"
{
continue
}
storage
[
k
]
=
v
storage
[
k
]
=
v
}
}
version
:=
m
.
defaultAPIGroupVersion
()
version
:=
m
.
defaultAPIGroupVersion
()
...
...
pkg/registry/pod/rest.go
View file @
10c2ace6
...
@@ -35,7 +35,6 @@ import (
...
@@ -35,7 +35,6 @@ import (
)
)
// podStrategy implements behavior for Pods
// podStrategy implements behavior for Pods
// TODO: move to a pod specific package.
type
podStrategy
struct
{
type
podStrategy
struct
{
runtime
.
ObjectTyper
runtime
.
ObjectTyper
api
.
NameGenerator
api
.
NameGenerator
...
...
pkg/registry/podtemplate/doc.go
0 → 100644
View file @
10c2ace6
/*
Copyright 2014 Google Inc. All rights reserved.
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 podtemplate provides RESTStorage implementations for storing PodTemplate API objects.
package
podtemplate
pkg/registry/podtemplate/etcd/etcd.go
0 → 100644
View file @
10c2ace6
/*
Copyright 2014 Google Inc. All rights reserved.
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
etcd
import
(
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
etcdgeneric
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic/etcd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/podtemplate"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
)
// rest implements a RESTStorage for pod templates against etcd
type
REST
struct
{
etcdgeneric
.
Etcd
}
// NewREST returns a RESTStorage object that will work against pod templates.
func
NewREST
(
h
tools
.
EtcdHelper
)
*
REST
{
prefix
:=
"/registry/podtemplates"
store
:=
etcdgeneric
.
Etcd
{
NewFunc
:
func
()
runtime
.
Object
{
return
&
api
.
PodTemplate
{}
},
NewListFunc
:
func
()
runtime
.
Object
{
return
&
api
.
PodTemplateList
{}
},
KeyRootFunc
:
func
(
ctx
api
.
Context
)
string
{
return
etcdgeneric
.
NamespaceKeyRootFunc
(
ctx
,
prefix
)
},
KeyFunc
:
func
(
ctx
api
.
Context
,
name
string
)
(
string
,
error
)
{
return
etcdgeneric
.
NamespaceKeyFunc
(
ctx
,
prefix
,
name
)
},
ObjectNameFunc
:
func
(
obj
runtime
.
Object
)
(
string
,
error
)
{
return
obj
.
(
*
api
.
PodTemplate
)
.
Name
,
nil
},
PredicateFunc
:
func
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
podtemplate
.
MatchPodTemplate
(
label
,
field
)
},
EndpointName
:
"podtemplates"
,
CreateStrategy
:
podtemplate
.
Strategy
,
UpdateStrategy
:
podtemplate
.
Strategy
,
ReturnDeletedObject
:
true
,
Helper
:
h
,
}
return
&
REST
{
store
}
}
pkg/registry/podtemplate/etcd/etcd_test.go
0 → 100644
View file @
10c2ace6
/*
Copyright 2014 Google Inc. All rights reserved.
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
etcd
import
(
"testing"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/rest/resttest"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/v1beta3"
"github.com/GoogleCloudPlatform/kubernetes/pkg/tools"
)
func
newHelper
(
t
*
testing
.
T
)
(
*
tools
.
FakeEtcdClient
,
tools
.
EtcdHelper
)
{
fakeEtcdClient
:=
tools
.
NewFakeEtcdClient
(
t
)
fakeEtcdClient
.
TestIndex
=
true
helper
:=
tools
.
NewEtcdHelper
(
fakeEtcdClient
,
v1beta3
.
Codec
)
return
fakeEtcdClient
,
helper
}
func
validNewPodTemplate
(
name
string
)
*
api
.
PodTemplate
{
return
&
api
.
PodTemplate
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
name
,
Namespace
:
api
.
NamespaceDefault
,
},
Spec
:
api
.
PodTemplateSpec
{
ObjectMeta
:
api
.
ObjectMeta
{
Labels
:
map
[
string
]
string
{
"test"
:
"foo"
},
},
Spec
:
api
.
PodSpec
{
RestartPolicy
:
api
.
RestartPolicyAlways
,
DNSPolicy
:
api
.
DNSClusterFirst
,
Containers
:
[]
api
.
Container
{
{
Name
:
"foo"
,
Image
:
"test"
,
ImagePullPolicy
:
api
.
PullAlways
,
TerminationMessagePath
:
api
.
TerminationMessagePathDefault
,
},
},
},
},
}
}
func
TestCreate
(
t
*
testing
.
T
)
{
fakeEtcdClient
,
helper
:=
newHelper
(
t
)
storage
:=
NewREST
(
helper
)
test
:=
resttest
.
New
(
t
,
storage
,
fakeEtcdClient
.
SetError
)
pod
:=
validNewPodTemplate
(
"foo"
)
pod
.
ObjectMeta
=
api
.
ObjectMeta
{}
test
.
TestCreate
(
// valid
pod
,
// invalid
&
api
.
PodTemplate
{
Spec
:
api
.
PodTemplateSpec
{},
},
)
}
func
TestUpdate
(
t
*
testing
.
T
)
{
fakeEtcdClient
,
helper
:=
newHelper
(
t
)
storage
:=
NewREST
(
helper
)
test
:=
resttest
.
New
(
t
,
storage
,
fakeEtcdClient
.
SetError
)
fakeEtcdClient
.
ExpectNotFoundGet
(
"/registry/podtemplates/default/foo"
)
fakeEtcdClient
.
ChangeIndex
=
2
pod
:=
validNewPodTemplate
(
"foo"
)
existing
:=
validNewPodTemplate
(
"exists"
)
obj
,
err
:=
storage
.
Create
(
api
.
NewDefaultContext
(),
existing
)
if
err
!=
nil
{
t
.
Fatalf
(
"unable to create object: %v"
,
err
)
}
older
:=
obj
.
(
*
api
.
PodTemplate
)
older
.
ResourceVersion
=
"1"
test
.
TestUpdate
(
pod
,
existing
,
older
,
)
}
pkg/registry/podtemplate/rest.go
0 → 100644
View file @
10c2ace6
/*
Copyright 2014 Google Inc. All rights reserved.
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
podtemplate
import
(
"fmt"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/validation"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
"github.com/GoogleCloudPlatform/kubernetes/pkg/registry/generic"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
errs
"github.com/GoogleCloudPlatform/kubernetes/pkg/util/fielderrors"
)
// podTemplateStrategy implements behavior for PodTemplates
type
podTemplateStrategy
struct
{
runtime
.
ObjectTyper
api
.
NameGenerator
}
// Strategy is the default logic that applies when creating and updating PodTemplate
// objects via the REST API.
var
Strategy
=
podTemplateStrategy
{
api
.
Scheme
,
api
.
SimpleNameGenerator
}
// NamespaceScoped is true for pod templates.
func
(
podTemplateStrategy
)
NamespaceScoped
()
bool
{
return
true
}
// PrepareForCreate clears fields that are not allowed to be set by end users on creation.
func
(
podTemplateStrategy
)
PrepareForCreate
(
obj
runtime
.
Object
)
{
_
=
obj
.
(
*
api
.
PodTemplate
)
}
// Validate validates a new pod template.
func
(
podTemplateStrategy
)
Validate
(
ctx
api
.
Context
,
obj
runtime
.
Object
)
errs
.
ValidationErrorList
{
pod
:=
obj
.
(
*
api
.
PodTemplate
)
return
validation
.
ValidatePodTemplate
(
pod
)
}
// AllowCreateOnUpdate is false for pod templates.
func
(
podTemplateStrategy
)
AllowCreateOnUpdate
()
bool
{
return
false
}
// PrepareForUpdate clears fields that are not allowed to be set by end users on update.
func
(
podTemplateStrategy
)
PrepareForUpdate
(
obj
,
old
runtime
.
Object
)
{
_
=
obj
.
(
*
api
.
PodTemplate
)
}
// ValidateUpdate is the default update validation for an end user.
func
(
podTemplateStrategy
)
ValidateUpdate
(
ctx
api
.
Context
,
obj
,
old
runtime
.
Object
)
errs
.
ValidationErrorList
{
return
validation
.
ValidatePodTemplateUpdate
(
obj
.
(
*
api
.
PodTemplate
),
old
.
(
*
api
.
PodTemplate
))
}
// MatchPodTemplate returns a generic matcher for a given label and field selector.
func
MatchPodTemplate
(
label
labels
.
Selector
,
field
fields
.
Selector
)
generic
.
Matcher
{
return
generic
.
MatcherFunc
(
func
(
obj
runtime
.
Object
)
(
bool
,
error
)
{
podObj
,
ok
:=
obj
.
(
*
api
.
PodTemplate
)
if
!
ok
{
return
false
,
fmt
.
Errorf
(
"not a pod template"
)
}
return
label
.
Matches
(
labels
.
Set
(
podObj
.
Labels
)),
nil
})
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment