From c2a61aac2e53f52ca0e997f91f289a3fa5b19f32 Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Fri, 23 Oct 2026 08:18:06 +0200 Subject: [PATCH 01/13] Implement support for running HAProxy with AWS-LC (FIPS) https://github.com/cloudfoundry/community/blob/main/toc/rfc/rfc-0061-haproxy-awslc.md --- .gitignore | 4 + README.md | 30 ++ acceptance-tests/README.md | 23 ++ .../acceptance_tests_suite_test.go | 26 +- acceptance-tests/bosh_helpers.go | 38 +++ acceptance-tests/config.go | 14 + acceptance-tests/lua_test.go | 4 +- acceptance-tests/run-local.sh | 4 +- acceptance-tests/ssl_variant_test.go | 64 +++++ acceptance-tests/strict_sni_test.go | 4 +- ci/README.md | 4 +- ci/pipeline.yml | 194 ++++++++++++- ci/scripts/autobump-dependencies.py | 224 +++++++++++++-- ci/scripts/functions-ci.sh | 2 + ci/scripts/requirements-test.txt | 2 + ci/scripts/shipit | 77 ++--- ci/scripts/test_autobump_dependencies.py | 270 ++++++++++++++++++ config/blobs.yml | 12 + docs/coredumps.md | 6 +- jobs/haproxy/spec | 16 +- jobs/haproxy/templates/haproxy_wrapper.erb | 27 +- jobs/haproxy/templates/pre-start.erb | 11 +- packages/README.md | 20 ++ packages/aws-lc-fips/packaging | 30 ++ packages/aws-lc-fips/spec | 8 + packages/aws-lc-src/packaging | 8 + packages/aws-lc-src/spec | 5 + packages/aws-lc/packaging | 21 ++ packages/aws-lc/spec | 7 + packages/cmake/packaging | 7 + packages/cmake/spec | 5 + packages/haproxy-awslc-fips-patched/packaging | 5 + packages/haproxy-awslc-fips-patched/spec | 11 + packages/haproxy-awslc-fips/packaging | 5 + packages/haproxy-awslc-fips/spec | 9 + packages/haproxy-awslc-patched/packaging | 5 + packages/haproxy-awslc-patched/spec | 11 + packages/haproxy-awslc/packaging | 5 + packages/haproxy-awslc/spec | 9 + packages/haproxy-deps/packaging | 36 +++ packages/{haproxy => haproxy-deps}/spec | 4 +- packages/haproxy-openssl-patched/packaging | 5 + packages/haproxy-openssl-patched/spec | 10 + packages/haproxy-openssl/packaging | 5 + packages/haproxy-openssl/spec | 8 + packages/haproxy/packaging | 72 ----- scripts/dev-build.sh | 113 ++++++++ .../haproxy/templates/haproxy_wrapper_spec.rb | 45 +++ src/apply-patches.sh | 17 ++ src/aws-lc-versions.sh | 14 + src/build-haproxy.sh | 34 +++ .../disable-rfc-6455-compliance.patch | 0 src/haproxy-versions.sh | 14 + 53 files changed, 1427 insertions(+), 177 deletions(-) create mode 100644 acceptance-tests/ssl_variant_test.go create mode 100644 ci/scripts/requirements-test.txt create mode 100644 ci/scripts/test_autobump_dependencies.py create mode 100644 packages/README.md create mode 100644 packages/aws-lc-fips/packaging create mode 100644 packages/aws-lc-fips/spec create mode 100644 packages/aws-lc-src/packaging create mode 100644 packages/aws-lc-src/spec create mode 100644 packages/aws-lc/packaging create mode 100644 packages/aws-lc/spec create mode 100644 packages/cmake/packaging create mode 100644 packages/cmake/spec create mode 100644 packages/haproxy-awslc-fips-patched/packaging create mode 100644 packages/haproxy-awslc-fips-patched/spec create mode 100644 packages/haproxy-awslc-fips/packaging create mode 100644 packages/haproxy-awslc-fips/spec create mode 100644 packages/haproxy-awslc-patched/packaging create mode 100644 packages/haproxy-awslc-patched/spec create mode 100644 packages/haproxy-awslc/packaging create mode 100644 packages/haproxy-awslc/spec create mode 100644 packages/haproxy-deps/packaging rename packages/{haproxy => haproxy-deps}/spec (74%) create mode 100644 packages/haproxy-openssl-patched/packaging create mode 100644 packages/haproxy-openssl-patched/spec create mode 100644 packages/haproxy-openssl/packaging create mode 100644 packages/haproxy-openssl/spec delete mode 100644 packages/haproxy/packaging create mode 100755 scripts/dev-build.sh create mode 100644 spec/haproxy/templates/haproxy_wrapper_spec.rb create mode 100644 src/apply-patches.sh create mode 100644 src/aws-lc-versions.sh create mode 100644 src/build-haproxy.sh rename {haproxy-patches => src/haproxy-patches}/disable-rfc-6455-compliance.patch (100%) create mode 100644 src/haproxy-versions.sh diff --git a/.gitignore b/.gitignore index 881ead696..3fcc0b20d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ releases/**/*.tgz ci/scripts/stemcell/*.tgz ci/scripts/stemcell-jammy/*.tgz dev_releases +builds blobs/* .blobs .dev_builds @@ -21,6 +22,9 @@ blobs/* tmp my*.yml .bundle +.pytest_cache +__pycache__ +*.pyc vendor .vscode/launch.json .vscode/settings.json diff --git a/README.md b/README.md index 4da0389ab..445d98f4b 100644 --- a/README.md +++ b/README.md @@ -81,3 +81,33 @@ Unit/RSpec tests can also be debugged/stepped through when needed. See for examp ### Acceptance Tests See [acceptance-tests README](/acceptance-tests/README.md). + +### Local Dev Builds + +`scripts/dev-build.sh` builds the release tarball and uploads it to the targeted BOSH +director. Useful for iterating on packaging changes without going through CI. + +```bash +./scripts/dev-build.sh # build, version=dev +./scripts/dev-build.sh --version 1.0 # custom version tag +./scripts/dev-build.sh --upload-only # re-upload previously built tarballs +``` + +Tarballs are written to `./builds/` and uploaded with `bosh upload-release --fix`. + +### Packaging model + +`packages/` holds **every** package, and `bosh create-release` bundles all of them, so a plain +`bosh create-release` of the committed tree produces the one release — there is no build-time +assembly. The `haproxy` job lists all six `haproxy-*` binaries; the SSL backend is chosen at deploy +time via `ha_proxy.ssl_variant` (default `openssl`) and `ha_proxy.include_haproxy_patches` +(default `false`), handled in `jobs/haproxy/templates/haproxy_wrapper.erb`. + +Dependencies are one-directional: every `haproxy-*` binary depends on the shared `haproxy-deps` +(lua, pcre2, socat, hatop), compiled once. AWS-LC is compiled from a single shared `aws-lc-src` source +package used by both the non-FIPS `aws-lc` and the FIPS `aws-lc-fips` compile packages (FIPS differs +only by `-DFIPS=1` plus the Go toolchain for the integrity step). Because `aws-lc`/`aws-lc-fips` do not +bundle the HAProxy version file, their fingerprints are independent of HAProxy — a HAProxy bump reuses +the cached AWS-LC compile instead of rebuilding it. The HAProxy community patches (the optional +`-patched` builds) are plain source files under `src/haproxy-patches/`, applied at compile time by +`src/apply-patches.sh`. \ No newline at end of file diff --git a/acceptance-tests/README.md b/acceptance-tests/README.md index c8ff20c3c..aceff1ae8 100644 --- a/acceptance-tests/README.md +++ b/acceptance-tests/README.md @@ -12,6 +12,29 @@ cd acceptance-tests ./run-local.sh ``` +### TLS Backend Variant + +There is a single release that bundles every SSL variant. By default, the tests deploy it with the +system OpenSSL backend. To exercise a different TLS backend, set the `VARIANT` environment variable — +it drives the `ha_proxy.ssl_variant` deployment property. The HAProxy patches are toggled with +`INCLUDE_HAPROXY_PATCHES` (which drives `ha_proxy.include_haproxy_patches`). Examples: + +```shell +VARIANT=awslc ./run-local.sh # AWS-LC, non-FIPS +VARIANT=awslc-fips ./run-local.sh # AWS-LC FIPS +INCLUDE_HAPROXY_PATCHES=true ./run-local.sh # system OpenSSL + HAProxy patches +VARIANT=awslc INCLUDE_HAPROXY_PATCHES=true ./run-local.sh # AWS-LC + patches +VARIANT=awslc-fips INCLUDE_HAPROXY_PATCHES=true ./run-local.sh # AWS-LC FIPS + patches +``` + +`VARIANT` accepts `openssl` (default), `awslc`, or `awslc-fips`. + +A single invocation runs the suite against the chosen variant. + +Each run builds the release from scratch, compiling every bundled binary (AWS-LC and its FIPS toolchain included) inside the BOSH compilation VM. + +When using `-k` (keep BOSH running, see below) the cached state belongs to whichever variant ran last — switching `VARIANT` inside a kept container is not supported. Stop the container between variants, or run without `-k`. + ### Running on Docker for Mac Acceptance tests cannot be run on Mac with arm64 architecture: diff --git a/acceptance-tests/acceptance_tests_suite_test.go b/acceptance-tests/acceptance_tests_suite_test.go index ab937416b..fd285ce0a 100644 --- a/acceptance-tests/acceptance_tests_suite_test.go +++ b/acceptance-tests/acceptance_tests_suite_test.go @@ -226,8 +226,21 @@ func expectTLSCertificateRequiredErr(err error) { checkNetOpErr(err, "tls: certificate required") } -func expectTLSUnrecognizedNameErr(err error) { - checkNetOpErr(err, "tls: unrecognized name") +// expectStrictSNIRejectedErr asserts that a strict-sni handshake was rejected. +// - OpenSSL registers the SNI reject through the servername callback and sends +// unrecognized_name(112) => "tls: unrecognized name" +// - AWS-LC uses the select_certificate_cb path, which sends +// handshake_failure(40) => "tls: handshake failure" +func expectStrictSNIRejectedErr(err error) { + msg := netOpErrString(err) + if strings.HasPrefix(config.Variant, "awslc") { + Expect(msg).To(Or( + ContainSubstring("tls: handshake failure"), + ContainSubstring("tls: unrecognized name"), + )) + return + } + Expect(msg).To(ContainSubstring("tls: unrecognized name")) } func expectConnectionRefusedErr(err error) { @@ -239,11 +252,18 @@ func expectConnectionResetErr(err error) { } func checkNetOpErr(err error, expectString string) { + Expect(netOpErrString(err)).To(ContainSubstring(expectString)) +} + +// netOpErrString unwraps an http client error down to the underlying +// *net.OpError and returns its message, failing the test if the error is not +// shaped that way. +func netOpErrString(err error) string { Expect(err).To(HaveOccurred()) urlErr, ok := err.(*url.Error) Expect(ok).To(BeTrue()) tlsErr := urlErr.Unwrap() var opErr *net.OpError Expect(errors.As(tlsErr, &opErr)).To(BeTrue()) - Expect(opErr.Err.Error()).To(ContainSubstring(expectString)) + return opErr.Err.Error() } diff --git a/acceptance-tests/bosh_helpers.go b/acceptance-tests/bosh_helpers.go index 415ee0e4a..afaefa660 100644 --- a/acceptance-tests/bosh_helpers.go +++ b/acceptance-tests/bosh_helpers.go @@ -93,6 +93,21 @@ var opsfileConfigureSSH string = `--- var defaultOpsfiles = []string{opsfileChangeName, opsfileChangeVersion, opsfileConfigureSSH} var defaultSSHUser string = "ginkgo" +// The release bundles every SSL variant; this selects one at deploy time. +var opsfileSSLVariant string = `--- +# Select the SSL variant at deploy time (the release bundles all of them) +- type: replace + path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/ssl_variant? + value: ((ssl-variant)) +` + +// Orthogonal to the SSL variant: run the patched HAProxy build. +var opsfileIncludePatches string = `--- +- type: replace + path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/include_haproxy_patches? + value: ((include-haproxy-patches)) +` + func buildManifestVars(baseManifestVars baseManifestVars, customVars map[string]interface{}) map[string]interface{} { vars := map[string]interface{}{ "release-version": config.ReleaseVersion, @@ -146,6 +161,21 @@ func buildHAProxyInfo(baseManifestVars baseManifestVars, varsStoreReader varsSto func deployHAProxy(baseManifestVars baseManifestVars, customOpsfiles []string, customVars map[string]interface{}, expectSuccess bool) (haproxyInfo, varsStoreReader) { manifestVars := buildManifestVars(baseManifestVars, customVars) opsfiles := append(defaultOpsfiles, customOpsfiles...) + + // The release bundles every SSL variant; select the one under test at deploy time. + // config.Variant comes from the VARIANT env (default "openssl"); openssl is the job's + // own default, so we only inject the property for the non-default variants. + if config.Variant != "" && config.Variant != "openssl" { + opsfiles = append(opsfiles, opsfileSSLVariant) + manifestVars["ssl-variant"] = config.Variant + } + + // INCLUDE_HAPROXY_PATCHES selects the patched build (orthogonal to the SSL variant). + if config.IncludePatches { + opsfiles = append(opsfiles, opsfileIncludePatches) + manifestVars["include-haproxy-patches"] = config.IncludePatches + } + cmd, varsStoreReader := deployBaseManifestCmd(baseManifestVars.deploymentName, opsfiles, manifestVars) dumpCmd(cmd) @@ -332,3 +362,11 @@ func runHAProxySocketCommand(haproxyInfo haproxyInfo, command string) string { return strings.TrimSpace(stdout) } +// runningHAProxyVersionInfo returns `haproxy -vv` for the HAProxy binary that is +// actually running on the VM. +func runningHAProxyVersionInfo(haproxyInfo haproxyInfo) string { + cmd := `sudo sh -c 'exe=$(readlink -f /proc/$(pgrep -x -n haproxy)/exe); "$exe" -vv'` + stdout, _, err := runOnRemote(haproxyInfo.SSHUser, haproxyInfo.PublicIP, haproxyInfo.SSHPrivateKey, cmd) + Expect(err).NotTo(HaveOccurred()) + return strings.TrimSpace(stdout) +} diff --git a/acceptance-tests/config.go b/acceptance-tests/config.go index 5d3c6bce3..55809ad71 100644 --- a/acceptance-tests/config.go +++ b/acceptance-tests/config.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "os/exec" + "strconv" ) var config Config @@ -18,6 +19,8 @@ type Config struct { BoshPath string `json:"boshPath"` BaseManifestPath string `json:"baseManifestPath"` HomePath string `json:"homePath"` + Variant string `json:"variant"` + IncludePatches bool `json:"includePatches"` } func loadConfig() (Config, error) { @@ -67,6 +70,15 @@ func loadConfig() (Config, error) { return Config{}, err } + // VARIANT selects the SSL library (openssl|awslc|awslc-fips); empty means openssl. + variant := os.Getenv("VARIANT") + if variant == "" { + variant = "openssl" + } + + // INCLUDE_HAPROXY_PATCHES toggles the patched build (orthogonal to VARIANT). + includePatches, _ := strconv.ParseBool(os.Getenv("INCLUDE_HAPROXY_PATCHES")) + return Config{ ReleaseRepoPath: releaseRepoPath, ReleaseVersion: releaseVersion, @@ -77,6 +89,8 @@ func loadConfig() (Config, error) { BoshPath: boshPath, BaseManifestPath: baseManifestPath, HomePath: homePath, + Variant: variant, + IncludePatches: includePatches, }, nil } diff --git a/acceptance-tests/lua_test.go b/acceptance-tests/lua_test.go index e690b41e2..c6deed0cf 100644 --- a/acceptance-tests/lua_test.go +++ b/acceptance-tests/lua_test.go @@ -16,7 +16,7 @@ var _ = Describe("Lua scripting", func() { # Enable Lua scripting - type: replace path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/lua_scripts?/- - value: "/var/vcap/packages/haproxy/lua_test.lua" + value: "/var/vcap/packages/haproxy-deps/lua_test.lua" - type: replace path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/frontend_config? value: "http-request use-service lua.lua_test if { path /lua_test }" @@ -53,7 +53,7 @@ core.register_service("lua_test", "http", lua_test) Expect(boshInstances(deploymentNameForTestNode())[0].ProcessState).To(Or(Equal("failing"), Equal("unresponsive agent"))) // upload Lua script file - uploadFile(haproxyInfo, strings.NewReader(replyLuaContent), "/var/vcap/packages/haproxy/lua_test.lua") + uploadFile(haproxyInfo, strings.NewReader(replyLuaContent), "/var/vcap/packages/haproxy-deps/lua_test.lua") closeLocalServer, localPort := startDefaultTestServer() defer closeLocalServer() diff --git a/acceptance-tests/run-local.sh b/acceptance-tests/run-local.sh index 1cb4b70aa..4c4c3fc65 100755 --- a/acceptance-tests/run-local.sh +++ b/acceptance-tests/run-local.sh @@ -94,9 +94,9 @@ if [ -n "$KEEP_RUNNING" ] ; then echo echo "*** KEEP_RUNNING enabled. Please clean up docker scratch after removing containers: ${DOCKER_SCRATCH}" echo - docker run --privileged -v "$REPO_DIR":/repo -v "${DOCKER_SCRATCH}":/scratch/docker -e REPO_ROOT=/repo -e FOCUS="${FOCUS}" -e PARALLELISM="${PARALLELISM}" -e KEEP_RUNNING="${KEEP_RUNNING}" haproxy-boshrelease-testflight bash -c "cd /repo/ci/scripts && ./acceptance-tests ; sleep infinity" + docker run --privileged -v "$REPO_DIR":/repo -v "${DOCKER_SCRATCH}":/scratch/docker -e REPO_ROOT=/repo -e FOCUS="${FOCUS}" -e PARALLELISM="${PARALLELISM}" -e KEEP_RUNNING="${KEEP_RUNNING}" -e VARIANT="${VARIANT:-}" haproxy-boshrelease-testflight bash -c "cd /repo/ci/scripts && ./acceptance-tests ; sleep infinity" else - docker run --rm --privileged -v "$REPO_DIR":/repo -v "${DOCKER_SCRATCH}":/scratch/docker -e REPO_ROOT=/repo -e KEEP_RUNNING="" -e PARALLELISM="${PARALLELISM}" haproxy-boshrelease-testflight bash -c "cd /repo/ci/scripts && ./acceptance-tests" + docker run --rm --privileged -v "$REPO_DIR":/repo -v "${DOCKER_SCRATCH}":/scratch/docker -e REPO_ROOT=/repo -e KEEP_RUNNING="" -e PARALLELISM="${PARALLELISM}" -e VARIANT="${VARIANT:-}" haproxy-boshrelease-testflight bash -c "cd /repo/ci/scripts && ./acceptance-tests" echo "Cleaning up docker scratch: ${DOCKER_SCRATCH}" sudo rm -rf "${DOCKER_SCRATCH}" fi diff --git a/acceptance-tests/ssl_variant_test.go b/acceptance-tests/ssl_variant_test.go new file mode 100644 index 000000000..be8a1500b --- /dev/null +++ b/acceptance-tests/ssl_variant_test.go @@ -0,0 +1,64 @@ +package acceptance_tests + +import ( + "fmt" + "regexp" + "strings" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +// Verifies that the SSL backend actually running on the VM matches the variant +// the release was assembled with (config.Variant, from the VARIANT env var). +// +// The signal is the running binary's `haproxy -vv`, which reports two dedicated +// lines describing the library loaded at runtime (verified against real output +// from AWS-LC 4.0.0 / OpenSSL 3.0.13): +// +// variant "Running on SSL library version : ..." "SSL library FIPS mode : ..." +// openssl OpenSSL 3.0.13 30 Jan 2024 (line absent) +// awslc AWS-LC 4.0.0 no +// awslc-fips AWS-LC FIPS 4.0.0 yes +var ( + runningSSLLibRe = regexp.MustCompile(`Running on SSL library version\s*:\s*(.+)`) + sslFIPSModeOnRe = regexp.MustCompile(`SSL library FIPS mode\s*:\s*yes`) +) + +var _ = Describe("SSL variant", func() { + It("Runs the HAProxy binary for the configured SSL variant", func() { + haproxyInfo, _ := deployHAProxy(baseManifestVars{ + haproxyBackendPort: 12000, + haproxyBackendServers: []string{"127.0.0.1"}, + deploymentName: deploymentNameForTestNode(), + }, []string{}, map[string]interface{}{}, true) + + By("Reading the SSL library from the running HAProxy binary (haproxy -vv)") + versionInfo := runningHAProxyVersionInfo(haproxyInfo) + fmt.Fprintf(GinkgoWriter, "----- haproxy -vv (variant %q) -----\n%s\n", config.Variant, versionInfo) + + match := runningSSLLibRe.FindStringSubmatch(versionInfo) + Expect(match).NotTo(BeNil(), "no 'Running on SSL library version' line in haproxy -vv:\n%s", versionInfo) + runningSSL := strings.TrimSpace(match[1]) + + isAWSLC := strings.Contains(runningSSL, "AWS-LC") + fipsMode := sslFIPSModeOnRe.MatchString(versionInfo) + + switch { + case strings.HasPrefix(config.Variant, "awslc-fips"): + By("Expecting AWS-LC FIPS") + Expect(isAWSLC).To(BeTrue(), "expected AWS-LC, running SSL library was %q", runningSSL) + Expect(fipsMode).To(BeTrue(), "expected FIPS mode on; haproxy -vv was:\n%s", versionInfo) + case strings.HasPrefix(config.Variant, "awslc"): + By("Expecting AWS-LC (non-FIPS)") + Expect(isAWSLC).To(BeTrue(), "expected AWS-LC, running SSL library was %q", runningSSL) + Expect(fipsMode).To(BeFalse(), "expected FIPS mode off; haproxy -vv was:\n%s", versionInfo) + default: + // openssl (VARIANT unset/openssl); patches are an orthogonal axis and don't change the library. + By("Expecting system OpenSSL") + Expect(runningSSL).To(ContainSubstring("OpenSSL"), "expected OpenSSL, running SSL library was %q", runningSSL) + Expect(isAWSLC).To(BeFalse(), "expected OpenSSL but found AWS-LC, running SSL library was %q", runningSSL) + Expect(fipsMode).To(BeFalse(), "expected FIPS mode off; haproxy -vv was:\n%s", versionInfo) + } + }) +}) diff --git a/acceptance-tests/strict_sni_test.go b/acceptance-tests/strict_sni_test.go index 420814e84..afabbc755 100644 --- a/acceptance-tests/strict_sni_test.go +++ b/acceptance-tests/strict_sni_test.go @@ -129,11 +129,11 @@ var _ = Describe("Strict SNI", func() { By("Sending a request to HAProxy with no SNI is forbidden") _, err := httpClientNoSNI.Get("https://haproxy.internal") - expectTLSUnrecognizedNameErr(err) + expectStrictSNIRejectedErr(err) By("Sending a request to HAProxy with an incorrect SNI is forbidden") _, err = httpClientWrongSNI.Get("https://haproxy.internal") - expectTLSUnrecognizedNameErr(err) + expectStrictSNIRejectedErr(err) }) }) }) diff --git a/ci/README.md b/ci/README.md index a20983e1f..9a37e245d 100644 --- a/ci/README.md +++ b/ci/README.md @@ -135,6 +135,6 @@ For creating a new release please follow the versioning guide based on the [Sema Used for documentation updates, changes in the test suite or any updates in the testing frameworks (e.g. ginkgo). -Since releases `11.16.3` and `11.17.5` the build metadata has been included into the version number. The build metadata denotes the contained HAProxy version. As an example, `11.16.2+2.6.9` means that HAProxy 2.6.9 is used. + Since releases `11.16.3` and `11.17.5` the build metadata (everything after the `+`) has been included in the version number to denote the contained upstream versions. Since version 17.0.0, it records both the HAProxy and the AWS-LC version: `17.0.0+3.2.26-awslc-4.0.0` means HAProxy 3.2.26 and AWS-LC 4.0.0. -The `haproxy-boshrelease` also contains patches (see [haproxy-patches](../haproxy-patches)). The patched version is a part of the build metadata and is denoted by appending a hyphen and key word `patched`, like `11.17.4+2.6.9-patched`. + The release bundles every SSL variant and the HAProxy community patches (see [haproxy-patches](../src/haproxy-patches)). One build is selected at deploy time via the `ha_proxy.ssl_variant` (`openssl` | `awslc` | `awslc-fips`) and `ha_proxy.include_haproxy_patches` (`true` | `false`) job properties. diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 42ebab1f8..20eb54e98 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -6,7 +6,11 @@ groups: - unit-tests - unit-tests-pr - acceptance-tests + - acceptance-tests-awslc + - acceptance-tests-awslc-fips - acceptance-tests-pr + - acceptance-tests-awslc-pr + - acceptance-tests-awslc-fips-pr - rc - shipit - patch @@ -151,6 +155,76 @@ jobs: icon_url: "((slack.icon))" text: "((slack.fail_url)) haproxy-boshrelease : acceptance tests failed" + - name: acceptance-tests-awslc + public: true + serial: true + serial_groups: [acceptance-tests] + plan: + - do: + - in_parallel: + - { get: git, trigger: true, passed: [acceptance-tests] } + - { get: stemcell } + - { get: stemcell-jammy } + - { get: haproxy-boshrelease-testflight, trigger: true, passed: [acceptance-tests] } + - task: acceptance-tests-awslc + privileged: true + timeout: 4h + image: haproxy-boshrelease-testflight + config: + platform: linux + inputs: + - { name: git } + - { name: stemcell } + - { name: stemcell-jammy } + run: + path: ./git/ci/scripts/acceptance-tests + args: [] + params: + REPO_ROOT: git + VARIANT: awslc + on_failure: + put: notify + params: + channel: "#haproxy-boshrelease" + username: ci-bot + icon_url: "((slack.icon))" + text: "((slack.fail_url)) haproxy-boshrelease : acceptance tests (AWS-LC) failed" + + - name: acceptance-tests-awslc-fips + public: true + serial: true + serial_groups: [acceptance-tests] + plan: + - do: + - in_parallel: + - { get: git, trigger: true, passed: [acceptance-tests-awslc] } + - { get: stemcell } + - { get: stemcell-jammy } + - { get: haproxy-boshrelease-testflight, trigger: true, passed: [acceptance-tests-awslc] } + - task: acceptance-tests-awslc-fips + privileged: true + timeout: 4h + image: haproxy-boshrelease-testflight + config: + platform: linux + inputs: + - { name: git } + - { name: stemcell } + - { name: stemcell-jammy } + run: + path: ./git/ci/scripts/acceptance-tests + args: [] + params: + REPO_ROOT: git + VARIANT: awslc-fips + on_failure: + put: notify + params: + channel: "#haproxy-boshrelease" + username: ci-bot + icon_url: "((slack.icon))" + text: "((slack.fail_url)) haproxy-boshrelease : acceptance tests (AWS-LC FIPS) failed" + - name: acceptance-tests-pr public: true serial: true @@ -197,12 +271,106 @@ jobs: status: failure context: acceptance-tests + - name: acceptance-tests-awslc-pr + public: true + serial: true + serial_groups: [acceptance-tests] + plan: + - do: + - in_parallel: + - { get: git-pull-requests-awslc, trigger: true, version: every } + - { get: stemcell } + - { get: stemcell-jammy } + - { get: haproxy-boshrelease-testflight-pr, passed: [acceptance-tests-pr] } + - put: git-pull-requests-awslc + params: + path: git-pull-requests-awslc + status: pending + context: acceptance-tests-awslc + get_params: + list_changed_files: true + - task: acceptance-tests-awslc + privileged: true + timeout: 4h + image: haproxy-boshrelease-testflight-pr + config: + platform: linux + inputs: + - { name: git-pull-requests-awslc } + - { name: stemcell } + - { name: stemcell-jammy } + run: + path: ./git-pull-requests-awslc/ci/scripts/acceptance-tests + args: [] + params: + REPO_ROOT: git-pull-requests-awslc + VARIANT: awslc + on_success: + put: git-pull-requests-awslc + params: + path: git-pull-requests-awslc + status: success + context: acceptance-tests-awslc + on_failure: + put: git-pull-requests-awslc + params: + path: git-pull-requests-awslc + status: failure + context: acceptance-tests-awslc + + - name: acceptance-tests-awslc-fips-pr + public: true + serial: true + serial_groups: [acceptance-tests] + plan: + - do: + - in_parallel: + - { get: git-pull-requests-awslc, trigger: true, version: every } + - { get: stemcell } + - { get: stemcell-jammy } + - { get: haproxy-boshrelease-testflight-pr, passed: [acceptance-tests-awslc-pr] } + - put: git-pull-requests-awslc + params: + path: git-pull-requests-awslc + status: pending + context: acceptance-tests-awslc-fips + get_params: + list_changed_files: true + - task: acceptance-tests-awslc-fips + privileged: true + timeout: 4h + image: haproxy-boshrelease-testflight-pr + config: + platform: linux + inputs: + - { name: git-pull-requests-awslc } + - { name: stemcell } + - { name: stemcell-jammy } + run: + path: ./git-pull-requests-awslc/ci/scripts/acceptance-tests + args: [] + params: + REPO_ROOT: git-pull-requests-awslc + VARIANT: awslc-fips + on_success: + put: git-pull-requests-awslc + params: + path: git-pull-requests-awslc + status: success + context: acceptance-tests-awslc-fips + on_failure: + put: git-pull-requests-awslc + params: + path: git-pull-requests-awslc + status: failure + context: acceptance-tests-awslc-fips + - name: rc public: true plan: - do: - in_parallel: - - { get: git, trigger: true, passed: [acceptance-tests] } + - { get: git, trigger: true, passed: [acceptance-tests, acceptance-tests-awslc, acceptance-tests-awslc-fips] } - { get: version, trigger: false, params: {pre: rc} } - put: version params: {file: version/number} @@ -264,7 +432,7 @@ jobs: - in_parallel: - { get: version, passed: [rc], params: {bump: final} } - { get: git, passed: [rc] } - - get: haproxy-boshrelease-testflight + - { get: haproxy-boshrelease-testflight, trigger: true, passed: [build-haproxy-testflight-image] } - task: release image: haproxy-boshrelease-testflight config: @@ -302,7 +470,7 @@ jobs: name: gh/name tag: gh/tag body: gh/notes.md - globs: [gh/artifacts/*, gh/artifacts-patched/*] + globs: [gh/artifacts/*] - put: notify params: channel: "#haproxy-boshrelease" @@ -325,7 +493,7 @@ jobs: - get: daily trigger: true - get: git - - get: haproxy-boshrelease-testflight + - { get: haproxy-boshrelease-testflight, trigger: true, passed: [build-haproxy-testflight-image] } - task: autobump-dependencies image: haproxy-boshrelease-testflight config: @@ -434,7 +602,21 @@ resources: access_token: ((github.access_token)) repository: cloudfoundry/haproxy-boshrelease base_branch: master - labels: [run-ci] + labels: [run-ci, run-ci-awslc] + required_review_approvals: 1 + trusted_teams: + - "wg-app-runtime-platform-networking-approvers" + trusted_users: + - "dependabot" + - "CFN-CI" + + - name: git-pull-requests-awslc + type: pull-request + source: + access_token: ((github.access_token)) + repository: cloudfoundry/haproxy-boshrelease + base_branch: master + labels: [run-ci-awslc] required_review_approvals: 1 trusted_teams: - "wg-app-runtime-platform-networking-approvers" @@ -479,7 +661,7 @@ resources: source: bucket: haproxy-boshrelease json_key: ((gcp.service_key)) - regexp: haproxy-([0-9\.+-]+).tgz + regexp: haproxy-([0-9a-z\.+-]+)\.tgz - name: daily type: time diff --git a/ci/scripts/autobump-dependencies.py b/ci/scripts/autobump-dependencies.py index 4a8c20d5c..2029ea2d4 100755 --- a/ci/scripts/autobump-dependencies.py +++ b/ci/scripts/autobump-dependencies.py @@ -24,18 +24,26 @@ LUA_VERSION = "5.4" PCRE_VERSION = "10" HATOP_VERSION = "0" - -# Required Environment Vars -BLOBSTORE_SECRET_ACCESS_KEY = os.environ["GCP_SERVICE_KEY"] -gh = github.Github(login_or_token=os.environ["GITHUB_COM_TOKEN"]) -PR_ORG = os.environ["PR_ORG"] -PR_BASE = os.environ["PR_BASE"] -PR_LABEL = os.environ["PR_LABEL"] +AWS_LC_VERSION = "4" # LTS line (v4.x); builds both FIPS and non-FIPS +CMAKE_VERSION = "4" +GOLANG_VERSION = "1.27" + +# Required environment variables — read lazily (via .get) so this module can be +# imported without them (e.g. by the offline resolution tests). main() validates +# that they are actually set before doing any real work. +BLOBSTORE_SECRET_ACCESS_KEY = os.environ.get("GCP_SERVICE_KEY") +_github_token = os.environ.get("GITHUB_COM_TOKEN") +gh = github.Github(auth=github.Auth.Token(_github_token)) if _github_token else github.Github() +PR_ORG = os.environ.get("PR_ORG") +PR_BASE = os.environ.get("PR_BASE") +PR_LABEL = os.environ.get("PR_LABEL") # if DRY_RUN is set, blobs will not be uploaded and no PR created (downloads and local changes are still performed) DRY_RUN = "DRY_RUN" in os.environ # Other Global Variables BLOBS_PATH = "config/blobs.yml" +VERSIONS_PATH = "src/haproxy-versions.sh" +AWS_LC_VERSIONS_PATH = "src/aws-lc-versions.sh" PACKAGING_PATH = "packages/{}/packaging" @@ -105,27 +113,44 @@ class Dependency: pinned_version: str root_url: str package: str = "haproxy" - remote_repo = gh.get_repo(f"{PR_ORG}/haproxy-boshrelease") + filename_suffix: str = ".tar.gz" + blob_version_prefix: str = "" + # Explicit path to the file holding this dependency's version constant. + # Defaults (below) to src/haproxy-versions.sh for package "haproxy"; the + # crypto deps override it to src/aws-lc-versions.sh. + versions_path: Optional[str] = None _latest_release: Optional[Release] = None _current_version: version.Version = None + @property + def remote_repo(self): + # Lazy so importing this module does not hit the GitHub API (keeps resolution testable offline). + return gh.get_repo(f"{PR_ORG}/haproxy-boshrelease") + @property def pr_branch(self): return f"{self.name}-auto-bump-{PR_BASE}" + @property + def versions_file(self) -> str: + if self.versions_path: + return self.versions_path + if self.package == "haproxy": + return VERSIONS_PATH + return PACKAGING_PATH.format(self.package) + @property def current_version(self) -> version.Version: """ - Fetches the current version of the release from the packaging file if not already known. + Fetches the current version of the release from the versions file if not already known. (Should always be identical to the version in blobs.yml) """ if self._current_version: return self._current_version - with open(PACKAGING_PATH.format(self.package), "r") as packaging_file: - for line in packaging_file.readlines(): + with open(self.versions_file, "r") as versions_file: + for line in versions_file.readlines(): if line.startswith(self.version_var_name): - # Regex: expecting e.g. "RELEASE_VERSION=1.2.3 # http://release.org/download". extracting Semver Group rgx = rf"{self.version_var_name}=((?:[0-9]+\.){{1,3}}[0-9]+)\s+#.*$" match = re.match(rgx, line) if match: @@ -155,8 +180,11 @@ def get_release_notes(self) -> str: """ raise NotImplementedError + def blob_filename(self, ver) -> str: + return f"{self.name}-{self.blob_version_prefix}{ver}{self.filename_suffix}" + def remove_current_blob(self): - current_blob_path = f"{self.package}/{self.name}-{self.current_version}.tar.gz" + current_blob_path = f"{self.package}/{self.blob_filename(self.current_version)}" if self._check_blob_exists(current_blob_path): BoshHelper.remove_blob(current_blob_path) else: @@ -172,17 +200,17 @@ def _check_blob_exists(self, blob_path) -> bool: def update_packaging_file(self): """ - Writes the new dependency version and download-url into packages/haproxy/packaging + Writes the new dependency version and download-url into the versions file. """ - with open(PACKAGING_PATH.format(self.package), "r") as packaging_file: + with open(self.versions_file, "r") as f: replacement = "" - for line in packaging_file.readlines(): + for line in f.readlines(): if line.startswith(self.version_var_name): line = f"{self.version_var_name}={self.latest_release.version} # {self.latest_release.url}\n" replacement += line - with open(PACKAGING_PATH.format(self.package), "w") as packaging_file_write: - packaging_file_write.write(replacement) + with open(self.versions_file, "w") as f: + f.write(replacement) def open_pr_exists(self) -> bool: prs_exist = False @@ -208,7 +236,7 @@ def create_pr(self): self._update_file( self.remote_repo, - PACKAGING_PATH.format(self.package), + self.versions_file, self.pr_branch, f"Bump {self.name} version to {self.latest_release.version}", ) @@ -254,10 +282,9 @@ def _update_file(self, repo, path, branch, message): class GithubDependency(Dependency): tagname_prefix: str = "" - filename_suffix: str = ".tar.gz" def fetch_latest_release(self) -> Release: - repo_org_and_name = self.root_url.lstrip("https://github.com/") + repo_org_and_name = self.root_url.removeprefix("https://github.com/") repo = gh.get_repo(repo_org_and_name) releases = repo.get_releases() @@ -274,14 +301,14 @@ def get_release_download_url(rel): for rel in releases: if rel.prerelease: continue - current_raw = rel.tag_name.lstrip(self.tagname_prefix) + current_raw = rel.tag_name.removeprefix(self.tagname_prefix) current_version = version.parse(current_raw) if latest_version < current_version and current_raw.startswith(self.pinned_version): latest_version = current_version latest_release = Release( rel.name, get_release_download_url(rel), - f"{self.name}-{str(current_version)}{self.filename_suffix}", + self.blob_filename(current_version), current_version, ) @@ -333,6 +360,94 @@ def get_release_notes(self) -> str: return f"Make sure to check the [CHANGELOG]({self.changelog_url}) for any breaking changes." +@dataclass +class GolangDependency(Dependency): + """ + Handles Go toolchain downloads from go.dev/dl/. + Go binaries are named go1.X.Y.linux-amd64.tar.gz but stored as golang-X.Y.Z.tar.gz in blobs. + """ + + def fetch_latest_release(self) -> Release: + data = requests.get(self.root_url) + html = BeautifulSoup(data.text, "html.parser") + + versions = [] + links = [link for link in html.select("a") if "href" in link.attrs] + + pattern = rf"go({self.pinned_version}(?:\.[0-9]+)*)\.linux-amd64\.tar\.gz" + + for link in links: + match = re.search(pattern, link.attrs["href"]) + if match: + ver = version.parse(match.group(1)) + url = requests.compat.urljoin(self.root_url, link.attrs["href"]) + versions.append( + Release( + f"golang-{match.group(1)}", + url, + self.blob_filename(ver), + ver, + ) + ) + + if versions: + return sorted(versions, key=lambda r: r.version, reverse=True)[0] + + raise Exception(f"Failed to get latest {self.name} version from {self.root_url}") + + def get_release_notes(self) -> str: + return f"Make sure to check the [CHANGELOG](https://go.dev/doc/devel/release) for any breaking changes." + + +@dataclass +class GithubArchiveDependency(Dependency): + """ + For GitHub repos where we resolve versions from git tags and download the + archive tarball, rather than from published Releases with attached assets. + AWS-LC LTS point releases (e.g. 4.0.1) are tagged but not always published + as GitHub Releases, so tag-based resolution avoids silently missing a bump. + """ + + tagname_prefix: str = "" + + def fetch_latest_release(self) -> Release: + repo_org_and_name = self.root_url.removeprefix("https://github.com/") + repo = gh.get_repo(repo_org_and_name) + tags = repo.get_tags() + + latest_release = None + latest_version = version.parse("0.0.0") + + for tag in tags: + current_raw = tag.name.removeprefix(self.tagname_prefix) + if not current_raw.startswith(self.pinned_version): + continue + try: + current_version = version.parse(current_raw) + except version.InvalidVersion: + # tags that aren't plain version numbers (e.g. FIPS branch tags) + continue + if current_version.is_prerelease: + continue + if latest_version < current_version: + latest_version = current_version + url = f"{self.root_url}/archive/refs/tags/{tag.name}.tar.gz" + latest_release = Release( + tag.name, + url, + self.blob_filename(current_version), + current_version, + ) + + if latest_version == version.parse("0.0.0") or latest_release is None: + raise Exception(f"No tag found for '{self.root_url}'") + + return latest_release + + def get_release_notes(self) -> str: + return f"Make sure to check the [CHANGELOG]({self.root_url}/releases) for any breaking changes." + + @dataclass class HaproxyDependency(Dependency): def __post_init__(self): @@ -456,8 +571,14 @@ def cleanup_local_changes(): local_git.clean("-fx") -def main() -> None: - dependencies: List[Dependency] = [ +def _require_env(): + missing = [v for v in ("GCP_SERVICE_KEY", "GITHUB_COM_TOKEN", "PR_ORG", "PR_BASE", "PR_LABEL") if not os.environ.get(v)] + if missing: + raise SystemExit("Missing required environment variables: " + ", ".join(missing)) + + +def build_dependencies() -> List[Dependency]: + return [ WebLinkDependency( "keepalived", "KEEPALIVED_VERSION", @@ -500,9 +621,48 @@ def main() -> None: tagname_prefix="v", filename_suffix="", ), + # AWS-LC LTS line (v4.x). One source blob builds both the non-FIPS and + # FIPS variants; FIPS is a build-time flag, not a separate release. + # LTS tags ship as archive tarballs (no release assets), so use + # GithubArchiveDependency; blob_version_prefix keeps the aws-lc-v* name. + GithubArchiveDependency( + "aws-lc", + "AWS_LC_VERSION", + AWS_LC_VERSION, + "https://github.com/aws/aws-lc", + tagname_prefix="v", + blob_version_prefix="v", + versions_path=AWS_LC_VERSIONS_PATH, + ), + GithubDependency( + "cmake", + "CMAKE_VERSION", + CMAKE_VERSION, + "https://github.com/Kitware/CMake", + tagname_prefix="v", + # We ship the prebuilt Linux binary tarball, not the source. This + # both selects the right release asset and produces a blob name + # (cmake-X.Y.Z-linux-x86_64.tar.gz) matching the packaging scripts. + filename_suffix="-linux-x86_64.tar.gz", + versions_path=AWS_LC_VERSIONS_PATH, + ), + GolangDependency( + "golang", + "GOLANG_VERSION", + GOLANG_VERSION, + "https://go.dev/dl/", + versions_path=AWS_LC_VERSIONS_PATH, + ), ] - write_private_yaml() + +def main() -> None: + _require_env() + dependencies = build_dependencies() + + # private.yml (blobstore creds) is only needed to upload blobs, which a dry run skips. + if not DRY_RUN: + write_private_yaml() for dependency in dependencies: current_version = dependency.current_version @@ -513,6 +673,15 @@ def main() -> None: print(f"[{dependency.name}] already on the latest version: {latest_version} " f"(pinned: {dependency.pinned_version}.*)") continue + if DRY_RUN: + # Read-only report: announce the bump but touch nothing — no PR-exists check, + # download, bosh blob op, file edit, upload, PR, or git reset/clean. + print( + f"[{dependency.name}] Version-Bump required: {current_version} --> {latest_version} " + f"(dry-run: would download {latest_release.url} -> blob {latest_release.file})" + ) + continue + if dependency.open_pr_exists(): print(f"[{dependency.name}] Open bump PR exists (for branch: {dependency.pr_branch})") continue @@ -521,8 +690,7 @@ def main() -> None: dependency.remove_current_blob() latest_release.add_blob(dependency.package) dependency.update_packaging_file() - if not DRY_RUN: - BoshHelper.upload_blobs() + BoshHelper.upload_blobs() dependency.create_pr() # clear the working directory for the next dependency bump. diff --git a/ci/scripts/functions-ci.sh b/ci/scripts/functions-ci.sh index fa8e5465d..5d68f567b 100755 --- a/ci/scripts/functions-ci.sh +++ b/ci/scripts/functions-ci.sh @@ -54,6 +54,8 @@ function bosh_release() { echo "----- Creating candidate BOSH release..." bosh -n reset-release # in case dev_releases/ is in repo accidentally + # Single release: the committed tree bundles every SSL variant; the backend is + # selected at deploy time via ha_proxy.ssl_variant (see the acceptance harness). bosh create-release --force bosh upload-release --rebase release_final_version=$(spruce json dev_releases/*/index.yml | jq -r ".builds[].version" | sed -e "s%+.*%%") diff --git a/ci/scripts/requirements-test.txt b/ci/scripts/requirements-test.txt new file mode 100644 index 000000000..26b77f68b --- /dev/null +++ b/ci/scripts/requirements-test.txt @@ -0,0 +1,2 @@ +-r requirements.txt +pytest diff --git a/ci/scripts/shipit b/ci/scripts/shipit index 636b7b51a..7daa130c5 100755 --- a/ci/scripts/shipit +++ b/ci/scripts/shipit @@ -64,11 +64,18 @@ git submodule update --init --recursive --force cd - version() { - # extract the version variable $1 from the packaging script $2 (default 'haproxy') pattern='s/VERSION=(.*)(\s?#.*)/\1/p' - package=${2:-haproxy} - # extract version and remove all spaces - sed -n -E "${pattern//VERSION/${1:?}}" "${REPO_ROOT}/packages/${package}/packaging" | sed 's/ *//g' + package=${2:-} + if [[ -n "${package}" ]]; then + source_file="${REPO_ROOT}/packages/${package}/packaging" + sed -n -E "${pattern//VERSION/${1:?}}" "${source_file}" | sed 's/ *//g' + else + # AWS_LC_VERSION / CMAKE_VERSION / GOLANG_VERSION live in aws-lc-versions.sh; + # the rest in haproxy-versions.sh. Each var appears in exactly one, so search both. + sed -n -E "${pattern//VERSION/${1:?}}" \ + "${REPO_ROOT}/src/haproxy-versions.sh" \ + "${REPO_ROOT}/src/aws-lc-versions.sh" | sed 's/ *//g' + fi } HAPROXY_VERSION=$(version HAPROXY_VERSION) @@ -76,11 +83,21 @@ LUA_VERSION=$(version LUA_VERSION) SOCAT_VERSION=$(version SOCAT_VERSION) PCRE_VERSION=$(version PCRE_VERSION) KEEPALIVED_VERSION=$(version KEEPALIVED_VERSION keepalived) +AWS_LC_VERSION=$(version AWS_LC_VERSION) +CMAKE_VERSION=$(version CMAKE_VERSION) +GOLANG_VERSION=$(version GOLANG_VERSION) -VERSION="${VERSION_TO_CREATE}+${HAPROXY_VERSION}" +VERSION="${VERSION_TO_CREATE}+${HAPROXY_VERSION}-awslc-${AWS_LC_VERSION}" cd "${REPO_ROOT}" header "Create final release..." + +# Single release: the committed tree bundles every build — SSL variant (openssl, awslc, +# awslc-fips), each with and without the HAProxy community patches. One is selected at deploy +# time via ha_proxy.ssl_variant + ha_proxy.include_haproxy_patches (default openssl, unpatched). +# A plain create-release of the tree produces it. +bosh upload-blobs + bosh -n create-release --final --version "${VERSION}" bosh -n create-release "releases/${RELEASE_NAME}/${RELEASE_NAME}-${VERSION}.yml" \ --tarball "releases/${RELEASE_NAME}/${RELEASE_NAME}-${VERSION}.tgz" @@ -95,8 +112,6 @@ echo "SHA1=${SHA1}" export SHA256=$(sha256sum "${RELEASE_TGZ}" | head -n1 | awk '{print $1}') echo "SHA256=${SHA256}" - - mkdir -p "${RELEASE_ROOT}/artifacts" echo "v${VERSION}" > "${RELEASE_ROOT}/tag" echo "v${VERSION}" > "${RELEASE_ROOT}/name" @@ -119,7 +134,7 @@ cat >> "${RELEASE_ROOT}/notes.md" < ### Versions @@ -133,6 +148,9 @@ The following versions of upstream components are included in this haproxy-boshr | Lua | \`${LUA_VERSION}\` | | PCRE | \`${PCRE_VERSION}\` | | socat | \`${SOCAT_VERSION}\` | +| AWS-LC (LTS) | \`${AWS_LC_VERSION}\` | +| cmake | \`${CMAKE_VERSION}\` | +| Go | \`${GOLANG_VERSION}\` | ### Deployment \`\`\`yaml @@ -144,6 +162,10 @@ releases: # for deployments with sha256, use the following line instead: # sha1: "sha256:${SHA256}" + +# The release bundles every SSL variant; select one at deploy time (defaults to openssl, stock): +# ha_proxy.ssl_variant: openssl | awslc | awslc-fips +# ha_proxy.include_haproxy_patches: false | true # append the bundled community patches \`\`\` EOF @@ -167,47 +189,8 @@ pushd "${REPO_ROOT}" git add -A git status git commit -m "release v${VERSION}" - - # After creating a final release we will also create a dev release patches from haproxy-patches directory - echo "- haproxy/patches.tar.gz" >> packages/haproxy/spec - tar -czvf haproxy-patches.tar.gz haproxy-patches - bosh add-blob haproxy-patches.tar.gz haproxy/patches.tar.gz - bosh upload-blobs - - bosh -n create-release --force --version "${VERSION}-patched" \ - --tarball "../${RELEASE_NAME}-${VERSION}-patched.tgz" - - # Undo changes to repo from creating dev release - git clean -df - git reset --hard popd -mkdir -p "${RELEASE_ROOT}/artifacts-patched" -mv "${RELEASE_NAME}-${VERSION}-patched.tgz" "${RELEASE_ROOT}/artifacts-patched" - -PATCHED_RELEASE_TGZ=${RELEASE_ROOT}/artifacts-patched/${RELEASE_NAME}-${VERSION}-patched.tgz -# shellcheck disable=SC2155 -export PATCHED_SHA1=$(sha1sum "${PATCHED_RELEASE_TGZ}" | head -n1 | awk '{print $1}') -echo "PATCHED_SHA1=${PATCHED_SHA1}" -# shellcheck disable=SC2155 -export PATCHED_SHA256=$(sha256sum "${PATCHED_RELEASE_TGZ}" | head -n1 | awk '{print $1}') -echo "PATCHED_SHA256=${PATCHED_SHA256}" - -cat >> "${RELEASE_ROOT}/notes.md" < skipped + FakeTag("v4.2.0-rc1"), # prerelease -> skipped + ]) + monkeypatch.setattr(autobump, "gh", FakeGithub(repo)) + + dep = autobump.GithubArchiveDependency( + name="aws-lc", version_var_name="AWS_LC_VERSION", pinned_version="4", + root_url="https://github.com/aws/aws-lc", tagname_prefix="v", blob_version_prefix="v", + ) + rel = dep.fetch_latest_release() + assert str(rel.version) == "4.1.0" + assert rel.file == "aws-lc-v4.1.0.tar.gz" + assert rel.url == "https://github.com/aws/aws-lc/archive/refs/tags/v4.1.0.tar.gz" + + +# --- GolangDependency (go.dev HTML scrape) ----------------------------------------- +def test_golang_dependency_scrapes_pinned_minor(monkeypatch): + html = """ + go1.27.0 + go1.27.1 + go1.28.0 + """ + monkeypatch.setattr(autobump.requests, "get", lambda *_a, **_k: FakeResponse(html)) + + dep = autobump.GolangDependency( + name="golang", version_var_name="GOLANG_VERSION", pinned_version="1.27", + root_url="https://go.dev/dl/", + ) + rel = dep.fetch_latest_release() + assert str(rel.version) == "1.27.1" + assert rel.file == "golang-1.27.1.tar.gz" + + +# --- WebLinkDependency (generic download-page scrape) ------------------------------ +def test_weblink_dependency_scrape(monkeypatch): + html = """ + socat-1.8.0.0 + socat-1.8.0.1 + """ + monkeypatch.setattr(autobump.requests, "get", lambda *_a, **_k: FakeResponse(html)) + + dep = autobump.WebLinkDependency( + name="socat", version_var_name="SOCAT_VERSION", pinned_version="1", + root_url="http://www.dest-unreach.org/socat/download/", + ) + rel = dep.fetch_latest_release() + assert str(rel.version) == "1.8.0.1" + assert rel.file == "socat-1.8.0.1.tar.gz" + + +# --- HaproxyDependency (releases.json) --------------------------------------------- +def test_haproxy_dependency_reads_releases_json(monkeypatch): + payload = '{"latest_release": "3.2.26", "releases": {"3.2.26": {"file": "haproxy-3.2.26.tar.gz"}}}' + monkeypatch.setattr(autobump.requests, "get", lambda *_a, **_k: FakeResponse(payload)) + + dep = autobump.HaproxyDependency( + name="haproxy", version_var_name="HAPROXY_VERSION", pinned_version="3.2", + root_url="https://www.haproxy.org/download/{}/src", + ) + rel = dep.fetch_latest_release() + assert str(rel.version) == "3.2.26" + assert rel.file == "haproxy-3.2.26.tar.gz" + assert rel.url.endswith("/download/3.2/src/haproxy-3.2.26.tar.gz") + + +# --- current_version parsing (from the versions file) ------------------------------ +def test_current_version_parsed_from_versions_file(tmp_path): + vfile = tmp_path / "versions.sh" + vfile.write_text("FOO_VERSION=1.2.3 # https://example.invalid/foo-1.2.3.tar.gz\n") + dep = autobump.GithubDependency( + name="foo", version_var_name="FOO_VERSION", pinned_version="1", + root_url="https://github.com/o/r", versions_path=str(vfile), + ) + assert dep.current_version == version.parse("1.2.3") + + +# --- no-bump decision uses >= on parsed versions (sanity on the comparison) -------- +def test_version_comparison_semantics(): + assert version.parse("3.2.26") > version.parse("3.2.9") # not lexical + assert version.parse("10.45") > version.parse("10.9") + + +# --- main() side-effect gating by DRY_RUN ------------------------------------------ +class _FakeDep: + """A dependency that is 'behind', so main() would try to bump it.""" + name = "cmake" + pinned_version = "4" + package = "haproxy" + pr_branch = "cmake-auto-bump-master" + + def __init__(self, latest): + self._latest = latest + self.calls = [] + + @property + def current_version(self): + return version.parse("4.4.3") + + @property + def latest_release(self): + return self._latest + + def open_pr_exists(self): + self.calls.append("open_pr_exists") + return False + + def remove_current_blob(self): + self.calls.append("remove_current_blob") + + def update_packaging_file(self): + self.calls.append("update_packaging_file") + + def create_pr(self): + self.calls.append("create_pr") + + +def _wire_main(monkeypatch, dry_run): + """Stub every side-effecting hook so main() can run offline; return the call log + dep.""" + module_calls = [] + monkeypatch.setattr(autobump, "DRY_RUN", dry_run) + monkeypatch.setattr(autobump, "_require_env", lambda: None) + monkeypatch.setattr(autobump, "write_private_yaml", lambda: module_calls.append("write_private_yaml")) + monkeypatch.setattr(autobump, "wget", lambda *a, **k: module_calls.append("wget")) + monkeypatch.setattr(autobump, "cleanup_local_changes", lambda: module_calls.append("cleanup")) + monkeypatch.setattr(autobump.BoshHelper, "add_blob", classmethod(lambda cls, *a: module_calls.append("add_blob"))) + monkeypatch.setattr(autobump.BoshHelper, "remove_blob", classmethod(lambda cls, *a: module_calls.append("remove_blob"))) + monkeypatch.setattr(autobump.BoshHelper, "upload_blobs", classmethod(lambda cls: module_calls.append("upload_blobs"))) + rel = autobump.Release("cmake-4.4.4", "https://example.invalid/cmake-4.4.4.tar.gz", "cmake-4.4.4.tar.gz", version.parse("4.4.4")) + dep = _FakeDep(rel) + monkeypatch.setattr(autobump, "build_dependencies", lambda: [dep]) + return module_calls, dep + + +def test_dry_run_is_side_effect_free(monkeypatch): + module_calls, dep = _wire_main(monkeypatch, dry_run=True) + autobump.main() + # A behind dependency is reported but NOTHING is touched. + assert module_calls == [] + assert dep.calls == [] + + +def test_real_run_performs_the_bump(monkeypatch): + module_calls, dep = _wire_main(monkeypatch, dry_run=False) + autobump.main() + # The full bump pipeline runs, including the destructive cleanup. + assert "write_private_yaml" in module_calls + assert "wget" in module_calls # Release.download + assert "add_blob" in module_calls # Release.add_blob -> BoshHelper + assert "upload_blobs" in module_calls + assert "cleanup" in module_calls + assert dep.calls == ["open_pr_exists", "remove_current_blob", "update_packaging_file", "create_pr"] diff --git a/config/blobs.yml b/config/blobs.yml index 0d2325780..64a2d634d 100644 --- a/config/blobs.yml +++ b/config/blobs.yml @@ -1,3 +1,15 @@ +haproxy/aws-lc-v4.0.0.tar.gz: + size: 130854647 + object_id: d911b2d3-6b54-4621-7d49-fb71b48d0968 + sha: sha256:dec49e5c38dd8d3b4c2700c692bbb457a149cd6d23ad99463ce3612720c23bb0 +haproxy/cmake-4.4.3-linux-x86_64.tar.gz: + size: 64872980 + object_id: b0d691d9-69ed-4964-51e8-cfaa7848976f + sha: sha256:d6c83076c575bc00b823522ac974bda66d0af05d6ddc30e739c12385cf32c6cc +haproxy/golang-1.27.1.tar.gz: + size: 70553950 + object_id: 3b678ee3-040f-4cde-7c9a-8a94ca41ff4c + sha: sha256:63d339f0da5ab53635a56f2490a7984dfe12dfcff22ad749f63edaf590168445 haproxy/haproxy-3.2.26.tar.gz: size: 5203667 object_id: b8a0ebf0-e6bc-4486-7873-12805ca22ba3 diff --git a/docs/coredumps.md b/docs/coredumps.md index 611ea1f56..22b278765 100644 --- a/docs/coredumps.md +++ b/docs/coredumps.md @@ -48,10 +48,12 @@ Add the `set-dumpable` directive to the `global` section in `haproxy.config.erb` Core dump files are written to `/var/vcap/data/haproxy/`. -To analyze a core dump, use `gdb` with the HAProxy binary and the core file: +To analyze a core dump, use `gdb` with the HAProxy binary and the core file. The binary lives in the +variant package (`haproxy-openssl`, `haproxy-awslc`, `haproxy-awslc-fips`), so resolve the running +one via its pid rather than hardcoding a package name: ```bash -gdb /var/vcap/packages/haproxy/bin/haproxy /var/vcap/data/haproxy/core... +gdb "$(readlink -f /proc/"$(pgrep -n haproxy)"/exe)" /var/vcap/data/haproxy/core... ``` Useful GDB commands once loaded: diff --git a/jobs/haproxy/spec b/jobs/haproxy/spec index 7da59dee4..6c49a6506 100644 --- a/jobs/haproxy/spec +++ b/jobs/haproxy/spec @@ -4,7 +4,13 @@ name: haproxy description: "The HAProxy server can be used to terminate SSL in front of the Routers. Each HAProxy instance should point to multiple Routers." packages: -- haproxy +- haproxy-deps +- haproxy-openssl +- haproxy-openssl-patched +- haproxy-awslc +- haproxy-awslc-patched +- haproxy-awslc-fips +- haproxy-awslc-fips-patched - ttar templates: @@ -42,6 +48,14 @@ consumes: optional: true properties: + ha_proxy.ssl_variant: + default: openssl + description: | + SSL library the HAProxy binary links against: openssl (default) | awslc | awslc-fips. + ha_proxy.include_haproxy_patches: + default: false + description: | + Run the HAProxy build that includes the bundled community patches ha_proxy.pre_start_script: description: | This script will be appended to the pre-start script and run before the job starts. diff --git a/jobs/haproxy/templates/haproxy_wrapper.erb b/jobs/haproxy/templates/haproxy_wrapper.erb index bb928f1d6..5e8db6463 100755 --- a/jobs/haproxy/templates/haproxy_wrapper.erb +++ b/jobs/haproxy/templates/haproxy_wrapper.erb @@ -3,7 +3,32 @@ set -e -export PATH=$PATH:/var/vcap/packages/haproxy/bin:/var/vcap/packages/ttar/bin +# --- Select the HAProxy binary package ------------------------------------------------ +# The release bundles every SSL variant; two orthogonal properties choose the binary, whose +# package name follows the convention haproxy-[-patched]: +# ha_proxy.ssl_variant openssl (default) | awslc | awslc-fips +# ha_proxy.include_haproxy_patches false (default) | true -> append "-patched" +<%- + base = p("ha_proxy.ssl_variant").to_s.strip + patches = p("ha_proxy.include_haproxy_patches") + want = "haproxy-#{base}" + (patches ? "-patched" : "") +-%> +<%- unless %w[openssl awslc awslc-fips].include?(base) -%> +echo "$(date): ERROR: ha_proxy.ssl_variant='<%= base %>' is not a valid SSL variant (openssl, awslc, awslc-fips)" >&2 +exit 1 +<%- end -%> + +HAPROXY_PKG="/var/vcap/packages/<%= want %>" +if [ ! -x "${HAPROXY_PKG}/bin/haproxy" ]; then + avail="" + for d in /var/vcap/packages/haproxy-*; do + [ -x "$d/bin/haproxy" ] && avail="${avail} $(basename "$d" | sed 's/^haproxy-//')" + done + echo "$(date): ERROR: '<%= want %>' is not bundled in this release; available:${avail}" >&2 + exit 1 +fi + +export PATH=$PATH:${HAPROXY_PKG}/bin:/var/vcap/packages/ttar/bin CONFIG=/var/vcap/jobs/haproxy/config/haproxy.config PID_FILE=/var/vcap/sys/run/haproxy/haproxy.pid DRAIN_LOCK=/var/vcap/sys/run/haproxy/drain.lock diff --git a/jobs/haproxy/templates/pre-start.erb b/jobs/haproxy/templates/pre-start.erb index b511c8c8e..67c52d96b 100644 --- a/jobs/haproxy/templates/pre-start.erb +++ b/jobs/haproxy/templates/pre-start.erb @@ -13,13 +13,10 @@ if [ ! -e /usr/bin/python ] && [ -e /usr/bin/python3 ]; then sudo ln -s /usr/bin/python3 /usr/bin/python fi -if [ ! -e /usr/local/bin/hatop ]; then - sudo ln -s /var/vcap/packages/haproxy/hatop-wrapper /usr/local/bin/hatop -fi - -if [ ! -e /usr/local/bin/socat ]; then - sudo ln -s /var/vcap/packages/haproxy/bin/socat /usr/local/bin/socat -fi +# socat and the hatop wrapper live in the shared haproxy-deps package. +DEPS_PKG="/var/vcap/packages/haproxy-deps" +sudo ln -sf ${DEPS_PKG}/hatop-wrapper /usr/local/bin/hatop +sudo ln -sf ${DEPS_PKG}/bin/socat /usr/local/bin/socat <%- if_p("ha_proxy.pre_start_script") do |script| -%> # ha_proxy.pre_start_script {{{ diff --git a/packages/README.md b/packages/README.md new file mode 100644 index 000000000..cc1428847 --- /dev/null +++ b/packages/README.md @@ -0,0 +1,20 @@ +# `packages/` — the complete release + +This directory holds **every** package in the release. `bosh create-release` bundles all of them, so a +plain `bosh create-release` of the committed tree produces the one and only release — there is no +build-time assembly. + +- `haproxy-deps`, `ttar`, `keepalived` — shared, compiled once +- `haproxy-openssl`, `haproxy-openssl-patched`, `haproxy-awslc`, `haproxy-awslc-patched`, + `haproxy-awslc-fips`, `haproxy-awslc-fips-patched` — the six HAProxy binaries: each SSL + variant (openssl, awslc, awslc-fips) built with and without the community patches +- `aws-lc-src` (shared source), `aws-lc`, `aws-lc-fips`, `cmake` — crypto build dependencies + +The SSL backend is chosen at **deploy time** via the `ha_proxy.ssl_variant` property (default +`openssl`); see `jobs/haproxy/templates/haproxy_wrapper.erb`. Every deploy compiles all bundled +binaries; switching backends later is a property change + redeploy with no recompile. + +Dependencies are one-directional: every `haproxy-*` binary depends on `haproxy-deps`; `aws-lc` and +`aws-lc-fips` build from the shared `aws-lc-src` + `cmake`. HAProxy patches for the `-patched` +variants are plain source files under [`../src/haproxy-patches/`](../src/haproxy-patches/), applied at +compile time by `src/apply-patches.sh`. diff --git a/packages/aws-lc-fips/packaging b/packages/aws-lc-fips/packaging new file mode 100644 index 000000000..b9c5eef0c --- /dev/null +++ b/packages/aws-lc-fips/packaging @@ -0,0 +1,30 @@ +set -euxo pipefail + +source aws-lc-versions.sh + +export PATH=/var/vcap/packages/cmake/bin:$PATH + +# Install Go toolchain (required for FIPS delocate/inject_hash) +tar xzf haproxy/golang-${GOLANG_VERSION}.tar.gz -C ${BOSH_INSTALL_TARGET} +export GOROOT=${BOSH_INSTALL_TARGET}/go +export GOPATH=${BOSH_INSTALL_TARGET}/gopath +export GOCACHE=${BOSH_INSTALL_TARGET}/gocache +export PATH=${GOROOT}/bin:$PATH + +# Build from the shared aws-lc-src package (source bundled once, not per variant). +cp -a /var/vcap/packages/aws-lc-src/aws-lc-${AWS_LC_VERSION} . +pushd aws-lc-${AWS_LC_VERSION} + mkdir -p build && cd build + cmake -DCMAKE_BUILD_TYPE=Release \ + -DFIPS=1 \ + -DBUILD_SHARED_LIBS=0 \ + -DBUILD_TESTING=0 \ + -DBUILD_TOOL=0 \ + -DCMAKE_INSTALL_PREFIX=${BOSH_INSTALL_TARGET} \ + .. + make -j$(nproc) + make install +popd + +# Clean up Go toolchain to save disk space +rm -rf ${BOSH_INSTALL_TARGET}/go ${BOSH_INSTALL_TARGET}/gopath ${BOSH_INSTALL_TARGET}/gocache diff --git a/packages/aws-lc-fips/spec b/packages/aws-lc-fips/spec new file mode 100644 index 000000000..125fd6eb8 --- /dev/null +++ b/packages/aws-lc-fips/spec @@ -0,0 +1,8 @@ +--- +name: aws-lc-fips +dependencies: +- cmake +- aws-lc-src +files: +- haproxy/golang-*.tar.gz +- aws-lc-versions.sh diff --git a/packages/aws-lc-src/packaging b/packages/aws-lc-src/packaging new file mode 100644 index 000000000..14b8ff584 --- /dev/null +++ b/packages/aws-lc-src/packaging @@ -0,0 +1,8 @@ +set -euxo pipefail + +source aws-lc-versions.sh + +# Unpack the AWS-LC source ONCE into this package. Both the non-FIPS (aws-lc) and +# FIPS (aws-lc-fips) compile packages depend on aws-lc-src and build from here, so +# the ~130 MB source blob is bundled in exactly one package instead of each. +tar xzf haproxy/aws-lc-v${AWS_LC_VERSION}.tar.gz -C ${BOSH_INSTALL_TARGET} diff --git a/packages/aws-lc-src/spec b/packages/aws-lc-src/spec new file mode 100644 index 000000000..53021b343 --- /dev/null +++ b/packages/aws-lc-src/spec @@ -0,0 +1,5 @@ +--- +name: aws-lc-src +files: +- haproxy/aws-lc-v*.tar.gz +- aws-lc-versions.sh diff --git a/packages/aws-lc/packaging b/packages/aws-lc/packaging new file mode 100644 index 000000000..c54b593f0 --- /dev/null +++ b/packages/aws-lc/packaging @@ -0,0 +1,21 @@ +set -euxo pipefail + +source aws-lc-versions.sh + +export PATH=/var/vcap/packages/cmake/bin:$PATH + +# Build from the shared aws-lc-src package (source bundled once, not per variant). +cp -a /var/vcap/packages/aws-lc-src/aws-lc-${AWS_LC_VERSION} . +pushd aws-lc-${AWS_LC_VERSION} + mkdir -p build && cd build + cmake -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=0 \ + -DDISABLE_GO=1 \ + -DDISABLE_PERL=1 \ + -DBUILD_TESTING=0 \ + -DBUILD_TOOL=0 \ + -DCMAKE_INSTALL_PREFIX=${BOSH_INSTALL_TARGET} \ + .. + make -j$(nproc) + make install +popd diff --git a/packages/aws-lc/spec b/packages/aws-lc/spec new file mode 100644 index 000000000..880794d1a --- /dev/null +++ b/packages/aws-lc/spec @@ -0,0 +1,7 @@ +--- +name: aws-lc +dependencies: +- cmake +- aws-lc-src +files: +- aws-lc-versions.sh diff --git a/packages/cmake/packaging b/packages/cmake/packaging new file mode 100644 index 000000000..54efb4838 --- /dev/null +++ b/packages/cmake/packaging @@ -0,0 +1,7 @@ +set -euxo pipefail + +source aws-lc-versions.sh + +# Install prebuilt cmake binary tarball — no compile step needed. +tar xzf haproxy/cmake-${CMAKE_VERSION}-linux-x86_64.tar.gz +cp -r cmake-${CMAKE_VERSION}-linux-x86_64/. ${BOSH_INSTALL_TARGET}/ diff --git a/packages/cmake/spec b/packages/cmake/spec new file mode 100644 index 000000000..ac8dfc416 --- /dev/null +++ b/packages/cmake/spec @@ -0,0 +1,5 @@ +--- +name: cmake +files: +- haproxy/cmake-*.tar.gz +- aws-lc-versions.sh diff --git a/packages/haproxy-awslc-fips-patched/packaging b/packages/haproxy-awslc-fips-patched/packaging new file mode 100644 index 000000000..4fad01848 --- /dev/null +++ b/packages/haproxy-awslc-fips-patched/packaging @@ -0,0 +1,5 @@ +set -euxo pipefail + +source haproxy-versions.sh +SSL_MAKE_FLAGS="USE_OPENSSL_AWSLC=1 SSL_INC=/var/vcap/packages/aws-lc-fips/include SSL_LIB=/var/vcap/packages/aws-lc-fips/lib" +source build-haproxy.sh diff --git a/packages/haproxy-awslc-fips-patched/spec b/packages/haproxy-awslc-fips-patched/spec new file mode 100644 index 000000000..a94a011b5 --- /dev/null +++ b/packages/haproxy-awslc-fips-patched/spec @@ -0,0 +1,11 @@ +--- +name: haproxy-awslc-fips-patched +dependencies: +- haproxy-deps +- aws-lc-fips +files: +- haproxy/haproxy-*.tar.gz +- haproxy-patches/*.patch +- haproxy-versions.sh +- apply-patches.sh +- build-haproxy.sh diff --git a/packages/haproxy-awslc-fips/packaging b/packages/haproxy-awslc-fips/packaging new file mode 100644 index 000000000..4fad01848 --- /dev/null +++ b/packages/haproxy-awslc-fips/packaging @@ -0,0 +1,5 @@ +set -euxo pipefail + +source haproxy-versions.sh +SSL_MAKE_FLAGS="USE_OPENSSL_AWSLC=1 SSL_INC=/var/vcap/packages/aws-lc-fips/include SSL_LIB=/var/vcap/packages/aws-lc-fips/lib" +source build-haproxy.sh diff --git a/packages/haproxy-awslc-fips/spec b/packages/haproxy-awslc-fips/spec new file mode 100644 index 000000000..12aa6f42e --- /dev/null +++ b/packages/haproxy-awslc-fips/spec @@ -0,0 +1,9 @@ +--- +name: haproxy-awslc-fips +dependencies: +- haproxy-deps +- aws-lc-fips +files: +- haproxy/haproxy-*.tar.gz +- haproxy-versions.sh +- build-haproxy.sh diff --git a/packages/haproxy-awslc-patched/packaging b/packages/haproxy-awslc-patched/packaging new file mode 100644 index 000000000..640430ed0 --- /dev/null +++ b/packages/haproxy-awslc-patched/packaging @@ -0,0 +1,5 @@ +set -euxo pipefail + +source haproxy-versions.sh +SSL_MAKE_FLAGS="USE_OPENSSL_AWSLC=1 SSL_INC=/var/vcap/packages/aws-lc/include SSL_LIB=/var/vcap/packages/aws-lc/lib" +source build-haproxy.sh diff --git a/packages/haproxy-awslc-patched/spec b/packages/haproxy-awslc-patched/spec new file mode 100644 index 000000000..3e1653342 --- /dev/null +++ b/packages/haproxy-awslc-patched/spec @@ -0,0 +1,11 @@ +--- +name: haproxy-awslc-patched +dependencies: +- haproxy-deps +- aws-lc +files: +- haproxy/haproxy-*.tar.gz +- haproxy-patches/*.patch +- haproxy-versions.sh +- apply-patches.sh +- build-haproxy.sh diff --git a/packages/haproxy-awslc/packaging b/packages/haproxy-awslc/packaging new file mode 100644 index 000000000..640430ed0 --- /dev/null +++ b/packages/haproxy-awslc/packaging @@ -0,0 +1,5 @@ +set -euxo pipefail + +source haproxy-versions.sh +SSL_MAKE_FLAGS="USE_OPENSSL_AWSLC=1 SSL_INC=/var/vcap/packages/aws-lc/include SSL_LIB=/var/vcap/packages/aws-lc/lib" +source build-haproxy.sh diff --git a/packages/haproxy-awslc/spec b/packages/haproxy-awslc/spec new file mode 100644 index 000000000..9bbe8b5b0 --- /dev/null +++ b/packages/haproxy-awslc/spec @@ -0,0 +1,9 @@ +--- +name: haproxy-awslc +dependencies: +- haproxy-deps +- aws-lc +files: +- haproxy/haproxy-*.tar.gz +- haproxy-versions.sh +- build-haproxy.sh diff --git a/packages/haproxy-deps/packaging b/packages/haproxy-deps/packaging new file mode 100644 index 000000000..6c2ac8764 --- /dev/null +++ b/packages/haproxy-deps/packaging @@ -0,0 +1,36 @@ +set -euxo pipefail + +source haproxy-versions.sh + +mkdir ${BOSH_INSTALL_TARGET}/bin + +echo "Extracting lua..." +tar xzf haproxy/lua-${LUA_VERSION}.tar.gz +pushd lua-${LUA_VERSION} + make linux install INSTALL_TOP=${BOSH_INSTALL_TARGET} +popd + +echo "Extracting pcre..." +tar xzf haproxy/pcre2-${PCRE_VERSION}.tar.gz +pushd pcre2-${PCRE_VERSION} + ./configure \ + --enable-jit \ + --prefix ${BOSH_INSTALL_TARGET} + make + make install +popd + +echo "Installing socat..." +tar xzf haproxy/socat-${SOCAT_VERSION}.tar.gz +pushd socat-${SOCAT_VERSION} + ./configure + make + cp socat ${BOSH_INSTALL_TARGET}/bin + chmod 755 ${BOSH_INSTALL_TARGET}/bin/socat +popd + +echo "Installing hatop..." +cp haproxy/hatop-${HATOP_VERSION} ${BOSH_INSTALL_TARGET}/bin/hatop +chmod 755 ${BOSH_INSTALL_TARGET}/bin/hatop +cp hatop-wrapper ${BOSH_INSTALL_TARGET}/ +chmod 755 ${BOSH_INSTALL_TARGET}/hatop-wrapper diff --git a/packages/haproxy/spec b/packages/haproxy-deps/spec similarity index 74% rename from packages/haproxy/spec rename to packages/haproxy-deps/spec index 65c277991..b1bf0b687 100644 --- a/packages/haproxy/spec +++ b/packages/haproxy-deps/spec @@ -1,9 +1,9 @@ --- -name: haproxy +name: haproxy-deps files: -- haproxy/haproxy-*.tar.gz - haproxy/pcre2-*.tar.gz - haproxy/socat-*.tar.gz - haproxy/lua-*.tar.gz - haproxy/hatop-* - hatop-wrapper +- haproxy-versions.sh diff --git a/packages/haproxy-openssl-patched/packaging b/packages/haproxy-openssl-patched/packaging new file mode 100644 index 000000000..f403c9eaf --- /dev/null +++ b/packages/haproxy-openssl-patched/packaging @@ -0,0 +1,5 @@ +set -euxo pipefail + +source haproxy-versions.sh +SSL_MAKE_FLAGS="USE_OPENSSL=1" +source build-haproxy.sh diff --git a/packages/haproxy-openssl-patched/spec b/packages/haproxy-openssl-patched/spec new file mode 100644 index 000000000..0e29f7f54 --- /dev/null +++ b/packages/haproxy-openssl-patched/spec @@ -0,0 +1,10 @@ +--- +name: haproxy-openssl-patched +dependencies: +- haproxy-deps +files: +- haproxy/haproxy-*.tar.gz +- haproxy-patches/*.patch +- haproxy-versions.sh +- apply-patches.sh +- build-haproxy.sh diff --git a/packages/haproxy-openssl/packaging b/packages/haproxy-openssl/packaging new file mode 100644 index 000000000..f403c9eaf --- /dev/null +++ b/packages/haproxy-openssl/packaging @@ -0,0 +1,5 @@ +set -euxo pipefail + +source haproxy-versions.sh +SSL_MAKE_FLAGS="USE_OPENSSL=1" +source build-haproxy.sh diff --git a/packages/haproxy-openssl/spec b/packages/haproxy-openssl/spec new file mode 100644 index 000000000..1e01dec98 --- /dev/null +++ b/packages/haproxy-openssl/spec @@ -0,0 +1,8 @@ +--- +name: haproxy-openssl +dependencies: +- haproxy-deps +files: +- haproxy/haproxy-*.tar.gz +- haproxy-versions.sh +- build-haproxy.sh diff --git a/packages/haproxy/packaging b/packages/haproxy/packaging deleted file mode 100644 index 5724031b9..000000000 --- a/packages/haproxy/packaging +++ /dev/null @@ -1,72 +0,0 @@ -# abort script on failures -set -euxo pipefail - - -LUA_VERSION=5.4.9 # https://www.lua.org/ftp/lua-5.4.9.tar.gz - -PCRE_VERSION=10.49 # https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.49/pcre2-10.49.tar.gz - -SOCAT_VERSION=1.8.1.3 # http://www.dest-unreach.org/socat/download/socat-1.8.1.3.tar.gz - -HAPROXY_VERSION=3.2.26 # https://www.haproxy.org/download/3.2/src/haproxy-3.2.26.tar.gz - -HATOP_VERSION=0.8.2 # https://github.com/jhunt/hatop/releases/download/v0.8.2/hatop - -mkdir ${BOSH_INSTALL_TARGET}/bin - -echo "Extracting lua..." -tar xzf haproxy/lua-${LUA_VERSION}.tar.gz -pushd lua-${LUA_VERSION} - make linux install INSTALL_TOP=${BOSH_INSTALL_TARGET} -popd - -echo "Extracting pcre..." -tar xzf haproxy/pcre2-${PCRE_VERSION}.tar.gz -pushd pcre2-${PCRE_VERSION} - ./configure \ - --enable-jit \ - --prefix ${BOSH_INSTALL_TARGET} - make - make install -popd - -echo "Installing socat..." -tar xzf haproxy/socat-${SOCAT_VERSION}.tar.gz -pushd socat-${SOCAT_VERSION} - ./configure - make - cp socat ${BOSH_INSTALL_TARGET}/bin - chmod 755 ${BOSH_INSTALL_TARGET}/bin/socat -popd - -echo "Unpacking HAproxy..." -tar xf haproxy/haproxy-${HAPROXY_VERSION}.tar.gz -pushd haproxy-${HAPROXY_VERSION} - if [ -f ../haproxy/patches.tar.gz ]; then - mkdir -p ${BOSH_INSTALL_TARGET}/applied-patches - tar xf ../haproxy/patches.tar.gz - - for patchfile in haproxy-patches/*.patch; do - echo "Applying patch file ${patchfile}" - - # Conservatively limit patch fuzz factor to 0 to reduce chance of faulty patch - patch -F 0 -p0 < ${patchfile} - - # Save patches in install target for inspection later - cp ${patchfile} ${BOSH_INSTALL_TARGET}/applied-patches - done - - rm -r haproxy-patches - fi - - echo "Installing HAproxy..." - make TARGET=linux-glibc USE_PROMEX=1 USE_OPENSSL=1 USE_PCRE2=1 USE_PCRE2_JIT=yes USE_STATIC_PCRE2=1 USE_ZLIB=1 PCRE2DIR=${BOSH_INSTALL_TARGET} USE_LUA=1 LUA_LIB=${BOSH_INSTALL_TARGET}/lib LUA_INC=${BOSH_INSTALL_TARGET}/include - cp haproxy ${BOSH_INSTALL_TARGET}/bin/ - chmod 755 ${BOSH_INSTALL_TARGET}/bin/haproxy -popd - -echo "Installing hatop..." -cp haproxy/hatop-${HATOP_VERSION} ${BOSH_INSTALL_TARGET}/bin/hatop -chmod 755 ${BOSH_INSTALL_TARGET}/bin/hatop -cp hatop-wrapper ${BOSH_INSTALL_TARGET}/ -chmod 755 ${BOSH_INSTALL_TARGET}/hatop-wrapper diff --git a/scripts/dev-build.sh b/scripts/dev-build.sh new file mode 100755 index 000000000..a89901b75 --- /dev/null +++ b/scripts/dev-build.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash +# +# dev-build.sh +# +# Builds the HAProxy release locally and uploads it to the BOSH director. +# +# Usage: ./scripts/dev-build.sh [--upload-only] [--version BASE] [--output-dir DIR] +## +# Versioning: +# Each invocation produces a release version of the form +dev-awslc-. +# e.g. "16.9.0+dev-awslc-4.0.0.1779286286". BASE defaults to the highest existing final release in +# releases/haproxy/ and can be overridden with --version. Each run uses a fresh timestamp. +# +# Examples: +# ./scripts/dev-build.sh # build and upload, BASE=highest final release +# ./scripts/dev-build.sh --version 17.0.0 # same, and override BASE +# ./scripts/dev-build.sh --upload-only # no build, only upload everything in builds/ + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR/.." + +# Pull in AWS_LC_VERSION so it can be embedded in the dev version +# shellcheck disable=SC1091 +source src/aws-lc-versions.sh + +UPLOAD_ONLY=false +BASE_VERSION="" +OUTPUT_DIR="./builds" + +while [[ $# -gt 0 ]]; do + case "$1" in + --upload-only) + UPLOAD_ONLY=true + shift + ;; + --version) + BASE_VERSION="$2" + shift 2 + ;; + --output-dir) + OUTPUT_DIR="$2" + shift 2 + ;; + *) + echo "Unknown argument: $1" >&2 + exit 1 + ;; + esac +done + +# Derive base version from the highest existing final release if --version not given. +if [[ -z "$BASE_VERSION" ]]; then + BASE_VERSION=$( + ls releases/haproxy/haproxy-*.yml 2>/dev/null \ + | sed 's|.*/haproxy-||;s|\.yml$||;s|+.*||' \ + | sort -V \ + | tail -1 + ) + BASE_VERSION="${BASE_VERSION:-0.0.0}" +fi + +TIMESTAMP=$(date +%s) +mkdir -p "$OUTPUT_DIR" + +if [[ "$UPLOAD_ONLY" == false ]]; then + VERSION="${BASE_VERSION}+dev-awslc-${AWS_LC_VERSION}.${TIMESTAMP}" + TARBALL="$OUTPUT_DIR/haproxy-${VERSION}.tgz" + + echo "" + echo "========================================" + echo " Building: haproxy (version: $VERSION)" + echo "========================================" + echo "" + + bosh -n create-release --force \ + --name "haproxy" \ + --version "$VERSION" \ + --tarball "$TARBALL" + + echo " -> $TARBALL" +fi + +# --- Upload release(s) --- +echo "" +echo "========================================" +echo " Uploading releases to BOSH director" +echo "========================================" +echo "" + +if [[ "$UPLOAD_ONLY" == true ]]; then + upload_glob="$OUTPUT_DIR/haproxy-*.tgz" +else + upload_glob="$OUTPUT_DIR/haproxy-*.${TIMESTAMP}.tgz" +fi + +shopt -s nullglob +uploaded=0 +for tgz in $upload_glob; do + echo "Uploading: $tgz" + bosh upload-release "$tgz" --fix + uploaded=$((uploaded + 1)) +done +shopt -u nullglob + +if [[ $uploaded -eq 0 ]]; then + echo "No tarballs matching '$upload_glob' to upload." >&2 + exit 1 +fi + +echo "" +echo "Done." diff --git a/spec/haproxy/templates/haproxy_wrapper_spec.rb b/spec/haproxy/templates/haproxy_wrapper_spec.rb new file mode 100644 index 000000000..ae6baefb6 --- /dev/null +++ b/spec/haproxy/templates/haproxy_wrapper_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'rspec' + +# The wrapper composes the HAProxy binary package from two orthogonal properties: +# ha_proxy.ssl_variant openssl (default) | awslc | awslc-fips +# ha_proxy.include_haproxy_patches false (default) | true -> append "-patched" +# yielding /var/vcap/packages/haproxy-[-patched]. The package name is composed +# at render time, so these specs assert the rendered path + the 3-value validation. +describe 'bin/haproxy_wrapper' do + let(:template) { haproxy_job.template('bin/haproxy_wrapper') } + + def render(props) + template.render({ 'ha_proxy' => props }) + end + + it 'defaults to haproxy-openssl when nothing is set' do + expect(render({})).to include('HAPROXY_PKG="/var/vcap/packages/haproxy-openssl"') + end + + it 'selects the plain variant package' do + expect(render({ 'ssl_variant' => 'awslc' })).to include('HAPROXY_PKG="/var/vcap/packages/haproxy-awslc"') + expect(render({ 'ssl_variant' => 'awslc-fips' })).to include('HAPROXY_PKG="/var/vcap/packages/haproxy-awslc-fips"') + end + + it 'appends -patched when include_haproxy_patches is true' do + expect(render({ 'ssl_variant' => 'awslc', 'include_haproxy_patches' => true })) + .to include('HAPROXY_PKG="/var/vcap/packages/haproxy-awslc-patched"') + end + + it 'patches the openssl default when only include_haproxy_patches is set' do + expect(render({ 'include_haproxy_patches' => true })) + .to include('HAPROXY_PKG="/var/vcap/packages/haproxy-openssl-patched"') + end + + it 'rejects an invalid ssl_variant' do + out = render({ 'ssl_variant' => 'bogus' }) + expect(out).to include("ha_proxy.ssl_variant='bogus' is not a valid SSL variant") + expect(out).to include('exit 1') + end + + it 'exports the selected package onto PATH' do + expect(render({})).to include('export PATH=$PATH:${HAPROXY_PKG}/bin') + end +end diff --git a/src/apply-patches.sh b/src/apply-patches.sh new file mode 100644 index 000000000..06bbc3d9d --- /dev/null +++ b/src/apply-patches.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Applies the HAProxy patches shipped as package source files (src/haproxy-patches/*.patch). +# +# Sourced (not executed) by the patched variant packaging scripts from within +# the unpacked HAProxy source tree, so patches apply to the current directory. +# Requires: +# PKG_ROOT - the package compile root (where haproxy-patches/ lives) +# BOSH_INSTALL_TARGET - set by BOSH; applied patches are copied here for inspection +mkdir -p ${BOSH_INSTALL_TARGET}/applied-patches + +for patchfile in ${PKG_ROOT}/haproxy-patches/*.patch; do + echo "Applying patch file ${patchfile}" + # Conservatively limit patch fuzz factor to 0 to reduce chance of faulty patch + patch -F 0 -p0 < ${patchfile} + # Save patches in install target for inspection later + cp ${patchfile} ${BOSH_INSTALL_TARGET}/applied-patches +done diff --git a/src/aws-lc-versions.sh b/src/aws-lc-versions.sh new file mode 100644 index 000000000..eb92d7574 --- /dev/null +++ b/src/aws-lc-versions.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Version definitions for the AWS-LC / crypto packages (cmake, aws-lc, aws-lc-fips). +# +# Kept separate from haproxy-versions.sh on purpose: BOSH fingerprints each +# package by the contents of the files it bundles. If these versions lived in +# haproxy-versions.sh (which the crypto packages would then bundle), every +# HAProxy/lua/pcre/socat/hatop bump would change the crypto packages' +# fingerprints and force an unnecessary AWS-LC recompile With this +# split, the aws-lc/cmake fingerprints only change when a crypto version does, +# so the director reuses the cached compiled artifact across HAProxy bumps. +# Maintained automatically by ci/scripts/autobump-dependencies.py — do not edit by hand. +AWS_LC_VERSION=4.0.0 # https://github.com/aws/aws-lc/archive/refs/tags/v4.0.0.tar.gz (LTS line; builds both FIPS and non-FIPS) +CMAKE_VERSION=4.4.3 # https://github.com/Kitware/CMake/releases/download/v4.4.3/cmake-4.4.3-linux-x86_64.tar.gz +GOLANG_VERSION=1.27.1 # https://go.dev/dl/go1.27.1.linux-amd64.tar.gz diff --git a/src/build-haproxy.sh b/src/build-haproxy.sh new file mode 100644 index 000000000..7f02b07b8 --- /dev/null +++ b/src/build-haproxy.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Shared HAProxy compile, sourced by every haproxy- packaging script. +# +# The caller sets SSL_MAKE_FLAGS (the only thing that differs between SSL +# backends) before sourcing this. Bundled HAProxy patches are applied when the +# package ships patch files under haproxy-patches/ — that presence is the ONLY +# thing distinguishing a -patched package from its twin, so the -patched and base +# packaging scripts are identical and this logic lives in one place. +# +# Requires, with the package root as CWD: +# HAPROXY_VERSION from haproxy-versions.sh (sourced by the caller) +# SSL_MAKE_FLAGS e.g. "USE_OPENSSL=1" or +# "USE_OPENSSL_AWSLC=1 SSL_INC=/include SSL_LIB=/lib" +PKG_ROOT=$(pwd) +DEPS_DIR=/var/vcap/packages/haproxy-deps + +mkdir -p ${BOSH_INSTALL_TARGET}/bin + +echo "Unpacking HAproxy..." +tar xf haproxy/haproxy-${HAPROXY_VERSION}.tar.gz +pushd haproxy-${HAPROXY_VERSION} + # -patched packages ship patch files under haproxy-patches/; apply them when present. + if ls ${PKG_ROOT}/haproxy-patches/*.patch >/dev/null 2>&1; then + source ${PKG_ROOT}/apply-patches.sh + fi + + echo "Installing HAproxy..." + make TARGET=linux-glibc USE_PROMEX=1 ${SSL_MAKE_FLAGS} \ + USE_PCRE2=1 USE_PCRE2_JIT=yes USE_STATIC_PCRE2=1 USE_ZLIB=1 \ + PCRE2DIR=${DEPS_DIR} \ + USE_LUA=1 LUA_LIB=${DEPS_DIR}/lib LUA_INC=${DEPS_DIR}/include + cp haproxy ${BOSH_INSTALL_TARGET}/bin/ + chmod 755 ${BOSH_INSTALL_TARGET}/bin/haproxy +popd diff --git a/haproxy-patches/disable-rfc-6455-compliance.patch b/src/haproxy-patches/disable-rfc-6455-compliance.patch similarity index 100% rename from haproxy-patches/disable-rfc-6455-compliance.patch rename to src/haproxy-patches/disable-rfc-6455-compliance.patch diff --git a/src/haproxy-versions.sh b/src/haproxy-versions.sh new file mode 100644 index 000000000..ec90ebc60 --- /dev/null +++ b/src/haproxy-versions.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Version definitions for HAProxy and its bundled dependencies (lua, pcre, +# socat, hatop). Sourced by the haproxy binary/deps packaging scripts. +# +# AWS-LC / cmake / golang versions live in src/aws-lc-versions.sh instead, so +# that bumping anything here does not re-fingerprint the crypto packages and +# trigger an unnecessary AWS-LC recompile. Consumers that need everything (the +# monolithic packages/haproxy/packaging and the CI scripts) source both files. +# Maintained automatically by ci/scripts/autobump-dependencies.py — do not edit by hand. +HAPROXY_VERSION=3.2.26 # https://www.haproxy.org/download/3.2/src/haproxy-3.2.26.tar.gz +LUA_VERSION=5.4.9 # https://www.lua.org/ftp/lua-5.4.9.tar.gz +PCRE_VERSION=10.49 # https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.49/pcre2-10.49.tar.gz +SOCAT_VERSION=1.8.1.3 # http://www.dest-unreach.org/socat/download/socat-1.8.1.3.tar.gz +HATOP_VERSION=0.8.2 # https://github.com/jhunt/hatop/releases/download/v0.8.2/hatop From 48ad09c74d76ba22e1d94b3f3de5b6e2dee27a6f Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Fri, 23 Oct 2026 12:12:23 +0200 Subject: [PATCH 02/13] Fix missing update of hatop location in hatop-wrapper --- src/hatop-wrapper | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hatop-wrapper b/src/hatop-wrapper index 5e1a5ccd0..7bda776ab 100644 --- a/src/hatop-wrapper +++ b/src/hatop-wrapper @@ -1,9 +1,9 @@ #!/bin/bash if [[ -z "${1:-}" ]]; then if [[ -e /var/vcap/sys/run/haproxy/stats.sock ]]; then - exec /var/vcap/packages/haproxy/bin/hatop -s /var/vcap/sys/run/haproxy/stats.sock + exec /var/vcap/packages/haproxy-deps/bin/hatop -s /var/vcap/sys/run/haproxy/stats.sock elif [[ -e /var/vcap/sys/run/haproxy/stats1.sock ]]; then - exec /var/vcap/packages/haproxy/bin/hatop -s /var/vcap/sys/run/haproxy/stats1.sock + exec /var/vcap/packages/haproxy-deps/bin/hatop -s /var/vcap/sys/run/haproxy/stats1.sock fi fi -exec /var/vcap/packages/haproxy/bin/hatop "$@" +exec /var/vcap/packages/haproxy-deps/bin/hatop "$@" From a49c9bae87fe9fe2c86302e118368b6e62aa9240 Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Fri, 23 Oct 2026 12:28:04 +0200 Subject: [PATCH 03/13] Remove ttar submodule, move to haoproxy-boshrelease --- .gitmodules | 3 - ci/scripts/functions-ci.sh | 3 - ci/scripts/shipit | 2 - jobs/haproxy/spec | 1 - jobs/haproxy/templates/haproxy_wrapper.erb | 2 +- packages/README.md | 2 +- packages/haproxy-deps/packaging | 4 ++ packages/haproxy-deps/spec | 1 + packages/ttar/packaging | 11 --- packages/ttar/spec | 5 -- src/ttar | 1 - src/ttar/LICENSE | 21 ++++++ src/ttar/README.md | 80 ++++++++++++++++++++++ src/ttar/ttar | 34 +++++++++ 14 files changed, 142 insertions(+), 28 deletions(-) delete mode 100644 .gitmodules delete mode 100644 packages/ttar/packaging delete mode 100644 packages/ttar/spec delete mode 160000 src/ttar create mode 100644 src/ttar/LICENSE create mode 100644 src/ttar/README.md create mode 100755 src/ttar/ttar diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 2f70e4059..000000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "src/ttar"] - path = src/ttar - url = https://github.com/jhunt/ttar.git diff --git a/ci/scripts/functions-ci.sh b/ci/scripts/functions-ci.sh index 5d68f567b..616ce77f2 100755 --- a/ci/scripts/functions-ci.sh +++ b/ci/scripts/functions-ci.sh @@ -44,10 +44,7 @@ function build_image() { function git_pull() { cd "${REPO_ROOT:?required}" - echo "----- Pulling in any git submodules..." git config --global --add safe.directory /repo - git config --global --add safe.directory /repo/src/ttar - git submodule update --init --recursive --force } function bosh_release() { diff --git a/ci/scripts/shipit b/ci/scripts/shipit index 7daa130c5..19286ef6e 100755 --- a/ci/scripts/shipit +++ b/ci/scripts/shipit @@ -59,8 +59,6 @@ blobstore: ${PADDED_GCP_SERVICE_KEY} YAML -header "Pulling in any git submodules..." -git submodule update --init --recursive --force cd - version() { diff --git a/jobs/haproxy/spec b/jobs/haproxy/spec index 6c49a6506..2afc912d3 100644 --- a/jobs/haproxy/spec +++ b/jobs/haproxy/spec @@ -11,7 +11,6 @@ packages: - haproxy-awslc-patched - haproxy-awslc-fips - haproxy-awslc-fips-patched -- ttar templates: haproxy_wrapper.erb: bin/haproxy_wrapper diff --git a/jobs/haproxy/templates/haproxy_wrapper.erb b/jobs/haproxy/templates/haproxy_wrapper.erb index 5e8db6463..fbbb22c49 100755 --- a/jobs/haproxy/templates/haproxy_wrapper.erb +++ b/jobs/haproxy/templates/haproxy_wrapper.erb @@ -28,7 +28,7 @@ if [ ! -x "${HAPROXY_PKG}/bin/haproxy" ]; then exit 1 fi -export PATH=$PATH:${HAPROXY_PKG}/bin:/var/vcap/packages/ttar/bin +export PATH=$PATH:${HAPROXY_PKG}/bin:/var/vcap/packages/haproxy-deps/bin CONFIG=/var/vcap/jobs/haproxy/config/haproxy.config PID_FILE=/var/vcap/sys/run/haproxy/haproxy.pid DRAIN_LOCK=/var/vcap/sys/run/haproxy/drain.lock diff --git a/packages/README.md b/packages/README.md index cc1428847..70b695cb5 100644 --- a/packages/README.md +++ b/packages/README.md @@ -4,7 +4,7 @@ This directory holds **every** package in the release. `bosh create-release` bun plain `bosh create-release` of the committed tree produces the one and only release — there is no build-time assembly. -- `haproxy-deps`, `ttar`, `keepalived` — shared, compiled once +- `haproxy-deps` (lua, pcre2, socat, hatop, and the `ttar` helper), `keepalived` — shared, compiled once - `haproxy-openssl`, `haproxy-openssl-patched`, `haproxy-awslc`, `haproxy-awslc-patched`, `haproxy-awslc-fips`, `haproxy-awslc-fips-patched` — the six HAProxy binaries: each SSL variant (openssl, awslc, awslc-fips) built with and without the community patches diff --git a/packages/haproxy-deps/packaging b/packages/haproxy-deps/packaging index 6c2ac8764..fafc8d72d 100644 --- a/packages/haproxy-deps/packaging +++ b/packages/haproxy-deps/packaging @@ -34,3 +34,7 @@ cp haproxy/hatop-${HATOP_VERSION} ${BOSH_INSTALL_TARGET}/bin/hatop chmod 755 ${BOSH_INSTALL_TARGET}/bin/hatop cp hatop-wrapper ${BOSH_INSTALL_TARGET}/ chmod 755 ${BOSH_INSTALL_TARGET}/hatop-wrapper + +echo "Installing ttar..." +cp ttar/ttar ${BOSH_INSTALL_TARGET}/bin/ttar +chmod 755 ${BOSH_INSTALL_TARGET}/bin/ttar diff --git a/packages/haproxy-deps/spec b/packages/haproxy-deps/spec index b1bf0b687..118d5394f 100644 --- a/packages/haproxy-deps/spec +++ b/packages/haproxy-deps/spec @@ -6,4 +6,5 @@ files: - haproxy/lua-*.tar.gz - haproxy/hatop-* - hatop-wrapper +- ttar/ttar - haproxy-versions.sh diff --git a/packages/ttar/packaging b/packages/ttar/packaging deleted file mode 100644 index 69b2608d9..000000000 --- a/packages/ttar/packaging +++ /dev/null @@ -1,11 +0,0 @@ -set -e # exit immediately if a simple command exits with a non-zero status -set -u # report the usage of uninitialized variables - - # Available variables -# $BOSH_COMPILE_TARGET - where this package & spec'd source files are available -# $BOSH_INSTALL_TARGET - where you copy/install files to be included in package -export HOME=/var/vcap - -mkdir -p ${BOSH_INSTALL_TARGET}/bin -cp ttar/ttar ${BOSH_INSTALL_TARGET}/bin -chmod 0755 ${BOSH_INSTALL_TARGET}/bin/ttar diff --git a/packages/ttar/spec b/packages/ttar/spec deleted file mode 100644 index 2610de3a3..000000000 --- a/packages/ttar/spec +++ /dev/null @@ -1,5 +0,0 @@ ---- -name: ttar -dependencies: [] -files: - - ttar/ttar diff --git a/src/ttar b/src/ttar deleted file mode 160000 index b7b382ed3..000000000 --- a/src/ttar +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b7b382ed3476b0e5bb5f1284e9e9cd2ac566804c diff --git a/src/ttar/LICENSE b/src/ttar/LICENSE new file mode 100644 index 000000000..d23bf3842 --- /dev/null +++ b/src/ttar/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 James Hunt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/src/ttar/README.md b/src/ttar/README.md new file mode 100644 index 000000000..5b84ed82e --- /dev/null +++ b/src/ttar/README.md @@ -0,0 +1,80 @@ +ttar - Tiny Text Archives +========================= + +> **Attribution:** `ttar` was written by **James Hunt** and is vendored into +> haproxy-boshrelease from [github.com/jhunt/ttar](https://github.com/jhunt/ttar) +> (previously a git submodule). It is licensed under the **MIT License, +> Copyright (c) 2017 James Hunt** — see the bundled [LICENSE](./LICENSE). The script +> itself is byte-identical to upstream `master`. + +`ttar` is a small utility that reads specially crafted "text +archives" which contain the smashed together contents of other +files, at different paths. + +Each file is preceded by a file header that looks like this: + +``` +========================================= [] +``` + +At least three equal signs must be present. More can be provided +if it makes the file easier to read. + +The `` parameter is optional. If present, the file will be +chmoded to that (octal) mode. + +The `` parameter is required, and must be an absolute path +starting with '/'. + +But Why? +-------- + +Seriously. Why do this? + +I needed to be able to use a single ERB template in a +[BOSH][bosh] release, but somehow generate an arbitrary number of +files based on configuration. An oddly specific problem, that +demanded a small, oddly-specific program. + +Example +------- + +Here's a full example: + +``` +=================== /etc/named/10.in-addr.arpa +$TTL 1h +$ORIGIN 10.in-addr.arpa. +@ IN SOA foo.bl. hostmaster.foo.bl. ( + 2015082504 ; serial + 15m ; slaves should check back with us every 15min + 20 ; slaves should retry (on failure) after 20sec + 4h ; slaves stop being authoritative after 4hr without updates + 1h ; other NSes should cache our results for 1h + ) + + IN NS ns1.foo.bl. + IN NS ns2.foo.bl. + +11.0.0 IN PTR ns1.foo.bl. +12.0.0 IN PTR ns2.foo.bl. +42.0.0 IN PTR bar.foo.bl. +=================== /etc/named/foo.bl.db +$TTL 1h +$ORIGIN foo.bl. +@ IN SOA foo.bl. hostmaster.foo.bl. ( + 2015082505 ; serial + 15m ; slaves should check back with us every 15min + 20 ; slaves should retry (on failure) after 20sec + 4h ; slaves stop being authoritative after 4hr without updates + 1h ; other NSes should cache our results for 1h + ) + + IN NS ns1.foo.bl. + IN NS ns2.foo.bl. + + IN A 10.0.0.42 ; bar +bar IN A 10.0.0.42 +``` + +[bosh]: https://bosh.io diff --git a/src/ttar/ttar b/src/ttar/ttar new file mode 100755 index 000000000..1579b66e9 --- /dev/null +++ b/src/ttar/ttar @@ -0,0 +1,34 @@ +#!/usr/bin/perl +use strict; +use warnings; + +sub mkdir_p { + for my $path (map { (my $t = $_) =~ s|^/*||; $t } @_) { + my $parent = '/'; + for (split '/', $path) { + mkdir $parent unless -d $parent; + $parent = "${parent}${_}/"; + } + } +} + +my $fh; +while (<>) { + if (m|^={3,} (/.+)$|) { + close $fh if $fh; + mkdir_p("$1"); + print STDERR "$1\n"; + open $fh, ">", $1; + + } elsif (m|^={3,} ([0-7]{3,}) (/.+)$|) { + close $fh if $fh; + mkdir_p("$2"); + print STDERR "$2\n"; + open $fh, ">", $2; + chmod oct($1), $2; + + } elsif ($fh) { + print $fh $_; + } +} +close $fh if $fh; From 14aa7b5ca45ec359fb0b7591ac28cbe852b593e5 Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Fri, 23 Oct 2026 13:27:48 +0200 Subject: [PATCH 04/13] Include package dependency tree, drop redundant packages readme --- README.md | 8 +++++++- packages/README.md | 20 -------------------- 2 files changed, 7 insertions(+), 21 deletions(-) delete mode 100644 packages/README.md diff --git a/README.md b/README.md index 445d98f4b..573a90233 100644 --- a/README.md +++ b/README.md @@ -110,4 +110,10 @@ only by `-DFIPS=1` plus the Go toolchain for the integrity step). Because `aws-l bundle the HAProxy version file, their fingerprints are independent of HAProxy — a HAProxy bump reuses the cached AWS-LC compile instead of rebuilding it. The HAProxy community patches (the optional `-patched` builds) are plain source files under `src/haproxy-patches/`, applied at compile time by -`src/apply-patches.sh`. \ No newline at end of file +`src/apply-patches.sh`. + +### Package dependency diagram + +![haproxy-boshrelease package dependency graph](docs/package-dependencies.png) + +Source: [`docs/package-dependencies.drawio`](docs/package-dependencies.drawio) (editable in [diagrams.net](https://app.diagrams.net/)). \ No newline at end of file diff --git a/packages/README.md b/packages/README.md deleted file mode 100644 index 70b695cb5..000000000 --- a/packages/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# `packages/` — the complete release - -This directory holds **every** package in the release. `bosh create-release` bundles all of them, so a -plain `bosh create-release` of the committed tree produces the one and only release — there is no -build-time assembly. - -- `haproxy-deps` (lua, pcre2, socat, hatop, and the `ttar` helper), `keepalived` — shared, compiled once -- `haproxy-openssl`, `haproxy-openssl-patched`, `haproxy-awslc`, `haproxy-awslc-patched`, - `haproxy-awslc-fips`, `haproxy-awslc-fips-patched` — the six HAProxy binaries: each SSL - variant (openssl, awslc, awslc-fips) built with and without the community patches -- `aws-lc-src` (shared source), `aws-lc`, `aws-lc-fips`, `cmake` — crypto build dependencies - -The SSL backend is chosen at **deploy time** via the `ha_proxy.ssl_variant` property (default -`openssl`); see `jobs/haproxy/templates/haproxy_wrapper.erb`. Every deploy compiles all bundled -binaries; switching backends later is a property change + redeploy with no recompile. - -Dependencies are one-directional: every `haproxy-*` binary depends on `haproxy-deps`; `aws-lc` and -`aws-lc-fips` build from the shared `aws-lc-src` + `cmake`. HAProxy patches for the `-patched` -variants are plain source files under [`../src/haproxy-patches/`](../src/haproxy-patches/), applied at -compile time by `src/apply-patches.sh`. From 698b29bd089fcfed85b7bde3d010b891a413b82c Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Fri, 23 Oct 2026 13:43:34 +0200 Subject: [PATCH 05/13] Fail early when invalid variant or patch parameter is provided --- jobs/haproxy/templates/haproxy.config.erb | 10 ++++++++++ .../global_and_default_options_spec.rb | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/jobs/haproxy/templates/haproxy.config.erb b/jobs/haproxy/templates/haproxy.config.erb index 03d334e0c..121baf7cb 100644 --- a/jobs/haproxy/templates/haproxy.config.erb +++ b/jobs/haproxy/templates/haproxy.config.erb @@ -172,6 +172,16 @@ if ![true, false, "true", "false", "mtls_only"].include?(disable_domain_fronting abort("Unknown 'disable_domain_fronting' option: #{disable_domain_fronting}. Known options: true, false or 'mtls_only'") end +ssl_variant = p("ha_proxy.ssl_variant") +if !["openssl", "awslc", "awslc-fips"].include?(ssl_variant) + abort("Unknown 'ssl_variant' option: #{ssl_variant}. Known options: 'openssl', 'awslc', 'awslc-fips'") +end + +include_haproxy_patches = p("ha_proxy.include_haproxy_patches") +if ![true, false].include?(include_haproxy_patches) + abort("Unknown 'include_haproxy_patches' option: #{include_haproxy_patches}. Known options: true or false") +end + # }}} # IPv4 and IPv6 binding (v4v6) Option {{{ v4v6 = "" diff --git a/spec/haproxy/templates/haproxy_config/global_and_default_options_spec.rb b/spec/haproxy/templates/haproxy_config/global_and_default_options_spec.rb index a638ee33b..ae0506860 100644 --- a/spec/haproxy/templates/haproxy_config/global_and_default_options_spec.rb +++ b/spec/haproxy/templates/haproxy_config/global_and_default_options_spec.rb @@ -13,6 +13,26 @@ let(:properties) { {} } + context 'when ha_proxy.ssl_variant is an invalid value' do + let(:properties) { { 'ssl_variant' => 'openss' } } + + it 'aborts rendering with a meaningful error message' do + expect do + template.render({ 'ha_proxy' => properties }) + end.to raise_error(/Unknown 'ssl_variant' option: openss\. Known options: 'openssl', 'awslc', 'awslc-fips'/) + end + end + + context 'when ha_proxy.include_haproxy_patches is an invalid value' do + let(:properties) { { 'include_haproxy_patches' => 'nope' } } + + it 'aborts rendering with a meaningful error message' do + expect do + template.render({ 'ha_proxy' => properties }) + end.to raise_error(/Unknown 'include_haproxy_patches' option: nope\. Known options: true or false/) + end + end + it 'renders a valid haproxy template' do expect do HAProxy::Parser.new.parse(template.render({})) From fd1adf325dc4ba270c071829c5890d2723ca0f30 Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Wed, 28 Oct 2026 09:14:27 +0100 Subject: [PATCH 06/13] Add package-dependencies graph --- docs/package-dependencies.drawio | 235 +++++++++++++++++++++++++++++++ docs/package-dependencies.png | Bin 0 -> 121349 bytes 2 files changed, 235 insertions(+) create mode 100644 docs/package-dependencies.drawio create mode 100644 docs/package-dependencies.png diff --git a/docs/package-dependencies.drawio b/docs/package-dependencies.drawio new file mode 100644 index 000000000..4e29a8338 --- /dev/null +++ b/docs/package-dependencies.drawio @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/package-dependencies.png b/docs/package-dependencies.png new file mode 100644 index 0000000000000000000000000000000000000000..9fc76d80d4d2b86b7231144f38aa51c5925d5fbc GIT binary patch literal 121349 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

5!`1LD8CU+MVs%{@p9#n| zH6CE(`zXSe114VeHk}i%4I+Y+qraIEOwTSw6)tNjx|G1%$ChftPev|29#`K`J@m&( zD2meS{O0{gjU8_;Zg|M!WShTo^3(Zj*uwzgEtbqMJ$6Dk zalucPL0`JZVIPZIZPB0W5|5y|ZpLNBrepPd2p~2x)WY-XPVC~+p z(2AkW$00?9DAY&ytz}a9Y&ad?)1T6C%Pn(PLw?=cbqj-e<_6-<1LJ#p4wWmN=9b;d zK1<2F;@qgG@gC<^_tReqmj254-oOkgA5ccJ_M*QF{eo&3&acwc%;^hH2CXP;Y$~iQ zb~f*dd|4@unp%FZX*tf;0NEoq=~!V@&q`NcC^)kXJNL* zx0c6oF)PaipAT1^>pEIOlPnPZW{!PzF_xuQDo2!}wP)quCxs(se7KaK=U`D1Ip)}5$ykV6lYpwGa#~v-%r%2AI^7rVs}`9b z-3{B+q4)#;7+QYcPo3fFc)|(#yjp~MOmbF%rDz&_G6P^cb*?H z#LS3Y!<~SE_Um)UyhB??KVQLfOC=Nui`GG!w#!ugc#03<8=+3{4_qTRUk5Xo!@%jH`WSN=jGln4iqJIA+1;!RbYT#`lsj0Xny|CaoPdnUdtXWrCtT*I<7#iS zF71;3`S`=GpTk0LD;iG_weHUFM(vFSa$f9wfrb9k#6a@eLh`bRW$cY7;9vGcuQOq? zQqy0R09o`4%4*O_El*#ROdaIdqZ+$0*5&1@n_=7s6$QuGi^v^eE0f2BWr%5Gw$;Y! zXT_g(mb0zn;8dM8d+fqnAI8;kG;fbZAkqCB(KrdxEHW;;Y4&!u0!kG@|e2Ty0oT&$QZAZZd5b?}6R6;5M&e(^o!AlvaJ+9`TzzF_P!8(ex$QIlP|+ zuP2!ICFUF67^f`vx{;}Pt}pXXL>-V8S2M?Yys%VuC+S<_2nAhRQF6B+1It z#3~4FG8}ep(!)EPj{&O1RA@iXtr2CMNa(R=cAo$IvF2p_J!;-$_#C3cBC?_q(Ifgk ze@t`f8Qfu{T~Ou3aW~niT(rk(OHBRp()h?hoQwZHPsaA~Ly(@wG!}R^zXj?M9zoopCw573xJ{K6x&3(biKedexQx5(j?5-%sY;9I zq~P0JINRfhz2JfsUplUenKx+cqvn33NPu0>XC+B+9Ti(J-|%y+^PuM+sT-om899}Q z+!!yGdW>`_jdL&)UabffUQCo|uu~)`elP4~pLWvd3!p5aToZ1>F;vjD;1Ta4Ku#(b zn%Imk55@kxsL887UtmHe3{siVCn=x_yp`E}?l^7p?r8Vn)NymwerJtMXcME^!}wVH zLI2K?5JuTC?pOk02VRZ_`v@bE{_JAa)&lbNbsTp8jVsNjwz3yev%U;ow4V7Cw_k4;Wp08)5C*Lv}d*BloqJ|UBW`O(ztaQvj#-Qxwfqe@X@j&OFC%b3 zU(1h0HZDQy43{97=&EsAawXkcpB`mS)v%ij*_r7}yMSo-KHvAkbv}#HO||NSv{V;= z)F|A4aNMxQCt>brN)PcH6d7spr?*(bF&Mkw%1HP_n_aW$zC^MSon}&|hM6YC255X4 zxz}&ps2tIHom4aDd0%l&cf#1JMa)(sg9(#D%o9mn>LjV17Wcpk#y1VkwWfa82HHo$ z9lM9JE2+!-nB0#es2oQ>s@?D%UELg$0~eefYfkAD?l}UKiNbnfxPCXVk2@wmxfua6 zPPxO6GB)WF{yT43*0o=~eGq@A$El`GZ9fukbMQiqsV!S#INJ#i>P2*}k+GX#-?PC{ z<;arBuG-P;uhGS76T-5;su3P?LVz~ryVQ1QwOikqu6-YcWQ7sx#Gp2#YwkNnM-5gv zA9@!byi_$mc-gG$+>eH`qS88|+q9y-VN+&XgUs)HKnd*gl=yaQCBLcF@!_kf)z3~i ziy);uwA$Hi%>8zJ^g}U=W=A4z8uRp)mJk@NCZ%S?6SE&}cg~lBgU;Z6+u9;nv8)Rp zqBSty_Gu`?YQpodI+Xtri=k_#j#`yP@`IVSS+4Kh8}F-kmZ!t$5L|MH+3I29EP1-* z#}C4o&9gyZXkh0Vy;u`ujy?L}lKE)YPK|Tvv(ofXS)Z3{7w3z~G_&>WW48y`)16h= zljCV-b{;7q@GIRLL;4ZPPW9aW$X<60D^8E4v1sCLZ@QlQ~D}!2KTK)f(4`2}SWEL!?FNyG-qQL2QT(-Wp)oy_S9A7gwTa zYFrYgcfxr%v?!%!JqZfD!AUCyU>%>;UZ!i=y$%kMMs;`i-ni6*q#*8P(58DBKvoZ* z^6xeal85Hs#RVK0?^wnlQ%X%Wj3OH&##eCMX>@s=M*J#RCmK>jtt}IBGAi2^v6-6q zE%hNg+JC zTiShG&!1gEe_+&nYpEG=m8F^Yt%4cKcy=iy=;-`158vbh=KtgEEu*4r!?sZvIusBj zq(MqRx)BDHk`xpq1O@5tZULo{?i37=?(S}-yStkK_BF=yJn#2@Yya3kwrdtkVCLq^ zGmrB)9h^p+w+p_5$2d>mjAy8YuM zAmC%p*Uay$&F#m_QLk?b>YYuM?<%1e;@(fT{*7tG#5Ec!`Cx3>w@1=l=rf$Vp%S*H zr}5EQc{g&q>D$BLWp36JzFRe&+NT$RwGQh`9_K2%_cka)H*Ir+bc}~^@XU+W+jdfZ ziQTvOjIyK}BNgCoJ;gqS`}q1Y5}%6r+sxT9jP&M5b(}MwRG|4!S!T}OTaJ>^;60lN z&@=CMa82N?rhH@^1<#F5AD&G+Ts|(3=S7NX$1$k2EZs2sBy0M!E*fqv?+6~??(Ebt z?DF_M(uG-VdLG_vom)RnK8!Kfn5baNAMf?GC`-@3Rf_dpc-Hl#Mx{fV1OL03Ekz&> zkLk}6JbeE|4-DmbUdx|Tj|OuK8#7ZKx)s{t5f|sd_&)9RK^*i7(%rP$1`4+oM7Hng zCmn}4i7+D!qr_12tsor{opvK8L%`~c1-d@mGkZ0Q^=A8K`gCe~Ch5YTDb!Hgx$XNs zt7zLa5@WcHn{x8@-q{cLlcf%ZsV(kD!e@KFThk=F6T_J)Md^B}@FW_zhHhuKU3JeE z;W?n(-DP+A^ECO?V|L+s-Terb$f_Euzp(&~JItq?7v89y*_*#EY04C)lnwS#mw!wh zh5gX8A{$Bl&AH~=Hlx2>P-vPi@=^M?(TLiuV~%f^+aR*1ZmOfel!-be)F6>@?S61n zF3N#5qXHswyhVthsc{(f>Ku)&f_p9Jsh7NZeIQRlJU?|?)aD*iN zz?a}`+w#7$z1{jzjXN1v4KV&vygEVBX<3p_Ap!QR_#Sz#B&^3i#X;pHf^LG1}k{Z}Tw?o%B!=-8xwGt|X z-w(Qg+%@D+PqASVTVnl9zzV=dGC<^qFj;nFoNz|N2-t_=1eMbtn`2f=uw?$yD z`M4eqc_eP%)6A!JmDI>t7I7$VVAxV&kCAkO{ZF$~1Cr=;nh48cbK1y*&opo5%H5E;7q@bWF-u-0?CL(yT*e~N z8J9$G29dxcJfp!XKVw423tc&Lxe0$UXdneI1RM6xU$F=}eYLejTaG*l2GAxL6e?fc=I5OmqePrwu)B!1tO~E z)6TDAy>yP9= zH^@v&^oL)g`xAfxkKldQ`ht07GP0~;g`6#lsh~|IGmgRjol%I(Eh-t{yvF0_Y0KeQ zT-$34C3D)%>5MS@DGSfUt4)TJ0|uPQNgbT>PA*B^*Wriyucu0Kwx;9R)RW~mCM#Wa z3`0zJKy!BDmbGxu5A!oR;>FLQSxO3W7pcBeHhuT74AHOBdCite=mXc$GuINPq(=Do zi;_YlQ3;`BV(=Qv$CZVTx2Ly%gsP2=C+8RLRFj#%aunoty;T(Hh!N#&Aw+4=US8et zaLuOJ-omBeMP7}zzsWE7W2H1$wiDNurPb{5Y){^-{0BSV*1~KGQ95?H2d`T#ZZbj& zjqqhxC4}N<&7Xex(yxaWeZar%Eq&qtleh39k*6%Le2fCgH|ZhLExy@4-pK+3sts~+ zkhZ9l_42TvKK*d~&BCaZH!pSAT~2)_6Fj^8deybd=w`(HCZqJ03BED@VsS$aP#fi1a_q6AADI=CaE8gEoUgk$(eN|A5~*D8Q*HV#p5%d>ZKY5SRW9 z!2iC|-ZgLtEL)L)1C8_V(y9M()qfFY+yw=PdAhK@|Dv#egQcmVEbzB;!jX4v1Ni^x z0|~vxqiX&8C{VjfU^E_Q3J^ZOU~C=t5f^@$Kfk~Af~LTAlp%?N4Ul6$k@^4R8~&38 zxI+g<`AoUdHsHzMhl2I|`(Jo(PGSTwQAjw(`#%%^lY4?vm1Bep!v8A3|D$L)tWpla zbKQS_n-zqx|MxlJ<#4E-`ADSI?=eb2vi?WMM_fiBFbjP{e^6mSRgC=pf02+-g{y)g z3 zX*6JnFWymj{5cKlw9r2l2!9vSA6{I7>y!Zxd{X`V=YxM|?7aow%3Nn);{ToYzsqHl zioo>lFWeg_#(zc!&rZuCOJn`|$^8Jhg0i{~0w4c8^#?B1^MAet_0$0BoPzSJp8EH+ z|L1;=!y&D_s}x0#|FG`--Ksy&3(rA5cCQis{kziV7;l3hc`&Ay|67aJad89zYFugfiHv7O|9e+|FX>x0M6ib7&w6XY z3wcLvqK^J~xHmckp!|aiWabF}+vXNdeH5KG2WmpW?EVnSsN%=5ziHaQ3jNO}F9Ttb zr!}^R>|KIKMe}<{pne$A-t;Q-Ug&?f3qU8CytzSHKom>ozqb&PT1iRiHK^5Xqx`)} zRHex1WhVidFp=;k_AMgO2B%dMH!#kF%H7a$k_0f!x!=v=gIjk zHSwpz~aBJRr(hoxCbsgLmRX zn9qOdfDHI0fWvIyYXx6PDk*dV0)mRD0=v#P@TGkl=M`mi{jtw3D8uQBmt)#`)zqy! zmW@qq2q0iYH7jlOD`5*55PkaaG&BMu44RlOxmQ%I3HVpC-VUInvXK4 zX6&Wj%4whIU&Q0^yuSlGTMQe?kO;DW5~*tzDbEXX&{Mj5bBzv-C`9ixt#5e;!wryq z7U;heDB&8Ad%0ak2=Nnf;Pfrid$kMGP<`?cG;IC44NCdmC^9=+UC+eE>l|<9tovNjevRfg1 zGgh+n{eqh;lkTU}+i`lKg^D8QEp!euHO>xWZvxbt{cq)&j($Js<(uUPh@hL9+mDWv zChbRG<>}OWoNVUT3tsLugLvsy#bRi2Uir+##mRPcXre?A;rIuJl(i<2wKQM3qVwze zs}s%5fpp((@IHsbUcO0yMS@8sQHSG!)5PhM3=Ti2WQs!21va;UJe-;c_lwvk0^_fF6UL9o>#Z$(4gz!a0jqemgPv`;|j}S{igvR~X`Xb5(w|*Nijs zbK@q}MnO|pYpQqN6{Xu6-C-up6$(_oJ?AF-$U{ahU;^VqbErZAb%?Jz-E|1?maPqGU4w$ zMd}TVQ(}AzZY)gfTN5UZ=twE*-~lb@x^erl2Zw}3HWk@i_&0s1x%h*jY^$GjozjSz zyowI<^lmq$d%V&IXFE3IGm3gk&N;~rMQS?kKOfc}Df3OrcCl7E&-)RXb+eY2tfsj3 z@yZ zd##Euy^4pTA!v;MZ|wm(y0?!HWEf$X@1Bur3!E?MEkR1^liDrQg2h>>lw&PPkGD%Y z*)%qDjx~)4sN+hgFkZ&-qOYva#yBI)LwA1C+i(1kiS6r1hIPE{m>D9^mvtJO?-#wX zb5z!rPZs=HHete?^JH_pIL8+{ZQ&;U-e&aKjTMZMJI=T-~8qTN%TUX9I} z+UjCQL_hK@XrzvMry?W4kp723xrziH)0ipK_!V$~R(I$Es`qZ!&H5D7F;7oDmwfAk zn;-D*1{=-xwKHKXyIC=>7_n-8-P#Sbf_s|9Cslj~Y$%L*VGQOqcE z<{(IMk~zbL@tZnEH^7u-`QnCu>c#cucFsK=C%MRxp!&{(1yi3$M}-SeFR2U?tLXNqR%#_BXOcw zEK}Z5uP!*etg6BK7UB4*vUTHluIL1aQ=5(zq@TN{pPyW-2Nq__Cr)H1T5M=WCzYP6 z*SZ`(-Khj@9O|*eASxcK5BB}9wObVCWsqci9+ofHT}MC#{2vg_;dYfe08Hru0{%)= z;UbWu)O9^_W_kjn!j9MfY3U4jX|WMLhL-3eE|5Z;#i7MI&7O}q6hF#y+P?RSsy|AP z?^Oa^l*@`+f7SQ%a0Jj<8G-F;JVH?#16Yq~pB59Y9-!RYR{FmDaNQf~0(S-3EOp_g z8g2-}FTH=@kH7^zp#LVr2)wj^n8COl-*VF9;ytFqKz^PbiHj}v+zaSaz>I0ikNAsD z=9fhZb%XR=zwZyo!S(Wrk3!~Dc9TI=RmBG^P#*eO+{5_@Lk(|HFYM?!LQ4SsX?$Z564)BI|a&4>i|t-SpH z*pk0LjqHbD16UoQLw+u*l+oG}8G{BqHJ^BCa6qQ$pk4nNYuDq~ z3oXBl${4Mfc2N)bud*V+>evn4Hqq+%pSC;{V9mG>dbln+w1E~_K3ln6CEtO&Q{UL)heTaf>GI%q+y#Geynx8?MU#10?4VH6`=nXXNF4Or?kXo*!O)rXM3(_#c-Uelj|U zAX%Vt7?3b}K+}@uKCazD(YW*G4#B^B4*iZ#<^Fqk-beUzYW&0f!km%>M!&1};Nw{m zL>&4LkpuWi)CaK2obyfK76CHKj{k-w;WO4j-$R1L_Zx#t(T$}0e;lx1YjTS5oZs*2 z@{}*i=x*D~bOhilqf@5*mDYdO>aRaXRS#}U_b!a#_}^9ZL=RW~y=KsuJ7CaUsn$T^ zr=m&!UL9QNIE35(dE7x5LVZ*Gxv-RX%(*ZWg1$tGIP{l>?cZ(hcmUK!SM)2VzwD-e z?!=!VBh&i9KqvV_L==scLj;UJTlIHLS)mBjVDZ%zy>#Y#+z0_NtQ!T@f8zs8$WH%C zBThI~BmFu)->;1T#nJzvgaRks1`o`s+mH223hsQD& zu*=JU9XAG)h7l6lZR}t%!UG!8t_EPeZjBqJmg0!Q24dKBQqDC(kwX!-?`=!*mQadC zM>zEI(Ed){fCoy`B4%hLLZ3a0NPnW4C{wjNqMYV_GHwW*O`}YyFnEcmdUp(K-s6DV z#KcOdT}r5+ErKO5w~7FJpT=yRyZKO-%=-7y79vS6hY;Q*kK6@)F9+7#XY)mJ$VWw# z{l2IW&i$!9YzQdu9c)G)pm^6f2dFu~MCdR}fSKOxk4>UGUF}$2+$Y!#xKwk2;Q-f; z*nk&Jp9LvTv%Czb$q~5WdkMU(>EM!FGwLEOqY0h~%Zq}gXvB$97E9c2R*%+4CIc+^ z6d$7u0C88@2YiMq$G$y7IE6r^ES$CSZIg<$E3SgCDSECv^tib^BD4+klX&~;Ak|ud z95DwvjG%)g&(sIE60640Ng&RWX$HLsBRPtcaOa}-Xh_yM=Awr_)&U4Hq`N{*_oETE zHI%Ja++JU_vgcWZ4+hoUG_ftmf48MTzyMzDQ!v*kcq{`0fA3PkS&950+UNp-PDsuL zgCAw0;7#+^z+;?J*77ON+CqF%oH{htlsM1{Wqb>|5kOmu|RJ@4Ck;)l<)dRH~;VFKT zw#hD#XrSW_>^Dd3yLnWI$;BR1H zD2HpX#B@DNUh7;AYMy|-tpSx4^J*FD_Vj8I17R>KUt}X3I5~guN9Y*~Hysp{JDFph zLCN_1U>Ov%{XA-y3&!nu3;})63V|!Yhoh1*bAR~zr&z}adbC?}V8mD+6etqnH-0*X zr~_i1cbB|?rT>{+sYh^_;yvI<*vB|Ke$vf zq-M_*_Y7z>GQuRjM+UF>c1?y-r@I4N@SNK4Ns8)_}F!X$pHL zjCV=!TDHBuyuP{-D0Z45=5VtvN`_ND3-GWS5jl$0$G*g_S(yd1rnyTTj??Ms;{lms51Ek!DtjlOcUud}RNCKTGOIh?YW0DZ4- zYI#gYax)s|C?Upl4MRsI3!!&OPH;Ppd#EY?#sXX+%Hc*0EUn`=<3d;nU%rY2rlwbC zRm1aB;>X1zTW%XQAXCs(y` z?uOT=p2x55t+1i7A@GNkf}N{yJ$(qelWx(;qov3|`;q#E^TjwGl)F<1SNa$YW(d41 zPJ5j$_@p5ky+u(Q_tbK$EXat9eEOr;3UppT2>674WVSAS=Rc&MG)SO-CZ(Z*Al_$p zJu&-{uR{r9o;a^%^l_Mx@9|j#i{8NSiP*HUnIGRSUi@)L)sy1li8Ga)g2opr&p{}7 zO_9VI=#_X!Iy~b&-eB&IEVNh}d7j}a$!>F`_lMKviFt|9AcTbTEwnd*M=T(nzOhcg zY7Sl!^DdZ#%O_(LJYO%&&pKB~w*{TsB#H zDxq&Q2Cz+KxfEd%TB*<{yEC=qOeOTpI(0SHTAOP1F|3*fu*fLJXON@Oh0hJ!j@$@% zxQOr<&`*HoMhfWO#`Og1;S3FHDad?tfYcY|PYw08Q-wDh#W(0{&U2y)Zyv=~3*)Sv zZix_Kqi-_EEjl7Wymx7G9J0H#DbIF4d|^o%H^G04jCz|4U11blcEFhf;$iQJIWo?h zKRawseAcSuq!9JMR^Z4KjRNMt8*t~_zF2LJChT@m)~Xy-JmD#&5*~% zIs?}W+sQKXG~$t3S4aHano6sAh(fZU-&Cco9`I6}u3?oj+7(vRAMeZPUNl#^Z^Y8& z@)!*u%(|bF!(~aA2`vO{AN)1v2|>f5coIq`0MmgAG_!aMJ0Ez3E;qAyv9nt}!f9%d zxt&2>cOs0Q;o@7AfW~)9?UMUeO#RcwfgdzCi_Us~h(|~HE_nuW$_!7h43vx5$KbG= ztsd_9yexQ)sN3@1JCZ?B_i&|`SlFq+nqUgFrr`?F8_t%G<1)MrR#(q0`qR^BOd#G+ zT8qGnC-x0!z-tlPY(hrNcT%y-8`}*Eroxi&8`u_G$=;4C-OLpGJZ$Ry<$Qoycdo z0C*s?#W7zfri$JfAj8<991Z@jR2K%Zm98S0&Jm$lVmx=O#xCNO)v&{8=^A%s=4 zZ0ytvEOA_PjdHf!hif2t`Db~7ZsHmi7Wj177D76guam^Np;pgpHs(bm5y=0QMJdfo zPe+?xS_mT&r8jI5-zb0BDXS^wY3-r4d!k$tI3LDC%%hP|3>|+D)200)CzXFJ3QJ@ z;I{tNT)vJz&vl`#mnfn6j0vmpfOXs!j)q?LYtBB*qp%oZXB(A~gMc<9O!E(S=pcE+34E5J-(OWPz|IeeMLmQg zudvO6Aoq}Rf`({%^F2PvM4~1^OkO-K?420R0h?QWN2y){iu~k1FLB?7=76xl&-#vb zn?rZpt4g_aM`Fw`<Ef#=B3^+%0utkoR$ zE1beES(K*ON##@0P*+(ik-M2^KZ^|&&8DmF%EqvWm6?r0nb~)^L|eHY>UnNY@L0Jl zT^w(Q;I@^-a~UR}pqTNJ;)L{bYa|Zp+{sj^^KD?ReP_ ztg~SMTcioO9>+n$lB0Q=hHjttM>)R}zs2-Bk=zdQLa%t_eSWx_NQuvni+Su)7yiyC z=T2I_iXwSp8y$oOmmT5)z$LLZ)x6%MIWcpM(}&-uWr#MXCqjgt6`RO#e^#Mb?j~qq z*q*gLvf9czH~LvZ$eAVk;RjP>Mz@qayL%s|l%OMph)eL`eHB5{ZYZYuEw{UQXSvbb;%MEMfJr$`DP4RGu`lpX|pW%ilEIXLh|MT5GnRihjn_z<2~F8 z3Z$&Bs!C)42xIo5mG@~B;~QAoa!>s5nGKg;2_BI6-q1V50ybIkPy0;He49XKqT<_c z3Hj?Qg;awIn%&I_ha$N~L5S%xrDh1!fCu`G-Snnsyj$|DD0KLfe5mQDrDnhimq}E| zSmh-<=jykB=i^`X=7)~yXD05;e{7g2t*@6tVx1W=pYr?h<)h%jaE`pU<3g(gnJL3- z2NgPvBl0_#|0$dXx&w?EI)1y&q1wv22h)$9tGzi^p;|E5i?W#lWTnkfH za{!K^1O6KGc27K4!9}}t{RNN36#v$A^=OHZ-I@}akVCKp0sKnMGNsrALnbztrEK4^{S)E5V?tC;7<;8n~PE%!LA1h?a#YQf6?s8AD$Uw4xV z9sS9BT#D6)TGl`8&Nptgdz7&lTh9-@Xy?dl4y+V#RWku_UtQfy88X^-Rs|L58jO47|On2>JpAbE( za+dT=Bor}pSiF{DU?ccjF?-6g+t*lQOH6QSut*0mcjWCEU%^KOdz=QWqK-I@Om&Hh z=UdOF=Pl7sy^-A z0HpV`ba52NwXYY9;CeklUYm{IG4}Z^_yXSt`A$}zzfqyeyVpTGv(F2gDxu8W3SZn# zwge=vE&cVBl41nhPoBbTZ@fQfR@fmuh+=wslGhudXBf`xDw!o4Nd}ZmbFct&-hCa> z!{t8Rca_J9*PPChq49`i=C?~Q*uBxp6^-${5md0!Au!sH!;FtV3-AENKG%gToMj0t zGConvJ)D)7g}T%rsXUiK4-=aMD@n|2MhwapAlD!w|4MM6YUG~FM2WGOSjaVL9>06w zZpNj@BWo^yw@ix}-R+G}gV_?~R(E?#1WagT7S2xUeRYTje&neWs^w3MPmq;{ ze>0-BdggUe+U-oj;hvK$;MkeF5MQhGIEpa=t@@O_)rU?y$3~DymsG{$itts{)mzn_ zDaSefg|-j+mV6nuyxW(N4adW5Pr9wHd-BbwrPJKb588Az(0NI6<-gd#ZL+-}=#S6O z_QBDQ|FQ-oCvQ*z|7w3EL)c;Z3D5%K9~wYVBKQ+=-lArS(VHoy0%jmbQFAnjn3P+x zENAP;fy*KZBuWV7SdL;UXJY4Ug|(j2{d~>xhYnj~Zx)jIw9Y<1%aoj3cp5BfHRq-N z_5)$Ao$o%7yX+cb$WN$RdS-tnERh-MMv@&OiBC5(JP* zV{S~|J*1zhEqdMAvikZCcHhR7Imb-tQ9=kvsEP+#$6YupzY z<=$-NG9T|FdZI67Jh5HrLAee*Q6}S5c@FYVV&1G`KFCI6 z1=JNbaQpWesB9~^U6q%{e#%)b0&c61H$p4>Od`lfGw}*kzDV075zhQWQ#Rl9@G-3%biyh1XKCtMZ#7ze8|OS7HPC97o-4_k!9kmU+@L(dEXy%I+$k zrwTjYQI@YA>D!(xZxrp*kyUz!{vP@scdn~tgl(|z5|+s?6-qYuTwa9Dus?;I=IR+O z*s^PehFF7(`%6JQYWS;|bNXFT*3TRCzVmD6Yd^9|;3eV)vOBi$^Q!DauDa71*Olc2 zEZRYzcWhn3hE6A2@r4>e#2hp%-FNDea)7m!>UMy!#uZ^cP_+z9SC))921L5RhDp4+ z(-KRIyH5Rw>Q;+ww+3z@O>^#Dui(5{?utg*m466%V*0`(M=?cs9DS~YY#E}D4KCct zP~rM;PGajYV~j0zI;AHJuV(kW=8XqxndA9^zE-^l`P6EYDcD7x9jce(AU4|IH)4dc zs_EX7gUgM)V|up_!FS27Yg`3&e(St@tl*pt`(g#(O2fd5854?_*y~?8>`{O3DP0F%Vrl@*Ci3|B&wO5CHi>hFt9A{AMU_U3Bv_V0XY4Sl~{7v`;asO_vi$` zUarm7i)NB}4~sB;P6o$=U^uQJ)=FVM%c(7#&r-WMtpkX-xLo*WoX$Jr`^;99A1*9+Vm z-^(NjuYMOnu@i#(*R9$5S-E`>vm?UY(})ZO5<@%zLB}dzt8&38hLA4F!Cc~{XO!(l z?A><7&A1q*-b6mMRHW7ZRJ2|9Y)$X$p*8#vLZhUFRwofs#+pOFF-$j$`-&+^otWTG zHA1~c-qr!Bllr)h)XIe6^xT&y$4*5lvq55$=epK?sRPeSklydK(HD(W_PIi*!Jf#c z;mcybCV@+6ddNA6(NY8DG-FSp!b#ZiOVN^XGq!i`3wwDY*-Xf{5Y;sNB0cIXW-ARn zw45)F#x-&FT6^-#*=|N|eM_6fML&MQf6fkIMUFa1Z8{8Bi^4HP&h;Kw4KK#eINQ$m za)Uk7tm*g?u!r~U>fFwu_&V7fXG;W;`+eSodT!Fg{cXT4CX<=k1%NPt6}F7%2QMI= z`o}vzV)VL`h4@THa*bKGH^?)kKKphdg>|Q5S1>0?4b)Vl2*xr}* z+ZQ9@C->RTQMl?FUj-PL0?SzuxAW!Lwi`sy1YFx2g3_Sle}>Y=k9zSK=r;^T|Do~^ zJP)&h58MNDX|Zi#Q*KjlEWgOL^SA~cdK--&^U1y%!-d*w;eIyHc^cR2!Cod>VMDoU z_e3u!gxeEb^gf#7vs;>V48J9-o7iL%N4{N!(cm#Z&9T`CkQj3KcxU zwCHK}LpduC?>*VjkKc#?Au*{2wsK6E_DZqWFdZuv_qDs?YyfPg&S{^<=#wOM$S&5; zZ))v{ERyH9i!7!E7psFua+0piuWEONA7Gxi;beC7eM!ho^*j_>ov-uU)YJAWr=5HH z&B|f-k}H%<$XBA9H$$?yPvrLJmFidQzMyP`}sQRdIY?J!P&`G)Jf1mS8DTl3@tRK%TZbFNd=~N_aYtVRm{>@&(uv`8 zm3=m830XR$#IvB)FgH-*QVMMNxcveTk8#eF#{7%8zJ@w(^9cfgo8pYID#6UE=;Xe} zyavcQFCW?)bWz(CY?cwbCtYl6DM1sZroQ#>p1pr75NPsEEq~?vKQSLKQH(J&-n{@> zg}eoVEfg%mnzFe7ofrF;u_7PW7(ztb_R$m-F0*vFR&BJF!`S9ZhE{QGVR#XuefyRX zK!P_jtS(HTxdSEb_~QlbO{5eVmz2md_Qbkr=+BmgV`yH4 zQ9KH^zvG#nh0f!7?MBGu?YUHVP3V9aFd|z*yqHg2C(z36S7ZKi73A5V`+hOjo1^(? zlrzBlp?MB>*5>_bsMJCaRP$mVCkU%BW(*JsIha|wAYGvquo^6RP*xMSS6;(jIIQ+1 zi(DA$QJ%Md*744u+O)gfvm05g82ADf{Xx|l_A%=PI!Y0UIQkmfQOW7hslF+7 zLHcY2nOP?8%j~;U^({=&MfC)7>i#-wFuKV*j3ha~9B^MR;;(%(}G_`RKSy9=|5JlYt5+m$k5uuS6n=1~V^;D9uJK|jvccUQ>G7c2^$s>o7;@t*o z6{$d$7lRq@l(4IQBtq*;+^^rPlpE6COFnC%A;AR_3$+2-7^0w0au#0R<9nY0@qG15e_ch}HN5;H_>Ap$L!#0cj*0UD}xkJ8ZlUo1dBMED@(-xW0d@CDnJ>-x-c3z}DnDOO7 zP}pt$b2Qe)S~L%_{jgEH^&xLEqerVr0ojwn**F9?*)L@*`dH3_xDMHCzKE=(*W+I+ z_qwBAcS#tgk2sf2yuG(LPLEOoOj@7%*ZWiKNrLuW)Pe`2oItXgRxxxx_#JpgW<~tD zQi*&<-cLC?|4Djy8LepiOXYa&(vDnW4w9#&wf5r2g12Y=%=-DDVXbiXKze;Ir|%xSt~qWhn%DyNmKVC-cqX z#J`^s;MCoXnSJ)f4bN_yK!?v_Gs9ZDd}uZjM_Q)F1b9kBg4f z;%;a-ZUr=<*t~9Hb1$&&w&0RD8O&s;I6ZZb`ZkDI`Zc<#?XDgklk$`5ijnS;-JQfU z;|B@U@3M^QDN#8rpuSyv8$UNiIkMSo2U7IXtd)b#i7s)R<_qK34L&NNJ~N z%Q>B*cfTOtTV>$O5psACJ8cg<7<^(x3lYIr%Ke+}_!Ggwx|2riaCAnJC3D;q81X8Y zoEi1vbmx82IM?g3(^rM=qheZ>E|D_yuu6B)zT|qJhm^Hp{DpcM_Qe{nNdlksG`QDy zafKR9{8`u9V6rm%v=k);J__*8Ml4 zW#c%q6=NYn4z-_sb;oij>jKQwhcce;*PP83P@q#@`;pmQwVCTZ8!0qLD!?(Lb*tEm z<9I`Lu+nAL26wxMQ>#y}5mCgyGba3rGLKx|^i+Ne=e6e)TBMgw=47h7tfGziK83B( zTd1(wfI>yQtLAjDq_ax%u<*v`CAy>EN)_xygSuA6ELR|HQns`#lL8{kvkYXTL5Uz9 zhluNrHD(sA3ahrMRQl^0=bfoaUy!IHsWPxqNjro_D*vWuSxte^O=KB`d1g)#ql z_9Np4fkFkQHzy(RrU`j~Px>rYwwY`CbgrHt&@qXolh;^gb!#h9oMBNNf4tB!@z^cs=4*mZ(_{;Quw z8jGb3U$T3e?NI(?JAVgke|^2dv+{ev-~Xz@XSM%^t10xS>4kU@E_IDS7QcjPiDtPD z$ySnpBgXl`TZi|OJ#i1^ZM3RAf~p-FnHgXYEIH2$WD@SzeOSKKFZuioiWg*lweLi*A?%V_mA2mf7hiBzvN%MR65-^UWmbU1Vc?##&OoM)glgka`dE zlGIx)KFo5s^AN<@-yn--TVrn2`L;)}o1@_KA0L9qQHAs7Pv_Sn{&h&664^D!FzlY@ zn(w$2QzCw7<+rJU83qKp2D^afeRU~*70 z+M0w|s7N)VKZpSKmGpk`KFTa~+|_2$t{F4AE>+ZcHYgXT!el(&f<1NG`-L@mQ#m)? znPc)b<;%8wsE!4X$q)7nDv3h9ZX7gAL5T8rtr01$klRq_8J%uTJiVmHSvVY_GZxbd@5 zI#CdA%@4R8YZ@WK^%#6I)Nw5Nm<0oMhcL}!S-rU94B>>+N0U-fgo9v!=b_LqfwzZSpqfvNpL92Qlb?!89i+SrOaUvsN3~ z_7q0rYG1VQw1i5#@cPI#dWiMp) z;z5KMTkBSo_#i{78^lziPsnk{OGRW{1j*fbkedE9Z%(s*p*1J~#3Ou}-wmbHwI*3F zwyC$0rPfrM@g@q;V`+?AW0ycP`CE}Sd|`*zWL4WgPY`5A?H$GJf0S#7vb~ZO#UaPg}L#=2e@_7Iertn#cFZF*V9&* z%U^jWgDE*;)ImwN0#&Bu&`osr5DV( zIH488M!(_=;w9x4ng+6W?2fTl8|t-EQmP zky8kTfCK7V>Aob)YL{tV1C$(d?FzfQn|xRLp;DpoZ(5#Gu#4ujq*Pn^1;p{13RI-| z_MV8JvPW3dIn%}Z??FLpYg9}&f{K|R+^r;-40dGeNqlZ+duhkdi{5r7Ws+YKIIit> z;qBW5EZpus2v^ldv<~d#RNc$dAvoZd463@8at)q|%BD_^&u!i5;)nXb_w-3U_h7#*4zw&qu%!uTbpxcr;h&|ebhh(^( z?iff^dp)nP-&D1FMjJyS;>LeQOLV$A={a@OX_M@p-LJl~Pq8-PD{A8shO?pfeWIOG z)VE6eCj+DoFReNO;3+O+%oYS({fkX{#L&$|V0(|xj$xmb(jjMk4Y8&U0iwaS&u|R~ zQ}h;a=KGq2Jg0U*)G{cJgyra1?lEHB?B2}k>>B;xr2j)_{>*mGlEv`;+jaGOwM770 zI_DawbLB{Yy-Z#wYRwzURj#z7?3LgM)SEdkX&_N&2!4(>hLN+4fw-@M4$Z4R4Ps$8 z&MHUq^NETJJJW!`QlSj!7Xt&j?%hlGt&T-aXH4^uZQV%POi>5^yh68lpN_bkhk;S1 zAH*Ir%m*p-%5`c9a1tX1VG+l@k4+3-SIH0`7oYo@pmlz5?JFgn!cFbs!L^}(JD<{) z=(|K8%`Qp%jc@(-TjT;%`>w^FO4$z0j1TIFQL1{s^JSZj+?a;zHY2>>49m=)p~*zv z-&1C~%70bqfK;y#7j}}j`KIN@0K~~G2RhFrNqHP%@ThZO7pzrwmz}vsGJ~8JNiW}% z31q~hURqx|_6BAp)s1g&Mx2>Hw`4P~*cAKxy~$WCvlX9wQL|laU#2lwg~m7I``p*X z!Az;MgKjo*PbE|}p|7LNh!=aa^oux(l=Jnfzjk?(EM6GWh6G?joLt^6r#rVE zuCr2R-d&$tLIG%J_; z63JX>gaQj!4|KBMdbmyPydv~u6|SuO8AMq&xjK4plg)ta)Yh`#R++u-uG>;qM8sg) zSc`FpO1ryhXfj_h15Q)bC%vAR{O80z!f^T!x|=@{#|eNeC`8C}i0&21qBR8D z8b2jEb)DsJ1fuO${X2;VR%umupZPdRM{{yGn7cj0A)DU)AjPU4Aa)>w7*ZdDDx=@{93zMAAofl-=1!>r0UitT z85UuFOSW)^~2tEIo;)j18xL#|Re zL)nV7K7U|qA;`NvU!{~x1P(lkidt6`lNe>D>OJ?)ncB-P4)!ogVW-#HMXaXyD&Fpo z--LZzVJl(5ee#}xt-MlvpwO(WD6geHS|y@PnISxR26 zj#25es zK#>M12?~sJ0p&9yn8f2&L#>IV!vRQiPL6CTd3;*DJsH8og}|enkbW;gD83qTw6=m3Poq z^TtbI#>yGDrH>R*(!kMPv({QTv3xnQinqi4O*n>t5{I!HI~t|!#CJLO245beKgSQ$ za3n_mUKy6Q?nPBHzQ>o4a{$=g4-r=%_hl=QbSt|~MGs5&HZVyCusa;v*?=LZ1)=H7 zy^QxGq}-vBZ45iT!xYTv4NDbuJ=|e(>B106Ah@bcoOC0fU+D-OWft%=}xd^{{cz?MN-wGoP~~ zD2~s5-a`s8{$Oc3`GWAQPH^KIn<@L>ejF0h6!uW?6BkxF@1y_+O9KCeAjEhMj6zGqPQKueAL-lntb%M-@O-H6T8Wykbb3#ytKJ7Mvgz89)q{uOUCtlG;%>h>r=l~Hq4}xQEeo>a|wW3 zySr^I=(3Hjn35s95f0Pk$Q;mwd_sDpckX(H$W>!kUU0pBqSq-YfD0PB&>YpDiX&Wi zY(?5Hng7<87=HRnA%&E6WeUeDY^x>Z)+^yqVE@Z7YzZ^zea&Ou=UdmRSqD%X0KkI0 zuhL%Qc|9u#l~r_~21aDtigKgJ=B8J-eU(O;S>f3dC9^sUEol#W1p8oF_vF2|dwh&z z$|2MD*z_kBWtIS6w}24~jUDmU*S4}nU_);yqkQc;n5)6gjF!A4lPjk;j-SDTGhe$m#*HXI#L)pj zsh-tyOz4}ZucJB8SMZAk2cBJ1;xO^3d2gOSH_8BN8xz6@MIGvpx zqjuQAXUr42VvEz_?s(Ta%5z1Ii!IR!U)=J5ma{uR^5#pokQ#kF>-uADP5%F1~>A4X%nt+6{u> z|1O4BjRGCc+-qBvCbO?|X8V_N#-MiH5wH|t6fuuHAv5H*&7;<_Pi@=s;kwJ3P_Qrx z6sgH$kHERG!dr3R7S6^c#N+2PR3wxfF%u+`*aL6pEn2=oe%S)FvHjF|X+YW%_kx4V zDyWarFU>wKZy^$^Gk(yedLt8=INIu+Muus!fL%kp=Amv0$l~&xL9sgzxblM!W`fzv zyV<`ai?#2A!|L{Qe!y&L1c8#s!*O%gW}|t?WT()(k-2+9*`>X2gVjawQS(HO%f9GE z@&d=}1cn&vidm>SFg==Z`c1$3XogvaDa_D5^WMne&Sq!guJLseRMUAuu(^^{(n2cStAA26~Lte@bQa0X5g=HJnZP=3% z2caDDW8N2|-S>zp8I>p3ciyr5cr-*~fhFG&^mSQ}hU*%|Cx_(Rq@LeDA`O)tT&UaozB?uW@vGj$*mxCf=<~~ z7MSTMh~a=xS$WoNzWg|k*w0AgUf3@*x1%j)*`6>(!MY?s&$SU+dw&h!SZ&|wluqfM zY}bY7HIZN|Jewx+V^u#LLR{XT*{155nf>4r*?H<$tTQ-%!M-- zEz>(CXtaeiQ!*dxnSdAFXS3li9gJbxtHpikFz&+1)kg&`5 zta~-J-j;xSF3&T`LXR15*!%hF(D=!Ex%)Rd8t=rgtlY_*wf^>W!9HmK8XQLLdB&KX zgY@9?+hGX^j28ucH3U+G+vC8hxp}3+{*cq&o5>W}(=D@w_=Kvrm^b?>=a}F|btv=0 ztuJ@|@&Oig0zE~YQd`5e3KzM`VZPgs9VVA)lQq|sloTsYaz@|#RNZ=q_jYmAY|7(MkM>vkr_)kbYmyn7t^oL;!8j7oO0G}{jvO-j?HBT0*H)1i;y&oioMx$U#0Z?y6- zN7cbx>q}ssYf5*>#XKvt82$X;#lj9=?A^>aNNEP>nMhcZzV`w0&bQWL?iAJgi(h+% zg()5KW@b}3^G{kMNQ?;aCLN;0DQ*2w6kJ|kYPFl`h{y8Q3bT{L@7_P28U|r>$O`;> z;i7GK5aeOx&rx4)47I-5UmsIoZ_JJ}YKe&QDR|5?Io5KGQH6tH#A{@nC2o6YjCNtr z^hR7KX;`zc>GX%OgFA^g5JtSGoJe_>yW)kp)!E6rbj6#WLbDCe8u7g6(C%b7RLev| zThh{BAgYWG)%dNNmdmyjo19>h3pn--@r_=;PM(szg~eR2u50(iFDDuf%H4k=a>lW@ zh=r%I_P%;o9>(h;>ag@)7%nBgcN6N@Fe!+-ZGGq!EQpioK&{JD-7rLCmE6be@?!3x z2~v%sS4c+9+C+w$?~vUN$I*V$%N5Yy$ue%9BIJa~Y9OE+s&FV66dFgLe0p2lhy@me zmeA^@z@Hh5k$>OyaS+Hv6X4`?x6#eO~$MpI5ywO=avfCP5G|M zzvOBWP?^Us0HN59}S*cR=D5oue9tTK#Q&7~`vLvDp); z`LpDzk3x)$%4t*F{(H3!Cvv9ytMA7K7o}3jxnS0DW(l-1EtjQb zp7AIsmVbJNl5*@&t|azkSR>2LlpHwvpECC!pW`$ZA+&O+O+~5L;Q;^V{zJW{$m-i&}9R;S>i(;Jx4Ww9CZd37f}l zs_#16A^pV8S0+tp2OPS16^S(}EJrIi1-kkwpOguOlM9wO#6%zAXPe>RGO4^8>eEUk zBpJgqY>hy>vc6eI!Ofm8;VJw6%j4Eh0jeFIvOcQhEj)E)+*DuFm0G>#8wf5jeX?63 zJ5kUwH!xWQpN0l7*c^tl&FignDV?i*E91W?p!rqm>)H|t(=bb3J% z*Y(kL$NJ6a;shN`YF54GYsJpURc$kRS`^P__L#AbA zYtn;&v~K0PwNfmx+3%qzAVwUL`%s_RVKUH+tqk21!jZo}t*FFP(iEyXKdyN^mtQTN z_bHW^;yIms2(FaF^uhL-QkmpEPyT)W#{j^AhW7zE==yr>x1%F5v*OnM4h`!xmot4O zU@q!R;v>$6=`{_9Zud?G9DYpZ>a8zD zFIyYN3c{Fa2-H7(I34#bLCArGQqj)K+FK|3ljX}MPnWSHHs1ARmbVwWe&T{`D*X2AchrsK{yoxsC*4Aq z)UTQ2riC1Xiez#>oY}iMlYf%#ar|4j%UgSWr**cY((afT!V@ zT(h^brAHjNX?CY9SHw}ST`pj}?Sp(8CFVEnmgv6-wwdcA`6ofZhS5oLsqtIX zk_#&$a26zcFKO3q`Phs)5p<(v9zE<>8YfS;?kW+(6f%i0tFW8H!n20zhch#%yW?a% zzY!G;H&aG^e_?yNp`vzEA1PAXnSb!1nEF1~^SVC0HJaesYYLHNQTecG2H0f0ox@YO zzjefWi?u+v{t+SP9V?<&d7g{?S(jKl^QP69p1TUZn@SN^y`dPW^M%`RAkm5*czJp? z2O1aahl>p-=Am^Th-#l)mq^@N=v_C>{;W}5_x*(+z(zkQd-K9>D3E9OMBZnO^N8s= z9UrX5WABs`$hJ^Qe%6eZ4)iC!CQf1iCpJ;DTIY3?VbB~r!NVA&J*9N->ahpa=K@_a z`2H!strg79Ie79K)^iGu zFR3d;89!(0L)7ByM~7FJN2UipTZWmJDR}Jcqp|5!EzuS31=vpN-DNM6+)3>=dN=f5 zMi}mI3BcvX8RU*x{Ng1q`(}|(cDW9=jivG}UfV72ioUQ|a^KHj8$UGX8sP_Pv&6=a!iS=ywCdq; zHK%{w_<~E9mYi{oaF7O9j_`MFFM=Pj+Smw0*VC*+d=-%%^PQcLuBd9Y1jz%|E_hkw zHpgp$aAM*jO<1@rP z?pFi`+?Un1toDR%Sg{s9fsNzNh+oTPzP6Nwe~c5PaQVhIDo{&`WliDkg`WL2@-_uw z<3`fEU$y`crOtv7OZ0;VsD_BehAmA1f#6@Eet-TA(%QFb6g}=#p}Hb5w!;qt+thjb z$fs2Gx#CzEwJ*BP0_>h8N822Sid1qP3@1&Bdq(NY?C_XNq0fEz7QWn7XOndOa`nVi z?<3+p2li2wJ~YY*sOHgH)z_{@1EW;G{AVmv~^U4!CmlW3ARo&Xa+F%}Dc41m_QTx#KbWWrOh4d4nB2F6YV6ym=)Gkq zfJ^|*)O9|^Wrh8gvQE12(k%|`k14|MQ&Acl2Jmtn!{;UTiP?O`9IGJ)VXEW@B>1AC z1l&T&*}Pc_FY%L?%myfcWxVXn@zNnCalpXxyG*U>v785`d9f?=3@6!k21p9RCjc!; zF6Mq1`Ka;^LVj!wTy zKyiT`aUe<|qx_7C0fyP0R;f#G)fj^(1FEj%FliTyy6+G#$45$lR49mQgY_>nhmlLg zzKt9voB)-F_+XluS%iwa(#)8rpn*g@dNBow=id&Y;nCl2^hf5j8Ot>%kkF{M{QOD} zDYXGWrzOH)fUKlf>bM3bN|1I$Y`>^Zt57&(&r9s=SK6M8n#51dFQ%kRX~ah-KK!hx zpMJkTQIBQtnA`b~Z(6O-_%7Zd!_kA;^p-C}b*N^@+m9}@E|0yPQewkrl~A@lq_4h? z5Q+aIJQae}M1v5ih2$R#0S5(m91;t-s8jQ+^6c8(hajuULT_)ClVuF+143qvg4@8g!RfhgdkjMB(G8wTfB|xX6qdI4TfI*XuLI{m zszb5m4VxQj^L`*-Da5QNB^T(45VoKBDB&LYrsOFt_Hf*eNY0}*zoO%-J7x0{W&3W=UVplZ$0$Z^ zA;j?k)`yA4#mg@X&cgu@orMG^K_0)o5_xpS%s{ zO^QGvPotC&wVzI@J-SG|pU>E8NNUlb)?DnTzH>KCB~LB@7eOBsZ=`XC{$yJeco75! zUHC-#s}}cAr}6ziJ@#FWR6%s-={IASTMBC|m;;!QbozC?Dl(f%}Vwt`eXv49t<=G1#v32$8aX zl}7}8qn(EH77p%j!kdyzc>BAP)Qo63Y`-|<$GB{-fogQ7 zMRJG$6;fp()4zxNdtPik;EZ#Mf934b=YPS6=Z(+f^`Lq&P$P7?@X5lHHT?atWk+24 zvC|`AAfTBw`rrSBRygN`hOf9vg1_IsscejE*@Ot8tWkezTg$b5JB&B%d_qXOS9FgxHJA4)lFP7BH6vr4S%3NCQY3bg{CZ&qySI zG!nsFIm{|v|K)P{)F?t|9Z}#DG0E~K`rjhJeEFFlPQwjbP((jL!gtNTi9k&Z7j9Q_-l_mW$AP4#{`b#6I7}xTNTmq@s<-FZv)^2I z{s6exEYKhr6yb1q%d7Nzet$jymEZ6uKg)qtl|;hyJK!JnVcdlL)hK|_>#DIT?g7UBE3UhsFHMBq$e!*Kt}A5vTp|8N51`}qQ?M2M~Z ziTSUs0lZLf3nF^X+Njq7i6v3X5-)Q4MyT)9pB^=Q2OV}ead<^}E-Na85WZjBJ3zl0 zGC`5;h5p>eP~S5&MtHKE|9)UdB6lI%Zh>LH&QX7napMLeX*g=20GQ3|Q99Rti=}^R zs=xyU)*Rn`*7)Iu|6TiUrlKxG&C&hQsvn08 z5Tgmgv!q3Tnz>|nVY1+Pu|Ps2n5^J=Lx30Ee+i7=vwK|<)DrSgot6f0d<)3F^QWi3 zo-2g>8ZgWX#3cWno^#Hj-at|dKn*m2Q)i=nsOPUyQRm_Gxc>ZR!V0Vx4>F6J7dnwH z17W?`XdnlCqOR(6or|QWzW6kH8TF&tN* zg~)>yYYQ|b2xoSbxx=HKKpi1w9cxxn@lQJ|K}X)RSK ze2`$<%CY*FCs2*xDp@gJ!DJnE+J(d1g|5%zp}xhDg<#x#{`QARy~q#X*+13S0!T|+ z1VCb)i5oc>zq7JQ;s-V8N>9-p5* z{%P(u^#q(W$uDIC*$~RvE{yg!b4?r|=~x7U-YhxhaQ|-V_e1I}2rXFn8~C6pky$wl z^54I}AF#=h)P67JOK%a?-GA8vZlo>J{NBbkToFmr{`4CR00}NB8+uf=;G;zqM6|g3 z_u_!hKnz?a(`^`(YDNCDbk4aIt~iXr6^Ajw0l3=u&j;}yWEMV?4WU2`G7yjaEmIU} z(u#i*5=6a&-Kbf){LeR72m?3&B3HTsoPnT-PVg$>!u~Hp{2=EV5bcS=(AuXf)g%8^ zE8x48Cn9NjG?bz$f&>(CYjyj~2#WZJ`!4-WfghCL21SDW?m=$-vxT2e9lXB=8#rK#@O*r~ z^sfnoQwq|6%J?4sZN&{hKQ=e*&rBCPyhoRo`g=vXl7b?s&eFV;KZ~HEBfh=$_nb9I z0Qy}Hat7TMiS%u~AX|QqO9B+pR#LiJC#3e@{=k<8Ts6~81~X11F0qvQZG+39H`L&Q=XZ_jB%{X2C&y?|tH)r&FmSana}^DhgL z9B=$3yuqv15@1#yB-1_E%lE=^Huu0+K_KH(E6Cwij z21vp?34;FUk~P~^7(SCfNFn#qar_hb=UPiR5&yxx7)Fo?1s$FMHR~!rvw9u`BxQL@ zcaN|$kvCi!oo2!i=`+OzQvP5ORAG2OQylW2xid__rUCjQ6JUQUT-GUXs^$2CdNTpA zC2I$yO!5QyMJK^Pq=4lXZXATCm;}Mb!TPgodNm;+h%6KIB!rBg4Ioh-W|@h(Zd?Mc zSV`dIDl&yp-nbWcRn%jb$IASF$$FX%LL~pRkaJUzNKylcM>NS&1n_nOkZ_k9SW?3P zGM%i~5~TSy*#P7~Y6i(!O`|F|bIJQjKwipVkO(USV1z1s&cr}6(}zoL`y1D#qbVan zx|B?C#Y^Yg3v&;jA?#o@vjy;weh+Li3tJk?){qG>$yxEq86?~$a>pQ9_uM`((o1iE zgpD{Lv!B5fuq>O1owo=8*Iig2!iiv>AT^0uYXG=DYwI#dKh6amxgeI3@Rau8S_$|x zSiw(CUsbcCp5Xg|i>%ss%AHrW;lcYjAjs(n$o)X(V+L}8zHe`SlVH+Tx0#zP`sH|f zDbb|O`~}w|SqEb@TR66}?PvWJhzQ?7;+gZx!Cz_?AnOSUVO6aw%znTeOj>WeBj3v5 zy74fENwsx`irXXt2gLqbnh>Ic*yGU6ARrOAjp)E#08j&vwwIor-#gZ*$|fB|F44b% zhgKQ*fyll@BajmABWe!Kzf6M-t|kQSQR{qKxryYTO9g@!8UW0d!T@BaGwXYW1|nsw zJYU4J>yHWSoq_wf;Q1|R(*S|cS!8_798Y0&y(OK6_MOuYCLDXfb!AA^F6+|agsczc zw|7|Ur+yOc_vqjRR7I=!RMFHs|2)@G`UKmrho+~<;MOq!3z@QKdIS_JzBHlT5Ni6mVo+S1GSdsh(V*3-99Ui0E z>gY@Wq|(HW{GpD~ctwtHdtT%}l2I5)YS1+iUtg9Uk%=1?sMl{%gTQQ%#*r2z&z&*b zfcl&wWb4cUT-a3*mvD)QEREo0Y~-W^W;uij(g^aYinHdHL)7!9&Si@PxZ>cC&;dJr!viq;yKxh0 za!4#d0N`KBHa-Q{DZpL(8Mi|X=|Bjbf3ok*i|WL=1V(iOJFaA^o2HHO^grs(c>$mm zQo@b6lukmt#Q)`jG}^R8_&_F*f!t;nF#FrI08)Kt{??6Ac|Z|A=^XUmOzRIW2KcK{ zzaF6Xu<|VCg2R{}Fb^92qaT1S*{XsLkM4X3Qg}b`!#93mxt-4zTxY4pL&Zg~I%_9O zsF_0b*0P0M*e}~GCx)a@inl-Vig@jg9=SY=`onG13urk%)G|~_L_fkFLL0$=SYdW* zy-|UWG4wySLim;o_R;7e$OwLD(a{I1t10C~@7F}pn+mz^|4<%N??GsRhImdsV1e|* z?Qy2848x0GOE+00|Cn$S;WiMaa&qS@=bN8A1KwL zq9I!Rtul|MLeh}Rbla?{WrB^Zu_P}4XrdmCk(Uu|29}8Ep*Y$QAfp&iqCN0Si~YG3 zfh1zm)JljW;#jHF>N_7B2L{c@CPCZJCgb#i2u!v5lTS5$;+w3=|Y z14bO>8nM%1xWle+*6;JD(c!)je=yFc0g`aY@f_Rx0^lujCNA@)>0l= zAL(q05mKD%MK#h8oZq9OybZQ_am6`MNIBP2%xBIy|FIRRhD@_X3y05O4E6GGSc`+* z<}r!*vgNk-wLBdm7)-=Q)|d=<&3L|y)am2VZD+MY$%Yc9dq!vOQW0se>wD(1>C`z= z-XrStH2SiB9fPB5BaKJYR@^sn>%ZyTYr_zcTC@N!ARRy=5$|IFlbWn=bQol!gZZj*jJi{F3V&{Osh-q z^=%pjPc2MdmQaWK+)NbmVYQ!Qnt0df~kE z0mpOKKvj;CA9sC-DJLwg@0TsWa*8ki!J|B_Et8NZ(c1hCk;@u(%X3aO4{9rldknHt zzVf9@HOuZ!i}#jU3vz#t+)Sn%%=1Pj7cGN6ImN7gXC-~6r^}HBn`eB?O@9I~MTV>>(ra#7<$EfE*lt4n*a zq0_;tLqhLu{Bhk>(g!^5LpXyruUcxba(XVS-weFpLCA4a^YYP|6|6gpec;}F)7!Vll!cPDSw<0v#iL_9ek|#$S-zQJg`0zpc9TS!W(b!)4{XtleLzY43 zM~Mm1o_Y;a2drd4x6YW!xg&4=L=WGi?nxioE9uhTq`Q?j7EcX>H|wt=z~p0b1vi@c zzY#xb(ty5eT^Vo7RL)nSt{;~^GoDgB*gl=|YF>W2cO7G^%2@Zw?)vVKKzFKGX!^KM zR|b6q1@G`q=AGSFbMEt>emc(mR>b6Lm2lbWw+ugjXyQS* zHs%C3WH(d_+O2R{k5`4B$?N%kUgR?T=$o3g(}!Fd(Zg#sDdgGffqnQji0;tI9fZog zv(`gF$2ZDmmF#eaW<1Eol6wg@ZPIkZfxZK?qfMfTvO0xT(sYk{=tkQ+qmVrXL?!YG z(_$5Zp7&p6(&}>x>-Vt|8EJTKH=A`P3lRcJaXPtJ3=!kdN;S<0<|@C@*5%26FcuMwcm+AqqI|qX!^^v& z=H&~y(}_`~OI0rGn1p#_q0UgxphBT?zA121>HCQ!%9M?}LxrpJo^^uycs>+subIjD zgF3ciEvHEVat#Sg7!615 ziLD;{6O`4idzTNd5{E*i6%mf?c6ZSB_fAW`Ja*kX!Q!a!!E(T|mo?A0efJr!45d$G zz%kQ1yQ@ItegI8y+U?4A>b*n$dZvS=ZNU|35Ot!rFyO;jx4?@%EsfQ9C?3a2YTjq^ zfu5oF%k4k6Nl+t#%REGX>_*XWHR4h>uXLy8!oe!Gap!Xid2Ppr_GuZpML8||G+4v4 zJBciGxO8{J?l|Mj?u2R(3PAVvyV(+6Nd(a6KciMQ>@f^M2I(vUCyh+gjK6$J8_-_! z3{uWhbK9OeZJ*Z|3U|=KVwRy6ELz5;Mt1T_}P}fqOMKb7Z zIsBYRtD>A!GGb6gP@rEubtl`2Y1rNry@OZog!N*$Lk_crxz+a`2hOW27ia~w56_P#&WcdcOi2F`Yn|py?Wnc$U z_vAQ(A|yQLt}{ZQVNY3TecD=e*R>&@MMh$8zegCRZf^qGm{eX%bnK=)W0A7(96WiD zSBgQqg2I}a`2K*HgzFJ<+g8^^@7&0p1jf)4ZZ2GgyO_Ig*3*=O74wGep5ByqUl}iL z?vNw37ekP|kVBaudRklmvBLhl`+kMfEf#$q z6wy^0qN5q89S4-aWF)BRF!F)#kR#VodC#XY_OKlF!|L6m`a7W|bELUu^%~}jZDnfa zeUp7H4wxNMtxV^dXCNN}JX7PZ)1@9-;I?}XZ9VD@xfuM(rdkLguePIz`@ZDU^n~y7 zdy2}`4w8w@p>8)-XSB7CtnD=+Q4o)Jq}fz^J_J$9qlA4J&oHi+zo*z#DAq%Ki@&R4^}x<16(c8lHM@D(S0 z;bBx{U#rc#oaffr-<^Oy2c1-p?fD_ zM|Q5z5F(d>bUKOV&w@(n5SqXAGuSn=tyz67!*s(Sp6sUgt(j?cFLwL; z^Lkq}X6BN)kCD~yZC*})xT~6Q1j9{{f5k_GjgO@E*mQ$*(a)m8l z+oiK+pQsa?Dj$EIMQ(%by6uE|3kJiMsO38zyDKD=A{FZbb37eLXt+s6Nvrq0%2cZC z7yU!$gPBECY^UxCoG{80b6;KLHfa&azE2X4&wlyv)Up)<6Z;}R*~D$g$lfVcJ>DlekZ?Zeh>`xu zbd14rh<8g3MwoZGO>C){&9@qZRnp0o%9D{-k5Xv2W~1UAcDIClRK-`(dpi0!3~#XJ z59aHcu=EP#4?WwreOKZhEIZqOJ_GT@E;Rvh_5Bweu6YV{kh#}!ouAXEi1uka@0Im zeY@S$uP0LBXoxaegT66NKh+T?zjZ8^cYiCB{{*`s%u{UjYD~s12 z=rNNG78F4{h|Gz)QxI4MQiATyY5YFWoj=$zBQE7Vfy29y7!t%1#4PSpeZNV>XQ&ZN z`kk|AeLgBtgDvIB(j)uKf$IAk_n{K48i}-!g?l;I^KeWv@DM-JV)k4xg(zritRjVkv%3Q$}gxp z&7ge;Q~*zht^_W^M;IoTG{RO!yK*x<24~4Lq@w-Sy-5RL;?{l^ukA-F2_)vN$BEg> zLT(xpIp2)`7=`$XtHzj2l3aISbVfr0a)%FxtxSO(V z2kpNiZoOUb#&R?V+B4a29kHw7sw!Tqp;Dl7ty;hpzr5!A&?nQi4B`B#iqJK7?Z)1zr`|_q2)o~X zCpATUuDr9-vRU%(7m&+}PYN4YBF0JBL(tHzb^gwEb0BAri$I$Ck@l?Nm#2jgC#dwxxw!S&q_myUTK)-wqe`EPQA{6i(1`|)?Td(-Tg*GR)F zS&!JK+LTpSjKqTIopCyD4D*XeB!}F8fN3;X!YVCLCh+xz|11@ZHQUGgXqvcFy9!w! zi`-x&-Hxcw_m?eTJ>RaLz2*4+S5AXLdpZ3woaB*DAHFeI(<(nV9+jFeJT&MZb0FU8 zP|F)}|G;*&Ho@@DJ-)b?rtGlT`{IXr@$E2Ih3#Xz&&B|LPQ=Vl)wH2+`fxGW%WQ8m ze!@w@uf(ICs*yln%XzS`E1}wuj0Ng;YCg`hYu|idQt%x?5+>=r+%69onI$v*`}Y{; zCs!h;*f3Lk7AoEm7jG|IGoqN+5PvXIcy=m&8vTXhy6oqiG>{Qb`JPPjUdrLFr5~Yl z#Ju3f>gi3Tiog?6L38yl$<_A4V#~c$#)&tyWC?jO9(L-K^cJ0Y@7vIK*Y9b32zgf2 z>An7Lsi!68UK|bYZfX^Vb`58f_%yiJtJ8vI#)SO{ub;?@W8P}S-zmgOyk1VH$UR<* zBk)A;Xp7QRz}L?lvv6GzwLK&z5(c>kLJ-ue^rypcxCu3* z+z#3~?Z@k{TYNT?zVWJOs#cDx8i2bkx;Ha}cYM11Y8>1j?ivlZNnU^IwWX)X<)P20 z;vVfH7DdKhM}mP&;(8Q~c|?0VVu6kiB#+a}ssw6!w_Uf<@KF;}wK{?xfBTA8QIyx= zPOjJdF^KjOfh9{Xk*|-R#CY%YzYXYjtzZ2@B6Tm$AtXXQahoA%5I7!&VT*U?&8YT( z{oI&vq6l}o_C4M0+0~p_3Ja+(z$|9=;u*T)$k3GO zZ5Egh(p(qO)d>#q5pF>)#4-Gk%|ifP$w~~9nPF6hWS=w+AbByBKOQG3o7v2b#7wEm z1iF5R5fMqv{Jr?=cuRFdqaJ1VC{_2+5nKJE4B^$>)Z6QA@H%P5^ zu|A4zft5*jjeJ4QQ}dp4`}%=Da(c1fr>luVJTi6bo%}@i>VtjvhK=`Z>)pt;vftN4 zaKB%K0>k|PEO5Z^vKFSNRMwo~Us!Vmxv zockS+nEfDVW_)D8uh}>ve*YY7G?9+f6jbUH>bfw@!vZY$?`hLi{xmT07739q?e$$; zvTU|d$ARKE`scr~-I-`jIda{ZVVY`-TJo>OaEw>;`&)7LMZral@l|JhK=b&U%N2(1 z@eK$M>2uV;`-r6PQIV+ps(r*i98$C?zqVbPu)NLtj|V*jf{h1WkK0LESWseMaHbRq zC+RqA^5;F$rOlxd!a6s^+g4gW9Ha8!eALc{-}xN-wLJsIR3Z0$hF@|W?lPoDGwY$j zmV}R^IQpeZt5o3}a&L(R;pdyrwEyxjq)EKo+272>WlUm6t{3|mFak_vdbmA5&jibO zsAaw;*EqHOi9bFSiGq9C|F{+sZxmyLY=+C0x8NySQl%i77vPxD^lAJg(PFivKOr0c z3t+hq2PeUF@R{L&#M+C1fZub9YLCdqkcNDKdjEgI9eq1+l%CvfNI^vk^>yA^((4@G zCi5N_ll*I#59hjj1#InvQ^n4PQtB86et|Im09l$){U8`-9hk>a@@?_gwPz~skg{j~ zJy?IuH^u8ym~x|Av})MU?^&Ipe zFUipjf4F1dum&;R%b|wZx7XBOfxn(16^28T zqDEUF@o>GnHbL5Hvt*E4MRsP6|v^9!&+0tE!Ay2yoeMJ?rl(OG(+wiP`&)#kVGUd?`A*0xZo$A z+<{R|-2o<5l%Ybswr|2Nn{G!iWj;l%GPgoj1q$)mkJa7-?nPt4v12V%9fJZ>wd=qm zC03wQ%y@0%~+tHjvF2Tgv0^v=$^2O=+|fooP4IfOB=_MAX^(oB5}w_bO{< zm1#Wg9uKd#@hjM@Zr;TL+VFVR%8NEdxo<6{aggm1R@>drT6pWDu=RRMfLf!$TJ$l7SFV+ z-B)tZ!C|^Y9+7guT(!3zrR-cBE!oqx%)cpKU9>yCJ)bjFK{?eL9xfhNkG;Ui)%7mE zJ&swJEw$P=ef-+3Z_-Yj24hIcBF^ae0a#)dkt@5N9fT}xIvy{_O`@B3 z9@QJQL4_qS%7=tz@QXd>DUXk4^zll)ww?P?;-a?|$UVPoGQ+1zXnnxXr*e+@IhI3q zmtBaf<%&@_kvL_O464miIbU65^dkPd6621DO3S&7gp^e*FBI;PoypR7(DdaYU5Nse zUGj#{#j0|o{5#7! zuk%h0N#?MXysFtW6)s>tYOs5L?UR8Vezw;~QxhF7BMuelGCZ=Mym$6e@I zzHTw0nEd#wjXm$Ay=P*o?y54-M*RRUBUUDrY{)p(QDU9OTV=Ezsn&hnug?G1)>%MB z)qQQ8mQWByT0l`cr9rxsMkGXfq@|^#L_m;Kx`&W%7`j2arMp8qq=x#==o|X}zqMSm zMqSKs?>({4-uroe^LMLHn%Va%w1#czRFet5jiEQ;LQC6Pg}KMhh>1R@NN|&Yc}cA>HTEQmof&sisKJCOww72@hEVjo zf7)kmam^nm`2u6oG(sLn-7J@GA2C5Xf3zVnuxU{`WWYs?WK$P-t0RQgnCg!S;wyL7Izew_e zk5Z1lJZH`{c?7m<>y)V-KJ#17LD%;ZSokbc0bMj^u*|t3K^kJ^j>HfZ+Kq@D-vi@b zjtP8|=@ze&jJ}2Ol8j7E7=z3!Mtzi)u#Hhmy|eVK_LppUB{82EbrlZ2yB%zf+ii|l z5)mBNWDIn8@K?7(TGU|yPsVKxIef=$jkusw;aSf~eUI)oB}_Vsu;&{bVgqy2rbK{` z4$Y7Yt}nYVoIQYtY%O(%HRH#8W9gkP4hRnRizs8c%GYQ6FXIv+75o88X3LL+IzU=0zW&BkF23g| z8+y6i`98u-jT7>s-VD`0lEG}1JYfJae2;e<#TTRUduS~RPj_j~+2B4`T!h?m1$728 ziA$ZJE}=5scZwq6M~ocik8{C%(XZGBzEGD^n<$mL6=;I)r z1`Nrd?PCzxsO4PW4G(y9!r%k?rh)YU5(VgEuTGzwcXjnLswp@#GJod+n1aBjK)S&N zAJ(kXBPppN)F_indsNWEk@CjpnMR!+ItB1M$M)39eHUpfcR&HME#7;nZE^I8F~x?q z5A5!tYK{!BlDQ=;Gl!3UQ9gJ6u~sy`O3-I`5Ebh{+$eO1S=GDx61xreE-LDU&%l*t zqXGKnh0}$@4_0;V&hI7XOVQvX+qEgZ6c?-Co@VctzSn1jKrx(cV`(qCm~{)|U&yzsu;E4a>SAC!Xldx} z#S;bKp4e+gzyH1S4>9YJ3=n4qGc+9!2wrJ^roQ?;r4AOR0sqWrjh!Z1c^|b2Dud1J zv*F{lj&VF+hinGrF7alsZh~d1ZD%pVOXY3?jxB>pJrtfY**4w70Nqh_?>j+}4Q0Yw zvkMe^c6f_RDeZ}B8%%k1e`@xmjRqvsQYcd*vKmao9!e9wu^dE?z)@}WR$d%98Z1-DDsZ^y8fIv;bKIMf4A0XV@qfED zn6a0p5Jf7viK5pNTB=n2=5BSvA=1ZCnx}di%2syzxcmEO3{kg*I8%Q z$fcsAy6j)Qwo9(X?}2s5$XN(o)NEJhWyReQ4&>?@O>&DmT5)~Os)PFYxDsbc3Y?L< zE04CScE5eX{bvkMCBDP>I}5k{1e|{a5=-^AIqpue&cHBJ)6WC(Z-0O+oMW|i`WajU zW~e=b3#L8W!rl6pO{Ya>t1{O~1u;3)dnHyW64=a#nUshp-3`cYJ#>C(5Rvl?m+YvZ zElGJ6a@ebC#Ezo!(T&4;NrY*-_-pR#adSOZjl;<>@~g3H{27iCyjx%W@8YNs$v3`s znPe7qwT5fj!wRy^69<5){Z#S07OJxMvRlD@IsBqXTCUq^Tf>6x1^1Ru+DHqR!yh%pHs{ymQr|DqQaewW?%_?`g z8lyzLk9}0)WOx3$ZwC%d%p1!O7u?r{&-cCN3tt@=Tt7XeWg08IN$Gly9C=YWl)HI) zJYByxuzI)At~slY{@Fw6D!K0(O#Lp{+ZR0cPnJ@oKCMc(AL#jwd);hgKiBLM)&l7KWmgq zc+|9@z>%IvA2QvuVm~6AzD@!@+gA@1V#oO3xPEht<)U%_c8yq4O!@=TCNPj(JZ3)c zYC&^l?6ljX$&a_>xBDgsL0{Xn>n`VaBcrT*u|PIyFC<*F_!Xl?b$0y+MIU`U!343Q zrX>H=-51s3g54! z@C1ely;}n9p@KMY-0j7*$OS|HRFR_hItx?FbNek_#6s@G-@Yg=nn#JdxW;o&&X*jG z?XBYWXH2YRrG9!OFQa>w^P3^{KZm1tI8-1pghDH-4LUW`7$c>;(r@U*tv?YqM)zOB zJH@s(6#2FMxMaiqB*i~I9h28n zq_*~pUleYX6%^YkhvDAO)XDA<+EmTb^fjK{osu>`GG@=X5Q*tOz8D-`84)MzWd&ul zYpj+nEt9lO*sMVuewdl0h(6G#bI>-&BG4}t-mM|{8l^w;-+oQRh82jv8$ORABO-f~ zgM^d_PTa<_(^MtSQFJ|~aNv;2^Lnz`@ z{V1`+PAM84pVt!tf6q|ppmr>#i=SA}=M~&=^Z#GPj`uB3s@wfySyyI1HOW){@A&_0 zs70Lo=iI@ltDNP-*`mmC`{N1xJ!<-BlkoWwx*jy~>R-8n-(M3!Uo9e?Zl^n%eXPz+;PT>lHt7^Yg&FY~H`Opr;{W-uWCd`g6M!>Z`1a5Y zU_mK>SU~+IDnem`Xl>oyBW;HY3*!Ph_C4_rbHFk*`4T-7*P98sl;*dr8tB`R1I?+V z%vcIgp&;NOP6g1-QWB}3(m&}iZNAUWN7cSY;c#QE4tL2d0r>54n)D+9>RBV;Wlx`0 ztGNAlEJ4tk(2Z&U?_3P@qNA$#bbg>i=KA@C$%;u@m9}GmH%#%^=_Wiu8SkHmhIrFJ zjb)-FDvxNC1tNza;3bD)4}JcZKE(I7AB7TH*g;nNCfq8+%zE&eL9CQt9g+iJA8Pu2LU8YS`GM*^HV#( z?&8!~$9<9p?g7@5BfUOZ79Ptf%p->(gq{nE7Ebraozwr>5)7yaADrJMqPz>PHSUhy z8)+V|c4S3Z!c)4R%;#_`a zE`;MH#(4Wj<(AWC`9bAbyr8ok(LkQBQw!&AN$50D|9jp0wMP7Wo%#6-lv}AiM3rl3 z!N~=V!p{3kjXbliiwlBo)!WLv5W44?{gbLUKgjM?X#lv)%iBqXCxD7kWAFUGjj84L zlX|QE(ie)As{nBcLKJ{-4jamSF&HpB3@${Ju~07NQL>P#0=$*wq2>_bOJV?0!%#m-m5how9m-P4)T!miCZKx<{C3C!XpZ8(U&AFA0VI%5 z><}rK#pK9Pi_?z&?p&i2;3La(b}0>=0;R(zK(ZxZRJ(q5yu)KU1$-n4mcjr_75M3( zf}9>}sxD402k?X|U_T1F0yfAZ_p*R`E4_Y6CWk!-9O{g{P;~RPDtE!GTLjJ298W>} zKL$Ee`f_*7?ZFI1p1mpHGjttHH0h7G9u@+_W+}d=$)R#!c4{rRG+t`1{@C^8CdjKG z9D8Opc8VZv{Qx2LMK0!>7RSg~wpyM)aQR$l^1%t_hyAX@nVUcx5 zzMpU_hC(a4PiczKnYwG##me4QuBVUa7C=kvWO>2U)HP0kv!m8f)_9Ns9O_~@S8t3L z3&#_778M0XY?EDqyYDGxxH(o7l=Q@N&@3vRPD8m6LP;0BH&xgR^h$a|naWaMUr$vO z@p%N6d-E&IUTjzIu-UIamx|lvK1>jB#N8CwNFgpaA7vTTg||%Bx*U^j81ngl2AUYQ z`{d(@j0%`%jdqr^!@_^91(@_GX1^)M$-#=wr)1)bX2LA-`QwN(L7)jbp|HCvb@V{2 z3AmT7{C@Wps@{AT`TPK=@({LR4Hcj*s4#X^48XWQf#C%+89@1Xn-(Ll!Zjx(c#(eP z$NF%W26Yi$WKyd?m`1_C5}D*46R`ge6f1i@&IUZXK@g1sT=daf*fcqnYm%3r0Y+sI zI=Lh%wj&d#aWDCor(qaS*L|#KX)@^k%0Ntpl(!OXiGH+tvbXreVyFHN5#S#5PXvRu zG0Aj}ATi>+%=TdWXKe9Y=7eE2XxI+0xm1yHpwWRCwq1AMGkyz{D7(v1x}+?C+|vN$ zWXMN5qq-jGKD?UOixmlo=oyNyqaJ)?2qb(B^GiJe%MkxkPuwV`8B7GC8xu8ev7VZ# z0c^sR!oQ%;fXQldQY^%HqPhbnh={qUjv^>CBKOs+2BS>mvXm}})eM8yFUe6r7-X3zlwY(AFlL6l$vs$)|h z$$-ZI1$t8He!=fpi>8@zhyK}Dd}$m$ijx-T_sx2cY+#||9Ow}85sM@faLC0+;fo9r zf@Ah>(L4?P8m{kdYwXd{T8S6GVD@O7$4X@uOvaueRTrCskjEQCS&*Z=Al*aT3Hp|o z{z(M)Oz#bL5F-`S2B8i@subW7Wh@4}%mUEEB~dkrY%nMce5nwv z*M+@K$&~usDhyfV?7fCZ!CU+d9vJz&Za9ifUkuVCHPFi-Va^WcUu0+QDPme~`#Tq4 zGX3@Y7d3L`d=qC$&kqY)Qx!HbcL*v?JdJQS$*|3VV6}7y8My3=0=3`W#U+hOB_v7S zu=(W=3*;Fgn#;uU_xz#PBPGd>P4OM~79_W0MI37k`Dnf;(~DqtfQH9Nq+F#B5jq@op==L6d{iUv2IEgX>Da$ce!GtyLBp#hU@_%; zqH7$#{d68Ioxy7Ci{>F0_7Wz)P1awVzt*RBRZEp%-a2nry5)SfVR+C&*i{vXq6Bnx zqRAg375HqIkXmkNW(|x+dXOa}wbsP%JFj$;aM<^k!|60sb2ac)(&gBLcM;ody6m@a z0rpCBDTcQ*p1PlHl?S4nb+p_7jlkF8I|gKObJ(8~P?<}s#cv_Z(4l(vOC(nbjCnH8eu^y>U{ z6&kmJp>TDoYW4kFT9B&#`cPI6${hkG`rIPkKH5Br%7VX7-an(nT(swvzw(}V;0~Q4 zJ!Fzr{*uysiYIi^z=SLE`Qv3KuTMTulP2*#gPACYN%`)8%6|*sDa`r>_8#%ce-^4* z^WBs`1kgCF#kLThx*o8Cq8>H6P{(&Z6%BlU>mqu9RTIQ_qBvYf5rk$x%DFA4cwG;N z)umo97$CtOr}nq1(hIyrcySfXd*b;@^Z{T=$oesYiqb;S z$J(ZV@p`iJtn5%ZJk_KFzUCXeI++~?ts9mdh$IYpC3-J>(AxQuxX+fL-((tr4*4~= zoH&qwE3JDbAV6krzk;IkxP^Nx509G%Ax0YE<#yVjuY7Kmj)Q3Gt?PJG& z7LPGrX=iNxHlt&$+3528H0cg$UIN&ljcrd<5ut+!4j2C+AZ*fy`G5!rSChd8>byo9 z(1eZ736Sb!T84Ij@08?2sE(J0$EomeX=niK@l-(MI@g4m>!qd%V~XRoxlhNhOz^7a zSOlu2^&)gHJ`_kw6~H{pd3+Rc4TkZu-o4glTQPt|Gtwqr&JOoSbE}XIK2n+NK&Tky z!AUFBlmM+#=Ak-gnu=SOFG&lBe|T=#dzy{qA%)0!voF1ulWVz9HE%gc9D(S#F?PrZ z?@XBx%OlZ57|N3K9D(Nkf_?MRd3KZvcL+J(dl1GVlS2m6a|d#Ntgol~$!jz}{t z3f5b-5oE7T&C09_JpUY{BcFA{k~rV6vg^=v#>iA?h$-B_ygK<(<^iB~+0A?%0K-M5W+HnRG1 zH&4gk{V@@Fs%m5kc^?!(#Q1%Y{q-Ib;f`=llRqSKD@ktz#OER-`$sJn+;K$`sZUDZ ze1FzoJ~7wmHJjZ8f|&P&R#vLKnAihP>kT9Bpbb|_-qA`*7W2VQx)b;EjYh(M1Yg$b zDC^~zCkSgIs8cwx1`6QQ_ELiARmhT$`({0%v)HBvwuG!P|cw||MlNL4+>hJ z5QSoZv{fjwZM4af{dG)YQJAyH6V-OrNO$>f_SA_G(P5%>CxnsgE#a*o;01y7jta0V z@GIVYzeOSBiplZ=|8-EN!GG^1Lb-XXANvji8o$wOxs~os2YTT2CHU+6@}=g0GB_GU zDBujRVy3O)@y}5XyqSu8$IpV&s0dDgn&70e3y3ffumjC?en4o@3I6p@aIM0S3MBUQ zM7?(3?4b4JZb%G*b#~j!V}RPwLGO9HReCl67a(f zult&SJ92WEj5soSqH#X>_o9F$1`wh$v4PM+8Zan+GjVXO!C2$r0DV^@qaSkIv;XR* z`E{L$*IiOXGC?Qj1wt>GEFseKpV{)OE`|0Gd6c04y{&h)?EiDTlW5?=%2dBUM+27e z%8rlEc>YMefbxIXySKlzrodU~y_|?Z^_F@3^vEPW#nc$qWreJ-plJM_k|JsOdK1M@fO%fEc()p0mqJX?QH>KTDpL7p* zVfTGQKwikGm*CSq2h1an1wCKAt5qBFOBerZ>LZJrWd&QQgMUZq|IAWrJj9slwcG$D zB0MLOtiO}ab3tgAE=R3QoxksXzfMw^vWS${eEn6^EylmB5UDUR`?GN!Kr2X|xTsQG z_Fo_GDT1%0|JQv0b{!2^CYNSnF@KHA21d{4&Xd%dHMu&}_Q2+1HxdnKy#F1vR25ht zWhEO?P_pMjIF)d{7Y-G4!TnHf;blm2{_=9W)?;^V;P#b~x{!b;@baJE@t_zxM!Edi zO#=V1mEjMtA65-yhidP)N+@Si?AK7x-Y=YEI1tyAq3&PDdhNpUQs?eJYUaOh2oVh; zk>S&}ypwOg#ZKVmt9Zoj(c@UHx87|il>XwgdqnxZ29!W~#(d!Jm5`g6B>LI`LK*CL z)zeUaRi}N5#I+LAy}`XL_ECoNgxYwnc&h&D=HcuW$`Vn3EHK+gV;1;v!-QS>lK832 zTx*X2Sb7~?WzXhPt=QZ<@6U$bp_D=Ejj#58Q)%Y&Y=brS0)Tct<>{en)!Cww91OMe zPW$cxvP%1>>fV6si8U8Hm9!xWkpEoAE*nZOO04gVp2H6ZlS@8y%A7m~t$s&p38@j- zx)qdyxGxD`V=c5v9_4;#Gdiy+Uq~0b51QEMa`Sa~Nr4yt*VvYND&w;2`4hubJEP;% z5GqO&(O}g(zs)lbEIP1aiXb5#l0daNCdHH>Wdn^i>)C05`cGuW6BUY{iKABGV_hgq zg>8@8E7qZ#MPU(Qwa4`h!{+7WsC$aeMwcsRMJ6*9{EqDIonq%~uWxC>cD!E2WGB7# zQkeUpKx5l!kb`$NpYYu9vyi%lTw-1LK<4C<-NB3E{cCy@c5|>(-~_!ycg|8wX!4HL z1O1lN0jG+3==F&HDu^)18;rf0dsF5Bb@zS#A}3YDM=j|v@@b(}WbT-E z_v!jQ$;fO3&xqV`^XUrZS@WfQT&sH~w45@@&fMYtFZPPOFKyg}U)_JSoEI<= zB-FfCRI<0|N1uM3x%;h~0I8|nkc8*69yUNgz1=4dSf~wqHc;YaBgJQN zNv~;QKJsL8(sAC7Ek7d#=#f`H%o__X!*i!F0wOI$5VYHk2Rm&Uy;__XK@qSA*b%0d zOi^Q&jo*66b6tLr`Gi#CKH4g_%3VB4a9KIA;BHe)ho<9 zqmBV@;8^R$S*^4=Tjc!Vaa+~a6j$;V?M0DImt~1=#cLc0er$#lWH2O8;3(BJZf50j z-mNRExZ4RB%oloeaHyjfcs5Hba!jD<0KXP)uF=u+mJPXhMY7p^-C6inE$(cmz^coY zm(GgN%7xAMeS6m#bGr6#d?C8W-gZJ;f3-FO0&bG>-|yS;F^O#DD=lT~f#Mc{Sebz} zj=9Y7!f%joq?N3)YPD4NRO`1l^jX`^qCD`Uyapzh&62Z9ors^aXh+5dt5={7a+I|^z4e82I`gW!o&P=e28tw2i485g-+OkerlK=Dp$UmcHy zr4~EkDyvRWK%}h3SMPBgHON$7ZGWA;AgmlGFc91=R-sb^Hh^djkmT^yoBwtg%zkuv zL=?|!PeBfW!|2&uE-9JzHFxubyDN-mm3QGMUoKqy0J=n$N0qT-fP^001j|Dr^j5Am({``&hD+`hDtVxHHA2!J#sRnp zr!hTqYkM3OZmR(G&@-@T-00$a7C*szdYpDLTS$RGPWh|94g%C@gT3x#jS_v@$by-s z*G>hJJQDuI_~udP@86borpT2#IGvwh1s0AJUz^F%#rHaMZ2D>%FhA%)K;~BM?zT~G zC+HsG*vpgDC+!EEw59MaI^99fQ2w-Zx7$v9TY*axAM{94q>KILi@$RLXj9Ses(v>s zoFfFm#<-%&cqn>*%F`PJtf6F3kBK3_dq*a1^-t?rML)miQ%aV*_tk?I7vPXW40Fon zW@eA&6L}(xX|PqZR36UfQ$J@=|ElrjPIuG|c~Z5qfNRDRZ$m5<_t9aV7JcCm4W9*-Ww6QnG?ERjm=TSh*%MQ9tqt){?y1&|Sm~FoP z@qGq&Nx4cwsODw)du=q$<_8kNY{zs#8TluAiGlD~o7dy%gF^;!CADv0%b-cu` za{VFH9yQ`z1Zio|toD08xK>PEMANrTE_8aN|@aV zWEyw%wS%&yaK2XU$AYa;@9(8}M}XYf|;> zuA>>Ll|oJy*4@+9Wnzh1F-lcVLQ2=aSXb(ISzad_x&yctoD27NQV-*i0W5ygX-(gxM~?W$2!#MV~X>MzF1;>Oi-FX7$);Sir=4>)IUbK^)S$P zZ6Jj-fI_M+>+u1(fDK_s=!2zv>Id?n4MmjHQk)#jp=tuKqh!_Kh$lts6Ni%{$sy2z z6v@Vlrw5-oA%;sV6PU1(efCtrN8<4CqpbiB0!QwP$~N+!j{hD)?Q(bX1}hjTYPFcd z7c;DlKu(V!Y<-l)covm6$g(ZpOX_-ZbZa{>aDl9DHye=}X1^Y;#SD$dj%#GeWTzC@ zuV(8|REVi@`c4`<(Nf`U%J|NcP)xmG`c*L&y~+azzet)U-y4!&41DbPo?#O?+0VF= z>27MU?;a@XE(FXpcZWAoT(~=guj2X$xPQQ-#8uuDqd>oAWo4LPv+~J0OoG4tLet2p@B+MZj|3;KIJy_O^3#7|U6pQMRf)N%y(8=(d4# zaQY^Q!@a$Mp$HY? z!aa4?A*Rb#K7UzlLtCRmCIls_&)2>BF@b1YOX>HKkMV$Lq$Gf{ddmf=r4V(}m=uT8JeH<~RFj)IM(}!6 zNP$QO9$8$?lmsRv#VU)|d_I<1t#XRQqe!(kneJOd3~XAkV+h#)<%BHT`7G97O&xNv zUDOO#@>>!;&+Vr45WN$=<5{~qoB52HtMID@bN!u5$kCAc6@N=LE#q0gzSfwU)Y zjJDiNk^3!P`IteiN!N4c5;D);Dk9=}*Sy`a>^?rc#k@t{BFNYdl(@pyz-Mtvi?_I2 zgCo{_u}Rg4XTIWspIcytyH2~_{cy4p8xc_L_0@T7V_glUKK}hFCrXJdf=W2%4U__c zc#xu#oQN+sVdf1A>74X4&9JJa?wr4>q|J2svnJYpg3Q|xn-CBBEEX@0(0diRntAXkTF@;SwDZqqj@JxQ_0lZ+ZPW@Vp{YdMEpIB>XY#<;;-^n4ql z*hC*A0Ak`>V(PQV_3sDC#-jkPiqv!O`=GHAJS(fcE*ZW5$2emU#0}d(#h9t2t*LN{ zv!-J(D%v!+d}m7hl=QBMG~DTwGB2UnNWnaq&fS_ckI#BySF7mK#o_ZV0Iz72nUzov zm+xs;yt&iD0K;JJGSODg(fmG|d-HBY%~UcmmvJMh-E{wcmR&itzjmk3h(Tu=TQYEm zt2iaI()em1Dy_yH%>05%9pTOd4r(y_P~c$@hDp8Ijt?m~8JyqV7C6mM(U}tUuQ3Um zh7vU~9SHaW{+y@KT8;0dqt59)h`Xl5<=Ky{7>tg^&kl`|gZD4i!JH?=jY;;K)8j*r;vddY&_D_N_0>DP0DoxG1$3~<#8W^J|FV7*Ix zi!hUwJ&NVJe;;vq5TcD9 z6}9;<_VO#Pho4!DL5bWE9Yhm*wxp)_#Fd#LiB)vZ@*iT{NbqLm=d$}5PNn%_pHaG%kpqAdVf3C9HkHsN_D_i z*_6d_iFxw*KIyD(ZWlH|INiS62n16jcx#1u;A^gyjCsZMS+GH4=wXs#;g_eksAMnU zdIGTARK2#hYvuk;(jTVmKk>i3@v18nH)vhm;8r`c&eT}aETfclktgfh8;ki-O7#wW zTD9)CwK~Fb()nNBhI0!QFZ0QT)`i;eUUgZO3}iv5Sr6X|pL}U{F(PGEXOfRAp;=p+ zT^Or`+_rvej3L077{G8x=hWFQAH)>At9usE%YKHDZOnW%O~8zFo!x;*kL;)6kSK=< zl{w|}O&8bT4f4E5vTJLdGq^T`+MaXgvvaev!GR;m#gxXrknnt;bG+|{y zxY^-V=-Bm!cl9N=BQNe&wBc8>u+!xaky4wpuvs`{^+Si$=2)q|KR&LGk&SCOt9HL! z!ep`8?T%kp4(SmcVZvpVOBrWN1+v{KkL|XnKwAFe-WG8 zsnI>nUykwESLI(T^hl*xNaVg788%%CH zF_TXUj%poiv3ad_Jm9tXwaBR02p4#)x=wjm+m|fD4eCvhJA6c(rr8owDEpv_$7q9I zRGHYnr#*kY_qgeltZ+h|nqi!Lhd{mgz&!rxtu~&^20DtyNsmkV*@FPQhC6~#L6_~k z9~-`~{gh!%u%qb62HqA}F}DfSBT@JWs?F+@Ff=*}0be@h`<{d{y*5)BPM^T$u^l^C z(^scKs7JGRgAALAkP&VViPH*#X+-@Z>D~R=x^imgSGPUV*mg_x(aem>N=*qo>&v7-E)ffkp zay{b3h1VSl z5yg!1yY_Sr@s|xIjkh$lGoR;U%G~KA)9i_JFjr+nhdV65nqI&77Ry`D4Lhgiso$sj zxySr<(D=jnGXNZTeOgNL*%28X5xU#FXQOnFE9~jQU6NOt*^qDiDHcYN0QHI341gM^ zGU)utG++^Js1?|o>!p_nh#IcFmi%9%Z*LMr`dSYs1i;yRNHj=IZr)b12Z4}&XoFYv z>K2GQ+4vl8{As)2^Z*%;_zehtpZmb);FUcT??lCa?Tw&!Wnf`dEL-eCESs6@y zh2wV0Lk46CdE@sBEuy1d+c<*Pevq^EA)kdX>(q+?V`$`uN$0=Ed94)@J2uFDe5`+3BM_o}_Q%g6$}^p4@3lnimK(FJ zM5RTz{;Nnqbm?It2t2$0uOTYp)8=B(I2jO=9+T748Z@2Uc=Is(w~ji*0HNZ=%KS&R ziZDgRf%ShWDEq7U0(`*xHU22XG{_^&g$HkESb`Dcjf-6RC(Quytv8P_iIFW9TZ1%e zoQlN8^pXy84{{MsrZ06-^>=bKss9iOdxAzhG0`VfTA;rCna4`!w~AGH1qP@UdxCx~ zw0ZU9?0+Pk*4ik)NJ14Do>!8{#WcsNJtonCyR=NZJ09hN{mq!{0q`kNd<{~ IF}?Ty2i+r8HUIzs literal 0 HcmV?d00001 From 7f2e70b7c5f10024c6d04d6ee887b85734de358d Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Wed, 28 Oct 2026 09:15:09 +0100 Subject: [PATCH 07/13] Improve wording in comment --- ci/scripts/shipit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/scripts/shipit b/ci/scripts/shipit index 19286ef6e..396c22df1 100755 --- a/ci/scripts/shipit +++ b/ci/scripts/shipit @@ -161,7 +161,7 @@ releases: # for deployments with sha256, use the following line instead: # sha1: "sha256:${SHA256}" -# The release bundles every SSL variant; select one at deploy time (defaults to openssl, stock): +# The release bundles every SSL variant; select one at deploy time (defaults to openssl, no patches): # ha_proxy.ssl_variant: openssl | awslc | awslc-fips # ha_proxy.include_haproxy_patches: false | true # append the bundled community patches \`\`\` From c64352c04bdc4aa2f543da9e950914339a2a3909 Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Wed, 28 Oct 2026 13:31:51 +0100 Subject: [PATCH 08/13] Do not use --fix by default with the dev-build --- scripts/dev-build.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/dev-build.sh b/scripts/dev-build.sh index a89901b75..0c5e8c482 100755 --- a/scripts/dev-build.sh +++ b/scripts/dev-build.sh @@ -15,6 +15,7 @@ # ./scripts/dev-build.sh # build and upload, BASE=highest final release # ./scripts/dev-build.sh --version 17.0.0 # same, and override BASE # ./scripts/dev-build.sh --upload-only # no build, only upload everything in builds/ +# ./scripts/dev-build.sh --fix # force re-upload AND full recompile (corrupt blobstore) set -euo pipefail @@ -28,6 +29,7 @@ source src/aws-lc-versions.sh UPLOAD_ONLY=false BASE_VERSION="" OUTPUT_DIR="./builds" +BOSH_UPLOAD_RELEASE_OPTS=() while [[ $# -gt 0 ]]; do case "$1" in @@ -35,6 +37,10 @@ while [[ $# -gt 0 ]]; do UPLOAD_ONLY=true shift ;; + --fix) + BOSH_UPLOAD_RELEASE_OPTS+=(--fix) + shift + ;; --version) BASE_VERSION="$2" shift 2 @@ -99,7 +105,7 @@ shopt -s nullglob uploaded=0 for tgz in $upload_glob; do echo "Uploading: $tgz" - bosh upload-release "$tgz" --fix + bosh upload-release "$tgz" "${BOSH_UPLOAD_RELEASE_OPTS[@]}" uploaded=$((uploaded + 1)) done shopt -u nullglob From 578d58d15015bf488d71bc2005d868421d6db966 Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Wed, 28 Oct 2026 14:10:00 +0100 Subject: [PATCH 09/13] Exclude the aws-lc version from release names. --- ci/README.md | 4 ++-- ci/scripts/shipit | 2 +- scripts/dev-build.sh | 10 +++------- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/ci/README.md b/ci/README.md index 9a37e245d..34d62a399 100644 --- a/ci/README.md +++ b/ci/README.md @@ -135,6 +135,6 @@ For creating a new release please follow the versioning guide based on the [Sema Used for documentation updates, changes in the test suite or any updates in the testing frameworks (e.g. ginkgo). - Since releases `11.16.3` and `11.17.5` the build metadata (everything after the `+`) has been included in the version number to denote the contained upstream versions. Since version 17.0.0, it records both the HAProxy and the AWS-LC version: `17.0.0+3.2.26-awslc-4.0.0` means HAProxy 3.2.26 and AWS-LC 4.0.0. +Since releases `11.16.3` and `11.17.5` the build metadata has been included into the version number. The build metadata denotes the contained HAProxy version. As an example, `11.16.2+2.6.9` means that HAProxy 2.6.9 is used. - The release bundles every SSL variant and the HAProxy community patches (see [haproxy-patches](../src/haproxy-patches)). One build is selected at deploy time via the `ha_proxy.ssl_variant` (`openssl` | `awslc` | `awslc-fips`) and `ha_proxy.include_haproxy_patches` (`true` | `false`) job properties. +The release bundles every SSL variant and the HAProxy community patches (see [haproxy-patches](../src/haproxy-patches)). One build is selected at deploy time via the `ha_proxy.ssl_variant` (`openssl` | `awslc` | `awslc-fips`) and `ha_proxy.include_haproxy_patches` (`true` | `false`) job properties. diff --git a/ci/scripts/shipit b/ci/scripts/shipit index 396c22df1..9e22ba40f 100755 --- a/ci/scripts/shipit +++ b/ci/scripts/shipit @@ -85,7 +85,7 @@ AWS_LC_VERSION=$(version AWS_LC_VERSION) CMAKE_VERSION=$(version CMAKE_VERSION) GOLANG_VERSION=$(version GOLANG_VERSION) -VERSION="${VERSION_TO_CREATE}+${HAPROXY_VERSION}-awslc-${AWS_LC_VERSION}" +VERSION="${VERSION_TO_CREATE}+${HAPROXY_VERSION}" cd "${REPO_ROOT}" header "Create final release..." diff --git a/scripts/dev-build.sh b/scripts/dev-build.sh index 0c5e8c482..91f3e4847 100755 --- a/scripts/dev-build.sh +++ b/scripts/dev-build.sh @@ -7,8 +7,8 @@ # Usage: ./scripts/dev-build.sh [--upload-only] [--version BASE] [--output-dir DIR] ## # Versioning: -# Each invocation produces a release version of the form +dev-awslc-. -# e.g. "16.9.0+dev-awslc-4.0.0.1779286286". BASE defaults to the highest existing final release in +# Each invocation produces a release version of the form +dev. +# e.g. "16.9.0+dev.1779286286". BASE defaults to the highest existing final release in # releases/haproxy/ and can be overridden with --version. Each run uses a fresh timestamp. # # Examples: @@ -22,10 +22,6 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR/.." -# Pull in AWS_LC_VERSION so it can be embedded in the dev version -# shellcheck disable=SC1091 -source src/aws-lc-versions.sh - UPLOAD_ONLY=false BASE_VERSION="" OUTPUT_DIR="./builds" @@ -71,7 +67,7 @@ TIMESTAMP=$(date +%s) mkdir -p "$OUTPUT_DIR" if [[ "$UPLOAD_ONLY" == false ]]; then - VERSION="${BASE_VERSION}+dev-awslc-${AWS_LC_VERSION}.${TIMESTAMP}" + VERSION="${BASE_VERSION}+dev.${TIMESTAMP}" TARBALL="$OUTPUT_DIR/haproxy-${VERSION}.tgz" echo "" From 91323098864cc15981fb3efd18a70c0abc21894f Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Wed, 28 Oct 2026 16:49:38 +0100 Subject: [PATCH 10/13] Move acceptance tests into a single job+task --- acceptance-tests/README.md | 24 ++- .../backend_match_http_protocol_test.go | 2 +- acceptance-tests/domain_fronting_test.go | 2 +- acceptance-tests/headers_test.go | 2 +- acceptance-tests/https_ext_crt_list_test.go | 2 +- acceptance-tests/https_frontend_test.go | 2 +- acceptance-tests/mtls_frontend_test.go | 2 +- acceptance-tests/run-local.sh | 4 +- acceptance-tests/ssl_variant_test.go | 2 +- acceptance-tests/strict_sni_test.go | 2 +- acceptance-tests/true_client_ip_test.go | 2 +- acceptance-tests/websocket_test.go | 2 +- acceptance-tests/xfcc_test.go | 45 ++--- ci/pipeline.yml | 186 +----------------- ci/scripts/acceptance-tests | 42 +++- 15 files changed, 93 insertions(+), 228 deletions(-) diff --git a/acceptance-tests/README.md b/acceptance-tests/README.md index aceff1ae8..1e911421c 100644 --- a/acceptance-tests/README.md +++ b/acceptance-tests/README.md @@ -14,12 +14,18 @@ cd acceptance-tests ### TLS Backend Variant -There is a single release that bundles every SSL variant. By default, the tests deploy it with the -system OpenSSL backend. To exercise a different TLS backend, set the `VARIANT` environment variable — -it drives the `ha_proxy.ssl_variant` deployment property. The HAProxy patches are toggled with -`INCLUDE_HAPROXY_PATCHES` (which drives `ha_proxy.include_haproxy_patches`). Examples: +There is a single release that bundles every SSL variant. The release is built and uploaded +**once**; each variant is selected at deploy time via the `ha_proxy.ssl_variant` property (driven +by the `VARIANT` environment variable), so nothing is rebuilt between variants. The HAProxy patches +are toggled with `INCLUDE_HAPROXY_PATCHES` (which drives `ha_proxy.include_haproxy_patches`). + +With **no `VARIANT` set**, the runner exercises all three backends sequentially against that one +build — `openssl` (full suite), then `awslc`, then `awslc-fips` (the latter two limited to the +TLS-exercising specs via `--label-filter tls`). This is what CI runs. To focus on a single backend, +set `VARIANT`: ```shell +./run-local.sh # all three variants, sequentially VARIANT=awslc ./run-local.sh # AWS-LC, non-FIPS VARIANT=awslc-fips ./run-local.sh # AWS-LC FIPS INCLUDE_HAPROXY_PATCHES=true ./run-local.sh # system OpenSSL + HAProxy patches @@ -27,11 +33,13 @@ VARIANT=awslc INCLUDE_HAPROXY_PATCHES=true ./run-local.sh # AWS-LC + patc VARIANT=awslc-fips INCLUDE_HAPROXY_PATCHES=true ./run-local.sh # AWS-LC FIPS + patches ``` -`VARIANT` accepts `openssl` (default), `awslc`, or `awslc-fips`. - -A single invocation runs the suite against the chosen variant. +`VARIANT` accepts `openssl` (default when running a single variant), `awslc`, or `awslc-fips`. When +`VARIANT` is pinned, the full suite runs for that backend unless you also set `LABEL_FILTER=tls` to +restrict it to the TLS subset. -Each run builds the release from scratch, compiling every bundled binary (AWS-LC and its FIPS toolchain included) inside the BOSH compilation VM. +The release is built from scratch once per run, compiling every bundled binary (AWS-LC and its FIPS +toolchain included) inside the BOSH compilation VM; subsequent variant deploys within the same run +reuse those compiled packages. When using `-k` (keep BOSH running, see below) the cached state belongs to whichever variant ran last — switching `VARIANT` inside a kept container is not supported. Stop the container between variants, or run without `-k`. diff --git a/acceptance-tests/backend_match_http_protocol_test.go b/acceptance-tests/backend_match_http_protocol_test.go index a4feb0377..ad1d8c390 100644 --- a/acceptance-tests/backend_match_http_protocol_test.go +++ b/acceptance-tests/backend_match_http_protocol_test.go @@ -9,7 +9,7 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("Backend match HTTP protocol", func() { +var _ = Describe("Backend match HTTP protocol", Label("tls"), func() { var haproxyInfo haproxyInfo var closeTunnel func() var closeLocalServer func() diff --git a/acceptance-tests/domain_fronting_test.go b/acceptance-tests/domain_fronting_test.go index 7b17d3241..865b48470 100644 --- a/acceptance-tests/domain_fronting_test.go +++ b/acceptance-tests/domain_fronting_test.go @@ -14,7 +14,7 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("Domain fronting", func() { +var _ = Describe("Domain fronting", Label("tls"), func() { opsfile := `--- # Disable domain fronting - type: replace diff --git a/acceptance-tests/headers_test.go b/acceptance-tests/headers_test.go index aa686fa22..87b8725d6 100644 --- a/acceptance-tests/headers_test.go +++ b/acceptance-tests/headers_test.go @@ -9,7 +9,7 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("Headers", func() { +var _ = Describe("Headers", Label("tls"), func() { opsfileHeaders := `--- - type: replace path: /instance_groups/name=haproxy/jobs/name=haproxy/properties/ha_proxy/strip_headers? diff --git a/acceptance-tests/https_ext_crt_list_test.go b/acceptance-tests/https_ext_crt_list_test.go index 06d52ae01..9766b56a4 100644 --- a/acceptance-tests/https_ext_crt_list_test.go +++ b/acceptance-tests/https_ext_crt_list_test.go @@ -26,7 +26,7 @@ import ( */ -var _ = Describe("External Certificate Lists", func() { +var _ = Describe("External Certificate Lists", Label("tls"), func() { haproxyBackendPort := 12000 It("Uses the correct certs", func() { diff --git a/acceptance-tests/https_frontend_test.go b/acceptance-tests/https_frontend_test.go index 9fa740330..f6af5d016 100644 --- a/acceptance-tests/https_frontend_test.go +++ b/acceptance-tests/https_frontend_test.go @@ -10,7 +10,7 @@ import ( "github.com/onsi/gomega/gbytes" ) -var _ = Describe("HTTPS Frontend", func() { +var _ = Describe("HTTPS Frontend", Label("tls"), func() { var haproxyInfo haproxyInfo var closeTunnel func() var closeLocalServer func() diff --git a/acceptance-tests/mtls_frontend_test.go b/acceptance-tests/mtls_frontend_test.go index 5c8406205..3d8f7323c 100644 --- a/acceptance-tests/mtls_frontend_test.go +++ b/acceptance-tests/mtls_frontend_test.go @@ -8,7 +8,7 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("mTLS", func() { +var _ = Describe("mTLS", Label("tls"), func() { var haproxyInfo haproxyInfo var closeTunnel func() var closeLocalServer func() diff --git a/acceptance-tests/run-local.sh b/acceptance-tests/run-local.sh index 4c4c3fc65..c4f2412be 100755 --- a/acceptance-tests/run-local.sh +++ b/acceptance-tests/run-local.sh @@ -94,9 +94,9 @@ if [ -n "$KEEP_RUNNING" ] ; then echo echo "*** KEEP_RUNNING enabled. Please clean up docker scratch after removing containers: ${DOCKER_SCRATCH}" echo - docker run --privileged -v "$REPO_DIR":/repo -v "${DOCKER_SCRATCH}":/scratch/docker -e REPO_ROOT=/repo -e FOCUS="${FOCUS}" -e PARALLELISM="${PARALLELISM}" -e KEEP_RUNNING="${KEEP_RUNNING}" -e VARIANT="${VARIANT:-}" haproxy-boshrelease-testflight bash -c "cd /repo/ci/scripts && ./acceptance-tests ; sleep infinity" + docker run --privileged -v "$REPO_DIR":/repo -v "${DOCKER_SCRATCH}":/scratch/docker -e REPO_ROOT=/repo -e FOCUS="${FOCUS}" -e PARALLELISM="${PARALLELISM}" -e KEEP_RUNNING="${KEEP_RUNNING}" -e VARIANT="${VARIANT:-}" -e LABEL_FILTER="${LABEL_FILTER:-}" haproxy-boshrelease-testflight bash -c "cd /repo/ci/scripts && ./acceptance-tests ; sleep infinity" else - docker run --rm --privileged -v "$REPO_DIR":/repo -v "${DOCKER_SCRATCH}":/scratch/docker -e REPO_ROOT=/repo -e KEEP_RUNNING="" -e PARALLELISM="${PARALLELISM}" -e VARIANT="${VARIANT:-}" haproxy-boshrelease-testflight bash -c "cd /repo/ci/scripts && ./acceptance-tests" + docker run --rm --privileged -v "$REPO_DIR":/repo -v "${DOCKER_SCRATCH}":/scratch/docker -e REPO_ROOT=/repo -e KEEP_RUNNING="" -e PARALLELISM="${PARALLELISM}" -e VARIANT="${VARIANT:-}" -e LABEL_FILTER="${LABEL_FILTER:-}" haproxy-boshrelease-testflight bash -c "cd /repo/ci/scripts && ./acceptance-tests" echo "Cleaning up docker scratch: ${DOCKER_SCRATCH}" sudo rm -rf "${DOCKER_SCRATCH}" fi diff --git a/acceptance-tests/ssl_variant_test.go b/acceptance-tests/ssl_variant_test.go index be8a1500b..34453510d 100644 --- a/acceptance-tests/ssl_variant_test.go +++ b/acceptance-tests/ssl_variant_test.go @@ -25,7 +25,7 @@ var ( sslFIPSModeOnRe = regexp.MustCompile(`SSL library FIPS mode\s*:\s*yes`) ) -var _ = Describe("SSL variant", func() { +var _ = Describe("SSL variant", Label("tls"), func() { It("Runs the HAProxy binary for the configured SSL variant", func() { haproxyInfo, _ := deployHAProxy(baseManifestVars{ haproxyBackendPort: 12000, diff --git a/acceptance-tests/strict_sni_test.go b/acceptance-tests/strict_sni_test.go index afabbc755..09bbcc82c 100644 --- a/acceptance-tests/strict_sni_test.go +++ b/acceptance-tests/strict_sni_test.go @@ -10,7 +10,7 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("Strict SNI", func() { +var _ = Describe("Strict SNI", Label("tls"), func() { opsfile := `--- # Strict SNI - type: replace diff --git a/acceptance-tests/true_client_ip_test.go b/acceptance-tests/true_client_ip_test.go index 7f00111da..8a4e8d607 100644 --- a/acceptance-tests/true_client_ip_test.go +++ b/acceptance-tests/true_client_ip_test.go @@ -13,7 +13,7 @@ import ( const TrueClientIpHeader string = "X-Cf-True-Client-Ip" const MockClientIp string = "8.8.8.8" -var _ = Describe("True Client IP", func() { +var _ = Describe("True Client IP", Label("tls"), func() { opsFileTrueClientIp := fmt.Sprintf(`--- - type: replace diff --git a/acceptance-tests/websocket_test.go b/acceptance-tests/websocket_test.go index b559e1826..f7b4f2b4b 100644 --- a/acceptance-tests/websocket_test.go +++ b/acceptance-tests/websocket_test.go @@ -14,7 +14,7 @@ import ( "github.com/onsi/gomega/gbytes" ) -var _ = Describe("HTTPS Frontend", func() { +var _ = Describe("HTTPS Frontend", Label("tls"), func() { var haproxyInfo haproxyInfo var closeTunnel func() var closeLocalServer func() diff --git a/acceptance-tests/xfcc_test.go b/acceptance-tests/xfcc_test.go index e0e77608d..dfb1216fd 100644 --- a/acceptance-tests/xfcc_test.go +++ b/acceptance-tests/xfcc_test.go @@ -28,21 +28,22 @@ type Certificate struct { } /* - https://bosh.io/jobs/haproxy?source=github.com/cloudfoundry-community/haproxy-boshrelease#p%3dha_proxy.forwarded_client_cert - forwarded_client_cert - always_forward_only => X-Forwarded-Client-Cert is always forwarded +https://bosh.io/jobs/haproxy?source=github.com/cloudfoundry-community/haproxy-boshrelease#p%3dha_proxy.forwarded_client_cert +forwarded_client_cert - forward_only => X-Forwarded-Client-Cert is removed for non-mTLS connections - => X-Forwarded-Client-Cert is forwarded for mTLS connections + always_forward_only => X-Forwarded-Client-Cert is always forwarded - sanitize_set => X-Forwarded-Client-Cert is removed for non-mTLS connections - => X-Forwarded-Client-Cert is overwritten for mTLS connections + forward_only => X-Forwarded-Client-Cert is removed for non-mTLS connections + => X-Forwarded-Client-Cert is forwarded for mTLS connections - forward_only_if_route_service => X-Forwarded-Client-Cert is removed for non-mTLS connections when X-Cf-Proxy-Signature header is not present - X-Forwarded-Client-Cert is forwarded for non-mTLS connections when X-Cf-Proxy-Signature header is present - X-Forwarded-Client-Cert is overwritten for mTLS connections + sanitize_set => X-Forwarded-Client-Cert is removed for non-mTLS connections + => X-Forwarded-Client-Cert is overwritten for mTLS connections + + forward_only_if_route_service => X-Forwarded-Client-Cert is removed for non-mTLS connections when X-Cf-Proxy-Signature header is not present + X-Forwarded-Client-Cert is forwarded for non-mTLS connections when X-Cf-Proxy-Signature header is present + X-Forwarded-Client-Cert is overwritten for mTLS connections */ -var _ = Describe("forwarded_client_cert", func() { +var _ = Describe("forwarded_client_cert", Label("tls"), func() { opsfileForwardedClientCert := `--- # Configure X-Forwarded-Client-Cert handling - type: replace @@ -396,17 +397,17 @@ func generateClientCerts() (*Certificate, *Certificate, error) { } return &Certificate{ - X509Cert: ca, - CertPEM: string(caPEMBytes), - PrivateKey: caKeyPair, - PrivateKeyPEM: string(caKeyPEMBytes), - }, &Certificate{ - X509Cert: cert, - CertPEM: string(certPEMBytes), - PrivateKey: certKeyPair, - PrivateKeyPEM: string(certKeyPEMBytes), - TLSCert: clientTLSCert, - }, nil + X509Cert: ca, + CertPEM: string(caPEMBytes), + PrivateKey: caKeyPair, + PrivateKeyPEM: string(caKeyPEMBytes), + }, &Certificate{ + X509Cert: cert, + CertPEM: string(certPEMBytes), + PrivateKey: certKeyPair, + PrivateKeyPEM: string(certKeyPEMBytes), + TLSCert: clientTLSCert, + }, nil } func pemEncodeCert(derBytes []byte) ([]byte, error) { diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 20eb54e98..0fd0bd9a1 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -6,11 +6,7 @@ groups: - unit-tests - unit-tests-pr - acceptance-tests - - acceptance-tests-awslc - - acceptance-tests-awslc-fips - acceptance-tests-pr - - acceptance-tests-awslc-pr - - acceptance-tests-awslc-fips-pr - rc - shipit - patch @@ -155,76 +151,6 @@ jobs: icon_url: "((slack.icon))" text: "((slack.fail_url)) haproxy-boshrelease : acceptance tests failed" - - name: acceptance-tests-awslc - public: true - serial: true - serial_groups: [acceptance-tests] - plan: - - do: - - in_parallel: - - { get: git, trigger: true, passed: [acceptance-tests] } - - { get: stemcell } - - { get: stemcell-jammy } - - { get: haproxy-boshrelease-testflight, trigger: true, passed: [acceptance-tests] } - - task: acceptance-tests-awslc - privileged: true - timeout: 4h - image: haproxy-boshrelease-testflight - config: - platform: linux - inputs: - - { name: git } - - { name: stemcell } - - { name: stemcell-jammy } - run: - path: ./git/ci/scripts/acceptance-tests - args: [] - params: - REPO_ROOT: git - VARIANT: awslc - on_failure: - put: notify - params: - channel: "#haproxy-boshrelease" - username: ci-bot - icon_url: "((slack.icon))" - text: "((slack.fail_url)) haproxy-boshrelease : acceptance tests (AWS-LC) failed" - - - name: acceptance-tests-awslc-fips - public: true - serial: true - serial_groups: [acceptance-tests] - plan: - - do: - - in_parallel: - - { get: git, trigger: true, passed: [acceptance-tests-awslc] } - - { get: stemcell } - - { get: stemcell-jammy } - - { get: haproxy-boshrelease-testflight, trigger: true, passed: [acceptance-tests-awslc] } - - task: acceptance-tests-awslc-fips - privileged: true - timeout: 4h - image: haproxy-boshrelease-testflight - config: - platform: linux - inputs: - - { name: git } - - { name: stemcell } - - { name: stemcell-jammy } - run: - path: ./git/ci/scripts/acceptance-tests - args: [] - params: - REPO_ROOT: git - VARIANT: awslc-fips - on_failure: - put: notify - params: - channel: "#haproxy-boshrelease" - username: ci-bot - icon_url: "((slack.icon))" - text: "((slack.fail_url)) haproxy-boshrelease : acceptance tests (AWS-LC FIPS) failed" - - name: acceptance-tests-pr public: true serial: true @@ -271,106 +197,12 @@ jobs: status: failure context: acceptance-tests - - name: acceptance-tests-awslc-pr - public: true - serial: true - serial_groups: [acceptance-tests] - plan: - - do: - - in_parallel: - - { get: git-pull-requests-awslc, trigger: true, version: every } - - { get: stemcell } - - { get: stemcell-jammy } - - { get: haproxy-boshrelease-testflight-pr, passed: [acceptance-tests-pr] } - - put: git-pull-requests-awslc - params: - path: git-pull-requests-awslc - status: pending - context: acceptance-tests-awslc - get_params: - list_changed_files: true - - task: acceptance-tests-awslc - privileged: true - timeout: 4h - image: haproxy-boshrelease-testflight-pr - config: - platform: linux - inputs: - - { name: git-pull-requests-awslc } - - { name: stemcell } - - { name: stemcell-jammy } - run: - path: ./git-pull-requests-awslc/ci/scripts/acceptance-tests - args: [] - params: - REPO_ROOT: git-pull-requests-awslc - VARIANT: awslc - on_success: - put: git-pull-requests-awslc - params: - path: git-pull-requests-awslc - status: success - context: acceptance-tests-awslc - on_failure: - put: git-pull-requests-awslc - params: - path: git-pull-requests-awslc - status: failure - context: acceptance-tests-awslc - - - name: acceptance-tests-awslc-fips-pr - public: true - serial: true - serial_groups: [acceptance-tests] - plan: - - do: - - in_parallel: - - { get: git-pull-requests-awslc, trigger: true, version: every } - - { get: stemcell } - - { get: stemcell-jammy } - - { get: haproxy-boshrelease-testflight-pr, passed: [acceptance-tests-awslc-pr] } - - put: git-pull-requests-awslc - params: - path: git-pull-requests-awslc - status: pending - context: acceptance-tests-awslc-fips - get_params: - list_changed_files: true - - task: acceptance-tests-awslc-fips - privileged: true - timeout: 4h - image: haproxy-boshrelease-testflight-pr - config: - platform: linux - inputs: - - { name: git-pull-requests-awslc } - - { name: stemcell } - - { name: stemcell-jammy } - run: - path: ./git-pull-requests-awslc/ci/scripts/acceptance-tests - args: [] - params: - REPO_ROOT: git-pull-requests-awslc - VARIANT: awslc-fips - on_success: - put: git-pull-requests-awslc - params: - path: git-pull-requests-awslc - status: success - context: acceptance-tests-awslc-fips - on_failure: - put: git-pull-requests-awslc - params: - path: git-pull-requests-awslc - status: failure - context: acceptance-tests-awslc-fips - - name: rc public: true plan: - do: - in_parallel: - - { get: git, trigger: true, passed: [acceptance-tests, acceptance-tests-awslc, acceptance-tests-awslc-fips] } + - { get: git, trigger: true, passed: [acceptance-tests] } - { get: version, trigger: false, params: {pre: rc} } - put: version params: {file: version/number} @@ -602,21 +434,7 @@ resources: access_token: ((github.access_token)) repository: cloudfoundry/haproxy-boshrelease base_branch: master - labels: [run-ci, run-ci-awslc] - required_review_approvals: 1 - trusted_teams: - - "wg-app-runtime-platform-networking-approvers" - trusted_users: - - "dependabot" - - "CFN-CI" - - - name: git-pull-requests-awslc - type: pull-request - source: - access_token: ((github.access_token)) - repository: cloudfoundry/haproxy-boshrelease - base_branch: master - labels: [run-ci-awslc] + labels: [run-ci] required_review_approvals: 1 trusted_teams: - "wg-app-runtime-platform-networking-approvers" diff --git a/ci/scripts/acceptance-tests b/ci/scripts/acceptance-tests index d6e353943..d9b3ed96e 100755 --- a/ci/scripts/acceptance-tests +++ b/ci/scripts/acceptance-tests @@ -4,11 +4,13 @@ set -e source "${REPO_ROOT}/ci/scripts/functions-ci.sh" START_DIR="${PWD}" # Differs for CI and manual execution +ADDITIONAL_ARGS=() + if [ -n "$FOCUS" ]; then echo "------------------------------------------------------------------" echo "FOCUS is set. Will only run tests matching '$FOCUS'" echo "------------------------------------------------------------------" - ADDITIONAL_ARGS=("--focus" "$FOCUS") + ADDITIONAL_ARGS+=("--focus" "$FOCUS") fi git_pull @@ -67,6 +69,42 @@ else fi echo "------------------------------------------------------------------" -ginkgo "$VERBOSITY_FLAG" "$PARALLELISM" -r --trace --show-node-events --randomize-all --flake-attempts "$FLAKE_ATTEMPTS" "${ADDITIONAL_ARGS[@]}" +# ------------------------------------------------------------------ +# Run the suite once per SSL variant against the release built above. +# +# The release bundles every SSL variant and is built/uploaded only once +# (prepare_bosh -> bosh_release). Each phase redeploys HAProxy with the +# matching ha_proxy.ssl_variant (selected by the Go harness from the VARIANT +# env), so nothing is rebuilt between variants -- the director just reuses the +# already-uploaded release and compiles each variant's packages on first use. +# +# openssl -> full suite +# awslc -> TLS-exercising subset only (--label-filter tls) +# awslc-fips -> TLS-exercising subset only (--label-filter tls) +# +# A local/debug run can pin a single variant via VARIANT (and optionally +# LABEL_FILTER); CI leaves VARIANT unset and runs all three sequentially. +# ------------------------------------------------------------------ +if [ -n "${VARIANT:-}" ]; then + PHASES=("${VARIANT}|${LABEL_FILTER:-}") +else + PHASES=("openssl|" "awslc|tls" "awslc-fips|tls") +fi + +for phase in "${PHASES[@]}"; do + phase_variant="${phase%%|*}" + phase_label="${phase#*|}" + + phase_args=("${ADDITIONAL_ARGS[@]}") + if [ -n "$phase_label" ]; then + phase_args+=("--label-filter" "$phase_label") + fi + + echo "==================================================================" + echo " Acceptance tests -- variant='${phase_variant}' label-filter='${phase_label:-}'" + echo "==================================================================" + + VARIANT="$phase_variant" ginkgo "$VERBOSITY_FLAG" "$PARALLELISM" -r --trace --show-node-events --randomize-all --flake-attempts "$FLAKE_ATTEMPTS" "${phase_args[@]}" +done keep_running_info \ No newline at end of file From ebc25b74320e08479e4ac76875ce735935c92b30 Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Thu, 29 Oct 2026 10:13:10 +0100 Subject: [PATCH 11/13] Revert change to release name in pipeline --- ci/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 0fd0bd9a1..9b1584791 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -479,7 +479,7 @@ resources: source: bucket: haproxy-boshrelease json_key: ((gcp.service_key)) - regexp: haproxy-([0-9a-z\.+-]+)\.tgz + regexp: haproxy-([0-9\.+-]+).tgz - name: daily type: time From 0d4fbb6031daf962ca0845b88b9948dfbfbe0ad8 Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Thu, 29 Oct 2026 13:32:50 +0100 Subject: [PATCH 12/13] Remove ttar as package from package diagram --- docs/package-dependencies.drawio | 7 ++----- docs/package-dependencies.png | Bin 121349 -> 119724 bytes 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/package-dependencies.drawio b/docs/package-dependencies.drawio index 4e29a8338..b54b32b62 100644 --- a/docs/package-dependencies.drawio +++ b/docs/package-dependencies.drawio @@ -1,6 +1,6 @@ - + @@ -41,7 +41,7 @@ - + @@ -226,9 +226,6 @@ - - - diff --git a/docs/package-dependencies.png b/docs/package-dependencies.png index 9fc76d80d4d2b86b7231144f38aa51c5925d5fbc..7829a3d0d3ebb63be89f2ba4dbb430caedcdacad 100644 GIT binary patch literal 119724 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

j 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 literal 121349 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

5!`1LD8CU+MVs%{@p9#n| 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 IF}?Ty2i+r8HUIzs From 8891cd2d55507926215e6f9930f464e8fe9fef08 Mon Sep 17 00:00:00 2001 From: Clemens Hoffmann Date: Thu, 29 Oct 2026 16:29:49 +0100 Subject: [PATCH 13/13] Revert changes to the pipeline done earlier for the multiple releases --- ci/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/pipeline.yml b/ci/pipeline.yml index 9b1584791..2f3b7cf68 100644 --- a/ci/pipeline.yml +++ b/ci/pipeline.yml @@ -264,7 +264,7 @@ jobs: - in_parallel: - { get: version, passed: [rc], params: {bump: final} } - { get: git, passed: [rc] } - - { get: haproxy-boshrelease-testflight, trigger: true, passed: [build-haproxy-testflight-image] } + - get: haproxy-boshrelease-testflight - task: release image: haproxy-boshrelease-testflight config: @@ -325,7 +325,7 @@ jobs: - get: daily trigger: true - get: git - - { get: haproxy-boshrelease-testflight, trigger: true, passed: [build-haproxy-testflight-image] } + - get: haproxy-boshrelease-testflight - task: autobump-dependencies image: haproxy-boshrelease-testflight config: