1
0
mirror of https://github.com/kubernetes-sigs/descheduler.git synced 2026-01-26 05:14:13 +01:00

Merge pull request #15 from aveshagarwal/master-dry-run

Add dry run option
This commit is contained in:
Avesh Agarwal
2017-09-26 17:12:02 -04:00
committed by GitHub
13 changed files with 301 additions and 174 deletions

View File

@@ -52,4 +52,5 @@ func (rs *DeschedulerServer) AddFlags(fs *pflag.FlagSet) {
fs.DurationVar(&rs.DeschedulingInterval, "descheduling-interval", rs.DeschedulingInterval, "time interval between two consecutive descheduler executions")
fs.StringVar(&rs.KubeconfigFile, "kubeconfig-file", rs.KubeconfigFile, "File with kube configuration.")
fs.StringVar(&rs.PolicyConfigFile, "policy-config-file", rs.PolicyConfigFile, "File with descheduler policy configuration.")
fs.BoolVar(&rs.DryRun, "dry-run", rs.DryRun, "execute descheduler in dry run mode.")
}

View File

@@ -81,16 +81,16 @@ func (x *DeschedulerConfiguration) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [5]bool
var yyq2 [6]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.Kind != ""
yyq2[1] = x.APIVersion != ""
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(5)
r.EncodeArrayStart(6)
} else {
yynn2 = 3
yynn2 = 4
for _, b := range yyq2 {
if b {
yynn2++
@@ -208,6 +208,25 @@ func (x *DeschedulerConfiguration) CodecEncodeSelf(e *codec1978.Encoder) {
r.EncodeString(codecSelferC_UTF81234, string(x.PolicyConfigFile))
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
yym19 := z.EncBinary()
_ = yym19
if false {
} else {
r.EncodeBool(bool(x.DryRun))
}
} else {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("DryRun"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym20 := z.EncBinary()
_ = yym20
if false {
} else {
r.EncodeBool(bool(x.DryRun))
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
@@ -330,6 +349,18 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.De
*((*string)(yyv12)) = r.DecodeString()
}
}
case "DryRun":
if r.TryDecodeAsNil() {
x.DryRun = false
} else {
yyv14 := &x.DryRun
yym15 := z.DecBinary()
_ = yym15
if false {
} else {
*((*bool)(yyv14)) = r.DecodeBool()
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
@@ -341,16 +372,16 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj14 int
var yyb14 bool
var yyhl14 bool = l >= 0
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
var yyj16 int
var yyb16 bool
var yyhl16 bool = l >= 0
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb14 = r.CheckBreak()
yyb16 = r.CheckBreak()
}
if yyb14 {
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -358,29 +389,7 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
if r.TryDecodeAsNil() {
x.Kind = ""
} else {
yyv15 := &x.Kind
yym16 := z.DecBinary()
_ = yym16
if false {
} else {
*((*string)(yyv15)) = r.DecodeString()
}
}
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb14 = r.CheckBreak()
}
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
yyv17 := &x.APIVersion
yyv17 := &x.Kind
yym18 := z.DecBinary()
_ = yym18
if false {
@@ -388,13 +397,35 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
*((*string)(yyv17)) = r.DecodeString()
}
}
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb14 = r.CheckBreak()
yyb16 = r.CheckBreak()
}
if yyb14 {
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
yyv19 := &x.APIVersion
yym20 := z.DecBinary()
_ = yym20
if false {
} else {
*((*string)(yyv19)) = r.DecodeString()
}
}
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb16 = r.CheckBreak()
}
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -402,22 +433,22 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
if r.TryDecodeAsNil() {
x.DeschedulingInterval = 0
} else {
yyv19 := &x.DeschedulingInterval
yym20 := z.DecBinary()
_ = yym20
yyv21 := &x.DeschedulingInterval
yym22 := z.DecBinary()
_ = yym22
if false {
} else if z.HasExtensions() && z.DecExt(yyv19) {
} else if z.HasExtensions() && z.DecExt(yyv21) {
} else {
*((*int64)(yyv19)) = int64(r.DecodeInt(64))
*((*int64)(yyv21)) = int64(r.DecodeInt(64))
}
}
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb14 = r.CheckBreak()
yyb16 = r.CheckBreak()
}
if yyb14 {
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -425,29 +456,7 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
if r.TryDecodeAsNil() {
x.KubeconfigFile = ""
} else {
yyv21 := &x.KubeconfigFile
yym22 := z.DecBinary()
_ = yym22
if false {
} else {
*((*string)(yyv21)) = r.DecodeString()
}
}
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb14 = r.CheckBreak()
}
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.PolicyConfigFile = ""
} else {
yyv23 := &x.PolicyConfigFile
yyv23 := &x.KubeconfigFile
yym24 := z.DecBinary()
_ = yym24
if false {
@@ -455,18 +464,62 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
*((*string)(yyv23)) = r.DecodeString()
}
}
for {
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb16 = r.CheckBreak()
}
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.PolicyConfigFile = ""
} else {
yyv25 := &x.PolicyConfigFile
yym26 := z.DecBinary()
_ = yym26
if false {
} else {
yyb14 = r.CheckBreak()
*((*string)(yyv25)) = r.DecodeString()
}
if yyb14 {
}
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb16 = r.CheckBreak()
}
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.DryRun = false
} else {
yyv27 := &x.DryRun
yym28 := z.DecBinary()
_ = yym28
if false {
} else {
*((*bool)(yyv27)) = r.DecodeBool()
}
}
for {
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb16 = r.CheckBreak()
}
if yyb16 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj14-1, "")
z.DecStructFieldNotFound(yyj16-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}

View File

@@ -34,4 +34,7 @@ type DeschedulerConfiguration struct {
// PolicyConfigFile is the filepath to the descheduler policy configuration.
PolicyConfigFile string
// Dry run
DryRun bool
}

View File

@@ -81,16 +81,17 @@ func (x *DeschedulerConfiguration) CodecEncodeSelf(e *codec1978.Encoder) {
} else {
yysep2 := !z.EncBinary()
yy2arr2 := z.EncBasicHandle().StructToArray
var yyq2 [5]bool
var yyq2 [6]bool
_, _, _ = yysep2, yyq2, yy2arr2
const yyr2 bool = false
yyq2[0] = x.Kind != ""
yyq2[1] = x.APIVersion != ""
yyq2[2] = x.DeschedulingInterval != 0
yyq2[4] = x.PolicyConfigFile != ""
yyq2[5] = x.DryRun != false
var yynn2 int
if yyr2 || yy2arr2 {
r.EncodeArrayStart(5)
r.EncodeArrayStart(6)
} else {
yynn2 = 1
for _, b := range yyq2 {
@@ -222,6 +223,31 @@ func (x *DeschedulerConfiguration) CodecEncodeSelf(e *codec1978.Encoder) {
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayElem1234)
if yyq2[5] {
yym19 := z.EncBinary()
_ = yym19
if false {
} else {
r.EncodeBool(bool(x.DryRun))
}
} else {
r.EncodeBool(false)
}
} else {
if yyq2[5] {
z.EncSendContainerState(codecSelfer_containerMapKey1234)
r.EncodeString(codecSelferC_UTF81234, string("dryRun"))
z.EncSendContainerState(codecSelfer_containerMapValue1234)
yym20 := z.EncBinary()
_ = yym20
if false {
} else {
r.EncodeBool(bool(x.DryRun))
}
}
}
if yyr2 || yy2arr2 {
z.EncSendContainerState(codecSelfer_containerArrayEnd1234)
} else {
@@ -344,6 +370,18 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromMap(l int, d *codec1978.De
*((*string)(yyv12)) = r.DecodeString()
}
}
case "dryRun":
if r.TryDecodeAsNil() {
x.DryRun = false
} else {
yyv14 := &x.DryRun
yym15 := z.DecBinary()
_ = yym15
if false {
} else {
*((*bool)(yyv14)) = r.DecodeBool()
}
}
default:
z.DecStructFieldNotFound(-1, yys3)
} // end switch yys3
@@ -355,16 +393,16 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
var h codecSelfer1234
z, r := codec1978.GenHelperDecoder(d)
_, _, _ = h, z, r
var yyj14 int
var yyb14 bool
var yyhl14 bool = l >= 0
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
var yyj16 int
var yyb16 bool
var yyhl16 bool = l >= 0
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb14 = r.CheckBreak()
yyb16 = r.CheckBreak()
}
if yyb14 {
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -372,29 +410,7 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
if r.TryDecodeAsNil() {
x.Kind = ""
} else {
yyv15 := &x.Kind
yym16 := z.DecBinary()
_ = yym16
if false {
} else {
*((*string)(yyv15)) = r.DecodeString()
}
}
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb14 = r.CheckBreak()
}
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
yyv17 := &x.APIVersion
yyv17 := &x.Kind
yym18 := z.DecBinary()
_ = yym18
if false {
@@ -402,13 +418,35 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
*((*string)(yyv17)) = r.DecodeString()
}
}
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb14 = r.CheckBreak()
yyb16 = r.CheckBreak()
}
if yyb14 {
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.APIVersion = ""
} else {
yyv19 := &x.APIVersion
yym20 := z.DecBinary()
_ = yym20
if false {
} else {
*((*string)(yyv19)) = r.DecodeString()
}
}
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb16 = r.CheckBreak()
}
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -416,22 +454,22 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
if r.TryDecodeAsNil() {
x.DeschedulingInterval = 0
} else {
yyv19 := &x.DeschedulingInterval
yym20 := z.DecBinary()
_ = yym20
yyv21 := &x.DeschedulingInterval
yym22 := z.DecBinary()
_ = yym22
if false {
} else if z.HasExtensions() && z.DecExt(yyv19) {
} else if z.HasExtensions() && z.DecExt(yyv21) {
} else {
*((*int64)(yyv19)) = int64(r.DecodeInt(64))
*((*int64)(yyv21)) = int64(r.DecodeInt(64))
}
}
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb14 = r.CheckBreak()
yyb16 = r.CheckBreak()
}
if yyb14 {
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
@@ -439,29 +477,7 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
if r.TryDecodeAsNil() {
x.KubeconfigFile = ""
} else {
yyv21 := &x.KubeconfigFile
yym22 := z.DecBinary()
_ = yym22
if false {
} else {
*((*string)(yyv21)) = r.DecodeString()
}
}
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
} else {
yyb14 = r.CheckBreak()
}
if yyb14 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.PolicyConfigFile = ""
} else {
yyv23 := &x.PolicyConfigFile
yyv23 := &x.KubeconfigFile
yym24 := z.DecBinary()
_ = yym24
if false {
@@ -469,18 +485,62 @@ func (x *DeschedulerConfiguration) codecDecodeSelfFromArray(l int, d *codec1978.
*((*string)(yyv23)) = r.DecodeString()
}
}
for {
yyj14++
if yyhl14 {
yyb14 = yyj14 > l
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb16 = r.CheckBreak()
}
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.PolicyConfigFile = ""
} else {
yyv25 := &x.PolicyConfigFile
yym26 := z.DecBinary()
_ = yym26
if false {
} else {
yyb14 = r.CheckBreak()
*((*string)(yyv25)) = r.DecodeString()
}
if yyb14 {
}
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb16 = r.CheckBreak()
}
if yyb16 {
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
return
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
if r.TryDecodeAsNil() {
x.DryRun = false
} else {
yyv27 := &x.DryRun
yym28 := z.DecBinary()
_ = yym28
if false {
} else {
*((*bool)(yyv27)) = r.DecodeBool()
}
}
for {
yyj16++
if yyhl16 {
yyb16 = yyj16 > l
} else {
yyb16 = r.CheckBreak()
}
if yyb16 {
break
}
z.DecSendContainerState(codecSelfer_containerArrayElem1234)
z.DecStructFieldNotFound(yyj14-1, "")
z.DecStructFieldNotFound(yyj16-1, "")
}
z.DecSendContainerState(codecSelfer_containerArrayEnd1234)
}

View File

@@ -33,5 +33,8 @@ type DeschedulerConfiguration struct {
KubeconfigFile string `json:"kubeconfigFile"`
// PolicyConfigFile is the filepath to the descheduler policy configuration.
PolicyConfigFile string `json:"policyConfigFile,,omitempty"`
PolicyConfigFile string `json:"policyConfigFile,omitempty"`
// Dry run
DryRun bool `json:"dryRun,omitempty"`
}

View File

@@ -44,6 +44,7 @@ func autoConvert_v1alpha1_DeschedulerConfiguration_To_componentconfig_Deschedule
out.DeschedulingInterval = time.Duration(in.DeschedulingInterval)
out.KubeconfigFile = in.KubeconfigFile
out.PolicyConfigFile = in.PolicyConfigFile
out.DryRun = in.DryRun
return nil
}
@@ -56,6 +57,7 @@ func autoConvert_componentconfig_DeschedulerConfiguration_To_v1alpha1_Deschedule
out.DeschedulingInterval = time.Duration(in.DeschedulingInterval)
out.KubeconfigFile = in.KubeconfigFile
out.PolicyConfigFile = in.PolicyConfigFile
out.DryRun = in.DryRun
return nil
}

View File

@@ -53,8 +53,8 @@ func Run(rs *options.DeschedulerServer) error {
return err
}
strategies.RemoveDuplicatePods(rs.Client, deschedulerPolicy.Strategies["RemoveDuplicates"], evictionPolicyGroupVersion, nodes)
strategies.LowNodeUtilization(rs.Client, deschedulerPolicy.Strategies["LowNodeUtilization"], evictionPolicyGroupVersion, nodes)
strategies.RemoveDuplicatePods(rs, deschedulerPolicy.Strategies["RemoveDuplicates"], evictionPolicyGroupVersion, nodes)
strategies.LowNodeUtilization(rs, deschedulerPolicy.Strategies["LowNodeUtilization"], evictionPolicyGroupVersion, nodes)
return nil
}

View File

@@ -28,7 +28,10 @@ import (
eutils "github.com/kubernetes-incubator/descheduler/pkg/descheduler/evictions/utils"
)
func EvictPod(client clientset.Interface, pod *v1.Pod, policyGroupVersion string) (bool, error) {
func EvictPod(client clientset.Interface, pod *v1.Pod, policyGroupVersion string, dryRun bool) (bool, error) {
if dryRun {
return true, nil
}
deleteOptions := &metav1.DeleteOptions{}
// GracePeriodSeconds ?
eviction := &policy.Eviction{

View File

@@ -32,7 +32,7 @@ func TestEvictPod(t *testing.T) {
fakeClient.Fake.AddReactor("list", "pods", func(action core.Action) (bool, runtime.Object, error) {
return true, &v1.PodList{Items: []v1.Pod{*p1}}, nil
})
evicted, _ := EvictPod(fakeClient, p1, "v1")
evicted, _ := EvictPod(fakeClient, p1, "v1", false)
if !evicted {
t.Errorf("Expected %v pod to be evicted", p1.Name)
}

View File

@@ -24,6 +24,7 @@ import (
//TODO: Change to client-go instead of generated clientset.
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"github.com/kubernetes-incubator/descheduler/cmd/descheduler/app/options"
"github.com/kubernetes-incubator/descheduler/pkg/api"
"github.com/kubernetes-incubator/descheduler/pkg/descheduler/evictions"
podutil "github.com/kubernetes-incubator/descheduler/pkg/descheduler/pod"
@@ -35,15 +36,15 @@ type DuplicatePodsMap map[string][]*v1.Pod
// RemoveDuplicatePods removes the duplicate pods on node. This strategy evicts all duplicate pods on node.
// A pod is said to be a duplicate of other if both of them are from same creator, kind and are within the same
// namespace. As of now, this strategy won't evict daemonsets, mirror pods, critical pods and pods with local storages.
func RemoveDuplicatePods(client clientset.Interface, strategy api.DeschedulerStrategy, policyGroupVersion string, nodes []*v1.Node) {
func RemoveDuplicatePods(ds *options.DeschedulerServer, strategy api.DeschedulerStrategy, policyGroupVersion string, nodes []*v1.Node) {
if !strategy.Enabled {
return
}
deleteDuplicatePods(client, policyGroupVersion, nodes)
deleteDuplicatePods(ds.Client, policyGroupVersion, nodes, ds.DryRun)
}
// deleteDuplicatePods evicts the pod from node and returns the count of evicted pods.
func deleteDuplicatePods(client clientset.Interface, policyGroupVersion string, nodes []*v1.Node) int {
func deleteDuplicatePods(client clientset.Interface, policyGroupVersion string, nodes []*v1.Node, dryRun bool) int {
podsEvicted := 0
for _, node := range nodes {
fmt.Printf("\nProcessing node: %#v\n", node.Name)
@@ -54,7 +55,7 @@ func deleteDuplicatePods(client clientset.Interface, policyGroupVersion string,
// i = 0 does not evict the first pod
for i := 1; i < len(pods); i++ {
//fmt.Printf("Removing duplicate pod %#v\n", k.Name)
success, err := evictions.EvictPod(client, pods[i], policyGroupVersion)
success, err := evictions.EvictPod(client, pods[i], policyGroupVersion, dryRun)
if !success {
//TODO: change fmt.Printf as glogs.
fmt.Printf("Error when evicting pod: %#v (%#v)\n", pods[i].Name, err)

View File

@@ -71,7 +71,7 @@ func TestFindDuplicatePods(t *testing.T) {
fakeClient.Fake.AddReactor("get", "nodes", func(action core.Action) (bool, runtime.Object, error) {
return true, node, nil
})
podsEvicted := deleteDuplicatePods(fakeClient, "v1", []*v1.Node{node})
podsEvicted := deleteDuplicatePods(fakeClient, "v1", []*v1.Node{node}, false)
if podsEvicted != expectedEvictedPodCount {
t.Errorf("Unexpected no of pods evicted")
}

View File

@@ -25,6 +25,7 @@ import (
helper "k8s.io/kubernetes/pkg/api/v1/resource"
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"github.com/kubernetes-incubator/descheduler/cmd/descheduler/app/options"
"github.com/kubernetes-incubator/descheduler/pkg/api"
"github.com/kubernetes-incubator/descheduler/pkg/descheduler/evictions"
podutil "github.com/kubernetes-incubator/descheduler/pkg/descheduler/pod"
@@ -39,7 +40,7 @@ type NodeUsageMap struct {
}
type NodePodsMap map[*v1.Node][]*v1.Pod
func LowNodeUtilization(client clientset.Interface, strategy api.DeschedulerStrategy, evictionPolicyGroupVersion string, nodes []*v1.Node) {
func LowNodeUtilization(ds *options.DeschedulerServer, strategy api.DeschedulerStrategy, evictionPolicyGroupVersion string, nodes []*v1.Node) {
if !strategy.Enabled {
return
}
@@ -55,7 +56,7 @@ func LowNodeUtilization(client clientset.Interface, strategy api.DeschedulerStra
return
}
npm := CreateNodePodsMap(client, nodes)
npm := CreateNodePodsMap(ds.Client, nodes)
lowNodes, targetNodes, _ := classifyNodes(npm, thresholds, targetThresholds)
if len(lowNodes) == 0 {
@@ -71,7 +72,7 @@ func LowNodeUtilization(client clientset.Interface, strategy api.DeschedulerStra
fmt.Printf("no node is above target utilization\n")
return
}
evictPodsFromTargetNodes(client, evictionPolicyGroupVersion, targetNodes, lowNodes, targetThresholds)
evictPodsFromTargetNodes(ds.Client, evictionPolicyGroupVersion, targetNodes, lowNodes, targetThresholds, ds.DryRun)
}
func validateThresholds(thresholds api.ResourceThresholds) bool {
@@ -123,7 +124,7 @@ func classifyNodes(npm NodePodsMap, thresholds api.ResourceThresholds, targetThr
return lowNodes, targetNodes, otherNodes
}
func evictPodsFromTargetNodes(client clientset.Interface, evictionPolicyGroupVersion string, targetNodes []NodeUsageMap, lowNodes []NodeUsageMap, targetThresholds api.ResourceThresholds) int {
func evictPodsFromTargetNodes(client clientset.Interface, evictionPolicyGroupVersion string, targetNodes []NodeUsageMap, lowNodes []NodeUsageMap, targetThresholds api.ResourceThresholds, dryRun bool) int {
podsEvicted := 0
SortNodesByUsage(targetNodes)
@@ -149,7 +150,7 @@ func evictPodsFromTargetNodes(client clientset.Interface, evictionPolicyGroupVer
onePodPercentage := api.Percentage((float64(1) * 100) / float64(nodeCapcity.Pods().Value()))
if nodePodsUsage > targetThresholds[v1.ResourcePods] && totalPods > 0 {
for _, pod := range node.bePods {
success, err := evictions.EvictPod(client, pod, evictionPolicyGroupVersion)
success, err := evictions.EvictPod(client, pod, evictionPolicyGroupVersion, dryRun)
if !success {
fmt.Printf("Error when evicting pod: %#v (%#v)\n", pod.Name, err)
} else {
@@ -164,7 +165,7 @@ func evictPodsFromTargetNodes(client clientset.Interface, evictionPolicyGroupVer
}
if nodePodsUsage > targetThresholds[v1.ResourcePods] && totalPods > 0 {
for _, pod := range node.otherPods {
success, err := evictions.EvictPod(client, pod, evictionPolicyGroupVersion)
success, err := evictions.EvictPod(client, pod, evictionPolicyGroupVersion, dryRun)
if !success {
fmt.Printf("Error when evicting pod: %#v (%#v)\n", pod.Name, err)
} else {

View File

@@ -103,7 +103,7 @@ func TestLowNodeUtilization(t *testing.T) {
expectedPodsEvicted := 4
npm := CreateNodePodsMap(fakeClient, []*v1.Node{n1, n2})
lowNodes, targetNodes, _ := classifyNodes(npm, thresholds, targetThresholds)
podsEvicted := evictPodsFromTargetNodes(fakeClient, "v1", targetNodes, lowNodes, targetThresholds)
podsEvicted := evictPodsFromTargetNodes(fakeClient, "v1", targetNodes, lowNodes, targetThresholds, false)
if expectedPodsEvicted != podsEvicted {
t.Errorf("Expected %#v pods to be evicted but %#v got evicted", expectedPodsEvicted)
}