diff options
Diffstat (limited to 'pkg/copy')
-rw-r--r-- | pkg/copy/copy.go | 1 | ||||
-rw-r--r-- | pkg/copy/fileinfo.go | 56 | ||||
-rw-r--r-- | pkg/copy/item.go | 13 |
3 files changed, 56 insertions, 14 deletions
diff --git a/pkg/copy/copy.go b/pkg/copy/copy.go index 0e68eb450..3993b532e 100644 --- a/pkg/copy/copy.go +++ b/pkg/copy/copy.go @@ -114,7 +114,6 @@ func enforceCopyRules(source, destination *CopyItem) error { return nil } - // Source is a *stream*. if source.info.IsStream { if !(destination.info.IsDir || destination.info.IsStream) { return errors.New("destination must be a directory or stream when copying from a stream") diff --git a/pkg/copy/fileinfo.go b/pkg/copy/fileinfo.go new file mode 100644 index 000000000..08b4eb377 --- /dev/null +++ b/pkg/copy/fileinfo.go @@ -0,0 +1,56 @@ +package copy + +import ( + "encoding/base64" + "encoding/json" + "net/http" + "os" + "strings" + "time" + + "github.com/pkg/errors" +) + +// XDockerContainerPathStatHeader is the *key* in http headers pointing to the +// base64 encoded JSON payload of stating a path in a container. +const XDockerContainerPathStatHeader = "X-Docker-Container-Path-Stat" + +// FileInfo describes a file or directory and is returned by +// (*CopyItem).Stat(). +type FileInfo struct { + Name string `json:"name"` + Size int64 `json:"size"` + Mode os.FileMode `json:"mode"` + ModTime time.Time `json:"mtime"` + IsDir bool `json:"isDir"` + IsStream bool `json:"isStream"` + LinkTarget string `json:"linkTarget"` +} + +// EncodeFileInfo serializes the specified FileInfo as a base64 encoded JSON +// payload. Intended for Docker compat. +func EncodeFileInfo(info *FileInfo) (string, error) { + buf, err := json.Marshal(&info) + if err != nil { + return "", errors.Wrap(err, "failed to serialize file stats") + } + return base64.URLEncoding.EncodeToString(buf), nil +} + +// ExtractFileInfoFromHeader extracts a base64 encoded JSON payload of a +// FileInfo in the http header. If no such header entry is found, nil is +// returned. Intended for Docker compat. +func ExtractFileInfoFromHeader(header *http.Header) (*FileInfo, error) { + rawData := header.Get(XDockerContainerPathStatHeader) + if len(rawData) == 0 { + return nil, nil + } + + info := FileInfo{} + base64Decoder := base64.NewDecoder(base64.URLEncoding, strings.NewReader(rawData)) + if err := json.NewDecoder(base64Decoder).Decode(&info); err != nil { + return nil, err + } + + return &info, nil +} diff --git a/pkg/copy/item.go b/pkg/copy/item.go index db6bca610..df8bf30b9 100644 --- a/pkg/copy/item.go +++ b/pkg/copy/item.go @@ -5,7 +5,6 @@ import ( "os" "path/filepath" "strings" - "time" buildahCopiah "github.com/containers/buildah/copier" "github.com/containers/buildah/pkg/chrootuser" @@ -75,18 +74,6 @@ type CopyItem struct { // deferFunc allows for returning functions that must be deferred at call sites. type deferFunc func() -// FileInfo describes a file or directory and is returned by -// (*CopyItem).Stat(). -type FileInfo struct { - Name string `json:"name"` - Size int64 `json:"size"` - Mode os.FileMode `json:"mode"` - ModTime time.Time `json:"mtime"` - IsDir bool `json:"isDir"` - IsStream bool `json:"isStream"` - LinkTarget string `json:"linkTarget"` -} - // Stat returns the FileInfo. func (item *CopyItem) Stat() (*FileInfo, error) { return &item.info, item.statError |