summaryrefslogtreecommitdiff
blob: bf76a9043540457d11d8eb89998ab7e0aedb60e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/python

import urllib2
import time
import rfc822

class GardCheck:
	# Base class which provides some helper functions
	def __init__(self, url):
		self.url = url

	def check_file_exists(self, url):
		ret = True
		try:
			f = urllib2.urlopen(url)
			if len(f.read()) == 0:
				raise IOError
		except:
			ret = False

		return ret

	# Takes the URL to a timestamp.{chk|x} file and returns the
	# corresponding time stamp in seconds
	def _get_timestamp_from_url(self, url):
		try:
			f = urllib2.urlopen(url)
			date = f.read()
			f.close()
			if date is None or len(date) == 0:
				raise ValueError
			try:
				# timestamp.chk format
				ts = self.timestamp_to_secs(date)
			except:
				# timestamp.x format?
				ts = float(date.split(' ')[0])
		except:
			return None

		return ts

	def get_lag(self, path, verbose=False):
		ts = self._get_timestamp_from_url(self.url + path)
		now = time.mktime(time.gmtime())
		if ts is None or now < ts:
			return None
		return now - ts

	def humanize_time(self, secs):
		mins, secs = divmod(secs, 60)
		hours, mins = divmod(mins, 60)
		days, hours = divmod(hours, 24)
    		return '%02d d %02dh %02d m %02d s' % (days, hours, mins, secs)

	def timestamp_to_secs(self, ts):
		return rfc822.mktime_tz(rfc822.parsedate_tz(ts))

	# Override these in child classes

	def check(self):
		return True

	def lag(self):
		return None

# Check distfiles mirrors
class DistfilesCheck(GardCheck):
	def lag(self):
		path = '/distfiles/timestamp.chk'
		return self.get_lag(path)

	def check(self, maxlag, verbose=False):
		# XXX: Replace 'verbose' with a logger object

		lag = self.lag()

		if lag is None:
			print 'ERROR: Could not get distfiles timestamp for ' + self.url
			ret = False
		elif lag > maxlag:
			if verbose is True:
				print 'ERROR: distfiles at %s is lagging\n\tdelta is %s' \
						% (self.url, self.humanize_time(lag))
			ret = False
		else:
			ret = True

		return ret

# Check releases mirrors
class ReleasesCheck(GardCheck):
	def lag(self):
		path = '/releases/.test/timestamp.x'
		return self.get_lag(path)

	def check(self, maxlag, verbose=False):
		# Verify that releases aren't lagging

		lag = self.lag()

		if lag is None:
			print 'ERROR: Could not get releases timestamp for ' + self.url
			ret = False
		elif lag > maxlag:
			if verbose is True:
				print 'ERROR: releases at %s is lagging\n\tdelta is %s' \
						% (self.url, self.humanize_time(lag))
			ret = False
		else:
			ret = True

		# Verify that releases/.test/THIS-FILE-SHOULD-NOT-BE-PUBLIC.txt
		# is not world readable
		if self.check_file_exists(self.url+'releases/.test/THIS-FILE-SHOULD-NOT-BE-PUBLIC.txt'):
			if verbose is True:
				print 'ERROR: THIS-FILE-SHOULD-NOT-BE-PUBLIC.txt is visible on %s' % self.url
			ret = False

		return ret