从 bazel genrule 调用 gcloud

Calling gcloud from bazel genrule

我在使用 Bazel genrule 将 gcloud 设置为 运行 时遇到了一些问题。看起来像 python 路径相关问题。

genrule(
    name="foo",
    outs=["bar"],
    srcs=[":bar.enc"],
    cmd="gcloud decrypt --location=global --keyring=foo --key=bar --plaintext-file $@ --ciphertext-file $(location bar.enc)"
)

例外情况是:

ImportError: No module named traceback

发件人:

 try:
    gcloud_main = _import_gcloud_main()
  except Exception as err:  # pylint: disable=broad-except
    # We want to catch *everything* here to display a nice message to the user
    # pylint:disable=g-import-not-at-top
    import traceback
    # We DON'T want to suggest `gcloud components reinstall` here (ex. as
    # opposed to the similar message in gcloud_main.py), as we know that no
    # commands will work.
    sys.stderr.write(
        ('ERROR: gcloud failed to load: {0}\n{1}\n\n'
         'This usually indicates corruption in your gcloud installation or '
         'problems with your Python interpreter.\n\n'
         'Please verify that the following is the path to a working Python 2.7 '
         'executable:\n'
         '    {2}\n\n'
         'If it is not, please set the CLOUDSDK_PYTHON environment variable to '
         'point to a working Python 2.7 executable.\n\n'
         'If you are still experiencing problems, please reinstall the Cloud '
         'SDK using the instructions here:\n'
         '    https://cloud.google.com/sdk/\n').format(
             err,
             '\n'.join(traceback.format_exc().splitlines()[2::2]),
             sys.executable))
    sys.exit(1)

我的问题是:

更新: 可以通过指定 CLOUDSDK_PYTHON.

来达到 运行

的确,bazel runs in a sandbox,因此 gcloud 找不到它的依赖项。实际上,我很惊讶 gcloud 竟然可以被调用。

为了继续,我会将 gcloud 包裹在一个 bazel py_binary 中,并在 genrule 中使用 tools 属性引用它。您还需要在 cmd 中用 location 包装它。最后,你将拥有

genrule(
    name = "foo",
    outs = ["bar"],
    srcs = [":bar.enc"],
    cmd = "$(location //third_party/google/gcloud) decrypt --location=global --keyring=foo --key=bar --plaintext-file $@ --ciphertext-file $(location bar.enc)",
    tools = ["//third_party/google/gcloud"],
)

为此,您在 third_party/google/gcloud/BUILD 中定义(或您想要的任何地方,我只是使用了对我来说有意义的路径)

py_binary(
    name = "gcloud",
    srcs = ["gcloud.py"],
    main = "gcloud.py",
    visibility = ["//visibility:public"],
    deps = [
        ":gcloud_sdk",
    ],
)
py_library(
  name = "gcloud_sdk",
  srcs = glob(
      ["**/*.py"],
      exclude = ["gcloud.py"],
      # maybe exclude tests and unrelated code, too.
  ),
  deps = [
    # Whatever extra deps are needed by gcloud to compile
  ]
)

我遇到了类似的问题,对我有用 运行 这个命令:

export CLOUDSDK_PYTHON=/usr/bin/python

(上面作为更新回答了这个问题,但我觉得 post 未来人们来到这里的整个命令)