summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Moser <smoser@ubuntu.com>2016-06-15 21:11:44 -0400
committerScott Moser <smoser@ubuntu.com>2016-06-15 21:11:44 -0400
commit10facc1861571b5bf38d568457f5e2dec51dd4ce (patch)
tree88dea04a2a8579ffdca779834ed7b70cb1cb0836
parent5d79ac3ddae5a17b5fbaee2261f80a10ef3bd10d (diff)
parent9fd1f50f5b20b02b05eeaeff91e01922c4d45645 (diff)
downloadcloud-init-10facc1861571b5bf38d568457f5e2dec51dd4ce.tar.gz
move 'main' into cloudinit/cmd/ for easier testing
This moves bin/cloud-init's content into cloudinit/cmd/main.py, and then fixes the pep8/flake8 issues with that. The end result is easier testing of main.
-rw-r--r--cloudinit/cmd/__init__.py21
-rw-r--r--[-rwxr-xr-x]cloudinit/cmd/main.py (renamed from bin/cloud-init)46
-rwxr-xr-xsetup.py8
-rw-r--r--tests/unittests/test_cli.py43
-rwxr-xr-xtools/run-pep85
-rwxr-xr-xtools/run-pyflakes2
6 files changed, 65 insertions, 60 deletions
diff --git a/cloudinit/cmd/__init__.py b/cloudinit/cmd/__init__.py
new file mode 100644
index 00000000..da124641
--- /dev/null
+++ b/cloudinit/cmd/__init__.py
@@ -0,0 +1,21 @@
+# vi: ts=4 expandtab
+#
+# Copyright (C) 2012 Canonical Ltd.
+# Copyright (C) 2012 Hewlett-Packard Development Company, L.P.
+# Copyright (C) 2012 Yahoo! Inc.
+#
+# Author: Scott Moser <scott.moser@canonical.com>
+# Author: Juerg Haefliger <juerg.haefliger@hp.com>
+# Author: Joshua Harlow <harlowja@yahoo-inc.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
diff --git a/bin/cloud-init b/cloudinit/cmd/main.py
index 21c3a684..63621c1d 100755..100644
--- a/bin/cloud-init
+++ b/cloudinit/cmd/main.py
@@ -25,19 +25,12 @@ import argparse
import json
import os
import sys
-import time
import tempfile
+import time
import traceback
-# This is more just for running from the bin folder so that
-# cloud-init binary can find the cloudinit module
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(
- sys.argv[0]), os.pardir, os.pardir))
-if os.path.exists(os.path.join(possible_topdir, "cloudinit", "__init__.py")):
- sys.path.insert(0, possible_topdir)
-
from cloudinit import patcher
-patcher.patch()
+patcher.patch() # noqa
from cloudinit import log as logging
from cloudinit import netinfo
@@ -46,9 +39,10 @@ from cloudinit import sources
from cloudinit import stages
from cloudinit import templater
from cloudinit import util
+from cloudinit import version
+
from cloudinit import reporting
from cloudinit.reporting import events
-from cloudinit import version
from cloudinit.settings import (PER_INSTANCE, PER_ALWAYS, PER_ONCE,
CLOUD_CONFIG)
@@ -188,7 +182,7 @@ def main_init(name, args):
LOG.debug("Closing stdin")
util.close_stdin()
(outfmt, errfmt) = util.fixup_output(init.cfg, name)
- except:
+ except Exception:
util.logexc(LOG, "Failed to setup output redirection!")
print_exc("Failed to setup output redirection!")
if args.debug:
@@ -325,7 +319,7 @@ def main_init(name, args):
if outfmt_orig != outfmt or errfmt_orig != errfmt:
LOG.warn("Stdout, stderr changing to (%s, %s)", outfmt, errfmt)
(outfmt, errfmt) = util.fixup_output(mods.cfg, name)
- except:
+ except Exception:
util.logexc(LOG, "Failed to re-adjust output redirection!")
logging.setupLogging(mods.cfg)
@@ -367,7 +361,7 @@ def main_modules(action_name, args):
LOG.debug("Closing stdin")
util.close_stdin()
util.fixup_output(mods.cfg, name)
- except:
+ except Exception:
util.logexc(LOG, "Failed to setup output redirection!")
if args.debug:
# Reset so that all the debug handlers are closed out
@@ -430,7 +424,7 @@ def main_single(name, args):
LOG.debug("Closing stdin")
util.close_stdin()
util.fixup_output(mods.cfg, None)
- except:
+ except Exception:
util.logexc(LOG, "Failed to setup output redirection!")
if args.debug:
# Reset so that all the debug handlers are closed out
@@ -510,7 +504,7 @@ def status_wrapper(name, args, data_d=None, link_d=None):
else:
try:
status = json.loads(util.load_file(status_path))
- except:
+ except Exception:
pass
if status is None:
@@ -569,8 +563,12 @@ def status_wrapper(name, args, data_d=None, link_d=None):
return len(v1[mode]['errors'])
-def main():
- parser = argparse.ArgumentParser()
+def main(sysv_args=None):
+ if sysv_args is not None:
+ parser = argparse.ArgumentParser(prog=sysv_args[0])
+ sysv_args = sysv_args[1:]
+ else:
+ parser = argparse.ArgumentParser()
# Top level args
parser.add_argument('--version', '-v', action='version',
@@ -646,7 +644,12 @@ def main():
' pass to this module'))
parser_single.set_defaults(action=('single', main_single))
- args = parser.parse_args()
+ args = parser.parse_args(args=sysv_args)
+
+ try:
+ (name, functor) = args.action
+ except AttributeError:
+ parser.error('too few arguments')
# Setup basic logging to start (until reinitialized)
# iff in debug mode...
@@ -656,9 +659,6 @@ def main():
# Setup signal handlers before running
signal_handler.attach_handlers()
- if not hasattr(args, 'action'):
- parser.error('too few arguments')
- (name, functor) = args.action
if name in ("modules", "init"):
functor = status_wrapper
@@ -683,7 +683,3 @@ def main():
return util.log_time(
logfunc=LOG.debug, msg="cloud-init mode '%s'" % name,
get_uptime=True, func=functor, args=(name, args))
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/setup.py b/setup.py
index 8c8f2402..0af576a9 100755
--- a/setup.py
+++ b/setup.py
@@ -204,10 +204,14 @@ setuptools.setup(
author_email='scott.moser@canonical.com',
url='http://launchpad.net/cloud-init/',
packages=setuptools.find_packages(exclude=['tests']),
- scripts=['bin/cloud-init',
- 'tools/cloud-init-per'],
+ scripts=['tools/cloud-init-per'],
license='GPLv3',
data_files=data_files,
install_requires=requirements,
cmdclass=cmdclass,
+ entry_points={
+ 'console_scripts': [
+ 'cloud-init = cloudinit.cmd.main:main'
+ ],
+ }
)
diff --git a/tests/unittests/test_cli.py b/tests/unittests/test_cli.py
index 163ce64c..5fa252f7 100644
--- a/tests/unittests/test_cli.py
+++ b/tests/unittests/test_cli.py
@@ -1,12 +1,10 @@
-import imp
-import os
import six
-import sys
from . import helpers as test_helpers
-mock = test_helpers.mock
-BIN_CLOUDINIT = "bin/cloud-init"
+from cloudinit.cmd import main as cli
+
+mock = test_helpers.mock
class TestCLI(test_helpers.FilesystemMockingTestCase):
@@ -15,35 +13,22 @@ class TestCLI(test_helpers.FilesystemMockingTestCase):
super(TestCLI, self).setUp()
self.stderr = six.StringIO()
self.patchStdoutAndStderr(stderr=self.stderr)
- self.sys_exit = mock.MagicMock()
- self.patched_funcs.enter_context(
- mock.patch.object(sys, 'exit', self.sys_exit))
-
- def _call_main(self):
- self.patched_funcs.enter_context(
- mock.patch.object(sys, 'argv', ['cloud-init']))
- cli = imp.load_module(
- 'cli', open(BIN_CLOUDINIT), '', ('', 'r', imp.PY_SOURCE))
+
+ def _call_main(self, sysv_args=None):
+ if not sysv_args:
+ sysv_args = ['cloud-init']
try:
- return cli.main()
- except Exception:
- pass
+ return cli.main(sysv_args=sysv_args)
+ except SystemExit as e:
+ return e.code
- @test_helpers.skipIf(not os.path.isfile(BIN_CLOUDINIT), "no bin/cloudinit")
def test_no_arguments_shows_usage(self):
- self._call_main()
- self.assertIn('usage: cloud-init', self.stderr.getvalue())
-
- @test_helpers.skipIf(not os.path.isfile(BIN_CLOUDINIT), "no bin/cloudinit")
- def test_no_arguments_exits_2(self):
exit_code = self._call_main()
- if self.sys_exit.call_count:
- self.assertEqual(mock.call(2), self.sys_exit.call_args)
- else:
- self.assertEqual(2, exit_code)
+ self.assertIn('usage: cloud-init', self.stderr.getvalue())
+ self.assertEqual(2, exit_code)
- @test_helpers.skipIf(not os.path.isfile(BIN_CLOUDINIT), "no bin/cloudinit")
def test_no_arguments_shows_error_message(self):
- self._call_main()
+ exit_code = self._call_main()
self.assertIn('cloud-init: error: too few arguments',
self.stderr.getvalue())
+ self.assertEqual(2, exit_code)
diff --git a/tools/run-pep8 b/tools/run-pep8
index 086400fc..4bd0bbfb 100755
--- a/tools/run-pep8
+++ b/tools/run-pep8
@@ -1,8 +1,7 @@
#!/bin/bash
-pycheck_dirs=( "cloudinit/" "bin/" "tests/" "tools/" )
-# FIXME: cloud-init modifies sys module path, pep8 does not like
-# bin_files=( "bin/cloud-init" )
+pycheck_dirs=( "cloudinit/" "tests/" "tools/" )
+
CR="
"
[ "$1" = "-v" ] && { verbose="$1"; shift; } || verbose=""
diff --git a/tools/run-pyflakes b/tools/run-pyflakes
index 4bea17f4..b3759a94 100755
--- a/tools/run-pyflakes
+++ b/tools/run-pyflakes
@@ -3,7 +3,7 @@
PYTHON_VERSION=${PYTHON_VERSION:-2}
CR="
"
-pycheck_dirs=( "cloudinit/" "bin/" "tests/" "tools/" )
+pycheck_dirs=( "cloudinit/" "tests/" "tools/" )
set -f
if [ $# -eq 0 ]; then