This is for Debian/Ubuntu flavored systems.
Keep a single server up to date is easy, but updating multiple servers at once, you need tools like Ansible . For each server, here is a list of basic steps:
Check if there are packages available to be upgraded
Upgrade all packages to the latest version
Check if a reboot is required
Reboot the server
When we log into the remote server, we might see the message showing the number of packages can be updated. The message is generated by:
1
2
3
4
$ sudo /usr/lib/update-notifier/update-motd-updates-available
25 packages can be updated.
18 updates are security updates.
And it is available at:
1
2
3
4
$ cat /var/lib/update-notifier/updates-available
25 packages can be updated.
18 updates are security updates.
We don’t need that detailed information, we just simply want to know if there are update available.
Shell script /usr/lib/update-notifier/apt-check
shows any pending updates:
1
2
$ /usr/lib/update-notifier/apt-check
25 ;18
To list all the packages instead of simple packages;security
format:
1
$ /usr/lib/update-notifier/apt-check --package-names
--package-names
option will write data to stderr
instead of stdout
. If there are no packages needed to be installed, then the stderr
should be empty.
If there are packages to be installed or upgraded. Ansible has the apt module to manage them in Debian/Ubuntu based systems.
1
2
3
4
5
6
7
- name: Check if there are packages available to be installed/upgraded
command: /usr/lib/update-notifier/apt-check --package-names
register: packages
- name: Upgrade all packages to the latest version
apt: update_cache=yes upgrade=dist
when: packages.stderr != ""
When a reboot is required in Debian/Ubuntu systems, the file /var/run/reboot-required
will be present.
1
$ test -e /var/run/reboot-required && echo 'Reboot required'
Therefore, we can simply check the file, and reboot the system.
The difference is also captured here:
1
2
3
4
5
$ uname -r
3.2 .0 -67 -virtual
$ cat /var/run/reboot-required.pkgs
linux-image-3.2 .0 -68 -virtual
linux-base
Therefore, these two packages are present if requiring a reboot:
1
2
/var/run/reboot-required
/var/run/reboot-required.pkgs
After reboot, these two files will be removed. Both files are updated by this shell script:
1
/usr/share/update-notifier/notify-reboot-required
So, the playbook can be written as:
1
2
3
- name: Check if a reboot is required
register: file
stat: path=/var/run/reboot-required get_md5=no
The registered file stat looks like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
"atime ": 1410212575.8964653 ,
"ctime ": 1410212506.3324652 ,
"dev ": 15 ,
"exists ": true ,
"gid ": 0 ,
"inode ": 2336609 ,
"isblk ": false ,
"ischr ": false ,
"isdir ": false ,
"isfifo ": false ,
"isgid ": false ,
"islnk ": false ,
"isreg ": true ,
"issock ": false ,
"isuid ": false ,
"mode ": "0644" ,
"mtime ": 1410212506.3324652 ,
"nlink ": 1 ,
"pw_name ": "root" ,
"rgrp ": true ,
"roth ": true ,
"rusr ": true ,
"size ": 32 ,
"uid ": 0 ,
"wgrp ": false ,
"woth ": false ,
"wusr ": true ,
"xgrp ": false ,
"xoth ": false ,
"xusr ": false
}
We can see the file exists ("exists": true
), hence reboot is needed:
1
2
3
- name: Reboot the server
command: /sbin/reboot
when: file.stat.exists == true
In summary, adding the reboot tasks and putting them all together in an Ansible playbook task file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
---
- name: Check if there are packages available to be installed/upgraded
command: /usr/lib/update-notifier/apt-check --package-names
register: packages
- name: Upgrade all packages to the latest version
apt: update_cache=yes upgrade=dist
when: packages.stderr != ""
- name: Check if a reboot is required
register: file
stat: path=/var/run/reboot-required get_md5=no
- name: Reboot the server
command: /sbin/reboot
when: file.stat.exists == true
The only problem is that when the reboot
is issued, the command exits, and the system is yet to go down for reboot right away. Any tasks after that will continue to be run. Therefore, it is not a good idea to add more tasks after the reboot task.