Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Setup environment for processes with os.Environ() #418

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion container_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (c *linuxContainer) Destroy() error {
return err
}
if status != Destroyed {
return newGenericError(nil, ContainerNotStopped)
return newGenericError(fmt.Errorf("container is not destroyed"), ContainerNotStopped)
}
if !c.config.Namespaces.Contains(configs.NEWPID) {
if err := killCgroupProcesses(c.cgroupManager); err != nil {
Expand Down
14 changes: 10 additions & 4 deletions generic_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,32 @@ func newGenericError(err error, c ErrorCode) Error {
if le, ok := err.(Error); ok {
return le
}
return &genericError{
gerr := &genericError{
Timestamp: time.Now(),
Err: err,
Message: err.Error(),
ECode: c,
Stack: stacktrace.Capture(1),
}
if err != nil {
gerr.Message = err.Error()
}
return gerr
}

func newSystemError(err error) Error {
if le, ok := err.(Error); ok {
return le
}
return &genericError{
gerr := &genericError{
Timestamp: time.Now(),
Err: err,
ECode: SystemError,
Message: err.Error(),
Stack: stacktrace.Capture(1),
}
if err != nil {
gerr.Message = err.Error()
}
return gerr
}

type genericError struct {
Expand Down
43 changes: 43 additions & 0 deletions integration/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,49 @@ func testExecPS(t *testing.T, userns bool) {
}
}

func TestExecEnvironment(t *testing.T) {
if testing.Short() {
return
}
rootfs, err := newRootfs()
if err != nil {
t.Fatal(err)
}
defer remove(rootfs)

config := newTemplateConfig(rootfs)
container, err := newContainer(config)
if err != nil {
t.Fatal(err)
}
defer container.Destroy()

buffers := newStdBuffers()
process := &libcontainer.Process{
Args: []string{"env"},
Env: []string{
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=dummy",
"TERM=xterm",
},
Stdin: buffers.Stdin,
Stdout: buffers.Stdout,
Stderr: buffers.Stderr,
}

if err := container.Start(process); err != nil {
t.Fatal(err)
}
waitProcess(process, t)

out := buffers.Stdout.String()
if !strings.Contains(out, "TERM=xterm") ||
!strings.Contains(out, "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin") ||
strings.Contains(out, "TERM=dummy") {
t.Fatalf("unexpected environment, output %q", out)
}
}

func TestIPCPrivate(t *testing.T) {
if testing.Short() {
return
Expand Down
68 changes: 68 additions & 0 deletions integration/execin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,74 @@ func TestExecIn(t *testing.T) {
}
}

func TestExecInEnvironment(t *testing.T) {
if testing.Short() {
return
}
rootfs, err := newRootfs()
if err != nil {
t.Fatal(err)
}
defer remove(rootfs)
config := newTemplateConfig(rootfs)
container, err := newContainer(config)
if err != nil {
t.Fatal(err)
}
defer container.Destroy()

// Execute a first process in the container
stdinR, stdinW, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
process := &libcontainer.Process{
Args: []string{"cat"},
Env: standardEnvironment,
Stdin: stdinR,
}
err = container.Start(process)
stdinR.Close()
defer stdinW.Close()
if err != nil {
t.Fatal(err)
}

buffers := newStdBuffers()
ps := &libcontainer.Process{
Args: []string{"env"},
Env: []string{
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"DEBUG=true",
"DEBUG=false",
"ENV=test",
},
Stdin: buffers.Stdin,
Stdout: buffers.Stdout,
Stderr: buffers.Stderr,
}
err = container.Start(ps)
if err != nil {
t.Fatal(err)
}
if _, err := ps.Wait(); err != nil {
out := buffers.Stdout.String()
t.Fatal(err, out)
}
stdinW.Close()
if _, err := process.Wait(); err != nil {
t.Log(err)
}
out := buffers.Stdout.String()
// check execin's process environment
if !strings.Contains(out, "DEBUG=false") ||
!strings.Contains(out, "ENV=test") ||
!strings.Contains(out, "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin") ||
strings.Contains(out, "DEBUG=true") {
t.Fatalf("unexpected running process, output %q", out)
}
}

func TestExecInRlimit(t *testing.T) {
if testing.Short() {
return
Expand Down
7 changes: 4 additions & 3 deletions process.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package libcontainer

import (
"fmt"
"io"
"os"
)
Expand Down Expand Up @@ -46,23 +47,23 @@ type Process struct {
// Wait releases any resources associated with the Process
func (p Process) Wait() (*os.ProcessState, error) {
if p.ops == nil {
return nil, newGenericError(nil, ProcessNotExecuted)
return nil, newGenericError(fmt.Errorf("invalid process"), ProcessNotExecuted)
}
return p.ops.wait()
}

// Pid returns the process ID
func (p Process) Pid() (int, error) {
if p.ops == nil {
return -1, newGenericError(nil, ProcessNotExecuted)
return -1, newGenericError(fmt.Errorf("invalid process"), ProcessNotExecuted)
}
return p.ops.pid(), nil
}

// Signal sends a signal to the Process.
func (p Process) Signal(sig os.Signal) error {
if p.ops == nil {
return newGenericError(nil, ProcessNotExecuted)
return newGenericError(fmt.Errorf("invalid process"), ProcessNotExecuted)
}
return p.ops.signal(sig)
}
Expand Down
4 changes: 3 additions & 1 deletion setns_init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
package libcontainer

import (
"os"

"github.com/docker/libcontainer/apparmor"
"github.com/docker/libcontainer/label"
"github.com/docker/libcontainer/system"
Expand All @@ -29,5 +31,5 @@ func (l *linuxSetnsInit) Init() error {
return err
}
}
return system.Execv(l.config.Args[0], l.config.Args[0:], l.config.Env)
return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
}
3 changes: 2 additions & 1 deletion standard_init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package libcontainer

import (
"os"
"syscall"

"github.com/docker/libcontainer/apparmor"
Expand Down Expand Up @@ -89,5 +90,5 @@ func (l *linuxStandardInit) Init() error {
if syscall.Getppid() == 1 {
return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
}
return system.Execv(l.config.Args[0], l.config.Args[0:], l.config.Env)
return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())
}