swarm id: Handle compatibility.

Containers created with Swarm<0.3.0 or directly on the host without
going through Swarm don't have a Swarm ID. We are going to fake it by
using the Container ID.

Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
Andrea Luzzardi 2015-05-07 01:09:19 -07:00
parent b2fa060957
commit 5c801d2c6a
3 changed files with 63 additions and 1 deletions

View File

@ -198,6 +198,11 @@ func getContainersJSON(c *context, w http.ResponseWriter, r *http.Request) {
tmp.Status = "Pending"
}
// Overwrite labels with the ones we have in the config.
// This ensures that we can freely manipulate them in the codebase and
// they will be properly exported back (for instance Swarm IDs).
tmp.Labels = container.Config.Labels
// TODO remove the Node Name in the name when we have a good solution
tmp.Names = make([]string, len(container.Names))
for i, name := range container.Names {
@ -251,6 +256,32 @@ func getContainerJSON(c *context, w http.ResponseWriter, r *http.Request) {
httpError(w, err.Error(), http.StatusInternalServerError)
return
}
// Compatibility: Inject the Swarm ID label if not available.
// This **must** be done before inserting the `Node` field since it too has
// a `Label` field.
if !bytes.Contains(data, []byte("\"com.docker.swarm.id\":")) {
label := fmt.Sprintf("%q:%q", "com.docker.swarm.id", container.Config.SwarmID())
switch {
// No `Labels` section at all
case !bytes.Contains(data, []byte("\"Labels\":")):
data = bytes.Replace(data,
[]byte("\"Image\":"),
[]byte("\"Labels\":{"+label+"},\"Image\":"),
1)
// Empty `Labels` section
case bytes.Contains(data, []byte("\"Labels\":{}")):
data = bytes.Replace(data,
[]byte("\"Labels\":{}"),
[]byte("\"Labels\":{"+label+"}"),
1)
// `Labels` section with labels in it
case bytes.Contains(data, []byte("\"Labels\":{")):
data = bytes.Replace(data,
[]byte("\"Labels\":{"),
[]byte("\"Labels\":{"+label+","),
1)
}
}
// insert Node field
data = bytes.Replace(data, []byte("\"Name\":\"/"), []byte(fmt.Sprintf("\"Node\":%s,\"Name\":\"/", n)), -1)

View File

@ -252,6 +252,13 @@ func (e *Engine) updateContainer(c dockerclient.Container, containers map[string
container.Config = BuildContainerConfig(*info.Config)
container.Config.CpuShares = container.Config.CpuShares * 1024.0 / e.Cpus
// Compatibility: Containers created with Swarm<0.3.0 or directly on
// the host without going through Swarm don't have a Swarm ID. We are
// going to fake it by using the Container ID.
if container.Config.SwarmID() == "" {
container.Config.SetSwarmID(c.Id)
}
// Save the entire inspect back into the container.
container.Info = *info
}

View File

@ -8,7 +8,7 @@ function teardown() {
}
@test "swarm id generation" {
start_docker_with_busybox 2
start_docker_with_busybox 1
swarm_manage
# Create a dummy container just so we interfere with the tests.
@ -29,3 +29,27 @@ function teardown() {
# `docker ps` should be able to filter by Swarm ID using the label.
[[ $(docker_swarm ps -a -q --no-trunc --filter="label=com.docker.swarm.id=$swarm_id") == "$id" ]]
}
@test "swarm id compatbility" {
start_docker_with_busybox 1
swarm_manage
# Create a dummy container just so we interfere with the tests.
# This one won't be used.
docker -H "${HOSTS[0]}" run -d busybox true
# Create a container directly on the node.
id=$(docker -H "${HOSTS[0]}" run -d busybox true)
# Wait a few seconds for Swarm to detect the container.
retry 10 0.5 docker_swarm inspect "$id"
# Fetch its Swarm ID
swarm_id=$(docker_swarm inspect -f '{{ index .Config.Labels "com.docker.swarm.id" }}' "$id")
# Make sure it's the same as the Container ID.
[[ "$id" == "$swarm_id" ]]
# `docker ps` should be able to filter by Swarm ID using the label.
[[ $(docker_swarm ps -a -q --no-trunc --filter="label=com.docker.swarm.id=$swarm_id") == "$id" ]]
}