Browse code

Container can now take a list of ports to expose in its config

Andrea Luzzardi authored on 2013/03/01 04:51:14
Showing 2 changed files
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"os"
12 12
 	"os/exec"
13 13
 	"path"
14
+	"strconv"
14 15
 	"strings"
15 16
 	"syscall"
16 17
 	"time"
... ...
@@ -35,9 +36,9 @@ type Container struct {
35 35
 	Filesystem *Filesystem
36 36
 	State      *State
37 37
 
38
-	network          *NetworkInterface
39
-	networkAllocator *NetworkAllocator
40
-	NetworkConfig    *NetworkConfig
38
+	network         *NetworkInterface
39
+	networkManager  *NetworkManager
40
+	NetworkSettings *NetworkSettings
41 41
 
42 42
 	SysInitPath   string
43 43
 	lxcConfigPath string
... ...
@@ -55,34 +56,36 @@ type Config struct {
55 55
 	Hostname  string
56 56
 	User      string
57 57
 	Ram       int64
58
+	Ports     []int
58 59
 	Tty       bool // Attach standard streams to a tty, including stdin if it is not closed.
59 60
 	OpenStdin bool // Open stdin
60 61
 }
61 62
 
62
-type NetworkConfig struct {
63
+type NetworkSettings struct {
63 64
 	IpAddress   string
64 65
 	IpPrefixLen int
66
+	Gateway     string
67
+	PortMapping map[string]string
65 68
 }
66 69
 
67
-func createContainer(id string, root string, command string, args []string, layers []string, config *Config, netAllocator *NetworkAllocator) (*Container, error) {
70
+func createContainer(id string, root string, command string, args []string, layers []string, config *Config, netManager *NetworkManager) (*Container, error) {
68 71
 	container := &Container{
69
-		Id:               id,
70
-		Root:             root,
71
-		Created:          time.Now(),
72
-		Path:             command,
73
-		Args:             args,
74
-		Config:           config,
75
-		Filesystem:       newFilesystem(path.Join(root, "rootfs"), path.Join(root, "rw"), layers),
76
-		State:            newState(),
77
-		networkAllocator: netAllocator,
78
-		NetworkConfig:    &NetworkConfig{},
79
-
80
-		SysInitPath:   sysInitPath,
81
-		lxcConfigPath: path.Join(root, "config.lxc"),
82
-		stdout:        newWriteBroadcaster(),
83
-		stderr:        newWriteBroadcaster(),
84
-		stdoutLog:     new(bytes.Buffer),
85
-		stderrLog:     new(bytes.Buffer),
72
+		Id:              id,
73
+		Root:            root,
74
+		Created:         time.Now(),
75
+		Path:            command,
76
+		Args:            args,
77
+		Config:          config,
78
+		Filesystem:      newFilesystem(path.Join(root, "rootfs"), path.Join(root, "rw"), layers),
79
+		State:           newState(),
80
+		networkManager:  netManager,
81
+		NetworkSettings: &NetworkSettings{},
82
+		SysInitPath:     sysInitPath,
83
+		lxcConfigPath:   path.Join(root, "config.lxc"),
84
+		stdout:          newWriteBroadcaster(),
85
+		stderr:          newWriteBroadcaster(),
86
+		stdoutLog:       new(bytes.Buffer),
87
+		stderrLog:       new(bytes.Buffer),
86 88
 	}
87 89
 	if container.Config.OpenStdin {
88 90
 		container.stdin, container.stdinPipe = io.Pipe()
... ...
@@ -104,19 +107,19 @@ func createContainer(id string, root string, command string, args []string, laye
104 104
 	return container, nil
105 105
 }
106 106
 
107
-func loadContainer(containerPath string, netAllocator *NetworkAllocator) (*Container, error) {
107
+func loadContainer(containerPath string, netManager *NetworkManager) (*Container, error) {
108 108
 	data, err := ioutil.ReadFile(path.Join(containerPath, "config.json"))
109 109
 	if err != nil {
110 110
 		return nil, err
111 111
 	}
112 112
 	container := &Container{
113
-		stdout:           newWriteBroadcaster(),
114
-		stderr:           newWriteBroadcaster(),
115
-		stdoutLog:        new(bytes.Buffer),
116
-		stderrLog:        new(bytes.Buffer),
117
-		lxcConfigPath:    path.Join(containerPath, "config.lxc"),
118
-		networkAllocator: netAllocator,
119
-		NetworkConfig:    &NetworkConfig{},
113
+		stdout:          newWriteBroadcaster(),
114
+		stderr:          newWriteBroadcaster(),
115
+		stdoutLog:       new(bytes.Buffer),
116
+		stderrLog:       new(bytes.Buffer),
117
+		lxcConfigPath:   path.Join(containerPath, "config.lxc"),
118
+		networkManager:  netManager,
119
+		NetworkSettings: &NetworkSettings{},
120 120
 	}
121 121
 	if err := json.Unmarshal(data, container); err != nil {
122 122
 		return nil, err
... ...
@@ -368,20 +371,30 @@ func (container *Container) StderrLog() io.Reader {
368 368
 }
369 369
 
370 370
 func (container *Container) allocateNetwork() error {
371
-	iface, err := container.networkAllocator.Allocate()
371
+	iface, err := container.networkManager.Allocate()
372 372
 	if err != nil {
373 373
 		return err
374 374
 	}
375
+	container.NetworkSettings.PortMapping = make(map[string]string)
376
+	for _, port := range container.Config.Ports {
377
+		if extPort, err := iface.AllocatePort(port); err != nil {
378
+			iface.Release()
379
+			return err
380
+		} else {
381
+			container.NetworkSettings.PortMapping[strconv.Itoa(port)] = strconv.Itoa(extPort)
382
+		}
383
+	}
375 384
 	container.network = iface
376
-	container.NetworkConfig.IpAddress = iface.IPNet.IP.String()
377
-	container.NetworkConfig.IpPrefixLen, _ = iface.IPNet.Mask.Size()
385
+	container.NetworkSettings.IpAddress = iface.IPNet.IP.String()
386
+	container.NetworkSettings.IpPrefixLen, _ = iface.IPNet.Mask.Size()
387
+	container.NetworkSettings.Gateway = iface.Gateway.String()
378 388
 	return nil
379 389
 }
380 390
 
381 391
 func (container *Container) releaseNetwork() error {
382
-	err := container.networkAllocator.Release(container.network)
392
+	err := container.network.Release()
383 393
 	container.network = nil
384
-	container.NetworkConfig = &NetworkConfig{}
394
+	container.NetworkSettings = &NetworkSettings{}
385 395
 	return err
386 396
 }
387 397
 
... ...
@@ -19,7 +19,7 @@ lxc.network.flags = up
19 19
 lxc.network.link = lxcbr0
20 20
 lxc.network.name = eth0
21 21
 lxc.network.mtu = 1500
22
-lxc.network.ipv4 = {{.NetworkConfig.IpAddress}}/{{.NetworkConfig.IpPrefixLen}}
22
+lxc.network.ipv4 = {{.NetworkSettings.IpAddress}}/{{.NetworkSettings.IpPrefixLen}}
23 23
 
24 24
 # root filesystem
25 25
 {{$ROOTFS := .Filesystem.RootFS}}