diff --git a/etc/ironic/ironic.conf.sample b/etc/ironic/ironic.conf.sample index d4073451d7..99d025003e 100644 --- a/etc/ironic/ironic.conf.sample +++ b/etc/ironic/ironic.conf.sample @@ -1334,6 +1334,18 @@ #root_helper = sudo ironic-rootwrap /etc/ironic/rootwrap.conf +[iscsi] + +# +# Options defined in ironic.drivers.modules.iscsi_deploy +# + +# The port number on which the iSCSI portal listens for +# incoming connections. (port value) +# Possible values: 0-65535 +#portal_port=3260 + + [keystone] # diff --git a/ironic/drivers/modules/agent_client.py b/ironic/drivers/modules/agent_client.py index d27c8dbd13..544bf47688 100644 --- a/ironic/drivers/modules/agent_client.py +++ b/ironic/drivers/modules/agent_client.py @@ -130,9 +130,9 @@ class AgentClient(object): params=params, wait=wait) - def start_iscsi_target(self, node, iqn): + def start_iscsi_target(self, node, iqn, portal_port=3260): """Expose the node's disk as an ISCSI target.""" - params = {'iqn': iqn} + params = {'iqn': iqn, 'portal_port': portal_port} return self._command(node=node, method='iscsi.start_iscsi_target', params=params, diff --git a/ironic/drivers/modules/iscsi_deploy.py b/ironic/drivers/modules/iscsi_deploy.py index bc111643e7..9853e7bd83 100644 --- a/ironic/drivers/modules/iscsi_deploy.py +++ b/ironic/drivers/modules/iscsi_deploy.py @@ -77,8 +77,16 @@ pxe_opts = [ help=_('The disk devices to scan while doing the deploy.')), ] +iscsi_opts = [ + cfg.PortOpt('portal_port', + default=3260, + help=_('The port number on which the iSCSI portal listens ' + 'for incoming connections.')), +] + CONF = cfg.CONF CONF.register_opts(pxe_opts, group='pxe') +CONF.register_opts(iscsi_opts, group='iscsi') DISK_LAYOUT_PARAMS = ('root_gb', 'swap_mb', 'ephemeral_gb') @@ -333,7 +341,11 @@ def do_agent_iscsi_deploy(task, agent_client): iscsi_options = build_deploy_ramdisk_options(node) iqn = iscsi_options['iscsi_target_iqn'] - result = agent_client.start_iscsi_target(node, iqn) + portal_port = iscsi_options['iscsi_portal_port'] + + result = agent_client.start_iscsi_target(node, iqn, + portal_port) + if result['command_status'] == 'FAILED': msg = (_("Failed to start the iSCSI target to deploy the " "node %(node)s. Error: %(error)s") % @@ -412,6 +424,7 @@ def build_deploy_ramdisk_options(node): 'deployment_id': node['uuid'], 'deployment_key': deploy_key, 'iscsi_target_iqn': 'iqn.2008-10.org.openstack:%s' % node.uuid, + 'iscsi_portal_port': CONF.iscsi.portal_port, 'ironic_api_url': ironic_api, 'disk': CONF.pxe.disk_devices, 'boot_option': boot_option, diff --git a/ironic/tests/unit/drivers/modules/test_agent_client.py b/ironic/tests/unit/drivers/modules/test_agent_client.py index aead8915a7..ff41df22b8 100644 --- a/ironic/tests/unit/drivers/modules/test_agent_client.py +++ b/ironic/tests/unit/drivers/modules/test_agent_client.py @@ -178,9 +178,10 @@ class TestAgentClient(base.TestCase): def test_start_iscsi_target(self): self.client._command = mock.MagicMock(spec_set=[]) iqn = 'fake-iqn' - params = {'iqn': iqn} + port = 3260 + params = {'iqn': iqn, 'portal_port': port} - self.client.start_iscsi_target(self.node, iqn) + self.client.start_iscsi_target(self.node, iqn, port) self.client._command.assert_called_once_with( node=self.node, method='iscsi.start_iscsi_target', params=params, wait=True) diff --git a/ironic/tests/unit/drivers/modules/test_iscsi_deploy.py b/ironic/tests/unit/drivers/modules/test_iscsi_deploy.py index d4b266d209..662c7f6feb 100644 --- a/ironic/tests/unit/drivers/modules/test_iscsi_deploy.py +++ b/ironic/tests/unit/drivers/modules/test_iscsi_deploy.py @@ -174,6 +174,7 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase): expected_iqn = 'iqn.2008-10.org.openstack:%s' % self.node.uuid expected_opts = { 'iscsi_target_iqn': expected_iqn, + 'iscsi_portal_port': 3260, 'deployment_id': self.node.uuid, 'deployment_key': fake_key, 'disk': fake_disk, @@ -504,7 +505,8 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase): def test_do_agent_iscsi_deploy_okay(self, build_options_mock, continue_deploy_mock): build_options_mock.return_value = {'deployment_key': 'abcdef', - 'iscsi_target_iqn': 'iqn-qweqwe'} + 'iscsi_target_iqn': 'iqn-qweqwe', + 'iscsi_portal_port': 3260} agent_client_mock = mock.MagicMock(spec_set=agent_client.AgentClient) agent_client_mock.start_iscsi_target.return_value = { 'command_status': 'SUCCESS', 'command_error': None} @@ -520,7 +522,7 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase): task, agent_client_mock) build_options_mock.assert_called_once_with(task.node) agent_client_mock.start_iscsi_target.assert_called_once_with( - task.node, 'iqn-qweqwe') + task.node, 'iqn-qweqwe', 3260) continue_deploy_mock.assert_called_once_with( task, error=None, iqn='iqn-qweqwe', key='abcdef', address='1.2.3.4') @@ -534,7 +536,8 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase): def test_do_agent_iscsi_deploy_start_iscsi_failure(self, build_options_mock): build_options_mock.return_value = {'deployment_key': 'abcdef', - 'iscsi_target_iqn': 'iqn-qweqwe'} + 'iscsi_target_iqn': 'iqn-qweqwe', + 'iscsi_portal_port': 3260} agent_client_mock = mock.MagicMock(spec_set=agent_client.AgentClient) agent_client_mock.start_iscsi_target.return_value = { 'command_status': 'FAILED', 'command_error': 'booom'} @@ -549,7 +552,7 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase): task, agent_client_mock) build_options_mock.assert_called_once_with(task.node) agent_client_mock.start_iscsi_target.assert_called_once_with( - task.node, 'iqn-qweqwe') + task.node, 'iqn-qweqwe', 3260) self.node.refresh() self.assertEqual(states.DEPLOYFAIL, self.node.provision_state) self.assertEqual(states.ACTIVE, self.node.target_provision_state) diff --git a/releasenotes/notes/add-iscsi-portal-port-option-bde3b386f44f2a90.yaml b/releasenotes/notes/add-iscsi-portal-port-option-bde3b386f44f2a90.yaml new file mode 100644 index 0000000000..d25100eea0 --- /dev/null +++ b/releasenotes/notes/add-iscsi-portal-port-option-bde3b386f44f2a90.yaml @@ -0,0 +1,8 @@ +--- +features: + - IPA supported iSCSI portal port customization already. + With this patch, we added new portal_port argument into + agent_client.start_iscsi_target() method to pass iSCSI portal + port to IPA side. And add new configuration into iscsi module as + CONF.iscsi.portal_port +