Example #1
0
    def backup(self, version_name: str, snapshot_name: str, source: str,
               rbd_hints: str, base_version_uid: str, block_size: int,
               labels: List[str], storage) -> None:
        # Validate version_name and snapshot_name
        if not InputValidation.is_backup_name(version_name):
            raise benji.exception.UsageError(
                'Version name {} is invalid.'.format(version_name))
        if not InputValidation.is_snapshot_name(snapshot_name):
            raise benji.exception.UsageError(
                'Snapshot name {} is invalid.'.format(snapshot_name))
        base_version_uid_obj = VersionUid(
            base_version_uid) if base_version_uid else None
        if labels:
            label_add, label_remove = self._parse_labels(labels)
            if label_remove:
                raise benji.exception.UsageError(
                    'Wanting to delete labels on a new version is senseless.')
        benji_obj = None
        try:
            benji_obj = Benji(self.config, block_size=block_size)
            hints = None
            if rbd_hints:
                data = ''.join(
                    [line for line in fileinput.input(rbd_hints).readline()])
                hints = hints_from_rbd_diff(data)
            backup_version = benji_obj.backup(version_name, snapshot_name,
                                              source, hints,
                                              base_version_uid_obj, storage)

            if labels:
                for key, value in label_add:
                    benji_obj.add_label(backup_version.uid, key, value)
                for key in label_remove:
                    benji_obj.rm_label(backup_version.uid, key)
                if label_add:
                    logger.info('Added label(s) to version {}: {}.'.format(
                        backup_version.uid.v_string, ', '.join([
                            '{}={}'.format(name, value)
                            for name, value in label_add
                        ])))
                if label_remove:
                    logger.info('Removed label(s) from version {}: {}.'.format(
                        backup_version.uid.v_string, ', '.join(label_remove)))

            if self.machine_output:
                benji_obj.export_any({'versions': [backup_version]},
                                     sys.stdout,
                                     ignore_relationships=[((Version, ),
                                                            ('blocks', ))])
        finally:
            if benji_obj:
                benji_obj.close()
Example #2
0
    def _api_v1_versions_patch(
        self, version_uid: str, protected: fields.Bool(missing=None),
        labels: fields.DelimitedList(fields.Str(), missing=None)
    ) -> StringIO:
        version_uid_obj = VersionUid(version_uid)
        if labels is not None:
            label_add, label_remove = InputValidation.parse_and_validate_labels(
                labels)
        else:
            label_add, label_remove = [], []
        result = StringIO()
        with Benji(self._config) as benji_obj:
            try:
                if protected is not None:
                    benji_obj.protect(version_uid_obj, protected=protected)

                for name, value in label_add:
                    benji_obj.add_label(version_uid_obj, name, value)
                for name in label_remove:
                    benji_obj.rm_label(version_uid_obj, name)

                benji_obj.export_any(
                    {
                        'versions': [
                            benji_obj.get_version_by_uid(
                                version_uid=version_uid_obj)
                        ]
                    },
                    result,
                    ignore_relationships=[((Version, ), ('blocks', ))])
            except KeyError:
                response.status = f'410 Version {version_uid} not found.'

        return result
Example #3
0
    def _protect(
        self, version_uid: str, protected: fields.Bool(missing=None),
        labels: fields.DelimitedList(fields.Str(), missing=None)
    ) -> StringIO:
        version_uid_obj = VersionUid(version_uid)
        if labels is not None:
            label_add, label_remove = InputValidation.parse_and_validate_labels(
                labels)
        else:
            label_add, label_remove = [], []
        benji_obj = None
        try:
            benji_obj = Benji(self._config)
            if protected is True:
                benji_obj.protect(version_uid_obj)
            elif protected is False:
                benji_obj.unprotect(version_uid_obj)

            for name, value in label_add:
                benji_obj.add_label(version_uid_obj, name, value)
            for name in label_remove:
                benji_obj.rm_label(version_uid_obj, name)

            result = StringIO()
            benji_obj.export_any(
                {'versions': [benji_obj.ls(version_uid=version_uid_obj)]},
                result,
                ignore_relationships=[((Version, ), ('blocks', ))])

            return result
        finally:
            if benji_obj:
                benji_obj.close()
Example #4
0
    def _parse_labels(
            labels: List[str]) -> Tuple[List[Tuple[str, str]], List[str]]:
        add_list: List[Tuple[str, str]] = []
        remove_list: List[str] = []
        for label in labels:
            if len(label) == 0:
                raise benji.exception.UsageError(
                    'A zero-length label is invalid.')

            if label.endswith('-'):
                name = label[:-1]

                if not InputValidation.is_label_name(name):
                    raise benji.exception.UsageError(
                        'Label name {} is invalid.'.format(name))

                remove_list.append(name)
            elif label.find('=') > -1:
                name, value = label.split('=')

                if len(name) == 0:
                    raise benji.exception.UsageError(
                        'Missing label key in label {}.'.format(label))
                if not InputValidation.is_label_name(name):
                    raise benji.exception.UsageError(
                        'Label name {} is invalid.'.format(name))
                if not InputValidation.is_label_value(value):
                    raise benji.exception.UsageError(
                        'Label value {} is not a valid.'.format(value))

                add_list.append((name, value))
            else:
                name = label

                if not InputValidation.is_label_name(name):
                    raise benji.exception.UsageError(
                        'Label name {} is invalid.'.format(name))

                add_list.append((name, ''))

        return add_list, remove_list
Example #5
0
    def _backup(
        self, version_name: fields.Str(required=True),
        snapshot_name: fields.Str(required=True),
        source: fields.Str(required=True), rbd_hints: fields.Str(missing=None),
        base_version_uid: fields.Str(missing=None),
        block_size: fields.Int(missing=None), labels: fields.DelimitedList(
            fields.Str(), missing=None), storage_name: fields.Str(missing=None)
    ) -> str:
        # Validate version_name and snapshot_name
        if not InputValidation.is_backup_name(version_name):
            raise benji.exception.UsageError(
                'Version name {} is invalid.'.format(version_name))
        if not InputValidation.is_snapshot_name(snapshot_name):
            raise benji.exception.UsageError(
                'Snapshot name {} is invalid.'.format(snapshot_name))
        base_version_uid_obj = VersionUid(
            base_version_uid) if base_version_uid else None
        if labels:
            label_add, label_remove = self._parse_labels(labels)
        benji_obj = None
        try:
            benji_obj = Benji(self._config, block_size=block_size)
            hints = None
            if rbd_hints:
                with open(rbd_hints, 'r') as f:
                    hints = hints_from_rbd_diff(f.read())
            backup_version = benji_obj.backup(version_name, snapshot_name,
                                              source, hints,
                                              base_version_uid_obj,
                                              storage_name)

            result = StringIO()
            benji_obj.export_any({'versions': [backup_version]},
                                 result,
                                 ignore_relationships=[((Version, ),
                                                        ('blocks', ))])

            return result
        finally:
            if benji_obj:
                benji_obj.close()
Example #6
0
 def label(self, version_uid: str, labels: List[str]) -> None:
     version_uid_obj = VersionUid(version_uid)
     label_add, label_remove = InputValidation.parse_and_validate_labels(
         labels)
     with Benji(self.config) as benji_obj:
         for name, value in label_add:
             benji_obj.add_label(version_uid_obj, name, value)
         for name in label_remove:
             benji_obj.rm_label(version_uid_obj, name)
         if label_add:
             logger.info('Added label(s) to version {}: {}.'.format(
                 version_uid_obj, ', '.join('{}={}'.format(name, value)
                                            for name, value in label_add)))
         if label_remove:
             logger.info('Removed label(s) from version {}: {}.'.format(
                 version_uid_obj, ', '.join(label_remove)))
Example #7
0
    def backup(self, version_uid: str, volume: str, snapshot: str, source: str,
               rbd_hints: str, base_version_uid: str, block_size: int,
               labels: List[str], storage: str) -> None:
        if version_uid is None:
            version_uid = '{}-{}'.format(volume[:248], random_string(6))
        version_uid_obj = VersionUid(version_uid)
        base_version_uid_obj = VersionUid(
            base_version_uid) if base_version_uid else None

        if labels:
            label_add, label_remove = InputValidation.parse_and_validate_labels(
                labels)
        with Benji(self.config) as benji_obj:
            hints = None
            if rbd_hints:
                logger.debug(f'Loading RBD hints from file {rbd_hints}.')
                with open(rbd_hints, 'r') as f:
                    hints = hints_from_rbd_diff(f.read())
            backup_version = benji_obj.backup(
                version_uid=version_uid_obj,
                volume=volume,
                snapshot=snapshot,
                source=source,
                hints=hints,
                base_version_uid=base_version_uid_obj,
                storage_name=storage,
                block_size=block_size)

            if labels:
                for key, value in label_add:
                    benji_obj.add_label(backup_version.uid, key, value)
                for key in label_remove:
                    benji_obj.rm_label(backup_version.uid, key)
                if label_add:
                    logger.info('Added label(s) to version {}: {}.'.format(
                        backup_version.uid,
                        ', '.join('{}={}'.format(name, value)
                                  for name, value in label_add)))
                if label_remove:
                    logger.info('Removed label(s) from version {}: {}.'.format(
                        backup_version.uid, ', '.join(label_remove)))

            if self.machine_output:
                benji_obj.export_any({'versions': [backup_version]},
                                     sys.stdout,
                                     ignore_relationships=(((Version, ),
                                                            ('blocks', )), ))
Example #8
0
 def label(self, version_uid: str, labels: List[str]) -> None:
     version_uid_obj = VersionUid(version_uid)
     label_add, label_remove = InputValidation.parse_and_validate_labels(labels)
     benji_obj = None
     try:
         benji_obj = Benji(self.config)
         for name, value in label_add:
             benji_obj.add_label(version_uid_obj, name, value)
         for name in label_remove:
             benji_obj.rm_label(version_uid_obj, name)
         if label_add:
             logger.info('Added label(s) to version {}: {}.'.format(
                 version_uid_obj.v_string, ', '.join(['{}={}'.format(name, value) for name, value in label_add])))
         if label_remove:
             logger.info('Removed label(s) from version {}: {}.'.format(version_uid_obj.v_string,
                                                                        ', '.join(label_remove)))
     finally:
         if benji_obj:
             benji_obj.close()