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
af31a202
Unverified
Commit
af31a202
authored
Jan 17, 2019
by
Kubernetes Prow Robot
Committed by
GitHub
Jan 17, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #72276 from vithati/users/vithati/kubectlissue503
Allow setting images for 'InitContainers' through kubectl set command.
parents
9cc39a56
f72072cd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
225 additions
and
31 deletions
+225
-31
set_image.go
pkg/kubectl/cmd/set/set_image.go
+22
-31
set_image_test.go
pkg/kubectl/cmd/set/set_image_test.go
+203
-0
No files found.
pkg/kubectl/cmd/set/set_image.go
View file @
af31a202
...
...
@@ -216,38 +216,20 @@ func (o *SetImageOptions) Run() error {
allErrs
:=
[]
error
{}
patches
:=
CalculatePatches
(
o
.
Infos
,
scheme
.
DefaultJSONEncoder
(),
func
(
obj
runtime
.
Object
)
([]
byte
,
error
)
{
transformed
:=
false
_
,
err
:=
o
.
UpdatePodSpecForObject
(
obj
,
func
(
spec
*
v1
.
PodSpec
)
error
{
for
name
,
image
:=
range
o
.
ContainerImages
{
var
(
containerFound
bool
err
error
resolved
string
)
// Find the container to update, and update its image
for
i
,
c
:=
range
spec
.
Containers
{
if
c
.
Name
==
name
||
name
==
"*"
{
containerFound
=
true
if
len
(
resolved
)
==
0
{
if
resolved
,
err
=
o
.
ResolveImage
(
image
);
err
!=
nil
{
allErrs
=
append
(
allErrs
,
fmt
.
Errorf
(
"error: unable to resolve image %q for container %q: %v"
,
image
,
name
,
err
))
// Do not loop again if the image resolving failed for wildcard case as we
// will report the same error again for the next container.
if
name
==
"*"
{
break
}
continue
}
}
if
spec
.
Containers
[
i
]
.
Image
!=
resolved
{
spec
.
Containers
[
i
]
.
Image
=
resolved
// Perform updates
transformed
=
true
}
resolvedImageName
,
err
:=
o
.
ResolveImage
(
image
)
if
err
!=
nil
{
allErrs
=
append
(
allErrs
,
fmt
.
Errorf
(
"error: unable to resolve image %q for container %q: %v"
,
image
,
name
,
err
))
if
name
==
"*"
{
break
}
continue
}
// Add a new container if not found
if
!
containerFound
{
initContainerFound
:=
setImage
(
spec
.
InitContainers
,
name
,
resolvedImageName
)
containerFound
:=
setImage
(
spec
.
Containers
,
name
,
resolvedImageName
)
if
!
containerFound
&&
!
initContainerFound
{
allErrs
=
append
(
allErrs
,
fmt
.
Errorf
(
"error: unable to find container named %q"
,
name
))
}
}
...
...
@@ -256,9 +238,6 @@ func (o *SetImageOptions) Run() error {
if
err
!=
nil
{
return
nil
,
err
}
if
!
transformed
{
return
nil
,
nil
}
// record this change (for rollout history)
if
err
:=
o
.
Recorder
.
Record
(
obj
);
err
!=
nil
{
klog
.
V
(
4
)
.
Infof
(
"error recording current command: %v"
,
err
)
...
...
@@ -300,6 +279,18 @@ func (o *SetImageOptions) Run() error {
return
utilerrors
.
NewAggregate
(
allErrs
)
}
func
setImage
(
containers
[]
v1
.
Container
,
containerName
string
,
image
string
)
bool
{
containerFound
:=
false
// Find the container to update, and update its image
for
i
,
c
:=
range
containers
{
if
c
.
Name
==
containerName
||
containerName
==
"*"
{
containerFound
=
true
containers
[
i
]
.
Image
=
image
}
}
return
containerFound
}
// getResourcesAndImages retrieves resources and container name:images pair from given args
func
getResourcesAndImages
(
args
[]
string
)
(
resources
[]
string
,
containerImages
map
[
string
]
string
,
err
error
)
{
pairType
:=
"image"
...
...
pkg/kubectl/cmd/set/set_image_test.go
View file @
af31a202
...
...
@@ -221,6 +221,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -242,6 +248,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -263,6 +275,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -284,6 +302,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -305,6 +329,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -326,6 +356,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -347,6 +383,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -368,6 +410,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -389,6 +437,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -410,6 +464,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -431,6 +491,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -452,6 +518,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -473,6 +545,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -494,6 +572,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -515,6 +599,12 @@ func TestSetImageRemote(t *testing.T) {
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
...
...
@@ -572,3 +662,116 @@ func TestSetImageRemote(t *testing.T) {
})
}
}
func
TestSetImageRemoteWithSpecificContainers
(
t
*
testing
.
T
)
{
inputs
:=
[]
struct
{
name
string
object
runtime
.
Object
groupVersion
schema
.
GroupVersion
path
string
args
[]
string
}{
{
name
:
"set container image only"
,
object
:
&
extensionsv1beta1
.
ReplicaSet
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"nginx"
},
Spec
:
extensionsv1beta1
.
ReplicaSetSpec
{
Template
:
corev1
.
PodTemplateSpec
{
Spec
:
corev1
.
PodSpec
{
Containers
:
[]
corev1
.
Container
{
{
Name
:
"nginx"
,
Image
:
"nginx"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
},
},
},
},
groupVersion
:
extensionsv1beta1
.
SchemeGroupVersion
,
path
:
"/namespaces/test/replicasets/nginx"
,
args
:
[]
string
{
"replicaset"
,
"nginx"
,
"nginx=thingy"
},
},
{
name
:
"set initContainer image only"
,
object
:
&
appsv1beta2
.
ReplicaSet
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"nginx"
},
Spec
:
appsv1beta2
.
ReplicaSetSpec
{
Template
:
corev1
.
PodTemplateSpec
{
Spec
:
corev1
.
PodSpec
{
Containers
:
[]
corev1
.
Container
{
{
Name
:
"busybox"
,
Image
:
"busybox"
,
},
},
InitContainers
:
[]
corev1
.
Container
{
{
Name
:
"nginx"
,
Image
:
"nginx"
,
},
},
},
},
},
},
groupVersion
:
appsv1beta2
.
SchemeGroupVersion
,
path
:
"/namespaces/test/replicasets/nginx"
,
args
:
[]
string
{
"replicaset"
,
"nginx"
,
"nginx=thingy"
},
},
}
for
_
,
input
:=
range
inputs
{
t
.
Run
(
input
.
name
,
func
(
t
*
testing
.
T
)
{
tf
:=
cmdtesting
.
NewTestFactory
()
.
WithNamespace
(
"test"
)
defer
tf
.
Cleanup
()
tf
.
Client
=
&
fake
.
RESTClient
{
GroupVersion
:
input
.
groupVersion
,
NegotiatedSerializer
:
serializer
.
DirectCodecFactory
{
CodecFactory
:
scheme
.
Codecs
},
Client
:
fake
.
CreateHTTPClient
(
func
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
switch
p
,
m
:=
req
.
URL
.
Path
,
req
.
Method
;
{
case
p
==
input
.
path
&&
m
==
http
.
MethodGet
:
return
&
http
.
Response
{
StatusCode
:
http
.
StatusOK
,
Header
:
cmdtesting
.
DefaultHeader
(),
Body
:
objBody
(
input
.
object
)},
nil
case
p
==
input
.
path
&&
m
==
http
.
MethodPatch
:
stream
,
err
:=
req
.
GetBody
()
if
err
!=
nil
{
return
nil
,
err
}
bytes
,
err
:=
ioutil
.
ReadAll
(
stream
)
if
err
!=
nil
{
return
nil
,
err
}
assert
.
Contains
(
t
,
string
(
bytes
),
`"image":"`
+
"thingy"
+
`","name":`
+
`"nginx"`
,
fmt
.
Sprintf
(
"image not updated for %#v"
,
input
.
object
))
assert
.
NotContains
(
t
,
string
(
bytes
),
`"image":"`
+
"thingy"
+
`","name":`
+
`"busybox"`
,
fmt
.
Sprintf
(
"image updated for %#v"
,
input
.
object
))
return
&
http
.
Response
{
StatusCode
:
http
.
StatusOK
,
Header
:
cmdtesting
.
DefaultHeader
(),
Body
:
objBody
(
input
.
object
)},
nil
default
:
t
.
Errorf
(
"%s: unexpected request: %s %#v
\n
%#v"
,
"image"
,
req
.
Method
,
req
.
URL
,
req
)
return
nil
,
fmt
.
Errorf
(
"unexpected request"
)
}
}),
}
outputFormat
:=
"yaml"
streams
:=
genericclioptions
.
NewTestIOStreamsDiscard
()
cmd
:=
NewCmdImage
(
tf
,
streams
)
cmd
.
Flags
()
.
Set
(
"output"
,
outputFormat
)
opts
:=
SetImageOptions
{
PrintFlags
:
genericclioptions
.
NewPrintFlags
(
""
)
.
WithDefaultOutput
(
outputFormat
)
.
WithTypeSetter
(
scheme
.
Scheme
),
Local
:
false
,
IOStreams
:
streams
,
}
err
:=
opts
.
Complete
(
tf
,
cmd
,
input
.
args
)
assert
.
NoError
(
t
,
err
)
err
=
opts
.
Run
()
assert
.
NoError
(
t
,
err
)
})
}
}
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