Skip to content

Commit 4792054

Browse files
author
Michal Minář
committed
image-pruning: add upstream deployments to the graph
Signed-off-by: Michal Minář <[email protected]>
1 parent 8beba52 commit 4792054

File tree

6 files changed

+124
-8
lines changed

6 files changed

+124
-8
lines changed

pkg/apps/graph/nodes/nodes.go

+27
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,33 @@ func FindOrCreateSyntheticDaemonSetNode(g osgraph.MutableUniqueGraph, ds *kapise
3737
).(*DaemonSetNode)
3838
}
3939

40+
// EnsureDeploymentNode adds the provided upstream deployment to the graph if it does not exist
41+
func EnsureDeploymentNode(g osgraph.MutableUniqueGraph, deployment *kapisext.Deployment) *DeploymentNode {
42+
deploymentName := DeploymentNodeName(deployment)
43+
deploymentNode := osgraph.EnsureUnique(
44+
g,
45+
deploymentName,
46+
func(node osgraph.Node) graph.Node {
47+
return &DeploymentNode{Node: node, Deployment: deployment, IsFound: true}
48+
},
49+
).(*DeploymentNode)
50+
51+
podTemplateSpecNode := kubegraph.EnsurePodTemplateSpecNode(g, &deployment.Spec.Template, deployment.Namespace, deploymentName)
52+
g.AddEdge(deploymentNode, podTemplateSpecNode, osgraph.ContainsEdgeKind)
53+
54+
return deploymentNode
55+
}
56+
57+
func FindOrCreateSyntheticDeploymentNode(g osgraph.MutableUniqueGraph, deployment *kapisext.Deployment) *DeploymentNode {
58+
return osgraph.EnsureUnique(
59+
g,
60+
DeploymentNodeName(deployment),
61+
func(node osgraph.Node) graph.Node {
62+
return &DeploymentNode{Node: node, Deployment: deployment, IsFound: false}
63+
},
64+
).(*DeploymentNode)
65+
}
66+
4067
// EnsureDeploymentConfigNode adds the provided deployment config to the graph if it does not exist
4168
func EnsureDeploymentConfigNode(g osgraph.MutableUniqueGraph, dc *deployapi.DeploymentConfig) *DeploymentConfigNode {
4269
dcName := DeploymentConfigNodeName(dc)

pkg/apps/graph/nodes/types.go

+28
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
var (
1313
DaemonSetNodeKind = reflect.TypeOf(kapisext.DaemonSet{}).Name()
14+
DeploymentNodeKind = reflect.TypeOf(kapisext.Deployment{}).Name()
1415
DeploymentConfigNodeKind = reflect.TypeOf(deployapi.DeploymentConfig{}).Name()
1516
)
1617

@@ -41,6 +42,33 @@ func (*DaemonSetNode) Kind() string {
4142
return DaemonSetNodeKind
4243
}
4344

45+
func DeploymentNodeName(o *kapisext.Deployment) osgraph.UniqueName {
46+
return osgraph.GetUniqueRuntimeObjectNodeName(DeploymentNodeKind, o)
47+
}
48+
49+
type DeploymentNode struct {
50+
osgraph.Node
51+
Deployment *kapisext.Deployment
52+
53+
IsFound bool
54+
}
55+
56+
func (n DeploymentNode) Found() bool {
57+
return n.IsFound
58+
}
59+
60+
func (n DeploymentNode) Object() interface{} {
61+
return n.Deployment
62+
}
63+
64+
func (n DeploymentNode) String() string {
65+
return string(DeploymentNodeName(n.Deployment))
66+
}
67+
68+
func (*DeploymentNode) Kind() string {
69+
return DeploymentNodeKind
70+
}
71+
4472
func DeploymentConfigNodeName(o *deployapi.DeploymentConfig) osgraph.UniqueName {
4573
return osgraph.GetUniqueRuntimeObjectNodeName(DeploymentConfigNodeKind, o)
4674
}

pkg/cmd/server/bootstrappolicy/policy.go

+1
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ func GetOpenshiftBootstrapClusterRoles() []rbac.ClusterRole {
552552
rbac.NewRule("get", "list").Groups(buildGroup, legacyBuildGroup).Resources("buildconfigs", "builds").RuleOrDie(),
553553
rbac.NewRule("get", "list").Groups(deployGroup, legacyDeployGroup).Resources("deploymentconfigs").RuleOrDie(),
554554
rbac.NewRule("get", "list").Groups(extensionsGroup).Resources("daemonsets").RuleOrDie(),
555+
rbac.NewRule("get", "list").Groups(extensionsGroup).Resources("deployments").RuleOrDie(),
555556

556557
rbac.NewRule("delete").Groups(imageGroup, legacyImageGroup).Resources("images").RuleOrDie(),
557558
rbac.NewRule("get", "list").Groups(imageGroup, legacyImageGroup).Resources("images", "imagestreams").RuleOrDie(),

pkg/image/prune/prune.go

+17
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ type PrunerOptions struct {
137137
Builds *buildapi.BuildList
138138
// DSs is the entire list of daemon sets across all namespaces in the cluster.
139139
DSs *kapisext.DaemonSetList
140+
// Deployments is the entire list of kube's deployments across all namespaces in the cluster.
141+
Deployments *kapisext.DeploymentList
140142
// DCs is the entire list of deployment configs across all namespaces in the cluster.
141143
DCs *deployapi.DeploymentConfigList
142144
// LimitRanges is a map of LimitRanges across namespaces, being keys in this map.
@@ -201,6 +203,7 @@ var _ Pruner = &pruner{}
201203
// - any pending pods
202204
// - any replication controllers
203205
// - any daemonsets
206+
// - any kube deployments
204207
// - any deployment configs
205208
// - any build configs
206209
// - any builds
@@ -246,6 +249,7 @@ func NewPruner(options PrunerOptions) (Pruner, error) {
246249
return nil, err
247250
}
248251
addDaemonSetsToGraph(g, options.DSs)
252+
addDeploymentsToGraph(g, options.Deployments)
249253
addDeploymentConfigsToGraph(g, options.DCs)
250254

251255
return &pruner{
@@ -489,6 +493,19 @@ func addDaemonSetsToGraph(g graph.Graph, dss *kapisext.DaemonSetList) {
489493
}
490494
}
491495

496+
// addDeploymentsToGraph adds kube's deployments to the graph.
497+
//
498+
// Edges are added to the graph from each deployment to the images specified by its pod spec's list of
499+
// containers, as long as the image is managed by OpenShift.
500+
func addDeploymentsToGraph(g graph.Graph, dmnts *kapisext.DeploymentList) {
501+
for i := range dmnts.Items {
502+
d := &dmnts.Items[i]
503+
glog.V(4).Infof("Examining Deployment %s", getName(d))
504+
dNode := deploygraph.EnsureDeploymentNode(g, d)
505+
addPodSpecToGraph(g, &d.Spec.Template.Spec, dNode)
506+
}
507+
}
508+
492509
// addDeploymentConfigsToGraph adds deployment configs to the graph.
493510
//
494511
// Edges are added to the graph from each deployment config to the images

pkg/image/prune/prune_test.go

+42-8
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,26 @@ func ds(namespace, name string, containerImages ...string) kapisext.DaemonSet {
265265
}
266266
}
267267

268+
func deploymentList(deployments ...kapisext.Deployment) kapisext.DeploymentList {
269+
return kapisext.DeploymentList{
270+
Items: deployments,
271+
}
272+
}
273+
274+
func deployment(namespace, name string, containerImages ...string) kapisext.Deployment {
275+
return kapisext.Deployment{
276+
ObjectMeta: metav1.ObjectMeta{
277+
Namespace: namespace,
278+
Name: name,
279+
},
280+
Spec: kapisext.DeploymentSpec{
281+
Template: kapi.PodTemplateSpec{
282+
Spec: podSpec(containerImages...),
283+
},
284+
},
285+
}
286+
}
287+
268288
func dcList(dcs ...deployapi.DeploymentConfig) deployapi.DeploymentConfigList {
269289
return deployapi.DeploymentConfigList{
270290
Items: dcs,
@@ -501,6 +521,7 @@ func TestImagePruning(t *testing.T) {
501521
bcs buildapi.BuildConfigList
502522
builds buildapi.BuildList
503523
dss kapisext.DaemonSetList
524+
deployments kapisext.DeploymentList
504525
dcs deployapi.DeploymentConfigList
505526
limits map[string][]*kapi.LimitRange
506527
expectedImageDeletions []string
@@ -665,6 +686,15 @@ func TestImagePruning(t *testing.T) {
665686
expectedImageDeletions: []string{"sha256:0000000000000000000000000000000000000000000000000000000000000001"},
666687
},
667688

689+
"referenced by upstream deployment - don't prune": {
690+
images: imageList(
691+
image("sha256:0000000000000000000000000000000000000000000000000000000000000000", registryHost+"/foo/bar@sha256:0000000000000000000000000000000000000000000000000000000000000000"),
692+
image("sha256:0000000000000000000000000000000000000000000000000000000000000001", registryHost+"/foo/bar@sha256:0000000000000000000000000000000000000000000000000000000000000001"),
693+
),
694+
deployments: deploymentList(deployment("foo", "rc1", registryHost+"/foo/bar@sha256:0000000000000000000000000000000000000000000000000000000000000000")),
695+
expectedImageDeletions: []string{"sha256:0000000000000000000000000000000000000000000000000000000000000001"},
696+
},
697+
668698
"referenced by bc - sti - ImageStreamImage - don't prune": {
669699
images: imageList(image("sha256:0000000000000000000000000000000000000000000000000000000000000000", registryHost+"/foo/bar@sha256:0000000000000000000000000000000000000000000000000000000000000000")),
670700
bcs: bcList(bc("foo", "bc1", "source", "ImageStreamImage", "foo", "bar@sha256:0000000000000000000000000000000000000000000000000000000000000000")),
@@ -1175,6 +1205,7 @@ func TestImagePruning(t *testing.T) {
11751205
BCs: &test.bcs,
11761206
Builds: &test.builds,
11771207
DSs: &test.dss,
1208+
Deployments: &test.deployments,
11781209
DCs: &test.dcs,
11791210
LimitRanges: test.limits,
11801211
RegistryURL: &url.URL{Scheme: "https", Host: registryHost},
@@ -1422,6 +1453,7 @@ func TestRegistryPruning(t *testing.T) {
14221453
BCs: &buildapi.BuildConfigList{},
14231454
Builds: &buildapi.BuildList{},
14241455
DSs: &kapisext.DaemonSetList{},
1456+
Deployments: &kapisext.DeploymentList{},
14251457
DCs: &deployapi.DeploymentConfigList{},
14261458
RegistryURL: &url.URL{Scheme: "https", Host: "registry1.io"},
14271459
}
@@ -1481,17 +1513,19 @@ func TestImageWithStrongAndWeakRefsIsNotPruned(t *testing.T) {
14811513
bcs := bcList()
14821514
builds := buildList()
14831515
dss := dsList()
1516+
deployments := deploymentList()
14841517
dcs := dcList()
14851518

14861519
options := PrunerOptions{
1487-
Images: &images,
1488-
Streams: &streams,
1489-
Pods: &pods,
1490-
RCs: &rcs,
1491-
BCs: &bcs,
1492-
Builds: &builds,
1493-
DSs: &dss,
1494-
DCs: &dcs,
1520+
Images: &images,
1521+
Streams: &streams,
1522+
Pods: &pods,
1523+
RCs: &rcs,
1524+
BCs: &bcs,
1525+
Builds: &builds,
1526+
DSs: &dss,
1527+
Deployments: &deployments,
1528+
DCs: &dcs,
14951529
}
14961530
keepYoungerThan := 24 * time.Hour
14971531
keepTagRevisions := 2

pkg/oc/admin/prune/images.go

+9
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,14 @@ func (o PruneImagesOptions) Run() error {
270270
fmt.Fprintf(os.Stderr, "Failed to list daemonsets: %v\n - * Make sure to update clusterRoleBindings.\n", err)
271271
}
272272

273+
allDeployments, err := o.KubeClient.Extensions().Deployments(o.Namespace).List(metav1.ListOptions{})
274+
if err != nil {
275+
if !kerrors.IsForbidden(err) {
276+
return err
277+
}
278+
fmt.Fprintf(os.Stderr, "Failed to list deployments: %v\n - * Make sure to update clusterRoleBindings.\n", err)
279+
}
280+
273281
allDCs, err := o.AppsClient.DeploymentConfigs(o.Namespace).List(metav1.ListOptions{})
274282
if err != nil {
275283
return err
@@ -342,6 +350,7 @@ func (o PruneImagesOptions) Run() error {
342350
BCs: allBCs,
343351
Builds: allBuilds,
344352
DSs: allDSs,
353+
Deployments: allDeployments,
345354
DCs: allDCs,
346355
LimitRanges: limitRangesMap,
347356
DryRun: o.Confirm == false,

0 commit comments

Comments
 (0)