Ejemplo n.º 1
0
    def test_add_ephemerals_with_zfs(self, block_device_info_get_ephemerals,
                                     execute):
        ctx = context.get_admin_context()
        block_device_info_get_ephemerals.return_value = [{
            'virtual_name':
            'ephemerals0'
        }]
        instance = fake_instance.fake_instance_obj(ctx,
                                                   name='test',
                                                   memory_mb=0)
        block_device_info = mock.Mock()
        lxd_config = {
            'environment': {
                'storage': 'zfs'
            },
            'config': {
                'storage.zfs_pool_name': 'zfs'
            }
        }

        container = mock.Mock()
        container.config = {
            'volatile.last_state.idmap':
            '[{"Isuid":true,"Isgid":false,'
            '"Hostid":165536,"Nsid":0,'
            '"Maprange":65536}]'
        }
        client = mock.Mock()
        client.containers.get.return_value = container

        storage.attach_ephemeral(client, block_device_info, lxd_config,
                                 instance)

        block_device_info_get_ephemerals.assert_called_once_with(
            block_device_info)

        expected_calls = [
            mock.call('zfs',
                      'create',
                      '-o',
                      'mountpoint=/i/instance-00000001/storage/ephemerals0',
                      '-o',
                      'quota=0G',
                      'zfs/instance-00000001-ephemeral',
                      run_as_root=True),
            mock.call('chown',
                      '165536',
                      '/i/instance-00000001/storage/ephemerals0',
                      run_as_root=True)
        ]

        self.assertEqual(expected_calls, execute.call_args_list)
Ejemplo n.º 2
0
    def test_ephemeral_with_lvm(
            self, block_device_info_get_ephemerals, execute):
        ctx = context.get_admin_context()
        block_device_info_get_ephemerals.return_value = [
            {'virtual_name': 'ephemerals0'}]
        instance = fake_instance.fake_instance_obj(
            ctx, name='test', memory_mb=0)
        block_device_info = mock.Mock()
        lxd_config = {'environment': {'storage': 'lvm'},
                      'config': {'storage.lvm_vg_name': 'lxd'}}

        storage.fileutils = mock.Mock()

        container = mock.Mock()
        container.config = {
            'volatile.last_state.idmap': '[{"Isuid":true,"Isgid":false,'
            '"Hostid":165536,"Nsid":0,'
            '"Maprange":65536}]'
        }
        client = mock.Mock()
        client.containers.get.return_value = container

        storage.attach_ephemeral(
            client, block_device_info, lxd_config, instance)

        block_device_info_get_ephemerals.assert_called_once_with(
            block_device_info)

        expected_calls = [
            mock.call(
                'lvcreate', '-L', '0G', '-n', 'instance-00000001-ephemerals0',
                'lxd', attempts=3, run_as_root=True),
            mock.call(
                'mkfs', '-t', 'ext4', '/dev/lxd/instance-00000001-ephemerals0',
                run_as_root=True),
            mock.call(
                'mount', '-t', 'ext4',
                '/dev/lxd/instance-00000001-ephemerals0',
                '/i/instance-00000001/storage/ephemerals0',
                run_as_root=True),
            mock.call(
                'chown', '165536', '/i/instance-00000001/storage/ephemerals0',
                run_as_root=True)]
        self.assertEqual(expected_calls, execute.call_args_list)
Ejemplo n.º 3
0
    def spawn(self, context, instance, image_meta, injected_files,
              admin_password, network_info=None, block_device_info=None):
        """Create a new lxd container as a nova instance.

        Creating a new container requires a number of steps. First, the
        image is fetched from glance, if needed. Next, the network is
        connected. A profile is created in LXD, and then the container
        is created and started.

        See `nova.virt.driver.ComputeDriver.spawn` for more
        information.
        """
        try:
            self.client.containers.get(instance.name)
            raise exception.InstanceExists(name=instance.name)
        except lxd_exceptions.LXDAPIException as e:
            if e.response.status_code != 404:
                raise  # Re-raise the exception if it wasn't NotFound

        instance_dir = common.InstanceAttributes(instance).instance_dir
        if not os.path.exists(instance_dir):
            fileutils.ensure_tree(instance_dir)

        # Check to see if LXD already has a copy of the image. If not,
        # fetch it.
        try:
            self.client.images.get_by_alias(instance.image_ref)
        except lxd_exceptions.LXDAPIException as e:
            if e.response.status_code != 404:
                raise
            _sync_glance_image_to_lxd(
                self.client, context, instance.image_ref)

        # Plug in the network
        if network_info:
            timeout = CONF.vif_plugging_timeout
            if (utils.is_neutron() and timeout):
                events = [('network-vif-plugged', vif['id'])
                          for vif in network_info if not vif.get(
                    'active', True)]
            else:
                events = []

            try:
                with self.virtapi.wait_for_instance_event(
                        instance, events, deadline=timeout,
                        error_callback=_neutron_failed_callback):
                    self.plug_vifs(instance, network_info)
            except eventlet.timeout.Timeout:
                LOG.warn('Timeout waiting for vif plugging callback for '
                         'instance %(uuid)s', {'uuid': instance['name']})
                if CONF.vif_plugging_is_fatal:
                    self.destroy(
                        context, instance, network_info, block_device_info)
                    raise exception.InstanceDeployFailure(
                        'Timeout waiting for vif plugging',
                        instance_id=instance['name'])

        # Create the profile
        try:
            profile = flavor.to_profile(
                self.client, instance, network_info, block_device_info)
        except lxd_exceptions.LXDAPIException as e:
            with excutils.save_and_reraise_exception():
                self.cleanup(
                    context, instance, network_info, block_device_info)

        # Create the container
        container_config = {
            'name': instance.name,
            'profiles': [profile.name],
            'source': {
                'type': 'image',
                'alias': instance.image_ref,
            },
        }
        try:
            container = self.client.containers.create(
                container_config, wait=True)
        except lxd_exceptions.LXDAPIException as e:
            with excutils.save_and_reraise_exception():
                self.cleanup(
                    context, instance, network_info, block_device_info)

        lxd_config = self.client.host_info
        storage.attach_ephemeral(
            self.client, block_device_info, lxd_config, instance)
        if configdrive.required_by(instance):
            configdrive_path = self._add_configdrive(
                context, instance,
                injected_files, admin_password,
                network_info)

            profile = self.client.profiles.get(instance.name)
            config_drive = {
                'configdrive': {
                    'path': '/config-drive',
                    'source': configdrive_path,
                    'type': 'disk',
                    'readonly': 'True',
                }
            }
            profile.devices.update(config_drive)
            profile.save()

        try:
            self.firewall_driver.setup_basic_filtering(
                instance, network_info)
            self.firewall_driver.instance_filter(
                instance, network_info)

            container.start(wait=True)

            self.firewall_driver.apply_instance_filter(
                instance, network_info)
        except lxd_exceptions.LXDAPIException as e:
            with excutils.save_and_reraise_exception():
                self.cleanup(
                    context, instance, network_info, block_device_info)
Ejemplo n.º 4
0
    def test_add_ephemerals_with_btrfs(
            self, block_device_info_get_ephemerals, execute):
        ctx = context.get_admin_context()
        block_device_info_get_ephemerals.return_value = [
            {'virtual_name': 'ephemerals0'}]
        instance = fake_instance.fake_instance_obj(
            ctx, name='test', memory_mb=0)
        instance.ephemeral_gb = 1
        block_device_info = mock.Mock()
        lxd_config = {'environment': {'storage': 'btrfs'}}
        profile = mock.Mock()
        profile.devices = {
            'root': {
                'path': '/',
                'type': 'disk',
                'size': '1G'
            },
            'ephemerals0': {
                'optional': 'True',
                'path': '/mnt',
                'source': '/path/fake_path',
                'type': 'disk'

            }
        }
        client = mock.Mock()
        client.profiles.get.return_value = profile

        container = mock.Mock()
        container.config = {
            'volatile.last_state.idmap': '[{"Isuid":true,"Isgid":false,'
            '"Hostid":165536,"Nsid":0,'
            '"Maprange":65536}]'
        }
        client.containers.get.return_value = container

        storage.attach_ephemeral(
            client, block_device_info, lxd_config, instance)

        block_device_info_get_ephemerals.assert_called_once_with(
            block_device_info)
        profile.save.assert_called_once_with()

        expected_calls = [
            mock.call(
                'btrfs', 'subvolume', 'create',
                '/var/lib/lxd/containers/instance-00000001/ephemerals0',
                run_as_root=True),
            mock.call(
                'btrfs', 'qgroup', 'limit', '1g',
                '/var/lib/lxd/containers/instance-00000001/ephemerals0',
                run_as_root=True),
            mock.call(
                'chown', '165536',
                '/var/lib/lxd/containers/instance-00000001/ephemerals0',
                run_as_root=True)
        ]
        self.assertEqual(expected_calls, execute.call_args_list)
        self.assertEqual(
            profile.devices['ephemerals0']['source'],
            '/var/lib/lxd/containers/instance-00000001/ephemerals0')
Ejemplo n.º 5
0
    def test_add_ephemerals_with_btrfs(self, block_device_info_get_ephemerals,
                                       execute):
        ctx = context.get_admin_context()
        block_device_info_get_ephemerals.return_value = [{
            'virtual_name':
            'ephemerals0'
        }]
        instance = fake_instance.fake_instance_obj(ctx,
                                                   name='test',
                                                   memory_mb=0)
        instance.ephemeral_gb = 1
        block_device_info = mock.Mock()
        lxd_config = {'environment': {'storage': 'btrfs'}}
        profile = mock.Mock()
        profile.devices = {
            'root': {
                'path': '/',
                'type': 'disk',
                'size': '1G'
            },
            'ephemerals0': {
                'optional': 'True',
                'path': '/mnt',
                'source': '/path/fake_path',
                'type': 'disk'
            }
        }
        client = mock.Mock()
        client.profiles.get.return_value = profile

        container = mock.Mock()
        container.config = {
            'volatile.last_state.idmap':
            '[{"Isuid":true,"Isgid":false,'
            '"Hostid":165536,"Nsid":0,'
            '"Maprange":65536}]'
        }
        client.containers.get.return_value = container

        storage.attach_ephemeral(client, block_device_info, lxd_config,
                                 instance)

        block_device_info_get_ephemerals.assert_called_once_with(
            block_device_info)
        profile.save.assert_called_once_with()

        expected_calls = [
            mock.call('btrfs',
                      'subvolume',
                      'create',
                      '/var/lib/lxd/containers/instance-00000001/ephemerals0',
                      run_as_root=True),
            mock.call('btrfs',
                      'qgroup',
                      'limit',
                      '1g',
                      '/var/lib/lxd/containers/instance-00000001/ephemerals0',
                      run_as_root=True),
            mock.call('chown',
                      '165536',
                      '/var/lib/lxd/containers/instance-00000001/ephemerals0',
                      run_as_root=True)
        ]
        self.assertEqual(expected_calls, execute.call_args_list)
        self.assertEqual(
            profile.devices['ephemerals0']['source'],
            '/var/lib/lxd/containers/instance-00000001/ephemerals0')