def _get_device_path_virtio_blk(self, volume): """ The virtio_blk driver allows a serial number to be assigned to virtual blockdevices. OpenStack will set a serial number containing the first 20 characters of the Cinder block device ID. This was introduced in * https://github.com/openstack/nova/commit/3a47c02c58cefed0e230190b4bcef14527c82709 # noqa * https://bugs.launchpad.net/nova/+bug/1004328 The udev daemon will read the serial number and create a symlink to the canonical virtio_blk device path. We do this because libvirt does not return the correct device path when additional disks have been attached using a client other than cinder. This is expected behaviour within Cinder and libvirt See https://bugs.launchpad.net/cinder/+bug/1387945 and http://libvirt.org/formatdomain.html#elementsDisks (target section) :param volume: The Cinder ``Volume`` which is attached. :returns: ``FilePath`` of the device created by the virtio_blk driver. """ expected_path = FilePath( "/dev/disk/by-id/virtio-{}".format(volume.id[:20]) ) if expected_path.exists(): return expected_path.realpath() else: raise UnattachedVolume(volume.id)
def _get_device_path_virtio_blk(self, volume): """ The virtio_blk driver allows a serial number to be assigned to virtual blockdevices. OpenStack will set a serial number containing the first 20 characters of the Cinder block device ID. This was introduced in * https://github.com/openstack/nova/commit/3a47c02c58cefed0e230190b4bcef14527c82709 # noqa * https://bugs.launchpad.net/nova/+bug/1004328 The udev daemon will read the serial number and create a symlink to the canonical virtio_blk device path. We do this because libvirt does not return the correct device path when additional disks have been attached using a client other than cinder. This is expected behaviour within Cinder and libvirt See https://bugs.launchpad.net/cinder/+bug/1387945 and http://libvirt.org/formatdomain.html#elementsDisks (target section) :param volume: The Cinder ``Volume`` which is attached. :returns: ``FilePath`` of the device created by the virtio_blk driver. """ expected_path = FilePath("/dev/disk/by-id/virtio-{}".format( volume.id[:20])) if expected_path.exists(): return expected_path.realpath() else: raise UnattachedVolume(volume.id)
def _get_device_path_virtio_blk(self, volume): """ The virtio_blk driver allows a serial number to be assigned to virtual blockdevices. OpenStack will set a serial number containing the first 20 characters of the Cinder block device ID. This was introduced in * https://github.com/openstack/nova/commit/3a47c02c58cefed0e230190b4bcef14527c82709 # noqa * https://bugs.launchpad.net/nova/+bug/1004328 The udev daemon will read the serial number and create a symlink to the canonical virtio_blk device path. We do this because libvirt does not return the correct device path when additional disks have been attached using a client other than cinder. This is expected behaviour within Cinder and libvirt See https://bugs.launchpad.net/cinder/+bug/1387945 and http://libvirt.org/formatdomain.html#elementsDisks (target section) :param volume: The Cinder ``Volume`` which is attached. :returns: ``FilePath`` of the device created by the virtio_blk driver. """ expected_path = FilePath( "/dev/disk/by-id/virtio-{}".format(volume.id[:20]) ) # Return the real path instead of the symlink to avoid two problems: # # 1. flocker-dataset-agent mounting volumes before udev has populated # the by-id symlinks. # 2. Even if we mount with `/dev/disk/by-id/xxx`, the mounted # filesystems are listed (in e.g. `/proc/mounts`) with the # **target** (i.e. the real path) of the `/dev/disk/by-id/xxx` # symlinks. This confuses flocker-dataset-agent (which assumes path # equality is string equality), causing it to believe that # `/dev/disk/by-id/xxx` has not been mounted, leading it to # repeatedly attempt to mount the device. if expected_path.exists(): return expected_path.realpath() else: raise UnattachedVolume(volume.id)
def getDirectory(self, path='/'): self.fs = yield FilePath(path) if not self.fs.getPermissions(): defer.returnValue(False) files = [] for f in self.fs.listdir(): if f == '/': continue fp = path+f fs = FilePath(fp) # dont follow symlinks if fs.realpath().path != fp: continue perm = None isdir = fs.isdir() size = fs.getsize() modified = datetime.utcfromtimestamp(fs.getModificationTime()) df = DiscoveredFile( resource_id=self.data['resource_id'], file_path=path, file_name=f, file_isdir=isdir, file_size=size, file_modified=modified, file_perm=perm ) print '[%s] LIST %s.' % (self.data['resource_name'], fp if not fp.endswith('.') else fp) files.append(df) defer.returnValue(files)
def get_device_path(self, blockdevice_id): try: vol = self._get_volume(blockdevice_id) path = FilePath( six.text_type("/dev/disk/by-id/scsi-0DO_Volume_{name}").format( name=vol.name)) # Even if we are not attached, the agent needs to know the # expected path for the convergence algorithm # FIXME: The functional tests seem to indicate otherwise if not vol.droplet_ids: # return path raise UnattachedVolume(blockdevice_id) # But if we are attached, we might need to resolve the symlink # noinspection PyBroadException try: return path.realpath() except Exception as _: return path except NotFoundError as _: raise UnknownVolume(blockdevice_id)