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
db120eb8
Commit
db120eb8
authored
Jun 30, 2017
by
ravisantoshgudimetla
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changes for converting node to v1 in drain
parent
8bece8ec
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
57 additions
and
38 deletions
+57
-38
drain.go
pkg/kubectl/cmd/drain.go
+22
-20
drain_test.go
pkg/kubectl/cmd/drain_test.go
+35
-18
No files found.
pkg/kubectl/cmd/drain.go
View file @
db120eb8
...
@@ -20,8 +20,8 @@ import (
...
@@ -20,8 +20,8 @@ import (
"errors"
"errors"
"fmt"
"fmt"
"io"
"io"
"k8s.io/apimachinery/pkg/util/json"
"math"
"math"
"reflect"
"strings"
"strings"
"time"
"time"
...
@@ -33,8 +33,11 @@ import (
...
@@ -33,8 +33,11 @@ import (
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/util/wait"
restclient
"k8s.io/client-go/rest"
restclient
"k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/apis/policy"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
...
@@ -43,7 +46,6 @@ import (
...
@@ -43,7 +46,6 @@ import (
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
cmdutil
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubelet/types"
"k8s.io/kubernetes/pkg/util/i18n"
"k8s.io/kubernetes/pkg/util/i18n"
)
)
...
@@ -84,7 +86,6 @@ const (
...
@@ -84,7 +86,6 @@ const (
kLocalStorageWarning
=
"Deleting pods with local storage"
kLocalStorageWarning
=
"Deleting pods with local storage"
kUnmanagedFatal
=
"pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet (use --force to override)"
kUnmanagedFatal
=
"pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet (use --force to override)"
kUnmanagedWarning
=
"Deleting pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet"
kUnmanagedWarning
=
"Deleting pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet"
kMaxNodeUpdateRetry
=
10
)
)
var
(
var
(
...
@@ -353,7 +354,7 @@ func (o *DrainOptions) daemonsetFilter(pod api.Pod) (bool, *warning, *fatal) {
...
@@ -353,7 +354,7 @@ func (o *DrainOptions) daemonsetFilter(pod api.Pod) (bool, *warning, *fatal) {
}
}
func
mirrorPodFilter
(
pod
api
.
Pod
)
(
bool
,
*
warning
,
*
fatal
)
{
func
mirrorPodFilter
(
pod
api
.
Pod
)
(
bool
,
*
warning
,
*
fatal
)
{
if
_
,
found
:=
pod
.
ObjectMeta
.
Annotations
[
types
.
ConfigMirror
AnnotationKey
];
found
{
if
_
,
found
:=
pod
.
ObjectMeta
.
Annotations
[
corev1
.
MirrorPod
AnnotationKey
];
found
{
return
false
,
nil
,
nil
return
false
,
nil
,
nil
}
}
return
true
,
nil
,
nil
return
true
,
nil
,
nil
...
@@ -621,27 +622,28 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error {
...
@@ -621,27 +622,28 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error {
}
}
if
o
.
nodeInfo
.
Mapping
.
GroupVersionKind
.
Kind
==
"Node"
{
if
o
.
nodeInfo
.
Mapping
.
GroupVersionKind
.
Kind
==
"Node"
{
unsched
:=
reflect
.
ValueOf
(
o
.
nodeInfo
.
Object
)
.
Elem
()
.
FieldByName
(
"Spec"
)
.
FieldByName
(
"Unschedulable"
)
obj
,
err
:=
o
.
nodeInfo
.
Mapping
.
ConvertToVersion
(
o
.
nodeInfo
.
Object
,
o
.
nodeInfo
.
Mapping
.
GroupVersionKind
.
GroupVersion
())
if
unsched
.
Bool
()
==
desired
{
if
err
!=
nil
{
return
err
}
oldData
,
err
:=
json
.
Marshal
(
obj
)
node
,
ok
:=
obj
.
(
*
corev1
.
Node
)
if
!
ok
{
return
fmt
.
Errorf
(
"unexpected Type%T, expected Node"
,
obj
)
}
unsched
:=
node
.
Spec
.
Unschedulable
if
unsched
==
desired
{
cmdutil
.
PrintSuccess
(
o
.
mapper
,
false
,
o
.
Out
,
o
.
nodeInfo
.
Mapping
.
Resource
,
o
.
nodeInfo
.
Name
,
false
,
already
(
desired
))
cmdutil
.
PrintSuccess
(
o
.
mapper
,
false
,
o
.
Out
,
o
.
nodeInfo
.
Mapping
.
Resource
,
o
.
nodeInfo
.
Name
,
false
,
already
(
desired
))
}
else
{
}
else
{
helper
:=
resource
.
NewHelper
(
o
.
restClient
,
o
.
nodeInfo
.
Mapping
)
helper
:=
resource
.
NewHelper
(
o
.
restClient
,
o
.
nodeInfo
.
Mapping
)
unsched
.
SetBool
(
desired
)
node
.
Spec
.
Unschedulable
=
desired
var
err
error
var
err
error
for
i
:=
0
;
i
<
kMaxNodeUpdateRetry
;
i
++
{
newData
,
err
:=
json
.
Marshal
(
obj
)
// We don't care about what previous versions may exist, we always want
patchBytes
,
err
:=
strategicpatch
.
CreateTwoWayMergePatch
(
oldData
,
newData
,
obj
)
// to overwrite, and Replace always sets current ResourceVersion if version is "".
if
err
!=
nil
{
helper
.
Versioner
.
SetResourceVersion
(
o
.
nodeInfo
.
Object
,
""
)
return
err
_
,
err
=
helper
.
Replace
(
cmdNamespace
,
o
.
nodeInfo
.
Name
,
true
,
o
.
nodeInfo
.
Object
)
if
err
!=
nil
{
if
!
apierrors
.
IsConflict
(
err
)
{
return
err
}
}
else
{
break
}
// It's a race, no need to sleep
}
}
_
,
err
=
helper
.
Patch
(
cmdNamespace
,
o
.
nodeInfo
.
Name
,
types
.
StrategicMergePatchType
,
patchBytes
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
...
pkg/kubectl/cmd/drain_test.go
View file @
db120eb8
...
@@ -33,11 +33,13 @@ import (
...
@@ -33,11 +33,13 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
apierrors
"k8s.io/apimachinery/pkg/api/errors"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/rest/fake"
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
...
@@ -55,27 +57,27 @@ const (
...
@@ -55,27 +57,27 @@ const (
DeleteMethod
=
"Delete"
DeleteMethod
=
"Delete"
)
)
var
node
*
api
.
Node
var
node
*
v1
.
Node
var
cordoned_node
*
api
.
Node
var
cordoned_node
*
v1
.
Node
func
boolptr
(
b
bool
)
*
bool
{
return
&
b
}
func
boolptr
(
b
bool
)
*
bool
{
return
&
b
}
func
TestMain
(
m
*
testing
.
M
)
{
func
TestMain
(
m
*
testing
.
M
)
{
// Create a node.
// Create a node.
node
=
&
api
.
Node
{
node
=
&
v1
.
Node
{
ObjectMeta
:
metav1
.
ObjectMeta
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"node"
,
Name
:
"node"
,
CreationTimestamp
:
metav1
.
Time
{
Time
:
time
.
Now
()},
CreationTimestamp
:
metav1
.
Time
{
Time
:
time
.
Now
()},
},
},
Spec
:
api
.
NodeSpec
{
Spec
:
v1
.
NodeSpec
{
ExternalID
:
"node"
,
ExternalID
:
"node"
,
},
},
Status
:
api
.
NodeStatus
{},
Status
:
v1
.
NodeStatus
{},
}
}
clone
,
_
:=
api
.
Scheme
.
DeepCopy
(
node
)
clone
,
_
:=
api
.
Scheme
.
DeepCopy
(
node
)
// A copy of the same node, but cordoned.
// A copy of the same node, but cordoned.
cordoned_node
=
clone
.
(
*
api
.
Node
)
cordoned_node
=
clone
.
(
*
v1
.
Node
)
cordoned_node
.
Spec
.
Unschedulable
=
true
cordoned_node
.
Spec
.
Unschedulable
=
true
os
.
Exit
(
m
.
Run
())
os
.
Exit
(
m
.
Run
())
}
}
...
@@ -83,8 +85,8 @@ func TestMain(m *testing.M) {
...
@@ -83,8 +85,8 @@ func TestMain(m *testing.M) {
func
TestCordon
(
t
*
testing
.
T
)
{
func
TestCordon
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
tests
:=
[]
struct
{
description
string
description
string
node
*
api
.
Node
node
*
v1
.
Node
expected
*
api
.
Node
expected
*
v1
.
Node
cmd
func
(
cmdutil
.
Factory
,
io
.
Writer
)
*
cobra
.
Command
cmd
func
(
cmdutil
.
Factory
,
io
.
Writer
)
*
cobra
.
Command
arg
string
arg
string
expectFatal
bool
expectFatal
bool
...
@@ -149,7 +151,7 @@ func TestCordon(t *testing.T) {
...
@@ -149,7 +151,7 @@ func TestCordon(t *testing.T) {
for
_
,
test
:=
range
tests
{
for
_
,
test
:=
range
tests
{
f
,
tf
,
codec
,
ns
:=
cmdtesting
.
NewAPIFactory
()
f
,
tf
,
codec
,
ns
:=
cmdtesting
.
NewAPIFactory
()
new_node
:=
&
api
.
Node
{}
new_node
:=
&
v1
.
Node
{}
updated
:=
false
updated
:=
false
tf
.
Client
=
&
fake
.
RESTClient
{
tf
.
Client
=
&
fake
.
RESTClient
{
APIRegistry
:
api
.
Registry
,
APIRegistry
:
api
.
Registry
,
...
@@ -161,17 +163,25 @@ func TestCordon(t *testing.T) {
...
@@ -161,17 +163,25 @@ func TestCordon(t *testing.T) {
return
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
test
.
node
)},
nil
return
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
test
.
node
)},
nil
case
m
.
isFor
(
"GET"
,
"/nodes/bar"
)
:
case
m
.
isFor
(
"GET"
,
"/nodes/bar"
)
:
return
&
http
.
Response
{
StatusCode
:
404
,
Header
:
defaultHeader
(),
Body
:
stringBody
(
"nope"
)},
nil
return
&
http
.
Response
{
StatusCode
:
404
,
Header
:
defaultHeader
(),
Body
:
stringBody
(
"nope"
)},
nil
case
m
.
isFor
(
"P
UT
"
,
"/nodes/node"
)
:
case
m
.
isFor
(
"P
ATCH
"
,
"/nodes/node"
)
:
data
,
err
:=
ioutil
.
ReadAll
(
req
.
Body
)
data
,
err
:=
ioutil
.
ReadAll
(
req
.
Body
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
}
}
defer
req
.
Body
.
Close
()
defer
req
.
Body
.
Close
()
if
err
:=
runtime
.
DecodeInto
(
codec
,
data
,
new_node
);
err
!=
nil
{
oldJSON
,
err
:=
runtime
.
Encode
(
codec
,
node
)
if
err
!=
nil
{
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
}
appliedPatch
,
err
:=
strategicpatch
.
StrategicMergePatch
(
oldJSON
,
data
,
&
v1
.
Node
{})
if
err
!=
nil
{
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
}
if
err
:=
runtime
.
DecodeInto
(
codec
,
appliedPatch
,
new_node
);
err
!=
nil
{
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
}
}
if
!
reflect
.
DeepEqual
(
test
.
expected
.
Spec
,
new_node
.
Spec
)
{
if
!
reflect
.
DeepEqual
(
test
.
expected
.
Spec
,
new_node
.
Spec
)
{
t
.
Fatalf
(
"%s: expected:
\n
%v
\n
saw:
\n
%v
\n
"
,
test
.
description
,
test
.
expected
.
Spec
,
new_node
.
Spec
)
t
.
Fatalf
(
"%s: expected:
\n
%v
\n
saw:
\n
%v
\n
"
,
test
.
description
,
test
.
expected
.
Spec
.
Unschedulable
,
new_node
.
Spec
.
Unschedulable
)
}
}
updated
=
true
updated
=
true
return
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
new_node
)},
nil
return
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
new_node
)},
nil
...
@@ -443,8 +453,8 @@ func TestDrain(t *testing.T) {
...
@@ -443,8 +453,8 @@ func TestDrain(t *testing.T) {
tests
:=
[]
struct
{
tests
:=
[]
struct
{
description
string
description
string
node
*
api
.
Node
node
*
v1
.
Node
expected
*
api
.
Node
expected
*
v1
.
Node
pods
[]
api
.
Pod
pods
[]
api
.
Pod
rcs
[]
api
.
ReplicationController
rcs
[]
api
.
ReplicationController
replicaSets
[]
extensions
.
ReplicaSet
replicaSets
[]
extensions
.
ReplicaSet
...
@@ -582,7 +592,7 @@ func TestDrain(t *testing.T) {
...
@@ -582,7 +592,7 @@ func TestDrain(t *testing.T) {
currMethod
=
DeleteMethod
currMethod
=
DeleteMethod
}
}
for
_
,
test
:=
range
tests
{
for
_
,
test
:=
range
tests
{
new_node
:=
&
api
.
Node
{}
new_node
:=
&
v1
.
Node
{}
deleted
:=
false
deleted
:=
false
evicted
:=
false
evicted
:=
false
f
,
tf
,
codec
,
ns
:=
cmdtesting
.
NewAPIFactory
()
f
,
tf
,
codec
,
ns
:=
cmdtesting
.
NewAPIFactory
()
...
@@ -649,13 +659,21 @@ func TestDrain(t *testing.T) {
...
@@ -649,13 +659,21 @@ func TestDrain(t *testing.T) {
return
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
&
api
.
PodList
{
Items
:
test
.
pods
})},
nil
return
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
&
api
.
PodList
{
Items
:
test
.
pods
})},
nil
case
m
.
isFor
(
"GET"
,
"/replicationcontrollers"
)
:
case
m
.
isFor
(
"GET"
,
"/replicationcontrollers"
)
:
return
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
&
api
.
ReplicationControllerList
{
Items
:
test
.
rcs
})},
nil
return
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
&
api
.
ReplicationControllerList
{
Items
:
test
.
rcs
})},
nil
case
m
.
isFor
(
"P
UT
"
,
"/nodes/node"
)
:
case
m
.
isFor
(
"P
ATCH
"
,
"/nodes/node"
)
:
data
,
err
:=
ioutil
.
ReadAll
(
req
.
Body
)
data
,
err
:=
ioutil
.
ReadAll
(
req
.
Body
)
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
}
}
defer
req
.
Body
.
Close
()
defer
req
.
Body
.
Close
()
if
err
:=
runtime
.
DecodeInto
(
codec
,
data
,
new_node
);
err
!=
nil
{
oldJSON
,
err
:=
runtime
.
Encode
(
codec
,
node
)
if
err
!=
nil
{
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
}
appliedPatch
,
err
:=
strategicpatch
.
StrategicMergePatch
(
oldJSON
,
data
,
&
v1
.
Node
{})
if
err
!=
nil
{
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
}
if
err
:=
runtime
.
DecodeInto
(
codec
,
appliedPatch
,
new_node
);
err
!=
nil
{
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
t
.
Fatalf
(
"%s: unexpected error: %v"
,
test
.
description
,
err
)
}
}
if
!
reflect
.
DeepEqual
(
test
.
expected
.
Spec
,
new_node
.
Spec
)
{
if
!
reflect
.
DeepEqual
(
test
.
expected
.
Spec
,
new_node
.
Spec
)
{
...
@@ -692,7 +710,6 @@ func TestDrain(t *testing.T) {
...
@@ -692,7 +710,6 @@ func TestDrain(t *testing.T) {
cmd
.
SetArgs
(
test
.
args
)
cmd
.
SetArgs
(
test
.
args
)
cmd
.
Execute
()
cmd
.
Execute
()
}()
}()
if
test
.
expectFatal
{
if
test
.
expectFatal
{
if
!
saw_fatal
{
if
!
saw_fatal
{
t
.
Fatalf
(
"%s: unexpected non-error when using %s"
,
test
.
description
,
currMethod
)
t
.
Fatalf
(
"%s: unexpected non-error when using %s"
,
test
.
description
,
currMethod
)
...
...
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