package containerd import ( "context" "fmt" "os" "github.com/containerd/containerd/v2/core/containers" "github.com/containerd/containerd/v2/core/mount" ) type MountedSnapshot struct { Dir string Info containers.Container Unmount func() error } // MountContainerSnapshot mounts the active snapshot for a container. func MountContainerSnapshot(ctx context.Context, service Service, containerID string) (*MountedSnapshot, error) { if containerID == "" { return nil, ErrInvalidArgument } container, err := service.GetContainer(ctx, containerID) if err != nil { return nil, err } info, err := container.Info(ctx) if err != nil { return nil, err } mounts, err := service.SnapshotMounts(ctx, info.Snapshotter, info.SnapshotKey) if err != nil { return nil, err } dir, err := os.MkdirTemp("", "memoh-snapshot-*") if err != nil { return nil, err } if err := mount.All(mounts, dir); err != nil { _ = os.RemoveAll(dir) return nil, err } return &MountedSnapshot{ Dir: dir, Info: info, Unmount: func() error { if err := mount.UnmountAll(dir, 0); err != nil { return fmt.Errorf("unmount snapshot: %w", err) } if err := os.RemoveAll(dir); err != nil { return fmt.Errorf("remove snapshot dir: %w", err) } return nil }, }, nil } // MountSnapshot mounts a snapshot by snapshotter/key without a container. func MountSnapshot(ctx context.Context, service Service, snapshotter, key string) (string, func() error, error) { if snapshotter == "" || key == "" { return "", nil, ErrInvalidArgument } mounts, err := service.SnapshotMounts(ctx, snapshotter, key) if err != nil { return "", nil, err } dir, err := os.MkdirTemp("", "memoh-snapshot-*") if err != nil { return "", nil, err } if err := mount.All(mounts, dir); err != nil { _ = os.RemoveAll(dir) return "", nil, err } cleanup := func() error { if err := mount.UnmountAll(dir, 0); err != nil { return fmt.Errorf("unmount snapshot: %w", err) } if err := os.RemoveAll(dir); err != nil { return fmt.Errorf("remove snapshot dir: %w", err) } return nil } return dir, cleanup, nil }