github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/containerizer/system/namespacing_execer_linux_test.go (about) 1 package system_test 2 3 import ( 4 "io/ioutil" 5 "os" 6 "os/exec" 7 "syscall" 8 9 "github.com/cloudfoundry-incubator/garden-linux/containerizer/system" 10 "github.com/cloudfoundry/gunk/command_runner/fake_command_runner" 11 . "github.com/cloudfoundry/gunk/command_runner/fake_command_runner/matchers" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 ) 15 16 var _ = Describe("Execer", func() { 17 var execer *system.NamespacingExecer 18 var commandRunner *fake_command_runner.FakeCommandRunner 19 20 BeforeEach(func() { 21 commandRunner = fake_command_runner.New() 22 process := &os.Process{ 23 Pid: 12, 24 } 25 26 commandRunner.WhenRunning(fake_command_runner.CommandSpec{}, func(cmd *exec.Cmd) error { 27 cmd.Process = process 28 return nil 29 }) 30 31 execer = &system.NamespacingExecer{ 32 CommandRunner: commandRunner, 33 } 34 }) 35 36 Describe("Exec", func() { 37 It("executes the given command", func() { 38 _, err := execer.Exec("something", "smthg") 39 Expect(err).To(Succeed()) 40 41 Expect(commandRunner).To(HaveStartedExecuting( 42 fake_command_runner.CommandSpec{ 43 Path: "something", 44 Args: []string{ 45 "smthg", 46 }, 47 }, 48 )) 49 }) 50 51 It("returns the correct PID", func() { 52 pid, err := execer.Exec("something", "smthg") 53 Expect(pid).To(Equal(12)) 54 Expect(err).ToNot(HaveOccurred()) 55 }) 56 57 It("sets the correct flags", func() { 58 _, err := execer.Exec("something", "smthg") 59 Expect(err).ToNot(HaveOccurred()) 60 61 cmd := commandRunner.StartedCommands()[0] 62 Expect(cmd.SysProcAttr).ToNot(BeNil()) 63 flags := syscall.CLONE_NEWIPC 64 flags = flags | syscall.CLONE_NEWNET 65 flags = flags | syscall.CLONE_NEWNS 66 flags = flags | syscall.CLONE_NEWUTS 67 flags = flags | syscall.CLONE_NEWPID 68 Expect(int(cmd.SysProcAttr.Cloneflags) & flags).ToNot(Equal(0)) 69 }) 70 71 Context("when the container is not privileged", func() { 72 It("creates a user namespace", func() { 73 _, err := execer.Exec("something", "smthg") 74 Expect(err).ToNot(HaveOccurred()) 75 76 cmd := commandRunner.StartedCommands()[0] 77 Expect(cmd.SysProcAttr).ToNot(BeNil()) 78 Expect(int(cmd.SysProcAttr.Cloneflags) & syscall.CLONE_NEWUSER).ToNot(Equal(0)) 79 }) 80 81 It("spawns as UID 0 (so that the process is run as container-root rather than 'nobody')", func() { 82 _, err := execer.Exec("something", "smthg") 83 Expect(err).ToNot(HaveOccurred()) 84 85 cmd := commandRunner.StartedCommands()[0] 86 Expect(cmd.SysProcAttr).ToNot(BeNil()) 87 Expect(cmd.SysProcAttr.Credential).To(Equal(&syscall.Credential{ 88 Uid: 0, 89 Gid: 0, 90 })) 91 }) 92 93 It("sets uid and gid mappings", func() { 94 execer.MaxUID = 33 95 _, err := execer.Exec("something", "smthg") 96 Expect(err).ToNot(HaveOccurred()) 97 98 cmd := commandRunner.StartedCommands()[0] 99 Expect(cmd.SysProcAttr.UidMappings).To(Equal([]syscall.SysProcIDMap{ 100 {ContainerID: 0, HostID: 33, Size: 1}, 101 {ContainerID: 1, HostID: 1, Size: 32}, 102 })) 103 104 Expect(cmd.SysProcAttr.GidMappings).To(Equal(cmd.SysProcAttr.UidMappings)) 105 }) 106 }) 107 108 Context("when the container is privileged", func() { 109 It("does not create a user namespace", func() { 110 execer.Privileged = true 111 112 _, err := execer.Exec("something", "smthg") 113 Expect(err).ToNot(HaveOccurred()) 114 115 cmd := commandRunner.StartedCommands()[0] 116 Expect(cmd.SysProcAttr.Cloneflags & syscall.CLONE_NEWUSER).To(Equal(uintptr(0))) 117 }) 118 }) 119 120 It("sets extra files", func() { 121 tmpFile, err := ioutil.TempFile("", "") 122 Expect(err).ToNot(HaveOccurred()) 123 tmpFile.Close() 124 defer os.Remove(tmpFile.Name()) 125 execer.ExtraFiles = []*os.File{tmpFile} 126 127 _, err = execer.Exec("something", "smthg") 128 Expect(err).ToNot(HaveOccurred()) 129 130 cmd := commandRunner.StartedCommands()[0] 131 Expect(cmd.ExtraFiles).To(HaveLen(1)) 132 Expect(cmd.ExtraFiles[0]).To(Equal(tmpFile)) 133 }) 134 }) 135 })