Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
8 changes: 4 additions & 4 deletions core/chaincode/chaincode_support_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"testing"
"time"

docker "github.com/fsouza/go-dockerclient"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-chaincode-go/shim"
"github.com/hyperledger/fabric-protos-go/common"
Expand Down Expand Up @@ -59,6 +58,7 @@ import (
mspmgmt "github.com/hyperledger/fabric/msp/mgmt"
msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools"
"github.com/hyperledger/fabric/protoutil"
dcli "github.com/moby/moby/client"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -192,7 +192,7 @@ func initMockPeer(channelIDs ...string) (*peer.Peer, *ChaincodeSupport, func(),

buildRegistry := &container.BuildRegistry{}

client, err := docker.NewClientFromEnv()
client, err := dcli.New(dcli.FromEnv)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -523,8 +523,8 @@ func initializeCC(t *testing.T, chainID, ccname string, ccSide *mock.MockCCComm,
// be triggered by the chaincode stream. We just expect an error from fabric. Hence pass nil for done
execCC(t, txParams, ccSide, "badccname", false, true, nil, cis, respSet, chaincodeSupport)

//---------try a successful init at last-------
//everything lined up
// ---------try a successful init at last-------
// everything lined up
// correct registered chaincode version
// matching txid
// txsim context
Expand Down
4 changes: 2 additions & 2 deletions core/chaincode/platforms/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ package platforms
import (
"io"

docker "github.com/fsouza/go-dockerclient"
dcli "github.com/moby/moby/client"
)

type Builder struct {
Registry *Registry
Client *docker.Client
Client dcli.APIClient
}

func (b *Builder) GenerateDockerBuild(ccType, path string, codePackage io.Reader) (io.Reader, error) {
Expand Down
8 changes: 4 additions & 4 deletions core/chaincode/platforms/platforms.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import (
"io"
"strings"

docker "github.com/fsouza/go-dockerclient"
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/common/metadata"
"github.com/hyperledger/fabric/core/chaincode/platforms/golang"
"github.com/hyperledger/fabric/core/chaincode/platforms/java"
"github.com/hyperledger/fabric/core/chaincode/platforms/node"
"github.com/hyperledger/fabric/core/chaincode/platforms/util"
dcli "github.com/moby/moby/client"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -49,7 +49,7 @@ func (pw PackageWriterWrapper) Write(name string, payload []byte, tw *tar.Writer
return pw(name, payload, tw)
}

type BuildFunc func(util.DockerBuildOptions, *docker.Client) error
type BuildFunc func(util.DockerBuildOptions, dcli.APIClient) error

type Registry struct {
Platforms map[string]Platform
Expand Down Expand Up @@ -107,7 +107,7 @@ func (r *Registry) GenerateDockerfile(ccType string) (string, error) {
return contents, nil
}

func (r *Registry) StreamDockerBuild(ccType, path string, codePackage io.Reader, inputFiles map[string][]byte, tw *tar.Writer, client *docker.Client) error {
func (r *Registry) StreamDockerBuild(ccType, path string, codePackage io.Reader, inputFiles map[string][]byte, tw *tar.Writer, client dcli.APIClient) error {
var err error

// ----------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -163,7 +163,7 @@ func writeBytesToPackage(name string, payload []byte, tw *tar.Writer) error {
return nil
}

func (r *Registry) GenerateDockerBuild(ccType, path string, codePackage io.Reader, client *docker.Client) (io.Reader, error) {
func (r *Registry) GenerateDockerBuild(ccType, path string, codePackage io.Reader, client dcli.APIClient) (io.Reader, error) {
inputFiles := make(map[string][]byte)

// ----------------------------------------------------------------------------------------------------
Expand Down
10 changes: 5 additions & 5 deletions core/chaincode/platforms/platforms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ import (
"fmt"
"io/ioutil"

docker "github.com/fsouza/go-dockerclient"
"github.com/hyperledger/fabric/common/metadata"
"github.com/hyperledger/fabric/core/chaincode/platforms"
"github.com/hyperledger/fabric/core/chaincode/platforms/mock"
"github.com/hyperledger/fabric/core/chaincode/platforms/util"
dcli "github.com/moby/moby/client"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
Expand Down Expand Up @@ -71,16 +71,16 @@ ENV CORE_CHAINCODE_BUILDLEVEL=%s`, metadata.Version, metadata.Version)
buf *bytes.Buffer
tw *tar.Writer
pw *mock.PackageWriter
client *docker.Client
client dcli.APIClient
)

BeforeEach(func() {
buf = &bytes.Buffer{}
tw = tar.NewWriter(buf)
pw = &mock.PackageWriter{}
registry.PackageWriter = pw
registry.DockerBuild = func(util.DockerBuildOptions, *docker.Client) error { return nil }
dockerClient, err := docker.NewClientFromEnv()
registry.DockerBuild = func(util.DockerBuildOptions, dcli.APIClient) error { return nil }
dockerClient, err := dcli.New(dcli.FromEnv)
Expect(err).NotTo(HaveOccurred())
client = dockerClient
})
Expand Down Expand Up @@ -134,7 +134,7 @@ ENV CORE_CHAINCODE_BUILDLEVEL=%s`, metadata.Version, metadata.Version)

Context("when the docker build fails", func() {
It("returns an error", func() {
registry.DockerBuild = func(util.DockerBuildOptions, *docker.Client) error { return errors.New("kaboom") }
registry.DockerBuild = func(util.DockerBuildOptions, dcli.APIClient) error { return errors.New("kaboom") }
err := registry.StreamDockerBuild("fakeType", "", nil, nil, tw, client)
Expect(err).To(MatchError("docker build failed: kaboom"))
})
Expand Down
107 changes: 53 additions & 54 deletions core/chaincode/platforms/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ SPDX-License-Identifier: Apache-2.0
package util

import (
"bytes"
"context"
"fmt"
"io"
"runtime"
"strings"

docker "github.com/fsouza/go-dockerclient"
"github.com/hyperledger/fabric/common/flogging"
"github.com/hyperledger/fabric/common/metadata"
dcontainer "github.com/moby/moby/api/types/container"
dcli "github.com/moby/moby/client"
"github.com/spf13/viper"
)

Expand Down Expand Up @@ -57,7 +58,7 @@ func (dbo DockerBuildOptions) String() string {
// after successful execution of Cmd.
//
// -------------------------------------------------------------------------------------------
func DockerBuild(opts DockerBuildOptions, client *docker.Client) error {
func DockerBuild(opts DockerBuildOptions, client dcli.APIClient) error {
if opts.Image == "" {
opts.Image = GetDockerImageFromConfig("chaincode.builder")
if opts.Image == "" {
Expand All @@ -67,105 +68,103 @@ func DockerBuild(opts DockerBuildOptions, client *docker.Client) error {

logger.Debugf("Attempting build with options: %s", opts)

//-----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
// Ensure the image exists locally, or pull it from a registry if it doesn't
//-----------------------------------------------------------------------------------
_, err := client.InspectImage(opts.Image)
// -----------------------------------------------------------------------------------
_, err := client.ImageInspect(context.Background(), opts.Image)
if err != nil {
logger.Debugf("Image %s does not exist locally, attempt pull", opts.Image)

err = client.PullImage(docker.PullImageOptions{Repository: opts.Image}, docker.AuthConfiguration{})
_, err = client.ImagePull(context.Background(), opts.Image, dcli.ImagePullOptions{})
if err != nil {
return fmt.Errorf("Failed to pull %s: %s", opts.Image, err)
}
}

//-----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
// Create an ephemeral container, armed with our Image/Cmd
//-----------------------------------------------------------------------------------
container, err := client.CreateContainer(docker.CreateContainerOptions{
Config: &docker.Config{
Image: opts.Image,
Cmd: []string{"/bin/sh", "-c", opts.Cmd},
Env: opts.Env,
// -----------------------------------------------------------------------------------
container, err := client.ContainerCreate(context.Background(), dcli.ContainerCreateOptions{
Config: &dcontainer.Config{
AttachStdout: true,
AttachStderr: true,
Env: opts.Env,
Cmd: []string{"/bin/sh", "-c", opts.Cmd},
Image: opts.Image,
},
})
if err != nil {
return fmt.Errorf("Error creating container: %s", err)
}
defer client.RemoveContainer(docker.RemoveContainerOptions{ID: container.ID})
defer client.ContainerRemove(context.Background(), container.ID, dcli.ContainerRemoveOptions{})

//-----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
// Upload our input stream
//-----------------------------------------------------------------------------------
err = client.UploadToContainer(container.ID, docker.UploadToContainerOptions{
Path: "/chaincode/input",
InputStream: opts.InputStream,
// -----------------------------------------------------------------------------------
_, err = client.CopyToContainer(context.Background(), container.ID, dcli.CopyToContainerOptions{
DestinationPath: "/chaincode/input",
Content: opts.InputStream,
AllowOverwriteDirWithFile: true,
})
if err != nil {
return fmt.Errorf("Error uploading input to container: %s", err)
}

//-----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
// Attach stdout buffer to capture possible compilation errors
//-----------------------------------------------------------------------------------
stdout := bytes.NewBuffer(nil)
cw, err := client.AttachToContainerNonBlocking(docker.AttachToContainerOptions{
Container: container.ID,
OutputStream: stdout,
ErrorStream: stdout,
Logs: true,
Stdout: true,
Stderr: true,
Stream: true,
// -----------------------------------------------------------------------------------
cw, err := client.ContainerAttach(context.Background(), container.ID, dcli.ContainerAttachOptions{
Stream: true,
Stdout: true,
Stderr: true,
Logs: true,
})
if err != nil {
return fmt.Errorf("Error attaching to container: %s", err)
}

//-----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
// Launch the actual build, realizing the Env/Cmd specified at container creation
//-----------------------------------------------------------------------------------
err = client.StartContainer(container.ID, nil)
// -----------------------------------------------------------------------------------
_, err = client.ContainerStart(context.Background(), container.ID, dcli.ContainerStartOptions{})
if err != nil {
buff, _ := io.ReadAll(cw.Reader)
cw.Close()
return fmt.Errorf("Error executing build: %s \"%s\"", err, stdout.String())
return fmt.Errorf("Error executing build: %s \"%s\"", err, string(buff))
}

//-----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
// Wait for the build to complete and gather the return value
//-----------------------------------------------------------------------------------
retval, err := client.WaitContainer(container.ID)
if err != nil {
// -----------------------------------------------------------------------------------
resWait := client.ContainerWait(context.Background(), container.ID, dcli.ContainerWaitOptions{})
var res dcontainer.WaitResponse
select {
case res = <-resWait.Result:
case err = <-resWait.Error:
buff, _ := io.ReadAll(cw.Reader)
cw.Close()
return fmt.Errorf("Error waiting for container to complete: %s", err)
return fmt.Errorf("Error waiting for container to complete: %s \"%s\"", err, string(buff))
}

// Wait for stream copying to complete before accessing stdout.
cw.Close()
if err := cw.Wait(); err != nil {
logger.Errorf("attach wait failed: %s", err)
}

if retval > 0 {
defer cw.Close()
buff, _ := io.ReadAll(cw.Reader)
if res.StatusCode > 0 {
logger.Errorf("Docker build failed using options: %s", opts)
return fmt.Errorf("Error returned from build: %d \"%s\"", retval, stdout.String())
return fmt.Errorf("Error returned from build: %d \"%s\"", res.StatusCode, string(buff))
}

logger.Debugf("Build output is %s", stdout.String())
logger.Debugf("Build output is %s", string(buff))

//-----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
// Finally, download the result
//-----------------------------------------------------------------------------------
err = client.DownloadFromContainer(container.ID, docker.DownloadFromContainerOptions{
Path: "/chaincode/output/.",
OutputStream: opts.OutputStream,
})
// -----------------------------------------------------------------------------------
resCont, err := client.CopyFromContainer(context.Background(), container.ID, dcli.CopyFromContainerOptions{SourcePath: "/chaincode/output/."})
if err != nil {
return fmt.Errorf("Error downloading output: %s", err)
}
defer resCont.Content.Close()
io.Copy(opts.OutputStream, resCont.Content)

return nil
}
Expand Down
19 changes: 12 additions & 7 deletions core/chaincode/platforms/util/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,26 @@ package util
import (
"archive/tar"
"bytes"
"context"
"encoding/base32"
"fmt"
"io"
"io/ioutil"
"os"
"runtime"
"strings"
"testing"

docker "github.com/fsouza/go-dockerclient"
"github.com/hyperledger/fabric/common/metadata"
"github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/core/config/configtest"
dcli "github.com/moby/moby/client"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)

func TestDockerBuild(t *testing.T) {
client, err := docker.NewClientFromEnv()
client, err := dcli.New(dcli.FromEnv)
require.NoError(t, err, "failed to get docker client")

is := bytes.NewBuffer(nil)
Expand Down Expand Up @@ -57,13 +59,16 @@ func TestDockerBuild(t *testing.T) {
tw.Close()

imageName := uniqueName()
err = client.BuildImage(docker.BuildImageOptions{
Name: imageName,
InputStream: is,
OutputStream: ioutil.Discard,
res, err := client.ImageBuild(context.Background(), is, dcli.ImageBuildOptions{
Tags: []string{imageName},
})
require.NoError(t, err, "failed to build base image")
defer client.RemoveImageExtended(imageName, docker.RemoveImageOptions{Force: true})
defer res.Body.Close()
defer client.ImageRemove(context.Background(), imageName, dcli.ImageRemoveOptions{
Force: true,
})

io.Copy(io.Discard, res.Body)

codepackage := bytes.NewBuffer(nil)
tw = tar.NewWriter(codepackage)
Expand Down
Loading