diff --git a/ironic_python_agent/cmd/agent.py b/ironic_python_agent/cmd/agent.py index 14fdf3815..431698d1b 100644 --- a/ironic_python_agent/cmd/agent.py +++ b/ironic_python_agent/cmd/agent.py @@ -17,51 +17,84 @@ limitations under the License. import argparse from ironic_python_agent import agent +from ironic_python_agent.openstack.common import log + + +LOG = log.getLogger() + + +def _get_kernel_params(): + try: + with open('/proc/cmdline') as f: + cmdline = f.read() + except Exception as e: + LOG.exception('Could not read /proc/cmdline: {e}'.format(e=e)) + return {} + + options = cmdline.split() + params = {} + for option in options: + if '=' not in option: + continue + k, v = option.split('=', 1) + params[k] = v + + return params def run(): + kparams = _get_kernel_params() + parser = argparse.ArgumentParser( description=('An agent that handles decomissioning and provisioning' ' on behalf of Ironic.')) - parser.add_argument('--api-url', - required=True, - help='URL of the Ironic API') + api_url = kparams.get('ipa-api-url') + if api_url is None: + parser.add_argument('--api-url', + required=True, + help='URL of the Ironic API') parser.add_argument('--listen-host', - default='0.0.0.0', + default=kparams.get('ipa-listen-host', '0.0.0.0'), type=str, help='The IP address to listen on.') parser.add_argument('--listen-port', - default=9999, + default=int(kparams.get('ipa-listen-port', 9999)), type=int, help='The port to listen on') + parser.add_argument('--advertise-host', - default='0.0.0.0', + default=kparams.get('ipa-advertise-host', '0.0.0.0'), type=str, help='The host to tell Ironic to reply and send ' 'commands to.') + parser.add_argument('--advertise-port', - default=9999, + default=int(kparams.get('ipa-advertise-port', 9999)), type=int, help='The port to tell Ironic to reply and send ' 'commands to.') + parser.add_argument('--lookup-timeout', - default=300, + default=int(kparams.get('ipa-lookup-timeout', 300)), type=int, help='The amount of time to retry the initial lookup ' 'call to Ironic. After the timeout, the agent ' 'will exit with a non-zero exit code.') + parser.add_argument('--lookup-interval', - default=1, + default=int(kparams.get('ipa-lookup-timeout', 1)), type=int, help='The initial interval for retries on the initial ' 'lookup call to Ironic. The interval will be ' 'doubled after each failure until timeout is ' 'exceeded.') + args = parser.parse_args() - agent.build_agent(args.api_url, + + agent.build_agent(api_url or args.api_url, args.advertise_host, args.advertise_port, args.listen_host, diff --git a/ironic_python_agent/tests/agent.py b/ironic_python_agent/tests/agent.py index 6ef421254..ee8437d20 100644 --- a/ironic_python_agent/tests/agent.py +++ b/ironic_python_agent/tests/agent.py @@ -25,6 +25,7 @@ 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 import hardware @@ -241,3 +242,24 @@ class TestBaseAgent(unittest.TestCase): str(EXPECTED_ERROR)) self.assertEqualEncoded(result, expected_result) + + +class TestAgentCmd(unittest.TestCase): + @mock.patch('__builtin__.open') + def test__get_kernel_params_fail(self, open_mock): + open_mock.side_effect = Exception + params = agent_cmd._get_kernel_params() + self.assertEqual(params, {}) + + @mock.patch('__builtin__.open') + def test__get_kernel_params(self, open_mock): + kernel_line = 'api-url=http://localhost:9999 baz foo=bar\n' + open_mock.return_value.__enter__ = lambda s: s + open_mock.return_value.__exit__ = mock.Mock() + read_mock = open_mock.return_value.read + read_mock.return_value = kernel_line + + params = agent_cmd._get_kernel_params() + self.assertEqual(params['api-url'], 'http://localhost:9999') + self.assertEqual(params['foo'], 'bar') + self.assertFalse('baz' in params)