Skip to content
This repository has been archived by the owner on Feb 2, 2022. It is now read-only.

Commit

Permalink
Merge pull request #38 from concourse/fix-nested-volumes
Browse files Browse the repository at this point in the history
fix nested volumes
  • Loading branch information
vito authored Aug 6, 2020
2 parents 9546325 + 3e4b940 commit ea9252e
Show file tree
Hide file tree
Showing 18 changed files with 351 additions and 807 deletions.
13 changes: 10 additions & 3 deletions baggageclaimcmd/command.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package baggageclaimcmd

import (
"code.cloudfoundry.org/lager"
"fmt"
"net/http"
"os"

"code.cloudfoundry.org/lager"
"github.com/concourse/baggageclaim/api"
"github.com/concourse/baggageclaim/uidgid"
"github.com/concourse/baggageclaim/volume"
Expand All @@ -11,8 +14,6 @@ import (
"github.com/tedsuo/ifrit/grouper"
"github.com/tedsuo/ifrit/http_server"
"github.com/tedsuo/ifrit/sigmon"
"net/http"
"os"
)

type BaggageclaimCommand struct {
Expand Down Expand Up @@ -81,6 +82,12 @@ func (cmd *BaggageclaimCommand) Runner(args []string) (ifrit.Runner, error) {
return nil, err
}

err = driver.Recover(filesystem)
if err != nil {
logger.Error("failed-to-recover-volume-driver", err)
return nil, err
}

volumeRepo := volume.NewRepository(
filesystem,
locker,
Expand Down
5 changes: 1 addition & 4 deletions baggageclaimcmd/driver_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,7 @@ func (cmd *BaggageclaimCommand) driver(logger lager.Logger) (volume.Driver, erro
var d volume.Driver
switch cmd.Driver {
case "overlay":
d, err = driver.NewOverlayDriver(volumesDir, cmd.OverlaysDir)
if err != nil {
return nil, err
}
d = driver.NewOverlayDriver(cmd.OverlaysDir)
case "btrfs":
d = driver.NewBtrFSDriver(logger.Session("driver"), cmd.BtrfsBin)
case "naive":
Expand Down
5 changes: 5 additions & 0 deletions ci/unit-linux.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
---
platform: linux

image_resource:
type: registry-image
source:
repository: concourse/baggageclaim-ci

inputs:
- name: baggageclaim

Expand Down
4 changes: 2 additions & 2 deletions volume/copy_unix.go → volume/copy/copy_unix.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
//+build !windows

package volume
package copy

import (
"os/exec"
)

func cp(followSymlinks bool, src, dest string) error {
func Cp(followSymlinks bool, src, dest string) error {
cpFlags := "-a"
if followSymlinks {
cpFlags = "-Lr"
Expand Down
13 changes: 13 additions & 0 deletions volume/copy/copy_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package copy

import (
"fmt"
)

func Cp(followSymlinks bool, src, dest string) error {
if followSymlinks {
return fmt.Errorf("FollowSymlinks not supported on Windows")
}

return Copy(src, dest)
}
15 changes: 0 additions & 15 deletions volume/copy_windows.go

This file was deleted.

8 changes: 5 additions & 3 deletions volume/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package volume
//go:generate counterfeiter . Driver

type Driver interface {
CreateVolume(path string) error
DestroyVolume(path string) error
CreateVolume(FilesystemInitVolume) error
DestroyVolume(FilesystemVolume) error

CreateCopyOnWriteLayer(path string, parent string) error
CreateCopyOnWriteLayer(FilesystemInitVolume, FilesystemLiveVolume) error

Recover(Filesystem) error
}
23 changes: 16 additions & 7 deletions volume/driver/btrfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"

"code.cloudfoundry.org/lager"
"github.com/concourse/baggageclaim/volume"
)

type BtrFSDriver struct {
Expand All @@ -25,16 +26,16 @@ func NewBtrFSDriver(
}
}

func (driver *BtrFSDriver) CreateVolume(path string) error {
_, _, err := driver.run(driver.btrfsBin, "subvolume", "create", path)
func (driver *BtrFSDriver) CreateVolume(vol volume.FilesystemInitVolume) error {
_, _, err := driver.run(driver.btrfsBin, "subvolume", "create", vol.DataPath())
if err != nil {
return err
}

return nil
}

func (driver *BtrFSDriver) DestroyVolume(path string) error {
func (driver *BtrFSDriver) DestroyVolume(vol volume.FilesystemVolume) error {
volumePathsToDelete := []string{}

findSubvolumes := func(p string, f os.FileInfo, err error) error {
Expand All @@ -58,8 +59,8 @@ func (driver *BtrFSDriver) DestroyVolume(path string) error {
return nil
}

if err := filepath.Walk(path, findSubvolumes); err != nil {
return fmt.Errorf("recursively walking subvolumes for %s failed: %v", path, err)
if err := filepath.Walk(vol.DataPath(), findSubvolumes); err != nil {
return fmt.Errorf("recursively walking subvolumes for %s failed: %v", vol.DataPath(), err)
}

for i := len(volumePathsToDelete) - 1; i >= 0; i-- {
Expand All @@ -72,8 +73,11 @@ func (driver *BtrFSDriver) DestroyVolume(path string) error {
return nil
}

func (driver *BtrFSDriver) CreateCopyOnWriteLayer(path string, parent string) error {
_, _, err := driver.run(driver.btrfsBin, "subvolume", "snapshot", parent, path)
func (driver *BtrFSDriver) CreateCopyOnWriteLayer(
childVol volume.FilesystemInitVolume,
parentVol volume.FilesystemLiveVolume,
) error {
_, _, err := driver.run(driver.btrfsBin, "subvolume", "snapshot", parentVol.DataPath(), childVol.DataPath())
return err
}

Expand Down Expand Up @@ -107,3 +111,8 @@ func (driver *BtrFSDriver) run(command string, args ...string) (string, string,

return stdout.String(), stderr.String(), nil
}

func (driver *BtrFSDriver) Recover(volume.Filesystem) error {
// nothing to do
return nil
}
66 changes: 29 additions & 37 deletions volume/driver/btrfs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"code.cloudfoundry.org/lager/lagertest"

"github.com/concourse/baggageclaim/fs"
"github.com/concourse/baggageclaim/volume"
"github.com/concourse/baggageclaim/volume/driver"
)

Expand All @@ -27,9 +28,9 @@ var _ = Describe("BtrFS", func() {

var (
tempDir string
volumeDir string
fsDriver *driver.BtrFSDriver
filesystem *fs.BtrfsFilesystem
volumeFs volume.Filesystem
)

BeforeEach(func() {
Expand All @@ -40,13 +41,16 @@ var _ = Describe("BtrFS", func() {
logger := lagertest.NewTestLogger("fs")

imagePath := filepath.Join(tempDir, "image.img")
volumeDir = filepath.Join(tempDir, "mountpoint")
volumesDir := filepath.Join(tempDir, "mountpoint")

filesystem = fs.New(logger, imagePath, volumeDir, "mkfs.btrfs")
filesystem = fs.New(logger, imagePath, volumesDir, "mkfs.btrfs")
err = filesystem.Create(1 * 1024 * 1024 * 1024)
Expect(err).NotTo(HaveOccurred())

fsDriver = driver.NewBtrFSDriver(logger, "btrfs")

volumeFs, err = volume.NewFilesystem(fsDriver, volumesDir)
Expect(err).ToNot(HaveOccurred())
})

AfterEach(func() {
Expand All @@ -59,63 +63,51 @@ var _ = Describe("BtrFS", func() {

Describe("Lifecycle", func() {
It("can create and delete a subvolume", func() {
subvolumePath := filepath.Join(volumeDir, "subvolume")

err := fsDriver.CreateVolume(subvolumePath)
initVol, err := volumeFs.NewVolume("some-volume")
Expect(err).NotTo(HaveOccurred())

Expect(subvolumePath).To(BeADirectory())
Expect(initVol.DataPath()).To(BeADirectory())

checkSubvolume := exec.Command("btrfs", "subvolume", "show", subvolumePath)
checkSubvolume := exec.Command("btrfs", "subvolume", "show", initVol.DataPath())
session, err := gexec.Start(checkSubvolume, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(session).Should(gbytes.Say("subvolume"))
Eventually(session).Should(gexec.Exit(0))
<-session.Exited
Expect(session).To(gbytes.Say("some-volume"))
Expect(session).To(gexec.Exit(0))

err = fsDriver.DestroyVolume(subvolumePath)
err = initVol.Destroy()
Expect(err).NotTo(HaveOccurred())

Expect(subvolumePath).NotTo(BeADirectory())
Expect(initVol.DataPath()).NotTo(BeADirectory())
})

It("can delete parent volume when it has subvolumes", func() {
parentPath := filepath.Join(volumeDir, "parent")
childPath := filepath.Join(parentPath, "volume", "child")
grandchildPath := filepath.Join(childPath, "volume", "grandchild")

err := os.MkdirAll(parentPath, os.ModePerm)
siblingVol, err := volumeFs.NewVolume("sibling-volume")
Expect(err).NotTo(HaveOccurred())

parentVolumePath := filepath.Join(parentPath, "volume")
err = fsDriver.CreateVolume(parentVolumePath)
parentVol, err := volumeFs.NewVolume("parent-volume")
Expect(err).NotTo(HaveOccurred())

err = os.MkdirAll(filepath.Join(volumeDir, "sibling"), os.ModePerm)
Expect(err).NotTo(HaveOccurred())
dataPath := parentVol.DataPath()

siblingVolumePath := filepath.Join(volumeDir, "sibling", "volume")
err = fsDriver.CreateVolume(siblingVolumePath)
create := exec.Command("btrfs", "subvolume", "create", filepath.Join(dataPath, "sub"))
session, err := gexec.Start(create, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())
<-session.Exited
Expect(session).To(gexec.Exit(0))

err = os.MkdirAll(childPath, os.ModePerm)
Expect(err).NotTo(HaveOccurred())
childVolumePath := filepath.Join(childPath, "volume")

err = fsDriver.CreateVolume(childVolumePath)
Expect(err).NotTo(HaveOccurred())

err = os.MkdirAll(grandchildPath, os.ModePerm)
Expect(err).NotTo(HaveOccurred())
grandchildVolumePath := filepath.Join(grandchildPath, "volume")
err = fsDriver.CreateVolume(grandchildVolumePath)
create = exec.Command("btrfs", "subvolume", "create", filepath.Join(dataPath, "sub", "sub"))
session, err = gexec.Start(create, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())
<-session.Exited
Expect(session).To(gexec.Exit(0))

err = fsDriver.DestroyVolume(parentVolumePath)
err = parentVol.Destroy()
Expect(err).NotTo(HaveOccurred())

Expect(parentVolumePath).NotTo(BeADirectory())
Expect(siblingVolumePath).To(BeADirectory())
Expect(parentVol.DataPath()).ToNot(BeADirectory())
Expect(siblingVol.DataPath()).To(BeADirectory())
})
})
})
Loading

0 comments on commit ea9252e

Please sign in to comment.