Skip to content

Commit

Permalink
wip: add support for deployments in oc status
Browse files Browse the repository at this point in the history
  • Loading branch information
mfojtik committed Feb 5, 2018
1 parent d4061a5 commit b035d04
Show file tree
Hide file tree
Showing 19 changed files with 773 additions and 106 deletions.
2 changes: 1 addition & 1 deletion pkg/oc/admin/prune/imageprune/prune.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@ func (p *pruner) addDeploymentsToGraph(dmnts *kapisext.DeploymentList) []error {
d := &dmnts.Items[i]
ref := getRef(d)
glog.V(4).Infof("Examining %s", getKindName(ref))
dNode := appsgraph.EnsureDeploymentNode(p.g, d)
dNode := kubegraph.EnsureDeploymentNode(p.g, d)
errs = append(errs, p.addPodSpecToGraph(ref, &d.Spec.Template.Spec, dNode)...)
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/oc/cli/describe/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,12 +473,12 @@ func (d *LatestDeploymentsDescriber) Describe(namespace, name string) (string, e
for i := range deployments {
kubegraph.EnsureReplicationControllerNode(g, &deployments[i])
}
appsedges.AddTriggerEdges(g, dcNode)
appsedges.AddDeploymentEdges(g, dcNode)
appsedges.AddTriggerDeploymentConfigsEdges(g, dcNode)
appsedges.AddDeploymentConfigsDeploymentEdges(g, dcNode)
activeDeployment, inactiveDeployments := appsedges.RelevantDeployments(g, dcNode)

return tabbedString(func(out *tabwriter.Writer) error {
descriptions := describeDeployments(f, dcNode, activeDeployment, inactiveDeployments, nil, d.count)
descriptions := describeDeploymentConfigDeployments(f, dcNode, activeDeployment, inactiveDeployments, nil, d.count)
for i, description := range descriptions {
descriptions[i] = fmt.Sprintf("%v %v", name, description)
}
Expand Down
210 changes: 189 additions & 21 deletions pkg/oc/cli/describe/projectstatus.go

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions pkg/oc/graph/appsgraph/analysis/dc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestMissingImageStreamTag(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
buildedges.AddAllInputOutputEdges(g)
appsedges.AddAllTriggerEdges(g)
appsedges.AddAllTriggerDeploymentConfigsEdges(g)
imageedges.AddAllImageStreamRefEdges(g)
imageedges.AddAllImageStreamImageRefEdges(g)

Expand All @@ -36,7 +36,7 @@ func TestMissingImageStream(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
buildedges.AddAllInputOutputEdges(g)
appsedges.AddAllTriggerEdges(g)
appsedges.AddAllTriggerDeploymentConfigsEdges(g)
imageedges.AddAllImageStreamRefEdges(g)
imageedges.AddAllImageStreamImageRefEdges(g)

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

markers := FindDeploymentConfigReadinessWarnings(g, osgraph.DefaultNamer, "command probe")
Expand Down
2 changes: 1 addition & 1 deletion pkg/oc/graph/appsgraph/edge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestNamespaceEdgeMatching(t *testing.T) {

fn("ns", g)
fn("other", g)
AddAllDeploymentEdges(g)
AddAllDeploymentConfigsDeploymentEdges(g)

if len(g.Edges()) != 4 {
t.Fatal(g)
Expand Down
14 changes: 7 additions & 7 deletions pkg/oc/graph/appsgraph/edges.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ const (
VolumeClaimEdgeKind = "VolumeClaim"
)

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

func AddAllTriggerEdges(g osgraph.MutableUniqueGraph) {
func AddAllTriggerDeploymentConfigsEdges(g osgraph.MutableUniqueGraph) {
for _, node := range g.(graph.Graph).Nodes() {
if dcNode, ok := node.(*appsgraph.DeploymentConfigNode); ok {
AddTriggerEdges(g, dcNode)
AddTriggerDeploymentConfigsEdges(g, dcNode)
}
}
}

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

func AddAllDeploymentEdges(g osgraph.MutableUniqueGraph) {
func AddAllDeploymentConfigsDeploymentEdges(g osgraph.MutableUniqueGraph) {
for _, node := range g.(graph.Graph).Nodes() {
if dcNode, ok := node.(*appsgraph.DeploymentConfigNode); ok {
AddDeploymentEdges(g, dcNode)
AddDeploymentConfigsDeploymentEdges(g, dcNode)
}
}
}
Expand Down
27 changes: 0 additions & 27 deletions pkg/oc/graph/appsgraph/nodes/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,6 @@ func FindOrCreateSyntheticDaemonSetNode(g osgraph.MutableUniqueGraph, ds *kapise
).(*DaemonSetNode)
}

// EnsureDeploymentNode adds the provided upstream deployment to the graph if it does not exist
func EnsureDeploymentNode(g osgraph.MutableUniqueGraph, deployment *kapisext.Deployment) *DeploymentNode {
deploymentName := DeploymentNodeName(deployment)
deploymentNode := osgraph.EnsureUnique(
g,
deploymentName,
func(node osgraph.Node) graph.Node {
return &DeploymentNode{Node: node, Deployment: deployment, IsFound: true}
},
).(*DeploymentNode)

podTemplateSpecNode := kubegraph.EnsurePodTemplateSpecNode(g, &deployment.Spec.Template, deployment.Namespace, deploymentName)
g.AddEdge(deploymentNode, podTemplateSpecNode, osgraph.ContainsEdgeKind)

return deploymentNode
}

func FindOrCreateSyntheticDeploymentNode(g osgraph.MutableUniqueGraph, deployment *kapisext.Deployment) *DeploymentNode {
return osgraph.EnsureUnique(
g,
DeploymentNodeName(deployment),
func(node osgraph.Node) graph.Node {
return &DeploymentNode{Node: node, Deployment: deployment, IsFound: false}
},
).(*DeploymentNode)
}

// EnsureDeploymentConfigNode adds the provided deployment config to the graph if it does not exist
func EnsureDeploymentConfigNode(g osgraph.MutableUniqueGraph, dc *appsapi.DeploymentConfig) *DeploymentConfigNode {
dcName := DeploymentConfigNodeName(dc)
Expand Down
27 changes: 0 additions & 27 deletions pkg/oc/graph/appsgraph/nodes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,33 +43,6 @@ func (*DaemonSetNode) Kind() string {
return DaemonSetNodeKind
}

func DeploymentNodeName(o *kapisext.Deployment) osgraph.UniqueName {
return osgraph.GetUniqueRuntimeObjectNodeName(DeploymentNodeKind, o)
}

type DeploymentNode struct {
osgraph.Node
Deployment *kapisext.Deployment

IsFound bool
}

func (n DeploymentNode) Found() bool {
return n.IsFound
}

func (n DeploymentNode) Object() interface{} {
return n.Deployment
}

func (n DeploymentNode) String() string {
return string(DeploymentNodeName(n.Deployment))
}

func (*DeploymentNode) Kind() string {
return DeploymentNodeKind
}

func DeploymentConfigNodeName(o *appsapi.DeploymentConfig) osgraph.UniqueName {
return osgraph.GetUniqueRuntimeObjectNodeName(DeploymentConfigNodeKind, o)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/oc/graph/genericgraph/graphview/dc_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

type DeploymentConfigPipeline struct {
Deployment *appsgraph.DeploymentConfigNode
DeploymentConfig *appsgraph.DeploymentConfigNode

ActiveDeployment *kubegraph.ReplicationControllerNode
InactiveDeployments []*kubegraph.ReplicationControllerNode
Expand Down Expand Up @@ -43,7 +43,7 @@ func NewDeploymentConfigPipeline(g osgraph.Graph, dcNode *appsgraph.DeploymentCo
covered.Insert(dcNode.ID())

dcPipeline := DeploymentConfigPipeline{}
dcPipeline.Deployment = dcNode
dcPipeline.DeploymentConfig = dcNode

// for everything that can trigger a deployment, create an image pipeline and add it to the list
for _, istNode := range g.PredecessorNodesByEdgeKind(dcNode, appsedges.TriggersDeploymentEdgeKind) {
Expand Down Expand Up @@ -80,5 +80,5 @@ type SortedDeploymentConfigPipeline []DeploymentConfigPipeline
func (m SortedDeploymentConfigPipeline) Len() int { return len(m) }
func (m SortedDeploymentConfigPipeline) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
func (m SortedDeploymentConfigPipeline) Less(i, j int) bool {
return CompareObjectMeta(&m[i].Deployment.DeploymentConfig.ObjectMeta, &m[j].Deployment.DeploymentConfig.ObjectMeta)
return CompareObjectMeta(&m[i].DeploymentConfig.DeploymentConfig.ObjectMeta, &m[j].DeploymentConfig.DeploymentConfig.ObjectMeta)
}
73 changes: 73 additions & 0 deletions pkg/oc/graph/genericgraph/graphview/deployments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package graphview

import (
appsedges "github.com/openshift/origin/pkg/oc/graph/appsgraph"
osgraph "github.com/openshift/origin/pkg/oc/graph/genericgraph"
kubeedges "github.com/openshift/origin/pkg/oc/graph/kubegraph"
kubegraph "github.com/openshift/origin/pkg/oc/graph/kubegraph/nodes"
)

type Deployment struct {
Deployment *kubegraph.DeploymentNode

ActiveDeployment *kubegraph.ReplicaSetNode
InactiveDeployments []*kubegraph.ReplicaSetNode

Images []ImagePipeline

// TODO: handle conflicting once controller refs are present, not worth it yet
}

// AllDeployments returns all the Deployments that aren't in the excludes set and the set of covered NodeIDs
func AllDeployments(g osgraph.Graph, excludeNodeIDs IntSet) ([]Deployment, IntSet) {
covered := IntSet{}
views := []Deployment{}

for _, uncastNode := range g.NodesByKind(kubegraph.DeploymentNodeKind) {
if excludeNodeIDs.Has(uncastNode.ID()) {
continue
}

view, covers := NewDeployment(g, uncastNode.(*kubegraph.DeploymentNode))
covered.Insert(covers.List()...)
views = append(views, view)
}

return views, covered
}

// NewDeployment returns the Deployment and a set of all the NodeIDs covered by the Deployment
func NewDeployment(g osgraph.Graph, node *kubegraph.DeploymentNode) (Deployment, IntSet) {
covered := IntSet{}
covered.Insert(node.ID())

view := Deployment{}
view.Deployment = node

for _, istNode := range g.PredecessorNodesByEdgeKind(node, kubeedges.TriggersDeploymentEdgeKind) {
imagePipeline, covers := NewImagePipelineFromImageTagLocation(g, istNode, istNode.(ImageTagLocation))
covered.Insert(covers.List()...)
view.Images = append(view.Images, imagePipeline)
}

// for image that we use, create an image pipeline and add it to the list
for _, tagNode := range g.PredecessorNodesByEdgeKind(node, appsedges.UsedInDeploymentEdgeKind) {
imagePipeline, covers := NewImagePipelineFromImageTagLocation(g, tagNode, tagNode.(ImageTagLocation))

covered.Insert(covers.List()...)
view.Images = append(view.Images, imagePipeline)
}

view.ActiveDeployment, view.InactiveDeployments = kubeedges.RelevantDeployments(g, view.Deployment)
for _, rs := range view.InactiveDeployments {
_, covers := NewReplicaSet(g, rs)
covered.Insert(covers.List()...)
}

if view.ActiveDeployment != nil {
_, covers := NewReplicaSet(g, view.ActiveDeployment)
covered.Insert(covers.List()...)
}

return view, covered
}
17 changes: 17 additions & 0 deletions pkg/oc/graph/genericgraph/graphview/petset.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package graphview

import (
appsedges "github.com/openshift/origin/pkg/oc/graph/appsgraph"
osgraph "github.com/openshift/origin/pkg/oc/graph/genericgraph"
kubeedges "github.com/openshift/origin/pkg/oc/graph/kubegraph"
kubegraph "github.com/openshift/origin/pkg/oc/graph/kubegraph/nodes"
Expand All @@ -12,6 +13,8 @@ type StatefulSet struct {
OwnedPods []*kubegraph.PodNode
CreatedPods []*kubegraph.PodNode

Images []ImagePipeline

// TODO: handle conflicting once controller refs are present, not worth it yet
}

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

for _, istNode := range g.PredecessorNodesByEdgeKind(node, kubeedges.TriggersDeploymentEdgeKind) {
imagePipeline, covers := NewImagePipelineFromImageTagLocation(g, istNode, istNode.(ImageTagLocation))
covered.Insert(covers.List()...)
view.Images = append(view.Images, imagePipeline)
}

// for image that we use, create an image pipeline and add it to the list
for _, tagNode := range g.PredecessorNodesByEdgeKind(node, appsedges.UsedInDeploymentEdgeKind) {
imagePipeline, covers := NewImagePipelineFromImageTagLocation(g, tagNode, tagNode.(ImageTagLocation))

covered.Insert(covers.List()...)
view.Images = append(view.Images, imagePipeline)
}

return view, covered
}
71 changes: 71 additions & 0 deletions pkg/oc/graph/genericgraph/graphview/rs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package graphview

import (
osgraph "github.com/openshift/origin/pkg/oc/graph/genericgraph"
kubeedges "github.com/openshift/origin/pkg/oc/graph/kubegraph"
"github.com/openshift/origin/pkg/oc/graph/kubegraph/analysis"
kubegraph "github.com/openshift/origin/pkg/oc/graph/kubegraph/nodes"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type ReplicaSet struct {
RS *kubegraph.ReplicaSetNode

OwnedPods []*kubegraph.PodNode
CreatedPods []*kubegraph.PodNode
}

func AllReplicaSets(g osgraph.Graph, excludeNodeIDs IntSet) ([]ReplicaSet, IntSet) {
covered := IntSet{}
rsViews := []ReplicaSet{}

for _, uncastNode := range g.NodesByKind(kubegraph.ReplicaSetNodeKind) {
if excludeNodeIDs.Has(uncastNode.ID()) {
continue
}

rsView, covers := NewReplicaSet(g, uncastNode.(*kubegraph.ReplicaSetNode))
covered.Insert(covers.List()...)
rsViews = append(rsViews, rsView)
}

return rsViews, covered
}

// MaxRecentContainerRestarts returns the maximum container restarts for all pods
func (rs *ReplicaSet) MaxRecentContainerRestarts() int32 {
var maxRestarts int32
for _, pod := range rs.OwnedPods {
for _, status := range pod.Status.ContainerStatuses {
if status.RestartCount > maxRestarts && analysis.ContainerRestartedRecently(status, metav1.Now()) {
maxRestarts = status.RestartCount
}
}
}
return maxRestarts
}

// NewReplicationController returns the ReplicationController and a set of all the NodeIDs covered by the ReplicationController
func NewReplicaSet(g osgraph.Graph, rsNode *kubegraph.ReplicaSetNode) (ReplicaSet, IntSet) {
covered := IntSet{}
covered.Insert(rsNode.ID())

rsView := ReplicaSet{}
rsView.RS = rsNode

for _, uncastPodNode := range g.PredecessorNodesByEdgeKind(rsNode, kubeedges.ManagedByControllerEdgeKind) {
podNode := uncastPodNode.(*kubegraph.PodNode)
covered.Insert(podNode.ID())
rsView.OwnedPods = append(rsView.OwnedPods, podNode)
}

return rsView, covered
}

func MaxRecentContainerRestartsForRS(g osgraph.Graph, rsNode *kubegraph.ReplicaSetNode) int32 {
if rsNode == nil {
return 0
}
rs, _ := NewReplicaSet(g, rsNode)
return rs.MaxRecentContainerRestarts()
}
Loading

0 comments on commit b035d04

Please sign in to comment.