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:
parent
e23965d620
commit
e2f09fa6dd
8 changed files with 32 additions and 16 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ func newTestControllerWithMount(m api.Mount) (*controller, error) {
|
|||
},
|
||||
},
|
||||
},
|
||||
}, nil)
|
||||
}, nil,
|
||||
nil)
|
||||
}
|
||||
|
||||
func TestControllerValidateMountBind(t *testing.T) {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue