github.com/reds/docker@v1.11.2-rc1/pkg/archive/wrap.go (about) 1 package archive 2 3 import ( 4 "archive/tar" 5 "bytes" 6 "io/ioutil" 7 ) 8 9 // Generate generates a new archive from the content provided 10 // as input. 11 // 12 // `files` is a sequence of path/content pairs. A new file is 13 // added to the archive for each pair. 14 // If the last pair is incomplete, the file is created with an 15 // empty content. For example: 16 // 17 // Generate("foo.txt", "hello world", "emptyfile") 18 // 19 // The above call will return an archive with 2 files: 20 // * ./foo.txt with content "hello world" 21 // * ./empty with empty content 22 // 23 // FIXME: stream content instead of buffering 24 // FIXME: specify permissions and other archive metadata 25 func Generate(input ...string) (Archive, error) { 26 files := parseStringPairs(input...) 27 buf := new(bytes.Buffer) 28 tw := tar.NewWriter(buf) 29 for _, file := range files { 30 name, content := file[0], file[1] 31 hdr := &tar.Header{ 32 Name: name, 33 Size: int64(len(content)), 34 } 35 if err := tw.WriteHeader(hdr); err != nil { 36 return nil, err 37 } 38 if _, err := tw.Write([]byte(content)); err != nil { 39 return nil, err 40 } 41 } 42 if err := tw.Close(); err != nil { 43 return nil, err 44 } 45 return ioutil.NopCloser(buf), nil 46 } 47 48 func parseStringPairs(input ...string) (output [][2]string) { 49 output = make([][2]string, 0, len(input)/2+1) 50 for i := 0; i < len(input); i += 2 { 51 var pair [2]string 52 pair[0] = input[i] 53 if i+1 < len(input) { 54 pair[1] = input[i+1] 55 } 56 output = append(output, pair) 57 } 58 return 59 }