Tuesday, 11 February 2014

SUSE: How to install only security patches

There appears to be no native method in SuSe Linux for installing only security patches. This is a problem when dealing with customers who like things to remain stable, adding features adds entropy and makes it harder to determine the root of what's caused your system to crash in the middle of the night.

On Red Hat, it's easy! Just make sure you have the yum-security plugin installed:

 # yum install yum-security

Check for security updates:

 # yum --security check-update  

And then apply them:

 # yum --security update  


This will update any packages that have security advisories marked against them. Easy right? Well, we're not here to do things the easy way!

In SuSe, you can also use Yast for updates and select the security options tab and install those only. From the command line it's not so easy but then you can't automate GUI tasks. What we need to do here is a bit of scripting to work out a one liner to do the same job.

Using zypper, SuSe's command line update manager, let's list the patches that are available (just a snippet below):

 linux-8nb5:~ # zypper lp  
 Loading repository data...  
 Reading installed packages...  
 Repository                   | Name              | Version | Category    | Status | Summary  
 -----------------------------+-------------------+---------+------------+--------+--------------------------------------------------------------------------  
 openSUSE-13.1-Update         | openSUSE-2013-984 | 1       | recommended | needed | gmime: Update to 2.6.19  
 openSUSE-13.1-Update         | openSUSE-2013-985 | 1       | recommended | needed | yast2: fixed reading bridge configuration  
 openSUSE-13.1-Update         | openSUSE-2013-991 | 1       | recommended | needed | libmtp: update current device list  
 openSUSE-13.1-Update-Non-Oss | openSUSE-2013-992 | 1       | security    | needed | update for flash-player  
 openSUSE-13.1-Update         | openSUSE-2014-104 | 1       | recommended | needed | folks: fix empathy-crash when using IRC channels  
 openSUSE-13.1-Update         | openSUSE-2014-105 | 1       | recommended | needed | clutter: Update to 1.16.4  
 openSUSE-13.1-Update         | openSUSE-2014-107 | 1       | recommended | needed | sysstat: rename nfsiostat to avoid a name collision with nfs-utils  
 openSUSE-13.1-Update-Non-Oss | openSUSE-2014-109 | 1       | security    | needed | flash-player: security update to 11.2.202.336  


Ok, so we can see there that there are some patches listed there that are in the security category. We can use awk to grab those, note they are in the 4th column  but awk will grab these with the "$7" token because it sees the pipe symbol as a valid token. We could escape the pipe character I suppose, but it will make the command longer for no real gain, so we'll stick with $7.

Let's test this:

 linux-8nb5:~ # zypper lp | awk ' { print $7 }'  
 Category  
 recommended  
 security  
 recommended  
 recommended  
 recommended  
 security  
 security  

Ok, we're getting the correct section (the Catgory column) but we're only interested in the security patches. More work is needed. Let's try to match the security only.

 linux-8nb5:~ # zypper lp | awk ' $7=="security" { print $7 }'  
 security  
 security  
 security  
 security  

Right, this is looking more like it. But we can't just install anything from this, this is useless I hear you mutteirng. Let's forge ahead with more awk.

If $7 matches the category, we can see that $3 will be the name of the patch that we want to apply should we be able to match them. Let's have a go:


 linux-8nb5:~ # zypper lp | awk ' $7=="security" { print $3 }'  
 openSUSE-2013-992  
 openSUSE-2014-109  
 openSUSE-2014-114  
 openSUSE-2014-78  

Ok, this looks better. Breaking down the command, we are listing patches with $7 that match the "security" string and then printing the name of the patch using $3. So we can see that these are the patches we want to install, we're getting there now. Can we get zypper to install them from a single command? Of course we can, this is Linux!

We're going to need to install these patches by name if we're using the output from awk. Helpfully we can do that with "-n" or "--name":

 -n, --name         Select packages by plain name, not by capability.  


Since we're using zypper and listing patches with the "lp" option let's continue to work with patches, using zypper's help (not man page) we can see that we will need to use -t option:

 -t, --type <type>      Type of package (package, patch, pattern, product, srcpackage).  


To use this command normally, one might use something along the lines of:


 linux-8nb5:~ # zypper install -n -t patch openSUSE-2014-78  
 Loading repository data...  
 Reading installed packages...  
 Resolving package dependencies...  
 The following NEW patch is going to be installed:  
  openSUSE-2014-78   
 The following 2 packages are going to be upgraded:  
  flash-player flash-player-gnome   
 2 packages to upgrade.  
 Overall download size: 5.1 MiB. No additional space will be used or freed   
 after the operation.  
 Continue? [y/n/? shows all options] (y):   

But because we want to use awk to extract all of the names of the patches from the security category for us, we'll need to roll it all up together:


 linux-8nb5:~ # zypper lp | awk '$7=="security" { print "zypper install -n in -t patch "$3}'  
 zypper install -n in -t patch openSUSE-2013-992  
 zypper install -n in -t patch openSUSE-2014-109  
 zypper install -n in -t patch openSUSE-2014-114  
 zypper install -n in -t patch openSUSE-2014-78  

Well, I guess we're getting closer. We need to have these commands executed by the shell, not printed out as text. So let's pipe the output back to the shell and execute it.

And here it is, our final working command:

 linux-8nb5:~ # zypper lp | awk '$7=="security" { print "zypper install -n -t patch "$3}' | sh +x 

Loading repository data...
Reading installed packages... 
Resolving package dependencies... 

The following NEW patch is going to be installed: 
openSUSE-2013-992 

The following 2 packages are going to be upgraded: 
flash-player flash-player-gnome 

2 packages to upgrade. Overall download size: 5.1 MiB. No additional space will be used or freed after the operation.  

If you've got any upgrades, such as flash-player in the above example, you'll need to "zypper up" and sort them out separately in order to agree with the licenses associated with them. After that, run the command again and it should run through successfully. Perhaps it would be useful to put this in as a cron job and have this command run every night. I hope you find this command useful.

No comments:

Post a Comment