~nskaggs/juju-release-tools/generate-release-notes

207.2.1 by Curtis Hovey
Added script to publish_streams.
1
#!/usr/bin/python
2
3
from __future__ import print_function
4
5
from argparse import ArgumentParser
207.2.3 by Curtis Hovey
Save point.
6
import difflib
207.2.1 by Curtis Hovey
Added script to publish_streams.
7
import os
8
import sys
9
import traceback
207.2.2 by Curtis Hovey
Added get_remote_file.
10
import urllib2
207.2.1 by Curtis Hovey
Added script to publish_streams.
11
12
221.1.1 by Aaron Bentley
Fix lint.
13
__metaclass__ = type
14
15
207.2.10 by Curtis Hovey
simplify the CPCS dict.
16
CPCS = {
17
    'aws': "http://juju-dist.s3.amazonaws.com",
18
    'azure': "https://jujutools.blob.core.windows.net/juju-tools",
19
    'canonistack': (
207.2.8 by Curtis Hovey
Added tests for calls to verify_metadata.
20
        "https://swift.canonistack.canonical.com"
207.2.10 by Curtis Hovey
simplify the CPCS dict.
21
        "/v1/AUTH_526ad877f3e3464589dc1145dfeaac60/juju-dist"),
22
    'joyent': (
23
        "https://us-east.manta.joyent.com/cpcjoyentsupport/public/juju-dist"),
24
    }
207.2.1 by Curtis Hovey
Added script to publish_streams.
25
26
207.2.2 by Curtis Hovey
Added get_remote_file.
27
def get_remote_file(url):
207.2.11 by Curtis Hovey
Updated docstrings.
28
    """Return the content of a remote file."""
207.2.2 by Curtis Hovey
Added get_remote_file.
29
    response = urllib2.urlopen(url)
30
    content = response.read()
31
    return content
32
33
207.2.5 by Curtis Hovey
Added verify_metadata.
34
def diff_files(local, remote):
207.2.11 by Curtis Hovey
Updated docstrings.
35
    """Return the difference of a local and a remote file.
36
37
    :return: a tuple of identical (True, None) or different (False, str).
38
    """
207.2.3 by Curtis Hovey
Save point.
39
    with open(local, 'r') as f:
40
        local_lines = f.read().splitlines()
207.2.5 by Curtis Hovey
Added verify_metadata.
41
    remote_lines = get_remote_file(remote).splitlines()
42
    diff_gen = difflib.unified_diff(local_lines, remote_lines, local, remote)
207.2.11 by Curtis Hovey
Updated docstrings.
43
    diff = '\n'.join(list(diff_gen))
207.2.3 by Curtis Hovey
Save point.
44
    if diff:
45
        return False, diff
46
    return True, None
47
48
207.2.8 by Curtis Hovey
Added tests for calls to verify_metadata.
49
def verify_metadata(location, remote_stream, verbose=False):
207.2.11 by Curtis Hovey
Updated docstrings.
50
    """Verify all the streams metadata in a cloud matches the local metadata.
51
52
53
    This verifies all the streams, not a single stream, to ensure the cloud
54
    has exactly the same metadata as the local instance.
55
    """
207.2.5 by Curtis Hovey
Added verify_metadata.
56
    local_metadata = os.path.join(location, 'tools', 'streams', 'v1')
207.2.8 by Curtis Hovey
Added tests for calls to verify_metadata.
57
    remote_metadata = '{}/tools/streams/v1'.format(remote_stream)
207.2.5 by Curtis Hovey
Added verify_metadata.
58
    if verbose:
59
        print('comparing {} to {}'.format(local_metadata, remote_metadata))
60
    for data_file in os.listdir(local_metadata):
61
        if data_file.endswith('.json'):
62
            local_file = os.path.join(local_metadata, data_file)
63
            remote_file = '{}/{}'.format(remote_metadata, data_file)
64
            if verbose:
65
                print('comparing {}'.format(data_file))
66
            identical, diff = diff_files(local_file, remote_file)
67
            if not identical:
68
                return False, diff
69
    if verbose:
70
        print('All json matches')
207.2.2 by Curtis Hovey
Added get_remote_file.
71
    return True, None
72
73
207.2.1 by Curtis Hovey
Added script to publish_streams.
74
def publish(stream, location, cloud,
75
            remote_root=None, dry_run=False, verbose=False):
207.2.11 by Curtis Hovey
Updated docstrings.
76
    """Publish a stream to a cloud and verify it."""
207.2.8 by Curtis Hovey
Added tests for calls to verify_metadata.
77
    if remote_root:
207.2.10 by Curtis Hovey
simplify the CPCS dict.
78
        remote_stream = '{}/{}'.format(CPCS[cloud], remote_root)
207.2.8 by Curtis Hovey
Added tests for calls to verify_metadata.
79
    else:
80
        remote_stream = CPCS.get(cloud)
81
    verify_metadata(location, remote_stream, verbose=verbose)
207.2.1 by Curtis Hovey
Added script to publish_streams.
82
83
207.2.10 by Curtis Hovey
simplify the CPCS dict.
84
def parse_args(argv=None):
207.2.1 by Curtis Hovey
Added script to publish_streams.
85
    """Return the argument parser for this program."""
86
    parser = ArgumentParser("Publish streams to a cloud.")
87
    parser.add_argument(
207.2.11 by Curtis Hovey
Updated docstrings.
88
        '-d', '--dry-run', action="store_true", help='Do not make changes.')
89
    parser.add_argument(
90
        '-v', '--verbose', action="store_true", help='Increase verbosity.')
91
    parser.add_argument(
92
        '-r', '--remote-root',
207.2.1 by Curtis Hovey
Added script to publish_streams.
93
        help='An alternate root to publish to such as testing or weekly.')
94
    parser.add_argument(
207.2.2 by Curtis Hovey
Added get_remote_file.
95
        'stream', help='The agent-stream to publish.',
207.2.1 by Curtis Hovey
Added script to publish_streams.
96
        choices=['released', 'proposed', 'devel'])
97
    parser.add_argument(
98
        'location', type=os.path.expanduser,
99
        help='The path to the local tree of all streams (tools/).')
100
    parser.add_argument(
101
        'cloud', help='The destination cloud.',
244 by Curtis Hovey
Remove HP from publication.
102
        choices=['streams', 'aws', 'azure', 'joyent', 'canonistack'])
207.2.10 by Curtis Hovey
simplify the CPCS dict.
103
    return parser.parse_args(argv)
207.2.1 by Curtis Hovey
Added script to publish_streams.
104
105
106
def main(argv):
207.2.11 by Curtis Hovey
Updated docstrings.
107
    """Publish streams to a cloud."""
207.2.1 by Curtis Hovey
Added script to publish_streams.
108
    args = parse_args(argv)
109
    try:
110
        publish(
111
            args.stream, args.location, args.cloud,
112
            remote_root=args.remote_root, dry_run=args.dry_run,
113
            verbose=args.verbose)
114
    except Exception as e:
207.2.11 by Curtis Hovey
Updated docstrings.
115
        print('{}: {}'.format(e.__class__.__name__, e))
207.2.1 by Curtis Hovey
Added script to publish_streams.
116
        if args.verbose:
117
            traceback.print_tb(sys.exc_info()[2])
118
        return 2
119
    if args.verbose:
120
        print("Done.")
121
    return 0
122
123
124
if __name__ == '__main__':
125
    sys.exit(main(sys.argv[1:]))