Files
hassio-addons/portainer_agent/config.yaml
Alexandre 7cd844ac9f fix(templates): populate /run/s6/container_environment when the entrypoint is PID 1 (#3013)
Add-ons that override the base image's ENTRYPOINT ["/init"] with
ENTRYPOINT ["/usr/bin/env"] plus CMD ["/ha_entrypoint.sh"] never run s6-overlay's
stage 1, so nothing creates /run/s6/container_environment. `with-contenv` empties
the environment and repopulates it from that directory, which means every script
carrying a #!/usr/bin/with-contenv shebang outside the three globs whose shebang
ha_entrypoint.sh rewrites either exits non-zero before its first line of logic
(directory missing: s6-envdir errors) or runs against whatever a cont-init script
happened to leave there.

Measured in a running add-on of this repo whose PID 1 is /ha_entrypoint.sh: a
with-contenv script saw 16 environment variables where the entrypoint has 110, with
SUPERVISOR_TOKEN among the missing. Neither failure prints anything, so all that
surfaces is whatever the caller makes of a non-zero exit — a Docker HEALTHCHECK
reading "unhealthy" for eight months, in the case that prompted this. Cron jobs,
user-facing CLI wrappers and the user's own script.sh share the blind spot.

Dump the environment here instead, with s6-dumpenv, which is what stage 1 would
have done. Guarded on being PID 1 and on with-contenv existing, so it neither runs
under /init — where stage 1 already wrote the directory — nor warns in images that
have no with-contenv to fix.

Filled in a sibling directory and renamed into place rather than written live. A
half-populated envdir is worse than an absent one: s6-envdir accepts it, so a
with-contenv script starts and runs against an environment quietly missing
SUPERVISOR_TOKEN, where an absent one stops it at its shebang. A HEALTHCHECK can run
alongside PID 1, and rename(2) means such a reader sees the directory either absent
or complete. Measured with a racing poller over 664 samples: only 0 or 110 entries,
never a partial count.

The directory is cleared first rather than written over. /run is not a tmpfs in
these containers, so an image layer could persist entries there, and merging into
them would leave variables PID 1 does not have, including a stale SUPERVISOR_TOKEN.
A failed rm aborts the attempt, since mkdir -p accepts a surviving
symlink-to-directory and would let the dump follow it.

A failed seed leaves the directory absent, which is how this already fails today, so
the failure mode is unchanged rather than newly degraded — but it now says so.

Placed after the shebang probe on purpose. The probe's first candidate is
"/command/with-contenv bashio" and it fails today in exactly these add-ons, so the
probe falls through to "/usr/bin/env bashio". Seeding earlier would make that first
candidate start succeeding and flip the shebang of every cont-init and service
script that lands here, which is a much larger change than this fixes.

Refs #3006

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 14:30:13 +02:00

44 lines
936 B
YAML

arch:
- aarch64
- amd64
backup_exclude:
- backups
description: An agent used to manage all the resources in a Swarm cluster
docker_api: true
full_access: true
hassio_api: true
image: ghcr.io/alexbelgium/portainer_agent-{arch}
init: false
map:
- config:rw
- share:rw
- ssl
name: Portainer Agent
options:
env_vars: []
ports:
80/tcp: null
9001/tcp: 9001
ports_description:
80/tcp: Portainer edge agent
9001/tcp: Portainer agent
schema:
env_vars:
- name: match(^[A-Za-z0-9_]+$)
value: str?
AGENT_CLUSTER_ADDR: str?
AGENT_CLUSTER_PROBE_INTERVAL: str?
AGENT_CLUSTER_PROBE_TIMEOUT: str?
AGENT_SECRET: str?
AGENT_SECRET_TIMEOUT: str?
EDGE: list(0|1)?
EDGE_ID: str?
EDGE_INACTIVITY_TIMEOUT: str?
EDGE_INSECURE_POLL: list(0|1)?
EDGE_KEY: str?
LOG_LEVEL: str?
PORTAINER_AGENT_ARGS: str?
slug: portainer_agent
udev: true
url: https://github.com/alexbelgium/hassio-addons
version: "2.44.0.1"