#!/usr/bin/env python3 """ This mirror status checker determines whether CSC mirror is up-to-date with upstream """ from datetime import datetime, timedelta import requests CSC_MIRROR = "http://mirror.csclub.uwaterloo.ca/" SUCCESS = "Success: {} up-to-date" FAILURE = "Failure: {} out-of-sync" ERROR = "Error: {}\n{}" def get_debian_dt(trace_file_url): """Get Debian datetime object from trace file""" response_text = requests.get(trace_file_url).text time_str = response_text.split('\n')[0] return datetime.strptime(time_str, "%a %b %d %H:%M:%S UTC %Y") def get_kernel_line_count(checksum_file_url): """Get Kernel line count of checksum file""" response_text = requests.get(checksum_file_url).text return len(response_text.split('\n')) def get_openbsd_sec(timestamp_file_url): """Get OpenBSD seconds since the Epoch from timestamp file""" sec_str = requests.get(timestamp_file_url).text return int(sec_str) if __name__ == "__main__": # Arch try: arch_json = requests.get("https://archlinux.org/mirrors/status/json/").json() last_check_str = arch_json["last_check"] last_sync_str = [url for url in arch_json["urls"] if url["url"] == \ f"{CSC_MIRROR}archlinux/"][0]["last_sync"] last_check_dt = datetime.strptime(last_check_str, "%Y-%m-%dT%H:%M:%S.%fZ") last_sync_dt = datetime.strptime(last_sync_str, "%Y-%m-%dT%H:%M:%SZ") # According to https://archlinux.org/mirrors/status/: # Due to the timing of mirror checks, any value under one hour should be viewed as ideal OUTPUT = SUCCESS if last_check_dt < last_sync_dt + timedelta(hours = 1) else FAILURE print(OUTPUT.format("Arch")) except requests.exceptions.RequestException as err: print(ERROR.format("Arch", err)) # Debian try: official_dt = get_debian_dt("https://ftp-master.debian.org/debian/project/trace/master") csc_dt = get_debian_dt(f"{CSC_MIRROR}debian/project/trace/master") # Keep the table cell at https://mirror-master.debian.org/status/mirror-status.html # green and not yellow OUTPUT = SUCCESS if official_dt < csc_dt + timedelta(hours = 7) else FAILURE print(OUTPUT.format("Debian")) except requests.exceptions.RequestException as err: print(ERROR.format("Debian", err)) # Kernel try: official_line_count = get_kernel_line_count( "https://mirrors.edge.kernel.org/pub/linux/kernel/next/sha256sums.asc") csc_line_count = get_kernel_line_count( f"{CSC_MIRROR}kernel.org/linux/kernel/next/sha256sums.asc") # A new update on a certain day adds 2 new lines OUTPUT = SUCCESS if official_line_count <= csc_line_count + 2 else FAILURE print(OUTPUT.format("Kernel")) except requests.exceptions.RequestException as err: print(ERROR.format("Kernel", err)) # OpenBSD try: official_sec = get_openbsd_sec("https://ftp.openbsd.org/pub/OpenBSD/timestamp") csc_sec = get_openbsd_sec(f"{CSC_MIRROR}OpenBSD/timestamp") # Out-of-sync by 1 day maximum OUTPUT = SUCCESS if official_sec < csc_sec + 86400 else FAILURE print(OUTPUT.format("OpenBSD")) except requests.exceptions.RequestException as err: print(ERROR.format("OpenBSD", err))