github.com/ahlemtn/fabric@v2.1.1+incompatible/core/container/externalbuilder/metadataprovider.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package externalbuilder
     8  
     9  import (
    10  	"archive/tar"
    11  	"bytes"
    12  	"io"
    13  	"os"
    14  	"path/filepath"
    15  
    16  	"github.com/pkg/errors"
    17  )
    18  
    19  type MetadataProvider struct {
    20  	DurablePath string
    21  }
    22  
    23  // PackageMetadata returns a set of bytes encoded as a tar file, containing
    24  // the release metadata as provided by the external builder.  If no directory
    25  // with build output from the external builder is found, the tar bytes will
    26  // be nil.  If the build output is found, but there is no metadata, the bytes
    27  // will be an empty tar.  An error is returned only if the build output is
    28  // found but some other error occurs.
    29  func (mp *MetadataProvider) PackageMetadata(ccid string) ([]byte, error) {
    30  	releasePath := filepath.Join(mp.DurablePath, SanitizeCCIDPath(ccid), "release")
    31  
    32  	_, err := os.Stat(releasePath)
    33  	if os.IsNotExist(err) {
    34  		return nil, nil
    35  	}
    36  	if err != nil {
    37  		return nil, errors.WithMessage(err, "could not stat path")
    38  	}
    39  
    40  	buffer := bytes.NewBuffer(nil)
    41  	tw := tar.NewWriter(buffer)
    42  
    43  	logger.Debugf("Walking package release dir '%s'", releasePath)
    44  	err = filepath.Walk(releasePath, func(file string, fi os.FileInfo, err error) error {
    45  		if err != nil {
    46  			return err
    47  		}
    48  
    49  		header, err := tar.FileInfoHeader(fi, file)
    50  		if err != nil {
    51  			return err
    52  		}
    53  
    54  		name, err := filepath.Rel(releasePath, file)
    55  		if err != nil {
    56  			return err
    57  		}
    58  
    59  		header.Name = filepath.Join("META-INF", name)
    60  		if fi.IsDir() {
    61  			header.Name += "/"
    62  		}
    63  
    64  		logger.Debugf("Adding file '%s' to tar with header name '%s'", file, header.Name)
    65  
    66  		if err := tw.WriteHeader(header); err != nil {
    67  			return err
    68  		}
    69  
    70  		if fi.IsDir() {
    71  			return nil
    72  		}
    73  
    74  		data, err := os.Open(file)
    75  		if err != nil {
    76  			return errors.WithMessage(err, "could not open file")
    77  		}
    78  
    79  		if _, err := io.Copy(tw, data); err != nil {
    80  			return errors.WithMessage(err, "could not copy file into tar")
    81  		}
    82  
    83  		return nil
    84  	})
    85  	if err != nil {
    86  		return nil, errors.WithMessage(err, "could not walk filepath")
    87  	}
    88  
    89  	if err := tw.Close(); err != nil {
    90  		return nil, errors.WithMessage(err, "could not write tar")
    91  	}
    92  
    93  	return buffer.Bytes(), err
    94  }