我正在编译一个GO应用,我想在谷歌云平台上传和运行。我正在导入appengine/datastore
包,并且遇到了销售包的问题。由于我想提供稳定的构建,我希望在源代码树中销售尽可能多的依赖项,但是当我提供商appengine/datastore
时,我遇到了运行gcloud app deploy
的问题:
OperationError:错误响应:[9]部署包含无法编译的文件:编译失败: 2017/09/19 01:07:31 go-app-builder:解析输入失败:包“vendor / google.golang.org / appengine / search”无法导入内部包“google.golang.org/appengine/internal/search “
ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:
2017/09/19 01:07:31 go-app-builder: Failed parsing input: package "vendor/google.golang.org/appengine/search" cannot import internal package "google.golang.org/appengine/internal/search"
我可以正常运行dev_appserver.py
脚本,应用程序在本地运行顺利,go test
成功编译并运行所有模块测试。
如果我尝试删除任何appengine软件包的销售,而是使用go get
在版本控制之外安装它们,dev_appserver.py
不再运行,抱怨重复的软件包:
rm -rf ../vendor/google.golang.org/appengine
go get google.golang.org/appengine
dev_appserver.py app.yaml
[....]
2017/09/19 10:20:10 go-app-builder: Failed parsing input: package "golang.org/x/net/context" is imported from multiple locations: "/home/peter/src/myproject/go/src/myproject/vendor/golang.org/x/net/context" and "/home/peter/src/myproject/go/src/golang.org/x/net/context"
而gcloud app deploy
反而抱怨根本找不到包裹:
[...]
File upload done.
Updating service [default]...failed.
ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:
Compile failed:
2017/09/19 01:22:13 go-app-builder: build timing: 7×compile (1.749s total), 0×link (0s total)
2017/09/19 01:22:13 go-app-builder: failed running compile: exit status 2
myproject/vendor/golang.org/x/text/unicode/norm/normalize.go:15: can't find import: "golang.org/x/text/transform"
$ find .. -name transform
../vendor/golang.org/x/text/transform
编辑:替代方法:我发现我可以通过对已销售的目录(gcloud
和{{进行符号链接来使用github.com
进行编译1}})进入应用程序目录(golang.org
),并手动下载appengine包(ln -s ../vendor/* .
)。但是,我需要删除符号链接以便能够运行go get google.golang.org/appengine
,因此这不是最佳选择。
答案 0 :(得分:2)
发生这种情况的原因是因为App Engine如何构建Go应用。
由于App Engine标准环境security sandbox和容器模型,它们禁止Go代码导入可能会干扰其系统的任何程序包,例如unsafe
。出于相同的原因,它们还阻止内部appengine程序包(google.golang.org/appengine/internal/whatever
)的直接导入。
对于这个项目,您已经在本地供应了依赖项。但是,对于应用程序引擎应用程序构建器来说,这看起来没有什么不同,如果您刚刚在应用程序中制作了另一个子程序包并将依赖项放在其中。其功能与您刚将appengine/search
复制并粘贴到项目中一样。
由于appengine/search
导入了其相应的内部包appengine/internal/search
,而Go应用程序构建器并没有真正区分应用程序代码和vendor
目录中的内容,因此失败构建。对于App Engine,看起来 you 导入了appengine/internal/search
,但是该安全模型禁止该行为。它不知道appengine/internal/search
的使用方式,因为它无法控制vendor
中的内容,因此为了保护沙箱的安全,不允许您导入它。
基本上,此问题的解决方案是不提供依赖性。
如果您从appengine/whatever
中删除了所有vendor
程序包,则App Engine构建器将在Google的构建服务器上而不是您的项目中寻找它们。 App Builder相信自己appengine
库的本地副本不会有不当行为,因此可以导入appengine/whatever/internal
软件包。
(顺便说一句,如果还没有,请确保gcloud
和所有相关组件都是最新的。这有时可以解决过分依赖的问题)