Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 58 additions & 11 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ default: build
build:
#!/bin/bash
set -euo pipefail
ob_build_dir="${OB_BIN_DIR:-bin}"
ob_build_version="${OB_VERSION:-}"
ob_build_dir="${ONEBOX_BIN_DIR:-bin}"
ob_build_version="${ONEBOX_VERSION:-}"
if [ -n "$ob_build_version" ] && [[ ! "$ob_build_version" =~ ^v[1-9][0-9]{3}\.([1-9]|1[0-2])\.(0|[1-9][0-9]{0,18})$ ]]; then
echo "OB_VERSION must match vYYYY.M.REVISION" >&2; exit 1
echo "ONEBOX_VERSION must match vYYYY.M.REVISION" >&2; exit 1
fi
if [ -z "$ob_build_version" ]; then
# --long keeps the commit suffix even on a tagged commit, so a checkout build
Expand All @@ -33,9 +33,9 @@ build:
install: build
#!/bin/bash
set -euo pipefail
ob_install_dir="${OB_INSTALL_DIR:-${HOME}/.local/bin}"
ob_install_dir="${ONEBOX_INSTALL_DIR:-${HOME}/.local/bin}"
mkdir -p "$ob_install_dir"
install -m 0755 "${OB_BIN_DIR:-bin}/ob" "${ob_install_dir}/ob"
install -m 0755 "${ONEBOX_BIN_DIR:-bin}/ob" "${ob_install_dir}/ob"
echo "installed ${ob_install_dir}/ob ($("${ob_install_dir}/ob" --version))"

# Run the test suite.
Expand Down Expand Up @@ -66,7 +66,7 @@ check: _mod-tidy _fmt-check vet test docs-generate-check site-build
# They are separate from `check` because each needs a tool the repository does
# not vendor; a contributor without them should still be able to run `just check`
# and get a truthful answer about their change.
ci: check lint vuln workflow-check
ci: check lint vuln workflow-check env-namespace
@echo "CI checks passed"

[private]
Expand Down Expand Up @@ -135,6 +135,53 @@ dead-exports:
done <<< "${names}"
echo "checked $(echo "${names}" | wc -l | tr -d ' ') exported identifiers, ${dead} unreferenced"

# Fail on any Onebox-owned environment variable still using the retired OB_
# prefix. The namespace is a contract other people write into CI settings,
# secrets stores, and hook scripts, so a single stray reference is a contract
# that disagrees with itself.
env-namespace:
#!/usr/bin/env bash
set -euo pipefail
# \bOB_ rather than OB_: the unanchored pattern also matches the tail of
# identifiers like JOB_SECRET, which have nothing to do with the namespace.
#
# Each stage is checked on its own rather than chained into one pipeline,
# because only the last command's status survives a pipeline: a scan whose
# file list failed to build reports a clean tree, which is the one answer a
# check like this must never give by accident.
listing=$(mktemp)
scanned=$(mktemp)
trap 'rm -f "${listing}" "${scanned}"' EXIT
git ls-files -z > "${listing}"
if [ ! -s "${listing}" ]; then
echo "no tracked files listed — the scan checked nothing" >&2
exit 1
fi
# The migration table in the environment-variables guide is the one place
# the old names are allowed, because naming them is the whole point of it.
grep -zZv '^site/src/content/docs/guides/environment-variables.mdx$' < "${listing}" > "${scanned}" || true
if [ ! -s "${scanned}" ]; then
echo "the exemption matched every tracked file — the scan checked nothing" >&2
exit 1
fi
set +e
stray=$(xargs -0 grep -nHE '\bOB_[A-Z0-9_]+' < "${scanned}")
status=$?
set -e
case "${status}" in
0)
echo "${stray}"
echo "retired OB_ prefix found — Onebox environment variables use ONEBOX_" >&2
exit 1
;;
1|123) ;; # no match, reported by grep itself or relayed by xargs
*)
echo "the namespace scan failed (exit ${status}) — it did not check anything" >&2
exit 1
;;
esac
echo "no retired OB_ environment references"

# Scan reachable code against the official vulnerability database.
vuln:
govulncheck ./...
Expand All @@ -155,7 +202,7 @@ workflow-check:
# The Docker end-to-end suite. Opt-in locally because it needs a working daemon;
# CI runs it as its own job so a slow suite never hides a fast failure.
e2e:
OB_E2E=1 go test ./e2e/ -count=1 -timeout 20m
ONEBOX_E2E=1 go test ./e2e/ -count=1 -timeout 20m

# Boot the throwaway server the `server-e2e` suite deploys to.
#
Expand Down Expand Up @@ -190,11 +237,11 @@ server-env:
# just built, named explicitly rather than resolved from PATH — otherwise an
# older `ob` installed elsewhere documents a tree it did not come from.
docs-generate: build
go run ./cmd/ob-docgen --ob "${OB_BIN_DIR:-bin}/ob"
go run ./cmd/ob-docgen --ob "${ONEBOX_BIN_DIR:-bin}/ob"

# Fail when a generated documentation page is behind the binary.
docs-generate-check: build
go run ./cmd/ob-docgen --check --ob "${OB_BIN_DIR:-bin}/ob"
go run ./cmd/ob-docgen --check --ob "${ONEBOX_BIN_DIR:-bin}/ob"

# Install the documentation site's dependencies.
site-install:
Expand Down Expand Up @@ -230,12 +277,12 @@ release:
clean:
#!/bin/bash
set -euo pipefail
rm -f "${OB_BIN_DIR:-bin}/ob"
rm -f "${ONEBOX_BIN_DIR:-bin}/ob"

# Remove the copy `just install` placed on PATH.
uninstall:
#!/bin/bash
set -euo pipefail
ob_install_dir="${OB_INSTALL_DIR:-${HOME}/.local/bin}"
ob_install_dir="${ONEBOX_INSTALL_DIR:-${HOME}/.local/bin}"
rm -f "${ob_install_dir}/ob"
echo "removed ${ob_install_dir}/ob"
4 changes: 2 additions & 2 deletions cmd/ob/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,10 +515,10 @@ func newUI(cmd *cobra.Command, g *globalFlags) *ui.UI {
return ui.New(commandOutput(cmd, g), g.Verbose && !isStructuredOutput(g))
}

// cliConnector is replaceable by in-package tests and honors OB_LOCAL for the
// cliConnector is replaceable by in-package tests and honors ONEBOX_LOCAL for the
// existing local-docker workflow. Production uses cancellable SSH dialing.
var cliConnector onebox.Connector = func(ctx context.Context, route transport.Route) (transport.Transport, error) {
if value := strings.TrimSpace(strings.ToLower(os.Getenv("OB_LOCAL"))); value == "1" || value == "true" {
if value := strings.TrimSpace(strings.ToLower(os.Getenv("ONEBOX_LOCAL"))); value == "1" || value == "true" {
return transport.NewLocal(), nil
}
return transport.NewSSHRoute(ctx, route)
Expand Down
6 changes: 3 additions & 3 deletions e2e/apps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ scope — putting several on one box would not test what this contract
describes.

It provisions against your own Hetzner account and costs real money, so it is
never run by CI. `hcloud` must be authenticated, and `OB_E2E_SSH_KEY` must name
never run by CI. `hcloud` must be authenticated, and `ONEBOX_E2E_SSH_KEY` must name
a key from `hcloud ssh-key list` that can reach the new host:

```sh
OB_E2E_SSH_KEY='my-key' ./e2e/apps/one-app-one-host.sh umami 3000 /api/heartbeat
ONEBOX_E2E_SSH_KEY='my-key' ./e2e/apps/one-app-one-host.sh umami 3000 /api/heartbeat
```

`OB_E2E_SERVER_TYPE`, `OB_E2E_IMAGE`, and `OB_E2E_LOCATION` override the
`ONEBOX_E2E_SERVER_TYPE`, `ONEBOX_E2E_IMAGE`, and `ONEBOX_E2E_LOCATION` override the
defaults (`cpx22`, `ubuntu-24.04`, `fsn1`).

| App | Bare image to serving | HTTP | Containers | Volumes |
Expand Down
18 changes: 9 additions & 9 deletions e2e/apps/one-app-one-host.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ set -uo pipefail
export PATH="/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
APP="$1"; PORT="$2"; PATHQ="$3"; WL="${4:-}"
NAME="ob-e2e-$APP"
S=${OB_E2E_SCRATCH:-/tmp}
S=${ONEBOX_E2E_SCRATCH:-/tmp}
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"

# The provisioning account is the operator's, not the repository's. The SSH key
# is whatever name `hcloud ssh-key list` shows for the key that can reach the
# host; the rest have defaults that are only a starting point.
OB_E2E_SSH_KEY="${OB_E2E_SSH_KEY:-}"
if [ -z "$OB_E2E_SSH_KEY" ]; then
echo "OB_E2E_SSH_KEY must name an SSH key registered with hcloud (see: hcloud ssh-key list)" >&2
ONEBOX_E2E_SSH_KEY="${ONEBOX_E2E_SSH_KEY:-}"
if [ -z "$ONEBOX_E2E_SSH_KEY" ]; then
echo "ONEBOX_E2E_SSH_KEY must name an SSH key registered with hcloud (see: hcloud ssh-key list)" >&2
exit 2
fi
OB_E2E_SERVER_TYPE="${OB_E2E_SERVER_TYPE:-cpx22}"
OB_E2E_IMAGE="${OB_E2E_IMAGE:-ubuntu-24.04}"
OB_E2E_LOCATION="${OB_E2E_LOCATION:-fsn1}"
ONEBOX_E2E_SERVER_TYPE="${ONEBOX_E2E_SERVER_TYPE:-cpx22}"
ONEBOX_E2E_IMAGE="${ONEBOX_E2E_IMAGE:-ubuntu-24.04}"
ONEBOX_E2E_LOCATION="${ONEBOX_E2E_LOCATION:-fsn1}"

cleanup() { hcloud server delete "$NAME" >/dev/null 2>&1; }
trap cleanup EXIT

hcloud server create --name "$NAME" --type "$OB_E2E_SERVER_TYPE" --image "$OB_E2E_IMAGE" --location "$OB_E2E_LOCATION" \
--ssh-key "$OB_E2E_SSH_KEY" --label purpose=onebox-e2e --label ephemeral=true >/dev/null 2>&1 || { echo " provision FAILED"; exit 1; }
hcloud server create --name "$NAME" --type "$ONEBOX_E2E_SERVER_TYPE" --image "$ONEBOX_E2E_IMAGE" --location "$ONEBOX_E2E_LOCATION" \
--ssh-key "$ONEBOX_E2E_SSH_KEY" --label purpose=onebox-e2e --label ephemeral=true >/dev/null 2>&1 || { echo " provision FAILED"; exit 1; }
IP=$(hcloud server ip "$NAME")
# Cloud providers recycle addresses. A stale host key from a destroyed server
# makes ob refuse the connection, which is correct of it and unhelpful here.
Expand Down
10 changes: 5 additions & 5 deletions e2e/e2e_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Package e2e proves the core live-deploy contract mechanically under
// load with zero failed requests. Gated: OB_E2E=1 + local docker.
// load with zero failed requests. Gated: ONEBOX_E2E=1 + local docker.
package e2e

import (
Expand Down Expand Up @@ -42,13 +42,13 @@ func TestV1ConfigFixturesLoad(t *testing.T) {
}

func TestZeroDowntimeDeploy(t *testing.T) {
if os.Getenv("OB_E2E") != "1" {
t.Skip("set OB_E2E=1 (requires local docker)")
if os.Getenv("ONEBOX_E2E") != "1" {
t.Skip("set ONEBOX_E2E=1 (requires local docker)")
}
// Opting in is a promise that Docker is here. Skipping past a broken daemon
// once OB_E2E=1 is set turns a gate into a green tick for work nobody did.
// once ONEBOX_E2E=1 is set turns a gate into a green tick for work nobody did.
if err := exec.CommandContext(t.Context(), "docker", "info").Run(); err != nil {
t.Fatalf("OB_E2E=1 was set but docker is not usable: %v", err)
t.Fatalf("ONEBOX_E2E=1 was set but docker is not usable: %v", err)
}
dir, err := filepath.Abs("testdata/app")
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions e2e/ops_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ import (

func gate(t *testing.T) {
t.Helper()
if os.Getenv("OB_E2E") != "1" {
t.Skip("set OB_E2E=1 (requires local docker)")
if os.Getenv("ONEBOX_E2E") != "1" {
t.Skip("set ONEBOX_E2E=1 (requires local docker)")
}
// Opting in is a promise that Docker is here. Skipping past a broken daemon
// once OB_E2E=1 is set turns a gate into a green tick for work nobody did.
// once ONEBOX_E2E=1 is set turns a gate into a green tick for work nobody did.
if err := exec.CommandContext(t.Context(), "docker", "info").Run(); err != nil {
t.Fatalf("OB_E2E=1 was set but docker is not usable: %v", err)
t.Fatalf("ONEBOX_E2E=1 was set but docker is not usable: %v", err)
}
}

Expand Down
16 changes: 8 additions & 8 deletions e2e/server_harness_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,19 @@ type server struct {

func requireServer(t *testing.T) *server {
t.Helper()
if os.Getenv("OB_SERVER_E2E") != "1" {
t.Skip("set OB_SERVER_E2E=1 (see `just server-e2e`)")
if os.Getenv("ONEBOX_SERVER_E2E") != "1" {
t.Skip("set ONEBOX_SERVER_E2E=1 (see `just server-e2e`)")
}
// Opting in is a promise the machine is there. Skipping past an
// unreachable one turns a gate into a green tick for work nobody did.
target := os.Getenv("OB_E2E_SERVER")
key := os.Getenv("OB_E2E_SERVER_KEY")
target := os.Getenv("ONEBOX_E2E_SERVER")
key := os.Getenv("ONEBOX_E2E_SERVER_KEY")
if target == "" || key == "" {
t.Fatal("OB_SERVER_E2E=1 without OB_E2E_SERVER and OB_E2E_SERVER_KEY")
t.Fatal("ONEBOX_SERVER_E2E=1 without ONEBOX_E2E_SERVER and ONEBOX_E2E_SERVER_KEY")
}
user, rest, ok := strings.Cut(target, "@")
if !ok {
t.Fatalf("OB_E2E_SERVER %q is not user@host[:port]", target)
t.Fatalf("ONEBOX_E2E_SERVER %q is not user@host[:port]", target)
}
host, port, ok := strings.Cut(rest, ":")
if !ok {
Expand All @@ -71,12 +71,12 @@ func requireServer(t *testing.T) *server {
// under /etc/systemd/system. A server it cannot reach as root fails later,
// in a place that looks like a deploy bug.
if user != "root" {
t.Fatalf("OB_E2E_SERVER is %q; ob writes to /etc/systemd/system and does not elevate, so it must be root", target)
t.Fatalf("ONEBOX_E2E_SERVER is %q; ob writes to /etc/systemd/system and does not elevate, so it must be root", target)
}
s := &server{target: target, user: user, host: host, port: port, key: key,
bootstrapped: map[string]bool{}}
if err := s.try(t, "true"); err != nil {
t.Fatalf("OB_SERVER_E2E=1 but %s is not reachable: %v", target, err)
t.Fatalf("ONEBOX_SERVER_E2E=1 but %s is not reachable: %v", target, err)
}
s.guest = strings.Fields(s.run(t, "hostname -I"))[0]
return s
Expand Down
4 changes: 2 additions & 2 deletions e2e/server_probe_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ func (s *server) teardown(t *testing.T, dir string) {
// Kept deliberately when asked. A probe that fails is a probe whose
// machine is worth looking at, and tearing it down is how the evidence for
// the last three wrong theories disappeared before it could be read.
if os.Getenv("OB_E2E_KEEP") == "1" {
t.Log("OB_E2E_KEEP=1: leaving the application in place")
if os.Getenv("ONEBOX_E2E_KEEP") == "1" {
t.Log("ONEBOX_E2E_KEEP=1: leaving the application in place")
return
}
if out, err := s.obInput(t, dir, s.obHome(t), "observer\ny\n", "destroy", "--volumes"); err != nil {
Expand Down
12 changes: 6 additions & 6 deletions e2e/testdata/postgres/secrets/backup.env
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
BACKUP_ACCESS_KEY_ID=ENC[AES256_GCM,data:lSmmCEHir7dioHfLwuo=,iv:Bt8xUhRZBGG9JP20IVxc2O1LnE9h2iPn0YRuxUs1udg=,tag:IB2q8mLvrknktl/qtjwVBw==,type:str]
BACKUP_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:gzaMGkamkHevSz1ABtJfoi0K+OwtyFqW,iv:9hUVpTJt3I53lx3aKAgeCfJS1KAhR9MAgJGgi2gAsus=,tag:m8RxxbIaIoiff7fjRTvWDw==,type:str]
OB_REPOSITORY_KEY=ENC[AES256_GCM,data:SG1JshUdQ7bWjupdNZmIod+trFELZn8HKoyLO7DLchi22UjUtNNcOBo0qXaPzlLzlk4cY/C62yBsxTUtXYaXbQ==,iv:retfIEsNiwlQW27S2s5ENxRDpdPZj70KtmUrH12poRY=,tag:Tw/aoKBM4zHtsmu8r/w9ew==,type:str]
sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsWUZYeHhnTnBXT0UweEpn\nTlJRQnV0by9yNlRPOTZhcFlQVHd5VkIvRjJBClViZXRiR2JOWjJLazRadU54M0VB\nZExmS0RqeWh3MlQ5ZVVPZnZCS2NnNGsKLS0tIFkxSktyc3lMN2srdkNwNkhIWUFD\nUStCbDh3MTBDUmV1Y2tzeWdTR01SMFUKh6PXLS/J02QYax8z/T35Sz24KxwHSH1A\nm1Fxpb4n3ue/lEsKRPbUlwwRpzAMBHhmccfSrNAyBwu2RQ6VyZ17jQ==\n-----END AGE ENCRYPTED FILE-----\n
BACKUP_ACCESS_KEY_ID=ENC[AES256_GCM,data:EkpvA6uAWHgF6rp3nX8=,iv:0c2fmfxyuYSjwG7nd4nW+dSSZdwjO+OSPDxBntmLUy8=,tag:2zBAqdVz59GAar01uylD3Q==,type:str]
BACKUP_SECRET_ACCESS_KEY=ENC[AES256_GCM,data:+Lw7tGBiyD7RTY0QBr0PWByBDdld29AB,iv:OKbgQyZqrf8+GVR6dfq8ba8fZeyxXLrw9T2Soa5NuA0=,tag:syYsub7TvLFWW44zyyxUYA==,type:str]
ONEBOX_REPOSITORY_KEY=ENC[AES256_GCM,data:GOANkTcfLADqV4UILxYmPo9mfsSYVR8Mot5cli9LwPbcqKY+0rleG4MfY6vPWlegYB0nS1ahhOq7ij1OdQQtNQ==,iv:KVu8JvYnS3cmZgx8U8IpGPM5d9JesqlIp2UNVIlPnvA=,tag:EBxQZUwxEvYq0rhcrkKVWQ==,type:str]
sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwbGp5cFlYQmNxTzJHamYr\nY0N4dFZrdGpuWVdyL01KR2cvYlZuTjhwemx3CnhUZnZmZHgxZ2FkcHZhUjRqTFIx\nbjZORmhMeGRFMDVjaHpqY09IK0Q3aGMKLS0tIGpnTUQzZUJQb2p5UEpnMnNnZy8v\nd1g2alVLeUYyWUk3azRSWXBoTXI1MWMKSOilXfdZbh2C7So8OPjC75v+ahd2y7aM\n/a/3vkjD0Z+iro7NEsHffyM+Ro18JYDnNcGZ8yPDn81HkvnzSwMjkA==\n-----END AGE ENCRYPTED FILE-----\n
sops_age__list_0__map_recipient=age1xtc0fzq29crqzk98r59zdetgyxdhqwqm7qrvkal4n7zr3cu5wgassh3u3x
sops_lastmodified=2026-08-21T23:47:21Z
sops_mac=ENC[AES256_GCM,data:bNfd63Xkxu6BQNWP0/Go5h1Brtcg6wDVvqmZDRSUDlyu1JhEWVbIBDsgmXf+v4Dy6wlkGpKWT97CCmScJKfP9LY9iKvZBa0uSlpESKgKgzFY7nHUnkiXPjM5U7v5lmWyBuBuGooW1D0kXG71l88mcnfXe0ij9zEQEfYTSAboCZ4=,iv:53tToUkZi3aQ47RX0Su+i9qqreTDUaTo34hFDyYaSfo=,tag:KCfqsNjBhshEsKZH0qItyQ==,type:str]
sops_lastmodified=2026-08-23T15:59:09Z
sops_mac=ENC[AES256_GCM,data:pTzRIDaKlrKtg+LaTigPToLqy91TaZthQpBAE5fRzjsZ8QkVGJXBWHYwe1x9/HT9/GbGJMXj3b3+cVxHRaXf3j/IFilwuGa4IvoMmotB6eRDJva9Fn1Sv8RlNvssWThzBRvJE8iY4ESfeY4b1rIc1pS5v0ucenaYffHCU6tYcG8=,iv:6pk9mQ+14X38hpOcqCDhTsQDVNp8TRG6iMDgsd41bpw=,tag:5YuWOEwOyrB/cPmzo32jmw==,type:str]
sops_unencrypted_suffix=_unencrypted
sops_version=3.13.3
20 changes: 13 additions & 7 deletions internal/app/backup_walg.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const WalgTrustStore = WalgMountPath + "/ca-certificates.crt"
// encryption key. Unlike the destination keys it has a fixed name: the key is
// Onebox's own requirement rather than a property of the destination, so there
// is no backup_targets field to indirect through.
const WalgRepositoryKeyEntry = "OB_REPOSITORY_KEY"
const WalgRepositoryKeyEntry = "ONEBOX_REPOSITORY_KEY"

// WalgPrefix is the repository location for one protected database generation.
//
Expand Down Expand Up @@ -193,14 +193,20 @@ func RenderWalgWrapper(target BackupTarget) []byte {
b.WriteString("# from the mode-0600 credential file on the host; only the names are\n")
b.WriteString("# here, and the names are not secret.\n")
b.WriteString("set -eu\n")
// A declared entry is a required one: WalgCredentialEntries is the same
// list enable-time validation insists on. Refusing here rather than
// skipping matters most for the repository key — wal-g with no
// WALG_LIBSODIUM_KEY does not fail, it writes the backup unencrypted, so a
// credential file that stops defining an entry would quietly downgrade
// every subsequent backup. The credential file is written once at enable
// time and read by every later deploy, so the two can drift.
assign := func(walgName, entry string) {
if entry == "" {
return
}
b.WriteString("if [ -n \"${" + entry + "-}\" ]; then\n")
b.WriteString(" " + walgName + "=\"$" + entry + "\"\n")
b.WriteString(" export " + walgName + "\n")
b.WriteString("fi\n")
b.WriteString(": \"${" + entry + ":?is not set in the credential file on this host — re-run `ob backup enable` for this service}\"\n")
b.WriteString(walgName + "=\"$" + entry + "\"\n")
b.WriteString("export " + walgName + "\n")
}
assign("AWS_ACCESS_KEY_ID", target.Credentials.AccessKeyEntry)
assign("AWS_SECRET_ACCESS_KEY", target.Credentials.SecretKeyEntry)
Expand Down Expand Up @@ -334,8 +340,8 @@ func (r *Resolved) backupForRender(n Names, serviceName string) (*serviceBackup,
if err != nil {
return nil, err
}
environment["OB_S3_KEY_ENTRY"] = projection.Target.Credentials.AccessKeyEntry
environment["OB_S3_SECRET_ENTRY"] = projection.Target.Credentials.SecretKeyEntry
environment["ONEBOX_S3_KEY_ENTRY"] = projection.Target.Credentials.AccessKeyEntry
environment["ONEBOX_S3_SECRET_ENTRY"] = projection.Target.Credentials.SecretKeyEntry
return &serviceBackup{
RuntimeHostDir: n.BackupRuntimeDir(serviceName),
CredentialFile: n.BackupCredentialFile(serviceName, projection.Policy.Target),
Expand Down
Loading
Loading