mirror of https://github.com/docker/docs.git
Updating ContainerConfig to use engine-api
Signed-off-by: Nishant Totla <nishanttotla@gmail.com>
This commit is contained in:
parent
a6c1f1463c
commit
79575f3df6
|
@ -388,7 +388,7 @@ func getContainersJSON(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
} else if len(filters.Get("name")) > 0 {
|
} else if len(filters.Get("name")) > 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !filters.Match("id", container.Id) {
|
if !filters.Match("id", container.ID) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !filters.MatchKVList("label", container.Config.Labels) {
|
if !filters.MatchKVList("label", container.Config.Labels) {
|
||||||
|
@ -427,7 +427,7 @@ func getContainersJSON(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
out := []*dockerclient.Container{}
|
out := []*dockerclient.Container{}
|
||||||
for _, container := range candidates {
|
for _, container := range candidates {
|
||||||
if before != nil {
|
if before != nil {
|
||||||
if container.Id == before.Id {
|
if container.ID == before.ID {
|
||||||
before = nil
|
before = nil
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
@ -490,7 +490,7 @@ func getContainerJSON(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := client.Get(scheme + "://" + container.Engine.Addr + "/containers/" + container.Id + "/json")
|
resp, err := client.Get(scheme + "://" + container.Engine.Addr + "/containers/" + container.ID + "/json")
|
||||||
container.Engine.CheckConnectionErr(err)
|
container.Engine.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
@ -526,12 +526,17 @@ func getContainerJSON(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
func postContainersCreate(c *context, w http.ResponseWriter, r *http.Request) {
|
func postContainersCreate(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
var (
|
var (
|
||||||
config = dockerclient.ContainerConfig{
|
oldConfig = dockerclient.ContainerConfig{
|
||||||
HostConfig: dockerclient.HostConfig{
|
HostConfig: dockerclient.HostConfig{
|
||||||
MemorySwappiness: -1,
|
MemorySwappiness: -1,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
name = r.Form.Get("name")
|
name = r.Form.Get("name")
|
||||||
|
config = cluster.ContainerConfig{
|
||||||
|
HostConfig: containertypes.HostConfig{
|
||||||
|
MemorySwappiness: -1,
|
||||||
|
},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&config); err != nil {
|
||||||
|
@ -539,13 +544,13 @@ func postContainersCreate(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Pass auth information along if present
|
// Pass auth information along if present
|
||||||
var authConfig *dockerclient.AuthConfig
|
var authConfig *apitypes.AuthConfig
|
||||||
buf, err := base64.URLEncoding.DecodeString(r.Header.Get("X-Registry-Auth"))
|
buf, err := base64.URLEncoding.DecodeString(r.Header.Get("X-Registry-Auth"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
authConfig = &dockerclient.AuthConfig{}
|
authConfig = &apitypes.AuthConfig{}
|
||||||
json.Unmarshal(buf, authConfig)
|
json.Unmarshal(buf, authConfig)
|
||||||
}
|
}
|
||||||
containerConfig := cluster.BuildContainerConfig(config)
|
containerConfig := cluster.BuildContainerConfig(config.Config, config.HostConfig, config.NetworkingConfig)
|
||||||
if err := containerConfig.Validate(); err != nil {
|
if err := containerConfig.Validate(); err != nil {
|
||||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
@ -563,7 +568,7 @@ func postContainersCreate(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
w.WriteHeader(http.StatusCreated)
|
w.WriteHeader(http.StatusCreated)
|
||||||
fmt.Fprintf(w, "{%q:%q}", "Id", container.Id)
|
fmt.Fprintf(w, "{%q:%q}", "Id", container.ID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -820,7 +825,7 @@ func postContainersExec(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := client.Post(scheme+"://"+container.Engine.Addr+"/containers/"+container.Id+"/exec", "application/json", r.Body)
|
resp, err := client.Post(scheme+"://"+container.Engine.Addr+"/containers/"+container.ID+"/exec", "application/json", r.Body)
|
||||||
container.Engine.CheckConnectionErr(err)
|
container.Engine.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(w, err.Error(), http.StatusInternalServerError)
|
httpError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
@ -1044,7 +1049,7 @@ func proxyContainer(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// Set the full container ID in the proxied URL path.
|
// Set the full container ID in the proxied URL path.
|
||||||
if name != "" {
|
if name != "" {
|
||||||
r.URL.Path = strings.Replace(r.URL.Path, name, container.Id, 1)
|
r.URL.Path = strings.Replace(r.URL.Path, name, container.ID, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = proxy(container.Engine, w, r)
|
err = proxy(container.Engine, w, r)
|
||||||
|
@ -1067,7 +1072,7 @@ func proxyContainerAndForceRefresh(c *context, w http.ResponseWriter, r *http.Re
|
||||||
|
|
||||||
// Set the full container ID in the proxied URL path.
|
// Set the full container ID in the proxied URL path.
|
||||||
if name != "" {
|
if name != "" {
|
||||||
r.URL.Path = strings.Replace(r.URL.Path, name, container.Id, 1)
|
r.URL.Path = strings.Replace(r.URL.Path, name, container.ID, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
cb := func(resp *http.Response) {
|
cb := func(resp *http.Response) {
|
||||||
|
@ -1200,7 +1205,7 @@ func postCommit(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
// Set the full container ID in the proxied URL path.
|
// Set the full container ID in the proxied URL path.
|
||||||
if name != "" {
|
if name != "" {
|
||||||
r.URL.RawQuery = strings.Replace(r.URL.RawQuery, name, container.Id, 1)
|
r.URL.RawQuery = strings.Replace(r.URL.RawQuery, name, container.ID, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
cb := func(resp *http.Response) {
|
cb := func(resp *http.Response) {
|
||||||
|
@ -1317,7 +1322,7 @@ func proxyHijack(c *context, w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
// Set the full container ID in the proxied URL path.
|
// Set the full container ID in the proxied URL path.
|
||||||
if name != "" {
|
if name != "" {
|
||||||
r.URL.Path = strings.Replace(r.URL.Path, name, container.Id, 1)
|
r.URL.Path = strings.Replace(r.URL.Path, name, container.ID, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = hijack(c.tlsConfig, container.Engine.Addr, w, r)
|
err = hijack(c.tlsConfig, container.Engine.Addr, w, r)
|
||||||
|
|
|
@ -6,7 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/samalba/dockerclient"
|
"github.com/docker/engine-api/types/container"
|
||||||
|
"github.com/docker/engine-api/types/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SwarmLabelNamespace defines the key prefix in all custom labels
|
// SwarmLabelNamespace defines the key prefix in all custom labels
|
||||||
|
@ -15,7 +16,10 @@ const SwarmLabelNamespace = "com.docker.swarm"
|
||||||
// ContainerConfig is exported
|
// ContainerConfig is exported
|
||||||
// TODO store affinities and constraints in their own fields
|
// TODO store affinities and constraints in their own fields
|
||||||
type ContainerConfig struct {
|
type ContainerConfig struct {
|
||||||
dockerclient.ContainerConfig
|
// dockerclient.ContainerConfig
|
||||||
|
container.Config
|
||||||
|
container.HostConfig
|
||||||
|
network.NetworkingConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseEnv(e string) (bool, string, string) {
|
func parseEnv(e string) (bool, string, string) {
|
||||||
|
@ -26,44 +30,8 @@ func parseEnv(e string) (bool, string, string) {
|
||||||
return false, "", ""
|
return false, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Temporary fix to handle forward/backward compatibility between Docker <1.6 and >=1.7
|
// BuildContainerConfig creates a cluster.ContainerConfig from a Config, HostConfig, and NetworkingConfig
|
||||||
// ContainerConfig should be handling converting to/from different docker versions
|
func BuildContainerConfig(c container.Config, h container.HostConfig, n network.NetworkingConfig) *ContainerConfig {
|
||||||
func consolidateResourceFields(c *dockerclient.ContainerConfig) {
|
|
||||||
if c.Memory != c.HostConfig.Memory {
|
|
||||||
if c.Memory != 0 {
|
|
||||||
c.HostConfig.Memory = c.Memory
|
|
||||||
} else {
|
|
||||||
c.Memory = c.HostConfig.Memory
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.MemorySwap != c.HostConfig.MemorySwap {
|
|
||||||
if c.MemorySwap != 0 {
|
|
||||||
c.HostConfig.MemorySwap = c.MemorySwap
|
|
||||||
} else {
|
|
||||||
c.MemorySwap = c.HostConfig.MemorySwap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.CpuShares != c.HostConfig.CpuShares {
|
|
||||||
if c.CpuShares != 0 {
|
|
||||||
c.HostConfig.CpuShares = c.CpuShares
|
|
||||||
} else {
|
|
||||||
c.CpuShares = c.HostConfig.CpuShares
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Cpuset != c.HostConfig.CpusetCpus {
|
|
||||||
if c.Cpuset != "" {
|
|
||||||
c.HostConfig.CpusetCpus = c.Cpuset
|
|
||||||
} else {
|
|
||||||
c.Cpuset = c.HostConfig.CpusetCpus
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuildContainerConfig creates a cluster.ContainerConfig from a dockerclient.ContainerConfig
|
|
||||||
func BuildContainerConfig(c dockerclient.ContainerConfig) *ContainerConfig {
|
|
||||||
var (
|
var (
|
||||||
affinities []string
|
affinities []string
|
||||||
constraints []string
|
constraints []string
|
||||||
|
@ -128,9 +96,7 @@ func BuildContainerConfig(c dockerclient.ContainerConfig) *ContainerConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
consolidateResourceFields(&c)
|
return &ContainerConfig{c, h, n}
|
||||||
|
|
||||||
return &ContainerConfig{c}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ContainerConfig) extractExprs(key string) []string {
|
func (c *ContainerConfig) extractExprs(key string) []string {
|
||||||
|
|
|
@ -4,21 +4,21 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/pkg/stringid"
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/samalba/dockerclient"
|
"github.com/docker/engine-api/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Container is exported
|
// Container is exported
|
||||||
type Container struct {
|
type Container struct {
|
||||||
dockerclient.Container
|
types.Container
|
||||||
|
|
||||||
Config *ContainerConfig
|
Config *ContainerConfig
|
||||||
Info dockerclient.ContainerInfo
|
Info types.ContainerJSON
|
||||||
Engine *Engine
|
Engine *Engine
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh container
|
// Refresh container
|
||||||
func (c *Container) Refresh() (*Container, error) {
|
func (c *Container) Refresh() (*Container, error) {
|
||||||
return c.Engine.refreshContainer(c.Id, true)
|
return c.Engine.refreshContainer(c.ID, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Containers represents a list of containers
|
// Containers represents a list of containers
|
||||||
|
@ -33,7 +33,7 @@ func (containers Containers) Get(IDOrName string) *Container {
|
||||||
|
|
||||||
// Match exact or short Container ID.
|
// Match exact or short Container ID.
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
if container.Id == IDOrName || stringid.TruncateID(container.Id) == IDOrName {
|
if container.ID == IDOrName || stringid.TruncateID(container.ID) == IDOrName {
|
||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ func (containers Containers) Get(IDOrName string) *Container {
|
||||||
|
|
||||||
// Match Container ID prefix.
|
// Match Container ID prefix.
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
if strings.HasPrefix(container.Id, IDOrName) {
|
if strings.HasPrefix(container.ID, IDOrName) {
|
||||||
candidates = append(candidates, container)
|
candidates = append(candidates, container)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
engineapi "github.com/docker/engine-api/client"
|
engineapi "github.com/docker/engine-api/client"
|
||||||
"github.com/docker/engine-api/types"
|
"github.com/docker/engine-api/types"
|
||||||
"github.com/docker/engine-api/types/filters"
|
"github.com/docker/engine-api/types/filters"
|
||||||
|
networktypes "github.com/docker/engine-api/types/network"
|
||||||
engineapinop "github.com/docker/swarm/api/nopclient"
|
engineapinop "github.com/docker/swarm/api/nopclient"
|
||||||
"github.com/samalba/dockerclient"
|
"github.com/samalba/dockerclient"
|
||||||
"github.com/samalba/dockerclient/nopclient"
|
"github.com/samalba/dockerclient/nopclient"
|
||||||
|
@ -627,7 +628,11 @@ func (e *Engine) RefreshVolumes() error {
|
||||||
// true, each container will be inspected.
|
// true, each container will be inspected.
|
||||||
// FIXME: unexport this method after mesos scheduler stops using it directly
|
// FIXME: unexport this method after mesos scheduler stops using it directly
|
||||||
func (e *Engine) RefreshContainers(full bool) error {
|
func (e *Engine) RefreshContainers(full bool) error {
|
||||||
containers, err := e.client.ListContainers(true, false, "")
|
opts := types.ContainerListOptions{
|
||||||
|
All: true,
|
||||||
|
Size: false,
|
||||||
|
}
|
||||||
|
containers, err := e.apiClient.ContainerList(opts)
|
||||||
e.CheckConnectionErr(err)
|
e.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -637,7 +642,7 @@ func (e *Engine) RefreshContainers(full bool) error {
|
||||||
for _, c := range containers {
|
for _, c := range containers {
|
||||||
mergedUpdate, err := e.updateContainer(c, merged, full)
|
mergedUpdate, err := e.updateContainer(c, merged, full)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{"name": e.Name, "id": e.ID}).Errorf("Unable to update state of container %q: %v", c.Id, err)
|
log.WithFields(log.Fields{"name": e.Name, "id": e.ID}).Errorf("Unable to update state of container %q: %v", c.ID, err)
|
||||||
} else {
|
} else {
|
||||||
merged = mergedUpdate
|
merged = mergedUpdate
|
||||||
}
|
}
|
||||||
|
@ -653,7 +658,14 @@ func (e *Engine) RefreshContainers(full bool) error {
|
||||||
// Refresh the status of a container running on the engine. If `full` is true,
|
// Refresh the status of a container running on the engine. If `full` is true,
|
||||||
// the container will be inspected.
|
// the container will be inspected.
|
||||||
func (e *Engine) refreshContainer(ID string, full bool) (*Container, error) {
|
func (e *Engine) refreshContainer(ID string, full bool) (*Container, error) {
|
||||||
containers, err := e.client.ListContainers(true, false, fmt.Sprintf("{%q:[%q]}", "id", ID))
|
filterArgs := filters.NewArgs()
|
||||||
|
filterArgs.Add("id", ID)
|
||||||
|
opts := types.ContainerListOptions{
|
||||||
|
All: true,
|
||||||
|
Size: false,
|
||||||
|
Filter: filterArgs,
|
||||||
|
}
|
||||||
|
containers, err := e.apiClient.ContainerList(opts)
|
||||||
e.CheckConnectionErr(err)
|
e.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -676,16 +688,16 @@ func (e *Engine) refreshContainer(ID string, full bool) (*Container, error) {
|
||||||
|
|
||||||
_, err = e.updateContainer(containers[0], e.containers, full)
|
_, err = e.updateContainer(containers[0], e.containers, full)
|
||||||
e.RLock()
|
e.RLock()
|
||||||
container := e.containers[containers[0].Id]
|
container := e.containers[containers[0].ID]
|
||||||
e.RUnlock()
|
e.RUnlock()
|
||||||
return container, err
|
return container, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Engine) updateContainer(c dockerclient.Container, containers map[string]*Container, full bool) (map[string]*Container, error) {
|
func (e *Engine) updateContainer(c types.Container, containers map[string]*Container, full bool) (map[string]*Container, error) {
|
||||||
var container *Container
|
var container *Container
|
||||||
|
|
||||||
e.RLock()
|
e.RLock()
|
||||||
if current, exists := e.containers[c.Id]; exists {
|
if current, exists := e.containers[c.ID]; exists {
|
||||||
// The container is already known.
|
// The container is already known.
|
||||||
container = current
|
container = current
|
||||||
// Restarting is a transit state. Unfortunately Docker doesn't always emit
|
// Restarting is a transit state. Unfortunately Docker doesn't always emit
|
||||||
|
@ -708,30 +720,30 @@ func (e *Engine) updateContainer(c dockerclient.Container, containers map[string
|
||||||
|
|
||||||
// Update ContainerInfo.
|
// Update ContainerInfo.
|
||||||
if full {
|
if full {
|
||||||
info, err := e.client.InspectContainer(c.Id)
|
info, err := e.apiClient.ContainerInspect(c.ID)
|
||||||
e.CheckConnectionErr(err)
|
e.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Convert the ContainerConfig from inspect into our own
|
// Convert the ContainerConfig from inspect into our own
|
||||||
// cluster.ContainerConfig.
|
// cluster.ContainerConfig.
|
||||||
if info.HostConfig != nil {
|
|
||||||
info.Config.HostConfig = *info.HostConfig
|
|
||||||
}
|
|
||||||
container.Config = BuildContainerConfig(*info.Config)
|
|
||||||
|
|
||||||
// FIXME remove "duplicate" lines and move this to cluster/config.go
|
info.HostConfig.CPUShares = info.HostConfig.CPUShares * int64(e.Cpus) / 1024.0
|
||||||
container.Config.CpuShares = container.Config.CpuShares * int64(e.Cpus) / 1024.0
|
networkingConfig := networktypes.NetworkingConfig{
|
||||||
container.Config.HostConfig.CpuShares = container.Config.CpuShares
|
EndpointsConfig: info.NetworkSettings.Networks,
|
||||||
|
}
|
||||||
|
container.Config = BuildContainerConfig(*info.Config, *info.HostConfig, networkingConfig)
|
||||||
|
// FIXME remove "duplicate" line and move this to cluster/config.go
|
||||||
|
container.Config.CPUShares = container.Config.CPUShares * int64(e.Cpus) / 1024.0
|
||||||
|
|
||||||
// Save the entire inspect back into the container.
|
// Save the entire inspect back into the container.
|
||||||
container.Info = *info
|
container.Info = info
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update its internal state.
|
// Update its internal state.
|
||||||
e.Lock()
|
e.Lock()
|
||||||
container.Container = c
|
container.Container = c
|
||||||
containers[container.Id] = container
|
containers[container.ID] = container
|
||||||
e.Unlock()
|
e.Unlock()
|
||||||
|
|
||||||
return containers, nil
|
return containers, nil
|
||||||
|
@ -829,7 +841,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.Config.CpuShares
|
r += c.Config.CPUShares
|
||||||
}
|
}
|
||||||
e.RUnlock()
|
e.RUnlock()
|
||||||
return r
|
return r
|
||||||
|
@ -848,23 +860,21 @@ func (e *Engine) TotalCpus() int {
|
||||||
// Create a new container
|
// Create a new container
|
||||||
func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool, authConfig *dockerclient.AuthConfig) (*Container, error) {
|
func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool, authConfig *dockerclient.AuthConfig) (*Container, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
id string
|
createResp types.ContainerCreateResponse
|
||||||
client = e.client
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Convert our internal ContainerConfig into something Docker will
|
// Convert our internal ContainerConfig into something Docker will
|
||||||
// understand. Start by making a copy of the internal ContainerConfig as
|
// understand. Start by making a copy of the internal ContainerConfig as
|
||||||
// we don't want to mess with the original.
|
// we don't want to mess with the original.
|
||||||
dockerConfig := config.ContainerConfig
|
dockerConfig := config
|
||||||
|
|
||||||
// nb of CPUs -> real CpuShares
|
// nb of CPUs -> real CpuShares
|
||||||
|
|
||||||
// FIXME remove "duplicate" lines and move this to cluster/config.go
|
// FIXME remove "duplicate" lines and move this to cluster/config.go
|
||||||
dockerConfig.CpuShares = int64(math.Ceil(float64(config.CpuShares*1024) / float64(e.Cpus)))
|
dockerConfig.CPUShares = int64(math.Ceil(float64(config.CPUShares*1024) / float64(e.Cpus)))
|
||||||
dockerConfig.HostConfig.CpuShares = dockerConfig.CpuShares
|
|
||||||
|
|
||||||
id, err = client.CreateContainer(&dockerConfig, name, nil)
|
createResp, err = e.apiClient.ContainerCreate(&dockerConfig.Config, &dockerConfig.HostConfig, &dockerConfig.NetworkingConfig, name)
|
||||||
e.CheckConnectionErr(err)
|
e.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If the error is other than not found, abort immediately.
|
// If the error is other than not found, abort immediately.
|
||||||
|
@ -876,7 +886,7 @@ func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool, au
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// ...And try again.
|
// ...And try again.
|
||||||
id, err = client.CreateContainer(&dockerConfig, name, nil)
|
createResp, err = e.apiClient.ContainerCreate(&dockerConfig.Config, &dockerConfig.HostConfig, &dockerConfig.NetworkingConfig, name)
|
||||||
e.CheckConnectionErr(err)
|
e.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -885,12 +895,12 @@ func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool, au
|
||||||
|
|
||||||
// Register the container immediately while waiting for a state refresh.
|
// Register the container immediately while waiting for a state refresh.
|
||||||
// Force a state refresh to pick up the newly created container.
|
// Force a state refresh to pick up the newly created container.
|
||||||
e.refreshContainer(id, true)
|
e.refreshContainer(createResp.ID, true)
|
||||||
e.RefreshVolumes()
|
e.RefreshVolumes()
|
||||||
e.RefreshNetworks()
|
e.RefreshNetworks()
|
||||||
|
|
||||||
e.Lock()
|
e.Lock()
|
||||||
container := e.containers[id]
|
container := e.containers[createResp.ID]
|
||||||
e.Unlock()
|
e.Unlock()
|
||||||
|
|
||||||
if container == nil {
|
if container == nil {
|
||||||
|
@ -901,7 +911,7 @@ func (e *Engine) Create(config *ContainerConfig, name string, pullImage bool, au
|
||||||
|
|
||||||
// RemoveContainer removes a container from the engine.
|
// RemoveContainer removes a container from the engine.
|
||||||
func (e *Engine) RemoveContainer(container *Container, force, volumes bool) error {
|
func (e *Engine) RemoveContainer(container *Container, force, volumes bool) error {
|
||||||
err := e.client.RemoveContainer(container.Id, force, volumes)
|
err := e.client.RemoveContainer(container.ID, force, volumes)
|
||||||
e.CheckConnectionErr(err)
|
e.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -911,7 +921,7 @@ func (e *Engine) RemoveContainer(container *Container, force, volumes bool) erro
|
||||||
// will rewrite this.
|
// will rewrite this.
|
||||||
e.Lock()
|
e.Lock()
|
||||||
defer e.Unlock()
|
defer e.Unlock()
|
||||||
delete(e.containers, container.Id)
|
delete(e.containers, container.ID)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1112,10 +1122,10 @@ func (e *Engine) AddContainer(container *Container) error {
|
||||||
e.Lock()
|
e.Lock()
|
||||||
defer e.Unlock()
|
defer e.Unlock()
|
||||||
|
|
||||||
if _, ok := e.containers[container.Id]; ok {
|
if _, ok := e.containers[container.ID]; ok {
|
||||||
return errors.New("container already exists")
|
return errors.New("container already exists")
|
||||||
}
|
}
|
||||||
e.containers[container.Id] = container
|
e.containers[container.ID] = container
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,10 +1142,10 @@ func (e *Engine) removeContainer(container *Container) error {
|
||||||
e.Lock()
|
e.Lock()
|
||||||
defer e.Unlock()
|
defer e.Unlock()
|
||||||
|
|
||||||
if _, ok := e.containers[container.Id]; !ok {
|
if _, ok := e.containers[container.ID]; !ok {
|
||||||
return errors.New("container not found")
|
return errors.New("container not found")
|
||||||
}
|
}
|
||||||
delete(e.containers, container.Id)
|
delete(e.containers, container.ID)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,14 +1172,14 @@ func (e *Engine) StartContainer(id string, hostConfig *dockerclient.HostConfig)
|
||||||
// RenameContainer renames a container
|
// RenameContainer renames a container
|
||||||
func (e *Engine) RenameContainer(container *Container, newName string) error {
|
func (e *Engine) RenameContainer(container *Container, newName string) error {
|
||||||
// send rename request
|
// send rename request
|
||||||
err := e.client.RenameContainer(container.Id, newName)
|
err := e.client.RenameContainer(container.ID, newName)
|
||||||
e.CheckConnectionErr(err)
|
e.CheckConnectionErr(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// refresh container
|
// refresh container
|
||||||
_, err = e.refreshContainer(container.Id, true)
|
_, err = e.refreshContainer(container.ID, true)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,10 @@ func (w *Watchdog) removeDuplicateContainers(e *Engine) {
|
||||||
|
|
||||||
for _, containerInCluster := range w.cluster.Containers() {
|
for _, containerInCluster := range w.cluster.Containers() {
|
||||||
if containerInCluster.Config.SwarmID() == container.Config.SwarmID() && containerInCluster.Engine.ID != container.Engine.ID {
|
if containerInCluster.Config.SwarmID() == container.Config.SwarmID() && containerInCluster.Engine.ID != container.Engine.ID {
|
||||||
log.Debugf("container %s was rescheduled on node %s, removing it", container.Id, containerInCluster.Engine.Name)
|
log.Debugf("container %s was rescheduled on node %s, removing it", container.ID, containerInCluster.Engine.Name)
|
||||||
// container already exists in the cluster, destroy it
|
// container already exists in the cluster, destroy it
|
||||||
if err := e.RemoveContainer(container, true, true); err != nil {
|
if err := e.RemoveContainer(container, true, true); err != nil {
|
||||||
log.Errorf("Failed to remove duplicate container %s on node %s: %v", container.Id, containerInCluster.Engine.Name, err)
|
log.Errorf("Failed to remove duplicate container %s on node %s: %v", container.ID, containerInCluster.Engine.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ func (w *Watchdog) rescheduleContainers(e *Engine) {
|
||||||
|
|
||||||
// Skip containers which don't have an "on-node-failure" reschedule policy.
|
// Skip containers which don't have an "on-node-failure" reschedule policy.
|
||||||
if !c.Config.HasReschedulePolicy("on-node-failure") {
|
if !c.Config.HasReschedulePolicy("on-node-failure") {
|
||||||
log.Debugf("Skipping rescheduling of %s based on rescheduling policies", c.Id)
|
log.Debugf("Skipping rescheduling of %s based on rescheduling policies", c.ID)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,15 +78,15 @@ func (w *Watchdog) rescheduleContainers(e *Engine) {
|
||||||
newContainer, err := w.cluster.CreateContainer(c.Config, c.Info.Name, nil)
|
newContainer, err := w.cluster.CreateContainer(c.Config, c.Info.Name, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to reschedule container %s: %v", c.Id, err)
|
log.Errorf("Failed to reschedule container %s: %v", c.ID, err)
|
||||||
// add the container back, so we can retry later
|
// add the container back, so we can retry later
|
||||||
c.Engine.AddContainer(c)
|
c.Engine.AddContainer(c)
|
||||||
} else {
|
} else {
|
||||||
log.Infof("Rescheduled container %s from %s to %s as %s", c.Id, c.Engine.Name, newContainer.Engine.Name, newContainer.Id)
|
log.Infof("Rescheduled container %s from %s to %s as %s", c.ID, c.Engine.Name, newContainer.Engine.Name, newContainer.ID)
|
||||||
if c.Info.State.Running {
|
if c.Info.State.Running {
|
||||||
log.Infof("Container %s was running, starting container %s", c.Id, newContainer.Id)
|
log.Infof("Container %s was running, starting container %s", c.ID, newContainer.ID)
|
||||||
if err := w.cluster.StartContainer(newContainer, nil); err != nil {
|
if err := w.cluster.StartContainer(newContainer, nil); err != nil {
|
||||||
log.Errorf("Failed to start rescheduled container %s: %v", newContainer.Id, err)
|
log.Errorf("Failed to start rescheduled container %s: %v", newContainer.ID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ func (n *Node) Container(IDOrName string) *cluster.Container {
|
||||||
func (n *Node) AddContainer(container *cluster.Container) error {
|
func (n *Node) AddContainer(container *cluster.Container) error {
|
||||||
if container.Config != nil {
|
if container.Config != nil {
|
||||||
memory := container.Config.Memory
|
memory := container.Config.Memory
|
||||||
cpus := container.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")
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ func weighNodes(config *cluster.ContainerConfig, nodes []*node.Node, healthiness
|
||||||
nodeCpus := node.TotalCpus
|
nodeCpus := node.TotalCpus
|
||||||
|
|
||||||
// Skip nodes that are smaller than the requested resources.
|
// Skip nodes that are smaller than the requested resources.
|
||||||
if nodeMemory < int64(config.Memory) || nodeCpus < config.CpuShares {
|
if nodeMemory < int64(config.Memory) || nodeCpus < config.CPUShares {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ func weighNodes(config *cluster.ContainerConfig, nodes []*node.Node, healthiness
|
||||||
memoryScore int64 = 100
|
memoryScore int64 = 100
|
||||||
)
|
)
|
||||||
|
|
||||||
if config.CpuShares > 0 {
|
if config.CPUShares > 0 {
|
||||||
cpuScore = (node.UsedCpus + config.CpuShares) * 100 / nodeCpus
|
cpuScore = (node.UsedCpus + config.CPUShares) * 100 / nodeCpus
|
||||||
}
|
}
|
||||||
if config.Memory > 0 {
|
if config.Memory > 0 {
|
||||||
memoryScore = (node.UsedMemory + config.Memory) * 100 / nodeMemory
|
memoryScore = (node.UsedMemory + config.Memory) * 100 / nodeMemory
|
||||||
|
|
Loading…
Reference in New Issue