def unpause(self, name): try: utils.execute('lxc-unfreeze', '-n', name) except Exception as ex: with excutils.save_and_reraise_exception(): LOG.error(_('Failed to unpause container for %(name)s: %(ex)s'), {'name': name, 'ex': ex.message})
def _do_pull_image(): name = local_image_name try: import re m = re.search(r'\d+\.\d+\.\d+\.\d+', repository) if m: utils.execute('ping', '-W', '3', '-c', '1', m.group()) LOG.debug(_("Starting pull image repository=%s:%s"), repository, image_id) resp = self.manager.pull(repository, tag=image_id, insecure_registry=True) LOG.debug( _("Done pull image repository=%s:%s, resp %s"), repository, image_id, resp) if any( resp.find(s) != -1 for s in ['"error":', image_name + " not found"]): LOG.warn( _("Can't pull image, use the local image with " "name=%s"), image_name) name = image_name except Exception as e: name = image_name LOG.exception(e) _do_create_after_download_image(name)
def _set_device_mtu(dev, mtu=None): """Set the device MTU.""" if not mtu: mtu = CONF.network_device_mtu if mtu: utils.execute('ip', 'link', 'set', dev, 'mtu', mtu, run_as_root=True, check_exit_code=[0, 2, 254])
def create_container(self, name, network_disabled=False): try: utils.execute('lxc-create', '-n', name, '-t', LXC_TEMPLATE_SCRIPT) except Exception as ex: with excutils.save_and_reraise_exception(): LOG.error(_('Faild to start container ' '%(name)s: %(ex)s'), {'name': name, 'ex': ex.message}) self.destroy(name, network_info)
def check_for_odirect_support(src, dest, flag='oflag=direct'): # Check whether O_DIRECT is supported try: utils.execute('dd', 'count=0', 'if=%s' % src, 'of=%s' % dest, flag, run_as_root=True) return True except processutils.ProcessExecutionError: return False
def delete_net_dev(dev): """Delete a network device only if it exists.""" if device_exists(dev): try: utils.execute('ip', 'link', 'delete', dev, run_as_root=True, check_exit_code=[0, 2, 254]) LOG.debug(_("Net device removed: '%s'"), dev) except processutils.ProcessExecutionError: with excutils.save_and_reraise_exception(): LOG.error(_("Failed removing net device: '%s'"), dev)
def _dynamic_attach_or_detach_volume(self, name, device, maj, min, attach=True): action = 'add' if attach else 'del' utils.execute('lxc-device', '-n', name, action, device) cgroup_device_allow = '/sys/fs/cgroup/devices/lxc/%s/devices.%s' \ %(name, 'allow' if attach else 'deny') for i in range(1, 16): with open(cgroup_device_allow, 'w') as f: f.write('b %(maj)s:%(min)s rwm\n'%{'maj':maj, 'min':min+i})
def start(self, name, network_info=None, block_device_info=None, timeout=10): # Start the container try: self.add_interfaces(name, network_info, append=False) utils.execute('lxc-start', '-n', name, '-d', '-l', 'DEBUG') utils.execute('lxc-wait', '-n', name, '-s', 'RUNNING', '-t', timeout) except Exception as ex: with excutils.save_and_reraise_exception(): LOG.error(_('Failed to start container' ' for %(name)s: %(ex)s'), {'name': name, 'ex': ex.message})
def teardown_network(container_id): try: output, err = utils.execute('ip', '-o', 'netns', 'list') for line in output.split('\n'): if container_id == line.strip(): utils.execute('ip', 'netns', 'delete', container_id, run_as_root=True) break except processutils.ProcessExecutionError: LOG.warning(_('Cannot remove network namespace, netns id: %s'), container_id)
def stop(self, name, timeout): containers = self.list() status = [c['status'] for c in containers if c['name'] == name]or [''] if status and status[0] != 'RUNNING': return "Container {} is {}, can't stop it".format(name, status[0]) try: utils.execute('lxc-stop', '-n', name, '-t', timeout) except Exception as ex: with excutils.save_and_reraise_exception(): LOG.error(_('Failed to stop container' ' for %(name)s: %(ex)s'), {'name': name, 'ex': ex.message})
def destroy(self, name, network_info): """Destroy the instance on the LXD host """ try: utils.execute('lxc-destroy', '-f', '-n', name) LOG.info('Destroyed for %s' %name) except Exception as ex: with excutils.save_and_reraise_exception(): LOG.error(_('Failed to remove container' ' for %(name)s: %(ex)s'), {'name': name, 'ex': ex.message})
def create_tap_dev(dev, mac_address=None): if not device_exists(dev): try: # First, try with 'ip' utils.execute('ip', 'tuntap', 'add', dev, 'mode', 'tap', run_as_root=True, check_exit_code=[0, 2, 254]) except processutils.ProcessExecutionError: # Second option: tunctl utils.execute('tunctl', '-b', '-t', dev, run_as_root=True) if mac_address: utils.execute('ip', 'link', 'set', dev, 'address', mac_address, run_as_root=True, check_exit_code=[0, 2, 254]) utils.execute('ip', 'link', 'set', dev, 'up', run_as_root=True, check_exit_code=[0, 2, 254])
def _create_ns(self): container_id = self.container['id'] netns_path = '/var/run/netns' if not os.path.exists(netns_path): utils.execute('mkdir', '-p', netns_path, run_as_root=True) nspid = self._find_container_pid(container_id) if not nspid: msg = _('Cannot find any PID under container "{0}"') raise RuntimeError(msg.format(container_id)) netns_path = os.path.join(netns_path, container_id) utils.execute( 'ln', '-sf', '/proc/{0}/ns/net'.format(nspid), '/var/run/netns/{0}'.format(container_id), run_as_root=True) self._ns_created = True
def _create_ns(self): container_id = self.container['id'] netns_path = '/var/run/netns' if not os.path.exists(netns_path): utils.execute('mkdir', '-p', netns_path, run_as_root=True) nspid = self._find_container_pid(container_id) if not nspid: msg = _('Cannot find any PID under container "{0}"') raise RuntimeError(msg.format(container_id)) netns_path = os.path.join(netns_path, container_id) utils.execute('ln', '-sf', '/proc/{0}/ns/net'.format(nspid), '/var/run/netns/{0}'.format(container_id), run_as_root=True) self._ns_created = True
def list(self, all=True): containers, _err = utils.execute('lxc-ls', '-f', '-F', 'NAME,STATE') if containers: # skip the header containers = filter(str.strip, containers.split('\n')[1:]) return [{'id': name, 'status': state, 'name':name} for name, state in map(str.split, containers)] return []
def _ovs_ofctl(args): full_args = ['ovs-ofctl', '--timeout=%s' % CONF.ovs_vsctl_timeout] + args try: return utils.execute(*full_args, run_as_root=True) except Exception as e: LOG.error(_("Unable to execute %(cmd)s. Exception: %(exception)s"), {'cmd': full_args, 'exception': e}) raise e
def _do_pull_image(): name = local_image_name try: import re m = re.search(r'\d+\.\d+\.\d+\.\d+', repository) if m: utils.execute('ping', '-W', '3', '-c', '1', m.group()) LOG.debug(_("Starting pull image repository=%s:%s"), repository, image_id) resp = self.manager.pull(repository, tag=image_id, insecure_registry=True) LOG.debug(_("Done pull image repository=%s:%s, resp %s"), repository, image_id, resp) if any(resp.find(s)!=-1 for s in ['"error":', image_name + " not found"]): LOG.warn(_("Can't pull image, use the local image with name=%s"), image_name) name = image_name except Exception as e: name = image_name LOG.exception(e) _do_create_after_download_image(name)
def unplug_ovs_hybrid(self, instance, vif): """UnPlug using hybrid strategy Unhook port from OVS, unhook port from bridge, delete bridge, and delete both veth devices. """ try: br_name = self.get_br_name(vif['id']) vm_port_name = self.get_vm_ovs_port_name(vif['id']) if_local_name = 'tap%s' % vif['id'][:11] if linux_net.device_exists(if_local_name): linux_net.delete_net_dev(if_local_name) if linux_net.device_exists(br_name): utils.execute('brctl', 'delif', br_name, vm_port_name, run_as_root=True) utils.execute('ip', 'link', 'set', br_name, 'down', run_as_root=True) utils.execute('brctl', 'delbr', br_name, run_as_root=True) linux_net.delete_ovs_vif_port(self.get_bridge_name(vif), vm_port_name) except processutils.ProcessExecutionError: LOG.exception(_("Failed while unplugging vif for %s"), instance)
def _create_veth_pair(dev1_name, dev2_name): """Create a pair of veth devices with the specified names, deleting any previous devices with those names. """ for dev in [dev1_name, dev2_name]: delete_net_dev(dev) utils.execute('ip', 'link', 'add', dev1_name, 'type', 'veth', 'peer', 'name', dev2_name, run_as_root=True) for dev in [dev1_name, dev2_name]: utils.execute('ip', 'link', 'set', dev, 'up', run_as_root=True) utils.execute('ip', 'link', 'set', dev, 'promisc', 'on', run_as_root=True) _set_device_mtu(dev)
def unplug_ovs_hybrid(self, instance, vif): """UnPlug using hybrid strategy Unhook port from OVS, unhook port from bridge, delete bridge, and delete both veth devices. """ try: br_name = self.get_br_name(vif['id']) vm_port_name = self.get_vm_ovs_port_name(vif['id']) if linux_net.device_exists(br_name): utils.execute('brctl', 'delif', br_name, vm_port_name, run_as_root=True) utils.execute('ip', 'link', 'set', br_name, 'down', run_as_root=True) utils.execute('brctl', 'delbr', br_name, run_as_root=True) linux_net.delete_ovs_vif_port(self.get_bridge_name(vif), vm_port_name) except processutils.ProcessExecutionError: LOG.exception(_("Failed while unplugging vif for %s"), instance)
def plug_ovs_hybrid(self, instance, vif): """Plug using hybrid strategy Create a per-VIF linux bridge, then link that bridge to the OVS integration bridge via an ovs internal port device. Then boot the VIF on the linux bridge using standard net_util mechanisms. """ if_local_name = 'tap%s' % vif['id'][:11] if_remote_name = 'ns%s' % vif['id'][:11] iface_id = self.get_ovs_interfaceid(vif) br_name = self.get_br_name(vif['id']) vm_port_name = self.get_vm_ovs_port_name(vif['id']) # Device already exists so return. if linux_net.device_exists(if_local_name): return undo_mgr = utils.UndoManager() try: if not linux_net.device_exists(br_name): utils.execute('brctl', 'addbr', br_name, run_as_root=True) undo_mgr.undo_with(lambda: utils.execute( 'brctl', 'delbr', br_name, run_as_root=True)) utils.execute('brctl', 'setfd', br_name, 0, run_as_root=True) utils.execute('brctl', 'stp', br_name, 'off', run_as_root=True) utils.execute( 'tee', ('/sys/class/net/%s/bridge/multicast_snooping' % br_name), process_input='0', run_as_root=True, check_exit_code=[0, 1]) #fix bridge's state is down after host reboot. linux_net.create_ovs_vif_port(self.get_bridge_name(vif), vm_port_name, iface_id, vif['address'], instance, internal=True) undo_mgr.undo_with(lambda: utils.execute('ovs-vsctl', 'del-port', self.get_bridge_name(vif), vm_port_name, run_as_root=True)) utils.execute('ip', 'link', 'set', br_name, 'up', run_as_root=True) utils.execute('brctl', 'addif', br_name, vm_port_name, run_as_root=True) # veth utils.execute('ip', 'link', 'add', 'name', if_local_name, 'type', 'veth', 'peer', 'name', if_remote_name, run_as_root=True) undo_mgr.undo_with(lambda: utils.execute( 'ip', 'link', 'delete', if_local_name, run_as_root=True)) # Deleting/Undoing the interface will delete all # associated resources (remove from the bridge, its pair, etc...) utils.execute('brctl', 'addif', br_name, if_local_name, run_as_root=True) utils.execute('ip', 'link', 'set', if_local_name, 'up', run_as_root=True) except Exception: msg = "Failed to configure Network." \ " Rolling back the network interfaces %s %s" % ( br_name, vm_port_name) undo_mgr.rollback_and_reraise(msg=msg, instance=instance)
def attach(self, vif, instance, container_id, new_remote_name): vif_type = vif['type'] if_remote_name = 'ns%s' % vif['id'][:11] gateway = network.find_gateway(instance, vif['network']) ip = network.find_fixed_ip(instance, vif['network']) LOG.debug( 'attach vif_type=%(vif_type)s instance=%(instance)s ' 'vif=%(vif)s', { 'vif_type': vif_type, 'instance': instance, 'vif': vif }) try: utils.execute('ip', 'link', 'set', if_remote_name, 'netns', container_id, run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', 'dev', if_remote_name, 'name', new_remote_name, run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', new_remote_name, 'address', vif['address'], run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'addr', 'add', ip, 'dev', new_remote_name, run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', new_remote_name, 'up', run_as_root=True) # Setup MTU on new_remote_name is required if it is a non # default value mtu = CONF.network_device_mtu if vif.get('mtu') is not None: mtu = vif.get('mtu') if mtu is not None: utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', new_remote_name, 'mtu', mtu, run_as_root=True) if gateway is not None: utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'route', 'replace', 'default', 'via', gateway, 'dev', new_remote_name, run_as_root=True) # utils.execute('ip', 'netns', 'exec', container_id, # 'ip', 'route', 'add', '0.0.0.0/0', 'via', # gateway, run_as_root=True) # Disable TSO, for now no config option utils.execute('ip', 'netns', 'exec', container_id, 'ethtool', '--offload', new_remote_name, 'tso', 'off', run_as_root=True) except Exception: LOG.exception("Failed to attach vif")
def create_ivs_vif_port(dev, iface_id, mac, instance_id): utils.execute('ivs-ctl', 'add-port', dev, run_as_root=True)
def delete_ivs_vif_port(dev): utils.execute('ivs-ctl', 'del-port', dev, run_as_root=True) utils.execute('ip', 'link', 'delete', dev, run_as_root=True)
def inspect_container(self, container_id): # need to return the container process pid # rsp structure rsp['State']['Pid'] = pid info, _err = utils.execute('lxc-info', '-p', '-n', container_id) return {'State': {'Pid': info.split()[-1]}} if info else {}
def _execute(*cmd, **kwargs): """Wrapper around utils._execute for fake_network.""" return utils.execute(*cmd, **kwargs)
def execute(self, container_id, *cmd): out, _err = utils.execute('lxc-attach', '-n', container_id, '--', *cmd, attempts=1) return out
def attach(self, vif, instance, container_id, new_remote_name): vif_type = vif['type'] if_local_name = 'tap%s' % vif['id'][:11] if_remote_name = 'ns%s' % vif['id'][:11] br_name = self.get_br_name(vif['id']) gateway = network.find_gateway(instance, vif['network']) ip = network.find_fixed_ip(instance, vif['network']) LOG.debug( 'attach vif_type=%(vif_type)s instance=%(instance)s ' 'vif=%(vif)s', { 'vif_type': vif_type, 'instance': instance, 'vif': vif }) try: if linux_net.device_exists(if_local_name): linux_net.delete_net_dev(if_local_name) # veth utils.execute('ip', 'link', 'add', 'name', if_local_name, 'type', 'veth', 'peer', 'name', if_remote_name, run_as_root=True) # Deleting/Undoing the interface will delete all # associated resources (remove from the bridge, its pair, etc...) utils.execute('brctl', 'addif', br_name, if_local_name, run_as_root=True) utils.execute('ip', 'link', 'set', if_local_name, 'up', run_as_root=True) utils.execute('ip', 'link', 'set', if_remote_name, 'netns', container_id, run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', 'dev', if_remote_name, 'name', new_remote_name, run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', new_remote_name, 'address', vif['address'], run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'addr', 'add', ip, 'dev', new_remote_name, run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', new_remote_name, 'up', run_as_root=True) # Setup MTU on new_remote_name is required if it is a non # default value #mtu = CONF.network_device_mtu mtu = 1300 if vif.get('mtu') is not None: mtu = vif.get('mtu') if mtu is not None: utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', new_remote_name, 'mtu', mtu, run_as_root=True) if gateway is not None: utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'route', 'replace', 'default', 'via', gateway, 'dev', new_remote_name, run_as_root=True) # utils.execute('ip', 'netns', 'exec', container_id, # 'ip', 'route', 'add', '0.0.0.0/0', 'via', # gateway, run_as_root=True) # Disable TSO, for now no config option utils.execute('ip', 'netns', 'exec', container_id, 'ethtool', '--offload', new_remote_name, 'tso', 'off', run_as_root=True) except Exception as e: LOG.exception(_("Failed to attach vif: %s"), str(e.message))
def plug_ovs_hybrid(self, instance, vif): """Plug using hybrid strategy Create a per-VIF linux bridge, then link that bridge to the OVS integration bridge via an ovs internal port device. Then boot the VIF on the linux bridge using standard net_util mechanisms. """ if_local_name = 'tap%s' % vif['id'][:11] if_remote_name = 'ns%s' % vif['id'][:11] iface_id = self.get_ovs_interfaceid(vif) br_name = self.get_br_name(vif['id']) vm_port_name = self.get_vm_ovs_port_name(vif['id']) # Device already exists so return. if linux_net.device_exists(if_local_name): return undo_mgr = utils.UndoManager() try: if not linux_net.device_exists(br_name): utils.execute('brctl', 'addbr', br_name, run_as_root=True) undo_mgr.undo_with(lambda: utils.execute('brctl', 'delbr', br_name, run_as_root=True)) utils.execute('brctl', 'setfd', br_name, 0, run_as_root=True) utils.execute('brctl', 'stp', br_name, 'off', run_as_root=True) utils.execute('tee', ('/sys/class/net/%s/bridge/multicast_snooping' % br_name), process_input='0', run_as_root=True, check_exit_code=[0, 1]) #fix bridge's state is down after host reboot. linux_net.create_ovs_vif_port(self.get_bridge_name(vif), vm_port_name, iface_id, vif['address'], instance, internal=True) undo_mgr.undo_with( lambda: utils.execute('ovs-vsctl', 'del-port', self.get_bridge_name(vif), vm_port_name, run_as_root=True)) utils.execute('ip', 'link', 'set', self.get_bridge_name(vif), 'up', run_as_root=True) utils.execute('ip', 'link', 'set', vm_port_name, 'up', run_as_root=True) utils.execute('ip', 'link', 'set', br_name, 'up', run_as_root=True) utils.execute('brctl', 'addif', br_name, vm_port_name, run_as_root=True) except Exception: msg = "Failed to configure Network." \ " Rolling back the network interfaces %s %s" % ( br_name, vm_port_name) undo_mgr.rollback_and_reraise(msg=msg, instance=instance)
def attach(self, vif, instance, container_id, new_remote_name): vif_type = vif['type'] if_local_name = 'tap%s' % vif['id'][:11] if_remote_name = 'ns%s' % vif['id'][:11] br_name = self.get_br_name(vif['id']) gateway = network.find_gateway(instance, vif['network']) ip = network.find_fixed_ip(instance, vif['network']) LOG.debug('attach vif_type=%(vif_type)s instance=%(instance)s ' 'vif=%(vif)s', {'vif_type': vif_type, 'instance': instance, 'vif': vif}) try: if linux_net.device_exists(if_local_name): linux_net.delete_net_dev(if_local_name) # veth utils.execute('ip', 'link', 'add', 'name', if_local_name, 'type', 'veth', 'peer', 'name', if_remote_name, run_as_root=True) # Deleting/Undoing the interface will delete all # associated resources (remove from the bridge, its pair, etc...) utils.execute('brctl', 'addif', br_name, if_local_name, run_as_root=True) utils.execute('ip', 'link', 'set', if_local_name, 'up', run_as_root=True) utils.execute('ip', 'link', 'set', if_remote_name, 'netns', container_id, run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', 'dev', if_remote_name, 'name', new_remote_name, run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', new_remote_name, 'address', vif['address'], run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'addr', 'add', ip, 'dev', new_remote_name, run_as_root=True) utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', new_remote_name, 'up', run_as_root=True) # Setup MTU on new_remote_name is required if it is a non # default value #mtu = CONF.network_device_mtu mtu = 1300 if vif.get('mtu') is not None: mtu = vif.get('mtu') if mtu is not None: utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'link', 'set', new_remote_name, 'mtu', mtu, run_as_root=True) if gateway is not None: utils.execute('ip', 'netns', 'exec', container_id, 'ip', 'route', 'replace', 'default', 'via', gateway, 'dev', new_remote_name, run_as_root=True) # utils.execute('ip', 'netns', 'exec', container_id, # 'ip', 'route', 'add', '0.0.0.0/0', 'via', # gateway, run_as_root=True) # Disable TSO, for now no config option utils.execute('ip', 'netns', 'exec', container_id, 'ethtool', '--offload', new_remote_name, 'tso', 'off', run_as_root=True) except Exception as e: LOG.exception(_("Failed to attach vif: %s"), str(e.message))