github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/core/container/util/writer.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package util
    18  
    19  import (
    20  	"archive/tar"
    21  	"bufio"
    22  	"fmt"
    23  	"io"
    24  	"os"
    25  	"path/filepath"
    26  	"strings"
    27  	"time"
    28  
    29  	"github.com/op/go-logging"
    30  )
    31  
    32  var vmLogger = logging.MustGetLogger("container")
    33  
    34  var includeFileTypes = map[string]bool{
    35  	".c":    true,
    36  	".h":    true,
    37  	".go":   true,
    38  	".yaml": true,
    39  	".json": true,
    40  }
    41  
    42  // These filetypes are excluded while creating the tar package sent to Docker
    43  // Generated .class and other temporary files can be excluded
    44  var javaExcludeFileTypes = map[string]bool{
    45  	".class": true,
    46  }
    47  
    48  func WriteFolderToTarPackage(tw *tar.Writer, srcPath string, excludeDir string, includeFileTypeMap map[string]bool, excludeFileTypeMap map[string]bool) error {
    49  	rootDirectory := srcPath
    50  	vmLogger.Infof("rootDirectory = %s", rootDirectory)
    51  
    52  	//append "/" if necessary
    53  	if excludeDir != "" && strings.LastIndex(excludeDir, "/") < len(excludeDir)-1 {
    54  		excludeDir = excludeDir + "/"
    55  	}
    56  
    57  	rootDirLen := len(rootDirectory)
    58  	walkFn := func(path string, info os.FileInfo, err error) error {
    59  
    60  		// If path includes .git, ignore
    61  		if strings.Contains(path, ".git") {
    62  			return nil
    63  		}
    64  
    65  		if info.Mode().IsDir() {
    66  			return nil
    67  		}
    68  
    69  		//exclude any files with excludeDir prefix. They should already be in the tar
    70  		if excludeDir != "" && strings.Index(path, excludeDir) == rootDirLen+1 {
    71  			//1 for "/"
    72  			return nil
    73  		}
    74  		// Because of scoping we can reference the external rootDirectory variable
    75  		if len(path[rootDirLen:]) == 0 {
    76  			return nil
    77  		}
    78  		ext := filepath.Ext(path)
    79  
    80  		if includeFileTypeMap != nil {
    81  			// we only want 'fileTypes' source files at this point
    82  			if _, ok := includeFileTypeMap[ext]; ok != true {
    83  				return nil
    84  			}
    85  		}
    86  
    87  		//exclude the given file types
    88  		if excludeFileTypeMap != nil {
    89  			if exclude, ok := excludeFileTypeMap[ext]; ok && exclude {
    90  				return nil
    91  			}
    92  		}
    93  
    94  		newPath := fmt.Sprintf("src%s", path[rootDirLen:])
    95  		//newPath := path[len(rootDirectory):]
    96  
    97  		err = WriteFileToPackage(path, newPath, tw)
    98  		if err != nil {
    99  			return fmt.Errorf("Error writing file to package: %s", err)
   100  		}
   101  		return nil
   102  	}
   103  
   104  	if err := filepath.Walk(rootDirectory, walkFn); err != nil {
   105  		vmLogger.Infof("Error walking rootDirectory: %s", err)
   106  		return err
   107  	}
   108  	return nil
   109  }
   110  
   111  //WriteGopathSrc tars up files under gopath src
   112  func WriteGopathSrc(tw *tar.Writer, excludeDir string) error {
   113  	gopath := os.Getenv("GOPATH")
   114  	// Only take the first element of GOPATH
   115  	gopath = filepath.SplitList(gopath)[0]
   116  
   117  	rootDirectory := filepath.Join(gopath, "src")
   118  	vmLogger.Infof("rootDirectory = %s", rootDirectory)
   119  
   120  	if err := WriteFolderToTarPackage(tw, rootDirectory, excludeDir, includeFileTypes, nil); err != nil {
   121  		vmLogger.Errorf("Error writing folder to tar package %s", err)
   122  		return err
   123  	}
   124  
   125  	// Write the tar file out
   126  	if err := tw.Close(); err != nil {
   127  		return err
   128  	}
   129  	//ioutil.WriteFile("/tmp/chaincode_deployment.tar", inputbuf.Bytes(), 0644)
   130  	return nil
   131  }
   132  
   133  //Package Java project to tar file from the source path
   134  func WriteJavaProjectToPackage(tw *tar.Writer, srcPath string) error {
   135  
   136  	vmLogger.Debugf("Packaging Java project from path %s", srcPath)
   137  
   138  	if err := WriteFolderToTarPackage(tw, srcPath, "", nil, javaExcludeFileTypes); err != nil {
   139  
   140  		vmLogger.Errorf("Error writing folder to tar package %s", err)
   141  		return err
   142  	}
   143  	// Write the tar file out
   144  	if err := tw.Close(); err != nil {
   145  		return err
   146  	}
   147  	return nil
   148  
   149  }
   150  
   151  //WriteFileToPackage writes a file to the tarball
   152  func WriteFileToPackage(localpath string, packagepath string, tw *tar.Writer) error {
   153  	fd, err := os.Open(localpath)
   154  	if err != nil {
   155  		return fmt.Errorf("%s: %s", localpath, err)
   156  	}
   157  	defer fd.Close()
   158  
   159  	is := bufio.NewReader(fd)
   160  	return WriteStreamToPackage(is, localpath, packagepath, tw)
   161  
   162  }
   163  
   164  //WriteStreamToPackage writes bytes (from a file reader) to the tarball
   165  func WriteStreamToPackage(is io.Reader, localpath string, packagepath string, tw *tar.Writer) error {
   166  	info, err := os.Stat(localpath)
   167  	if err != nil {
   168  		return fmt.Errorf("%s: %s", localpath, err)
   169  	}
   170  	header, err := tar.FileInfoHeader(info, localpath)
   171  	if err != nil {
   172  		return fmt.Errorf("Error getting FileInfoHeader: %s", err)
   173  	}
   174  
   175  	//Let's take the variance out of the tar, make headers identical by using zero time
   176  	oldname := header.Name
   177  	var zeroTime time.Time
   178  	header.AccessTime = zeroTime
   179  	header.ModTime = zeroTime
   180  	header.ChangeTime = zeroTime
   181  	header.Name = packagepath
   182  
   183  	if err = tw.WriteHeader(header); err != nil {
   184  		return fmt.Errorf("Error write header for (path: %s, oldname:%s,newname:%s,sz:%d) : %s", localpath, oldname, packagepath, header.Size, err)
   185  	}
   186  	if _, err := io.Copy(tw, is); err != nil {
   187  		return fmt.Errorf("Error copy (path: %s, oldname:%s,newname:%s,sz:%d) : %s", localpath, oldname, packagepath, header.Size, err)
   188  	}
   189  
   190  	return nil
   191  }
   192  
   193  func WriteBytesToPackage(name string, payload []byte, tw *tar.Writer) error {
   194  	//Make headers identical by using zero time
   195  	var zeroTime time.Time
   196  	tw.WriteHeader(&tar.Header{Name: name, Size: int64(len(payload)), ModTime: zeroTime, AccessTime: zeroTime, ChangeTime: zeroTime})
   197  	tw.Write(payload)
   198  
   199  	return nil
   200  }