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  }