From 3949e0e918e2501c4953a7d9beb58511688d84e1 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Thu, 6 Aug 2015 00:19:48 +1000 Subject: [PATCH] Ship the default image schema in the client Now that we have stable branches for clients, it's easier to keep track of the current default image's schema in Glance and update it respectively. This patch adds the current image schema, including the schema-properties. One good reason to do this is to be able to react when a running Glance instance is not around to be introspected. It's really unfortunate that things like help text can't be rendered when there image schema is not available in the system. We could keep the schema in a json file but rather than shipping data files with glanceclient we can just have it in the python modules. Change-Id: I9b8cc1d18d6717ccf991fb8149ab13c06d653ee4 Closes-bug: #1481729 --- glanceclient/tests/unit/test_shell.py | 7 + glanceclient/v2/image_schema.py | 223 ++++++++++++++++++++++++++ glanceclient/v2/shell.py | 3 + 3 files changed, 233 insertions(+) create mode 100644 glanceclient/v2/image_schema.py diff --git a/glanceclient/tests/unit/test_shell.py b/glanceclient/tests/unit/test_shell.py index 4a0f629..a38608e 100644 --- a/glanceclient/tests/unit/test_shell.py +++ b/glanceclient/tests/unit/test_shell.py @@ -158,6 +158,13 @@ class ShellTest(testutils.TestCase): def test_help_on_subcommand_error(self): self.assertRaises(exc.CommandError, shell, 'help bad') + def test_help_v2_no_schema(self): + shell = openstack_shell.OpenStackImagesShell() + argstr = '--os-image-api-version 2 help image-create' + actual = shell.main(argstr.split()) + self.assertEqual(0, actual) + self.assertNotIn('', actual) + def test_get_base_parser(self): test_shell = openstack_shell.OpenStackImagesShell() actual_parser = test_shell.get_base_parser() diff --git a/glanceclient/v2/image_schema.py b/glanceclient/v2/image_schema.py new file mode 100644 index 0000000..29c1b2f --- /dev/null +++ b/glanceclient/v2/image_schema.py @@ -0,0 +1,223 @@ +# Copyright 2015 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +_doc_url = "http://docs.openstack.org/trunk/openstack-compute/admin/content/adding-images.html" # noqa +# NOTE(flaper87): Keep a copy of the current default schema so that +# we can react on cases where there's no connection to an OpenStack +# deployment. See #1481729 +_BASE_SCHEMA = { + "additionalProperties": { + "type": "string" + }, + "name": "image", + "links": [ + { + "href": "{self}", + "rel": "self" + }, + { + "href": "{file}", + "rel": "enclosure" + }, + { + "href": "{schema}", + "rel": "describedby" + } + ], + "properties": { + "container_format": { + "enum": [ + "ami", + "ari", + "aki", + "bare", + "ovf", + "ova" + ], + "type": "string", + "description": "Format of the container" + }, + "min_ram": { + "type": "integer", + "description": "Amount of ram (in MB) required to boot image." + }, + "ramdisk_id": { + "pattern": ("^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}" + "-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}" + "-([0-9a-fA-F]){12}$"), + "type": "string", + "description": ("ID of image stored in Glance that should be " + "used as the ramdisk when booting an AMI-style " + "image.") + }, + "locations": { + "items": { + "required": [ + "url", + "metadata" + ], + "type": "object", + "properties": { + "url": { + "type": "string", + "maxLength": 255 + }, + "metadata": { + "type": "object" + } + } + }, + "type": "array", + "description": ("A set of URLs to access the image " + "file kept in external store") + }, + "file": { + "type": "string", + "description": "(READ-ONLY)" + }, + "owner": { + "type": "string", + "description": "Owner of the image", + "maxLength": 255 + }, + "id": { + "pattern": ("^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}" + "-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}" + "-([0-9a-fA-F]){12}$"), + "type": "string", + "description": "An identifier for the image" + }, + "size": { + "type": "integer", + "description": "Size of image file in bytes (READ-ONLY)" + }, + "os_distro": { + "type": "string", + "description": ("Common name of operating system distribution " + "as specified in %s" % _doc_url) + }, + "self": { + "type": "string", + "description": "(READ-ONLY)" + }, + "disk_format": { + "enum": [ + "ami", + "ari", + "aki", + "vhd", + "vmdk", + "raw", + "qcow2", + "vdi", + "iso" + ], + "type": "string", + "description": "Format of the disk" + }, + "os_version": { + "type": "string", + "description": ("Operating system version as " + "specified by the distributor") + }, + "direct_url": { + "type": "string", + "description": ("URL to access the image file kept in " + "external store (READ-ONLY)") + }, + "schema": { + "type": "string", + "description": "(READ-ONLY)" + }, + "status": { + "enum": [ + "queued", + "saving", + "active", + "killed", + "deleted", + "pending_delete" + ], + "type": "string", + "description": "Status of the image (READ-ONLY)" + }, + "tags": { + "items": { + "type": "string", + "maxLength": 255 + }, + "type": "array", + "description": "List of strings related to the image" + }, + "kernel_id": { + "pattern": ("^([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-" + "([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-" + "([0-9a-fA-F]){12}$"), + "type": "string", + "description": ("ID of image stored in Glance that should be " + "used as the kernel when booting an AMI-style " + "image.") + }, + "visibility": { + "enum": [ + "public", + "private" + ], + "type": "string", + "description": "Scope of image accessibility" + }, + "updated_at": { + "type": "string", + "description": ("Date and time of the last " + "image modification (READ-ONLY)") + }, + "min_disk": { + "type": "integer", + "description": ("Amount of disk space (in GB) " + "required to boot image.") + }, + "virtual_size": { + "type": "integer", + "description": "Virtual size of image in bytes (READ-ONLY)" + }, + "instance_uuid": { + "type": "string", + "description": "ID of instance used to create this image." + }, + "name": { + "type": "string", + "description": "Descriptive name for the image", + "maxLength": 255 + }, + "checksum": { + "type": "string", + "description": "md5 hash of image contents. (READ-ONLY)", + "maxLength": 32 + }, + "created_at": { + "type": "string", + "description": "Date and time of image registration (READ-ONLY)" + }, + "protected": { + "type": "boolean", + "description": "If true, image will not be deletable." + }, + "architecture": { + "type": "string", + "description": ("Operating system architecture as specified " + "in %s" % _doc_url) + } + } +} diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py index a56e552..65a0743 100644 --- a/glanceclient/v2/shell.py +++ b/glanceclient/v2/shell.py @@ -19,6 +19,7 @@ from glanceclient.common import progressbar from glanceclient.common import utils from glanceclient import exc from glanceclient.v2 import image_members +from glanceclient.v2 import image_schema from glanceclient.v2 import images from glanceclient.v2 import tasks import json @@ -36,6 +37,8 @@ def get_image_schema(): with open(schema_path, "r") as f: schema_raw = f.read() IMAGE_SCHEMA = json.loads(schema_raw) + else: + return image_schema._BASE_SCHEMA return IMAGE_SCHEMA