MCPcopy
hub / github.com/moby/moby / splitConfigRootFSFromTar

Function splitConfigRootFSFromTar

daemon/pkg/plugin/backend_linux.go:759–818  ·  view source on GitHub ↗
(in io.ReadCloser, config *[]byte)

Source from the content-addressed store, hash-verified

757}
758
759func splitConfigRootFSFromTar(in io.ReadCloser, config *[]byte) io.ReadCloser {
760 pr, pw := io.Pipe()
761 go func() {
762 tarReader := tar.NewReader(in)
763 tarWriter := tar.NewWriter(pw)
764 defer in.Close()
765
766 hasRootFS := false
767
768 for {
769 hdr, err := tarReader.Next()
770 if err == io.EOF {
771 if !hasRootFS {
772 pw.CloseWithError(errors.Wrap(err, "no rootfs found"))
773 return
774 }
775 // Signals end of archive.
776 tarWriter.Close()
777 pw.Close()
778 return
779 }
780 if err != nil {
781 pw.CloseWithError(errors.Wrap(err, "failed to read from tar"))
782 return
783 }
784
785 content := io.Reader(tarReader)
786 name := path.Clean(hdr.Name)
787 if path.IsAbs(name) {
788 name = name[1:]
789 }
790 if name == configFileName {
791 dt, err := io.ReadAll(content)
792 if err != nil {
793 pw.CloseWithError(errors.Wrapf(err, "failed to read %s", configFileName))
794 return
795 }
796 *config = dt
797 }
798 if parts := strings.Split(name, "/"); len(parts) != 0 && parts[0] == rootFSFileName {
799 hdr.Name = path.Clean(path.Join(parts[1:]...))
800 if hdr.Typeflag == tar.TypeLink && strings.HasPrefix(strings.ToLower(hdr.Linkname), rootFSFileName+"/") {
801 hdr.Linkname = hdr.Linkname[len(rootFSFileName)+1:]
802 }
803 if err := tarWriter.WriteHeader(hdr); err != nil {
804 pw.CloseWithError(errors.Wrap(err, "error writing tar header"))
805 return
806 }
807 if _, err := pools.Copy(tarWriter, content); err != nil {
808 pw.CloseWithError(errors.Wrap(err, "error copying tar data"))
809 return
810 }
811 hasRootFS = true
812 } else {
813 io.Copy(io.Discard, content)
814 }
815 }
816 }()

Callers 1

CreateFromContextMethod · 0.85

Calls 9

CopyFunction · 0.92
CloseWithErrorMethod · 0.80
ReaderMethod · 0.80
WriteHeaderMethod · 0.80
CloseMethod · 0.65
JoinMethod · 0.65
NextMethod · 0.45
CleanMethod · 0.45
CopyMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…