def apply_config_lxc(self, lxc_name, waittime=5, retries=12): """Generate and apply VPP configuration for node in a container. Use data from calls to this class to form a startup.conf file and replace /etc/vpp/startup.conf with it on node inside a container. :param lxc_name: LXC container name. :param waittime: Time to wait for VPP to restart (default 5 seconds). :param retries: Number of times (default 12) to re-try waiting. :type lxc_name: str :type waittime: int :type retries: int :raises RuntimeError: If writing config file failed, or restarting of VPP failed. """ self.dump_config(self._nodeconfig) ssh = SSH() ssh.connect(self._node) # We're using this "| sudo tee" construct because redirecting # a sudo's output ("sudo echo xxx > /path/to/file") does not # work on most platforms... (ret, _, _) = \ ssh.exec_command_lxc('echo "{0}" | sudo tee {1}'. format(self._vpp_config, self._vpp_config_filename), lxc_name) if ret != 0: raise RuntimeError('Writing config file failed in {0} to node {1}'. format(lxc_name, self._hostname)) # Instead of restarting, we'll do separate start and stop # actions. This way we don't care whether VPP was running # to begin with. ssh.exec_command_lxc('service {0} stop'. format(self._vpp_service_name), lxc_name) (ret, _, _) = \ ssh.exec_command_lxc('service {0} start'. format(self._vpp_service_name), lxc_name) if ret != 0: raise RuntimeError('Restarting VPP failed in {0} on node {1}'. format(lxc_name, self._hostname)) # Sleep <waittime> seconds, up to <retry> times, # and verify if VPP is running. for _ in range(retries): time.sleep(waittime) (ret, _, _) = \ ssh.exec_command_lxc('echo show hardware-interfaces | ' 'nc 0 5002 || echo "VPP not yet running"', lxc_name) if ret == 0: break else: raise RuntimeError('VPP failed to restart in {0} on node {1}'. format(lxc_name, self._hostname))
def lxc_attach(self, command): """Start a process inside a running container. Runs the specified command inside the container specified by name. The container has to be running already. :param command: Command to run inside container. :type command: str :raises RuntimeError: If container is not running. :raises RuntimeError: If failed to run the command. """ env_var = '--keep-env {0}'\ .format(' '.join('--set-var %s' % var for var in self._env_vars)) ssh = SSH() ssh.connect(self._node) if not self.is_container_running(): raise RuntimeError('LXC {0} is not running.'.format( self._container_name)) ret, _, _ = ssh.exec_command_lxc(lxc_cmd=command, lxc_name=self._container_name, lxc_params=env_var, timeout=180) if int(ret) != 0: raise RuntimeError( 'Failed to run "{0}" on LXC container {1}.'.format( command, self._container_name))