Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
 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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
Archivo: lxd.py Proyecto: Sofoca/marvis
    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)
Ejemplo n.º 6
0
Archivo: lxd.py Proyecto: Sofoca/marvis
    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)
Ejemplo n.º 7
0
 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()
Ejemplo n.º 8
0
    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()
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
0
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'")
Ejemplo n.º 13
0
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)
Ejemplo n.º 14
0
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()
Ejemplo n.º 15
0
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 {}
Ejemplo n.º 16
0
 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
Ejemplo n.º 17
0
    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()
Ejemplo n.º 18
0
    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)
Ejemplo n.º 19
0
 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
Ejemplo n.º 20
0
 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
Ejemplo n.º 21
0
 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)
Ejemplo n.º 22
0
 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]
Ejemplo n.º 23
0
    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)
Ejemplo n.º 25
0
    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',
                },
            })
Ejemplo n.º 26
0
    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)
Ejemplo n.º 27
0
    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()
Ejemplo n.º 28
0
    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)
Ejemplo n.º 29
0
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 ""
Ejemplo n.º 30
0
    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)