Skip to content

Instantly share code, notes, and snippets.

@thiagokokada
Last active June 9, 2018 05:33
Show Gist options
  • Save thiagokokada/bae4ecd896c77c6a24e0 to your computer and use it in GitHub Desktop.
Save thiagokokada/bae4ecd896c77c6a24e0 to your computer and use it in GitHub Desktop.
Get e-mail notifications of updates in Arch Linux
Auto-upgrade Arch Linux or get e-mail in case of failure.

auto_upgrade

Auto-upgrade Arch Linux or get e-mail in case of failure

Small Python script that tries to update an Arch Linux system (by running pacman -Syu --noconfirm) and send update notifications via e-mail in case of failure. Needs Python >3.5, cower and pacman.

Installation

Firstly, install cower (optional) if you want AUR updates notification. Secondly, open auto_upgrade.py and modify according your necessities (at least you need to modify EMAILand PASSWORD variables). Afterwards, copy auto_upgrade.py to /root (or any other directory with 700 permission for root, so a normal user can't read your password in plain text!) and auto_upgrage.service and auto_upgrade.timer to /etc/systemd/system. Finally enable the timer service by running:

# systemctl enable auto_upgrade.timer

That's it.

#!/usr/bin/python3
import smtplib
import sys
import time
from distutils.spawn import find_executable
from email.mime.text import MIMEText
from socket import gethostname
from subprocess import run, PIPE
# Needs to be a TLS protected SMTP server
SMTP_SERVER = "smtp.gmail.com"
SMTP_PORT = 587
SENDER_EMAIL = "INSERT EMAIL HERE"
SENDER_PASSWORD = "INSERT PASSWORD HERE"
RECEIVER_EMAIL = SENDER_EMAIL
SUBJECT_TEMPLATE = "Updates available in {hostname}"
MSG_TEMPLATE = """
At {time}, there are updates available in {hostname} due to an impossibility to do an auto-upgrade.
{updates}
Login to {hostname} and run:
\t# pacman -Syu
To upgrade the system.
"""
def add_prefix(prefix, text):
result = ""
for line in text.splitlines():
result += prefix + line + "\n"
return result
def do_auto_upgrade(timeout=1800):
packages = ""
try:
run(["pacman", "-Syu", "--noconfirm"], timeout=timeout, universal_newlines=True)
except TimeoutExpired:
result = run(["checkupdates"], stdout=PIPE, universal_newlines=True)
packages += "\nOfficial repositories:\n"
packages += add_prefix("\t:: ", result.stdout)
if find_executable("cower"):
result = run(["cower", "--update", "--color=never"], stdout=PIPE, universal_newlines=True)
if result.stdout:
packages += "\nAUR:\n"
# cower already adds "::" as a prefix
packages += add_prefix("\t", result.stdout)
return packages
def send_email(receiver, sender, password, subject, message):
# Connect to SMTP server
server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
server.ehlo()
server.starttls()
server.login(sender, password)
msg = MIMEText(message)
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receiver
server.send_message(msg)
server.quit()
def main():
available_updates = do_auto_upgrade()
if available_updates:
print("Available updates thanks to a failure to auto-upgrade, sending e-mail to {}".format(RECEIVER_EMAIL))
hostname = gethostname()
send_email(RECEIVER_EMAIL, SENDER_EMAIL, SENDER_PASSWORD,
SUBJECT_TEMPLATE.format(hostname=hostname),
MSG_TEMPLATE.format(time=time.strftime("%c"),
hostname=hostname,
updates=available_updates)
)
else:
print("No available package to upgrage or auto-upgrade successful, not sending e-mail")
sys.exit()
if __name__ == "__main__":
main()
[Unit]
Description=Run auto_upgrade.py script
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /root/auto_upgrade.py
[Install]
WantedBy=multi-user.target
[Unit]
Description=Run auto_upgrade.py daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org>
@Tank-Missile
Copy link

Tank-Missile commented Apr 10, 2017

Not providing a setting to disable auto-upgrades is kind of irritating for someone like me who just wants email notifications. I also would write a PKGBUILD for this script, but every time I would use it the settings would be overwritten since they are tied into the code. Using an external file for settings would be more sufficient. Settings for custom update commands for official repositories and AUR would also be handy. The password could be encrypted through python-keyring or other means for those who don't use keyring. One more thing: email_updates would be a better name for this script if my suggestions were applied.

@EugeneFlash
Copy link

Hello! I use your script "notify_updates". This script is exactly what I need, thanks!!! But I have some ignored packeges in Arch and when there is no updates I recieve notifications too because of [ignored]. Can you tell me how to fix this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment