Skip to content
Open
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
17 changes: 17 additions & 0 deletions examples/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ bazel_dep(name = "rules_python", version = "0.38.0")
bazel_dep(name = "boost.any", version = "1.83.0")
bazel_dep(name = "boost.smart_ptr", version = "1.83.0.bcr.1")
bazel_dep(name = "boost.thread", version = "1.83.0")
bazel_dep(name = "rules_oci", version = "2.0.1")
bazel_dep(name = "rules_pkg", version = "1.0.1")

# This import is relevant for these examples and this (rules_ros) repository.
bazel_dep(name = "rules_ros")
Expand Down Expand Up @@ -44,3 +46,18 @@ use_repo(
"urdfdom",
"urdfdom_headers",
)

# in order to build an oci image with our ros nodes in it, one
# needs to define the base image to use, and that must be performed
# at the module level here.
# NOTE: Even though the version of python that the nodes run in is contained
# in the runfiles, a version of python is required at the system level in order
# to run the roslaunch command.
oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")
oci.pull(
name = "rules_ros_base_image",
image = "python:3.10-bookworm",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this is an overkill, as we need system python (-like app) to bootstrap the Bazel-managed Python. You could fetch https://raw.githubusercontent.com/buildbarn/bb-remote-execution/96c4fdce659fabfaba7ee2a60fd4e2ffab8352e2/cmd/fake_python/main.go with http_file, compile it using rules_go and inject it into the output image as e.g. /usr/bin/python3 (using ubuntu:22.04 image in this case should be sufficient).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps overkill.... but needing to replicate your suggestion in each and every repo feels way to repetitive. Could we bake this into rules_ros or better yet, rules_python?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use ubuntu:22.04 as base image?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think ubuntu:22.04 includes a python.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really? I thought it comes with 3.10

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not appear that the image does.

oci = use_extension("@rules_oci//oci:extensions.bzl", "oci")
oci.pull(
    name = "rules_ros_base_image",
    image = "ubuntu:22.04",
    platforms = ["linux/amd64"],
)
use_repo(oci, "rules_ros_base_image", "rules_ros_base_image_linux_amd64")
$ docker run -ti --rm chatter:latest
/usr/bin/env: 'python3': No such file or directory

digest = "sha256:fd0fa50d997eb56ce560c6e5ca6a1f5cf8fdff87572a16ac07fb1f5ca01eb608",
platforms = ["linux/amd64"],
)
use_repo(oci, "rules_ros_base_image", "rules_ros_base_image_linux_amd64")
40 changes: 40 additions & 0 deletions examples/chatter/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ load("@rules_ros//ros:launch.bzl", "ros_launch")
load("@rules_ros//ros:test.bzl", "ros_test")
load("@rules_ros//ros:topic.bzl", "ros_topic")
load("@rules_ros//third_party:expand_template.bzl", "expand_template")
load(
"@rules_oci//oci:defs.bzl",
"oci_image",
"oci_load"
)
load("@rules_pkg//pkg:pkg.bzl", "pkg_tar")

# Handling of ROS messages & services resembles to some extent Bazel's rules for
# handling protobuf messages (e.g. proto_library and cc_proto_library).
Expand Down Expand Up @@ -127,3 +133,37 @@ ros_topic(
name = "rostopic",
deps = [":chatter"],
)


# packages up the nodes, launch file, and all the other required runfiles.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rules_oci have a good example for to structure python apps, see https://github.com/aspect-build/bazel-examples/tree/main/oci_python_image, py_layer.bzl file in particular. Maybe not for this PR, but it's a nice optimization.

# Note the symlink is required in order to place the files where ros_launch is
# expecting them to be.
pkg_tar(
name = "chatter_tar",
srcs = [
":chatter",
],
include_runfiles = True,
package_dir = "chatter",
symlinks = {
"/chatter/chatter.runfiles/_main/external": "/chatter/chatter.runfiles",
}
Comment on lines +148 to +150
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you specify the workdir down below, you shoudn't need this symlink. Please double-check.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without the symlink, an error occurs:

RLException: Invalid roslaunch XML syntax: [Errno 2] No such file or directory: 'external/rules_ros~/third_party/ros/roslaunch/roscore.xml'
The traceback for the exception was written to the log file

Something is expecting all the runfiles to be in an 'external' directory below the working directory.

)

# builds the oci image on top of the @rules_ros_base_image defined at the MODULE level.
oci_image(
name = "chatter_oci_image",
base = "@rules_ros_base_image",
tars = [":chatter_tar"],
workdir = "/chatter/chatter.runfiles/_main",
entrypoint = ["/chatter/chatter"],
)

# loads the oci image into the docker daemon.
# Example usage: `bazel run //chatter:chatter_oci_load`
# Then to run the container: `docker run -it --rm chatter:latest`
oci_load(
name = "chatter_oci_load",
image = ":chatter_oci_image",
repo_tags = ["chatter:latest"],
)