Skip to content

Commit

Permalink
checkpoint structure tests passing
Browse files Browse the repository at this point in the history
  • Loading branch information
pcj committed Mar 1, 2024
1 parent 736777b commit fd5f8df
Show file tree
Hide file tree
Showing 21 changed files with 392 additions and 307 deletions.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,43 @@ You can use the rules directly from this repo, or simply as examples and
copy/paste them into your own project.


Given a pycross_oci_image rule `//my:image` wrapping a py_binary rule `//my:app`, the following targets are defined:

| Kind | Label | Description |
|---------------------------------|------------------------------|----------------------------------------------------------|
| oci_image rule | //my:image | The target container image |
| oci_tarball rule | //my:image.tar | Tarball rule that can be `bazel run` to `docker load` it |
| tar rule | //my:image.app_layer | Image layer for the application code |
| tar rule | //my:image.packages_layer | Image layer for site-packages |
| tar rule | //my:image.interpreter_layer | Image layer for the python3 interpreter |
| platform_transition_binary rule | //my:xapp | The transitioned "cross" py_binary |
| py_binary rule | //my:app | The source py_binary app |

`docker inspect` yields the following (subset):

```json
[
{
"RepoTags": [
"my/app:latest",
],
"Config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt",
"LANG=C.UTF-8"
],
"Cmd": [
"app"
],
"WorkingDir": "/my/xapp",
"Entrypoint": [
"/my/xapp/app.runfiles/python_x86_64-unknown-linux-gnu/bin/python3"
],
},
"Architecture": "amd64",
"Os": "linux"
}
]
```

6 changes: 4 additions & 2 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ step1.setup_rules_oci()

step1.setup_rules_docker()

step1.setup_container_structure_test()

# -----------------------------------------

load("@pycross_image//bazel/workspace:step2.bzl", "step2")

step2.setup_oci_containers()
step2.setup_pycross_image_base_oci()

step2.setup_docker_containers()
step2.setup_pycross_image_base_container()

step2.setup_rules_pycross()

Expand Down
2 changes: 1 addition & 1 deletion bazel/rules/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ example_test_filegroup(
"BUILD.bazel",
"docker.bzl",
"oci.bzl",
"py_layers.bzl",
"support.bzl",
],
)
109 changes: 26 additions & 83 deletions bazel/rules/docker.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,107 +4,50 @@ Wrapper macro to make three separate layers for python applications
based on: https://github.com/aspect-build/bazel-examples/blob/a25b6c0ba307545aff6c4b5feb4ae875d7d507f1/oci_python_image/py_layer.bzl
"""

load("@aspect_bazel_lib//lib:transitions.bzl", "platform_transition_binary")
load(":py_layers.bzl", "py_layers")
load(":support.bzl", "defaults", "py_layers", "pycross_binary")
load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_layer")

def _make_entrypoint(toolchain_config_setting_label, workdir, cmd):
label = Label(toolchain_config_setting_label)
return "{workdir}/{cmd}.runfiles/{python_toolchains_workspace_name}_{python_toolchains_config_setting}/bin/python3".format(
workdir = workdir,
cmd = cmd,
python_toolchains_workspace_name = label.workspace_name,
python_toolchains_config_setting = label.name,
)

def py_image(
name,
binary,
base = "@distroless_python3_debian12_container//image",
config = "@python//:x86_64-unknown-linux-gnu",
target_platform = "@pycross_image//bazel/platforms:linux_x86_64",
base = "@pycross_image_base_container//image",
layers = [],
**kwargs):
"""
pycross_oci_image is a macro that instantiates an oci_image from a py_binary rule
Given a pycross_oci_image rule `//my:image` wrapping a py_binary rule `//my:app`, the following targets are defined:
| Kind | Label | Description |
|---------------------------------|------------------------------|----------------------------------------------------------|
| oci_image rule | //my:image | The target container image |
| oci_tarball rule | //my:image.tar | Tarball rule that can be `bazel run` to `docker load` it |
| tar rule | //my:image.app_layer | Image layer for the application code |
| tar rule | //my:image.packages_layer | Image layer for site-packages |
| tar rule | //my:image.interpreter_layer | Image layer for the python3 interpreter |
| platform_transition_binary rule | //my:xapp | The transitioned "cross" py_binary |
| py_binary rule | //my:app | The source py_binary app |
`docker inspect` yields the following (subset):
```json
[
{
"RepoTags": [
"my/app:latest",
],
"Config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt",
"LANG=C.UTF-8"
],
"Cmd": [
"app"
],
"WorkingDir": "/my/xapp",
"Entrypoint": [
"/my/xapp/app.runfiles/python_x86_64-unknown-linux-gnu/bin/python3"
],
},
"Architecture": "amd64",
"Os": "linux"
}
]
```
py_image is a macro that instantiates an container_image from a py_binary rule
Args:
name: (String) name for the oci_image rule
binary: (Label) target label of the py_binary rule
base: (Label) target label of the base image
tars: (Label List) optional additional tars for the image
config: (Label) target label for the python toolchains repo config setting that determines the python entrypoint name
target_platform: (Label) target label for the image platform (for the platform_transition_binary rule)
**kwargs: (Dict) additional argument for the oci_image rule
name: name for the image rule
binary: target label of the py_binary rule
base: target label of the base image
layers: additional container_layer targets
**kwargs: additional arguments for the pycross_binary and container_image rules
"""

target = Label(binary)
cmd = target.name
cross_binary = cmd + "_cross_binary"
repo_tag = "%s/%s:latest" % (target.package, target.name)

workdir = "/%s/%s/%s" % (target.package, target.name, cross_binary)
entrypoint = _make_entrypoint(config, workdir, cmd)

layer_tars = py_layers(name, cross_binary)

platform_transition_binary(
name = cross_binary,
binary = binary,
target_platform = target_platform,
metadata = pycross_binary(
binary,
cross_name_prefix = kwargs.pop("cross_name_prefix", defaults.cross_name_prefix),
python_config_setting = kwargs.pop("python_config_setting", defaults.python_config_setting),
target_platform = kwargs.pop("target_platform", defaults.target_platform),
image_tag = kwargs.pop("tag", defaults.cross_name_prefix),
repo_tag = kwargs.pop("repo_tag", None),
)

for tar in layer_tars:
tars = py_layers(name, metadata.cross_binary_name)

for tar in tars:
container_layer(
name = tar + "_layer",
tars = [tar],
)

container_image(
name = name + "_container",
name = name,
base = base,
layers = [tar + "_layer" for tar in layer_tars],
workdir = workdir,
entrypoint = [entrypoint],
tags = [repo_tag],
cmd = [cmd],
layers = layers + [tar + "_layer" for tar in tars],
entrypoint = metadata.entrypoint,
cmd = metadata.cmd,
workdir = metadata.workdir,
tags = [metadata.repo_tag],
**kwargs
)
115 changes: 24 additions & 91 deletions bazel/rules/oci.bzl
Original file line number Diff line number Diff line change
@@ -1,112 +1,45 @@
"""
Wrapper macro to make three separate layers for python applications
based on: https://github.com/aspect-build/bazel-examples/blob/a25b6c0ba307545aff6c4b5feb4ae875d7d507f1/oci_python_image/py_layer.bzl
"""

load("@aspect_bazel_lib//lib:transitions.bzl", "platform_transition_binary")
load(":support.bzl", "defaults", "py_layers", "pycross_binary")
load("@rules_oci//oci:defs.bzl", "oci_image", "oci_tarball")
load(":py_layers.bzl", "py_layers")

def _make_entrypoint(toolchain_config_setting_label, workdir, cmd):
label = Label(toolchain_config_setting_label)
return "{workdir}/{cmd}.runfiles/{python_toolchains_workspace_name}_{python_toolchains_config_setting}/bin/python3".format(
workdir = workdir,
cmd = cmd,
python_toolchains_workspace_name = label.workspace_name,
python_toolchains_config_setting = label.name,
)

def py_image(
name,
binary,
base = "@distroless_python3_debian12_oci",
tars = [],
config = "@python//:x86_64-unknown-linux-gnu",
target_platform = "@pycross_image//bazel/platforms:linux_x86_64",
base = "@pycross_image_base_oci",
layers = [],
**kwargs):
"""
pycross_oci_image is a macro that instantiates an oci_image from a py_binary rule
Given a pycross_oci_image rule `//my:image` wrapping a py_binary rule `//my:app`, the following targets are defined:
| Kind | Label | Description |
|---------------------------------|------------------------------|----------------------------------------------------------|
| oci_image rule | //my:image | The target container image |
| oci_tarball rule | //my:image.tar | Tarball rule that can be `bazel run` to `docker load` it |
| tar rule | //my:image.app_layer | Image layer for the application code |
| tar rule | //my:image.packages_layer | Image layer for site-packages |
| tar rule | //my:image.interpreter_layer | Image layer for the python3 interpreter |
| platform_transition_binary rule | //my:xapp | The transitioned "cross" py_binary |
| py_binary rule | //my:app | The source py_binary app |
`docker inspect` yields the following (subset):
```json
[
{
"RepoTags": [
"my/app:latest",
],
"Config": {
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt",
"LANG=C.UTF-8"
],
"Cmd": [
"app"
],
"WorkingDir": "/my/xapp",
"Entrypoint": [
"/my/xapp/app.runfiles/python_x86_64-unknown-linux-gnu/bin/python3"
],
},
"Architecture": "amd64",
"Os": "linux"
}
]
```
py_image is a macro that instantiates an oci_image from a py_binary rule
Args:
name: (String) name for the oci_image rule
binary: (Label) target label of the py_binary rule
base: (Label) target label of the base image
tars: (Label List) optional additional tars for the image
config: (Label) target label for the python toolchains repo config setting that determines the python entrypoint name
target_platform: (Label) target label for the image platform (for the platform_transition_binary rule)
**kwargs: (Dict) additional argument for the oci_image rule
name: name for the image rule
binary: target label of the py_binary rule
base: target label of the base image
layers: additional layer tarballs
**kwargs: additional arguments for the pycross_binary and oci_image rules
"""

name_tar = name + ".tar"
target = Label(binary)
cmd = target.name
cross_binary = cmd + "_cross_binary"
repo_tag = "%s/%s:latest" % (target.package, target.name)

workdir = "/%s/%s/%s" % (target.package, target.name, cross_binary)
entrypoint = _make_entrypoint(config, workdir, cmd)

layer_tars = py_layers(name, cross_binary)

platform_transition_binary(
name = cross_binary,
binary = binary,
target_platform = target_platform,
metadata = pycross_binary(
binary,
cross_name_prefix = kwargs.pop("cross_name_prefix", "y"),
python_config_setting = kwargs.pop("python_config_setting", defaults.python_config_setting),
target_platform = kwargs.pop("target_platform", defaults.target_platform),
image_tag = kwargs.pop("tag", defaults.cross_name_prefix),
repo_tag = kwargs.pop("repo_tag", None),
)

tars = py_layers(name, metadata.cross_binary_name)

oci_image(
name = name,
tars = tars + layer_tars,
workdir = workdir,
entrypoint = [entrypoint],
cmd = [cmd],
base = base,
tars = layers + tars,
workdir = metadata.workdir,
entrypoint = metadata.entrypoint,
cmd = metadata.cmd,
**kwargs
)

oci_tarball(
name = name_tar,
name = name + ".tar",
image = name,
repo_tags = [repo_tag],
repo_tags = [metadata.repo_tag],
)
Loading

0 comments on commit fd5f8df

Please sign in to comment.