imglife eol
Synopsis
Section titled “Synopsis”imglife eol update [flags]imglife eol notify [flags]Fetches EOL data from endoflife.date for every product referenced in sync.entries[].lifecycle.product and writes the result to eol_data_file.
| Flag | Default | Description |
|---|---|---|
--dry-run |
false |
Fetch and display data without writing |
--prune |
false |
Rebuild the cache from the collected cycles only, dropping the others |
--data-file string |
eol-data.yaml |
Path to the output file (overrides lifecycle.eol_data_file) |
Examples
Section titled “Examples”# Refresh EOL dataimglife eol update
# Dry-run: fetch and display without writingimglife eol update --dry-run
# Drop the cycles that are no longer used by any imageimglife eol update --prune
# Write to a custom pathimglife eol update --data-file /tmp/eol-cache.yamlWhen to run
Section titled “When to run”Run imglife eol update periodically (e.g. weekly) to keep EOL dates current. In CI, add it as a scheduled job:
# GitLab CI scheduled jobeol-update: stage: eol image: registry.gitlab.com/imglife-project/imglife:latest script: - imglife eol update - | if git diff --quiet eol-data.yaml; then echo "EOL data unchanged" else git add eol-data.yaml git commit -m "chore(lifecycle): update EOL data" git push fi rules: - if: $CI_PIPELINE_SOURCE == "schedule"Configuration
Section titled “Configuration”The set of products to fetch is derived from sync.entries[].lifecycle.product in your imglife.yaml. Only products with a lifecycle: block are fetched.
sync: entries: - source: docker.io/library/alpine lifecycle: product: alpine # ← will be fetched - source: docker.io/library/golang lifecycle: product: go # ← will be fetched - source: docker.io/library/nginx # no lifecycle: block — not fetchedCollected cycles
Section titled “Collected cycles”Cycles come from two sources:
- Mirror tags — the tags present in the target registry for each
syncentry with alifecycle:block. - Applicative build records — the base image of every build record published in the Package Registry.
The second source matters when an application stays on a version line whose mirror tags have already
been removed by keep_last: without it, the EOL data for that cycle would never be fetched and
status would show ⚠️ N/A. It requires the Package Registry token; when the token is missing, a
warning is logged and only the mirror cycles are collected.
Cache merge semantics
Section titled “Cache merge semantics”eol update merges the fresh data into the existing cache (local file or Package Registry): a
cycle already known is kept even once no mirror tag references it. Fresh data wins on conflict.
--prune skips the merge and rebuilds the cache from the collected cycles only — the only way to
remove a cycle that is no longer in use.
Missing cycles at read time
Section titled “Missing cycles at read time”status, check and eol notify resolve a cycle that is absent from the cache by falling back on
the neighboring cycles:
| Case | Result |
|---|---|
| Cycle newer than anything endoflife.date knows | Inherits the previous cycle’s status if that cycle is still supported |
| Cycle older than every known cycle | ⚠️ outdated — no status is fabricated |
| Unknown product | ⚠️ N/A with the reason in the tooltip |
Storage target
Section titled “Storage target”By default, the data is written to a local file (git target). For environments where CI cannot push to git, switch to pkgregistry:
lifecycle: eol_target: pkgregistryThe file is then stored in the Package Registry and read from there by imglife status and imglife check.
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
Data fetched and written successfully |
1 |
Fetch or write error |
Execution flow
Section titled “Execution flow”imglife eol notify
Section titled “imglife eol notify”Evaluates all lifecycle entries and sends alerts to Slack or generic webhooks for images at or above the configured status threshold.
| Flag | Default | Description |
|---|---|---|
--dry-run |
false |
Print alerts without sending |
--min-status string |
warning |
Minimum alert level: warning, critical, eol (overrides config) |
Examples
Section titled “Examples”# Send notifications using config defaultsimglife eol notify
# Preview without sendingimglife eol notify --dry-run
# Only notify for critical/EOL imagesimglife eol notify --min-status criticalConfiguration
Section titled “Configuration”Destinations are configured in imglife.yaml under lifecycle.notifications:
lifecycle: notifications: min_status: warning # warning | critical | eol slack_webhook_url: "${SLACK_WEBHOOK_URL}" webhooks: - url: "${MY_WEBHOOK_URL}" headers: Authorization: "Bearer ${TOKEN}"Slack payload (Blocks API)
Section titled “Slack payload (Blocks API)”Each base alert gets its own section block with associated applicative images grouped into two lists: Apps to update (a newer base tag is available) and Apps on latest (already on the most recent tag). A divider separates alerts; a context block closes the message.
{ "blocks": [ {"type": "header", "text": {"type": "plain_text", "text": "🚨 imglife Lifecycle Alerts"}}, { "type": "section", "text": { "type": "mrkdwn", "text": "🟡 *python/3.12* — WARNING · EOL: 2028-10-31\n*Apps to update:*\n • reg/apps/myapp:1.0.0\n `3.12.0-core1.0.0` → `3.12.5-core1.0.0`" } }, {"type": "divider"}, { "type": "section", "text": { "type": "mrkdwn", "text": "🔴 *alpine/3.17* — EOL exceeded · EOL: 2023-11-01\n*Apps on latest (no newer version available):*\n • reg/apps/legacy:2.0.0 (base: `3.17.9-core1.0.0`)" } }, {"type": "context", "elements": [{"type": "mrkdwn", "text": "Generated by *imglife* · 2026-04-22"}]} ]}Generic webhook payload
Section titled “Generic webhook payload”The latest_base field is populated only for applicative alerts (applicative_image non-empty). It contains the most recent available base tag when an upgrade exists, or is omitted when the app is already on the latest tag.
{ "alerts": [ { "product": "python", "cycle": "3.12", "status": "WARNING", "eol_date": "2028-10-31", "applicative_image": "reg/apps/myapp:1.0.0", "base_image": "reg/base/python:3.12.0-core1.0.0", "latest_base": "3.12.5-core1.0.0" }, { "product": "alpine", "cycle": "3.17", "status": "EOL", "eol_date": "2023-11-01", "applicative_image": "reg/apps/legacy:2.0.0", "base_image": "reg/base/alpine:3.17.9-core1.0.0" } ]}Dry-run output
Section titled “Dry-run output”[dry-run] Would send 2 base alert(s) + 2 app alert(s) to 1 destination(s): python/3.12 WARNING EOL: 2028-10-31 → reg/apps/myapp:1.0.0 (update: 3.12.0-core1.0.0 → 3.12.5-core1.0.0) alpine/3.17 EOL EOL: 2023-11-01 → reg/apps/legacy:2.0.0 (on latest, no upgrade available)Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
Success (even when alerts are present) |
1 |
Error (config invalid, HTTP send failure, etc.) |