dryrunclient.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. /*
  2. Copyright 2020 Docker Compose CLI authors
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package dryrun
  14. import (
  15. "bytes"
  16. "context"
  17. "crypto/rand"
  18. "encoding/json"
  19. "errors"
  20. "fmt"
  21. "io"
  22. "net"
  23. "net/http"
  24. "runtime"
  25. "strings"
  26. "sync"
  27. "github.com/docker/buildx/builder"
  28. "github.com/docker/buildx/util/imagetools"
  29. "github.com/docker/cli/cli/command"
  30. containerType "github.com/moby/moby/api/types/container"
  31. "github.com/moby/moby/api/types/image"
  32. "github.com/moby/moby/api/types/jsonstream"
  33. "github.com/moby/moby/api/types/volume"
  34. "github.com/moby/moby/client"
  35. )
  36. var _ client.APIClient = &DryRunClient{}
  37. // DryRunClient implements APIClient by delegating to implementation functions. This allows lazy init and per-method overrides
  38. type DryRunClient struct {
  39. apiClient client.APIClient
  40. containers []containerType.Summary
  41. execs sync.Map
  42. resolver *imagetools.Resolver
  43. }
  44. type execDetails struct {
  45. container string
  46. command []string
  47. }
  48. type fakeStreamResult struct {
  49. io.ReadCloser
  50. client.ImagePushResponse // same interface as [client.ImagePullResponse]
  51. }
  52. func (e fakeStreamResult) Read(p []byte) (int, error) { return e.ReadCloser.Read(p) }
  53. func (e fakeStreamResult) Close() error { return e.ReadCloser.Close() }
  54. // NewDryRunClient produces a DryRunClient
  55. func NewDryRunClient(apiClient client.APIClient, cli command.Cli) (*DryRunClient, error) {
  56. b, err := builder.New(cli, builder.WithSkippedValidation())
  57. if err != nil {
  58. return nil, err
  59. }
  60. configFile, err := b.ImageOpt()
  61. if err != nil {
  62. return nil, err
  63. }
  64. return &DryRunClient{
  65. apiClient: apiClient,
  66. containers: []containerType.Summary{},
  67. execs: sync.Map{},
  68. resolver: imagetools.New(configFile),
  69. }, nil
  70. }
  71. func getCallingFunction() string {
  72. pc, _, _, _ := runtime.Caller(2)
  73. fullName := runtime.FuncForPC(pc).Name()
  74. return fullName[strings.LastIndex(fullName, ".")+1:]
  75. }
  76. // All methods and functions which need to be overridden for dry run.
  77. func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, options client.ContainerAttachOptions) (client.ContainerAttachResult, error) {
  78. return client.ContainerAttachResult{}, errors.New("interactive run is not supported in dry-run mode")
  79. }
  80. func (d *DryRunClient) ContainerCreate(ctx context.Context, options client.ContainerCreateOptions) (client.ContainerCreateResult, error) {
  81. d.containers = append(d.containers, containerType.Summary{
  82. ID: options.Name,
  83. Names: []string{options.Name},
  84. Labels: options.Config.Labels,
  85. HostConfig: struct {
  86. NetworkMode string `json:",omitempty"`
  87. Annotations map[string]string `json:",omitempty"`
  88. }{},
  89. })
  90. return client.ContainerCreateResult{ID: options.Name}, nil
  91. }
  92. func (d *DryRunClient) ContainerInspect(ctx context.Context, container string, options client.ContainerInspectOptions) (client.ContainerInspectResult, error) {
  93. containerJSON, err := d.apiClient.ContainerInspect(ctx, container, options)
  94. if err != nil {
  95. id := "dryRunId"
  96. for _, c := range d.containers {
  97. if c.ID == container {
  98. id = container
  99. }
  100. }
  101. return client.ContainerInspectResult{
  102. Container: containerType.InspectResponse{
  103. ID: id,
  104. Name: container,
  105. State: &containerType.State{
  106. Status: containerType.StateRunning, // needed for --wait option
  107. Health: &containerType.Health{
  108. Status: containerType.Healthy, // needed for healthcheck control
  109. },
  110. },
  111. Mounts: nil,
  112. Config: &containerType.Config{},
  113. NetworkSettings: &containerType.NetworkSettings{},
  114. },
  115. }, nil
  116. }
  117. return containerJSON, err
  118. }
  119. func (d *DryRunClient) ContainerKill(ctx context.Context, container string, options client.ContainerKillOptions) (client.ContainerKillResult, error) {
  120. return client.ContainerKillResult{}, nil
  121. }
  122. func (d *DryRunClient) ContainerList(ctx context.Context, options client.ContainerListOptions) (client.ContainerListResult, error) {
  123. caller := getCallingFunction()
  124. switch caller {
  125. case "start":
  126. return client.ContainerListResult{
  127. Items: d.containers,
  128. }, nil
  129. case "getContainers":
  130. if len(d.containers) == 0 {
  131. res, err := d.apiClient.ContainerList(ctx, options)
  132. if err == nil {
  133. d.containers = res.Items
  134. }
  135. return client.ContainerListResult{
  136. Items: d.containers,
  137. }, err
  138. }
  139. }
  140. return d.apiClient.ContainerList(ctx, options)
  141. }
  142. func (d *DryRunClient) ContainerPause(ctx context.Context, container string, options client.ContainerPauseOptions) (client.ContainerPauseResult, error) {
  143. return client.ContainerPauseResult{}, nil
  144. }
  145. func (d *DryRunClient) ContainerRemove(ctx context.Context, container string, options client.ContainerRemoveOptions) (client.ContainerRemoveResult, error) {
  146. return client.ContainerRemoveResult{}, nil
  147. }
  148. func (d *DryRunClient) ContainerRename(ctx context.Context, container string, options client.ContainerRenameOptions) (client.ContainerRenameResult, error) {
  149. return client.ContainerRenameResult{}, nil
  150. }
  151. func (d *DryRunClient) ContainerRestart(ctx context.Context, container string, options client.ContainerRestartOptions) (client.ContainerRestartResult, error) {
  152. return client.ContainerRestartResult{}, nil
  153. }
  154. func (d *DryRunClient) ContainerStart(ctx context.Context, container string, options client.ContainerStartOptions) (client.ContainerStartResult, error) {
  155. return client.ContainerStartResult{}, nil
  156. }
  157. func (d *DryRunClient) ContainerStop(ctx context.Context, container string, options client.ContainerStopOptions) (client.ContainerStopResult, error) {
  158. return client.ContainerStopResult{}, nil
  159. }
  160. func (d *DryRunClient) ContainerUnpause(ctx context.Context, container string, options client.ContainerUnpauseOptions) (client.ContainerUnpauseResult, error) {
  161. return client.ContainerUnpauseResult{}, nil
  162. }
  163. func (d *DryRunClient) CopyFromContainer(ctx context.Context, container string, options client.CopyFromContainerOptions) (client.CopyFromContainerResult, error) {
  164. if _, err := d.ContainerStatPath(ctx, container, client.ContainerStatPathOptions{Path: options.SourcePath}); err != nil {
  165. return client.CopyFromContainerResult{}, fmt.Errorf("could not find the file %s in container %s", options.SourcePath, container)
  166. }
  167. return client.CopyFromContainerResult{}, nil
  168. }
  169. func (d *DryRunClient) CopyToContainer(ctx context.Context, container string, options client.CopyToContainerOptions) (client.CopyToContainerResult, error) {
  170. return client.CopyToContainerResult{}, nil
  171. }
  172. func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options client.ImageBuildOptions) (client.ImageBuildResult, error) {
  173. return client.ImageBuildResult{
  174. Body: io.NopCloser(bytes.NewReader(nil)),
  175. }, nil
  176. }
  177. func (d *DryRunClient) ImageInspect(ctx context.Context, imageName string, options ...client.ImageInspectOption) (client.ImageInspectResult, error) {
  178. caller := getCallingFunction()
  179. switch caller {
  180. case "pullServiceImage", "buildContainerVolumes":
  181. return client.ImageInspectResult{
  182. InspectResponse: image.InspectResponse{ID: "dryRunId"},
  183. }, nil
  184. default:
  185. return d.apiClient.ImageInspect(ctx, imageName, options...)
  186. }
  187. }
  188. func (d *DryRunClient) ImagePull(ctx context.Context, ref string, options client.ImagePullOptions) (client.ImagePullResponse, error) {
  189. if _, _, err := d.resolver.Resolve(ctx, ref); err != nil {
  190. return nil, err
  191. }
  192. return fakeStreamResult{ReadCloser: http.NoBody}, nil
  193. }
  194. func (d *DryRunClient) ImagePush(ctx context.Context, ref string, options client.ImagePushOptions) (client.ImagePushResponse, error) {
  195. if _, _, err := d.resolver.Resolve(ctx, ref); err != nil {
  196. return nil, err
  197. }
  198. jsonMessage, err := json.Marshal(&jsonstream.Message{
  199. Status: "Pushed",
  200. Progress: &jsonstream.Progress{
  201. Current: 100,
  202. Total: 100,
  203. Start: 0,
  204. HideCounts: false,
  205. Units: "Mb",
  206. },
  207. ID: ref,
  208. })
  209. if err != nil {
  210. return nil, err
  211. }
  212. return fakeStreamResult{ReadCloser: io.NopCloser(bytes.NewReader(jsonMessage))}, nil
  213. }
  214. func (d *DryRunClient) ImageRemove(ctx context.Context, imageName string, options client.ImageRemoveOptions) (client.ImageRemoveResult, error) {
  215. return client.ImageRemoveResult{}, nil
  216. }
  217. func (d *DryRunClient) NetworkConnect(ctx context.Context, networkName string, options client.NetworkConnectOptions) (client.NetworkConnectResult, error) {
  218. return client.NetworkConnectResult{}, nil
  219. }
  220. func (d *DryRunClient) NetworkCreate(ctx context.Context, name string, options client.NetworkCreateOptions) (client.NetworkCreateResult, error) {
  221. return client.NetworkCreateResult{
  222. ID: name,
  223. }, nil
  224. }
  225. func (d *DryRunClient) NetworkDisconnect(ctx context.Context, networkName string, options client.NetworkDisconnectOptions) (client.NetworkDisconnectResult, error) {
  226. return client.NetworkDisconnectResult{}, nil
  227. }
  228. func (d *DryRunClient) NetworkRemove(ctx context.Context, networkName string, options client.NetworkRemoveOptions) (client.NetworkRemoveResult, error) {
  229. return client.NetworkRemoveResult{}, nil
  230. }
  231. func (d *DryRunClient) VolumeCreate(ctx context.Context, options client.VolumeCreateOptions) (client.VolumeCreateResult, error) {
  232. return client.VolumeCreateResult{
  233. Volume: volume.Volume{
  234. ClusterVolume: nil,
  235. Driver: options.Driver,
  236. Labels: options.Labels,
  237. Name: options.Name,
  238. Options: options.DriverOpts,
  239. },
  240. }, nil
  241. }
  242. func (d *DryRunClient) VolumeRemove(ctx context.Context, volumeID string, options client.VolumeRemoveOptions) (client.VolumeRemoveResult, error) {
  243. return client.VolumeRemoveResult{}, nil
  244. }
  245. func (d *DryRunClient) ExecCreate(ctx context.Context, container string, config client.ExecCreateOptions) (client.ExecCreateResult, error) {
  246. b := make([]byte, 32)
  247. _, _ = rand.Read(b)
  248. id := fmt.Sprintf("%x", b)
  249. d.execs.Store(id, execDetails{
  250. container: container,
  251. command: config.Cmd,
  252. })
  253. return client.ExecCreateResult{
  254. ID: id,
  255. }, nil
  256. }
  257. func (d *DryRunClient) ExecStart(ctx context.Context, execID string, config client.ExecStartOptions) (client.ExecStartResult, error) {
  258. _, ok := d.execs.LoadAndDelete(execID)
  259. if !ok {
  260. return client.ExecStartResult{}, fmt.Errorf("invalid exec ID %q", execID)
  261. }
  262. return client.ExecStartResult{}, nil
  263. }
  264. // Functions delegated to original APIClient (not used by Compose or not modifying the Compose stack)
  265. func (d *DryRunClient) ConfigList(ctx context.Context, options client.ConfigListOptions) (client.ConfigListResult, error) {
  266. return d.apiClient.ConfigList(ctx, options)
  267. }
  268. func (d *DryRunClient) ConfigInspect(ctx context.Context, name string, options client.ConfigInspectOptions) (client.ConfigInspectResult, error) {
  269. return d.apiClient.ConfigInspect(ctx, name, options)
  270. }
  271. func (d *DryRunClient) ConfigCreate(ctx context.Context, options client.ConfigCreateOptions) (client.ConfigCreateResult, error) {
  272. return d.apiClient.ConfigCreate(ctx, options)
  273. }
  274. func (d *DryRunClient) ConfigRemove(ctx context.Context, id string, options client.ConfigRemoveOptions) (client.ConfigRemoveResult, error) {
  275. return d.apiClient.ConfigRemove(ctx, id, options)
  276. }
  277. func (d *DryRunClient) ConfigUpdate(ctx context.Context, id string, options client.ConfigUpdateOptions) (client.ConfigUpdateResult, error) {
  278. return d.apiClient.ConfigUpdate(ctx, id, options)
  279. }
  280. func (d *DryRunClient) ContainerCommit(ctx context.Context, container string, options client.ContainerCommitOptions) (client.ContainerCommitResult, error) {
  281. return d.apiClient.ContainerCommit(ctx, container, options)
  282. }
  283. func (d *DryRunClient) ContainerDiff(ctx context.Context, container string, options client.ContainerDiffOptions) (client.ContainerDiffResult, error) {
  284. return d.apiClient.ContainerDiff(ctx, container, options)
  285. }
  286. func (d *DryRunClient) ExecAttach(ctx context.Context, execID string, config client.ExecAttachOptions) (client.ExecAttachResult, error) {
  287. return client.ExecAttachResult{}, errors.New("interactive exec is not supported in dry-run mode")
  288. }
  289. func (d *DryRunClient) ExecInspect(ctx context.Context, execID string, options client.ExecInspectOptions) (client.ExecInspectResult, error) {
  290. return d.apiClient.ExecInspect(ctx, execID, options)
  291. }
  292. func (d *DryRunClient) ExecResize(ctx context.Context, execID string, options client.ExecResizeOptions) (client.ExecResizeResult, error) {
  293. return d.apiClient.ExecResize(ctx, execID, options)
  294. }
  295. func (d *DryRunClient) ContainerExport(ctx context.Context, container string, options client.ContainerExportOptions) (client.ContainerExportResult, error) {
  296. return d.apiClient.ContainerExport(ctx, container, options)
  297. }
  298. func (d *DryRunClient) ContainerLogs(ctx context.Context, container string, options client.ContainerLogsOptions) (client.ContainerLogsResult, error) {
  299. return d.apiClient.ContainerLogs(ctx, container, options)
  300. }
  301. func (d *DryRunClient) ContainerResize(ctx context.Context, container string, options client.ContainerResizeOptions) (client.ContainerResizeResult, error) {
  302. return d.apiClient.ContainerResize(ctx, container, options)
  303. }
  304. func (d *DryRunClient) ContainerStatPath(ctx context.Context, container string, options client.ContainerStatPathOptions) (client.ContainerStatPathResult, error) {
  305. return d.apiClient.ContainerStatPath(ctx, container, options)
  306. }
  307. func (d *DryRunClient) ContainerStats(ctx context.Context, container string, options client.ContainerStatsOptions) (client.ContainerStatsResult, error) {
  308. return d.apiClient.ContainerStats(ctx, container, options)
  309. }
  310. func (d *DryRunClient) ContainerTop(ctx context.Context, container string, options client.ContainerTopOptions) (client.ContainerTopResult, error) {
  311. return d.apiClient.ContainerTop(ctx, container, options)
  312. }
  313. func (d *DryRunClient) ContainerUpdate(ctx context.Context, container string, options client.ContainerUpdateOptions) (client.ContainerUpdateResult, error) {
  314. return d.apiClient.ContainerUpdate(ctx, container, options)
  315. }
  316. func (d *DryRunClient) ContainerWait(ctx context.Context, container string, options client.ContainerWaitOptions) client.ContainerWaitResult {
  317. return d.apiClient.ContainerWait(ctx, container, options)
  318. }
  319. func (d *DryRunClient) ContainerPrune(ctx context.Context, options client.ContainerPruneOptions) (client.ContainerPruneResult, error) {
  320. return d.apiClient.ContainerPrune(ctx, options)
  321. }
  322. func (d *DryRunClient) DistributionInspect(ctx context.Context, imageName string, options client.DistributionInspectOptions) (client.DistributionInspectResult, error) {
  323. return d.apiClient.DistributionInspect(ctx, imageName, options)
  324. }
  325. func (d *DryRunClient) BuildCachePrune(ctx context.Context, opts client.BuildCachePruneOptions) (client.BuildCachePruneResult, error) {
  326. return d.apiClient.BuildCachePrune(ctx, opts)
  327. }
  328. func (d *DryRunClient) BuildCancel(ctx context.Context, id string, opts client.BuildCancelOptions) (client.BuildCancelResult, error) {
  329. return d.apiClient.BuildCancel(ctx, id, opts)
  330. }
  331. func (d *DryRunClient) ImageHistory(ctx context.Context, imageName string, options ...client.ImageHistoryOption) (client.ImageHistoryResult, error) {
  332. return d.apiClient.ImageHistory(ctx, imageName, options...)
  333. }
  334. func (d *DryRunClient) ImageImport(ctx context.Context, source client.ImageImportSource, ref string, options client.ImageImportOptions) (client.ImageImportResult, error) {
  335. return d.apiClient.ImageImport(ctx, source, ref, options)
  336. }
  337. func (d *DryRunClient) ImageList(ctx context.Context, options client.ImageListOptions) (client.ImageListResult, error) {
  338. return d.apiClient.ImageList(ctx, options)
  339. }
  340. func (d *DryRunClient) ImageLoad(ctx context.Context, input io.Reader, options ...client.ImageLoadOption) (client.ImageLoadResult, error) {
  341. return d.apiClient.ImageLoad(ctx, input, options...)
  342. }
  343. func (d *DryRunClient) ImageSearch(ctx context.Context, term string, options client.ImageSearchOptions) (client.ImageSearchResult, error) {
  344. return d.apiClient.ImageSearch(ctx, term, options)
  345. }
  346. func (d *DryRunClient) ImageSave(ctx context.Context, images []string, options ...client.ImageSaveOption) (client.ImageSaveResult, error) {
  347. return d.apiClient.ImageSave(ctx, images, options...)
  348. }
  349. func (d *DryRunClient) ImageTag(ctx context.Context, options client.ImageTagOptions) (client.ImageTagResult, error) {
  350. return d.apiClient.ImageTag(ctx, options)
  351. }
  352. func (d *DryRunClient) ImagePrune(ctx context.Context, options client.ImagePruneOptions) (client.ImagePruneResult, error) {
  353. return d.apiClient.ImagePrune(ctx, options)
  354. }
  355. func (d *DryRunClient) NodeInspect(ctx context.Context, nodeID string, options client.NodeInspectOptions) (client.NodeInspectResult, error) {
  356. return d.apiClient.NodeInspect(ctx, nodeID, options)
  357. }
  358. func (d *DryRunClient) NodeList(ctx context.Context, options client.NodeListOptions) (client.NodeListResult, error) {
  359. return d.apiClient.NodeList(ctx, options)
  360. }
  361. func (d *DryRunClient) NodeRemove(ctx context.Context, nodeID string, options client.NodeRemoveOptions) (client.NodeRemoveResult, error) {
  362. return d.apiClient.NodeRemove(ctx, nodeID, options)
  363. }
  364. func (d *DryRunClient) NodeUpdate(ctx context.Context, nodeID string, options client.NodeUpdateOptions) (client.NodeUpdateResult, error) {
  365. return d.apiClient.NodeUpdate(ctx, nodeID, options)
  366. }
  367. func (d *DryRunClient) NetworkInspect(ctx context.Context, networkName string, options client.NetworkInspectOptions) (client.NetworkInspectResult, error) {
  368. return d.apiClient.NetworkInspect(ctx, networkName, options)
  369. }
  370. func (d *DryRunClient) NetworkList(ctx context.Context, options client.NetworkListOptions) (client.NetworkListResult, error) {
  371. return d.apiClient.NetworkList(ctx, options)
  372. }
  373. func (d *DryRunClient) NetworkPrune(ctx context.Context, options client.NetworkPruneOptions) (client.NetworkPruneResult, error) {
  374. return d.apiClient.NetworkPrune(ctx, options)
  375. }
  376. func (d *DryRunClient) PluginList(ctx context.Context, options client.PluginListOptions) (client.PluginListResult, error) {
  377. return d.apiClient.PluginList(ctx, options)
  378. }
  379. func (d *DryRunClient) PluginRemove(ctx context.Context, name string, options client.PluginRemoveOptions) (client.PluginRemoveResult, error) {
  380. return d.apiClient.PluginRemove(ctx, name, options)
  381. }
  382. func (d *DryRunClient) PluginEnable(ctx context.Context, name string, options client.PluginEnableOptions) (client.PluginEnableResult, error) {
  383. return d.apiClient.PluginEnable(ctx, name, options)
  384. }
  385. func (d *DryRunClient) PluginDisable(ctx context.Context, name string, options client.PluginDisableOptions) (client.PluginDisableResult, error) {
  386. return d.apiClient.PluginDisable(ctx, name, options)
  387. }
  388. func (d *DryRunClient) PluginInstall(ctx context.Context, name string, options client.PluginInstallOptions) (client.PluginInstallResult, error) {
  389. return d.apiClient.PluginInstall(ctx, name, options)
  390. }
  391. func (d *DryRunClient) PluginUpgrade(ctx context.Context, name string, options client.PluginUpgradeOptions) (client.PluginUpgradeResult, error) {
  392. return d.apiClient.PluginUpgrade(ctx, name, options)
  393. }
  394. func (d *DryRunClient) PluginPush(ctx context.Context, name string, options client.PluginPushOptions) (client.PluginPushResult, error) {
  395. return d.apiClient.PluginPush(ctx, name, options)
  396. }
  397. func (d *DryRunClient) PluginSet(ctx context.Context, name string, options client.PluginSetOptions) (client.PluginSetResult, error) {
  398. return d.apiClient.PluginSet(ctx, name, options)
  399. }
  400. func (d *DryRunClient) PluginInspect(ctx context.Context, name string, options client.PluginInspectOptions) (client.PluginInspectResult, error) {
  401. return d.apiClient.PluginInspect(ctx, name, options)
  402. }
  403. func (d *DryRunClient) PluginCreate(ctx context.Context, createContext io.Reader, options client.PluginCreateOptions) (client.PluginCreateResult, error) {
  404. return d.apiClient.PluginCreate(ctx, createContext, options)
  405. }
  406. func (d *DryRunClient) ServiceCreate(ctx context.Context, options client.ServiceCreateOptions) (client.ServiceCreateResult, error) {
  407. return d.apiClient.ServiceCreate(ctx, options)
  408. }
  409. func (d *DryRunClient) ServiceInspect(ctx context.Context, serviceID string, options client.ServiceInspectOptions) (client.ServiceInspectResult, error) {
  410. return d.apiClient.ServiceInspect(ctx, serviceID, options)
  411. }
  412. func (d *DryRunClient) ServiceList(ctx context.Context, options client.ServiceListOptions) (client.ServiceListResult, error) {
  413. return d.apiClient.ServiceList(ctx, options)
  414. }
  415. func (d *DryRunClient) ServiceRemove(ctx context.Context, serviceID string, options client.ServiceRemoveOptions) (client.ServiceRemoveResult, error) {
  416. return d.apiClient.ServiceRemove(ctx, serviceID, options)
  417. }
  418. func (d *DryRunClient) ServiceUpdate(ctx context.Context, serviceID string, options client.ServiceUpdateOptions) (client.ServiceUpdateResult, error) {
  419. return d.apiClient.ServiceUpdate(ctx, serviceID, options)
  420. }
  421. func (d *DryRunClient) ServiceLogs(ctx context.Context, serviceID string, options client.ServiceLogsOptions) (client.ServiceLogsResult, error) {
  422. return d.apiClient.ServiceLogs(ctx, serviceID, options)
  423. }
  424. func (d *DryRunClient) TaskLogs(ctx context.Context, taskID string, options client.TaskLogsOptions) (client.TaskLogsResult, error) {
  425. return d.apiClient.TaskLogs(ctx, taskID, options)
  426. }
  427. func (d *DryRunClient) TaskInspect(ctx context.Context, taskID string, options client.TaskInspectOptions) (client.TaskInspectResult, error) {
  428. return d.apiClient.TaskInspect(ctx, taskID, options)
  429. }
  430. func (d *DryRunClient) TaskList(ctx context.Context, options client.TaskListOptions) (client.TaskListResult, error) {
  431. return d.apiClient.TaskList(ctx, options)
  432. }
  433. func (d *DryRunClient) SwarmInit(ctx context.Context, options client.SwarmInitOptions) (client.SwarmInitResult, error) {
  434. return d.apiClient.SwarmInit(ctx, options)
  435. }
  436. func (d *DryRunClient) SwarmJoin(ctx context.Context, options client.SwarmJoinOptions) (client.SwarmJoinResult, error) {
  437. return d.apiClient.SwarmJoin(ctx, options)
  438. }
  439. func (d *DryRunClient) SwarmGetUnlockKey(ctx context.Context) (client.SwarmGetUnlockKeyResult, error) {
  440. return d.apiClient.SwarmGetUnlockKey(ctx)
  441. }
  442. func (d *DryRunClient) SwarmUnlock(ctx context.Context, options client.SwarmUnlockOptions) (client.SwarmUnlockResult, error) {
  443. return d.apiClient.SwarmUnlock(ctx, options)
  444. }
  445. func (d *DryRunClient) SwarmLeave(ctx context.Context, options client.SwarmLeaveOptions) (client.SwarmLeaveResult, error) {
  446. return d.apiClient.SwarmLeave(ctx, options)
  447. }
  448. func (d *DryRunClient) SwarmInspect(ctx context.Context, options client.SwarmInspectOptions) (client.SwarmInspectResult, error) {
  449. return d.apiClient.SwarmInspect(ctx, options)
  450. }
  451. func (d *DryRunClient) SwarmUpdate(ctx context.Context, options client.SwarmUpdateOptions) (client.SwarmUpdateResult, error) {
  452. return d.apiClient.SwarmUpdate(ctx, options)
  453. }
  454. func (d *DryRunClient) SecretList(ctx context.Context, options client.SecretListOptions) (client.SecretListResult, error) {
  455. return d.apiClient.SecretList(ctx, options)
  456. }
  457. func (d *DryRunClient) SecretCreate(ctx context.Context, options client.SecretCreateOptions) (client.SecretCreateResult, error) {
  458. return d.apiClient.SecretCreate(ctx, options)
  459. }
  460. func (d *DryRunClient) SecretRemove(ctx context.Context, id string, options client.SecretRemoveOptions) (client.SecretRemoveResult, error) {
  461. return d.apiClient.SecretRemove(ctx, id, options)
  462. }
  463. func (d *DryRunClient) SecretInspect(ctx context.Context, name string, options client.SecretInspectOptions) (client.SecretInspectResult, error) {
  464. return d.apiClient.SecretInspect(ctx, name, options)
  465. }
  466. func (d *DryRunClient) SecretUpdate(ctx context.Context, id string, options client.SecretUpdateOptions) (client.SecretUpdateResult, error) {
  467. return d.apiClient.SecretUpdate(ctx, id, options)
  468. }
  469. func (d *DryRunClient) Events(ctx context.Context, options client.EventsListOptions) client.EventsResult {
  470. return d.apiClient.Events(ctx, options)
  471. }
  472. func (d *DryRunClient) Info(ctx context.Context, options client.InfoOptions) (client.SystemInfoResult, error) {
  473. return d.apiClient.Info(ctx, options)
  474. }
  475. func (d *DryRunClient) RegistryLogin(ctx context.Context, options client.RegistryLoginOptions) (client.RegistryLoginResult, error) {
  476. return d.apiClient.RegistryLogin(ctx, options)
  477. }
  478. func (d *DryRunClient) DiskUsage(ctx context.Context, options client.DiskUsageOptions) (client.DiskUsageResult, error) {
  479. return d.apiClient.DiskUsage(ctx, options)
  480. }
  481. func (d *DryRunClient) Ping(ctx context.Context, options client.PingOptions) (client.PingResult, error) {
  482. return d.apiClient.Ping(ctx, options)
  483. }
  484. func (d *DryRunClient) VolumeInspect(ctx context.Context, volumeID string, options client.VolumeInspectOptions) (client.VolumeInspectResult, error) {
  485. return d.apiClient.VolumeInspect(ctx, volumeID, options)
  486. }
  487. func (d *DryRunClient) VolumeList(ctx context.Context, opts client.VolumeListOptions) (client.VolumeListResult, error) {
  488. return d.apiClient.VolumeList(ctx, opts)
  489. }
  490. func (d *DryRunClient) VolumePrune(ctx context.Context, options client.VolumePruneOptions) (client.VolumePruneResult, error) {
  491. return d.apiClient.VolumePrune(ctx, options)
  492. }
  493. func (d *DryRunClient) VolumeUpdate(ctx context.Context, volumeID string, options client.VolumeUpdateOptions) (client.VolumeUpdateResult, error) {
  494. return d.apiClient.VolumeUpdate(ctx, volumeID, options)
  495. }
  496. func (d *DryRunClient) ClientVersion() string {
  497. return d.apiClient.ClientVersion()
  498. }
  499. func (d *DryRunClient) DaemonHost() string {
  500. return d.apiClient.DaemonHost()
  501. }
  502. func (d *DryRunClient) ServerVersion(ctx context.Context, options client.ServerVersionOptions) (client.ServerVersionResult, error) {
  503. return d.apiClient.ServerVersion(ctx, options)
  504. }
  505. func (d *DryRunClient) DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) {
  506. return d.apiClient.DialHijack(ctx, url, proto, meta)
  507. }
  508. func (d *DryRunClient) Dialer() func(context.Context) (net.Conn, error) {
  509. return d.apiClient.Dialer()
  510. }
  511. func (d *DryRunClient) Close() error {
  512. return d.apiClient.Close()
  513. }
  514. func (d *DryRunClient) CheckpointCreate(ctx context.Context, container string, options client.CheckpointCreateOptions) (client.CheckpointCreateResult, error) {
  515. return d.apiClient.CheckpointCreate(ctx, container, options)
  516. }
  517. func (d *DryRunClient) CheckpointRemove(ctx context.Context, container string, options client.CheckpointRemoveOptions) (client.CheckpointRemoveResult, error) {
  518. return d.apiClient.CheckpointRemove(ctx, container, options)
  519. }
  520. func (d *DryRunClient) CheckpointList(ctx context.Context, container string, options client.CheckpointListOptions) (client.CheckpointListResult, error) {
  521. return d.apiClient.CheckpointList(ctx, container, options)
  522. }