def __init__( self, *, project, echoer, is_ephemeral: bool = False, build_provider_flags: Dict[str, str] = None, ) -> None: super().__init__( project=project, echoer=echoer, is_ephemeral=is_ephemeral, build_provider_flags=build_provider_flags, ) self.echoer.warning( "The LXD provider is offered as a technology preview for early adopters.\n" "The command line interface, container names or lifecycle handling may " "change in upcoming releases.") # This endpoint is hardcoded everywhere lxc/lxd-pkg-snap#33 lxd_socket_path = "/var/snap/lxd/common/lxd/unix.socket" endpoint = "http+unix://{}".format( urllib.parse.quote(lxd_socket_path, safe="")) try: self._lxd_client: pylxd.Client = pylxd.Client(endpoint=endpoint) except pylxd.client.exceptions.ClientConnectionFailed: raise errors.ProviderCommunicationError( provider_name=self._get_provider_name(), message="cannot connect to the LXD socket ({!r}).".format( lxd_socket_path), ) self._container: Optional[pylxd.models.container.Container] = None
def setUp(self): self.client = pylxd.Client() self.fingerprint = self.client.images.all()[0].fingerprint self.db_path = './lab.db' self.port_start = 61000 self.ip_start = '10.18.242.2/24' self.conn = sqlite3.connect(':memory:') cursor = self.conn.cursor() cursor.execute( 'CREATE TABLE lab_users'+\ '(uid INTEGER PRIMARY KEY AUTOINCREMENT,'+\ 'username TEXT NOT NULL UNIQUE,'+\ 'password TEXT NOT NULL );' ) cursor.execute( 'CREATE TABLE lab_containers(\ container_name TEXT NOT NULL PRIMARY KEY UNIQUE,\ belongs_to_username TEXT NOT NULL,\ FOREIGN KEY(belongs_to_username) REFERENCES \ lab_users(username)\ );') cursor.close() self.conn.commit() self.username = self._gen_name('testing-user') self.user = LabUser( self.username, self.conn, self.client, 61000, '10.18.242.2/24' )
def __init__(self, path, token, app_name, reconcile_interval): http_proxy = os.environ.get("JUJU_CHARM_HTTP_PROXY", None) https_proxy = os.environ.get("JUJU_CHARM_HTTPS_PROXY", None) no_proxy = os.environ.get("JUJU_CHARM_NO_PROXY", None) self.proxies = {} if http_proxy: self.proxies["http"] = http_proxy if https_proxy: self.proxies["https"] = https_proxy if no_proxy: self.proxies["no_proxy"] = no_proxy self.session = requests.Session() if self.proxies: # setup proxy for requests self.session.proxies.update(self.proxies) # add proxy to fastcore which ghapi uses proxy = urllib.request.ProxyHandler(self.proxies) opener = urllib.request.build_opener(proxy) fastcore.net._opener = opener self.jinja = Environment(loader=FileSystemLoader("templates")) self.lxd = pylxd.Client() self.path = path self.api = GhApi(token=token) self.app_name = app_name self.reconcile_interval = reconcile_interval
def __init__( self, *, project, echoer, is_ephemeral: bool = False, build_provider_flags: Dict[str, str] = None, ) -> None: super().__init__( project=project, echoer=echoer, is_ephemeral=is_ephemeral, build_provider_flags=build_provider_flags, ) # This endpoint is hardcoded everywhere lxc/lxd-pkg-snap#33 lxd_socket_path = "/var/snap/lxd/common/lxd/unix.socket" endpoint = "http+unix://{}".format( urllib.parse.quote(lxd_socket_path, safe="")) try: self._lxd_client: pylxd.Client = pylxd.Client(endpoint=endpoint) except pylxd.client.exceptions.ClientConnectionFailed: raise errors.ProviderCommunicationError( provider_name=self._get_provider_name(), message="cannot connect to the LXD socket ({!r}).".format( lxd_socket_path), ) self._container: Optional[pylxd.models.container.Container] = None
def create_container(self): """Create the LXC container.""" logger.info('Creating LXC container for: %s', self.name) client = pylxd.Client() config = { 'name': self.name, 'source': { 'type': 'image', 'alias': self.image, } } if isinstance(self.custom_configuration, dict): config.update(self.custom_configuration) # Check whether image with alias exists locally. try: client.images.get_by_alias(self.image) except pylxd.exceptions.NotFound: # Not found, so use the server. logger.debug('Image "%s" not found locally, pulling from %s', self.image, self.image_server) config['source'].update({ 'protocol': 'simplestreams', 'server': self.image_server }) # Tag for removal with cleanup. self.container = client.containers.create(config, wait=True) self.container.config.update({'user.created-by': 'ns-3'}) self.container.save(wait=True)
def setup_host_interfaces(self): """Setup the interfaces (bridge, tap, VETH pair) on the host and connect them to the container.""" for name, interface in self.interfaces.items(): logger.debug('Setting up interface %s on %s.', name, self.name) interface.setup_bridge() interface.connect_tap_to_bridge() self.container.devices.update({ name: { 'name': name, 'type': 'nic', 'nictype': 'bridged', 'parent': interface.bridge_name, 'hwaddr': interface.mac_address, 'host_name': interface.veth_name, } }) self.container.save(wait=True) container_state = pylxd.Client().api.containers[ self.name].state.get().json() pid = container_state['metadata']['pid'] # Get container's namespace and setup the interface in the container with Namespace(pid, 'net'): interface.setup_veth_container_end(name)
def setUpClass(self): warnings.simplefilter('ignore') self.client = pylxd.Client() self.fingerprint = self.client.images.all()[0].fingerprint self.conn = sqlite3.connect(':memory:') self.username = '******' self.password = '******' cursor = self.conn.cursor() # create lab_users cursor.execute( 'CREATE TABLE lab_users'+\ '(uid INTEGER PRIMARY KEY AUTOINCREMENT,'+\ 'username TEXT NOT NULL UNIQUE,'+\ 'password TEXT NOT NULL );' ) # insert one record into lab_users cursor.execute('insert into lab_users(username, password) values(?,?)', (self.username, \ self.password)) # create lab_containers cursor.execute( 'CREATE TABLE lab_containers(\ container_name TEXT NOT NULL PRIMARY KEY UNIQUE,\ belongs_to_username TEXT NOT NULL,\ FOREIGN KEY(belongs_to_username) REFERENCES \ lab_users(username)\ );') cursor.close() self.conn.commit()
def __init__(self): self.config = Config() #self.client = pylxd.Client(endpoint=self.config['DEFAULT']['LXD_URL'], cert=(self.config['DEFAULT']['LXD_CERT'], self.config['DEFAULT']['LXD_KEY']), verify=False) self.client = pylxd.Client() #client.authenticate('ferrari') self.status = Status()
def process_metrics(g_cpu,g_mem_usage,g_mem_usage_peak,g_swap_usage,g_swap_usage_peak,\ g_process_count,g_disk_usage,g_container_pid,g_network_usage,g_container_status,\ g_total_cpu,g_total_mem): time.sleep(1) client = pylxd.Client() containers = client.containers.all() for container in containers: try: if container.state().status == 'Running': cpu_usage = container.state().cpu['usage'] mem_usage = container.state().memory['usage'] mem_usage_peak = container.state().memory['usage_peak'] swap_usage = container.state().memory['swap_usage'] swap_usage_peak = container.state().memory['swap_usage'] process_count = container.state().processes disk_usage = container.state().disk['root']['usage'] container_pid = container.state().pid container_name = container.name container_status = 1 network = container.state().network g_disk_uage.labels(container_name, 'disk_usage').set(disk_usage) for interface, value in network.iteritems(): for operation, value in value['counters'].iteritems(): g_network_usage.labels(container_name, 'container_pid', interface, operation).set(value) else: cpu_usage = 0 mem_usage = 0 mem_usage_peak = 0 swap_usage = 0 swap_usage_peak = 0 process_count = 0 disk_usage = 0 container_pid = -1 container_name = container.name container_status = 0 total_cpu = multiprocessing.cpu_count() total_mem = virtual_memory().total g_total_cpu.labels('total_cpu').set(total_cpu) g_total_mem.labels('total_mem').set(total_mem) g_cpu.labels(container_name, 'cpu_usage').set(cpu_usage) g_mem_usage.labels(container_name, 'mem_usage').set(mem_usage) g_mem_usage_peak.labels(container_name, 'mem_usage_peak').set(mem_usage_peak) g_swap_usage.labels(container_name, 'swap_usage').set(swap_usage) g_swap_usage_peak.labels(container_name, 'swap_usage_peak').set(swap_usage_peak) g_process_count.labels(container_name, 'process_count').set(process_count) g_container_pid.labels(container_name, 'container_pid').set(container_pid) g_container_status.labels(container_name, 'container_status').set(container_status) except: pass
def test_authenticate(self): client = pylxd.Client("https://127.0.0.1:8443/", verify=False) self.assertFalse(client.trusted) client.authenticate("password") self.assertTrue(client.trusted)
def _migrate(self, source_host, instance): """Migrate an instance from source.""" source_client = pylxd.Client( endpoint='https://{}'.format(source_host), verify=False) container = source_client.containers.get(instance.name) data = container.generate_migration_data() self.containers.create(data, wait=True)
def get_pylxd_client(): lxd_port = config.get_config(config.Key.lxd_port) try: return pylxd.Client(endpoint=f"http://127.0.0.1:{lxd_port}") except pylxd.exceptions.ClientConnectionFailed as e: logging.debug(e) raise LXCException( "Error connecting to LXD. Try restarting the VM: 'yurt vm restart'")
def get_client(rname="main", verify=False): cert = None remote = cfg.remotes.get(rname) if remote.addr and remote.addr.startswith("https://"): cert = cfg.key_pair_paths() log.info(f"Connecting to LXD: {remote.addr or 'local unix-socket'}") return pylxd.Client(endpoint=remote.addr, cert=cert, verify=verify)
def remove_all_lxd(): lxd_inst = pylxd.Client() lxd_running = lxd_inst.containers.all() for cont in lxd_running: if cont.status == "Running": cont.stop(wait=True) cont.delete()
def detect_capabilities(): if pylxd is None: return {} try: client = pylxd.Client() info = client.host_info return {'lxd': info['environment']['server_version']} except Exception: return {}
def connect(self, client_address): print('Establish a connection to the LXD daemon at {} ... '.format( client_address)), client = pylxd.Client(endpoint=client_address, cert=(self.CERT_PATH, self.KEY_PATH), verify=False) client.authenticate('trust') print('DONE.') return client
def __init__(self, name, config, service): super().__init__(name, 'lxd', config, service) self._host_info = HostInfo.HostInfo() self._container = None self._freeze_on_stop = config.get_freeze_on_stop(self.container_id) if not _setup_lxd(): raise Exception("Failed to setup lxd.") self._lxd_client = pylxd.Client()
def test_authenticate(self): # This is another test with multiple assertions, as it is a test of # flow, rather than a single source of functionality. client = pylxd.Client('https://127.0.0.1:8443/', verify=False) self.assertFalse(client.trusted) client.authenticate('password') self.assertTrue(client.trusted)
def __init__(self, project_: project.Project, name: str = None, image: str = None, arch: str = None, ephemeral: bool = True): self._project = project_ self._lxd = pylxd.Client() self._name = name if name else self._gen_name() self._image = image or 'ubuntu:xenial' self._arch = arch or 'amd64' self._ephemeral = ephemeral self._container = None self._ready = False
def setUp(self): super().setUp() try: pylxd.Client("https://127.0.0.1:8443/", verify=False, project="test-project") except exceptions.ClientConnectionFailed as e: message = str(e) if message == "Remote server doesn't handle projects": self.skipTest(message) raise
def __init__(self, connection: Connection, interval: timedelta, lxd_config: LxdConfig, job: Job, **kwargs) -> None: cert = (str(lxd_config.cert.expanduser()), str(lxd_config.key.expanduser())) self._client = pylxd.Client(cert=cert, endpoint=lxd_config.endpoint, verify=lxd_config.verify) self._lxd_config = lxd_config self._job = job self._interval = interval self._connection = connection super().__init__(**kwargs)
def __init__(self, *, project, echoer, is_ephemeral: bool = False) -> None: super().__init__(project=project, echoer=echoer, is_ephemeral=is_ephemeral) self.echoer.warning( "The LXD provider is offered as a technology preview for early adopters.\n" "The command line interface, container names or lifecycle handling may " "change in upcoming releases." ) # This endpoint is hardcoded everywhere lxc/lxd-pkg-snap#33 lxd_socket_path = "/var/snap/lxd/common/lxd/unix.socket" endpoint = "http+unix://{}".format(urllib.parse.quote(lxd_socket_path, safe="")) self._lxd_client = pylxd.Client(endpoint=endpoint) self._container = None # type: Optional[pylxd.models.container.Container]
def test_authenticate_with_project(self): try: client = pylxd.Client("https://127.0.0.1:8443/", verify=False, project="test-project") except exceptions.ClientConnectionFailed as e: message = str(e) if message == "Remote server doesn't handle projects": self.skipTest(message) raise client.authenticate("password") self.assertEqual(client.host_info["environment"]["project"], "test-project")
def _lxd_client(self): """ _lxd_client returns a client object to manage LXD containers. """ # TODO(axw) this just gives a localhost conn, we'll need # to use configuration to get a remote conn. # # TODO(axw) obtain LXD server's CA cert so we can verify. kwargs = {'verify': False} if self.lxd_endpoint: kwargs['endpoint'] = self.lxd_endpoint if self.lxd_client_cert and self.lxd_client_key: kwargs['cert'] = (self.lxd_client_cert, self.lxd_client_key) return pylxd.Client(**kwargs)
def setUpClass(cls): cls.client = pylxd.Client() cls.image = None if cls.client.images.exists(cls.IMAGE_ALIAS, alias=True): cls.image = cls.client.images.get_by_alias(cls.IMAGE_ALIAS) else: with open(cls.UNIFIED_TARBALL, 'rb') as unified_tarball: cls.image = cls.client.images.create(unified_tarball) cls.image.add_alias(cls.IMAGE_ALIAS, 'lxd test image') cls.image.save(wait=True) # Profile setup + mocks to bind-mount in. cls.profile = None if cls.client.profiles.exists(cls.TEST_PROFILE): cls.profile = cls.client.profiles.get(cls.TEST_PROFILE) cls.profile.delete(wait=True) script_dir = os.path.dirname(os.path.abspath(__file__)) lddtree_dir = os.path.join(script_dir, 'mocks', 'lddtree') sshd_dir = os.path.join(script_dir, 'mocks', 'sshd_config') cls.profile = cls.client.profiles.create( cls.TEST_PROFILE, config={ 'boot.autostart': 'false', 'security.syscalls.blacklist': 'keyctl errno 38' }, devices={ 'root': { 'path': '/', 'pool': 'default', 'type': 'disk', }, 'eth0': { 'nictype': 'bridged', 'parent': 'lxdbr0', 'type': 'nic', }, 'cros_containers': { 'source': lddtree_dir, 'path': '/opt/google/cros-containers', 'type': 'disk', }, 'sshd_config': { 'source': sshd_dir, 'path': '/dev/.ssh/sshd_config', 'type': 'disk', }, })
def client_connect(self, hosts=None): if not hosts: hosts = Host.query.all() app = current_app key = app.config['LXKEY'] cert = app.config['LXCERT'] for host in hosts: if not host.name in self.clients: logger.debug('Connecting LXC Client to {}'.format(host.name)) self.clients[host.name] = pylxd.Client( endpoint='https://{}:8443'.format(host.name), cert=(cert, key), verify=False)
def init_host(self, host): """Initialize the driver on the host. The pylxd Client is initialized. This initialization may raise an exception if the LXD instance cannot be found. The `host` argument is ignored here, as the LXD instance is assumed to be on the same system as the compute worker running this code. This is by (current) design. See `nova.virt.driver.ComputeDriver.init_host` for more information. """ try: self.client = pylxd.Client() except lxd_exceptions.ClientConnectionFailed as e: msg = _('Unable to connect to LXD daemon: %s') % e raise exception.HostNotFound(msg) self._after_reboot()
def __init__(self, image=None, name=None): super().__init__() print("Creating a LXD node") self.client = pylxd.Client() if name: print(f"getting container {name}") self.container = self.client.containers.get(name) elif image: self.__setup_profile() print(f"creating container {image}") config = { "name": f"{self.__class__.__name__.lower()}-{self.__hash__()}", "source": { "type": "image", "mode": "pull", "server": "https://cloud-images.ubuntu.com/daily", "protocol": "simplestreams", "alias": image, }, "profiles": ["default", self.profile_name], } self.container = self.client.containers.create(config=config, wait=True)
def getPrivIPv6(): eth0 = pylxd.Client().containers.get(sys.argv[1]).state().network.get("eth0") for address in eth0["addresses"]: if address["family"] == "inet6" and address["scope"] == "global": return address["address"] return ""
def _start(self, timeout): log.set_ctx(job=self.job['id']) self.client = pylxd.Client() # prepare network for container for net in self.client.networks.all(): if net.name.endswith('lab_net'): self.lab_net = net break if self.lab_net is None: self.lab_net = self.client.networks.create('lab_net') # prepare container definition image = self.job['system'] config = { 'name': 'kktool-%d' % self.job['id'], 'source': { 'type': 'image', "mode": "pull", #"server": "https://cloud-images.ubuntu.com/daily", "server": "https://images.linuxcontainers.org:8443", # https://images.linuxcontainers.org/ "protocol": "simplestreams", 'alias': image }, "devices": { "lab_net": { "nictype": "bridged", "parent": "lab_net", "type": "nic" } }, } log.info('lxd container config: %s', config) self.cntr = self.client.containers.create(config, wait=True) self.cntr.start(wait=True) log.info('lxd container %s', self.cntr.name) for _ in range(100): if self.cntr.status != 'Running': time.sleep(0.1) self.cntr.sync() log.info('container status %s', self.cntr.status) if self.cntr.status != 'Running': self.stop() raise Exception('cannot start container') kktool_path = os.path.realpath(os.path.join(consts.AGENT_DIR, 'kktool')) with open(kktool_path, 'rb') as f: filedata = f.read() self.cntr.files.put('/root/kktool', filedata) deadline = time.time() + timeout self._async_run('chmod a+x kktool', deadline, cwd='.') logs = self._async_run('cat /etc/os-release', deadline) m = re.search('^ID="?(.*?)"?$', logs, re.M) distro = m.group(1).lower() if distro in ['debian', 'ubuntu']: self._async_run('apt-get update', deadline) self._async_run('apt-get install -y python3', deadline) elif distro in ['centos', 'fedora']: self._async_run('yum install -y python3', deadline) elif 'suse' in distro: time.sleep(3) # wait for network self._async_run( 'zypper install -y curl python3 sudo system-group-wheel', deadline)