def __init__(self, cmd, run_as_root=False, respawn_interval=None, namespace=None, log_output=False, die_on_error=False): """Constructor. :param cmd: The list of command arguments to invoke. :param run_as_root: The process should run with elevated privileges. :param respawn_interval: Optional, the interval in seconds to wait to respawn after unexpected process death. Respawn will only be attempted if a value of 0 or greater is provided. :param namespace: Optional, start the command in the specified namespace. :param log_output: Optional, also log received output. :param die_on_error: Optional, kills the process on stderr output. """ self.cmd_without_namespace = cmd self._cmd = ip_lib.add_namespace_to_cmd(cmd, namespace) self.run_as_root = run_as_root if respawn_interval is not None and respawn_interval < 0: raise ValueError(_('respawn_interval must be >= 0 if provided.')) self.respawn_interval = respawn_interval self._process = None self._is_running = False self._kill_event = None self._reset_queues() self._watchers = [] self.log_output = log_output self.die_on_error = die_on_error
def _ssh_and_ping_server(self, ssh_server, ping_server, namespace, key_file_name): """Ssh into the server from the namespace. In order to ssh it uses the following command: ip netns exec <namespace> ssh -i <path to keyfile> cirros@<server_ip> :param ssh_server: ip of the server to ssh into :param ping_server: ip of the server to ping to :param namespace: qrouter namespace :param key_file_name: path to private key file :return: """ LOG.debug( "SSH INTO SERVER %s AND PING THE PEER SERVER %s FROM THE" " NAMESPACE %s", ssh_server, ping_server, namespace) try: # ssh instance host = "cirros@" + ssh_server count = 20 cmd = [ 'ssh', '-o', 'StrictHostKeyChecking=no', '-i', key_file_name, host, 'ping', '-w', 2 * count, '-c', count, ping_server ] cmd = ip_lib.add_namespace_to_cmd(cmd, namespace) ping_result = linux_utils.execute(cmd, run_as_root=True) LOG.debug("%s", ping_result) return True except RuntimeError: return False
def _ping_mtu(self, namespace, ip, size): """Pings ip address using packets of given size and with DF=1. In order to ping it uses following cli command: ip netns exec <namespace> ping -c 4 -M do -s <size> <ip> """ try: cmd = ['ping', '-c', 4, '-M', 'do', '-s', size, ip] cmd = ip_lib.add_namespace_to_cmd(cmd, namespace) linux_utils.execute(cmd, run_as_root=True) return True except RuntimeError: return False
def _get_namespace(self): """Get namespaces :return: namespaces """ LOG.debug("GET NAMESPACES USING 'ip netns'") try: cmd = ['ip', 'netns'] cmd = ip_lib.add_namespace_to_cmd(cmd) namespaces = linux_utils.execute(cmd) LOG.debug("%s", namespaces) return namespaces except RuntimeError: return None
def _delete_knownhosts_file(self): """Removes the knownhosts file :param server_ips: ips to be removed from /root/.ssh/knownhosts :return: """ LOG.debug("DELETE THE KNOWNHOST FILE") try: cmd = ['rm', '-rf', "~/.ssh/known_hosts"] cmd = ip_lib.add_namespace_to_cmd(cmd) linux_utils.execute(cmd) return True except RuntimeError: return False
def _ping_mtu(self, from_site, to_site, size, instance=0): """Pings ip address using packets of given size and with DF=1. In order to ping it uses following cli command: ip netns exec <namespace> ping -c 4 -M do -s <size> <ip> """ namespace = from_site.vm[instance].namespace ip = to_site.vm[instance].port_ip try: cmd = ["ping", "-c", 4, "-M", "do", "-s", size, ip] cmd = ip_lib.add_namespace_to_cmd(cmd, namespace) linux_utils.execute(cmd, run_as_root=True) return True except RuntimeError: return False
def _get_interfaces(self, namespace): """Do an "ip a". In order to do "ip a" it uses following cli command: ip netns exec <namespace> ip a | grep qg :param namespace: namespace """ LOG.debug("GET THE INTERFACES BY USING 'ip a' FROM THE NAMESPACE %s", namespace) try: cmd = ['ip', 'a'] cmd = ip_lib.add_namespace_to_cmd(cmd, namespace) interfaces = linux_utils.execute(cmd, run_as_root=True) LOG.debug("%s", interfaces) return interfaces except RuntimeError: return None
def _ping(self, namespace, ip): """Pings ip address from network namespace. In order to ping it uses following cli command: ip netns exec <namespace> ping -c 4 -q <ip> :param namespace: namespace :param ip: ip to ping to """ LOG.debug("PING %s FROM THE NAMESPACE %s", ip, namespace) try: count = 4 cmd = ['ping', '-w', 2 * count, '-c', count, ip] cmd = ip_lib.add_namespace_to_cmd(cmd, namespace) ping_result = linux_utils.execute(cmd, run_as_root=True) LOG.debug("%s", ping_result) return True except RuntimeError: return False
def _start_tcpdump(self, namespace, interface): """Starts tcpdump at the given interface In order to start a "tcpdump" it uses the following command: ip netns exec <namespace> sudo tcpdump -i <interface> :param namespace: namespace :param interface: interface :return: """ LOG.debug( "START THE TCPDUMP USING 'tcpdump -i <%s> FROM THE NAMESPACE" " %s", interface, namespace) try: cmd = ['timeout', '10', 'tcpdump', '-n', '-i', interface] cmd = ip_lib.add_namespace_to_cmd(cmd, namespace) tcpdump = linux_utils.execute(cmd, run_as_root=True, extra_ok_codes=[124]) LOG.debug("%s", tcpdump) return tcpdump except RuntimeError: return None
def test_add_namespace_to_cmd_without_namespace(self): cmd = ['ping', '8.8.8.8'] self.assertEqual(cmd, ip_lib.add_namespace_to_cmd(cmd, None))
def test_add_namespace_to_cmd_with_namespace(self): cmd = ['ping', '8.8.8.8'] self.assertEqual(['ip', 'netns', 'exec', 'tmp'] + cmd, ip_lib.add_namespace_to_cmd(cmd, 'tmp'))
def test_add_namespace_to_cmd_without_namespace(self): cmd = ["ping", "8.8.8.8"] self.assertEqual(cmd, ip_lib.add_namespace_to_cmd(cmd, None))
def test_add_namespace_to_cmd_with_namespace(self): cmd = ["ping", "8.8.8.8"] self.assertEqual(["ip", "netns", "exec", "tmp"] + cmd, ip_lib.add_namespace_to_cmd(cmd, "tmp"))