rpm-software-management/dnf

dnf-automatic(-install).service progress monitoring

MarkBenjamin opened this issue · 3 comments

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

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?

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

$ 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