diff options
author | Vasyl Saienko <vsaienko@mirantis.com> | 2016-08-25 11:25:32 -0400 |
---|---|---|
committer | Vasyl Saienko <vsaienko@mirantis.com> | 2016-11-18 16:25:29 +0200 |
commit | c8d518898e27951123ad7816337d2a0f862ea5b4 (patch) | |
tree | 87af8d68dbc779f3ad715e83c0a36a7b3fdec613 /ironic/conductor | |
parent | e1f4cbdab3ce681daa4c3939c013fd86e152f4a3 (diff) | |
download | ironic-c8d518898e27951123ad7816337d2a0f862ea5b4.tar.gz |
Rely on portgroup standalone_ports_supported
Some hardware doesn't support portgroup fallback to single interface
fashion. This imposes additional restrictions on ports, for example
such ports will not support booting by PXE.
This patch adds restrictions setting pxe_enabled=True on ports that
are members of portgroups with standalone_ports_supported=False. And
vice versa portgroup.standalone_ports_supported can't be set to False
until portgroup contains ports with pxe_enabled=True.
Setting 'vif_port_id' means that we are using this port in standalone
mode. This patch also ensures that 'vif_port_id' can't be updated on
ports which are members of portgroups with
standalone_ports_supported=False. And vice versa updating portgroup
standalone_ports_supported=False is not allowed if portgroup contains
ports with extra/vif_port_id set.
Partial-bug: #1526403
Change-Id: I9b4682918725bed2da0b7c89666e2c37d8826290
Diffstat (limited to 'ironic/conductor')
-rw-r--r-- | ironic/conductor/manager.py | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/ironic/conductor/manager.py b/ironic/conductor/manager.py index fd63ce631..35730e933 100644 --- a/ironic/conductor/manager.py +++ b/ironic/conductor/manager.py @@ -1644,7 +1644,8 @@ class ConductorManager(base_manager.BaseConductorManager): exception.FailedToUpdateMacOnPort, exception.MACAlreadyExists, exception.InvalidState, - exception.FailedToUpdateDHCPOptOnPort) + exception.FailedToUpdateDHCPOptOnPort, + exception.Conflict) def update_port(self, context, port_obj): """Update a port. @@ -1658,6 +1659,9 @@ class ConductorManager(base_manager.BaseConductorManager): :raises: InvalidState if port connectivity attributes are updated while node not in a MANAGEABLE or ENROLL or INSPECTING state or not in MAINTENANCE mode. + :raises: Conflict if trying to set extra/vif_port_id or + pxe_enabled=True on port which is a member of portgroup with + standalone_ports_supported=False. """ port_uuid = port_obj.uuid LOG.debug("RPC update_port called for port %s.", port_uuid) @@ -1665,6 +1669,10 @@ class ConductorManager(base_manager.BaseConductorManager): with task_manager.acquire(context, port_obj.node_id, purpose='port update') as task: node = task.node + portgroup_obj = None + if port_obj.portgroup_id: + portgroup_obj = [pg for pg in task.portgroups if + pg.id == port_obj.portgroup_id][0] # Only allow updating MAC addresses for active nodes if maintenance # mode is on. @@ -1717,12 +1725,12 @@ class ConductorManager(base_manager.BaseConductorManager): "address."), {'port': port_uuid, 'instance': node.instance_uuid}) + vif = port_obj.extra.get('vif_port_id') if 'extra' in port_obj.obj_what_changed(): orignal_port = objects.Port.get_by_id(context, port_obj.id) updated_client_id = port_obj.extra.get('client-id') if (orignal_port.extra.get('client-id') != updated_client_id): - vif = port_obj.extra.get('vif_port_id') # DHCP Option with opt_value=None will remove it # from the neutron port if vif: @@ -1742,6 +1750,19 @@ class ConductorManager(base_manager.BaseConductorManager): {'port': port_uuid, 'instance': node.instance_uuid}) + if portgroup_obj and ((set(port_obj.obj_what_changed()) & + {'pxe_enabled', 'portgroup_id'}) or vif): + if ((port_obj.pxe_enabled or vif) and not + portgroup_obj.standalone_ports_supported): + msg = (_("Port group %(portgroup)s doesn't support " + "standalone ports. This port %(port)s cannot be " + " a member of that port group because either " + "'extra/vif_port_id' was specified or " + "'pxe_enabled' was set to True.") % + {"portgroup": portgroup_obj.uuid, + "port": port_uuid}) + raise exception.Conflict(msg) + port_obj.save() return port_obj @@ -1751,7 +1772,8 @@ class ConductorManager(base_manager.BaseConductorManager): exception.FailedToUpdateMacOnPort, exception.PortgroupMACAlreadyExists, exception.PortgroupNotEmpty, - exception.InvalidState) + exception.InvalidState, + exception.Conflict) def update_portgroup(self, context, portgroup_obj): """Update a portgroup. @@ -1767,6 +1789,9 @@ class ConductorManager(base_manager.BaseConductorManager): in MAINTENANCE mode. :raises: PortgroupNotEmpty if there are ports associated with this portgroup. + :raises: Conflict when trying to set standalone_ports_supported=False + on portgroup with ports that has pxe_enabled=True and vice + versa. """ portgroup_uuid = portgroup_obj.uuid LOG.debug("RPC update_portgroup called for portgroup %s.", @@ -1829,6 +1854,21 @@ class ConductorManager(base_manager.BaseConductorManager): 'instance': node.instance_uuid, 'node': node.uuid}) + if ('standalone_ports_supported' in + portgroup_obj.obj_what_changed()): + if not portgroup_obj.standalone_ports_supported: + ports = [p for p in task.ports if + p.portgroup_id == portgroup_obj.id] + for p in ports: + extra = p.extra + vif = extra.get('vif_port_id') + if vif or p.pxe_enabled: + msg = _("standalone_ports_supported can not be " + "set to False, because the port group %s " + "contains ports with 'extra/vif_port_id' " + "or pxe_enabled=True") % portgroup_uuid + raise exception.Conflict(msg) + portgroup_obj.save() return portgroup_obj |