From 958abd8ba894cf46c69290062d539d3b189177f9 Mon Sep 17 00:00:00 2001 From: saurabh Date: Fri, 8 Oct 2021 22:57:03 +0530 Subject: [PATCH 1/2] export file system changes --- containerd/containerd.go | 56 ++++++++++++++++++++++++++++++++++++++++ docker/docker.go | 19 ++++++++++++++ runtime.go | 1 + 3 files changed, 76 insertions(+) diff --git a/containerd/containerd.go b/containerd/containerd.go index fcd177f..3530508 100644 --- a/containerd/containerd.go +++ b/containerd/containerd.go @@ -2,10 +2,17 @@ package containerd import ( "bytes" + "context" "errors" "fmt" + "time" + containerdApi "github.com/containerd/containerd" + "github.com/containerd/containerd/namespaces" + "github.com/containerd/containerd/oci" + "os" "os/exec" "path" + "strings" ) // New instantiates a new Containerd runtime object @@ -141,3 +148,52 @@ func MigrateOCITarToDockerV1Tar(dir, tarName string) error { return nil } + +// ExtractFileSystem Extract the file system from tar of an image by creating a temporary dormant container instance +func (c Containerd) ExtractFileSystem(imageTarPath string, outputTarPath string, imageName string) error { + // create a new client connected to the default socket path for containerd + client, err := containerdApi.New("/run/containerd/containerd.sock") + if err != nil { + return err + } + defer client.Close() + // create a new context with an "temp" namespace + ctx := namespaces.WithNamespace(context.Background(), "temp") + reader, err := os.Open(imageTarPath) + if err != nil { + return err + } + imgs, err := client.Import(ctx, reader) + if err != nil { + return err + } + image, err := client.GetImage(ctx, imgs[0].Name) + if err != nil { + return err + } + snapshotName := imageName + string(time.Now().Unix()) + container, err := client.NewContainer( + ctx, + imageName, + containerdApi.WithImage(image), + containerdApi.WithNewSnapshot(snapshotName, image), + containerdApi.WithNewSpec(oci.WithImageConfig(image)), + ) + if err != nil { + return err + } + info, _ := container.Info(ctx) + snapshotter := client.SnapshotService(info.Snapshotter) + mounts, err := snapshotter.Mounts(ctx, snapshotName) + path := []string{""} + if len(mounts) > 0 { + options := mounts[len(mounts)-1].Options + path = strings.Split(options[len(options)-1], ":") + } + _, err = exec.Command("tar", "-czvf", outputTarPath, path[len(path)-1]).Output() + if err != nil { + return err + } + defer container.Delete(ctx, containerdApi.WithSnapshotCleanup) + return nil +} \ No newline at end of file diff --git a/docker/docker.go b/docker/docker.go index b12bab5..c15a65d 100644 --- a/docker/docker.go +++ b/docker/docker.go @@ -59,3 +59,22 @@ func (d Docker) GetImageID(imageName string) ([]byte, error) { func (d Docker) Save(imageName, outputParam string) ([]byte, error) { return exec.Command("docker", "save", imageName, "-o", outputParam).Output() } + +// ExtractFileSystem Extract the file system from tar of an image by creating a temporary dormant container instance +func (d Docker) ExtractFileSystem(imageTarPath string, outputTarPath string, imageName string) error { + _, err := exec.Command("docker", "import", imageTarPath, imageName+":temp").Output() + if err != nil { + return err + } + containerId, err := exec.Command("docker", "create", imageName+":temp", "--name", imageName+"-temp").Output() + if err != nil { + return err + } + _, err = exec.Command("docker", "export", string(containerId), ">", outputTarPath).Output() + if err != nil { + return err + } + exec.Command("docker", "container", "rm", string(containerId)) + exec.Command("docker", "image", "rm", imageName+":temp") + return nil +} diff --git a/runtime.go b/runtime.go index 046e3d8..9b5e82d 100644 --- a/runtime.go +++ b/runtime.go @@ -6,4 +6,5 @@ type Runtime interface { GetImageID(imageName string) ([]byte, error) Save(imageName, outputParam string) ([]byte, error) GetSocket() string + ExtractFileSystem(imageTarPath string, outputTarPath string, imageName string) error } From 60fd136e672c297335941805c2492cddeb1cfbda Mon Sep 17 00:00:00 2001 From: Saurabh Kumar Date: Sun, 10 Oct 2021 16:22:47 +0530 Subject: [PATCH 2/2] move socket address to constant --- constants/constants.go | 1 + containerd/containerd.go | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/constants/constants.go b/constants/constants.go index 8d519ef..f9f94b0 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -8,6 +8,7 @@ const ( CONTAINERD_K8S_NS = "k8s.io" CONTAINERD = "containerd" DOCKER = "docker" + CONTAINERD_SOCKET_ADDRESS = "/run/containerd/containerd.sock" ) var SupportedRuntimes = map[string]string{ diff --git a/containerd/containerd.go b/containerd/containerd.go index 3530508..cebfff0 100644 --- a/containerd/containerd.go +++ b/containerd/containerd.go @@ -5,14 +5,15 @@ import ( "context" "errors" "fmt" - "time" containerdApi "github.com/containerd/containerd" "github.com/containerd/containerd/namespaces" "github.com/containerd/containerd/oci" + "github.com/deepfence/vessel/constants" "os" "os/exec" "path" "strings" + "time" ) // New instantiates a new Containerd runtime object @@ -152,7 +153,7 @@ func MigrateOCITarToDockerV1Tar(dir, tarName string) error { // ExtractFileSystem Extract the file system from tar of an image by creating a temporary dormant container instance func (c Containerd) ExtractFileSystem(imageTarPath string, outputTarPath string, imageName string) error { // create a new client connected to the default socket path for containerd - client, err := containerdApi.New("/run/containerd/containerd.sock") + client, err := containerdApi.New(constants.CONTAINERD_SOCKET_ADDRESS) if err != nil { return err }