Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Oci py interpreter #245

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions oci_python_image/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,20 @@ register_toolchains(
oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")

oci.pull(
name = "distroless_python",
name = "docker_python",
digest = "sha256:b48e216f7c4adcf24fecd7016f3b8ead76866a19571819f67f47c1ccaf899717",
# Shorthand for https://hub.docker.com/_/python
image = "python",
)

use_repo(oci, "distroless_python")
oci.pull(
name = "distroless_base",
digest = "sha256:ccaef5ee2f1850270d453fdf700a5392534f8d1a8ca2acda391fbb6a06b81c86",
image = "gcr.io/distroless/base",
platforms = [
"linux/amd64",
"linux/arm64",
],
)

use_repo(oci, "distroless_base", "docker_python")
9 changes: 9 additions & 0 deletions oci_python_image/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Example of Python plus rules_oci

There are a couple ways to treat the interpreter:

1. Choose a base image which includes it. This is the typical approach outside Bazel, and is
recommended when migrating from a Dockerfile or similar build system to avoid changing
multiple things at the same time. In `/MODULE.bazel` we use `oci.pull` to pull https://hub.docker.com/_/python and then in `use_python_base/BUILD.bazel` we choose that as the base image. Then, the Bazel-built Python application just falls through to the "system interpreter".
2. Propagate Bazel's "toolchain resolution" so that the same interpreter used by `bazel run`
will also be used when the Python application runs in a container. This avoids version skew in the Python version used. In `/MODULE.bazel` we use `oci.pull` to pull the Distroless base image (which is tiny). Then the `interpreter_as_layer/BUILD.bazel` file shows how we get that interpreter as a layer in the image.
35 changes: 35 additions & 0 deletions oci_python_image/interpreter_as_layer/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
load(":current_py_toolchain.bzl", "current_py_toolchain")
load("@rules_oci//oci:defs.bzl", "oci_image")
load("@rules_pkg//pkg:pkg.bzl", "pkg_tar")

current_py_toolchain(
name = "current_py_toolchain_runfiles",
)

pkg_tar(
name = "py_interpreter_toolchain",
# If we just used @rules_python//python:current_py_toolchain then we would end up with platform
# specific paths here. The current_py_toolchain_runfiles remaps the paths to be platform independent
srcs = [":current_py_toolchain_runfiles"],
extension = "tar.gz",
package_dir = "/opt/python",
strip_prefix = ".",
)

pkg_tar(
name = "python_aliases",
symlinks = {
"/usr/bin/python": "/usr/bin/fake_python",
"/usr/bin/python3": "/usr/bin/fake_python",
},
)

oci_image(
name = "py_base",
base = "@distroless_base",
tars = [
":python_aliases",
":py_interpreter_toolchain",
],
visibility = ["//visibility:public"],
)
35 changes: 35 additions & 0 deletions oci_python_image/interpreter_as_layer/current_py_toolchain.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
load("@rules_pkg//:providers.bzl", "PackageFilegroupInfo", "PackageFilesInfo")

def _strip_platform_specific(path):
parts = path.split("/")
return "/".join(parts[2:])

def _current_py_toolchain_impl(ctx):
default = ctx.toolchains["@rules_python//python:toolchain_type"].py3_runtime
file_map = {}

files = depset(transitive = [default.files])

for file in files.to_list():
file_map[_strip_platform_specific(file.path)] = file

files = depset([], transitive = [files])

return [
PackageFilegroupInfo(
pkg_dirs = [],
pkg_files = [
[PackageFilesInfo(
dest_src_map = file_map,
attributes = {},
), ctx.label],
],
),
DefaultInfo(files = files),
]

current_py_toolchain = rule(
implementation = _current_py_toolchain_impl,
attrs = {},
toolchains = ["@rules_python//python:toolchain_type"],
)
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ py_image_layer(

oci_image(
name = "image",
base = "@distroless_python",
base = "@docker_python",
entrypoint = ["/opt/hello_world/hello_world_bin"],
tars = [":hello_world_layer"],
)
Expand Down
Loading