topgrade-rs / topgrade

Upgrade all the things
GNU General Public License v3.0
2.04k stars 139 forks source link

Fails to update ClamAV db - needs sudo #903

Open mouse07410 opened 2 months ago

mouse07410 commented 2 months ago

Erroneous Behavior

── 10:39:17 - Update ClamAV Database(FreshClam) ────────────────────────────────
ERROR: Failed to open log file /opt/local/var/log/clamav/freshclam.log: Permission denied
ERROR: Problem with internal logger (UpdateLogFile = /opt/local/var/log/clamav/freshclam.log).
ERROR: initialize: libfreshclam init failed.
ERROR: Initialization error!
ClamAV Databases failed: 
   0: Command failed: `/opt/local/bin/freshclam`
   1: `/opt/local/bin/freshclam` failed: exit status: 2

Location:
   src/steps/generic.rs:973

Expected Behavior

$ sudo /opt/local/bin/freshclam
ClamAV update process started at Fri Sep  6 10:41:11 2024
WARNING: DNS record is older than 12 hours.
Trying to retrieve CVD header from https://database.clamav.net/daily.cvd
daily.cld database is up-to-date (version: 27390, sigs: 2066512, f-level: 90, builder: raynman)
Trying to retrieve CVD header from https://database.clamav.net/main.cvd
main.cvd database is up-to-date (version: 62, sigs: 6647427, f-level: 90, builder: sigmgr)
Trying to retrieve CVD header from https://database.clamav.net/bytecode.cvd
bytecode.cld database is up-to-date (version: 335, sigs: 86, f-level: 90, builder: raynman)
rogue.hdb is up-to-date (version: custom database)    ]         0B/777.50KiB
foxhole_filename.cdb is up-to-date (version: custom database)
foxhole_generic.cdb is up-to-date (version: custom database)
badmacro.ndb is up-to-date (version: custom database)
Time:    2.9s, ETA:    0.0s [========================>]    1.88MiB/1.88MiB
Testing database: '/opt/local/share/clamav/tmp.86fcd5afd7/clamav-2a4c1baf2ec3ad4e9913da0ccef84b48.tmp-scam.ndb' ...
Database test passed.
scam.ndb updated (version: custom database, sigs: 13098)
sanesecurity.ftm is up-to-date (version: custom database)
WARNING: Clamd was NOT notified: Can't connect to clamd through /opt/local/var/run/clamav/clamd.socket: No such file or directory
$ 

Steps to reproduce

Install the latest version on a machine that has Macports-installed ClamAV, and run topgrade. When it reaches updating ClamAV db, observe the failure (shown above).

Possible Cause (Optional)

freshclam not invoked with privilege, which on Macports installation it must.

Problem persists without calling from topgrade

Did you run topgrade through Remote Execution

Configuration file (Optional)

[include]
# paths = ["/etc/topgrade.toml"]

[misc]
# Run `sudo -v` to cache credentials at the start of the run
# This avoids a blocking password prompt in the middle of an unattended run
# (default: false)
pre_sudo = true

# Sudo command to be used
# sudo_command = "sudo"

# Disable specific steps - same options as the command line flag
# disable = ["system", "emacs"]
disable = ["system", "node", "containers", "bin", "gem", "vcpkg", "firmware"]

# Ignore failures for these steps
# ignore_failures = ["powershell"]

# List of remote machines with Topgrade installed on them
# remote_topgrades = ["toothless", "pi", "parnas"]

# Path to Topgrade executable on remote machines
# remote_topgrade_path = ".cargo/bin/topgrade"

# Arguments to pass to SSH when upgrading remote systems
# ssh_arguments = "-o ConnectTimeout=2"

# Arguments to pass tmux when pulling Repositories
# tmux_arguments = "-S /var/tmux.sock"

# Do not set the terminal title (default: true)
# set_title = true

# Display the time in step titles (default: true)
# display_time = true

# Don't ask for confirmations (no default value)
# assume_yes = true

# Do not ask to retry failed steps (default: false)
# no_retry = true

# Run inside tmux (default: false)
# run_in_tmux = true

# Cleanup temporary or old files (default: false)
cleanup = true

# Send a notification for every step (default: false)
# notify_each_step = false

# Skip sending a notification at the end of a run (default: false)
# skip_notify = true

# The Bash-it branch to update (default: "stable")
# bashit_branch = "stable"

# Run specific steps - same options as the command line flag
# only = ["system", "emacs"]

# Whether to self update
#
# this will be ignored if the binary is built without self update support
#
# available also via setting the environment variable TOPGRADE_NO_SELF_UPGRADE)
# no_self_update = true

# Extra tracing filter directives
# These are prepended to the `--log-filter` argument
# See: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives
# log_filters = ["topgrade::command=debug", "warn"]

# Commands to run before anything
[pre_commands]
# "Emacs Snapshot" = "rm -rf ~/.emacs.d/elpa.bak && cp -rl ~/.emacs.d/elpa ~/.emacs.d/elpa.bak"

# Commands to run after anything
[post_commands]
# "Emacs Snapshot" = "rm -rf ~/.emacs.d/elpa.bak && cp -rl ~/.emacs.d/elpa ~/.emacs.d/elpa.bak"

# Custom commands
[commands]
# "Python Environment" = "~/dev/.env/bin/pip install -i https://pypi.python.org/simple -U --upgrade-strategy eager jupyter"
# "Custom command using interactive shell (unix)" = "-i vim_upgrade"
"Haskell" = "stack update && cabal update && hoogle generate"

[python]
# enable_pip_review = true                         ###disabled by default
# enable_pip_review_local = true                   ###disabled by default
# enable_pipupgrade = true                         ###disabled by default
# pipupgrade_arguments = "-y -u --pip-path pip"    ###disabled by default

[composer]
# self_update = true

[brew]
# For the BrewCask step
# If `Repo Cask Upgrade` exists, then use the `-a` option.
# Otherwise, use the `--greedy` option.
# greedy_cask = true

# For the BrewCask step
# If `Repo Cask Upgrade` does not exist, then use the `--greedy_latest` option.
# NOTE: the above entry `greedy_cask` contains this entry, though you can enable
# both of them, they won't clash with each other.
# greedy_latest = true

# For the BrewFormula step
# Execute `brew autoremove` after the step.
# autoremove = true

# For the BrewFormula step
# Upgrade formulae built from the HEAD branch; `brew upgrade --fetch-HEAD`
# fetch_head = true

[linux]
# Arch Package Manager to use.
# Allowed values:
#   autodetect, aura, garuda_update, pacman, pamac, paru, pikaur, trizen, yay
# arch_package_manager = "pacman"

# Arguments to pass yay (or paru) when updating packages
# yay_arguments = "--nodevel"

# Arguments to pass dnf when updating packages
# dnf_arguments = "--refresh"

# aura_aur_arguments = "-kx"

# aura_pacman_arguments = ""
# garuda_update_arguments = ""

# show_arch_news = true

# trizen_arguments = "--devel"

# pikaur_arguments = ""

# pamac_arguments = "--no-devel"

# enable_tlmgr = true

# emerge_sync_flags = "-q"

# emerge_update_flags = "-uDNa --with-bdeps=y world"

# redhat_distro_sync = false

# suse_dup = false

# rpm_ostree = false

# nix_arguments = "--flake"

# nix_env_arguments = "--prebuilt-only"

# Extra Home Manager arguments
# home_manager_arguments = ["--flake", "file"]

[git]
# How many repos to pull at max in parallel
# max_concurrency = 5

# Additional git repositories to pull
# repos = [
#     "~/src/*/",
#     "~/.config/something"
# ]

# Don't pull the predefined git repos
# pull_predefined = false

# Arguments to pass Git when pulling Repositories
# arguments = "--rebase --autostash"

[windows]
# Manually select Windows updates
# accept_all_updates = false

# open_remotes_in_new_terminal = true

# wsl_update_pre_release = true

# wsl_update_use_web_download = true

self_rename = true

[npm]
# Use sudo if the NPM directory isn't owned by the current user
# use_sudo = true

[yarn]
# Run `yarn global upgrade` with `sudo`
# use_sudo = true

[vim]
# For `vim-plug`, execute `PlugUpdate!` instead of `PlugUpdate`
# force_plug_update = true

[firmware]
# Offer to update firmware; if false just check for and display available updates
upgrade = false

[vagrant]
# Vagrant directories
# directories = []

# power on vagrant boxes if needed
# power_on = true

# Always suspend vagrant boxes instead of powering off
# always_suspend = true

[flatpak]
# Use sudo for updating the system-wide installation
# use_sudo = true

[distrobox]
# use_root = false

# containers = ["archlinux-latest"]
[containers]
# Specify the containers to ignore while updating (Wildcard supported)
# ignored_containers = ["ghcr.io/rancher-sandbox/rancher-desktop/rdx-proxy:latest", "docker.io*"]
# Specify the runtime to use for containers (default: "docker", allowed values: "docker", "podman")
# runtime = "podman"

[lensfun]

# use_sudo = false

Additional Details

Verbose Output (topgrade -v)

Probably unnecessary - it's obvious that what's missing is a way to tell topgrade to invoke freshclam under sudo.

SteveLauC commented 2 months ago

How did you install ClamAV, via Homebrew?

mouse07410 commented 2 months ago

How did you install ClamAV, via Homebrew?

No, via Macports: sudo port install clamav.

Update

Shouldn't really matter - all that counts is that in some cases ClamAV installation is owned and run by user (unprivileged), and in other cases (like mine) it runs under either root or _clamav user name. Those latter ones require sudo, which the current topgrade does not provide.

mouse07410 commented 1 month ago

Here's the patch that addressed all of my current issues related to (a) not invoking certain managers or apps (poetry, freshclam) with sudo, and (b) insisting on invocation of tlmgr using full path (/Library/TeX/texbin/tlmgr on MacOS with MacTeX). Please feel free to incorporate it, or do as you see fit.

index 152c721..bfdd3ae 100644
--- a/src/steps/generic.rs
+++ b/src/steps/generic.rs
@@ -668,7 +668,8 @@ pub fn run_tlmgr_update(ctx: &ExecutionContext) -> Result<()> {
     } else {
         let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
         let mut c = ctx.run_type().execute(sudo);
-        c.arg(&tlmgr);
+        //c.arg(&tlmgr);
+        c.arg("tlmgr");
         c
     };
     command.args(["update", "--self", "--all"]);
@@ -969,8 +970,9 @@ pub fn run_certbot(ctx: &ExecutionContext) -> Result<()> {
 /// doc: https://docs.clamav.net/manual/Usage/SignatureManagement.html#freshclam
 pub fn run_freshclam(ctx: &ExecutionContext) -> Result<()> {
     let freshclam = require("freshclam")?;
+    let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
     print_separator("Update ClamAV Database(FreshClam)");
-    ctx.run_type().execute(freshclam).status_checked()
+    ctx.run_type().execute(sudo).arg("-EH").arg(freshclam).status_checked()
 }

 /// Involve `pio upgrade` to update PlatformIO core.
@@ -1020,8 +1022,9 @@ pub fn run_lensfun_update_data(ctx: &ExecutionContext) -> Result<()> {

 pub fn run_poetry(ctx: &ExecutionContext) -> Result<()> {
     let poetry = require("poetry")?;
+    let sudo = require_option(ctx.sudo().as_ref(), REQUIRE_SUDO.to_string())?;
     print_separator("Poetry");
-    ctx.run_type().execute(poetry).args(["self", "update"]).status_checked()
+    ctx.run_type().execute(sudo).arg(poetry).args(["self", "update"]).status_checked()
 }

 pub fn run_uv(ctx: &ExecutionContext) -> Result<()> {
mouse07410 commented 1 week ago

Any update...?

SteveLauC commented 1 week ago

Hi, thanks for the ping, I am too busy with my work so I may ignore replies.

For your change to the freshclam step:

+    ctx.run_type().execute(sudo).arg("-EH").arg(freshclam).status_checked()

Why is -EH needed?


For your poetry issue, is it also installed via Macports? If so, I think you should disable this step and let Macports manage and update it.


For your tlmgr issue, let's discuss it in this thread: #865

mouse07410 commented 1 week ago

For your change to the freshclam step, why is -EH needed?

I think - to pass local env vars. But, honestly, not sure.

For your poetry issue, is it also installed via Macports? If so, I think you should disable this step and let Macports manage and update it.

This is not about updating the poetry itself, which Macports indeed does on its own - it's about updating the stuff that poetry manages, and which Macports can't/won't do by itself.

SteveLauC commented 5 days ago

I think - to pass local env vars. But, honestly, not sure.

If a simple sudo freshclam works in your case, then no.

This is not about updating the poetry itself, which Macports indeed does on its own - it's about updating the stuff that poetry manages, and which Macports can't/won't do by itself.

Makes sense

I need a way to inspect if sudo is needed, a naive solution (for UNIX) is to check the owner of the files that freshclam will modify, then check if the current process is capable of doing that, if not, sudo is needed.

Not sure how to do this on Windows though.