Gentoo Linux update system
Glus is a maintenance script for Gentoo Linux systems. It keeps Portage and selected package sets up to date, rebuilds packages affected by toolchain, Perl, Python, or shared-library changes, and optionally removes obsolete packages and downloaded source archives.
It is intended for periodic system maintenance, from small daily security
updates to larger system, world, or full rebuild runs. The script can also show
the planned operations with --plan, run Portage in pretend mode with
--pretend, and print commands without executing them with --debug.
-
Unify the regular Gentoo maintenance workflow: sync Portage, update Portage itself, update selected package sets, rebuild affected packages, and clean old packages or source files when requested.
-
Use the executable
emergewrapper found under/usr/lib/python-exec/python*/emerge. This helps when the regularemergecommand is temporarily broken during Python upgrades or when the system is between two Python versions. -
Update the active binutils and GCC configuration before compiling packages so newly built binaries use the latest available development toolchain.
-
Check and repair packages with missing shared-library dependencies using
revdep-rebuild. -
Optionally verify installed package file integrity with
qcheck, reporting packages with changed or missing files while ignoring protected configuration paths. -
Rebuild Perl packages and headers affected by Perl upgrades using
perl-cleaner. -
Rebuild preserved packages, repair Portage merge metadata, and check the world file with
emaint. -
Support binary package modes, package exclusions, live package rebuilds, kernel module rebuilds, Go package rebuilds, hooks, quiet output, colored output, error email notifications, and dry-run planning.
Glus performs the update in a conservative order so that the package manager and the base build toolchain are refreshed before larger package updates are attempted:
-
Load
/etc/portage/glus.conf, validate options and hooks, and build the ordered list of steps shared by planning and execution. Executing the plan acquires an instance lock and creates a persistent run log directory. -
Sync Portage with
emaint -a sync, unless synchronization is disabled. A failed sync is retried once, since a second run usually picks another mirror when one fails Manifest verification. -
Run optional sync hooks configured with
GLUS_BEFORE_SYNCandGLUS_AFTER_SYNC. -
Leave build-directory cleanup to Portage, which coordinates its own locks. Glus no longer deletes
/var/tmp/portage/*: checking for processes cannot prevent a different build from starting during deletion. Automatically merge Portage configuration updates withetc-update --automode -5 /etc/portage. -
Update Portage first.
-
Refresh development tools before and after package compilation: select the latest available binutils and GCC profiles, run
env-update, and refresh Python wrappers witheselect python update --python3when the optionaleselect-pythonmodule is installed. If it is absent, Glus skips the selector updates and continues; failures from an installed selector still stop the run. -
Resolve
emergethrough the Python exec wrappers in/usr/lib/python-exec/python*/emerge, which can recover from situations where the defaultemergecommand is not usable during Python transitions. -
Fetch required package sources before compiling, retrying downloads before giving up.
-
Update the requested target: security packages, explicit packages, live packages, Go packages, kernel modules, the base system, world, or a full empty-tree world rebuild.
-
Rebuild preserved packages, rebuild Perl packages, and run
revdep-rebuildto find and repair binaries linked against missing or updated libraries. Perl maintenance is skipped in effective binary-only mode (only, orautoonlywhen binary packages are available), with the reason included in the final summary. Modes that allow source builds runperl-cleaner --allwithout forcing binary packages, passing the other options throughEMERGE_DEFAULT_OPTSand preserving Portage's configured defaults. WhenGLUS_QCHECK=trueor--qcheckis enabled, also runqcheck -B -P -vto verify installed package file integrity. -
Optionally run
emerge --depclean, clean old binary packages and distfiles witheclean, run compile hooks, reload systemd when required, and write a final summary. Optionally send that summary by email, Slack, or both.
--color false (or GLUS_COLOR=false) also exports NOCOLOR=true and
NO_COLOR=1 to synchronization and build tools, keeping their output suitable
for plain-text logs and Healthchecks. --color auto does the same when output
is not a terminal.
Each execution creates a private directory under /var/log/glus, named
run-<UTC timestamp>-<unique suffix>. Override the parent directory with
GLUS_LOG_DIR or --log-dir /absolute/path. Failure to create logs stops the
run before maintenance begins.
summary.txt: final status, exit code, total duration and each step's result.steps.tsv: step index, result, exit code, seconds and title. Remaining steps are marked skipped if a previous step fails or the run is interrupted.command-<step>-*.log: unique output file for each command, including retries. The accompanying.metafile records the command, duration and exit status; an interrupted command may retainStatus: runningwithout an exit entry.commands.tsv: exit code, log filename, seconds, step index, quoted command and short command label.retries.logandnotifications.log: retry decisions and delivery results, when applicable.
Use --quiet (or GLUS_QUIET=true) when wrapping Glus with runitor: the final
summary includes each command's name, duration and exit code, while full command
output stays in the local logs. Failures show only the last 20 output lines.
Logs survive both failure and interruption. The summary is printed even with
--quiet. GLUS_LOG_ROTATIONS / --log-rotations defaults to 10 runs,
including the current one; 0 disables the count limit. The oldest completed,
marked Glus run directories are removed first. Unfinished runs, symlinks and
unrelated directories are retained and do not count towards the limit.
GLUS_LOG_RETENTION_DAYS / --log-retention-days optionally expires runs by
age as well; it defaults to 0 (disabled). Set both limits to 0 to keep all runs.
--plan and --debug use the same ordered steps but do not acquire a lock,
create run logs, run maintenance commands or send notifications. Conditional
steps can depend on the current machine state; the basic-system fallback only
executes when the initial system update fails. --pretend executes Portage
checks and keeps logs, but sends no notifications.
| Option | Configuration | Default |
|---|---|---|
--fetch-attempts |
GLUS_FETCH_ATTEMPTS |
3 total attempts |
--fetch-delay |
GLUS_FETCH_DELAY |
300 seconds |
--cancel-grace |
GLUS_CANCEL_GRACE |
10 seconds |
Only the download phase is retried. Invocation errors (exit 2), missing or
non-executable commands (126/127), signal exits and recognized invalid-argument
diagnostics stop immediately. Portage uses exit 1 for several different causes,
so unclassified exit-1 failures are retried up to the configured limit. Use
--fetch-attempts 1 to disable retries or --fetch-delay 0 to retry immediately.
Maintenance runs in a dedicated process group. On TERM, INT or HUP, Glus sends
TERM to the group, waits up to the grace period, then kills remaining members.
It preserves the logs and exits with 143, 130 or 129 respectively. Hooks should
run in the foreground and must not detach into their own session if they need
to participate in cancellation. The instance lock remains held during shutdown.
Maintenance is unattended: the worker receives closed interactive input
(/dev/null). Hooks and Portage options must not require terminal prompts.
Configure either destination or both in /etc/portage/glus.conf:
GLUS_EMAIL="admin@example.com"
GLUS_SLACK_WEBHOOK="https://hooks.slack.com/services/T_EXAMPLE/B_EXAMPLE/REPLACE_ME"
GLUS_NOTIFY="failures"GLUS_NOTIFY / --notify accepts failures (default), always or never.
Once an execution has started, one final summary is sent according to that
policy, including interrupted runs. Email now receives the final summary
instead of separate messages for individual command failures. Slack receives
the host, result, duration, step counts and the local log path; command output
is retained locally. A local path is not a downloadable link in Slack.
Create an incoming webhook in Slack
for the destination channel. Slack delivery requires curl. --slack-webhook
overrides the configured URL and --no-slack disables Slack for a single run.
Prefer the configuration file over the CLI for the secret URL; restrict the
configuration file's permissions. Glus does not print the URL or pass it in
curl's command-line arguments, and removes the configured webhook environment
variable before running package commands.
Delivery failures are recorded and warned about without changing the update's
exit status. Slack requests have a 10-second connection timeout and a 20-second
overall timeout, with no automatic resend to avoid duplicate messages after
ambiguous responses. No notifications are sent by --plan, --debug or
--pretend. The documented example is a placeholder, not a usable webhook.
glus.sh --plan --world --binary only
glus.sh --world --fetch-attempts 2 --fetch-delay 60 --notify always
glus.sh --security --no-slackFor a targeted update, use glus.sh --packages-only dev-lang/rust-bin.
This mode only fetches and updates the selected packages and any dependencies
Portage requires. It skips synchronization, the automatic Portage update,
toolchain selection, hooks, Perl maintenance, rebuilds and cleanup, even when
those are enabled in the configuration. Locks, retries, logs and notifications
remain active. Preview the exact scope with --plan or --pretend.
It cannot be combined with --system, --world or --full.
-
flock (sys-apps/util-linux)
Prevents multiple Glus instances from running at the same time.
-
perl-cleaner (app-admin/perl-cleaner)
Find & rebuild packages and Perl header files broken due to a perl upgrade.
-
revdep-rebuild (app-portage/gentoolkit)
Scans libraries and binaries for missing shared library dependencies and attempts to fix them by re-emerging those broken binaries and shared libraries. It is useful when an upgraded package breaks other software packages that are dependent upon the upgraded package.
-
qcheck (app-portage/portage-utils)
Optionally verifies the integrity of installed package files when
GLUS_QCHECKor--qcheckis enabled. -
mailx (virtual/mta)
Send mail for alerts and notifications when
GLUS_EMAILor--emailis configured.
The latest available version can also be installed manually by running the following commands:
curl -o /usr/sbin/glus.sh 'https://raw.githubusercontent.com/inode64/glus/main/glus.sh' \
&& chown 0:0 /usr/sbin/glus.sh \
&& chmod 755 /usr/sbin/glus.sh
curl -o /etc/portage/glus.conf 'https://raw.githubusercontent.com/inode64/glus/main/glus.conf' PORTAGE OPTIONS:
-S, --[no-]sync, ${GLUS_SYNC}
Sync portage.
(default: true)
-e, --exclude <EXCLUDE>, ${GLUS_EXCLUDE}
Exclude packages.
(default: "")
-P --[no-]pretend, ${GLUS_PRETEND}
Instead of actually performing the merge, simply display what *would* have been installed if --pretend weren't used.
(default: "false")
-c --[no-]check, ${GLUS_CHECK}
Check the system.
(default: true)
--[no-]qcheck, ${GLUS_QCHECK}
Verify installed package integrity with qcheck.
(default: false)
-C --[no-]clean, ${GLUS_CLEAN}
Clean packages and source files after compile.
(default: false)
-f, --[no-]fetch, ${GLUS_FETCH}
Only download, no compile or install.
(default: false)
-b, --binary <auto|autoonly|true|false|only>, --no-binary, ${GLUS_BINARY}
Use binary packages.
Force use only binary packages for only option selected.
(default: false)
SETS:
-p --packages <PACKAGES>, ${GLUS_PACKAGES}
Add this packages for update.
(default: "")
-g --[no-]go, ${GLUS_GO}
Add go lang packages for update.
(default: false)
-m --[no-]modules, ${GLUS_MODULES}
Add kernel modules for update.
(default: false)
-l --[no-]live, ${GLUS_LIVE}
Add live packages for update. (force compile)
(default: false)
-s --[no-]security, ${GLUS_SECURITY}
Compile security relevant packages (daily process, for example).
(default: true)
ACTIONS:
--[no-]system
Compile only system core (weekly process, for example).
(default: false)
--world
Compile only system core (monthly process, for example).
--full
Recompile the entire system (annual process, for example).
--dry-run, --plan
Show the planned steps and commands without executing them.
Shows commands like --debug and disables --quiet.
MISC OPTIONS:
--[no-]debug, ${GLUS_DEBUG}
Show the commands to run.
(default: false)
-q, --[no-]quiet, ${GLUS_QUIET}
Suppress non-error messages.
(default: false)
-x, --color <auto|true|false>, ${GLUS_COLOR}
Colorize the output.
(default: true)
--email <email> ${GLUS_EMAIL}
Send mail for alerts and notifications.
(default: "")
-v, --version
Show version number and quit.
-h, --help
Show this help and quit.
The default behavior of Glus can be adjusted with multiple options. Use the --help option for the full list. By default, Glus sync the portage and update the security packages with:
glus.sh
- Update security, kernel modules and live packages
glus.sh --security --modules --live
- Update security packages and system
glus.sh --system
- Update world
glus.sh --world
- Update empty tree world and debug
glus.sh --full --debug
- Show the update plan without executing commands
glus.sh --plan
- Run the regular checks and verify installed package file integrity with qcheck
glus.sh --qcheck