Yum Updates Daemon for XFCE

Noah Petherbridge
kirsle
Posted by Noah Petherbridge on Monday, June 04 2012 @ 10:09:36 AM

Update (5/28/13): I've ported this script over to Python: pyupdatesd. The Python version only requires pygtk2, which tends to come preinstalled on Fedora XFCE systems.


Since about three versions of Fedora ago, there wasn't an updates daemon for the XFCE desktop environment (or LXDE or the others, for that matter). KDE still had theirs, and Gnome 3's update daemon was built in to the desktop environment. So, XFCE users were stuck having to look for updates manually.

Not anymore!

I finally got around to writing a Perl script that checks for available updates, and shows a Gtk2 tray icon and a notification pop-up when one has been found. You can set it to start up automatically in your session settings and it will check updates for you every 15 minutes.

kupdatesd screenshot

You can get it from http://sh.kirsle.net/kupdatesd. Or you can see its source code here. :)

#!/usr/bin/perl

# kupdatesd - A simple yum update checker.
#
# This script will watch for available yum updates and show a GTK+ TrayIcon
# and notification pop-up when updates become available.
#
# This is intended for desktop environments like XFCE that don't have a native
# PackageKit update watcher.
#
# Set this script to run on session startup and it will check for updates every
# 5 minutes (by default; this is configurable in the source code).
#
# --Kirsle
# http://sh.kirsle.net

use 5.14.0;
use strict;
use warnings;
use Gtk2 -init;
use Gtk2::TrayIcon;
use Gtk2::Notify -init, "kupdatesd";

################################################################################
# Configuration Section                                                        #
################################################################################

my %c = (
    # The title to be shown on the pop-up and the icon tooltip.
    title    => "Updates Available",

    # The message to be shown in the pop-up.
    message  => "There are updates ready to install.",

    # The icon to use for the pop-up and tray icon.
    icon     => '/usr/share/icons/gnome/32x32/status/software-update-available.png',

    # How often to check for updates (in seconds).
    interval => 900,

    # The path to your yum binary.
    yum      => '/usr/bin/yum',

    # The path to your graphical updater.
    # gpk-update-viewer is provided by gnome-packagekit
    gui      => '/usr/bin/gpk-update-viewer',
);

################################################################################
# End Configuration Section                                                    #
################################################################################

# Gtk objects
my ($icon, $image, $eventbox, $tooltip, $notify);
my $visible = 0; # Icon is currently being displayed?

# Enter the main loop.
my $check = time() + $c{interval};
while (1) {
    select(undef,undef,undef,0.1);

    # Keep Gtk2 active.
    if (defined $icon) {
        Gtk2->main_iteration while Gtk2->events_pending;
    }

    if (time() > $check) {
        # Look for updates.
        unless ($visible) {
            system("$c{yum} check-update > /dev/null 2>&1");
            if ($? >> 8 == 100) {
                say "There are updates available!";
                show_icon();
            }
        }

        # Queue another check.
        $check = time() + $c{interval};
    }
}

sub show_icon {
    # Already initialized this once before?
    if (defined $icon) {
        # Just show the icon and notification again.
        $icon->show_all;
        $notify->show;
        $visible = 1;
        return;
    }

    # Tray icon. Image goes in EventBox, EventBox goes inside TrayIcon.
    $icon = Gtk2::TrayIcon->new("kupdatesd");
    $image = Gtk2::Image->new_from_file($c{icon});
    $eventbox = Gtk2::EventBox->new;
    $eventbox->add($image);
    $icon->add($eventbox);
    $icon->show_all;

    # Attach the tooltip.
    $tooltip = Gtk2::Tooltips->new;
    $tooltip->set_tip($icon, $c{title});

    $eventbox->signal_connect("button_press_event", sub {
        $icon->hide;
        $visible = 0;
        system($c{gui});
    });

    $notify = Gtk2::Notify->new(
        $c{title},
        $c{message},
        $c{icon},
    );
    $notify->show;
    $visible = 1;
}

Categories:

[ Blog ]

Comments

There are 15 comments on this page.

guest
guest
Posted on Friday, July 20 2012 @ 07:32:57 PM by Matt B.

Works great!

guest
guest
Posted on Wednesday, February 13 2013 @ 05:25:09 PM by Peter Ajamian.

Great tool, thanks for this.

One thing I noticed is that with the main loop running so often (1000 times per second) this daemon uses quite a bit of CPU. It's the first entry in "top" and eats up 2.0-2.4% of the CPU on my laptop. I found that changing the fourth arg to the select from 0.001 to 0.1 fixes this issue nicely, and it won't affect the responsiveness of the app noticeably. The CPU usage is now down to 0.3% and it has fallen off of the "top" list entirely.

guest
guest
Posted on Friday, February 15 2013 @ 03:00:16 PM by Peter Ajamian.

Actually with the change CPU is at 0.0% (negligible) now and responsiveness seems just fine. Other than needing to make this minor change the script is fantastic, thanks.

Avatar
kirsle
Posted on Friday, February 15 2013 @ 03:02:02 PM by Noah Petherbridge.

I've fixed the source code to have a 0.1s delay in the main loop. :)

guest
guest
Posted on Wednesday, February 20 2013 @ 03:55:30 PM by james.

can you let me know what dependencies I would need to make this work? I am running lxde spin of Fedora 17. Would I need all the gnome dependencies to use gtk? or just gtk2?

Avatar
kirsle
Posted on Wednesday, February 20 2013 @ 04:41:50 PM by Noah Petherbridge.

I don't think you'll need all the Gnome dependencies. LXDE uses GTK+ for its GUIs so you should already have that.

On a fresh install of Fedora's XFCE spin, I only need to do this to get this script to work:

$ sudo yum install perl-Gtk2 perl-Gtk2-TrayIcon perl-Gtk2-Notify

guest
guest
Posted on Friday, February 22 2013 @ 11:01:30 AM by james.

Hi thanks for that. I've installed it using systemctl, having written the following service file and placed it in /usr/lib/systemd/system:

[Unit]
Description=Automatic updates daemon instance

[Service]
ExecStart=/usr/lib/kupdatesd
GuessMainPID=no
Type=forking
Restart=on-abort
Environment=DISPLAY=:0
[Install]
WantedBy=multi-user.target

This has root as owner and group and rwx perms for root and rx for group and world. I used systemctl enable kupdatesd.service and it is running ok when I start up but I am getting no physical presence, no updates being checked and although ps -A shows the script as present and systemctl status reports no problems, top shows no indication that the script is running. Any ideas? Many thanks.

guest
guest
Posted on Friday, February 22 2013 @ 11:08:32 AM by james.

Doh! I just realised that I didn't have gpk-package-viewer installed! I've now installed it and will try it again. Is it not going to consume a lot of resources checking every 0.1 seconds? I was thinking that I'd like to get it to check on start up (just once). I think I'll exit after the loop has run for a few minutes.

guest
guest
Posted on Friday, February 22 2013 @ 11:12:23 AM by james.

doh again! every 5 minutes the check is made.

Avatar
kirsle
Posted on Friday, February 22 2013 @ 11:23:11 AM by Noah Petherbridge.

You could probably change the sleep interval to something more reasonable like 5 minutes.

I tend to leave my computer running 24/7 until it gets a kernel update, so multiple different sets of updates can come in during one period of time between reboots. So that's why I programmed it to run constantly and check updates now and then.

guest
guest
Posted on Friday, February 22 2013 @ 02:54:25 PM by james.

sorry for this but I'd be grateful if you could help. I have been trying to add the updates daemon script so that it starts when a user logs in but my inexperience with fedora has left me drawing a blank. I tried systemd, but was faced with all sorts of problems finding relevant examples and documentation in a language I understand with regards to the --user part. I managed to get it working for a user with root access, but as it was running in root the script couldn't access the display:0. I tried chkconfig with an initscript and adding use Proc::Daemon to the update script but this just leads to similar problems (plus it can't load the Proc::Daemon module. I don't think I can run it as a login script, so I am stuck. Can you help? Many thanks.

Avatar
kirsle
Posted on Friday, February 22 2013 @ 03:03:00 PM by Noah Petherbridge.

You shouldn't have to involve systemd or anything.

On my XFCE desktop, I just went to my Session Preferences -> Application Autostart, and added it there. Does LXDE have something similar?

What XFCE does on the back-end is creates a .desktop launcher in ~/.config/autostart, so you should be able to create one yourself that should work in all desktop environments.

$ cat $HOME/.config/autostart/kupdatesd.desktop
[Desktop Entry]
Encoding=UTF-8
Version=0.9.4
Type=Application
Name=kupdatesd
Comment=
Exec=/home/kirsle/bin/kupdatesd
OnlyShowIn=XFCE;
StartupNotify=false
Terminal=false
Hidden=false

guest
guest
Posted on Friday, February 22 2013 @ 03:55:08 PM by Peter Ajamian.

I am thinking about creating an rpm package for this, should be fairly easy, I'll let you know if I do.

guest
guest
Posted on Wednesday, June 12 2013 @ 08:11:07 AM by Peter Ajamian.

I've now packaged this for Fedora 17 and 18. If anyone is interested they can get the rpm from my repository at http://www.pajamian.dhs.org/repos/fedora/18/safe/ (or 17 for F17).

Peter

Avatar
guest
Posted on Monday, June 30 2014 @ 07:48:36 AM by Jason.

I installed your updated script and it's working perfectly on Fedora 19.

Thank you very much!

Add a Comment

Your name:
Your Email:
Message:
Comments can be formatted with Markdown, and you can use
emoticons in your comment.

If you can see this, don't touch the following fields.