首页 > 解决方案 > 如何创建在运行时也将首先运行依赖目标的规则

问题描述

我正在尝试创建 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可执行,然后是我的可执行文件?

标签: dockerbazelbazel-rulesstarlark

解决方案


推荐阅读