From b1d9732f653e52fac6f6d2a38d0d875ed91bbaec Mon Sep 17 00:00:00 2001 From: gizmotronic Date: Thu, 20 Apr 2017 00:01:10 -0500 Subject: [PATCH] Create mount points for non-swap mounts; fixes #1506 --- cmd/cloudinitexecute/cloudinitexecute.go | 31 ++++++++----- tests/assets/test_23/cloud-config.yml | 2 +- tests/mounts_test.go | 1 + util/util_linux.go | 56 +++++++++++++++++++++--- 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/cmd/cloudinitexecute/cloudinitexecute.go b/cmd/cloudinitexecute/cloudinitexecute.go index f77a0412..aae4d01a 100644 --- a/cmd/cloudinitexecute/cloudinitexecute.go +++ b/cmd/cloudinitexecute/cloudinitexecute.go @@ -71,6 +71,25 @@ func ApplyConsole(cfg *rancherConfig.CloudConfig) { if len(mount) != 4 { log.Errorf("Unable to mount %s: must specify exactly four arguments", mount[1]) } + + if mount[2] == "nfs" || mount[2] == "nfs4" { + if err := os.MkdirAll(mount[1], 0755); err != nil { + log.Errorf("Unable to create mount point %s: %v", mount[1], err) + continue + } + cmdArgs := []string{mount[0], mount[1], "-t", mount[2]} + if mount[3] != "" { + cmdArgs = append(cmdArgs, "-o", mount[3]) + } + cmd := exec.Command("mount", cmdArgs...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + log.Errorf("Failed to mount %s: %v", mount[1], err) + } + continue + } + device := util.ResolveDevice(mount[0]) if mount[2] == "swap" { @@ -84,17 +103,7 @@ func ApplyConsole(cfg *rancherConfig.CloudConfig) { continue } - cmdArgs := []string{device, mount[1]} - if mount[2] != "" { - cmdArgs = append(cmdArgs, "-t", mount[2]) - } - if mount[3] != "" { - cmdArgs = append(cmdArgs, "-o", mount[3]) - } - cmd := exec.Command("mount", cmdArgs...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { + if err := util.Mount(device, mount[1], mount[2], mount[3]); err != nil { log.Errorf("Failed to mount %s: %v", mount[1], err) } } diff --git a/tests/assets/test_23/cloud-config.yml b/tests/assets/test_23/cloud-config.yml index 47bd9b47..2f53d628 100644 --- a/tests/assets/test_23/cloud-config.yml +++ b/tests/assets/test_23/cloud-config.yml @@ -2,11 +2,11 @@ write_files: - path: /test content: test -- path: /home/rancher/test mounts: - ["/test", "/home/rancher/test", "", "bind"] - [/dev/vdb, /home/rancher/a, ext4, ""] - [/dev/vdb, /home/rancher/b, "", ""] - [/dev/vdb, /home/rancher/c, auto, defaults] +- [/dev/vdb, /home/rancher/d, "auto", "defaults"] ssh_authorized_keys: - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC85w9stZyiLQp/DkVO6fqwiShYcj1ClKdtCqgHtf+PLpJkFReSFu8y21y+ev09gsSMRRrjF7yt0pUHV6zncQhVeqsZtgc5WbELY2DOYUGmRn/CCvPbXovoBrQjSorqlBmpuPwsStYLr92Xn+VVsMNSUIegHY22DphGbDKG85vrKB8HxUxGIDxFBds/uE8FhSy+xsoyT/jUZDK6pgq2HnGl6D81ViIlKecpOpWlW3B+fea99ADNyZNVvDzbHE5pcI3VRw8u59WmpWOUgT6qacNVACl8GqpBvQk8sw7O/X9DSZHCKafeD9G5k+GYbAUz92fKWrx/lOXfUXPS3+c8dRIF diff --git a/tests/mounts_test.go b/tests/mounts_test.go index 6f9983c7..dbdacf81 100644 --- a/tests/mounts_test.go +++ b/tests/mounts_test.go @@ -13,4 +13,5 @@ func (s *QemuSuite) TestMounts(c *C) { s.CheckCall(c, "mount | grep /home/rancher/a") s.CheckCall(c, "mount | grep /home/rancher/b") s.CheckCall(c, "mount | grep /home/rancher/c") + s.CheckCall(c, "mount | grep /home/rancher/d") } diff --git a/util/util_linux.go b/util/util_linux.go index 6c6a4367..e93e228c 100755 --- a/util/util_linux.go +++ b/util/util_linux.go @@ -7,6 +7,7 @@ import ( "bytes" "os" "os/exec" + "path/filepath" "strings" "syscall" @@ -30,19 +31,62 @@ func mountProc() error { return nil } -func Mount(device, directory, fsType, options string) error { +func Mount(device, target, fsType, options string) error { if err := mountProc(); err != nil { return nil } - if _, err := os.Stat(directory); os.IsNotExist(err) { - err = os.MkdirAll(directory, 0755) - if err != nil { - return err + bindMount := false + for _, v := range strings.Split(options, ",") { + if v == "bind" { + bindMount = true + break } } - return mount.Mount(device, directory, fsType, options) + if bindMount { + deviceInfo, err := os.Stat(device) + if err != nil { + return err + } + mode := deviceInfo.Mode() + + switch { + case mode.IsDir(): + if err := os.MkdirAll(target, 0755); err != nil { + return err + } + case mode.IsRegular(): + err := os.MkdirAll(filepath.Dir(target), 0755) + if err != nil { + return err + } + file, err := os.OpenFile(target, os.O_CREATE, mode&os.ModePerm) + if err != nil { + return err + } + if err := file.Close(); err != nil { + return err + } + default: + return os.ErrInvalid + } + } else { + err := os.MkdirAll(target, 0755) + if err != nil { + return err + } + + if fsType == "auto" || fsType == "" { + inferredType, err := GetFsType(device) + if err != nil { + return err + } + fsType = inferredType + } + } + + return mount.Mount(device, target, fsType, options) } func Unmount(target string) error {