Skip to content

Commit b035d04

Browse files
committed
wip: add support for deployments in oc status
1 parent d4061a5 commit b035d04

File tree

19 files changed

+773
-106
lines changed

19 files changed

+773
-106
lines changed

pkg/oc/admin/prune/imageprune/prune.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ func (p *pruner) addDeploymentsToGraph(dmnts *kapisext.DeploymentList) []error {
578578
d := &dmnts.Items[i]
579579
ref := getRef(d)
580580
glog.V(4).Infof("Examining %s", getKindName(ref))
581-
dNode := appsgraph.EnsureDeploymentNode(p.g, d)
581+
dNode := kubegraph.EnsureDeploymentNode(p.g, d)
582582
errs = append(errs, p.addPodSpecToGraph(ref, &d.Spec.Template.Spec, dNode)...)
583583
}
584584

pkg/oc/cli/describe/deployments.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -473,12 +473,12 @@ func (d *LatestDeploymentsDescriber) Describe(namespace, name string) (string, e
473473
for i := range deployments {
474474
kubegraph.EnsureReplicationControllerNode(g, &deployments[i])
475475
}
476-
appsedges.AddTriggerEdges(g, dcNode)
477-
appsedges.AddDeploymentEdges(g, dcNode)
476+
appsedges.AddTriggerDeploymentConfigsEdges(g, dcNode)
477+
appsedges.AddDeploymentConfigsDeploymentEdges(g, dcNode)
478478
activeDeployment, inactiveDeployments := appsedges.RelevantDeployments(g, dcNode)
479479

480480
return tabbedString(func(out *tabwriter.Writer) error {
481-
descriptions := describeDeployments(f, dcNode, activeDeployment, inactiveDeployments, nil, d.count)
481+
descriptions := describeDeploymentConfigDeployments(f, dcNode, activeDeployment, inactiveDeployments, nil, d.count)
482482
for i, description := range descriptions {
483483
descriptions[i] = fmt.Sprintf("%v %v", name, description)
484484
}

pkg/oc/cli/describe/projectstatus.go

Lines changed: 189 additions & 21 deletions
Large diffs are not rendered by default.

pkg/oc/graph/appsgraph/analysis/dc_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func TestMissingImageStreamTag(t *testing.T) {
1616
t.Fatalf("unexpected error: %v", err)
1717
}
1818
buildedges.AddAllInputOutputEdges(g)
19-
appsedges.AddAllTriggerEdges(g)
19+
appsedges.AddAllTriggerDeploymentConfigsEdges(g)
2020
imageedges.AddAllImageStreamRefEdges(g)
2121
imageedges.AddAllImageStreamImageRefEdges(g)
2222

@@ -36,7 +36,7 @@ func TestMissingImageStream(t *testing.T) {
3636
t.Fatalf("unexpected error: %v", err)
3737
}
3838
buildedges.AddAllInputOutputEdges(g)
39-
appsedges.AddAllTriggerEdges(g)
39+
appsedges.AddAllTriggerDeploymentConfigsEdges(g)
4040
imageedges.AddAllImageStreamRefEdges(g)
4141
imageedges.AddAllImageStreamImageRefEdges(g)
4242

@@ -56,7 +56,7 @@ func TestMissingReadinessProbe(t *testing.T) {
5656
t.Fatalf("unexpected error: %v", err)
5757
}
5858
buildedges.AddAllInputOutputEdges(g)
59-
appsedges.AddAllTriggerEdges(g)
59+
appsedges.AddAllTriggerDeploymentConfigsEdges(g)
6060
imageedges.AddAllImageStreamRefEdges(g)
6161

6262
markers := FindDeploymentConfigReadinessWarnings(g, osgraph.DefaultNamer, "command probe")

pkg/oc/graph/appsgraph/edge_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func TestNamespaceEdgeMatching(t *testing.T) {
3939

4040
fn("ns", g)
4141
fn("other", g)
42-
AddAllDeploymentEdges(g)
42+
AddAllDeploymentConfigsDeploymentEdges(g)
4343

4444
if len(g.Edges()) != 4 {
4545
t.Fatal(g)

pkg/oc/graph/appsgraph/edges.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ const (
2727
VolumeClaimEdgeKind = "VolumeClaim"
2828
)
2929

30-
// AddTriggerEdges creates edges that point to named Docker image repositories for each image used in the deployment.
31-
func AddTriggerEdges(g osgraph.MutableUniqueGraph, node *appsgraph.DeploymentConfigNode) *appsgraph.DeploymentConfigNode {
30+
// AddTriggerDeploymentConfigsEdges creates edges that point to named Docker image repositories for each image used in the deployment.
31+
func AddTriggerDeploymentConfigsEdges(g osgraph.MutableUniqueGraph, node *appsgraph.DeploymentConfigNode) *appsgraph.DeploymentConfigNode {
3232
podTemplate := node.DeploymentConfig.Spec.Template
3333
if podTemplate == nil {
3434
return node
@@ -60,15 +60,15 @@ func AddTriggerEdges(g osgraph.MutableUniqueGraph, node *appsgraph.DeploymentCon
6060
return node
6161
}
6262

63-
func AddAllTriggerEdges(g osgraph.MutableUniqueGraph) {
63+
func AddAllTriggerDeploymentConfigsEdges(g osgraph.MutableUniqueGraph) {
6464
for _, node := range g.(graph.Graph).Nodes() {
6565
if dcNode, ok := node.(*appsgraph.DeploymentConfigNode); ok {
66-
AddTriggerEdges(g, dcNode)
66+
AddTriggerDeploymentConfigsEdges(g, dcNode)
6767
}
6868
}
6969
}
7070

71-
func AddDeploymentEdges(g osgraph.MutableUniqueGraph, node *appsgraph.DeploymentConfigNode) *appsgraph.DeploymentConfigNode {
71+
func AddDeploymentConfigsDeploymentEdges(g osgraph.MutableUniqueGraph, node *appsgraph.DeploymentConfigNode) *appsgraph.DeploymentConfigNode {
7272
for _, n := range g.(graph.Graph).Nodes() {
7373
if rcNode, ok := n.(*kubegraph.ReplicationControllerNode); ok {
7474
if rcNode.ReplicationController.Namespace != node.DeploymentConfig.Namespace {
@@ -84,10 +84,10 @@ func AddDeploymentEdges(g osgraph.MutableUniqueGraph, node *appsgraph.Deployment
8484
return node
8585
}
8686

87-
func AddAllDeploymentEdges(g osgraph.MutableUniqueGraph) {
87+
func AddAllDeploymentConfigsDeploymentEdges(g osgraph.MutableUniqueGraph) {
8888
for _, node := range g.(graph.Graph).Nodes() {
8989
if dcNode, ok := node.(*appsgraph.DeploymentConfigNode); ok {
90-
AddDeploymentEdges(g, dcNode)
90+
AddDeploymentConfigsDeploymentEdges(g, dcNode)
9191
}
9292
}
9393
}

pkg/oc/graph/appsgraph/nodes/nodes.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,33 +37,6 @@ 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-
6740
// EnsureDeploymentConfigNode adds the provided deployment config to the graph if it does not exist
6841
func EnsureDeploymentConfigNode(g osgraph.MutableUniqueGraph, dc *appsapi.DeploymentConfig) *DeploymentConfigNode {
6942
dcName := DeploymentConfigNodeName(dc)

pkg/oc/graph/appsgraph/nodes/types.go

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -43,33 +43,6 @@ func (*DaemonSetNode) Kind() string {
4343
return DaemonSetNodeKind
4444
}
4545

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

pkg/oc/graph/genericgraph/graphview/dc_pipeline.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
)
1111

1212
type DeploymentConfigPipeline struct {
13-
Deployment *appsgraph.DeploymentConfigNode
13+
DeploymentConfig *appsgraph.DeploymentConfigNode
1414

1515
ActiveDeployment *kubegraph.ReplicationControllerNode
1616
InactiveDeployments []*kubegraph.ReplicationControllerNode
@@ -43,7 +43,7 @@ func NewDeploymentConfigPipeline(g osgraph.Graph, dcNode *appsgraph.DeploymentCo
4343
covered.Insert(dcNode.ID())
4444

4545
dcPipeline := DeploymentConfigPipeline{}
46-
dcPipeline.Deployment = dcNode
46+
dcPipeline.DeploymentConfig = dcNode
4747

4848
// for everything that can trigger a deployment, create an image pipeline and add it to the list
4949
for _, istNode := range g.PredecessorNodesByEdgeKind(dcNode, appsedges.TriggersDeploymentEdgeKind) {
@@ -80,5 +80,5 @@ type SortedDeploymentConfigPipeline []DeploymentConfigPipeline
8080
func (m SortedDeploymentConfigPipeline) Len() int { return len(m) }
8181
func (m SortedDeploymentConfigPipeline) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
8282
func (m SortedDeploymentConfigPipeline) Less(i, j int) bool {
83-
return CompareObjectMeta(&m[i].Deployment.DeploymentConfig.ObjectMeta, &m[j].Deployment.DeploymentConfig.ObjectMeta)
83+
return CompareObjectMeta(&m[i].DeploymentConfig.DeploymentConfig.ObjectMeta, &m[j].DeploymentConfig.DeploymentConfig.ObjectMeta)
8484
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package graphview
2+
3+
import (
4+
appsedges "github.com/openshift/origin/pkg/oc/graph/appsgraph"
5+
osgraph "github.com/openshift/origin/pkg/oc/graph/genericgraph"
6+
kubeedges "github.com/openshift/origin/pkg/oc/graph/kubegraph"
7+
kubegraph "github.com/openshift/origin/pkg/oc/graph/kubegraph/nodes"
8+
)
9+
10+
type Deployment struct {
11+
Deployment *kubegraph.DeploymentNode
12+
13+
ActiveDeployment *kubegraph.ReplicaSetNode
14+
InactiveDeployments []*kubegraph.ReplicaSetNode
15+
16+
Images []ImagePipeline
17+
18+
// TODO: handle conflicting once controller refs are present, not worth it yet
19+
}
20+
21+
// AllDeployments returns all the Deployments that aren't in the excludes set and the set of covered NodeIDs
22+
func AllDeployments(g osgraph.Graph, excludeNodeIDs IntSet) ([]Deployment, IntSet) {
23+
covered := IntSet{}
24+
views := []Deployment{}
25+
26+
for _, uncastNode := range g.NodesByKind(kubegraph.DeploymentNodeKind) {
27+
if excludeNodeIDs.Has(uncastNode.ID()) {
28+
continue
29+
}
30+
31+
view, covers := NewDeployment(g, uncastNode.(*kubegraph.DeploymentNode))
32+
covered.Insert(covers.List()...)
33+
views = append(views, view)
34+
}
35+
36+
return views, covered
37+
}
38+
39+
// NewDeployment returns the Deployment and a set of all the NodeIDs covered by the Deployment
40+
func NewDeployment(g osgraph.Graph, node *kubegraph.DeploymentNode) (Deployment, IntSet) {
41+
covered := IntSet{}
42+
covered.Insert(node.ID())
43+
44+
view := Deployment{}
45+
view.Deployment = node
46+
47+
for _, istNode := range g.PredecessorNodesByEdgeKind(node, kubeedges.TriggersDeploymentEdgeKind) {
48+
imagePipeline, covers := NewImagePipelineFromImageTagLocation(g, istNode, istNode.(ImageTagLocation))
49+
covered.Insert(covers.List()...)
50+
view.Images = append(view.Images, imagePipeline)
51+
}
52+
53+
// for image that we use, create an image pipeline and add it to the list
54+
for _, tagNode := range g.PredecessorNodesByEdgeKind(node, appsedges.UsedInDeploymentEdgeKind) {
55+
imagePipeline, covers := NewImagePipelineFromImageTagLocation(g, tagNode, tagNode.(ImageTagLocation))
56+
57+
covered.Insert(covers.List()...)
58+
view.Images = append(view.Images, imagePipeline)
59+
}
60+
61+
view.ActiveDeployment, view.InactiveDeployments = kubeedges.RelevantDeployments(g, view.Deployment)
62+
for _, rs := range view.InactiveDeployments {
63+
_, covers := NewReplicaSet(g, rs)
64+
covered.Insert(covers.List()...)
65+
}
66+
67+
if view.ActiveDeployment != nil {
68+
_, covers := NewReplicaSet(g, view.ActiveDeployment)
69+
covered.Insert(covers.List()...)
70+
}
71+
72+
return view, covered
73+
}

pkg/oc/graph/genericgraph/graphview/petset.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package graphview
22

33
import (
4+
appsedges "github.com/openshift/origin/pkg/oc/graph/appsgraph"
45
osgraph "github.com/openshift/origin/pkg/oc/graph/genericgraph"
56
kubeedges "github.com/openshift/origin/pkg/oc/graph/kubegraph"
67
kubegraph "github.com/openshift/origin/pkg/oc/graph/kubegraph/nodes"
@@ -12,6 +13,8 @@ type StatefulSet struct {
1213
OwnedPods []*kubegraph.PodNode
1314
CreatedPods []*kubegraph.PodNode
1415

16+
Images []ImagePipeline
17+
1518
// TODO: handle conflicting once controller refs are present, not worth it yet
1619
}
1720

@@ -47,5 +50,19 @@ func NewStatefulSet(g osgraph.Graph, node *kubegraph.StatefulSetNode) (StatefulS
4750
view.OwnedPods = append(view.OwnedPods, podNode)
4851
}
4952

53+
for _, istNode := range g.PredecessorNodesByEdgeKind(node, kubeedges.TriggersDeploymentEdgeKind) {
54+
imagePipeline, covers := NewImagePipelineFromImageTagLocation(g, istNode, istNode.(ImageTagLocation))
55+
covered.Insert(covers.List()...)
56+
view.Images = append(view.Images, imagePipeline)
57+
}
58+
59+
// for image that we use, create an image pipeline and add it to the list
60+
for _, tagNode := range g.PredecessorNodesByEdgeKind(node, appsedges.UsedInDeploymentEdgeKind) {
61+
imagePipeline, covers := NewImagePipelineFromImageTagLocation(g, tagNode, tagNode.(ImageTagLocation))
62+
63+
covered.Insert(covers.List()...)
64+
view.Images = append(view.Images, imagePipeline)
65+
}
66+
5067
return view, covered
5168
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package graphview
2+
3+
import (
4+
osgraph "github.com/openshift/origin/pkg/oc/graph/genericgraph"
5+
kubeedges "github.com/openshift/origin/pkg/oc/graph/kubegraph"
6+
"github.com/openshift/origin/pkg/oc/graph/kubegraph/analysis"
7+
kubegraph "github.com/openshift/origin/pkg/oc/graph/kubegraph/nodes"
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
)
10+
11+
type ReplicaSet struct {
12+
RS *kubegraph.ReplicaSetNode
13+
14+
OwnedPods []*kubegraph.PodNode
15+
CreatedPods []*kubegraph.PodNode
16+
}
17+
18+
func AllReplicaSets(g osgraph.Graph, excludeNodeIDs IntSet) ([]ReplicaSet, IntSet) {
19+
covered := IntSet{}
20+
rsViews := []ReplicaSet{}
21+
22+
for _, uncastNode := range g.NodesByKind(kubegraph.ReplicaSetNodeKind) {
23+
if excludeNodeIDs.Has(uncastNode.ID()) {
24+
continue
25+
}
26+
27+
rsView, covers := NewReplicaSet(g, uncastNode.(*kubegraph.ReplicaSetNode))
28+
covered.Insert(covers.List()...)
29+
rsViews = append(rsViews, rsView)
30+
}
31+
32+
return rsViews, covered
33+
}
34+
35+
// MaxRecentContainerRestarts returns the maximum container restarts for all pods
36+
func (rs *ReplicaSet) MaxRecentContainerRestarts() int32 {
37+
var maxRestarts int32
38+
for _, pod := range rs.OwnedPods {
39+
for _, status := range pod.Status.ContainerStatuses {
40+
if status.RestartCount > maxRestarts && analysis.ContainerRestartedRecently(status, metav1.Now()) {
41+
maxRestarts = status.RestartCount
42+
}
43+
}
44+
}
45+
return maxRestarts
46+
}
47+
48+
// NewReplicationController returns the ReplicationController and a set of all the NodeIDs covered by the ReplicationController
49+
func NewReplicaSet(g osgraph.Graph, rsNode *kubegraph.ReplicaSetNode) (ReplicaSet, IntSet) {
50+
covered := IntSet{}
51+
covered.Insert(rsNode.ID())
52+
53+
rsView := ReplicaSet{}
54+
rsView.RS = rsNode
55+
56+
for _, uncastPodNode := range g.PredecessorNodesByEdgeKind(rsNode, kubeedges.ManagedByControllerEdgeKind) {
57+
podNode := uncastPodNode.(*kubegraph.PodNode)
58+
covered.Insert(podNode.ID())
59+
rsView.OwnedPods = append(rsView.OwnedPods, podNode)
60+
}
61+
62+
return rsView, covered
63+
}
64+
65+
func MaxRecentContainerRestartsForRS(g osgraph.Graph, rsNode *kubegraph.ReplicaSetNode) int32 {
66+
if rsNode == nil {
67+
return 0
68+
}
69+
rs, _ := NewReplicaSet(g, rsNode)
70+
return rs.MaxRecentContainerRestarts()
71+
}

0 commit comments

Comments
 (0)