Skip to content

Commit

Permalink
support copying files in volume
Browse files Browse the repository at this point in the history
Signed-off-by: fahed dorgaa <fahed.dorgaa@gmail.com>
  • Loading branch information
fahedouch committed Apr 30, 2021
1 parent d57846d commit 7a00aaa
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68
github.com/containerd/console v1.0.2
github.com/containerd/containerd v1.5.0-rc.1
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e
github.com/containerd/go-cni v1.0.1
github.com/containerd/imgcrypt v1.1.1
github.com/containerd/stargz-snapshotter v0.5.0
Expand Down
1 change: 1 addition & 0 deletions run.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ func runAction(clicontext *cli.Context) error {
if ensuredImage != nil {
imageVolumes = ensuredImage.ImageConfig.Volumes
}

mountOpts, anonVolumes, err := generateMountOpts(clicontext, imageVolumes)
if err != nil {
return err
Expand Down
69 changes: 69 additions & 0 deletions run_mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,20 @@
package main

import (
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/containerd/containerd"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/oci"
"github.com/containerd/continuity/fs"
"github.com/containerd/nerdctl/pkg/idgen"
"github.com/containerd/nerdctl/pkg/mountutil"
"github.com/containerd/nerdctl/pkg/strutil"
"github.com/opencontainers/image-spec/identity"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -69,12 +77,59 @@ func generateMountOpts(clicontext *cli.Context, imageVolumes map[string]struct{}
continue
}
anonVolName := idgen.GenerateID()

logrus.Debugf("creating anonymous volume %q, for \"VOLUME %s\"",
anonVolName, imgVolRaw)
anonVol, err := volStore.Create(anonVolName)
if err != nil {
return nil, nil, err
}

client, ctx, cancel, err := newClient(clicontext)
if err != nil {
return nil, nil, err
}
defer cancel()

img, err := client.ImageService().Get(ctx, clicontext.Args().First())
if err != nil {
return nil, nil, err
}

i := containerd.NewImage(client, img)

if err := i.Unpack(ctx, clicontext.String("snapshotter")); err != nil {
return nil, nil, errors.Wrap(err, "error unpacking image")
}

diffIDs, err := i.RootFS(ctx)
if err != nil {
return nil, nil, err
}
chainID := identity.ChainID(diffIDs).String()

s := client.SnapshotService(clicontext.String("snapshotter"))

tempDir, err := ioutil.TempDir(os.Getenv("GOTMPDIR"), "initialC")
if err != nil {
return nil, nil, err
}
defer os.RemoveAll(tempDir)

var mounts []mount.Mount
mounts, err = s.View(ctx, tempDir, chainID)

if err := mount.All(mounts, tempDir); err != nil {
if err := s.Remove(ctx, tempDir); err != nil && !errdefs.IsNotFound(err) {
return nil, nil, err
}
return nil, nil, err
}
target := strings.Join([]string{tempDir, imgVol}, "")

//copying up initial contents of the mount point directory
copyExistingContents(target, anonVol.Mountpoint)

m := []specs.Mount{
{
Type: "none",
Expand All @@ -83,9 +138,23 @@ func generateMountOpts(clicontext *cli.Context, imageVolumes map[string]struct{}
Options: []string{"rbind"},
},
}

opts = append(opts, oci.WithMounts(m))
anonVolumes = append(anonVolumes, anonVolName)
}

return opts, anonVolumes, nil
}

// copyExistingContents copies from the source to the destination and
// ensures the ownership is appropriately set.
func copyExistingContents(source, destination string) error {
dstList, err := ioutil.ReadDir(destination)
if err != nil {
return err
}
if len(dstList) != 0 {
return errors.Errorf("volume at %q is not initially empty", destination)
}
return fs.CopyDir(destination, source)
}
21 changes: 21 additions & 0 deletions run_mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,24 @@ VOLUME /foo
base.Cmd("run", "--rm", "-v", "/foo", testutil.AlpineImage,
"mountpoint", "-q", "/foo").AssertOK()
}

func TestCopyingUpInitialContentsOnAnonymousVolume(t *testing.T) {
t.Parallel()
testutil.RequiresBuild(t)
base := testutil.NewBase(t)
const imageName = "nerdctl-test-copying-initial-content-on-anonvolume"
defer base.Cmd("rmi", imageName).Run()

dockerfile := fmt.Sprintf(`FROM %s
RUN mkdir -p /mnt && echo hi > /mnt/initial_file
VOLUME /mnt
CMD ["cat", "/mnt/initial_file"]
`, testutil.AlpineImage)

buildCtx, err := createBuildContext(dockerfile)
assert.NilError(t, err)
defer os.RemoveAll(buildCtx)

base.Cmd("build", "-t", imageName, buildCtx).AssertOK()
base.Cmd("run", "--rm", imageName).AssertOK()
}

0 comments on commit 7a00aaa

Please sign in to comment.