110 lines
2.4 KiB
Go
110 lines
2.4 KiB
Go
/*
|
|
Copyright IBM Corp All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package nwo
|
|
|
|
import (
|
|
"archive/tar"
|
|
"compress/gzip"
|
|
"encoding/json"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
// PackageChaincodeBinary is a helper function to package
|
|
// an already built chaincode and write it to the location
|
|
// specified by Chaincode.PackageFile.
|
|
func PackageChaincodeBinary(c Chaincode) {
|
|
file, err := os.Create(c.PackageFile)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
defer file.Close()
|
|
writeTarGz(c, file)
|
|
}
|
|
|
|
func writeTarGz(c Chaincode, w io.Writer) {
|
|
gw := gzip.NewWriter(w)
|
|
tw := tar.NewWriter(gw)
|
|
defer closeAll(tw, gw)
|
|
|
|
writeMetadataJSON(tw, c.Path, c.Lang, c.Label)
|
|
|
|
writeCodeTarGz(tw, c.CodeFiles)
|
|
}
|
|
|
|
// packageMetadata holds the path, type, and label for a chaincode package
|
|
type packageMetadata struct {
|
|
Path string `json:"path"`
|
|
Type string `json:"type"`
|
|
Label string `json:"label"`
|
|
}
|
|
|
|
func writeMetadataJSON(tw *tar.Writer, path, ccType, label string) {
|
|
metadata, err := json.Marshal(&packageMetadata{
|
|
Path: path,
|
|
Type: ccType,
|
|
Label: label,
|
|
})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
// write it to the package as metadata.json
|
|
err = tw.WriteHeader(&tar.Header{
|
|
Name: "metadata.json",
|
|
Size: int64(len(metadata)),
|
|
Mode: 0o100644,
|
|
})
|
|
Expect(err).NotTo(HaveOccurred())
|
|
_, err = tw.Write(metadata)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
}
|
|
|
|
func writeCodeTarGz(tw *tar.Writer, codeFiles map[string]string) {
|
|
// create temp file to hold code.tar.gz
|
|
tempfile, err := ioutil.TempFile("", "code.tar.gz")
|
|
Expect(err).NotTo(HaveOccurred())
|
|
defer os.Remove(tempfile.Name())
|
|
|
|
gzipWriter := gzip.NewWriter(tempfile)
|
|
tarWriter := tar.NewWriter(gzipWriter)
|
|
|
|
for source, target := range codeFiles {
|
|
file, err := os.Open(source)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
writeFileToTar(tarWriter, file, target)
|
|
file.Close()
|
|
}
|
|
|
|
// close down the inner tar
|
|
closeAll(tarWriter, gzipWriter)
|
|
|
|
writeFileToTar(tw, tempfile, "code.tar.gz")
|
|
}
|
|
|
|
func writeFileToTar(tw *tar.Writer, file *os.File, name string) {
|
|
_, err := file.Seek(0, 0)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
fi, err := file.Stat()
|
|
Expect(err).NotTo(HaveOccurred())
|
|
header, err := tar.FileInfoHeader(fi, "")
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
header.Name = name
|
|
err = tw.WriteHeader(header)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
|
|
_, err = io.Copy(tw, file)
|
|
Expect(err).NotTo(HaveOccurred())
|
|
}
|
|
|
|
func closeAll(closers ...io.Closer) {
|
|
for _, c := range closers {
|
|
Expect(c.Close()).To(Succeed())
|
|
}
|
|
}
|