1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Update libcontainaer to d00b8369852285d6a830a8d3b9

Fixes #12015

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2015-04-02 14:12:14 -07:00
parent c88b2c422f
commit d12fef1515
9 changed files with 96 additions and 40 deletions

View file

@ -75,7 +75,7 @@ rm -rf src/github.com/docker/distribution
mkdir -p src/github.com/docker/distribution mkdir -p src/github.com/docker/distribution
mv tmp-digest src/github.com/docker/distribution/digest mv tmp-digest src/github.com/docker/distribution/digest
clone git github.com/docker/libcontainer c8512754166539461fd860451ff1a0af7491c197 clone git github.com/docker/libcontainer d00b8369852285d6a830a8d3b966608b2ed89705
# see src/github.com/docker/libcontainer/update-vendor.sh which is the "source of truth" for libcontainer deps (just like this file) # see src/github.com/docker/libcontainer/update-vendor.sh which is the "source of truth" for libcontainer deps (just like this file)
rm -rf src/github.com/docker/libcontainer/vendor rm -rf src/github.com/docker/libcontainer/vendor
eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli' | grep -v 'github.com/Sirupsen/logrus')" eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli' | grep -v 'github.com/Sirupsen/logrus')"

View file

@ -67,12 +67,12 @@ func generateProfile(out io.Writer) error {
data := &data{ data := &data{
Name: "docker-default", Name: "docker-default",
} }
if tuntablesExists() { if tunablesExists() {
data.Imports = append(data.Imports, "#include <tunables/global>") data.Imports = append(data.Imports, "#include <tunables/global>")
} else { } else {
data.Imports = append(data.Imports, "@{PROC}=/proc/") data.Imports = append(data.Imports, "@{PROC}=/proc/")
} }
if abstrctionsEsists() { if abstractionsExists() {
data.InnerImports = append(data.InnerImports, "#include <abstractions/base>") data.InnerImports = append(data.InnerImports, "#include <abstractions/base>")
} }
if err := compiled.Execute(out, data); err != nil { if err := compiled.Execute(out, data); err != nil {
@ -82,13 +82,13 @@ func generateProfile(out io.Writer) error {
} }
// check if the tunables/global exist // check if the tunables/global exist
func tuntablesExists() bool { func tunablesExists() bool {
_, err := os.Stat("/etc/apparmor.d/tunables/global") _, err := os.Stat("/etc/apparmor.d/tunables/global")
return err == nil return err == nil
} }
// check if abstractions/base exist // check if abstractions/base exist
func abstrctionsEsists() bool { func abstractionsExists() bool {
_, err := os.Stat("/etc/apparmor.d/abstractions/base") _, err := os.Stat("/etc/apparmor.d/abstractions/base")
return err == nil return err == nil
} }

View file

@ -1,6 +1,7 @@
package fs package fs
import ( import (
"fmt"
"strings" "strings"
"time" "time"
@ -41,6 +42,10 @@ func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error {
} }
time.Sleep(1 * time.Millisecond) time.Sleep(1 * time.Millisecond)
} }
case configs.Undefined:
return nil
default:
return fmt.Errorf("Invalid argument '%s' to freezer.state", string(cgroup.Freezer))
} }
return nil return nil

View file

@ -0,0 +1,45 @@
package fs
import (
"testing"
"github.com/docker/libcontainer/configs"
)
func TestFreezerSetState(t *testing.T) {
helper := NewCgroupTestUtil("freezer", t)
defer helper.cleanup()
helper.writeFileContents(map[string]string{
"freezer.state": string(configs.Frozen),
})
helper.CgroupData.c.Freezer = configs.Thawed
freezer := &FreezerGroup{}
if err := freezer.Set(helper.CgroupPath, helper.CgroupData.c); err != nil {
t.Fatal(err)
}
value, err := getCgroupParamString(helper.CgroupPath, "freezer.state")
if err != nil {
t.Fatalf("Failed to parse freezer.state - %s", err)
}
if value != string(configs.Thawed) {
t.Fatal("Got the wrong value, set freezer.state failed.")
}
}
func TestFreezerSetInvalidState(t *testing.T) {
helper := NewCgroupTestUtil("freezer", t)
defer helper.cleanup()
const (
invalidArg configs.FreezerState = "Invalid"
)
helper.CgroupData.c.Freezer = invalidArg
freezer := &FreezerGroup{}
if err := freezer.Set(helper.CgroupPath, helper.CgroupData.c); err == nil {
t.Fatal("Failed to return invalid argument error")
}
}

View file

@ -218,16 +218,7 @@ func (m *Manager) Apply(pid int) error {
} }
paths := make(map[string]string) paths := make(map[string]string)
for _, sysname := range []string{ for sysname := range subsystems {
"devices",
"memory",
"cpu",
"cpuset",
"cpuacct",
"blkio",
"perf_event",
"freezer",
} {
subsystemPath, err := getSubsystemPath(m.Cgroups, sysname) subsystemPath, err := getSubsystemPath(m.Cgroups, sysname)
if err != nil { if err != nil {
// Don't fail if a cgroup hierarchy was not found, just skip this subsystem // Don't fail if a cgroup hierarchy was not found, just skip this subsystem

View file

@ -140,7 +140,9 @@ func (c *linuxContainer) commandTemplate(p *Process, childPipe *os.File) (*exec.
cmd.SysProcAttr = &syscall.SysProcAttr{} cmd.SysProcAttr = &syscall.SysProcAttr{}
} }
cmd.ExtraFiles = []*os.File{childPipe} cmd.ExtraFiles = []*os.File{childPipe}
cmd.SysProcAttr.Pdeathsig = syscall.SIGKILL // NOTE: when running a container with no PID namespace and the parent process spawning the container is
// PID1 the pdeathsig is being delivered to the container's init process by the kernel for some reason
// even with the parent still running.
if c.config.ParentDeathSignal > 0 { if c.config.ParentDeathSignal > 0 {
cmd.SysProcAttr.Pdeathsig = syscall.Signal(c.config.ParentDeathSignal) cmd.SysProcAttr.Pdeathsig = syscall.Signal(c.config.ParentDeathSignal)
} }

View file

@ -69,7 +69,8 @@ func newContainerInit(t initType, pipe *os.File) (initer, error) {
}, nil }, nil
case initStandard: case initStandard:
return &linuxStandardInit{ return &linuxStandardInit{
config: config, parentPid: syscall.Getppid(),
config: config,
}, nil }, nil
} }
return nil, fmt.Errorf("unknown init type %q", t) return nil, fmt.Errorf("unknown init type %q", t)

View file

@ -5,13 +5,15 @@ It is able to spawn new containers or join existing containers.
### How to build? ### How to build?
First to add the `libcontainer/vendor` into your GOPATH. It's because something related with this [issue](https://github.com/docker/libcontainer/issues/210). First add the `libcontainer/vendor` into your GOPATH. It's because libcontainer
vendors all its dependencies, so it can be built predictably.
``` ```
export GOPATH=$GOPATH:/your/path/to/libcontainer/vendor export GOPATH=$GOPATH:/your/path/to/libcontainer/vendor
``` ```
Then get into the nsinit folder and get the imported file. Use `make` command to make the nsinit binary. Then get into the nsinit folder and get the imported file. Use `make` command
to make the nsinit binary.
``` ```
cd libcontainer/nsinit cd libcontainer/nsinit
@ -19,7 +21,8 @@ go get
make make
``` ```
We have finished compiling the nsinit package, but a root filesystem must be provided for use along with a container configuration file. We have finished compiling the nsinit package, but a root filesystem must be
provided for use along with a container configuration file.
Choose a proper place to run your container. For example we use `/busybox`. Choose a proper place to run your container. For example we use `/busybox`.
@ -28,30 +31,37 @@ mkdir /busybox
curl -sSL 'https://github.com/jpetazzo/docker-busybox/raw/buildroot-2014.11/rootfs.tar' | tar -xC /busybox curl -sSL 'https://github.com/jpetazzo/docker-busybox/raw/buildroot-2014.11/rootfs.tar' | tar -xC /busybox
``` ```
Then you may need to write a configure file named `container.json` in the `/busybox` folder. Then you may need to write a configuration file named `container.json` in the
Environment, networking, and different capabilities for the container are specified in this file. `/busybox` folder. Environment, networking, and different capabilities for
The configuration is used for each process executed inside the container the container are specified in this file. The configuration is used for each
See the `sample_configs` folder for examples of what the container configuration should look like. process executed inside the container.
See the `sample_configs` folder for examples of what the container configuration
should look like.
``` ```
cp libcontainer/sample_configs/minimal.json /busybox/container.json cp libcontainer/sample_configs/minimal.json /busybox/container.json
cd /busybox cd /busybox
``` ```
Now the nsinit is ready to work. You can customize `container.json` per your needs. After that, nsinit is
To execute `/bin/bash` in the current directory as a container just run the following **as root**: ready to work.
To execute `/bin/bash` in the current directory as a container just run the
following **as root**:
```bash ```bash
nsinit exec --tty /bin/bash nsinit exec --tty --config container.json /bin/bash
``` ```
If you wish to spawn another process inside the container while your If you wish to spawn another process inside the container while your current
current bash session is running, run the same command again to bash session is running, run the same command again to get another bash shell
get another bash shell (or change the command). If the original (or change the command). If the original process (PID 1) dies, all other
process (PID 1) dies, all other processes spawned inside the container processes spawned inside the container will be killed and the namespace will
will be killed and the namespace will be removed. be removed.
You can identify if a process is running in a container by You can identify if a process is running in a container by looking to see if
looking to see if `state.json` is in the root of the directory. `state.json` is in the root of the directory.
You may also specify an alternate root place where You may also specify an alternate root directory from where the `container.json`
the `container.json` file is read and where the `state.json` file will be saved. file is read and where the `state.json` file will be saved.

View file

@ -13,7 +13,8 @@ import (
) )
type linuxStandardInit struct { type linuxStandardInit struct {
config *initConfig parentPid int
config *initConfig
} }
func (l *linuxStandardInit) Init() error { func (l *linuxStandardInit) Init() error {
@ -85,9 +86,10 @@ func (l *linuxStandardInit) Init() error {
if err := pdeath.Restore(); err != nil { if err := pdeath.Restore(); err != nil {
return err return err
} }
// Signal self if parent is already dead. Does nothing if running in a new // compare the parent from the inital start of the init process and make sure that it did not change.
// PID namespace, as Getppid will always return 0. // if the parent changes that means it died and we were reparened to something else so we should
if syscall.Getppid() == 1 { // just kill ourself and not cause problems for someone else.
if syscall.Getppid() != l.parentPid {
return syscall.Kill(syscall.Getpid(), syscall.SIGKILL) return syscall.Kill(syscall.Getpid(), syscall.SIGKILL)
} }
return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ()) return system.Execv(l.config.Args[0], l.config.Args[0:], os.Environ())