context.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package template
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/docker/swarmkit/api"
  6. "github.com/docker/swarmkit/api/naming"
  7. )
  8. // Context defines the strict set of values that can be injected into a
  9. // template expression in SwarmKit data structure.
  10. type Context struct {
  11. Service struct {
  12. ID string
  13. Name string
  14. Labels map[string]string
  15. }
  16. Node struct {
  17. ID string
  18. }
  19. Task struct {
  20. ID string
  21. Name string
  22. Slot string
  23. // NOTE(stevvooe): Why no labels here? Tasks don't actually have labels
  24. // (from a user perspective). The labels are part of the container! If
  25. // one wants to use labels for templating, use service labels!
  26. }
  27. }
  28. // NewContextFromTask returns a new template context from the data available in
  29. // task. The provided context can then be used to populate runtime values in a
  30. // ContainerSpec.
  31. func NewContextFromTask(t *api.Task) (ctx Context) {
  32. ctx.Service.ID = t.ServiceID
  33. ctx.Service.Name = t.ServiceAnnotations.Name
  34. ctx.Service.Labels = t.ServiceAnnotations.Labels
  35. ctx.Node.ID = t.NodeID
  36. ctx.Task.ID = t.ID
  37. ctx.Task.Name = naming.Task(t)
  38. if t.Slot != 0 {
  39. ctx.Task.Slot = fmt.Sprint(t.Slot)
  40. } else {
  41. // fall back to node id for slot when there is no slot
  42. ctx.Task.Slot = t.NodeID
  43. }
  44. return
  45. }
  46. // Expand treats the string s as a template and populates it with values from
  47. // the context.
  48. func (ctx *Context) Expand(s string) (string, error) {
  49. tmpl, err := newTemplate(s)
  50. if err != nil {
  51. return s, err
  52. }
  53. var buf bytes.Buffer
  54. if err := tmpl.Execute(&buf, ctx); err != nil {
  55. return s, err
  56. }
  57. return buf.String(), nil
  58. }