Beispiel #1
0
    def create_snapshot(self, volume_id, snapshot_id, timestamp=None,
                        type_='backup', clone_id=None):
        snapshot = self._get_snapshot(volume_id)
        if snapshot:
            if type_ == 'backup':
                if snapshot['id'] == snapshot_id:
                    return snapshot
            elif type_ == 'clone':
                if snapshot.get('clone_id') == clone_id:
                    return snapshot
            raise AlreadyExists(
                "Volume %s already has a snapshot." % volume_id)

        origin = self.get(volume_id)
        # TODO: support size as kwarg or % of origin.size?
        sizestr = '%sB' % self._max_snapshot_size(origin['size'])

        if type_ == 'backup':
            # TODO: should we prevent create snapshot if timestamp is too old?
            timestamp = int(timestamp or time())
            tag = encode_tag(backup_id=snapshot_id, timestamp=timestamp)
        elif type_ == 'clone':
            tag = encode_tag(clone_id=clone_id)
        else:
            raise ValueError("Invalid snapshot type: %s" % type_)

        try:
            # Create an lvm snapshot
            execute('lvcreate', origin['path'], name=snapshot_id,
                    size=sizestr, snapshot=None, addtag=tag)
            return self.get(snapshot_id)
        except ProcessError, e:
            if e.errcode != 5 or 'already exists' not in e.err:
                raise
            raise AlreadyExists("snapshot id '%s' already in use" % id)
Beispiel #2
0
 def _do_create(self,
                volume_id,
                size_str,
                tag,
                backup_source_volume_id=None):
     try:
         out = execute('lvcreate',
                       self.volume_group,
                       name=volume_id,
                       size=size_str,
                       addtag=tag)
     except ProcessError, e:
         if not e.errcode == 5 and 'already exists' not in e.err:
             raise
         # We ran out of space on the storage node!
         if "Insufficient free extents" in e.err \
                 or "insufficient free space" in e.err:
             logger.error(e.err)
             raise ServiceUnavailable("LVM reports insufficient "
                                      "free space on drive")
         # If we are requesting a restore, and the existing volume is this
         # same failed restore, it's not an error.
         if backup_source_volume_id and backup_source_volume_id == \
                 self.get(volume_id).get('backup_source_volume_id', False):
             logger.info("Restarting failed restore on '%s'" % volume_id)
         else:
             raise AlreadyExists("Unable to create a new volume named "
                                 "'%s' because one already exists." %
                                 volume_id)
Beispiel #3
0
    def create(self, id, ip=None):
        with lock.ResourceFile(self._build_lock_path(id)):
            try:
                # see if an export was created while we were locking
                self.get(id)
            except NotFound:
                pass
            else:
                raise AlreadyExists("An export already exists for "
                                    "volume '%s'" % id)
            # create target
            params = {'Name': self._generate_target_name(id)}
            try:
                out = self.ietadm(op='new', tid='auto', params=params)
            except InvalidArgument:
                logger.exception("Unable to create target for '%s'" % id)
                raise ServiceUnavailable("Invalid argument while trying to "
                                         "create export for '%s'" % id)
            # lookup tid
            tid = self._get_tid(id)
            # add lun
            path = self._lun_path(id)
            params = {'Path': path, 'Type': 'blockio'}
            try:
                out += self.ietadm(op='new', tid=tid, lun=0, params=params)
            except (NoSuchFile, NotPermitted):
                # clean up the target
                self.delete(id)
                if not os.path.exists(path):
                    raise NotFound("No volume named '%s'" % id)
                logger.exception('Unable to create export for %s' % id)
                raise ServiceUnavailable("Invalid param trying to create "
                                         "export for '%s'" % id)
        # Write the new exports to the iet config
        exports = self.rewrite_config()

        if ip:
            self.add_initiator_allow(id, ip)

        return self.get(id, exports=exports)