def check_command(self, cmd, error_text, skip_msg, run_as_root=False): try: utils.execute(cmd, run_as_root=run_as_root) except RuntimeError as e: if error_text in str(e) and not self.fail_on_missing_deps: self.skipTest(skip_msg) raise
def add_root_qdisc(device, namespace, root_helper=None): """Add the root htb qdisc for device.""" cmd = ['tc', 'qdisc', 'add', 'dev', device, 'root', 'handle', '1:0', 'htb', 'default', 'fffe'] if namespace: cmd = ['ip', 'netns', 'exec', namespace] + cmd linux_utils.execute(cmd, root_helper=root_helper)
def destroy_root_qdisc(device, namespace, root_helper=None): """Delete the root htb qdisc for device.""" cmd = ['tc', 'qdisc', 'del', 'dev', device, 'root'] if namespace: cmd = ['ip', 'netns', 'exec', namespace] + cmd linux_utils.execute(cmd, root_helper=root_helper, check_exit_code=False)
def device_exists(self, device): """Check if ethernet device exists.""" try: utils.execute(["ip", "link", "show", "dev", device], root_helper=self.root_helper) except RuntimeError: return False return True
def _is_pingable(ip): """Checks whether an IP address is reachable by pinging. Use linux utils to execute the ping (ICMP ECHO) command. Sends 5 packets with an interval of 0.2 seconds and timeout of 1 seconds. Runtime error implies unreachability else IP is pingable. :param ip: IP to check :return: bool - True or False depending on pingability. """ if not ip: LOG.warning("inputing ip adress is None") return False #ip = '10.0.88.138' ping_cmd = ['ping', '-c', '5', '-W', '1', '-i', '0.2', ip] try: linux_utils.execute(ping_cmd, check_exit_code=True) return True except RuntimeError: LOG.warning("Cannot ping ip address: %s", ip) return False
def del_flow(self,nsname = None,devname=None, classid=None,src_ip=None): """ :param nsname: :param devname: :param classid: "1:10" :param src_ip: "192.168.10.100" :return: """ LOG.debug(_('del_flow classid %s,src_ip %s'%(classid,src_ip))) cmd=nscmd=[] if nsname is not None: nscmd=["ip","netns","exec",nsname] cmd.extend(nscmd) cmd.extend(["tc","filter","show","dev",devname]) output=utils.execute(cmd,self.root_helper) res=self._re_match_src_ip_filter(output,class_id=classid,src_ip=src_ip) if res: filter_perf_info=res[:res.index(" fh")] rule_set=filter_perf_info.split(" ") del_cmd=nscmd del_cmd.extend(["tc","filter","del","dev",devname]) del_cmd.extend(rule_set) #print rule_set output=utils.execute(del_cmd,self.root_helper)
def setup_physical_bridges(self, bridge_mappings): """Setup the physical network bridges. Creates physical network bridges and links them to the integration bridge using veths. :param bridge_mappings: map physical network names to bridge names. """ self.phys_brs = {} self.int_ofports = {} self.phys_ofports = {} ip_wrapper = ip_lib.IPWrapper(self.root_helper) for physical_network, bridge in bridge_mappings.iteritems(): LOG.info( _("Mapping physical network %(physical_network)s to " "bridge %(bridge)s"), {"physical_network": physical_network, "bridge": bridge}, ) # setup physical bridge if not ip_lib.device_exists(bridge, self.root_helper): LOG.error( _( "Bridge %(bridge)s for physical network " "%(physical_network)s does not exist. Agent " "terminated!" ), {"physical_network": physical_network, "bridge": bridge}, ) sys.exit(1) br = ovs_lib.OVSBridge(bridge, self.root_helper) br.remove_all_flows() br.add_flow(priority=1, actions="normal") self.phys_brs[physical_network] = br # create veth to patch physical bridge with integration bridge int_veth_name = constants.VETH_INTEGRATION_PREFIX + bridge self.int_br.delete_port(int_veth_name) phys_veth_name = constants.VETH_PHYSICAL_PREFIX + bridge br.delete_port(phys_veth_name) if ip_lib.device_exists(int_veth_name, self.root_helper): ip_lib.IPDevice(int_veth_name, self.root_helper).link.delete() # Give udev a chance to process its rules here, to avoid # race conditions between commands launched by udev rules # and the subsequent call to ip_wrapper.add_veth utils.execute(["/sbin/udevadm", "settle", "--timeout=10"]) int_veth, phys_veth = ip_wrapper.add_veth(int_veth_name, phys_veth_name) self.int_ofports[physical_network] = self.int_br.add_port(int_veth) self.phys_ofports[physical_network] = br.add_port(phys_veth) # block all untranslated traffic over veth between bridges self.int_br.add_flow(priority=2, in_port=self.int_ofports[physical_network], actions="drop") br.add_flow(priority=2, in_port=self.phys_ofports[physical_network], actions="drop") # enable veth to pass traffic int_veth.link.set_up() phys_veth.link.set_up() if self.veth_mtu: # set up mtu size for veth interfaces int_veth.link.set_mtu(self.veth_mtu) phys_veth.link.set_mtu(self.veth_mtu)
def check_command(self, cmd, error_text, skip_msg): try: utils.execute(cmd) except RuntimeError as e: if error_text in str(e): self.skipTest(skip_msg) raise
def _check_keepalived_process(self): cmd = ["service", "keepalived", "status"] try: status = utils.execute(cmd, root_helper=self.root_helper) except Exception: status = '' if 'running' not in status: LOG.debug(_('Keepalived is not running')) cmd = ['ps', '-ewwf', '|', 'grep', '/usr/sbin/keepalived', '|', 'grep', '-v', 'grep', '|', 'awk', '\'{print $2}\''] try: output = os.popen(' '.join(cmd)) pids = output.read() except Exception: LOG.exception(_('Excute %s failed'), cmd) return pids = pids.split('\n') for pid in pids: if pid: LOG.debug(_('Try to kill unactive keepalived process: %s'), pid) try: cmd = ['kill', '-9', pid] utils.execute(cmd, root_helper=self.root_helper) except Exception: LOG.error(_('Kill keepalived process: %s failed'), pid) cmd = ["service", "keepalived", "restart"] utils.execute(cmd, root_helper=self.root_helper)
def check_command(self, cmd, error_text, skip_msg, root_helper=None): try: utils.execute(cmd, root_helper=root_helper) except RuntimeError as e: if error_text in str(e) and not self.fail_on_missing_deps: self.skipTest(skip_msg) raise
def delete_vlan_bridge(self, bridge_name): if ip_lib.device_exists(bridge_name): interfaces_on_bridge = self.get_interfaces_on_bridge(bridge_name) for interface in interfaces_on_bridge: self.remove_interface(bridge_name, interface) if interface.startswith(VXLAN_INTERFACE_PREFIX): self.delete_vxlan(interface) continue for physical_interface in self.interface_mappings.values(): if (interface.startswith(physical_interface)): ips, gateway = self.get_interface_details(bridge_name) if ips: # This is a flat network or a VLAN interface that # was setup outside of neutron => return IP's from # bridge to interface self.update_interface_ip_details(interface, bridge_name, ips, gateway) elif physical_interface != interface: self.delete_vlan(interface) LOG.debug("Deleting bridge %s", bridge_name) if utils.execute(['ip', 'link', 'set', bridge_name, 'down'], run_as_root=True): return if utils.execute(['brctl', 'delbr', bridge_name], run_as_root=True): return LOG.debug("Done deleting bridge %s", bridge_name) else: LOG.error(_LE("Cannot delete bridge %s, does not exist"), bridge_name)
def external_gateway_added(self, ri, ex_gw_port, interface_name, internal_cidrs): if not ip_lib.device_exists(interface_name, root_helper=self.root_helper, namespace=ri.ns_name()): self.driver.plug(ex_gw_port['network_id'], ex_gw_port['id'], interface_name, ex_gw_port['mac_address'], bridge=self.conf.external_network_bridge, namespace=ri.ns_name(), prefix=EXTERNAL_DEV_PREFIX) self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']], namespace=ri.ns_name()) ip_address = ex_gw_port['ip_cidr'].split('/')[0] self._send_gratuitous_arp_packet(ri, interface_name, ip_address) gw_ip = ex_gw_port['subnet']['gateway_ip'] if ex_gw_port['subnet']['gateway_ip']: cmd = ['route', 'add', 'default', 'gw', gw_ip] if self.conf.use_namespaces: ip_wrapper = ip_lib.IPWrapper(self.root_helper, namespace=ri.ns_name()) ip_wrapper.netns.execute(cmd, check_exit_code=False) else: utils.execute(cmd, check_exit_code=False, root_helper=self.root_helper)
def disable(self, retain_port=False): """Disable DHCP for this network by killing the local process.""" pid = self.pid if self.active: cmd = ['kill', '-9', pid] utils.execute(cmd, self.root_helper) if not retain_port: self.device_manager.destroy(self.network, self.interface_name) elif pid: LOG.debug(_('DHCP for %(net_id)s pid %(pid)d is stale, ignoring ' 'command'), {'net_id': self.network.id, 'pid': pid}) else: LOG.debug(_('No DHCP started for %s'), self.network.id) self._remove_config_files() if not retain_port: if self.conf.dhcp_delete_namespaces and self.network.namespace: ns_ip = ip_lib.IPWrapper(self.root_helper, self.network.namespace) try: ns_ip.netns.delete(self.network.namespace) except RuntimeError: msg = _('Failed trying to delete namespace: %s') LOG.exception(msg, self.network.namespace)
def plug(self, network_id, port_id, device_name, mac_address, bridge=None, namespace=None, prefix=None): """This method is called by the Dhcp agent or by the L3 agent when a new network is created """ if not ip_lib.device_exists(device_name, self.root_helper, namespace=namespace): ip = ip_lib.IPWrapper(self.root_helper) tap_name = device_name.replace(prefix or n_const.TAP_DEVICE_PREFIX, n_const.TAP_DEVICE_PREFIX) # Create ns_dev in a namespace if one is configured. root_dev, ns_dev = ip.add_veth(tap_name, device_name, namespace2=namespace) ns_dev.link.set_address(mac_address) # Add an interface created by ovs to the namespace. namespace_obj = ip.ensure_namespace(namespace) namespace_obj.add_device_to_namespace(ns_dev) ns_dev.link.set_up() root_dev.link.set_up() cmd = ['mm-ctl', '--bind-port', port_id, device_name] utils.execute(cmd, self.root_helper) else: LOG.info(_LI("Device %s already exists"), device_name)
def update_device_link(self, port_id, dom_id, hw_addr, owner, state, device): """Set link state of interface based on admin state in libvirt/kvm""" if not hw_addr or not dom_id: return False # For compatibility, treat all without owner starting with virl- as lxcs is_lxc = owner == 'virl:lxc' or not owner and dom_id.startswith('virl-') if not (is_lxc or (owner and owner.startswith('compute:'))): return None state = 'up' if state else 'down' if is_lxc: instance_dir = LXC_INSTANCE_DIR cmd = ['ip', 'link', 'set', 'dev', device, state] else: instance_dir = NOVA_INSTANCE_DIR cmd = ['virsh', 'domif-setlink', '--domain', dom_id, '--interface', hw_addr, '--state', state] if not os.path.isdir(instance_dir % dom_id): LOG.warning('Cannot update device %s link %s on missing domain %s', port_id, hw_addr, dom_id) return None LOG.debug('Bringing port %s with %s of domain %s %s', port_id, hw_addr, dom_id, state) try: utils.execute(cmd, run_as_root=True) return True except RuntimeError: LOG.exception('Failed to update port %s of domain %s mac %s to %s', port_id, dom_id, hw_addr, state) return False
def delete_vlan_bridge(self, bridge_name): if self.device_exists(bridge_name): interfaces_on_bridge = self.get_interfaces_on_bridge(bridge_name) for interface in interfaces_on_bridge: self.remove_interface(bridge_name, interface) if interface.startswith(VXLAN_INTERFACE_PREFIX): self.delete_vxlan(interface) continue for physical_interface in self.interface_mappings.itervalues(): if physical_interface == interface: # This is a flat network => return IP's from bridge to # interface ips, gateway = self.get_interface_details(bridge_name) self.update_interface_ip_details(interface, bridge_name, ips, gateway) elif interface.startswith(physical_interface): self.delete_vlan(interface) LOG.debug(_("Deleting bridge %s"), bridge_name) if utils.execute(['ip', 'link', 'set', bridge_name, 'down'], root_helper=self.root_helper): return if utils.execute(['brctl', 'delbr', bridge_name], root_helper=self.root_helper): return LOG.debug(_("Done deleting bridge %s"), bridge_name) else: LOG.error(_("Cannot delete bridge %s, does not exist"), bridge_name)
def plug_new(self, network_id, port_id, device_name, mac_address, bridge=None, namespace=None, prefix=None, mtu=None): """This method is called by the Dhcp agent or by the L3 agent when a new network is created """ ip = ip_lib.IPWrapper() tap_name = device_name.replace(prefix or n_const.TAP_DEVICE_PREFIX, n_const.TAP_DEVICE_PREFIX) # Create ns_dev in a namespace if one is configured. root_dev, ns_dev = ip.add_veth(tap_name, device_name, namespace2=namespace) root_dev.disable_ipv6() ns_dev.link.set_address(mac_address) mtu = self.conf.network_device_mtu or mtu if mtu: ns_dev.link.set_mtu(mtu) root_dev.link.set_mtu(mtu) else: LOG.warning(_LW("No MTU configured for port %s"), port_id) ns_dev.link.set_up() root_dev.link.set_up() cmd = ['mm-ctl', '--bind-port', port_id, device_name] utils.execute(cmd, run_as_root=True)
def spawn_process(self): """Spawns a Dnsmasq process for the network.""" env = {self.NEUTRON_NETWORK_ID_KEY: self.network.id} cmd = [ "dnsmasq", "--no-hosts", "--no-resolv", "--strict-order", "--bind-interfaces", "--interface=%s" % self.interface_name, "--except-interface=lo", "--pid-file=%s" % self.get_conf_file_name("pid", ensure_conf_dir=True), "--dhcp-hostsfile=%s" % self._output_hosts_file(), "--dhcp-optsfile=%s" % self._output_opts_file(), "--leasefile-ro", ] possible_leases = 0 for i, subnet in enumerate(self.network.subnets): # if a subnet is specified to have dhcp disabled if not subnet.enable_dhcp: continue if subnet.ip_version == 4: mode = "static" else: # TODO(mark): how do we indicate other options # ra-only, slaac, ra-nameservers, and ra-stateless. mode = "static" if self.version >= self.MINIMUM_VERSION: set_tag = "set:" else: set_tag = "" cidr = netaddr.IPNetwork(subnet.cidr) cmd.append( "--dhcp-range=%s%s,%s,%s,%ss" % (set_tag, self._TAG_PREFIX % i, cidr.network, mode, self.conf.dhcp_lease_duration) ) possible_leases += cidr.size # Cap the limit because creating lots of subnets can inflate # this possible lease cap. cmd.append("--dhcp-lease-max=%d" % min(possible_leases, self.conf.dnsmasq_lease_max)) cmd.append("--conf-file=%s" % self.conf.dnsmasq_config_file) if self.conf.dnsmasq_dns_server: cmd.append("--server=%s" % self.conf.dnsmasq_dns_server) if self.conf.dhcp_domain: cmd.append("--domain=%s" % self.conf.dhcp_domain) if self.network.namespace: ip_wrapper = ip_lib.IPWrapper(self.root_helper, self.network.namespace) ip_wrapper.netns.execute(cmd, addl_env=env) else: # For normal sudo prepend the env vars before command cmd = ["%s=%s" % pair for pair in env.items()] + cmd utils.execute(cmd, self.root_helper)
def spawn_process(self): """Spawns a Dnsmasq process for the network.""" env = { self.NEUTRON_NETWORK_ID_KEY: self.network.id, self.NEUTRON_RELAY_SOCKET_PATH_KEY: self.conf.dhcp_lease_relay_socket } cmd = [ 'dnsmasq', '--no-hosts', '--no-resolv', '--strict-order', '--bind-interfaces', '--interface=%s' % self.interface_name, '--except-interface=lo', '--pid-file=%s' % self.get_conf_file_name( 'pid', ensure_conf_dir=True), #TODO (mark): calculate value from cidr (defaults to 150) #'--dhcp-lease-max=%s' % ?, '--dhcp-hostsfile=%s' % self._output_hosts_file(), '--dhcp-optsfile=%s' % self._output_opts_file(), '--dhcp-script=%s' % self._lease_relay_script_path(), '--leasefile-ro', ] for i, subnet in enumerate(self.network.subnets): # if a subnet is specified to have dhcp disabled if not subnet.enable_dhcp: continue if subnet.ip_version == 4: mode = 'static' else: # TODO(mark): how do we indicate other options # ra-only, slaac, ra-nameservers, and ra-stateless. mode = 'static' if self.version >= self.MINIMUM_VERSION: set_tag = 'set:' else: set_tag = '' cmd.append('--dhcp-range=%s%s,%s,%s,%ss' % (set_tag, self._TAG_PREFIX % i, netaddr.IPNetwork(subnet.cidr).network, mode, self.conf.dhcp_lease_duration)) cmd.append('--conf-file=%s' % self.conf.dnsmasq_config_file) if self.conf.dnsmasq_dns_server: cmd.append('--server=%s' % self.conf.dnsmasq_dns_server) if self.conf.dhcp_domain: cmd.append('--domain=%s' % self.conf.dhcp_domain) if self.namespace: ip_wrapper = ip_lib.IPWrapper(self.root_helper, self.namespace) ip_wrapper.netns.execute(cmd, addl_env=env) else: # For normal sudo prepend the env vars before command cmd = ['%s=%s' % pair for pair in env.items()] + cmd utils.execute(cmd, self.root_helper)
def vxlan_ucast_supported(self): if not cfg.CONF.VXLAN.l2_population: return False if not ip_lib.iproute_arg_supported(["bridge", "fdb"], "append"): LOG.warning( _LW('Option "%(option)s" must be supported by command ' '"%(command)s" to enable %(mode)s mode'), {"option": "append", "command": "bridge fdb", "mode": "VXLAN UCAST"}, ) return False test_iface = None for seg_id in moves.range(1, p_const.MAX_VXLAN_VNI + 1): if ip_lib.device_exists(self.get_vxlan_device_name(seg_id)) or ip_lib.vxlan_in_use(seg_id): continue test_iface = self.ensure_vxlan(seg_id) break else: LOG.error(_LE("No valid Segmentation ID to perform UCAST test.")) return False try: utils.execute( cmd=["bridge", "fdb", "append", constants.FLOODING_ENTRY[0], "dev", test_iface, "dst", "1.1.1.1"], run_as_root=True, log_fail_as_error=False, ) return True except RuntimeError: return False finally: self.delete_interface(test_iface)
def gen_client_ca(self, id): file_prefix = get_file_name(id, server = False) file_key = file_prefix + '.key' file_csr = file_prefix + '.csr' remove_file(file_key) remove_file(file_csr) cmd = ['openssl', 'req', '-batch', '-nodes', '-new', '-newkey', 'rsa:' + str(vpn_connstants.KEY_SIZE), '-keyout', file_key, '-out', file_csr, '-config', cfg.CONF.openvpn.openssl_conf] result = utils.execute(cmd, root_helper=self.root_helper) LOG.info("openvpn generate key of client, result:%s" % result) file_crt = file_prefix + '.crt' remove_file(file_crt) cmd = ['openssl', 'ca', '-batch', '-days', vpn_connstants.KEY_EXPIRE, '-out', file_crt, '-in', file_csr, '-config', cfg.CONF.openvpn.openssl_conf] result = utils.execute(cmd, root_helper=self.root_helper) LOG.info("openvpn generate crt of cient, result:%s" % result) remove_file(file_csr)
def _enable_netfilter_for_bridges(self): # we only need to set these values once, but it has to be when # we create a bridge; before that the bridge module might not # be loaded and the proc values aren't there. if self._enabled_netfilter_for_bridges: return else: self._enabled_netfilter_for_bridges = True # These proc values ensure that netfilter is enabled on # bridges; essential for enforcing security groups rules with # OVS Hybrid. Distributions can differ on whether this is # enabled by default or not (Ubuntu - yes, Redhat - no, for # example). LOG.debug("Enabling netfilter for bridges") entries = utils.execute(['sysctl', '-N', 'net.bridge'], run_as_root=True).splitlines() for proto in ('arp', 'ip', 'ip6'): knob = 'net.bridge.bridge-nf-call-%stables' % proto if 'net.bridge.bridge-nf-call-%stables' % proto not in entries: raise SystemExit( _("sysctl value %s not present on this system.") % knob) enabled = utils.execute(['sysctl', '-b', knob]) if enabled != '1': versionutils.report_deprecated_feature( LOG, _LW('Bridge firewalling is disabled; enabling to make ' 'iptables firewall work. This may not work in future ' 'releases.')) utils.execute( ['sysctl', '-w', '%s=1' % knob], run_as_root=True)
def _test_get_vif_port_set(self, is_xen): utils.execute(["ovs-vsctl", self.TO, "list-ports", self.BR_NAME], root_helper=self.root_helper).AndReturn('tap99\ntun22') if is_xen: id_key = 'xs-vif-uuid' else: id_key = 'iface-id' headings = ['name', 'external_ids'] data = [ # A vif port on this bridge: ['tap99', {id_key: 'tap99id', 'attached-mac': 'tap99mac'}], # A vif port on another bridge: ['tap88', {id_key: 'tap88id', 'attached-mac': 'tap88id'}], # Non-vif port on this bridge: ['tun22', {}], ] utils.execute(["ovs-vsctl", self.TO, "--format=json", "--", "--columns=name,external_ids", "list", "Interface"], root_helper=self.root_helper).AndReturn( self._encode_ovs_json(headings, data)) if is_xen: self.mox.StubOutWithMock(self.br, 'get_xapi_iface_id') self.br.get_xapi_iface_id('tap99id').AndReturn('tap99id') self.mox.ReplayAll() port_set = self.br.get_vif_port_set() self.assertEqual(set(['tap99id']), port_set) self.mox.VerifyAll()
def copy_and_overwrite(self, from_path, to_path): # NOTE(toabctl): the agent may run as non-root user, so rm/copy as root if os.path.exists(to_path): utils.execute( cmd=["rm", "-rf", to_path], run_as_root=True) utils.execute( cmd=["cp", "-a", from_path, to_path], run_as_root=True)
def vxlan_ucast_supported(self): if not cfg.CONF.VXLAN.l2_population: return False if not ip_lib.iproute_arg_supported( ['bridge', 'fdb'], 'append'): LOG.warning(_LW('Option "%(option)s" must be supported by command ' '"%(command)s" to enable %(mode)s mode'), {'option': 'append', 'command': 'bridge fdb', 'mode': 'VXLAN UCAST'}) return False test_iface = None for seg_id in moves.range(1, p_const.MAX_VXLAN_VNI + 1): if not ip_lib.device_exists( self.get_vxlan_device_name(seg_id)): test_iface = self.ensure_vxlan(seg_id) break else: LOG.error(_LE('No valid Segmentation ID to perform UCAST test.')) return False try: utils.execute( cmd=['bridge', 'fdb', 'append', constants.FLOODING_ENTRY[0], 'dev', test_iface, 'dst', '1.1.1.1'], run_as_root=True, log_fail_as_error=False) return True except RuntimeError: return False finally: self.delete_vxlan(test_iface)
def _test_get_vif_port_set(self, is_xen): utils.execute(["ovs-vsctl", self.TO, "list-ports", self.BR_NAME], root_helper=self.root_helper).AndReturn( "tap99\ntun22" ) if is_xen: id_key = "xs-vif-uuid" else: id_key = "iface-id" headings = ["name", "external_ids"] data = [ # A vif port on this bridge: ["tap99", {id_key: "tap99id", "attached-mac": "tap99mac"}], # A vif port on another bridge: ["tap88", {id_key: "tap88id", "attached-mac": "tap88id"}], # Non-vif port on this bridge: ["tun22", {}], ] utils.execute( ["ovs-vsctl", self.TO, "--format=json", "--", "--columns=name,external_ids", "list", "Interface"], root_helper=self.root_helper, ).AndReturn(self._encode_ovs_json(headings, data)) if is_xen: self.mox.StubOutWithMock(self.br, "get_xapi_iface_id") self.br.get_xapi_iface_id("tap99id").AndReturn("tap99id") self.mox.ReplayAll() port_set = self.br.get_vif_port_set() self.assertEqual(set(["tap99id"]), port_set) self.mox.VerifyAll()
def test_reset_bridge(self): utils.execute(["ovs-vsctl", self.TO, "--", "--if-exists", "del-br", self.BR_NAME], root_helper=self.root_helper) utils.execute(["ovs-vsctl", self.TO, "add-br", self.BR_NAME], root_helper=self.root_helper) self.mox.ReplayAll() self.br.reset_bridge() self.mox.VerifyAll()
def test_clear_db_attribute(self): pname = "tap77" utils.execute(["ovs-vsctl", self.TO, "clear", "Port", pname, "tag"], root_helper=self.root_helper) self.mox.ReplayAll() self.br.clear_db_attribute("Port", pname, "tag") self.mox.VerifyAll()
def add_or_update_class(self,nsname=None,devname=None,parent_classid=None,curent_classid=None,rate=None,ceil=None ): """ add or update class qos bandwidth :param nsname: :param devname: :param parent_classid: "1:1" :param curent_classid: "1:10" :param rate: 10000Kbit :param ceil:10000Kbit :return:0 :class sfq not exist """ LOG.debug(_('add_or_update_class in call,nsname %s,devname %s,curent_class %s,rate %s' %(nsname,devname,curent_classid,rate))) cmd=[] nscmd=[] if nsname is not None: nscmd=["ip","netns","exec",nsname] cmd.extend(nscmd) is_exist=self.check_class(nsname,devname,"class htb "+curent_classid) #print "add_class" #print is_exist if is_exist==-1 :#class not exist cmd.extend(["tc","class","add","dev",devname,"parent",parent_classid,"classid",curent_classid,"htb","rate",rate,"ceil",ceil]) utils.execute(cmd,self.root_helper) return 0 else:#class is exist ,update class rate cmd.extend(["tc","class","replace","dev",devname,"parent",parent_classid,"classid",curent_classid,"htb","rate",rate,"ceil",ceil]) utils.execute(cmd,self.root_helper) return 1
def remove_static_route(self, tap_device_name, fixed_ips, mac_address): # We don't use the mac_address parameter right now, but it's kept for # symmetry. LOG.debug('CalicoManager::remove_static_route') for ip_data in fixed_ips: ip_address = ip_data['ip_address'] LOG.info(_("Removing static route for %s via %s"), ip_address, tap_device_name) route_out, route_err = utils.execute( ['ip', 'route', 'del', ip_address, 'dev', tap_device_name, 'proto', 'static'], root_helper=self.root_helper, check_exit_code=False, return_stderr=True, ) if route_err: LOG.warning(_("Unable to remove route for %s via %s"), ip_address, tap_device_name) utils.execute(['neutron-disable-proxy-arp', tap_device_name], root_helper=self.root_helper) arp_out, arp_err = utils.execute( ['arp', '-d', ip_address, '-i', tap_device_name], root_helper=self.root_helper, check_exit_code=False, return_stderr=True ) if arp_err: LOG.warning(_("ARP entry missing for %s"), ip_address) return True
def _execute(self, *args): cmd = ['rabbitmqctl'] cmd.extend(args) utils.execute(cmd, run_as_root=True)
def _ivs_add_port(self, device_name, port_id, mac_address): cmd = ['ivs-ctl', 'add-port', device_name] utils.execute(cmd, run_as_root=True)
def spawn_process(self): """Spawns a Dnsmasq process for the network.""" env = { self.NEUTRON_NETWORK_ID_KEY: self.network.id, } cmd = [ 'dnsmasq', '--no-hosts', '--no-resolv', '--strict-order', '--bind-interfaces', '--interface=%s' % self.interface_name, '--except-interface=lo', '--pid-file=%s' % self.get_conf_file_name( 'pid', ensure_conf_dir=True), '--dhcp-hostsfile=%s' % self._output_hosts_file(), '--dhcp-optsfile=%s' % self._output_opts_file(), '--leasefile-ro', ] possible_leases = 0 for i, subnet in enumerate(self.network.subnets): # if a subnet is specified to have dhcp disabled if not subnet.enable_dhcp: continue if subnet.ip_version == 4: mode = 'static' else: # TODO(mark): how do we indicate other options # ra-only, slaac, ra-nameservers, and ra-stateless. mode = 'static' if self.version >= self.MINIMUM_VERSION: set_tag = 'set:' else: set_tag = '' cidr = netaddr.IPNetwork(subnet.cidr) cmd.append('--dhcp-range=%s%s,%s,%s,%ss' % (set_tag, self._TAG_PREFIX % i, cidr.network, mode, self.conf.dhcp_lease_duration)) possible_leases += cidr.size # Cap the limit because creating lots of subnets can inflate # this possible lease cap. cmd.append('--dhcp-lease-max=%d' % min(possible_leases, self.conf.dnsmasq_lease_max)) cmd.append('--conf-file=%s' % self.conf.dnsmasq_config_file) if self.conf.dnsmasq_dns_server: cmd.append('--server=%s' % self.conf.dnsmasq_dns_server) if self.conf.dhcp_domain: cmd.append('--domain=%s' % self.conf.dhcp_domain) if self.network.namespace: ip_wrapper = ip_lib.IPWrapper(self.root_helper, self.network.namespace) ip_wrapper.netns.execute(cmd, addl_env=env) else: # For normal sudo prepend the env vars before command cmd = ['%s=%s' % pair for pair in env.items()] + cmd utils.execute(cmd, self.root_helper)
def remove_fdb_bridge_entry(self, mac, agent_ip, interface): utils.execute( ['bridge', 'fdb', 'del', mac, 'dev', interface, 'dst', agent_ip], run_as_root=True, check_exit_code=False)
def fdb_ip_entry_exists(self, mac, ip, interface): entries = utils.execute(['ip', 'neigh', 'show', 'to', ip, 'dev', interface], run_as_root=True) return mac in entries
def fdb_ip_entry_exists(self, mac, ip, interface): entries = utils.execute( ['ip', 'neigh', 'show', 'to', ip, 'dev', interface], root_helper=self.root_helper) return mac in entries
def ensure_bridge(self, bridge_name, interface=None, ips=None, gateway=None): """Create a bridge unless it already exists.""" # _bridge_exists_and_ensure_up instead of device_exists is used here # because there are cases where the bridge exists but it's not UP, # for example: # 1) A greenthread was executing this function and had not yet executed # "ip link set bridge_name up" before eventlet switched to this # thread running the same function # 2) The Nova VIF driver was running concurrently and had just created # the bridge, but had not yet put it UP if not self._bridge_exists_and_ensure_up(bridge_name): LOG.debug( "Starting bridge %(bridge_name)s for subinterface " "%(interface)s", { 'bridge_name': bridge_name, 'interface': interface }) if utils.execute(['brctl', 'addbr', bridge_name], root_helper=self.root_helper): return if utils.execute(['brctl', 'setfd', bridge_name, str(0)], root_helper=self.root_helper): return if utils.execute(['brctl', 'stp', bridge_name, 'off'], root_helper=self.root_helper): return if utils.execute(['ip', 'link', 'set', bridge_name, 'up'], root_helper=self.root_helper): return LOG.debug( "Done starting bridge %(bridge_name)s for " "subinterface %(interface)s", { 'bridge_name': bridge_name, 'interface': interface }) if not interface: return bridge_name # Update IP info if necessary self.update_interface_ip_details(bridge_name, interface, ips, gateway) # Check if the interface is part of the bridge if not self.interface_exists_on_bridge(bridge_name, interface): try: # Check if the interface is not enslaved in another bridge if self.is_device_on_bridge(interface): bridge = self.get_bridge_for_tap_device(interface) utils.execute(['brctl', 'delif', bridge, interface], root_helper=self.root_helper) utils.execute(['brctl', 'addif', bridge_name, interface], root_helper=self.root_helper) except Exception as e: LOG.error( _LE("Unable to add %(interface)s to %(bridge_name)s" "! Exception: %(e)s"), { 'interface': interface, 'bridge_name': bridge_name, 'e': e }) return return bridge_name
def execute_sysfs_command(self, command, ts_port_params, src_port_params, common_vlans_ranges_str, vf_to_vf_all_vlans, direction): """Execute the SRIOV NIC Switch Driver's SysFs command. # Mirror traffic from VF0 to VF3 on interface p2p1, ex. echo add 3 > /sys/class/net/p2p1/device/sriov/0/ingress_mirror echo add 3 > /sys/class/net/p2p1/device/sriov/0/egress_mirror # Remove traffic mirroring from VF0 to VF3 on interface p2p1, ex. echo rem 3 > /sys/class/net/p2p1/device/sriov/0/ingress_mirror echo rem 3 > /sys/class/net/p2p1/device/sriov/0/egress_mirror # Add VLANs 2,6,18-22 to Mirror traffic to VF3 (port p2p1), ex. echo add 2,6,18-22 > /sys/class/net/p2p1/device/sriov/3/vlan_mirror # Remove VLANs 2,6,18-22 to Mirror traffic to VF3 (port p2p1), ex. echo rem 2,6,18-22 > /sys/class/net/p2p1/device/sriov/3/vlan_mirror # Remove all VLANs from mirroring at VF3, ex. echo rem 0-4095 > /sys/class/net/p1p1/device/sriov/3/vlan_mirror """ if vf_to_vf_all_vlans: if direction in ['OUT', 'BOTH']: sysfs_kobject_path = \ '/sys/class/net/' + ts_port_params['pf_device'] + \ '/device/sriov/' + src_port_params['vf_index'] + \ '/egress_mirror/' commit_cmd = ['echo', command, ts_port_params['vf_index'], '>', sysfs_kobject_path] if not os.path.exists(sysfs_kobject_path): raise n_exc.Invalid("Invalid PF (%s) and/or " "Source VF (%s) combination" % (ts_port_params['pf_device'], src_port_params['vf_index'])) try: utils.execute(commit_cmd, run_as_root=True) except (OSError, RuntimeError, IndexError, ValueError) as e: LOG.error("Exception while executing Sysfs command " "Exception: %s", e) return if direction in ['IN', 'BOTH']: sysfs_kobject_path = \ '/sys/class/net/' + ts_port_params['pf_device'] + \ '/device/sriov/' + src_port_params['vf_index'] + \ '/ingress_mirror/' commit_cmd = ['echo', command, ts_port_params['vf_index'], '>', sysfs_kobject_path] if not os.path.exists(sysfs_kobject_path): raise n_exc.Invalid("Invalid PF (%s) and/or " "Source VF (%s) combination" % (ts_port_params['pf_device'], src_port_params['vf_index'])) try: utils.execute(commit_cmd, run_as_root=True) except (OSError, RuntimeError, IndexError, ValueError) as e: LOG.error("Exception while executing Sysfs command " "Exception: %s", e) return else: if direction != 'BOTH': LOG.warning("SRIOV NIC Switch driver only supports" "direction=BOTH for specific VLANs' mirroring") sysfs_kobject_path = '/sys/class/net/' + \ ts_port_params['pf_device'] + \ '/device/sriov/' + \ ts_port_params['vf_index'] + '/' commit_cmd = ['echo', command, common_vlans_ranges_str, '>', sysfs_kobject_path] if not os.path.exists(sysfs_kobject_path): raise n_exc.Invalid("Invalid PF (%s) or Tap-service VF (%s) " "combination" % (ts_port_params['pf_device'], ts_port_params['vf_index'])) try: utils.execute(commit_cmd, run_as_root=True) except (OSError, RuntimeError, IndexError, ValueError) as e: LOG.error("Exception while executing Sysfs command " "Exception: %s", e) return
def enabled(self): cmd = ['/usr/bin/svcs', '-H', '-o', 'state', NDP_SMF_FMRI] stdout = utils.execute(cmd) return 'online' in stdout
def _get_num_spawned_procs(): cmd = ['ps', '-f', '-u', 'root'] out = utils.execute(cmd, run_as_root=True) return sum([1 for line in out.splitlines() if 'process_spawn' in line])
def kill(self, sig=signal.SIGKILL): pid = self.child_pid or str(self.pid) utils.execute(['kill', '-%d' % sig, pid], run_as_root=True)
def show(cls, dev=None, **kwargs): cmd = ['bridge', 'fdb', 'show'] if dev: cmd += ['dev', dev] return utils.execute(cmd, run_as_root=True, **kwargs)
def gre_conntrack_supported(): cmd = ['modinfo', CONNTRACK_GRE_MODULE] try: return agent_utils.execute(cmd, log_fail_as_error=False) except exceptions.ProcessExecutionError: return False
#!/usr/bin/python import time from oslo_config import cfg from neutron.agent.linux import utils as linux_utils CONF = cfg.CONF ROOT_HELPER_OPTS = [ cfg.StrOpt('root_helper', default='sudo'), cfg.StrOpt('root_helper_daemon') ] CONF.register_opts(ROOT_HELPER_OPTS, 'AGENT') cmd = [ 'conntrack', '-D', '-f', 'ipv4', '-s', '192.168.100.1', '-w', '1', '-d', '192.168.100.2' ] start = time.time() linux_utils.execute(list(cmd), run_as_root=True, check_exit_code=True, extra_ok_codes=[1]) elapsed = (time.time() - start) print "Elapsed %s seconds" % elapsed
def test_with_addl_env(self): expected = "%s\n" % self.test_file self.mock_popen.return_value = [expected, ""] result = utils.execute(["ls", self.test_file], addl_env={'foo': 'bar'}) self.assertEqual(result, expected)
def test_return_code_log_error_no_raise_runtime(self): self.mock_popen.return_value = ('', '') self.process.return_value.returncode = 1 with mock.patch.object(utils, 'LOG') as log: utils.execute(['ls'], check_exit_code=False) self.assertTrue(log.error.called)
def test_check_exit_code(self): self.mock_popen.return_value = ["", ""] stdout = utils.execute(["ls", self.test_file[:-1]], check_exit_code=False) self.assertEqual("", stdout)
def test_process_input(self): expected = "%s\n" % self.test_file[:-1] self.mock_popen.return_value = [expected, ""] result = utils.execute(["cat"], process_input="%s\n" % self.test_file[:-1]) self.assertEqual(result, expected)
def test_with_helper(self): expected = "ls %s\n" % self.test_file self.mock_popen.return_value = [expected, ""] self.config(group='AGENT', root_helper='echo') result = utils.execute(["ls", self.test_file], run_as_root=True) self.assertEqual(result, expected)
def test_stderr_true(self): expected = "%s\n" % self.test_file self.mock_popen.return_value = [expected, ""] out = utils.execute(["ls", self.test_file], return_stderr=True) self.assertIsInstance(out, tuple) self.assertEqual(out, (expected, ""))
def test_decode_return_data(self): str_data = "%s\n" % self.test_file result = utils.execute(['ls', self.test_file], return_stderr=True) self.assertEqual((str_data, ''), result)
def test_without_helper(self): expected = "%s\n" % self.test_file self.mock_popen.return_value = [expected, ""] result = utils.execute(["ls", self.test_file]) self.assertEqual(result, expected)
def test_return_code_log_debug(self): self.mock_popen.return_value = ('', '') with mock.patch.object(utils, 'LOG') as log: utils.execute(['ls']) self.assertTrue(log.debug.called)
def test_return_str_data(self): str_data = "%s\n" % self.test_file self.mock_popen.return_value = [str_data, ''] result = utils.execute(['ls', self.test_file], return_stderr=True) self.assertEqual((str_data, ''), result)
def remove_fdb_ip_entry(self, mac, ip, interface): utils.execute( ['ip', 'neigh', 'del', ip, 'lladdr', mac, 'dev', interface], root_helper=self.root_helper, check_exit_code=False)
def add_fdb_ip_entry(self, mac, ip, interface): utils.execute(['ip', 'neigh', 'add', ip, 'lladdr', mac, 'dev', interface, 'nud', 'permanent'], root_helper=self.root_helper, check_exit_code=False)
def add_fdb_bridge_entry(self, mac, agent_ip, interface, operation="add"): utils.execute([ 'bridge', 'fdb', operation, mac, 'dev', interface, 'dst', agent_ip ], root_helper=self.root_helper, check_exit_code=False)
def remove_fdb_bridge_entry(self, mac, agent_ip, interface): utils.execute( ['bridge', 'fdb', 'del', mac, 'dev', interface, 'dst', agent_ip], root_helper=self.root_helper, check_exit_code=False)
def vxlan_module_supported(self): try: utils.execute(cmd=['modinfo', 'vxlan'], log_fail_as_error=False) return True except RuntimeError: return False
def _execute(cls, op, mac, dev, ip_dst, **kwargs): cmd = ['bridge', 'fdb', op, mac, 'dev', dev] if ip_dst is not None: cmd += ['dst', ip_dst] return utils.execute(cmd, run_as_root=True, **kwargs)