~canonical-ci-engineering/ubuntu-ci-services-itself/ansible

« back to all changes in this revision

Viewing changes to library/packaging/apt_repository

  • Committer: Package Import Robot
  • Author(s): Harlan Lieberman-Berg
  • Date: 2014-04-21 16:51:47 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20140421165147-8ua5msw3mse8r2br
Tags: 1.5.5+dfsg-1
* New upstream version 1.5.5, security update.
* d/control: Add myself to Uploaders to silence Lintian
* Refresh patches for new version.  Add DEP-3 headers to one patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
description:
29
29
    - Add or remove an APT repositories in Ubuntu and Debian.
30
30
notes:
31
 
    - This module works on Debian and Ubuntu and requires C(python-apt) and C(python-pycurl) packages.
 
31
    - This module works on Debian and Ubuntu and requires C(python-apt).
32
32
    - This module supports Debian Squeeze (version 6) as well as its successors.
33
33
    - This module treats Debian and Ubuntu distributions separately. So PPA could be installed only on Ubuntu machines.
34
34
options:
43
43
        default: "present"
44
44
        description:
45
45
            - A source string state.
 
46
    mode:
 
47
        required: false
 
48
        default: 0644
 
49
        description:
 
50
            - The octal mode for newly created files in sources.list.d
 
51
        version_added: "1.6"
46
52
    update_cache:
47
53
        description:
48
 
            - Run the equivalent of C(apt-get update) if has changed.
 
54
            - Run the equivalent of C(apt-get update) when a change occurs.  Cache updates are run after making changes.
49
55
        required: false
50
56
        default: "yes"
51
57
        choices: [ "yes", "no" ]
52
58
author: Alexander Saltanov
53
59
version_added: "0.7"
54
 
requirements: [ python-apt, python-pycurl ]
 
60
requirements: [ python-apt ]
55
61
'''
56
62
 
57
63
EXAMPLES = '''
70
76
'''
71
77
 
72
78
import glob
73
 
try:
74
 
  import json
75
 
except ImportError:
76
 
  import simplejson as json
77
79
import os
78
80
import re
79
81
import tempfile
87
89
except ImportError:
88
90
    HAVE_PYTHON_APT = False
89
91
 
90
 
try:
91
 
    import pycurl
92
 
    HAVE_PYCURL = True
93
 
except ImportError:
94
 
    HAVE_PYCURL = False
95
92
 
96
93
VALID_SOURCE_TYPES = ('deb', 'deb-src')
97
94
 
98
 
 
99
 
class CurlCallback:
100
 
    def __init__(self):
101
 
        self.contents = ''
102
 
 
103
 
    def body_callback(self, buf):
104
 
        self.contents = self.contents + buf
105
 
 
 
95
def install_python_apt(module):
 
96
 
 
97
    if not module.check_mode:
 
98
        apt_get_path = module.get_bin_path('apt-get')
 
99
        if apt_get_path:
 
100
            rc, so, se = module.run_command('%s update && %s install python-apt -y -q' % (apt_get_path, apt_get_path))
 
101
            if rc == 0:
 
102
                global apt, apt_pkg
 
103
                import apt
 
104
                import apt_pkg
106
105
 
107
106
class InvalidSource(Exception):
108
107
    pass
140
139
    def _suggest_filename(self, line):
141
140
        def _cleanup_filename(s):
142
141
            return '_'.join(re.sub('[^a-zA-Z0-9]', ' ', s).split())
 
142
        def _strip_username_password(s):
 
143
            if '@' in s:
 
144
                s = s.split('@', 1)
 
145
                s = s[-1]
 
146
            return s
143
147
 
144
148
        # Drop options and protocols.
145
149
        line = re.sub('\[[^\]]+\]', '', line)
146
150
        line = re.sub('\w+://', '', line)
147
151
 
 
152
        # split line into valid keywords
148
153
        parts = [part for part in line.split() if part not in VALID_SOURCE_TYPES]
 
154
 
 
155
        # Drop usernames and passwords
 
156
        parts[0] = _strip_username_password(parts[0])
 
157
 
149
158
        return '%s.list' % _cleanup_filename(' '.join(parts[:1]))
150
159
 
151
160
    def _parse(self, line, raise_if_invalid_or_disabled=False):
214
223
            if sources:
215
224
                d, fn = os.path.split(filename)
216
225
                fd, tmp_path = tempfile.mkstemp(prefix=".%s-" % fn, dir=d)
217
 
                os.chmod(os.path.join(fd, tmp_path), 0644)
 
226
 
 
227
                # allow the user to override the default mode
 
228
                this_mode = module.params['mode']
 
229
                module.set_mode_if_different(tmp_path, this_mode, False)
218
230
 
219
231
                f = os.fdopen(fd, 'w')
220
232
                for n, valid, enabled, source, comment in sources:
290
302
 
291
303
class UbuntuSourcesList(SourcesList):
292
304
 
293
 
    LP_API = 'https://launchpad.net/api/1.0/~%s/+archive/%s' 
 
305
    LP_API = 'https://launchpad.net/api/1.0/~%s/+archive/%s'
294
306
 
295
 
    def __init__(self, add_ppa_signing_keys_callback=None):
 
307
    def __init__(self, module, add_ppa_signing_keys_callback=None):
 
308
        self.module = module
296
309
        self.add_ppa_signing_keys_callback = add_ppa_signing_keys_callback
297
310
        super(UbuntuSourcesList, self).__init__()
298
311
 
299
312
    def _get_ppa_info(self, owner_name, ppa_name):
300
 
        # we can not use urllib2 here as it does not do cert verification
301
313
        lp_api = self.LP_API % (owner_name, ppa_name)
302
 
        return self._get_ppa_info_curl(lp_api)
303
314
 
304
 
    def _get_ppa_info_curl(self, lp_api):
305
 
        callback = CurlCallback()
306
 
        curl = pycurl.Curl()
307
 
        curl.setopt(pycurl.SSL_VERIFYPEER, 1)
308
 
        curl.setopt(pycurl.SSL_VERIFYHOST, 2)
309
 
        curl.setopt(pycurl.WRITEFUNCTION, callback.body_callback)
310
 
        curl.setopt(pycurl.URL, str(lp_api))
311
 
        curl.setopt(pycurl.HTTPHEADER, ["Accept: application/json"])
312
 
        curl.perform()
313
 
        curl.close()
314
 
        lp_page = callback.contents
315
 
        return json.loads(lp_page)
 
315
        headers = dict(Accept='application/json')
 
316
        response, info = fetch_url(self.module, lp_api, headers=headers)
 
317
        return json.load(response)
316
318
 
317
319
    def _expand_ppa(self, path):
318
320
        ppa = path.split(':')[1]
363
365
        argument_spec=dict(
364
366
            repo=dict(required=True),
365
367
            state=dict(choices=['present', 'absent'], default='present'),
 
368
            mode=dict(required=False, default=0644),
366
369
            update_cache = dict(aliases=['update-cache'], type='bool', default='yes'),
 
370
            # this should not be needed, but exists as a failsafe
 
371
            install_python_apt=dict(required=False, default="yes", type='bool'),
367
372
        ),
368
373
        supports_check_mode=True,
369
374
    )
370
375
 
371
 
    if not HAVE_PYTHON_APT:
372
 
        module.fail_json(msg='Could not import python modules: apt_pkg. Please install python-apt package.')
373
 
 
374
 
    if not HAVE_PYCURL:
375
 
        module.fail_json(msg='Could not import python modules: pycurl. Please install python-pycurl package.')
 
376
    params = module.params
 
377
    if params['install_python_apt'] and not HAVE_PYTHON_APT and not module.check_mode:
 
378
        install_python_apt(module)
376
379
 
377
380
    repo = module.params['repo']
378
381
    state = module.params['state']
380
383
    sourceslist = None
381
384
 
382
385
    if isinstance(distro, aptsources.distro.UbuntuDistribution):
383
 
        sourceslist = UbuntuSourcesList(add_ppa_signing_keys_callback=get_add_ppa_signing_key_callback(module))
 
386
        sourceslist = UbuntuSourcesList(module,
 
387
                                        add_ppa_signing_keys_callback=get_add_ppa_signing_key_callback(module))
384
388
    elif isinstance(distro, aptsources.distro.DebianDistribution) or \
385
389
            isinstance(distro, aptsources.distro.Distribution):
386
390
        sourceslist = SourcesList()
413
417
 
414
418
# import module snippets
415
419
from ansible.module_utils.basic import *
 
420
from ansible.module_utils.urls import *
416
421
 
417
422
main()