00 导言
在上一讲中,我们手把手带着大家一步一步《在Ubuntu 18.04上搭建HyperLedger Fabric 1.2.0 环境》,其中有两个步骤是:下载bootstrap.sh引导脚本和执行该引导脚本。很多朋友执行这两个步骤时可能会有疑问:为什么要下载这个脚本?执行这个脚本的作用是什么?
别急,接下来我们会深入分析一下这个文件的源码,探个究竟。不过在分析之前,我们先来回顾一下上一讲是怎么下载和执行这个脚本的。
02 如何下载和执行bootstrap.sh脚本
我们先来看看官方是怎么说的。官方提供的命令如下:
$ curl -sSL http://bit.ly/2ysbOFE | bash -s 1.2.0 1.2.0 0.4.10
我们来解释一下这条命令:curl -sSL http://bit.ly/2ysbOFE,这条命令是通过请求短链接http://bit.ly/2ysbOFE,该短链接会重定向到真正的目标地址,目标地址会响应我们要的内容,响应的内容就是bootstrap.sh文件里的内容。很不幸的是,上面的短链接已经失效,不过我们已经找到了一个有效的长链接:https://raw.githubusercontent.com/hyperledger/fabric/release-1.2/scripts/bootstrap.sh,用它替换掉短链接就可以了。于是我们得到了下面的命令:
$ curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/release-1.2/scripts/bootstrap.sh | bash -s 1.2.0 1.2.0 0.4.10
这里要解释一下-sSL的作用,小s指的是沉默模式,表示不输出请求过程的任何信息,只输出最终响应的内容,大S指的是如果有错显示出来,L指的是短链接要进行重定向。
接下来是一根竖线 |,学过linux的朋友应该都知道,这根竖线表示管道,意思是上一个命令输出的内容,交给下一个命令去执行,这里表示交给bash去执行。
bash 后面是-s ,-s后面的所有内容将做为参数传给bootstrap.sh。1.2.0 1.2.0 0.4.10这3个对应的是 Fabric, Fabric-ca 和 thirdparty(couchdb, kafka and zookeeper) 这三个模块的版本。如果我们想要安装更早的版本,我们可以修改它们,脚本程序会知道下载对应的版本。
上面实际上是两条命令通过管道( | )连接在一起执行,实际上我们也可以将它们分开:
$ curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/release-1.2/scripts/bootstrap.sh -o bootstrap.sh
$ chmod 755 bootstrap.sh
$ sudo ./bootstrap.sh 1.2.0 1.2.0 0.4.10
03 bootstrap.sh到底帮我们做了什么?
bootstrap.sh实际上帮我们作了如下几件事情:
1. 从github上克隆 hyperledger/fabric-samples并进入该目录,然后检出适当的版本
2. 在fabric-samples目录下安装特定平台的 Hyperledger Fabric 二进制可执行文件 和配置文件
3.下载 指定版本的Hyperledger Fabric 的docker镜像
整个脚本帮我们做了上面这三件事情,bootstrap.sh中对应的代码如下:
218 if [ "$SAMPLES" == "true" ]; then
219 echo
220 echo "Installing hyperledger/fabric-samples repo"
221 echo
222 samplesInstall
223 fi
224 if [ "$BINARIES" == "true" ]; then
225 echo
226 echo "Installing Hyperledger Fabric binaries"
227 echo
228 binariesInstall
229 fi
230 if [ "$DOCKER" == "true" ]; then
231 echo
232 echo "Installing Hyperledger Fabric docker images"
233 echo
234 dockerInstall
235 fi
其中samplesInstall对应的是克隆fabric-samples,binariesInstall对应的是安装二进制文件,dockerInstall对应的是下载docker镜像。
接下来我们分析一下它们对应的代码部分。
04 第一件事:克隆fabric-samples并检出适当的版本
对应bootstrap.sh中的samplesInstall函数,代码如下:
56 samplesInstall() {
57 # clone (if needed) hyperledger/fabric-samples and checkout corresponding
58 # version to the binaries and docker images to be downloaded
59 if [ -d first-network ]; then
60 # if we are in the fabric-samples repo, checkout corresponding version
61 echo "===> Checking out v${VERSION} branch of hyperledger/fabric-samples"
62 git checkout v${VERSION}
63 elif [ -d fabric-samples ]; then
64 # if fabric-samples repo already cloned and in current directory,
65 # cd fabric-samples and checkout corresponding version
66 echo "===> Checking out v${VERSION} branch of hyperledger/fabric-samples"
67 cd fabric-samples && git checkout v${VERSION}
68 else
69 echo "===> Cloning hyperledger/fabric-samples repo and checkout v${VERSION}"
70 git clone -b master https://github.com/hyperledger/fabric-samples.git && cd fabric-samples && git checkout v${VERSION}
71 fi
72 }
我们可以看到第70行代码,这行代码的作用就是 从github上克隆 hyperledger/fabric-samples,然后进入该目录,并检出指定的版本。
该仓库的地址是:
https://github.com/hyperledger/fabric-samples.git
05 第二件事:安装二进制可执行文件 和配置文件
对应bootstrap.sh中的binariesInstall函数,代码如下:
133 binariesInstall() {
134 echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
135 binaryDownload ${BINARY_FILE} https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/${ARCH}-${VERSION}/${BINARY_FILE}
136 if [ $? -eq 22 ]; then
137 echo
138 echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
139 echo
140 fi
141
142 echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
143 binaryDownload ${CA_BINARY_FILE} https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric-ca/hyperledger-fabric-ca/${ARCH}-${CA_VERSION}/${CA_BINARY_FILE}
144 if [ $? -eq 22 ]; then
145 echo
146 echo "------> ${CA_TAG} fabric-ca-client binary is not available to download (Available from 1.1.0-rc1) <----"
147 echo
148 fi
149 }
可以看到第135行和第143行分别调用binaryDownload函数去下面这两个地址下载fabric和fabric-ca相应的二进制文件打成的压缩包。实际上我们也可以使用浏览器或者下载软件单独下载它们。
1.https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/linux-amd64-1.2.0/hyperledger-fabric-linux-amd64-1.2.0.tar.gz
2.https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric-ca/hyperledger-fabric-ca/linux-amd64-1.2.0/hyperledger-fabric-ca-linux-amd64-1.2.0.tar.gz
我们接下来看看binaryDownload函数:
113 binaryDownload() {
114 local BINARY_FILE=$1
115 local URL=$2
116 echo "===> Downloading: " ${URL}
117 # Check if a previous failure occurred and the file was partially downloaded
118 if [ -e ${BINARY_FILE} ]; then
119 echo "==> Partial binary file found. Resuming download..."
120 binaryIncrementalDownload ${BINARY_FILE} ${URL}
121 else
122 curl ${URL} | tar xz || rc=$?
123 if [ ! -z "$rc" ]; then
124 echo "==> There was an error downloading the binary file. Switching to incremental download."
125 echo "==> Downloading file..."
126 binaryIncrementalDownload ${BINARY_FILE} ${URL}
127 else
128 echo "==> Done."
129 fi
130 fi
131 }
可以看到第122行,执行curl命令去下载tar包,并用tar命令解压。解压后的命令出现在bin目录下。实际上,这些二进制命令我们也可以通过编译hyperledger fabric的源码生成!后面我们有文章会讲到怎么编译源码去生成这些二进制文件。
-rwxrwxr-x 1 1001 1001 16784432 7月 4 03:04 configtxgen*
-rwxrwxr-x 1 1001 1001 17925784 7月 4 03:04 configtxlator*
-rwxrwxr-x 1 1001 1001 8660280 7月 4 03:04 cryptogen*
-rwxrwxr-x 1 1001 1001 17611704 7月 4 03:04 discover*
-rwxrwxr-x 1 1001 1001 14298688 7月 4 04:41 fabric-ca-client*
-rwxrwxr-x 1 1001 1001 817 7月 4 03:04 get-docker-images.sh*
-rwxrwxr-x 1 1001 1001 7152824 7月 4 03:04 idemixgen*
-rwxrwxr-x 1 1001 1001 22075240 7月 4 03:04 orderer*
-rwxrwxr-x 1 1001 1001 29880000 7月 4 03:04 peer*
我们解释一下其中这些命令的作用:
名称 | 作用 |
---|---|
peer | 负责启动节点,存储区块链数据,运行维护链码 |
order | 负责启动排序节点,对交易进行排序,并将排序好的交易打包成模块 |
cryptogen | 生成组织结构和身份文件 |
configtxgen | 生成配置区块和配置交易 |
configtxlator | 解读配置信息 |
fabric-ca-client | fabric-ca客户端命令 |
discover | fabric发现服务的客户端命令 |
idemixgen | 身份混合机制 |
06 第三件事:下载docker镜像
对应bootstrap.sh中的dockerInstall函数,代码如下:
151 dockerInstall() {
152 which docker >& /dev/null
153 NODOCKER=$?
154 if [ "${NODOCKER}" == 0 ]; then
155 echo "===> Pulling fabric Images"
156 dockerFabricPull ${FABRIC_TAG}
157 echo "===> Pulling fabric ca Image"
158 dockerCaPull ${CA_TAG}
159 echo "===> Pulling thirdparty docker images"
160 dockerThirdPartyImagesPull ${THIRDPARTY_TAG}
161 echo
162 echo "===> List out hyperledger docker images"
163 docker images | grep hyperledger*
164 else
165 echo "========================================================="
166 echo "Docker not installed, bypassing download of Fabric images"
167 echo "========================================================="
168 fi
169 }
可以看到第156行,第158行,第160行,分别调用了dockerFabricPull 、dockerCaPull 、dockerThirdPartyImagesPull 三个函数去拉取相应的docker镜像并打标签。最后下载完还执行docker images | grep hyperledger*(第163行)查看是否已下载好下面所列的镜像。
hyperledger/fabric-ca 1.2.0 66cc132bd09c 4 weeks ago 252MB
hyperledger/fabric-tools 1.2.0 379602873003 4 weeks ago 1.51GB
hyperledger/fabric-ccenv 1.2.0 6acf31e2d9a4 4 weeks ago 1.43GB
hyperledger/fabric-orderer 1.2.0 4baf7789a8ec 4 weeks ago 152MB
hyperledger/fabric-peer 1.2.0 82c262e65984 4 weeks ago 159MB
hyperledger/fabric-zookeeper 0.4.10 2b51158f3898 4 weeks ago 1.44GB
hyperledger/fabric-kafka 0.4.10 936aef6db0e6 4 weeks ago 1.45GB
hyperledger/fabric-couchdb 0.4.10 3092eca241fc 4 weeks ago 1.61GB
hyperledger/fabric-baseos amd64-0.4.10 52190e831002 4 weeks ago 132MB
hyperledger/fabric-ca x86_64-1.0.4 8e691b3509bf 9 months ago 238MB
hyperledger/fabric-javaenv x86_64-1.0.4 a517b70135c7 9 months ago 1.41GB
dockerFabricPull函数代码如下:
28 dockerFabricPull() {
29 local FABRIC_TAG=$1
30 for IMAGES in peer orderer ccenv tools; do
31 echo "==> FABRIC IMAGE: $IMAGES"
32 echo
33 docker pull hyperledger/fabric-$IMAGES:$FABRIC_TAG
34 docker tag hyperledger/fabric-$IMAGES:$FABRIC_TAG hyperledger/fabric-$IMAGES
35 done
36 }
dockerCaPull 函数代码如下:
48 dockerCaPull() {
49 local CA_TAG=$1
50 echo "==> FABRIC CA IMAGE"
51 echo
52 docker pull hyperledger/fabric-ca:$CA_TAG
53 docker tag hyperledger/fabric-ca:$CA_TAG hyperledger/fabric-ca
54 }
dockerThirdPartyImagesPull 函数代码如下:
38 dockerThirdPartyImagesPull() {
39 local THIRDPARTY_TAG=$1
40 for IMAGES in couchdb kafka zookeeper; do
41 echo "==> THIRDPARTY DOCKER IMAGE: $IMAGES"
42 echo
43 docker pull hyperledger/fabric-$IMAGES:$THIRDPARTY_TAG
44 docker tag hyperledger/fabric-$IMAGES:$THIRDPARTY_TAG hyperledger/fabric-$IMAGES
45 done
46 }
上面dockerThirdPartyImagesPull 函数内部使用了一个for循环(第40行)挨个去下载couchdb、kafka、zookeeper三个镜像。
部分镜像说明如下:
镜像名称 | 是否可选 | 镜像说明 |
---|---|---|
hyperledger/fabric-tools | 可选 | 包含crytogen、configtxgen、configtxlator我第二次工具的镜像文件 |
hyperledger/fabric-couchdb | 可选 | CouchDB的数据库镜像文件、状态数据库选择CouchDB的时候才需要 |
hyperledger/fabric-kafka | 可选 | Kafka的镜像文件 |
hyperledger/fabric-zookeeper | 可选 | Zookeeper的镜像文件 |
hyperledger/fabric-peer | 必选 | Peer节点的镜像文件 |
hyperledger/fabric-orderer | 必选 | 排序服务节点的镜像文件 |
hyperledger/fabric-javaenv | 可选 | java链码的基础镜像文件 |
hyperledger/fabric-ccenv | 必选 | Golang链码的基础镜像文件 |
hyperledger/fabric-ca | 可选 | fabric-ca的镜像文件,用到fabric-ca的时候才需要 |
07 总结
通过上面的介绍,相信大家已经了解了bootstrap.sh的作用了。读者可能会纳闷了,为啥要花这么大篇幅来介绍这个脚本文件??吃饱了撑的吗。这是因为我们通过分析这个文件,知道了具体内部干了什么,知其然也要知其所以然嘛。这样,我们也可以不需要这个脚本文件,手动就能把环境搭建好!!
08 参考资料
1.https://hyperledger-fabric.readthedocs.io/en/release-1.2/install.html
2.《深度探索区块链:Hyperledger技术与应用》作者: 张增骏 / 董宁 / 朱轩彤 / 陈剑雄 出版社: 机械工业出版社
- 《区块链开发实战 Hyperledger Fabric关键技术与案例分析》作者: 冯翔 刘涛 吴寿鹤 周广益 出版社:机械工业出版社
- 《HyperLedger Fabric开发实战快速掌握区块链技术》作者:杨毅 出版社: 电子工业出版社