Merge lp:~james-page/charm-helpers/configure_source_proposed into lp:charm-helpers

Proposed by James Page
Status: Merged
Merged at revision: 43
Proposed branch: lp:~james-page/charm-helpers/configure_source_proposed
Merge into: lp:charm-helpers
Diff against target: 188 lines (+75/-12)
4 files modified
charmhelpers/core/host.py (+16/-6)
charmhelpers/fetch/__init__.py (+9/-1)
tests/core/test_host.py (+39/-5)
tests/fetch/test_fetch.py (+11/-0)
To merge this branch: bzr merge lp:~james-page/charm-helpers/configure_source_proposed
Reviewer Review Type Date Requested Status
Matthew Wedgwood (community) Approve
Review via email: mp+172796@code.launchpad.net

Description of the change

Add support for 'proposed' as a valid source configuration.

I needed this to enable easy testing of proposed SRU changes.

To post a comment you must log in.
Revision history for this message
Matthew Wedgwood (mew) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'charmhelpers/core/host.py'
--- charmhelpers/core/host.py 2013-06-24 03:26:19 +0000
+++ charmhelpers/core/host.py 2013-07-03 11:53:59 +0000
@@ -48,13 +48,13 @@
48 log('creating user {0}'.format(username))48 log('creating user {0}'.format(username))
49 cmd = ['useradd']49 cmd = ['useradd']
50 if system_user or password is None:50 if system_user or password is None:
51 cmd.append('--system')51 cmd.append('--system')
52 else:52 else:
53 cmd.extend([53 cmd.extend([
54 '--create-home',54 '--create-home',
55 '--shell', shell,55 '--shell', shell,
56 '--password', password,56 '--password', password,
57 ])57 ])
58 cmd.append(username)58 cmd.append(username)
59 subprocess.check_call(cmd)59 subprocess.check_call(cmd)
60 user_info = pwd.getpwnam(username)60 user_info = pwd.getpwnam(username)
@@ -261,3 +261,13 @@
261 service('restart', service_name)261 service('restart', service_name)
262 return wrapped_f262 return wrapped_f
263 return wrap263 return wrap
264
265
266def lsb_release():
267 '''Return /etc/lsb-release in a dict'''
268 d = {}
269 with open('/etc/lsb-release', 'r') as lsb:
270 for l in lsb:
271 k, v = l.split('=')
272 d[k.strip()] = v.strip()
273 return d
264274
=== modified file 'charmhelpers/fetch/__init__.py'
--- charmhelpers/fetch/__init__.py 2013-06-27 15:59:39 +0000
+++ charmhelpers/fetch/__init__.py 2013-07-03 11:53:59 +0000
@@ -3,7 +3,8 @@
3from charmhelpers.core.host import (3from charmhelpers.core.host import (
4 apt_install,4 apt_install,
5 apt_update,5 apt_update,
6 filter_installed_packages6 filter_installed_packages,
7 lsb_release
7)8)
8from urlparse import (9from urlparse import (
9 urlparse,10 urlparse,
@@ -18,6 +19,9 @@
18CLOUD_ARCHIVE = """# Ubuntu Cloud Archive19CLOUD_ARCHIVE = """# Ubuntu Cloud Archive
19deb http://ubuntu-cloud.archive.canonical.com/ubuntu {} main20deb http://ubuntu-cloud.archive.canonical.com/ubuntu {} main
20"""21"""
22PROPOSED_POCKET = """# Proposed
23deb http://archive.ubuntu.com/ubuntu {}-proposed main universe multiverse restricted
24"""
2125
2226
23def add_source(source, key=None):27def add_source(source, key=None):
@@ -30,6 +34,10 @@
30 pocket = source.split(':')[-1]34 pocket = source.split(':')[-1]
31 with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as apt:35 with open('/etc/apt/sources.list.d/cloud-archive.list', 'w') as apt:
32 apt.write(CLOUD_ARCHIVE.format(pocket))36 apt.write(CLOUD_ARCHIVE.format(pocket))
37 elif source == 'proposed':
38 release = lsb_release()['DISTRIB_CODENAME']
39 with open('/etc/apt/sources.list.d/proposed.list', 'w') as apt:
40 apt.write(PROPOSED_POCKET.format(release))
33 if key:41 if key:
34 subprocess.check_call(['apt-key', 'import', key])42 subprocess.check_call(['apt-key', 'import', key])
3543
3644
=== modified file 'tests/core/test_host.py'
--- tests/core/test_host.py 2013-06-24 03:26:19 +0000
+++ tests/core/test_host.py 2013-07-03 11:53:59 +0000
@@ -1,7 +1,7 @@
1from collections import OrderedDict1from collections import OrderedDict
2from contextlib import contextmanager2from contextlib import contextmanager
3import os
4import subprocess3import subprocess
4import io
55
6from mock import patch, call, MagicMock6from mock import patch, call, MagicMock
7from testtools import TestCase7from testtools import TestCase
@@ -28,6 +28,13 @@
28 }28 }
29}29}
3030
31LSB_RELEASE = u'''DISTRIB_ID=Ubuntu
32DISTRIB_RELEASE=13.10
33DISTRIB_CODENAME=saucy
34DISTRIB_DESCRIPTION="Ubuntu Saucy Salamander (development branch)"
35'''
36
37
31def fake_apt_cache():38def fake_apt_cache():
32 def _get(package):39 def _get(package):
33 pkg = MagicMock()40 pkg = MagicMock()
@@ -43,6 +50,7 @@
43 cache.__getitem__.side_effect = _get50 cache.__getitem__.side_effect = _get
44 return cache51 return cache
4552
53
46@contextmanager54@contextmanager
47def patch_open():55def patch_open():
48 '''Patch open() to allow mocking both open() itself and the file that is56 '''Patch open() to allow mocking both open() itself and the file that is
@@ -61,6 +69,18 @@
61 yield mock_open, mock_file69 yield mock_open, mock_file
6270
6371
72@contextmanager
73def mock_open(filename, contents=None):
74 ''' Slightly simpler mock of open to return contents for filename '''
75 def mock_file(*args):
76 if args[0] == filename:
77 return io.StringIO(contents)
78 else:
79 return open(*args)
80 with patch('__builtin__.open', mock_file):
81 yield
82
83
64class HelpersTest(TestCase):84class HelpersTest(TestCase):
65 @patch('subprocess.call')85 @patch('subprocess.call')
66 def test_runs_service_action(self, mock_call):86 def test_runs_service_action(self, mock_call):
@@ -120,9 +140,9 @@
120 host.service_reload(service_name, restart_on_failure=True)140 host.service_reload(service_name, restart_on_failure=True)
121141
122 service.assert_has_calls([142 service.assert_has_calls([
123 call('reload', service_name),143 call('reload', service_name),
124 call('restart', service_name)144 call('restart', service_name)
125 ])145 ])
126146
127 @patch.object(host, 'service')147 @patch.object(host, 'service')
128 def test_failed_reload_without_restart(self, service):148 def test_failed_reload_without_restart(self, service):
@@ -711,7 +731,7 @@
711 def test_multiservice_restart_on_change_in_order(self, exists, service):731 def test_multiservice_restart_on_change_in_order(self, exists, service):
712 restart_map = OrderedDict([732 restart_map = OrderedDict([
713 ('/etc/cinder/cinder.conf', ['some-api']),733 ('/etc/cinder/cinder.conf', ['some-api']),
714 ('/etc/haproxy/haproxy.conf', ['haproxy'])734 ('/etc/haproxy/haproxy.conf', ['haproxy'])
715 ])735 ])
716 exists.side_effect = [False, True, True, True]736 exists.side_effect = [False, True, True, True]
717737
@@ -730,3 +750,17 @@
730 call('restart', 'haproxy')750 call('restart', 'haproxy')
731 ]751 ]
732 self.assertEquals(expected, service.call_args_list)752 self.assertEquals(expected, service.call_args_list)
753
754 def test_lsb_release(self):
755 result = {
756 "DISTRIB_ID": "Ubuntu",
757 "DISTRIB_RELEASE": "13.10",
758 "DISTRIB_CODENAME": "saucy",
759 "DISTRIB_DESCRIPTION": "\"Ubuntu Saucy Salamander "
760 "(development branch)\""
761 }
762 with mock_open('/etc/lsb-release', LSB_RELEASE):
763 lsb_release = host.lsb_release()
764 for key in result:
765 print lsb_release
766 self.assertEqual(result[key], lsb_release[key])
733767
=== modified file 'tests/fetch/test_fetch.py'
--- tests/fetch/test_fetch.py 2013-06-27 15:59:39 +0000
+++ tests/fetch/test_fetch.py 2013-07-03 11:53:59 +0000
@@ -55,6 +55,17 @@
55 mock_file.write.assert_called_with(result)55 mock_file.write.assert_called_with(result)
56 filter_pkg.assert_called_with(['ubuntu-cloud-keyring'])56 filter_pkg.assert_called_with(['ubuntu-cloud-keyring'])
5757
58 @patch.object(fetch, 'lsb_release')
59 def test_add_source_proposed(self, lsb_release):
60 source = "proposed"
61 result = """# Proposed
62deb http://archive.ubuntu.com/ubuntu precise-proposed main universe multiverse restricted
63"""
64 lsb_release.return_value = {'DISTRIB_CODENAME': 'precise'}
65 with patch_open() as (mock_open, mock_file):
66 fetch.add_source(source=source)
67 mock_file.write.assert_called_with(result)
68
58 @patch('subprocess.check_call')69 @patch('subprocess.check_call')
59 def test_add_source_http_and_key(self, check_call):70 def test_add_source_http_and_key(self, check_call):
60 source = "http://archive.ubuntu.com/ubuntu raring-backports main"71 source = "http://archive.ubuntu.com/ubuntu raring-backports main"

Subscribers

People subscribed via source and target branches