2
"""Manage pip dependencies for juju qa using a cache in S3."""
4
from __future__ import print_function
11
import boto.s3.connection
17
BUCKET = "juju-qa-data"
18
PREFIX = "pip-archives/"
21
def s3_from_rc(cloud_city):
22
"""Gives authenticated S3 connection using cloud-city credentials."""
23
access_key = secret_key = None
24
with open(os.path.join(os.path.expanduser(cloud_city), "ec2rc")) as rc:
26
parts = line.rstrip().split("=", 1)
27
if parts[0] == "AWS_ACCESS_KEY":
29
elif parts[0] == "AWS_SECRET_KEY":
31
return boto.s3.connection.S3Connection(access_key, secret_key)
34
def run_pip_install(extra_args, verbose=False):
35
"""Run pip install in a subprocess with given additional arguments."""
39
requirements = os.path.join(os.path.dirname(__file__), "requirements.txt")
40
args.extend(["install", "-r", requirements])
41
args.extend(extra_args)
42
subprocess.check_call(args)
45
def command_install(bucket, verbose=False):
46
with utility.temp_dir() as archives_dir:
47
for key in bucket.list(prefix=PREFIX):
48
archive = key.name[len(PREFIX):]
49
key.get_contents_to_filename(os.path.join(archives_dir, archive))
50
run_pip_install(["--user", "--no-index", "--find-links", archives_dir],
54
def command_update(bucket, verbose=False):
55
with utility.temp_dir() as archives_dir:
56
run_pip_install(["--download", archives_dir], verbose=verbose)
57
for archive in os.listdir(archives_dir):
58
key = boto.s3.key.Key(bucket)
59
key.key = PREFIX + archive
60
key.set_contents_from_filename(os.path.join(archives_dir, archive))
63
def command_list(bucket, verbose=False):
64
for key in bucket.list(prefix=PREFIX):
65
print(key.name[len(PREFIX):])
69
"""Parse and return arguments."""
70
parser = argparse.ArgumentParser(
71
prog=argv[0], description="Manage pip dependencies")
72
parser.add_argument("-v", "--verbose", action="store_true",
73
help="Show more output.")
74
parser.add_argument("--cloud-city", default="~/cloud-city",
75
help="Location of cloud-city repository for credentials.")
76
subparsers = parser.add_subparsers(dest="command")
77
subparsers.add_parser("install", help="Download deps from S3 and install.")
78
subparsers.add_parser("update",
79
help="Get latest deps from PyPI and upload to S3.")
80
subparsers.add_parser("list", help="Show packages currently in S3.")
81
return parser.parse_args(argv[1:])
86
s3 = s3_from_rc(args.cloud_city)
87
bucket = s3.get_bucket(BUCKET)
88
if args.command == "install":
89
# XXX: Should maybe not bother requiring S3 creds?
90
command_install(bucket, args.verbose)
91
elif args.command == "update":
92
command_update(bucket, args.verbose)
93
elif args.command == "list":
94
command_list(bucket, args.verbose)
98
if __name__ == "__main__":
99
sys.exit(main(sys.argv))