| ... | ... |
@@ -45,12 +45,17 @@ Sample `container.json` file: |
| 45 | 45 |
"AUDIT_WRITE", |
| 46 | 46 |
"AUDIT_CONTROL", |
| 47 | 47 |
"MAC_OVERRIDE", |
| 48 |
- "MAC_ADMIN" |
|
| 48 |
+ "MAC_ADMIN", |
|
| 49 |
+ "NET_ADMIN" |
|
| 49 | 50 |
], |
| 50 | 51 |
"network": {
|
| 52 |
+ "type": "veth", |
|
| 53 |
+ "context": {
|
|
| 54 |
+ "bridge": "docker0", |
|
| 55 |
+ "prefix": "dock" |
|
| 56 |
+ }, |
|
| 51 | 57 |
"address": "172.17.0.100/16", |
| 52 | 58 |
"gateway": "172.17.42.1", |
| 53 |
- "bridge": "docker0", |
|
| 54 | 59 |
"mtu": 1500 |
| 55 | 60 |
}, |
| 56 | 61 |
"cgroups": {
|
| ... | ... |
@@ -4,6 +4,10 @@ import ( |
| 4 | 4 |
"github.com/dotcloud/docker/pkg/cgroups" |
| 5 | 5 |
) |
| 6 | 6 |
|
| 7 |
+// Context is a generic key value pair that allows |
|
| 8 |
+// arbatrary data to be sent |
|
| 9 |
+type Context map[string]string |
|
| 10 |
+ |
|
| 7 | 11 |
// Container defines configuration options for how a |
| 8 | 12 |
// container is setup inside a directory and how a process should be executed |
| 9 | 13 |
type Container struct {
|
| ... | ... |
@@ -24,8 +28,9 @@ type Container struct {
|
| 24 | 24 |
// The network configuration can be omited from a container causing the |
| 25 | 25 |
// container to be setup with the host's networking stack |
| 26 | 26 |
type Network struct {
|
| 27 |
- Address string `json:"address,omitempty"` |
|
| 28 |
- Gateway string `json:"gateway,omitempty"` |
|
| 29 |
- Bridge string `json:"bridge,omitempty"` |
|
| 30 |
- Mtu int `json:"mtu,omitempty"` |
|
| 27 |
+ Type string `json:"type,omitempty"` // type of networking to setup i.e. veth, macvlan, etc |
|
| 28 |
+ Context Context `json:"context,omitempty"` // generic context for type specific networking options |
|
| 29 |
+ Address string `json:"address,omitempty"` |
|
| 30 |
+ Gateway string `json:"gateway,omitempty"` |
|
| 31 |
+ Mtu int `json:"mtu,omitempty"` |
|
| 31 | 32 |
} |
| ... | ... |
@@ -28,12 +28,17 @@ |
| 28 | 28 |
"AUDIT_WRITE", |
| 29 | 29 |
"AUDIT_CONTROL", |
| 30 | 30 |
"MAC_OVERRIDE", |
| 31 |
- "MAC_ADMIN" |
|
| 31 |
+ "MAC_ADMIN", |
|
| 32 |
+ "NET_ADMIN" |
|
| 32 | 33 |
], |
| 33 | 34 |
"network": {
|
| 35 |
+ "type": "veth", |
|
| 36 |
+ "context": {
|
|
| 37 |
+ "bridge": "docker0", |
|
| 38 |
+ "prefix": "dock" |
|
| 39 |
+ }, |
|
| 34 | 40 |
"address": "172.17.0.100/16", |
| 35 | 41 |
"gateway": "172.17.42.1", |
| 36 |
- "bridge": "docker0", |
|
| 37 | 42 |
"mtu": 1500 |
| 38 | 43 |
}, |
| 39 | 44 |
"cgroups": {
|
| 40 | 45 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,32 @@ |
| 0 |
+package network |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "errors" |
|
| 4 |
+ "github.com/dotcloud/docker/pkg/libcontainer" |
|
| 5 |
+) |
|
| 6 |
+ |
|
| 7 |
+var ( |
|
| 8 |
+ ErrNotValidStrategyType = errors.New("not a valid network strategy type")
|
|
| 9 |
+) |
|
| 10 |
+ |
|
| 11 |
+var strategies = map[string]NetworkStrategy{
|
|
| 12 |
+ "veth": &Veth{},
|
|
| 13 |
+} |
|
| 14 |
+ |
|
| 15 |
+// NetworkStrategy represends a specific network configuration for |
|
| 16 |
+// a containers networking stack |
|
| 17 |
+type NetworkStrategy interface {
|
|
| 18 |
+ Create(*libcontainer.Network, int) (libcontainer.Context, error) |
|
| 19 |
+ Initialize(*libcontainer.Network, libcontainer.Context) error |
|
| 20 |
+} |
|
| 21 |
+ |
|
| 22 |
+// GetStrategy returns the specific network strategy for the |
|
| 23 |
+// provided type. If no strategy is registered for the type an |
|
| 24 |
+// ErrNotValidStrategyType is returned. |
|
| 25 |
+func GetStrategy(tpe string) (NetworkStrategy, error) {
|
|
| 26 |
+ s, exists := strategies[tpe] |
|
| 27 |
+ if !exists {
|
|
| 28 |
+ return nil, ErrNotValidStrategyType |
|
| 29 |
+ } |
|
| 30 |
+ return s, nil |
|
| 31 |
+} |
| 0 | 32 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,103 @@ |
| 0 |
+package network |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "fmt" |
|
| 4 |
+ "github.com/dotcloud/docker/pkg/libcontainer" |
|
| 5 |
+ "github.com/dotcloud/docker/pkg/libcontainer/utils" |
|
| 6 |
+ "log" |
|
| 7 |
+) |
|
| 8 |
+ |
|
| 9 |
+type Veth struct {
|
|
| 10 |
+} |
|
| 11 |
+ |
|
| 12 |
+func (v *Veth) Create(n *libcontainer.Network, nspid int) (libcontainer.Context, error) {
|
|
| 13 |
+ log.Printf("creating veth network")
|
|
| 14 |
+ var ( |
|
| 15 |
+ bridge string |
|
| 16 |
+ prefix string |
|
| 17 |
+ exists bool |
|
| 18 |
+ ) |
|
| 19 |
+ if bridge, exists = n.Context["bridge"]; !exists {
|
|
| 20 |
+ return nil, fmt.Errorf("bridge does not exist in network context")
|
|
| 21 |
+ } |
|
| 22 |
+ if prefix, exists = n.Context["prefix"]; !exists {
|
|
| 23 |
+ return nil, fmt.Errorf("veth prefix does not exist in network context")
|
|
| 24 |
+ } |
|
| 25 |
+ name1, name2, err := createVethPair(prefix) |
|
| 26 |
+ if err != nil {
|
|
| 27 |
+ return nil, err |
|
| 28 |
+ } |
|
| 29 |
+ context := libcontainer.Context{
|
|
| 30 |
+ "vethHost": name1, |
|
| 31 |
+ "vethChild": name2, |
|
| 32 |
+ } |
|
| 33 |
+ log.Printf("veth pair created %s <> %s", name1, name2)
|
|
| 34 |
+ if err := SetInterfaceMaster(name1, bridge); err != nil {
|
|
| 35 |
+ return context, err |
|
| 36 |
+ } |
|
| 37 |
+ if err := SetMtu(name1, n.Mtu); err != nil {
|
|
| 38 |
+ return context, err |
|
| 39 |
+ } |
|
| 40 |
+ if err := InterfaceUp(name1); err != nil {
|
|
| 41 |
+ return context, err |
|
| 42 |
+ } |
|
| 43 |
+ log.Printf("setting %s inside %d namespace", name2, nspid)
|
|
| 44 |
+ if err := SetInterfaceInNamespacePid(name2, nspid); err != nil {
|
|
| 45 |
+ return context, err |
|
| 46 |
+ } |
|
| 47 |
+ return context, nil |
|
| 48 |
+} |
|
| 49 |
+ |
|
| 50 |
+func (v *Veth) Initialize(config *libcontainer.Network, context libcontainer.Context) error {
|
|
| 51 |
+ var ( |
|
| 52 |
+ vethChild string |
|
| 53 |
+ exists bool |
|
| 54 |
+ ) |
|
| 55 |
+ if vethChild, exists = context["vethChild"]; !exists {
|
|
| 56 |
+ return fmt.Errorf("vethChild does not exist in network context")
|
|
| 57 |
+ } |
|
| 58 |
+ if err := InterfaceDown(vethChild); err != nil {
|
|
| 59 |
+ return fmt.Errorf("interface down %s %s", vethChild, err)
|
|
| 60 |
+ } |
|
| 61 |
+ if err := ChangeInterfaceName(vethChild, "eth0"); err != nil {
|
|
| 62 |
+ return fmt.Errorf("change %s to eth0 %s", vethChild, err)
|
|
| 63 |
+ } |
|
| 64 |
+ if err := SetInterfaceIp("eth0", config.Address); err != nil {
|
|
| 65 |
+ return fmt.Errorf("set eth0 ip %s", err)
|
|
| 66 |
+ } |
|
| 67 |
+ if err := SetMtu("eth0", config.Mtu); err != nil {
|
|
| 68 |
+ return fmt.Errorf("set eth0 mtu to %d %s", config.Mtu, err)
|
|
| 69 |
+ } |
|
| 70 |
+ if err := InterfaceUp("eth0"); err != nil {
|
|
| 71 |
+ return fmt.Errorf("eth0 up %s", err)
|
|
| 72 |
+ } |
|
| 73 |
+ if err := SetMtu("lo", config.Mtu); err != nil {
|
|
| 74 |
+ return fmt.Errorf("set lo mtu to %d %s", config.Mtu, err)
|
|
| 75 |
+ } |
|
| 76 |
+ if err := InterfaceUp("lo"); err != nil {
|
|
| 77 |
+ return fmt.Errorf("lo up %s", err)
|
|
| 78 |
+ } |
|
| 79 |
+ if config.Gateway != "" {
|
|
| 80 |
+ if err := SetDefaultGateway(config.Gateway); err != nil {
|
|
| 81 |
+ return fmt.Errorf("set gateway to %s %s", config.Gateway, err)
|
|
| 82 |
+ } |
|
| 83 |
+ } |
|
| 84 |
+ return nil |
|
| 85 |
+} |
|
| 86 |
+ |
|
| 87 |
+// createVethPair will automatically generage two random names for |
|
| 88 |
+// the veth pair and ensure that they have been created |
|
| 89 |
+func createVethPair(prefix string) (name1 string, name2 string, err error) {
|
|
| 90 |
+ name1, err = utils.GenerateRandomName(prefix, 4) |
|
| 91 |
+ if err != nil {
|
|
| 92 |
+ return |
|
| 93 |
+ } |
|
| 94 |
+ name2, err = utils.GenerateRandomName(prefix, 4) |
|
| 95 |
+ if err != nil {
|
|
| 96 |
+ return |
|
| 97 |
+ } |
|
| 98 |
+ if err = CreateVethPair(name1, name2); err != nil {
|
|
| 99 |
+ return |
|
| 100 |
+ } |
|
| 101 |
+ return |
|
| 102 |
+} |
| ... | ... |
@@ -3,10 +3,10 @@ |
| 3 | 3 |
package nsinit |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
+ "encoding/json" |
|
| 6 | 7 |
"fmt" |
| 7 | 8 |
"github.com/dotcloud/docker/pkg/libcontainer" |
| 8 | 9 |
"github.com/dotcloud/docker/pkg/libcontainer/network" |
| 9 |
- "github.com/dotcloud/docker/pkg/libcontainer/utils" |
|
| 10 | 10 |
"github.com/dotcloud/docker/pkg/system" |
| 11 | 11 |
"github.com/dotcloud/docker/pkg/term" |
| 12 | 12 |
"io" |
| ... | ... |
@@ -19,11 +19,11 @@ import ( |
| 19 | 19 |
|
| 20 | 20 |
// Exec performes setup outside of a namespace so that a container can be |
| 21 | 21 |
// executed. Exec is a high level function for working with container namespaces. |
| 22 |
-func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io.Writer, master *os.File, logFile string, args []string) (int, error) {
|
|
| 22 |
+func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io.Writer, |
|
| 23 |
+ master *os.File, logFile string, args []string) (int, error) {
|
|
| 23 | 24 |
var ( |
| 24 |
- console string |
|
| 25 |
- err error |
|
| 26 |
- |
|
| 25 |
+ console string |
|
| 26 |
+ err error |
|
| 27 | 27 |
inPipe io.WriteCloser |
| 28 | 28 |
outPipe, errPipe io.ReadCloser |
| 29 | 29 |
) |
| ... | ... |
@@ -46,7 +46,7 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io. |
| 46 | 46 |
|
| 47 | 47 |
command := CreateCommand(container, console, logFile, r.Fd(), args) |
| 48 | 48 |
if !container.Tty {
|
| 49 |
- log.Printf("opening pipes on command")
|
|
| 49 |
+ log.Printf("opening std pipes")
|
|
| 50 | 50 |
if inPipe, err = command.StdinPipe(); err != nil {
|
| 51 | 51 |
return -1, err |
| 52 | 52 |
} |
| ... | ... |
@@ -78,15 +78,9 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io. |
| 78 | 78 |
return -1, err |
| 79 | 79 |
} |
| 80 | 80 |
} |
| 81 |
- |
|
| 82 |
- if container.Network != nil {
|
|
| 83 |
- log.Printf("creating veth pair")
|
|
| 84 |
- vethPair, err := InitializeContainerVeth(container.Network.Bridge, container.Network.Mtu, command.Process.Pid) |
|
| 85 |
- if err != nil {
|
|
| 86 |
- return -1, err |
|
| 87 |
- } |
|
| 88 |
- log.Printf("sending %s as veth pair name", vethPair)
|
|
| 89 |
- SendVethName(w, vethPair) |
|
| 81 |
+ if err := InitializeNetworking(container, command.Process.Pid, w); err != nil {
|
|
| 82 |
+ command.Process.Kill() |
|
| 83 |
+ return -1, err |
|
| 90 | 84 |
} |
| 91 | 85 |
|
| 92 | 86 |
// Sync with child |
| ... | ... |
@@ -104,7 +98,7 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io. |
| 104 | 104 |
command.Process.Kill() |
| 105 | 105 |
return -1, err |
| 106 | 106 |
} |
| 107 |
- defer term.RestoreTerminal(uintptr(syscall.Stdin), state) |
|
| 107 |
+ defer term.RestoreTerminal(os.Stdin.Fd(), state) |
|
| 108 | 108 |
} else {
|
| 109 | 109 |
log.Printf("starting copy for std pipes")
|
| 110 | 110 |
go func() {
|
| ... | ... |
@@ -125,39 +119,34 @@ func Exec(container *libcontainer.Container, stdin io.Reader, stdout, stderr io. |
| 125 | 125 |
return command.ProcessState.Sys().(syscall.WaitStatus).ExitStatus(), nil |
| 126 | 126 |
} |
| 127 | 127 |
|
| 128 |
-// SendVethName writes the veth pair name to the child's stdin then closes the |
|
| 129 |
-// pipe so that the child stops waiting for more data |
|
| 130 |
-func SendVethName(pipe io.Writer, name string) {
|
|
| 131 |
- fmt.Fprint(pipe, name) |
|
| 128 |
+func InitializeNetworking(container *libcontainer.Container, nspid int, pipe io.Writer) error {
|
|
| 129 |
+ if container.Network != nil {
|
|
| 130 |
+ log.Printf("creating host network configuration type %s", container.Network.Type)
|
|
| 131 |
+ strategy, err := network.GetStrategy(container.Network.Type) |
|
| 132 |
+ if err != nil {
|
|
| 133 |
+ return err |
|
| 134 |
+ } |
|
| 135 |
+ networkContext, err := strategy.Create(container.Network, nspid) |
|
| 136 |
+ if err != nil {
|
|
| 137 |
+ return err |
|
| 138 |
+ } |
|
| 139 |
+ log.Printf("sending %v as network context", networkContext)
|
|
| 140 |
+ if err := SendContext(pipe, networkContext); err != nil {
|
|
| 141 |
+ return err |
|
| 142 |
+ } |
|
| 143 |
+ } |
|
| 144 |
+ return nil |
|
| 132 | 145 |
} |
| 133 | 146 |
|
| 134 |
-// initializeContainerVeth will create a veth pair and setup the host's |
|
| 135 |
-// side of the pair by setting the specified bridge as the master and bringing |
|
| 136 |
-// up the interface. |
|
| 137 |
-// |
|
| 138 |
-// Then will with set the other side of the veth pair into the container's namespaced |
|
| 139 |
-// using the pid and returns the veth's interface name to provide to the container to |
|
| 140 |
-// finish setting up the interface inside the namespace |
|
| 141 |
-func InitializeContainerVeth(bridge string, mtu, nspid int) (string, error) {
|
|
| 142 |
- name1, name2, err := createVethPair() |
|
| 147 |
+// SendContext writes the veth pair name to the child's stdin then closes the |
|
| 148 |
+// pipe so that the child stops waiting for more data |
|
| 149 |
+func SendContext(pipe io.Writer, context libcontainer.Context) error {
|
|
| 150 |
+ data, err := json.Marshal(context) |
|
| 143 | 151 |
if err != nil {
|
| 144 |
- return "", err |
|
| 145 |
- } |
|
| 146 |
- log.Printf("veth pair created %s <> %s", name1, name2)
|
|
| 147 |
- if err := network.SetInterfaceMaster(name1, bridge); err != nil {
|
|
| 148 |
- return "", err |
|
| 149 |
- } |
|
| 150 |
- if err := network.SetMtu(name1, mtu); err != nil {
|
|
| 151 |
- return "", err |
|
| 152 |
- } |
|
| 153 |
- if err := network.InterfaceUp(name1); err != nil {
|
|
| 154 |
- return "", err |
|
| 155 |
- } |
|
| 156 |
- log.Printf("setting %s inside %d namespace", name2, nspid)
|
|
| 157 |
- if err := network.SetInterfaceInNamespacePid(name2, nspid); err != nil {
|
|
| 158 |
- return "", err |
|
| 152 |
+ return err |
|
| 159 | 153 |
} |
| 160 |
- return name2, nil |
|
| 154 |
+ pipe.Write(data) |
|
| 155 |
+ return nil |
|
| 161 | 156 |
} |
| 162 | 157 |
|
| 163 | 158 |
// SetupWindow gets the parent window size and sets the master |
| ... | ... |
@@ -190,29 +179,13 @@ func CreateMasterAndConsole() (*os.File, string, error) {
|
| 190 | 190 |
return master, console, nil |
| 191 | 191 |
} |
| 192 | 192 |
|
| 193 |
-// createVethPair will automatically generage two random names for |
|
| 194 |
-// the veth pair and ensure that they have been created |
|
| 195 |
-func createVethPair() (name1 string, name2 string, err error) {
|
|
| 196 |
- name1, err = utils.GenerateRandomName("dock", 4)
|
|
| 197 |
- if err != nil {
|
|
| 198 |
- return |
|
| 199 |
- } |
|
| 200 |
- name2, err = utils.GenerateRandomName("dock", 4)
|
|
| 201 |
- if err != nil {
|
|
| 202 |
- return |
|
| 203 |
- } |
|
| 204 |
- if err = network.CreateVethPair(name1, name2); err != nil {
|
|
| 205 |
- return |
|
| 206 |
- } |
|
| 207 |
- return |
|
| 208 |
-} |
|
| 209 |
- |
|
| 210 | 193 |
// writePidFile writes the namespaced processes pid to .nspid in the rootfs for the container |
| 211 | 194 |
func writePidFile(command *exec.Cmd) error {
|
| 212 | 195 |
return ioutil.WriteFile(".nspid", []byte(fmt.Sprint(command.Process.Pid)), 0655)
|
| 213 | 196 |
} |
| 214 | 197 |
|
| 215 | 198 |
func deletePidFile() error {
|
| 199 |
+ log.Printf("removing .nspid file")
|
|
| 216 | 200 |
return os.Remove(".nspid")
|
| 217 | 201 |
} |
| 218 | 202 |
|
| ... | ... |
@@ -3,6 +3,7 @@ |
| 3 | 3 |
package nsinit |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
+ "encoding/json" |
|
| 6 | 7 |
"fmt" |
| 7 | 8 |
"github.com/dotcloud/docker/pkg/libcontainer" |
| 8 | 9 |
"github.com/dotcloud/docker/pkg/libcontainer/capabilities" |
| ... | ... |
@@ -27,13 +28,10 @@ func Init(container *libcontainer.Container, uncleanRootfs, console string, pipe |
| 27 | 27 |
log.Printf("initializing namespace at %s", rootfs)
|
| 28 | 28 |
|
| 29 | 29 |
// We always read this as it is a way to sync with the parent as well |
| 30 |
- tempVethName, err := getVethName(pipe) |
|
| 30 |
+ context, err := GetContextFromParent(pipe) |
|
| 31 | 31 |
if err != nil {
|
| 32 | 32 |
return err |
| 33 | 33 |
} |
| 34 |
- if tempVethName != "" {
|
|
| 35 |
- log.Printf("received veth name %s", tempVethName)
|
|
| 36 |
- } |
|
| 37 | 34 |
if console != "" {
|
| 38 | 35 |
log.Printf("setting up console for %s", console)
|
| 39 | 36 |
// close pipes so that we can replace it with the pty |
| ... | ... |
@@ -62,7 +60,7 @@ func Init(container *libcontainer.Container, uncleanRootfs, console string, pipe |
| 62 | 62 |
if err := setupNewMountNamespace(rootfs, console, container.ReadonlyFs); err != nil {
|
| 63 | 63 |
return fmt.Errorf("setup mount namespace %s", err)
|
| 64 | 64 |
} |
| 65 |
- if err := setupVethNetwork(container.Network, tempVethName); err != nil {
|
|
| 65 |
+ if err := setupNetwork(container.Network, context); err != nil {
|
|
| 66 | 66 |
return fmt.Errorf("setup networking %s", err)
|
| 67 | 67 |
} |
| 68 | 68 |
if err := system.Sethostname(container.Hostname); err != nil {
|
| ... | ... |
@@ -145,46 +143,29 @@ func openTerminal(name string, flag int) (*os.File, error) {
|
| 145 | 145 |
// setupVethNetwork uses the Network config if it is not nil to initialize |
| 146 | 146 |
// the new veth interface inside the container for use by changing the name to eth0 |
| 147 | 147 |
// setting the MTU and IP address along with the default gateway |
| 148 |
-func setupVethNetwork(config *libcontainer.Network, tempVethName string) error {
|
|
| 148 |
+func setupNetwork(config *libcontainer.Network, context libcontainer.Context) error {
|
|
| 149 | 149 |
if config != nil {
|
| 150 |
- if err := network.InterfaceDown(tempVethName); err != nil {
|
|
| 151 |
- return fmt.Errorf("interface down %s %s", tempVethName, err)
|
|
| 152 |
- } |
|
| 153 |
- if err := network.ChangeInterfaceName(tempVethName, "eth0"); err != nil {
|
|
| 154 |
- return fmt.Errorf("change %s to eth0 %s", tempVethName, err)
|
|
| 155 |
- } |
|
| 156 |
- if err := network.SetInterfaceIp("eth0", config.Address); err != nil {
|
|
| 157 |
- return fmt.Errorf("set eth0 ip %s", err)
|
|
| 158 |
- } |
|
| 159 |
- if err := network.SetMtu("eth0", config.Mtu); err != nil {
|
|
| 160 |
- return fmt.Errorf("set eth0 mtu to %d %s", config.Mtu, err)
|
|
| 161 |
- } |
|
| 162 |
- if err := network.InterfaceUp("eth0"); err != nil {
|
|
| 163 |
- return fmt.Errorf("eth0 up %s", err)
|
|
| 164 |
- } |
|
| 165 |
- if err := network.SetMtu("lo", config.Mtu); err != nil {
|
|
| 166 |
- return fmt.Errorf("set lo mtu to %d %s", config.Mtu, err)
|
|
| 167 |
- } |
|
| 168 |
- if err := network.InterfaceUp("lo"); err != nil {
|
|
| 169 |
- return fmt.Errorf("lo up %s", err)
|
|
| 170 |
- } |
|
| 171 |
- if config.Gateway != "" {
|
|
| 172 |
- if err := network.SetDefaultGateway(config.Gateway); err != nil {
|
|
| 173 |
- return fmt.Errorf("set gateway to %s %s", config.Gateway, err)
|
|
| 174 |
- } |
|
| 150 |
+ strategy, err := network.GetStrategy(config.Type) |
|
| 151 |
+ if err != nil {
|
|
| 152 |
+ return err |
|
| 175 | 153 |
} |
| 154 |
+ return strategy.Initialize(config, context) |
|
| 176 | 155 |
} |
| 177 | 156 |
return nil |
| 178 | 157 |
} |
| 179 | 158 |
|
| 180 |
-// getVethName reads from Stdin the temp veth name |
|
| 181 |
-// sent by the parent processes after the veth pair |
|
| 182 |
-// has been created and setup |
|
| 183 |
-func getVethName(pipe io.ReadCloser) (string, error) {
|
|
| 159 |
+func GetContextFromParent(pipe io.ReadCloser) (libcontainer.Context, error) {
|
|
| 184 | 160 |
defer pipe.Close() |
| 185 | 161 |
data, err := ioutil.ReadAll(pipe) |
| 186 | 162 |
if err != nil {
|
| 187 |
- return "", fmt.Errorf("error reading from stdin %s", err)
|
|
| 163 |
+ return nil, fmt.Errorf("error reading from stdin %s", err)
|
|
| 164 |
+ } |
|
| 165 |
+ var context libcontainer.Context |
|
| 166 |
+ if len(data) > 0 {
|
|
| 167 |
+ if err := json.Unmarshal(data, &context); err != nil {
|
|
| 168 |
+ return nil, err |
|
| 169 |
+ } |
|
| 170 |
+ log.Printf("received context %v", context)
|
|
| 188 | 171 |
} |
| 189 |
- return string(data), nil |
|
| 172 |
+ return context, nil |
|
| 190 | 173 |
} |