agama/live/live-root/usr/lib/dracut/modules.d/99live-self-update/module-setup.sh
Ladislav Slezák 3ba7513cda
Implement proxy support in the self-update, fixed handling fallback (#2845)
## Problem

- Missing HTTP proxy support in self-update
- Fallback for failing SCC/RMT was not handled correctly (I forgot about
the global `set -e` option which fails the whole script on any error
😟 )

## Solution

- Get the configured proxy
- Pass it to the `curl` call which contacts the SCC and zypper which
downloads the packages via `http_proxy` and `https_proxy` environment
variables.
- Fixed checking the result of the `curl` call
- Fixed keeping the systemd service status (workaround: enable the
service also in the root system, but due to `WantedBy=initrd.target` it
runs only once in initramfs.

## Testing

- Tested manually with `proxy=` boot option and also when setting the
proxy interactively with the dracut menu (invoked with the
`rd.cmdline=menu` boot option)
- Tested with my locally running Squid proxy server
- In both cases the proxy was use for contacting both the registration
server (SCC) and the self-update repository.
- So far tested with plain proxy without authentication, later I'll test
it with authenticated proxy

I checked the Squid access log and it contained these two lines
confirming that the proxy was really used for both connections:

```
1762155964.003    101 192.168.1.112 TCP_TUNNEL/200 5313 CONNECT scc.suse.com:443 - HIER_DIRECT/99.83.188.102 -
1762155967.332    277 192.168.1.112 TCP_TUNNEL/200 8724 CONNECT installer-updates.suse.com:443 - HIER_DIRECT/75.2.43.231 -
```


## Screenshots

Screenshot of the log:

<img width="1280" height="800" alt="agama-self-update-proxy-log"
src="https://github.com/user-attachments/assets/55a2aabc-c006-4724-80f6-8c5f3b622452"
/>

## Fixed systemd status

Self-update service status in initramfs (started from emergency shell
invoked with `rd.break` boot option):

<img width="1280" height="800" alt="self-update-status-initramfs"
src="https://github.com/user-attachments/assets/14a3cf44-88ee-4314-ad19-d1a62786b139"
/>

Self-update service status in the root image after fully booting the
system, the exit status is missing although the log is correctly kept:

<img width="1280" height="800" alt="self-update-status-root"
src="https://github.com/user-attachments/assets/8f4347e9-0db1-4a2c-b900-390558da84ab"
/>


The service status after enabling it also in the root image (after fully
booting the system):

<img width="1280" height="800" alt="self-update-status-root-fixed"
src="https://github.com/user-attachments/assets/cb63bf47-9abf-4149-a8d8-cf7c3237ee36"
/>


## Updates

- Set the proxy rather via environment variables than via the command
line options or URL query. That avoids showing or logging the proxy URL
with a password.
- Disable logging the proxy URL in the code
- Tested also with authenticated proxy, the Squid proxy then contains
these lines:
```
1762184588.402      0 192.168.1.105 TCP_DENIED/407 3892 CONNECT scc.suse.com:443 - HIER_NONE/- text/html
1762184588.763    359 192.168.1.105 TCP_TUNNEL/200 5313 CONNECT scc.suse.com:443 proxyuser HIER_DIRECT/99.83.188.102 -
1762184591.959      0 192.168.1.105 TCP_DENIED/407 3968 CONNECT installer-updates.suse.com:443 - HIER_NONE/- text/html
1762184592.517    555 192.168.1.105 TCP_TUNNEL/200 8724 CONNECT installer-updates.suse.com:443 proxyuser HIER_DIRECT/99.83.188.102 -
```

The "proxyuser" is the configured proxy account user name. The proxy is
connected twice, in the first attempt it checks whether a password is
required and which form (basic/digest) authentication is expected. In
the second request the actual user name and password is sent.
2025-11-04 10:00:40 +01:00

50 lines
1.3 KiB
Bash
Executable file

#!/bin/bash
# module-setup.sh for Agama self-update
# see https://www.man7.org/linux/man-pages/man7/dracut.modules.7.html
# called by dracut
check() {
# always include this dracut module in the initramfs
return 0
}
# called by dracut
depends() {
echo network
return 0
}
installkernel() {
return 0
}
# install hook for dracut
install() {
# install the hook for processing the boot parameters
inst_hook cmdline 99 "$moddir/live-self-update-parser.sh"
# needed by the live-self-update-parser.sh script
inst_multiple systemd-cat dirname /usr/lib/live-self-update/conf.sh jq
# install the systemd service and the self-update script to the initramfs
inst_multiple "$systemdsystemconfdir"/live-self-update.service live-self-update
# needed by the live-self-update script
inst_multiple grep tail sed
# include the self-update configuration if present
if [ -d /etc/live-self-update ]; then
. /usr/lib/live-self-update/conf.sh
if [ -f "$CONFIG_DEFAULT_REG_SERVER_FILE" ]; then
inst_simple "$CONFIG_DEFAULT_REG_SERVER_FILE"
fi
if [ -f "$CONFIG_FALLBACK_FILE" ]; then
inst_simple "$CONFIG_FALLBACK_FILE"
fi
fi
# enable the self-update service in the initramfs
$SYSTEMCTL -q --root "$initdir" enable live-self-update.service
}