func (vm *VM) buildChaincodeContainerUsingDockerfilePackageBytes(spec *pb.ChaincodeSpec, code []byte) error {
	outputbuf := bytes.NewBuffer(nil)
	vmName := spec.ChaincodeID.Name
	inputbuf := bytes.NewReader(code)
	opts := docker.BuildImageOptions{
		Name:         vmName,
		Pull:         true,
		InputStream:  inputbuf,
		OutputStream: outputbuf,
	}
	if err := vm.Client.BuildImage(opts); err != nil {
		vmLogger.Debug(fmt.Sprintf("Failed Chaincode docker build:\n%s\n", outputbuf.String()))
		return fmt.Errorf("Error building Chaincode container: %s", err)
	}
	return nil
}
Builds the Chaincode image using the supplied Dockerfile package contents
package container
import (
	"archive/tar"
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"time"
	"golang.org/x/net/context"
	"github.com/spf13/viper"
	"github.com/fsouza/go-dockerclient"
	"github.com/op/go-logging"
	pb "github.com/openblockchain/obc-peer/protos"
)
func newDockerClient() (client *docker.Client, err error) {
	endpoint := viper.GetString("vm.endpoint")
	vmLogger.Info("Creating VM with endpoint: %s", endpoint)
	if viper.GetBool("vm.docker.tls.enabled") {
		cert := viper.GetString("vm.docker.tls.cert.file")
		key := viper.GetString("vm.docker.tls.key.file")
		ca := viper.GetString("vm.docker.tls.ca.file")
		client, err = docker.NewTLSClient(endpoint, cert, key, ca)
	} else {
		client, err = docker.NewClient(endpoint)
	}
	return
}
type VM struct {
	Client *docker.Client
}
func NewVM() (*VM, error) {
	client, err := newDockerClient()
	if err != nil {
		return nil, err
	}
	VM := &VM{Client: client}
	return VM, nil
}
var vmLogger = logging.MustGetLogger("container")
func (vm *VM) ListImages(context context.Context) error {
	imgs, err := vm.Client.ListImages(docker.ListImagesOptions{All: false})
	if err != nil {
		return err
	}
	for _, img := range imgs {
		fmt.Println("ID: ", img.ID)
		fmt.Println("RepoTags: ", img.RepoTags)
		fmt.Println("Created: ", img.Created)
		fmt.Println("Size: ", img.Size)
		fmt.Println("VirtualSize: ", img.VirtualSize)
		fmt.Println("ParentId: ", img.ParentID)
	}
	return nil
}
func (vm *VM) BuildChaincodeContainer(spec *pb.ChaincodeSpec) ([]byte, error) {
	chaincodePkgBytes, err := GetChaincodePackageBytes(spec)
	if err != nil {
		return nil, fmt.Errorf("Error getting chaincode package bytes: %s", err)
	}
	err = vm.buildChaincodeContainerUsingDockerfilePackageBytes(spec, chaincodePkgBytes)
	if err != nil {
		return nil, fmt.Errorf("Error building Chaincode container: %s", err)
	}
	return chaincodePkgBytes, nil
}
func GetChaincodePackageBytes(spec *pb.ChaincodeSpec) ([]byte, error) {
	if spec == nil || spec.ChaincodeID == nil {
		return nil, fmt.Errorf("invalid chaincode spec")
	}
	if spec.ChaincodeID.Name != "" {
		return nil, fmt.Errorf("chaincode name exists")
	}
	inputbuf := bytes.NewBuffer(nil)
	gw := gzip.NewWriter(inputbuf)
	tw := tar.NewWriter(gw)
	var err error
	spec.ChaincodeID.Name, err = generateHashcode(spec, tw)
	if err != nil {
		tw.Close()
		gw.Close()
		return nil, fmt.Errorf("Error generating hashcode: %s", err)
	}
	err = writeChaincodePackage(spec, tw)
	if err != nil {
		tw.Close()
		gw.Close()
		return nil, fmt.Errorf("Error writing chaincode package: %s", err)
	}
	tw.Close()
	gw.Close()
	chaincodePkgBytes := inputbuf.Bytes()
	return chaincodePkgBytes, nil
}