Skip to content

Commit

Permalink
Allow gdn/GQTs to compile and run on Windows
Browse files Browse the repository at this point in the history
* Introduce runner.UserCredential to use as opposed to directly calling
syscall.Credential
* _linuxify files containing non-Windows-friendly syscalls

[#145185373]

Signed-off-by: Ed King <[email protected]>
  • Loading branch information
mdelillo authored and teddyking committed May 11, 2017
1 parent 5ed668c commit 9fd0cc1
Show file tree
Hide file tree
Showing 13 changed files with 382 additions and 239 deletions.
3 changes: 1 addition & 2 deletions gqt/gqt_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"os/exec"
"path/filepath"
"runtime"
"syscall"
"time"

"code.cloudfoundry.org/garden"
Expand Down Expand Up @@ -131,7 +130,7 @@ func startGarden(argv ...string) *runner.RunningGarden {
return startGardenAsUser(nil, argv...)
}

func startGardenAsUser(user *syscall.Credential, argv ...string) *runner.RunningGarden {
func startGardenAsUser(user runner.UserCredential, argv ...string) *runner.RunningGarden {
rootfs := os.Getenv("GARDEN_TEST_ROOTFS")
return runner.Start(gardenBin, initBin, nstarBin, dadooBin, testImagePluginBin, rootfs, tarBin, user, argv...)
}
Expand Down
File renamed without changes.
File renamed without changes.
111 changes: 2 additions & 109 deletions gqt/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,17 @@ import (
"net/http"
"os"
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"

"code.cloudfoundry.org/garden/client"
"code.cloudfoundry.org/garden/client/connection"
"code.cloudfoundry.org/lager"
"code.cloudfoundry.org/lager/lagertest"
"github.com/eapache/go-resiliency/retrier"
"github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/tedsuo/ifrit"
"github.com/tedsuo/ifrit/ginkgomon"
Expand Down Expand Up @@ -75,7 +71,7 @@ func init() {
}
}

func NewGardenRunner(bin, initBin, nstarBin, dadooBin, grootfsBin, rootfs, tarBin, network, address string, user *syscall.Credential, argv ...string) GardenRunner {
func NewGardenRunner(bin, initBin, nstarBin, dadooBin, grootfsBin, rootfs, tarBin, network, address string, user UserCredential, argv ...string) GardenRunner {
r := GardenRunner{}

r.Network = network
Expand Down Expand Up @@ -114,7 +110,7 @@ func NewGardenRunner(bin, initBin, nstarBin, dadooBin, grootfsBin, rootfs, tarBi
return r
}

func Start(bin, initBin, nstarBin, dadooBin, grootfsBin, rootfs, tarBin string, user *syscall.Credential, argv ...string) *RunningGarden {
func Start(bin, initBin, nstarBin, dadooBin, grootfsBin, rootfs, tarBin string, user UserCredential, argv ...string) *RunningGarden {
runner := NewGardenRunner(bin, initBin, nstarBin, dadooBin, grootfsBin, rootfs, tarBin, "unix", fmt.Sprintf("/tmp/garden_%d.sock", GinkgoParallelNode()), user, argv...)

r := &RunningGarden{
Expand Down Expand Up @@ -179,109 +175,6 @@ func (r *RunningGarden) Stop() error {
return err
}

func cmd(tmpdir, depotDir, graphPath, consoleSocketsPath, network, addr, bin, initBin, nstarBin, dadooBin, grootfsBin, tarBin, rootfs string, user *syscall.Credential, argv ...string) *exec.Cmd {
Expect(os.MkdirAll(tmpdir, 0755)).To(Succeed())
Expect(os.MkdirAll(depotDir, 0755)).To(Succeed())

appendDefaultFlag := func(ar []string, key, value string) []string {
for _, a := range argv {
if a == key {
return ar
}
}

if value != "" {
return append(ar, key, value)
} else {
return append(ar, key)
}
}

gardenArgs := make([]string, len(argv))
copy(gardenArgs, argv)

switch network {
case "tcp":
gardenArgs = appendDefaultFlag(gardenArgs, "--bind-ip", strings.Split(addr, ":")[0])
gardenArgs = appendDefaultFlag(gardenArgs, "--bind-port", strings.Split(addr, ":")[1])
case "unix":
gardenArgs = appendDefaultFlag(gardenArgs, "--bind-socket", addr)
}

if rootfs != "" {
gardenArgs = appendDefaultFlag(gardenArgs, "--default-rootfs", rootfs)
}

gardenArgs = appendDefaultFlag(gardenArgs, "--depot", depotDir)
gardenArgs = appendDefaultFlag(gardenArgs, "--graph", graphPath)
gardenArgs = appendDefaultFlag(gardenArgs, "--console-sockets-path", consoleSocketsPath)
gardenArgs = appendDefaultFlag(gardenArgs, "--tag", fmt.Sprintf("%d", GinkgoParallelNode()))
gardenArgs = appendDefaultFlag(gardenArgs, "--network-pool", fmt.Sprintf("10.254.%d.0/22", 4*GinkgoParallelNode()))
gardenArgs = appendDefaultFlag(gardenArgs, "--init-bin", initBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--dadoo-bin", dadooBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--nstar-bin", nstarBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--tar-bin", tarBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--port-pool-start", fmt.Sprintf("%d", GinkgoParallelNode()*7000))

cmd := exec.Command(bin, append([]string{"server"}, gardenArgs...)...)
if user != nil {
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = user

uidGid := fmt.Sprintf("%d:%d", user.Uid, user.Gid)
Eventually(func() error {
cmd := exec.Command("chown", "-R", uidGid, tmpdir)
cmd.Stdout = GinkgoWriter
cmd.Stderr = GinkgoWriter
return cmd.Run()
}, "3s", "1s").Should(Succeed())
}

return cmd
}

func (r *RunningGarden) Cleanup() {
// unmount aufs since the docker graph driver leaves this around,
// otherwise the following commands might fail
retry := retrier.New(retrier.ConstantBackoff(200, 500*time.Millisecond), nil)

err := retry.Run(func() error {
if err := os.RemoveAll(path.Join(r.GraphPath, "aufs")); err == nil {
return nil // if we can remove it, it's already unmounted
}

if err := syscall.Unmount(path.Join(r.GraphPath, "aufs"), MNT_DETACH); err != nil {
r.logger.Error("failed-unmount-attempt", err)
return err
}

return nil
})

if err != nil {
r.logger.Error("failed-to-unmount", err)
}

MustUnmountTmpfs(r.GraphPath)

// In the kernel version 3.19.0-51-generic the code bellow results in
// hanging the running VM. We are not deleting the node-X directories. They
// are empty and the next test will re-use them. We will stick with that
// workaround until we can test on a newer kernel that will hopefully not
// have this bug.
//
// if err := os.RemoveAll(r.GraphPath); err != nil {
// r.logger.Error("remove-graph", err)
// }

r.logger.Info("cleanup-tempdirs")
if err := os.RemoveAll(r.Tmpdir); err != nil {
r.logger.Error("cleanup-tempdirs-failed", err, lager.Data{"tmpdir": r.Tmpdir})
} else {
r.logger.Info("tempdirs-removed")
}
}

func (r *RunningGarden) DestroyContainers() error {
containers, err := r.Containers(nil)
if err != nil {
Expand Down
123 changes: 123 additions & 0 deletions gqt/runner/runner_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// +build !windows

package runner

import (
"fmt"
"os"
"os/exec"
"path"
"strings"
"syscall"
"time"

"code.cloudfoundry.org/lager"
"github.com/eapache/go-resiliency/retrier"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

type UserCredential *syscall.Credential

func cmd(tmpdir, depotDir, graphPath, consoleSocketsPath, network, addr, bin, initBin, nstarBin, dadooBin, grootfsBin, tarBin, rootfs string, user UserCredential, argv ...string) *exec.Cmd {
Expect(os.MkdirAll(tmpdir, 0755)).To(Succeed())
Expect(os.MkdirAll(depotDir, 0755)).To(Succeed())

appendDefaultFlag := func(ar []string, key, value string) []string {
for _, a := range argv {
if a == key {
return ar
}
}

if value != "" {
return append(ar, key, value)
} else {
return append(ar, key)
}
}

gardenArgs := make([]string, len(argv))
copy(gardenArgs, argv)

switch network {
case "tcp":
gardenArgs = appendDefaultFlag(gardenArgs, "--bind-ip", strings.Split(addr, ":")[0])
gardenArgs = appendDefaultFlag(gardenArgs, "--bind-port", strings.Split(addr, ":")[1])
case "unix":
gardenArgs = appendDefaultFlag(gardenArgs, "--bind-socket", addr)
}

if rootfs != "" {
gardenArgs = appendDefaultFlag(gardenArgs, "--default-rootfs", rootfs)
}

gardenArgs = appendDefaultFlag(gardenArgs, "--depot", depotDir)
gardenArgs = appendDefaultFlag(gardenArgs, "--graph", graphPath)
gardenArgs = appendDefaultFlag(gardenArgs, "--console-sockets-path", consoleSocketsPath)
gardenArgs = appendDefaultFlag(gardenArgs, "--tag", fmt.Sprintf("%d", GinkgoParallelNode()))
gardenArgs = appendDefaultFlag(gardenArgs, "--network-pool", fmt.Sprintf("10.254.%d.0/22", 4*GinkgoParallelNode()))
gardenArgs = appendDefaultFlag(gardenArgs, "--init-bin", initBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--dadoo-bin", dadooBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--nstar-bin", nstarBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--tar-bin", tarBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--port-pool-start", fmt.Sprintf("%d", GinkgoParallelNode()*7000))

cmd := exec.Command(bin, append([]string{"server"}, gardenArgs...)...)
if user != nil {
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = user

uidGid := fmt.Sprintf("%d:%d", user.Uid, user.Gid)
Eventually(func() error {
cmd := exec.Command("chown", "-R", uidGid, tmpdir)
cmd.Stdout = GinkgoWriter
cmd.Stderr = GinkgoWriter
return cmd.Run()
}, "3s", "1s").Should(Succeed())
}

return cmd
}

func (r *RunningGarden) Cleanup() {
// unmount aufs since the docker graph driver leaves this around,
// otherwise the following commands might fail
retry := retrier.New(retrier.ConstantBackoff(200, 500*time.Millisecond), nil)

err := retry.Run(func() error {
if err := os.RemoveAll(path.Join(r.GraphPath, "aufs")); err == nil {
return nil // if we can remove it, it's already unmounted
}

if err := syscall.Unmount(path.Join(r.GraphPath, "aufs"), MNT_DETACH); err != nil {
r.logger.Error("failed-unmount-attempt", err)
return err
}

return nil
})

if err != nil {
r.logger.Error("failed-to-unmount", err)
}

MustUnmountTmpfs(r.GraphPath)

// In the kernel version 3.19.0-51-generic the code bellow results in
// hanging the running VM. We are not deleting the node-X directories. They
// are empty and the next test will re-use them. We will stick with that
// workaround until we can test on a newer kernel that will hopefully not
// have this bug.
//
// if err := os.RemoveAll(r.GraphPath); err != nil {
// r.logger.Error("remove-graph", err)
// }

r.logger.Info("cleanup-tempdirs")
if err := os.RemoveAll(r.Tmpdir); err != nil {
r.logger.Error("cleanup-tempdirs-failed", err, lager.Data{"tmpdir": r.Tmpdir})
} else {
r.logger.Info("tempdirs-removed")
}
}
82 changes: 82 additions & 0 deletions gqt/runner/runner_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package runner

import (
"fmt"
"os"
"os/exec"
"strings"

"code.cloudfoundry.org/lager"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

type UserCredential interface{}

func cmd(tmpdir, depotDir, graphPath, consoleSocketsPath, network, addr, bin, initBin, nstarBin, dadooBin, grootfsBin, tarBin, rootfs string, user UserCredential, argv ...string) *exec.Cmd {
Expect(os.MkdirAll(tmpdir, 0755)).To(Succeed())
Expect(os.MkdirAll(depotDir, 0755)).To(Succeed())

appendDefaultFlag := func(ar []string, key, value string) []string {
for _, a := range argv {
if a == key {
return ar
}
}

if value != "" {
return append(ar, key, value)
} else {
return append(ar, key)
}
}

gardenArgs := make([]string, len(argv))
copy(gardenArgs, argv)

switch network {
case "tcp":
gardenArgs = appendDefaultFlag(gardenArgs, "--bind-ip", strings.Split(addr, ":")[0])
gardenArgs = appendDefaultFlag(gardenArgs, "--bind-port", strings.Split(addr, ":")[1])
case "unix":
gardenArgs = appendDefaultFlag(gardenArgs, "--bind-socket", addr)
}

if rootfs != "" {
gardenArgs = appendDefaultFlag(gardenArgs, "--default-rootfs", rootfs)
}

gardenArgs = appendDefaultFlag(gardenArgs, "--depot", depotDir)
gardenArgs = appendDefaultFlag(gardenArgs, "--graph", graphPath)
gardenArgs = appendDefaultFlag(gardenArgs, "--console-sockets-path", consoleSocketsPath)
gardenArgs = appendDefaultFlag(gardenArgs, "--tag", fmt.Sprintf("%d", GinkgoParallelNode()))
gardenArgs = appendDefaultFlag(gardenArgs, "--network-pool", fmt.Sprintf("10.254.%d.0/22", 4*GinkgoParallelNode()))
gardenArgs = appendDefaultFlag(gardenArgs, "--init-bin", initBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--dadoo-bin", dadooBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--nstar-bin", nstarBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--tar-bin", tarBin)
gardenArgs = appendDefaultFlag(gardenArgs, "--port-pool-start", fmt.Sprintf("%d", GinkgoParallelNode()*7000))

return exec.Command(bin, append([]string{"server"}, gardenArgs...)...)
}

func (r *RunningGarden) Cleanup() {
MustUnmountTmpfs(r.GraphPath)

// In the kernel version 3.19.0-51-generic the code bellow results in
// hanging the running VM. We are not deleting the node-X directories. They
// are empty and the next test will re-use them. We will stick with that
// workaround until we can test on a newer kernel that will hopefully not
// have this bug.
//
// if err := os.RemoveAll(r.GraphPath); err != nil {
// r.logger.Error("remove-graph", err)
// }

r.logger.Info("cleanup-tempdirs")
if err := os.RemoveAll(r.Tmpdir); err != nil {
r.logger.Error("cleanup-tempdirs-failed", err, lager.Data{"tmpdir": r.Tmpdir})
} else {
r.logger.Info("tempdirs-removed")
}
}
File renamed without changes.
Loading

0 comments on commit 9fd0cc1

Please sign in to comment.