Code review comment for lp:~makyo/juju-quickstart/ensure-juju-lxc

Revision history for this message
Madison Scott-Clary (makyo) wrote :

Reviewers: mp+196011_code.launchpad.net,

Message:
Please take a look.

Description:
Ensure juju and lxc are installed

To test: make check

To QA:
- Create an lxc or vm without juju installed
- Clone this branch
- Run `make sysdeps`
- Run `make run`

It should install juju, lxc, and dependencies, then prompt you to run
again after initializing your juju environments.

https://code.launchpad.net/~makyo/juju-quickstart/ensure-juju-lxc/+merge/196011

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/29980043/

Affected files (+96, -1 lines):
   A [revision details]
   M quickstart/app.py
   M quickstart/manage.py
   M quickstart/tests/helpers.py
   M quickstart/tests/test_app.py

Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision:
<email address hidden>
+New revision: <email address hidden>

Index: quickstart/app.py
=== modified file 'quickstart/app.py'
--- quickstart/app.py 2013-11-20 11:35:30 +0000
+++ quickstart/app.py 2013-11-20 20:36:24 +0000
@@ -45,6 +45,35 @@
          return 'juju-quickstart: error: {}'.format(self.message)

+def ensure_dependencies():
+ """Ensure that Juju and LXC are installed.
+
+ If juju is not found in the PATH, then add the juju stable PPA and
install
+ both juju and lxc.
+
+ Return when juju is available.
+ Raise a ProgramExit if an error occurs installing.
+ """
+ retcode = utils.call('juju', 'version')[0]
+ retcode += utils.call('lxc-ls')[0]
+ if retcode > 0:
+ cmds = [
+ ['apt-add-repository', '-y', 'ppa:juju/stable'],
+ ['apt-get', 'update'],
+ ['apt-get', 'install', '-y', 'juju-core', 'lxc']
+ ]
+ for cmd in cmds:
+ cmd.insert(0, 'sudo')
+ retcode, _, error = utils.call(*cmd)
+ if retcode:
+ raise ProgramExit(error)
+ # XXX Makyo #1247214:
+ # Here, we should guide the user through cloud credentials and
+ # juju init.
+ raise ProgramExit('Juju is now installed; please run the same
juju '
+ 'quickstart command again to proceed.')
+
+
  def bootstrap(env_name, is_local=False, debug=False):
      """Bootstrap the Juju environment with the given name.

Index: quickstart/manage.py
=== modified file 'quickstart/manage.py'
--- quickstart/manage.py 2013-11-20 11:35:30 +0000
+++ quickstart/manage.py 2013-11-20 20:30:08 +0000
@@ -218,6 +218,8 @@
  def run(options):
      """Run the application."""
      print('juju quickstart v{}'.format(version))
+ print('ensuring juju and lxc are installed')
+ app.ensure_dependencies()
      print('bootstrapping the {} environment (type: {})'.format(
          options.env_name, options.env_type))
      is_local = options.env_type == 'local'

Index: quickstart/tests/helpers.py
=== modified file 'quickstart/tests/helpers.py'
--- quickstart/tests/helpers.py 2013-11-18 11:42:15 +0000
+++ quickstart/tests/helpers.py 2013-11-20 20:30:08 +0000
@@ -85,7 +85,8 @@

  class CallTestsMixin(object):
- """Easily use the quickstart.utils.call function."""
+ """Easily use the quickstart.utils.call and
+ quickstart.utils.sudo_call functions."""

      def patch_call(self, retcode, output='', error=''):
          """Patch the quickstart.utils.call function."""

Index: quickstart/tests/test_app.py
=== modified file 'quickstart/tests/test_app.py'
--- quickstart/tests/test_app.py 2013-11-20 11:35:30 +0000
+++ quickstart/tests/test_app.py 2013-11-20 20:36:24 +0000
@@ -61,6 +61,67 @@
          return jujuclient.EnvError({'Error': message})

+class TestEnsureDependencies(
+ helpers.CallTestsMixin, ProgramExitTestsMixin, unittest.TestCase):
+
+ def call_ensure_dependencies(self, call_effects):
+ with self.patch_multiple_calls(call_effects) as mock_call:
+ app.ensure_dependencies()
+ return mock_call
+
+ def test_success_install(self):
+ # XXX Makyo #1247214:
+ # Here, we should guide the user through cloud credentials and
+ # juju init.
+ with self.assert_program_exit('Juju is now installed; please run
the '
+ 'same juju quickstart command again
to '
+ 'proceed.'):
+ call = self.call_ensure_dependencies(
+ [
+ (127, '', 'no juju'),
+ (127, '', 'no lxc'),
+ (0, 'add repo', ''),
+ (0, 'update', ''),
+ (0, 'install', ''),
+ ]
+ )
+ self.assertEqual(call.call_count, 5)
+ call.assert_has_calls([
+ mock.call('juju', 'version'),
+ mock.call('lxc-ls'),
+ mock.call('sudo', 'apt-add-repository', '-y',
+ 'ppa:juju/stable'),
+ mock.call('sudo', 'apt-get', 'update'),
+ mock.call('sudo', 'apt-get', 'install', '-y', 'juju-core',
+ 'lxc'),
+ ])
+
+ def test_success_no_install(self):
+ call = self.call_ensure_dependencies(
+ [
+ (0, '1.16', ''),
+ (0, '', ''),
+ (0, 'add repo', ''),
+ (0, 'update', ''),
+ (0, 'install', ''),
+ ]
+ )
+ self.assertEqual(call.call_count, 2)
+
+ def test_failure(self):
+ with self.assert_program_exit('install failure'):
+ call = self.call_ensure_dependencies(
+ [
+ (127, '', ''),
+ (127, '', ''),
+ (1, 'add repo', 'install failure'),
+ (1, 'update', 'uh-oh'),
+ (1, 'install', 'oh no'),
+ ]
+ )
+ self.assertEqual(call.call_count, 3)
+
+
  @mock_print
  class TestBootstrap(
          helpers.CallTestsMixin, ProgramExitTestsMixin, unittest.TestCase):

« Back to merge proposal