mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Update libcontainer to aab3f6d17f2f56606f07f3a6eb6
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
8b40d385b5
commit
291b84610f
25 changed files with 452 additions and 20 deletions
|
@ -64,7 +64,7 @@ if [ "$1" = '--go' ]; then
|
||||||
mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
|
mv tmp-tar src/code.google.com/p/go/src/pkg/archive/tar
|
||||||
fi
|
fi
|
||||||
|
|
||||||
clone git github.com/docker/libcontainer 8d1d0ba38a7348c5cfdc05aea3be34d75aadc8de
|
clone git github.com/docker/libcontainer aab3f6d17f2f56606f07f3a6eb6b693303f75812
|
||||||
# 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')"
|
eval "$(grep '^clone ' src/github.com/docker/libcontainer/update-vendor.sh | grep -v 'github.com/codegangsta/cli')"
|
||||||
|
|
|
@ -6,7 +6,7 @@ feels wrong or incomplete.
|
||||||
|
|
||||||
## Reporting Issues
|
## Reporting Issues
|
||||||
|
|
||||||
When reporting [issues](https://github.com/docker/libcontainer/issues)
|
When reporting [issues](https://github.com/docker/libcontainer/issues)
|
||||||
on GitHub please include your host OS (Ubuntu 12.04, Fedora 19, etc),
|
on GitHub please include your host OS (Ubuntu 12.04, Fedora 19, etc),
|
||||||
the output of `uname -a`. Please include the steps required to reproduce
|
the output of `uname -a`. Please include the steps required to reproduce
|
||||||
the problem if possible and applicable.
|
the problem if possible and applicable.
|
||||||
|
@ -14,7 +14,60 @@ This information will help us review and fix your issue faster.
|
||||||
|
|
||||||
## Development Environment
|
## Development Environment
|
||||||
|
|
||||||
*Add instructions on setting up the development environment.*
|
### Requirements
|
||||||
|
|
||||||
|
For best results, use a Linux development environment.
|
||||||
|
The following packages are required to compile libcontainer natively.
|
||||||
|
|
||||||
|
- Golang 1.3
|
||||||
|
- GCC
|
||||||
|
- git
|
||||||
|
- cgutils
|
||||||
|
|
||||||
|
You can develop on OSX, but you are limited to Dockerfile-based builds only.
|
||||||
|
|
||||||
|
### Building libcontainer from Dockerfile
|
||||||
|
|
||||||
|
make all
|
||||||
|
|
||||||
|
This is the easiest way of building libcontainer.
|
||||||
|
As this build is done using Docker, you can even run this from [OSX](https://github.com/boot2docker/boot2docker)
|
||||||
|
|
||||||
|
### Testing changes with "nsinit"
|
||||||
|
|
||||||
|
make sh
|
||||||
|
|
||||||
|
This will create an container that runs `nsinit exec sh` on a busybox rootfs with the configuration from ['minimal.json'](https://github.com/docker/libcontainer/blob/master/sample_configs/minimal.json).
|
||||||
|
Like the previous command, you can run this on OSX too!
|
||||||
|
|
||||||
|
### Building libcontainer directly
|
||||||
|
|
||||||
|
> Note: You should add the `vendor` directory to your GOPATH to use the vendored libraries
|
||||||
|
|
||||||
|
./update-vendor.sh
|
||||||
|
go get -d ./...
|
||||||
|
make direct-build
|
||||||
|
# Run the tests
|
||||||
|
make direct-test-short | egrep --color 'FAIL|$'
|
||||||
|
# Run all the test
|
||||||
|
make direct-test | egrep --color 'FAIL|$'
|
||||||
|
|
||||||
|
### Testing Changes with "nsinit" directly
|
||||||
|
|
||||||
|
To test a change:
|
||||||
|
|
||||||
|
# Install nsinit
|
||||||
|
make direct-install
|
||||||
|
|
||||||
|
# Optional, add a docker0 bridge
|
||||||
|
ip link add docker0 type bridge
|
||||||
|
ifconfig docker0 172.17.0.1/16 up
|
||||||
|
|
||||||
|
mkdir testfs
|
||||||
|
curl -sSL https://github.com/jpetazzo/docker-busybox/raw/buildroot-2014.02/rootfs.tar | tar -xC testfs
|
||||||
|
cd testfs
|
||||||
|
cp <your-sample-config.json> container.json
|
||||||
|
nsinit exec sh
|
||||||
|
|
||||||
## Contribution Guidelines
|
## Contribution Guidelines
|
||||||
|
|
|
@ -3,6 +3,9 @@ FROM crosbymichael/golang
|
||||||
RUN apt-get update && apt-get install -y gcc make
|
RUN apt-get update && apt-get install -y gcc make
|
||||||
RUN go get code.google.com/p/go.tools/cmd/cover
|
RUN go get code.google.com/p/go.tools/cmd/cover
|
||||||
|
|
||||||
|
ENV GOPATH $GOPATH:/go/src/github.com/docker/libcontainer/vendor
|
||||||
|
RUN go get github.com/docker/docker/pkg/term
|
||||||
|
|
||||||
# setup a playground for us to spawn containers in
|
# setup a playground for us to spawn containers in
|
||||||
RUN mkdir /busybox && \
|
RUN mkdir /busybox && \
|
||||||
curl -sSL 'https://github.com/jpetazzo/docker-busybox/raw/buildroot-2014.02/rootfs.tar' | tar -xC /busybox
|
curl -sSL 'https://github.com/jpetazzo/docker-busybox/raw/buildroot-2014.02/rootfs.tar' | tar -xC /busybox
|
||||||
|
@ -14,8 +17,6 @@ COPY . /go/src/github.com/docker/libcontainer
|
||||||
WORKDIR /go/src/github.com/docker/libcontainer
|
WORKDIR /go/src/github.com/docker/libcontainer
|
||||||
RUN cp sample_configs/minimal.json /busybox/container.json
|
RUN cp sample_configs/minimal.json /busybox/container.json
|
||||||
|
|
||||||
ENV GOPATH $GOPATH:/go/src/github.com/docker/libcontainer/vendor
|
|
||||||
|
|
||||||
RUN go get -d -v ./...
|
RUN go get -d -v ./...
|
||||||
RUN make direct-install
|
RUN make direct-install
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,19 @@ func Apply(c *cgroups.Cgroup, pid int) (cgroups.ActiveCgroup, error) {
|
||||||
return d, nil
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Symmetrical public function to update device based cgroups. Also available
|
||||||
|
// in the systemd implementation.
|
||||||
|
func ApplyDevices(c *cgroups.Cgroup, pid int) error {
|
||||||
|
d, err := getCgroupData(c, pid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
devices := subsystems["devices"]
|
||||||
|
|
||||||
|
return devices.Set(d)
|
||||||
|
}
|
||||||
|
|
||||||
func Cleanup(c *cgroups.Cgroup) error {
|
func Cleanup(c *cgroups.Cgroup) error {
|
||||||
d, err := getCgroupData(c, 0)
|
d, err := getCgroupData(c, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -20,6 +20,10 @@ func GetPids(c *cgroups.Cgroup) ([]int, error) {
|
||||||
return nil, fmt.Errorf("Systemd not supported")
|
return nil, fmt.Errorf("Systemd not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ApplyDevices(c *cgroups.Cgroup, pid int) error {
|
||||||
|
return fmt.Errorf("Systemd not supported")
|
||||||
|
}
|
||||||
|
|
||||||
func Freeze(c *cgroups.Cgroup, state cgroups.FreezerState) error {
|
func Freeze(c *cgroups.Cgroup, state cgroups.FreezerState) error {
|
||||||
return fmt.Errorf("Systemd not supported")
|
return fmt.Errorf("Systemd not supported")
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,6 +327,12 @@ func joinDevices(c *cgroups.Cgroup, pid int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Symmetrical public function to update device based cgroups. Also available
|
||||||
|
// in the fs implementation.
|
||||||
|
func ApplyDevices(c *cgroups.Cgroup, pid int) error {
|
||||||
|
return joinDevices(c, pid)
|
||||||
|
}
|
||||||
|
|
||||||
func joinMemory(c *cgroups.Cgroup, pid int) error {
|
func joinMemory(c *cgroups.Cgroup, pid int) error {
|
||||||
memorySwap := c.MemorySwap
|
memorySwap := c.MemorySwap
|
||||||
|
|
||||||
|
|
|
@ -67,14 +67,14 @@ func OpenAndDup(consolePath string) error {
|
||||||
// Unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
|
// Unlockpt unlocks the slave pseudoterminal device corresponding to the master pseudoterminal referred to by f.
|
||||||
// Unlockpt should be called before opening the slave side of a pseudoterminal.
|
// Unlockpt should be called before opening the slave side of a pseudoterminal.
|
||||||
func Unlockpt(f *os.File) error {
|
func Unlockpt(f *os.File) error {
|
||||||
var u int
|
var u int32
|
||||||
|
|
||||||
return Ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
|
return Ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ptsname retrieves the name of the first available pts for the given master.
|
// Ptsname retrieves the name of the first available pts for the given master.
|
||||||
func Ptsname(f *os.File) (string, error) {
|
func Ptsname(f *os.File) (string, error) {
|
||||||
var n int
|
var n int32
|
||||||
|
|
||||||
if err := Ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
|
if err := Ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n))); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
2
vendor/src/github.com/docker/libcontainer/integration/doc.go
vendored
Normal file
2
vendor/src/github.com/docker/libcontainer/integration/doc.go
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
// integration is used for integration testing of libcontainer
|
||||||
|
package integration
|
38
vendor/src/github.com/docker/libcontainer/integration/exec_test.go
vendored
Normal file
38
vendor/src/github.com/docker/libcontainer/integration/exec_test.go
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExecPS(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rootfs, err := newRootFs()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer remove(rootfs)
|
||||||
|
|
||||||
|
config := newTemplateConfig(rootfs)
|
||||||
|
buffers, exitCode, err := runContainer(config, "", "ps")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if exitCode != 0 {
|
||||||
|
t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr)
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(buffers.Stdout.String(), "\n")
|
||||||
|
if len(lines) < 2 {
|
||||||
|
t.Fatalf("more than one process running for output %q", buffers.Stdout.String())
|
||||||
|
}
|
||||||
|
expected := `1 root ps`
|
||||||
|
actual := strings.Trim(lines[1], "\n ")
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("expected output %q but received %q", expected, actual)
|
||||||
|
}
|
||||||
|
}
|
39
vendor/src/github.com/docker/libcontainer/integration/init_test.go
vendored
Normal file
39
vendor/src/github.com/docker/libcontainer/integration/init_test.go
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/docker/libcontainer/namespaces"
|
||||||
|
"github.com/docker/libcontainer/syncpipe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// init runs the libcontainer initialization code because of the busybox style needs
|
||||||
|
// to work around the go runtime and the issues with forking
|
||||||
|
func init() {
|
||||||
|
if len(os.Args) < 2 || os.Args[1] != "init" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
runtime.LockOSThread()
|
||||||
|
|
||||||
|
container, err := loadConfig()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rootfs, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
syncPipe, err := syncpipe.NewSyncPipeFromFd(0, 3)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("unable to create sync pipe: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := namespaces.Init(container, rootfs, "", syncPipe, os.Args[3:]); err != nil {
|
||||||
|
log.Fatalf("unable to initialize for container: %s", err)
|
||||||
|
}
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
64
vendor/src/github.com/docker/libcontainer/integration/template_test.go
vendored
Normal file
64
vendor/src/github.com/docker/libcontainer/integration/template_test.go
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/docker/libcontainer"
|
||||||
|
"github.com/docker/libcontainer/cgroups"
|
||||||
|
"github.com/docker/libcontainer/devices"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newTemplateConfig returns a base template for running a container
|
||||||
|
//
|
||||||
|
// it uses a network strategy of just setting a loopback interface
|
||||||
|
// and the default setup for devices
|
||||||
|
func newTemplateConfig(rootfs string) *libcontainer.Config {
|
||||||
|
return &libcontainer.Config{
|
||||||
|
RootFs: rootfs,
|
||||||
|
Tty: false,
|
||||||
|
Capabilities: []string{
|
||||||
|
"CHOWN",
|
||||||
|
"DAC_OVERRIDE",
|
||||||
|
"FSETID",
|
||||||
|
"FOWNER",
|
||||||
|
"MKNOD",
|
||||||
|
"NET_RAW",
|
||||||
|
"SETGID",
|
||||||
|
"SETUID",
|
||||||
|
"SETFCAP",
|
||||||
|
"SETPCAP",
|
||||||
|
"NET_BIND_SERVICE",
|
||||||
|
"SYS_CHROOT",
|
||||||
|
"KILL",
|
||||||
|
"AUDIT_WRITE",
|
||||||
|
},
|
||||||
|
Namespaces: map[string]bool{
|
||||||
|
"NEWNS": true,
|
||||||
|
"NEWUTS": true,
|
||||||
|
"NEWIPC": true,
|
||||||
|
"NEWPID": true,
|
||||||
|
"NEWNET": true,
|
||||||
|
},
|
||||||
|
Cgroups: &cgroups.Cgroup{
|
||||||
|
Parent: "integration",
|
||||||
|
AllowAllDevices: false,
|
||||||
|
AllowedDevices: devices.DefaultAllowedDevices,
|
||||||
|
},
|
||||||
|
|
||||||
|
MountConfig: &libcontainer.MountConfig{
|
||||||
|
DeviceNodes: devices.DefaultAutoCreatedDevices,
|
||||||
|
},
|
||||||
|
Hostname: "integration",
|
||||||
|
Env: []string{
|
||||||
|
"HOME=/root",
|
||||||
|
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
|
"HOSTNAME=integration",
|
||||||
|
"TERM=xterm",
|
||||||
|
},
|
||||||
|
Networks: []*libcontainer.Network{
|
||||||
|
{
|
||||||
|
Type: "loopback",
|
||||||
|
Address: "127.0.0.1/0",
|
||||||
|
Gateway: "localhost",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
95
vendor/src/github.com/docker/libcontainer/integration/utils_test.go
vendored
Normal file
95
vendor/src/github.com/docker/libcontainer/integration/utils_test.go
vendored
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/docker/libcontainer"
|
||||||
|
"github.com/docker/libcontainer/namespaces"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newStdBuffers() *stdBuffers {
|
||||||
|
return &stdBuffers{
|
||||||
|
Stdin: bytes.NewBuffer(nil),
|
||||||
|
Stdout: bytes.NewBuffer(nil),
|
||||||
|
Stderr: bytes.NewBuffer(nil),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type stdBuffers struct {
|
||||||
|
Stdin *bytes.Buffer
|
||||||
|
Stdout *bytes.Buffer
|
||||||
|
Stderr *bytes.Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeConfig(config *libcontainer.Config) error {
|
||||||
|
f, err := os.OpenFile(filepath.Join(config.RootFs, "container.json"), os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0700)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
return json.NewEncoder(f).Encode(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfig() (*libcontainer.Config, error) {
|
||||||
|
f, err := os.Open(filepath.Join(os.Getenv("data_path"), "container.json"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
var container *libcontainer.Config
|
||||||
|
if err := json.NewDecoder(f).Decode(&container); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return container, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newRootFs creates a new tmp directory and copies the busybox root filesystem
|
||||||
|
func newRootFs() (string, error) {
|
||||||
|
dir, err := ioutil.TempDir("", "")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err := os.MkdirAll(dir, 0700); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if err := copyBusybox(dir); err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
return dir, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func remove(dir string) {
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
// copyBusybox copies the rootfs for a busybox container created for the test image
|
||||||
|
// into the new directory for the specific test
|
||||||
|
func copyBusybox(dest string) error {
|
||||||
|
out, err := exec.Command("sh", "-c", fmt.Sprintf("cp -R /busybox/* %s/", dest)).CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("copy error %q: %q", err, out)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// runContainer runs the container with the specific config and arguments
|
||||||
|
//
|
||||||
|
// buffers are returned containing the STDOUT and STDERR output for the run
|
||||||
|
// along with the exit code and any go error
|
||||||
|
func runContainer(config *libcontainer.Config, console string, args ...string) (buffers *stdBuffers, exitCode int, err error) {
|
||||||
|
if err := writeConfig(config); err != nil {
|
||||||
|
return nil, -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers = newStdBuffers()
|
||||||
|
exitCode, err = namespaces.Exec(config, buffers.Stdin, buffers.Stdout, buffers.Stderr,
|
||||||
|
console, config.RootFs, args, namespaces.DefaultCreateCommand, nil)
|
||||||
|
return
|
||||||
|
}
|
|
@ -681,7 +681,7 @@ func NetworkChangeName(iface *net.Interface, newName string) error {
|
||||||
|
|
||||||
// Add a new VETH pair link on the host
|
// Add a new VETH pair link on the host
|
||||||
// This is identical to running: ip link add name $name type veth peer name $peername
|
// This is identical to running: ip link add name $name type veth peer name $peername
|
||||||
func NetworkCreateVethPair(name1, name2 string) error {
|
func NetworkCreateVethPair(name1, name2 string, txQueueLen int) error {
|
||||||
s, err := getNetlinkSocket()
|
s, err := getNetlinkSocket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -696,6 +696,11 @@ func NetworkCreateVethPair(name1, name2 string) error {
|
||||||
nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name1))
|
nameData := newRtAttr(syscall.IFLA_IFNAME, zeroTerminated(name1))
|
||||||
wb.AddData(nameData)
|
wb.AddData(nameData)
|
||||||
|
|
||||||
|
txqLen := make([]byte, 4)
|
||||||
|
native.PutUint32(txqLen, uint32(txQueueLen))
|
||||||
|
txqData := newRtAttr(syscall.IFLA_TXQLEN, txqLen)
|
||||||
|
wb.AddData(txqData)
|
||||||
|
|
||||||
nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil)
|
nest1 := newRtAttr(syscall.IFLA_LINKINFO, nil)
|
||||||
newRtAttrChild(nest1, IFLA_INFO_KIND, zeroTerminated("veth"))
|
newRtAttrChild(nest1, IFLA_INFO_KIND, zeroTerminated("veth"))
|
||||||
nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil)
|
nest2 := newRtAttrChild(nest1, IFLA_INFO_DATA, nil)
|
||||||
|
@ -704,6 +709,10 @@ func NetworkCreateVethPair(name1, name2 string) error {
|
||||||
newIfInfomsgChild(nest3, syscall.AF_UNSPEC)
|
newIfInfomsgChild(nest3, syscall.AF_UNSPEC)
|
||||||
newRtAttrChild(nest3, syscall.IFLA_IFNAME, zeroTerminated(name2))
|
newRtAttrChild(nest3, syscall.IFLA_IFNAME, zeroTerminated(name2))
|
||||||
|
|
||||||
|
txqLen2 := make([]byte, 4)
|
||||||
|
native.PutUint32(txqLen2, uint32(txQueueLen))
|
||||||
|
newRtAttrChild(nest3, syscall.IFLA_TXQLEN, txqLen2)
|
||||||
|
|
||||||
wb.AddData(nest1)
|
wb.AddData(nest1)
|
||||||
|
|
||||||
if err := s.Send(wb); err != nil {
|
if err := s.Send(wb); err != nil {
|
||||||
|
|
|
@ -290,7 +290,7 @@ func TestCreateVethPair(t *testing.T) {
|
||||||
name2 = "veth2"
|
name2 = "veth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := NetworkCreateVethPair(name1, name2); err != nil {
|
if err := NetworkCreateVethPair(name1, name2, 0); err != nil {
|
||||||
t.Fatalf("Could not create veth pair %s %s: %s", name1, name2, err)
|
t.Fatalf("Could not create veth pair %s %s: %s", name1, name2, err)
|
||||||
}
|
}
|
||||||
defer NetworkLinkDel(name1)
|
defer NetworkLinkDel(name1)
|
||||||
|
|
|
@ -47,7 +47,7 @@ func NetworkSetMTU(iface *net.Interface, mtu int) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
func NetworkCreateVethPair(name1, name2 string) error {
|
func NetworkCreateVethPair(name1, name2 string, txQueueLen int) error {
|
||||||
return ErrNotImplemented
|
return ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ func ChangeInterfaceName(old, newName string) error {
|
||||||
return netlink.NetworkChangeName(iface, newName)
|
return netlink.NetworkChangeName(iface, newName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateVethPair(name1, name2 string) error {
|
func CreateVethPair(name1, name2 string, txQueueLen int) error {
|
||||||
return netlink.NetworkCreateVethPair(name1, name2)
|
return netlink.NetworkCreateVethPair(name1, name2, txQueueLen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetInterfaceInNamespacePid(name string, nsPid int) error {
|
func SetInterfaceInNamespacePid(name string, nsPid int) error {
|
||||||
|
|
|
@ -36,6 +36,11 @@ type Network struct {
|
||||||
// container's interfaces if a pair is created, specifically in the case of type veth
|
// container's interfaces if a pair is created, specifically in the case of type veth
|
||||||
// Note: This does not apply to loopback interfaces.
|
// Note: This does not apply to loopback interfaces.
|
||||||
Mtu int `json:"mtu,omitempty"`
|
Mtu int `json:"mtu,omitempty"`
|
||||||
|
|
||||||
|
// TxQueueLen sets the tx_queuelen value for the interface and will be mirrored on both the host and
|
||||||
|
// container's interfaces if a pair is created, specifically in the case of type veth
|
||||||
|
// Note: This does not apply to loopback interfaces.
|
||||||
|
TxQueueLen int `json:"txqueuelen,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Struct describing the network specific runtime state that will be maintained by libcontainer for all running containers
|
// Struct describing the network specific runtime state that will be maintained by libcontainer for all running containers
|
||||||
|
|
|
@ -19,8 +19,9 @@ const defaultDevice = "eth0"
|
||||||
|
|
||||||
func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error {
|
func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error {
|
||||||
var (
|
var (
|
||||||
bridge = n.Bridge
|
bridge = n.Bridge
|
||||||
prefix = n.VethPrefix
|
prefix = n.VethPrefix
|
||||||
|
txQueueLen = n.TxQueueLen
|
||||||
)
|
)
|
||||||
if bridge == "" {
|
if bridge == "" {
|
||||||
return fmt.Errorf("bridge is not specified")
|
return fmt.Errorf("bridge is not specified")
|
||||||
|
@ -28,7 +29,7 @@ func (v *Veth) Create(n *Network, nspid int, networkState *NetworkState) error {
|
||||||
if prefix == "" {
|
if prefix == "" {
|
||||||
return fmt.Errorf("veth prefix is not specified")
|
return fmt.Errorf("veth prefix is not specified")
|
||||||
}
|
}
|
||||||
name1, name2, err := createVethPair(prefix)
|
name1, name2, err := createVethPair(prefix, txQueueLen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -96,7 +97,7 @@ func (v *Veth) Initialize(config *Network, networkState *NetworkState) error {
|
||||||
|
|
||||||
// createVethPair will automatically generage two random names for
|
// createVethPair will automatically generage two random names for
|
||||||
// the veth pair and ensure that they have been created
|
// the veth pair and ensure that they have been created
|
||||||
func createVethPair(prefix string) (name1 string, name2 string, err error) {
|
func createVethPair(prefix string, txQueueLen int) (name1 string, name2 string, err error) {
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
if name1, err = utils.GenerateRandomName(prefix, 7); err != nil {
|
if name1, err = utils.GenerateRandomName(prefix, 7); err != nil {
|
||||||
return
|
return
|
||||||
|
@ -106,7 +107,7 @@ func createVethPair(prefix string) (name1 string, name2 string, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CreateVethPair(name1, name2); err != nil {
|
if err = CreateVethPair(name1, name2, txQueueLen); err != nil {
|
||||||
if err == netlink.ErrInterfaceExists {
|
if err == netlink.ErrInterfaceExists {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ func TestGenerateVethNames(t *testing.T) {
|
||||||
|
|
||||||
prefix := "veth"
|
prefix := "veth"
|
||||||
|
|
||||||
name1, name2, err := createVethPair(prefix)
|
name1, name2, err := createVethPair(prefix, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,13 @@ func TestCreateDuplicateVethPair(t *testing.T) {
|
||||||
|
|
||||||
prefix := "veth"
|
prefix := "veth"
|
||||||
|
|
||||||
name1, name2, err := createVethPair(prefix)
|
name1, name2, err := createVethPair(prefix, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// retry to create the name interfaces and make sure that we get the correct error
|
// retry to create the name interfaces and make sure that we get the correct error
|
||||||
err = CreateVethPair(name1, name2)
|
err = CreateVethPair(name1, name2, 0)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("expected error to not be nil with duplicate interface")
|
t.Fatal("expected error to not be nil with duplicate interface")
|
||||||
}
|
}
|
||||||
|
|
24
vendor/src/github.com/docker/libcontainer/system/syscall_linux_386.go
vendored
Normal file
24
vendor/src/github.com/docker/libcontainer/system/syscall_linux_386.go
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// +build linux,386
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Setuid sets the uid of the calling thread to the specified uid.
|
||||||
|
func Setuid(uid int) (err error) {
|
||||||
|
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setgid sets the gid of the calling thread to the specified gid.
|
||||||
|
func Setgid(gid int) (err error) {
|
||||||
|
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
24
vendor/src/github.com/docker/libcontainer/system/syscall_linux_amd64.go
vendored
Normal file
24
vendor/src/github.com/docker/libcontainer/system/syscall_linux_amd64.go
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// +build linux,amd64
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Setuid sets the uid of the calling thread to the specified uid.
|
||||||
|
func Setuid(uid int) (err error) {
|
||||||
|
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setgid sets the gid of the calling thread to the specified gid.
|
||||||
|
func Setgid(gid int) (err error) {
|
||||||
|
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID, uintptr(gid), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
24
vendor/src/github.com/docker/libcontainer/system/syscall_linux_arm.go
vendored
Normal file
24
vendor/src/github.com/docker/libcontainer/system/syscall_linux_arm.go
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// +build linux,arm
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Setuid sets the uid of the calling thread to the specified uid.
|
||||||
|
func Setuid(uid int) (err error) {
|
||||||
|
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setgid sets the gid of the calling thread to the specified gid.
|
||||||
|
func Setgid(gid int) (err error) {
|
||||||
|
_, _, e1 := syscall.RawSyscall(syscall.SYS_SETGID32, uintptr(gid), 0, 0)
|
||||||
|
if e1 != 0 {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
15
vendor/src/github.com/docker/libcontainer/utils/utils_test.go
vendored
Normal file
15
vendor/src/github.com/docker/libcontainer/utils/utils_test.go
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestGenerateName(t *testing.T) {
|
||||||
|
name, err := GenerateRandomName("veth", 5)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := 5 + len("veth")
|
||||||
|
if len(name) != 5+len("veth") {
|
||||||
|
t.Fatalf("expected name to be %d chars but received %d", expected, len(name))
|
||||||
|
}
|
||||||
|
}
|
15
vendor/src/github.com/docker/libcontainer/xattr/xattr_unsupported.go
vendored
Normal file
15
vendor/src/github.com/docker/libcontainer/xattr/xattr_unsupported.go
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package xattr
|
||||||
|
|
||||||
|
func Listxattr(path string) ([]string, error) {
|
||||||
|
return nil, ErrNotSupportedPlatform
|
||||||
|
}
|
||||||
|
|
||||||
|
func Getxattr(path, attr string) (string, error) {
|
||||||
|
return "", ErrNotSupportedPlatform
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setxattr(path, xattr, value string) error {
|
||||||
|
return ErrNotSupportedPlatform
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue