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
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)
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')"

View File

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

View File

@ -1,6 +1,7 @@
package fs
import (
"fmt"
"strings"
"time"
@ -41,6 +42,10 @@ func (s *FreezerGroup) Set(path string, cgroup *configs.Cgroup) error {
}
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

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)
for _, sysname := range []string{
"devices",
"memory",
"cpu",
"cpuset",
"cpuacct",
"blkio",
"perf_event",
"freezer",
} {
for sysname := range subsystems {
subsystemPath, err := getSubsystemPath(m.Cgroups, sysname)
if err != nil {
// 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.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 {
cmd.SysProcAttr.Pdeathsig = syscall.Signal(c.config.ParentDeathSignal)
}

View File

@ -69,7 +69,8 @@ func newContainerInit(t initType, pipe *os.File) (initer, error) {
}, nil
case initStandard:
return &linuxStandardInit{
config: config,
parentPid: syscall.Getppid(),
config: config,
}, nil
}
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?
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
```
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
@ -19,7 +21,8 @@ go get
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`.
@ -28,30 +31,37 @@ mkdir /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.
Environment, networking, and different capabilities for the container are specified in this file.
The configuration is used for each process executed inside the container
See the `sample_configs` folder for examples of what the container configuration should look like.
Then you may need to write a configuration file named `container.json` in the
`/busybox` folder. Environment, networking, and different capabilities for
the container are specified in this file. The configuration is used for each
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
cd /busybox
```
Now the nsinit is ready to work.
To execute `/bin/bash` in the current directory as a container just run the following **as root**:
You can customize `container.json` per your needs. After that, nsinit is
ready to work.
To execute `/bin/bash` in the current directory as a container just run the
following **as root**:
```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
current bash session is running, run the same command again to
get another bash shell (or change the command). If the original
process (PID 1) dies, all other processes spawned inside the container
will be killed and the namespace will be removed.
If you wish to spawn another process inside the container while your current
bash session is running, run the same command again to get another bash shell
(or change the command). If the original process (PID 1) dies, all other
processes spawned inside the container will be killed and the namespace will
be removed.
You can identify if a process is running in a container by
looking to see if `state.json` is in the root of the directory.
You can identify if a process is running in a container by looking to see if
`state.json` is in the root of the directory.
You may also specify an alternate root place where
the `container.json` file is read and where the `state.json` file will be saved.
You may also specify an alternate root directory from where the `container.json`
file is read and where the `state.json` file will be saved.

View File

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