Skip to content

Remove the partial external builder output when the copy fails - #5636

Open
hmdsefi wants to merge 1 commit into
hyperledger:mainfrom
hmdsefi:fix/externalbuilder-partial-build-cleanup
Open

hmdsefi wants to merge 1 commit into
hyperledger:mainfrom
hmdsefi:fix/externalbuilder-partial-build-cleanup

Conversation

@hmdsefi

@hmdsefi hmdsefi commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Type of change

  • Bug fix

Description

After an external builder runs build and release, Detector.Build in core/container/externalbuilder/externalbuilder.go creates the durable directory for the package, writes build-info.json, and then copies the release and bld directories into it with CopyDir.

CopyDir refuses some files, for example an absolute symlink, a symlink that points outside the directory, or a socket. When it fails, it removes its own destination, but Build returns without removing the durable directory. build-info.json stays, and if the bld copy is the one that failed, the copied release directory stays too. The earlier error paths in Build already remove the directory.

On the next Build for the same package, CachedBuild finds build-info.json and returns the incomplete build as an instance, with no error, and the peer uses it to run the chaincode. Fixing the builder doesn't help, because the builder is not called again until someone deletes the directory under externalbuilder/builds by hand.

This change removes the durable directory when either copy fails, the same way Build does when build-info.json can't be written.

Additional details

Tests:

  • A new spec, "when the build output cannot be copied to the durable path", uses a test builder, testdata/symlinkbuilder, whose build leaves an absolute symlink in its output. It checks that Build fails, that the package directory is gone, and that a second Build fails the same way instead of returning a cached instance.
  • With the fix reverted, the spec fails because the package directory still exists. With that check removed, it fails on the second Build with Expected an error, got nil.

Ran:

  • go test -race ./core/container/externalbuilder/... passes.
  • golangci-lint reports no issues.

Related issues

Fixes #5635.

After an external builder builds and releases a chaincode,
Detector.Build creates the durable directory for the package, writes
build-info.json and copies the release and bld directories into it.
If one of the copies fails, for example because the build output has
an absolute symlink, Build returned the error but left the directory
and build-info.json behind.

The next Build for the same package found build-info.json and
returned the incomplete build as a cached instance, without running
the builder again. Fixing the builder did not help until the directory
was deleted by hand.

Remove the durable directory when either copy fails, as Build already
does when build-info.json cannot be written.

Signed-off-by: Hamed Yousefi <hdyousefi@gmail.com>
@hmdsefi
hmdsefi requested a review from a team as a code owner October 21, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

External builder leaves a partial build behind when copying the output fails

1 participant