forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
prune.go
128 lines (110 loc) · 4.54 KB
/
prune.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package prune
import (
"time"
"github.com/golang/glog"
kapi "k8s.io/kubernetes/pkg/api"
kclient "k8s.io/kubernetes/pkg/client/unversioned"
deployapi "github.com/openshift/origin/pkg/deploy/api"
deployutil "github.com/openshift/origin/pkg/deploy/util"
)
type Pruner interface {
// Prune is responsible for actual removal of deployments identified as candidates
// for pruning based on pruning algorithm.
Prune(deleter DeploymentDeleter) error
}
// DeploymentDeleter knows how to delete deployments from OpenShift.
type DeploymentDeleter interface {
// DeleteDeployment removes the deployment from OpenShift's storage.
DeleteDeployment(deployment *kapi.ReplicationController) error
}
// pruner is an object that knows how to prune a data set
type pruner struct {
resolver Resolver
}
var _ Pruner = &pruner{}
// PrunerOptions contains the fields used to initialize a new Pruner.
type PrunerOptions struct {
// KeepYoungerThan will filter out all objects from prune data set that are younger than the specified time duration.
KeepYoungerThan time.Duration
// Orphans if true will include inactive orphan deployments in candidate prune set.
Orphans bool
// KeepComplete is per DeploymentConfig how many of the most recent deployments should be preserved.
KeepComplete int
// KeepFailed is per DeploymentConfig how many of the most recent failed deployments should be preserved.
KeepFailed int
// DeploymentConfigs is the entire list of deploymentconfigs across all namespaces in the cluster.
DeploymentConfigs []*deployapi.DeploymentConfig
// Deployments is the entire list of deployments across all namespaces in the cluster.
Deployments []*kapi.ReplicationController
}
// NewPruner returns a Pruner over specified data using specified options.
// deploymentConfigs, deployments, opts.KeepYoungerThan, opts.Orphans, opts.KeepComplete, opts.KeepFailed, deploymentPruneFunc
func NewPruner(options PrunerOptions) Pruner {
glog.V(1).Infof("Creating deployment pruner with keepYoungerThan=%v, orphans=%v, keepComplete=%v, keepFailed=%v",
options.KeepYoungerThan, options.Orphans, options.KeepComplete, options.KeepFailed)
filter := &andFilter{
filterPredicates: []FilterPredicate{
FilterDeploymentsPredicate,
FilterZeroReplicaSize,
NewFilterBeforePredicate(options.KeepYoungerThan),
},
}
deployments := filter.Filter(options.Deployments)
dataSet := NewDataSet(options.DeploymentConfigs, deployments)
resolvers := []Resolver{}
if options.Orphans {
inactiveDeploymentStatus := []deployapi.DeploymentStatus{
deployapi.DeploymentStatusComplete,
deployapi.DeploymentStatusFailed,
}
resolvers = append(resolvers, NewOrphanDeploymentResolver(dataSet, inactiveDeploymentStatus))
}
resolvers = append(resolvers, NewPerDeploymentConfigResolver(dataSet, options.KeepComplete, options.KeepFailed))
return &pruner{
resolver: &mergeResolver{resolvers: resolvers},
}
}
// Prune will visit each item in the prunable set and invoke the associated DeploymentDeleter.
func (p *pruner) Prune(deleter DeploymentDeleter) error {
deployments, err := p.resolver.Resolve()
if err != nil {
return err
}
for _, deployment := range deployments {
if err := deleter.DeleteDeployment(deployment); err != nil {
return err
}
}
return nil
}
// deploymentDeleter removes a deployment from OpenShift.
type deploymentDeleter struct {
deployments kclient.ReplicationControllersNamespacer
pods kclient.PodsNamespacer
}
var _ DeploymentDeleter = &deploymentDeleter{}
// NewDeploymentDeleter creates a new deploymentDeleter.
func NewDeploymentDeleter(deployments kclient.ReplicationControllersNamespacer, pods kclient.PodsNamespacer) DeploymentDeleter {
return &deploymentDeleter{
deployments: deployments,
pods: pods,
}
}
func (p *deploymentDeleter) DeleteDeployment(deployment *kapi.ReplicationController) error {
glog.V(4).Infof("Deleting deployment %q", deployment.Name)
// If the deployment is failed we need to remove its deployer pods, too.
if deployutil.IsFailedDeployment(deployment) {
dpSelector := deployutil.DeployerPodSelector(deployment.Name)
deployers, err := p.pods.Pods(deployment.Namespace).List(kapi.ListOptions{LabelSelector: dpSelector})
if err != nil {
glog.Warning("Cannot list deployer pods for %q: %v\n", deployment.Name, err)
} else {
for _, pod := range deployers.Items {
if err := p.pods.Pods(pod.Namespace).Delete(pod.Name, nil); err != nil {
glog.Warning("Cannot remove deployer pod %q: %v\n", pod.Name, err)
}
}
}
}
return p.deployments.ReplicationControllers(deployment.Namespace).Delete(deployment.Name, nil)
}