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
Show 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__
# Update the deployment (revision 2)
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
}
:"
# 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
kubectl rollout undo deployment nginx
--to-revision
=
1
"
${
kube_flags
[@]
}
"
sleep
1
...
...
pkg/kubectl/cmd/rollout/rollout_undo.go
View file @
6a68dbda
...
...
@@ -38,6 +38,7 @@ type UndoOptions struct {
Typer
runtime
.
ObjectTyper
Infos
[]
*
resource
.
Info
ToRevision
int64
DryRun
bool
Out
io
.
Writer
Filenames
[]
string
...
...
@@ -52,7 +53,10 @@ var (
kubectl rollout undo deployment/abc
# 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
{
...
...
@@ -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)."
)
usage
:=
"Filename, directory, or URL to a file identifying the resource to get from a server."
kubectl
.
AddJsonFilenameFlag
(
cmd
,
&
opts
.
Filenames
,
usage
)
cmdutil
.
AddDryRunFlag
(
cmd
)
cmdutil
.
AddRecursiveFlag
(
cmd
,
&
opts
.
Recursive
)
return
cmd
}
...
...
@@ -92,6 +97,7 @@ func (o *UndoOptions) CompleteUndo(f *cmdutil.Factory, cmd *cobra.Command, out i
o
.
ToRevision
=
cmdutil
.
GetFlagInt64
(
cmd
,
"to-revision"
)
o
.
Mapper
,
o
.
Typer
=
f
.
Object
(
false
)
o
.
Out
=
out
o
.
DryRun
=
cmdutil
.
GetFlagBool
(
cmd
,
"dry-run"
)
cmdNamespace
,
enforceNamespace
,
err
:=
f
.
DefaultNamespace
()
if
err
!=
nil
{
...
...
@@ -129,7 +135,7 @@ func (o *UndoOptions) CompleteUndo(f *cmdutil.Factory, cmd *cobra.Command, out i
func
(
o
*
UndoOptions
)
RunUndo
()
error
{
allErrs
:=
[]
error
{}
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
{
allErrs
=
append
(
allErrs
,
cmdutil
.
AddSourceToErr
(
"undoing"
,
info
.
Source
,
err
))
continue
...
...
pkg/kubectl/cmd/util/factory.go
View file @
6a68dbda
...
...
@@ -631,10 +631,10 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
HistoryViewer
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
HistoryViewer
,
error
)
{
mappingVersion
:=
mapping
.
GroupVersionKind
.
GroupVersion
()
client
,
err
:=
clients
.
ClientForVersion
(
&
mappingVersion
)
clientset
:=
clientset
.
FromUnversionedClient
(
client
)
if
err
!=
nil
{
return
nil
,
err
}
clientset
:=
clientset
.
FromUnversionedClient
(
client
)
return
kubectl
.
HistoryViewerFor
(
mapping
.
GroupVersionKind
.
GroupKind
(),
clientset
)
},
Rollbacker
:
func
(
mapping
*
meta
.
RESTMapping
)
(
kubectl
.
Rollbacker
,
error
)
{
...
...
@@ -643,7 +643,8 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
if
err
!=
nil
{
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
)
{
mappingVersion
:=
mapping
.
GroupVersionKind
.
GroupVersion
()
...
...
pkg/kubectl/rollback.go
View file @
6a68dbda
...
...
@@ -17,6 +17,7 @@ limitations under the License.
package
kubectl
import
(
"bytes"
"fmt"
"os"
"os/signal"
...
...
@@ -25,18 +26,19 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"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"
"k8s.io/kubernetes/pkg/runtime"
sliceutil
"k8s.io/kubernetes/pkg/util/slice"
"k8s.io/kubernetes/pkg/watch"
)
// Rollbacker provides an interface for resources that can be rolled back.
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
{
case
extensions
.
Kind
(
"Deployment"
)
:
return
&
DeploymentRollbacker
{
c
},
nil
...
...
@@ -45,14 +47,17 @@ func RollbackerFor(kind unversioned.GroupKind, c client.Interface) (Rollbacker,
}
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
)
if
!
ok
{
return
""
,
fmt
.
Errorf
(
"passed object is not a Deployment: %#v"
,
obj
)
}
if
dryRun
{
return
simpleDryRun
(
d
,
r
.
c
,
toRevision
)
}
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
)
}
...
...
@@ -66,7 +71,7 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
result
:=
""
// 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
{
return
result
,
err
}
...
...
@@ -75,7 +80,7 @@ func (r *DeploymentRollbacker) Rollback(obj runtime.Object, updatedAnnotations m
return
result
,
err
}
// 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
{
return
result
,
err
}
...
...
@@ -123,3 +128,50 @@ func isRollbackEvent(e *api.Event) (bool, string) {
}
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