func addImageStreamsToGraph(g graph.Graph, streams *imageapi.ImageStreamList) { for i := range streams.Items { stream := &streams.Items[i] glog.V(4).Infof("Adding ImageStream %s/%s to graph", stream.Namespace, stream.Name) isNode := imagegraph.EnsureImageStreamNode(g, stream) imageStreamNode := isNode.(*imagegraph.ImageStreamNode) // connect IS with underlying images for tag, history := range stream.Status.Tags { for i := range history.Items { image := history.Items[i] n := imagegraph.FindImage(g, image.Image) if n == nil { glog.V(2).Infof("Unable to find image %q in graph (from tag=%q, dockerImageReference=%s)", history.Items[i].Image, tag, image.DockerImageReference) continue } imageNode := n.(*imagegraph.ImageNode) glog.V(4).Infof("Adding edge from %q to %q", imageStreamNode.UniqueName(), imageNode.UniqueName()) edgeKind := ImageStreamImageEdgeKind if i > 1 { edgeKind = HistoricImageStreamImageEdgeKind } g.AddEdge(imageStreamNode, imageNode, edgeKind) } } } }
// addImageStreamsToGraph adds all the streams to the graph. The most recent n // image revisions for a tag will be preserved, where n is specified by the // algorithm's keepTagRevisions. Image revisions older than n are candidates // for pruning. if the image stream's age is at least as old as the minimum // threshold in algorithm. Otherwise, if the image stream is younger than the // threshold, all image revisions for that stream are ineligible for pruning. // // addImageStreamsToGraph also adds references from each stream to all the // layers it references (via each image a stream references). func addImageStreamsToGraph(g graph.Graph, streams *imageapi.ImageStreamList, algorithm pruneAlgorithm) { for i := range streams.Items { stream := &streams.Items[i] glog.V(4).Infof("Examining ImageStream %s/%s", stream.Namespace, stream.Name) // use a weak reference for old image revisions by default oldImageRevisionReferenceKind := WeakReferencedImageEdgeKind age := util.Now().Sub(stream.CreationTimestamp.Time) if age < algorithm.keepYoungerThan { // stream's age is below threshold - use a strong reference for old image revisions instead glog.V(4).Infof("Stream %s/%s is below age threshold - none of its images are eligible for pruning", stream.Namespace, stream.Name) oldImageRevisionReferenceKind = ReferencedImageEdgeKind } glog.V(4).Infof("Adding ImageStream %s/%s to graph", stream.Namespace, stream.Name) isNode := imagegraph.EnsureImageStreamNode(g, stream) imageStreamNode := isNode.(*imagegraph.ImageStreamNode) for tag, history := range stream.Status.Tags { for i := range history.Items { n := imagegraph.FindImage(g, history.Items[i].Image) if n == nil { glog.V(2).Infof("Unable to find image %q in graph (from tag=%q, revision=%d, dockerImageReference=%s)", history.Items[i].Image, tag, i, history.Items[i].DockerImageReference) continue } imageNode := n.(*imagegraph.ImageNode) var kind string switch { case i < algorithm.keepTagRevisions: kind = ReferencedImageEdgeKind default: kind = oldImageRevisionReferenceKind } glog.V(4).Infof("Checking for existing strong reference from stream %s/%s to image %s", stream.Namespace, stream.Name, imageNode.Image.Name) if edge := g.Edge(imageStreamNode, imageNode); edge != nil && g.EdgeKinds(edge).Has(ReferencedImageEdgeKind) { glog.V(4).Infof("Strong reference found") continue } glog.V(4).Infof("Adding edge (kind=%d) from %q to %q", kind, imageStreamNode.UniqueName.UniqueName(), imageNode.UniqueName.UniqueName()) g.AddEdge(imageStreamNode, imageNode, kind) glog.V(4).Infof("Adding stream->layer references") // add stream -> layer references so we can prune them later for _, s := range g.From(imageNode) { if g.Kind(s) != imagegraph.ImageLayerNodeKind { continue } glog.V(4).Infof("Adding reference from stream %q to layer %q", stream.Name, s.(*imagegraph.ImageLayerNode).Layer) g.AddEdge(imageStreamNode, s, ReferencedImageLayerEdgeKind) } } } } }
func (l *isLoader) AddToGraph(g osgraph.Graph) error { for i := range l.items { imagegraph.EnsureImageStreamNode(g, &l.items[i]) imagegraph.EnsureAllImageStreamTagNodes(g, &l.items[i]) } return nil }
func (d *ProjectStatusDescriber) MakeGraph(namespace string) (osgraph.Graph, error) { g := osgraph.New() svcs, err := d.K.Services(namespace).List(labels.Everything()) if err != nil { return g, err } iss, err := d.C.ImageStreams(namespace).List(labels.Everything(), fields.Everything()) if err != nil { return g, err } bcs, err := d.C.BuildConfigs(namespace).List(labels.Everything(), fields.Everything()) if err != nil { return g, err } dcs, err := d.C.DeploymentConfigs(namespace).List(labels.Everything(), fields.Everything()) if err != nil { return g, err } builds := &buildapi.BuildList{} if len(bcs.Items) > 0 { if b, err := d.C.Builds(namespace).List(labels.Everything(), fields.Everything()); err == nil { builds = b } } rcs, err := d.K.ReplicationControllers(namespace).List(labels.Everything()) if err != nil { rcs = &kapi.ReplicationControllerList{} } for i := range iss.Items { imagegraph.EnsureImageStreamNode(g, &iss.Items[i]) imagegraph.EnsureAllImageStreamTagNodes(g, &iss.Items[i]) } for i := range bcs.Items { build := buildgraph.EnsureBuildConfigNode(g, &bcs.Items[i]) buildedges.AddInputOutputEdges(g, build) buildedges.JoinBuilds(build, builds.Items) } for i := range dcs.Items { deploy := deploygraph.EnsureDeploymentConfigNode(g, &dcs.Items[i]) deployedges.AddTriggerEdges(g, deploy) deployedges.JoinDeployments(deploy, rcs.Items) } for i := range svcs.Items { service := kubegraph.EnsureServiceNode(g, &svcs.Items[i]) kubeedges.AddExposedPodTemplateSpecEdges(g, service) } imageedges.AddAllImageStreamRefEdges(g) return g, nil }
func loadImageStreams(g osgraph.Graph, graphLock sync.Mutex, namespace string, kclient kclient.Interface, client client.Interface) error { iss, err := client.ImageStreams(namespace).List(labels.Everything(), fields.Everything()) if err != nil { return err } graphLock.Lock() defer graphLock.Unlock() for i := range iss.Items { imagegraph.EnsureImageStreamNode(g, &iss.Items[i]) imagegraph.EnsureAllImageStreamTagNodes(g, &iss.Items[i]) } return nil }
// addImageStreamsToGraph adds all the streams to the graph. The most recent n // image revisions for a tag will be preserved, where n is specified by the // algorithm's keepTagRevisions. Image revisions older than n are candidates // for pruning if the image stream's age is at least as old as the minimum // threshold in algorithm. Otherwise, if the image stream is younger than the // threshold, all image revisions for that stream are ineligible for pruning. // If pruneOverSizeLimit flag is set to true, above does not matter, instead // all images size is checked against LimitRanges defined in that same namespace, // and whenever its size exceeds the smallest limit in that namespace, it will be // considered a candidate for pruning. // // addImageStreamsToGraph also adds references from each stream to all the // layers it references (via each image a stream references). func addImageStreamsToGraph(g graph.Graph, streams *imageapi.ImageStreamList, limits map[string][]*kapi.LimitRange, algorithm pruneAlgorithm) { for i := range streams.Items { stream := &streams.Items[i] glog.V(4).Infof("Examining ImageStream %s/%s", stream.Namespace, stream.Name) // use a weak reference for old image revisions by default oldImageRevisionReferenceKind := WeakReferencedImageEdgeKind age := unversioned.Now().Sub(stream.CreationTimestamp.Time) if !algorithm.pruneOverSizeLimit && age < algorithm.keepYoungerThan { // stream's age is below threshold - use a strong reference for old image revisions instead oldImageRevisionReferenceKind = ReferencedImageEdgeKind } glog.V(4).Infof("Adding ImageStream %s/%s to graph", stream.Namespace, stream.Name) isNode := imagegraph.EnsureImageStreamNode(g, stream) imageStreamNode := isNode.(*imagegraph.ImageStreamNode) for tag, history := range stream.Status.Tags { for i := range history.Items { n := imagegraph.FindImage(g, history.Items[i].Image) if n == nil { glog.V(2).Infof("Unable to find image %q in graph (from tag=%q, revision=%d, dockerImageReference=%s) - skipping", history.Items[i].Image, tag, i, history.Items[i].DockerImageReference) continue } imageNode := n.(*imagegraph.ImageNode) kind := oldImageRevisionReferenceKind if algorithm.pruneOverSizeLimit { if exceedsLimits(stream, imageNode.Image, limits) { kind = WeakReferencedImageEdgeKind } else { kind = ReferencedImageEdgeKind } } else { if i < algorithm.keepTagRevisions { kind = ReferencedImageEdgeKind } } glog.V(4).Infof("Checking for existing strong reference from stream %s/%s to image %s", stream.Namespace, stream.Name, imageNode.Image.Name) if edge := g.Edge(imageStreamNode, imageNode); edge != nil && g.EdgeKinds(edge).Has(ReferencedImageEdgeKind) { glog.V(4).Infof("Strong reference found") continue } glog.V(4).Infof("Adding edge (kind=%s) from %q to %q", kind, imageStreamNode.UniqueName(), imageNode.UniqueName()) g.AddEdge(imageStreamNode, imageNode, kind) glog.V(4).Infof("Adding stream->(layer|config) references") // add stream -> layer references so we can prune them later for _, s := range g.From(imageNode) { cn, ok := s.(*imagegraph.ImageComponentNode) if !ok { continue } glog.V(4).Infof("Adding reference from stream %q to %s", stream.Name, cn.Describe()) if cn.Type == imagegraph.ImageComponentTypeConfig { g.AddEdge(imageStreamNode, s, ReferencedImageConfigEdgeKind) } else { g.AddEdge(imageStreamNode, s, ReferencedImageLayerEdgeKind) } } } } } }