From b7026236f42915fbf8cb72761aca254747200379 Mon Sep 17 00:00:00 2001 From: Peng Tao Date: Tue, 14 Apr 2020 00:37:54 -0700 Subject: [PATCH] snapshot/devmapper: use losetup in mount package No need to use the private losetup command line wrapper package. The generic package provides the same functionality. Signed-off-by: Peng Tao --- snapshots/devmapper/dmsetup/dmsetup_test.go | 13 +- snapshots/devmapper/losetup/losetup.go | 92 --------------- snapshots/devmapper/losetup/losetup_test.go | 124 -------------------- snapshots/devmapper/pool_device_test.go | 5 +- snapshots/devmapper/snapshotter_test.go | 3 +- 5 files changed, 8 insertions(+), 229 deletions(-) delete mode 100644 snapshots/devmapper/losetup/losetup.go delete mode 100644 snapshots/devmapper/losetup/losetup_test.go diff --git a/snapshots/devmapper/dmsetup/dmsetup_test.go b/snapshots/devmapper/dmsetup/dmsetup_test.go index 3b4c688bb..e8b95330b 100644 --- a/snapshots/devmapper/dmsetup/dmsetup_test.go +++ b/snapshots/devmapper/dmsetup/dmsetup_test.go @@ -29,8 +29,8 @@ import ( "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" + "github.com/containerd/containerd/mount" "github.com/containerd/containerd/pkg/testutil" - "github.com/containerd/containerd/snapshots/devmapper/losetup" ) const ( @@ -55,16 +55,13 @@ func TestDMSetup(t *testing.T) { metaImage, loopMetaDevice := createLoopbackDevice(t, tempDir) defer func() { - err = losetup.RemoveLoopDevicesAssociatedWithImage(dataImage) - assert.NilError(t, err, "failed to detach loop devices for data image: %s", dataImage) - - err = losetup.RemoveLoopDevicesAssociatedWithImage(metaImage) - assert.NilError(t, err, "failed to detach loop devices for meta image: %s", metaImage) + err = mount.DetachLoopDevice(loopDataDevice, loopMetaDevice) + assert.NilError(t, err, "failed to detach loop devices for data image: %s and meta image: %s", dataImage, metaImage) }() t.Run("CreatePool", func(t *testing.T) { err := CreatePool(testPoolName, loopDataDevice, loopMetaDevice, 128) - assert.NilError(t, err, "failed to create thin-pool") + assert.NilError(t, err, "failed to create thin-pool with %s %s", loopDataDevice, loopMetaDevice) table, err := Table(testPoolName) t.Logf("table: %s", table) @@ -201,7 +198,7 @@ func createLoopbackDevice(t *testing.T, dir string) (string, string) { imagePath := file.Name() - loopDevice, err := losetup.AttachLoopDevice(imagePath) + loopDevice, err := mount.AttachLoopDevice(imagePath) assert.NilError(t, err) return imagePath, loopDevice diff --git a/snapshots/devmapper/losetup/losetup.go b/snapshots/devmapper/losetup/losetup.go deleted file mode 100644 index b9e9bf980..000000000 --- a/snapshots/devmapper/losetup/losetup.go +++ /dev/null @@ -1,92 +0,0 @@ -// +build linux - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package losetup - -import ( - "os/exec" - "strings" - - "github.com/pkg/errors" - "golang.org/x/sys/unix" -) - -// FindAssociatedLoopDevices returns a list of loop devices attached to a given image -func FindAssociatedLoopDevices(imagePath string) ([]string, error) { - output, err := losetup("--list", "--output", "NAME", "--associated", imagePath) - if err != nil { - return nil, errors.Wrapf(err, "failed to get loop devices: '%s'", output) - } - - if output == "" { - return []string{}, nil - } - - items := strings.Split(output, "\n") - if len(items) <= 1 { - return []string{}, nil - } - - // Skip header with column names - return items[1:], nil -} - -// AttachLoopDevice finds first available loop device and associates it with an image. -func AttachLoopDevice(imagePath string) (string, error) { - return losetup("--find", "--show", imagePath) -} - -// DetachLoopDevice detaches loop devices -func DetachLoopDevice(loopDevice ...string) error { - args := append([]string{"--detach"}, loopDevice...) - _, err := losetup(args...) - return err -} - -// RemoveLoopDevicesAssociatedWithImage detaches all loop devices attached to a given sparse image -func RemoveLoopDevicesAssociatedWithImage(imagePath string) error { - loopDevices, err := FindAssociatedLoopDevices(imagePath) - if err != nil { - return err - } - - for _, loopDevice := range loopDevices { - if err = DetachLoopDevice(loopDevice); err != nil && err != unix.ENOENT { - return err - } - } - - return nil -} - -// losetup is a wrapper around losetup command line tool -func losetup(args ...string) (string, error) { - cmd := exec.Command("losetup", args...) - cmd.Env = append(cmd.Env, "LANG=C") - data, err := cmd.CombinedOutput() - output := string(data) - if err != nil { - if strings.Contains(output, "No such file or directory") || strings.Contains(output, "No such device") { - return "", unix.ENOENT - } - - return "", errors.Wrapf(err, "losetup %s\nerror: %s\n", strings.Join(args, " "), output) - } - - return strings.TrimSuffix(output, "\n"), err -} diff --git a/snapshots/devmapper/losetup/losetup_test.go b/snapshots/devmapper/losetup/losetup_test.go deleted file mode 100644 index b6d2d5ebc..000000000 --- a/snapshots/devmapper/losetup/losetup_test.go +++ /dev/null @@ -1,124 +0,0 @@ -// +build linux - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package losetup - -import ( - "io/ioutil" - "os" - "testing" - - "github.com/docker/go-units" - "golang.org/x/sys/unix" - "gotest.tools/v3/assert" - is "gotest.tools/v3/assert/cmp" - - "github.com/containerd/containerd/pkg/testutil" -) - -func TestLosetup(t *testing.T) { - testutil.RequiresRoot(t) - - var ( - imagePath = createSparseImage(t) - loopDevice1 string - loopDevice2 string - ) - - defer func() { - err := os.Remove(imagePath) - assert.NilError(t, err) - }() - - t.Run("AttachLoopDevice", func(t *testing.T) { - dev1, err := AttachLoopDevice(imagePath) - assert.NilError(t, err) - assert.Assert(t, dev1 != "") - - dev2, err := AttachLoopDevice(imagePath) - assert.NilError(t, err) - assert.Assert(t, dev2 != dev1, "should attach different loop device") - - loopDevice1 = dev1 - loopDevice2 = dev2 - }) - - t.Run("AttachEmptyLoopDevice", func(t *testing.T) { - _, err := AttachLoopDevice("") - assert.Assert(t, err != nil, "shouldn't attach empty path") - }) - - t.Run("FindAssociatedLoopDevices", func(t *testing.T) { - devices, err := FindAssociatedLoopDevices(imagePath) - assert.NilError(t, err) - assert.Assert(t, is.Len(devices, 2), "unexpected number of attached devices") - assert.Assert(t, is.Contains(devices, loopDevice1)) - assert.Assert(t, is.Contains(devices, loopDevice2)) - }) - - t.Run("FindAssociatedLoopDevicesForInvalidImage", func(t *testing.T) { - devices, err := FindAssociatedLoopDevices("") - assert.NilError(t, err) - assert.Assert(t, is.Len(devices, 0)) - }) - - t.Run("DetachLoopDevice", func(t *testing.T) { - err := DetachLoopDevice(loopDevice2) - assert.NilError(t, err, "failed to detach %q", loopDevice2) - }) - - t.Run("DetachEmptyDevice", func(t *testing.T) { - err := DetachLoopDevice("") - assert.Assert(t, err != nil, "shouldn't detach empty path") - }) - - t.Run("RemoveLoopDevicesAssociatedWithImage", func(t *testing.T) { - err := RemoveLoopDevicesAssociatedWithImage(imagePath) - assert.NilError(t, err) - - devices, err := FindAssociatedLoopDevices(imagePath) - assert.NilError(t, err) - assert.Assert(t, is.Len(devices, 0)) - }) - - t.Run("RemoveLoopDevicesAssociatedWithInvalidImage", func(t *testing.T) { - err := RemoveLoopDevicesAssociatedWithImage("") - assert.NilError(t, err) - }) - - t.Run("DetachInvalidDevice", func(t *testing.T) { - err := DetachLoopDevice("/dev/loop_invalid_idx") - assert.Equal(t, unix.ENOENT, err) - }) -} - -func createSparseImage(t *testing.T) string { - file, err := ioutil.TempFile("", "losetup-tests-") - assert.NilError(t, err) - - size, err := units.RAMInBytes("16Mb") - assert.NilError(t, err) - - err = file.Truncate(size) - assert.NilError(t, err) - - err = file.Close() - assert.NilError(t, err) - - return file.Name() -} diff --git a/snapshots/devmapper/pool_device_test.go b/snapshots/devmapper/pool_device_test.go index cc729a3a0..8525c0028 100644 --- a/snapshots/devmapper/pool_device_test.go +++ b/snapshots/devmapper/pool_device_test.go @@ -31,7 +31,6 @@ import ( "github.com/containerd/containerd/mount" "github.com/containerd/containerd/pkg/testutil" "github.com/containerd/containerd/snapshots/devmapper/dmsetup" - "github.com/containerd/containerd/snapshots/devmapper/losetup" "github.com/docker/go-units" "github.com/sirupsen/logrus" "gotest.tools/v3/assert" @@ -74,7 +73,7 @@ func TestPoolDevice(t *testing.T) { defer func() { // Detach loop devices and remove images - err := losetup.DetachLoopDevice(loopDataDevice, loopMetaDevice) + err := mount.DetachLoopDevice(loopDataDevice, loopMetaDevice) assert.NilError(t, err) err = os.RemoveAll(tempDir) @@ -306,7 +305,7 @@ func createLoopbackDevice(t *testing.T, dir string) (string, string) { imagePath := file.Name() - loopDevice, err := losetup.AttachLoopDevice(imagePath) + loopDevice, err := mount.AttachLoopDevice(imagePath) assert.NilError(t, err) return imagePath, loopDevice diff --git a/snapshots/devmapper/snapshotter_test.go b/snapshots/devmapper/snapshotter_test.go index 5157be869..419ed7206 100644 --- a/snapshots/devmapper/snapshotter_test.go +++ b/snapshots/devmapper/snapshotter_test.go @@ -37,7 +37,6 @@ import ( "github.com/containerd/containerd/pkg/testutil" "github.com/containerd/containerd/snapshots" "github.com/containerd/containerd/snapshots/devmapper/dmsetup" - "github.com/containerd/containerd/snapshots/devmapper/losetup" "github.com/containerd/containerd/snapshots/testsuite" ) @@ -70,7 +69,7 @@ func TestSnapshotterSuite(t *testing.T) { removePool := func() error { result := multierror.Append( snap.pool.RemovePool(ctx), - losetup.DetachLoopDevice(loopDataDevice, loopMetaDevice)) + mount.DetachLoopDevice(loopDataDevice, loopMetaDevice)) return result.ErrorOrNil() }