mirror of https://github.com/docker/docs.git
add images cache
Signed-off-by: Victor Vieux <vieux@docker.com>
This commit is contained in:
parent
d54c5f8046
commit
5564894744
|
@ -18,6 +18,7 @@ func createNode(t *testing.T, ID string, containers ...dockerclient.Container) *
|
|||
client := mockclient.NewMockClient()
|
||||
client.On("Info").Return(mockInfo, nil)
|
||||
client.On("ListContainers", true, false, "").Return(containers, nil)
|
||||
client.On("ListImages").Return([]*dockerclient.Image{}, nil)
|
||||
client.On("InspectContainer", mock.Anything).Return(
|
||||
&dockerclient.ContainerInfo{
|
||||
Config: &dockerclient.ContainerConfig{CpuShares: 100},
|
||||
|
|
|
@ -46,6 +46,7 @@ type Node struct {
|
|||
|
||||
ch chan bool
|
||||
containers map[string]*Container
|
||||
images []*dockerclient.Image
|
||||
client dockerclient.Client
|
||||
eventHandler EventHandler
|
||||
healthy bool
|
||||
|
@ -84,6 +85,10 @@ func (n *Node) connectClient(client dockerclient.Client) error {
|
|||
n.client = nil
|
||||
return err
|
||||
}
|
||||
if err := n.refreshImages(); err != nil {
|
||||
n.client = nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Start the update loop.
|
||||
go n.refreshLoop()
|
||||
|
@ -131,6 +136,18 @@ func (n *Node) updateSpecs() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Refresh the list of images on the node.
|
||||
func (n *Node) refreshImages() error {
|
||||
images, err := n.client.ListImages()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
n.Lock()
|
||||
n.images = images
|
||||
n.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Refresh the list and status of containers running on the node.
|
||||
func (n *Node) refreshContainers() error {
|
||||
containers, err := n.client.ListContainers(true, false, "")
|
||||
|
@ -237,6 +254,10 @@ func (n *Node) refreshLoop() {
|
|||
err = n.refreshContainers()
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
err = n.refreshImages()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
n.healthy = false
|
||||
log.Errorf("[%s/%s] Flagging node as dead. Updated state failed: %v", n.ID, n.Name, err)
|
||||
|
@ -316,23 +337,6 @@ func (n *Node) Create(config *dockerclient.ContainerConfig, name string, pullIma
|
|||
return n.containers[id], nil
|
||||
}
|
||||
|
||||
func (n *Node) ListImages() ([]string, error) {
|
||||
images, err := n.client.ListImages()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := []string{}
|
||||
|
||||
for _, i := range images {
|
||||
for _, t := range i.RepoTags {
|
||||
out = append(out, t)
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Destroy and remove a container from the node.
|
||||
func (n *Node) Destroy(container *Container, force bool) error {
|
||||
if err := n.client.RemoveContainer(container.Id, force); err != nil {
|
||||
|
@ -374,6 +378,12 @@ func (n *Node) Containers() []*Container {
|
|||
return containers
|
||||
}
|
||||
|
||||
func (n *Node) Images() []*dockerclient.Image {
|
||||
n.RLock()
|
||||
defer n.RUnlock()
|
||||
return n.images
|
||||
}
|
||||
|
||||
func (n *Node) String() string {
|
||||
return fmt.Sprintf("node %s addr %s", n.ID, n.Addr)
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ func TestNodeCpusMemory(t *testing.T) {
|
|||
client := mockclient.NewMockClient()
|
||||
client.On("Info").Return(mockInfo, nil)
|
||||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil)
|
||||
client.On("ListImages").Return([]*dockerclient.Image{}, nil)
|
||||
client.On("StartMonitorEvents", mock.Anything, mock.Anything).Return()
|
||||
|
||||
assert.NoError(t, node.connectClient(client))
|
||||
|
@ -77,6 +78,7 @@ func TestNodeSpecs(t *testing.T) {
|
|||
client := mockclient.NewMockClient()
|
||||
client.On("Info").Return(mockInfo, nil)
|
||||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil)
|
||||
client.On("ListImages").Return([]*dockerclient.Image{}, nil)
|
||||
client.On("StartMonitorEvents", mock.Anything, mock.Anything).Return()
|
||||
|
||||
assert.NoError(t, node.connectClient(client))
|
||||
|
@ -104,6 +106,7 @@ func TestNodeState(t *testing.T) {
|
|||
|
||||
// The client will return one container at first, then a second one will appear.
|
||||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{{Id: "one"}}, nil).Once()
|
||||
client.On("ListImages").Return([]*dockerclient.Image{}, nil).Once()
|
||||
client.On("InspectContainer", "one").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: 100}}, nil).Once()
|
||||
client.On("ListContainers", true, false, fmt.Sprintf("{%q:[%q]}", "id", "two")).Return([]dockerclient.Container{{Id: "two"}}, nil).Once()
|
||||
client.On("InspectContainer", "two").Return(&dockerclient.ContainerInfo{Config: &dockerclient.ContainerConfig{CpuShares: 100}}, nil).Once()
|
||||
|
@ -147,6 +150,7 @@ func TestCreateContainer(t *testing.T) {
|
|||
client.On("Info").Return(mockInfo, nil)
|
||||
client.On("StartMonitorEvents", mock.Anything, mock.Anything).Return()
|
||||
client.On("ListContainers", true, false, "").Return([]dockerclient.Container{}, nil).Once()
|
||||
client.On("ListImages").Return([]*dockerclient.Image{}, nil).Once()
|
||||
assert.NoError(t, node.connectClient(client))
|
||||
assert.True(t, node.IsConnected())
|
||||
|
||||
|
@ -158,6 +162,7 @@ func TestCreateContainer(t *testing.T) {
|
|||
id := "id1"
|
||||
client.On("CreateContainer", &mockConfig, name).Return(id, nil).Once()
|
||||
client.On("ListContainers", true, false, fmt.Sprintf(`{"id":[%q]}`, id)).Return([]dockerclient.Container{{Id: id}}, nil).Once()
|
||||
client.On("ListImages").Return([]*dockerclient.Image{}, nil).Once()
|
||||
client.On("InspectContainer", id).Return(&dockerclient.ContainerInfo{Config: config}, nil).Once()
|
||||
container, err := node.Create(config, name, false)
|
||||
assert.Nil(t, err)
|
||||
|
@ -180,6 +185,7 @@ func TestCreateContainer(t *testing.T) {
|
|||
client.On("CreateContainer", &mockConfig, name).Return("", dockerclient.ErrNotFound).Once()
|
||||
client.On("CreateContainer", &mockConfig, name).Return(id, nil).Once()
|
||||
client.On("ListContainers", true, false, fmt.Sprintf(`{"id":[%q]}`, id)).Return([]dockerclient.Container{{Id: id}}, nil).Once()
|
||||
client.On("ListImages").Return([]*dockerclient.Image{}, nil).Once()
|
||||
client.On("InspectContainer", id).Return(&dockerclient.ContainerInfo{Config: config}, nil).Once()
|
||||
container, err = node.Create(config, name, true)
|
||||
assert.Nil(t, err)
|
||||
|
|
|
@ -21,23 +21,24 @@ func (f *AffinityFilter) Filter(config *dockerclient.ContainerConfig, nodes []*c
|
|||
switch k {
|
||||
case "container":
|
||||
for _, container := range node.Containers() {
|
||||
// "node" label is a special case pinning a container to a specific node.
|
||||
if match(v, container.Id) || match(v, container.Names[0]) {
|
||||
candidates = append(candidates, node)
|
||||
break
|
||||
}
|
||||
}
|
||||
case "image":
|
||||
//TODO use cache
|
||||
images, err := node.ListImages()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
for _, image := range images {
|
||||
if match(v, image) {
|
||||
done:
|
||||
for _, image := range node.Images() {
|
||||
if match(v, image.Id) {
|
||||
candidates = append(candidates, node)
|
||||
break
|
||||
}
|
||||
for _, t := range image.RepoTags {
|
||||
if match(v, t) {
|
||||
candidates = append(candidates, node)
|
||||
break done
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,9 +14,9 @@ func TestAffinityFilter(t *testing.T) {
|
|||
var (
|
||||
f = AffinityFilter{}
|
||||
nodes = []*cluster.Node{
|
||||
cluster.NewNode("node-0"),
|
||||
cluster.NewNode("node-1"),
|
||||
cluster.NewNode("node-2"),
|
||||
cluster.NewNode("node-0", 0),
|
||||
cluster.NewNode("node-1", 0),
|
||||
cluster.NewNode("node-2", 0),
|
||||
}
|
||||
result []*cluster.Node
|
||||
err error
|
||||
|
|
Loading…
Reference in New Issue