前言
fabric2.0 可以使用external builder跑chaincode源码,方便chaincode调试,但是external builder编译和启动chaincode等操作使用的是4个bash脚本,而windows原生不支持bash。
折腾
经过一番研究(折腾),我发现只要完成以下3个步骤,即可在windows上run external chaincode。
1、安装git-windows,记住安装目录
2、安装jq(不低于1.6版本),放到git安装目录底下的usr/bin里面,并改名为jq
3、修改core/container/externalbuilder/externalbuilder.go
添加兼容windows的执行bash的代码:
// convert windows path format to unix path because bash only support unix path format
// if wpath is unix path format, it won't return wpath directly.
func winPath2UnixPath(wpath string) (upath string) {
vname := filepath.VolumeName(wpath)
if strings.HasSuffix(vname, ":") {
upath = "/" + strings.ToLower(vname[:len(vname) - 1])
upath += filepath.ToSlash(wpath[len(vname):])
} else {
upath = filepath.ToSlash(wpath)
}
return
}
func (b *Builder) NewCommand(name string, args ...string) *exec.Cmd {
//cmd := exec.Command(name, args...)
var cmd *exec.Cmd
// If you use windows, you should download git-windows and jq(version >= 1.6) firstly.
if runtime.GOOS == "windows" {
cmdString := winPath2UnixPath(name)
for _, arg := range args {
cmdString +=" " + winPath2UnixPath(arg)
}
// Both windows and linux support bash -c "cmd args..." type.
cmd = exec.Command("bash", "-c", cmdString)
} else {
cmd = exec.Command(name, args...)
}
whitelist := appendDefaultWhitelist(b.EnvWhitelist)
for _, key := range whitelist {
if val, ok := os.LookupEnv(key); ok {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", key, val))
}
}
return cmd
}
4、添加core.yaml中关于endpoint和externalBuilders的配置
endpoint:
externalBuilders:
- path: E:\share_vir\go\src\github.com\hyperledger\fabric\myNetwork\externalbuilders\golang
name: external-golang
environmentWhitelist:
- GOPROXY
- GOCACHE
- GOPATH
注:这一步是使用windows和linux都需要做的。
说明
1、安装git-windows后会自带一个bash.exe,但是它支持的linux命令有限,缺少external buidler那4个脚本用到的jq命令。
2、jq.exe 1.5版本有个bug,如果传入的参数长度过长,就会段错误。
3、bash只能识别unix path, 代码主要用于将windows path转化为unix path,然后使用bash -c "xxx"这种形式调用脚本。
执行环境
4、core.yaml中external builder,path设置为绝对路径;environmentWhitelist列举的是运行4个bash脚本需要的环境变量,主要用于支持go build。
externalBuilders:
- path: E:\share_vir\go\src\github.com\hyperledger\fabric\myNetwork\externalbuilders\golang
name: external-golang
environmentWhitelist:
- GOPROXY
- GOCACHE
- GOPATH
更进一步
4个bash脚本的运行环境是受限的,所有环境变量都靠bash传入。
从1.12开始,go build强制要求GOCACHE,因此需要传入GOCACHE。如果没改过GOCACHE的默认路径,不传入GOCACHE,改为传入LocalAppData(linux为$HOME)也行,go可以推断出GOCACHE的路径。
go build支持mod的代码时,会自动下载依赖,将GOPROXY设置为七牛云维护的地址,可以快速拉包。
go env -w GOPROXY=https://goproxy.cn,direct
5、在IDE里面运行peer,需要配置FABRIC_CFG_PATH, GOCACHE和GOPROXY(如果已经设置成系统环境变量,则可不配置)。
6、环境变量传递路径:IDE–>peer–>bash–>4个bash脚本。
7、detect脚本限定了type和label,因此lifecycle chaincode package时指定的–label 后缀必须为-external,–lang 必须为golang。