Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
2017-07-20 08:01:23 +00:00
|
|
|
"errors"
|
2017-06-08 13:45:34 +00:00
|
|
|
"net"
|
2017-10-30 21:18:42 +00:00
|
|
|
"path"
|
2017-07-20 08:01:23 +00:00
|
|
|
"strings"
|
2018-02-15 01:55:31 +00:00
|
|
|
"sync"
|
2017-06-08 13:45:34 +00:00
|
|
|
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
"github.com/containers/image/copy"
|
2017-03-24 15:34:12 +00:00
|
|
|
"github.com/containers/image/docker/reference"
|
2017-06-07 17:54:02 +00:00
|
|
|
"github.com/containers/image/image"
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
"github.com/containers/image/manifest"
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
"github.com/containers/image/signature"
|
|
|
|
istorage "github.com/containers/image/storage"
|
2017-03-13 15:16:03 +00:00
|
|
|
"github.com/containers/image/transports/alltransports"
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
"github.com/containers/image/types"
|
2017-05-17 17:18:35 +00:00
|
|
|
"github.com/containers/storage"
|
2017-11-09 18:15:56 +00:00
|
|
|
digest "github.com/opencontainers/go-digest"
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
)
|
|
|
|
|
2017-12-11 21:02:54 +00:00
|
|
|
const (
|
|
|
|
minimumTruncatedIDLength = 3
|
|
|
|
)
|
|
|
|
|
2017-11-28 00:34:55 +00:00
|
|
|
var (
|
|
|
|
// ErrCannotParseImageID is returned when we try to ResolveNames for an image ID
|
|
|
|
ErrCannotParseImageID = errors.New("cannot parse an image ID")
|
2017-10-30 21:18:42 +00:00
|
|
|
// ErrImageMultiplyTagged is returned when we try to remove an image that still has multiple names
|
|
|
|
ErrImageMultiplyTagged = errors.New("image still has multiple names applied")
|
2017-11-28 00:34:55 +00:00
|
|
|
)
|
|
|
|
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
// ImageResult wraps a subset of information about an image: its ID, its names,
|
|
|
|
// and the size, if known, or nil if it isn't.
|
|
|
|
type ImageResult struct {
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
ID string
|
|
|
|
Name string
|
|
|
|
RepoTags []string
|
|
|
|
RepoDigests []string
|
|
|
|
Size *uint64
|
|
|
|
Digest digest.Digest
|
2017-11-09 18:15:56 +00:00
|
|
|
ConfigDigest digest.Digest
|
2018-02-14 12:16:55 +00:00
|
|
|
User string
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
}
|
|
|
|
|
2017-06-08 13:45:34 +00:00
|
|
|
type indexInfo struct {
|
|
|
|
name string
|
|
|
|
secure bool
|
|
|
|
}
|
|
|
|
|
2018-02-14 18:57:18 +00:00
|
|
|
// A set of information that we prefer to cache about images, so that we can
|
|
|
|
// avoid having to reread them every time we need to return information about
|
|
|
|
// images.
|
|
|
|
type imageCacheItem struct {
|
|
|
|
user string
|
|
|
|
size *uint64
|
|
|
|
configDigest digest.Digest
|
|
|
|
}
|
|
|
|
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
type imageService struct {
|
2017-06-08 13:45:34 +00:00
|
|
|
store storage.Store
|
|
|
|
defaultTransport string
|
|
|
|
insecureRegistryCIDRs []*net.IPNet
|
|
|
|
indexConfigs map[string]*indexInfo
|
2017-07-20 08:01:23 +00:00
|
|
|
registries []string
|
2018-02-14 18:57:18 +00:00
|
|
|
imageCache map[string]imageCacheItem
|
2018-02-15 01:55:31 +00:00
|
|
|
imageCacheLock sync.Mutex
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
}
|
|
|
|
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
// sizer knows its size.
|
|
|
|
type sizer interface {
|
|
|
|
Size() (int64, error)
|
|
|
|
}
|
|
|
|
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
// ImageServer wraps up various CRI-related activities into a reusable
|
|
|
|
// implementation.
|
|
|
|
type ImageServer interface {
|
|
|
|
// ListImages returns list of all images which match the filter.
|
2017-08-31 15:48:10 +00:00
|
|
|
ListImages(systemContext *types.SystemContext, filter string) ([]ImageResult, error)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
// ImageStatus returns status of an image which matches the filter.
|
|
|
|
ImageStatus(systemContext *types.SystemContext, filter string) (*ImageResult, error)
|
2017-11-09 18:15:56 +00:00
|
|
|
// PrepareImage returns an Image where the config digest can be grabbed
|
|
|
|
// for further analysis. Call Close() on the resulting image.
|
|
|
|
PrepareImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.Image, error)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
// PullImage imports an image from the specified location.
|
|
|
|
PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error)
|
2017-10-30 21:18:42 +00:00
|
|
|
// UntagImage removes a name from the specified image, and if it was
|
|
|
|
// the only name the image had, removes the image.
|
|
|
|
UntagImage(systemContext *types.SystemContext, imageName string) error
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
// RemoveImage deletes the specified image.
|
|
|
|
RemoveImage(systemContext *types.SystemContext, imageName string) error
|
|
|
|
// GetStore returns the reference to the storage library Store which
|
|
|
|
// the image server uses to hold images, and is the destination used
|
|
|
|
// when it's asked to pull an image.
|
|
|
|
GetStore() storage.Store
|
2017-06-07 17:54:02 +00:00
|
|
|
// CanPull preliminary checks whether we're allowed to pull an image
|
2017-06-08 13:45:34 +00:00
|
|
|
CanPull(imageName string, options *copy.Options) (bool, error)
|
2017-07-20 08:01:23 +00:00
|
|
|
// ResolveNames takes an image reference and if it's unqualified (w/o hostname),
|
|
|
|
// it uses crio's default registries to qualify it.
|
|
|
|
ResolveNames(imageName string) ([]string, error)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
}
|
|
|
|
|
2017-08-31 15:48:10 +00:00
|
|
|
func (svc *imageService) getRef(name string) (types.ImageReference, error) {
|
|
|
|
ref, err := alltransports.ParseImageName(name)
|
|
|
|
if err != nil {
|
|
|
|
ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, "@"+name)
|
|
|
|
if err2 != nil {
|
|
|
|
ref3, err3 := istorage.Transport.ParseStoreReference(svc.store, name)
|
|
|
|
if err3 != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
ref2 = ref3
|
|
|
|
}
|
|
|
|
ref = ref2
|
|
|
|
}
|
|
|
|
return ref, nil
|
|
|
|
}
|
|
|
|
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
func sortNamesByType(names []string) (bestName string, tags, digests []string) {
|
|
|
|
for _, name := range names {
|
|
|
|
if len(name) > 72 && name[len(name)-72:len(name)-64] == "@sha256:" {
|
|
|
|
digests = append(digests, name)
|
|
|
|
} else {
|
|
|
|
tags = append(tags, name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(digests) > 0 {
|
|
|
|
bestName = digests[0]
|
|
|
|
}
|
|
|
|
if len(tags) > 0 {
|
|
|
|
bestName = tags[0]
|
|
|
|
}
|
|
|
|
return bestName, tags, digests
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svc *imageService) makeRepoDigests(knownRepoDigests, tags []string, imageID string) (imageDigest digest.Digest, repoDigests []string) {
|
|
|
|
// Look up the image's digest.
|
|
|
|
img, err := svc.store.Image(imageID)
|
|
|
|
if err != nil {
|
|
|
|
return "", knownRepoDigests
|
|
|
|
}
|
|
|
|
imageDigest = img.Digest
|
|
|
|
if imageDigest == "" {
|
|
|
|
imgDigest, err := svc.store.ImageBigDataDigest(imageID, storage.ImageDigestBigDataKey)
|
|
|
|
if err != nil || imgDigest == "" {
|
|
|
|
return "", knownRepoDigests
|
|
|
|
}
|
|
|
|
imageDigest = imgDigest
|
|
|
|
}
|
|
|
|
// If there are no names to convert to canonical references, we're done.
|
|
|
|
if len(tags) == 0 {
|
|
|
|
return imageDigest, knownRepoDigests
|
|
|
|
}
|
|
|
|
// We only want to supplement what's already explicitly in the list, so keep track of values
|
|
|
|
// that we already know.
|
|
|
|
digestMap := make(map[string]struct{})
|
|
|
|
repoDigests = knownRepoDigests
|
|
|
|
for _, repoDigest := range knownRepoDigests {
|
|
|
|
digestMap[repoDigest] = struct{}{}
|
|
|
|
}
|
|
|
|
// For each tagged name, parse the name, and if we can extract a named reference, convert
|
|
|
|
// it into a canonical reference using the digest and add it to the list.
|
|
|
|
for _, tag := range tags {
|
|
|
|
if ref, err2 := reference.ParseAnyReference(tag); err2 == nil {
|
|
|
|
if name, ok := ref.(reference.Named); ok {
|
|
|
|
trimmed := reference.TrimNamed(name)
|
|
|
|
if imageRef, err3 := reference.WithDigest(trimmed, imageDigest); err3 == nil {
|
|
|
|
if _, ok := digestMap[imageRef.String()]; !ok {
|
|
|
|
repoDigests = append(repoDigests, imageRef.String())
|
|
|
|
digestMap[imageRef.String()] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return imageDigest, repoDigests
|
|
|
|
}
|
|
|
|
|
2017-08-31 15:48:10 +00:00
|
|
|
func (svc *imageService) ListImages(systemContext *types.SystemContext, filter string) ([]ImageResult, error) {
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
results := []ImageResult{}
|
|
|
|
if filter != "" {
|
2017-08-31 15:48:10 +00:00
|
|
|
ref, err := svc.getRef(filter)
|
2017-04-06 17:28:55 +00:00
|
|
|
if err != nil {
|
2017-08-31 15:48:10 +00:00
|
|
|
return nil, err
|
2017-04-06 17:28:55 +00:00
|
|
|
}
|
|
|
|
if image, err := istorage.Transport.GetStoreImage(svc.store, ref); err == nil {
|
2018-02-14 18:57:18 +00:00
|
|
|
var user string
|
|
|
|
var size *uint64
|
|
|
|
var configDigest digest.Digest
|
|
|
|
if cacheItem, ok := svc.imageCache[image.ID]; ok {
|
|
|
|
user, size, configDigest = cacheItem.user, cacheItem.size, cacheItem.configDigest
|
|
|
|
} else {
|
|
|
|
img, err := ref.NewImageSource(systemContext)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
size = imageSize(img)
|
|
|
|
configDigest, err = imageConfigDigest(img, nil)
|
|
|
|
img.Close()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
imageFull, err := ref.NewImage(systemContext)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer imageFull.Close()
|
|
|
|
imageConfig, err := imageFull.OCIConfig()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
user = imageConfig.Config.User
|
|
|
|
cacheItem := imageCacheItem{
|
|
|
|
user: user,
|
|
|
|
size: size,
|
|
|
|
configDigest: configDigest,
|
|
|
|
}
|
|
|
|
svc.imageCache[image.ID] = cacheItem
|
2018-02-14 12:16:55 +00:00
|
|
|
}
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
name, tags, digests := sortNamesByType(image.Names)
|
|
|
|
imageDigest, repoDigests := svc.makeRepoDigests(digests, tags, image.ID)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
results = append(results, ImageResult{
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
ID: image.ID,
|
|
|
|
Name: name,
|
|
|
|
RepoTags: tags,
|
|
|
|
RepoDigests: repoDigests,
|
|
|
|
Size: size,
|
|
|
|
Digest: imageDigest,
|
|
|
|
ConfigDigest: configDigest,
|
2018-02-14 18:57:18 +00:00
|
|
|
User: user,
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
images, err := svc.store.Images()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-02-14 18:57:18 +00:00
|
|
|
visited := make(map[string]struct{})
|
|
|
|
defer func() {
|
|
|
|
// We built a map using IDs of images that we looked
|
|
|
|
// at, so remove any items from the cache that don't
|
|
|
|
// correspond to any of those IDs.
|
|
|
|
removedIDs := make([]string, 0, len(svc.imageCache))
|
|
|
|
for imageID := range svc.imageCache {
|
|
|
|
if _, keep := visited[imageID]; !keep {
|
|
|
|
// We have cached data for an image
|
|
|
|
// with this ID, but it's not in the
|
|
|
|
// list of images now, so the image has
|
|
|
|
// been removed.
|
|
|
|
removedIDs = append(removedIDs, imageID)
|
|
|
|
}
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
}
|
2018-02-14 18:57:18 +00:00
|
|
|
// Handle the removals.
|
2018-02-15 01:55:31 +00:00
|
|
|
svc.imageCacheLock.Lock()
|
2018-02-14 18:57:18 +00:00
|
|
|
for _, removedID := range removedIDs {
|
|
|
|
delete(svc.imageCache, removedID)
|
2018-02-14 12:16:55 +00:00
|
|
|
}
|
2018-02-15 01:55:31 +00:00
|
|
|
svc.imageCacheLock.Unlock()
|
2018-02-14 18:57:18 +00:00
|
|
|
}()
|
|
|
|
for _, image := range images {
|
|
|
|
visited[image.ID] = struct{}{}
|
|
|
|
var user string
|
|
|
|
var size *uint64
|
|
|
|
var configDigest digest.Digest
|
2018-02-15 01:55:31 +00:00
|
|
|
svc.imageCacheLock.Lock()
|
|
|
|
cacheItem, ok := svc.imageCache[image.ID]
|
|
|
|
svc.imageCacheLock.Unlock()
|
|
|
|
if ok {
|
2018-02-14 18:57:18 +00:00
|
|
|
user, size, configDigest = cacheItem.user, cacheItem.size, cacheItem.configDigest
|
|
|
|
} else {
|
|
|
|
ref, err := istorage.Transport.ParseStoreReference(svc.store, "@"+image.ID)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
img, err := ref.NewImageSource(systemContext)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
size = imageSize(img)
|
|
|
|
configDigest, err = imageConfigDigest(img, nil)
|
|
|
|
img.Close()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
imageFull, err := ref.NewImage(systemContext)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer imageFull.Close()
|
2018-02-14 12:16:55 +00:00
|
|
|
|
2018-02-14 18:57:18 +00:00
|
|
|
imageConfig, err := imageFull.OCIConfig()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
user = imageConfig.Config.User
|
|
|
|
cacheItem := imageCacheItem{
|
|
|
|
user: user,
|
|
|
|
size: size,
|
|
|
|
configDigest: configDigest,
|
|
|
|
}
|
2018-02-15 01:55:31 +00:00
|
|
|
svc.imageCacheLock.Lock()
|
2018-02-14 18:57:18 +00:00
|
|
|
svc.imageCache[image.ID] = cacheItem
|
2018-02-15 01:55:31 +00:00
|
|
|
svc.imageCacheLock.Unlock()
|
2018-02-14 12:16:55 +00:00
|
|
|
}
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
name, tags, digests := sortNamesByType(image.Names)
|
|
|
|
imageDigest, repoDigests := svc.makeRepoDigests(digests, tags, image.ID)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
results = append(results, ImageResult{
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
ID: image.ID,
|
|
|
|
Name: name,
|
|
|
|
RepoTags: tags,
|
|
|
|
RepoDigests: repoDigests,
|
|
|
|
Size: size,
|
|
|
|
Digest: imageDigest,
|
|
|
|
ConfigDigest: configDigest,
|
2018-02-14 18:57:18 +00:00
|
|
|
User: user,
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return results, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svc *imageService) ImageStatus(systemContext *types.SystemContext, nameOrID string) (*ImageResult, error) {
|
2017-03-13 15:16:03 +00:00
|
|
|
ref, err := alltransports.ParseImageName(nameOrID)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
if err != nil {
|
|
|
|
ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, "@"+nameOrID)
|
|
|
|
if err2 != nil {
|
|
|
|
ref3, err3 := istorage.Transport.ParseStoreReference(svc.store, nameOrID)
|
|
|
|
if err3 != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
ref2 = ref3
|
|
|
|
}
|
|
|
|
ref = ref2
|
|
|
|
}
|
|
|
|
image, err := istorage.Transport.GetStoreImage(svc.store, ref)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-02-14 12:16:55 +00:00
|
|
|
imageFull, err := ref.NewImage(systemContext)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer imageFull.Close()
|
|
|
|
|
|
|
|
imageConfig, err := imageFull.OCIConfig()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
img, err := ref.NewImageSource(systemContext)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-11-10 13:21:22 +00:00
|
|
|
defer img.Close()
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
size := imageSize(img)
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
configDigest, err := imageConfigDigest(img, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
name, tags, digests := sortNamesByType(image.Names)
|
|
|
|
imageDigest, repoDigests := svc.makeRepoDigests(digests, tags, image.ID)
|
|
|
|
result := ImageResult{
|
2017-11-09 18:15:56 +00:00
|
|
|
ID: image.ID,
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
Name: name,
|
|
|
|
RepoTags: tags,
|
|
|
|
RepoDigests: repoDigests,
|
2017-11-09 18:15:56 +00:00
|
|
|
Size: size,
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
Digest: imageDigest,
|
|
|
|
ConfigDigest: configDigest,
|
2018-02-14 12:16:55 +00:00
|
|
|
User: imageConfig.Config.User,
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &result, nil
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
}
|
|
|
|
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
func imageSize(img types.ImageSource) *uint64 {
|
|
|
|
if s, ok := img.(sizer); ok {
|
|
|
|
if sum, err := s.Size(); err == nil {
|
|
|
|
usum := uint64(sum)
|
|
|
|
return &usum
|
|
|
|
}
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
Return image references from the storage package
The image's canonical reference is a name with a digest of the image's
manifest, so in imageService.ImageStatus() and
imageService.ListImages(), divide the image's name list into tagged and
digested values, and if we have names, add canonical versions.
In Server.ContainerStatus(), return the image name as it was given to us
as the image, and the image digested reference as the image reference.
In Server.ListImages(), be sure to only return tagged names in the
RepoTags field. In Server.ImageStatus(), also return canonical
references in the RepoDigests field.
In Server.PullImage(), be sure that we consistently return the same
image reference for an image, whether we ended up pulling it or not.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2017-07-12 16:41:38 +00:00
|
|
|
func imageConfigDigest(img types.ImageSource, instanceDigest *digest.Digest) (digest.Digest, error) {
|
|
|
|
manifestBytes, manifestType, err := img.GetManifest(instanceDigest)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
imgManifest, err := manifest.FromBlob(manifestBytes, manifestType)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return imgManifest.ConfigInfo().Digest, nil
|
|
|
|
}
|
|
|
|
|
2017-06-08 13:45:34 +00:00
|
|
|
func (svc *imageService) CanPull(imageName string, options *copy.Options) (bool, error) {
|
2017-11-09 18:15:56 +00:00
|
|
|
srcRef, err := svc.prepareReference(imageName, options)
|
2017-06-07 17:54:02 +00:00
|
|
|
if err != nil {
|
2017-06-08 13:45:34 +00:00
|
|
|
return false, err
|
2017-06-07 17:54:02 +00:00
|
|
|
}
|
2017-09-13 17:01:06 +00:00
|
|
|
rawSource, err := srcRef.NewImageSource(options.SourceCtx)
|
2017-06-07 17:54:02 +00:00
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
2017-11-27 23:46:10 +00:00
|
|
|
sourceCtx := &types.SystemContext{}
|
|
|
|
if options.SourceCtx != nil {
|
|
|
|
sourceCtx = options.SourceCtx
|
|
|
|
}
|
|
|
|
src, err := image.FromSource(sourceCtx, rawSource)
|
2017-06-07 17:54:02 +00:00
|
|
|
if err != nil {
|
2017-07-26 19:44:38 +00:00
|
|
|
rawSource.Close()
|
2017-06-07 17:54:02 +00:00
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
src.Close()
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
2017-11-09 18:15:56 +00:00
|
|
|
// prepareReference creates an image reference from an image string and set options
|
2017-06-08 13:45:34 +00:00
|
|
|
// for the source context
|
2017-11-09 18:15:56 +00:00
|
|
|
func (svc *imageService) prepareReference(imageName string, options *copy.Options) (types.ImageReference, error) {
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
if imageName == "" {
|
|
|
|
return nil, storage.ErrNotAnImage
|
|
|
|
}
|
2017-06-08 13:45:34 +00:00
|
|
|
|
2017-03-13 15:16:03 +00:00
|
|
|
srcRef, err := alltransports.ParseImageName(imageName)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
if err != nil {
|
|
|
|
if svc.defaultTransport == "" {
|
|
|
|
return nil, err
|
|
|
|
}
|
2017-03-13 15:16:03 +00:00
|
|
|
srcRef2, err2 := alltransports.ParseImageName(svc.defaultTransport + imageName)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
if err2 != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
srcRef = srcRef2
|
|
|
|
}
|
2017-06-08 13:45:34 +00:00
|
|
|
|
|
|
|
if options.SourceCtx == nil {
|
|
|
|
options.SourceCtx = &types.SystemContext{}
|
|
|
|
}
|
|
|
|
|
|
|
|
hostname := reference.Domain(srcRef.DockerReference())
|
|
|
|
if secure := svc.isSecureIndex(hostname); !secure {
|
|
|
|
options.SourceCtx.DockerInsecureSkipTLSVerify = !secure
|
|
|
|
}
|
|
|
|
return srcRef, nil
|
|
|
|
}
|
|
|
|
|
2017-11-09 18:15:56 +00:00
|
|
|
func (svc *imageService) PrepareImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.Image, error) {
|
|
|
|
if options == nil {
|
|
|
|
options = ©.Options{}
|
|
|
|
}
|
|
|
|
|
|
|
|
srcRef, err := svc.prepareReference(imageName, options)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return srcRef.NewImage(systemContext)
|
|
|
|
}
|
|
|
|
|
2017-06-08 13:45:34 +00:00
|
|
|
func (svc *imageService) PullImage(systemContext *types.SystemContext, imageName string, options *copy.Options) (types.ImageReference, error) {
|
|
|
|
policy, err := signature.DefaultPolicy(systemContext)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
policyContext, err := signature.NewPolicyContext(policy)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if options == nil {
|
|
|
|
options = ©.Options{}
|
|
|
|
}
|
|
|
|
|
2017-11-09 18:15:56 +00:00
|
|
|
srcRef, err := svc.prepareReference(imageName, options)
|
2017-06-08 13:45:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
dest := imageName
|
|
|
|
if srcRef.DockerReference() != nil {
|
2017-03-13 15:16:03 +00:00
|
|
|
dest = srcRef.DockerReference().Name()
|
2017-03-24 15:34:12 +00:00
|
|
|
if tagged, ok := srcRef.DockerReference().(reference.NamedTagged); ok {
|
|
|
|
dest = dest + ":" + tagged.Tag()
|
|
|
|
}
|
2017-04-06 17:28:55 +00:00
|
|
|
if canonical, ok := srcRef.DockerReference().(reference.Canonical); ok {
|
|
|
|
dest = dest + "@" + canonical.Digest().String()
|
|
|
|
}
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
}
|
|
|
|
destRef, err := istorage.Transport.ParseStoreReference(svc.store, dest)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
err = copy.Image(policyContext, destRef, srcRef, options)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return destRef, nil
|
|
|
|
}
|
|
|
|
|
2017-10-30 21:18:42 +00:00
|
|
|
func (svc *imageService) UntagImage(systemContext *types.SystemContext, nameOrID string) error {
|
|
|
|
ref, err := alltransports.ParseImageName(nameOrID)
|
|
|
|
if err != nil {
|
|
|
|
ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, "@"+nameOrID)
|
|
|
|
if err2 != nil {
|
|
|
|
ref3, err3 := istorage.Transport.ParseStoreReference(svc.store, nameOrID)
|
|
|
|
if err3 != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
ref2 = ref3
|
|
|
|
}
|
|
|
|
ref = ref2
|
|
|
|
}
|
|
|
|
|
|
|
|
img, err := istorage.Transport.GetStoreImage(svc.store, ref)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !strings.HasPrefix(img.ID, nameOrID) {
|
|
|
|
namedRef, err := svc.prepareReference(nameOrID, ©.Options{})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
name := nameOrID
|
|
|
|
if namedRef.DockerReference() != nil {
|
|
|
|
name = namedRef.DockerReference().Name()
|
|
|
|
if tagged, ok := namedRef.DockerReference().(reference.NamedTagged); ok {
|
|
|
|
name = name + ":" + tagged.Tag()
|
|
|
|
}
|
|
|
|
if canonical, ok := namedRef.DockerReference().(reference.Canonical); ok {
|
|
|
|
name = name + "@" + canonical.Digest().String()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
prunedNames := make([]string, 0, len(img.Names))
|
|
|
|
for _, imgName := range img.Names {
|
|
|
|
if imgName != name && imgName != nameOrID {
|
|
|
|
prunedNames = append(prunedNames, imgName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(prunedNames) > 0 {
|
|
|
|
return svc.store.SetNames(img.ID, prunedNames)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ref.DeleteImage(systemContext)
|
|
|
|
}
|
|
|
|
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
func (svc *imageService) RemoveImage(systemContext *types.SystemContext, nameOrID string) error {
|
2017-03-13 15:16:03 +00:00
|
|
|
ref, err := alltransports.ParseImageName(nameOrID)
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
if err != nil {
|
|
|
|
ref2, err2 := istorage.Transport.ParseStoreReference(svc.store, "@"+nameOrID)
|
|
|
|
if err2 != nil {
|
|
|
|
ref3, err3 := istorage.Transport.ParseStoreReference(svc.store, nameOrID)
|
|
|
|
if err3 != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
ref2 = ref3
|
|
|
|
}
|
|
|
|
ref = ref2
|
|
|
|
}
|
|
|
|
return ref.DeleteImage(systemContext)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svc *imageService) GetStore() storage.Store {
|
|
|
|
return svc.store
|
|
|
|
}
|
|
|
|
|
2017-06-08 13:45:34 +00:00
|
|
|
func (svc *imageService) isSecureIndex(indexName string) bool {
|
|
|
|
if index, ok := svc.indexConfigs[indexName]; ok {
|
|
|
|
return index.secure
|
|
|
|
}
|
|
|
|
|
|
|
|
host, _, err := net.SplitHostPort(indexName)
|
|
|
|
if err != nil {
|
|
|
|
// assume indexName is of the form `host` without the port and go on.
|
|
|
|
host = indexName
|
|
|
|
}
|
|
|
|
|
|
|
|
addrs, err := net.LookupIP(host)
|
|
|
|
if err != nil {
|
|
|
|
ip := net.ParseIP(host)
|
|
|
|
if ip != nil {
|
|
|
|
addrs = []net.IP{ip}
|
|
|
|
}
|
|
|
|
|
|
|
|
// if ip == nil, then `host` is neither an IP nor it could be looked up,
|
|
|
|
// either because the index is unreachable, or because the index is behind an HTTP proxy.
|
|
|
|
// So, len(addrs) == 0 and we're not aborting.
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try CIDR notation only if addrs has any elements, i.e. if `host`'s IP could be determined.
|
|
|
|
for _, addr := range addrs {
|
|
|
|
for _, ipnet := range svc.insecureRegistryCIDRs {
|
|
|
|
// check if the addr falls in the subnet
|
2017-08-22 10:35:19 +00:00
|
|
|
if ipnet.Contains(addr) {
|
2017-06-08 13:45:34 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2017-11-28 00:34:55 +00:00
|
|
|
func splitDockerDomain(name string) (domain, remainder string) {
|
2017-09-07 09:57:16 +00:00
|
|
|
i := strings.IndexRune(name, '/')
|
|
|
|
if i == -1 || (!strings.ContainsAny(name[:i], ".:") && name[:i] != "localhost") {
|
2017-11-28 00:34:55 +00:00
|
|
|
domain, remainder = "", name
|
2017-09-07 09:57:16 +00:00
|
|
|
} else {
|
2017-11-28 00:34:55 +00:00
|
|
|
domain, remainder = name[:i], name[i+1:]
|
2017-09-07 09:57:16 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-07-20 08:01:23 +00:00
|
|
|
func (svc *imageService) ResolveNames(imageName string) ([]string, error) {
|
2017-12-11 21:02:54 +00:00
|
|
|
// _Maybe_ it's a truncated image ID. Don't prepend a registry name, then.
|
|
|
|
if len(imageName) >= minimumTruncatedIDLength && svc.store != nil {
|
|
|
|
if img, err := svc.store.Image(imageName); err == nil && img != nil && strings.HasPrefix(img.ID, imageName) {
|
|
|
|
// It's a truncated version of the ID of an image that's present in local storage;
|
|
|
|
// we need to expand it.
|
|
|
|
return []string{img.ID}, nil
|
|
|
|
}
|
|
|
|
}
|
2017-11-28 00:34:55 +00:00
|
|
|
// This to prevent any image ID to go through this routine
|
|
|
|
_, err := reference.ParseNormalizedNamed(imageName)
|
2017-07-20 08:01:23 +00:00
|
|
|
if err != nil {
|
2017-11-28 00:34:55 +00:00
|
|
|
if strings.Contains(err.Error(), "cannot specify 64-byte hexadecimal strings") {
|
|
|
|
return nil, ErrCannotParseImageID
|
|
|
|
}
|
2017-07-20 08:01:23 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2017-11-28 00:34:55 +00:00
|
|
|
domain, remainder := splitDockerDomain(imageName)
|
|
|
|
if domain != "" {
|
2017-07-20 08:01:23 +00:00
|
|
|
// this means the image is already fully qualified
|
|
|
|
return []string{imageName}, nil
|
|
|
|
}
|
|
|
|
// we got an unqualified image here, we can't go ahead w/o registries configured
|
|
|
|
// properly.
|
|
|
|
if len(svc.registries) == 0 {
|
|
|
|
return nil, errors.New("no registries configured while trying to pull an unqualified image")
|
|
|
|
}
|
|
|
|
// this means we got an image in the form of "busybox"
|
|
|
|
// we need to use additional registries...
|
|
|
|
// normalize the unqualified image to be domain/repo/image...
|
|
|
|
images := []string{}
|
|
|
|
for _, r := range svc.registries {
|
2017-11-28 00:34:55 +00:00
|
|
|
rem := remainder
|
|
|
|
if r == "docker.io" && !strings.ContainsRune(remainder, '/') {
|
|
|
|
rem = "library/" + rem
|
|
|
|
}
|
2017-10-30 21:18:42 +00:00
|
|
|
images = append(images, path.Join(r, rem))
|
2017-07-20 08:01:23 +00:00
|
|
|
}
|
|
|
|
return images, nil
|
|
|
|
}
|
|
|
|
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
// GetImageService returns an ImageServer that uses the passed-in store, and
|
|
|
|
// which will prepend the passed-in defaultTransport value to an image name if
|
|
|
|
// a name that's passed to its PullImage() method can't be resolved to an image
|
|
|
|
// in the store and can't be resolved to a source on its own.
|
2017-07-20 08:01:23 +00:00
|
|
|
func GetImageService(store storage.Store, defaultTransport string, insecureRegistries []string, registries []string) (ImageServer, error) {
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
if store == nil {
|
|
|
|
var err error
|
|
|
|
store, err = storage.GetStore(storage.DefaultStoreOptions)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
2017-06-08 13:45:34 +00:00
|
|
|
|
2017-07-20 08:01:23 +00:00
|
|
|
seenRegistries := make(map[string]bool, len(registries))
|
|
|
|
cleanRegistries := []string{}
|
|
|
|
for _, r := range registries {
|
|
|
|
if seenRegistries[r] {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
cleanRegistries = append(cleanRegistries, r)
|
|
|
|
seenRegistries[r] = true
|
|
|
|
}
|
|
|
|
|
2017-06-08 13:45:34 +00:00
|
|
|
is := &imageService{
|
|
|
|
store: store,
|
|
|
|
defaultTransport: defaultTransport,
|
|
|
|
indexConfigs: make(map[string]*indexInfo, 0),
|
|
|
|
insecureRegistryCIDRs: make([]*net.IPNet, 0),
|
2017-07-20 08:01:23 +00:00
|
|
|
registries: cleanRegistries,
|
2018-02-14 18:57:18 +00:00
|
|
|
imageCache: make(map[string]imageCacheItem),
|
2017-06-08 13:45:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
insecureRegistries = append(insecureRegistries, "127.0.0.0/8")
|
|
|
|
// Split --insecure-registry into CIDR and registry-specific settings.
|
|
|
|
for _, r := range insecureRegistries {
|
|
|
|
// Check if CIDR was passed to --insecure-registry
|
|
|
|
_, ipnet, err := net.ParseCIDR(r)
|
|
|
|
if err == nil {
|
|
|
|
// Valid CIDR.
|
|
|
|
is.insecureRegistryCIDRs = append(is.insecureRegistryCIDRs, ipnet)
|
|
|
|
} else {
|
|
|
|
// Assume `host:port` if not CIDR.
|
|
|
|
is.indexConfigs[r] = &indexInfo{
|
|
|
|
name: r,
|
|
|
|
secure: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return is, nil
|
Add storage utility functions
Add an intermediate API layer that uses containers/storage, and a
containers/image that has been patched to use it, to manage images and
containers, storing the data that we need to know about containers and
pods in the metadata fields provided by containers/storage.
While ocid manages pods and containers as different types of items, with
disjoint sets of IDs and names, it remains true that every pod includes
at least one container. When a container's only purpose is to serve as
a home for namespaces that are shared with the other containers in the
pod, it is referred to as the pod's infrastructure container.
At the storage level, a pod is stored as its set of containers. We keep
track of both pod IDs and container IDs in the metadata field of
Container objects that the storage library manages for us. Containers
which bear the same pod ID are members of the pod which has that ID.
Other information about the pod, which ocid needs to remember in order
to answer requests for information about the pod, is also kept in the
metadata field of its member containers.
The container's runtime configuration should be stored in the
container's ContainerDirectory, and used as a template. Each time the
container is about to be started, its layer should be mounted, that
configuration template should be read, the template's rootfs location
should be replaced with the mountpoint for the container's layer, and
the result should be saved to the container's ContainerRunDirectory,
for use as the configuration for the container.
Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
2016-11-22 18:50:33 +00:00
|
|
|
}
|