Embed ContainerConfig into Container.

The cluster configuration is now embedded into the container. It's
guaranteed to be correct (as in, generated by BuildContainerConfig) at
all times.

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
Andrea Luzzardi 2015-04-30 18:15:22 -07:00
parent cd3a0f03fc
commit 1d2e073813
4 changed files with 24 additions and 12 deletions

View File

@ -6,6 +6,7 @@ import "github.com/samalba/dockerclient"
type Container struct { type Container struct {
dockerclient.Container dockerclient.Container
Config *ContainerConfig
Info dockerclient.ContainerInfo Info dockerclient.ContainerInfo
Engine *Engine Engine *Engine
} }

View File

@ -247,9 +247,13 @@ func (e *Engine) updateContainer(c dockerclient.Container, containers map[string
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Convert the ContainerConfig from inspect into our own
// cluster.ContainerConfig.
container.Config = BuildContainerConfig(*info.Config)
container.Config.CpuShares = container.Config.CpuShares * 1024.0 / e.Cpus
// Save the entire inspect back into the container.
container.Info = *info container.Info = *info
// real CpuShares -> nb of CPUs
container.Info.Config.CpuShares = container.Info.Config.CpuShares * 1024.0 / e.Cpus
} }
// Update its internal state. // Update its internal state.
@ -321,7 +325,7 @@ func (e *Engine) UsedMemory() int64 {
var r int64 var r int64
e.RLock() e.RLock()
for _, c := range e.containers { for _, c := range e.containers {
r += c.Info.Config.Memory r += c.Config.Memory
} }
e.RUnlock() e.RUnlock()
return r return r
@ -332,7 +336,7 @@ func (e *Engine) UsedCpus() int64 {
var r int64 var r int64
e.RLock() e.RLock()
for _, c := range e.containers { for _, c := range e.containers {
r += c.Info.Config.CpuShares r += c.Config.CpuShares
} }
e.RUnlock() e.RUnlock()
return r return r
@ -356,12 +360,15 @@ func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool) (*
client = e.client client = e.client
) )
newConfig := *config // Convert our internal ContainerConfig into something Docker will
// understand. Start by making a copy of the internal ContainerConfig as
// we don't want to mess with the original.
dockerConfig := config.ContainerConfig
// nb of CPUs -> real CpuShares // nb of CPUs -> real CpuShares
newConfig.CpuShares = config.CpuShares * 1024 / e.Cpus dockerConfig.CpuShares = config.CpuShares * 1024 / e.Cpus
if id, err = client.CreateContainer(&newConfig.ContainerConfig, name); err != nil { if id, err = client.CreateContainer(&dockerConfig, name); err != nil {
// If the error is other than not found, abort immediately. // If the error is other than not found, abort immediately.
if err != dockerclient.ErrNotFound || !pullImage { if err != dockerclient.ErrNotFound || !pullImage {
return nil, err return nil, err
@ -371,7 +378,7 @@ func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool) (*
return nil, err return nil, err
} }
// ...And try agaie. // ...And try agaie.
if id, err = client.CreateContainer(&newConfig.ContainerConfig, name); err != nil { if id, err = client.CreateContainer(&dockerConfig, name); err != nil {
return nil, err return nil, err
} }
} }

View File

@ -72,9 +72,9 @@ func (n *Node) Container(IDOrName string) *cluster.Container {
// AddContainer inject a container into the internal state. // AddContainer inject a container into the internal state.
func (n *Node) AddContainer(container *cluster.Container) error { func (n *Node) AddContainer(container *cluster.Container) error {
if container.Info.Config != nil { if container.Config != nil {
memory := container.Info.Config.Memory memory := container.Config.Memory
cpus := container.Info.Config.CpuShares cpus := container.Config.CpuShares
if n.TotalMemory-memory < 0 || n.TotalCpus-cpus < 0 { if n.TotalMemory-memory < 0 || n.TotalCpus-cpus < 0 {
return errors.New("not enough resources") return errors.New("not enough resources")
} }

View File

@ -27,7 +27,11 @@ func createConfig(memory int64, cpus int64) *cluster.ContainerConfig {
} }
func createContainer(ID string, config *cluster.ContainerConfig) *cluster.Container { func createContainer(ID string, config *cluster.ContainerConfig) *cluster.Container {
return &cluster.Container{Container: dockerclient.Container{Id: ID}, Info: dockerclient.ContainerInfo{Config: &config.ContainerConfig}} return &cluster.Container{
Container: dockerclient.Container{Id: ID},
Config: config,
Info: dockerclient.ContainerInfo{Config: &config.ContainerConfig},
}
} }
func TestPlaceEqualWeight(t *testing.T) { func TestPlaceEqualWeight(t *testing.T) {