FIX #2411 Do not default to aufs on a btrfs filesystem

Signed-off-by: Rob Van Mieghem <rob@vanmieghemcloud.com>
This commit is contained in:
Rob Van Mieghem
2016-01-08 21:17:54 +01:00
parent 36abac3891
commit 3e758c6d86
14 changed files with 232 additions and 10 deletions

View File

@@ -94,9 +94,11 @@ func (provisioner *ArchProvisioner) Provision(swarmOptions swarm.Options, authOp
provisioner.EngineOptions = engineOptions
swarmOptions.Env = engineOptions.Env
if provisioner.EngineOptions.StorageDriver == "" {
provisioner.EngineOptions.StorageDriver = "overlay"
storageDriver, err := decideStorageDriver(provisioner, "overlay", engineOptions.StorageDriver)
if err != nil {
return err
}
provisioner.EngineOptions.StorageDriver = storageDriver
// HACK: since Arch does not come with sudo by default we install
log.Debug("Installing sudo")

View File

@@ -0,0 +1,20 @@
package provision
import (
"testing"
"github.com/docker/machine/drivers/fakedriver"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/provision/provisiontest"
"github.com/docker/machine/libmachine/swarm"
)
func TestArchDefaultStorageDriver(t *testing.T) {
p := NewArchProvisioner(&fakedriver.Driver{}).(*ArchProvisioner)
p.SSHCommander = provisiontest.FakeSSHCommander{FilesystemType: "ext4"}
p.Provision(swarm.Options{}, auth.Options{}, engine.Options{})
if p.EngineOptions.StorageDriver != "overlay" {
t.Fatal("Default storage driver should be overlay")
}
}

View File

@@ -106,9 +106,11 @@ func (provisioner *DebianProvisioner) Provision(swarmOptions swarm.Options, auth
provisioner.EngineOptions = engineOptions
swarmOptions.Env = engineOptions.Env
if provisioner.EngineOptions.StorageDriver == "" {
provisioner.EngineOptions.StorageDriver = "aufs"
storageDriver, err := decideStorageDriver(provisioner, "aufs", engineOptions.StorageDriver)
if err != nil {
return err
}
provisioner.EngineOptions.StorageDriver = storageDriver
// HACK: since debian does not come with sudo by default we install
log.Debug("installing sudo")

View File

@@ -0,0 +1,20 @@
package provision
import (
"testing"
"github.com/docker/machine/drivers/fakedriver"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/provision/provisiontest"
"github.com/docker/machine/libmachine/swarm"
)
func TestDebianDefaultStorageDriver(t *testing.T) {
p := NewDebianProvisioner(&fakedriver.Driver{}).(*DebianProvisioner)
p.SSHCommander = provisiontest.FakeSSHCommander{FilesystemType: "ext4"}
p.Provision(swarm.Options{}, auth.Options{}, engine.Options{})
if p.EngineOptions.StorageDriver != "aufs" {
t.Fatal("Default storage driver should be aufs")
}
}

View File

@@ -0,0 +1,22 @@
//Package provisiontest provides utilities for testing provisioners
package provisiontest
import (
"errors"
"strings"
)
//FakeSSHCommander is an implementation of provision.SSHCommander to provide predictable responses set by testing code
//Extend it when needed
type FakeSSHCommander struct {
//Result of the ssh command to look up the FilesystemType
FilesystemType string
}
//SSHCommand is an implementation of provision.SSHCommander.SSHCommand to provide predictable responses set by testing code
func (sshCmder FakeSSHCommander) SSHCommand(args string) (string, error) {
if !strings.HasPrefix(args, "stat -f") {
return "", errors.New("Not implemented by FakeSSHCommander")
}
return sshCmder.FilesystemType + "\n", nil
}

View File

@@ -0,0 +1,11 @@
package provisiontest
import "testing"
func TestStatSSHCommand(t *testing.T) {
sshCmder := FakeSSHCommander{FilesystemType: "btrfs"}
output, err := sshCmder.SSHCommand("stat -f -c %T /var/lib")
if err != nil || output != "btrfs\n" {
t.Fatal("FakeSSHCommander should have returned btrfs and no error but returned '", output, "' and error", err)
}
}

View File

@@ -159,9 +159,11 @@ func (provisioner *RedHatProvisioner) Provision(swarmOptions swarm.Options, auth
swarmOptions.Env = engineOptions.Env
// set default storage driver for redhat
if provisioner.EngineOptions.StorageDriver == "" {
provisioner.EngineOptions.StorageDriver = "devicemapper"
storageDriver, err := decideStorageDriver(provisioner, "devicemapper", engineOptions.StorageDriver)
if err != nil {
return err
}
provisioner.EngineOptions.StorageDriver = storageDriver
if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil {
return err

View File

@@ -3,6 +3,12 @@ package provision
import (
"regexp"
"testing"
"github.com/docker/machine/drivers/fakedriver"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/provision/provisiontest"
"github.com/docker/machine/libmachine/swarm"
)
func TestRedHatGenerateYumRepoList(t *testing.T) {
@@ -26,3 +32,12 @@ func TestRedHatGenerateYumRepoList(t *testing.T) {
t.Fatalf("expected match for centos/7")
}
}
func TestRedHatDefaultStorageDriver(t *testing.T) {
p := NewRedHatProvisioner("", &fakedriver.Driver{})
p.SSHCommander = provisiontest.FakeSSHCommander{FilesystemType: "ext4"}
p.Provision(swarm.Options{}, auth.Options{}, engine.Options{})
if p.EngineOptions.StorageDriver != "devicemapper" {
t.Fatal("Default storage driver should be devicemapper")
}
}

View File

@@ -122,9 +122,11 @@ func (provisioner *UbuntuSystemdProvisioner) Provision(swarmOptions swarm.Option
provisioner.EngineOptions = engineOptions
swarmOptions.Env = engineOptions.Env
if provisioner.EngineOptions.StorageDriver == "" {
provisioner.EngineOptions.StorageDriver = "aufs"
storageDriver, err := decideStorageDriver(provisioner, "aufs", engineOptions.StorageDriver)
if err != nil {
return err
}
provisioner.EngineOptions.StorageDriver = storageDriver
log.Debug("setting hostname")
if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil {

View File

@@ -2,6 +2,12 @@ package provision
import (
"testing"
"github.com/docker/machine/drivers/fakedriver"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/provision/provisiontest"
"github.com/docker/machine/libmachine/swarm"
)
func TestUbuntuSystemdCompatibleWithHost(t *testing.T) {
@@ -27,3 +33,12 @@ func TestUbuntuSystemdCompatibleWithHost(t *testing.T) {
}
}
func TestUbuntuSystemdDefaultStorageDriver(t *testing.T) {
p := NewUbuntuSystemdProvisioner(&fakedriver.Driver{}).(*UbuntuSystemdProvisioner)
p.SSHCommander = provisiontest.FakeSSHCommander{FilesystemType: "ext4"}
p.Provision(swarm.Options{}, auth.Options{}, engine.Options{})
if p.EngineOptions.StorageDriver != "aufs" {
t.Fatal("Default storage driver should be aufs")
}
}

View File

@@ -141,9 +141,11 @@ func (provisioner *UbuntuProvisioner) Provision(swarmOptions swarm.Options, auth
provisioner.EngineOptions = engineOptions
swarmOptions.Env = engineOptions.Env
if provisioner.EngineOptions.StorageDriver == "" {
provisioner.EngineOptions.StorageDriver = "aufs"
storageDriver, err := decideStorageDriver(provisioner, "aufs", engineOptions.StorageDriver)
if err != nil {
return err
}
provisioner.EngineOptions.StorageDriver = storageDriver
if err := provisioner.SetHostname(provisioner.Driver.GetMachineName()); err != nil {
return err

View File

@@ -2,6 +2,12 @@ package provision
import (
"testing"
"github.com/docker/machine/drivers/fakedriver"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/provision/provisiontest"
"github.com/docker/machine/libmachine/swarm"
)
func TestUbuntuCompatibleWithHost(t *testing.T) {
@@ -27,3 +33,12 @@ func TestUbuntuCompatibleWithHost(t *testing.T) {
}
}
func TestUbuntuDefaultStorageDriver(t *testing.T) {
p := NewUbuntuProvisioner(&fakedriver.Driver{}).(*UbuntuProvisioner)
p.SSHCommander = provisiontest.FakeSSHCommander{FilesystemType: "ext4"}
p.Provision(swarm.Options{}, auth.Options{}, engine.Options{})
if p.EngineOptions.StorageDriver != "aufs" {
t.Fatal("Default storage driver should be aufs")
}
}

View File

@@ -208,6 +208,46 @@ func matchNetstatOut(reDaemonListening, netstatOut string) bool {
return false
}
func decideStorageDriver(p Provisioner, defaultDriver, suppliedDriver string) (string, error) {
if suppliedDriver != "" {
return suppliedDriver, nil
}
bestSuitedDriver := ""
defer func() {
if bestSuitedDriver != "" {
log.Debugf("No storagedriver specified, using %s\n", bestSuitedDriver)
}
}()
if defaultDriver != "aufs" {
bestSuitedDriver = defaultDriver
} else {
remoteFilesystemType, err := getFilesystemType(p, "/var/lib")
if err != nil {
return "", err
}
if remoteFilesystemType == "btrfs" {
bestSuitedDriver = "btrfs"
} else {
bestSuitedDriver = "aufs"
}
}
return bestSuitedDriver, nil
}
func getFilesystemType(p Provisioner, directory string) (string, error) {
statCommandOutput, err := p.SSHCommand("stat -f -c %T " + directory)
if err != nil {
err = fmt.Errorf("Error looking up filesystem type: %s", err)
return "", err
}
fstype := strings.TrimSpace(statCommandOutput)
return fstype, nil
}
func checkDaemonUp(p Provisioner, dockerPort int) func() bool {
reDaemonListening := fmt.Sprintf(":%d.*LISTEN", dockerPort)
return func() bool {

View File

@@ -8,6 +8,12 @@ import (
"github.com/docker/machine/drivers/fakedriver"
"github.com/docker/machine/libmachine/auth"
"github.com/docker/machine/libmachine/engine"
"github.com/docker/machine/libmachine/provision/pkgaction"
"github.com/docker/machine/libmachine/provision/provisiontest"
"github.com/docker/machine/libmachine/provision/serviceaction"
"github.com/docker/machine/libmachine/swarm"
"github.com/stretchr/testify/assert"
)
var (
@@ -156,3 +162,51 @@ func TestMachineCustomPortBoot2Docker(t *testing.T) {
t.Errorf("expected url %s; received %s", bindURL, url)
}
}
type fakeProvisioner struct {
GenericProvisioner
}
func (provisioner *fakeProvisioner) Package(name string, action pkgaction.PackageAction) error {
return nil
}
func (provisioner *fakeProvisioner) Provision(swarmOptions swarm.Options, authOptions auth.Options, engineOptions engine.Options) error {
return nil
}
func (provisioner *fakeProvisioner) Service(name string, action serviceaction.ServiceAction) error {
return nil
}
func (provisioner *fakeProvisioner) String() string {
return "fake"
}
func TestDecideStorageDriver(t *testing.T) {
var tests = []struct {
suppliedDriver string
defaultDriver string
remoteFilesystemType string
expectedDriver string
}{
{"", "aufs", "ext4", "aufs"},
{"", "aufs", "btrfs", "btrfs"},
{"", "overlay", "btrfs", "overlay"},
{"devicemapper", "aufs", "ext4", "devicemapper"},
{"devicemapper", "aufs", "btrfs", "devicemapper"},
}
p := &fakeProvisioner{GenericProvisioner{
Driver: &fakedriver.Driver{},
}}
engineOptions := engine.Options{}
for _, test := range tests {
engineOptions.StorageDriver = test.suppliedDriver
p.SSHCommander = provisiontest.FakeSSHCommander{FilesystemType: test.remoteFilesystemType}
storageDriver, err := decideStorageDriver(p, test.defaultDriver, test.suppliedDriver)
assert.NoError(t, err)
assert.Equal(t, test.expectedDriver, storageDriver)
}
}