1
0

transformers.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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 bridge
  14. import (
  15. "context"
  16. "fmt"
  17. "os"
  18. "path/filepath"
  19. "github.com/docker/cli/cli/command"
  20. "github.com/docker/docker/api/types/container"
  21. "github.com/docker/docker/api/types/filters"
  22. "github.com/docker/docker/api/types/image"
  23. "github.com/docker/docker/api/types/network"
  24. "github.com/moby/go-archive"
  25. )
  26. const (
  27. TransformerLabel = "com.docker.compose.bridge"
  28. DefaultTransformerImage = "docker/compose-bridge-kubernetes"
  29. )
  30. type CreateTransformerOptions struct {
  31. Dest string
  32. From string
  33. }
  34. func CreateTransformer(ctx context.Context, dockerCli command.Cli, options CreateTransformerOptions) error {
  35. if options.From == "" {
  36. options.From = DefaultTransformerImage
  37. }
  38. out, err := filepath.Abs(options.Dest)
  39. if err != nil {
  40. return err
  41. }
  42. if _, err := os.Stat(out); err == nil {
  43. return fmt.Errorf("output folder %s already exists", out)
  44. }
  45. tmpl := filepath.Join(out, "templates")
  46. err = os.MkdirAll(tmpl, 0o744)
  47. if err != nil && !os.IsExist(err) {
  48. return fmt.Errorf("cannot create output folder: %w", err)
  49. }
  50. if err := command.ValidateOutputPath(out); err != nil {
  51. return err
  52. }
  53. created, err := dockerCli.Client().ContainerCreate(ctx, &container.Config{
  54. Image: options.From,
  55. }, &container.HostConfig{}, &network.NetworkingConfig{}, nil, "")
  56. defer func() {
  57. _ = dockerCli.Client().ContainerRemove(context.Background(), created.ID, container.RemoveOptions{Force: true})
  58. }()
  59. if err != nil {
  60. return err
  61. }
  62. content, stat, err := dockerCli.Client().CopyFromContainer(ctx, created.ID, "/templates")
  63. if err != nil {
  64. return err
  65. }
  66. defer func() {
  67. _ = content.Close()
  68. }()
  69. srcInfo := archive.CopyInfo{
  70. Path: "/templates",
  71. Exists: true,
  72. IsDir: stat.Mode.IsDir(),
  73. }
  74. preArchive := content
  75. if srcInfo.RebaseName != "" {
  76. _, srcBase := archive.SplitPathDirEntry(srcInfo.Path)
  77. preArchive = archive.RebaseArchiveEntries(content, srcBase, srcInfo.RebaseName)
  78. }
  79. if err := archive.CopyTo(preArchive, srcInfo, out); err != nil {
  80. return err
  81. }
  82. dockerfile := `FROM docker/compose-bridge-transformer
  83. LABEL com.docker.compose.bridge=transformation
  84. COPY templates /templates
  85. `
  86. if err := os.WriteFile(filepath.Join(out, "Dockerfile"), []byte(dockerfile), 0o700); err != nil {
  87. return err
  88. }
  89. _, err = fmt.Fprintf(dockerCli.Out(), "Transformer created in %q\n", out)
  90. return err
  91. }
  92. func ListTransformers(ctx context.Context, dockerCli command.Cli) ([]image.Summary, error) {
  93. api := dockerCli.Client()
  94. return api.ImageList(ctx, image.ListOptions{
  95. Filters: filters.NewArgs(
  96. filters.Arg("label", fmt.Sprintf("%s=%s", TransformerLabel, "transformation")),
  97. ),
  98. })
  99. }