Compare commits

..

6 Commits

Author SHA1 Message Date
Dimitri John Ledkov a6e81cff5f Change version tag
Signed-off-by: Dimitri John Ledkov <dimitri.j.ledkov@intel.com>
2015-09-18 14:15:07 +01:00
Dimitri John Ledkov 023d4ed189 Fix ups.
Signed-off-by: Dimitri John Ledkov <dimitri.j.ledkov@intel.com>
2015-09-17 18:26:29 +01:00
Dimitri John Ledkov d7c5f31c5b Properly find the right Endpoint to steal networking information from.
Signed-off-by: Dimitri John Ledkov <dimitri.j.ledkov@intel.com>
2015-09-17 18:26:20 +01:00
Dimitri John Ledkov e51462ac68 Merge branch 'release/1.8' of git://github.com/docker/docker into new-merge
Signed-off-by: Dimitri John Ledkov <dimitri.j.ledkov@intel.com>
2015-09-09 14:42:44 +01:00
Dimitri John Ledkov e45d0eb532 Clear Containers for Docker Engine execution driver
Signed-off-by: Dimitri John Ledkov <dimitri.j.ledkov@intel.com>
Signed-off-by: James Hunt <james.o.hunt@intel.com>
Signed-off-by: Michael Doherty <michael.i.doherty@intel.com>
2015-09-09 14:31:36 +01:00
Vincent Batts 6bf1c41b77 devicemapper: fix zero-sized field access
Fixes: #15279

Due to
https://github.com/golang/go/commit/7904946eeb35faece61bbf6f5b3cc8be2f519c17
the devices field is dropped.

This solution works on go1.4 and go1.5

Signed-off-by: Vincent Batts <vbatts@redhat.com>
2015-08-26 13:27:04 +01:00
56 changed files with 1190 additions and 488 deletions
-27
View File
@@ -1,32 +1,5 @@
# Changelog
## 1.8.2 (2015-09-03)
### Distribution:
- Fixes rare edge case of handling GNU LongLink and LongName entries.
- Avoid buffering to tempfile when pushing to registry V2.
- Fix ^C on docker pull.
- Fix docker pull issues on client disconnection.
- Fix issue that caused the daemon to panic when loggers weren't configured properly.
- Fix goroutine leak pulling images from registry V2.
### Runtime:
- Fix a bug mounting cgroups for docker daemons running inside docker containers.
- Initialize log configuration properly.
### Client:
- Handle `-q` flag in `docker ps` properly when there is a default format.
### Networking:
- Fix several corner cases with netlink.
### Contrib:
- Fix several issues with bash completion.
## 1.8.1 (2015-08-12)
### Distribution
+1 -1
View File
@@ -127,7 +127,7 @@ RUN git clone https://github.com/golang/lint.git /go/src/github.com/golang/lint
RUN gem install --no-rdoc --no-ri fpm --version 1.3.2
# Install registry
ENV REGISTRY_COMMIT ec87e9b6971d831f0eff752ddb54fb64693e51cd
ENV REGISTRY_COMMIT 2317f721a3d8428215a2b65da4ae85212ed473b4
RUN set -x \
&& export GOPATH="$(mktemp -d)" \
&& git clone https://github.com/docker/distribution.git "$GOPATH/src/github.com/docker/distribution" \
+1 -1
View File
@@ -1 +1 @@
1.8.2-rc1
1.8.1-clear-containers
+1 -1
View File
@@ -95,7 +95,7 @@ func (cli *DockerCli) CmdPs(args ...string) error {
f := *format
if len(f) == 0 {
if len(cli.PsFormat()) > 0 && !*quiet {
if len(cli.PsFormat()) > 0 {
f = cli.PsFormat()
} else {
f = "table"
@@ -2,7 +2,7 @@
# THIS FILE IS AUTOGENERATED; SEE "contrib/builder/deb/generate.sh"!
#
FROM ubuntu:precise
FROM ubuntu-debootstrap:precise
RUN apt-get update && apt-get install -y bash-completion build-essential curl ca-certificates debhelper git libapparmor-dev libsqlite3-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
@@ -2,7 +2,7 @@
# THIS FILE IS AUTOGENERATED; SEE "contrib/builder/deb/generate.sh"!
#
FROM ubuntu:wily
FROM ubuntu-debootstrap:trusty
RUN apt-get update && apt-get install -y bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
@@ -2,7 +2,7 @@
# THIS FILE IS AUTOGENERATED; SEE "contrib/builder/deb/generate.sh"!
#
FROM ubuntu:vivid
FROM ubuntu-debootstrap:vivid
RUN apt-get update && apt-get install -y bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
@@ -2,7 +2,7 @@
# THIS FILE IS AUTOGENERATED; SEE "contrib/builder/deb/generate.sh"!
#
FROM ubuntu:trusty
FROM ubuntu-debootstrap:wily
RUN apt-get update && apt-get install -y bash-completion btrfs-tools build-essential curl ca-certificates debhelper dh-systemd git libapparmor-dev libdevmapper-dev libsqlite3-dev --no-install-recommends && rm -rf /var/lib/apt/lists/*
+14 -73
View File
@@ -139,7 +139,7 @@ __docker_value_of_option() {
local counter=$((command_pos + 1))
while [ $counter -lt $cword ]; do
case ${words[$counter]} in
@($option_glob) )
$option_glob )
echo ${words[$counter + 1]}
break
;;
@@ -229,12 +229,11 @@ __docker_log_driver_options() {
# see docs/reference/logging/index.md
local fluentd_options="fluentd-address fluentd-tag"
local gelf_options="gelf-address gelf-tag"
local json_file_options="max-file max-size"
local syslog_options="syslog-address syslog-facility syslog-tag"
case $(__docker_value_of_option --log-driver) in
'')
COMPREPLY=( $( compgen -W "$fluentd_options $gelf_options $json_file_options $syslog_options" -S = -- "$cur" ) )
COMPREPLY=( $( compgen -W "$fluentd_options $gelf_options $syslog_options" -S = -- "$cur" ) )
;;
fluentd)
COMPREPLY=( $( compgen -W "$fluentd_options" -S = -- "$cur" ) )
@@ -242,9 +241,6 @@ __docker_log_driver_options() {
gelf)
COMPREPLY=( $( compgen -W "$gelf_options" -S = -- "$cur" ) )
;;
json-file)
COMPREPLY=( $( compgen -W "$json_file_options" -S = -- "$cur" ) )
;;
syslog)
COMPREPLY=( $( compgen -W "$syslog_options" -S = -- "$cur" ) )
;;
@@ -324,7 +320,7 @@ __docker_signals() {
_docker_docker() {
local boolean_options="
$global_boolean_options
--help
--help -h
--version -v
"
@@ -342,6 +338,8 @@ _docker_docker() {
;;
esac
__docker_complete_log_driver_options && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "$boolean_options $global_options_with_args" -- "$cur" ) )
@@ -462,7 +460,7 @@ _docker_create() {
_docker_daemon() {
local boolean_options="
$global_boolean_options
--help
--help -h
--icc=false
--ip-forward=false
--ip-masq=false
@@ -514,39 +512,7 @@ _docker_daemon() {
return
;;
--storage-driver|-s)
COMPREPLY=( $( compgen -W "aufs btrfs devicemapper overlay vfs zfs" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) )
return
;;
--storage-opt)
local devicemapper_options="
dm.basesize
dm.blkdiscard
dm.blocksize
dm.fs
dm.loopdatasize
dm.loopmetadatasize
dm.mkfsarg
dm.mountopt
dm.override_udev_sync_check
dm.thinpooldev
"
local zfs_options="zfs.fsname"
case $(__docker_value_of_option '--storage-driver|-s') in
'')
COMPREPLY=( $( compgen -W "$devicemapper_options $zfs_options" -S = -- "$cur" ) )
;;
devicemapper)
COMPREPLY=( $( compgen -W "$devicemapper_options" -S = -- "$cur" ) )
;;
zfs)
COMPREPLY=( $( compgen -W "$zfs_options" -S = -- "$cur" ) )
;;
*)
return
;;
esac
compopt -o nospace
COMPREPLY=( $( compgen -W "aufs devicemapper btrfs overlay" -- "$(echo $cur | tr '[:upper:]' '[:lower:]')" ) )
return
;;
--log-level|-l)
@@ -562,27 +528,6 @@ _docker_daemon() {
;;
esac
__docker_complete_log_driver_options && return
case "${words[$cword-2]}$prev=" in
*dm.blkdiscard=*)
COMPREPLY=( $( compgen -W "false true" -- "${cur#=}" ) )
return
;;
*dm.fs=*)
COMPREPLY=( $( compgen -W "ext4 xfs" -- "${cur#=}" ) )
return
;;
*dm.override_udev_sync_check=*)
COMPREPLY=( $( compgen -W "false true" -- "${cur#=}" ) )
return
;;
*dm.thinpooldev=*)
_filedir
return
;;
esac
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "$boolean_options $options_with_args" -- "$cur" ) )
@@ -924,7 +869,7 @@ _docker_ps() {
compopt -o nospace
return
;;
--format|-n)
-n)
return
;;
esac
@@ -948,7 +893,7 @@ _docker_ps() {
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--all -a --before --filter -f --format --help --latest -l -n --no-trunc --quiet -q --size -s --since" -- "$cur" ) )
COMPREPLY=( $( compgen -W "--all -a --before --filter -f --help --latest -l -n --no-trunc --quiet -q --size -s --since" -- "$cur" ) )
;;
esac
}
@@ -1053,16 +998,15 @@ _docker_rmi() {
_docker_run() {
local options_with_args="
--add-host
--attach -a
--blkio-weight
--attach -a
--cap-add
--cap-drop
--cgroup-parent
--cidfile
--cpuset
--cpu-period
--cpu-quota
--cpuset-cpus
--cpuset-mems
--cpu-shares -c
--device
--dns
@@ -1074,8 +1018,8 @@ _docker_run() {
--group-add
--hostname -h
--ipc
--label-file
--label -l
--label-file
--link
--log-driver
--log-opt
@@ -1083,15 +1027,14 @@ _docker_run() {
--mac-address
--memory -m
--memory-swap
--memory-swappiness
--name
--net
--pid
--publish -p
--restart
--security-opt
--ulimit
--user -u
--ulimit
--uts
--volumes-from
--volume -v
@@ -1099,10 +1042,8 @@ _docker_run() {
"
local all_options="$options_with_args
--disable-content-trust=false
--help
--interactive -i
--oom-kill-disable
--privileged
--publish-all -P
--read-only
@@ -1112,7 +1053,7 @@ _docker_run() {
[ "$command" = "run" ] && all_options="$all_options
--detach -d
--rm
--sig-proxy=false
--sig-proxy
"
local options_with_args_glob=$(__docker_to_extglob "$options_with_args")
+1 -1
View File
@@ -11,7 +11,7 @@ import (
var (
defaultPidFile = "/var/run/docker.pid"
defaultGraph = "/var/lib/docker"
defaultExec = "native"
defaultExec = "clr"
)
// Config defines the configuration of a docker daemon.
+1 -1
View File
@@ -979,7 +979,7 @@ func getDefaultRouteMtu() (int, error) {
return 0, err
}
for _, r := range routes {
if r.Default && r.Iface != nil {
if r.Default {
return r.Iface.MTU, nil
}
}
+721
View File
@@ -0,0 +1,721 @@
// +build linux
package clr
import (
"fmt"
"io"
"io/ioutil"
"math"
"net/http"
"os"
"os/exec"
"net"
"path"
"strconv"
"strings"
"sync"
"syscall"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/pkg/mount"
sysinfo "github.com/docker/docker/pkg/system"
"github.com/docker/docker/pkg/term"
"github.com/docker/libnetwork/netlabel"
"github.com/kr/pty"
"github.com/opencontainers/runc/libcontainer/configs"
)
const (
// Clear Linux for Intel(R) Architecture
driverName = "clr"
envVarPrefix = "CLR_"
// Command used for lkvm control
lkvmName = "lkvm"
// local "latest" information
clrFile = "latest"
// upstream base URL
clrURL = "https://download.clearlinux.org"
// upstream latest release file
latestFile = "https://download.clearlinux.org/latest"
// clr kernel (not bzimage)
clrKernel = "/usr/lib/kernel/vmlinux.container"
)
type driver struct {
root string // root path for the driver to use
libPath string
initPath string
version string
apparmor bool
sharedRoot bool
activeContainers map[string]*activeContainer
machineMemory int64
containerPid int
sync.Mutex
}
type activeContainer struct {
container *configs.Config
cmd *exec.Cmd
}
func getTapIf(c *execdriver.Command) string {
return fmt.Sprintf("tb-%s", c.ID[:12])
}
func getClrVersion(libPath string) string {
txt, err := ioutil.ReadFile(path.Join(libPath, clrFile))
if err != nil {
return ""
}
return strings.Split(string(txt), "\n")[0]
}
func fetchLatest(libPath string) error {
out, err := os.Create(path.Join(libPath, clrFile))
if err != nil {
return err
}
defer out.Close()
resp, err := http.Get(latestFile)
if err != nil {
return err
}
defer resp.Body.Close()
_, err = io.Copy(out, resp.Body)
return err
}
func fetchImage(version, libPath string) error {
// TODO: Add checksum validation
outfile := fmt.Sprintf("clear-%s-containers.img.xz", version)
url := fmt.Sprintf("%s/releases/%s/clear/%s", clrURL, version, outfile)
outpath := path.Join(libPath, outfile)
var output []byte
logrus.Debugf("Fetching clr version: %s, %s", version, outpath)
out, err := os.Create(outpath)
if err != nil {
return err
}
defer out.Close()
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Consider progress feedback ?
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
// decompress the file
cmd := exec.Command("unxz", outpath)
cmd.Dir = libPath
if output, err = cmd.CombinedOutput(); err != nil {
logrus.Debugf("Unable to extract image %s: %s", version, output)
return err
}
return nil
}
// NewDriver creates a new clear linux execution driver.
func NewDriver(root, libPath, initPath string, apparmor bool) (*driver, error) {
if err := os.MkdirAll(root, 0700); err != nil {
return nil, err
}
meminfo, err := sysinfo.ReadMemInfo()
if err != nil {
return nil, err
}
version, err := prepareClr(libPath)
if err != nil {
return nil, err
}
return &driver{
apparmor: apparmor,
root: root,
libPath: libPath,
initPath: initPath,
version: version,
sharedRoot: false,
activeContainers: make(map[string]*activeContainer),
// FIXME:
machineMemory: meminfo.MemTotal,
}, nil
}
func prepareClr(libPath string) (string, error) {
var version = getClrVersion(libPath)
var nversion string
logrus.Debugf("%s preparing environment", driverName)
err := fetchLatest(libPath)
if err != nil {
return "", err
}
nversion = getClrVersion(libPath)
if nversion != version && version != "" {
logrus.Debugf("Updating to clr version: %s", nversion)
err = fetchImage(nversion, libPath)
} else if version == "" {
logrus.Debugf("Installing clr version: %s", nversion)
err = fetchImage(nversion, libPath)
} else {
logrus.Debugf("Using clr version: %s", nversion)
}
return nversion, nil
}
func (d *driver) Name() string {
return fmt.Sprintf("%s-%s", driverName, d.version)
}
func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (execdriver.ExitStatus, error) {
var (
term execdriver.Terminal
err error
)
container, err := d.createContainer(c)
if err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
memoryMiB := c.HostConfig.Memory
if memoryMiB == 0 {
memoryMiB = 1024
} else {
// docker passes the value as bytes
memoryMiB = memoryMiB / int64(math.Pow(2, 20))
}
workingDirVar := fmt.Sprintf("%s%s=%q", envVarPrefix, "WORKINGDIR", c.WorkingDir)
c.ProcessConfig.Cmd.Env = append(c.ProcessConfig.Cmd.Env, workingDirVar)
userVar := fmt.Sprintf("%s%s=%q", envVarPrefix, "USER", c.ProcessConfig.User)
c.ProcessConfig.Cmd.Env = append(c.ProcessConfig.Cmd.Env, userVar)
if err := d.setupNetwork(c); err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
if c.ProcessConfig.Tty {
term, err = NewTtyConsole(&c.ProcessConfig, pipes)
} else {
term, err = execdriver.NewStdConsole(&c.ProcessConfig, pipes)
}
if err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
c.ProcessConfig.Terminal = term
d.Lock()
d.activeContainers[c.ID] = &activeContainer{
container: container,
cmd: &c.ProcessConfig.Cmd,
}
d.Unlock()
if err := d.generateEnvConfig(c); err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
if err := d.generateDockerInit(c); err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
for _, m := range c.Mounts {
dest := path.Join(c.Rootfs, m.Destination)
if m.Destination == "/etc/hostname" {
continue
}
if !pathExists(m.Source) {
continue
}
opts := "bind"
if m.Private {
opts = opts + ",rprivate"
}
if m.Slave {
opts = opts + ",rslave"
}
// This may look racy, but it isn't since the VM isn't
// running yet.
//
// The check is necessary to handle bind mounting of
// regular files correctly since without it we may be
// attempting to create a directory where there already
// exists a normal file.
if !pathExists(dest) {
if err := os.MkdirAll(dest, 0750); err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
}
if err := mount.Mount(m.Source, dest, "", opts); err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
if !m.Writable {
if err := mount.Mount("", dest, "", "bind,remount,ro"); err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
}
defer mount.Unmount(dest)
}
var args []string
// various things for lkvm
ifname := getTapIf(c)
// FIXME: Should be real hostname from like process/container struct
hostname := c.ID[0:12]
img := fmt.Sprintf("%s/clear-%s-containers.img", d.libPath, d.version)
memory := fmt.Sprintf("%d", memoryMiB)
// FIXME: Locked cores to 6 ?
cores := fmt.Sprintf("%d", 6)
ipaddr := c.NetworkSettings.IPAddress
gateway := c.NetworkSettings.Gateway
macaddr := c.NetworkSettings.MacAddress
args = append(args, c.ProcessConfig.Entrypoint)
args = append(args, c.ProcessConfig.Arguments...)
rootParams := fmt.Sprintf("root=/dev/plkvm0p1 rootfstype=ext4 rootflags=dax,data=ordered "+
"init=/usr/lib/systemd/systemd systemd.unit=container.target rw tsc=reliable "+
"systemd.show_status=false "+
"no_timer_check rcupdate.rcu_expedited=1 console=hvc0 quiet ip=%s::%s::%s::off",
ipaddr, gateway, hostname)
params := []string{
lkvmName, "run", "-c", cores, "-m", memory,
"--name", c.ID, "--console", "virtio",
"--kernel", clrKernel,
"--params", rootParams,
"--shmem", fmt.Sprintf("0x200000000:0:file=%s:private", img),
"--network", fmt.Sprintf("mode=tap,script=none,tapif=%s,guest_mac=%s", ifname, macaddr),
"--9p", fmt.Sprintf("%s,rootfs", c.Rootfs),
}
logrus.Debugf("%s params %s", driverName, params)
var (
name = params[0]
arg = params[1:]
)
aname, err := exec.LookPath(name)
if err != nil {
aname = name
}
c.ProcessConfig.Path = aname
c.ProcessConfig.Args = append([]string{name}, arg...)
c.ProcessConfig.Env = []string{fmt.Sprintf("HOME=%s", d.root)}
// Start the container. Since it runs synchronously, we don't Wait()
// for it since we need to check the status to determine if it did
// actually start successfully.
if err := c.ProcessConfig.Start(); err != nil {
return execdriver.ExitStatus{ExitCode: -1}, err
}
var (
waitErr error
waitLock = make(chan struct{})
)
go func() {
if err := c.ProcessConfig.Wait(); err != nil {
if _, ok := err.(*exec.ExitError); !ok { // Do not propagate the error if it's simply a status code != 0
waitErr = err
}
}
close(waitLock)
}()
// FIXME: need to create state.json for Stats() to work.
c.ContainerPid = c.ProcessConfig.Process.Pid
d.containerPid = c.ProcessConfig.Process.Pid
if startCallback != nil {
logrus.Debugf("Invoking startCallback")
startCallback(&c.ProcessConfig, c.ProcessConfig.Process.Pid)
}
// FIXME:
oomKill := false
// Wait for the VM to shutdown
<-waitLock
exitCode := getExitCode(c)
cExitStatus, cerr := d.cleanupVM(c)
if cerr != nil {
waitErr = cerr
exitCode = cExitStatus
}
// check oom error
if oomKill {
exitCode = 137
}
return execdriver.ExitStatus{ExitCode: exitCode, OOMKilled: false}, waitErr
}
func pathExists(path string) bool {
if _, err := os.Stat(path); err == nil {
return true
}
return false
}
func pathExecutable(path string) bool {
s, err := os.Stat(path)
if err != nil {
return false
}
mode := s.Mode()
if mode&0111 != 0 {
return true
}
return false
}
func (d *driver) cleanupVM(c *execdriver.Command) (exitStatus int, err error) {
cmd := exec.Command("ip", "tuntap", "del", "dev", getTapIf(c), "mode", "tap")
var output []byte
if output, err = cmd.CombinedOutput(); err != nil {
if exitError, ok := err.(*exec.ExitError); ok {
waitStatus := exitError.Sys().(syscall.WaitStatus)
exitStatus = waitStatus.ExitStatus()
}
logrus.Debugf("teardown failed for vm %s: %s (%s)", c.ID, string(output), err.Error())
}
// doesn't matter if this fails
// lkvm could have removed it, and stale sockets are not fatal
_ = os.Remove(fmt.Sprintf("%s/.lkvm/%s.sock", d.root, c.ID))
return exitStatus, err
}
// createContainer populates and configures the container type with the
// data provided by the execdriver.Command
func (d *driver) createContainer(c *execdriver.Command) (*configs.Config, error) {
return execdriver.InitContainer(c), nil
}
/// Return the exit code of the process
// if the process has not exited -1 will be returned
func getExitCode(c *execdriver.Command) int {
if c.ProcessConfig.ProcessState == nil {
return -1
}
return c.ProcessConfig.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
}
func (d *driver) lkvmCommand(c *execdriver.Command, arg string) ([]byte, error) {
args := append([]string{lkvmName}, arg)
if c != nil {
args = append(args, "--name", c.ID)
}
cmd := exec.Command(lkvmName, args...)
cmd.Env = []string{fmt.Sprintf("HOME=%s", d.root)}
return cmd.Output()
}
// Kill sends a signal to workload
func (d *driver) Kill(c *execdriver.Command, sig int) error {
// Not supported
return nil
}
func (d *driver) Pause(c *execdriver.Command) error {
_, err := d.lkvmCommand(c, "pause")
return err
}
func (d *driver) Unpause(c *execdriver.Command) error {
_, err := d.lkvmCommand(c, "resume")
return err
}
// Terminate forcibly stops a container
func (d *driver) Terminate(c *execdriver.Command) error {
_, err := d.lkvmCommand(c, "stop")
return err
}
func (d *driver) containerDir(containerID string) string {
return path.Join(d.libPath, "containers", containerID)
}
// isDigit returns true if s can be represented as an integer
func isDigit(s string) bool {
if _, err := strconv.Atoi(s); err == nil {
return true
}
return false
}
func (d *driver) getInfo(id string) ([]byte, error) {
output, err := d.lkvmCommand(nil, "list")
if err != nil {
return nil, err
}
for i, line := range strings.Split(string(output), "\n") {
if i < 2 {
continue
}
fields := strings.Fields(strings.TrimSpace(line))
if len(fields) != 3 {
continue
}
if !isDigit(fields[0]) {
continue
}
if fields[1] != id {
continue
}
return []byte(line), nil
}
return []byte(fmt.Sprintf("-1 %s stopped", id)), nil
}
type info struct {
ID string
driver *driver
}
func (i *info) IsRunning() bool {
output, err := i.driver.getInfo(i.ID)
if err != nil {
logrus.Errorf("Error getting info for %s container %s: %s (%s)",
driverName, i.ID, err, output)
return false
}
clrInfo, err := parseClrInfo(i.ID, string(output))
if err != nil {
return false
}
return clrInfo.Running
}
func (d *driver) Info(id string) execdriver.Info {
return &info{
ID: id,
driver: d,
}
}
func (d *driver) GetPidsForContainer(id string) ([]int, error) {
// The VM doesn't expose the worload pid(s), so the only meaningful
// pid is that of the VM
return []int{d.containerPid}, nil
}
// TtyConsole is a type to represent a pseud-oterminal (see pty(7))
type TtyConsole struct {
MasterPty *os.File
SlavePty *os.File
}
// NewTtyConsole returns a new TtyConsole object.
func NewTtyConsole(processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes) (*TtyConsole, error) {
// lxc is special in that we cannot create the master outside of the container without
// opening the slave because we have nothing to provide to the cmd. We have to open both then do
// the crazy setup on command right now instead of passing the console path to lxc and telling it
// to open up that console. we save a couple of openfiles in the native driver because we can do
// this.
ptyMaster, ptySlave, err := pty.Open()
if err != nil {
return nil, err
}
tty := &TtyConsole{
MasterPty: ptyMaster,
SlavePty: ptySlave,
}
if err := tty.AttachPipes(&processConfig.Cmd, pipes); err != nil {
tty.Close()
return nil, err
}
processConfig.Console = tty.SlavePty.Name()
return tty, nil
}
// Master returns the master end of the pty
func (t *TtyConsole) Master() *os.File {
return t.MasterPty
}
// Resize modifies the size of the pty terminal being used.
func (t *TtyConsole) Resize(h, w int) error {
return term.SetWinsize(t.MasterPty.Fd(), &term.Winsize{Height: uint16(h), Width: uint16(w)})
}
// AttachPipes associates the specified pipes with the pty master.
func (t *TtyConsole) AttachPipes(command *exec.Cmd, pipes *execdriver.Pipes) error {
command.Stdout = t.SlavePty
command.Stderr = t.SlavePty
go func() {
if wb, ok := pipes.Stdout.(interface {
CloseWriters() error
}); ok {
defer wb.CloseWriters()
}
io.Copy(pipes.Stdout, t.MasterPty)
}()
if pipes.Stdin != nil {
command.Stdin = t.SlavePty
command.SysProcAttr.Setctty = true
go func() {
io.Copy(t.MasterPty, pipes.Stdin)
pipes.Stdin.Close()
}()
}
return nil
}
// Close closes both ends of the pty.
func (t *TtyConsole) Close() error {
t.SlavePty.Close()
return t.MasterPty.Close()
}
func (d *driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
return -1, fmt.Errorf("Unsupported: Exec is not supported by the %q driver", driverName)
}
// Clean up after an Exec
func (d *driver) Clean(id string) error {
return nil
}
func (d *driver) generateEnvConfig(c *execdriver.Command) error {
data := []byte(strings.Join(c.ProcessConfig.Env, "\n"))
p := path.Join(d.libPath, "containers", c.ID, "config.env")
c.Mounts = append(c.Mounts, execdriver.Mount{
Source: p,
Destination: "/.dockerenv",
Writable: false,
Private: true,
})
return ioutil.WriteFile(p, data, 0600)
}
func (d *driver) generateDockerInit(c *execdriver.Command) error {
p := fmt.Sprintf("%s/.containerexec", c.Rootfs)
var args []string
if pathExecutable(p) {
return nil
}
args = append(args, c.ProcessConfig.Entrypoint)
args = append(args, c.ProcessConfig.Arguments...)
data := []byte(fmt.Sprintf("#!/bin/sh\n%s\n", strings.Join(args, " ")))
return ioutil.WriteFile(p, data, 0755)
}
func (d *driver) setupNetwork(c *execdriver.Command) error {
ifname := getTapIf(c)
var bridgeName string
var bridgeLinkName string
var output []byte
var err error
for _, info := range c.EndpointInfo {
if mac, ok := info[netlabel.MacAddress].(net.HardwareAddr); ok {
if mac.String() == c.NetworkSettings.MacAddress {
bridgeName = info[netlabel.BridgeName].(string)
bridgeLinkName = info[netlabel.BridgeLinkName].(string)
}
}
}
// Strip existing veth
cmd := exec.Command("ip", "link", "del", bridgeLinkName)
if output, err = cmd.CombinedOutput(); err != nil {
logrus.Debugf("%s setupNetwork error: %v, %s", driverName, cmd.Args, output)
return err
}
cmd = exec.Command("ip", "tuntap", "add", "dev", ifname, "mode", "tap", "vnet_hdr")
if output, err = cmd.CombinedOutput(); err != nil {
logrus.Debugf("%s setupNetwork error: %v, %s", driverName, cmd.Args, output)
return err
}
cmd = exec.Command("ip", "link", "set", "dev", ifname, "master", bridgeName)
if output, err = cmd.CombinedOutput(); err != nil {
logrus.Debugf("%s setupNetwork error: %v, %s", driverName, cmd.Args, output)
return err
}
cmd = exec.Command("ip", "link", "set", "dev", ifname, "up")
if output, err = cmd.CombinedOutput(); err != nil {
logrus.Debugf("%s setupNetwork error: %v, %s", driverName, cmd.Args, output)
return err
}
return err
}
func (d *driver) Stats(id string) (*execdriver.ResourceStats, error) {
if _, ok := d.activeContainers[id]; !ok {
return nil, fmt.Errorf("%s is not a key in active containers", id)
}
// FIXME:
return execdriver.Stats(d.containerDir(id), d.activeContainers[id].container.Cgroups.Memory, d.machineMemory)
}
+51
View File
@@ -0,0 +1,51 @@
// +build linux
package clr
import (
"errors"
"strconv"
"strings"
)
var (
ErrCannotParse = errors.New("cannot parse raw input")
)
type clrInfo struct {
Running bool
Pid int
}
func parseClrInfo(name, raw string) (*clrInfo, error) {
if raw == "" {
return nil, ErrCannotParse
}
var (
err error
info = &clrInfo{}
)
fields := strings.Fields(strings.TrimSpace(raw))
// The format is expected to be:
//
// <pid> <name> <state>
//
if len(fields) != 3 {
return nil, ErrCannotParse
}
info.Pid, err = strconv.Atoi(fields[0])
if err != nil {
return nil, ErrCannotParse
}
if fields[1] != name {
return nil, ErrCannotParse
}
info.Running = fields[2] == "running"
return info, nil
}
+97
View File
@@ -0,0 +1,97 @@
// +build linux
package clr
import (
"encoding/json"
"flag"
"fmt"
"os"
"strings"
"syscall"
)
// Args provided to the init function for a driver
type InitArgs struct {
User string
Gateway string
Ip string
WorkDir string
Privileged bool
Env []string
Args []string
Mtu int
Console string
Pipe int
Root string
CapAdd string
CapDrop string
}
func getArgs() *InitArgs {
var (
// Get cmdline arguments
user = flag.String("u", "", "username or uid")
gateway = flag.String("g", "", "gateway address")
ip = flag.String("i", "", "ip address")
workDir = flag.String("w", "", "workdir")
privileged = flag.Bool("privileged", false, "privileged mode")
mtu = flag.Int("mtu", 1500, "interface mtu")
capAdd = flag.String("cap-add", "", "capabilities to add")
capDrop = flag.String("cap-drop", "", "capabilities to drop")
)
flag.Parse()
return &InitArgs{
User: *user,
Gateway: *gateway,
Ip: *ip,
WorkDir: *workDir,
Privileged: *privileged,
Args: flag.Args(),
Mtu: *mtu,
CapAdd: *capAdd,
CapDrop: *capDrop,
}
}
// Clear environment pollution introduced by lxc-start
func setupEnv(args *InitArgs) error {
// Get env
var env []string
dockerenv, err := os.Open(".dockerenv")
if err != nil {
return fmt.Errorf("Unable to load environment variables: %v", err)
}
defer dockerenv.Close()
if err := json.NewDecoder(dockerenv).Decode(&env); err != nil {
return fmt.Errorf("Unable to decode environment variables: %v", err)
}
// Propagate the plugin-specific container env variable
env = append(env, "container="+os.Getenv("container"))
args.Env = env
os.Clearenv()
for _, kv := range args.Env {
parts := strings.SplitN(kv, "=", 2)
if len(parts) == 1 {
parts = append(parts, "")
}
os.Setenv(parts[0], parts[1])
}
return nil
}
// Setup working directory
func setupWorkingDirectory(args *InitArgs) error {
if args.WorkDir == "" {
return nil
}
if err := syscall.Chdir(args.WorkDir); err != nil {
return fmt.Errorf("Unable to change dir to %v: %v", args.WorkDir, err)
}
return nil
}
+32 -27
View File
@@ -7,7 +7,9 @@ import (
"time"
// TODO Windows: Factor out ulimit
"github.com/docker/docker/daemon/network"
"github.com/docker/docker/pkg/ulimit"
"github.com/docker/docker/runconfig"
"github.com/opencontainers/runc/libcontainer"
"github.com/opencontainers/runc/libcontainer/configs"
)
@@ -150,31 +152,34 @@ type ProcessConfig struct {
//
// Process wrapps an os/exec.Cmd to add more metadata
type Command struct {
ID string `json:"id"`
Rootfs string `json:"rootfs"` // root fs of the container
ReadonlyRootfs bool `json:"readonly_rootfs"`
InitPath string `json:"initpath"` // dockerinit
WorkingDir string `json:"working_dir"`
ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver
Network *Network `json:"network"`
Ipc *Ipc `json:"ipc"`
Pid *Pid `json:"pid"`
UTS *UTS `json:"uts"`
Resources *Resources `json:"resources"`
Mounts []Mount `json:"mounts"`
AllowedDevices []*configs.Device `json:"allowed_devices"`
AutoCreatedDevices []*configs.Device `json:"autocreated_devices"`
CapAdd []string `json:"cap_add"`
CapDrop []string `json:"cap_drop"`
GroupAdd []string `json:"group_add"`
ContainerPid int `json:"container_pid"` // the pid for the process inside a container
ProcessConfig ProcessConfig `json:"process_config"` // Describes the init process of the container.
ProcessLabel string `json:"process_label"`
MountLabel string `json:"mount_label"`
LxcConfig []string `json:"lxc_config"`
AppArmorProfile string `json:"apparmor_profile"`
CgroupParent string `json:"cgroup_parent"` // The parent cgroup for this command.
FirstStart bool `json:"first_start"`
LayerPaths []string `json:"layer_paths"` // Windows needs to know the layer paths and folder for a command
LayerFolder string `json:"layer_folder"`
ID string `json:"id"`
Rootfs string `json:"rootfs"` // root fs of the container
ReadonlyRootfs bool `json:"readonly_rootfs"`
InitPath string `json:"initpath"` // dockerinit
WorkingDir string `json:"working_dir"`
ConfigPath string `json:"config_path"` // this should be able to be removed when the lxc template is moved into the driver
Network *Network `json:"network"`
Ipc *Ipc `json:"ipc"`
Pid *Pid `json:"pid"`
UTS *UTS `json:"uts"`
Resources *Resources `json:"resources"`
Mounts []Mount `json:"mounts"`
AllowedDevices []*configs.Device `json:"allowed_devices"`
AutoCreatedDevices []*configs.Device `json:"autocreated_devices"`
CapAdd []string `json:"cap_add"`
CapDrop []string `json:"cap_drop"`
GroupAdd []string `json:"group_add"`
ContainerPid int `json:"container_pid"` // the pid for the process inside a container
ProcessConfig ProcessConfig `json:"process_config"` // Describes the init process of the container.
ProcessLabel string `json:"process_label"`
MountLabel string `json:"mount_label"`
LxcConfig []string `json:"lxc_config"`
AppArmorProfile string `json:"apparmor_profile"`
CgroupParent string `json:"cgroup_parent"` // The parent cgroup for this command.
FirstStart bool `json:"first_start"`
LayerPaths []string `json:"layer_paths"` // Windows needs to know the layer paths and folder for a command
LayerFolder string `json:"layer_folder"`
NetworkSettings *network.Settings `json:"network_settings"`
EndpointInfo []map[string]interface{} `json:"endpoint_info"`
HostConfig *runconfig.HostConfig
}
@@ -8,13 +8,17 @@ import (
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/daemon/execdriver/clr"
"github.com/docker/docker/daemon/execdriver/lxc"
"github.com/docker/docker/daemon/execdriver/native"
"github.com/docker/docker/pkg/sysinfo"
)
func NewDriver(name string, options []string, root, libPath, initPath string, sysInfo *sysinfo.SysInfo) (execdriver.Driver, error) {
rootPath := path.Join(root, "execdriver", name)
switch name {
case "clr":
return clr.NewDriver(rootPath, libPath, initPath, sysInfo.AppArmor)
case "lxc":
// we want to give the lxc driver the full docker root because it needs
// to access and write config and template files in /var/lib/docker/containers/*
@@ -22,7 +26,7 @@ func NewDriver(name string, options []string, root, libPath, initPath string, sy
logrus.Warn("LXC built-in support is deprecated.")
return lxc.NewDriver(root, libPath, initPath, sysInfo.AppArmor)
case "native":
return native.NewDriver(path.Join(root, "execdriver", "native"), initPath, options)
return native.NewDriver(rootPath, initPath, options)
}
return nil, fmt.Errorf("unknown exec driver %s", name)
}
+9 -5
View File
@@ -1482,12 +1482,16 @@ func (devices *DeviceSet) deactivatePool() error {
if err != nil {
return err
}
if d, err := devicemapper.GetDeps(devname); err == nil {
// Access to more Debug output
logrus.Debugf("[devmapper] devicemapper.GetDeps() %s: %#v", devname, d)
if devinfo.Exists == 0 {
return nil
}
if devinfo.Exists != 0 {
return devicemapper.RemoveDevice(devname)
if err := devicemapper.RemoveDevice(devname); err != nil {
return err
}
if d, err := devicemapper.GetDeps(devname); err == nil {
logrus.Warnf("[devmapper] device %s still has %d active dependents", devname, d.Count)
}
return nil
+24
View File
@@ -138,6 +138,30 @@ func (m *containerMonitor) Start() error {
m.lastStartTime = time.Now()
// Make the network settings available to the execution
// driver to allow for integration with libnetwork networking.
m.container.command.NetworkSettings = m.container.NetworkSettings
// Allow the execution driver to query memory limits
m.container.command.HostConfig = m.container.hostConfig
// Make the network endpoint details available to the execution
// driver as well.
n, _err := m.container.daemon.netController.NetworkByID(m.container.NetworkSettings.NetworkID)
if _err == nil {
var eps []map[string]interface{}
for _, ep := range n.Endpoints() {
info, err := ep.DriverInfo()
if err != nil {
continue
}
eps = append(eps, info)
}
m.container.command.EndpointInfo = eps
}
if exitStatus, err = m.container.daemon.Run(m.container, pipes, m.callback); err != nil {
// if we receive an internal error from the initial start of a container then lets
// return it instead of entering the restart loop
+4 -1
View File
@@ -76,7 +76,6 @@ func NewDaemonCli() *DaemonCli {
// TODO(tiborvass): remove InstallFlags?
daemonConfig := new(daemon.Config)
daemonConfig.LogConfig.Config = make(map[string]string)
daemonConfig.InstallFlags(daemonFlags, presentInHelp)
daemonConfig.InstallFlags(flag.CommandLine, absentFromHelp)
registryOptions := new(registry.Options)
@@ -209,6 +208,10 @@ func (cli *DaemonCli) CmdDaemon(args ...string) error {
}()
}
if cli.LogConfig.Config == nil {
cli.LogConfig.Config = make(map[string]string)
}
serverConfig := &apiserver.ServerConfig{
Logging: true,
EnableCors: cli.EnableCors,
+1 -1
View File
@@ -28,7 +28,7 @@ func main() {
flag.Merge(flag.CommandLine, clientFlags.FlagSet, commonFlags.FlagSet)
flag.Usage = func() {
fmt.Fprint(os.Stdout, "Usage: docker [OPTIONS] COMMAND [arg...]\n"+daemonUsage+" docker [ --help | -v | --version ]\n\n")
fmt.Fprint(os.Stdout, "Usage: docker [OPTIONS] COMMAND [arg...]\n"+daemonUsage+" docker [ -h | --help | -v | --version ]\n\n")
fmt.Fprint(os.Stdout, "A self-sufficient runtime for containers.\n\nOptions:\n")
flag.CommandLine.SetOutput(os.Stdout)
+1 -1
View File
@@ -16,7 +16,7 @@ or execute `docker help`:
$ docker
Usage: docker [OPTIONS] COMMAND [arg...]
docker daemon [ --help | ... ]
docker [ --help | -v | --version ]
docker [ -h | --help | -v | --version ]
-H, --host=[]: The socket(s) to bind to in daemon mode, specified using one or more tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd.
+1 -1
View File
@@ -32,7 +32,7 @@ parent = "smn_cli"
-G, --group="docker" Group for the unix socket
-g, --graph="/var/lib/docker" Root of the Docker runtime
-H, --host=[] Daemon socket(s) to connect to
--help=false Print usage
-h, --help=false Print usage
--icc=true Enable inter-container communication
--insecure-registry=[] Enable insecure registry communication
--ip=0.0.0.0 Default IP when binding container ports
+8 -13
View File
@@ -74,21 +74,16 @@ The output will provide details on the container configurations including the
volumes. The output should look something similar to the following:
...
Mounts": [
{
"Name": "fac362...80535",
"Source": "/var/lib/docker/volumes/fac362...80535/_data",
"Destination": "/webapp",
"Driver": "local",
"Mode": "",
"RW": true
}
]
"Volumes": {
"/webapp": "/var/lib/docker/volumes/fac362...80535"
},
"VolumesRW": {
"/webapp": true
}
...
You will notice in the above 'Source' is specifying the location on the host and
'Destination' is specifying the volume location inside the container. `RW` shows
if the volume is read/write.
You will notice in the above 'Volumes' is specifying the location on the host and
'VolumesRW' is specifying that the volume is read/write.
### Mount a host directory as a data volume
+4 -10
View File
@@ -77,7 +77,7 @@ func (p *v2Puller) pullV2Repository(tag string) (err error) {
if err != nil {
if c != nil {
// Another pull of the same repository is already taking place; just wait for it to finish
p.config.OutStream.Write(p.sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", p.repoInfo.CanonicalName))
p.sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", p.repoInfo.CanonicalName)
<-c
return nil
}
@@ -140,9 +140,9 @@ func (p *v2Puller) download(di *downloadInfo) {
return
}
blobs := p.repo.Blobs(context.Background())
blobs := p.repo.Blobs(nil)
desc, err := blobs.Stat(context.Background(), di.digest)
desc, err := blobs.Stat(nil, di.digest)
if err != nil {
logrus.Debugf("Error statting layer: %v", err)
di.err <- err
@@ -150,7 +150,7 @@ func (p *v2Puller) download(di *downloadInfo) {
}
di.size = desc.Size
layerDownload, err := blobs.Open(context.Background(), di.digest)
layerDownload, err := blobs.Open(nil, di.digest)
if err != nil {
logrus.Debugf("Error fetching layer: %v", err)
di.err <- err
@@ -223,9 +223,6 @@ func (p *v2Puller) pullV2Tag(tag, taggedName string) (verified bool, err error)
go func() {
if _, err := io.Copy(out, pipeReader); err != nil {
logrus.Errorf("error copying from layer download progress reader: %s", err)
if err := pipeReader.CloseWithError(err); err != nil {
logrus.Errorf("error closing the progress reader: %s", err)
}
}
}()
defer func() {
@@ -235,9 +232,6 @@ func (p *v2Puller) pullV2Tag(tag, taggedName string) (verified bool, err error)
// set the error. All successive reads/writes will return with this
// error.
pipeWriter.CloseWithError(errors.New("download canceled"))
} else {
// If no error then just close the pipe.
pipeWriter.Close()
}
}()
+4 -4
View File
@@ -138,7 +138,7 @@ func (p *v2Pusher) pushV2Tag(tag string) error {
dgst, err := p.graph.GetDigest(layer.ID)
switch err {
case nil:
_, err := p.repo.Blobs(context.Background()).Stat(context.Background(), dgst)
_, err := p.repo.Blobs(nil).Stat(nil, dgst)
switch err {
case nil:
exists = true
@@ -158,7 +158,7 @@ func (p *v2Pusher) pushV2Tag(tag string) error {
// if digest was empty or not saved, or if blob does not exist on the remote repository,
// then fetch it.
if !exists {
if pushDigest, err := p.pushV2Image(p.repo.Blobs(context.Background()), layer); err != nil {
if pushDigest, err := p.pushV2Image(p.repo.Blobs(nil), layer); err != nil {
return err
} else if pushDigest != dgst {
// Cache new checksum
@@ -226,7 +226,7 @@ func (p *v2Pusher) pushV2Image(bs distribution.BlobService, img *image.Image) (d
// Send the layer
logrus.Debugf("rendered layer for %s of [%d] size", img.ID, size)
layerUpload, err := bs.Create(context.Background())
layerUpload, err := bs.Create(nil)
if err != nil {
return "", err
}
@@ -250,7 +250,7 @@ func (p *v2Pusher) pushV2Image(bs distribution.BlobService, img *image.Image) (d
}
desc := distribution.Descriptor{Digest: dgst}
if _, err := layerUpload.Commit(context.Background(), desc); err != nil {
if _, err := layerUpload.Commit(nil, desc); err != nil {
return "", err
}
+3 -83
View File
@@ -20,70 +20,21 @@ APTDIR=$DOCKER_RELEASE_DIR/apt/repo
# setup the apt repo (if it does not exist)
mkdir -p "$APTDIR/conf" "$APTDIR/db"
# supported arches/sections
arches=( amd64 i386 )
components=( main testing experimental )
# create/update distributions file
if [ ! -f "$APTDIR/conf/distributions" ]; then
if [[ ! -f "$APTDIR/conf/distributions" ]]; then
for suite in $(exec contrib/reprepro/suites.sh); do
cat <<-EOF
Origin: Docker
Suite: $suite
Codename: $suite
Architectures: ${arches[*]}
Components: ${components[*]}
Architectures: amd64 i386
Components: main testing experimental
Description: Docker APT Repository
EOF
done > "$APTDIR/conf/distributions"
fi
# create/update distributions file
if [ ! -f "$APTDIR/conf/apt-ftparchive.conf" ]; then
cat <<-EOF > "$APTDIR/conf/apt-ftparchive.conf"
Dir {
ArchiveDir "${APTDIR}";
CacheDir "${APTDIR}/db";
};
Default {
Packages::Compress ". gzip bzip2";
Sources::Compress ". gzip bzip2";
Contents::Compress ". gzip bzip2";
};
TreeDefault {
BinCacheDB "packages-\$(SECTION)-\$(ARCH).db";
Directory "pool/\$(SECTION)";
Packages "\$(DIST)/\$(SECTION)/binary-\$(ARCH)/Packages";
SrcDirectory "pool/\$(SECTION)";
Sources "\$(DIST)/\$(SECTION)/source/Sources";
Contents "\$(DIST)/\$(SECTION)/Contents-\$(ARCH)";
FileList "$APTDIR/\$(DIST)/\$(SECTION)/filelist";
};
EOF
for suite in $(exec contrib/reprepro/suites.sh); do
cat <<-EOF
Tree "dists/${suite}" {
Sections "main testing experimental";
Architectures "${arches[*]}";
}
EOF
done >> "$APTDIR/conf/apt-ftparchive.conf"
fi
if [ ! -f "$APTDIR/conf/docker-engine-release.conf" ]; then
cat <<-EOF > "$APTDIR/conf/docker-engine-release.conf"
APT::FTPArchive::Release::Origin "Docker";
APT::FTPArchive::Release::Components "${components[*]}";
APT::FTPArchive::Release::Label "Docker APT Repository";
APT::FTPArchive::Release::Architectures "${arches[*]}";
EOF
fi
# set the component and priority for the version being released
component="main"
priority=700
@@ -116,35 +67,4 @@ for dir in contrib/builder/deb/*/; do
reprepro -v --keepunreferencedfiles \
-S docker-engine -P "$priority" -C "$component" \
-b "$APTDIR" includedeb "$codename" "${DEBFILE[@]}"
# update the filelist for this codename/component
find "$APTDIR/pool/$component" \
-name *~${codename#*-}*.deb > "$APTDIR/dists/$codename/$component/filelist"
done
# run the apt-ftparchive commands so we can have pinning
apt-ftparchive generate "$APTDIR/conf/apt-ftparchive.conf"
for dir in contrib/builder/deb/*/; do
version="$(basename "$dir")"
codename="${version//debootstrap-}"
apt-ftparchive \
-o "APT::FTPArchive::Release::Codename=$codename" \
-o "APT::FTPArchive::Release::Suite=$codename" \
-c "$APTDIR/conf/docker-engine-release.conf" \
release \
"$APTDIR/dists/$codename" > "$APTDIR/dists/$codename/Release"
for arch in "${arches[@]}"; do
apt-ftparchive \
-o "APT::FTPArchive::Release::Codename=$codename" \
-o "APT::FTPArchive::Release::Suite=$codename" \
-o "APT::FTPArchive::Release::Component=$component" \
-o "APT::FTPArchive::Release::Architecture=$arch" \
-c "$APTDIR/conf/docker-engine-release.conf" \
release \
"$APTDIR/dists/$codename/$component/binary-$arch" > "$APTDIR/dists/$codename/$component/binary-$arch/Release"
done
done
+5 -5
View File
@@ -21,29 +21,29 @@ clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://gith
clone hg code.google.com/p/gosqlite 74691fb6f837
#get libnetwork packages
clone git github.com/docker/libnetwork bc565c2d295067c1a43674a23a473ec6336d7fd4
clone git github.com/docker/libnetwork bd3eecc96f3c05a4acef1bedcf74397bc6850d22
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
clone git github.com/hashicorp/serf 7151adcef72687bf95f451a2e0ba15cb19412bf2
clone git github.com/docker/libkv 60c7c881345b3c67defc7f93a8297debf041d43c
clone git github.com/vishvananda/netns 493029407eeb434d0c2d44e02ea072ff2488d322
clone git github.com/vishvananda/netlink 4b5dce31de6d42af5bb9811c6d265472199e0fec
clone git github.com/vishvananda/netlink 20397a138846e4d6590e01783ed023ed7e1c38a6
clone git github.com/BurntSushi/toml f706d00e3de6abe700c994cdd545a1a4915af060
clone git github.com/samuel/go-zookeeper d0e0d8e11f318e000a8cc434616d69e329edc374
clone git github.com/coreos/go-etcd v2.0.0
clone git github.com/hashicorp/consul v0.5.2
# get graph and distribution packages
clone git github.com/docker/distribution ec87e9b6971d831f0eff752ddb54fb64693e51cd # docker/1.8 branch
clone git github.com/vbatts/tar-split v0.9.6
clone git github.com/docker/distribution 7dc8d4a26b689bd4892f2f2322dbce0b7119d686
clone git github.com/vbatts/tar-split v0.9.4
clone git github.com/docker/notary 8e8122eb5528f621afcd4e2854c47302f17392f7
clone git github.com/endophage/gotuf a592b03b28b02bb29bb5878308fb1abed63383b5
clone git github.com/tent/canonical-json-go 96e4ba3a7613a1216cbd1badca4efe382adea337
clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
clone git github.com/opencontainers/runc v0.0.2.1 # libcontainer
clone git github.com/opencontainers/runc v0.0.2 # libcontainer
# libcontainer deps (see src/github.com/docker/libcontainer/update-vendor.sh)
clone git github.com/coreos/go-systemd v2
clone git github.com/godbus/dbus v2
-23
View File
@@ -2,10 +2,7 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"reflect"
"strconv"
"strings"
@@ -557,23 +554,3 @@ func (s *DockerSuite) TestPsFormatHeaders(c *check.C) {
c.Fatalf(`Expected 'NAMES\ntest\n', got %v`, out)
}
}
func (s *DockerSuite) TestPsDefaultFormatAndQuiet(c *check.C) {
config := `{
"psFormat": "{{ .ID }} default"
}`
d, err := ioutil.TempDir("", "integration-cli-")
c.Assert(err, check.IsNil)
defer os.RemoveAll(d)
err = ioutil.WriteFile(filepath.Join(d, "config.json"), []byte(config), 0644)
c.Assert(err, check.IsNil)
out, _ := dockerCmd(c, "run", "--name=test", "-d", "busybox", "top")
id := strings.TrimSpace(out)
out, _ = dockerCmd(c, "--config", d, "ps", "-q")
if !strings.HasPrefix(id, strings.TrimSpace(out)) {
c.Fatalf("Expected to print only the container id, got %v\n", out)
}
}
-37
View File
@@ -369,40 +369,3 @@ func (s *DockerTrustSuite) TestTrustedPullWithExpiredSnapshot(c *check.C) {
}
})
}
// Test that pull continues after client has disconnected. #15589
func (s *DockerTrustSuite) TestPullClientDisconnect(c *check.C) {
testRequires(c, Network)
repoName := "hello-world:latest"
dockerCmdWithError(c, "rmi", repoName) // clean just in case
pullCmd := exec.Command(dockerBinary, "pull", repoName)
stdout, err := pullCmd.StdoutPipe()
c.Assert(err, check.IsNil)
err = pullCmd.Start()
c.Assert(err, check.IsNil)
// cancel as soon as we get some output
buf := make([]byte, 10)
_, err = stdout.Read(buf)
c.Assert(err, check.IsNil)
err = pullCmd.Process.Kill()
c.Assert(err, check.IsNil)
maxAttempts := 20
for i := 0; ; i++ {
if _, _, err := dockerCmdWithError(c, "inspect", repoName); err == nil {
break
}
if i >= maxAttempts {
c.Fatal("Timeout reached. Image was not pulled after client disconnected.")
}
time.Sleep(500 * time.Millisecond)
}
}
+1 -1
View File
@@ -23,7 +23,7 @@ its own man page which explain usage and arguments.
To see the man page for a command run **man docker <command>**.
# OPTIONS
**--help**
**-h**, **--help**
Print usage statement
**--api-cors-header**=""
+15 -3
View File
@@ -38,7 +38,10 @@ static void log_with_errno_init()
*/
import "C"
import "unsafe"
import (
"reflect"
"unsafe"
)
type (
CDmTask C.struct_dm_task
@@ -184,12 +187,21 @@ func dmTaskGetDepsFct(task *CDmTask) *Deps {
if Cdeps == nil {
return nil
}
// golang issue: https://github.com/golang/go/issues/11925
hdr := reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(uintptr(unsafe.Pointer(Cdeps)) + unsafe.Sizeof(*Cdeps))),
Len: int(Cdeps.count),
Cap: int(Cdeps.count),
}
devices := *(*[]C.uint64_t)(unsafe.Pointer(&hdr))
deps := &Deps{
Count: uint32(Cdeps.count),
Filler: uint32(Cdeps.filler),
}
for _, device := range Cdeps.device {
deps.Device = append(deps.Device, (uint64)(device))
for _, device := range devices {
deps.Device = append(deps.Device, uint64(device))
}
return deps
}
@@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"io/ioutil"
"os"
)
var (
@@ -12,12 +13,22 @@ var (
// file to check to determine Operating System
etcOsRelease = "/etc/os-release"
// used by stateless systems like Clear Linux
altEtcOSRelease = "/usr/lib/os-release"
)
func GetOperatingSystem() (string, error) {
b, err := ioutil.ReadFile(etcOsRelease)
if err != nil {
return "", err
if _, err2 := os.Stat(altEtcOSRelease); err2 == nil {
b, err2 = ioutil.ReadFile(altEtcOSRelease)
if err2 != nil {
return "", err2
}
} else {
return "", err
}
}
if i := bytes.Index(b, []byte("PRETTY_NAME")); i >= 0 {
b = b[i+13:]
@@ -359,18 +359,25 @@ type blobs struct {
distribution.BlobDeleter
}
func sanitizeLocation(location, base string) (string, error) {
baseURL, err := url.Parse(base)
if err != nil {
return "", err
}
func sanitizeLocation(location, source string) (string, error) {
locationURL, err := url.Parse(location)
if err != nil {
return "", err
}
return baseURL.ResolveReference(locationURL).String(), nil
if locationURL.Scheme == "" {
sourceURL, err := url.Parse(source)
if err != nil {
return "", err
}
locationURL = &url.URL{
Scheme: sourceURL.Scheme,
Host: sourceURL.Host,
Path: location,
}
location = locationURL.String()
}
return location, nil
}
func (bs *blobs) Stat(ctx context.Context, dgst digest.Digest) (distribution.Descriptor, error) {
@@ -19,7 +19,6 @@ import (
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/options"
"github.com/docker/libnetwork/portmapper"
"github.com/docker/libnetwork/sandbox"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
)
@@ -90,6 +89,7 @@ type bridgeNetwork struct {
config *networkConfiguration
endpoints map[types.UUID]*bridgeEndpoint // key: endpoint id
portMapper *portmapper.PortMapper
veth *netlink.Veth
sync.Mutex
}
@@ -545,8 +545,6 @@ func (d *driver) getNetworks() []*bridgeNetwork {
func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) error {
var err error
defer sandbox.InitOSContext()()
// Sanity checks
d.Lock()
if _, ok := d.networks[id]; ok {
@@ -698,8 +696,6 @@ func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) err
func (d *driver) DeleteNetwork(nid types.UUID) error {
var err error
defer sandbox.InitOSContext()()
// Get network handler and remove it from driver
d.Lock()
n, ok := d.networks[nid]
@@ -827,8 +823,6 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
err error
)
defer sandbox.InitOSContext()()
if epInfo == nil {
return errors.New("invalid endpoint info passed")
}
@@ -901,11 +895,13 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
return err
}
logrus.Warnf("network %v", n)
logrus.Warnf("veth %v", n.veth)
// Generate and add the interface pipe host <-> sandbox
veth := &netlink.Veth{
n.veth = &netlink.Veth{
LinkAttrs: netlink.LinkAttrs{Name: hostIfName, TxQLen: 0},
PeerName: containerIfName}
if err = netlink.LinkAdd(veth); err != nil {
if err = netlink.LinkAdd(n.veth); err != nil {
return err
}
@@ -1036,8 +1032,6 @@ func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointIn
func (d *driver) DeleteEndpoint(nid, eid types.UUID) error {
var err error
defer sandbox.InitOSContext()()
// Get the network handler and make sure it exists
d.Lock()
n, ok := d.networks[nid]
@@ -1172,13 +1166,16 @@ func (d *driver) EndpointOperInfo(nid, eid types.UUID) (map[string]interface{},
m[netlabel.MacAddress] = ep.macAddress
}
// Add details of the bridge
m[netlabel.BridgeName] = n.config.BridgeName
m[netlabel.BridgePeername] = n.veth.PeerName
m[netlabel.BridgeLinkName] = n.veth.LinkAttrs.Name
return m, nil
}
// Join method is invoked when a Sandbox is attached to an endpoint.
func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinInfo, options map[string]interface{}) error {
defer sandbox.InitOSContext()()
network, err := d.getNetwork(nid)
if err != nil {
return err
@@ -1222,8 +1219,6 @@ func (d *driver) Join(nid, eid types.UUID, sboxKey string, jinfo driverapi.JoinI
// Leave method is invoked when a Sandbox detaches from an endpoint.
func (d *driver) Leave(nid, eid types.UUID) error {
defer sandbox.InitOSContext()()
network, err := d.getNetwork(nid)
if err != nil {
return err
@@ -4,7 +4,6 @@ import (
"fmt"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/sandbox"
"github.com/docker/libnetwork/types"
"github.com/vishvananda/netlink"
)
@@ -22,8 +21,6 @@ func validateID(nid, eid types.UUID) error {
}
func createVethPair() (string, string, error) {
defer sandbox.InitOSContext()()
// Generate a name for what will be the host side pipe interface
name1, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
if err != nil {
@@ -48,8 +45,6 @@ func createVethPair() (string, string, error) {
}
func createVxlan(vni uint32) (string, error) {
defer sandbox.InitOSContext()()
name, err := netutils.GenerateIfaceName("vxlan", 7)
if err != nil {
return "", fmt.Errorf("error generating vxlan name: %v", err)
@@ -73,8 +68,6 @@ func createVxlan(vni uint32) (string, error) {
}
func deleteVxlan(name string) error {
defer sandbox.InitOSContext()()
link, err := netlink.LinkByName(name)
if err != nil {
return fmt.Errorf("failed to find vxlan interface with name %s: %v", name, err)
@@ -24,6 +24,17 @@ const (
//EnableIPv6 constant represents enabling IPV6 at network level
EnableIPv6 = Prefix + ".enable_ipv6"
// BridgeName constant represents the name of the network bridge
BridgeName = "io.docker.network.bridge.name"
// BridgePeername constant represents the interface name provided to
// the container.
BridgePeername = "io.docker.network.bridge.peername"
// BridgeLinkName constant represents the interface name created on
// the host side.
BridgeLinkName = "io.docker.network.bridge.linkname"
// KVProvider constant represents the KV provider backend
KVProvider = DriverPrefix + ".kv_provider"
@@ -0,0 +1,41 @@
package netutils
import (
"flag"
"runtime"
"syscall"
"testing"
)
var runningInContainer = flag.Bool("incontainer", false, "Indicates if the test is running in a container")
// IsRunningInContainer returns whether the test is running inside a container.
func IsRunningInContainer() bool {
return (*runningInContainer)
}
// SetupTestNetNS joins a new network namespace, and returns its associated
// teardown function.
//
// Example usage:
//
// defer SetupTestNetNS(t)()
//
func SetupTestNetNS(t *testing.T) func() {
runtime.LockOSThread()
if err := syscall.Unshare(syscall.CLONE_NEWNET); err != nil {
t.Fatalf("Failed to enter netns: %v", err)
}
fd, err := syscall.Open("/proc/self/ns/net", syscall.O_RDONLY, 0)
if err != nil {
t.Fatal("Failed to open netns file")
}
return func() {
if err := syscall.Close(fd); err != nil {
t.Logf("Warning: netns closing failed (%v)", err)
}
runtime.UnlockOSThread()
}
}
@@ -26,8 +26,6 @@ var (
gpmWg sync.WaitGroup
gpmCleanupPeriod = 60 * time.Second
gpmChan = make(chan chan struct{})
nsOnce sync.Once
initNs netns.NsHandle
)
// The networkNamespace type is the linux implementation of the Sandbox
@@ -244,37 +242,15 @@ func (n *networkNamespace) InvokeFunc(f func()) error {
})
}
func getLink() (string, error) {
return os.Readlink(fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), syscall.Gettid()))
}
func nsInit() {
var err error
if initNs, err = netns.Get(); err != nil {
log.Errorf("could not get initial namespace: %v", err)
}
}
// InitOSContext initializes OS context while configuring network resources
func InitOSContext() func() {
runtime.LockOSThread()
nsOnce.Do(nsInit)
if err := netns.Set(initNs); err != nil {
linkInfo, linkErr := getLink()
if linkErr != nil {
linkInfo = linkErr.Error()
}
log.Errorf("failed to set to initial namespace, %v, initns fd %d: %v",
linkInfo, initNs, err)
}
return runtime.UnlockOSThread
}
func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD int) error) error {
defer InitOSContext()()
runtime.LockOSThread()
defer runtime.UnlockOSThread()
origns, err := netns.Get()
if err != nil {
return err
}
defer origns.Close()
f, err := os.OpenFile(path, os.O_RDONLY, 0)
if err != nil {
@@ -293,10 +269,10 @@ func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD
if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
return err
}
defer netns.Set(initNs)
defer netns.Set(origns)
// Invoked after the namespace switch.
return postfunc(int(initNs))
return postfunc(int(origns))
}
func (n *networkNamespace) nsPath() string {
@@ -21,8 +21,3 @@ func NewSandbox(key string, osCreate bool) (Sandbox, error) {
// and waits for it.
func GC() {
}
// InitOSContext initializes OS context while configuring network resources
func InitOSContext() func() {
return func() {}
}
@@ -21,8 +21,3 @@ func NewSandbox(key string, osCreate bool) (Sandbox, error) {
// and waits for it.
func GC() {
}
// InitOSContext initializes OS context while configuring network resources
func InitOSContext() func() {
return func() {}
}
@@ -3,7 +3,6 @@ package fluent
import (
"errors"
"fmt"
"io"
"math"
"net"
"reflect"
@@ -34,7 +33,7 @@ type Config struct {
type Fluent struct {
Config
conn io.WriteCloser
conn net.Conn
pending []byte
reconnecting bool
mu sync.Mutex
@@ -1,3 +1,3 @@
package fluent
const Version = "1.0.0"
const Version = "0.5.1"
@@ -236,7 +236,7 @@ func getCgroupData(c *configs.Cgroup, pid int) (*data, error) {
}
func (raw *data) parent(subsystem, mountpoint, src string) (string, error) {
initPath, err := cgroups.GetThisCgroupDir(subsystem)
initPath, err := cgroups.GetInitCgroupDir(subsystem)
if err != nil {
return "", err
}
@@ -159,19 +159,17 @@ func (tr *Reader) Next() (*Header, error) {
if err != nil {
return nil, err
}
var buf []byte
var b []byte
if tr.RawAccounting {
if _, err = tr.rawBytes.Write(realname); err != nil {
return nil, err
}
buf = make([]byte, tr.rawBytes.Len())
copy(buf[:], tr.RawBytes())
b = tr.RawBytes()
}
hdr, err := tr.Next()
// since the above call to Next() resets the buffer, we need to throw the bytes over
if tr.RawAccounting {
buf = append(buf, tr.RawBytes()...)
if _, err = tr.rawBytes.Write(buf); err != nil {
if _, err = tr.rawBytes.Write(b); err != nil {
return nil, err
}
}
@@ -183,19 +181,17 @@ func (tr *Reader) Next() (*Header, error) {
if err != nil {
return nil, err
}
var buf []byte
var b []byte
if tr.RawAccounting {
if _, err = tr.rawBytes.Write(realname); err != nil {
return nil, err
}
buf = make([]byte, tr.rawBytes.Len())
copy(buf[:], tr.RawBytes())
b = tr.RawBytes()
}
hdr, err := tr.Next()
// since the above call to Next() resets the buffer, we need to throw the bytes over
if tr.RawAccounting {
buf = append(buf, tr.RawBytes()...)
if _, err = tr.rawBytes.Write(buf); err != nil {
if _, err = tr.rawBytes.Write(b); err != nil {
return nil, err
}
}
+2 -1
View File
@@ -9,7 +9,7 @@ import (
"github.com/vbatts/tar-split/tar/storage"
)
// NewOutputTarStream returns an io.ReadCloser that is an assembled tar archive
// NewOutputTarStream returns an io.ReadCloser that is an assemble tar archive
// stream.
//
// It takes a storage.FileGetter, for mapping the file payloads that are to be read in,
@@ -62,6 +62,7 @@ func NewOutputTarStream(fg storage.FileGetter, up storage.Unpacker) io.ReadClose
fh.Close()
}
}
pw.Close()
}()
return pr
}
+16 -21
View File
@@ -22,8 +22,8 @@ func NewInputTarStream(r io.Reader, p storage.Packer, fp storage.FilePutter) (io
// What to do here... folks will want their own access to the Reader that is
// their tar archive stream, but we'll need that same stream to use our
// forked 'archive/tar'.
// Perhaps do an io.TeeReader that hands back an io.Reader for them to read
// from, and we'll MITM the stream to store metadata.
// Perhaps do an io.TeeReader that hand back an io.Reader for them to read
// from, and we'll mitm the stream to store metadata.
// We'll need a storage.FilePutter too ...
// Another concern, whether to do any storage.FilePutter operations, such that we
@@ -32,7 +32,7 @@ func NewInputTarStream(r io.Reader, p storage.Packer, fp storage.FilePutter) (io
// Perhaps we have a DiscardFilePutter that is a bit bucket.
// we'll return the pipe reader, since TeeReader does not buffer and will
// only read what the outputRdr Read's. Since Tar archives have padding on
// only read what the outputRdr Read's. Since Tar archive's have padding on
// the end, we want to be the one reading the padding, even if the user's
// `archive/tar` doesn't care.
pR, pW := io.Pipe()
@@ -55,15 +55,13 @@ func NewInputTarStream(r io.Reader, p storage.Packer, fp storage.FilePutter) (io
}
// even when an EOF is reached, there is often 1024 null bytes on
// the end of an archive. Collect them too.
if b := tr.RawBytes(); len(b) > 0 {
_, err := p.AddEntry(storage.Entry{
Type: storage.SegmentType,
Payload: b,
})
if err != nil {
pW.CloseWithError(err)
return
}
_, err := p.AddEntry(storage.Entry{
Type: storage.SegmentType,
Payload: tr.RawBytes(),
})
if err != nil {
pW.CloseWithError(err)
return
}
break // not return. We need the end of the reader.
}
@@ -71,15 +69,12 @@ func NewInputTarStream(r io.Reader, p storage.Packer, fp storage.FilePutter) (io
break // not return. We need the end of the reader.
}
if b := tr.RawBytes(); len(b) > 0 {
_, err := p.AddEntry(storage.Entry{
Type: storage.SegmentType,
Payload: b,
})
if err != nil {
pW.CloseWithError(err)
return
}
if _, err := p.AddEntry(storage.Entry{
Type: storage.SegmentType,
Payload: tr.RawBytes(),
}); err != nil {
pW.CloseWithError(err)
return
}
var csum []byte
+1 -1
View File
@@ -5,7 +5,7 @@ Packing and unpacking the Entries of the stream. The types of streams are
either segments of raw bytes (for the raw headers and various padding) and for
an entry marking a file payload.
The raw bytes are stored precisely in the packed (marshalled) Entry, whereas
The raw bytes are stored precisely in the packed (marshalled) Entry. Where as
the file payload marker include the name of the file, size, and crc64 checksum
(for basic file integrity).
*/
@@ -19,11 +19,11 @@ const (
// SegmentType represents a raw bytes segment from the archive stream. These raw
// byte segments consist of the raw headers and various padding.
//
// Its payload is to be marshalled base64 encoded.
// It's payload is to be marshalled base64 encoded.
SegmentType
)
// Entry is the structure for packing and unpacking the information read from
// Entry is a the structure for packing and unpacking the information read from
// the Tar archive.
//
// FileType Payload checksum is using `hash/crc64` for basic file integrity,
@@ -32,8 +32,8 @@ const (
// collisions in a sample of 18.2 million, CRC64 had none.
type Entry struct {
Type Type `json:"type"`
Name string `json:"name,omitempty"`
Size int64 `json:"size,omitempty"`
Payload []byte `json:"payload"` // SegmentType stores payload here; FileType stores crc64 checksum here;
Name string `json:"name",omitempty`
Size int64 `json:"size",omitempty`
Payload []byte `json:"payload"` // SegmentType store payload here; FileType store crc64 checksum here;
Position int `json:"position"`
}
+13 -11
View File
@@ -5,13 +5,14 @@ import (
"errors"
"hash/crc64"
"io"
"io/ioutil"
"os"
"path/filepath"
)
// FileGetter is the interface for getting a stream of a file payload,
// addressed by name/filename. Presumably, the names will be scoped to relative
// file paths.
// FileGetter is the interface for getting a stream of a file payload, address
// by name/filename. Presumably, the names will be scoped to relative file
// paths.
type FileGetter interface {
// Get returns a stream for the provided file path
Get(filename string) (output io.ReadCloser, err error)
@@ -59,15 +60,15 @@ func (bfgp bufferFileGetPutter) Get(name string) (io.ReadCloser, error) {
}
func (bfgp *bufferFileGetPutter) Put(name string, r io.Reader) (int64, []byte, error) {
crc := crc64.New(CRCTable)
buf := bytes.NewBuffer(nil)
cw := io.MultiWriter(crc, buf)
i, err := io.Copy(cw, r)
c := crc64.New(CRCTable)
tRdr := io.TeeReader(r, c)
b := bytes.NewBuffer([]byte{})
i, err := io.Copy(b, tRdr)
if err != nil {
return 0, nil, err
}
bfgp.files[name] = buf.Bytes()
return i, crc.Sum(nil), nil
bfgp.files[name] = b.Bytes()
return i, c.Sum(nil), nil
}
type readCloserWrapper struct {
@@ -76,7 +77,7 @@ type readCloserWrapper struct {
func (w *readCloserWrapper) Close() error { return nil }
// NewBufferFileGetPutter is a simple in-memory FileGetPutter
// NewBufferFileGetPutter is simple in memory FileGetPutter
//
// Implication is this is memory intensive...
// Probably best for testing or light weight cases.
@@ -96,7 +97,8 @@ type bitBucketFilePutter struct {
func (bbfp *bitBucketFilePutter) Put(name string, r io.Reader) (int64, []byte, error) {
c := crc64.New(CRCTable)
i, err := io.Copy(c, r)
tRdr := io.TeeReader(r, c)
i, err := io.Copy(ioutil.Discard, tRdr)
return i, c.Sum(nil), err
}
@@ -8,8 +8,8 @@ import (
"path/filepath"
)
// ErrDuplicatePath occurs when a tar archive has more than one entry for the
// same file path
// ErrDuplicatePath is occured when a tar archive has more than one entry for
// the same file path
var ErrDuplicatePath = errors.New("duplicates of file paths not supported")
// Packer describes the methods to pack Entries to a storage destination
@@ -65,7 +65,7 @@ func (jup *jsonUnpacker) Next() (*Entry, error) {
if _, ok := jup.seen[cName]; ok {
return nil, ErrDuplicatePath
}
jup.seen[cName] = struct{}{}
jup.seen[cName] = emptyByte
}
return &e, err
@@ -90,7 +90,11 @@ type jsonPacker struct {
seen seenNames
}
type seenNames map[string]struct{}
type seenNames map[string]byte
// used in the seenNames map. byte is a uint8, and we'll re-use the same one
// for minimalism.
const emptyByte byte = 0
func (jp *jsonPacker) AddEntry(e Entry) (int, error) {
// check early for dup name
@@ -99,7 +103,7 @@ func (jp *jsonPacker) AddEntry(e Entry) (int, error) {
if _, ok := jp.seen[cName]; ok {
return -1, ErrDuplicatePath
}
jp.seen[cName] = struct{}{}
jp.seen[cName] = emptyByte
}
e.Position = jp.pos
@@ -113,7 +117,7 @@ func (jp *jsonPacker) AddEntry(e Entry) (int, error) {
return e.Position, nil
}
// NewJSONPacker provides a Packer that writes each Entry (SegmentType and
// NewJSONPacker provides an Packer that writes each Entry (SegmentType and
// FileType) as a json document.
//
// The Entries are delimited by new line.
-1
View File
@@ -157,7 +157,6 @@ type Vxlan struct {
L2miss bool
L3miss bool
NoAge bool
GBP bool
Age int
Limit int
Port int
+21 -6
View File
@@ -73,7 +73,10 @@ func LinkSetMTU(link Link, mtu int) error {
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
msg.Type = syscall.RTM_SETLINK
msg.Flags = syscall.NLM_F_REQUEST
msg.Index = int32(base.Index)
msg.Change = syscall.IFLA_MTU
req.AddData(msg)
b := make([]byte, 4)
@@ -94,7 +97,10 @@ func LinkSetName(link Link, name string) error {
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
msg.Type = syscall.RTM_SETLINK
msg.Flags = syscall.NLM_F_REQUEST
msg.Index = int32(base.Index)
msg.Change = syscall.IFLA_IFNAME
req.AddData(msg)
data := nl.NewRtAttr(syscall.IFLA_IFNAME, []byte(name))
@@ -112,7 +118,10 @@ func LinkSetHardwareAddr(link Link, hwaddr net.HardwareAddr) error {
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
msg.Type = syscall.RTM_SETLINK
msg.Flags = syscall.NLM_F_REQUEST
msg.Index = int32(base.Index)
msg.Change = syscall.IFLA_ADDRESS
req.AddData(msg)
data := nl.NewRtAttr(syscall.IFLA_ADDRESS, []byte(hwaddr))
@@ -142,7 +151,10 @@ func LinkSetMasterByIndex(link Link, masterIndex int) error {
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
msg.Type = syscall.RTM_SETLINK
msg.Flags = syscall.NLM_F_REQUEST
msg.Index = int32(base.Index)
msg.Change = syscall.IFLA_MASTER
req.AddData(msg)
b := make([]byte, 4)
@@ -164,7 +176,10 @@ func LinkSetNsPid(link Link, nspid int) error {
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
msg.Type = syscall.RTM_SETLINK
msg.Flags = syscall.NLM_F_REQUEST
msg.Index = int32(base.Index)
msg.Change = syscall.IFLA_NET_NS_PID
req.AddData(msg)
b := make([]byte, 4)
@@ -186,7 +201,10 @@ func LinkSetNsFd(link Link, fd int) error {
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_UNSPEC)
msg.Type = syscall.RTM_SETLINK
msg.Flags = syscall.NLM_F_REQUEST
msg.Index = int32(base.Index)
msg.Change = nl.IFLA_NET_NS_FD
req.AddData(msg)
b := make([]byte, 4)
@@ -248,10 +266,6 @@ func addVxlanAttrs(vxlan *Vxlan, linkInfo *nl.RtAttr) {
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_L2MISS, boolAttr(vxlan.L2miss))
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_L3MISS, boolAttr(vxlan.L3miss))
if vxlan.GBP {
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_GBP, boolAttr(vxlan.GBP))
}
if vxlan.NoAge {
nl.NewRtAttrChild(data, nl.IFLA_VXLAN_AGEING, nl.Uint32Attr(0))
} else if vxlan.Age > 0 {
@@ -613,7 +627,10 @@ func setProtinfoAttr(link Link, mode bool, attr int) error {
req := nl.NewNetlinkRequest(syscall.RTM_SETLINK, syscall.NLM_F_ACK)
msg := nl.NewIfInfomsg(syscall.AF_BRIDGE)
msg.Type = syscall.RTM_SETLINK
msg.Flags = syscall.NLM_F_REQUEST
msg.Index = int32(base.Index)
msg.Change = syscall.IFLA_PROTINFO | syscall.NLA_F_NESTED
req.AddData(msg)
br := nl.NewRtAttr(syscall.IFLA_PROTINFO|syscall.NLA_F_NESTED, nil)
@@ -666,8 +683,6 @@ func parseVxlanData(link Link, data []syscall.NetlinkRouteAttr) {
vxlan.L2miss = int8(datum.Value[0]) != 0
case nl.IFLA_VXLAN_L3MISS:
vxlan.L3miss = int8(datum.Value[0]) != 0
case nl.IFLA_VXLAN_GBP:
vxlan.GBP = int8(datum.Value[0]) != 0
case nl.IFLA_VXLAN_AGEING:
vxlan.Age = int(native.Uint32(datum.Value[0:4]))
vxlan.NoAge = vxlan.Age == 0
+1 -9
View File
@@ -47,15 +47,7 @@ const (
IFLA_VXLAN_PORT
IFLA_VXLAN_GROUP6
IFLA_VXLAN_LOCAL6
IFLA_VXLAN_UDP_CSUM
IFLA_VXLAN_UDP_ZERO_CSUM6_TX
IFLA_VXLAN_UDP_ZERO_CSUM6_RX
IFLA_VXLAN_REMCSUM_TX
IFLA_VXLAN_REMCSUM_RX
IFLA_VXLAN_GBP
IFLA_VXLAN_REMCSUM_NOPARTIAL
IFLA_VXLAN_FLOWBASED
IFLA_VXLAN_MAX = IFLA_VXLAN_FLOWBASED
IFLA_VXLAN_MAX = IFLA_VXLAN_LOCAL6
)
const (
+1 -2
View File
@@ -39,9 +39,8 @@ func NativeEndian() binary.ByteOrder {
var x uint32 = 0x01020304
if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
nativeEndian = binary.BigEndian
} else {
nativeEndian = binary.LittleEndian
}
nativeEndian = binary.LittleEndian
}
return nativeEndian
}
@@ -20,15 +20,6 @@ func NewRtMsg() *RtMsg {
}
}
func NewRtDelMsg() *RtMsg {
return &RtMsg{
RtMsg: syscall.RtMsg{
Table: syscall.RT_TABLE_MAIN,
Scope: syscall.RT_SCOPE_NOWHERE,
},
}
}
func (msg *RtMsg) Len() int {
return syscall.SizeofRtMsg
}
+4 -3
View File
@@ -14,21 +14,22 @@ import (
// Equivalent to: `ip route add $route`
func RouteAdd(route *Route) error {
req := nl.NewNetlinkRequest(syscall.RTM_NEWROUTE, syscall.NLM_F_CREATE|syscall.NLM_F_EXCL|syscall.NLM_F_ACK)
return routeHandle(route, req, nl.NewRtMsg())
return routeHandle(route, req)
}
// RouteAdd will delete a route from the system.
// Equivalent to: `ip route del $route`
func RouteDel(route *Route) error {
req := nl.NewNetlinkRequest(syscall.RTM_DELROUTE, syscall.NLM_F_ACK)
return routeHandle(route, req, nl.NewRtDelMsg())
return routeHandle(route, req)
}
func routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg) error {
func routeHandle(route *Route, req *nl.NetlinkRequest) error {
if (route.Dst == nil || route.Dst.IP == nil) && route.Src == nil && route.Gw == nil {
return fmt.Errorf("one of Dst.IP, Src, or Gw must not be nil")
}
msg := nl.NewRtMsg()
msg.Scope = uint8(route.Scope)
family := -1
var rtAttrs []*nl.RtAttr