123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- #! /usr/bin/env python3
- """
- This script checks for available updates on Void Linux using xbps and notifies
- the configured administrator account about them. It currently requires
- python 3.x and no additional packages and is supposed to be run with cron or
- another scheduled execution mechanism.
- """
- import subprocess
- import smtplib
- import socket
- import re
- from email.mime.multipart import MIMEMultipart
- from email.mime.text import MIMEText
- # Email server to be used to send the notification
- ADMIN_EMAIL = "root"
- # Mail server to be used to send the notification
- MAIL_SERVER = "localhost"
- # Port to use on the mail server
- MAIL_SERVER_PORT = 25
- # User name to log in to the mail server
- MAIL_SERVER_USER = ""
- # Password to log in to the mail server
- MAIL_SERVER_PASSWORD = ""
- AVAILABLE_UPDATES = []
- DEVNULL = open("/dev/null", "w")
- try:
- XBPS_INSTALL_RESULT = subprocess.check_output(["xbps-install", "-Sun"],
- stderr=DEVNULL)
- except subprocess.CalledProcessError:
- pass
- else:
- XBPS_INSTALL_RESULT = XBPS_INSTALL_RESULT.decode("utf-8").split("\n")
- for line in XBPS_INSTALL_RESULT:
- if "update" in line:
- try:
- package = line.split(" ")[0]
- package_regex = "^([A-Za-z0-9-]*)-([0-9].*_[0-9])$"
- match_object = re.match(package_regex, package)
- package_name = match_object.groups()[0]
- new_package_version = match_object.groups()[1]
- except IndexError:
- continue
- else:
- try:
- xbps_query_result = subprocess.check_output(
- ["xbps-query", "--show", package_name], stderr=DEVNULL)
- except subprocess.CalledProcessError:
- pass
- else:
- xbps_query_result = xbps_query_result.decode(
- "utf-8").split("\n")
- for line in xbps_query_result:
- if "pkgver" in line:
- installed_package = line.split(
- ":")[1].strip()
- match = re.match(package_regex,
- installed_package)
- installed_package_version = match.groups()[1]
- package_update = {
- "name": package_name,
- "new_version": new_package_version,
- "old_version": installed_package_version,
- }
- AVAILABLE_UPDATES.append(package_update)
- break
- if AVAILABLE_UPDATES:
- HOSTNAME = socket.getfqdn()
- MSG = MIMEMultipart()
- MAIL_TEXT = "The following package updates are available on host %s:\n\n"\
- % HOSTNAME
- MSG["Subject"] = "%s updates available on host %s"\
- % (len(AVAILABLE_UPDATES), HOSTNAME)
- MSG["From"] = "voixicron@%s" % HOSTNAME
- MSG["To"] = ADMIN_EMAIL
- for update in AVAILABLE_UPDATES:
- MAIL_TEXT += "%s (%s -> %s)\n"\
- % (update["name"],
- update["old_version"],
- update["new_version"])
- MSG_TEXT = MIMEText(MAIL_TEXT.encode("utf-8"), _charset="utf-8")
- MSG.attach(MSG_TEXT)
- SERVER_CONNECTION = smtplib.SMTP(MAIL_SERVER, MAIL_SERVER_PORT)
- try:
- SERVER_CONNECTION.connect()
- except (smtplib.SMTPConnectError, smtplib.SMTPServerDisconnected,
- socket.error):
- pass
- else:
- try:
- SERVER_CONNECTION.starttls()
- except smtplib.SMTPException:
- pass
- if MAIL_SERVER_USER:
- try:
- SERVER_CONNECTION.login(MAIL_SERVER_USER, MAIL_SERVER_PASSWORD)
- except smtplib.SMTPAuthenticationError:
- pass
- except smtplib.SMTPException:
- pass
- try:
- SERVER_CONNECTION.sendmail("voixicron@%s" % HOSTNAME, ADMIN_EMAIL,
- MSG.as_string())
- except smtplib.SMTPRecipientsRefused:
- pass
- except smtplib.SMTPSenderRefused:
- pass
- else:
- SERVER_CONNECTION.quit()
- DEVNULL.close()
|