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

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
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/python

from __future__ import print_function

from argparse import ArgumentParser
import os
import sys

from launchpadlib.launchpad import Launchpad

# Juju devel versions
DEVEL = 'devel'
# Juju supported versions
PROPOSED = 'proposed'
STABLE = 'stable'
# Ubuntu supported versions
PROPOSED_1_22 = '1.22-proposed'
SUPPORTED_1_22 = '1.22'
PROPOSED_1_25 = '1.25-proposed'
SUPPORTED_1_25 = '1.25'


def get_archives(lp, to_archive_name):
    """Return the archives used in the copy.

    The build archives are private and owned by a different team than the
    public archives. The policy for building and copying is:
    1. Always build in private PPAs because the client cannot be made public
       before the tools made from the client package.
    2. Devel packages are built in a separate PPA from stable packages
       because devel can change the archive deps.
    3. Built devel packages can be copied to the public devel PPA.
    4. Built stable packages can be copied to the public proposed PPA.
    5. After evaluation, the stable packages in public proposed can be copied
       to the public stable PPA.
    The Supported Ubuntu versions have a similar path for the version:
    juju-packaging/<version> -> juju/<version>-proposed -> juju/<version>
    """
    to_team_name = 'juju'
    if to_archive_name == DEVEL:
        from_archive_name = DEVEL
        from_team_name = 'juju-packaging'
    elif to_archive_name == PROPOSED:
        from_archive_name = STABLE
        from_team_name = 'juju-packaging'
    elif to_archive_name == STABLE:
        from_archive_name = PROPOSED
        from_team_name = 'juju'
    # Ubuntu supported builds.
    elif to_archive_name == PROPOSED_1_22:
        from_archive_name = SUPPORTED_1_22
        from_team_name = 'juju-packaging'
    elif to_archive_name == SUPPORTED_1_22:
        from_archive_name = PROPOSED_1_22
        from_team_name = 'juju'
    elif to_archive_name == PROPOSED_1_25:
        from_archive_name = SUPPORTED_1_25
        from_team_name = 'juju-packaging'
    elif to_archive_name == SUPPORTED_1_25:
        from_archive_name = PROPOSED_1_25
        from_team_name = 'juju'
    else:
        raise ValueError('{} is not a valid archive'.format(to_archive_name))
    from_team = lp.people[from_team_name]
    from_archive = from_team.getPPAByName(name=from_archive_name)
    to_team = lp.people[to_team_name]
    to_archive = to_team.getPPAByName(name=to_archive_name)
    return from_archive, to_archive


def copy_packages(lp, version, to_archive_name, dry_run=False):
    """Copy the juju-core/juju-2.0 source and binary packages archive."""
    from_archive, to_archive = get_archives(lp, to_archive_name)
    # Look for juju-2.0 first.
    package_histories = from_archive.getPublishedSources(
        source_name='juju-2.0', status='Published')
    package_histories = [
        package for package in package_histories
        if package.source_package_version.startswith(version)]
    # Look for juju-core second.
    if len(package_histories) == 0:
        package_histories = from_archive.getPublishedSources(
            source_name='juju-core', status='Published')
        package_histories = [
            package for package in package_histories
            if package.source_package_version.startswith(version)]
    if len(package_histories) == 0:
        raise ValueError(
            'No packages matching {} were found in {} to copy to {}.'.format(
                version, from_archive.web_link, to_archive.web_link))
    for package in package_histories:
        print(
            'Copying {} and its binaries to {}.'.format(
                package.display_name, to_archive_name))
        if not dry_run:
            to_archive.copyPackage(
                from_archive=from_archive,
                source_name=package.source_package_name,
                version=package.source_package_version,
                to_pocket='Release', include_binaries=True, unembargo=True)
    return 0


def get_args(argv=None):
    """Return the option parser for this program."""
    parser = ArgumentParser(
        'Copy juju-core/juju-2 from one archive to another')
    parser.add_argument(
        '--dry-run', action="store_true", default=False,
        help='Explain what will happen without making changes')
    parser.add_argument(
        "-c", "--credentials", default=None, type=os.path.expanduser,
        help="Launchpad credentials file.")
    parser.add_argument('version', help='The package version like 1.20.8')
    parser.add_argument(
        'to_archive_name',
        help='The archive to copy the source and binary packages to.')
    return parser.parse_args(argv)


def main(argv=None):
    args = get_args(argv)
    lp = Launchpad.login_with(
        'lp-copy-packages', service_root='https://api.launchpad.net',
        version='devel', credentials_file=args.credentials)
    ret_code = copy_packages(
        lp, args.version, args.to_archive_name, args.dry_run)
    return ret_code


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))