Skip to content

Instantly share code, notes, and snippets.

@alexeldeib
Last active March 31, 2023 16:29
Show Gist options
  • Save alexeldeib/92c5eec418a863d333ddf00c7f41a030 to your computer and use it in GitHub Desktop.
Save alexeldeib/92c5eec418a863d333ddf00c7f41a030 to your computer and use it in GitHub Desktop.
unpack/repack containerd snapshot manually
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/containerd/containerd"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/snapshots"
"github.com/moby/moby/pkg/archive"
)
func main() {
if err := run(); err != nil {
log.Fatal(err)
}
}
func run() error {
ctx := namespaces.WithNamespace(context.Background(), "example")
client, err := containerd.New("/run/containerd/containerd.sock")
if err != nil {
return err
}
defer client.Close()
snapshotter := client.SnapshotService("overlayfs")
tmpDir := "/tmp/unpack"
err = os.MkdirAll(tmpDir, 0666)
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
layerPath := "/tmp/layer/layer.tar" // just a path to layer tar file.
noGcOpt := snapshots.WithLabels(map[string]string{
"containerd.io/gc.root": time.Now().UTC().Format(time.RFC3339),
})
mounts, err := snapshotter.Prepare(ctx, "foo", "", noGcOpt)
if err != nil {
return fmt.Errorf("failed to prepare snapshot: %v", err)
}
fmt.Printf("%#+v\n", mounts)
if err := mount.All(mounts, tmpDir); err != nil {
return fmt.Errorf("failed to mount all: %v", err)
}
defer mount.UnmountAll(tmpDir, 0)
layer, err := os.Open(layerPath)
if err != nil {
return fmt.Errorf("failed to open layer: %v", err)
}
_, err = archive.UnpackLayer(tmpDir, layer, nil) // unpack into layer location
if err != nil {
return fmt.Errorf("failed to unpack layer: %v", err)
}
// tmpDir would have the unpacked layer.
// it would be a bindmount to an active snapshot dir
if err := snapshotter.Commit(ctx, "bar", "foo", noGcOpt); err != nil {
return fmt.Errorf("failed to commit snapshot: %v", err)
}
// at this point the original snapshot is gone, but the new one could be seen in storage
// ctr -n example snapshot ls
// to clean up:
// ctr -n example snapshot rm foo
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment