def validate_manifest_url(self, attrs, source): try: url = attrs[source] except KeyError: return attrs img = self.img try: req = HttpClient(url) res = req.get(timeout=5, max_size=8192) except RequestException as e: raise s.ValidationError( _('Image manifest URL is unreachable (%s).') % e) try: self.manifest = manifest = res.json() except ValueError: raise s.ValidationError(_('Could not parse image manifest.')) try: self.img_file = manifest['files'][0] img.uuid = manifest['uuid'] img.version = manifest['version'] img.ostype = Image.os_to_ostype(manifest) img.size = int(manifest.get('image_size', Image.DEFAULT_SIZE)) img.desc = manifest.get('description', '')[:128] tags = manifest.pop('tags', {}) img.tags = tags.get(Image.TAGS_KEY, []) img.deploy = tags.get('deploy', False) img.resize = tags.get('resize', img.ostype in img.ZONE) except Exception: raise s.ValidationError(_('Invalid image manifest.')) if len(manifest['files']) > 1: raise s.ValidationError( 'Multiple files inside manifest are not supported.') if img.uuid: try: x = Image.objects.only('name').get(uuid=img.uuid) except Image.DoesNotExist: pass else: raise s.ValidationError( _('Image UUID is already registered by image "%(name)s".') % {'name': x.name}) return attrs
def _save_image(manifest, default_dc, admin_dc): """Save image from image manifest""" # noinspection PyProtectedMember image_desc_max_length = Image._meta.get_field('desc').max_length # noinspection PyProtectedMember image_name_max_length = Image._meta.get_field('name').max_length name = manifest['name'][:image_name_max_length] i = 0 i_str = str(i) while Image.objects.filter( name=name).exists() and len(i_str) < image_name_max_length: i += 1 i_str = str(i) # Create new name by appending a number to the existing name # (optionally stripping n-number of characters from end of the name) name = name[:(image_name_max_length - len(i_str))] + i_str img = Image(uuid=manifest['uuid']) img.owner_id = settings.ADMIN_USER img.name = img.alias = name img.version = manifest['version'] img.ostype = Image.os_to_ostype(manifest) img.size = int(manifest.get('image_size', Image.DEFAULT_SIZE)) img.desc = manifest.get('description', '')[:image_desc_max_length] img.status = Image.OK img.manifest = img.manifest_active = manifest tags = manifest.pop('tags', {}) img.tags = tags.get(Image.TAGS_KEY, []) img.deploy = tags.get('deploy', False) img.resize = tags.get('resize', img.ostype in img.ZONE) internal = tags.get('internal', False) if internal: img.dc_bound = admin_dc img.access = Image.INTERNAL else: img.dc_bound = None img.access = Image.PUBLIC img.save() img.dc.add(admin_dc) if not internal: img.dc.add(default_dc) return img