Skip to content

Commit 8106914

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

File tree

14 files changed

+670
-79
lines changed

14 files changed

+670
-79
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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ func (d *LatestDeploymentsDescriber) Describe(namespace, name string) (string, e
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: 154 additions & 14 deletions
Large diffs are not rendered by default.

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+
}
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+
}

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,16 @@ type ServiceGroup struct {
2121

2222
DeploymentConfigPipelines []DeploymentConfigPipeline
2323
ReplicationControllers []ReplicationController
24+
ReplicaSets []ReplicaSet
25+
Deployments []Deployment
2426
StatefulSets []StatefulSet
2527

2628
// TODO: this has to stop
2729
FulfillingStatefulSets []*kubegraph.StatefulSetNode
30+
FulfillingDeployments []*kubegraph.DeploymentNode
2831
FulfillingDCs []*appsgraph.DeploymentConfigNode
2932
FulfillingRCs []*kubegraph.ReplicationControllerNode
33+
FulfillingRSs []*kubegraph.ReplicaSetNode
3034
FulfillingPods []*kubegraph.PodNode
3135

3236
ExposingRoutes []*routegraph.RouteNode
@@ -67,12 +71,16 @@ func NewServiceGroup(g osgraph.Graph, serviceNode *kubegraph.ServiceNode) (Servi
6771
service.FulfillingDCs = append(service.FulfillingDCs, castContainer)
6872
case *kubegraph.ReplicationControllerNode:
6973
service.FulfillingRCs = append(service.FulfillingRCs, castContainer)
74+
case *kubegraph.ReplicaSetNode:
75+
service.FulfillingRSs = append(service.FulfillingRSs, castContainer)
7076
case *kubegraph.PodNode:
7177
service.FulfillingPods = append(service.FulfillingPods, castContainer)
7278
case *kubegraph.StatefulSetNode:
7379
service.FulfillingStatefulSets = append(service.FulfillingStatefulSets, castContainer)
80+
case *kubegraph.DeploymentNode:
81+
service.FulfillingDeployments = append(service.FulfillingDeployments, castContainer)
7482
default:
75-
utilruntime.HandleError(fmt.Errorf("unrecognized container: %v", castContainer))
83+
utilruntime.HandleError(fmt.Errorf("unrecognized container: %v (%T)", castContainer, castContainer))
7684
}
7785
}
7886

@@ -102,13 +110,27 @@ func NewServiceGroup(g osgraph.Graph, serviceNode *kubegraph.ServiceNode) (Servi
102110
service.ReplicationControllers = append(service.ReplicationControllers, rcView)
103111
}
104112

113+
for _, fulfillingRS := range service.FulfillingRSs {
114+
rsView, rsCovers := NewReplicaSet(g, fulfillingRS)
115+
116+
covered.Insert(rsCovers.List()...)
117+
service.ReplicaSets = append(service.ReplicaSets, rsView)
118+
}
119+
105120
for _, fulfillingStatefulSet := range service.FulfillingStatefulSets {
106121
view, covers := NewStatefulSet(g, fulfillingStatefulSet)
107122

108123
covered.Insert(covers.List()...)
109124
service.StatefulSets = append(service.StatefulSets, view)
110125
}
111126

127+
for _, fulfillingDeployment := range service.FulfillingDeployments {
128+
view, covers := NewDeployment(g, fulfillingDeployment)
129+
130+
covered.Insert(covers.List()...)
131+
service.Deployments = append(service.Deployments, view)
132+
}
133+
112134
for _, fulfillingPod := range service.FulfillingPods {
113135
_, podCovers := NewPod(g, fulfillingPod)
114136
covered.Insert(podCovers.List()...)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ func TestGraph(t *testing.T) {
399399
}
400400

401401
for _, bareDCPipeline := range bareDCPipelines {
402-
t.Logf("from %s", bareDCPipeline.Deployment.DeploymentConfig.Name)
402+
t.Logf("from %s", bareDCPipeline.DeploymentConfig.DeploymentConfig.Name)
403403
for _, path := range bareDCPipeline.Images {
404404
t.Logf(" %v", path)
405405
}
@@ -413,7 +413,7 @@ func TestGraph(t *testing.T) {
413413
indent := " "
414414

415415
for _, deployment := range serviceGroup.DeploymentConfigPipelines {
416-
t.Logf("%sdeployment %s", indent, deployment.Deployment.DeploymentConfig.Name)
416+
t.Logf("%sdeployment %s", indent, deployment.DeploymentConfig.DeploymentConfig.Name)
417417
for _, image := range deployment.Images {
418418
t.Logf("%s image %s", indent, image.Image.ImageSpec())
419419
if image.Build != nil {

0 commit comments

Comments
 (0)