github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/bindings/containers/archive.go (about) 1 package containers 2 3 import ( 4 "context" 5 "io" 6 "net/http" 7 "net/url" 8 9 "github.com/hanks177/podman/v4/pkg/bindings" 10 "github.com/hanks177/podman/v4/pkg/copy" 11 "github.com/hanks177/podman/v4/pkg/domain/entities" 12 "github.com/pkg/errors" 13 ) 14 15 // Stat checks if the specified path is on the container. Note that the stat 16 // report may be set even in case of an error. This happens when the path 17 // resolves to symlink pointing to a non-existent path. 18 func Stat(ctx context.Context, nameOrID string, path string) (*entities.ContainerStatReport, error) { 19 conn, err := bindings.GetClient(ctx) 20 if err != nil { 21 return nil, err 22 } 23 params := url.Values{} 24 params.Set("path", path) 25 26 response, err := conn.DoRequest(ctx, nil, http.MethodHead, "/containers/%s/archive", params, nil, nameOrID) 27 if err != nil { 28 return nil, err 29 } 30 defer response.Body.Close() 31 32 var finalErr error 33 if response.StatusCode == http.StatusNotFound { 34 finalErr = copy.ErrENOENT 35 } else if response.StatusCode != http.StatusOK { 36 finalErr = errors.New(response.Status) 37 } 38 39 var statReport *entities.ContainerStatReport 40 41 fileInfo, err := copy.ExtractFileInfoFromHeader(&response.Header) 42 if err != nil && finalErr == nil { 43 return nil, err 44 } 45 46 if fileInfo != nil { 47 statReport = &entities.ContainerStatReport{FileInfo: *fileInfo} 48 } 49 50 return statReport, finalErr 51 } 52 53 func CopyFromArchive(ctx context.Context, nameOrID string, path string, reader io.Reader) (entities.ContainerCopyFunc, error) { 54 return CopyFromArchiveWithOptions(ctx, nameOrID, path, reader, nil) 55 } 56 57 // CopyFromArchiveWithOptions copy files into container 58 func CopyFromArchiveWithOptions(ctx context.Context, nameOrID string, path string, reader io.Reader, options *CopyOptions) (entities.ContainerCopyFunc, error) { 59 conn, err := bindings.GetClient(ctx) 60 if err != nil { 61 return nil, err 62 } 63 64 params, err := options.ToParams() 65 if err != nil { 66 return nil, err 67 } 68 69 params.Set("path", path) 70 71 return func() error { 72 response, err := conn.DoRequest(ctx, reader, http.MethodPut, "/containers/%s/archive", params, nil, nameOrID) 73 if err != nil { 74 return err 75 } 76 77 if response.StatusCode != http.StatusOK { 78 return errors.New(response.Status) 79 } 80 return response.Process(nil) 81 }, nil 82 } 83 84 // CopyToArchive copy files from container 85 func CopyToArchive(ctx context.Context, nameOrID string, path string, writer io.Writer) (entities.ContainerCopyFunc, error) { 86 conn, err := bindings.GetClient(ctx) 87 if err != nil { 88 return nil, err 89 } 90 params := url.Values{} 91 params.Set("path", path) 92 93 response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/archive", params, nil, nameOrID) 94 if err != nil { 95 return nil, err 96 } 97 98 if response.StatusCode != http.StatusOK { 99 defer response.Body.Close() 100 return nil, response.Process(nil) 101 } 102 103 return func() error { 104 defer response.Body.Close() 105 _, err := io.Copy(writer, response.Body) 106 return err 107 }, nil 108 }