1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Add support for .Node.Hostname templating in swarm services

Signed-off-by: Carlo Mion <mion00@gmail.com>
This commit is contained in:
Carlo Mion 2017-08-30 21:45:05 +02:00
parent e23965d620
commit e2f09fa6dd
8 changed files with 32 additions and 16 deletions

View file

@ -41,8 +41,8 @@ type containerAdapter struct {
dependencies exec.DependencyGetter
}
func newContainerAdapter(b executorpkg.Backend, task *api.Task, dependencies exec.DependencyGetter) (*containerAdapter, error) {
ctnr, err := newContainerConfig(task)
func newContainerAdapter(b executorpkg.Backend, task *api.Task, node *api.NodeDescription, dependencies exec.DependencyGetter) (*containerAdapter, error) {
ctnr, err := newContainerConfig(task, node)
if err != nil {
return nil, err
}

View file

@ -20,8 +20,8 @@ type networkAttacherController struct {
closed chan struct{}
}
func newNetworkAttacherController(b executorpkg.Backend, task *api.Task, dependencies exec.DependencyGetter) (*networkAttacherController, error) {
adapter, err := newContainerAdapter(b, task, dependencies)
func newNetworkAttacherController(b executorpkg.Backend, task *api.Task, node *api.NodeDescription, dependencies exec.DependencyGetter) (*networkAttacherController, error) {
adapter, err := newContainerAdapter(b, task, node, dependencies)
if err != nil {
return nil, err
}

View file

@ -48,12 +48,12 @@ type containerConfig struct {
// newContainerConfig returns a validated container config. No methods should
// return an error if this function returns without error.
func newContainerConfig(t *api.Task) (*containerConfig, error) {
func newContainerConfig(t *api.Task, node *api.NodeDescription) (*containerConfig, error) {
var c containerConfig
return &c, c.setTask(t)
return &c, c.setTask(t, node)
}
func (c *containerConfig) setTask(t *api.Task) error {
func (c *containerConfig) setTask(t *api.Task, node *api.NodeDescription) error {
if t.Spec.GetContainer() == nil && t.Spec.GetAttachment() == nil {
return exec.ErrRuntimeUnsupported
}
@ -78,7 +78,7 @@ func (c *containerConfig) setTask(t *api.Task) error {
c.task = t
if t.Spec.GetContainer() != nil {
preparedSpec, err := template.ExpandContainerSpec(nil, t)
preparedSpec, err := template.ExpandContainerSpec(node, t)
if err != nil {
return err
}

View file

@ -40,8 +40,8 @@ type controller struct {
var _ exec.Controller = &controller{}
// NewController returns a docker exec runner for the provided task.
func newController(b executorpkg.Backend, task *api.Task, dependencies exec.DependencyGetter) (*controller, error) {
adapter, err := newContainerAdapter(b, task, dependencies)
func newController(b executorpkg.Backend, task *api.Task, node *api.NodeDescription, dependencies exec.DependencyGetter) (*controller, error) {
adapter, err := newContainerAdapter(b, task, node, dependencies)
if err != nil {
return nil, err
}

View file

@ -4,6 +4,7 @@ import (
"fmt"
"sort"
"strings"
"sync"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
@ -26,6 +27,8 @@ type executor struct {
backend executorpkg.Backend
pluginBackend plugin.Backend
dependencies exec.DependencyManager
mutex sync.Mutex // This mutex protects the following node field
node *api.NodeDescription
}
// NewExecutor returns an executor from the docker client.
@ -124,6 +127,11 @@ func (e *executor) Describe(ctx context.Context) (*api.NodeDescription, error) {
},
}
// Save the node information in the executor field
e.mutex.Lock()
e.node = description
e.mutex.Unlock()
return description, nil
}
@ -168,8 +176,13 @@ func (e *executor) Configure(ctx context.Context, node *api.Node) error {
func (e *executor) Controller(t *api.Task) (exec.Controller, error) {
dependencyGetter := agent.Restrict(e.dependencies, t)
// Get the node description from the executor field
e.mutex.Lock()
nodeDescription := e.node
e.mutex.Unlock()
if t.Spec.GetAttachment() != nil {
return newNetworkAttacherController(e.backend, t, dependencyGetter)
return newNetworkAttacherController(e.backend, t, nodeDescription, dependencyGetter)
}
var ctlr exec.Controller
@ -198,7 +211,7 @@ func (e *executor) Controller(t *api.Task) (exec.Controller, error) {
return ctlr, fmt.Errorf("unsupported runtime type: %q", runtimeKind)
}
case *api.TaskSpec_Container:
c, err := newController(e.backend, t, dependencyGetter)
c, err := newController(e.backend, t, nodeDescription, dependencyGetter)
if err != nil {
return ctlr, err
}

View file

@ -52,7 +52,7 @@ func TestHealthStates(t *testing.T) {
EventsService: e,
}
controller, err := newController(daemon, task, nil)
controller, err := newController(daemon, task, nil, nil)
if err != nil {
t.Fatalf("create controller fail %v", err)
}

View file

@ -26,7 +26,8 @@ func newTestControllerWithMount(m api.Mount) (*controller, error) {
},
},
},
}, nil)
}, nil,
nil)
}
func TestControllerValidateMountBind(t *testing.T) {

View file

@ -169,8 +169,10 @@ func (s *DockerSwarmSuite) TestSwarmIncompatibleDaemon(c *check.C) {
func (s *DockerSwarmSuite) TestSwarmServiceTemplatingHostname(c *check.C) {
d := s.AddDaemon(c, true, true)
hostname, err := d.Cmd("node", "inspect", "--format", "{{.Description.Hostname}}", "self")
c.Assert(err, checker.IsNil, check.Commentf(hostname))
out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "test", "--hostname", "{{.Service.Name}}-{{.Task.Slot}}", "busybox", "top")
out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "test", "--hostname", "{{.Service.Name}}-{{.Task.Slot}}-{{.Node.Hostname}}", "busybox", "top")
c.Assert(err, checker.IsNil, check.Commentf(out))
// make sure task has been deployed.
@ -179,7 +181,7 @@ func (s *DockerSwarmSuite) TestSwarmServiceTemplatingHostname(c *check.C) {
containers := d.ActiveContainers()
out, err = d.Cmd("inspect", "--type", "container", "--format", "{{.Config.Hostname}}", containers[0])
c.Assert(err, checker.IsNil, check.Commentf(out))
c.Assert(strings.Split(out, "\n")[0], checker.Equals, "test-1", check.Commentf("hostname with templating invalid"))
c.Assert(strings.Split(out, "\n")[0], checker.Equals, "test-1-"+strings.Split(hostname, "\n")[0], check.Commentf("hostname with templating invalid"))
}
// Test case for #24270