Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
executable file 193 lines (144 sloc) 4.95 KB
#!/usr/bin/python
"""
Runs a squid instance to cache TKLBAM's duplicity archives
Arguments:
<http_port> [hostname:]port (e.g., 3128, 127.0.0.1:33128)
<cachesize> Size of squid cache (can be absolute or relative size)
1000MB - 1000 MBs
2GB - 2000 MBs
50% - 50% of free space in spool location
Environment variables:
TKLBAM_SQUID_CACHE_DIR location of cache dir (default: %s)
TKLBAM_SQUID_USER user under which we execute squid (default: %s)
TKLBAM_SQUID_BIN path to tklbam squid binary (default: %s)
"""
import os
import sys
import string
import statvfs
import re
from executil import system
from temp import TempFile
import pwd
TKLBAM_SQUID_BIN = "/usr/lib/tklbam/deps"
TKLBAM_SQUID_CACHE_DIR = "/var/spool/tklbam-squid"
TKLBAM_SQUID_USER = "proxy"
TKLBAM_SQUID_BIN = "/usr/lib/tklbam/deps/usr/sbin/squid"
TKLBAM_CONF_TPL = \
"""
# autogenerated file, do not edit
cache_dir ufs $CACHE_DIR $CACHE_SIZE 16 256
maximum_object_size $MAXIMUM_OBJECT_SIZE MB
# static
http_port $HTTP_PORT
icp_port 0
acl all src all
acl localhost src 127.0.0.1/32
http_access allow localhost
http_access deny all
cache_mem 0 MB
maximum_object_size_in_memory 0 KB
refresh_pattern -i duplicity.*\.gpg$$ 86400 90% 604800 ignore-auth
cache_log /dev/null
access_log none
cache_store_log none
pid_filename none
netdb_filename none
"""
class Error(Exception):
pass
def get_freespace(path):
stats = os.statvfs(path)
freespace = stats[statvfs.F_BFREE] * stats[statvfs.F_BSIZE]
return freespace
def parse_cache_size(sizestr, cache_dir):
"""Parse cache size string and return the size of the cache in megabytes.
Valid format examples:
100 100 megabytes
50% 50% of free space on cache_dir filesystem
100M 100 megabytes
100MB 100 megabytes
100mb 100 megabytes
10G 10 gigabytes
10GB 10 gigabytes
10gb 10 gigabytes
"""
try:
return int(sizestr)
except ValueError:
pass
m = re.match(r'^(.*)MB?$', sizestr, re.IGNORECASE)
if m:
size = int(m.group(1))
return size + 16 # why 16 extra MB? make room for the cache structure overhead
m = re.match(r'^(.*)GB?$', sizestr, re.IGNORECASE)
if m:
size = int(m.group(1))
return size * 1024
m = re.match(r'^(.*)%$', sizestr, re.IGNORECASE)
if m:
percent = int(m.group(1))
if percent > 100 or percent < 0:
raise Error("bad percent %d%% - should be between 0 and 100" % percent)
return int((get_freespace(cache_dir) * percent / 100.0) / (1024 * 1024))
raise Error("illegal cache_size value '%s'" % sizestr)
def user_exists(user):
try:
pwd.getpwnam(user)
return True
except KeyError:
return False
def is_other_user(user):
if pwd.getpwnam(user).pw_uid == os.getuid():
return False
else:
return True
def usage(e=None):
if e:
print >> sys.stderr, "error: " + str(e)
print >> sys.stderr, "Syntax: %s <http_port> <cache_size>" % sys.argv[0]
print >> sys.stderr, __doc__.strip() % (TKLBAM_SQUID_CACHE_DIR, TKLBAM_SQUID_USER, TKLBAM_SQUID_BIN)
sys.exit(1)
def fatal(e):
print >> sys.stderr, "error: " + str(e)
sys.exit(1)
def main():
args = sys.argv[1:]
if len(args) != 2:
usage("incorrect number of arguments")
user = os.environ.get('TKLBAM_SQUID_USER', TKLBAM_SQUID_USER)
if not user_exists(user):
fatal("no such user '%s'" % user)
cache_dir = os.environ.get('TKLBAM_SQUID_CACHE_DIR', TKLBAM_SQUID_CACHE_DIR)
if os.path.exists(cache_dir):
if not os.path.isdir(cache_dir):
usage("'%s' - not a directory" % cache_dir)
else:
os.makedirs(cache_dir)
os.chmod(cache_dir, 0750)
if is_other_user(user):
pw = pwd.getpwnam(user)
os.chown(cache_dir, pw.pw_uid, pw.pw_gid)
http_port = args[0]
try:
cache_size = parse_cache_size(args[1], cache_dir)
except ValueError:
usage("bad cache_size '%s'" % args[1])
conf_tpl = string.Template(TKLBAM_CONF_TPL)
if cache_size > 2000 and (not sys.maxsize > 2 ** 32):
print >> sys.stderr, "Detected 32-bit system, limiting maximum_object_size to 2000 MB"
maximum_object_size = 2000
else:
maximum_object_size = cache_size
conf = conf_tpl.substitute(HTTP_PORT=http_port,
CACHE_DIR=cache_dir,
CACHE_SIZE=cache_size,
MAXIMUM_OBJECT_SIZE=maximum_object_size)
conf_tmp = TempFile("tklbam-squid-conf-")
file(conf_tmp.path, "w").write(conf)
os.chmod(conf_tmp.path, 0644)
squid_bin = os.environ.get('TKLBAM_SQUID_BIN', TKLBAM_SQUID_BIN)
system("%s -f %s -z" % (squid_bin, conf_tmp.path))
system("%s -f %s -N -D -d 1" % (squid_bin, conf_tmp.path))
if __name__ == "__main__":
main()
Something went wrong with that request. Please try again.