From 26da583da77f1f5785e80799da438a1bfd3d17e5 Mon Sep 17 00:00:00 2001 From: Dan Fuhry Date: Mon, 19 Oct 2026 16:32:25 -0400 Subject: [PATCH] [pkg] multiarch support! --- bazel/pkg.bzl | 40 ++++++++++++++++++++++++----- cmd/apcups_exporter/BUILD.bazel | 2 +- cmd/ephs_client/BUILD.bazel | 8 ++++++ cmd/http_proxy/BUILD.bazel | 10 +++++++- cmd/metricbus_server/BUILD.bazel | 8 ++++++ cmd/mtls_exporter/BUILD.bazel | 8 ++++++ cmd/mtls_supervisor/BUILD.bazel | 8 ++++++ cmd/sd_health_exporter/BUILD.bazel | 8 ++++++ cmd/sd_publish/BUILD.bazel | 8 ++++++ cmd/sd_register/BUILD.bazel | 8 ++++++ cmd/sd_watcher/BUILD.bazel | 8 ++++++ pkg/BUILD.bazel | 33 ++++++++++++++++-------- pkg/apcupsd-exporter.yaml | 2 -- pkg/coredns.yaml | 2 -- pkg/http-proxy.yaml | 2 -- pkg/ldap-health-exporter.yaml | 2 -- pkg/nfpmgen/config_generator.go | 41 ++++++++++++++++++++++++------ pkg/nfpmgen/main.go | 9 ++++++- pkg/prometheus-helpers.yaml | 2 -- pkg/runtime-utils.yaml | 2 -- 20 files changed, 171 insertions(+), 40 deletions(-) diff --git a/bazel/pkg.bzl b/bazel/pkg.bzl index db25097..eda0121 100644 --- a/bazel/pkg.bzl +++ b/bazel/pkg.bzl @@ -1,8 +1,13 @@ +load("@bazel_skylib//lib:paths.bzl", "paths") + def _nfpm_package( package_name, config, + exes, data, packager, + os, + arch, ): extension_map = { "archlinux": "pkg.tar.zst", @@ -18,9 +23,24 @@ def _nfpm_package( "ENV_DIR": "/etc/default", }, } - pkg_prefix = "{}_{}".format(package_name.replace("-", "_"), packager) extra_args = [] - for target in data: + _exes = [] + exe_suffix = "" + if os != "linux" or arch != "amd64": + exe_suffix = "_{}_{}".format(os, arch) + extra_args.append("--platform={}".format(os)) + extra_args.append("--arch={}".format(arch)) + + for exe in exes: + if ":" not in exe: + exe += ":" + paths.basename(exe) + exe += exe_suffix + _exes.append(exe) + + pkg_prefix = "{}_{}".format(package_name.replace("-", "_"), packager) + if arch != "amd64": + pkg_prefix += "_{}".format(arch) + for target in data + _exes: extra_args.append('--include="$(location {})"'.format(target)) for var, val in distro_vars.get(packager, {}).items(): @@ -31,7 +51,7 @@ def _nfpm_package( tools = [ "//pkg/nfpmgen", ], - srcs = [config] + data, + srcs = [config] + data + _exes, outs = [ "{}_nfpm_config.yaml".format(pkg_prefix), ], @@ -47,9 +67,9 @@ def _nfpm_package( ], srcs = [ ":{}_nfpm_config".format(pkg_prefix), - ] + data, + ] + data + _exes, outs = [ - "{}.{}".format(package_name, extension_map.get(packager, packager)), + "{}_{}.{}".format(package_name, arch, extension_map.get(packager, packager)), ], cmd = " ".join([ "$(location @com_github_goreleaser_nfpm_v2//cmd/nfpm:nfpm)", @@ -63,8 +83,14 @@ def _nfpm_package( def nfpm_package( name, # type: str config, # type: str - data, # type: list[str] + exes = [], # type: list[str] + data = [], # type: list[str] + linux_arm64 = False, # type: bool ): #for packager in ["deb", "archlinux", "rpm"]: for packager in ["archlinux", "apk", "deb"]: - _nfpm_package(name, config, data, packager) \ No newline at end of file + _nfpm_package(name, config, exes, data, packager, "linux", "amd64") + + if linux_arm64: + _nfpm_package(name, config, exes, data, packager, "linux", "arm64") + _nfpm_package(name, config, exes, data, packager, "linux", "arm") \ No newline at end of file diff --git a/cmd/apcups_exporter/BUILD.bazel b/cmd/apcups_exporter/BUILD.bazel index 2f829ec..1f99536 100644 --- a/cmd/apcups_exporter/BUILD.bazel +++ b/cmd/apcups_exporter/BUILD.bazel @@ -38,7 +38,7 @@ systemd_service( "$APCUPSD_EXPORTER_ARGS", ], description = "apcupsd-exporter polls apcupsd for UPS %i and exports metrics via metric-collector", - environment_file = "$${const:ExePrefix}apcupsd-exporter@%i", + environment_file = "${const:ExePrefix}apcupsd-exporter@%i", exe = "apcups_exporter", group = "daemon", type = "notify", diff --git a/cmd/ephs_client/BUILD.bazel b/cmd/ephs_client/BUILD.bazel index 5933180..e6f9aa1 100644 --- a/cmd/ephs_client/BUILD.bazel +++ b/cmd/ephs_client/BUILD.bazel @@ -1,5 +1,8 @@ +load("//bazel:cross.bzl", "go_cross_binaries") load("//bazel:go.bzl", "go_multi_binary", "go_multi_library") +package(default_visibility = ["//visibility:public"]) + go_multi_library( name = "ephs_client_lib", srcs = ["main.go"], @@ -22,3 +25,8 @@ go_multi_binary( embed = [":ephs_client_lib"], visibility = ["//visibility:public"], ) + +go_cross_binaries( + base_target = "ephs_client", + linux_arm = True, +) diff --git a/cmd/http_proxy/BUILD.bazel b/cmd/http_proxy/BUILD.bazel index e289341..f99db51 100644 --- a/cmd/http_proxy/BUILD.bazel +++ b/cmd/http_proxy/BUILD.bazel @@ -1,6 +1,10 @@ +load("//bazel:cross.bzl", "go_cross_binaries") load("//bazel:go.bzl", "go_multi_binary", "go_multi_library") load("//bazel:svc.bzl", "systemd_service") + +package(default_visibility = ["//visibility:public"]) + go_multi_library( name = "http_proxy_lib", srcs = ["main.go"], @@ -20,7 +24,11 @@ go_multi_library( go_multi_binary( name = "http_proxy", embed = [":http_proxy_lib"], - visibility = ["//visibility:public"], +) + +go_cross_binaries( + base_target = "http_proxy", + linux_arm = True, ) systemd_service( diff --git a/cmd/metricbus_server/BUILD.bazel b/cmd/metricbus_server/BUILD.bazel index 959b9b0..2009fe6 100644 --- a/cmd/metricbus_server/BUILD.bazel +++ b/cmd/metricbus_server/BUILD.bazel @@ -1,6 +1,9 @@ +load("//bazel:cross.bzl", "go_cross_binaries") load("//bazel:go.bzl", "go_multi_binary", "go_multi_library") load("//bazel:svc.bzl", "systemd_dbus_service") +package(default_visibility = ["//visibility:public"]) + go_multi_library( name = "metricbus_server_lib", srcs = ["main.go"], @@ -19,6 +22,11 @@ go_multi_binary( visibility = ["//visibility:public"], ) +go_cross_binaries( + base_target = "metricbus_server", + linux_arm = True, +) + systemd_dbus_service( name = "metric-collector", args = [ diff --git a/cmd/mtls_exporter/BUILD.bazel b/cmd/mtls_exporter/BUILD.bazel index a68278f..8d7fa5a 100644 --- a/cmd/mtls_exporter/BUILD.bazel +++ b/cmd/mtls_exporter/BUILD.bazel @@ -1,6 +1,9 @@ +load("//bazel:cross.bzl", "go_cross_binaries") load("//bazel:go.bzl", "go_multi_binary", "go_multi_library") load("//bazel:svc.bzl", "systemd_service") +package(default_visibility = ["//visibility:public"]) + go_multi_library( name = "mtls_exporter_lib", srcs = ["main.go"], @@ -19,6 +22,11 @@ go_multi_binary( visibility = ["//visibility:public"], ) +go_cross_binaries( + base_target = "mtls_exporter", + linux_arm = True, +) + systemd_service( name = "mtls-exporter", args = [ diff --git a/cmd/mtls_supervisor/BUILD.bazel b/cmd/mtls_supervisor/BUILD.bazel index 419b4e6..e209e91 100644 --- a/cmd/mtls_supervisor/BUILD.bazel +++ b/cmd/mtls_supervisor/BUILD.bazel @@ -1,5 +1,8 @@ +load("//bazel:cross.bzl", "go_cross_binaries") load("//bazel:go.bzl", "go_multi_binary", "go_multi_library") +package(default_visibility = ["//visibility:public"]) + go_multi_library( name = "mtls_supervisor_lib", srcs = [ @@ -23,3 +26,8 @@ go_multi_binary( embed = [":mtls_supervisor_lib"], visibility = ["//visibility:public"], ) + +go_cross_binaries( + base_target = "mtls_supervisor", + linux_arm = True, +) \ No newline at end of file diff --git a/cmd/sd_health_exporter/BUILD.bazel b/cmd/sd_health_exporter/BUILD.bazel index 6fdcdad..36852b7 100644 --- a/cmd/sd_health_exporter/BUILD.bazel +++ b/cmd/sd_health_exporter/BUILD.bazel @@ -1,6 +1,9 @@ +load("//bazel:cross.bzl", "go_cross_binaries") load("//bazel:go.bzl", "go_multi_binary", "go_multi_library") load("//bazel:svc.bzl", "systemd_service") +package(default_visibility = ["//visibility:public"]) + go_multi_library( name = "sd_health_exporter_lib", srcs = ["main.go"], @@ -20,6 +23,11 @@ go_multi_binary( visibility = ["//visibility:public"], ) +go_cross_binaries( + base_target = "sd_health_exporter", + linux_arm = True, +) + systemd_service( name = "sd-health-exporter", args = [ diff --git a/cmd/sd_publish/BUILD.bazel b/cmd/sd_publish/BUILD.bazel index 31cbb73..c94c46d 100644 --- a/cmd/sd_publish/BUILD.bazel +++ b/cmd/sd_publish/BUILD.bazel @@ -1,5 +1,8 @@ +load("//bazel:cross.bzl", "go_cross_binaries") load("//bazel:go.bzl", "go_multi_binary", "go_multi_library") +package(default_visibility = ["//visibility:public"]) + go_multi_library( name = "sd_publish_lib", srcs = ["main.go"], @@ -18,3 +21,8 @@ go_multi_binary( embed = [":sd_publish_lib"], visibility = ["//visibility:public"], ) + +go_cross_binaries( + base_target = "sd_publish", + linux_arm = True, +) diff --git a/cmd/sd_register/BUILD.bazel b/cmd/sd_register/BUILD.bazel index 16f7c81..2126504 100644 --- a/cmd/sd_register/BUILD.bazel +++ b/cmd/sd_register/BUILD.bazel @@ -1,6 +1,9 @@ +load("//bazel:cross.bzl", "go_cross_binaries") load("//bazel:go.bzl", "go_multi_binary", "go_multi_library") load("//bazel:svc.bzl", "systemd_service") +package(default_visibility = ["//visibility:public"]) + go_multi_library( name = "sd_register_lib", srcs = ["main.go"], @@ -21,6 +24,11 @@ go_multi_binary( visibility = ["//visibility:public"], ) +go_cross_binaries( + base_target = "sd_register", + linux_arm = True, +) + systemd_service( name = "sd-register", args = [ diff --git a/cmd/sd_watcher/BUILD.bazel b/cmd/sd_watcher/BUILD.bazel index 5bbf167..7f5572e 100644 --- a/cmd/sd_watcher/BUILD.bazel +++ b/cmd/sd_watcher/BUILD.bazel @@ -1,5 +1,8 @@ +load("//bazel:cross.bzl", "go_cross_binaries") load("//bazel:go.bzl", "go_multi_binary", "go_multi_library") +package(default_visibility = ["//visibility:public"]) + go_multi_library( name = "sd_watcher_lib", srcs = ["main.go"], @@ -17,3 +20,8 @@ go_multi_binary( embed = [":sd_watcher_lib"], visibility = ["//visibility:public"], ) + +go_cross_binaries( + base_target = "sd_watcher", + linux_arm = True, +) diff --git a/pkg/BUILD.bazel b/pkg/BUILD.bazel index 87d805b..9f6e2c1 100644 --- a/pkg/BUILD.bazel +++ b/pkg/BUILD.bazel @@ -3,29 +3,35 @@ load("//bazel:pkg.bzl", "nfpm_package") nfpm_package( name = "runtime-utils", config = ":runtime-utils.yaml", - data = [ + exes = [ "//cmd/ephs_client", "//cmd/metricbus_server", - "//cmd/metricbus_server:metric_collector_systemd_service", "//cmd/mtls_exporter", - "//cmd/mtls_exporter:mtls_exporter_systemd_service", "//cmd/mtls_supervisor", "//cmd/sd_health_exporter", - "//cmd/sd_health_exporter:sd_health_exporter_systemd_service", "//cmd/sd_publish", "//cmd/sd_register", + "//cmd/sd_watcher", + "//cmd/sqpkg_upload", + ], + data = [ + "//cmd/metricbus_server:metric_collector_systemd_service", + "//cmd/mtls_exporter:mtls_exporter_systemd_service", + "//cmd/sd_health_exporter:sd_health_exporter_systemd_service", "//cmd/sd_register:sd_register@_systemd_service", "//cmd/sd_register:sd_register_systemd_service", - "//cmd/sd_watcher", "//metrics/metricbus:dbus_conf", ], + linux_arm64 = True, ) nfpm_package( name = "apcupsd-exporter", config = ":apcupsd-exporter.yaml", - data = [ + exes = [ "//cmd/apcups_exporter", + ], + data = [ "//cmd/apcups_exporter:apcupsd_exporter@_systemd_service", "//cmd/apcups_exporter:apcupsd_exporter_systemd_service", ], @@ -34,17 +40,22 @@ nfpm_package( nfpm_package( name = "http-proxy", config = ":http-proxy.yaml", - data = [ + exes = [ "//cmd/http_proxy", + ], + data = [ "//cmd/http_proxy:http_proxy@_systemd_service", ], + linux_arm64 = True, ) nfpm_package( name = "ldap-health-exporter", config = ":ldap-health-exporter.yaml", - data = [ + exes = [ "//cmd/ldap_health_exporter", + ], + data = [ "//cmd/ldap_health_exporter:ldap_health_exporter@_systemd_service", ], ) @@ -52,8 +63,10 @@ nfpm_package( nfpm_package( name = "prometheus-helpers", config = ":prometheus-helpers.yaml", - data = [ + exes = [ "//cmd/prometheus_http_discovery", + ], + data = [ "//cmd/prometheus_http_discovery:prometheus_http_discovery_systemd_service", ], ) @@ -61,7 +74,7 @@ nfpm_package( nfpm_package( name = "coredns", config = ":coredns.yaml", - data = [ + exes = [ "//thirdparty/coredns", ], ) diff --git a/pkg/apcupsd-exporter.yaml b/pkg/apcupsd-exporter.yaml index b6b620c..b7958fc 100644 --- a/pkg/apcupsd-exporter.yaml +++ b/pkg/apcupsd-exporter.yaml @@ -1,6 +1,4 @@ name: "${const:ExePrefix}apcupsd-exporter" -arch: "amd64" -platform: "linux" version: "${sub:${const:Version},+unset,}" section: "net" priority: "extra" diff --git a/pkg/coredns.yaml b/pkg/coredns.yaml index 980c28e..03b5f58 100644 --- a/pkg/coredns.yaml +++ b/pkg/coredns.yaml @@ -1,6 +1,4 @@ name: "${const:ExePrefix}coredns" -arch: "amd64" -platform: "linux" version: "${sub:${const:Version},+unset,}" section: "net" priority: "extra" diff --git a/pkg/http-proxy.yaml b/pkg/http-proxy.yaml index 3b83f6f..b8be4c4 100644 --- a/pkg/http-proxy.yaml +++ b/pkg/http-proxy.yaml @@ -1,6 +1,4 @@ name: "${const:ExePrefix}http-proxy" -arch: "amd64" -platform: "linux" version: "${sub:${const:Version},+unset,}" section: "net" priority: "extra" diff --git a/pkg/ldap-health-exporter.yaml b/pkg/ldap-health-exporter.yaml index e7013d2..833924f 100644 --- a/pkg/ldap-health-exporter.yaml +++ b/pkg/ldap-health-exporter.yaml @@ -1,6 +1,4 @@ name: "${const:ExePrefix}ldap-health-exporter" -arch: "amd64" -platform: "linux" version: "${sub:${const:Version},+unset,}" section: "net" priority: "extra" diff --git a/pkg/nfpmgen/config_generator.go b/pkg/nfpmgen/config_generator.go index 0f4aeb3..543ec35 100644 --- a/pkg/nfpmgen/config_generator.go +++ b/pkg/nfpmgen/config_generator.go @@ -3,6 +3,7 @@ package main import ( "flag" "fmt" + "io/fs" "os" "path" "regexp" @@ -49,9 +50,16 @@ func (e executable) String() string { return string(e) } -func (e executable) buildPath(bazelBinDir string) string { +func (e executable) buildPath(bazelBinDir string, platform, arch string) string { + if platform == "linux" && arch == "amd64" { + return path.Join( + bazelBinDir, "cmd", e.String(), e.String()+"_", e.String(), + ) + } + return path.Join( - bazelBinDir, "cmd", e.String(), e.String()+"_", e.String()) + bazelBinDir, "cmd", e.String(), fmt.Sprintf("%s_%s_%s", e.String(), platform, arch), + ) } func (e executable) pkgPath(vars subst.KV) string { @@ -117,7 +125,8 @@ func (c *NfpmConfig) DiscoverBuildArtifacts() error { if err != nil { return fmt.Errorf( "failed reading runfile %q (abspath: %q): %v\nwd: %q", - entry.Source, newsrc, err, wd) + entry.Source, newsrc, err, wd, + ) } entry.Source = newsrc } @@ -126,7 +135,7 @@ func (c *NfpmConfig) DiscoverBuildArtifacts() error { return nil } -func (c *NfpmConfig) DiscoverBinaries(bazelBinDirs []string) error { +func (c *NfpmConfig) DiscoverBinaries(bazelBinDirs []string, platform, arch string) error { wd, err := os.Getwd() if err != nil { return err @@ -155,7 +164,8 @@ func (c *NfpmConfig) DiscoverBinaries(bazelBinDirs []string) error { var exePath string for _, bazelBinDir := range bazelBinDirs { - checkPath := exe.buildPath(bazelBinDir) + checkPath := exe.buildPath(bazelBinDir, platform, arch) + debug("evaluating buildPath: %s", checkPath) if _, ok := c.files[checkPath]; ok { exePath = checkPath @@ -170,7 +180,15 @@ func (c *NfpmConfig) DiscoverBinaries(bazelBinDirs []string) error { debug("evaluating exe with buildPath %s", exePath) - if derefPath, err := os.Readlink(exePath); err == nil { + for { + if !isSymlink(exePath) { + break + } + + derefPath, err := os.Readlink(exePath) + if err != nil { + return fmt.Errorf("readlink(%q): %v", exePath, err) + } if path.IsAbs(derefPath) { exePath = derefPath } else { @@ -179,9 +197,8 @@ func (c *NfpmConfig) DiscoverBinaries(bazelBinDirs []string) error { derefPath, ) } - - debug(" -> dereferenced symlink to: %s", exePath) } + debug(" -> dereferenced symlink to: %s", exePath) st, err := os.Stat(exePath) if err != nil { @@ -326,6 +343,14 @@ func (c *NfpmConfig) Generate() (string, error) { return string(out), nil } +func isSymlink(fullPath string) bool { + if stat, err := os.Lstat(fullPath); err == nil { + return stat.Mode()&fs.ModeSymlink == fs.ModeSymlink + } + + return false +} + func init() { flag.BoolVar(&verbose, "verbose", false, "enable debug logging") } diff --git a/pkg/nfpmgen/main.go b/pkg/nfpmgen/main.go index 0046142..bf05a0b 100644 --- a/pkg/nfpmgen/main.go +++ b/pkg/nfpmgen/main.go @@ -14,6 +14,8 @@ import ( func main() { yamlFile := flag.String("in", "", "path to yaml template to consume") outFile := flag.String("out", "", "output file to write; if omitted, uses stdout") + arch := flag.String("arch", "amd64", "architecture") + platform := flag.String("platform", "linux", "platform") var includes []string parseInclude := func(flagVal string) error { @@ -44,6 +46,11 @@ func main() { if err != nil { panic(err) } + c.Platform = *platform + c.Arch = *arch + if *arch == "arm" { + c.Arch = "armv7h" + } wd, err := os.Getwd() if err != nil { @@ -77,7 +84,7 @@ func main() { panic(err) } - if err := c.DiscoverBinaries(bazelBinDirs); err != nil { + if err := c.DiscoverBinaries(bazelBinDirs, *platform, *arch); err != nil { panic(err) } diff --git a/pkg/prometheus-helpers.yaml b/pkg/prometheus-helpers.yaml index de239c7..e64fc74 100644 --- a/pkg/prometheus-helpers.yaml +++ b/pkg/prometheus-helpers.yaml @@ -1,6 +1,4 @@ name: "${const:ExePrefix}prometheus-helpers" -arch: "amd64" -platform: "linux" version: "${sub:${const:Version},+unset,}" section: "net" priority: "extra" diff --git a/pkg/runtime-utils.yaml b/pkg/runtime-utils.yaml index 85e11d6..69a4cbd 100644 --- a/pkg/runtime-utils.yaml +++ b/pkg/runtime-utils.yaml @@ -1,6 +1,4 @@ name: "${const:ExePrefix}runtime-utils" -arch: "amd64" -platform: "linux" version: "${sub:${const:Version},+unset,}" section: "net" priority: "extra" -- 2.52.0