Split layer and image stores into RO and RW kinds

Split the LayerStore and ImageStore interfaces into read-only and
write-only subset interfaces, and make the proper stores into unions of
the read-only and write-only method sets.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai 2017-06-08 13:58:19 -04:00
parent 162e676330
commit 198f752fb5
3 changed files with 118 additions and 69 deletions

View File

@ -49,11 +49,32 @@ type Image struct {
Flags map[string]interface{} `json:"flags,omitempty"`
}
// ROImageStore provides bookkeeping for information about Images.
type ROImageStore interface {
ROFileBasedStore
ROMetadataStore
ROBigDataStore
// Exists checks if there is an image with the given ID or name.
Exists(id string) bool
// Get retrieves information about an image given an ID or name.
Get(id string) (*Image, error)
// Lookup attempts to translate a name to an ID. Most methods do this
// implicitly.
Lookup(name string) (string, error)
// Images returns a slice enumerating the known images.
Images() ([]Image, error)
}
// ImageStore provides bookkeeping for information about Images.
type ImageStore interface {
FileBasedStore
MetadataStore
BigDataStore
ROImageStore
RWFileBasedStore
RWMetadataStore
RWBigDataStore
FlaggableStore
// Create creates an image that has a specified ID (or a random one) and
@ -65,24 +86,11 @@ type ImageStore interface {
// supplied values.
SetNames(id string, names []string) error
// Exists checks if there is an image with the given ID or name.
Exists(id string) bool
// Get retrieves information about an image given an ID or name.
Get(id string) (*Image, error)
// Delete removes the record of the image.
Delete(id string) error
// Wipe removes records of all images.
Wipe() error
// Lookup attempts to translate a name to an ID. Most methods do this
// implicitly.
Lookup(name string) (string, error)
// Images returns a slice enumerating the known images.
Images() ([]Image, error)
}
type imageStore struct {

View File

@ -75,28 +75,12 @@ type layerMountPoint struct {
MountCount int `json:"count"`
}
// LayerStore wraps a graph driver, adding the ability to refer to layers by
// ROLayerStore wraps a graph driver, adding the ability to refer to layers by
// name, and keeping track of parent-child relationships, along with a list of
// all known layers.
type LayerStore interface {
FileBasedStore
MetadataStore
FlaggableStore
// Create creates a new layer, optionally giving it a specified ID rather than
// a randomly-generated one, either inheriting data from another specified
// layer or the empty base layer. The new layer can optionally be given names
// and have an SELinux label specified for use when mounting it. Some
// underlying drivers can accept a "size" option. At this time, most
// underlying drivers do not themselves distinguish between writeable
// and read-only layers.
Create(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool) (*Layer, error)
// CreateWithFlags combines the functions of Create and SetFlag.
CreateWithFlags(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool, flags map[string]interface{}) (layer *Layer, err error)
// Put combines the functions of CreateWithFlags and ApplyDiff.
Put(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool, flags map[string]interface{}, diff archive.Reader) (*Layer, int64, error)
type ROLayerStore interface {
ROFileBasedStore
ROMetadataStore
// Exists checks if a layer with the specified name or ID is known.
Exists(id string) bool
@ -104,28 +88,10 @@ type LayerStore interface {
// Get retrieves information about a layer given an ID or name.
Get(id string) (*Layer, error)
// SetNames replaces the list of names associated with a layer with the
// supplied values.
SetNames(id string, names []string) error
// Status returns an slice of key-value pairs, suitable for human consumption,
// relaying whatever status information the underlying driver can share.
Status() ([][2]string, error)
// Delete deletes a layer with the specified name or ID.
Delete(id string) error
// Wipe deletes all layers.
Wipe() error
// Mount mounts a layer for use. If the specified layer is the parent of other
// layers, it should not be written to. An SELinux label to be applied to the
// mount can be specified to override the one configured for the layer.
Mount(id, mountLabel string) (string, error)
// Unmount unmounts a layer when it is no longer in use.
Unmount(id string) error
// Changes returns a slice of Change structures, which contain a pathname
// (Path) and a description of what sort of change (Kind) was made by the
// layer (either ChangeModify, ChangeAdd, or ChangeDelete), relative to a
@ -142,10 +108,6 @@ type LayerStore interface {
// produced by Diff.
DiffSize(from, to string) (int64, error)
// ApplyDiff reads a tarstream which was created by a previous call to Diff and
// applies its changes to a specified layer.
ApplyDiff(to string, diff archive.Reader) (int64, error)
// Lookup attempts to translate a name to an ID. Most methods do this
// implicitly.
Lookup(name string) (string, error)
@ -154,6 +116,53 @@ type LayerStore interface {
Layers() ([]Layer, error)
}
// LayerStore wraps a graph driver, adding the ability to refer to layers by
// name, and keeping track of parent-child relationships, along with a list of
// all known layers.
type LayerStore interface {
ROLayerStore
RWFileBasedStore
RWMetadataStore
FlaggableStore
// Create creates a new layer, optionally giving it a specified ID rather than
// a randomly-generated one, either inheriting data from another specified
// layer or the empty base layer. The new layer can optionally be given names
// and have an SELinux label specified for use when mounting it. Some
// underlying drivers can accept a "size" option. At this time, most
// underlying drivers do not themselves distinguish between writeable
// and read-only layers.
Create(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool) (*Layer, error)
// CreateWithFlags combines the functions of Create and SetFlag.
CreateWithFlags(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool, flags map[string]interface{}) (layer *Layer, err error)
// Put combines the functions of CreateWithFlags and ApplyDiff.
Put(id, parent string, names []string, mountLabel string, options map[string]string, writeable bool, flags map[string]interface{}, diff archive.Reader) (*Layer, int64, error)
// SetNames replaces the list of names associated with a layer with the
// supplied values.
SetNames(id string, names []string) error
// Delete deletes a layer with the specified name or ID.
Delete(id string) error
// Wipe deletes all layers.
Wipe() error
// Mount mounts a layer for use. If the specified layer is the parent of other
// layers, it should not be written to. An SELinux label to be applied to the
// mount can be specified to override the one configured for the layer.
Mount(id, mountLabel string) (string, error)
// Unmount unmounts a layer when it is no longer in use.
Unmount(id string) error
// ApplyDiff reads a tarstream which was created by a previous call to Diff and
// applies its changes to a specified layer.
ApplyDiff(to string, diff archive.Reader) (int64, error)
}
type layerStore struct {
lockfile Locker
rundir string

View File

@ -58,37 +58,54 @@ var (
storesLock sync.Mutex
)
// FileBasedStore wraps up the most common methods of the various types of file-based
// data stores that we implement.
type FileBasedStore interface {
// ROFileBasedStore wraps up the methods of the various types of file-based
// data stores that we implement which are needed for both read-only and
// read-write files.
type ROFileBasedStore interface {
Locker
// Load reloads the contents of the store from disk. It should be called
// with the lock held.
Load() error
}
// RWFileBasedStore wraps up the methods of various types of file-based data
// stores that we implement using read-write files.
type RWFileBasedStore interface {
// Save saves the contents of the store to disk. It should be called with
// the lock held, and Touch() should be called afterward before releasing the
// lock.
Save() error
}
// MetadataStore wraps up methods for getting and setting metadata associated with IDs.
type MetadataStore interface {
// FileBasedStore wraps up the common methods of various types of file-based
// data stores that we implement.
type FileBasedStore interface {
ROFileBasedStore
RWFileBasedStore
}
// ROMetadataStore wraps a method for reading metadata associated with an ID.
type ROMetadataStore interface {
// Metadata reads metadata associated with an item with the specified ID.
Metadata(id string) (string, error)
}
// RWMetadataStore wraps a method for setting metadata associated with an ID.
type RWMetadataStore interface {
// SetMetadata updates the metadata associated with the item with the specified ID.
SetMetadata(id, metadata string) error
}
// A BigDataStore wraps up the most common methods of the various types of
// file-based lookaside stores that we implement.
type BigDataStore interface {
// SetBigData stores a (potentially large) piece of data associated with this
// ID.
SetBigData(id, key string, data []byte) error
// MetadataStore wraps up methods for getting and setting metadata associated with IDs.
type MetadataStore interface {
ROMetadataStore
RWMetadataStore
}
// An ROBigDataStore wraps up the read-only big-data related methods of the
// various types of file-based lookaside stores that we implement.
type ROBigDataStore interface {
// BigData retrieves a (potentially large) piece of data associated with
// this ID, if it has previously been set.
BigData(id, key string) ([]byte, error)
@ -102,6 +119,21 @@ type BigDataStore interface {
BigDataNames(id string) ([]string, error)
}
// A RWBigDataStore wraps up the read-write big-data related methods of the
// various types of file-based lookaside stores that we implement.
type RWBigDataStore interface {
// SetBigData stores a (potentially large) piece of data associated with this
// ID.
SetBigData(id, key string, data []byte) error
}
// A BigDataStore wraps up the most common big-data related methods of the
// various types of file-based lookaside stores that we implement.
type BigDataStore interface {
ROBigDataStore
RWBigDataStore
}
// A FlaggableStore can have flags set and cleared on items which it manages.
type FlaggableStore interface {
// ClearFlag removes a named flag from an item in the store.