Add rawsetenv message type for provider plugins#13742
Conversation
Providers can now send rawsetenv messages to inject environment variables into dependent services without the automatic service name prefix. This enables use cases where applications require exact variable names that cannot be altered. Closes docker#13727 Signed-off-by: Yohta Kimura <38206553+rajyan@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
this patch worked for my issue with mariadb requiring MYSQL_ROOT_PASSWORD with no override, not LOCKET_MYSQL_ROOT_PASSWORD as the compose provider was passing. |
glours
left a comment
There was a problem hiding this comment.
Few things to address before we can merge.
Also we need to add a sibling fixture to pkg/e2e/fixtures/providers/rawsetenv.yaml that sets environment: { CLOUD_REGION: user-value } on the test service, and assert that the resulting value matches the documented behavior (skipped write, warning, or overwrite, depending on which resolution is chosen).
| } | ||
|
|
||
| variables, err := s.executePlugin(cmd, command, service) | ||
| vars, err := s.executePlugin(cmd, command, service) |
| s.Environment[prefix+key] = &val | ||
| } | ||
| for key, val := range vars.raw { | ||
| s.Environment[key] = &val |
There was a problem hiding this comment.
rawsetenv silently overwrites user-defined env vars
If a user sets environment: { CLOUD_REGION: eu-west-1 } and a provider emits rawsetenv CLOUD_REGION=us-east-1, the user value is silently clobbered. setenv was immune thanks to the prefix.
Please either skip writes when the key already exists, or we need to document this precedence explicitly.
@ndeloof what is you preference here? I'm in favor of the overwrite + warning message in logs, and you?
| This is useful when injecting secrets or configuration values that must match exact variable names expected by | ||
| applications or frameworks. Unlike `setenv`, which avoids collisions through automatic prefixing, `rawsetenv` keys | ||
| are the provider's responsibility to keep unique. If multiple providers emit the same `rawsetenv` key, the last one | ||
| to run will overwrite previous values. |
There was a problem hiding this comment.
executor.go runs plan nodes concurrently via errgroup. Two providers without a mutual dependency run in parallel; mux serializes the writes but not their order. The doc says "the last one to run will overwrite previous values", literally true, but readers will assume declaration order wins.
Either tighten the doc, or detect cross-provider rawsetenv collisions and fail.
| env := getEnv(res.Combined(), false) | ||
| assert.Check(t, slices.Contains(env, "PROVIDER1_URL=https://magic.cloud/provider1"), env) | ||
| assert.Check(t, slices.Contains(env, "PROVIDER2_URL=https://magic.cloud/provider2"), env) | ||
| assert.Check(t, slices.Contains(env, "CLOUD_REGION=us-east-1"), env) |
There was a problem hiding this comment.
both providers emit the same CLOUD_REGION value, so the conflict path is never exercised. Please add a test where a rawsetenv key collides with a user-defined env var
What I did
Added a new
rawsetenvmessage type to the provider plugin protocol. This allows providers to inject environment variables into dependent services without the automatic service name prefix.Currently,
setenvalways prefixes variables with the service name (e.g.,URLbecomesDATABASE_URL). This works well for connection strings, but some applications require exact variable names that cannot be altered. There is no way to inject these as-is today.With this change, providers can choose per-variable whether to use the prefixed (
setenv) or unprefixed (rawsetenv) behavior:{"type": "setenv", "message": "URL=https://example.com"} {"type": "rawsetenv", "message": "SECRET_KEY=xxx"}Changes
pkg/compose/plugins.go— AddRawSetEnvTypeconstant andpluginVariablesstruct to separate prefixed/raw variablesdocs/extension.md— Documentrawsetenvin the protocol specificationdocs/examples/provider.go— Addrawsetenvusage to the example providerpkg/e2e/providers_test.go— Test for single-provider rawsetenv and multi-provider rawsetenvpkg/e2e/fixtures/providers/rawsetenv.yaml— Test fixtureRelated issue
resolves #13727