fix container matching algorithm

Signed-off-by: Victor Vieux <victorvieux@gmail.com>
This commit is contained in:
Victor Vieux 2015-05-15 17:57:40 -07:00
parent a30c2ae680
commit faf26a62f4
4 changed files with 63 additions and 74 deletions

View File

@ -455,35 +455,6 @@ func (e *Engine) Containers() []*Container {
return containers
}
// Container returns the container with IDOrName in the engine.
func (e *Engine) Container(IDOrName string) *Container {
// Abort immediately if the name is empty.
if len(IDOrName) == 0 {
return nil
}
for _, container := range e.Containers() {
// Match Container ID prefix.
if strings.HasPrefix(container.Id, IDOrName) {
return container
}
// Match Swarm ID prefix.
if strings.HasPrefix(container.Config.SwarmID(), IDOrName) {
return container
}
// Match name, /name or engine/name.
for _, name := range container.Names {
if name == IDOrName || name == "/"+IDOrName || container.Engine.ID+name == IDOrName || container.Engine.Name+name == IDOrName {
return container
}
}
}
return nil
}
// Images returns all the images in the engine
func (e *Engine) Images() []*Image {
e.RLock()

View File

@ -135,38 +135,6 @@ func TestEngineState(t *testing.T) {
client.Mock.AssertExpectations(t)
}
func TestEngineContainerLookup(t *testing.T) {
engine := NewEngine("test-engine", 0)
assert.False(t, engine.isConnected())
client := mockclient.NewMockClient()
client.On("Info").Return(mockInfo, nil)
client.On("StartMonitorEvents", mock.Anything, mock.Anything, mock.Anything).Return()
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{{Id: "container-id", Names: []string{"/container-name1", "/container-name2"}}}, nil).Once()
client.On("ListImages").Return([]*dockerclient.Image{}, nil).Once()
client.On("InspectContainer", "container-id").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: 100}}, nil).Once()
assert.NoError(t, engine.connectClient(client))
assert.True(t, engine.isConnected())
// Invalid lookup
assert.Nil(t, engine.Container("invalid-id"))
assert.Nil(t, engine.Container(""))
// Container ID lookup.
assert.NotNil(t, engine.Container("container-id"))
// Container ID prefix lookup.
assert.NotNil(t, engine.Container("container-"))
// Container name lookup.
assert.NotNil(t, engine.Container("container-name1"))
assert.NotNil(t, engine.Container("container-name2"))
// Container engine/name matching.
assert.NotNil(t, engine.Container("id/container-name1"))
assert.NotNil(t, engine.Container("id/container-name2"))
client.Mock.AssertExpectations(t)
}
func TestCreateContainer(t *testing.T) {
var (
config = &ContainerConfig{dockerclient.ContainerConfig{

View File

@ -371,8 +371,42 @@ func (c *Cluster) Container(IDOrName string) *cluster.Container {
c.RLock()
defer c.RUnlock()
for _, n := range c.engines {
if container := n.Container(IDOrName); container != nil {
containers := c.Containers()
// Match exact or short Container ID.
for _, container := range containers {
if container.Id == IDOrName || stringid.TruncateID(container.Id) == IDOrName {
return container
}
}
// Match exact Swarm ID.
for _, container := range containers {
if swarmID := container.Config.SwarmID(); swarmID == IDOrName || stringid.TruncateID(swarmID) == IDOrName {
return container
}
}
// Match name, /name or engine/name.
for _, container := range containers {
for _, name := range container.Names {
if name == IDOrName || name == "/"+IDOrName || container.Engine.ID+name == IDOrName || container.Engine.Name+name == IDOrName {
return container
}
}
}
// Match Container ID prefix.
for _, container := range containers {
if strings.HasPrefix(container.Id, IDOrName) {
return container
}
}
// Match Swarm ID prefix.
for _, container := range containers {
if strings.HasPrefix(container.Config.SwarmID(), IDOrName) {
return container
}
}

View File

@ -25,36 +25,52 @@ func TestContainerLookup(t *testing.T) {
c := &Cluster{
engines: make(map[string]*cluster.Engine),
}
container := &cluster.Container{
container1 := &cluster.Container{
Container: dockerclient.Container{
Id: "container-id",
Names: []string{"/container-name1", "/container-name2"},
Id: "container-id1",
Names: []string{"/container1-name1", "/container1-name2"},
},
Config: cluster.BuildContainerConfig(dockerclient.ContainerConfig{
Labels: map[string]string{
"com.docker.swarm.id": "swarm-id",
"com.docker.swarm.id": "swarm-id1",
},
}),
}
n := createEngine(t, "test-engine", container)
container2 := &cluster.Container{
Container: dockerclient.Container{
Id: "container-id2",
Names: []string{"/con"},
},
Config: cluster.BuildContainerConfig(dockerclient.ContainerConfig{
Labels: map[string]string{
"com.docker.swarm.id": "swarm-id2",
},
}),
}
n := createEngine(t, "test-engine", container1, container2)
c.engines[n.ID] = n
// Invalid lookup
assert.Nil(t, c.Container("invalid-id"))
assert.Nil(t, c.Container(""))
// Container ID lookup.
assert.NotNil(t, c.Container("container-id"))
assert.NotNil(t, c.Container("container-id1"))
// Container ID prefix lookup.
assert.NotNil(t, c.Container("container-"))
// Container name lookup.
assert.NotNil(t, c.Container("container-name1"))
assert.NotNil(t, c.Container("container-name2"))
assert.NotNil(t, c.Container("container1-name1"))
assert.NotNil(t, c.Container("container1-name2"))
// Container engine/name matching.
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/container1-name1"))
assert.NotNil(t, c.Container("test-engine/container1-name2"))
// Swarm ID lookup.
assert.NotNil(t, c.Container("swarm-id"))
assert.NotNil(t, c.Container("swarm-id1"))
// Swarm ID prefix lookup.
assert.NotNil(t, c.Container("swarm-"))
// Match name before ID prefix
cc := c.Container("con")
assert.NotNil(t, cc)
assert.Equal(t, cc.Id, "container-id2")
}