// WritePackage satisfies the platform interface for generating a docker package // that encapsulates the environment for a CAR based chaincode func (carPlatform *Platform) WritePackage(spec *pb.ChaincodeSpec, tw *tar.Writer) error { path, err := download(spec.ChaincodeID.Path) if err != nil { return err } spec.ChaincodeID.Name, err = generateHashcode(spec, path) if err != nil { return fmt.Errorf("Error generating hashcode: %s", err) } var buf []string //let the executable's name be chaincode ID's name buf = append(buf, viper.GetString("chaincode.car.Dockerfile")) buf = append(buf, "COPY package.car /tmp/package.car") buf = append(buf, fmt.Sprintf("RUN chaintool buildcar /tmp/package.car -o $GOPATH/bin/%s && rm /tmp/package.car", spec.ChaincodeID.Name)) dockerFileContents := strings.Join(buf, "\n") dockerFileSize := int64(len([]byte(dockerFileContents))) //Make headers identical by using zero time var zeroTime time.Time tw.WriteHeader(&tar.Header{Name: "Dockerfile", Size: dockerFileSize, ModTime: zeroTime, AccessTime: zeroTime, ChangeTime: zeroTime}) tw.Write([]byte(dockerFileContents)) err = cutil.WriteFileToPackage(path, "package.car", tw) if err != nil { return err } return nil }
// WritePackage satisfies the platform interface for generating a docker package // that encapsulates the environment for a CAR based chaincode func (carPlatform *Platform) WritePackage(spec *pb.ChaincodeSpec, tw *tar.Writer) error { path, err := download(spec.ChaincodeID.Path) if err != nil { return err } var buf []string //let the executable's name be chaincode ID's name buf = append(buf, cutil.GetDockerfileFromConfig("chaincode.car.Dockerfile")) buf = append(buf, "COPY package.car /tmp/package.car") // invoking directly for maximum JRE compatiblity buf = append(buf, fmt.Sprintf("RUN java -jar /usr/local/bin/chaintool buildcar /tmp/package.car -o $GOPATH/bin/%s && rm /tmp/package.car", spec.ChaincodeID.Name)) dockerFileContents := strings.Join(buf, "\n") dockerFileSize := int64(len([]byte(dockerFileContents))) //Make headers identical by using zero time var zeroTime time.Time tw.WriteHeader(&tar.Header{Name: "Dockerfile", Size: dockerFileSize, ModTime: zeroTime, AccessTime: zeroTime, ChangeTime: zeroTime}) tw.Write([]byte(dockerFileContents)) err = cutil.WriteFileToPackage(path, "package.car", tw) if err != nil { return err } return nil }
// Find the instance of "name" installed on the host's $PATH and inject it into the package // This is a bit naive in that it assumes that the file returned from "which" is all that is // required to run the binary in a different environment. If the binary happened to have // dependencies (such as to .so libraries or /etc/ files, etc) this probably wouldn't work // as expected. However, our intended use cases involves binaries generated in golang and // clojure, both of which have a tendency to create stand-alone binaries. Therefore, this // is still helpful despite being a bit dumb. func writeExecutableToPackage(name string, tw *tar.Writer) error { cmd := exec.Command("which", name) path, err := cmd.Output() if err != nil { return fmt.Errorf("Error determining %s path dynamically", name) } return cutil.WriteFileToPackage(strings.Trim(string(path), "\n"), "bin/"+name, tw) }