~andrewjbeach/juju-ci-tools/make-local-patcher

« back to all changes in this revision

Viewing changes to pipdeps.py

  • Committer: Martin Packman
  • Date: 2015-07-01 17:17:53 UTC
  • mto: This revision was merged to the branch mainline in revision 1005.
  • Revision ID: martin.packman@canonical.com-20150701171753-bo4ncv7sbbfzjnie
Add pipdeps tool for installing requirements from s3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
"""Manage pip dependencies for juju qa using a cache in S3."""
 
3
 
 
4
from __future__ import print_function
 
5
 
 
6
import argparse
 
7
import os
 
8
import subprocess
 
9
import sys
 
10
 
 
11
import boto.s3.connection
 
12
import boto.s3.key
 
13
 
 
14
import utility
 
15
 
 
16
 
 
17
BUCKET = "juju-qa-data"
 
18
PREFIX = "pip-archives/"
 
19
 
 
20
 
 
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:
 
25
        for line in rc:
 
26
            parts = line.rstrip().split("=", 1)
 
27
            if parts[0] == "AWS_ACCESS_KEY":
 
28
                access_key = parts[1]
 
29
            elif parts[0] == "AWS_SECRET_KEY":
 
30
                secret_key = parts[1]
 
31
    return boto.s3.connection.S3Connection(access_key, secret_key)
 
32
 
 
33
 
 
34
def run_pip_install(extra_args, verbose=False):
 
35
    """Run pip install in a subprocess with given additional arguments."""
 
36
    args = ["pip"]
 
37
    if not verbose:
 
38
        args.append("-q")
 
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)
 
43
 
 
44
 
 
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],
 
51
            verbose=verbose)
 
52
 
 
53
 
 
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))
 
61
 
 
62
 
 
63
def command_list(bucket, verbose=False):
 
64
    for key in bucket.list(prefix=PREFIX):
 
65
        print(key.name[len(PREFIX):])
 
66
 
 
67
 
 
68
def get_args(argv):
 
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:])
 
82
 
 
83
 
 
84
def main(argv):
 
85
    args = get_args(argv)
 
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)
 
95
    return 0
 
96
 
 
97
 
 
98
if __name__ == "__main__":
 
99
    sys.exit(main(sys.argv))