diff --git a/openstackclient/image/client.py b/openstackclient/image/client.py
index 371605692a..70bef1c8a6 100644
--- a/openstackclient/image/client.py
+++ b/openstackclient/image/client.py
@@ -1,4 +1,4 @@
-#   Copyright 2012-2013 OpenStack, LLC.
+#   Copyright 2012-2013 OpenStack Foundation
 #
 #   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
@@ -15,6 +15,9 @@
 
 import logging
 
+from glanceclient import exc as gc_exceptions
+from glanceclient.v1 import client as gc_v1_client
+from glanceclient.v1 import images as gc_v1_images
 from openstackclient.common import utils
 
 
@@ -22,8 +25,8 @@ LOG = logging.getLogger(__name__)
 
 API_NAME = "image"
 API_VERSIONS = {
-    "1": "glanceclient.v1.client.Client",
-    "2": "glanceclient.v2.client.Client"
+    "1": "openstackclient.image.client.Client_v1",
+    "2": "glanceclient.v2.client.Client",
 }
 
 
@@ -38,3 +41,54 @@ def make_client(instance):
         instance._url = instance.get_endpoint_for_service_type(API_NAME)
 
     return image_client(instance._url, token=instance._token)
+
+
+# NOTE(dtroyer): glanceclient.v1.image.ImageManager() doesn't have a find()
+#                method so add one here until the common client libs arrive
+#                A similar subclass will be required for v2
+
+class Client_v1(gc_v1_client.Client):
+    """An image v1 client that uses ImageManager_v1"""
+
+    def __init__(self, *args, **kwargs):
+        super(Client_v1, self).__init__(*args, **kwargs)
+        self.images = ImageManager_v1(self)
+
+
+class ImageManager_v1(gc_v1_images.ImageManager):
+    """Add find() and findall() to the ImageManager class"""
+
+    def find(self, **kwargs):
+        """Find a single item with attributes matching ``**kwargs``.
+
+        This isn't very efficient: it loads the entire list then filters on
+        the Python side.
+        """
+        rl = self.findall(**kwargs)
+        num = len(rl)
+
+        if num == 0:
+            raise gc_exceptions.NotFound
+        elif num > 1:
+            raise gc_exceptions.NoUniqueMatch
+        else:
+            return rl[0]
+
+    def findall(self, **kwargs):
+        """Find all items with attributes matching ``**kwargs``.
+
+        This isn't very efficient: it loads the entire list then filters on
+        the Python side.
+        """
+        found = []
+        searches = kwargs.items()
+
+        for obj in self.list():
+            try:
+                if all(getattr(obj, attr) == value
+                       for (attr, value) in searches):
+                    found.append(obj)
+            except AttributeError:
+                continue
+
+        return found
diff --git a/openstackclient/image/v1/image.py b/openstackclient/image/v1/image.py
index 5b4a939daa..0213ed1e28 100644
--- a/openstackclient/image/v1/image.py
+++ b/openstackclient/image/v1/image.py
@@ -1,4 +1,4 @@
-#   Copyright 2013 OpenStack, LLC.
+#   Copyright 2012-2013 OpenStack Foundation
 #
 #   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
@@ -17,6 +17,7 @@
 
 import logging
 import os
+import six
 import sys
 
 if os.name == "nt":
@@ -24,11 +25,18 @@ if os.name == "nt":
 else:
     msvcrt = None
 
+from cliff import command
+from cliff import lister
 from cliff import show
 
+from glanceclient.common import utils as gc_utils
+from openstackclient.common import exceptions
+from openstackclient.common import parseractions
+from openstackclient.common import utils
+
 
 class CreateImage(show.ShowOne):
-    """Create image command"""
+    """Create/upload an image"""
 
     log = logging.getLogger(__name__ + ".CreateImage")
 
@@ -37,89 +45,108 @@ class CreateImage(show.ShowOne):
         parser.add_argument(
             "name",
             metavar="<name>",
-            help="Name of image.")
+            help="Name of image",
+        )
         parser.add_argument(
             "--disk_format",
             default="raw",
             metavar="<disk_format>",
-            help="Disk format of image.")
+            help="Disk format of image",
+        )
         parser.add_argument(
             "--id",
             metavar="<id>",
-            help="ID of image to reserve.")
+            help="ID of image to reserve",
+        )
         parser.add_argument(
             "--store",
             metavar="<store>",
-            help="Store to upload image to.")
+            help="Store to upload image to",
+        )
         parser.add_argument(
             "--container-format",
             default="bare",
             metavar="<container_format>",
-            help="Container format of image.")
+            help="Container format of image",
+        )
         parser.add_argument(
             "--owner",
-            metavar="<tenant_id>",
-            help="Owner of the image.")
+            metavar="<tenant>",
+            help="Owner of the image",
+        )
         parser.add_argument(
             "--size",
             metavar="<size>",
             help="Size of image in bytes. Only used with --location and"
-                 " --copy-from.")
+                 " --copy-from",
+        )
         parser.add_argument(
             "--min-disk",
             metavar="<disk_gb>",
-            help="Minimum size of disk needed to boot image in gigabytes.")
+            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.")
+            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.")
+            help="URL where the data for this image already resides",
+        )
         parser.add_argument(
             "--file",
             metavar="<file>",
-            help="Local file that contains disk image.")
+            help="Local file that contains disk image",
+        )
         parser.add_argument(
             "--checksum",
             metavar="<checksum>",
-            help="Hash of image data used for verification.")
+            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.")
+                 " should immediately be copied from the data store",
+        )
         parser.add_argument(
             "--property",
+            dest="properties",
             metavar="<key=value>",
-            default=[],
-            action="append",
-            help="Arbitrary property to associate with image.")
+            action=parseractions.KeyValueAction,
+            help="Set property on this image "
+                 '(repeat option to set multiple properties)',
+        )
         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).")
+            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).")
+            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).")
+            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.")
+            help="Image is inaccessible to the public",
+        )
         return parser
 
     def take_action(self, parsed_args):
@@ -134,11 +161,6 @@ class CreateImage(show.ShowOne):
         args.pop("prefix")
         args.pop("variables")
 
-        args["properties"] = {}
-        for _property in args.pop("property"):
-            key, value = _property.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")
@@ -150,6 +172,231 @@ class CreateImage(show.ShowOne):
                     args["data"] = sys.stdin
 
         image_client = self.app.client_manager.image
-        data = image_client.images.create(**args)._info.copy()
+        try:
+            image = utils.find_resource(
+                image_client.images,
+                parsed_args.name,
+            )
+        except exceptions.CommandError:
+            # This is normal for a create or reserve (create w/o an image)
+            image = image_client.images.create(**args)
+        else:
+            # It must be an update
+            # If an image is specified via --file, --location or --copy-from
+            # let the API handle it
+            image = image_client.images.update(image, **args)
 
-        return zip(*sorted(data.iteritems()))
+        info = {}
+        info.update(image._info)
+        return zip(*sorted(six.iteritems(info)))
+
+
+class DeleteImage(command.Command):
+    """Delete an image"""
+
+    log = logging.getLogger(__name__ + ".DeleteImage")
+
+    def get_parser(self, prog_name):
+        parser = super(DeleteImage, self).get_parser(prog_name)
+        parser.add_argument(
+            "image",
+            metavar="<image>",
+            help="Name or 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 = utils.find_resource(
+            image_client.images,
+            parsed_args.image,
+        )
+        image_client.images.delete(image)
+
+
+class ListImage(lister.Lister):
+    """List available images"""
+
+    log = logging.getLogger(__name__ + ".ListImage")
+
+    def get_parser(self, prog_name):
+        parser = super(ListImage, self).get_parser(prog_name)
+        parser.add_argument(
+            "--page-size",
+            metavar="<size>",
+            help="Number of images to request in each paginated request",
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug("take_action(%s)" % parsed_args)
+
+        image_client = self.app.client_manager.image
+
+        kwargs = {}
+        if parsed_args.page_size is not None:
+            kwargs["page_size"] = parsed_args.page_size
+
+        data = image_client.images.list(**kwargs)
+        columns = ["ID", "Name"]
+
+        return (columns, (utils.get_item_properties(s, columns) for s in data))
+
+
+class SaveImage(command.Command):
+    """Save an image locally"""
+
+    log = logging.getLogger(__name__ + ".SaveImage")
+
+    def get_parser(self, prog_name):
+        parser = super(SaveImage, self).get_parser(prog_name)
+        parser.add_argument(
+            "--file",
+            metavar="<filename>",
+            help="Downloaded image save filename [default: stdout]",
+        )
+        parser.add_argument(
+            "image",
+            metavar="<image>",
+            help="Name or 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 = utils.find_resource(
+            image_client.images,
+            parsed_args.image,
+        )
+        data = image_client.images.data(image)
+
+        gc_utils.save_image(data, parsed_args.file)
+
+
+class SetImage(show.ShowOne):
+    """Change image properties"""
+
+    log = logging.getLogger(__name__ + ".SetImage")
+
+    def get_parser(self, prog_name):
+        parser = super(SetImage, self).get_parser(prog_name)
+        parser.add_argument(
+            "image",
+            metavar="<image>",
+            help="Name or ID of image to change",
+        )
+        parser.add_argument(
+            "--name",
+            metavar="<name>",
+            help="Name of image",
+        )
+        parser.add_argument(
+            "--owner",
+            metavar="<tenant>",
+            help="Owner of the image",
+        )
+        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(
+            "--property",
+            dest="properties",
+            metavar="<key=value>",
+            action=parseractions.KeyValueAction,
+            help="Set property on this image "
+                 '(repeat option to set multiple properties)',
+        )
+        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")
+        image_arg = args.pop("image")
+
+        image_client = self.app.client_manager.image
+        image = utils.find_resource(
+            image_client.images,
+            image_arg,
+        )
+        # Merge properties
+        args["properties"].update(image.properties)
+        image = image_client.images.update(image, **args)
+
+        info = {}
+        info.update(image._info)
+        return zip(*sorted(six.iteritems(info)))
+
+
+class ShowImage(show.ShowOne):
+    """Show image details"""
+
+    log = logging.getLogger(__name__ + ".ShowImage")
+
+    def get_parser(self, prog_name):
+        parser = super(ShowImage, self).get_parser(prog_name)
+        parser.add_argument(
+            "image",
+            metavar="<image>",
+            help="Name or ID of image to display",
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        self.log.debug("take_action(%s)" % parsed_args)
+
+        image_client = self.app.client_manager.image
+        image = utils.find_resource(
+            image_client.images,
+            parsed_args.image,
+        )
+
+        info = {}
+        info.update(image._info)
+        return zip(*sorted(six.iteritems(info)))
diff --git a/openstackclient/image/v2/image.py b/openstackclient/image/v2/image.py
index 61273aa2c3..e84e0d0191 100644
--- a/openstackclient/image/v2/image.py
+++ b/openstackclient/image/v2/image.py
@@ -1,4 +1,4 @@
-#   Copyright 2012-2013 OpenStack, LLC.
+#   Copyright 2012-2013 OpenStack Foundation
 #
 #   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
@@ -16,6 +16,7 @@
 """Image V2 Action Implementations"""
 
 import logging
+import six
 
 from cliff import command
 from cliff import lister
@@ -26,27 +27,32 @@ from openstackclient.common import utils
 
 
 class DeleteImage(command.Command):
-    """Delete image command"""
+    """Delete an 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.")
+            "image",
+            metavar="<image>",
+            help="Name or 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)
+        image = utils.find_resource(
+            image_client.images,
+            parsed_args.image,
+        )
+        image_client.images.delete(image)
 
 
 class ListImage(lister.Lister):
-    """List image command"""
+    """List available images"""
 
     log = logging.getLogger(__name__ + ".ListImage")
 
@@ -55,7 +61,8 @@ class ListImage(lister.Lister):
         parser.add_argument(
             "--page-size",
             metavar="<size>",
-            help="Number of images to request in each paginated request.")
+            help="Number of images to request in each paginated request",
+        )
         return parser
 
     def take_action(self, parsed_args):
@@ -74,7 +81,7 @@ class ListImage(lister.Lister):
 
 
 class SaveImage(command.Command):
-    """Save image command"""
+    """Save an image locally"""
 
     log = logging.getLogger(__name__ + ".SaveImage")
 
@@ -82,42 +89,52 @@ class SaveImage(command.Command):
         parser = super(SaveImage, self).get_parser(prog_name)
         parser.add_argument(
             "--file",
-            metavar="<file>",
-            help="Local file to save downloaded image data "
-                 "to. If this is not specified the image "
-                 "data will be written to stdout.")
+            metavar="<filename>",
+            help="Downloaded image save filename [default: stdout]",
+        )
         parser.add_argument(
-            "id",
-            metavar="<image_id>",
-            help="ID of image to describe.")
+            "image",
+            metavar="<image>",
+            help="Name or 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
-        data = image_client.images.data(parsed_args.id)
+        image = utils.find_resource(
+            image_client.images,
+            parsed_args.image,
+        )
+        data = image_client.images.data(image)
 
         gc_utils.save_image(data, parsed_args.file)
 
 
 class ShowImage(show.ShowOne):
-    """Show image command"""
+    """Show image details"""
 
     log = logging.getLogger(__name__ + ".ShowImage")
 
     def get_parser(self, prog_name):
         parser = super(ShowImage, self).get_parser(prog_name)
         parser.add_argument(
-            "id",
-            metavar="<image_id>",
-            help="ID of image to describe.")
+            "image",
+            metavar="<image>",
+            help="Name or ID of image to display",
+        )
         return parser
 
     def take_action(self, parsed_args):
         self.log.debug("take_action(%s)" % parsed_args)
 
         image_client = self.app.client_manager.image
-        data = image_client.images.get(parsed_args.id)
+        image = utils.find_resource(
+            image_client.images,
+            parsed_args.image,
+        )
 
-        return zip(*sorted(data.iteritems()))
+        info = {}
+        info.update(image._info)
+        return zip(*sorted(six.iteritems(info)))
diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index 561b8ddf6c..dad4a693a1 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -1,4 +1,4 @@
-#   Copyright 2012-2013 OpenStack, LLC.
+#   Copyright 2012-2013 OpenStack Foundation
 #
 #   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
@@ -35,7 +35,7 @@ KEYRING_SERVICE = 'openstack'
 
 DEFAULT_COMPUTE_API_VERSION = '2'
 DEFAULT_IDENTITY_API_VERSION = '2.0'
-DEFAULT_IMAGE_API_VERSION = '2'
+DEFAULT_IMAGE_API_VERSION = '1'
 DEFAULT_VOLUME_API_VERSION = '1'
 DEFAULT_DOMAIN = 'default'
 
diff --git a/openstackclient/tests/test_shell.py b/openstackclient/tests/test_shell.py
index f479b11e4b..ca87997f67 100644
--- a/openstackclient/tests/test_shell.py
+++ b/openstackclient/tests/test_shell.py
@@ -36,7 +36,7 @@ DEFAULT_VOLUME_API_VERSION = "1"
 
 LIB_COMPUTE_API_VERSION = "2"
 LIB_IDENTITY_API_VERSION = "2.0"
-LIB_IMAGE_API_VERSION = "2"
+LIB_IMAGE_API_VERSION = "1"
 LIB_VOLUME_API_VERSION = "1"
 
 
diff --git a/setup.cfg b/setup.cfg
index 3178103929..b3a6657bf7 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -149,6 +149,11 @@ openstack.identity.v3 =
 
 openstack.image.v1 =
     image_create = openstackclient.image.v1.image:CreateImage
+    image_delete = openstackclient.image.v1.image:DeleteImage
+    image_list = openstackclient.image.v1.image:ListImage
+    image_save = openstackclient.image.v1.image:SaveImage
+    image_set = openstackclient.image.v1.image:SetImage
+    image_show = openstackclient.image.v1.image:ShowImage
 
 openstack.image.v2 =
     image_delete = openstackclient.image.v2.image:DeleteImage