Distribute updates from server to pool computers (hacky way)

This is the crowning achievement of my days at the MINT computer pool. Sadly, by the time I write this post, it will all be deleted. So here it is, archived for posterity.

The setting is a typical computer pool setting. 24 computers and one server. All computers load their home directories from the server (see here). Otherwise, each computer is totally independent. The idea is now, that updates to the pool computers can also be distributed from the server. So that I don’t have to sit down at each computer and execute a script which is a real pain. Again, a really common problem and many solutions exist – but I made my own, hacky, one.

Setting up the server side of things is easy. Basically, we create a few folders and put one shell script in the home of a special user called admin. There is a folder /home/admin/poolsetup/script into which we put a script poolupdate.sh. You can get the script from my wkutils github repository. This script goes through all files in another folder, /home/admin/poolsetup/updates, and executes any scripts it finds in there. It redirects the outputs of the execution into a log file in the folder /home/admin/poolsetup/logs. We can use this file to check what happened. And the update script uses the log file to avoid executing scripts twice. If a log file for a given script exists, we don’t execute the script again.

Because the home directories are loaded from the server, each pool computer will have access to files in the home directory of admin. We don’t have to do any copying to distribute the update script to the pool computers and any changes to the script will take effect right away.

So here are the commands for the server setup – basically just create the necessary folder structure with the correct permissions and put the update script there:

mkdir /home/admin/poolsetup/script
mkdir /home/admin/poolsetup/updates
mkdir /home/admin/poolsetup/logs
chmod o+rx /home/admin/poolsetup/script
chmod o+rx /home/admin/poolsetup/updates
chmod o+rwx /home/admin/poolsetup/logs
wget https://github.com/Kaffeedrache/wkutils/blob/master/admin/poolupdate.sh
mv poolupdate.sh /home/admin/poolsetup/script
chmod o+rx /home/admin/poolsetup/script/poolupdate.sh

On client side, we only have to make the computer execute the update script on a regular basis. We use cron and therefor call crontab which manages the cron jobs:

crontab -e

In the editor, we add these two lines:

00 17 * * 5 bash /home/admin/poolsetup/script/poolupdate.sh
@reboot bash -c "while [[ ! -d /home/admin/ ]] ; do sleep 5; done" ; bash /home/admin/poolsetup/script/poolupdate.sh

The first line will execute the update script every Friday at 5 PM. The second line will execute the script at every system start. We need the ugly loop with the sleep to ensure that the home directories have been mounted, before trying to access them.

So how does making an update work now? Write a script that does what you want to do. Put this script into the folder /home/admin/poolsetup/updates. When a pool computer starts up, it will execute the script. After that, look into the log folder and read the corresponding log to see what has happened. When all computers execute the update, usually you need to read only one log file and then check if all other log files have the same size. Done!

Setting computer time from the internet [hacky way]

Most of my pool computers show the wrong time and most of them are different. Just for fun, here are the times shown by those running at the moment of the poll:

8:36 (2x), 8:40, 9:36 (2x), 10:35, 10:36 (3x), 10:39 (6x), 11:36 (2x), 11:40

I assume it is the result of setting the time wrong in the installation and then a few semesters of trying to fix some of them (those running at the moment, the first three rows, until the admin was bored, a single one now and then, …), adjusting to daylight savings time or forgetting it and so on.

So this is what I tried to get them back on track (courtesy of AskUbuntu.com):

sudo date -s "$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z"

The line first gets a random web page (here google.com) and prints the header of the HTTP response, e.g.,:

  HTTP/1.1 302 Found
  Cache-Control: private
  Content-Type: text/html; charset=UTF-8
  Referrer-Policy: no-referrer
  Location: http://www.google.de/?gfe_rd=cr&dcr=0&ei=mVYyWqvyKNHPXuKYpeAP
  Content-Length: 266
  Date: Thu, 14 Dec 2017 10:46:49 GMT

The line then retrieves the part of the response with the date using grep. It splits the line with the date at spaces with cut -d ' ' and uses the parts 5 to 8. In this line, part 4 is the day of the week, part 3 is the text Date: and parts 1-2 are empty because of the leading spaces. So using parts 5 to 8 results in a date and time in a format that the tool date can understand. Before passing the time on to date, the letter Z is appended. This Z stands for UTC, meaning the time zone set on the computer will be taken into account.

So the line after evaluating wget, grep and cut for the example page we got will be:

sudo date -s "14 Dec 2017 10:46:49Z"

The option -s sets the date to the specified value. So if the request ran in a reasonable time, we should have a reasonably accurate time set for the computer.

PS: Yes, I know that there is such a thing as NTP and I know that time synchronization is not a problem that you need to hack on your own. But this version is much more freaky and cool!! [Also NTP and the university firewall don’t seem to be friends]