From 2ca6939ac27c872f57a3e1985379a88ee6e9311d Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Sun, 16 Feb 2014 19:24:22 -0500 Subject: [PATCH 1/6] support for `docker run` environment variables file Docker-DCO-1.1-Signed-off-by: Vincent Batts (github: vbatts) --- opts/envfile.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 opts/envfile.go diff --git a/opts/envfile.go b/opts/envfile.go new file mode 100644 index 0000000..004c320 --- /dev/null +++ b/opts/envfile.go @@ -0,0 +1,44 @@ +package opts + +import ( + "bufio" + "bytes" + "io" + "os" +) + +/* +Read in a line delimited file with environment variables enumerated +*/ +func ParseEnvFile(filename string) ([]string, error) { + fh, err := os.Open(filename) + if err != nil { + return []string{}, err + } + var ( + lines []string = []string{} + line, chunk []byte + ) + reader := bufio.NewReader(fh) + line, isPrefix, err := reader.ReadLine() + + for err == nil { + if isPrefix { + chunk = append(chunk, line...) + } else if !isPrefix && len(chunk) > 0 { + line = chunk + chunk = []byte{} + } else { + chunk = []byte{} + } + + if !isPrefix && len(line) > 0 && bytes.Contains(line, []byte("=")) { + lines = append(lines, string(line)) + } + line, isPrefix, err = reader.ReadLine() + } + if err != nil && err != io.EOF { + return []string{}, err + } + return lines, nil +} From f5f422f7dce120d92a64bf42e2f73d9dc11c6349 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Tue, 18 Feb 2014 14:22:46 -0500 Subject: [PATCH 2/6] pkg/opts: Close the file handle Docker-DCO-1.1-Signed-off-by: Vincent Batts (github: vbatts) --- opts/envfile.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opts/envfile.go b/opts/envfile.go index 004c320..65495a1 100644 --- a/opts/envfile.go +++ b/opts/envfile.go @@ -15,6 +15,8 @@ func ParseEnvFile(filename string) ([]string, error) { if err != nil { return []string{}, err } + defer fh.Close() + var ( lines []string = []string{} line, chunk []byte From 321381301e96e2113cd8b6c236323971ea1e407b Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Thu, 20 Feb 2014 15:34:45 -0500 Subject: [PATCH 3/6] go fmt Docker-DCO-1.1-Signed-off-by: Vincent Batts (github: vbatts) --- opts/envfile.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opts/envfile.go b/opts/envfile.go index 65495a1..7c69f5d 100644 --- a/opts/envfile.go +++ b/opts/envfile.go @@ -15,7 +15,7 @@ func ParseEnvFile(filename string) ([]string, error) { if err != nil { return []string{}, err } - defer fh.Close() + defer fh.Close() var ( lines []string = []string{} From e659708bcc09be04db7e53bb835deec1a8d07e96 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Thu, 6 Mar 2014 17:49:47 -0500 Subject: [PATCH 4/6] env-file: update functionality and docs Multiple flags allowed. Order prescribed. Examples provided. Multiline accounted for. Docker-DCO-1.1-Signed-off-by: Vincent Batts (github: vbatts) --- opts/envfile.go | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/opts/envfile.go b/opts/envfile.go index 7c69f5d..d9afdd9 100644 --- a/opts/envfile.go +++ b/opts/envfile.go @@ -2,9 +2,10 @@ package opts import ( "bufio" - "bytes" - "io" + "fmt" "os" + "strconv" + "strings" ) /* @@ -17,30 +18,20 @@ func ParseEnvFile(filename string) ([]string, error) { } defer fh.Close() - var ( - lines []string = []string{} - line, chunk []byte - ) - reader := bufio.NewReader(fh) - line, isPrefix, err := reader.ReadLine() - - for err == nil { - if isPrefix { - chunk = append(chunk, line...) - } else if !isPrefix && len(chunk) > 0 { - line = chunk - chunk = []byte{} - } else { - chunk = []byte{} + lines := []string{} + scanner := bufio.NewScanner(fh) + for scanner.Scan() { + line := scanner.Text() + // line is not empty, and not starting with '#' + if len(line) > 0 && !strings.HasPrefix(line, "#") && strings.Contains(line, "=") { + data := strings.SplitN(line, "=", 2) + key := data[0] + val := data[1] + if str, err := strconv.Unquote(data[1]); err == nil { + val = str + } + lines = append(lines, fmt.Sprintf("%s=%s", key, val)) } - - if !isPrefix && len(line) > 0 && bytes.Contains(line, []byte("=")) { - lines = append(lines, string(line)) - } - line, isPrefix, err = reader.ReadLine() - } - if err != nil && err != io.EOF { - return []string{}, err } return lines, nil } From a031814bc46f8163fbdb510aa989327e0e17bfe2 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Tue, 11 Mar 2014 16:22:58 -0400 Subject: [PATCH 5/6] --env-file: simple line-delimited match dock functionality, and not try to achieve shell-sourcing compatibility Docker-DCO-1.1-Signed-off-by: Vincent Batts (github: vbatts) --- opts/envfile.go | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 opts/envfile.go diff --git a/opts/envfile.go b/opts/envfile.go deleted file mode 100644 index d9afdd9..0000000 --- a/opts/envfile.go +++ /dev/null @@ -1,37 +0,0 @@ -package opts - -import ( - "bufio" - "fmt" - "os" - "strconv" - "strings" -) - -/* -Read in a line delimited file with environment variables enumerated -*/ -func ParseEnvFile(filename string) ([]string, error) { - fh, err := os.Open(filename) - if err != nil { - return []string{}, err - } - defer fh.Close() - - lines := []string{} - scanner := bufio.NewScanner(fh) - for scanner.Scan() { - line := scanner.Text() - // line is not empty, and not starting with '#' - if len(line) > 0 && !strings.HasPrefix(line, "#") && strings.Contains(line, "=") { - data := strings.SplitN(line, "=", 2) - key := data[0] - val := data[1] - if str, err := strconv.Unquote(data[1]); err == nil { - val = str - } - lines = append(lines, fmt.Sprintf("%s=%s", key, val)) - } - } - return lines, nil -} From ba89d04fbc1ef63b336cc4548b980eb66fd92941 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 31 Mar 2014 21:02:42 +0000 Subject: [PATCH 6/6] Set bridge mac addr on supported kernels Fixes #3200 Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- netlink/netlink_linux.go | 51 ++++++++++++++++++++++++++++++++++ netlink/netlink_unsupported.go | 4 +++ 2 files changed, 55 insertions(+) diff --git a/netlink/netlink_linux.go b/netlink/netlink_linux.go index f8bb6ba..f4aa92e 100644 --- a/netlink/netlink_linux.go +++ b/netlink/netlink_linux.go @@ -5,6 +5,7 @@ package netlink import ( "encoding/binary" "fmt" + "math/rand" "net" "syscall" "unsafe" @@ -17,10 +18,16 @@ const ( IFLA_INFO_DATA = 2 VETH_INFO_PEER = 1 IFLA_NET_NS_FD = 28 + SIOC_BRADDBR = 0x89a0 ) var nextSeqNr int +type ifreqHwaddr struct { + IfrnName [16]byte + IfruHwaddr syscall.RawSockaddr +} + func nativeEndian() binary.ByteOrder { var x uint32 = 0x01020304 if *(*byte)(unsafe.Pointer(&x)) == 0x01 { @@ -808,3 +815,47 @@ func NetworkCreateVethPair(name1, name2 string) error { } return s.HandleAck(wb.Seq) } + +// Create the actual bridge device. This is more backward-compatible than +// netlink.NetworkLinkAdd and works on RHEL 6. +func CreateBridge(name string, setMacAddr bool) error { + s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_IP) + if err != nil { + // ipv6 issue, creating with ipv4 + s, err = syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_IP) + if err != nil { + return err + } + } + defer syscall.Close(s) + + nameBytePtr, err := syscall.BytePtrFromString(name) + if err != nil { + return err + } + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDBR, uintptr(unsafe.Pointer(nameBytePtr))); err != 0 { + return err + } + if setMacAddr { + return setBridgeMacAddress(s, name) + } + return nil +} + +func setBridgeMacAddress(s int, name string) error { + ifr := ifreqHwaddr{} + ifr.IfruHwaddr.Family = syscall.ARPHRD_ETHER + copy(ifr.IfrnName[:], name) + + for i := 0; i < 6; i++ { + ifr.IfruHwaddr.Data[i] = int8(rand.Intn(255)) + } + + ifr.IfruHwaddr.Data[0] &^= 0x1 // clear multicast bit + ifr.IfruHwaddr.Data[0] |= 0x2 // set local assignment bit (IEEE802) + + if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), syscall.SIOCSIFHWADDR, uintptr(unsafe.Pointer(&ifr))); err != 0 { + return err + } + return nil +} diff --git a/netlink/netlink_unsupported.go b/netlink/netlink_unsupported.go index bd9e962..00a3b3f 100644 --- a/netlink/netlink_unsupported.go +++ b/netlink/netlink_unsupported.go @@ -59,3 +59,7 @@ func NetworkSetMaster(iface, master *net.Interface) error { func NetworkLinkDown(iface *net.Interface) error { return ErrNotImplemented } + +func CreateBridge(name string, setMacAddr bool) error { + return ErrNotImplemented +}