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
2af1c03b
Commit
2af1c03b
authored
Oct 06, 2016
by
ymqytw
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor edit cmd
parent
6a9d56b3
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
118 additions
and
87 deletions
+118
-87
edit.go
pkg/kubectl/cmd/edit.go
+118
-87
No files found.
pkg/kubectl/cmd/edit.go
View file @
2af1c03b
...
@@ -122,53 +122,12 @@ func NewCmdEdit(f *cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
...
@@ -122,53 +122,12 @@ func NewCmdEdit(f *cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
}
}
func
RunEdit
(
f
*
cmdutil
.
Factory
,
out
,
errOut
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
,
options
*
resource
.
FilenameOptions
)
error
{
func
RunEdit
(
f
*
cmdutil
.
Factory
,
out
,
errOut
io
.
Writer
,
cmd
*
cobra
.
Command
,
args
[]
string
,
options
*
resource
.
FilenameOptions
)
error
{
var
printer
kubectl
.
ResourcePrinter
o
,
err
:=
getPrinter
(
cmd
)
var
ext
string
var
addHeader
bool
switch
format
:=
cmdutil
.
GetFlagString
(
cmd
,
"output"
);
format
{
case
"json"
:
printer
=
&
kubectl
.
JSONPrinter
{}
ext
=
".json"
addHeader
=
false
case
"yaml"
:
printer
=
&
kubectl
.
YAMLPrinter
{}
ext
=
".yaml"
addHeader
=
true
default
:
return
cmdutil
.
UsageError
(
cmd
,
"The flag 'output' must be one of yaml|json"
)
}
cmdNamespace
,
enforceNamespace
,
err
:=
f
.
DefaultNamespace
()
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
mapper
,
typer
:=
f
.
Object
()
mapper
,
resourceMapper
,
r
,
cmdNamespace
,
err
:=
getMapperAndResult
(
f
,
args
,
options
)
resourceMapper
:=
&
resource
.
Mapper
{
ObjectTyper
:
typer
,
RESTMapper
:
mapper
,
ClientMapper
:
resource
.
ClientMapperFunc
(
f
.
ClientForMapping
),
// NB: we use `f.Decoder(false)` to get a plain deserializer for
// the resourceMapper, since it's used to read in edits and
// we don't want to convert into the internal version when
// reading in edits (this would cause us to potentially try to
// compare two different GroupVersions).
Decoder
:
f
.
Decoder
(
false
),
}
r
:=
resource
.
NewBuilder
(
mapper
,
typer
,
resource
.
ClientMapperFunc
(
f
.
ClientForMapping
),
f
.
Decoder
(
true
))
.
NamespaceParam
(
cmdNamespace
)
.
DefaultNamespace
()
.
FilenameParam
(
enforceNamespace
,
options
)
.
ResourceTypeOrNameArgs
(
true
,
args
...
)
.
ContinueOnError
()
.
Flatten
()
.
Latest
()
.
Do
()
err
=
r
.
Err
()
if
err
!=
nil
{
return
err
}
clientConfig
,
err
:=
f
.
ClientConfig
()
clientConfig
,
err
:=
f
.
ClientConfig
()
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -212,12 +171,12 @@ func RunEdit(f *cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
...
@@ -212,12 +171,12 @@ func RunEdit(f *cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
w
=
crlf
.
NewCRLFWriter
(
w
)
w
=
crlf
.
NewCRLFWriter
(
w
)
}
}
if
addHeader
{
if
o
.
addHeader
{
results
.
header
.
writeTo
(
w
)
results
.
header
.
writeTo
(
w
)
}
}
if
!
containsError
{
if
!
containsError
{
if
err
:=
printer
.
PrintObj
(
objToEdit
,
w
);
err
!=
nil
{
if
err
:=
o
.
printer
.
PrintObj
(
objToEdit
,
w
);
err
!=
nil
{
return
preservedFile
(
err
,
results
.
file
,
errOut
)
return
preservedFile
(
err
,
results
.
file
,
errOut
)
}
}
original
=
buf
.
Bytes
()
original
=
buf
.
Bytes
()
...
@@ -230,7 +189,7 @@ func RunEdit(f *cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
...
@@ -230,7 +189,7 @@ func RunEdit(f *cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
// launch the editor
// launch the editor
editedDiff
:=
edited
editedDiff
:=
edited
edited
,
file
,
err
=
edit
.
LaunchTempFile
(
fmt
.
Sprintf
(
"%s-edit-"
,
filepath
.
Base
(
os
.
Args
[
0
])),
ext
,
buf
)
edited
,
file
,
err
=
edit
.
LaunchTempFile
(
fmt
.
Sprintf
(
"%s-edit-"
,
filepath
.
Base
(
os
.
Args
[
0
])),
o
.
ext
,
buf
)
if
err
!=
nil
{
if
err
!=
nil
{
return
preservedFile
(
err
,
results
.
file
,
errOut
)
return
preservedFile
(
err
,
results
.
file
,
errOut
)
}
}
...
@@ -297,34 +256,109 @@ func RunEdit(f *cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
...
@@ -297,34 +256,109 @@ func RunEdit(f *cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
return
preservedFile
(
err
,
file
,
errOut
)
return
preservedFile
(
err
,
file
,
errOut
)
}
}
mutatedObjects
:=
[]
runtime
.
Object
{}
annotationVisitor
:=
resource
.
NewFlattenListVisitor
(
updates
,
resourceMapper
)
// iterate through all items to apply annotations
// iterate through all items to apply annotations
if
err
=
annotationVisitor
.
Visit
(
func
(
info
*
resource
.
Info
,
incomingErr
error
)
error
{
mutatedObjects
,
err
:=
visitAnnotation
(
cmd
,
f
,
updates
,
resourceMapper
,
encoder
)
// put configuration annotation in "updates"
if
err
!=
nil
{
if
err
:=
kubectl
.
CreateOrUpdateAnnotation
(
cmdutil
.
GetFlagBool
(
cmd
,
cmdutil
.
ApplyAnnotationsFlag
),
info
,
encoder
);
err
!=
nil
{
return
preservedFile
(
err
,
file
,
errOut
)
return
err
}
}
if
cmdutil
.
ShouldRecord
(
cmd
,
info
)
{
if
err
:=
cmdutil
.
RecordChangeCause
(
info
.
Object
,
f
.
Command
());
err
!=
nil
{
// if we mutated a list in the visitor, persist the changes on the overall object
return
err
if
meta
.
IsListType
(
updates
.
Object
)
{
meta
.
SetList
(
updates
.
Object
,
mutatedObjects
)
}
}
err
=
visitToPatch
(
originalObj
,
updates
,
mapper
,
resourceMapper
,
encoder
,
out
,
errOut
,
defaultVersion
,
&
results
,
file
)
if
err
!=
nil
{
return
preservedFile
(
err
,
results
.
file
,
errOut
)
}
}
mutatedObjects
=
append
(
mutatedObjects
,
info
.
Object
)
// Handle all possible errors
//
// 1. retryable: propose kubectl replace -f
// 2. notfound: indicate the location of the saved configuration of the deleted resource
// 3. invalid: retry those on the spot by looping ie. reloading the editor
if
results
.
retryable
>
0
{
fmt
.
Fprintf
(
errOut
,
"You can run `%s replace -f %s` to try this update again.
\n
"
,
filepath
.
Base
(
os
.
Args
[
0
]),
file
)
return
errExit
}
if
results
.
notfound
>
0
{
fmt
.
Fprintf
(
errOut
,
"The edits you made on deleted resources have been saved to %q
\n
"
,
file
)
return
errExit
}
if
len
(
results
.
edit
)
==
0
{
if
results
.
notfound
==
0
{
os
.
Remove
(
file
)
}
else
{
fmt
.
Fprintf
(
out
,
"The edits you made on deleted resources have been saved to %q
\n
"
,
file
)
}
return
nil
return
nil
}
});
err
!=
nil
{
// loop again and edit the remaining items
return
preservedFile
(
err
,
file
,
errOut
)
infos
=
results
.
edit
}
}
})
return
err
}
// if we mutated a list in the visitor, persist the changes on the overall object
func
getPrinter
(
cmd
*
cobra
.
Command
)
(
*
editPrinterOptions
,
error
)
{
if
meta
.
IsListType
(
updates
.
Object
)
{
switch
format
:=
cmdutil
.
GetFlagString
(
cmd
,
"output"
);
format
{
meta
.
SetList
(
updates
.
Object
,
mutatedObjects
)
case
"json"
:
return
&
editPrinterOptions
{
printer
:
&
kubectl
.
JSONPrinter
{},
ext
:
".json"
,
addHeader
:
false
,
},
nil
case
"yaml"
:
return
&
editPrinterOptions
{
printer
:
&
kubectl
.
YAMLPrinter
{},
ext
:
".yaml"
,
addHeader
:
true
,
},
nil
default
:
return
nil
,
cmdutil
.
UsageError
(
cmd
,
"The flag 'output' must be one of yaml|json"
)
}
}
func
getMapperAndResult
(
f
*
cmdutil
.
Factory
,
args
[]
string
,
options
*
resource
.
FilenameOptions
)
(
meta
.
RESTMapper
,
*
resource
.
Mapper
,
*
resource
.
Result
,
string
,
error
)
{
cmdNamespace
,
enforceNamespace
,
err
:=
f
.
DefaultNamespace
()
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
""
,
err
}
}
mapper
,
typer
:=
f
.
Object
()
resourceMapper
:=
&
resource
.
Mapper
{
ObjectTyper
:
typer
,
RESTMapper
:
mapper
,
ClientMapper
:
resource
.
ClientMapperFunc
(
f
.
ClientForMapping
),
// NB: we use `f.Decoder(false)` to get a plain deserializer for
// the resourceMapper, since it's used to read in edits and
// we don't want to convert into the internal version when
// reading in edits (this would cause us to potentially try to
// compare two different GroupVersions).
Decoder
:
f
.
Decoder
(
false
),
}
r
:=
resource
.
NewBuilder
(
mapper
,
typer
,
resource
.
ClientMapperFunc
(
f
.
ClientForMapping
),
f
.
Decoder
(
true
))
.
NamespaceParam
(
cmdNamespace
)
.
DefaultNamespace
()
.
FilenameParam
(
enforceNamespace
,
options
)
.
ResourceTypeOrNameArgs
(
true
,
args
...
)
.
ContinueOnError
()
.
Flatten
()
.
Latest
()
.
Do
()
err
=
r
.
Err
()
if
err
!=
nil
{
return
nil
,
nil
,
nil
,
""
,
err
}
return
mapper
,
resourceMapper
,
r
,
cmdNamespace
,
err
}
func
visitToPatch
(
originalObj
runtime
.
Object
,
updates
*
resource
.
Info
,
mapper
meta
.
RESTMapper
,
resourceMapper
*
resource
.
Mapper
,
encoder
runtime
.
Encoder
,
out
,
errOut
io
.
Writer
,
defaultVersion
unversioned
.
GroupVersion
,
results
*
editResults
,
file
string
)
error
{
patchVisitor
:=
resource
.
NewFlattenListVisitor
(
updates
,
resourceMapper
)
patchVisitor
:=
resource
.
NewFlattenListVisitor
(
updates
,
resourceMapper
)
err
=
patchVisitor
.
Visit
(
func
(
info
*
resource
.
Info
,
incomingErr
error
)
error
{
err
:
=
patchVisitor
.
Visit
(
func
(
info
*
resource
.
Info
,
incomingErr
error
)
error
{
currOriginalObj
:=
originalObj
currOriginalObj
:=
originalObj
// if we're editing a list, then navigate the list to find the item that we're currently trying to edit
// if we're editing a list, then navigate the list to find the item that we're currently trying to edit
...
@@ -404,38 +438,29 @@ func RunEdit(f *cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
...
@@ -404,38 +438,29 @@ func RunEdit(f *cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
cmdutil
.
PrintSuccess
(
mapper
,
false
,
out
,
info
.
Mapping
.
Resource
,
info
.
Name
,
false
,
"edited"
)
cmdutil
.
PrintSuccess
(
mapper
,
false
,
out
,
info
.
Mapping
.
Resource
,
info
.
Name
,
false
,
"edited"
)
return
nil
return
nil
})
})
if
err
!=
nil
{
return
err
return
preservedFile
(
err
,
results
.
file
,
errOut
)
}
}
// Handle all possible errors
func
visitAnnotation
(
cmd
*
cobra
.
Command
,
f
*
cmdutil
.
Factory
,
updates
*
resource
.
Info
,
resourceMapper
*
resource
.
Mapper
,
encoder
runtime
.
Encoder
)
([]
runtime
.
Object
,
error
)
{
//
mutatedObjects
:=
[]
runtime
.
Object
{}
// 1. retryable: propose kubectl replace -f
annotationVisitor
:=
resource
.
NewFlattenListVisitor
(
updates
,
resourceMapper
)
// 2. notfound: indicate the location of the saved configuration of the deleted resource
// iterate through all items to apply annotations
// 3. invalid: retry those on the spot by looping ie. reloading the editor
err
:=
annotationVisitor
.
Visit
(
func
(
info
*
resource
.
Info
,
incomingErr
error
)
error
{
if
results
.
retryable
>
0
{
// put configuration annotation in "updates"
fmt
.
Fprintf
(
errOut
,
"You can run `%s replace -f %s` to try this update again.
\n
"
,
filepath
.
Base
(
os
.
Args
[
0
]),
file
)
if
err
:=
kubectl
.
CreateOrUpdateAnnotation
(
cmdutil
.
GetFlagBool
(
cmd
,
cmdutil
.
ApplyAnnotationsFlag
),
info
,
encoder
);
err
!=
nil
{
return
errExit
return
err
}
}
if
results
.
notfound
>
0
{
if
cmdutil
.
ShouldRecord
(
cmd
,
info
)
{
fmt
.
Fprintf
(
errOut
,
"The edits you made on deleted resources have been saved to %q
\n
"
,
file
)
if
err
:=
cmdutil
.
RecordChangeCause
(
info
.
Object
,
f
.
Command
());
err
!=
nil
{
return
err
Exit
return
err
}
}
if
len
(
results
.
edit
)
==
0
{
if
results
.
notfound
==
0
{
os
.
Remove
(
file
)
}
else
{
fmt
.
Fprintf
(
out
,
"The edits you made on deleted resources have been saved to %q
\n
"
,
file
)
}
}
mutatedObjects
=
append
(
mutatedObjects
,
info
.
Object
)
return
nil
return
nil
}
// loop again and edit the remaining items
infos
=
results
.
edit
}
})
})
return
err
return
mutatedObjects
,
err
}
}
// editReason preserves a message about the reason this file must be edited again
// editReason preserves a message about the reason this file must be edited again
...
@@ -474,6 +499,12 @@ func (h *editHeader) flush() {
...
@@ -474,6 +499,12 @@ func (h *editHeader) flush() {
h
.
reasons
=
[]
editReason
{}
h
.
reasons
=
[]
editReason
{}
}
}
type
editPrinterOptions
struct
{
printer
kubectl
.
ResourcePrinter
ext
string
addHeader
bool
}
// editResults capture the result of an update
// editResults capture the result of an update
type
editResults
struct
{
type
editResults
struct
{
header
editHeader
header
editHeader
...
...
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