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
6a68dbda
Commit
6a68dbda
authored
Sep 08, 2016
by
AdoHe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rollout undo add dry-run implementation
parent
85c91eb3
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
73 additions
and
11 deletions
+73
-11
test-cmd.sh
hack/make-rules/test-cmd.sh
+3
-0
rollout_undo.go
pkg/kubectl/cmd/rollout/rollout_undo.go
+8
-2
factory.go
pkg/kubectl/cmd/util/factory.go
+3
-2
rollback.go
pkg/kubectl/rollback.go
+59
-7
No files found.
hack/make-rules/test-cmd.sh
View file @
6a68dbda
...
@@ -1931,6 +1931,9 @@ __EOF__
...
@@ -1931,6 +1931,9 @@ __EOF__
# Update the deployment (revision 2)
# Update the deployment (revision 2)
kubectl apply
-f
hack/testdata/deployment-revision2.yaml
"
${
kube_flags
[@]
}
"
kubectl apply
-f
hack/testdata/deployment-revision2.yaml
"
${
kube_flags
[@]
}
"
kube::test::get_object_assert deployment.extensions
"{{range.items}}{{
$deployment_image_field
}}:{{end}}"
"
${
IMAGE_DEPLOYMENT_R2
}
:"
kube::test::get_object_assert deployment.extensions
"{{range.items}}{{
$deployment_image_field
}}:{{end}}"
"
${
IMAGE_DEPLOYMENT_R2
}
:"
# Rollback to revision 1 with dry-run - should be no-op
kubectl rollout undo deployment nginx
--to-revision
=
1
--dry-run
=
true
"
${
kube_flags
[@]
}
"
kube::test::get_object_assert deployment.extensions
"{{range.items}}{{
$deployment_image_field
}}:{{end}}"
"
${
IMAGE_DEPLOYMENT_R2
}
:"
# Rollback to revision 1
# Rollback to revision 1
kubectl rollout undo deployment nginx
--to-revision
=
1
"
${
kube_flags
[@]
}
"
kubectl rollout undo deployment nginx
--to-revision
=
1
"
${
kube_flags
[@]
}
"
sleep
1
sleep
1
...
...
pkg/kubectl/cmd/rollout/rollout_undo.go
View file @
6a68dbda
...
@@ -38,6 +38,7 @@ type UndoOptions struct {
...
@@ -38,6 +38,7 @@ type UndoOptions struct {
Typer
runtime
.
ObjectTyper
Typer
runtime
.
ObjectTyper
Infos
[]
*
resource
.
Info
Infos
[]
*
resource
.
Info
ToRevision
int64
ToRevision
int64
DryRun
bool
Out
io
.
Writer
Out
io
.
Writer
Filenames
[]
string
Filenames
[]
string
...
@@ -52,7 +53,10 @@ var (
...
@@ -52,7 +53,10 @@ var (
kubectl rollout undo deployment/abc
kubectl rollout undo deployment/abc
# Rollback to deployment revision 3
# Rollback to deployment revision 3
kubectl rollout undo deployment/abc --to-revision=3`
)
kubectl rollout undo deployment/abc --to-revision=3
# Rollback to the previous deployment with dry-run
kubectl rollout undo --dry-run=true deployment/abc`
)
)
)
func
NewCmdRolloutUndo
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
func
NewCmdRolloutUndo
(
f
*
cmdutil
.
Factory
,
out
io
.
Writer
)
*
cobra
.
Command
{
...
@@ -80,6 +84,7 @@ func NewCmdRolloutUndo(f *cmdutil.Factory, out io.Writer) *cobra.Command {
...
@@ -80,6 +84,7 @@ func NewCmdRolloutUndo(f *cmdutil.Factory, out io.Writer) *cobra.Command {
cmd
.
Flags
()
.
Int64
(
"to-revision"
,
0
,
"The revision to rollback to. Default to 0 (last revision)."
)
cmd
.
Flags
()
.
Int64
(
"to-revision"
,
0
,
"The revision to rollback to. Default to 0 (last revision)."
)
usage
:=
"Filename, directory, or URL to a file identifying the resource to get from a server."
usage
:=
"Filename, directory, or URL to a file identifying the resource to get from a server."
kubectl
.
AddJsonFilenameFlag
(
cmd
,
&
opts
.
Filenames
,
usage
)
kubectl
.
AddJsonFilenameFlag
(
cmd
,
&
opts
.
Filenames
,
usage
)
cmdutil
.
AddDryRunFlag
(
cmd
)
cmdutil
.
AddRecursiveFlag
(
cmd
,
&
opts
.
Recursive
)
cmdutil
.
AddRecursiveFlag
(
cmd
,
&
opts
.
Recursive
)
return
cmd
return
cmd
}
}
...
@@ -92,6 +97,7 @@ func (o *UndoOptions) CompleteUndo(f *cmdutil.Factory, cmd *cobra.Command, out i
...
@@ -92,6 +97,7 @@ func (o *UndoOptions) CompleteUndo(f *cmdutil.Factory, cmd *cobra.Command, out i
o
.
ToRevision
=
cmdutil
.
GetFlagInt64
(
cmd
,
"to-revision"
)
o
.
ToRevision
=
cmdutil
.
GetFlagInt64
(
cmd
,
"to-revision"
)
o
.
Mapper
,
o
.
Typer
=
f
.
Object
(
false
)
o
.
Mapper
,
o
.
Typer
=
f
.
Object
(
false
)
o
.
Out
=
out
o
.
Out
=
out
o
.
DryRun
=
cmdutil
.
GetFlagBool
(
cmd
,
"dry-run"
)
cmdNamespace
,
enforceNamespace
,
err
:=
f
.
DefaultNamespace
()
cmdNamespace
,
enforceNamespace
,
err
:=
f
.
DefaultNamespace
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -129,7 +135,7 @@ func (o *UndoOptions) CompleteUndo(f *cmdutil.Factory, cmd *cobra.Command, out i
...
@@ -129,7 +135,7 @@ func (o *UndoOptions) CompleteUndo(f *cmdutil.Factory, cmd *cobra.Command, out i
func
(
o
*
UndoOptions
)
RunUndo
()
error
{
func
(
o
*
UndoOptions
)
RunUndo
()
error
{
allErrs
:=
[]
error
{}
allErrs
:=
[]
error
{}
for
ix
,
info
:=
range
o
.
Infos
{
for
ix
,
info
:=
range
o
.
Infos
{
result
,
err
:=
o
.
Rollbackers
[
ix
]
.
Rollback
(
info
.
Object
,
nil
,
o
.
ToRevision
)
result
,
err
:=
o
.
Rollbackers
[
ix
]
.
Rollback
(
info
.
Object
,
nil
,
o
.
ToRevision
,
o
.
DryRun
)
if
err
!=
nil
{
if
err
!=
nil
{
allErrs
=
append
(
allErrs
,
cmdutil
.
AddSourceToErr
(
"undoing"
,
info
.
Source
,
err
))
allErrs
=
append
(
allErrs
,
cmdutil
.
AddSourceToErr
(
"undoing"
,
info
.
Source
,
err
))
continue
continue
...
...
pkg/kubectl/cmd/util/factory.go
View file @
6a68dbda
...
@@ -631,10 +631,10 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
...
@@ -631,10 +631,10 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
HistoryViewer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
HistoryViewer
,
error
)
{
HistoryViewer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
HistoryViewer
,
error
)
{
mappingVersion
:=
mapping
.
GroupVersionKind
.
GroupVersion
()
mappingVersion
:=
mapping
.
GroupVersionKind
.
GroupVersion
()
client
,
err
:=
clients
.
ClientForVersion
(
&
mappingVersion
)
client
,
err
:=
clients
.
ClientForVersion
(
&
mappingVersion
)
clientset
:=
clientset
.
FromUnversionedClient
(
client
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
clientset
:=
clientset
.
FromUnversionedClient
(
client
)
return
kubectl
.
HistoryViewerFor
(
mapping
.
GroupVersionKind
.
GroupKind
(),
clientset
)
return
kubectl
.
HistoryViewerFor
(
mapping
.
GroupVersionKind
.
GroupKind
(),
clientset
)
},
},
Rollbacker
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Rollbacker
,
error
)
{
Rollbacker
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Rollbacker
,
error
)
{
...
@@ -643,7 +643,8 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
...
@@ -643,7 +643,8 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
err
return
nil
,
err
}
}
return
kubectl
.
RollbackerFor
(
mapping
.
GroupVersionKind
.
GroupKind
(),
client
)
clientset
:=
clientset
.
FromUnversionedClient
(
client
)
return
kubectl
.
RollbackerFor
(
mapping
.
GroupVersionKind
.
GroupKind
(),
clientset
)
},
},
StatusViewer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
StatusViewer
,
error
)
{
StatusViewer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
StatusViewer
,
error
)
{
mappingVersion
:=
mapping
.
GroupVersionKind
.
GroupVersion
()
mappingVersion
:=
mapping
.
GroupVersionKind
.
GroupVersion
()
...
...
pkg/kubectl/rollback.go
View file @
6a68dbda
...
@@ -17,6 +17,7 @@ limitations under the License.
...
@@ -17,6 +17,7 @@ limitations under the License.
package
kubectl
package
kubectl
import
(
import
(
"bytes"
"fmt"
"fmt"
"os"
"os"
"os/signal"
"os/signal"
...
@@ -25,18 +26,19 @@ import (
...
@@ -25,18 +26,19 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apis/extensions"
client
"k8s.io/kubernetes/pkg/client/unversioned
"
client
set
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset
"
deploymentutil
"k8s.io/kubernetes/pkg/controller/deployment/util"
deploymentutil
"k8s.io/kubernetes/pkg/controller/deployment/util"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime"
sliceutil
"k8s.io/kubernetes/pkg/util/slice"
"k8s.io/kubernetes/pkg/watch"
"k8s.io/kubernetes/pkg/watch"
)
)
// Rollbacker provides an interface for resources that can be rolled back.
// Rollbacker provides an interface for resources that can be rolled back.
type
Rollbacker
interface
{
type
Rollbacker
interface
{
Rollback
(
obj
runtime
.
Object
,
updatedAnnotations
map
[
string
]
string
,
toRevision
int64
)
(
string
,
error
)
Rollback
(
obj
runtime
.
Object
,
updatedAnnotations
map
[
string
]
string
,
toRevision
int64
,
dryRun
bool
)
(
string
,
error
)
}
}
func
RollbackerFor
(
kind
unversioned
.
GroupKind
,
c
client
.
Interface
)
(
Rollbacker
,
error
)
{
func
RollbackerFor
(
kind
unversioned
.
GroupKind
,
c
client
set
.
Interface
)
(
Rollbacker
,
error
)
{
switch
kind
{
switch
kind
{
case
extensions
.
Kind
(
"Deployment"
)
:
case
extensions
.
Kind
(
"Deployment"
)
:
return
&
DeploymentRollbacker
{
c
},
nil
return
&
DeploymentRollbacker
{
c
},
nil
...
@@ -45,14 +47,17 @@ func RollbackerFor(kind unversioned.GroupKind, c client.Interface) (Rollbacker,
...
@@ -45,14 +47,17 @@ func RollbackerFor(kind unversioned.GroupKind, c client.Interface) (Rollbacker,
}
}
type
DeploymentRollbacker
struct
{
type
DeploymentRollbacker
struct
{
c
client
.
Interface
c
client
set
.
Interface
}
}
func
(
r
*
DeploymentRollbacker
)
Rollback
(
obj
runtime
.
Object
,
updatedAnnotations
map
[
string
]
string
,
toRevision
int64
)
(
string
,
error
)
{
func
(
r
*
DeploymentRollbacker
)
Rollback
(
obj
runtime
.
Object
,
updatedAnnotations
map
[
string
]
string
,
toRevision
int64
,
dryRun
bool
)
(
string
,
error
)
{
d
,
ok
:=
obj
.
(
*
extensions
.
Deployment
)
d
,
ok
:=
obj
.
(
*
extensions
.
Deployment
)
if
!
ok
{
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"passed object is not a Deployment: %#v"
,
obj
)
return
""
,
fmt
.
Errorf
(
"passed object is not a Deployment: %#v"
,
obj
)
}
}
if
dryRun
{
return
simpleDryRun
(
d
,
r
.
c
,
toRevision
)
}
if
d
.
Spec
.
Paused
{
if
d
.
Spec
.
Paused
{
return
""
,
fmt
.
Errorf
(
"you cannot rollback a paused deployment; resume it first with 'kubectl rollout resume deployment/%s' and try again"
,
d
.
Name
)
return
""
,
fmt
.
Errorf
(
"you cannot rollback a paused deployment; resume it first with 'kubectl rollout resume deployment/%s' and try again"
,
d
.
Name
)
}
}
...
@@ -66,7 +71,7 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
...
@@ -66,7 +71,7 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
result
:=
""
result
:=
""
// Get current events
// Get current events
events
,
err
:=
r
.
c
.
Events
(
d
.
Namespace
)
.
List
(
api
.
ListOptions
{})
events
,
err
:=
r
.
c
.
Core
()
.
Events
(
d
.
Namespace
)
.
List
(
api
.
ListOptions
{})
if
err
!=
nil
{
if
err
!=
nil
{
return
result
,
err
return
result
,
err
}
}
...
@@ -75,7 +80,7 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
...
@@ -75,7 +80,7 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
return
result
,
err
return
result
,
err
}
}
// Watch for the changes of events
// Watch for the changes of events
watch
,
err
:=
r
.
c
.
Events
(
d
.
Namespace
)
.
Watch
(
api
.
ListOptions
{
Watch
:
true
,
ResourceVersion
:
events
.
ResourceVersion
})
watch
,
err
:=
r
.
c
.
Core
()
.
Events
(
d
.
Namespace
)
.
Watch
(
api
.
ListOptions
{
Watch
:
true
,
ResourceVersion
:
events
.
ResourceVersion
})
if
err
!=
nil
{
if
err
!=
nil
{
return
result
,
err
return
result
,
err
}
}
...
@@ -123,3 +128,50 @@ func isRollbackEvent(e *api.Event) (bool, string) {
...
@@ -123,3 +128,50 @@ func isRollbackEvent(e *api.Event) (bool, string) {
}
}
return
false
,
""
return
false
,
""
}
}
func
simpleDryRun
(
deployment
*
extensions
.
Deployment
,
c
clientset
.
Interface
,
toRevision
int64
)
(
string
,
error
)
{
_
,
allOldRSs
,
newRS
,
err
:=
deploymentutil
.
GetAllReplicaSets
(
deployment
,
c
)
if
err
!=
nil
{
return
""
,
fmt
.
Errorf
(
"failed to retrieve replica sets from deployment %s: %v"
,
deployment
.
Name
,
err
)
}
allRSs
:=
allOldRSs
if
newRS
!=
nil
{
allRSs
=
append
(
allRSs
,
newRS
)
}
revisionToSpec
:=
make
(
map
[
int64
]
*
api
.
PodTemplateSpec
)
for
_
,
rs
:=
range
allRSs
{
v
,
err
:=
deploymentutil
.
Revision
(
rs
)
if
err
!=
nil
{
continue
}
revisionToSpec
[
v
]
=
&
rs
.
Spec
.
Template
}
if
len
(
revisionToSpec
)
==
0
{
return
"No rollout history found."
,
nil
}
if
toRevision
>
0
{
template
,
ok
:=
revisionToSpec
[
toRevision
]
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"unable to find specified revision"
)
}
buf
:=
bytes
.
NewBuffer
([]
byte
{})
DescribePodTemplate
(
template
,
buf
)
return
buf
.
String
(),
nil
}
// Sort the revisionToSpec map by revision
revisions
:=
make
([]
int64
,
0
,
len
(
revisionToSpec
))
for
r
:=
range
revisionToSpec
{
revisions
=
append
(
revisions
,
r
)
}
sliceutil
.
SortInts64
(
revisions
)
template
,
_
:=
revisionToSpec
[
revisions
[
len
(
revisions
)
-
1
]]
buf
:=
bytes
.
NewBuffer
([]
byte
{})
buf
.
WriteString
(
"
\n
"
)
DescribePodTemplate
(
template
,
buf
)
return
buf
.
String
(),
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