Merge pull request #72 from rackerlabs/JoshNang/ipa
Rename to Ironic Python Agent
This commit is contained in:
commit
0e6776f6c0
.testr.confDockerfileREADME.md
imagebuild
README.md
coreos
ironic_python_agent
__init__.pyagent.py
openstack-common.confsetup.cfgtox.iniapi
base.pycmd
configdrive.pydecom.pydecorators.pyencoding.pyerrors.pyhardware.pyironic_api_client.pyopenstack
shell
standby.pytests
utils.py@ -1,4 +1,4 @@
|
|||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_TEST_TIMEOUT=60 ${PYTHON:-python} -m subunit.run discover -s teeth_agent/tests/ -p "*.py" $LISTOPT $IDOPTION
|
test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_TEST_TIMEOUT=60 ${PYTHON:-python} -m subunit.run discover -s ironic_python_agent/tests/ -p "*.py" $LISTOPT $IDOPTION
|
||||||
test_id_option=--load-list $IDFILE
|
test_id_option=--load-list $IDFILE
|
||||||
test_list_option=--list
|
test_list_option=--list
|
||||||
|
14
Dockerfile
14
Dockerfile
@ -3,17 +3,19 @@ FROM jayofdoom/docker-ubuntu-14.04
|
|||||||
# The add is before the RUN to ensure we get the latest version of packages
|
# The add is before the RUN to ensure we get the latest version of packages
|
||||||
# Docker will cache RUN commands, but because the SHA1 of the dir will be
|
# Docker will cache RUN commands, but because the SHA1 of the dir will be
|
||||||
# different it will not cache this layer
|
# different it will not cache this layer
|
||||||
ADD . /tmp/teeth-agent
|
ADD . /tmp/ironic-python-agent
|
||||||
|
|
||||||
# Install requirements: Python for teeth-agent, others for putting an image on disk
|
# Install requirements: Python for ironic-python-agent, others for putting an
|
||||||
|
# image on disk
|
||||||
RUN apt-get update && apt-get -y install \
|
RUN apt-get update && apt-get -y install \
|
||||||
python python-pip python-dev \
|
python python-pip python-dev \
|
||||||
qemu-utils parted util-linux genisoimage git
|
qemu-utils parted util-linux genisoimage git
|
||||||
|
|
||||||
# Install requirements separately, because pip understands a git+https url while setuptools doesn't
|
# Install requirements separately, because pip understands a git+https url
|
||||||
RUN pip install -r /tmp/teeth-agent/requirements.txt
|
# while setuptools doesn't
|
||||||
|
RUN pip install -r /tmp/ironic-python-agent/requirements.txt
|
||||||
|
|
||||||
# This will succeed because all the dependencies were installed previously
|
# This will succeed because all the dependencies were installed previously
|
||||||
RUN pip install /tmp/teeth-agent
|
RUN pip install /tmp/ironic-python-agent
|
||||||
|
|
||||||
CMD [ "/usr/local/bin/teeth-agent" ]
|
CMD [ "/usr/local/bin/ironic-python-agent" ]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# teeth-agent
|
# ironic-python-agent
|
||||||
|
|
||||||
[](https://travis-ci.org/rackerlabs/teeth-agent)
|
[](https://travis-ci.org/rackerlabs/teeth-agent)
|
||||||
|
|
||||||
An agent for rebuilding and controlling Teeth chassis.
|
An agent for rebuilding and controlling Ironic nodes.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
teeth-agent images
|
ironic-python-agent images
|
||||||
==================
|
==================
|
||||||
|
|
||||||
coreos - Builds a CoreOS Ramdisk and Kernel suitable for running teeth-agent
|
coreos - Builds a CoreOS Ramdisk and Kernel suitable for running ironic-python-agent
|
||||||
|
@ -8,7 +8,7 @@ coreos:
|
|||||||
./coreos-oem-inject.py oem UPLOAD
|
./coreos-oem-inject.py oem UPLOAD
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf teeth-agent
|
rm -rf ironic-python-agent
|
||||||
rm -f oem/container.tar.gz
|
rm -f oem/container.tar.gz
|
||||||
rm -f UPLOAD/coreos_production_pxe_image-oem.cpio.gz
|
rm -f UPLOAD/coreos_production_pxe_image-oem.cpio.gz
|
||||||
rm -f UPLOAD/coreos_production_pxe.vmlinuz
|
rm -f UPLOAD/coreos_production_pxe.vmlinuz
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# teeth-agent CoreOS Image builder.
|
# ironic-python-agent CoreOS Image builder.
|
||||||
|
|
||||||
Builds a CoreOS image suitable for running the teeth-agent on a server.
|
Builds a CoreOS image suitable for running the ironic-python-agent on a server.
|
||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ if [[ -e "${OUTPUT_FILE}" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Build the docker image
|
# Build the docker image
|
||||||
cd ../../teeth-agent
|
cd ../../ironic-python-agent
|
||||||
docker build -t oemdocker .
|
docker build -t oemdocker .
|
||||||
cd -
|
cd -
|
||||||
|
|
||||||
|
@ -28,4 +28,4 @@ done
|
|||||||
docker load < container.tar.gz
|
docker load < container.tar.gz
|
||||||
|
|
||||||
systemctl enable --runtime /usr/share/oem/system/*
|
systemctl enable --runtime /usr/share/oem/system/*
|
||||||
systemctl start teeth-agent.service
|
systemctl start ironic-python-agent.service
|
||||||
|
6
imagebuild/coreos/oem/system/ironic-python-agent.service
Normal file
6
imagebuild/coreos/oem/system/ironic-python-agent.service
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[Service]
|
||||||
|
ExecStart=/usr/bin/docker run -p 9999:9999 -privileged=true -v=/sys:/mnt/sys oemdocker /usr/local/bin/ironic-python-agent --ipaddr="`ip a | grep '10\.' | sed -e 's/inet \(10\.[0-9\.]\+\).*/\1/'`"
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=oem.target
|
@ -1,6 +0,0 @@
|
|||||||
[Service]
|
|
||||||
ExecStart=/usr/bin/docker run -p 9999:9999 -privileged=true -v=/sys:/mnt/sys oemdocker /usr/local/bin/teeth-agent --ipaddr="`ip a | grep '10\.' | sed -e 's/inet \(10\.[0-9\.]\+\).*/\1/'`"
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=oem.target
|
|
@ -22,14 +22,14 @@ import pkg_resources
|
|||||||
from stevedore import driver
|
from stevedore import driver
|
||||||
from wsgiref import simple_server
|
from wsgiref import simple_server
|
||||||
|
|
||||||
from teeth_agent.api import app
|
from ironic_python_agent.api import app
|
||||||
from teeth_agent import base
|
from ironic_python_agent import base
|
||||||
from teeth_agent import encoding
|
from ironic_python_agent import encoding
|
||||||
from teeth_agent import errors
|
from ironic_python_agent import errors
|
||||||
from teeth_agent import hardware
|
from ironic_python_agent import hardware
|
||||||
from teeth_agent.openstack.common import log
|
from ironic_python_agent import ironic_api_client
|
||||||
from teeth_agent import overlord_agent_api
|
from ironic_python_agent.openstack.common import log
|
||||||
from teeth_agent import utils
|
from ironic_python_agent import utils
|
||||||
|
|
||||||
|
|
||||||
def _time():
|
def _time():
|
||||||
@ -37,7 +37,7 @@ def _time():
|
|||||||
return time.time()
|
return time.time()
|
||||||
|
|
||||||
|
|
||||||
class TeethAgentStatus(encoding.Serializable):
|
class IronicPythonAgentStatus(encoding.Serializable):
|
||||||
def __init__(self, mode, started_at, version):
|
def __init__(self, mode, started_at, version):
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
self.started_at = started_at
|
self.started_at = started_at
|
||||||
@ -52,7 +52,7 @@ class TeethAgentStatus(encoding.Serializable):
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
class TeethAgentHeartbeater(threading.Thread):
|
class IronicPythonAgentHeartbeater(threading.Thread):
|
||||||
# If we could wait at most N seconds between heartbeats (or in case of an
|
# If we could wait at most N seconds between heartbeats (or in case of an
|
||||||
# error) we will instead wait r x N seconds, where r is a random value
|
# error) we will instead wait r x N seconds, where r is a random value
|
||||||
# between these multipliers.
|
# between these multipliers.
|
||||||
@ -67,10 +67,10 @@ class TeethAgentHeartbeater(threading.Thread):
|
|||||||
backoff_factor = 2.7
|
backoff_factor = 2.7
|
||||||
|
|
||||||
def __init__(self, agent):
|
def __init__(self, agent):
|
||||||
super(TeethAgentHeartbeater, self).__init__()
|
super(IronicPythonAgentHeartbeater, self).__init__()
|
||||||
self.agent = agent
|
self.agent = agent
|
||||||
self.hardware = hardware.get_manager()
|
self.hardware = hardware.get_manager()
|
||||||
self.api = overlord_agent_api.APIClient(agent.api_url)
|
self.api = ironic_api_client.APIClient(agent.api_url)
|
||||||
self.log = log.getLogger(__name__)
|
self.log = log.getLogger(__name__)
|
||||||
self.stop_event = threading.Event()
|
self.stop_event = threading.Event()
|
||||||
self.error_delay = self.initial_delay
|
self.error_delay = self.initial_delay
|
||||||
@ -111,17 +111,18 @@ class TeethAgentHeartbeater(threading.Thread):
|
|||||||
return self.join()
|
return self.join()
|
||||||
|
|
||||||
|
|
||||||
class TeethAgent(object):
|
class IronicPythonAgent(object):
|
||||||
def __init__(self, api_url, advertise_address, listen_address):
|
def __init__(self, api_url, advertise_address, listen_address):
|
||||||
self.api_url = api_url
|
self.api_url = api_url
|
||||||
self.api_client = overlord_agent_api.APIClient(self.api_url)
|
self.api_client = ironic_api_client.APIClient(self.api_url)
|
||||||
self.listen_address = listen_address
|
self.listen_address = listen_address
|
||||||
self.advertise_address = advertise_address
|
self.advertise_address = advertise_address
|
||||||
self.mode_implementation = None
|
self.mode_implementation = None
|
||||||
self.version = pkg_resources.get_distribution('teeth-agent').version
|
self.version = pkg_resources.get_distribution('ironic-python-agent')\
|
||||||
|
.version
|
||||||
self.api = app.VersionSelectorApplication(self)
|
self.api = app.VersionSelectorApplication(self)
|
||||||
self.command_results = utils.get_ordereddict()
|
self.command_results = utils.get_ordereddict()
|
||||||
self.heartbeater = TeethAgentHeartbeater(self)
|
self.heartbeater = IronicPythonAgentHeartbeater(self)
|
||||||
self.hardware = hardware.get_manager()
|
self.hardware = hardware.get_manager()
|
||||||
self.command_lock = threading.Lock()
|
self.command_lock = threading.Lock()
|
||||||
self.log = log.getLogger(__name__)
|
self.log = log.getLogger(__name__)
|
||||||
@ -136,7 +137,7 @@ class TeethAgent(object):
|
|||||||
|
|
||||||
def get_status(self):
|
def get_status(self):
|
||||||
"""Retrieve a serializable status."""
|
"""Retrieve a serializable status."""
|
||||||
return TeethAgentStatus(
|
return IronicPythonAgentStatus(
|
||||||
mode=self.get_mode_name(),
|
mode=self.get_mode_name(),
|
||||||
started_at=self.started_at,
|
started_at=self.started_at,
|
||||||
version=self.version
|
version=self.version
|
||||||
@ -209,7 +210,7 @@ class TeethAgent(object):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Run the Teeth Agent."""
|
"""Run the Ironic Python Agent."""
|
||||||
self.started_at = _time()
|
self.started_at = _time()
|
||||||
# Get the UUID so we can heartbeat to Ironic
|
# Get the UUID so we can heartbeat to Ironic
|
||||||
self.node = self.api_client.lookup_node(
|
self.node = self.api_client.lookup_node(
|
||||||
@ -232,7 +233,7 @@ class TeethAgent(object):
|
|||||||
|
|
||||||
def _load_mode_implementation(mode_name):
|
def _load_mode_implementation(mode_name):
|
||||||
mgr = driver.DriverManager(
|
mgr = driver.DriverManager(
|
||||||
namespace='teeth_agent.modes',
|
namespace='ironic_python_agent.modes',
|
||||||
name=mode_name.lower(),
|
name=mode_name.lower(),
|
||||||
invoke_on_load=True,
|
invoke_on_load=True,
|
||||||
invoke_args=[],
|
invoke_args=[],
|
||||||
@ -246,6 +247,6 @@ def build_agent(api_url,
|
|||||||
listen_host,
|
listen_host,
|
||||||
listen_port):
|
listen_port):
|
||||||
|
|
||||||
return TeethAgent(api_url,
|
return IronicPythonAgent(api_url,
|
||||||
(advertise_host, advertise_port),
|
(advertise_host, advertise_port),
|
||||||
(listen_host, listen_port))
|
(listen_host, listen_port))
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||||||
import pecan
|
import pecan
|
||||||
from pecan import hooks
|
from pecan import hooks
|
||||||
|
|
||||||
from teeth_agent.api import config
|
from ironic_python_agent.api import config
|
||||||
|
|
||||||
|
|
||||||
class AgentHook(hooks.PecanHook):
|
class AgentHook(hooks.PecanHook):
|
@ -24,8 +24,8 @@ server = {
|
|||||||
# Pecan Application Configurations
|
# Pecan Application Configurations
|
||||||
# See https://pecan.readthedocs.org/en/latest/configuration.html#application-configuration # noqa
|
# See https://pecan.readthedocs.org/en/latest/configuration.html#application-configuration # noqa
|
||||||
app = {
|
app = {
|
||||||
'root': 'teeth_agent.api.controllers.root.RootController',
|
'root': 'ironic_python_agent.api.controllers.root.RootController',
|
||||||
'modules': ['teeth_agent.api'],
|
'modules': ['ironic_python_agent.api'],
|
||||||
'static_root': '%(confdir)s/public',
|
'static_root': '%(confdir)s/public',
|
||||||
'debug': False,
|
'debug': False,
|
||||||
'enable_acl': True,
|
'enable_acl': True,
|
@ -18,9 +18,9 @@ from pecan import rest
|
|||||||
from wsme import types as wtypes
|
from wsme import types as wtypes
|
||||||
import wsmeext.pecan as wsme_pecan
|
import wsmeext.pecan as wsme_pecan
|
||||||
|
|
||||||
from teeth_agent.api.controllers import v1
|
from ironic_python_agent.api.controllers import v1
|
||||||
from teeth_agent.api.controllers.v1 import base
|
from ironic_python_agent.api.controllers.v1 import base
|
||||||
from teeth_agent.api.controllers.v1 import link
|
from ironic_python_agent.api.controllers.v1 import link
|
||||||
|
|
||||||
|
|
||||||
class Version(base.APIBase):
|
class Version(base.APIBase):
|
@ -22,10 +22,10 @@ from pecan import rest
|
|||||||
from wsme import types as wtypes
|
from wsme import types as wtypes
|
||||||
import wsmeext.pecan as wsme_pecan
|
import wsmeext.pecan as wsme_pecan
|
||||||
|
|
||||||
from teeth_agent.api.controllers.v1 import base
|
from ironic_python_agent.api.controllers.v1 import base
|
||||||
from teeth_agent.api.controllers.v1 import command
|
from ironic_python_agent.api.controllers.v1 import command
|
||||||
from teeth_agent.api.controllers.v1 import link
|
from ironic_python_agent.api.controllers.v1 import link
|
||||||
from teeth_agent.api.controllers.v1 import status
|
from ironic_python_agent.api.controllers.v1 import status
|
||||||
|
|
||||||
|
|
||||||
class MediaType(base.APIBase):
|
class MediaType(base.APIBase):
|
@ -18,7 +18,7 @@ from pecan import rest
|
|||||||
from wsme import types
|
from wsme import types
|
||||||
from wsmeext import pecan as wsme_pecan
|
from wsmeext import pecan as wsme_pecan
|
||||||
|
|
||||||
from teeth_agent.api.controllers.v1 import base
|
from ironic_python_agent.api.controllers.v1 import base
|
||||||
|
|
||||||
|
|
||||||
class CommandResult(base.APIBase):
|
class CommandResult(base.APIBase):
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
from wsme import types as wtypes
|
from wsme import types as wtypes
|
||||||
|
|
||||||
from teeth_agent.api.controllers.v1 import base
|
from ironic_python_agent.api.controllers.v1 import base
|
||||||
|
|
||||||
|
|
||||||
class Link(base.APIBase):
|
class Link(base.APIBase):
|
@ -18,7 +18,7 @@ from pecan import rest
|
|||||||
from wsme import types
|
from wsme import types
|
||||||
from wsmeext import pecan as wsme_pecan
|
from wsmeext import pecan as wsme_pecan
|
||||||
|
|
||||||
from teeth_agent.api.controllers.v1 import base
|
from ironic_python_agent.api.controllers.v1 import base
|
||||||
|
|
||||||
|
|
||||||
class AgentStatus(base.APIBase):
|
class AgentStatus(base.APIBase):
|
@ -18,9 +18,9 @@ import threading
|
|||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
from teeth_agent import encoding
|
from ironic_python_agent import encoding
|
||||||
from teeth_agent import errors
|
from ironic_python_agent import errors
|
||||||
from teeth_agent.openstack.common import log
|
from ironic_python_agent.openstack.common import log
|
||||||
|
|
||||||
|
|
||||||
class AgentCommandStatus(object):
|
class AgentCommandStatus(object):
|
@ -16,17 +16,17 @@ limitations under the License.
|
|||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from teeth_agent import agent
|
from ironic_python_agent import agent
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description=('An agent that handles decomissioning and provisioning'
|
description=('An agent that handles decomissioning and provisioning'
|
||||||
' on behalf of teeth-overlord.'))
|
' on behalf of Ironic.'))
|
||||||
|
|
||||||
parser.add_argument('--api-url',
|
parser.add_argument('--api-url',
|
||||||
required=True,
|
required=True,
|
||||||
help='URL of the Teeth agent API')
|
help='URL of the Ironic API')
|
||||||
|
|
||||||
parser.add_argument('--listen-host',
|
parser.add_argument('--listen-host',
|
||||||
default='0.0.0.0',
|
default='0.0.0.0',
|
@ -15,9 +15,11 @@ limitations under the License.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from teeth_agent import utils
|
|
||||||
|
from ironic_python_agent import utils
|
||||||
|
|
||||||
|
|
||||||
class ConfigDriveWriter(object):
|
class ConfigDriveWriter(object):
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from teeth_agent import base
|
from ironic_python_agent import base
|
||||||
|
|
||||||
|
|
||||||
class DecomMode(base.BaseAgentMode):
|
class DecomMode(base.BaseAgentMode):
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||||||
"""
|
"""
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
from teeth_agent import base
|
from ironic_python_agent import base
|
||||||
|
|
||||||
|
|
||||||
def async_command(validator=None):
|
def async_command(validator=None):
|
@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from teeth_agent import encoding
|
from ironic_python_agent import encoding
|
||||||
from teeth_agent import utils
|
from ironic_python_agent import utils
|
||||||
|
|
||||||
|
|
||||||
class RESTError(Exception, encoding.Serializable):
|
class RESTError(Exception, encoding.Serializable):
|
||||||
"""Base class for errors generated in teeth."""
|
"""Base class for errors generated in ironic-python-client."""
|
||||||
message = 'An error occurred'
|
message = 'An error occurred'
|
||||||
details = 'An unexpected error occurred. Please try back later.'
|
details = 'An unexpected error occurred. Please try back later.'
|
||||||
status_code = 500
|
status_code = 500
|
||||||
@ -91,17 +91,17 @@ class RequestedObjectNotFoundError(NotFound):
|
|||||||
self.details = details
|
self.details = details
|
||||||
|
|
||||||
|
|
||||||
class OverlordAPIError(RESTError):
|
class IronicAPIError(RESTError):
|
||||||
"""Error raised when a call to the agent API fails."""
|
"""Error raised when a call to the agent API fails."""
|
||||||
|
|
||||||
message = 'Error in call to teeth-agent-api.'
|
message = 'Error in call to ironic-api.'
|
||||||
|
|
||||||
def __init__(self, details):
|
def __init__(self, details):
|
||||||
super(OverlordAPIError, self).__init__(details)
|
super(IronicAPIError, self).__init__(details)
|
||||||
self.details = details
|
self.details = details
|
||||||
|
|
||||||
|
|
||||||
class HeartbeatError(OverlordAPIError):
|
class HeartbeatError(IronicAPIError):
|
||||||
"""Error raised when a heartbeat to the agent API fails."""
|
"""Error raised when a heartbeat to the agent API fails."""
|
||||||
|
|
||||||
message = 'Error heartbeating to agent API.'
|
message = 'Error heartbeating to agent API.'
|
||||||
@ -110,7 +110,7 @@ class HeartbeatError(OverlordAPIError):
|
|||||||
super(HeartbeatError, self).__init__(details)
|
super(HeartbeatError, self).__init__(details)
|
||||||
|
|
||||||
|
|
||||||
class LookupNodeError(OverlordAPIError):
|
class LookupNodeError(IronicAPIError):
|
||||||
"""Error raised when the node configuration lookup to the Ironic API
|
"""Error raised when the node configuration lookup to the Ironic API
|
||||||
fails.
|
fails.
|
||||||
"""
|
"""
|
@ -20,9 +20,9 @@ import subprocess
|
|||||||
|
|
||||||
import stevedore
|
import stevedore
|
||||||
|
|
||||||
from teeth_agent import encoding
|
from ironic_python_agent import encoding
|
||||||
from teeth_agent.openstack.common import log
|
from ironic_python_agent.openstack.common import log
|
||||||
from teeth_agent import utils
|
from ironic_python_agent import utils
|
||||||
|
|
||||||
_global_manager = None
|
_global_manager = None
|
||||||
|
|
||||||
@ -30,9 +30,9 @@ _global_manager = None
|
|||||||
class HardwareSupport(object):
|
class HardwareSupport(object):
|
||||||
"""These are just guidelines to suggest values that might be returned by
|
"""These are just guidelines to suggest values that might be returned by
|
||||||
calls to `evaluate_hardware_support`. No HardwareManager in mainline
|
calls to `evaluate_hardware_support`. No HardwareManager in mainline
|
||||||
teeth-agent will ever offer a value greater than `MAINLINE`. Service
|
ironic-python-agent will ever offer a value greater than `MAINLINE`.
|
||||||
Providers should feel free to return values greater than SERVICE_PROVIDER
|
Service Providers should feel free to return values greater than
|
||||||
to distinguish between additional levels of support.
|
SERVICE_PROVIDER to distinguish between additional levels of support.
|
||||||
"""
|
"""
|
||||||
NONE = 0
|
NONE = 0
|
||||||
GENERIC = 1
|
GENERIC = 1
|
||||||
@ -164,7 +164,7 @@ def get_manager():
|
|||||||
if not _global_manager:
|
if not _global_manager:
|
||||||
LOG = log.getLogger()
|
LOG = log.getLogger()
|
||||||
extension_manager = stevedore.ExtensionManager(
|
extension_manager = stevedore.ExtensionManager(
|
||||||
namespace='teeth_agent.hardware_managers',
|
namespace='ironic_python_agent.hardware_managers',
|
||||||
invoke_on_load=True)
|
invoke_on_load=True)
|
||||||
|
|
||||||
# There will always be at least one extension available (the
|
# There will always be at least one extension available (the
|
@ -18,8 +18,8 @@ import json
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from teeth_agent import encoding
|
from ironic_python_agent import encoding
|
||||||
from teeth_agent import errors
|
from ironic_python_agent import errors
|
||||||
|
|
||||||
|
|
||||||
class APIClient(object):
|
class APIClient(object):
|
14
teeth_agent/openstack/common/gettextutils.py → ironic_python_agent/openstack/common/gettextutils.py
14
teeth_agent/openstack/common/gettextutils.py → ironic_python_agent/openstack/common/gettextutils.py
@ -19,7 +19,7 @@ gettext for openstack-common modules.
|
|||||||
|
|
||||||
Usual usage in an openstack.common module:
|
Usual usage in an openstack.common module:
|
||||||
|
|
||||||
from teeth_agent.openstack.common.gettextutils import _
|
from ironic_python_agent.openstack.common.gettextutils import _
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
@ -32,15 +32,15 @@ import os
|
|||||||
from babel import localedata
|
from babel import localedata
|
||||||
import six
|
import six
|
||||||
|
|
||||||
_localedir = os.environ.get('teeth_agent'.upper() + '_LOCALEDIR')
|
_localedir = os.environ.get('ironic_python_agent'.upper() + '_LOCALEDIR')
|
||||||
_t = gettext.translation('teeth_agent', localedir=_localedir, fallback=True)
|
_t = gettext.translation('ironic_python_agent', localedir=_localedir, fallback=True)
|
||||||
|
|
||||||
# We use separate translation catalogs for each log level, so set up a
|
# We use separate translation catalogs for each log level, so set up a
|
||||||
# mapping between the log level name and the translator. The domain
|
# mapping between the log level name and the translator. The domain
|
||||||
# for the log level is project_name + "-log-" + log_level so messages
|
# for the log level is project_name + "-log-" + log_level so messages
|
||||||
# for each level end up in their own catalog.
|
# for each level end up in their own catalog.
|
||||||
_t_log_levels = dict(
|
_t_log_levels = dict(
|
||||||
(level, gettext.translation('teeth_agent' + '-log-' + level,
|
(level, gettext.translation('ironic_python_agent' + '-log-' + level,
|
||||||
localedir=_localedir,
|
localedir=_localedir,
|
||||||
fallback=True))
|
fallback=True))
|
||||||
for level in ['info', 'warning', 'error', 'critical']
|
for level in ['info', 'warning', 'error', 'critical']
|
||||||
@ -64,7 +64,7 @@ def enable_lazy():
|
|||||||
|
|
||||||
def _(msg):
|
def _(msg):
|
||||||
if USE_LAZY:
|
if USE_LAZY:
|
||||||
return Message(msg, domain='teeth_agent')
|
return Message(msg, domain='ironic_python_agent')
|
||||||
else:
|
else:
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
return _t.gettext(msg)
|
return _t.gettext(msg)
|
||||||
@ -75,7 +75,7 @@ def _log_translation(msg, level):
|
|||||||
"""Build a single translation of a log message
|
"""Build a single translation of a log message
|
||||||
"""
|
"""
|
||||||
if USE_LAZY:
|
if USE_LAZY:
|
||||||
return Message(msg, domain='teeth_agent' + '-log-' + level)
|
return Message(msg, domain='ironic_python_agent' + '-log-' + level)
|
||||||
else:
|
else:
|
||||||
translator = _t_log_levels[level]
|
translator = _t_log_levels[level]
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
@ -152,7 +152,7 @@ class Message(six.text_type):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __new__(cls, msgid, msgtext=None, params=None,
|
def __new__(cls, msgid, msgtext=None, params=None,
|
||||||
domain='teeth_agent', *args):
|
domain='ironic_python_agent', *args):
|
||||||
"""Create a new Message object.
|
"""Create a new Message object.
|
||||||
|
|
||||||
In order for translation to work gettext requires a message ID, this
|
In order for translation to work gettext requires a message ID, this
|
@ -59,7 +59,7 @@ def import_module(import_str):
|
|||||||
|
|
||||||
|
|
||||||
def import_versioned_module(version, submodule=None):
|
def import_versioned_module(version, submodule=None):
|
||||||
module = 'teeth_agent.v%s' % version
|
module = 'ironic_python_agent.v%s' % version
|
||||||
if submodule:
|
if submodule:
|
||||||
module = '.'.join((module, submodule))
|
module = '.'.join((module, submodule))
|
||||||
return import_module(module)
|
return import_module(module)
|
@ -40,9 +40,9 @@ import json
|
|||||||
import six
|
import six
|
||||||
import six.moves.xmlrpc_client as xmlrpclib
|
import six.moves.xmlrpc_client as xmlrpclib
|
||||||
|
|
||||||
from teeth_agent.openstack.common import gettextutils
|
from ironic_python_agent.openstack.common import gettextutils
|
||||||
from teeth_agent.openstack.common import importutils
|
from ironic_python_agent.openstack.common import importutils
|
||||||
from teeth_agent.openstack.common import timeutils
|
from ironic_python_agent.openstack.common import timeutils
|
||||||
|
|
||||||
netaddr = importutils.try_import("netaddr")
|
netaddr = importutils.try_import("netaddr")
|
||||||
|
|
@ -41,10 +41,10 @@ from oslo.config import cfg
|
|||||||
import six
|
import six
|
||||||
from six import moves
|
from six import moves
|
||||||
|
|
||||||
from teeth_agent.openstack.common.gettextutils import _
|
from ironic_python_agent.openstack.common.gettextutils import _
|
||||||
from teeth_agent.openstack.common import importutils
|
from ironic_python_agent.openstack.common import importutils
|
||||||
from teeth_agent.openstack.common import jsonutils
|
from ironic_python_agent.openstack.common import jsonutils
|
||||||
from teeth_agent.openstack.common import local
|
from ironic_python_agent.openstack.common import local
|
||||||
|
|
||||||
|
|
||||||
_DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
|
_DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
|
||||||
@ -537,7 +537,7 @@ def _setup_logging_from_conf(project, version):
|
|||||||
|
|
||||||
if CONF.publish_errors:
|
if CONF.publish_errors:
|
||||||
handler = importutils.import_object(
|
handler = importutils.import_object(
|
||||||
"teeth_agent.openstack.common.log_handler.PublishErrorsHandler",
|
"ironic_python_agent.openstack.common.log_handler.PublishErrorsHandler",
|
||||||
logging.ERROR)
|
logging.ERROR)
|
||||||
log_root.addHandler(handler)
|
log_root.addHandler(handler)
|
||||||
|
|
@ -37,7 +37,7 @@ genisoimage \
|
|||||||
-allow-lowercase \
|
-allow-lowercase \
|
||||||
-allow-multidot \
|
-allow-multidot \
|
||||||
-l \
|
-l \
|
||||||
-publisher "teeth" \
|
-publisher "ironic" \
|
||||||
-J \
|
-J \
|
||||||
-r \
|
-r \
|
||||||
-V 'config-2' \
|
-V 'config-2' \
|
@ -20,12 +20,12 @@ import requests
|
|||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from teeth_agent import base
|
from ironic_python_agent import base
|
||||||
from teeth_agent import configdrive
|
from ironic_python_agent import configdrive
|
||||||
from teeth_agent import decorators
|
from ironic_python_agent import decorators
|
||||||
from teeth_agent import errors
|
from ironic_python_agent import errors
|
||||||
from teeth_agent import hardware
|
from ironic_python_agent import hardware
|
||||||
from teeth_agent.openstack.common import log
|
from ironic_python_agent.openstack.common import log
|
||||||
|
|
||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
@ -22,12 +22,11 @@ import mock
|
|||||||
import pkg_resources
|
import pkg_resources
|
||||||
from wsgiref import simple_server
|
from wsgiref import simple_server
|
||||||
|
|
||||||
|
from ironic_python_agent import agent
|
||||||
from teeth_agent import agent
|
from ironic_python_agent import base
|
||||||
from teeth_agent import base
|
from ironic_python_agent import encoding
|
||||||
from teeth_agent import encoding
|
from ironic_python_agent import errors
|
||||||
from teeth_agent import errors
|
from ironic_python_agent import hardware
|
||||||
from teeth_agent import hardware
|
|
||||||
|
|
||||||
EXPECTED_ERROR = RuntimeError('command execution failed')
|
EXPECTED_ERROR = RuntimeError('command execution failed')
|
||||||
|
|
||||||
@ -47,13 +46,13 @@ class FakeMode(base.BaseAgentMode):
|
|||||||
class TestHeartbeater(unittest.TestCase):
|
class TestHeartbeater(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.mock_agent = mock.Mock()
|
self.mock_agent = mock.Mock()
|
||||||
self.heartbeater = agent.TeethAgentHeartbeater(self.mock_agent)
|
self.heartbeater = agent.IronicPythonAgentHeartbeater(self.mock_agent)
|
||||||
self.heartbeater.api = mock.Mock()
|
self.heartbeater.api = mock.Mock()
|
||||||
self.heartbeater.hardware = mock.create_autospec(
|
self.heartbeater.hardware = mock.create_autospec(
|
||||||
hardware.HardwareManager)
|
hardware.HardwareManager)
|
||||||
self.heartbeater.stop_event = mock.Mock()
|
self.heartbeater.stop_event = mock.Mock()
|
||||||
|
|
||||||
@mock.patch('teeth_agent.agent._time')
|
@mock.patch('ironic_python_agent.agent._time')
|
||||||
@mock.patch('random.uniform')
|
@mock.patch('random.uniform')
|
||||||
def test_heartbeat(self, mocked_uniform, mocked_time):
|
def test_heartbeat(self, mocked_uniform, mocked_time):
|
||||||
time_responses = []
|
time_responses = []
|
||||||
@ -119,9 +118,10 @@ class TestHeartbeater(unittest.TestCase):
|
|||||||
class TestBaseAgent(unittest.TestCase):
|
class TestBaseAgent(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.encoder = encoding.RESTJSONEncoder(indent=4)
|
self.encoder = encoding.RESTJSONEncoder(indent=4)
|
||||||
self.agent = agent.TeethAgent('https://fake_api.example.org:8081/',
|
self.agent = agent.IronicPythonAgent('https://fake_api.example.'
|
||||||
('203.0.113.1', 9990),
|
'org:8081/',
|
||||||
('192.0.2.1', 9999))
|
('203.0.113.1', 9990),
|
||||||
|
('192.0.2.1', 9999))
|
||||||
|
|
||||||
def assertEqualEncoded(self, a, b):
|
def assertEqualEncoded(self, a, b):
|
||||||
# Evidently JSONEncoder.default() can't handle None (??) so we have to
|
# Evidently JSONEncoder.default() can't handle None (??) so we have to
|
||||||
@ -136,10 +136,11 @@ class TestBaseAgent(unittest.TestCase):
|
|||||||
self.agent.started_at = started_at
|
self.agent.started_at = started_at
|
||||||
|
|
||||||
status = self.agent.get_status()
|
status = self.agent.get_status()
|
||||||
self.assertTrue(isinstance(status, agent.TeethAgentStatus))
|
self.assertTrue(isinstance(status, agent.IronicPythonAgentStatus))
|
||||||
self.assertEqual(status.started_at, started_at)
|
self.assertEqual(status.started_at, started_at)
|
||||||
self.assertEqual(status.version,
|
self.assertEqual(status.version,
|
||||||
pkg_resources.get_distribution('teeth-agent').version)
|
pkg_resources.get_distribution('ironic-python-agent')
|
||||||
|
.version)
|
||||||
|
|
||||||
def test_execute_command(self):
|
def test_execute_command(self):
|
||||||
do_something_impl = mock.Mock()
|
do_something_impl = mock.Mock()
|
@ -21,17 +21,17 @@ import unittest
|
|||||||
import pecan
|
import pecan
|
||||||
import pecan.testing
|
import pecan.testing
|
||||||
|
|
||||||
from teeth_agent import agent
|
from ironic_python_agent import agent
|
||||||
from teeth_agent import base
|
from ironic_python_agent import base
|
||||||
|
|
||||||
|
|
||||||
PATH_PREFIX = '/v1'
|
PATH_PREFIX = '/v1'
|
||||||
|
|
||||||
|
|
||||||
class TestTeethAPI(unittest.TestCase):
|
class TestIronicAPI(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestTeethAPI, self).setUp()
|
super(TestIronicAPI, self).setUp()
|
||||||
self.mock_agent = mock.MagicMock()
|
self.mock_agent = mock.MagicMock()
|
||||||
self.app = self._make_app(self.mock_agent)
|
self.app = self._make_app(self.mock_agent)
|
||||||
|
|
||||||
@ -41,8 +41,9 @@ class TestTeethAPI(unittest.TestCase):
|
|||||||
def _make_app(self, enable_acl=False):
|
def _make_app(self, enable_acl=False):
|
||||||
self.config = {
|
self.config = {
|
||||||
'app': {
|
'app': {
|
||||||
'root': 'teeth_agent.api.controllers.root.RootController',
|
'root': 'ironic_python_agent.api.controllers.root.'
|
||||||
'modules': ['teeth_agent.api'],
|
'RootController',
|
||||||
|
'modules': ['ironic_python_agent.api'],
|
||||||
'static_root': '',
|
'static_root': '',
|
||||||
'debug': True,
|
'debug': True,
|
||||||
},
|
},
|
||||||
@ -165,7 +166,9 @@ class TestTeethAPI(unittest.TestCase):
|
|||||||
self.assertTrue('commands' in data.keys())
|
self.assertTrue('commands' in data.keys())
|
||||||
|
|
||||||
def test_get_agent_status(self):
|
def test_get_agent_status(self):
|
||||||
status = agent.TeethAgentStatus('TEST_MODE', time.time(), 'v72ac9')
|
status = agent.IronicPythonAgentStatus('TEST_MODE',
|
||||||
|
time.time(),
|
||||||
|
'v72ac9')
|
||||||
self.mock_agent.get_status.return_value = status
|
self.mock_agent.get_status.return_value = status
|
||||||
|
|
||||||
response = self.get_json('/status')
|
response = self.get_json('/status')
|
@ -21,8 +21,8 @@ import json
|
|||||||
import mock
|
import mock
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from teeth_agent import configdrive
|
from ironic_python_agent import configdrive
|
||||||
from teeth_agent import utils
|
from ironic_python_agent import utils
|
||||||
|
|
||||||
|
|
||||||
class ConfigDriveWriterTestCase(unittest.TestCase):
|
class ConfigDriveWriterTestCase(unittest.TestCase):
|
||||||
@ -45,7 +45,7 @@ class ConfigDriveWriterTestCase(unittest.TestCase):
|
|||||||
def test_write_no_files(self, open_mock, makedirs_mock):
|
def test_write_no_files(self, open_mock, makedirs_mock):
|
||||||
metadata = {'admin_pass': 'password', 'hostname': 'test'}
|
metadata = {'admin_pass': 'password', 'hostname': 'test'}
|
||||||
json_metadata = json.dumps(metadata)
|
json_metadata = json.dumps(metadata)
|
||||||
metadata_path = '/lol/teeth/latest/meta_data.json'
|
metadata_path = '/lol/ironic/latest/meta_data.json'
|
||||||
for k, v in metadata.iteritems():
|
for k, v in metadata.iteritems():
|
||||||
self.writer.add_metadata(k, v)
|
self.writer.add_metadata(k, v)
|
||||||
|
|
||||||
@ -53,12 +53,12 @@ class ConfigDriveWriterTestCase(unittest.TestCase):
|
|||||||
open_mock.return_value.__exit__ = mock.Mock()
|
open_mock.return_value.__exit__ = mock.Mock()
|
||||||
write_mock = open_mock.return_value.write
|
write_mock = open_mock.return_value.write
|
||||||
|
|
||||||
self.writer.write('/lol', prefix='teeth', version='latest')
|
self.writer.write('/lol', prefix='ironic', version='latest')
|
||||||
open_mock.assert_called_once_with(metadata_path, 'wb')
|
open_mock.assert_called_once_with(metadata_path, 'wb')
|
||||||
write_mock.assert_called_once_with(json_metadata)
|
write_mock.assert_called_once_with(json_metadata)
|
||||||
makedirs_calls = [
|
makedirs_calls = [
|
||||||
mock.call('/lol/teeth/latest'),
|
mock.call('/lol/ironic/latest'),
|
||||||
mock.call('/lol/teeth/content')
|
mock.call('/lol/ironic/content')
|
||||||
]
|
]
|
||||||
self.assertEqual(makedirs_calls, makedirs_mock.call_args_list)
|
self.assertEqual(makedirs_calls, makedirs_mock.call_args_list)
|
||||||
|
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from teeth_agent import decom
|
from ironic_python_agent import decom
|
||||||
|
|
||||||
|
|
||||||
class TestDecomMode(unittest.TestCase):
|
class TestDecomMode(unittest.TestCase):
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||||||
import mock
|
import mock
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from teeth_agent import hardware
|
from ironic_python_agent import hardware
|
||||||
|
|
||||||
|
|
||||||
class TestGenericHardwareManager(unittest.TestCase):
|
class TestGenericHardwareManager(unittest.TestCase):
|
@ -20,16 +20,16 @@ import mock
|
|||||||
import time
|
import time
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from teeth_agent import errors
|
from ironic_python_agent import errors
|
||||||
from teeth_agent import hardware
|
from ironic_python_agent import hardware
|
||||||
from teeth_agent import overlord_agent_api
|
from ironic_python_agent import ironic_api_client
|
||||||
|
|
||||||
API_URL = 'http://agent-api.overlord.example.org/'
|
API_URL = 'http://agent-api.ironic.example.org/'
|
||||||
|
|
||||||
|
|
||||||
class TestBaseTeethAgent(unittest.TestCase):
|
class TestBaseIronicPythonAgent(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.api_client = overlord_agent_api.APIClient(API_URL)
|
self.api_client = ironic_api_client.APIClient(API_URL)
|
||||||
self.hardware_info = [
|
self.hardware_info = [
|
||||||
hardware.HardwareInfo(hardware.HardwareType.MAC_ADDRESS,
|
hardware.HardwareInfo(hardware.HardwareType.MAC_ADDRESS,
|
||||||
'aa:bb:cc:dd:ee:ff'),
|
'aa:bb:cc:dd:ee:ff'),
|
@ -17,8 +17,8 @@ limitations under the License.
|
|||||||
import mock
|
import mock
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from teeth_agent import errors
|
from ironic_python_agent import errors
|
||||||
from teeth_agent import standby
|
from ironic_python_agent import standby
|
||||||
|
|
||||||
|
|
||||||
class TestStandbyMode(unittest.TestCase):
|
class TestStandbyMode(unittest.TestCase):
|
||||||
@ -177,7 +177,7 @@ class TestStandbyMode(unittest.TestCase):
|
|||||||
standby._download_image,
|
standby._download_image,
|
||||||
image_info)
|
image_info)
|
||||||
|
|
||||||
@mock.patch('teeth_agent.standby._verify_image', autospec=True)
|
@mock.patch('ironic_python_agent.standby._verify_image', autospec=True)
|
||||||
@mock.patch('__builtin__.open', autospec=True)
|
@mock.patch('__builtin__.open', autospec=True)
|
||||||
@mock.patch('requests.get', autospec=True)
|
@mock.patch('requests.get', autospec=True)
|
||||||
def test_download_image_verify_fails(self, requests_mock, open_mock,
|
def test_download_image_verify_fails(self, requests_mock, open_mock,
|
||||||
@ -218,9 +218,9 @@ class TestStandbyMode(unittest.TestCase):
|
|||||||
self.assertFalse(verified)
|
self.assertFalse(verified)
|
||||||
self.assertEqual(md5_mock.call_count, 1)
|
self.assertEqual(md5_mock.call_count, 1)
|
||||||
|
|
||||||
@mock.patch('teeth_agent.hardware.get_manager', autospec=True)
|
@mock.patch('ironic_python_agent.hardware.get_manager', autospec=True)
|
||||||
@mock.patch('teeth_agent.standby._write_image', autospec=True)
|
@mock.patch('ironic_python_agent.standby._write_image', autospec=True)
|
||||||
@mock.patch('teeth_agent.standby._download_image', autospec=True)
|
@mock.patch('ironic_python_agent.standby._download_image', autospec=True)
|
||||||
def test_cache_image(self, download_mock, write_mock, hardware_mock):
|
def test_cache_image(self, download_mock, write_mock, hardware_mock):
|
||||||
image_info = self._build_fake_image_info()
|
image_info = self._build_fake_image_info()
|
||||||
download_mock.return_value = None
|
download_mock.return_value = None
|
||||||
@ -236,13 +236,15 @@ class TestStandbyMode(unittest.TestCase):
|
|||||||
self.assertEqual('SUCCEEDED', async_result.command_status)
|
self.assertEqual('SUCCEEDED', async_result.command_status)
|
||||||
self.assertEqual(None, async_result.command_result)
|
self.assertEqual(None, async_result.command_result)
|
||||||
|
|
||||||
@mock.patch('teeth_agent.standby._copy_configdrive_to_disk', autospec=True)
|
@mock.patch('ironic_python_agent.standby._copy_configdrive_to_disk',
|
||||||
@mock.patch('teeth_agent.standby.configdrive.write_configdrive',
|
autospec=True)
|
||||||
|
@mock.patch('ironic_python_agent.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',
|
||||||
autospec=True)
|
autospec=True)
|
||||||
@mock.patch('teeth_agent.hardware.get_manager', autospec=True)
|
|
||||||
@mock.patch('teeth_agent.standby._write_image', autospec=True)
|
|
||||||
@mock.patch('teeth_agent.standby._download_image', autospec=True)
|
|
||||||
@mock.patch('teeth_agent.standby._configdrive_location', autospec=True)
|
|
||||||
def test_prepare_image(self,
|
def test_prepare_image(self,
|
||||||
location_mock,
|
location_mock,
|
||||||
download_mock,
|
download_mock,
|
@ -4,4 +4,4 @@
|
|||||||
modules=log
|
modules=log
|
||||||
|
|
||||||
# The base module to hold the copy of openstack.common
|
# The base module to hold the copy of openstack.common
|
||||||
base=teeth_agent
|
base=ironic_python_agent
|
||||||
|
18
setup.cfg
18
setup.cfg
@ -1,8 +1,8 @@
|
|||||||
[metadata]
|
[metadata]
|
||||||
name = teeth-agent
|
name = ironic-python-agent
|
||||||
author = Rackspace
|
author = Rackspace
|
||||||
author-email = teeth-dev@lists.rackspace.com
|
author-email = teeth-dev@lists.rackspace.com
|
||||||
summary = Teeth Host Agent
|
summary = Ironic Python Agent Ramdisk
|
||||||
license = Apache-2
|
license = Apache-2
|
||||||
classifier =
|
classifier =
|
||||||
Development Status :: 4 - Beta
|
Development Status :: 4 - Beta
|
||||||
@ -12,18 +12,18 @@ classifier =
|
|||||||
Programming Language :: Python
|
Programming Language :: Python
|
||||||
[files]
|
[files]
|
||||||
packages =
|
packages =
|
||||||
teeth_agent
|
ironic_python_agent
|
||||||
|
|
||||||
[entry_points]
|
[entry_points]
|
||||||
console_scripts =
|
console_scripts =
|
||||||
teeth-agent = teeth_agent.cmd.agent:run
|
ironic-python-agent = ironic_python_agent.cmd.agent:run
|
||||||
|
|
||||||
teeth_agent.modes =
|
ironic_python_agent.modes =
|
||||||
standby = teeth_agent.standby:StandbyMode
|
standby = ironic_python_agent.standby:StandbyMode
|
||||||
decom = teeth_agent.decom:DecomMode
|
decom = ironic_python_agent.decom:DecomMode
|
||||||
|
|
||||||
teeth_agent.hardware_managers =
|
ironic_python_agent.hardware_managers =
|
||||||
generic = teeth_agent.hardware:GenericHardwareManager
|
generic = ironic_python_agent.hardware:GenericHardwareManager
|
||||||
|
|
||||||
[pbr]
|
[pbr]
|
||||||
autodoc_index_modules = True
|
autodoc_index_modules = True
|
||||||
|
4
tox.ini
4
tox.ini
@ -17,12 +17,12 @@ downloadcache = ~/cache/pip
|
|||||||
|
|
||||||
[testenv:pep8]
|
[testenv:pep8]
|
||||||
commands =
|
commands =
|
||||||
flake8 {posargs:teeth_agent}
|
flake8 {posargs:ironic_python_agent}
|
||||||
|
|
||||||
[testenv:cover]
|
[testenv:cover]
|
||||||
setenv = VIRTUAL_ENV={envdir}
|
setenv = VIRTUAL_ENV={envdir}
|
||||||
commands =
|
commands =
|
||||||
python setup.py testr --coverage {posargs:teeth_agent}
|
python setup.py testr --coverage {posargs:ironic_python_agent}
|
||||||
|
|
||||||
[testenv:venv]
|
[testenv:venv]
|
||||||
commands = {posargs:}
|
commands = {posargs:}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user