summaryrefslogtreecommitdiff
path: root/openstackclient/image
diff options
context:
space:
mode:
authorJosh Kearney <josh@jk0.org>2013-04-09 13:59:12 -0500
committerJosh Kearney <josh@jk0.org>2013-04-23 14:09:20 -0500
commit6da61e03f03f9a65cbc9203ea9fdd47c64990184 (patch)
treed54da4c152a93bc0aa553c1b542a6e8b2cc884bf /openstackclient/image
parent95bf187a4fde78b6d9d93e40a245ddada004c32a (diff)
downloadpython-openstackclient-6da61e03f03f9a65cbc9203ea9fdd47c64990184.tar.gz
Adds image `create` and `delete` functionality.
We use the V1 API for `create` since it does not yet exist in the V2 API in glanceclient. For blueprint glance-client. Change-Id: Ifa819c14f6a013f4530d16247a671e5a1c740a28
Diffstat (limited to 'openstackclient/image')
-rw-r--r--openstackclient/image/client.py2
-rw-r--r--openstackclient/image/v1/__init__.py14
-rw-r--r--openstackclient/image/v1/image.py156
-rw-r--r--openstackclient/image/v2/image.py23
4 files changed, 193 insertions, 2 deletions
diff --git a/openstackclient/image/client.py b/openstackclient/image/client.py
index 8a63da9c..37160569 100644
--- a/openstackclient/image/client.py
+++ b/openstackclient/image/client.py
@@ -22,7 +22,7 @@ LOG = logging.getLogger(__name__)
API_NAME = "image"
API_VERSIONS = {
- "1.0": "glanceclient.v2.client.Client",
+ "1": "glanceclient.v1.client.Client",
"2": "glanceclient.v2.client.Client"
}
diff --git a/openstackclient/image/v1/__init__.py b/openstackclient/image/v1/__init__.py
new file mode 100644
index 00000000..ebf59b32
--- /dev/null
+++ b/openstackclient/image/v1/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2013 OpenStack, LLC.
+#
+# 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.
+#
diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py
new file mode 100644
index 00000000..fa566bd9
--- /dev/null
+++ b/openstackclient/image/v1/image.py
@@ -0,0 +1,156 @@
+# Copyright 2013 OpenStack, LLC.
+#
+# 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.
+#
+
+"""Image V1 Action Implementations"""
+
+import logging
+import os
+import sys
+
+if os.name == "nt":
+ import msvcrt
+else:
+ msvcrt = None
+
+from cliff import show
+
+
+class CreateImage(show.ShowOne):
+ """Create image command"""
+
+ api = "image"
+ log = logging.getLogger(__name__ + ".CreateImage")
+
+ def get_parser(self, prog_name):
+ parser = super(CreateImage, self).get_parser(prog_name)
+ parser.add_argument(
+ "name",
+ metavar="<name>",
+ help="Name of image.")
+ parser.add_argument(
+ "--disk_format",
+ default="raw",
+ metavar="<disk_format>",
+ help="Disk format of image.")
+ parser.add_argument(
+ "--id",
+ metavar="<id>",
+ help="ID of image to reserve.")
+ parser.add_argument(
+ "--store",
+ metavar="<store>",
+ help="Store to upload image to.")
+ parser.add_argument(
+ "--container-format",
+ default="bare",
+ metavar="<container_format>",
+ help="Container format of image.")
+ parser.add_argument(
+ "--owner",
+ metavar="<tenant_id>",
+ help="Owner of the image.")
+ parser.add_argument(
+ "--size",
+ metavar="<size>",
+ help="Size of image in bytes. Only used with --location and"
+ " --copy-from.")
+ parser.add_argument(
+ "--min-disk",
+ metavar="<disk_gb>",
+ help="Minimum size of disk needed to boot image in gigabytes.")
+ parser.add_argument(
+ "--min-ram",
+ metavar="<disk_ram>",
+ help="Minimum amount of ram needed to boot image in megabytes.")
+ parser.add_argument(
+ "--location",
+ metavar="<image_url>",
+ help="URL where the data for this image already resides.")
+ parser.add_argument(
+ "--file",
+ metavar="<file>",
+ help="Local file that contains disk image.")
+ parser.add_argument(
+ "--checksum",
+ metavar="<checksum>",
+ help="Hash of image data used for verification.")
+ parser.add_argument(
+ "--copy-from",
+ metavar="<image_url>",
+ help="Similar to --location, but this indicates that the image"
+ " should immediately be copied from the data store.")
+ parser.add_argument(
+ "--metadata",
+ metavar="<key=value>",
+ default=[],
+ action="append",
+ help="Arbitrary metadata to associate with image.")
+ protected_group = parser.add_mutually_exclusive_group()
+ protected_group.add_argument(
+ "--protected",
+ dest="protected",
+ action="store_true",
+ help="Prevent image from being deleted (default: False).")
+ protected_group.add_argument(
+ "--unprotected",
+ dest="protected",
+ action="store_false",
+ default=False,
+ help="Allow images to be deleted (default: True).")
+ public_group = parser.add_mutually_exclusive_group()
+ public_group.add_argument(
+ "--public",
+ dest="is_public",
+ action="store_true",
+ default=True,
+ help="Image is accessible to the public (default).")
+ public_group.add_argument(
+ "--private",
+ dest="is_public",
+ action="store_false",
+ help="Image is inaccessible to the public.")
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action(%s)" % parsed_args)
+
+ # NOTE(jk0): Since create() takes kwargs, it's easiest to just make a
+ # copy of parsed_args and remove what we don't need.
+ args = vars(parsed_args)
+ args = dict(filter(lambda x: x[1] is not None, args.items()))
+ args.pop("columns")
+ args.pop("formatter")
+ args.pop("prefix")
+ args.pop("variables")
+
+ args["properties"] = {}
+ for _metadata in args.pop("metadata"):
+ key, value = _metadata.split("=", 1)
+ args["properties"][key] = value
+
+ if "location" not in args and "copy_from" not in args:
+ if "file" in args:
+ args["data"] = open(args.pop("file"), "rb")
+ else:
+ args["data"] = None
+ if sys.stdin.isatty() is not True:
+ if msvcrt:
+ msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
+ args["data"] = sys.stdin
+
+ image_client = self.app.client_manager.image
+ data = image_client.images.create(**args)._info.copy()
+
+ return zip(*sorted(data.iteritems()))
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index ce53df20..3b9b349d 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -13,7 +13,7 @@
# under the License.
#
-"""Image Action Implementations"""
+"""Image V2 Action Implementations"""
import logging
@@ -25,6 +25,27 @@ from glanceclient.common import utils as gc_utils
from openstackclient.common import utils
+class DeleteImage(command.Command):
+ """Delete image command"""
+
+ api = "image"
+ log = logging.getLogger(__name__ + ".DeleteImage")
+
+ def get_parser(self, prog_name):
+ parser = super(DeleteImage, self).get_parser(prog_name)
+ parser.add_argument(
+ "id",
+ metavar="<image_id>",
+ help="ID of image to delete.")
+ return parser
+
+ def take_action(self, parsed_args):
+ self.log.debug("take_action(%s)" % parsed_args)
+
+ image_client = self.app.client_manager.image
+ image_client.images.delete(parsed_args.id)
+
+
class ListImage(lister.Lister):
"""List image command"""