From f0c6cd3cedc42a4371381edcd398307e93ce1594 Mon Sep 17 00:00:00 2001 From: Qi Wang Date: Mon, 21 Oct 2019 21:59:15 -0400 Subject: [PATCH] Enable --device directory as src device Enables --device accepte directory path as source device. Add the devices under the source directory to the destination directory. complete card test criteria: https://jira.coreos.com/browse/RUN-497 related podman issue: https://github.com/containers/libpod/issues/2380 Signed-off-by: Qi Wang --- cmd/buildah/bud.go | 2 +- cmd/buildah/from.go | 2 +- pkg/parse/parse_test.go | 15 ++++++++------- pkg/parse/parse_unix.go | 38 +++++++++++++++++++++++++++++++------- tests/bud.bats | 14 +++++++++++++- 5 files changed, 54 insertions(+), 17 deletions(-) diff --git a/cmd/buildah/bud.go b/cmd/buildah/bud.go index 728e202dcfd..9d9e8c7d80f 100644 --- a/cmd/buildah/bud.go +++ b/cmd/buildah/bud.go @@ -273,7 +273,7 @@ func budCmd(c *cobra.Command, inputArgs []string, iopts budResults) error { if err != nil { return err } - devices = append(devices, dev) + devices = append(devices, dev...) } options := imagebuildah.BuildOptions{ diff --git a/cmd/buildah/from.go b/cmd/buildah/from.go index 5826311d23a..55d048a1623 100644 --- a/cmd/buildah/from.go +++ b/cmd/buildah/from.go @@ -218,7 +218,7 @@ func fromCmd(c *cobra.Command, args []string, iopts fromReply) error { if err != nil { return err } - devices = append(devices, dev) + devices = append(devices, dev...) } options := buildah.BuilderOptions{ diff --git a/pkg/parse/parse_test.go b/pkg/parse/parse_test.go index c7afdaca018..91156bc2ddd 100644 --- a/pkg/parse/parse_test.go +++ b/pkg/parse/parse_test.go @@ -74,17 +74,18 @@ func TestDeviceFromPath(t *testing.T) { // Path is valid dev, err := DeviceFromPath("/dev/null") assert.NoError(t, err) - assert.Equal(t, dev.Major, int64(1)) - assert.Equal(t, dev.Minor, int64(3)) - assert.Equal(t, dev.Permissions, "rwm") - assert.Equal(t, dev.Uid, uint32(0)) - assert.Equal(t, dev.Gid, uint32(0)) + assert.Equal(t, len(dev), 1) + assert.Equal(t, dev[0].Major, int64(1)) + assert.Equal(t, dev[0].Minor, int64(3)) + assert.Equal(t, dev[0].Permissions, "rwm") + assert.Equal(t, dev[0].Uid, uint32(0)) + assert.Equal(t, dev[0].Gid, uint32(0)) // Path does not exists _, err = DeviceFromPath("/dev/BOGUS") assert.Error(t, err) - // Path exists but is not a device + // Path is a directory of devices _, err = DeviceFromPath("/dev/pts") - assert.Error(t, err) + assert.NoError(t, err) } diff --git a/pkg/parse/parse_unix.go b/pkg/parse/parse_unix.go index 238293894f3..1aaeca27863 100644 --- a/pkg/parse/parse_unix.go +++ b/pkg/parse/parse_unix.go @@ -4,6 +4,8 @@ package parse import ( "fmt" + "os" + "path/filepath" "github.com/containers/buildah/pkg/unshare" "github.com/opencontainers/runc/libcontainer/configs" @@ -24,18 +26,40 @@ func getDefaultProcessLimits() []string { return defaultLimits } -func DeviceFromPath(device string) (configs.Device, error) { +func DeviceFromPath(device string) ([]configs.Device, error) { + var devs []configs.Device src, dst, permissions, err := Device(device) if err != nil { - return configs.Device{}, err + return nil, err } if unshare.IsRootless() { - return configs.Device{}, errors.Errorf("Renaming device %s to %s is not a supported in rootless containers", src, dst) + return nil, errors.Errorf("Renaming device %s to %s is not a supported in rootless containers", src, dst) } - dev, err := devices.DeviceFromPath(src, permissions) + srcInfo, err := os.Stat(src) if err != nil { - return configs.Device{}, errors.Wrapf(err, "%s is not a valid device", src) + return nil, errors.Wrapf(err, "error getting info of source device %s", src) } - dev.Path = dst - return *dev, nil + + if !srcInfo.IsDir() { + + dev, err := devices.DeviceFromPath(src, permissions) + if err != nil { + return nil, errors.Wrapf(err, "%s is not a valid device", src) + } + dev.Path = dst + devs = append(devs, *dev) + return devs, nil + } + + // If source device is a directory + srcDevices, err := devices.GetDevices(src) + if err != nil { + return nil, errors.Wrapf(err, "error getting source devices from directory %s", src) + } + for _, d := range srcDevices { + d.Path = filepath.Join(dst, filepath.Base(d.Path)) + d.Permissions = permissions + devs = append(devs, *d) + } + return devs, nil } diff --git a/tests/bud.bats b/tests/bud.bats index 3bd482e7915..5d17bdf6ab8 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -1690,6 +1690,18 @@ load helpers run_buildah bud --signature-policy ${TESTSDIR}/policy.json --squash ${TESTSDIR}/bud/layers-squash } +@test "bud with additional directory of devices" { + target=alpine-image + mkdir ${TESTSDIR}/foo + mknod ${TESTSDIR}/foo/null c 1 3 + run_buildah bud --signature-policy ${TESTSDIR}/policy.json --device ${TESTSDIR}/foo:/dev/fuse -t ${target} -f ${TESTSDIR}/bud/device/Dockerfile ${TESTSDIR}/bud/device + [ "${status}" -eq 0 ] + expect_output --substring "null" + + buildah rmi ${target} + rm -rf ${TESTSDIR}/foo +} + @test "bud with additional device" { target=alpine-image run_buildah bud --signature-policy ${TESTSDIR}/policy.json --device /dev/fuse -t ${target} -f ${TESTSDIR}/bud/device/Dockerfile ${TESTSDIR}/bud/device @@ -1793,7 +1805,7 @@ load helpers echo "$output" expect_output --substring "abc.txt" - rm ${TESTSDIR}/bud/use-args/abc.txt + rm ${TESTSDIR}/bud/use-args/abc.txt buildah rm --all buildah rmi --all --force }