daemon: make the snapshotter configurable
Treat (storage/graph)Driver as snapshotter Also moved some layerStore related initialization to the non-c8d case because otherwise they get treated as a graphdriver plugins. Co-authored-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Djordje Lukic <djordje.lukic@docker.com> Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
464882e398
commit
d8d990f2e3
6 changed files with 77 additions and 65 deletions
|
@ -53,7 +53,7 @@ func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outSt
|
|||
for _, img := range imgs {
|
||||
platformImg := containerd.NewImageWithPlatform(i.client, img, platform)
|
||||
|
||||
unpacked, err := platformImg.IsUnpacked(ctx, containerd.DefaultSnapshotter)
|
||||
unpacked, err := platformImg.IsUnpacked(ctx, i.snapshotter)
|
||||
if err != nil {
|
||||
// TODO(thaJeztah): remove this log or change to debug once we can; see https://github.com/moby/moby/pull/43822#discussion_r937502405
|
||||
logrus.WithError(err).WithField("image", img.Name).Debug("failed to check if image is unpacked")
|
||||
|
@ -61,7 +61,7 @@ func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outSt
|
|||
}
|
||||
|
||||
if !unpacked {
|
||||
err := platformImg.Unpack(ctx, containerd.DefaultSnapshotter)
|
||||
err := platformImg.Unpack(ctx, i.snapshotter)
|
||||
if err != nil {
|
||||
// TODO(thaJeztah): remove this log or change to debug once we can; see https://github.com/moby/moby/pull/43822#discussion_r937502405
|
||||
logrus.WithError(err).WithField("image", img.Name).Warn("failed to unpack image")
|
||||
|
|
|
@ -41,7 +41,7 @@ func (i *ImageService) Images(ctx context.Context, opts types.ImageListOptions)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
snapshotter := i.client.SnapshotService(containerd.DefaultSnapshotter)
|
||||
snapshotter := i.client.SnapshotService(i.snapshotter)
|
||||
sizeCache := make(map[digest.Digest]int64)
|
||||
snapshotSizeFn := func(d digest.Digest) (int64, error) {
|
||||
if s, ok := sizeCache[d]; ok {
|
||||
|
|
|
@ -13,13 +13,15 @@ import (
|
|||
|
||||
// ImageService implements daemon.ImageService
|
||||
type ImageService struct {
|
||||
client *containerd.Client
|
||||
client *containerd.Client
|
||||
snapshotter string
|
||||
}
|
||||
|
||||
// NewService creates a new ImageService.
|
||||
func NewService(c *containerd.Client) *ImageService {
|
||||
func NewService(c *containerd.Client, snapshotter string) *ImageService {
|
||||
return &ImageService{
|
||||
client: c,
|
||||
client: c,
|
||||
snapshotter: snapshotter,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +83,7 @@ func (i *ImageService) Cleanup() error {
|
|||
// StorageDriver returns the name of the default storage-driver (snapshotter)
|
||||
// used by the ImageService.
|
||||
func (i *ImageService) StorageDriver() string {
|
||||
return ""
|
||||
return i.snapshotter
|
||||
}
|
||||
|
||||
// ReleaseLayer releases a layer allowing it to be removed
|
||||
|
|
113
daemon/daemon.go
113
daemon/daemon.go
|
@ -833,22 +833,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
|||
}
|
||||
}
|
||||
|
||||
var graphDriver string
|
||||
if isWindows {
|
||||
// On Windows we don't support the environment variable, or a user supplied graphdriver
|
||||
graphDriver = "windowsfilter"
|
||||
} else {
|
||||
// Unix platforms however run a single graphdriver for all containers, and it can
|
||||
// be set through an environment variable, a daemon start parameter, or chosen through
|
||||
// initialization of the layerstore through driver priority order for example.
|
||||
if drv := os.Getenv("DOCKER_DRIVER"); drv != "" {
|
||||
graphDriver = drv
|
||||
logrus.Infof("Setting the storage driver from the $DOCKER_DRIVER environment variable (%s)", drv)
|
||||
} else {
|
||||
graphDriver = config.GraphDriver // May still be empty. Layerstore init determines instead.
|
||||
}
|
||||
}
|
||||
|
||||
d.registryService = registryService
|
||||
logger.RegisterPluginGetter(d.PluginStore)
|
||||
|
||||
|
@ -938,27 +922,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
|||
return nil, err
|
||||
}
|
||||
|
||||
layerStore, err := layer.NewStoreFromOptions(layer.StoreOptions{
|
||||
Root: config.Root,
|
||||
MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"),
|
||||
GraphDriver: graphDriver,
|
||||
GraphDriverOptions: config.GraphOptions,
|
||||
IDMapping: idMapping,
|
||||
PluginGetter: d.PluginStore,
|
||||
ExperimentalEnabled: config.Experimental,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Configure and validate the kernels security support. Note this is a Linux/FreeBSD
|
||||
// operation only, so it is safe to pass *just* the runtime OS graphdriver.
|
||||
if err := configureKernelSecuritySupport(config, layerStore.DriverName()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
imageRoot := filepath.Join(config.Root, "image", layerStore.DriverName())
|
||||
|
||||
d.volumes, err = volumesservice.NewVolumeService(config.Root, d.PluginStore, rootIDs, d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -972,23 +935,6 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
|||
logrus.WithError(err).Warnf("unable to migrate engine ID; a new engine ID will be generated")
|
||||
}
|
||||
|
||||
// We have a single tag/reference store for the daemon globally. However, it's
|
||||
// stored under the graphdriver. On host platforms which only support a single
|
||||
// container OS, but multiple selectable graphdrivers, this means depending on which
|
||||
// graphdriver is chosen, the global reference store is under there. For
|
||||
// platforms which support multiple container operating systems, this is slightly
|
||||
// more problematic as where does the global ref store get located? Fortunately,
|
||||
// for Windows, which is currently the only daemon supporting multiple container
|
||||
// operating systems, the list of graphdrivers available isn't user configurable.
|
||||
// For backwards compatibility, we just put it under the windowsfilter
|
||||
// directory regardless.
|
||||
refStoreLocation := filepath.Join(imageRoot, `repositories.json`)
|
||||
rs, err := refstore.NewReferenceStore(refStoreLocation)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Couldn't create reference store repository: %s", err)
|
||||
}
|
||||
d.ReferenceStore = rs
|
||||
|
||||
// Check if Devices cgroup is mounted, it is hard requirement for container security,
|
||||
// on Linux.
|
||||
//
|
||||
|
@ -1019,14 +965,69 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
|
|||
|
||||
d.linkIndex = newLinkIndex()
|
||||
|
||||
if d.UsesSnapshotter() {
|
||||
d.imageService = ctrd.NewService(d.containerdCli)
|
||||
// On Windows we don't support the environment variable, or a user supplied graphdriver
|
||||
// Unix platforms however run a single graphdriver for all containers, and it can
|
||||
// be set through an environment variable, a daemon start parameter, or chosen through
|
||||
// initialization of the layerstore through driver priority order for example.
|
||||
driverName := os.Getenv("DOCKER_DRIVER")
|
||||
if isWindows {
|
||||
driverName = "windowsfilter"
|
||||
} else if driverName != "" {
|
||||
logrus.Infof("Setting the storage driver from the $DOCKER_DRIVER environment variable (%s)", driverName)
|
||||
} else {
|
||||
driverName = config.GraphDriver
|
||||
}
|
||||
|
||||
if d.UsesSnapshotter() {
|
||||
// Configure and validate the kernels security support. Note this is a Linux/FreeBSD
|
||||
// operation only, so it is safe to pass *just* the runtime OS graphdriver.
|
||||
if err := configureKernelSecuritySupport(config, driverName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d.imageService = ctrd.NewService(d.containerdCli, driverName)
|
||||
} else {
|
||||
layerStore, err := layer.NewStoreFromOptions(layer.StoreOptions{
|
||||
Root: config.Root,
|
||||
MetadataStorePathTemplate: filepath.Join(config.Root, "image", "%s", "layerdb"),
|
||||
GraphDriver: driverName,
|
||||
GraphDriverOptions: config.GraphOptions,
|
||||
IDMapping: idMapping,
|
||||
PluginGetter: d.PluginStore,
|
||||
ExperimentalEnabled: config.Experimental,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Configure and validate the kernels security support. Note this is a Linux/FreeBSD
|
||||
// operation only, so it is safe to pass *just* the runtime OS graphdriver.
|
||||
if err := configureKernelSecuritySupport(config, layerStore.DriverName()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
imageRoot := filepath.Join(config.Root, "image", layerStore.DriverName())
|
||||
ifs, err := image.NewFSStoreBackend(filepath.Join(imageRoot, "imagedb"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// We have a single tag/reference store for the daemon globally. However, it's
|
||||
// stored under the graphdriver. On host platforms which only support a single
|
||||
// container OS, but multiple selectable graphdrivers, this means depending on which
|
||||
// graphdriver is chosen, the global reference store is under there. For
|
||||
// platforms which support multiple container operating systems, this is slightly
|
||||
// more problematic as where does the global ref store get located? Fortunately,
|
||||
// for Windows, which is currently the only daemon supporting multiple container
|
||||
// operating systems, the list of graphdrivers available isn't user configurable.
|
||||
// For backwards compatibility, we just put it under the windowsfilter
|
||||
// directory regardless.
|
||||
refStoreLocation := filepath.Join(imageRoot, `repositories.json`)
|
||||
rs, err := refstore.NewReferenceStore(refStoreLocation)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Couldn't create reference store repository: %s", err)
|
||||
}
|
||||
d.ReferenceStore = rs
|
||||
|
||||
imageStore, err := image.NewImageStore(ifs, layerStore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -822,7 +822,7 @@ func configureKernelSecuritySupport(config *config.Config, driverName string) er
|
|||
return nil
|
||||
}
|
||||
|
||||
if driverName == "overlay" || driverName == "overlay2" {
|
||||
if driverName == "overlay" || driverName == "overlay2" || driverName == "overlayfs" {
|
||||
// If driver is overlay or overlay2, make sure kernel
|
||||
// supports selinux with overlay.
|
||||
supported, err := overlaySupportsSelinux()
|
||||
|
|
|
@ -1045,8 +1045,17 @@ func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, e
|
|||
if daemon.configStore.Rootless {
|
||||
opts = append(opts, WithRootless(daemon))
|
||||
}
|
||||
|
||||
var snapshotter, snapshotKey string
|
||||
if daemon.UsesSnapshotter() {
|
||||
snapshotter = daemon.imageService.StorageDriver()
|
||||
snapshotKey = c.ID
|
||||
}
|
||||
|
||||
return &s, coci.ApplyOpts(context.Background(), nil, &containers.Container{
|
||||
ID: c.ID,
|
||||
ID: c.ID,
|
||||
Snapshotter: snapshotter,
|
||||
SnapshotKey: snapshotKey,
|
||||
}, &s, opts...)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue