def search_and_replace(self, lvalue, rvalue, position, vrouter_file): """Search and replace strings in the format <key>=<filepath> <args> - 'position' determines where the <rvalue> needs to be inserted - If it is "Begin", the string becomes: <key>=<rvalue> <filepath> <args> - If it is "End", the string becomes: <key>=<filepath> <args> <rvalue> - If <rvalue> already exists in <args>, it deletes it first - If <rvalue> already preceeds <filepath> it deletes it first Input: - lvalue = <key> - rvalue = <arg> to be searched and replaced - position = Begin/End - vrouter_file = path of vrouter file """ if position == "Begin": regexp_del = r"'s/\(^ *%s *=\)\(.*\)\( \/.*\)/\1\3/'" % (lvalue) regexp_add = r"'s/\(^%s=\)\(.*\)/\1%s \2/'" % (lvalue, rvalue) regexp = "sed -i.bak -e %s -e %s %s" \ % (regexp_del, regexp_add, vrouter_file) local(regexp, warn_only=False) elif position == "End": regexp_del = r"'s/\(^ *%s *=.*\) \(%s [^ ]*\)\(.*\) *$/\1\3/'" \ % (lvalue, rvalue.split(' ')[0]) regexp_add = r"'s/\(^ *%s *=.*\)/\1 %s/'" % (lvalue, rvalue) regexp = "sed -i.bak -e %s -e %s %s" \ % (regexp_del, regexp_add, vrouter_file) local(regexp, warn_only=False)
def enable_kernel_core(self): """ enable_kernel_core: update grub file install grub2 enable services """ gcnf = '' with open('/etc/default/grub', 'r') as f: gcnf = f.read() p = re.compile('\s*GRUB_CMDLINE_LINUX') el = ExtList(gcnf.split('\n')) try: i = el.findex(p.match) exec(el[i]) el[i] = 'GRUB_CMDLINE_LINUX="%s crashkernel=128M"' % ( ' '.join(filter(lambda x: not x.startswith( 'crashkernel='), GRUB_CMDLINE_LINUX.split()))) exec(el[i]) el[i] = 'GRUB_CMDLINE_LINUX="%s kvm-intel.nested=1"' % ( ' '.join(filter(lambda x: not x.startswith( 'kvm-intel.nested='), GRUB_CMDLINE_LINUX.split()))) with open('%s/grub' % self._temp_dir_name, 'w') as f: f.write('\n'.join(el)) f.flush() local('sudo mv %s/grub /etc/default/grub' % self._temp_dir_name) local('sudo /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg') except LookupError: log.warning('Improper grub file, kernel crash not enabled')
def run_services(self): if self.pdist not in ['Ubuntu']: for svc in ['supervisor-vrouter']: local('sudo chkconfig %s on' % svc) if self.running_in_container: for svc in ['contrail-vrouter-agent', 'contrail-vrouter-nodemgr']: local('sudo service %s restart' % svc)
def setup_sriov_grub(self): if not self._args.sriov: return if self.pdist != 'Ubuntu': log.info("Not configuring SRIOV Grub changes for %s distribution", self.pdist) return with open('/etc/default/grub', 'r') as f: gcnf = f.read() p = re.compile('\s*GRUB_CMDLINE_LINUX_DEFAULT') el = gcnf.split('\n') for i, x in enumerate(el): if not p.match(x): continue exec(el[i]) el[i] = 'GRUB_CMDLINE_LINUX_DEFAULT="%s intel_iommu=on"' % ( ' '.join(filter(lambda x: not x.startswith( 'intel_iommu='), GRUB_CMDLINE_LINUX_DEFAULT.split()))) exec(el[i]) el[i] = 'GRUB_CMDLINE_LINUX_DEFAULT="%s iommu=pt"' % ( ' '.join(filter(lambda x: not x.startswith( 'iommu='), GRUB_CMDLINE_LINUX_DEFAULT.split()))) exec(el[i]) with open('%s/grub' % self._temp_dir_name, 'w') as f: f.write('\n'.join(el)) f.flush() local('sudo mv %s/grub /etc/default/grub' % self._temp_dir_name) local('sudo /usr/sbin/update-grub') break
def migrate_routes(self, device): ''' add route entries in /proc/net/route ''' temp_dir_name = self._temp_dir_name cfg_file = '/etc/sysconfig/network-scripts/route-vhost0' tmp_file = '%s/route-vhost0' % temp_dir_name with open(tmp_file, 'w') as route_cfg_file: for route in open('/proc/net/route', 'r').readlines(): if route.startswith(device): route_fields = route.split() destination = int(route_fields[1], 16) gateway = int(route_fields[2], 16) flags = int(route_fields[3], 16) mask = int(route_fields[7], 16) if flags & 0x2: if destination != 0: route_cfg_file.write(socket.inet_ntoa( struct.pack('I', destination))) route_cfg_file.write( '/' + str(bin(mask).count('1')) + ' ') route_cfg_file.write('via ') route_cfg_file.write(socket.inet_ntoa( struct.pack('I', gateway)) + ' ') route_cfg_file.write('dev vhost0') # end if detination... # end if flags &... # end if route.startswith... # end for route... # end with open... local("sudo mv -f %s %s" % (tmp_file, cfg_file)) # delete the route-dev file if os.path.isfile('/etc/sysconfig/network-scripts/route-%s' % device): os.unlink('/etc/sysconfig/network-scripts/route-%s' % device)
def fixup_contrail_vrouter_nodemgr(self): # Workaround https://bugs.launchpad.net/juniperopenstack/+bug/1681172 cfgfile = '/etc/contrail/contrail-vrouter-nodemgr.conf' if not os.path.isfile(cfgfile): local('sudo touch %s' % cfgfile) collector_list = ' '.join('%s:%s' % (server, '8086') for server in self._args.collectors) self.set_config(cfgfile, 'COLLECTOR', 'server_list', collector_list)
def start_tsn_service(self): nova_conf_file = '/etc/contrail/contrail-vrouter-agent.conf' mode = 'tsn' if self._args.tsn_evpn_mode: mode = 'tsn-no-forwarding' local( "openstack-config --set %s DEFAULT agent_mode %s" % (nova_conf_file, mode))
def get_domain_search_list(self): domain_list = '' cmd = "sudo grep ^\"search\" /etc/resolv.conf | " cmd += "sudo awk '{$1=\"\";print $0}'" domain_list = local(cmd, capture=True).strip() if not domain_list: cmd = "sudo grep ^\"domain\" /etc/resolv.conf | " cmd += "sudo awk '{$1=\"\"; print $0}'" domain_list = local(cmd, capture=True).strip() return domain_list
def del_physical_device(self): cmd = "sudo python /opt/contrail/utils/provision_physical_device.py" cmd += " --device_name %s" % self.tor_name cmd += " --vendor_name %s" % self.tor_vendor_name cmd += " --api_server_ip %s" % self._args.cfgm_ip cmd += " --admin_user %s" % self._args.admin_user cmd += " --admin_password %s" % self._args.admin_password cmd += " --admin_tenant_name %s" % self._args.admin_tenant_name cmd += " --openstack_ip %s" % self._args.authserver_ip cmd += " --oper del" local(cmd)
def stop_services(self): if self._args.restart: if not self.systemd_setup: local("sudo supervisorctl -c /etc/contrail/supervisord_vrouter.conf update") try: vrouter_nodemgr_pid = [line.split()[1] for line in \ subprocess.check_output("ps -eaf".split()).split("\n") \ if '--nodetype=contrail-vrouter' in line][0] os.kill(int(vrouter_nodemgr_pid), signal.SIGHUP) except: log.warning("contrail-vrouter-nodemgr is not running")
def del_vnc_config(self): cmd = "sudo python /opt/contrail/utils/provision_vrouter.py" cmd += " --host_name %s" % self.tor_agent_name cmd += " --host_ip %s" % self._args.self_ip cmd += " --api_server_ip %s" % self._args.cfgm_ip cmd += " --admin_user %s" % self._args.admin_user cmd += " --admin_password %s" % self._args.admin_password cmd += " --admin_tenant_name %s" % self._args.admin_tenant_name cmd += " --openstack_ip %s" % self._args.authserver_ip cmd += " --oper del " local(cmd)
def get_if_mtu(self, dev): cmd = "sudo ifconfig %s | sudo grep mtu | sudo awk '{ print $NF }'" %\ dev mtu = local(cmd, capture=True).strip() if not mtu: # for debian cmd = r"sudo ifconfig %s | sudo grep MTU | " % dev cmd += r"sudo sed 's/.*MTU.\([0-9]\+\).*/\1/g'" mtu = local(cmd, capture=True).strip() if (mtu and mtu != '1500'): return mtu return ''
def fixup_tor_service(self): self.tor_process_name = 'contrail-tor-agent-' + self._args.tor_id template_vals = { '__contrail_tor_agent_conf_file__': self.tor_file_name, } self._template_substitute_write( tor_agent_service.template, template_vals, self._temp_dir_name + '/tor_agent_service') self.tor_service_file_name = self.tor_process_name + '.service' src = "%s/tor_agent_service" % self._temp_dir_name dst = "/lib/systemd/system/%s" %\ self.tor_service_file_name local("sudo mv %s %s" % (src, dst))
def add_vnc_config(self): cmd = "sudo python /opt/contrail/utils/provision_vrouter.py" cmd += " --host_name %s" % self._args.tor_agent_name cmd += " --host_ip %s" % self._args.self_ip cmd += " --api_server_ip %s" % self._args.cfgm_ip cmd += " --admin_user %s" % self._args.admin_user cmd += " --admin_password %s" % self._args.admin_password cmd += " --admin_tenant_name %s" % self._args.admin_tenant_name cmd += " --openstack_ip %s" % self._args.authserver_ip cmd += " --router_type tor-agent" if self._args.auth_protocol == 'https': cmd += " --api_server_use_ssl True" cmd += " --oper add " local(cmd)
def remove_tor_agent_conf_files(self, tor_id): ssl_cert = '/etc/contrail/ssl/certs/tor.' + tor_id + '.cert.pem' ssl_privkey = '/etc/contrail/ssl/private/tor.' + tor_id + '.privkey.pem' # Remove ssl certs once if os.path.exists(ssl_cert): os.remove(ssl_cert) if os.path.exists(ssl_privkey): os.remove(ssl_privkey) self.tor_file_name = '/etc/contrail/contrail-tor-agent-' + tor_id + '.conf' if os.path.exists(self.tor_file_name): os.remove(self.tor_file_name) self.tor_process_name = 'contrail-tor-agent-' + tor_id local("sudo service %s stop" % self.tor_process_name) if self.systemd_setup: local("sudo systemctl disable %s" % self.tor_process_name)
def add_tsn_vnc_config(self): tsn_ip = self._args.self_ip self.tsn_hostname = socket.gethostname() prov_args = "--host_name %s --host_ip %s --api_server_ip %s --oper add "\ "--admin_user %s --admin_password %s --admin_tenant_name %s "\ "--openstack_ip %s --router_type tor-service-node --disable_vhost_vmi "\ % (self.tsn_hostname, tsn_ip, self._args.cfgm_ip, self._args.keystone_admin_user, self._args.keystone_admin_password, self._args.keystone_admin_tenant_name, self._args.keystone_ip) if self._args.apiserver_auth_protocol == 'https': prov_args += " --api_server_use_ssl True" local( "python /opt/contrail/utils/provision_vrouter.py %s" % (prov_args))
def setup_coremask_node(self, dpdk_args): """Setup core mask on one or list of nodes """ try: coremask = dpdk_args['coremask'] except KeyError: raise RuntimeError("Core mask for host %s is not defined." % (dpdk_args)) if not coremask: raise RuntimeError("Core mask for host %s is not defined." % dpdk_args) # if a list of cpus is provided, -c flag must be passed to taskset if (',' in coremask) or ('-' in coremask): taskset_param = ' -c' else: taskset_param = '' # supported coremask format: hex: (0x3f); list: (0,3-5), (0,1,2,3,4,5) # try taskset on a dummy command if local('sudo taskset%s %s true' % (taskset_param, coremask), capture=True, warn_only=False).succeeded: self.search_and_replace(self.command_key, '\/usr\/bin\/taskset ' + coremask, "Begin", self.vrouter_file) else: raise RuntimeError("Error: Core mask %s for host %s is invalid." % (coremask, dpdk_args))
def fixup_tor_ini(self): self.tor_process_name = 'contrail-tor-agent-' + self._args.tor_id self.tor_log_file_name = self.tor_process_name + '-stdout.log' template_vals = { '__contrail_tor_agent__': self.tor_process_name, '__contrail_tor_agent_conf_file__': self.tor_file_name, '__contrail_tor_agent_log_file__': self.tor_log_file_name } self._template_substitute_write( tor_agent_ini.template, template_vals, self._temp_dir_name + '/tor_agent_ini') self.tor_ini_file_name = self.tor_process_name + '.ini' src = "%s/tor_agent_ini" % self._temp_dir_name dst = "/etc/contrail/supervisord_vrouter_files/%s" %\ self.tor_ini_file_name local("sudo mv %s %s" % (src, dst))
def is_interface_vlan(interface): iface = local("sudo ip link show %s | head -1" % interface + "| cut -f2 -d':' | grep '@'", capture=True, warn_only=True) if iface.succeeded: return True else: return False
def add_physical_device(self): cmd = "sudo python /opt/contrail/utils/provision_physical_device.py" cmd += " --device_name %s" % self._args.tor_name cmd += " --vendor_name %s" % self._args.tor_vendor_name cmd += " --device_mgmt_ip %s" % self._args.tor_ip cmd += " --device_tunnel_ip %s" % self._args.tor_tunnel_ip cmd += " --device_tor_agent %s" % self._args.tor_agent_name cmd += " --device_tsn %s" % self._args.tor_tsn_name cmd += " --api_server_ip %s" % self._args.cfgm_ip cmd += " --admin_user %s" % self._args.admin_user cmd += " --admin_password %s" % self._args.admin_password cmd += " --admin_tenant_name %s" % self._args.admin_tenant_name cmd += " --openstack_ip %s" % self._args.authserver_ip if self._args.auth_protocol == 'https': cmd += " --api_server_use_ssl True" if self._args.tor_product_name: cmd += " --product_name %s" %(self._args.tor_product_name) cmd += " --oper add " local(cmd)
def setup_uio_driver(self, dpdk_args): """Setup UIO driver to use for DPDK (igb_uio, uio_pci_generic or vfio-pci) """ vrouter_agent_file = '/etc/contrail/contrail-vrouter-agent.conf' if 'uio_driver' in dpdk_args: uio_driver = dpdk_args['uio_driver'] else: print "No UIO driver defined for host, skipping..." return if local('sudo modprobe %s' % (uio_driver), capture=True, warn_only=False).succeeded: log.info("Setting UIO driver to %s for host..." % uio_driver) local('sudo contrail-config --set %s DEFAULT '\ 'physical_uio_driver %s' % (vrouter_agent_file, uio_driver)) else: raise RuntimeError("Error: invalid UIO driver %s for host" % (uio_driver))
def fixup_contrail_lbaas(self): auth_url = self._args.keystone_auth_protocol + '://' auth_url += self._args.keystone_ip auth_url += ':' + self._args.keystone_auth_port auth_url += '/' + 'v2.0' configs = { 'BARBICAN': { 'admin_tenant_name': 'service', 'admin_user': '******', 'admin_password': self._args.neutron_password, 'auth_url': auth_url, 'region': 'RegionOne'} } # Workaround https://bugs.launchpad.net/juniperopenstack/+bug/1681172 cfgfile = '/etc/contrail/contrail-lbaas-auth.conf' if not os.path.isfile(cfgfile): local('sudo touch %s' % cfgfile) for section, key_vals in configs.items(): for key, val in key_vals.items(): self.set_config(cfgfile, section, key, val)
def add_vnc_config(self): compute_ip = self._args.self_ip compute_hostname = socket.gethostname() use_ssl = False if self._args.apiserver_auth_protocol == 'https': use_ssl = True prov_args = "--host_name %s --host_ip %s --api_server_ip %s "\ "--oper add --admin_user %s --admin_password %s "\ "--admin_tenant_name %s --openstack_ip %s "\ "--api_server_use_ssl %s" \ % (compute_hostname, compute_ip, self._args.cfgm_ip, self._args.keystone_admin_user, self._args.keystone_admin_password, self._args.keystone_admin_tenant_name, self._args.keystone_ip, use_ssl) if self._args.dpdk: prov_args += " --dpdk_enabled" cmd = "sudo python /opt/contrail/utils/provision_vrouter.py " local(cmd + prov_args)
def setup_crashkernel_params(self): kcmd = r"sudo sed -i 's/crashkernel=.*\([ | \"]\)" kcmd += r"/crashkernel=384M-2G:64M,2G-16G:128M,16G-:256M\1/g' " kcmd += "/etc/default/grub.d/kexec-tools.cfg" if self.pdistversion == '14.04': local(kcmd, warn_only=True) cmd = "[ -f /etc/default/kdump-tools ] && " cmd += "sudo sed -i 's/USE_KDUMP=0/USE_KDUMP=1/' " cmd += "/etc/default/kdump-tools" local(cmd, warn_only=True) else: local(kcmd) local("sudo update-grub")
def fixup_tor_agent(self): #if self._args.tor_ovs_protocol.lower() == 'pssl': self.ssl_cacert = '/etc/contrail/ssl/certs/tor-ca-cert.pem' self.ssl_cert = '/etc/contrail/ssl/certs/tor.' + self._args.tor_id + '.cert.pem' self.ssl_privkey = '/etc/contrail/ssl/private/tor.' + self._args.tor_id + '.private.pem' control_servers = ' '.join('%s:%s' % (server, '5269') for server in self._args.control_nodes) collector_servers = ' '.join('%s:%s' % (server, '8086') for server in self._args.collectors) dns_servers = ' '.join('%s:%s' % (server, '53') for server in self._args.control_nodes) template_vals = { '__contrail_control_ip__': self._args.self_ip, '__contrail_tor_name__': self._args.tor_name, '__contrail_http_server_port__': self._args.http_server_port, '__contrail_tor_ip__': self._args.tor_ip, '__contrail_tor_id__': self._args.tor_id, '__contrail_tsn_ovs_port__': self._args.tor_ovs_port, '__contrail_tsn_ip__': self._args.tsn_ip, '__contrail_tor_ovs_protocol__': self._args.tor_ovs_protocol, '__contrail_tor_agent_ovs_ka__': self._args.tor_agent_ovs_ka, '__contrail_tor_agent_name__': self._args.tor_agent_name, '__contrail_tor_tunnel_ip__': self._args.tor_tunnel_ip, '__contrail_tor_product_name__': self._args.tor_product_name, '__contrail_tor_vendor_name__': self._args.tor_vendor_name, '__contrail_tor_ssl_cert__': self.ssl_cert, '__contrail_tor_ssl_privkey__': self.ssl_privkey, '__contrail_tor_ssl_cacert__': self.ssl_cacert, '__contrail_control_servers__': control_servers, '__contrail_collector_servers__': collector_servers, '__contrail_dns_servers__': dns_servers, '__xmpp_dns_auth_enable__': self._args.xmpp_dns_auth_enable, '__xmpp_auth_enable__': self._args.xmpp_auth_enable, } self._template_substitute_write( tor_agent_conf.template, template_vals, self._temp_dir_name + '/tor_agent_conf') self.tor_file_name = ('contrail-tor-agent-' + self._args.tor_id + '.conf') local("sudo mv %s/tor_agent_conf /etc/contrail/%s" % (self._temp_dir_name, self.tor_file_name))
def setup_sriov_vfs(self): # Set the required number of Virtual Functions for given interfaces if self.pdist != 'Ubuntu': log.info("Not configuring VF's for %s distribution", self.pdist) return sriov_string = self._args.sriov if sriov_string: intf_list = sriov_string.split(",") for intf_details in intf_list: info = intf_details.split(":") str = 'echo %s > ' % info[1] str += '/sys/class/net/%s/device/sriov_numvfs;' % info[0] str += 'sleep 2; ifup -a' # Do nothing if the entry already present in /etc/rc.local if local('sudo grep -w \'%s\' /etc/rc.local' % str, warn_only=True).succeeded: continue sed = 'sudo sed -i \'/^\s*exit/i ' + str + '\' /etc/rc.local' local(sed, warn_only=True)
def disable_nova_compute(self): # Check if nova-compute is present in nova service list # Disable nova-compute on TSN node if local("nova service-list | grep nova-compute", warn_only=True).succeeded: # Stop the service local("sudo service nova-compute stop", warn_only=True) if self.pdist in ['Ubuntu']: local('sudo echo "manual" >> /etc/init/nova-compute.override') else: local('sudo chkconfig nova-compute off')
def disable_nova_compute(self): # Check if nova-compute is allready running # Stop if running on TSN node if local("sudo service nova-compute status | grep running", warn_only=True).succeeded: # Stop the service local("sudo service nova-compute stop", warn_only=True) if self.pdist in ['Ubuntu']: local('sudo echo "manual" >> /etc/init/nova-compute.override') else: local('sudo chkconfig nova-compute off')
def increase_vrouter_limit(self): """Increase the maximum number of mpls label and nexthop on tsn node""" if self._args.vrouter_module_params: vrouter_module_params = self._args.vrouter_module_params.rstrip( ',') vrouter_module_params_args = dict( u.split("=") for u in vrouter_module_params.split(",")) if self._args.dpdk: self.dpdk_increase_vrouter_limit( vrouter_module_params_args) else: cmd = "options vrouter" if 'mpls_labels' in vrouter_module_params_args.keys(): cmd += " vr_mpls_labels=%s" % vrouter_module_params_args['mpls_labels'] if 'nexthops' in vrouter_module_params_args.keys(): cmd += " vr_nexthops=%s" % vrouter_module_params_args['nexthops'] if 'vrfs' in vrouter_module_params_args.keys(): cmd += " vr_vrfs=%s" % vrouter_module_params_args['vrfs'] if 'macs' in vrouter_module_params_args.keys(): cmd += " vr_bridge_entries=%s" % vrouter_module_params_args['macs'] if 'flow_entries' in vrouter_module_params_args.keys(): cmd += " vr_flow_entries=%s" % vrouter_module_params_args['flow_entries'] if 'oflow_entries' in vrouter_module_params_args.keys(): cmd += " vr_oflow_entries=%s" % vrouter_module_params_args['oflow_entries'] if 'mac_oentries' in vrouter_module_params_args.keys(): cmd += " vr_bridge_oentries=%s" % vrouter_module_params_args['mac_oentries'] if 'flow_hold_limit' in vrouter_module_params_args.keys(): cmd += " vr_flow_hold_limit=%s" % vrouter_module_params_args['flow_hold_limit'] if 'max_interface_entries' in vrouter_module_params_args.keys(): cmd += " vr_interfaces=%s" % vrouter_module_params_args['max_interface_entries'] if 'vrouter_dbg' in vrouter_module_params_args.keys(): cmd += " vrouter_dbg=%s" % vrouter_module_params_args['vrouter_dbg'] if 'vr_memory_alloc_checks' in vrouter_module_params_args.keys(): cmd += " vr_memory_alloc_checks=%s" % vrouter_module_params_args['vr_memory_alloc_checks'] local( "echo %s > %s" % (cmd, '/etc/modprobe.d/vrouter.conf'), warn_only=True)
def disable_selinux(self): # Disable selinux os.chdir(self._temp_dir_name) cmd = "sudo sed -i 's/SELINUX=.*/SELINUX=disabled/g'" cmd += " /etc/selinux/config" local(cmd, warn_only=True) local("sudo setenforce 0", warn_only=True) # cleanup in case move had error local("sudo rm config.new", warn_only=True)
def enable_kernel_core(self): self.enable_kernel_core() if self.pdist not in ['Ubuntu']: for svc in ['abrt-vmcore', 'abrtd', 'kdump']: local('sudo chkconfig %s on' % svc)
def run_services(self): if self._args.restart: local( "sudo supervisorctl -c /etc/contrail/supervisord_vrouter.conf update" )
def fixup_contrail_vrouter_agent(self): compute_ip = self._args.self_ip non_mgmt_gw = self._args.non_mgmt_gw vgw_public_subnet = self._args.vgw_public_subnet vgw_public_vn_name = self._args.vgw_public_vn_name vgw_intf_list = self._args.vgw_intf_list vgw_gateway_routes = self._args.vgw_gateway_routes gateway_server_list = self._args.gateway_server_list qos_logical_queue = self._args.qos_logical_queue qos_queue_id_list = self._args.qos_queue_id default_hw_queue_qos = self._args.default_hw_queue_qos priority_id_list = self._args.priority_id priority_scheduling = self._args.priority_scheduling priority_bandwidth = self._args.priority_bandwidth self.mac = None if self.dev and self.dev != 'vhost0': self.mac = netifaces.ifaddresses( self.dev)[netifaces.AF_LINK][0]['addr'] if not self.mac: raise KeyError('Interface %s Mac %s' % (str(self.dev), str(self.mac))) self.netmask = netifaces.ifaddresses( self.dev)[netifaces.AF_INET][0]['netmask'] if self.multi_net: self.gateway = non_mgmt_gw else: self.gateway = self.find_gateway(self.dev) self.cidr = netaddr.IPNetwork('%s/%s' % (self.vhost_ip, self.netmask)) if vgw_public_subnet: os.chdir(self._temp_dir_name) # Manipulating the string to use in agent_param vgw_public_subnet_str = [] for i in vgw_public_subnet[1:-1].split(";"): j = i[1:-1].split(",") j = ";".join(j) vgw_public_subnet_str.append(j) vgw_public_subnet_str = str( tuple(vgw_public_subnet_str)).replace("'", "") vgw_public_subnet_str = vgw_public_subnet_str.replace(" ", "") vgw_intf_list_str = str(tuple( vgw_intf_list[1:-1].split(";"))).replace(" ", "") cmds = [ "sudo sed 's@dev=.*@dev=%s@g;" % self.dev, "s@vgw_subnet_ip=.*@vgw_subnet_ip=%s@g;" % vgw_public_subnet_str, "s@vgw_intf=.*@vgw_intf=%s@g'" % vgw_intf_list_str, " /etc/contrail/agent_param.tmpl > agent_param.new" ] local(' '.join(cmds)) local("sudo mv agent_param.new /etc/contrail/agent_param") else: os.chdir(self._temp_dir_name) cmds = [ "sudo sed 's/dev=.*/dev=%s/g' " % self.dev, "/etc/contrail/agent_param.tmpl > agent_param.new" ] local(''.join(cmds)) local("sudo mv agent_param.new /etc/contrail/agent_param") vmware_dev = "" hypervisor_type = "kvm" mode = "" gateway_mode = "" if self._args.mode == 'vcenter': mode = "vcenter" vmware_dev = self.get_secondary_device(self.dev) hypervisor_type = "vmware" if self._args.vmware: vmware_dev = self.get_secondary_device(self.dev) hypervisor_type = "vmware" if self._args.hypervisor == 'docker': hypervisor_type = "docker" if compute_ip in gateway_server_list: gateway_mode = "server" # Set template options for DPDK mode pci_dev = "" platform_mode = "default" if self._args.dpdk: dpdk_args = dict( u.split("=") for u in self._args.dpdk.split(",")) log.info(dpdk_args) platform_mode = "dpdk" iface = self.dev if self.is_interface_vlan(self.dev): iface = self.get_physical_interface_of_vlan(self.dev) local("ls /opt/contrail/bin/dpdk_nic_bind.py", warn_only=False) cmd = "sudo /opt/contrail/bin/dpdk_nic_bind.py --status | " cmd += "sudo grep -w %s | cut -d' ' -f 1" % iface pci_dev = local(cmd, capture=True, warn_only=False) # If there is no PCI address, the device is a bond. # Bond interface in DPDK has zero PCI address. if not pci_dev: pci_dev = "0000:00:00.0" self.setup_hugepages_node(dpdk_args) self.setup_coremask_node(dpdk_args) self.setup_vm_coremask_node(False, dpdk_args) if self._args.vrouter_module_params: vrouter_module_params_args = dict( u.split("=") for u in self._args.vrouter_module_params.split(",")) self.dpdk_increase_vrouter_limit( vrouter_module_params_args) if self.pdist == 'Ubuntu': # Fix /dev/vhost-net permissions. It is required for # multiqueue operation local( 'sudo echo \'KERNEL=="vhost-net", ' 'GROUP="kvm", MODE="0660"\' > ' '/etc/udev/rules.d/vhost-net.rules', warn_only=True) # The vhost-net module has to be loaded at startup to # ensure the correct permissions while the qemu is being # launched local('sudo echo "vhost-net" >> /etc/modules') self.setup_uio_driver(dpdk_args) control_servers = ' '.join('%s:%s' % (server, '5269') for server in self._args.control_nodes) dns_servers = ' '.join('%s:%s' % (server, '53') for server in self._args.control_nodes) collector_servers = ' '.join('%s:%s' % (server, '8086') for server in self._args.collectors) configs = { 'DEFAULT': { 'platform': platform_mode, 'gateway_mode': gateway_mode, 'physical_interface_address': pci_dev, 'physical_interface_mac': self.mac, 'collectors': collector_servers, 'xmpp_auth_enable': self._args.xmpp_auth_enable }, 'NETWORKS': { 'control_network_ip': compute_ip }, 'VIRTUAL-HOST-INTERFACE': { 'name': 'vhost0', 'ip': str(self.cidr), 'gateway': self.gateway, 'physical_interface': self.dev }, 'HYPERVISOR': { 'type': hypervisor_type, 'vmware_mode': mode, 'vmware_physical_interface': vmware_dev }, 'CONTROL-NODE': { 'servers': control_servers }, 'DNS': { 'servers': dns_servers }, 'SANDESH': { 'sandesh_ssl_enable': self._args.sandesh_ssl_enable, 'introspect_ssl_enable': self._args.introspect_ssl_enable } } # VGW configs if vgw_public_vn_name and vgw_public_subnet: vgw_public_vn_name = vgw_public_vn_name[1:-1].split(';') vgw_public_subnet = vgw_public_subnet[1:-1].split(';') vgw_intf_list = vgw_intf_list[1:-1].split(';') if vgw_gateway_routes is not None: vgw_gateway_routes = vgw_gateway_routes[1:-1].split(';') for i in range(len(vgw_public_vn_name)): ip_blocks = '' if vgw_public_subnet[i].find("[") != -1: for ele in vgw_public_subnet[i][1:-1].split(","): ip_blocks += ele[1:-1] + " " else: ip_blocks += vgw_public_subnet[i] routes = '' if (vgw_gateway_routes is not None and i < len(vgw_gateway_routes)): if vgw_gateway_routes[i] != '[]': if vgw_gateway_routes[i].find("[") != -1: for ele in vgw_gateway_routes[i][1:-1].split( ","): routes += ele[1:-1] + " " else: routes += vgw_gateway_routes[i] configs['GATEWAY-%s' % i] = { 'interface': vgw_intf_list[i], 'ip_blocks': ip_blocks, 'routes': routes } # QOS configs if qos_queue_id_list is not None: qos_str = "" qos_str += "[QOS]\n" num_sections = len(qos_logical_queue) if (len(qos_logical_queue) == len(qos_queue_id_list) and default_hw_queue_qos): num_sections = num_sections - 1 for i in range(num_sections): configs['QUEUE-%s' % qos_queue_id_list[i]] = { 'logical_queue': '[%s]' % qos_logical_queue[i].replace(",", ", ") } if (default_hw_queue_qos): if (len(qos_logical_queue) == len(qos_queue_id_list)): logical_queue = '[%s]' %\ qos_logical_queue[-1].replace(",", ", ") else: logical_queue = '[ ]' configs['QUEUE-%s' % qos_queue_id_list[-1]] = { 'default_hw_queue': 'true', 'logical_queue': logical_queue } if priority_id_list is not None: for i in range(len(priority_id_list)): configs['PG-%s' % priority_id_list[i]] = { 'scheduling': priority_scheduling[i], 'bandwidth': priority_bandwidth[i] } if self._args.metadata_secret: configs['METADATA'] = { 'metadata_proxy_secret': self._args.metadata_secret } for section, key_vals in configs.items(): for key, val in key_vals.items(): self.set_config( '/etc/contrail/contrail-vrouter-agent.conf', section, key, val) if self.running_in_container: self.config_vhost0_interface_in_container() else: self.fixup_vhost0_interface_configs()
def add_dev_tun_in_cgroup_device_acl(self): # add /dev/net/tun in cgroup_device_acl needed # for type=ethernet interfaces fl = "/etc/libvirt/qemu.conf" ret = local("sudo grep -q '^cgroup_device_acl' %s" % fl, warn_only=True) if ret.failed: if self.pdist in ['centos', 'redhat']: local('sudo echo "clear_emulator_capabilities = 1" >> %s' % fl, warn_only=True) local('sudo echo \'user = "******"\' >> %s' % fl, warn_only=True) local('sudo echo \'group = "root"\' >> %s' % fl, warn_only=True) cmds = [ 'echo \'cgroup_device_acl = [\' >> %s' % fl, 'echo \' "/dev/null", "/dev/full", "/dev/zero",\'' + ' >> %s' % fl, 'echo \' "/dev/random", "/dev/urandom",\'' + ' >> %s' % fl, 'echo \' "/dev/ptmx", "/dev/kvm", "/dev/kqemu",\'' + ' >> %s' % fl, 'echo \' "/dev/rtc", "/dev/hpet", "/dev/net/tun",\'' + ' >> %s' % fl, 'echo \']\' >> %s' % fl ] for cmd in cmds: local('sudo ' + cmd, warn_only=True) self._fixed_qemu_conf = True # add "alias bridge off" in /etc/modprobe.conf for Centos if self.pdist in ['centos', 'redhat']: local('sudo echo "alias bridge off" > /etc/modprobe.conf', warn_only=True)
def start_tsn_service(self): nova_conf_file = '/etc/contrail/contrail-vrouter-agent.conf' local("openstack-config --set %s DEFAULT agent_mode tsn" % nova_conf_file)
def setup_vm_coremask_node(self, q_coremask, dpdk_args): """ Setup CPU affinity for QEMU processes based on vRouter/DPDK core affinity on a given node. Supported core mask format: vRouter/DPDK: hex (0x3f), list (0,1,2,3,4,5), range (0,3-5) QEMU/nova.conf: list (0,1,2,3,4,5), range (0,3-5), exclusion (0-5,^4) QEMU needs to be pinned to different cores than vRouter. Because of different core mask formats, it is not possible to just set QEMU to <not vRouter cores>. This function takes vRouter core mask from testbed, changes it to list of cores and removes them from list of all possible cores (generated as a list from 0 to N-1, where N = number of cores). This is changed back to string and passed to openstack-config. """ try: vr_coremask = dpdk_args['coremask'] except KeyError: raise RuntimeError("vRouter core mask for " "host %s is not defined." % (dpdk_args)) if not vr_coremask: raise RuntimeError("vRouter core mask for host " "%s is not defined." % dpdk_args) if not q_coremask: try: cpu_count = int( local('sudo grep -c processor /proc/cpuinfo', capture=True)) except ValueError: log.info("Cannot count CPUs on host %s. VM core " "mask cannot be computed." % (dpdk_args)) raise if not cpu_count or cpu_count == -1: raise ValueError("Cannot count CPUs on host %s. " "VM core mask cannot be computed." % (dpdk_args)) all_cores = [x for x in xrange(cpu_count)] if 'x' in vr_coremask: # String containing hexadecimal mask. vr_coremask = int(vr_coremask, 16) """ Convert hexmask to a string with numbers of cores to be used, eg. 0x19 -> 11001 -> 10011 -> [(0,1), (1,0), (2,0), (3,1), (4,1)] -> '0,3,4' """ vr_coremask = [ x[0] for x in enumerate(reversed(bin(vr_coremask)[2:])) if x[1] == '1' ] # Range or list of cores. elif (',' in vr_coremask) or ('-' in vr_coremask): # Get list of core numbers and/or core ranges. vr_coremask = vr_coremask.split(',') # Expand ranges like 0-4 to 0, 1, 2, 3, 4. vr_coremask_expanded = [] for rng in vr_coremask: if '-' in rng: # If it's a range - expand it. a, b = rng.split('-') vr_coremask_expanded += range(int(a), int(b) + 1) else: # If not, just add to the list. vr_coremask_expanded.append(int(rng)) vr_coremask = vr_coremask_expanded else: # A single core. try: single_core = int(vr_coremask) except ValueError: log.error("vRouter core mask %s for host %s is invalid." % (vr_coremask, dpdk_args)) raise vr_coremask = [] vr_coremask.append(single_core) # From list of all cores remove list of vRouter cores # and stringify. diff = set(all_cores) - set(vr_coremask) q_coremask = ','.join(str(x) for x in diff) # If we have no spare cores for VMs if not q_coremask: raise RuntimeError("Setting QEMU core mask for host %s " "failed - empty string." % (dpdk_args)) # This can fail eg. because openstack-config is not present. # There's no sanity check in openstack-config. if local("sudo crudini --set /etc/nova/nova.conf " "DEFAULT vcpu_pin_set %s" % q_coremask, capture=True, warn_only=False).succeeded: log.info("QEMU coremask on host %s set to %s." % (dpdk_args, q_coremask)) else: raise RuntimeError("Error: setting QEMU core mask %s for " "host %s failed." % (vr_coremask, dpdk_args))
def setup_lbaas_prereq(self): if self.pdist in ['centos', 'redhat']: local('sudo groupadd -f nogroup') cmd = "sudo sed -i s/'Defaults requiretty'/'#Defaults " cmd += "requiretty'/g /etc/sudoers" local(cmd)
def set_config(self, fl, sec, var, val=''): local("sudo contrail-config --set %s %s %s '%s'" % (fl, sec, var, val), warn_only=True)
def del_config(self, fl, sec, var=''): local("sudo contrail-config --del %s %s %s" % (fl, sec, var), warn_only=True)
def enable_kdump(self): '''Enable kdump for centos based systems''' status = local("sudo chkconfig --list | grep kdump", warn_only=True) if status.failed: log.warning("Seems kexec-tools is not installed.") log.warning("Skipping enable kdump") return False local("sudo chkconfig kdump on") local("sudo service kdump start") local("sudo service kdump status") local("sudo cat /sys/kernel/kexec_crash_loaded") local("sudo cat /proc/iomem | grep Crash")
def setup_coredump(self): # usable core dump initf = '/etc/sysconfig/init' local("sudo sed '/DAEMON_COREFILE_LIMIT=.*/d' %s > %s.new" % (initf, initf), warn_only=True) local("sudo mv %s.new %s" % (initf, initf), warn_only=True) if self.pdist in ['centos', 'fedora', 'redhat']: core_unlim = "echo DAEMON_COREFILE_LIMIT=\"'unlimited'\"" local("sudo %s >> %s" % (core_unlim, initf)) # Core pattern pattern = 'kernel.core_pattern = /var/crashes/core.%e.%p.%h.%t' ip_fwd_setting = 'net.ipv4.ip_forward = 1' sysctl_file = '/etc/sysctl.conf' log.info(pattern) cmd = "sudo grep -q '%s' /etc/sysctl.conf || " % pattern cmd += "sudo echo '%s' >> /etc/sysctl.conf" % pattern local(cmd, warn_only=True) local("sudo sed 's/net.ipv4.ip_forward.*/%s/g' %s > /tmp/sysctl.new" % (ip_fwd_setting, sysctl_file), warn_only=True) local("sudo mv /tmp/sysctl.new %s" % (sysctl_file), warn_only=True) local("sudo rm /tmp/sysctl.new", warn_only=True) local('sudo sysctl -p', warn_only=True) local('sudo mkdir -p /var/crashes', warn_only=True) local('sudo chmod 777 /var/crashes', warn_only=True) try: if self.pdist in ['fedora', 'centos', 'redhat']: self.enable_kernel_core() if self.pdist == 'Ubuntu': self.setup_crashkernel_params() except Exception as e: log.warning("Ignoring failure kernel core dump") try: if self.pdist in ['fedora', 'centos', 'redhat']: self.enable_kdump() except Exception as e: log.warning("Ignoring failure when enabling kdump") log.warning("Exception: %s", str(e))
def run_services(self): if self.pdist not in ['Ubuntu']: for svc in ['supervisor-vrouter']: local('sudo chkconfig %s on' % svc)
def disable_iptables(self): # Disable iptables if self.pdist not in ['Ubuntu']: local("sudo chkconfig iptables off", warn_only=True) local("sudo iptables --flush", warn_only=True) if self.pdist == 'redhat' or \ self.pdist == 'centos' and self.pdistversion.startswith('7'): local("sudo service iptables stop", warn_only=True) local("sudo service ip6tables stop", warn_only=True) local("sudo systemctl stop firewalld", warn_only=True) local("sudo systemctl status firewalld", warn_only=True) local("sudo chkconfig firewalld off", warn_only=True) local("sudo /usr/libexec/iptables/iptables.init stop", warn_only=True) local("sudo /usr/libexec/iptables/ip6tables.init stop", warn_only=True) local("sudo service iptables save", warn_only=True) local("sudo service ip6tables save", warn_only=True) local("sudo iptables -L", warn_only=True)
def get_physical_interface_of_vlan(interface): iface = local( "sudo ip link show %s | head -1 | cut -f2 -d':'" % interface + "| cut -f2 -d'@'", capture=True) return iface
def setup_hugepages_node(self, dpdk_args): """Setup hugepages on one or list of nodes """ # How many times DPDK inits hugepages (rte_eal_init()) # See function map_all_hugepages() in DPDK DPDK_HUGEPAGES_INIT_TIMES = 2 # get required size of hugetlbfs factor = int(dpdk_args['huge_pages']) print dpdk_args if factor == 0: factor = 1 # set number of huge pages memsize = local( "sudo grep MemTotal /proc/meminfo |" " tr -s ' ' | cut -d' ' -f 2 | tr -d '\n'", capture=True, warn_only=True) pagesize = local( "sudo grep Hugepagesize /proc/meminfo" " | tr -s ' 'i | cut -d' ' -f 2 | tr -d '\n'", capture=True, warn_only=True) reserved = local( "sudo grep HugePages_Total /proc/meminfo" " | tr -s ' 'i | cut -d' ' -f 2 | tr -d '\n'", capture=True, warn_only=True) if (reserved == ""): reserved = "0" requested = ((int(memsize) * factor) / 100) / int(pagesize) if (requested > int(reserved)): pattern = "^vm.nr_hugepages =" line = "vm.nr_hugepages = %d" % requested insert_line_to_file(pattern=pattern, line=line, file_name='/etc/sysctl.conf') current_max_map_count = local("sudo sysctl -n " "vm.max_map_count") if current_max_map_count == "": current_max_map_count = 0 current_huge_pages = max(int(requested), int(reserved)) requested_max_map_count = (DPDK_HUGEPAGES_INIT_TIMES * int(current_huge_pages)) if int(requested_max_map_count) > int(current_max_map_count): pattern = "^vm.max_map_count =" line = "vm.max_map_count = %d" % requested_max_map_count insert_line_to_file(pattern=pattern, line=line, file_name='/etc/sysctl.conf') local('sudo sysctl -p', warn_only=True) mounted = local("sudo mount | grep hugetlbfs | cut -d' ' -f 3", capture=True, warn_only=False) if (mounted != ""): print "hugepages already mounted on %s" % mounted else: local("sudo mkdir -p /hugepages", warn_only=False) pattern = "^hugetlbfs" line = "hugetlbfs "\ "/hugepages hugetlbfs defaults 0 0" insert_line_to_file(pattern=pattern, line=line, file_name='/etc/fstab') local("sudo mount -t hugetlbfs hugetlbfs /hugepages", warn_only=False)
def update_supervisor(self): if self._args.restart: local( "sudo supervisorctl -c /etc/contrail/supervisord_vrouter.conf update", warn_only=True)
def insert_line_to_file(line, file_name, pattern=None): if pattern: local('sed -i \'/%s/d\' %s' % (pattern, file_name), warn_only=True) local('printf "%s\n" >> %s' % (line, file_name))
def has_config(self, fl, sec, var=''): output = local("sudo contrail-config --get %s %s %s" % (fl, sec, var), capture=True, warn_only=True) return output.succeeded
def fixup_contrail_vrouter_agent(self): compute_ip = self._args.self_ip non_mgmt_gw = self._args.non_mgmt_gw vgw_public_subnet = self._args.vgw_public_subnet vgw_public_vn_name = self._args.vgw_public_vn_name vgw_intf_list = self._args.vgw_intf_list vgw_gateway_routes = self._args.vgw_gateway_routes compute_as_gateway = self._args.compute_as_gateway flow_thread_count = self._args.flow_thread_count self.mac = None # Fresh install if self.dev and not self.reprov: self.mac = netifaces.ifaddresses( self.dev)[netifaces.AF_LINK][0]['addr'] if not self.mac: raise KeyError('Interface %s Mac %s' % (str(self.dev), str(self.mac))) self.netmask = netifaces.ifaddresses( self.dev)[netifaces.AF_INET][0]['netmask'] if self.multi_net: self.gateway = non_mgmt_gw else: self.gateway = self.find_gateway(self.dev) self.cidr = netaddr.IPNetwork('%s/%s' % (self.vhost_ip, self.netmask)) elif self.dev: # Reprovision cfg_file = "/etc/contrail/contrail-vrouter-agent.conf" section = "DEFAULT" key = "physical_interface_mac" self.mac = self.get_config(cfg_file, section, key).strip() section = "VIRTUAL-HOST-INTERFACE" key = "ip" self.cidr = self.get_config(cfg_file, section, key).strip() section = "VIRTUAL-HOST-INTERFACE" key = "gateway" self.gateway = self.get_config(cfg_file, section, key).strip() self.netmask = "255.255.255.0" if self.dev: if vgw_public_subnet: os.chdir(self._temp_dir_name) # Manipulating the string to use in agent_param vgw_public_subnet_str = [] for i in vgw_public_subnet[1:-1].split(";"): j = i[1:-1].split(",") j = ";".join(j) vgw_public_subnet_str.append(j) vgw_public_subnet_str = str( tuple(vgw_public_subnet_str)).replace("'", "") vgw_public_subnet_str = vgw_public_subnet_str.replace(" ", "") vgw_intf_list_str = str(tuple( vgw_intf_list[1:-1].split(";"))).replace(" ", "") cmds = [ "sudo sed 's@dev=.*@dev=%s@g;" % self.dev, "s@vgw_subnet_ip=.*@vgw_subnet_ip=%s@g;" % vgw_public_subnet_str, "s@vgw_intf=.*@vgw_intf=%s@g'" % vgw_intf_list_str, " /etc/contrail/agent_param.tmpl > agent_param.new" ] local(' '.join(cmds)) local("sudo mv agent_param.new /etc/contrail/agent_param") else: os.chdir(self._temp_dir_name) cmds = [ "sudo sed 's/dev=.*/dev=%s/g' " % self.dev, "/etc/contrail/agent_param.tmpl > agent_param.new" ] local(''.join(cmds)) local("sudo mv agent_param.new /etc/contrail/agent_param") vmware_dev = None gateway_mode = None if (self._args.mode == 'vcenter' or self._args.hypervisor == 'vmware'): vmware_dev = self.get_secondary_device(self.dev) if compute_as_gateway == 'server': gateway_mode = "server" # Set template options for DPDK mode pci_dev = "" platform_mode = "default" if self._args.dpdk: dpdk_args = dict( u.split("=") for u in self._args.dpdk.split(",")) log.info(dpdk_args) platform_mode = "dpdk" supervisor_vrouter_file = ('/etc/contrail/' + 'supervisord_vrouter_files/' + 'contrail-vrouter-dpdk.ini') systemd_vrouter_file = ('/lib/systemd/system/' + 'contrail-vrouter-dpdk.service') if os.path.isfile(supervisor_vrouter_file): self.vrouter_file = supervisor_vrouter_file self.command_key = "command" elif os.path.isfile(systemd_vrouter_file): self.vrouter_file = systemd_vrouter_file self.command_key = "ExecStart" else: raise RuntimeError("Vrouter Supervisor/Systemd not found.") self.setup_hugepages_node(dpdk_args) self.setup_coremask_node(dpdk_args) self.setup_vm_coremask_node(False, dpdk_args) self.setup_uio_driver(dpdk_args) if self._args.dpdk and not self.reprov: iface = self.dev if self.is_interface_vlan(self.dev): iface = self.get_physical_interface_of_vlan(self.dev) local("ls /opt/contrail/bin/dpdk_nic_bind.py", warn_only=False) cmd = "sudo /opt/contrail/bin/dpdk_nic_bind.py --status | " cmd += "sudo grep -w %s | cut -d' ' -f 1" % iface.strip() pci_dev = local(cmd, capture=True, warn_only=False) # If there is no PCI address, the device is a bond. # Bond interface in DPDK has zero PCI address. if not pci_dev: pci_dev = "0000:00:00.0" elif self._args.dpdk and self.reprov: cfg_file = "/etc/contrail/contrail-vrouter-agent.conf" section = "DEFAULT" key = "physical_interface_address" pci_dev = self.get_config(cfg_file, section, key).strip() if self.pdist == 'Ubuntu': # Fix /dev/vhost-net permissions. It is required for # multiqueue operation local( 'sudo echo \'KERNEL=="vhost-net", ' 'GROUP="kvm", MODE="0660"\' > ' '/etc/udev/rules.d/vhost-net.rules', warn_only=True) # The vhost-net module has to be loaded at startup to # ensure the correct permissions while the qemu is being # launched pattern = "vhost-net" line = "vhost-net" insert_line_to_file(pattern=pattern, line=line, file_name='/etc/modules') control_servers = ' '.join('%s:%s' % (server, '5269') for server in self._args.control_nodes) dns_servers = ' '.join('%s:%s' % (server, '53') for server in self._args.control_nodes) collector_servers = ' '.join('%s:%s' % (server, '8086') for server in self._args.collectors) configs = { 'DEFAULT': { 'platform': platform_mode, 'gateway_mode': gateway_mode or '', 'physical_interface_address': pci_dev, 'physical_interface_mac': self.mac, 'collectors': collector_servers, 'xmpp_auth_enable': self._args.xmpp_auth_enable, 'xmpp_dns_auth_enable': self._args.xmpp_dns_auth_enable }, 'NETWORKS': { 'control_network_ip': compute_ip }, 'VIRTUAL-HOST-INTERFACE': { 'name': 'vhost0', 'ip': str(self.cidr), 'gateway': self.gateway, 'physical_interface': self.dev }, 'HYPERVISOR': { 'type': ('kvm' if self._args.hypervisor == 'libvirt' else self._args.hypervisor), 'vmware_mode': self._args.mode or '', 'vmware_physical_interface': vmware_dev or '' }, 'CONTROL-NODE': { 'servers': control_servers }, 'DNS': { 'servers': dns_servers }, 'SANDESH': { 'sandesh_ssl_enable': self._args.sandesh_ssl_enable, 'introspect_ssl_enable': self._args.introspect_ssl_enable }, 'FLOWS': { 'thread_count': flow_thread_count } } # VGW configs if vgw_public_vn_name and vgw_public_subnet: vgw_public_vn_name = vgw_public_vn_name[1:-1].split(';') vgw_public_subnet = vgw_public_subnet[1:-1].split(';') vgw_intf_list = vgw_intf_list[1:-1].split(';') if vgw_gateway_routes is not None: vgw_gateway_routes = vgw_gateway_routes[1:-1].split(';') for i in range(len(vgw_public_vn_name)): ip_blocks = '' if vgw_public_subnet[i].find("[") != -1: for ele in vgw_public_subnet[i][1:-1].split(","): ip_blocks += ele[1:-1] + " " else: ip_blocks += vgw_public_subnet[i] routes = '' if (vgw_gateway_routes is not None and i < len(vgw_gateway_routes)): if vgw_gateway_routes[i] != '[]': if vgw_gateway_routes[i].find("[") != -1: for ele in vgw_gateway_routes[i][1:-1].split( ","): routes += ele[1:-1] + " " else: routes += vgw_gateway_routes[i] configs['GATEWAY-%s' % i] = { 'interface': vgw_intf_list[i], 'ip_blocks': ip_blocks, 'routes': routes, 'routing_instance': vgw_public_vn_name[i] } if self._args.metadata_secret: configs['METADATA'] = { 'metadata_proxy_secret': self._args.metadata_secret } for section, key_vals in configs.items(): for key, val in key_vals.items(): self.set_config( '/etc/contrail/contrail-vrouter-agent.conf', section, key, val) if self.running_in_container: self.config_vhost0_interface_in_container() else: self.fixup_vhost0_interface_configs()
def find_gateway(self, dev): gateway = '' cmd = "sudo netstat -rn | sudo grep ^\"0.0.0.0\" | " cmd += "sudo head -n 1 | sudo grep %s | sudo awk '{ print $2 }'" % dev gateway = local(cmd, capture=True).strip() return gateway
def fixup_vhost0_interface_configs(self): if self.reprov: log.info("fixup_vhost0_interface_configs() not applicable") return if self.pdist in ['centos', 'fedora', 'redhat']: # make ifcfg-vhost0 with open('%s/ifcfg-vhost0' % self._temp_dir_name, 'w') as f: f.write('''#Contrail vhost0 DEVICE=vhost0 ONBOOT=yes BOOTPROTO=none IPV6INIT=no USERCTL=yes IPADDR=%s NETMASK=%s NM_CONTROLLED=no #NETWORK MANAGER BUG WORKAROUND SUBCHANNELS=1,2,3 ''' % (self.vhost_ip, self.netmask)) # Don't set gateway and DNS on vhost0 if on non-mgmt network if not self.multi_net: if self.gateway: f.write('GATEWAY=%s\n' % self.gateway) dns_list = self.get_dns_servers(self.dev) for i, dns in enumerate(dns_list): f.write('DNS%d=%s\n' % (i + 1, dns)) domain_list = self.get_domain_search_list() if domain_list: f.write('DOMAIN="%s"\n' % domain_list) prsv_cfg = [] mtu = self.get_if_mtu(self.dev) if mtu: dcfg = 'MTU=%s' % str(mtu) f.write(dcfg + '\n') prsv_cfg.append(dcfg) f.flush() if self.dev != 'vhost0': src = "%s/ifcfg-vhost0" % self._temp_dir_name dst = "/etc/sysconfig/network-scripts/ifcfg-vhost0" local("sudo mv %s %s" % (src, dst), warn_only=True) local("sudo sync", warn_only=True) # make ifcfg-$dev ifcfg = "/etc/sysconfig/network-scripts/ifcfg-%s" % self.dev ifcfg_bkp = "/etc/sysconfig/network-scripts/ifcfg-%s.rpmsave"\ % self.dev if not os.path.isfile(ifcfg_bkp): local("sudo cp %s %s" % (ifcfg, ifcfg_bkp), warn_only=True) ifcfg_tmp = '%s/ifcfg-%s' % (self._temp_dir_name, self.dev) self._rewrite_ifcfg_file(ifcfg_tmp, self.dev, prsv_cfg) if self.multi_net: self.migrate_routes(self.dev) local("sudo mv %s /etc/contrail/" % ifcfg_tmp, warn_only=True) if self.pdist not in ['Ubuntu']: local("sudo chkconfig network on", warn_only=True) local("sudo chkconfig supervisor-vrouter on", warn_only=True) # end self.pdist == centos | fedora | redhat # setup lbaas prereqs self.setup_lbaas_prereq() if self.pdist in ['Ubuntu']: self._rewrite_net_interfaces_file( self.dev, self.mac, self.vhost_ip, self.netmask, self.gateway, self._args.vmware, self._args.vmware_vmpg_vswitch_mtu, self._args.vmware_datanic_mtu)
def get_dns_servers(self, dev): cmd = "sudo grep \"^nameserver\\>\" /etc/resolv.conf | " cmd += "sudo awk '{print $2}'" dns_list = local(cmd, capture=True) return dns_list.split()
def add_qos_config(self): qos_logical_queue = self._args.qos_logical_queue qos_queue_id_list = self._args.qos_queue_id default_hw_queue_qos = self._args.default_hw_queue_qos qos_priority_tagging = self._args.qos_priority_tagging priority_id_list = self._args.priority_id priority_scheduling = self._args.priority_scheduling priority_bandwidth = self._args.priority_bandwidth agent_conf = "/etc/contrail/contrail-vrouter-agent.conf" conf_file = "contrail-vrouter-agent.conf" configs = {} # Clean existing qos config ltemp_dir = tempfile.mkdtemp() local("sudo cp %s %s/" % (agent_conf, ltemp_dir)) local( "sudo sed -i -e '/^\[QOS\]/d' -e '/^\[QUEUE-/d' -e '/^logical_queue/d' -e '/^default_hw_queue/d' -e '/^priority_tagging/d' %s/%s" % (ltemp_dir, conf_file)) local( "sudo sed -i -e '/^\[QOS-NIANTIC\]/d' -e '/^\[PG-/d' -e '/^scheduling/d' -e '/^bandwidth/d' %s/%s" % (ltemp_dir, conf_file)) local("sudo cp %s/%s %s" % (ltemp_dir, conf_file, agent_conf)) local('sudo rm -rf %s' % (ltemp_dir)) # Set qos_enabled in agent_param to false self.set_config('/etc/contrail/agent_param', sec="''", var='qos_enabled', val='false') # QOS configs if qos_queue_id_list is not None: self.set_config(agent_conf, 'QOS', 'priority_tagging', qos_priority_tagging) num_sections = len(qos_logical_queue) if (len(qos_logical_queue) == len(qos_queue_id_list) and default_hw_queue_qos): num_sections = num_sections - 1 for i in range(num_sections): configs['QUEUE-%s' % qos_queue_id_list[i]] = { 'logical_queue': '[%s]' % qos_logical_queue[i].replace(",", ", ") } if (default_hw_queue_qos): if (len(qos_logical_queue) == len(qos_queue_id_list)): logical_queue = '[%s]' %\ qos_logical_queue[-1].replace(",", ", ") else: logical_queue = '[ ]' configs['QUEUE-%s' % qos_queue_id_list[-1]] = { 'default_hw_queue': 'true', 'logical_queue': logical_queue } for section, key_vals in configs.items(): for key, val in key_vals.items(): self.set_config(agent_conf, section, key, val) if priority_id_list is not None: local( 'sudo contrail-config --set /etc/contrail/contrail-vrouter-agent.conf QOS-NIANTIC' ) for i in range(len(priority_id_list)): configs['PG-%s' % priority_id_list[i]] = { 'scheduling': priority_scheduling[i], 'bandwidth': priority_bandwidth[i] } for section, key_vals in configs.items(): for key, val in key_vals.items(): self.set_config(agent_conf, section, key, val) if (qos_queue_id_list or priority_id_list): # Set qos_enabled in agent_param self.set_config('/etc/contrail/agent_param', sec="''", var='qos_enabled', val='true') # Run qosmap script on physical interface (on all members for bond # interface) physical_interface = local( "sudo openstack-config --get /etc/contrail/contrail-vrouter-agent.conf VIRTUAL-HOST-INTERFACE physical_interface" ) if os.path.isdir('/sys/class/net/%s/bonding' % physical_interface): physical_interfaces_str = local( "sudo cat /sys/class/net/%s/bonding/slaves | tr ' ' '\n' | sort | tr '\n' ' '" % physical_interface) else: physical_interfaces_str = physical_interface local( "cd /opt/contrail/utils; python qosmap.py --interface_list %s " % physical_interfaces_str)
def _rewrite_net_interfaces_file(self, dev, mac, vhost_ip, netmask, gateway_ip, esxi_vm, vmpg_mtu, datapg_mtu): self.default_cfg_file = '/etc/network/interfaces' cfg_files = self.get_sourced_files() cfg_files.append(self.default_cfg_file) intf_cfgfile = self.get_cfgfile_for_dev('vhost0', cfg_files) if intf_cfgfile: log.info("Interface vhost0 is already present in" + "/etc/network/interfaces") log.info("Skipping rewrite of this file") return # endif vlan = False if os.path.isfile('/proc/net/vlan/%s' % dev): vlan_info = open('/proc/net/vlan/config').readlines() match = re.search('^%s.*\|\s+(\S+)$' % dev, "\n".join(vlan_info), flags=re.M | re.I) if not match: raise RuntimeError('Configured vlan %s is not found in', '/proc/net/vlan/config' % dev) phydev = match.group(1) vlan = True # Replace strings matching dev to vhost0 in ifup and ifdown parts file # Any changes to the file/logic with static routes has to be # reflected in setup-vnc-static-routes.py too ifup_parts_file = os.path.join(os.path.sep, 'etc', 'network', 'if-up.d', 'routes') ifdown_parts_file = os.path.join(os.path.sep, 'etc', 'network', 'if-down.d', 'routes') if (os.path.isfile(ifup_parts_file) and os.path.isfile(ifdown_parts_file)): local("sudo sed -i 's/%s/vhost0/g' %s" % (dev, ifup_parts_file), warn_only=True) local("sudo sed -i 's/%s/vhost0/g' %s" % (dev, ifdown_parts_file), warn_only=True) dev_cfgfile = self.get_cfgfile_for_dev(dev, cfg_files) temp_intf_file = '%s/interfaces' % self._temp_dir_name local("sudo cp %s %s" % (dev_cfgfile, temp_intf_file)) with open(dev_cfgfile, 'r') as fd: cfg_file = fd.read() if not self._args.non_mgmt_ip: # remove entry from auto <dev> to auto excluding these pattern # then delete specifically auto <dev> local("sudo sed -i '/auto %s/,/auto/{/auto/!d}' %s" % (dev, temp_intf_file)) local("sudo sed -i '/auto %s/d' %s" % (dev, temp_intf_file)) # add manual entry for dev local("sudo echo 'auto %s' >> %s" % (dev, temp_intf_file)) local("sudo echo 'iface %s inet manual' >> %s" % (dev, temp_intf_file)) if vlan: local("sudo echo ' post-up ifconfig %s up' >> %s" % (dev, temp_intf_file)) local("sudo echo ' pre-down ifconfig %s down' >> %s" % (dev, temp_intf_file)) else: local("sudo echo ' pre-up ifconfig %s up' >> %s" % (dev, temp_intf_file)) local("sudo echo ' post-down ifconfig %s down' >> %s" % (dev, temp_intf_file)) if esxi_vm: local("sudo echo ' pre-up ifconfig %s up mtu %s' >> %s" % (dev, datapg_mtu, temp_intf_file)) cmd = "sudo ethtool -i %s | grep driver | cut -f 2 -d ' '"\ % dev device_driver = local(cmd, capture=True) if (device_driver == "vmxnet3"): cmd = "sudo echo ' pre-up ethtool --offload " rx_cmd = (cmd + "%s rx off' >> %s" % (dev, temp_intf_file)) tx_cmd = (cmd + "%s tx off' >> %s" % (dev, temp_intf_file)) local(rx_cmd) local(tx_cmd) if vlan: local("sudo echo ' vlan-raw-device %s' >> %s" % (phydev, temp_intf_file)) if 'bond' in dev.lower(): iters = re.finditer('^\s*auto\s', cfg_file, re.M) indices = [pat_match.start() for pat_match in iters] matches = map(cfg_file.__getslice__, indices, indices[1:] + [len(cfg_file)]) for each in matches: each = each.strip() if re.match('^auto\s+%s' % dev, each): string = '' for lines in each.splitlines(): if 'bond-' in lines: string += lines + os.linesep local("sudo echo '%s' >> %s" % (string, temp_intf_file)) else: continue local("sudo echo '' >> %s" % temp_intf_file) else: # remove ip address and gateway local("sudo sed -i '/iface %s inet static/, +2d' %s" % (dev, temp_intf_file), warn_only=True) if esxi_vm: local("sudo echo ' pre-up ifconfig %s up mtu %s' >> %s" % (dev, datapg_mtu, temp_intf_file), warn_only=True) cmd = "sudo ethtool -i %s | " % dev cmd += "sudo grep driver | sudo cut -f 2 -d ' '" device_driver = local(cmd, capture=True, warn_only=True) if (device_driver == "vmxnet3"): cmd = "sudo echo ' pre-up ethtool --offload " rx_cmd = cmd + "%s rx off' >> %s" % (dev, temp_intf_file) tx_cmd = cmd + "%s tx off' >> %s" % (dev, temp_intf_file) local(rx_cmd, warn_only=True) local(tx_cmd, warn_only=True) if vlan: cmd = "sudo sed -i '/auto %s/ a\iface %s inet manual\\n " %\ (dev, dev) cmd += "post-up ifconfig %s up\\n " % dev cmd += "pre-down ifconfig %s down\' %s" % (dev, temp_intf_file) local(cmd) else: cmd = "sudo sed -i '/auto %s/ a\iface %s inet manual\\n " %\ (dev, dev) cmd += "pre-up ifconfig %s up\\n " % dev cmd += "post-down ifconfig %s down\' %s" %\ (dev, temp_intf_file) local(cmd) if esxi_vm and vmpg_mtu: intf = self.get_secondary_device(self.dev) mac_addr = self.get_if_mac(intf) udev_net_file = '/etc/udev/rules.d/70-persistent-net.rules' temp_udev_net_file = '%s/70-persistent-net.rules' %\ (self._temp_dir_name) local("sudo touch %s" % temp_udev_net_file) local("sudo cp %s %s" % (udev_net_file, temp_udev_net_file)) cmd = "sudo echo 'SUBSYSTEM==\"net\", ACTION==\"add\"," cmd += " DRIVERS==\"?*\"," cmd += " ATTR{address}==\"%s\", ATTR{dev_id}==\"0x0\", " % mac_addr cmd += "ATTR{type}==\"1\", KERNEL==\"eth*\", NAME=\"%s\"' >> %s" %\ (intf, temp_udev_net_file) local(cmd) local("sudo mv -f %s %s" % (temp_udev_net_file, udev_net_file)) local("sudo sed -i '/auto %s/,/down/d' %s" % (intf, temp_intf_file)) local("sudo echo '\nauto %s' >> %s" % (intf, temp_intf_file)) local("sudo echo 'iface %s inet manual' >> %s" % (intf, temp_intf_file)) local("sudo echo ' pre-up ifconfig %s up mtu %s' >> %s" % (intf, vmpg_mtu, temp_intf_file)) local("sudo echo ' post-down ifconfig %s down' >> %s" % (intf, temp_intf_file)) local("sudo echo ' pre-up ethtool --offload %s lro off' >> %s" % (intf, temp_intf_file)) # populte vhost0 as static local("sudo echo '' >> %s" % (temp_intf_file)) local("sudo echo 'auto vhost0' >> %s" % (temp_intf_file)) local("sudo echo 'iface vhost0 inet static' >> %s" % (temp_intf_file)) local("sudo echo ' pre-up %s/if-vhost0' >> %s" % (self.contrail_bin_dir, temp_intf_file)) local("sudo echo ' netmask %s' >> %s" % (netmask, temp_intf_file)) local("sudo echo ' network_name application' >> %s" % temp_intf_file) if esxi_vm and datapg_mtu: local("sudo echo ' mtu %s' >> %s" % (datapg_mtu, temp_intf_file)) if vhost_ip: local("sudo echo ' address %s' >> %s" % (vhost_ip, temp_intf_file)) if (not self._args.non_mgmt_ip) and gateway_ip: local("sudo echo ' gateway %s' >> %s" % (gateway_ip, temp_intf_file)) domain = self.get_domain_search_list() if domain: local("sudo echo ' dns-search %s' >> %s" % (domain, temp_intf_file)) dns_list = self.get_dns_servers(dev) if dns_list: local("sudo echo -n ' dns-nameservers' >> %s" % temp_intf_file) for dns in dns_list: local("sudo echo -n ' %s' >> %s" % (dns, temp_intf_file)) local("sudo echo '' >> %s" % temp_intf_file) local("sudo echo ' post-up ip link set vhost0 address %s' >> %s" % (mac, temp_intf_file)) # move it to right place local("sudo mv -f %s %s" % (temp_intf_file, dev_cfgfile))
def create_init_file(self): local("sudo cp /etc/init.d/contrail-vrouter-agent /etc/init.d/%s" % (self.tor_process_name))
def setup_vrouter_kmod_hugepages(self): """Setup 1G and 2M hugepages for vrouter""" no_of_pages = 2 # Update vrouter kernel mode hugepage config self.setup_vrouter_kmod_hugepage_grub() # Delete vrouter kernel mode 1G hugepage config if os.path.isfile('/etc/fstab'): pattern = "hugepage_1G" line = "" insert_line_to_file(pattern=pattern, line=line, file_name='/etc/fstab') pattern = "vrouter_kmod_1G_hugepages" line = "vrouter_kmod_1G_hugepages=0" insert_line_to_file(pattern=pattern, line=line, file_name='/etc/contrail/agent_param') # Delete vrouter kernel mode 2M hugepage config if os.path.isfile('/etc/fstab'): pattern = "hugepage_2M" line = "" insert_line_to_file(pattern=pattern, line=line, file_name='/etc/fstab') pattern = "vrouter_kmod_2M_hugepages" line = "vrouter_kmod_2M_hugepages=0" insert_line_to_file(pattern=pattern, line=line, file_name='/etc/contrail/agent_param') # Configure vrouter kernel mode 1G hugepages if self._args.vrouter_1G_hugepages != '0': if int(self._args.vrouter_1G_hugepages) > 0 and int(self._args.vrouter_1G_hugepages) <= 2: no_of_pages = int(self._args.vrouter_1G_hugepages) mounted = local("sudo mount | grep hugepage_1G | cut -d' ' -f 3", capture=True, warn_only=False) if (mounted != ""): print("hugepages already mounted on %s" % mounted) else: local("sudo mkdir -p /mnt/hugepage_1G", warn_only=False) local("sudo mount -t hugetlbfs -o pagesize=1G none /mnt/hugepage_1G", warn_only=False) if os.path.isdir('/mnt/hugepage_1G'): for i in range(no_of_pages): local("sudo touch /mnt/hugepage_1G/vrouter_1G_mem_%s " % i, warn_only=False) pattern = "hugepage_1G" line = "hugetlbfs "\ "/mnt/hugepage_1G hugetlbfs defaults,pagesize=1G 0 0" insert_line_to_file(pattern=pattern, line=line, file_name='/etc/fstab') pattern = "vrouter_kmod_1G_hugepages" line = "vrouter_kmod_1G_hugepages=%s" % no_of_pages insert_line_to_file(pattern=pattern, line=line, file_name='/etc/contrail/agent_param') # Configure vrouter kernel mode 2M hugepages if self._args.vrouter_2M_hugepages != '0' and self._args.vrouter_1G_hugepages != '0': if int(self._args.vrouter_2M_hugepages) >= 0 and int(self._args.vrouter_2M_hugepages) <= 2: no_of_pages = int(self._args.vrouter_2M_hugepages) mounted = local("sudo mount | grep hugepage_2M | cut -d' ' -f 3", capture=True, warn_only=False) if (mounted != ""): print("hugepages already mounted on %s" % mounted) else: local("sudo mkdir -p /mnt/hugepage_2M", warn_only=False) local("sudo mount -t hugetlbfs -o pagesize=2M none /mnt/hugepage_2M", warn_only=False) if os.path.isdir('/mnt/hugepage_2M'): for i in range(no_of_pages): local("sudo touch /mnt/hugepage_2M/vrouter_2M_mem_%s " % i, warn_only=False) pattern = "hugepage_2M" line = "hugetlbfs "\ "/mnt/hugepage_2M hugetlbfs defaults,pagesize=2M 0 0" insert_line_to_file(pattern=pattern, line=line, file_name='/etc/fstab') pattern = "vrouter_kmod_2M_hugepages" line = "vrouter_kmod_2M_hugepages=%s" % no_of_pages insert_line_to_file(pattern=pattern, line=line, file_name='/etc/contrail/agent_param')
def run_services(self): if self._args.restart: cmd = "sudo service %s start" % self.tor_process_name local(cmd) cmd = "sudo systemctl enable %s" % self.tor_process_name local(cmd)
def enable_apt_get_auto_start(self): if self.pdist in ['Ubuntu']: local('sudo rm -f /usr/sbin/policy-rc.d')
def _rewrite_ifcfg_file(self, filename, dev, prsv_cfg): bond = False mac = '' temp_dir_name = self._temp_dir_name vlan = False if os.path.isfile('/proc/net/vlan/%s' % dev): vlan_info = open('/proc/net/vlan/config').readlines() match = re.search('^%s.*\|\s+(\S+)$' % dev, "\n".join(vlan_info), flags=re.M | re.I) if not match: raise RuntimeError("Configured vlan %s is not found in", "/proc/net/vlan/config" % dev) vlan = True if os.path.isdir('/sys/class/net/%s/bonding' % dev): bond = True # end if os.path.isdir... mac = netifaces.ifaddresses(dev)[netifaces.AF_LINK][0]['addr'] ifcfg_file = '/etc/sysconfig/network-scripts/ifcfg-%s' % dev if not os.path.isfile(ifcfg_file): ifcfg_file = temp_dir_name + 'ifcfg-' + dev with open(ifcfg_file, 'w') as f: f.write('''#Contrail %s TYPE=Ethernet ONBOOT=yes DEVICE="%s" USERCTL=yes NM_CONTROLLED=no HWADDR=%s ''' % (dev, dev, mac)) for dcfg in prsv_cfg: f.write(dcfg + '\n') if vlan: f.write('VLAN=yes\n') fd = open(ifcfg_file) f_lines = fd.readlines() fd.close() local("sudo rm -f %s" % ifcfg_file) new_f_lines = [] remove_items = [ 'IPADDR', 'NETMASK', 'PREFIX', 'GATEWAY', 'HWADDR', 'DNS1', 'DNS2', 'BOOTPROTO', 'NM_CONTROLLED', '#Contrail' ] remove_items.append('DEVICE') new_f_lines.append('#Contrail %s\n' % dev) new_f_lines.append('DEVICE=%s\n' % dev) for line in f_lines: found = False for text in remove_items: if text in line: found = True if not found: new_f_lines.append(line) new_f_lines.append('NM_CONTROLLED=no\n') if bond: new_f_lines.append('SUBCHANNELS=1,2,3\n') elif not vlan: new_f_lines.append('HWADDR=%s\n' % mac) fdw = open(filename, 'w') fdw.writelines(new_f_lines) fdw.close()
def stop_services(self): if self._args.restart: if not self.systemd_setup: local("sudo supervisorctl -c /etc/contrail/supervisord_vrouter.conf update")