Skip to content

Commit 2eadb11

Browse files
committed
Add versioning support to our applications
This patch introduces a more robust versioning mechanism, summarized as follows: 1) The top-level makefile defines $PROJECT_VERSION which is intended to be consumed throughout (though some places are left for a future patch) 2) The variable is expected to use Semantic Versioning with X.Y.Z for releases, and X.Y.Z-SNAPSHOT for intermediate development builds. 3) We bake the $PROJECT_VERSION into the binaries (peer and membersrvc) at compile time and remove the yaml configuration that attempted to provide competing versioning. 4) We tag our docker images (except for baseimage, that will be addressed later) with :$(ARCH)-$(PROJECT_VERSION), suitable for unambiguous long term hosting on something like dockerhub. 5) We add support for dynamically parsing yaml-based Dockerfile definitions to support variable subsitution. This allows the yaml to set a Dockerfile definition with something like "FROM foo:$(ARCH)-$(PROJECT_VERSION)" and the variables will resolve at runtime based on the context it runs under. This is all as a first step in supporting a more reasonable release mechanism in general, and a docker-based release mechanism in particular. Change-Id: Ic6df02be4046ca5dbb256f26658a4c393da55c0f Signed-off-by: Greg Haskins <[email protected]>
1 parent 1e7030a commit 2eadb11

File tree

14 files changed

+145
-32
lines changed

14 files changed

+145
-32
lines changed

Makefile

+37-12
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,21 @@
3636
# - clean - cleans the build area
3737
# - dist-clean - superset of 'clean' that also removes persistent state
3838

39-
PROJECT_NAME=hyperledger/fabric
39+
PROJECT_NAME = hyperledger/fabric
40+
BASE_VERSION = 0.6.0
41+
IS_RELEASE = false # commit as 'true' only once for a given $(BASE_VERSION)
42+
43+
ifneq ($(IS_RELEASE),true)
44+
EXTRA_VERSION ?= SNAPSHOT-$(shell git rev-parse --short HEAD)
45+
PROJECT_VERSION=$(BASE_VERSION)-$(EXTRA_VERSION)
46+
else
47+
PROJECT_VERSION=$(BASE_VERSION)
48+
endif
49+
50+
DOCKER_TAG=$(shell uname -m)-$(PROJECT_VERSION)
51+
4052
PKGNAME = github.com/$(PROJECT_NAME)
53+
GO_LDFLAGS = -X github.com/hyperledger/fabric/metadata.Version=$(PROJECT_VERSION)
4154
CGO_FLAGS = CGO_CFLAGS=" " CGO_LDFLAGS="-lrocksdb -lstdc++ -lm -lz -lbz2 -lsnappy"
4255
UID = $(shell id -u)
4356
CHAINTOOL_RELEASE=v0.8.1
@@ -76,7 +89,7 @@ membersrvc: build/bin/membersrvc
7689
membersrvc-image: build/image/membersrvc/.dummy
7790

7891
unit-test: peer-image gotools
79-
@./scripts/goUnitTests.sh
92+
@./scripts/goUnitTests.sh $(DOCKER_TAG) "$(GO_LDFLAGS)"
8093

8194
.PHONY: images
8295
images: $(patsubst %,build/image/%/.dummy, $(IMAGES))
@@ -137,7 +150,7 @@ build/docker/bin/%: build/image/src/.dummy $(PROJECT_FILES)
137150
--user=$(UID) \
138151
-v $(abspath build/docker/bin):/opt/gopath/bin \
139152
-v $(abspath build/docker/pkg):/opt/gopath/pkg \
140-
hyperledger/fabric-src go install github.com/hyperledger/fabric/$(TARGET)
153+
hyperledger/fabric-src:$(DOCKER_TAG) go install -ldflags "$(GO_LDFLAGS)" github.com/hyperledger/fabric/$(TARGET)
141154
@touch $@
142155

143156
build/bin:
@@ -156,7 +169,7 @@ build/bin/block-listener:
156169
build/bin/%: build/image/base/.dummy $(PROJECT_FILES)
157170
@mkdir -p $(@D)
158171
@echo "$@"
159-
$(CGO_FLAGS) GOBIN=$(abspath $(@D)) go install $(PKGNAME)/$(@F)
172+
$(CGO_FLAGS) GOBIN=$(abspath $(@D)) go install -ldflags "$(GO_LDFLAGS)" $(PKGNAME)/$(@F)
160173
@echo "Binary available as $@"
161174
@touch $@
162175

@@ -171,16 +184,22 @@ build/image/base/.dummy: $(BASEIMAGE_DEPS)
171184
build/image/src/.dummy: build/image/base/.dummy $(PROJECT_FILES)
172185
@echo "Building docker src-image"
173186
@mkdir -p $(@D)
174-
@cat images/src/Dockerfile.in > $(@D)/Dockerfile
187+
@cat images/src/Dockerfile.in \
188+
| sed -e 's/_TAG_/$(DOCKER_TAG)/g' \
189+
> $(@D)/Dockerfile
175190
@git ls-files | tar -jcT - > $(@D)/gopath.tar.bz2
176-
docker build -t $(PROJECT_NAME)-src:latest $(@D)
191+
docker build -t $(PROJECT_NAME)-src $(@D)
192+
docker tag $(PROJECT_NAME)-src $(PROJECT_NAME)-src:$(DOCKER_TAG)
177193
@touch $@
178194

179195
# Special override for ccenv-image (chaincode-environment)
180196
build/image/ccenv/.dummy: build/image/src/.dummy build/image/ccenv/bin/protoc-gen-go build/image/ccenv/bin/chaintool Makefile
181197
@echo "Building docker ccenv-image"
182-
@cat images/ccenv/Dockerfile.in > $(@D)/Dockerfile
183-
docker build -t $(PROJECT_NAME)-ccenv:latest $(@D)
198+
@cat images/ccenv/Dockerfile.in \
199+
| sed -e 's/_TAG_/$(DOCKER_TAG)/g' \
200+
> $(@D)/Dockerfile
201+
docker build -t $(PROJECT_NAME)-ccenv $(@D)
202+
docker tag $(PROJECT_NAME)-ccenv $(PROJECT_NAME)-ccenv:$(DOCKER_TAG)
184203
@touch $@
185204

186205
# Special override for java-image
@@ -194,17 +213,21 @@ build/image/javaenv/.dummy: Makefile $(JAVASHIM_DEPS)
194213
# 3. Gradle settings file
195214
@git ls-files core/chaincode/shim/java | tar -jcT - > $(@D)/javashimsrc.tar.bz2
196215
@git ls-files protos settings.gradle | tar -jcT - > $(@D)/protos.tar.bz2
197-
docker build -t $(PROJECT_NAME)-javaenv:latest $(@D)
216+
docker build -t $(PROJECT_NAME)-javaenv $(@D)
217+
docker tag $(PROJECT_NAME)-javaenv $(PROJECT_NAME)-javaenv:$(DOCKER_TAG)
198218
@touch $@
199219

200220
# Default rule for image creation
201221
build/image/%/.dummy: build/image/src/.dummy build/docker/bin/%
202222
$(eval TARGET = ${patsubst build/image/%/.dummy,%,${@}})
203223
@echo "Building docker $(TARGET)-image"
204224
@mkdir -p $(@D)/bin
205-
@cat images/app/Dockerfile.in | sed -e 's/_TARGET_/$(TARGET)/g' > $(@D)/Dockerfile
225+
@cat images/app/Dockerfile.in \
226+
| sed -e 's/_TAG_/$(DOCKER_TAG)/g' \
227+
> $(@D)/Dockerfile
206228
cp build/docker/bin/$(TARGET) $(@D)/bin
207-
docker build -t $(PROJECT_NAME)-$(TARGET):latest $(@D)
229+
docker build -t $(PROJECT_NAME)-$(TARGET) $(@D)
230+
docker tag $(PROJECT_NAME)-$(TARGET) $(PROJECT_NAME)-$(TARGET):$(DOCKER_TAG)
208231
@touch $@
209232

210233
.PHONY: protos
@@ -215,9 +238,11 @@ base-image-clean:
215238
-docker rmi -f $(PROJECT_NAME)-baseimage
216239
-@rm -rf build/image/base ||:
217240

241+
src-image-clean: ccenv-image-clean peer-image-clean membersrvc-image-clean
242+
218243
%-image-clean:
219244
$(eval TARGET = ${patsubst %-image-clean,%,${@}})
220-
-docker rmi -f $(PROJECT_NAME)-$(TARGET)
245+
-docker images -q $(PROJECT_NAME)-$(TARGET) | xargs -r docker rmi -f
221246
-@rm -rf build/image/$(TARGET) ||:
222247

223248
images-clean: $(patsubst %,%-image-clean, $(IMAGES))

core/chaincode/platforms/car/package.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828

2929
cutil "github.com/hyperledger/fabric/core/container/util"
3030
pb "github.com/hyperledger/fabric/protos"
31-
"github.com/spf13/viper"
3231
)
3332

3433
func download(path string) (string, error) {
@@ -78,7 +77,7 @@ func (carPlatform *Platform) WritePackage(spec *pb.ChaincodeSpec, tw *tar.Writer
7877
var buf []string
7978

8079
//let the executable's name be chaincode ID's name
81-
buf = append(buf, viper.GetString("chaincode.car.Dockerfile"))
80+
buf = append(buf, cutil.GetDockerfileFromConfig("chaincode.car.Dockerfile"))
8281
buf = append(buf, "COPY package.car /tmp/package.car")
8382
buf = append(buf, fmt.Sprintf("RUN chaintool buildcar /tmp/package.car -o $GOPATH/bin/%s && rm /tmp/package.car", spec.ChaincodeID.Name))
8483

core/chaincode/platforms/golang/package.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func writeChaincodePackage(spec *pb.ChaincodeSpec, tw *tar.Writer) error {
6969
newRunLine = fmt.Sprintf("%s\nCOPY src/certs/cert.pem %s", newRunLine, viper.GetString("peer.tls.cert.file"))
7070
}
7171

72-
dockerFileContents := fmt.Sprintf("%s\n%s", viper.GetString("chaincode.golang.Dockerfile"), newRunLine)
72+
dockerFileContents := fmt.Sprintf("%s\n%s", cutil.GetDockerfileFromConfig("chaincode.golang.Dockerfile"), newRunLine)
7373
dockerFileSize := int64(len([]byte(dockerFileContents)))
7474

7575
//Make headers identical by using zero time

core/chaincode/platforms/java/package.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func writeChaincodePackage(spec *pb.ChaincodeSpec, tw *tar.Writer) error {
4444
if viper.GetBool("security.enabled") {
4545
//todo
4646
} else {
47-
buf = append(buf, viper.GetString("chaincode.java.Dockerfile"))
47+
buf = append(buf, cutil.GetDockerfileFromConfig("chaincode.java.Dockerfile"))
4848
buf = append(buf, "COPY src /root")
4949
buf = append(buf, "RUN gradle -b build.gradle build")
5050
buf = append(buf, "RUN unzip -od /root build/distributions/Chaincode.zip")

core/container/util/dockerutil.go

+31
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ limitations under the License.
1717
package util
1818

1919
import (
20+
"runtime"
21+
"strings"
22+
2023
"github.com/fsouza/go-dockerclient"
24+
"github.com/hyperledger/fabric/metadata"
2125
"github.com/spf13/viper"
2226
)
2327

@@ -35,3 +39,30 @@ func NewDockerClient() (client *docker.Client, err error) {
3539
}
3640
return
3741
}
42+
43+
// Our docker images retrieve $ARCH via "uname -m", which is typically "x86_64" for, well, x86_64.
44+
// However, GOARCH uses "amd64". We therefore need to normalize any discrepancies between "uname -m"
45+
// and GOARCH here.
46+
var archRemap = map[string]string{
47+
"amd64": "x86_64",
48+
}
49+
50+
func getArch() string {
51+
if remap, ok := archRemap[runtime.GOARCH]; ok {
52+
return remap
53+
} else {
54+
return runtime.GOARCH
55+
}
56+
}
57+
58+
func parseDockerfileTemplate(template string) string {
59+
r := strings.NewReplacer(
60+
"$(ARCH)", getArch(),
61+
"$(PROJECT_VERSION)", metadata.Version)
62+
63+
return r.Replace(template)
64+
}
65+
66+
func GetDockerfileFromConfig(path string) string {
67+
return parseDockerfileTemplate(viper.GetString(path))
68+
}
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Copyright London Stock Exchange 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package util
18+
19+
import (
20+
"testing"
21+
22+
"github.com/hyperledger/fabric/metadata"
23+
)
24+
25+
func TestUtil_DockerfileTemplateParser(t *testing.T) {
26+
expected := "FROM foo:" + getArch() + "-" + metadata.Version
27+
actual := parseDockerfileTemplate("FROM foo:$(ARCH)-$(PROJECT_VERSION)")
28+
if actual != expected {
29+
t.Errorf("Error parsing Dockerfile Template. Expected \"%s\", got \"%s\"", expected, actual)
30+
}
31+
}

images/app/Dockerfile.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM hyperledger/fabric-src:latest
1+
FROM hyperledger/fabric-src:_TAG_
22
RUN mkdir -p /var/hyperledger/db
33
COPY bin/* $GOPATH/bin/
44
WORKDIR $GOPATH/src/github.com/hyperledger/fabric

images/ccenv/Dockerfile.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
FROM hyperledger/fabric-src:latest
1+
FROM hyperledger/fabric-src:_TAG_
22
COPY bin/* /usr/local/bin/

membersrvc/membersrvc.yaml

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# CA server parameters
22
#
33
server:
4-
# current version of the CA
5-
version: "0.1"
64

75
# limits the number of operating system threads used by the CA
86
# set to negative to use the system default setting

membersrvc/server.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/hyperledger/fabric/core/crypto"
2828
"github.com/hyperledger/fabric/flogging"
2929
"github.com/hyperledger/fabric/membersrvc/ca"
30+
"github.com/hyperledger/fabric/metadata"
3031
"github.com/op/go-logging"
3132
"github.com/spf13/viper"
3233
"google.golang.org/grpc"
@@ -67,7 +68,7 @@ func main() {
6768
// cache configure
6869
ca.CacheConfiguration()
6970

70-
logger.Infof("CA Server (" + viper.GetString("server.version") + ")")
71+
logger.Infof("CA Server (" + metadata.Version + ")")
7172

7273
aca := ca.NewACA()
7374
defer aca.Stop()

metadata/metadata.go

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
Copyright London Stock Exchange 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package metadata
18+
19+
var Version string // defined by the Makefile and passed in with ldflags

peer/core.yaml

+3-6
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,6 @@ logging:
7676
###############################################################################
7777
peer:
7878

79-
# Peer Version following version semantics as described here http://semver.org/
80-
# The Peer supplies this version in communications with other Peers
81-
version: 0.1.0
82-
8379
# The Peer id is used for identifying this Peer instance.
8480
id: jdoe
8581

@@ -292,14 +288,15 @@ chaincode:
292288
# This is the basis for the CAR Dockerfile. Additional commands will
293289
# be appended depedendent upon the chaincode specification.
294290
Dockerfile: |
295-
FROM hyperledger/fabric-ccenv
291+
FROM hyperledger/fabric-ccenv:$(ARCH)-$(PROJECT_VERSION)
292+
296293
java:
297294
# This is an image based on java:openjdk-8 with addition compiler
298295
# tools added for java shim layer packaging.
299296
# This image is packed with shim layer libraries that are necessary
300297
# for Java chaincode runtime.
301298
Dockerfile: |
302-
from hyperledger/fabric-javaenv
299+
from hyperledger/fabric-javaenv:$(ARCH)-$(PROJECT_VERSION)
303300
304301
# timeout in millisecs for starting up a container and waiting for Register
305302
# to come through. 1sec should be plenty for chaincode unit tests

peer/version/version.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ package version
1919
import (
2020
"fmt"
2121

22+
"github.com/hyperledger/fabric/metadata"
2223
"github.com/spf13/cobra"
23-
"github.com/spf13/viper"
2424
)
2525

2626
// Cmd returns the Cobra Command for Version
@@ -39,6 +39,5 @@ var cobraCommand = &cobra.Command{
3939

4040
// Print outputs the current executable version to stdout
4141
func Print() {
42-
version := viper.GetString("peer.version")
43-
fmt.Printf("Fabric peer server version %s\n", version)
42+
fmt.Printf("Fabric peer server version %s\n", metadata.Version)
4443
}

scripts/goUnitTests.sh

+15-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22

33
set -e
44

5+
TAG=$1
6+
GO_LDFLAGS=$2
7+
8+
BASEIMAGE="hyperledger/fabric-peer"
9+
IMAGE=$BASEIMAGE
10+
11+
if [ "$TAG" != "" ]
12+
then
13+
IMAGE="$BASEIMAGE:$TAG"
14+
fi
15+
16+
echo "Running unit tests using $IMAGE"
17+
518
echo "Cleaning membership services folder"
619
rm -rf membersrvc/ca/.ca/
720

@@ -10,7 +23,7 @@ PKGS=`go list github.com/hyperledger/fabric/... | grep -v /vendor/ | grep -v /ex
1023
echo "DONE!"
1124

1225
echo -n "Starting peer.."
13-
CID=`docker run -dit -p 7051:7051 hyperledger/fabric-peer peer node start`
26+
CID=`docker run -dit -p 7051:7051 $IMAGE peer node start`
1427
cleanup() {
1528
echo "Stopping peer.."
1629
docker kill $CID 2>&1 > /dev/null
@@ -19,4 +32,4 @@ trap cleanup 0
1932
echo "DONE!"
2033

2134
echo "Running tests..."
22-
gocov test $PKGS -p 1 -timeout=20m | gocov-xml > report.xml
35+
gocov test -ldflags "$GO_LDFLAGS" $PKGS -p 1 -timeout=20m | gocov-xml > report.xml

0 commit comments

Comments
 (0)