mirror of
https://github.com/containers/podman.git
synced 2025-10-17 19:24:04 +08:00
add new artifact mount type
Add a new option to allow for mounting artifacts in the container, the syntax is added to the existing --mount option: type=artifact,src=$artifactName,dest=/path[,digest=x][,title=x] This works very similar to image mounts. The name is passed down into the container config and then on each start we lookup the artifact and the figure out which blobs to mount. There is no protaction against a user removing the artifact while still being used in a container. When the container is running the bind mounted files will stay there (as the kernel keeps the mounts active even if the bind source was deleted). On the next start it will fail to start as if it does not find the artifact. The good thing is that this technically allows someone to update the artifact with the new file by creating a new artifact with the same name. Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
@ -41,6 +41,7 @@ import (
|
||||
"github.com/containers/podman/v5/pkg/annotations"
|
||||
"github.com/containers/podman/v5/pkg/checkpoint/crutils"
|
||||
"github.com/containers/podman/v5/pkg/criu"
|
||||
libartTypes "github.com/containers/podman/v5/pkg/libartifact/types"
|
||||
"github.com/containers/podman/v5/pkg/lookup"
|
||||
"github.com/containers/podman/v5/pkg/rootless"
|
||||
"github.com/containers/podman/v5/pkg/util"
|
||||
@ -483,6 +484,52 @@ func (c *Container) generateSpec(ctx context.Context) (s *spec.Spec, cleanupFunc
|
||||
g.AddMount(overlayMount)
|
||||
}
|
||||
|
||||
if len(c.config.ArtifactVolumes) > 0 {
|
||||
artStore, err := c.runtime.ArtifactStore()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for _, artifactMount := range c.config.ArtifactVolumes {
|
||||
paths, err := artStore.BlobMountPaths(ctx, artifactMount.Source, &libartTypes.BlobMountPathOptions{
|
||||
FilterBlobOptions: libartTypes.FilterBlobOptions{
|
||||
Title: artifactMount.Title,
|
||||
Digest: artifactMount.Digest,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Ignore the error, destIsFile will return false with errors so if the file does not exist
|
||||
// we treat it as dir, the oci runtime will always create the target bind mount path.
|
||||
destIsFile, _ := containerPathIsFile(c.state.Mountpoint, artifactMount.Dest)
|
||||
if destIsFile && len(paths) > 1 {
|
||||
return nil, nil, fmt.Errorf("artifact %q contains more than one blob and container path %q is a file", artifactMount.Source, artifactMount.Dest)
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
var dest string
|
||||
if destIsFile {
|
||||
dest = artifactMount.Dest
|
||||
} else {
|
||||
dest = filepath.Join(artifactMount.Dest, path.Name)
|
||||
}
|
||||
|
||||
logrus.Debugf("Mounting artifact %q in container %s, mount blob %q to %q", artifactMount.Source, c.ID(), path.SourcePath, dest)
|
||||
|
||||
g.AddMount(spec.Mount{
|
||||
Destination: dest,
|
||||
Source: path.SourcePath,
|
||||
Type: define.TypeBind,
|
||||
// Important: This must always be mounted read only here, we are using
|
||||
// the source in the artifact store directly and because that is digest
|
||||
// based a write will break the layout.
|
||||
Options: []string{define.TypeBind, "ro"},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = c.setHomeEnvIfNeeded()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
|
Reference in New Issue
Block a user