Skip to content

Commit b7dd5aa

Browse files
author
Jason Yellick
committed
FAB-9763 Fix container control inversion
The core/container package directly references the core/container/dockercontroller and core/container/inproccontroller packages. Consequently, because these packages cannot refer back to the core/container package, there is an awkward core/container/api package. This CR improves the initialization path and tests so that this indirection is no longer necessary. Change-Id: I5cf8e617b09f7d399fe5d5e5f6239fdda1197bc4 Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
1 parent 367e5b3 commit b7dd5aa

19 files changed

+174
-243
lines changed

core/chaincode/chaincode_support_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import (
3535
"github.com/hyperledger/fabric/core/common/ccprovider"
3636
"github.com/hyperledger/fabric/core/config"
3737
"github.com/hyperledger/fabric/core/container"
38+
"github.com/hyperledger/fabric/core/container/dockercontroller"
39+
"github.com/hyperledger/fabric/core/container/inproccontroller"
3840
"github.com/hyperledger/fabric/core/ledger"
3941
"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
4042
cmp "github.com/hyperledger/fabric/core/mocks/peer"
@@ -177,7 +179,12 @@ func initMockPeer(chainIDs ...string) (*ChaincodeSupport, error) {
177179
certGenerator,
178180
&ccprovider.CCInfoFSImpl{},
179181
aclmgmt.GetACLProvider(),
180-
container.NewVMController(),
182+
container.NewVMController(
183+
map[string]container.VMProvider{
184+
dockercontroller.ContainerType: dockercontroller.NewProvider(),
185+
inproccontroller.ContainerType: inproccontroller.NewProvider(),
186+
},
187+
),
181188
)
182189
SideEffectInitialize(chaincodeSupport)
183190
chaincodeSupport.SetSysCCProvider(sccp)

core/chaincode/container_runtime.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@ import (
1818
"github.com/hyperledger/fabric/core/common/ccprovider"
1919
"github.com/hyperledger/fabric/core/container"
2020
"github.com/hyperledger/fabric/core/container/ccintf"
21+
"github.com/hyperledger/fabric/core/container/dockercontroller"
22+
"github.com/hyperledger/fabric/core/container/inproccontroller"
2123
pb "github.com/hyperledger/fabric/protos/peer"
2224
"github.com/pkg/errors"
2325
"golang.org/x/net/context"
2426
)
2527

2628
// Processor processes vm and container requests.
2729
type Processor interface {
28-
Process(ctxt context.Context, vmtype string, req container.VMCReqIntf) error
30+
Process(ctxt context.Context, vmtype string, req container.VMCReq) error
2931
}
3032

3133
// CertGenerator generates client certificates for chaincode.
@@ -112,9 +114,9 @@ func (c *ContainerRuntime) Stop(ctxt context.Context, cccid *ccprovider.CCContex
112114

113115
func getVMType(cds *pb.ChaincodeDeploymentSpec) string {
114116
if cds.ExecEnv == pb.ChaincodeDeploymentSpec_SYSTEM {
115-
return container.SYSTEM
117+
return inproccontroller.ContainerType
116118
}
117-
return container.DOCKER
119+
return dockercontroller.ContainerType
118120
}
119121

120122
const (

core/chaincode/container_runtime_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import (
1616
"github.com/hyperledger/fabric/core/common/ccprovider"
1717
"github.com/hyperledger/fabric/core/container"
1818
"github.com/hyperledger/fabric/core/container/ccintf"
19+
"github.com/hyperledger/fabric/core/container/dockercontroller"
20+
"github.com/hyperledger/fabric/core/container/inproccontroller"
1921
pb "github.com/hyperledger/fabric/protos/peer"
2022
"github.com/pkg/errors"
2123
"github.com/stretchr/testify/assert"
@@ -162,8 +164,8 @@ func TestContainerRuntimeStart(t *testing.T) {
162164
execEnv pb.ChaincodeDeploymentSpec_ExecutionEnvironment
163165
vmType string
164166
}{
165-
{pb.ChaincodeDeploymentSpec_DOCKER, container.DOCKER},
166-
{pb.ChaincodeDeploymentSpec_SYSTEM, container.SYSTEM},
167+
{pb.ChaincodeDeploymentSpec_DOCKER, dockercontroller.ContainerType},
168+
{pb.ChaincodeDeploymentSpec_SYSTEM, inproccontroller.ContainerType},
167169
}
168170

169171
for _, tc := range tests {
@@ -245,8 +247,8 @@ func TestContainerRuntimeStop(t *testing.T) {
245247
execEnv pb.ChaincodeDeploymentSpec_ExecutionEnvironment
246248
vmType string
247249
}{
248-
{pb.ChaincodeDeploymentSpec_DOCKER, container.DOCKER},
249-
{pb.ChaincodeDeploymentSpec_SYSTEM, container.SYSTEM},
250+
{pb.ChaincodeDeploymentSpec_DOCKER, dockercontroller.ContainerType},
251+
{pb.ChaincodeDeploymentSpec_SYSTEM, inproccontroller.ContainerType},
250252
}
251253

252254
for _, tc := range tests {

core/chaincode/exectransaction_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import (
3535
"github.com/hyperledger/fabric/core/common/ccprovider"
3636
"github.com/hyperledger/fabric/core/config"
3737
"github.com/hyperledger/fabric/core/container"
38+
"github.com/hyperledger/fabric/core/container/dockercontroller"
39+
"github.com/hyperledger/fabric/core/container/inproccontroller"
3840
"github.com/hyperledger/fabric/core/ledger"
3941
"github.com/hyperledger/fabric/core/ledger/ledgerconfig"
4042
"github.com/hyperledger/fabric/core/ledger/ledgermgmt"
@@ -125,7 +127,12 @@ func initPeer(chainIDs ...string) (net.Listener, *ChaincodeSupport, func(), erro
125127
certGenerator,
126128
&ccprovider.CCInfoFSImpl{},
127129
aclmgmt.GetACLProvider(),
128-
container.NewVMController(),
130+
container.NewVMController(
131+
map[string]container.VMProvider{
132+
dockercontroller.ContainerType: dockercontroller.NewProvider(),
133+
inproccontroller.ContainerType: inproccontroller.NewProvider(),
134+
},
135+
),
129136
)
130137
chaincodeSupport.SetSysCCProvider(sccp)
131138
SideEffectInitialize(chaincodeSupport)

core/chaincode/mock/processor.go

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/chaincode/systemchaincode_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
"github.com/hyperledger/fabric/core/common/ccprovider"
2020
"github.com/hyperledger/fabric/core/common/sysccprovider"
2121
"github.com/hyperledger/fabric/core/container"
22+
"github.com/hyperledger/fabric/core/container/dockercontroller"
23+
"github.com/hyperledger/fabric/core/container/inproccontroller"
2224
"github.com/hyperledger/fabric/core/peer"
2325
"github.com/hyperledger/fabric/core/scc"
2426
pb "github.com/hyperledger/fabric/protos/peer"
@@ -132,7 +134,12 @@ func initSysCCTests() (*oldSysCCInfo, net.Listener, *ChaincodeSupport, error) {
132134
certGenerator,
133135
&ccprovider.CCInfoFSImpl{},
134136
aclmgmt.GetACLProvider(),
135-
container.NewVMController(),
137+
container.NewVMController(
138+
map[string]container.VMProvider{
139+
dockercontroller.ContainerType: dockercontroller.NewProvider(),
140+
inproccontroller.ContainerType: inproccontroller.NewProvider(),
141+
},
142+
),
136143
)
137144
pb.RegisterChaincodeSupportServer(grpcServer, chaincodeSupport)
138145

core/container/api/core.go

Lines changed: 0 additions & 38 deletions
This file was deleted.

core/container/container_suite_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package container_test
77

88
import (
99
"github.com/hyperledger/fabric/core/container"
10-
"github.com/hyperledger/fabric/core/container/api"
1110
. "github.com/onsi/ginkgo"
1211
. "github.com/onsi/gomega"
1312

@@ -21,17 +20,17 @@ type vmProvider interface {
2120

2221
//go:generate counterfeiter -o mock/vm.go --fake-name VM . vm
2322
type vm interface {
24-
api.VM
23+
container.VM
2524
}
2625

2726
//go:generate counterfeiter -o mock/vm_req.go --fake-name VMCReq . vmcReq
2827
type vmcReq interface {
29-
container.VMCReqIntf
28+
container.VMCReq
3029
}
3130

3231
//go:generate counterfeiter -o mock/builder.go --fake-name Builder . builder
3332
type builder interface {
34-
api.Builder
33+
container.Builder
3534
}
3635

3736
func TestContainer(t *testing.T) {

core/container/container_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,34 @@ var _ = Describe("Container", func() {
115115
})
116116
})
117117
})
118+
119+
Describe("VMController", func() {
120+
var (
121+
ctxt = context.Background()
122+
vmProvider *mock.VMProvider
123+
vmController *container.VMController
124+
vmcReq *mock.VMCReq
125+
)
126+
127+
BeforeEach(func() {
128+
vmProvider = &mock.VMProvider{}
129+
vmController = container.NewVMController(map[string]container.VMProvider{
130+
"FakeProvider": vmProvider,
131+
})
132+
vmProvider.NewVMReturns(&mock.VM{})
133+
vmcReq = &mock.VMCReq{}
134+
})
135+
136+
Describe("Process", func() {
137+
It("Panics if there is no underlying VM provider", func() {
138+
Expect(func() { vmController.Process(ctxt, "Unknown-Type", nil) }).To(Panic())
139+
Expect(vmProvider.NewVMCallCount()).To(Equal(0))
140+
})
141+
It("Returns no error if the underlying VM provider is successful", func() {
142+
err := vmController.Process(ctxt, "FakeProvider", vmcReq)
143+
Expect(vmProvider.NewVMCallCount()).To(Equal(1))
144+
Expect(err).NotTo(HaveOccurred())
145+
})
146+
})
147+
})
118148
})

core/container/controller.go

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,32 @@ package container
88

99
import (
1010
"fmt"
11+
"io"
1112
"sync"
1213

1314
"golang.org/x/net/context"
1415

1516
"github.com/hyperledger/fabric/common/flogging"
1617
"github.com/hyperledger/fabric/core/chaincode/platforms"
17-
"github.com/hyperledger/fabric/core/container/api"
1818
"github.com/hyperledger/fabric/core/container/ccintf"
19-
"github.com/hyperledger/fabric/core/container/dockercontroller"
20-
"github.com/hyperledger/fabric/core/container/inproccontroller"
2119
pb "github.com/hyperledger/fabric/protos/peer"
2220
)
2321

2422
type VMProvider interface {
25-
NewVM() api.VM
23+
NewVM() VM
24+
}
25+
26+
type Builder interface {
27+
Build() (io.Reader, error)
28+
}
29+
30+
//VM is an abstract virtual image for supporting arbitrary virual machines
31+
type VM interface {
32+
Deploy(ctxt context.Context, ccid ccintf.CCID, args []string, env []string, reader io.Reader) error
33+
Start(ctxt context.Context, ccid ccintf.CCID, args []string, env []string, filesToUpload map[string][]byte, builder Builder) error
34+
Stop(ctxt context.Context, ccid ccintf.CCID, timeout uint, dontkill bool, dontremove bool) error
35+
Destroy(ctxt context.Context, ccid ccintf.CCID, force bool, noprune bool) error
36+
GetVMName(ccID ccintf.CCID, format func(string) (string, error)) (string, error)
2637
}
2738

2839
type refCountedLock struct {
@@ -44,23 +55,14 @@ type VMController struct {
4455
var vmLogger = flogging.MustGetLogger("container")
4556

4657
// NewVMController creates a new instance of VMController
47-
func NewVMController() *VMController {
58+
func NewVMController(vmProviders map[string]VMProvider) *VMController {
4859
return &VMController{
4960
containerLocks: make(map[string]*refCountedLock),
50-
vmProviders: map[string]VMProvider{
51-
DOCKER: dockercontroller.NewProvider(),
52-
SYSTEM: inproccontroller.NewProvider(),
53-
},
61+
vmProviders: vmProviders,
5462
}
5563
}
5664

57-
//constants for supported containers
58-
const (
59-
DOCKER = "Docker"
60-
SYSTEM = "System"
61-
)
62-
63-
func (vmc *VMController) newVM(typ string) api.VM {
65+
func (vmc *VMController) newVM(typ string) VM {
6466
v, ok := vmc.vmProviders[typ]
6567
if !ok {
6668
vmLogger.Panicf("Programming error: unsupported VM type: %s", typ)
@@ -103,25 +105,25 @@ func (vmc *VMController) unlockContainer(id string) {
103105
vmc.Unlock()
104106
}
105107

106-
//VMCReqIntf - all requests should implement this interface.
108+
//VMCReq - all requests should implement this interface.
107109
//The context should be passed and tested at each layer till we stop
108110
//note that we'd stop on the first method on the stack that does not
109111
//take context
110-
type VMCReqIntf interface {
111-
Do(ctxt context.Context, v api.VM) error
112+
type VMCReq interface {
113+
Do(ctxt context.Context, v VM) error
112114
GetCCID() ccintf.CCID
113115
}
114116

115117
//StartContainerReq - properties for starting a container.
116118
type StartContainerReq struct {
117119
ccintf.CCID
118-
Builder api.Builder
120+
Builder Builder
119121
Args []string
120122
Env []string
121123
FilesToUpload map[string][]byte
122124
}
123125

124-
func (si StartContainerReq) Do(ctxt context.Context, v api.VM) error {
126+
func (si StartContainerReq) Do(ctxt context.Context, v VM) error {
125127
return v.Start(ctxt, si.CCID, si.Args, si.Env, si.FilesToUpload, si.Builder)
126128
}
127129

@@ -139,7 +141,7 @@ type StopContainerReq struct {
139141
Dontremove bool
140142
}
141143

142-
func (si StopContainerReq) Do(ctxt context.Context, v api.VM) error {
144+
func (si StopContainerReq) Do(ctxt context.Context, v VM) error {
143145
return v.Stop(ctxt, si.CCID, si.Timeout, si.Dontkill, si.Dontremove)
144146
}
145147

@@ -155,7 +157,7 @@ func (si StopContainerReq) GetCCID() ccintf.CCID {
155157
//context can be cancelled. VMCProcess will try to cancel calling functions if it can
156158
//For instance docker clients api's such as BuildImage are not cancelable.
157159
//In all cases VMCProcess will wait for the called go routine to return
158-
func (vmc *VMController) Process(ctxt context.Context, vmtype string, req VMCReqIntf) error {
160+
func (vmc *VMController) Process(ctxt context.Context, vmtype string, req VMCReq) error {
159161
v := vmc.newVM(vmtype)
160162
if v == nil {
161163
return fmt.Errorf("Unknown VM type %s", vmtype)

0 commit comments

Comments
 (0)