Skip to content

Commit a561dbe

Browse files
authored
dist: build openwrt packages (scionproto#4464)
The method is the following: * Add the prebuild openwrt SDKs for the desired target platform as an http_archive dependency. * Slap a BUILD.bazel file on top of the SDK so bazel can make it do two things: * Configure a bazel toolchain around the compiler suite embedded in the SDK (musl-gcc/musl-libc). * Make one openwrt package for each SCION component (the pieces are provided by the SCION main workspace). * Declare a platform for each supported openwrt target. * Bind each openwrt toolchain to its matching platform. * Add rules to produce ipk packages for scion components (they just reference and copy the packages produced by the openwrt workspace). * Use multiplatform_filegroup() to transition these packages to each supported openwrt platform. * Add a Make target, dist-openwrt, to build the openwrt file group. That results in the following chain of dependencies for one given component and the amd64 target: => Want openwrt => build openwrt_amd64 (among others, if any) => build "component.ipk for openwrt_amd64" => copy "component.ipk for openwrt_amd64" from @external/openwrtSDK_x86_64 => @external/openwrtSDK_x86_64 obtains "component exec for openwrt_amd64" from @scion, then embed in component.ipk package. => @scion builds component with the openwrt_amd64 toolchain Embellishments: * Optionally generate versioned file names for installables. That removes the need for renaming the files after the build. * Added coremark to our build (and as an openwrt package). The intent is to use it in benchmarking as a rough cpu power metric. * Executable compression when packaging for openwrt, as these devices can be storage constrained and Go executables are huge. Unfortunately there's not much I can do for the in-ram size yet. <!-- Reviewable:start --> - - - This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/scionproto/scion/4464) <!-- Reviewable:end -->
1 parent c5a8e6f commit a561dbe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+4677
-50
lines changed

.bazelrc

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ build --workspace_status_command=./tools/bazel-build-env
1414
build --java_runtime_version=remotejdk_11
1515
# disable legacy_create_init for py_binary, py_test etc. This may eventually become the default.
1616
build --incompatible_default_to_explicit_init_py
17+
# Enable resolution of cc toolchain by go toolchain
18+
build --incompatible_enable_cc_toolchain_resolution
19+
build --flag_alias=file_name_version=//:file_name_version
1720

1821
# include one of "--define gotags=sqlite_mattn" or "--define gotags=sqlite_modernc"
1922
# cannot be in common, because query chokes on it.

.buildkite/pipeline.yml

+18-13
Original file line numberDiff line numberDiff line change
@@ -23,27 +23,32 @@ steps:
2323
- exit_status: 255 # Forced agent shutdown
2424
timeout_in_minutes: 10
2525
- wait
26-
- label: "Package :debian:"
26+
- label: "Package :debian: :openwrt:"
2727
command:
28-
- make dist-deb
29-
- cd deb;
30-
- tar -chaf scion-deb-amd64.tar.gz *_amd64.deb
31-
- tar -chaf scion-deb-arm64.tar.gz *_arm64.deb
32-
- tar -chaf scion-deb-i386.tar.gz *_i386.deb
33-
- tar -chaf scion-deb-armel.tar.gz *_armel.deb
28+
- version="$(tools/git-version)"
29+
- make dist-deb BFLAGS="--file_name_version=${version}"
30+
- make dist-openwrt BFLAGS="--file_name_version=${version}"
31+
- cd installables;
32+
- tar -chaf scion-deb-amd64.tar.gz *_${version}_amd64.deb
33+
- tar -chaf scion-deb-arm64.tar.gz *_${version}_arm64.deb
34+
- tar -chaf scion-deb-i386.tar.gz *_${version}_i386.deb
35+
- tar -chaf scion-deb-armel.tar.gz *_${version}_armel.deb
36+
- tar -chaf scion-openwrt-x86_64.tar.gz *_${version}_x86_64.ipk
3437
artifact_paths:
35-
- "deb/*.tar.gz"
38+
- "installables/scion-*.tar.gz"
3639
plugins:
3740
- scionproto/metahook#v0.3.0:
3841
post-artifact: |
3942
cat << EOF | buildkite-agent annotate --style "info" --context "packages"
4043
#### Packages :debian:
41-
- <a href="artifact://deb/scion-deb-amd64.tar.gz">amd64</a>
42-
- <a href="artifact://deb/scion-deb-arm64.tar.gz">arm64</a>
43-
- <a href="artifact://deb/scion-deb-i386.tar.gz">i386</a>
44-
- <a href="artifact://deb/scion-deb-armel.tar.gz">armel</a>
44+
- <a href="artifact://installables/scion-deb-amd64.tar.gz">amd64</a>
45+
- <a href="artifact://installables/scion-deb-arm64.tar.gz">arm64</a>
46+
- <a href="artifact://installables/scion-deb-i386.tar.gz">i386</a>
47+
- <a href="artifact://installables/scion-deb-armel.tar.gz">armel</a>
48+
#### Packages :openwrt:
49+
- <a href="artifact://installables/scion-openwrt-x86_64.tar.gz">x86_64</a>
4550
EOF
46-
key: dist-deb
51+
key: dist
4752
retry: *automatic-retry
4853
- label: "Unit Tests :bazel:"
4954
command:

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ doc/venv/
6868

6969
# Generated package files
7070
##########################
71-
/deb/
71+
/installables/
7272

7373
# CTags
7474
##########################

BUILD.bazel

+12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
2+
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
23
load("@bazel_gazelle//:def.bzl", "gazelle")
34
load("@rules_pkg//:pkg.bzl", "pkg_tar")
45
load("@io_bazel_rules_go//go:def.bzl", "nogo")
@@ -156,6 +157,17 @@ flake8_lint_config(
156157
],
157158
)
158159

160+
# Optional version string to produce versioned file names. End deliverables, such as installable
161+
# packages will have a name derived from that string.
162+
# The flag is to be used when producing publishable assets (so, typically by the CI build).
163+
# The rest of the time the assets will have an unversioned name. The version tags embedded
164+
# in binaries and package manifests are always set. Regardless of this flag.
165+
string_flag(
166+
name = "file_name_version",
167+
build_setting_default = "dev",
168+
visibility = ["//visibility:public"],
169+
)
170+
159171
# Add a build flag to enable bundling the management API documentation with the
160172
# binaries. This can be enabled by passing --//:mgmtapi_bundle_doc=true when
161173
# invoking bazel

Makefile

+20-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: all build build-dev dist-deb antlr clean docker-images gazelle go.mod licenses mocks protobuf scion-topo test test-integration write_all_source_files
1+
.PHONY: all build build-dev dist-deb antlr clean docker-images gazelle go.mod licenses mocks protobuf scion-topo test test-integration write_all_source_files git-version
22

33
build-dev:
44
rm -f bin/*
@@ -11,20 +11,25 @@ build:
1111
bazel build //:scion
1212
tar -kxf bazel-bin/scion.tar -C bin
1313

14+
# BFLAGS is optional. It may contain additional command line flags for CI builds. Currently this is:
15+
# "--file_name_version=$(tools/git-version)" to include the git version in the artifacts names.
1416
dist-deb:
15-
bazel build //dist:deb_all
16-
mkdir -p deb; rm -f deb/*;
17-
@ # Bazel cannot include the version in the filename, if we want to set it automatically from the git tag.
18-
@ # Extract the version from the .deb "control" manifest and expand the "__" in the filename to "_<version>_".
19-
@ # See e.g. https://en.wikipedia.org/wiki/Deb_(file_format)#Control_archive
20-
@for f in `bazel cquery //dist:deb_all --output=files 2>/dev/null`; do \
21-
if [ -f "$$f" ]; then \
22-
bf=`basename $$f`; \
23-
v="$$(ar p $$f control.tar.gz | tar -xz --to-stdout ./control | sed -n 's/Version: //p')"; \
24-
bfv=$${bf%%__*}_$${v}_$${bf#*__}; \
25-
cp -v "$$f" deb/$$bfv; \
26-
fi \
27-
done
17+
bazel build //dist:deb_all $(BFLAGS)
18+
@ # These artefacts have unique names but varied locations. Link them somewhere convenient.
19+
@ mkdir -p installables
20+
@ cd installables ; ln -sfv ../bazel-out/*/bin/dist/*.deb .
21+
22+
dist-openwrt:
23+
bazel build //dist:openwrt_all $(BFLAGS)
24+
@ # These artefacts have unique names but varied locations. Link them somewhere convenient.
25+
@ mkdir -p installables
26+
@ cd installables ; ln -sfv ../bazel-out/*/bin/dist/*.ipk .
27+
28+
dist-openwrt-testing:
29+
bazel build //dist:openwrt_testing_all $(BFLAGS)
30+
@ # These artefacts have unique names but varied locations. Link them somewhere convenient.
31+
@ mkdir -p installables
32+
@ cd installables ; ln -sfv ../bazel-out/*/bin/dist/*.ipk .
2833

2934
# all: performs the code-generation steps and then builds; the generated code
3035
# is git controlled, and therefore this is only necessary when changing the
@@ -41,6 +46,7 @@ clean:
4146
scrub:
4247
bazel clean --expunge
4348
rm -f bin/*
49+
rm -f installables/*
4450

4551
test:
4652
bazel test --config=unit_all

WORKSPACE

+15
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,18 @@ npm_translate_lock(
299299
load("@npm//:repositories.bzl", "npm_repositories")
300300

301301
npm_repositories()
302+
303+
# Support cross building and packaging for openwrt_amd64 via the openwrt SDK
304+
http_archive(
305+
name = "openwrt_x86_64_SDK",
306+
build_file = "@//dist/openwrt:BUILD.external.bazel",
307+
patch_args = ["-p1"],
308+
patches = ["@//dist/openwrt:endian_h.patch"],
309+
sha256 = "df9cbce6054e6bd46fcf28e2ddd53c728ceef6cb27d1d7fc54a228f272c945b0",
310+
strip_prefix = "openwrt-sdk-23.05.2-x86-64_gcc-12.3.0_musl.Linux-x86_64",
311+
urls = ["https://downloads.openwrt.org/releases/23.05.2/targets/x86/64/openwrt-sdk-23.05.2-x86-64_gcc-12.3.0_musl.Linux-x86_64.tar.xz"],
312+
)
313+
314+
register_toolchains(
315+
"//dist/openwrt:x86_64_openwrt_toolchain",
316+
)

dist/BUILD.bazel

+102-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,42 @@
11
load(":package.bzl", "scion_pkg_deb")
2+
load(":package.bzl", "scion_pkg_ipk")
23
load(":platform.bzl", "multiplatform_filegroup")
34
load(":git_version.bzl", "git_version")
45

6+
DEB_PLATFORMS = [
7+
"@io_bazel_rules_go//go/toolchain:linux_amd64",
8+
"@io_bazel_rules_go//go/toolchain:linux_arm64",
9+
"@io_bazel_rules_go//go/toolchain:linux_386",
10+
"@io_bazel_rules_go//go/toolchain:linux_arm",
11+
]
12+
13+
14+
# For now only a single openwrt platform can be in this list. If we allow several, they get
15+
# built in parallel, which breaks on non-reentrant openwrt makefiles. For a single platform
16+
# things work because we force the packages to be build serialy by making them depend on
17+
# each other.
18+
OPENWRT_PLATFORMS = [
19+
"@//dist/openwrt:openwrt_amd64",
20+
]
21+
22+
# Some files that the openwrt build consumes directly.
23+
exports_files(
24+
[
25+
"conffiles/gateway.toml",
26+
"conffiles/gateway.json",
27+
"conffiles/daemon.toml",
28+
"conffiles/dispatcher.toml",
29+
30+
# Directory itself. Indicates the common root of config files.
31+
"conffiles",
32+
],
33+
visibility = ["//visibility:public"],
34+
)
35+
536
git_version(
637
name = "git_version",
738
tags = ["manual"],
8-
visibility = ["//visibility:private"],
39+
visibility = ["@openwrt_x86_64_SDK//:__subpackages__"],
940
)
1041

1142
scion_pkg_deb(
@@ -57,7 +88,7 @@ scion_pkg_deb(
5788

5889
scion_pkg_deb(
5990
name = "daemon_deb",
60-
configs = ["conffiles/sciond.toml"],
91+
configs = ["conffiles/daemon.toml"],
6192
depends = [
6293
"adduser",
6394
],
@@ -74,8 +105,8 @@ scion_pkg_deb(
74105
scion_pkg_deb(
75106
name = "gateway_deb",
76107
configs = [
77-
"conffiles/sig.json",
78-
"conffiles/sig.toml",
108+
"conffiles/gateway.json",
109+
"conffiles/gateway.toml",
79110
],
80111
depends = [
81112
"adduser",
@@ -117,5 +148,72 @@ multiplatform_filegroup(
117148
"router_deb",
118149
"tools_deb",
119150
],
151+
target_platforms = DEB_PLATFORMS,
152+
visibility = ["//dist:__subpackages__"],
153+
)
154+
155+
scion_pkg_ipk(
156+
name = "persistdbs_ipk",
157+
)
158+
159+
scion_pkg_ipk(
160+
name = "router_ipk",
161+
)
162+
163+
scion_pkg_ipk(
164+
name = "gateway_ipk",
165+
)
166+
167+
scion_pkg_ipk(
168+
name = "control_ipk",
169+
)
170+
171+
scion_pkg_ipk(
172+
name = "dispatcher_ipk",
173+
)
174+
175+
scion_pkg_ipk(
176+
name = "daemon_ipk",
177+
)
178+
179+
scion_pkg_ipk(
180+
name = "tools_ipk",
181+
)
182+
183+
scion_pkg_ipk(
184+
name = "coremark_ipk",
185+
)
186+
187+
scion_pkg_ipk(
188+
name = "testconfig_ipk",
189+
)
190+
191+
# multiplatform_filegroup creates two targets: <name> and <name>_all.
192+
# <name> means "local platform".
193+
# So "build //dist/openwrt" means "make me ipk packages for the local platform only. It wont work,
194+
# unles you happen to be building on an openwrt system (really?).
195+
# What you really want is "build //dist/openwrt_all".
196+
multiplatform_filegroup(
197+
name = "openwrt",
198+
srcs = [
199+
"control_ipk",
200+
"daemon_ipk",
201+
"dispatcher_ipk",
202+
"gateway_ipk",
203+
"persistdbs_ipk",
204+
"router_ipk",
205+
"tools_ipk",
206+
],
207+
target_platforms = OPENWRT_PLATFORMS,
208+
visibility = ["//dist:__subpackages__"],
209+
)
210+
211+
multiplatform_filegroup(
212+
name = "openwrt_testing",
213+
srcs = [
214+
"coremark_ipk",
215+
"testconfig_ipk",
216+
],
217+
target_platforms = OPENWRT_PLATFORMS,
120218
visibility = ["//dist:__subpackages__"],
121219
)
File renamed without changes.
File renamed without changes.

dist/conffiles/sig.toml renamed to dist/conffiles/gateway.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[gateway]
2-
traffic_policy_file = "/etc/scion/sig.json"
2+
traffic_policy_file = "/etc/scion/gateway.json"
33

44
[tunnel]
55
name = "sig"

dist/git_version.bzl

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ def _git_version_impl(ctx):
22
ctx.actions.run_shell(
33
outputs = [ctx.outputs.outfile],
44
inputs = [ctx.info_file],
5-
command = r"sed -n 's/STABLE_GIT_VERSION\s*v\?//p' " + ctx.info_file.path + " > " + ctx.outputs.outfile.path,
5+
command = r"sed -n 's/STABLE_GIT_VERSION\s*//p' " + ctx.info_file.path + " > " + ctx.outputs.outfile.path,
66
)
77

88
git_version = rule(
99
doc = """
1010
Extracts the STABLE_GIT_VERSION from the workspace_status_command output.
1111
See also .bazelrc and tools/bazel-build-env.
1212
13-
The output of this rule is a file containing the version only.
14-
The leading "v" from the git tag is removed.
13+
The output of this rule is a file containing the version only. The leading "v" from the git tag
14+
is removed by tools/git-version so workspace_status_command never even sees it.
1515
""",
1616
implementation = _git_version_impl,
1717
outputs = {

dist/openwrt/BUILD.bazel

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# This BUILD file only takes care of hooking the assets derived
2+
# from the openwrt SDK into the SCION bazel build.
3+
#
4+
# These assets are:
5+
# * a cross-compilation toolchain that targets openwrt_<arch> (i.e. links with musl-libc).
6+
# * openwrt (ipk) packaging of scion binaries built with the above.
7+
#
8+
# Turning these assets into bazel reeferencable dependencies happens in the context of the external
9+
# src tree openwrt_<target>_SDK, which receives its own buildfile (BUILD.external.bazel, installed there by
10+
# the http_archive target "openwrt_<target>_SDK" in //WORKSPACE).
11+
12+
# Some files that our openwrt build needs.
13+
exports_files(
14+
[
15+
# Gear to drive the make-based openwrt package build process.
16+
"BUILD.external.bazel",
17+
"endian_h.patch",
18+
"package_makefile.tpl",
19+
20+
# init.d start/stop files.
21+
"initds/router",
22+
"initds/gateway",
23+
"initds/control",
24+
"initds/daemon",
25+
"initds/dispatcher",
26+
"initds/persistdbs",
27+
28+
# Directory itself. Indicates the common root of config files.
29+
"test_configs",
30+
31+
# Minimal configuration for testing.
32+
"test_configs/topology.json",
33+
"test_configs/keys/master0.key",
34+
"test_configs/keys/master1.key",
35+
"test_configs/router.toml",
36+
"test_configs/control.toml",
37+
],
38+
visibility = ["//visibility:public"],
39+
)
40+
41+
# Plumb the musl toolchain of the openwrt SDK as a toolchain we can use here to build SCION
42+
# components.
43+
constraint_value(
44+
name = "musl_libc",
45+
constraint_setting = "@bazel_tools//tools/cpp:cc_compiler",
46+
visibility = ["//visibility:public"],
47+
)
48+
49+
toolchain(
50+
name = "x86_64_openwrt_toolchain",
51+
exec_compatible_with = [
52+
"@platforms//cpu:x86_64",
53+
"@platforms//os:linux",
54+
],
55+
target_compatible_with = [
56+
"@platforms//cpu:x86_64",
57+
"@platforms//os:linux",
58+
":musl_libc",
59+
],
60+
toolchain = "@openwrt_x86_64_SDK//:x86_64_musl",
61+
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
62+
)
63+
64+
platform(
65+
name = "openwrt_amd64",
66+
constraint_values = [
67+
"@platforms//cpu:x86_64",
68+
"@platforms//os:linux",
69+
":musl_libc",
70+
],
71+
visibility = ["//dist:__subpackages__"],
72+
)

0 commit comments

Comments
 (0)