~paulgear/charms/trusty/ntpmaster/fix-python3-on-trusty

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/fetch/__init__.py

  • Committer: Adam Israel
  • Date: 2016-03-30 17:02:08 UTC
  • mfrom: (12.1.1 trunk)
  • Revision ID: adam.israel@gmail.com-20160330170208-hlkrwz32rw4jcfl4
[paulgear] Sync charm-helpers

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2014-2015 Canonical Limited.
 
2
#
 
3
# This file is part of charm-helpers.
 
4
#
 
5
# charm-helpers is free software: you can redistribute it and/or modify
 
6
# it under the terms of the GNU Lesser General Public License version 3 as
 
7
# published by the Free Software Foundation.
 
8
#
 
9
# charm-helpers is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU Lesser General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU Lesser General Public License
 
15
# along with charm-helpers.  If not, see <http://www.gnu.org/licenses/>.
 
16
 
1
17
import importlib
2
18
from tempfile import NamedTemporaryFile
3
19
import time
5
21
from charmhelpers.core.host import (
6
22
    lsb_release
7
23
)
8
 
from urlparse import (
9
 
    urlparse,
10
 
    urlunparse,
11
 
)
12
24
import subprocess
13
25
from charmhelpers.core.hookenv import (
14
26
    config,
16
28
)
17
29
import os
18
30
 
 
31
import six
 
32
if six.PY3:
 
33
    from urllib.parse import urlparse, urlunparse
 
34
else:
 
35
    from urlparse import urlparse, urlunparse
 
36
 
19
37
 
20
38
CLOUD_ARCHIVE = """# Ubuntu Cloud Archive
21
39
deb http://ubuntu-cloud.archive.canonical.com/ubuntu {} main
62
80
    'trusty-juno/updates': 'trusty-updates/juno',
63
81
    'trusty-updates/juno': 'trusty-updates/juno',
64
82
    'juno/proposed': 'trusty-proposed/juno',
65
 
    'juno/proposed': 'trusty-proposed/juno',
66
83
    'trusty-juno/proposed': 'trusty-proposed/juno',
67
84
    'trusty-proposed/juno': 'trusty-proposed/juno',
 
85
    # Kilo
 
86
    'kilo': 'trusty-updates/kilo',
 
87
    'trusty-kilo': 'trusty-updates/kilo',
 
88
    'trusty-kilo/updates': 'trusty-updates/kilo',
 
89
    'trusty-updates/kilo': 'trusty-updates/kilo',
 
90
    'kilo/proposed': 'trusty-proposed/kilo',
 
91
    'trusty-kilo/proposed': 'trusty-proposed/kilo',
 
92
    'trusty-proposed/kilo': 'trusty-proposed/kilo',
 
93
    # Liberty
 
94
    'liberty': 'trusty-updates/liberty',
 
95
    'trusty-liberty': 'trusty-updates/liberty',
 
96
    'trusty-liberty/updates': 'trusty-updates/liberty',
 
97
    'trusty-updates/liberty': 'trusty-updates/liberty',
 
98
    'liberty/proposed': 'trusty-proposed/liberty',
 
99
    'trusty-liberty/proposed': 'trusty-proposed/liberty',
 
100
    'trusty-proposed/liberty': 'trusty-proposed/liberty',
 
101
    # Mitaka
 
102
    'mitaka': 'trusty-updates/mitaka',
 
103
    'trusty-mitaka': 'trusty-updates/mitaka',
 
104
    'trusty-mitaka/updates': 'trusty-updates/mitaka',
 
105
    'trusty-updates/mitaka': 'trusty-updates/mitaka',
 
106
    'mitaka/proposed': 'trusty-proposed/mitaka',
 
107
    'trusty-mitaka/proposed': 'trusty-proposed/mitaka',
 
108
    'trusty-proposed/mitaka': 'trusty-proposed/mitaka',
68
109
}
69
110
 
70
111
# The order of this list is very important. Handlers should be listed in from
72
113
FETCH_HANDLERS = (
73
114
    'charmhelpers.fetch.archiveurl.ArchiveUrlFetchHandler',
74
115
    'charmhelpers.fetch.bzrurl.BzrUrlFetchHandler',
 
116
    'charmhelpers.fetch.giturl.GitUrlFetchHandler',
75
117
)
76
118
 
77
119
APT_NO_LOCK = 100  # The return code for "couldn't acquire lock" in APT.
132
174
 
133
175
def apt_cache(in_memory=True):
134
176
    """Build and return an apt cache"""
135
 
    import apt_pkg
 
177
    from apt import apt_pkg
136
178
    apt_pkg.init()
137
179
    if in_memory:
138
180
        apt_pkg.config.set("Dir::Cache::pkgcache", "")
148
190
    cmd = ['apt-get', '--assume-yes']
149
191
    cmd.extend(options)
150
192
    cmd.append('install')
151
 
    if isinstance(packages, basestring):
 
193
    if isinstance(packages, six.string_types):
152
194
        cmd.append(packages)
153
195
    else:
154
196
        cmd.extend(packages)
181
223
def apt_purge(packages, fatal=False):
182
224
    """Purge one or more packages"""
183
225
    cmd = ['apt-get', '--assume-yes', 'purge']
184
 
    if isinstance(packages, basestring):
 
226
    if isinstance(packages, six.string_types):
185
227
        cmd.append(packages)
186
228
    else:
187
229
        cmd.extend(packages)
189
231
    _run_apt_command(cmd, fatal)
190
232
 
191
233
 
 
234
def apt_mark(packages, mark, fatal=False):
 
235
    """Flag one or more packages using apt-mark"""
 
236
    log("Marking {} as {}".format(packages, mark))
 
237
    cmd = ['apt-mark', mark]
 
238
    if isinstance(packages, six.string_types):
 
239
        cmd.append(packages)
 
240
    else:
 
241
        cmd.extend(packages)
 
242
 
 
243
    if fatal:
 
244
        subprocess.check_call(cmd, universal_newlines=True)
 
245
    else:
 
246
        subprocess.call(cmd, universal_newlines=True)
 
247
 
 
248
 
192
249
def apt_hold(packages, fatal=False):
193
 
    """Hold one or more packages"""
194
 
    cmd = ['apt-mark', 'hold']
195
 
    if isinstance(packages, basestring):
196
 
        cmd.append(packages)
197
 
    else:
198
 
        cmd.extend(packages)
199
 
    log("Holding {}".format(packages))
200
 
 
201
 
    if fatal:
202
 
        subprocess.check_call(cmd)
203
 
    else:
204
 
        subprocess.call(cmd)
 
250
    return apt_mark(packages, 'hold', fatal=fatal)
 
251
 
 
252
 
 
253
def apt_unhold(packages, fatal=False):
 
254
    return apt_mark(packages, 'unhold', fatal=fatal)
205
255
 
206
256
 
207
257
def add_source(source, key=None):
218
268
        pocket for the release.
219
269
        'cloud:' may be used to activate official cloud archive pockets,
220
270
        such as 'cloud:icehouse'
 
271
        'distro' may be used as a noop
221
272
 
222
273
    @param key: A key to be added to the system's APT keyring and used
223
274
    to verify the signatures on packages. Ideally, this should be an
251
302
        release = lsb_release()['DISTRIB_CODENAME']
252
303
        with open('/etc/apt/sources.list.d/proposed.list', 'w') as apt:
253
304
            apt.write(PROPOSED_POCKET.format(release))
 
305
    elif source == 'distro':
 
306
        pass
254
307
    else:
255
 
        raise SourceConfigError("Unknown source: {!r}".format(source))
 
308
        log("Unknown source: {!r}".format(source))
256
309
 
257
310
    if key:
258
311
        if '-----BEGIN PGP PUBLIC KEY BLOCK-----' in key:
259
 
            with NamedTemporaryFile() as key_file:
 
312
            with NamedTemporaryFile('w+') as key_file:
260
313
                key_file.write(key)
261
314
                key_file.flush()
262
315
                key_file.seek(0)
293
346
    sources = safe_load((config(sources_var) or '').strip()) or []
294
347
    keys = safe_load((config(keys_var) or '').strip()) or None
295
348
 
296
 
    if isinstance(sources, basestring):
 
349
    if isinstance(sources, six.string_types):
297
350
        sources = [sources]
298
351
 
299
352
    if keys is None:
300
353
        for source in sources:
301
354
            add_source(source, None)
302
355
    else:
303
 
        if isinstance(keys, basestring):
 
356
        if isinstance(keys, six.string_types):
304
357
            keys = [keys]
305
358
 
306
359
        if len(sources) != len(keys):
341
394
    for handler in handlers:
342
395
        try:
343
396
            installed_to = handler.install(source, *args, **kwargs)
344
 
        except UnhandledSource:
345
 
            pass
 
397
        except UnhandledSource as e:
 
398
            log('Install source attempt unsuccessful: {}'.format(e),
 
399
                level='WARNING')
346
400
    if not installed_to:
347
401
        raise UnhandledSource("No handler found for source {}".format(source))
348
402
    return installed_to
365
419
                importlib.import_module(package),
366
420
                classname)
367
421
            plugin_list.append(handler_class())
368
 
        except (ImportError, AttributeError):
 
422
        except NotImplementedError:
369
423
            # Skip missing plugins so that they can be ommitted from
370
424
            # installation if desired
371
425
            log("FetchHandler {} not found, skipping plugin".format(
397
451
        while result is None or result == APT_NO_LOCK:
398
452
            try:
399
453
                result = subprocess.check_call(cmd, env=env)
400
 
            except subprocess.CalledProcessError, e:
 
454
            except subprocess.CalledProcessError as e:
401
455
                retry_count = retry_count + 1
402
456
                if retry_count > APT_NO_LOCK_RETRY_COUNT:
403
457
                    raise