Add a tiny bit of error handling for health checking
[mirror/dsa-puppet.git] / modules / roles / files / mirror_health / mirror-health
1 #! /usr/bin/python3
2
3 import os
4 import requests
5 import time
6 import calendar
7 import logging
8 from email.utils import parsedate
9 logging.basicConfig(level=logging.INFO)
10
11 HOSTS = os.environ['MIRROR_CHECK_HOSTS'].split()
12 OUTPUT_DIR = "/run/dsa-mirror-health-{}".format(os.environ['MIRROR_CHECK_SERVICE'])
13 HEALTH_FILE = os.path.join(OUTPUT_DIR, "health")
14 URL = os.environ['MIRROR_CHECK_URL']
15 INTERVAL = int(os.environ.get('MIRROR_CHECK_INTERVAL', '60'))
16
17 latest_ts = 0
18
19 def retrieve_from_host(host, url):
20     proxies = {
21         'http': 'http://{}:80'.format(host),
22         'https': 'http://{}:443'.format(host),
23     }
24     return requests.get(url, timeout=5, proxies=proxies, allow_redirects=False)
25
26 def last_modified(response):
27     lm = 0
28     if response.status_code == 200 and response.headers.get('last-modified'):
29         lm = calendar.timegm(parsedate(response.headers['last-modified']))
30     return lm
31
32 while True:
33     start = time.time()
34     for host in HOSTS:
35         try:
36             lm = last_modified(retrieve_from_host(host, URL))
37             logging.debug("lm for host %s: %s", host, lm)
38             if lm > latest_ts:
39                 latest_ts = lm
40         except requests.exceptions.ProxyError:
41             pass
42     local_lm = last_modified(retrieve_from_host('localhost', URL))
43     logging.debug("lm for localhost: %s", local_lm)
44     if local_lm < latest_ts:
45         try:
46             logging.info("considering myself unhealthy my ts=%s latest_ts=%s", local_lm, latest_ts)
47             os.remove(HEALTH_FILE)
48         except OSError:
49             pass
50     else:
51         logging.info("considering myself healthy")
52         open(HEALTH_FILE, 'w').write("OK")
53     sleep_time = start + INTERVAL - time.time()
54     logging.debug("sleeping for %d seconds", sleep_time)
55     time.sleep(sleep_time)