Skip to content

Commit

Permalink
Add image pruning support
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Goldstein committed Apr 27, 2015
1 parent 4add7b9 commit 6cc747e
Show file tree
Hide file tree
Showing 11 changed files with 1,416 additions and 19 deletions.
14 changes: 13 additions & 1 deletion pkg/api/graph/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

type Node struct {
concrete.Node
graph.Node
UniqueName
}

Expand All @@ -23,6 +23,10 @@ type uniqueNamer interface {
UniqueName() string
}

type NodeFinder interface {
Find(name UniqueName) graph.Node
}

// UniqueNodeInitializer is a graph that allows nodes with a unique name to be added without duplication.
// If the node is newly added, true will be returned.
type UniqueNodeInitializer interface {
Expand All @@ -44,6 +48,7 @@ type MutableUniqueGraph interface {
graph.Mutable
MutableDirectedEdge
UniqueNodeInitializer
NodeFinder
}

type Edge struct {
Expand Down Expand Up @@ -294,6 +299,13 @@ func (g uniqueNamedGraph) FindOrCreate(name UniqueName, fn NodeInitializerFunc)
return node, false
}

func (g uniqueNamedGraph) Find(name UniqueName) graph.Node {
if node, ok := g.names[name]; ok {
return node
}
return nil
}

type typedGraph struct{}

type stringer interface {
Expand Down
3 changes: 2 additions & 1 deletion pkg/api/graph/graph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ func TestGraph(t *testing.T) {
}
bc++
case *image.ImageStream:
if g.Kind(node) != ImageStreamGraphKind {
// TODO resolve this check for 2 kinds, since both have the same object type
if g.Kind(node) != ImageStreamGraphKind && g.Kind(node) != ImageStreamTagGraphKind {
t.Fatalf("unexpected kind: %v", g.Kind(node))
}
ir++
Expand Down
141 changes: 137 additions & 4 deletions pkg/api/graph/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ import (

const (
UnknownGraphKind = iota
ImageStreamGraphKind
ImageStreamTagGraphKind
DockerRepositoryGraphKind
BuildConfigGraphKind
DeploymentConfigGraphKind
SourceRepositoryGraphKind
ServiceGraphKind
ImageGraphKind
PodGraphKind
ImageStreamGraphKind
ReplicationControllerGraphKind
ImageLayerGraphKind
)
const (
UnknownGraphEdgeKind = iota
Expand All @@ -34,6 +39,9 @@ const (
BuildOutputGraphEdgeKind
UsedInDeploymentGraphEdgeKind
ExposedThroughServiceGraphEdgeKind
ReferencedImageGraphEdgeKind
WeakReferencedImageGraphEdgeKind
ReferencedImageLayerGraphKind
)

type ServiceNode struct {
Expand Down Expand Up @@ -117,7 +125,7 @@ func (n ImageStreamTagNode) String() string {
}

func (*ImageStreamTagNode) Kind() int {
return ImageStreamGraphKind
return ImageStreamTagGraphKind
}

type DockerImageRepositoryNode struct {
Expand Down Expand Up @@ -157,6 +165,50 @@ func (SourceRepositoryNode) Kind() int {
return SourceRepositoryGraphKind
}

type ImageNode struct {
Node
Image *image.Image
}

func (n ImageNode) Object() interface{} {
return n.Image
}

func (n ImageNode) String() string {
return fmt.Sprintf("<image %s>", n.Image.Name)
}

func (*ImageNode) Kind() int {
return ImageGraphKind
}

func Image(g MutableUniqueGraph, img *image.Image) graph.Node {
return EnsureUnique(g,
UniqueName(fmt.Sprintf("%d|%s", ImageGraphKind, img.Name)),
func(node Node) graph.Node {
return &ImageNode{node, img}
},
)
}

func FindImage(g MutableUniqueGraph, imageName string) graph.Node {
return g.Find(UniqueName(fmt.Sprintf("%d|%s", ImageGraphKind, imageName)))
}

type PodNode struct {
Node
Pod *kapi.Pod
}

func Pod(g MutableUniqueGraph, pod *kapi.Pod) graph.Node {
return EnsureUnique(g,
UniqueName(fmt.Sprintf("%d|%s/%s", PodGraphKind, pod.Namespace, pod.Name)),
func(node Node) graph.Node {
return &PodNode{node, pod}
},
)
}

// Service adds the provided service to the graph if it does not already exist. It does not
// link the service to covered nodes (that is a separate method).
func Service(g MutableUniqueGraph, svc *kapi.Service) graph.Node {
Expand Down Expand Up @@ -216,14 +268,14 @@ func SourceRepository(g MutableUniqueGraph, source build.BuildSource) (graph.Nod
), true
}

// ImageStreamTag adds a graph node for the specific tag in an Image Repository if it
// ImageStreamTag adds a graph node for the specific tag in an Image Stream if it
// does not already exist.
func ImageStreamTag(g MutableUniqueGraph, namespace, name, tag string) graph.Node {
if len(tag) == 0 {
tag = image.DefaultImageTag
}
return EnsureUnique(g,
UniqueName(fmt.Sprintf("%d|%s/%s:%s", ImageStreamGraphKind, namespace, name, tag)),
UniqueName(fmt.Sprintf("%d|%s/%s:%s", ImageStreamTagGraphKind, namespace, name, tag)),
func(node Node) graph.Node {
return &ImageStreamTagNode{node, &image.ImageStream{
ObjectMeta: kapi.ObjectMeta{
Expand Down Expand Up @@ -444,3 +496,84 @@ func defaultNamespace(value, defaultValue string) string {
}
return value
}

type ImageStreamNode struct {
Node
*image.ImageStream
}

func (n ImageStreamNode) Object() interface{} {
return n.ImageStream
}

func (n ImageStreamNode) String() string {
return fmt.Sprintf("<image stream %s/%s>", n.Namespace, n.Name)
}

func (*ImageStreamNode) Kind() int {
return ImageStreamGraphKind
}

// ImageStream adds a graph node for the Image Stream if it does not already exist.
func ImageStream(g MutableUniqueGraph, stream *image.ImageStream) graph.Node {
return EnsureUnique(g,
UniqueName(fmt.Sprintf("%d|%s/%s", ImageStreamGraphKind, stream.Namespace, stream.Name)),
func(node Node) graph.Node {
return &ImageStreamNode{node, stream}
},
)
}

type ReplicationControllerNode struct {
Node
*kapi.ReplicationController
}

func (n ReplicationControllerNode) Object() interface{} {
return n.ReplicationController
}

func (n ReplicationControllerNode) String() string {
return fmt.Sprintf("<replication controller %s/%s>", n.Namespace, n.Name)
}

func (*ReplicationControllerNode) Kind() int {
return ReplicationControllerGraphKind
}

// ReplicationController adds a graph node for the ReplicationController if it does not already exist.
func ReplicationController(g MutableUniqueGraph, rc *kapi.ReplicationController) graph.Node {
return EnsureUnique(g,
UniqueName(fmt.Sprintf("%d|%s/%s", ReplicationControllerGraphKind, rc.Namespace, rc.Name)),
func(node Node) graph.Node {
return &ReplicationControllerNode{node, rc}
},
)
}

type ImageLayerNode struct {
Node
Layer string
}

func (n ImageLayerNode) Object() interface{} {
return n.Layer
}

func (n ImageLayerNode) String() string {
return fmt.Sprintf("<image layer %s>", n.Layer)
}

func (*ImageLayerNode) Kind() int {
return ImageLayerGraphKind
}

// ImageLayer adds a graph node for the layer if it does not already exist.
func ImageLayer(g MutableUniqueGraph, layer string) graph.Node {
return EnsureUnique(g,
UniqueName(fmt.Sprintf("%d|%s", ImageLayerGraphKind, layer)),
func(node Node) graph.Node {
return &ImageLayerNode{node, layer}
},
)
}
11 changes: 8 additions & 3 deletions pkg/client/fake_imagestreams.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ func (c *FakeImageStreams) Get(name string) (*imageapi.ImageStream, error) {
return obj.(*imageapi.ImageStream), err
}

func (c *FakeImageStreams) Create(repo *imageapi.ImageStream) (*imageapi.ImageStream, error) {
func (c *FakeImageStreams) Create(stream *imageapi.ImageStream) (*imageapi.ImageStream, error) {
obj, err := c.Fake.Invokes(FakeAction{Action: "create-imagestream"}, &imageapi.ImageStream{})
return obj.(*imageapi.ImageStream), err
}

func (c *FakeImageStreams) Update(repo *imageapi.ImageStream) (*imageapi.ImageStream, error) {
obj, err := c.Fake.Invokes(FakeAction{Action: "update-imagestream"}, &imageapi.ImageStream{})
func (c *FakeImageStreams) Update(stream *imageapi.ImageStream) (*imageapi.ImageStream, error) {
obj, err := c.Fake.Invokes(FakeAction{Action: "update-imagestream", Value: stream}, stream)
return obj.(*imageapi.ImageStream), err
}

Expand All @@ -47,3 +47,8 @@ func (c *FakeImageStreams) Watch(label labels.Selector, field fields.Selector, r
c.Fake.Actions = append(c.Fake.Actions, FakeAction{Action: "watch-imagestreams"})
return nil, nil
}

func (c *FakeImageStreams) UpdateStatus(stream *imageapi.ImageStream) (result *imageapi.ImageStream, err error) {
obj, err := c.Fake.Invokes(FakeAction{Action: "update-status-imagestream", Value: stream}, stream)
return obj.(*imageapi.ImageStream), err
}
8 changes: 8 additions & 0 deletions pkg/client/imagestreams.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type ImageStreamInterface interface {
Update(stream *imageapi.ImageStream) (*imageapi.ImageStream, error)
Delete(name string) error
Watch(label labels.Selector, field fields.Selector, resourceVersion string) (watch.Interface, error)
UpdateStatus(stream *imageapi.ImageStream) (*imageapi.ImageStream, error)
}

// ImageStreamNamespaceGetter exposes methods to get ImageStreams by Namespace
Expand Down Expand Up @@ -100,3 +101,10 @@ func (c *imageStreams) Watch(label labels.Selector, field fields.Selector, resou
FieldsSelectorParam(field).
Watch()
}

// UpdateStatus updates the image stream's status. Returns the server's representation of the image stream, and an error, if it occurs.
func (c *imageStreams) UpdateStatus(stream *imageapi.ImageStream) (result *imageapi.ImageStream, err error) {
result = &imageapi.ImageStream{}
err = c.r.Put().Namespace(c.ns).Resource("imageStreams").Name(stream.Name).SubResource("status").Body(stream).Do().Into(result)
return
}
2 changes: 2 additions & 0 deletions pkg/cmd/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"io"

eximageprune "github.com/openshift/origin/pkg/cmd/experimental/imageprune"
"github.com/spf13/cobra"

"github.com/openshift/origin/pkg/cmd/cli/cmd"
Expand Down Expand Up @@ -47,6 +48,7 @@ func NewCommandAdmin(name, fullName string, out io.Writer) *cobra.Command {
cmds.AddCommand(exipfailover.NewCmdIPFailoverConfig(f, fullName, "ipfailover", out))
cmds.AddCommand(exrouter.NewCmdRouter(f, fullName, "router", out))
cmds.AddCommand(exregistry.NewCmdRegistry(f, fullName, "registry", out))
cmds.AddCommand(eximageprune.NewCmdPruneImages(f, fullName, "prune-images", out))
cmds.AddCommand(buildchain.NewCmdBuildChain(f, fullName, "build-chain"))
cmds.AddCommand(cmd.NewCmdConfig(fullName, "config"))

Expand Down
Loading

0 comments on commit 6cc747e

Please sign in to comment.