示例#1
0
 def _check_nbd_module(self):
     from bootstrapvz.base.fs.partitionmaps.none import NoPartitions
     if isinstance(self.partition_map, NoPartitions):
         if not self._module_loaded('nbd'):
             msg = (
                 'The kernel module `nbd\' must be loaded '
                 '(`modprobe nbd\') to attach .{extension} images'.format(
                     extension=self.extension))
             raise VolumeError(msg)
     else:
         num_partitions = len(self.partition_map.partitions)
         if not self._module_loaded('nbd'):
             msg = ('The kernel module `nbd\' must be loaded '
                    '(run `modprobe nbd max_part={num_partitions}\') '
                    'to attach .{extension} images'.format(
                        num_partitions=num_partitions,
                        extension=self.extension))
             raise VolumeError(msg)
         nbd_max_part = int(self._module_param('nbd', 'max_part'))
         if nbd_max_part < num_partitions:
             # Found here: http://bethesignal.org/blog/2011/01/05/how-to-mount-virtualbox-vdi-image/
             msg = (
                 'The kernel module `nbd\' was loaded with the max_part '
                 'parameter set to {max_part}, which is below '
                 'the amount of partitions for this volume ({num_partitions}). '
                 'Reload the nbd kernel module with max_part set to at least {num_partitions} '
                 '(`rmmod nbd; modprobe nbd max_part={num_partitions}\').'.
                 format(max_part=nbd_max_part,
                        num_partitions=num_partitions))
             raise VolumeError(msg)
示例#2
0
    def _before_attach(self, e):
        import os.path
        import string

        self.instance_id = e.instance_id
        for letter in string.ascii_lowercase[5:]:
            dev_path = os.path.join('/dev', 'xvd' + letter)
            if not os.path.exists(dev_path):
                self.device_path = dev_path
                self.ec2_device_path = os.path.join('/dev', 'sd' + letter)
                break

        if self.device_path is None:
            raise VolumeError(
                'Unable to find a free block device path for mounting the bootstrap volume'
            )

        self.conn.attach_volume(VolumeId=self.vol_id,
                                InstanceId=self.instance_id,
                                Device=self.ec2_device_path)
        waiter = self.conn.get_waiter('volume_in_use')
        waiter.wait(VolumeIds=[self.vol_id],
                    Filters=[{
                        'Name': 'attachment.status',
                        'Values': ['attached']
                    }])
示例#3
0
 def _find_free_nbd_device(self):
     import os.path
     for i in xrange(0, 15):
         device_name = 'nbd' + str(i)
         if not self._is_nbd_used(device_name):
             return os.path.join('/dev', device_name)
     raise VolumeError('Unable to find free nbd device.')
示例#4
0
	def _before_attach(self, e):
		instance_id = e.instance_id
		import os.path
		import string
		for letter in string.ascii_lowercase[5:]:
			dev_path = os.path.join('/dev', 'xvd' + letter)
			if not os.path.exists(dev_path):
				self.device_path = dev_path
				self.ec2_device_path = os.path.join('/dev', 'sd' + letter)
				break

		if self.device_path is None:
			raise VolumeError('Unable to find a free block device path for mounting the bootstrap volume')

		self.volume.attach(instance_id, self.ec2_device_path)
		while self.volume.attachment_state() != 'attached':
			time.sleep(2)
			self.volume.update()
    def _before_attach(self, e):
        import os.path
        import string
        import urllib2

        def name_mapped(path):
            return path.split('/')[-1].replace('xvd', 'sd')[:3]

        self.instance_id = e.instance_id

        dev_map_names = set()
        launch_map_url = 'http://169.254.169.254/latest/meta-data/block-device-mapping/'
        launch_map_response = urllib2.urlopen(url=launch_map_url, timeout=5)
        for map_name in [d.strip() for d in launch_map_response.readlines()]:
            dev_url = launch_map_url + map_name
            dev_response = urllib2.urlopen(url=dev_url, timeout=5)
            dev_map_names.add(name_mapped(dev_response.read().strip()))

        try:
            instance = self.conn.describe_instances(
                Filters=[{
                    'Name': 'instance-id',
                    'Values': [self.instance_id]
                }])['Reservations'][0]['Instances'][0]
        except (IndexError, KeyError):
            raise VolumeError('Unable to fetch EC2 instance volume data')

        for mapped_dev in instance.get('BlockDeviceMappings', list()):
            dev_map_names.add(name_mapped(mapped_dev['DeviceName']))

        for letter in reversed(string.ascii_lowercase[1:]):
            if 'sd' + letter not in dev_map_names:
                self.ec2_device_path = '/dev/sd' + letter
                break

        if self.ec2_device_path is None:
            raise VolumeError(
                'Unable to find a free block device mapping for bootstrap volume'
            )

        self.device_path = None

        lsblk_command = [
            'lsblk', '--noheadings', '--list', '--nodeps', '--output', 'NAME'
        ]

        lsblk_start = log_check_call(lsblk_command)
        start_dev_names = set(lsblk_start)

        self.conn.attach_volume(VolumeId=self.vol_id,
                                InstanceId=self.instance_id,
                                Device=self.ec2_device_path)
        waiter = self.conn.get_waiter('volume_in_use')
        waiter.wait(VolumeIds=[self.vol_id],
                    Filters=[{
                        'Name': 'attachment.status',
                        'Values': ['attached']
                    }])

        log_check_call(['udevadm', 'settle'])

        lsblk_end = log_check_call(lsblk_command)
        end_dev_names = set(lsblk_end)

        if len(start_dev_names ^ end_dev_names) != 1:
            raise VolumeError(
                'Could not determine the device name for bootstrap volume')

        udev_name = (start_dev_names ^ end_dev_names).pop()
        udev_path = log_check_call(
            ['udevadm', 'info', '--root', '--query=name', '--name', udev_name])
        if len(udev_path) != 1 or not os.path.exists(udev_path[0]):
            raise VolumeError(
                'Could not find device path for bootstrap volume')

        self.device_path = udev_path[0]