def generate_legacy_dir(ctx, config, manifest, layers):
    """Generate a intermediate legacy directory from the image represented by the given layers and config to /image_runfiles.

    Args:
      ctx: the execution context
      config: the image config file
      manifest: the image manifest file
      layers: the list of layer tarballs

    Returns:
      The filepaths generated and runfiles to be made available.
      config: the generated config file.
      layers: the generated layer tarball files.
      temp_files: all the files generated to be made available at runtime.
    """

    # Construct image runfiles for input to pusher.
    image_files = [] + layers
    if config:
        image_files += [config]
    if manifest:
        image_files += [manifest]

    path = "image_runfiles/"
    layer_files = []

    # Symlink layers to ./image_runfiles/<i>.tar.gz
    for i in range(len(layers)):
        layer_symlink = ctx.actions.declare_file(path + str(i) + ".tar.gz")
        layer_files.append(layer_symlink)
        ctx.actions.run_shell(
            outputs = [layer_symlink],
            inputs = [layers[i]],
            command = "ln {src} {dst}".format(
                src = layers[i].path,
                dst = layer_symlink.path,
            ),
        )

    # Symlink config to ./image_runfiles/config.json
    config_symlink = ctx.actions.declare_file(path + "config.json")
    ctx.actions.run_shell(
        outputs = [config_symlink],
        inputs = [config],
        command = "ln {src} {dst}".format(
            src = config.path,
            dst = config_symlink.path,
        ),
    )

    return {
        "config": config_symlink,
        "layers": layer_files,
        "temp_files": [config_symlink] + layer_files,
    }