10
istorage "github.com/containers/image/v5/storage"
11
"github.com/containers/image/v5/types"
12
"github.com/containers/podman/v5/libpod/define"
13
"github.com/containers/storage"
14
"github.com/containers/storage/pkg/idtools"
15
v1 "github.com/opencontainers/image-spec/specs-go/v1"
16
"github.com/sirupsen/logrus"
19
type storageService struct {
25
func getStorageService(store storage.Store) *storageService {
26
return &storageService{store: store}
34
type ContainerInfo struct {
40
UIDMap []idtools.IDMap
41
GIDMap []idtools.IDMap
51
type RuntimeContainerMetadata struct {
54
ImageName string `json:"image-name"`
55
ImageID string `json:"image-id"`
57
ContainerName string `json:"name"`
58
CreatedAt int64 `json:"created-at"`
59
MountLabel string `json:"mountlabel,omitempty"`
64
func (metadata *RuntimeContainerMetadata) SetMountLabel(mountLabel string) {
65
metadata.MountLabel = mountLabel
71
func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID string, options storage.ContainerOptions) (_ ContainerInfo, retErr error) {
72
var imageConfig *v1.Image
74
if containerName == "" {
75
return ContainerInfo{}, define.ErrEmptyID
78
ref, err := istorage.Transport.NewStoreReference(r.store, nil, imageID)
80
return ContainerInfo{}, err
83
image, err := ref.NewImage(ctx, systemContext)
85
return ContainerInfo{}, err
90
imageConfig, err = image.OCIConfig(ctx)
92
return ContainerInfo{}, err
97
metadata := RuntimeContainerMetadata{
100
ContainerName: containerName,
101
CreatedAt: time.Now().Unix(),
103
mdata, err := json.Marshal(&metadata)
105
return ContainerInfo{}, err
109
names := []string{containerName}
111
container, err := r.store.CreateContainer(containerID, names, imageID, "", string(mdata), &options)
113
logrus.Debugf("Failed to create container %s(%s): %v", metadata.ContainerName, containerID, err)
115
return ContainerInfo{}, err
117
logrus.Debugf("Created container %q", container.ID)
123
if err := r.store.DeleteContainer(container.ID); err != nil {
124
logrus.Infof("Error deleting partially-created container %q: %v", container.ID, err)
128
logrus.Infof("Deleted partially-created container %q", container.ID)
134
layerName := metadata.ContainerName + "-layer"
135
names, err = r.store.Names(container.LayerID)
137
return ContainerInfo{}, err
139
names = append(names, layerName)
140
err = r.store.SetNames(container.LayerID, names)
142
return ContainerInfo{}, err
146
containerDir, err := r.store.ContainerDirectory(container.ID)
148
return ContainerInfo{}, err
150
logrus.Debugf("Container %q has work directory %q", container.ID, containerDir)
152
containerRunDir, err := r.store.ContainerRunDirectory(container.ID)
154
return ContainerInfo{}, err
156
logrus.Debugf("Container %q has run directory %q", container.ID, containerRunDir)
158
return ContainerInfo{
159
UIDMap: container.UIDMap,
160
GIDMap: container.GIDMap,
162
RunDir: containerRunDir,
164
ProcessLabel: container.ProcessLabel(),
165
MountLabel: container.MountLabel(),
169
func (r *storageService) DeleteContainer(idOrName string) error {
171
return define.ErrEmptyID
173
container, err := r.store.Container(idOrName)
177
err = r.store.DeleteContainer(container.ID)
179
if errors.Is(err, storage.ErrNotAContainer) || errors.Is(err, storage.ErrContainerUnknown) {
180
logrus.Infof("Storage for container %s already removed", container.ID)
182
logrus.Debugf("Failed to delete container %q: %v", container.ID, err)
189
func (r *storageService) SetContainerMetadata(idOrName string, metadata RuntimeContainerMetadata) error {
190
mdata, err := json.Marshal(&metadata)
192
logrus.Debugf("Failed to encode metadata for %q: %v", idOrName, err)
195
return r.store.SetMetadata(idOrName, string(mdata))
198
func (r *storageService) GetContainerMetadata(idOrName string) (RuntimeContainerMetadata, error) {
199
metadata := RuntimeContainerMetadata{}
200
mdata, err := r.store.Metadata(idOrName)
204
if err = json.Unmarshal([]byte(mdata), &metadata); err != nil {
210
func (r *storageService) MountContainerImage(idOrName string) (string, error) {
211
container, err := r.store.Container(idOrName)
213
if errors.Is(err, storage.ErrContainerUnknown) {
214
return "", define.ErrNoSuchCtr
218
metadata := RuntimeContainerMetadata{}
219
if err = json.Unmarshal([]byte(container.Metadata), &metadata); err != nil {
222
mountPoint, err := r.store.Mount(container.ID, metadata.MountLabel)
224
logrus.Debugf("Failed to mount container %q: %v", container.ID, err)
227
logrus.Debugf("Mounted container %q at %q", container.ID, mountPoint)
228
return mountPoint, nil
231
func (r *storageService) UnmountContainerImage(idOrName string, force bool) (bool, error) {
233
return false, define.ErrEmptyID
235
container, err := r.store.Container(idOrName)
241
mounted, err := r.store.Mounted(container.ID)
246
return false, storage.ErrLayerNotMounted
249
mounted, err := r.store.Unmount(container.ID, force)
251
logrus.Debugf("Failed to unmount container %q: %v", container.ID, err)
254
logrus.Debugf("Unmounted container %q", container.ID)
258
func (r *storageService) MountedContainerImage(idOrName string) (int, error) {
260
return 0, define.ErrEmptyID
262
container, err := r.store.Container(idOrName)
266
mounted, err := r.store.Mounted(container.ID)
273
func (r *storageService) GetMountpoint(id string) (string, error) {
274
container, err := r.store.Container(id)
276
if errors.Is(err, storage.ErrContainerUnknown) {
277
return "", define.ErrNoSuchCtr
281
layer, err := r.store.Layer(container.LayerID)
286
return layer.MountPoint, nil
289
func (r *storageService) GetWorkDir(id string) (string, error) {
290
container, err := r.store.Container(id)
292
if errors.Is(err, storage.ErrContainerUnknown) {
293
return "", define.ErrNoSuchCtr
297
return r.store.ContainerDirectory(container.ID)
300
func (r *storageService) GetRunDir(id string) (string, error) {
301
container, err := r.store.Container(id)
303
if errors.Is(err, storage.ErrContainerUnknown) {
304
return "", define.ErrNoSuchCtr
308
return r.store.ContainerRunDirectory(container.ID)