Automating software upgrades
I’m a big fan of Homeassistant, and have been using it since its early stages. The cool thing with it, is that you can do about anything that you need to base on events (it is basically an event machine). Keeping up to date on software relases, can be a chore. So why not try to automate it?
Here’s how I upgrade some package releases automatically using Homeassistant with a shell command and an ansible playbook.
First I define a sensor, using the rest integration to pull the release version from github (github login required) :
- platform: rest
name: element web release
resource: https://api.github.com/repos/vector-im/element-web/releases/latest
scan_interval: 7200
value_template: '{{ value_json.tag_name }}'
username: !secret github_username
password: !secret github_access_token
authentication: basic
headers:
Accept: application/vnd.github.v3+json
Content-Type: application/json
User-Agent: Home Assistant REST sensor
The automation will trigger on any state change in the sensor, and call the ansible playbook (assuming a predefined boolean switch ‘automatic_updates’ is switched on), and notify a notification platform of any changes:
alias: "upgrade elements on new version"
trigger:
- platform: state
entity_id: sensor.elements_release
variables:
playbook: 'upgrade_elements.yml'
condition:
condition: state
entity_id: input_boolean.automatic_updates
state: "on"
action:
- service: shell_command.run_playbook
data_template:
playbook: "{{ playbook }}"
release: "{{ trigger.to_state.state }}
- service: notify.notify
data:
title: "Upgrade notification"
message: "Running playbook {{ playbook }} New state: {{ trigger.to_state.state }}"
.. Below is the command script which actually executes the ansible playbook. (note: I use fish as my shell). Since Ansible runs on another server, you need to setup password-less login with ssh keys.
#!/usr/bin/fish
set -l playbook $argv[1]
set -l args $argv[2..-1]
if test -z $playbook
exit 0
end
ssh -i /config/.ssh/id_rsa.pub user@server "cd /data/ansible; ansible-playbook $playbook $args"
And here’s my Ansible playbook for this one (only showing the playbook):
- hosts: <your host>
vars:
release: ""
version: "v1.8.2""
target_dir: "/var/www/html"
gather_facts: no
become: true
- name: Download release version
get_url:
url: https://github.com/vector-im/element-web/releases/download/{{ version }}/element-{{ version }}.tar.gz
dest: /tmp
tags:
- download
- name: unarchive
unarchive:
src: "/tmp/element-{{version }}.tar.gz"
dest: /var/www/html
remote_src: yes
creates: "{{ target_dir }}/element-{{ version }}"
tags:
- unarchive
- name: Copy config file
copy:
src: "{{ target_dir }}/element/config.json"
dest: "{{ target_dir }}/element-{{ version }}"
remote_src: yes
tags:
- config
- name: unlink
file:
src: "{{ target_dir }}/element-{{ version }}"
dest: "{{ target_dir }}/element"
state: link
force: yes
This is just one example, but you can add more triggers, to get more packages upgraded in the same automation, with more custom playbooks.
Best,
=Jinxd=