我正在尝试创建 Bazel 规则,该规则将执行 docker-compose 命令并从 docker-compose.yaml 文件中启动所有 docker 图像。我能够做到这一点,但我的下一步是让我的规则依赖于container_image
我的构建文件中的另一个目标。
我想先运行这个container_image
目标,然后运行我自己的规则。我需要运行container_image
规则,因为这是规则将构建的图像实际加载到 docker 的唯一方法。我需要这样做,因为我打算将这个新建图像的名称注入到我的 docker-compose.yaml 文件中。
我的规则代码是:
def _dcompose_up_impl(ctx):
toolchain_info = ctx.toolchains["@com_unfold_backend//rules:toolchain_type"].dc_info
test_image = ctx.attr.test_image
docker_up = ctx.actions.declare_file(ctx.label.package + "-" + ctx.label.name + ".yaml")
image_name = "bazel/%s:%s" % (test_image.label.package, test_image.label.name)
ctx.actions.expand_template(
output = docker_up,
template = ctx.file.docker_compose,
substitutions = {"{IMAGE}": image_name},
)
out = ctx.actions.declare_file(ctx.label.name + ".out")
ctx.actions.run(executable = ctx.executable.test_image, outputs = [out])
runfiles = ctx.runfiles(files = ctx.files.data + [docker_up, out])
cmd = """echo Running docker compose for {file}
{dockerbin} -f {file} up -d
""".format(file = docker_up.short_path, dockerbin = toolchain_info.path)
exe = ctx.actions.declare_file("docker-up.sh")
ctx.actions.write(exe, cmd)
return [DefaultInfo(
executable = exe,
runfiles = runfiles,
)]
dcompose_up = rule(
implementation = _dcompose_up_impl,
attrs = {
"docker_compose": attr.label(allow_single_file = [".yaml", ".yml"], mandatory = True),
"data": attr.label_list(allow_files = True),
"test_image": attr.label(
executable = True,
cfg = "exec",
mandatory = True,
),
},
toolchains = ["//rules:toolchain_type"],
executable = True,
)
问题是我在运行container_image
任务时创建的文件test_image
。我从巴泽尔那里得到错误Loaded image ID: sha256:c15a1b44d84dc5d3f1ba5be852e6a5dfbdc11e24ff42615739e348bdb0522813 Tagging c15a1b44d84dc5d3f1ba5be852e6a5dfbdc11e24ff42615739e348bdb0522813 as bazel/images/test:image_test ERROR: /monogit/test/BUILD:18:22: output '/test/integration.up.out' was not created ERROR: /monogit/test/BUILD:18:22: Action test/integration.up.out failed: not all outputs were created or valid
如果我从运行文件中删除文件以执行 docker-compose,那么我的文件test_image
不会加载到 docker。在第一个示例中,它被加载但 docker-compose 然后失败。
对我来说很明显 container_image 规则不会创建输出文件。在那种情况下,我怎样才能让 Bazel 运行,而不仅仅是构建、container_image
可执行,然后是我的可执行文件?