mirror of https://github.com/docker/docs.git
Add support for Swarm IDs.
- Every container that gets created through Swarm gets a Swarm ID assigned (as a label). - All API operations (start, stop, ...) can be performed by using either the container ID or the swarm ID. Signed-off-by: Andrea Luzzardi <aluzzardi@gmail.com>
This commit is contained in:
parent
c4c07c97ac
commit
abfe5e6f4c
|
|
@ -463,11 +463,16 @@ func (e *Engine) Container(IDOrName string) *Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, container := range e.Containers() {
|
for _, container := range e.Containers() {
|
||||||
// Match ID prefix.
|
// Match Container ID prefix.
|
||||||
if strings.HasPrefix(container.Id, IDOrName) {
|
if strings.HasPrefix(container.Id, IDOrName) {
|
||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Match Swarm ID prefix.
|
||||||
|
if strings.HasPrefix(container.Config.SwarmID(), IDOrName) {
|
||||||
|
return container
|
||||||
|
}
|
||||||
|
|
||||||
// Match name, /name or engine/name.
|
// Match name, /name or engine/name.
|
||||||
for _, name := range container.Names {
|
for _, name := range container.Names {
|
||||||
if name == IDOrName || name == "/"+IDOrName || container.Engine.ID+name == IDOrName || container.Engine.Name+name == IDOrName {
|
if name == IDOrName || name == "/"+IDOrName || container.Engine.ID+name == IDOrName || container.Engine.Name+name == IDOrName {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/docker/docker/pkg/stringid"
|
||||||
"github.com/docker/docker/pkg/units"
|
"github.com/docker/docker/pkg/units"
|
||||||
"github.com/docker/swarm/cluster"
|
"github.com/docker/swarm/cluster"
|
||||||
"github.com/docker/swarm/discovery"
|
"github.com/docker/swarm/discovery"
|
||||||
|
|
@ -80,16 +81,29 @@ func (c *Cluster) RegisterEventHandler(h cluster.EventHandler) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a globally (across the cluster) unique ID.
|
||||||
|
func (c *Cluster) generateUniqueID() string {
|
||||||
|
for {
|
||||||
|
id := stringid.GenerateRandomID()
|
||||||
|
if c.Container(id) == nil {
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CreateContainer aka schedule a brand new container into the cluster.
|
// CreateContainer aka schedule a brand new container into the cluster.
|
||||||
func (c *Cluster) CreateContainer(config *cluster.ContainerConfig, name string) (*cluster.Container, error) {
|
func (c *Cluster) CreateContainer(config *cluster.ContainerConfig, name string) (*cluster.Container, error) {
|
||||||
c.scheduler.Lock()
|
c.scheduler.Lock()
|
||||||
defer c.scheduler.Unlock()
|
defer c.scheduler.Unlock()
|
||||||
|
|
||||||
// check new name whether avaliable
|
// Ensure the name is avaliable
|
||||||
if cID := c.getIDFromName(name); cID != "" {
|
if cID := c.getIDFromName(name); cID != "" {
|
||||||
return nil, fmt.Errorf("Conflict, The name %s is already assigned to %s. You have to delete (or rename) that container to be able to assign %s to a container again.", name, cID, name)
|
return nil, fmt.Errorf("Conflict, The name %s is already assigned to %s. You have to delete (or rename) that container to be able to assign %s to a container again.", name, cID, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Associate a Swarm ID to the container we are creating.
|
||||||
|
config.SetSwarmID(c.generateUniqueID())
|
||||||
|
|
||||||
n, err := c.scheduler.SelectNodeForContainer(c.listNodes(), config)
|
n, err := c.scheduler.SelectNodeForContainer(c.listNodes(), config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,14 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func createEngine(t *testing.T, ID string, containers ...dockerclient.Container) *cluster.Engine {
|
func createEngine(t *testing.T, ID string, containers ...*cluster.Container) *cluster.Engine {
|
||||||
engine := cluster.NewEngine(ID, 0)
|
engine := cluster.NewEngine(ID, 0)
|
||||||
engine.Name = ID
|
engine.Name = ID
|
||||||
engine.ID = ID
|
engine.ID = ID
|
||||||
|
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
engine.AddContainer(&cluster.Container{Container: container, Engine: engine})
|
container.Engine = engine
|
||||||
|
engine.AddContainer(container)
|
||||||
}
|
}
|
||||||
|
|
||||||
return engine
|
return engine
|
||||||
|
|
@ -24,9 +25,16 @@ func TestContainerLookup(t *testing.T) {
|
||||||
c := &Cluster{
|
c := &Cluster{
|
||||||
engines: make(map[string]*cluster.Engine),
|
engines: make(map[string]*cluster.Engine),
|
||||||
}
|
}
|
||||||
container := dockerclient.Container{
|
container := &cluster.Container{
|
||||||
Id: "container-id",
|
Container: dockerclient.Container{
|
||||||
Names: []string{"/container-name1", "/container-name2"},
|
Id: "container-id",
|
||||||
|
Names: []string{"/container-name1", "/container-name2"},
|
||||||
|
},
|
||||||
|
Config: cluster.BuildContainerConfig(dockerclient.ContainerConfig{
|
||||||
|
Labels: map[string]string{
|
||||||
|
"com.docker.swarm.id": "swarm-id",
|
||||||
|
},
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
n := createEngine(t, "test-engine", container)
|
n := createEngine(t, "test-engine", container)
|
||||||
|
|
@ -45,4 +53,8 @@ func TestContainerLookup(t *testing.T) {
|
||||||
// Container engine/name matching.
|
// Container engine/name matching.
|
||||||
assert.NotNil(t, c.Container("test-engine/container-name1"))
|
assert.NotNil(t, c.Container("test-engine/container-name1"))
|
||||||
assert.NotNil(t, c.Container("test-engine/container-name2"))
|
assert.NotNil(t, c.Container("test-engine/container-name2"))
|
||||||
|
// Swarm ID lookup.
|
||||||
|
assert.NotNil(t, c.Container("swarm-id"))
|
||||||
|
// Swarm ID prefix lookup.
|
||||||
|
assert.NotNil(t, c.Container("swarm-"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/usr/bin/env bats
|
||||||
|
|
||||||
|
load helpers
|
||||||
|
|
||||||
|
function teardown() {
|
||||||
|
swarm_manage_cleanup
|
||||||
|
stop_docker
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "swarm id generation" {
|
||||||
|
start_docker_with_busybox 2
|
||||||
|
swarm_manage
|
||||||
|
|
||||||
|
# Create a dummy container just so we interfere with the tests.
|
||||||
|
# This one won't be used.
|
||||||
|
docker_swarm run -d busybox true
|
||||||
|
|
||||||
|
# Create a container and get its Swarm ID back.
|
||||||
|
id=$(docker_swarm run -d busybox true)
|
||||||
|
swarm_id=$(docker_swarm inspect -f '{{ index .Config.Labels "com.docker.swarm.id" }}' "$id")
|
||||||
|
|
||||||
|
# Make sure we got a valid Swarm ID.
|
||||||
|
[[ "${#swarm_id}" -eq 64 ]]
|
||||||
|
[[ "$id" != "$swarm_id" ]]
|
||||||
|
|
||||||
|
# API operations should work with Swarm IDs as well as Container IDs.
|
||||||
|
[[ $(docker_swarm inspect -f "{{ .Id }}" "$swarm_id") == "$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" ]]
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue