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