summaryrefslogtreecommitdiff
path: root/ironic_python_agent
diff options
context:
space:
mode:
authorRussell Haering <russellhaering@gmail.com>2014-04-11 16:46:36 -0700
committerRussell Haering <russellhaering@gmail.com>2014-04-14 15:09:12 -0700
commit5ebd2e97977cc7b2ef2625b72db6bad5de757998 (patch)
tree658269a10e0de6790eabbd32548454c253ba8734 /ironic_python_agent
parent2960f71c64a52e9f4daf9bbb8d4fd06e923b213c (diff)
downloadironic-python-agent-5ebd2e97977cc7b2ef2625b72db6bad5de757998.tar.gz
Organize agent extensions
Move extensions under an ironic_python_agent.extensions module. This change also moves the @async_command() decorator into the base extension module. Change-Id: I4021fcc33a30f3460a31bca44a4bf776cd53d488
Diffstat (limited to 'ironic_python_agent')
-rw-r--r--ironic_python_agent/agent.py2
-rw-r--r--ironic_python_agent/decorators.py41
-rw-r--r--ironic_python_agent/extensions/__init__.py0
-rw-r--r--ironic_python_agent/extensions/base.py (renamed from ironic_python_agent/base.py)25
-rw-r--r--ironic_python_agent/extensions/decom.py (renamed from ironic_python_agent/decom.py)2
-rw-r--r--ironic_python_agent/extensions/flow.py (renamed from ironic_python_agent/flow.py)5
-rw-r--r--ironic_python_agent/extensions/standby.py (renamed from ironic_python_agent/standby.py)9
-rw-r--r--ironic_python_agent/tests/agent.py2
-rw-r--r--ironic_python_agent/tests/api.py2
-rw-r--r--ironic_python_agent/tests/extensions/__init__.py0
-rw-r--r--ironic_python_agent/tests/extensions/base.py (renamed from ironic_python_agent/tests/base.py)2
-rw-r--r--ironic_python_agent/tests/extensions/decom.py (renamed from ironic_python_agent/tests/decom.py)2
-rw-r--r--ironic_python_agent/tests/extensions/flow.py (renamed from ironic_python_agent/tests/flow.py)7
-rw-r--r--ironic_python_agent/tests/extensions/standby.py (renamed from ironic_python_agent/tests/standby.py)25
14 files changed, 56 insertions, 68 deletions
diff --git a/ironic_python_agent/agent.py b/ironic_python_agent/agent.py
index a611c04e..39c8368c 100644
--- a/ironic_python_agent/agent.py
+++ b/ironic_python_agent/agent.py
@@ -21,9 +21,9 @@ from stevedore import extension
from wsgiref import simple_server
from ironic_python_agent.api import app
-from ironic_python_agent import base
from ironic_python_agent import encoding
from ironic_python_agent import errors
+from ironic_python_agent.extensions import base
from ironic_python_agent import hardware
from ironic_python_agent import ironic_api_client
from ironic_python_agent.openstack.common import log
diff --git a/ironic_python_agent/decorators.py b/ironic_python_agent/decorators.py
deleted file mode 100644
index 30f7cf7c..00000000
--- a/ironic_python_agent/decorators.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2013 Rackspace, Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import functools
-
-from ironic_python_agent import base
-
-
-def async_command(validator=None):
- """Will run the command in an AsyncCommandResult in its own thread.
- command_name is set based on the func name and command_params will
- be whatever args/kwargs you pass into the decorated command.
- """
- def async_decorator(func):
- @functools.wraps(func)
- def wrapper(self, command_name, **command_params):
- # Run a validator before passing everything off to async.
- # validators should raise exceptions or return silently.
- if validator:
- validator(self, **command_params)
-
- # bind self to func so that AsyncCommandResult doesn't need to
- # know about the mode
- bound_func = functools.partial(func, self)
-
- return base.AsyncCommandResult(command_name,
- command_params,
- bound_func).start()
- return wrapper
- return async_decorator
diff --git a/ironic_python_agent/extensions/__init__.py b/ironic_python_agent/extensions/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ironic_python_agent/extensions/__init__.py
diff --git a/ironic_python_agent/base.py b/ironic_python_agent/extensions/base.py
index 8a795535..54fde2c6 100644
--- a/ironic_python_agent/base.py
+++ b/ironic_python_agent/extensions/base.py
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import functools
import threading
import uuid
@@ -192,3 +193,27 @@ class ExecuteCommandMixin(object):
self.command_results[result.id] = result
return result
+
+
+def async_command(validator=None):
+ """Will run the command in an AsyncCommandResult in its own thread.
+ command_name is set based on the func name and command_params will
+ be whatever args/kwargs you pass into the decorated command.
+ """
+ def async_decorator(func):
+ @functools.wraps(func)
+ def wrapper(self, command_name, **command_params):
+ # Run a validator before passing everything off to async.
+ # validators should raise exceptions or return silently.
+ if validator:
+ validator(self, **command_params)
+
+ # bind self to func so that AsyncCommandResult doesn't need to
+ # know about the mode
+ bound_func = functools.partial(func, self)
+
+ return AsyncCommandResult(command_name,
+ command_params,
+ bound_func).start()
+ return wrapper
+ return async_decorator
diff --git a/ironic_python_agent/decom.py b/ironic_python_agent/extensions/decom.py
index 85a138d8..6cd483fb 100644
--- a/ironic_python_agent/decom.py
+++ b/ironic_python_agent/extensions/decom.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from ironic_python_agent import base
+from ironic_python_agent.extensions import base
class DecomExtension(base.BaseAgentExtension):
diff --git a/ironic_python_agent/flow.py b/ironic_python_agent/extensions/flow.py
index 9d4d43ba..617eebac 100644
--- a/ironic_python_agent/flow.py
+++ b/ironic_python_agent/extensions/flow.py
@@ -14,9 +14,8 @@
from stevedore import enabled
-from ironic_python_agent import base
-from ironic_python_agent import decorators
from ironic_python_agent import errors
+from ironic_python_agent.extensions import base
from ironic_python_agent.openstack.common import log
LOG = log.getLogger(__name__)
@@ -51,7 +50,7 @@ class FlowExtension(base.BaseAgentExtension, base.ExecuteCommandMixin):
propagate_map_exceptions=True,
)
- @decorators.async_command(_validate_exts)
+ @base.async_command(_validate_exts)
def start_flow(self, command_name, flow=None):
for task in flow:
for method, params in task.items():
diff --git a/ironic_python_agent/standby.py b/ironic_python_agent/extensions/standby.py
index 133bcf71..a73086c8 100644
--- a/ironic_python_agent/standby.py
+++ b/ironic_python_agent/extensions/standby.py
@@ -18,10 +18,9 @@ import requests
import subprocess
import time
-from ironic_python_agent import base
from ironic_python_agent import configdrive
-from ironic_python_agent import decorators
from ironic_python_agent import errors
+from ironic_python_agent.extensions import base
from ironic_python_agent import hardware
from ironic_python_agent.openstack.common import log
@@ -160,7 +159,7 @@ class StandbyExtension(base.BaseAgentExtension):
self.cached_image_id = None
- @decorators.async_command(_validate_image_info)
+ @base.async_command(_validate_image_info)
def cache_image(self, command_name, image_info=None, force=False):
device = hardware.get_manager().get_os_install_device()
@@ -169,7 +168,7 @@ class StandbyExtension(base.BaseAgentExtension):
_write_image(image_info, device)
self.cached_image_id = image_info['id']
- @decorators.async_command(_validate_image_info)
+ @base.async_command(_validate_image_info)
def prepare_image(self,
command_name,
image_info=None,
@@ -188,7 +187,7 @@ class StandbyExtension(base.BaseAgentExtension):
configdrive.write_configdrive(location, metadata, files)
_copy_configdrive_to_disk(location, device)
- @decorators.async_command()
+ @base.async_command()
def run_image(self, command_name):
script = _path_to_script('shell/reboot.sh')
LOG.info('Rebooting system')
diff --git a/ironic_python_agent/tests/agent.py b/ironic_python_agent/tests/agent.py
index 680a8fb5..49fa28f8 100644
--- a/ironic_python_agent/tests/agent.py
+++ b/ironic_python_agent/tests/agent.py
@@ -22,10 +22,10 @@ import six
from wsgiref import simple_server
from ironic_python_agent import agent
-from ironic_python_agent import base
from ironic_python_agent.cmd import agent as agent_cmd
from ironic_python_agent import encoding
from ironic_python_agent import errors
+from ironic_python_agent.extensions import base
from ironic_python_agent import hardware
EXPECTED_ERROR = RuntimeError('command execution failed')
diff --git a/ironic_python_agent/tests/api.py b/ironic_python_agent/tests/api.py
index c5493267..c762a7c6 100644
--- a/ironic_python_agent/tests/api.py
+++ b/ironic_python_agent/tests/api.py
@@ -20,7 +20,7 @@ import pecan
import pecan.testing
from ironic_python_agent import agent
-from ironic_python_agent import base
+from ironic_python_agent.extensions import base
PATH_PREFIX = '/v1'
diff --git a/ironic_python_agent/tests/extensions/__init__.py b/ironic_python_agent/tests/extensions/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/ironic_python_agent/tests/extensions/__init__.py
diff --git a/ironic_python_agent/tests/base.py b/ironic_python_agent/tests/extensions/base.py
index 7b221e1b..8eb91554 100644
--- a/ironic_python_agent/tests/base.py
+++ b/ironic_python_agent/tests/extensions/base.py
@@ -16,8 +16,8 @@ import mock
from oslotest import base as test_base
from stevedore import extension
-from ironic_python_agent import base
from ironic_python_agent import errors
+from ironic_python_agent.extensions import base
class FakeExtension(base.BaseAgentExtension):
diff --git a/ironic_python_agent/tests/decom.py b/ironic_python_agent/tests/extensions/decom.py
index 8aa5a1a5..8d76c828 100644
--- a/ironic_python_agent/tests/decom.py
+++ b/ironic_python_agent/tests/extensions/decom.py
@@ -14,7 +14,7 @@
from oslotest import base as test_base
-from ironic_python_agent import decom
+from ironic_python_agent.extensions import decom
class TestDecomExtension(test_base.BaseTestCase):
diff --git a/ironic_python_agent/tests/flow.py b/ironic_python_agent/tests/extensions/flow.py
index 5369b049..d8b26ccb 100644
--- a/ironic_python_agent/tests/flow.py
+++ b/ironic_python_agent/tests/extensions/flow.py
@@ -19,10 +19,9 @@ from oslotest import base as test_base
from stevedore import enabled
from stevedore import extension
-from ironic_python_agent import base
-from ironic_python_agent import decorators
from ironic_python_agent import errors
-from ironic_python_agent import flow
+from ironic_python_agent.extensions import base
+from ironic_python_agent.extensions import flow
FLOW_INFO = [
@@ -42,7 +41,7 @@ class FakeExtension(base.BaseAgentExtension):
self.command_map['sleep'] = self.sleep
self.command_map['sync_sleep'] = self.sync_sleep
- @decorators.async_command()
+ @base.async_command()
def sleep(self, command_name, sleep_info=None):
time.sleep(sleep_info['time'])
diff --git a/ironic_python_agent/tests/standby.py b/ironic_python_agent/tests/extensions/standby.py
index b8911ba0..739cf96b 100644
--- a/ironic_python_agent/tests/standby.py
+++ b/ironic_python_agent/tests/extensions/standby.py
@@ -17,7 +17,7 @@ from oslotest import base as test_base
import six
from ironic_python_agent import errors
-from ironic_python_agent import standby
+from ironic_python_agent.extensions import standby
if six.PY2:
OPEN_FUNCTION_NAME = '__builtin__.open'
@@ -182,7 +182,8 @@ class TestStandbyExtension(test_base.BaseTestCase):
standby._download_image,
image_info)
- @mock.patch('ironic_python_agent.standby._verify_image', autospec=True)
+ @mock.patch('ironic_python_agent.extensions.standby._verify_image',
+ autospec=True)
@mock.patch(OPEN_FUNCTION_NAME, autospec=True)
@mock.patch('requests.get', autospec=True)
def test_download_image_verify_fails(self, requests_mock, open_mock,
@@ -224,8 +225,10 @@ class TestStandbyExtension(test_base.BaseTestCase):
self.assertEqual(md5_mock.call_count, 1)
@mock.patch('ironic_python_agent.hardware.get_manager', autospec=True)
- @mock.patch('ironic_python_agent.standby._write_image', autospec=True)
- @mock.patch('ironic_python_agent.standby._download_image', autospec=True)
+ @mock.patch('ironic_python_agent.extensions.standby._write_image',
+ autospec=True)
+ @mock.patch('ironic_python_agent.extensions.standby._download_image',
+ autospec=True)
def test_cache_image(self, download_mock, write_mock, hardware_mock):
image_info = self._build_fake_image_info()
download_mock.return_value = None
@@ -242,14 +245,18 @@ class TestStandbyExtension(test_base.BaseTestCase):
self.assertEqual('SUCCEEDED', async_result.command_status)
self.assertEqual(None, async_result.command_result)
- @mock.patch('ironic_python_agent.standby._copy_configdrive_to_disk',
+ @mock.patch(('ironic_python_agent.extensions.standby.'
+ '_copy_configdrive_to_disk'),
autospec=True)
- @mock.patch('ironic_python_agent.standby.configdrive.write_configdrive',
+ @mock.patch(('ironic_python_agent.extensions.standby.configdrive.'
+ 'write_configdrive'),
autospec=True)
@mock.patch('ironic_python_agent.hardware.get_manager', autospec=True)
- @mock.patch('ironic_python_agent.standby._write_image', autospec=True)
- @mock.patch('ironic_python_agent.standby._download_image', autospec=True)
- @mock.patch('ironic_python_agent.standby._configdrive_location',
+ @mock.patch('ironic_python_agent.extensions.standby._write_image',
+ autospec=True)
+ @mock.patch('ironic_python_agent.extensions.standby._download_image',
+ autospec=True)
+ @mock.patch('ironic_python_agent.extensions.standby._configdrive_location',
autospec=True)
def test_prepare_image(self,
location_mock,