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)
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'] }])
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.')
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]