Signed-off-by: Carlo Mion <mion00@gmail.com>
| ... | ... |
@@ -41,8 +41,8 @@ type containerAdapter struct {
|
| 41 | 41 |
dependencies exec.DependencyGetter |
| 42 | 42 |
} |
| 43 | 43 |
|
| 44 |
-func newContainerAdapter(b executorpkg.Backend, task *api.Task, dependencies exec.DependencyGetter) (*containerAdapter, error) {
|
|
| 45 |
- ctnr, err := newContainerConfig(task) |
|
| 44 |
+func newContainerAdapter(b executorpkg.Backend, task *api.Task, node *api.NodeDescription, dependencies exec.DependencyGetter) (*containerAdapter, error) {
|
|
| 45 |
+ ctnr, err := newContainerConfig(task, node) |
|
| 46 | 46 |
if err != nil {
|
| 47 | 47 |
return nil, err |
| 48 | 48 |
} |
| ... | ... |
@@ -20,8 +20,8 @@ type networkAttacherController struct {
|
| 20 | 20 |
closed chan struct{}
|
| 21 | 21 |
} |
| 22 | 22 |
|
| 23 |
-func newNetworkAttacherController(b executorpkg.Backend, task *api.Task, dependencies exec.DependencyGetter) (*networkAttacherController, error) {
|
|
| 24 |
- adapter, err := newContainerAdapter(b, task, dependencies) |
|
| 23 |
+func newNetworkAttacherController(b executorpkg.Backend, task *api.Task, node *api.NodeDescription, dependencies exec.DependencyGetter) (*networkAttacherController, error) {
|
|
| 24 |
+ adapter, err := newContainerAdapter(b, task, node, dependencies) |
|
| 25 | 25 |
if err != nil {
|
| 26 | 26 |
return nil, err |
| 27 | 27 |
} |
| ... | ... |
@@ -48,12 +48,12 @@ type containerConfig struct {
|
| 48 | 48 |
|
| 49 | 49 |
// newContainerConfig returns a validated container config. No methods should |
| 50 | 50 |
// return an error if this function returns without error. |
| 51 |
-func newContainerConfig(t *api.Task) (*containerConfig, error) {
|
|
| 51 |
+func newContainerConfig(t *api.Task, node *api.NodeDescription) (*containerConfig, error) {
|
|
| 52 | 52 |
var c containerConfig |
| 53 |
- return &c, c.setTask(t) |
|
| 53 |
+ return &c, c.setTask(t, node) |
|
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 |
-func (c *containerConfig) setTask(t *api.Task) error {
|
|
| 56 |
+func (c *containerConfig) setTask(t *api.Task, node *api.NodeDescription) error {
|
|
| 57 | 57 |
if t.Spec.GetContainer() == nil && t.Spec.GetAttachment() == nil {
|
| 58 | 58 |
return exec.ErrRuntimeUnsupported |
| 59 | 59 |
} |
| ... | ... |
@@ -78,7 +78,7 @@ func (c *containerConfig) setTask(t *api.Task) error {
|
| 78 | 78 |
c.task = t |
| 79 | 79 |
|
| 80 | 80 |
if t.Spec.GetContainer() != nil {
|
| 81 |
- preparedSpec, err := template.ExpandContainerSpec(nil, t) |
|
| 81 |
+ preparedSpec, err := template.ExpandContainerSpec(node, t) |
|
| 82 | 82 |
if err != nil {
|
| 83 | 83 |
return err |
| 84 | 84 |
} |
| ... | ... |
@@ -40,8 +40,8 @@ type controller struct {
|
| 40 | 40 |
var _ exec.Controller = &controller{}
|
| 41 | 41 |
|
| 42 | 42 |
// NewController returns a docker exec runner for the provided task. |
| 43 |
-func newController(b executorpkg.Backend, task *api.Task, dependencies exec.DependencyGetter) (*controller, error) {
|
|
| 44 |
- adapter, err := newContainerAdapter(b, task, dependencies) |
|
| 43 |
+func newController(b executorpkg.Backend, task *api.Task, node *api.NodeDescription, dependencies exec.DependencyGetter) (*controller, error) {
|
|
| 44 |
+ adapter, err := newContainerAdapter(b, task, node, dependencies) |
|
| 45 | 45 |
if err != nil {
|
| 46 | 46 |
return nil, err |
| 47 | 47 |
} |
| ... | ... |
@@ -4,6 +4,7 @@ import ( |
| 4 | 4 |
"fmt" |
| 5 | 5 |
"sort" |
| 6 | 6 |
"strings" |
| 7 |
+ "sync" |
|
| 7 | 8 |
|
| 8 | 9 |
"github.com/docker/docker/api/types" |
| 9 | 10 |
"github.com/docker/docker/api/types/filters" |
| ... | ... |
@@ -26,6 +27,8 @@ type executor struct {
|
| 26 | 26 |
backend executorpkg.Backend |
| 27 | 27 |
pluginBackend plugin.Backend |
| 28 | 28 |
dependencies exec.DependencyManager |
| 29 |
+ mutex sync.Mutex // This mutex protects the following node field |
|
| 30 |
+ node *api.NodeDescription |
|
| 29 | 31 |
} |
| 30 | 32 |
|
| 31 | 33 |
// NewExecutor returns an executor from the docker client. |
| ... | ... |
@@ -124,6 +127,11 @@ func (e *executor) Describe(ctx context.Context) (*api.NodeDescription, error) {
|
| 124 | 124 |
}, |
| 125 | 125 |
} |
| 126 | 126 |
|
| 127 |
+ // Save the node information in the executor field |
|
| 128 |
+ e.mutex.Lock() |
|
| 129 |
+ e.node = description |
|
| 130 |
+ e.mutex.Unlock() |
|
| 131 |
+ |
|
| 127 | 132 |
return description, nil |
| 128 | 133 |
} |
| 129 | 134 |
|
| ... | ... |
@@ -168,8 +176,13 @@ func (e *executor) Configure(ctx context.Context, node *api.Node) error {
|
| 168 | 168 |
func (e *executor) Controller(t *api.Task) (exec.Controller, error) {
|
| 169 | 169 |
dependencyGetter := agent.Restrict(e.dependencies, t) |
| 170 | 170 |
|
| 171 |
+ // Get the node description from the executor field |
|
| 172 |
+ e.mutex.Lock() |
|
| 173 |
+ nodeDescription := e.node |
|
| 174 |
+ e.mutex.Unlock() |
|
| 175 |
+ |
|
| 171 | 176 |
if t.Spec.GetAttachment() != nil {
|
| 172 |
- return newNetworkAttacherController(e.backend, t, dependencyGetter) |
|
| 177 |
+ return newNetworkAttacherController(e.backend, t, nodeDescription, dependencyGetter) |
|
| 173 | 178 |
} |
| 174 | 179 |
|
| 175 | 180 |
var ctlr exec.Controller |
| ... | ... |
@@ -198,7 +211,7 @@ func (e *executor) Controller(t *api.Task) (exec.Controller, error) {
|
| 198 | 198 |
return ctlr, fmt.Errorf("unsupported runtime type: %q", runtimeKind)
|
| 199 | 199 |
} |
| 200 | 200 |
case *api.TaskSpec_Container: |
| 201 |
- c, err := newController(e.backend, t, dependencyGetter) |
|
| 201 |
+ c, err := newController(e.backend, t, nodeDescription, dependencyGetter) |
|
| 202 | 202 |
if err != nil {
|
| 203 | 203 |
return ctlr, err |
| 204 | 204 |
} |
| ... | ... |
@@ -169,8 +169,10 @@ func (s *DockerSwarmSuite) TestSwarmIncompatibleDaemon(c *check.C) {
|
| 169 | 169 |
|
| 170 | 170 |
func (s *DockerSwarmSuite) TestSwarmServiceTemplatingHostname(c *check.C) {
|
| 171 | 171 |
d := s.AddDaemon(c, true, true) |
| 172 |
+ hostname, err := d.Cmd("node", "inspect", "--format", "{{.Description.Hostname}}", "self")
|
|
| 173 |
+ c.Assert(err, checker.IsNil, check.Commentf(hostname)) |
|
| 172 | 174 |
|
| 173 |
- out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "test", "--hostname", "{{.Service.Name}}-{{.Task.Slot}}", "busybox", "top")
|
|
| 175 |
+ out, err := d.Cmd("service", "create", "--no-resolve-image", "--name", "test", "--hostname", "{{.Service.Name}}-{{.Task.Slot}}-{{.Node.Hostname}}", "busybox", "top")
|
|
| 174 | 176 |
c.Assert(err, checker.IsNil, check.Commentf(out)) |
| 175 | 177 |
|
| 176 | 178 |
// make sure task has been deployed. |
| ... | ... |
@@ -179,7 +181,7 @@ func (s *DockerSwarmSuite) TestSwarmServiceTemplatingHostname(c *check.C) {
|
| 179 | 179 |
containers := d.ActiveContainers() |
| 180 | 180 |
out, err = d.Cmd("inspect", "--type", "container", "--format", "{{.Config.Hostname}}", containers[0])
|
| 181 | 181 |
c.Assert(err, checker.IsNil, check.Commentf(out)) |
| 182 |
- c.Assert(strings.Split(out, "\n")[0], checker.Equals, "test-1", check.Commentf("hostname with templating invalid"))
|
|
| 182 |
+ c.Assert(strings.Split(out, "\n")[0], checker.Equals, "test-1-"+strings.Split(hostname, "\n")[0], check.Commentf("hostname with templating invalid"))
|
|
| 183 | 183 |
} |
| 184 | 184 |
|
| 185 | 185 |
// Test case for #24270 |