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