copy.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package server
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. "os"
  9. "strings"
  10. "github.com/docker/docker/api/types"
  11. "github.com/docker/docker/pkg/version"
  12. )
  13. // postContainersCopy is deprecated in favor of getContainersArchive.
  14. func (s *Server) postContainersCopy(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
  15. if vars == nil {
  16. return fmt.Errorf("Missing parameter")
  17. }
  18. if err := checkForJSON(r); err != nil {
  19. return err
  20. }
  21. cfg := types.CopyConfig{}
  22. if err := json.NewDecoder(r.Body).Decode(&cfg); err != nil {
  23. return err
  24. }
  25. if cfg.Resource == "" {
  26. return fmt.Errorf("Path cannot be empty")
  27. }
  28. data, err := s.daemon.ContainerCopy(vars["name"], cfg.Resource)
  29. if err != nil {
  30. if strings.Contains(strings.ToLower(err.Error()), "no such id") {
  31. w.WriteHeader(http.StatusNotFound)
  32. return nil
  33. }
  34. if os.IsNotExist(err) {
  35. return fmt.Errorf("Could not find the file %s in container %s", cfg.Resource, vars["name"])
  36. }
  37. return err
  38. }
  39. defer data.Close()
  40. w.Header().Set("Content-Type", "application/x-tar")
  41. if _, err := io.Copy(w, data); err != nil {
  42. return err
  43. }
  44. return nil
  45. }
  46. // // Encode the stat to JSON, base64 encode, and place in a header.
  47. func setContainerPathStatHeader(stat *types.ContainerPathStat, header http.Header) error {
  48. statJSON, err := json.Marshal(stat)
  49. if err != nil {
  50. return err
  51. }
  52. header.Set(
  53. "X-Docker-Container-Path-Stat",
  54. base64.StdEncoding.EncodeToString(statJSON),
  55. )
  56. return nil
  57. }
  58. func (s *Server) headContainersArchive(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
  59. v, err := archiveFormValues(r, vars)
  60. if err != nil {
  61. return err
  62. }
  63. stat, err := s.daemon.ContainerStatPath(v.name, v.path)
  64. if err != nil {
  65. return err
  66. }
  67. return setContainerPathStatHeader(stat, w.Header())
  68. }
  69. func (s *Server) getContainersArchive(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
  70. v, err := archiveFormValues(r, vars)
  71. if err != nil {
  72. return err
  73. }
  74. tarArchive, stat, err := s.daemon.ContainerArchivePath(v.name, v.path)
  75. if err != nil {
  76. return err
  77. }
  78. defer tarArchive.Close()
  79. if err := setContainerPathStatHeader(stat, w.Header()); err != nil {
  80. return err
  81. }
  82. w.Header().Set("Content-Type", "application/x-tar")
  83. _, err = io.Copy(w, tarArchive)
  84. return err
  85. }
  86. func (s *Server) putContainersArchive(version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
  87. v, err := archiveFormValues(r, vars)
  88. if err != nil {
  89. return err
  90. }
  91. noOverwriteDirNonDir := boolValue(r, "noOverwriteDirNonDir")
  92. return s.daemon.ContainerExtractToDir(v.name, v.path, noOverwriteDirNonDir, r.Body)
  93. }