Skip to content

Commit 9d159a7

Browse files
committed
[FAB-4883] Fix vendoring with parent vendored deps
We change the way auto-vendoring works such that deps that are already vendored are not re-vendored inappropriately. It was found that nested vendoring could break the previously employed scheme. For example, consider a package "foo/bar/baz". It's conceivable that a vendor folder may appear anywhere in that hierarchy, e.g. [ "foo/vendor", "foo/bar/vendor", "foo/bar/baz/vendor"] and golang would recognize the contents as a legitimate vendor. This was precisely the situation when we had chaincode in the package github.com/fabric/hyperledger/examples/chaincode where github.com/fabric/vendor was in effect. We now scan the entire package heirarchy to ensure we capture the potential relationships regardless of where they sit in the tree. Fixes FAB-4883 Change-Id: I7c6aa5ba0401cecc26bc58f5e6cda6e208109411 Signed-off-by: Greg Haskins <[email protected]>
1 parent 5a66dd3 commit 9d159a7

File tree

1 file changed

+77
-18
lines changed

1 file changed

+77
-18
lines changed

core/chaincode/platforms/golang/platform.go

+77-18
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,74 @@ func (goPlatform *Platform) ValidateDeploymentSpec(cds *pb.ChaincodeDeploymentSp
178178
return nil
179179
}
180180

181+
// Vendor any packages that are not already within our chaincode's primary package
182+
// or vendored by it. We take the name of the primary package and a list of files
183+
// that have been previously determined to comprise the package's dependencies.
184+
// For anything that needs to be vendored, we simply update its path specification.
185+
// Everything else, we pass through untouched.
186+
func vendorDependencies(pkg string, files Sources) {
187+
188+
exclusions := make([]string, 0)
189+
elements := strings.Split(pkg, "/")
190+
191+
// --------------------------------------------------------------------------------------
192+
// First, add anything already vendored somewhere within our primary package to the
193+
// "exclusions". For a package "foo/bar/baz", we want to ensure we don't auto-vendor
194+
// any of the following:
195+
//
196+
// [ "foo/vendor", "foo/bar/vendor", "foo/bar/baz/vendor"]
197+
//
198+
// and we therefore employ a recursive path building process to form this list
199+
// --------------------------------------------------------------------------------------
200+
prev := filepath.Join("src")
201+
for _, element := range elements {
202+
curr := filepath.Join(prev, element)
203+
vendor := filepath.Join(curr, "vendor")
204+
exclusions = append(exclusions, vendor)
205+
prev = curr
206+
}
207+
208+
// --------------------------------------------------------------------------------------
209+
// Next add our primary package to the list of "exclusions"
210+
// --------------------------------------------------------------------------------------
211+
exclusions = append(exclusions, filepath.Join("src", pkg))
212+
213+
count := len(files)
214+
sem := make(chan bool, count)
215+
216+
// --------------------------------------------------------------------------------------
217+
// Now start a parallel process which checks each file in files to see if it matches
218+
// any of the excluded patterns. Any that match are renamed such that they are vendored
219+
// under src/$pkg/vendor.
220+
// --------------------------------------------------------------------------------------
221+
vendorPath := filepath.Join("src", pkg, "vendor")
222+
for i, file := range files {
223+
go func(i int, file SourceDescriptor) {
224+
excluded := false
225+
226+
for _, exclusion := range exclusions {
227+
if strings.HasPrefix(file.Name, exclusion) == true {
228+
excluded = true
229+
break
230+
}
231+
}
232+
233+
if excluded == false {
234+
origName := file.Name
235+
file.Name = strings.Replace(origName, "src", vendorPath, 1)
236+
logger.Debugf("vendoring %s -> %s", origName, file.Name)
237+
}
238+
239+
files[i] = file
240+
sem <- true
241+
}(i, file)
242+
}
243+
244+
for i := 0; i < count; i++ {
245+
<-sem
246+
}
247+
}
248+
181249
// Generates a deployment payload for GOLANG as a series of src/$pkg entries in .tar.gz format
182250
func (goPlatform *Platform) GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error) {
183251

@@ -320,30 +388,21 @@ func (goPlatform *Platform) GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte
320388
logger.Debugf("done")
321389

322390
// --------------------------------------------------------------------------------------
323-
// Reclassify and sort the files:
324-
//
325-
// Two goals:
326-
// * Remap non-package dependencies to package/vendor
327-
// * Sort the final filename so the tarball at least looks sane in terms of package grouping
391+
// Reprocess into a list for easier handling going forward
328392
// --------------------------------------------------------------------------------------
329393
files := make(Sources, 0)
330-
pkgPath := filepath.Join("src", code.Pkg)
331-
vendorPath := filepath.Join(pkgPath, "vendor")
332394
for _, file := range fileMap {
333-
// Vendor any packages that are not already within our chaincode's primary package. We
334-
// detect this by checking the path-prefix. Anything that is prefixed by "src/$pkg"
335-
// (which includes the package itself and anything explicitly vendored in "src/$pkg/vendor")
336-
// are left unperturbed. Everything else is implicitly vendored under src/$pkg/vendor by
337-
// simply remapping "src" -> "src/$pkg/vendor" in the tarball index.
338-
if strings.HasPrefix(file.Name, pkgPath) == false {
339-
origName := file.Name
340-
file.Name = strings.Replace(origName, "src", vendorPath, 1)
341-
logger.Debugf("vendoring %s -> %s", origName, file.Name)
342-
}
343-
344395
files = append(files, file)
345396
}
346397

398+
// --------------------------------------------------------------------------------------
399+
// Remap non-package dependencies to package/vendor
400+
// --------------------------------------------------------------------------------------
401+
vendorDependencies(code.Pkg, files)
402+
403+
// --------------------------------------------------------------------------------------
404+
// Sort on the filename so the tarball at least looks sane in terms of package grouping
405+
// --------------------------------------------------------------------------------------
347406
sort.Sort(files)
348407

349408
// --------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)