volume.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package main
  2. import (
  3. "archive/tar"
  4. "bytes"
  5. "context"
  6. "io"
  7. "github.com/docker/docker/api/types"
  8. "github.com/docker/docker/api/types/container"
  9. "github.com/docker/docker/api/types/mount"
  10. "github.com/docker/docker/api/types/volume"
  11. "github.com/docker/docker/client"
  12. )
  13. func createTar(data map[string][]byte) (io.Reader, error) {
  14. var b bytes.Buffer
  15. tw := tar.NewWriter(&b)
  16. for path, datum := range data {
  17. hdr := tar.Header{
  18. Name: path,
  19. Mode: 0644,
  20. Size: int64(len(datum)),
  21. }
  22. if err := tw.WriteHeader(&hdr); err != nil {
  23. return nil, err
  24. }
  25. _, err := tw.Write(datum)
  26. if err != nil {
  27. return nil, err
  28. }
  29. }
  30. if err := tw.Close(); err != nil {
  31. return nil, err
  32. }
  33. return &b, nil
  34. }
  35. // createVolumeWithData creates a volume with the given data (e.g. data["/foo"] = []byte("bar"))
  36. // Internally, a container is created from the image so as to provision the data to the volume,
  37. // which is attached to the container.
  38. func createVolumeWithData(cli *client.Client, volumeName string, data map[string][]byte, image string) error {
  39. _, err := cli.VolumeCreate(context.Background(),
  40. volume.VolumesCreateBody{
  41. Driver: "local",
  42. Name: volumeName,
  43. })
  44. if err != nil {
  45. return err
  46. }
  47. mnt := "/mnt"
  48. miniContainer, err := cli.ContainerCreate(context.Background(),
  49. &container.Config{
  50. Image: image,
  51. },
  52. &container.HostConfig{
  53. Mounts: []mount.Mount{
  54. {
  55. Type: mount.TypeVolume,
  56. Source: volumeName,
  57. Target: mnt,
  58. },
  59. },
  60. }, nil, "")
  61. if err != nil {
  62. return err
  63. }
  64. tr, err := createTar(data)
  65. if err != nil {
  66. return err
  67. }
  68. if cli.CopyToContainer(context.Background(),
  69. miniContainer.ID, mnt, tr, types.CopyToContainerOptions{}); err != nil {
  70. return err
  71. }
  72. return cli.ContainerRemove(context.Background(),
  73. miniContainer.ID,
  74. types.ContainerRemoveOptions{})
  75. }
  76. func hasVolume(cli *client.Client, volumeName string) bool {
  77. _, err := cli.VolumeInspect(context.Background(), volumeName)
  78. return err == nil
  79. }
  80. func removeVolume(cli *client.Client, volumeName string) error {
  81. return cli.VolumeRemove(context.Background(), volumeName, true)
  82. }