rpm-software-management / dnf

Package manager based on libdnf and libsolv. Replaces YUM.
GNU General Public License v2.0
1.23k stars 409 forks source link

dnf-automatic(-install).service progress monitoring #2068

Closed MarkBenjamin closed 6 months ago

MarkBenjamin commented 6 months ago

Hi,

When I # dnf update --refresh I see progress of downloads, that is helpful when my connection is patchy / to see how large of a download the update involves, while it is happening, when it kind of matters (rather than needing to wait until it is finished, when it becomes more academic)

I try to simplify / automate the updates to some degree (allowing my non-root user to call dnf only for updates) ; however, even a fork()/exec() c program with setuid/setgid seems to run into difficulty when dnf calls what must be a gpg script, to verify signatures for particular repos such as virtualbox or skype; as a result of the way systemctl works, that method (fork()/exec() c program with setuid/setgid) seems to allow those repos to update without errors, when the exec() call is to systemctl start dnf-automatic-install.service

The only trouble is, that it won't show me very helpful progress; there is of course systemctl status as well as journalctl although those are a combination of brief/vanishing messages (systemctl statusCGroup messages) or after-the-event summaries (installed/upgraded/removed packages listed at journalctl) similarly to what the emitters give me

It should be possible to connect to the progress messaging during dnf-automatic similarly to the interactive cli progress messaging during dnf upgrade/update; possibly needing a socket/screen or similar specified in a config, or for instance a data object (such as JSON) sent to a progress callback script specified in the config?

Of course there are less secure alternatives such as passwordless sudo or similar, that I'd rather avoid too

MarkBenjamin commented 6 months ago

Alright a relatively simple change/fix for a good start to provide a little more information to journalctl at least (dnf/automatic/main.py, in main())

            lst = output.list_transaction(trans, total_width=80)
            emitters = build_emitters(conf)
            emitters.notify_available(lst)
            if not conf.commands.download_updates:
                emitters.commit()
                return 0
            print(_("Downloading updates"))
            print(lst)

            base.download_packages(trans.install_set)
            emitters.notify_downloaded()
            if not conf.commands.apply_updates:
                emitters.commit()
                return 0
            print(_("Downloaded"))

            gpgsigcheck(base, trans.install_set)
            base.do_transaction()

The more advanced fix leverages a/the StdIoEmitter for that, rather than simply print(), while adding a progress CommandEmitter (plus config changes) to handle actual progress callbacks.

My thinking is that a progress CommandEmitter is possibly a better option than the alternatives, making it the user's responsibility how precisely to handle (listening for / actioning) progress reports. Would that accord with your opinions, is it worthwhile working at?

MarkBenjamin commented 6 months ago

verbose_stdio.PATCH adds a config option verbose_stdio, default False, to the [emitters] in automatic.conf would need the documentation updating too

Future work maybe a fork/PR for the command callback / progress

MarkBenjamin commented 6 months ago
$ echo -e "alias up='sudo /root/bin/dnf_update'\n" >> $HOME/.bashrc
$ su -
# mkdir -p /root/bin
# echo -e '#!/bin/sh\n\ndnf update --refresh\n' > /root/bin/dnf_update
# chmod 740 /root/bin/dnf_update
# visudo

then add

<user_name>    ALL=(ALL)       NOPASSWD: /root/bin/dnf_update