executor.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package container
  2. import (
  3. "sort"
  4. "strings"
  5. "github.com/docker/docker/api/types"
  6. "github.com/docker/docker/api/types/network"
  7. executorpkg "github.com/docker/docker/daemon/cluster/executor"
  8. clustertypes "github.com/docker/docker/daemon/cluster/provider"
  9. networktypes "github.com/docker/libnetwork/types"
  10. "github.com/docker/swarmkit/agent/exec"
  11. "github.com/docker/swarmkit/agent/secrets"
  12. "github.com/docker/swarmkit/api"
  13. "golang.org/x/net/context"
  14. )
  15. type executor struct {
  16. backend executorpkg.Backend
  17. secrets exec.SecretsManager
  18. }
  19. // NewExecutor returns an executor from the docker client.
  20. func NewExecutor(b executorpkg.Backend) exec.Executor {
  21. return &executor{
  22. backend: b,
  23. secrets: secrets.NewManager(),
  24. }
  25. }
  26. // Describe returns the underlying node description from the docker client.
  27. func (e *executor) Describe(ctx context.Context) (*api.NodeDescription, error) {
  28. info, err := e.backend.SystemInfo()
  29. if err != nil {
  30. return nil, err
  31. }
  32. plugins := map[api.PluginDescription]struct{}{}
  33. addPlugins := func(typ string, names []string) {
  34. for _, name := range names {
  35. plugins[api.PluginDescription{
  36. Type: typ,
  37. Name: name,
  38. }] = struct{}{}
  39. }
  40. }
  41. addPlugins("Volume", info.Plugins.Volume)
  42. // Add builtin driver "overlay" (the only builtin multi-host driver) to
  43. // the plugin list by default.
  44. addPlugins("Network", append([]string{"overlay"}, info.Plugins.Network...))
  45. addPlugins("Authorization", info.Plugins.Authorization)
  46. pluginFields := make([]api.PluginDescription, 0, len(plugins))
  47. for k := range plugins {
  48. pluginFields = append(pluginFields, k)
  49. }
  50. sort.Sort(sortedPlugins(pluginFields))
  51. // parse []string labels into a map[string]string
  52. labels := map[string]string{}
  53. for _, l := range info.Labels {
  54. stringSlice := strings.SplitN(l, "=", 2)
  55. // this will take the last value in the list for a given key
  56. // ideally, one shouldn't assign multiple values to the same key
  57. if len(stringSlice) > 1 {
  58. labels[stringSlice[0]] = stringSlice[1]
  59. }
  60. }
  61. description := &api.NodeDescription{
  62. Hostname: info.Name,
  63. Platform: &api.Platform{
  64. Architecture: info.Architecture,
  65. OS: info.OSType,
  66. },
  67. Engine: &api.EngineDescription{
  68. EngineVersion: info.ServerVersion,
  69. Labels: labels,
  70. Plugins: pluginFields,
  71. },
  72. Resources: &api.Resources{
  73. NanoCPUs: int64(info.NCPU) * 1e9,
  74. MemoryBytes: info.MemTotal,
  75. },
  76. }
  77. return description, nil
  78. }
  79. func (e *executor) Configure(ctx context.Context, node *api.Node) error {
  80. na := node.Attachment
  81. if na == nil {
  82. return nil
  83. }
  84. options := types.NetworkCreate{
  85. Driver: na.Network.DriverState.Name,
  86. IPAM: &network.IPAM{
  87. Driver: na.Network.IPAM.Driver.Name,
  88. },
  89. Options: na.Network.DriverState.Options,
  90. CheckDuplicate: true,
  91. }
  92. for _, ic := range na.Network.IPAM.Configs {
  93. c := network.IPAMConfig{
  94. Subnet: ic.Subnet,
  95. IPRange: ic.Range,
  96. Gateway: ic.Gateway,
  97. }
  98. options.IPAM.Config = append(options.IPAM.Config, c)
  99. }
  100. return e.backend.SetupIngress(clustertypes.NetworkCreateRequest{
  101. ID: na.Network.ID,
  102. NetworkCreateRequest: types.NetworkCreateRequest{
  103. Name: na.Network.Spec.Annotations.Name,
  104. NetworkCreate: options,
  105. },
  106. }, na.Addresses[0])
  107. }
  108. // Controller returns a docker container runner.
  109. func (e *executor) Controller(t *api.Task) (exec.Controller, error) {
  110. if t.Spec.GetAttachment() != nil {
  111. return newNetworkAttacherController(e.backend, t, e.secrets)
  112. }
  113. ctlr, err := newController(e.backend, t, e.secrets)
  114. if err != nil {
  115. return nil, err
  116. }
  117. return ctlr, nil
  118. }
  119. func (e *executor) SetNetworkBootstrapKeys(keys []*api.EncryptionKey) error {
  120. nwKeys := []*networktypes.EncryptionKey{}
  121. for _, key := range keys {
  122. nwKey := &networktypes.EncryptionKey{
  123. Subsystem: key.Subsystem,
  124. Algorithm: int32(key.Algorithm),
  125. Key: make([]byte, len(key.Key)),
  126. LamportTime: key.LamportTime,
  127. }
  128. copy(nwKey.Key, key.Key)
  129. nwKeys = append(nwKeys, nwKey)
  130. }
  131. e.backend.SetNetworkBootstrapKeys(nwKeys)
  132. return nil
  133. }
  134. func (e *executor) Secrets() exec.SecretsManager {
  135. return e.secrets
  136. }
  137. type sortedPlugins []api.PluginDescription
  138. func (sp sortedPlugins) Len() int { return len(sp) }
  139. func (sp sortedPlugins) Swap(i, j int) { sp[i], sp[j] = sp[j], sp[i] }
  140. func (sp sortedPlugins) Less(i, j int) bool {
  141. if sp[i].Type != sp[j].Type {
  142. return sp[i].Type < sp[j].Type
  143. }
  144. return sp[i].Name < sp[j].Name
  145. }