--- a/components/openstack/neutron/files/agent/solaris/interface.py Mon May 16 14:46:20 2016 +0200
+++ b/components/openstack/neutron/files/agent/solaris/interface.py Fri May 20 17:42:29 2016 -0400
@@ -14,18 +14,34 @@
#
# @author: Girish Moodalbail, Oracle, Inc.
-from oslo.config import cfg
+
+import rad.client as radcli
+import rad.connect as radcon
+import rad.bindings.com.oracle.solaris.rad.evscntl_1 as evsbind
+
+from oslo_config import cfg
+from oslo_log import log as logging
from neutron.agent.linux import utils
from neutron.agent.solaris import net_lib
+from neutron.common import exceptions
+LOG = logging.getLogger(__name__)
+
OPTS = [
cfg.StrOpt('evs_controller', default='ssh://evsuser@localhost',
help=_("An URI that specifies an EVS controller"))
]
+class EVSControllerError(exceptions.NeutronException):
+ message = _("EVS controller: %(errmsg)s")
+
+ def __init__(self, evs_errmsg):
+ super(EVSControllerError, self).__init__(errmsg=evs_errmsg)
+
+
class SolarisVNICDriver(object):
"""Driver used to manage Solaris EVS VNICs.
@@ -54,6 +70,9 @@
raise SystemExit(_("'user' and 'hostname' need to be specified "
"for evs_controller"))
+ # save the user and EVS controller info
+ self.uh = uh
+ self._rad_connection = None
# set the controller property for this host
cmd = ['/usr/sbin/evsadm', 'show-prop', '-co', 'value', '-p',
'controller']
@@ -63,17 +82,31 @@
'controller=%s' % (conf.evs_controller)]
utils.execute(cmd)
+ @property
+ def rad_connection(self):
+ if (self._rad_connection is not None and
+ self._rad_connection._closed is None):
+ return self._rad_connection
+
+ LOG.debug(_("Connecting to EVS Controller at %s as %s") %
+ (self.uh[1], self.uh[0]))
+
+ self._rad_connection = radcon.connect_ssh(self.uh[1], user=self.uh[0])
+ return self._rad_connection
+
def fini_l3(self, device_name):
ipif = net_lib.IPInterface(device_name)
ipif.delete_ip()
- def init_l3(self, device_name, ip_cidrs):
+ def init_l3(self, device_name, ip_cidrs, addrconf=False):
"""Set the L3 settings for the interface using data from the port.
ip_cidrs: list of 'X.X.X.X/YY' strings
"""
ipif = net_lib.IPInterface(device_name)
for ip_cidr in ip_cidrs:
ipif.create_address(ip_cidr)
+ if addrconf:
+ ipif.create_addrconf()
# TODO(gmoodalb): - probably take PREFIX?? for L3
def get_device_name(self, port):
@@ -86,27 +119,42 @@
namespace=None, prefix=None, protection=False):
"""Plug in the interface."""
- evs_vport = ('%s/%s') % (network_id, port_id)
- dl = net_lib.Datalink(datalink_name)
+ try:
+ evsc = self.rad_connection.get_object(evsbind.EVSController())
+ vports_info = evsc.getVPortInfo("vport=%s" % (port_id))
+ if vports_info:
+ vport_info = vports_info[0]
+ # This is to handle HA when the 1st DHCP/L3 agent is down and
+ # the second DHCP/L3 agent tries to connect its VNIC to EVS, we
+ # will end up in "vport in use" error. So, we need to reset the
+ # vport before we connect the VNIC to EVS.
+ if vport_info.status == evsbind.VPortStatus.USED:
+ LOG.debug(_("Retrieving EVS: %s"), vport_info.evsuuid)
+ pat = radcli.ADRGlobPattern({'uuid': network_id,
+ 'tenant': tenant_id})
+ evs_objs = self.rad_connection.list_objects(evsbind.EVS(),
+ pat)
+ if evs_objs:
+ evs = self.rad_connection.get_object(evs_objs[0])
+ evs.resetVPort(port_id, "force=yes")
- # This is to handle HA when the 1st DHCP/L3 agent is down and
- # the second DHCP/L3 agent tries to connect its VNIC to EVS, we will
- # end up in "vport in use" error. So, we need to reset the vport
- # before we connect the VNIC to EVS.
- cmd = ['/usr/sbin/evsadm', 'show-vport', '-f',
- 'vport=%s' % port_id, '-co', 'evs,vport,status']
- stdout = utils.execute(cmd)
- evsname, vportname, status = stdout.strip().split(':')
- if status == 'used':
- cmd = ['/usr/sbin/evsadm', 'reset-vport', '-T', tenant_id,
- '%s/%s' % (evsname, vportname)]
- utils.execute(cmd)
+ if not protection:
+ LOG.debug(_("Retrieving VPort: %s"), port_id)
+ pat = radcli.ADRGlobPattern({'uuid': port_id,
+ 'tenant': tenant_id,
+ 'evsuuid': network_id})
+ vport_objs = self.rad_connection.list_objects(
+ evsbind.VPort(), pat)
+ if vport_objs:
+ vport = self.rad_connection.get_object(vport_objs[0])
+ vport.setProperty("protection=none")
+ except radcli.ObjectError as oe:
+ raise EVSControllerError(oe.get_payload().errmsg)
+ finally:
+ self.rad_connection.close()
- if not protection:
- cmd = ['/usr/sbin/evsadm', 'set-vportprop', '-T', tenant_id,
- '-p', 'protection=none', evs_vport]
- utils.execute(cmd)
-
+ dl = net_lib.Datalink(datalink_name)
+ evs_vport = "%s/%s" % (network_id, port_id)
dl.connect_vnic(evs_vport, tenant_id)
def unplug(self, device_name, namespace=None, prefix=None):