mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
109 lines
2.3 KiB
Go
109 lines
2.3 KiB
Go
package containerd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/containerd/containerd/v2/core/mount"
|
|
)
|
|
|
|
type MountedSnapshot struct {
|
|
Dir string
|
|
Info ContainerInfo
|
|
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
|
|
}
|
|
|
|
info, err := service.GetContainer(ctx, containerID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
mountInfos, err := service.SnapshotMounts(ctx, info.Snapshotter, info.SnapshotKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
mounts := make([]mount.Mount, len(mountInfos))
|
|
for i, m := range mountInfos {
|
|
mounts[i] = mount.Mount{
|
|
Type: m.Type,
|
|
Source: m.Source,
|
|
Options: m.Options,
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
mountInfos, err := service.SnapshotMounts(ctx, snapshotter, key)
|
|
if err != nil {
|
|
return "", nil, err
|
|
}
|
|
|
|
mounts := make([]mount.Mount, len(mountInfos))
|
|
for i, m := range mountInfos {
|
|
mounts[i] = mount.Mount{
|
|
Type: m.Type,
|
|
Source: m.Source,
|
|
Options: m.Options,
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|