commit a868c8310ead3b7411140c468d7cfc266e1be7fc
Author: Christos Stavrakakis <cstavr@grnet.gr>
Date:   Mon Jan 27 12:24:11 2014 +0200

    cyclades: volume-modify and various fixes

diff --git a/snf-cyclades-app/synnefo/logic/backend.py b/snf-cyclades-app/synnefo/logic/backend.py
index 393e754..c9a1ed9 100644
--- a/snf-cyclades-app/synnefo/logic/backend.py
+++ b/snf-cyclades-app/synnefo/logic/backend.py
@@ -1146,7 +1146,7 @@ def attach_volume(vm, volume, depends=[]):
             "name": volume.backend_volume_uuid,
             "volume_name": volume.backend_volume_uuid}
 
-    disk_provider = volume.disk_provider
+    disk_provider = volume.provider
     if disk_provider is not None:
         disk["provider"] = disk_provider
 
diff --git a/snf-cyclades-app/synnefo/management/pprint.py b/snf-cyclades-app/synnefo/management/pprint.py
index 5693d52..026b134 100644
--- a/snf-cyclades-app/synnefo/management/pprint.py
+++ b/snf-cyclades-app/synnefo/management/pprint.py
@@ -397,14 +397,15 @@ def pprint_volume(volume, display_mails=False, stdout=None, title=None):
     volume_dict = OrderedDict([
         ("id", volume.id),
         ("size", volume.size),
-        ("disk_template", volume.disk_template),
-        ("disk_provider", volume.disk_provider),
+        ("disk_template", volume.template),
+        ("disk_provider", volume.provider),
         ("server_id", volume.machine_id),
         ("userid", volume.userid),
         ("username", ucache.get_name(userid) if display_mails else None),
         ("index", volume.index),
         ("name", volume.name),
         ("state", volume.status),
+        ("delete_on_termination", volume.delete_on_termination),
         ("deleted", volume.deleted),
         ("backendjobid", volume.backendjobid),
         ])
diff --git a/snf-cyclades-app/synnefo/volume/management/commands/volume-list.py b/snf-cyclades-app/synnefo/volume/management/commands/volume-list.py
index 7d575d7..82314e1 100644
--- a/snf-cyclades-app/synnefo/volume/management/commands/volume-list.py
+++ b/snf-cyclades-app/synnefo/volume/management/commands/volume-list.py
@@ -56,11 +56,14 @@ class Command(ListCommand):
         "id": ("id", "ID of the server"),
         "name": ("name", "Name of the server"),
         "user.uuid": ("userid", "The UUID of the server's owner"),
-        "server_id": ("machine_id", ""),
-        "source": ("source", ""),
-        "status": ("status", ""),
+        "server_id": ("machine_id", "The UUID of the server that the volume"
+                                    " is currently attached"),
+        "source": ("source", "The source of the volume"),
+        "status": ("status", "The status of the volume"),
         "created": ("created", "The date the server was created"),
         "deleted": ("deleted", "Whether the server is deleted or not"),
+        "disk_template": ("disk_template", "The disk template of the volume")
     }
 
-    fields = ["id", "name", "user.uuid", "status", "source", "server_id"]
+    fields = ["id", "user.uuid", "status", "source", "disk_template",
+              "server_id"]
diff --git a/snf-cyclades-app/synnefo/volume/management/commands/volume-modify.py b/snf-cyclades-app/synnefo/volume/management/commands/volume-modify.py
new file mode 100644
index 0000000..661ea36
--- /dev/null
+++ b/snf-cyclades-app/synnefo/volume/management/commands/volume-modify.py
@@ -0,0 +1,83 @@
+# Copyright 2013 GRNET S.A. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or
+# without modification, are permitted provided that the following
+# conditions are met:
+#
+#   1. Redistributions of source code must retain the above
+#      copyright notice, this list of conditions and the following
+#      disclaimer.
+#
+#   2. Redistributions in binary form must reproduce the above
+#      copyright notice, this list of conditions and the following
+#      disclaimer in the documentation and/or other materials
+#      provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and
+# documentation are those of the authors and should not be
+# interpreted as representing official policies, either expressed
+# or implied, of GRNET S.A.
+
+from optparse import make_option
+from django.core.management.base import BaseCommand, CommandError
+
+from snf_django.management.utils import parse_bool
+from synnefo.management.common import convert_api_faults
+from synnefo.management import pprint, common
+from synnefo.volume import volumes
+
+
+class Command(BaseCommand):
+    help = "Modify a volume"
+    args = "<volume ID>"
+
+    option_list = BaseCommand.option_list + (
+        make_option(
+            '--name',
+            dest='name',
+            help="Modify a volume's display name"),
+        make_option(
+            '--description',
+            dest='description',
+            help="Modify a volume's display description"),
+        make_option(
+            '--delete-on-termination',
+            dest='delete_on_termination',
+            default="True",
+            choices=["True", "False"],
+            metavar="True|False",
+            help="Set whether volume will be preserved when the server"
+                 " the volume is attached will be deleted"),
+    )
+
+    @convert_api_faults
+    def handle(self, *args, **options):
+        if len(args) != 1:
+            raise CommandError("Please provide a volume ID")
+
+        volume = common.get_volume(args[0])
+
+        name = options.get("name")
+        description = options.get("description")
+        delete_on_termination = options.get("delete_on_termination")
+        if delete_on_termination is not None:
+            delete_on_termination = parse_bool(delete_on_termination)
+
+        volume = volumes.update(volume, name, description,
+                                delete_on_termination)
+
+        pprint.pprint_volume(volume, stdout=self.stdout)
+        self.stdout.write('\n\n')
diff --git a/snf-cyclades-app/synnefo/volume/views.py b/snf-cyclades-app/synnefo/volume/views.py
index 2ce647f..33358ad 100644
--- a/snf-cyclades-app/synnefo/volume/views.py
+++ b/snf-cyclades-app/synnefo/volume/views.py
@@ -202,14 +202,15 @@ def update_volume(request, volume_id):
 
     new_name = req.get("display_name")
     description = req.get("display_description")
+    delete_on_termination = req.get("delete_on_termination")
 
-    if new_name is None and description is None:
+    if new_name is None and description is None and\
+       delete_on_termination is None:
         raise faults.BadRequest("Nothing to update.")
+    else:
+        volume = volumes.update(volume, new_name, description,
+                                delete_on_termination)
 
-    if new_name is not None:
-        volume = volumes.rename(volume, new_name)
-    if description is not None:
-        volume = volumes.update_description(volume, description)
     data = json.dumps({'volume': volume_to_dict(volume, detail=True)})
     return HttpResponse(data, content_type="application/json", status=200)
 
diff --git a/snf-cyclades-app/synnefo/volume/volumes.py b/snf-cyclades-app/synnefo/volume/volumes.py
index 483d9a1..32e0c06 100644
--- a/snf-cyclades-app/synnefo/volume/volumes.py
+++ b/snf-cyclades-app/synnefo/volume/volumes.py
@@ -37,7 +37,8 @@ def create(user_id, size, server_id, name=None, description=None,
         source_type = "image"
         source_uuid = source_image_id
     else:
-        source_type = source_uuid = None
+        source_type = "blank"
+        source_uuid = None
 
     volume = _create_volume(server, user_id, size, source_type, source_uuid,
                             name, description, index=None)
@@ -142,14 +143,13 @@ def delete(volume):
 
 
 @transaction.commit_on_success
-def rename(volume, new_name):
-    volume.name = new_name
-    volume.save()
-    return volume
+def update(volume, name=None, description=None, delete_on_termination=None):
+    if name is not None:
+        volume.name = name
+    if description is not None:
+        volume.description = description
+    if delete_on_termination is not None:
+        volume.delete_on_termination = delete_on_termination
 
-
-@transaction.commit_on_success
-def update_description(volume, new_description):
-    volume.description = new_description
     volume.save()
     return volume
