Skip to content

Comments

template: support templating of task runtime parameters#1650

Merged
aaronlehmann merged 1 commit intomoby:masterfrom
stevvooe:template-expansion
Nov 1, 2016
Merged

template: support templating of task runtime parameters#1650
aaronlehmann merged 1 commit intomoby:masterfrom
stevvooe:template-expansion

Conversation

@stevvooe
Copy link
Contributor

To better support common use cases that require injected service and
task information, we now treat ContainerSpec fields as templates. A
common, simplified context is defined that contains commonly needed
values, with access to names, identifiers and labels.

This initial PR focuses on supporting mounts and environment variables.
By supporting these, users will be able to locate mounts based on task
context or service name, unlocking many use cases that were previously
challenging or impossible. Environment variables open up further
possibilities.

Signed-off-by: Stephen J Day [email protected]

cc @aluzzardi @mgoelzer @ehazlett @NathanMcCauley @diogomonica

@aaronlehmann
Copy link
Collaborator

This is pretty cool.

@aaronlehmann
Copy link
Collaborator

There are some golint issues around copying a structure with a lock inside it.

I don't have a strong opinion about the template cache. I would think that templates are relatively cheap to parse (sort of like a printf format string), and if we didn't cache them, we would only need to reparse when handling a new task. This is not exactly something we'd be doing in an inner loop, so the caching probably doesn't buy us much. But maybe template parsing has more overhead than I naively expect.

@aluzzardi
Copy link
Member

I don't have a strong opinion about the template cache

Yeah, template compilation is dirt cheap compared to prepping a container

@stevvooe
Copy link
Contributor Author

I'll remove the template cache. I was breaking my own rules about premature optimization and felt dirty while doing it. If we prove a bottleneck here, we'll take care of it later. The actual answer might be to "de-feature" the template system, since complex templating isn't really needed.

@diogomonica
Copy link
Contributor

Looks pretty cool. Will this bear any relation with config management?

@stevvooe
Copy link
Contributor Author

@diogomonica This is the engine for configuration management:

  • Imagine a new mount type that carries a file that can be evaluated as a template.
  • Imagine having a secret template function to access to secrets within a template
  • Imagine wiring this context to the evaluated resources to have the template re-expanded on resource change
  • Imagine hooking in new sources for populating template variables

@tlvenn
Copy link

tlvenn commented Oct 24, 2016

That is awesome @stevvooe !

My usecase would be to create a dir mounted as tmpfs and create a file in it containing credentials pulled from Vault that my service can access transparently.

Can't wait for this to land.

@diogomonica
Copy link
Contributor

@tlvenn for this release all the secrets will be stored on the swarm managers, and will have to be added/removed/managed directly from the docker secret command. Later on we would love to support adding externally managed secrets that are imported from external secret stores and distributed throughout all the nodes.

@dnephin
Copy link
Member

dnephin commented Oct 24, 2016

This looks great.

What do you think about supporting ContainerSpec.Name and ContainerSpec.Hostname ?

@stevvooe
Copy link
Contributor Author

@dnephin There is no ContainerSpec.Name field. We'd have to integrate Annotations and work to fix the backwards compatibility issues.

ContainerSpec.Hostname is not yet merged, but I think we can go ahead and merge it and add it without issue. The main problem with it, as I found out the other day, is that Hostname isn't just the hostname. It is parsed into both Hostname and DomainName, so we have to honor that model.

@thaJeztah
Copy link
Member

Based on all the "ooooh" and "ahhhh" above, shall I move this to "code review"?

@aluzzardi
Copy link
Member

LGTM

Please rebase

@stevvooe stevvooe force-pushed the template-expansion branch 2 times, most recently from ed66a05 to 7e18ee1 Compare October 25, 2016 00:55
@stevvooe
Copy link
Contributor Author

Added support for parameterizing hostname.

@stevvooe stevvooe force-pushed the template-expansion branch 2 times, most recently from 34a8aad to c70ff24 Compare October 25, 2016 01:19
@codecov-io
Copy link

codecov-io commented Oct 25, 2016

Current coverage is 55.89% (diff: 54.34%)

Merging #1650 into master will decrease coverage by 0.08%

@@             master      #1650   diff @@
==========================================
  Files            93         96     +3   
  Lines         14796      14886    +90   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits           8283       8320    +37   
- Misses         5425       5466    +41   
- Partials       1088       1100    +12   

Sunburst

Powered by Codecov. Last update 328d703...21cdd63

@tlvenn
Copy link

tlvenn commented Oct 25, 2016

@diogomonica Can you link the Issue/PR/Proposal if any that introduce docker secret command ? I would love to learn more about it. Thanks !

@stevvooe
Copy link
Contributor Author

A few more changes:

  • removed support for Task.Labels. These aren't really of interest to the user. They can set container labels manually or template with task labels. We may allow templating of container labels in the future and this limitation preserves that choice.
  • Added some pedantic units tests ensuring that labels from the task.annotations don't pollute the templates.

@thaJeztah
Copy link
Member

ping @aaronlehmann @diogomonica PTAL, let's see if we can get this into 1.13 ❤️

ctx.Node.ID = t.NodeID

ctx.Task.ID = t.ID
ctx.Task.Name = fmt.Sprintf("%s.%d.%s", t.ServiceAnnotations.Name, t.Slot, t.ID)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it probably sounds like I'm trolling, but I remember you felt very strongly that task name derivation should not be duplicated throughout the code, and this seems to add another copy of it.

I think in the current code, t.Annotations.Name stores a precomputed task name? Although @aluzzardi said he wanted to revert this by 1.13.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do as I say, not as I do? :trollface: 🐹

We still need to centralize the naming. Is this okay for now or do want me to introduce the naming package?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A function in api/naming would do

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aluzzardi Seems outside the scope of this PR. I've asked for this in 6 other PRs and I'm not gating this feature on that addition if no one else is willing to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming package: #1694.

func ExpandContainerSpec(t *api.Task) (*api.ContainerSpec, error) {
container := t.Spec.GetContainer()
if container == nil {
return nil, nil
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this return an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, yes.

return values, err
}

entry = fmt.Sprintf("%s=%s", entry, expanded)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personal preference - feel free to ignore - but I find entry + "=" + expanded easier to read and I like the type safety benefits.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't that require two intermediates?

}

n[k] = v

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: blank line looks out of place

return container, err
}

container.Hostname, err = ctx.Expand(container.Hostname)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this and all the other calls to ctx.Expand, it seems like a good idea to wrap the error with an indication of which field caused the error.

@stevvooe stevvooe force-pushed the template-expansion branch 8 times, most recently from a9ac2ae to 2b15064 Compare October 27, 2016 22:19
@aluzzardi
Copy link
Member

LGTM

Needs rebase

To better support common use cases that require injected service and
task information, we now treat ContainerSpec fields as templates. A
common, simplified context is defined that contains commonly needed
values, with access to names, identifiers and labels.

This initial PR focuses on supporting mounts, hostname and environment
variables. By supporting these, users will be able to locate mounts
based on task context or service name, unlocking many use cases that
were previously challenging or impossible. Environment variables open up
further possibilities. Hostname is mostly harmless but useful in certain
applications.

Signed-off-by: Stephen J Day <[email protected]>
@aaronlehmann aaronlehmann merged commit b693657 into moby:master Nov 1, 2016
@stevvooe stevvooe deleted the template-expansion branch November 1, 2016 01:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants