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 }