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 {
dockerclient.Container
Config *ContainerConfig
Info dockerclient.ContainerInfo
Engine *Engine
}

View File

@ -247,9 +247,13 @@ func (e *Engine) updateContainer(c dockerclient.Container, containers map[string
if err != nil {
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
// real CpuShares -> nb of CPUs
container.Info.Config.CpuShares = container.Info.Config.CpuShares * 1024.0 / e.Cpus
}
// Update its internal state.
@ -321,7 +325,7 @@ func (e *Engine) UsedMemory() int64 {
var r int64
e.RLock()
for _, c := range e.containers {
r += c.Info.Config.Memory
r += c.Config.Memory
}
e.RUnlock()
return r
@ -332,7 +336,7 @@ func (e *Engine) UsedCpus() int64 {
var r int64
e.RLock()
for _, c := range e.containers {
r += c.Info.Config.CpuShares
r += c.Config.CpuShares
}
e.RUnlock()
return r
@ -356,12 +360,15 @@ func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool) (*
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
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 err != dockerclient.ErrNotFound || !pullImage {
return nil, err
@ -371,7 +378,7 @@ func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool) (*
return nil, err
}
// ...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
}
}

View File

@ -72,9 +72,9 @@ func (n *Node) Container(IDOrName string) *cluster.Container {
// AddContainer inject a container into the internal state.
func (n *Node) AddContainer(container *cluster.Container) error {
if container.Info.Config != nil {
memory := container.Info.Config.Memory
cpus := container.Info.Config.CpuShares
if container.Config != nil {
memory := container.Config.Memory
cpus := container.Config.CpuShares
if n.TotalMemory-memory < 0 || n.TotalCpus-cpus < 0 {
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 {
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) {