From 4b0dbe507160020a5bf40a3c56cda0d2fa1cf71f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es>
Date: Wed, 15 Jun 2011 12:12:23 +0200
Subject: [PATCH 1/2] Feature #661: Add help comments and a few missing
 commands

---
 src/cli/onegroup    |  39 +++++--
 src/cli/onehost     |  89 ++++++++++-----
 src/cli/oneimage    | 144 ++++++++++++++++++-------
 src/cli/onetemplate | 134 ++++++++++++++++-------
 src/cli/oneuser     |  85 +++++++++++----
 src/cli/onevm       | 256 +++++++++++++++++++++++++++++++++-----------
 src/cli/onevnet     | 117 +++++++++++++-------
 7 files changed, 628 insertions(+), 236 deletions(-)

diff --git a/src/cli/onegroup b/src/cli/onegroup
index b8f641faa0..662cf70dc9 100755
--- a/src/cli/onegroup
+++ b/src/cli/onegroup
@@ -56,26 +56,45 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         helper.list_to_id(arg)
     end
 
-    set :format, :filterflag, OneGroupHelper.filterflag_to_i_desc do |arg|
-        helper.filterflag_to_i(arg)
-    end
-
     ########################################################################
     # Commands
     ########################################################################
-    command :create, 'Creates a new Group', :text, do
+
+    create_desc = <<-EOT.unindent
+        Creates a new Group
+    EOT
+
+    command :create, create_desc, :name do
         helper.create_resource(options) do |group|
             group.allocate(args[0])
         end
     end
 
-    command :list, 'Lists Groups in the pool', [:filterflag, nil], :options=>list_options do
+    delete_desc = <<-EOT.unindent
+        Deletes the given Group
+    EOT
+
+    command :delete, delete_desc, [:range, :groupid_list] do
+        helper.perform_actions(args[0],options,"deleted") do |obj|
+            obj.delete
+        end
+    end
+
+    list_desc = <<-EOT.unindent
+        Lists Groups in the pool
+    EOT
+
+    command :list, list_desc, :options=>list_options do
         helper.list_pool(options)
     end
 
-    command :delete, 'Removes a Group', [:range, :userid_list] do
-        helper.perform_actions(args[0],options,"deleted") do |user|
-            user.delete
-        end
+    show_desc = <<-EOT.unindent
+        Shows information for the given Group
+    EOT
+
+    command :show, show_desc, :groupid, :options=>OpenNebulaHelper::XML do
+        puts "TODO"
+        -1
     end
+
 end
diff --git a/src/cli/onehost b/src/cli/onehost
index cf497843e3..8f28d75c8f 100755
--- a/src/cli/onehost
+++ b/src/cli/onehost
@@ -52,55 +52,68 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         helper.list_to_id(arg)
     end
 
-    set :format, :filterflag, OneHostHelper.filterflag_to_i_desc do |arg|
-        helper.filterflag_to_i(arg)
-    end
-
     ########################################################################
     # Commands
     ########################################################################
-    command :create, 'Create a new Virtual Network', :text, :text, :text, :text do
+
+    create_desc = <<-EOT.unindent
+        Creates a new Host
+    EOT
+
+    command :create, create_desc, :hostname, :im_mad, :vmm_mad, :tm_mad do
         helper.create_resource(options) do |host|
             host.allocate(args[0], args[1], args[2], args[3])
         end
     end
 
-    command :delete, 'Removes a Virtual Network', [:range, :hostid_list] do
+    delete_desc = <<-EOT.unindent
+        Deletes the given Host
+    EOT
+
+    command :delete, delete_desc, [:range, :hostid_list] do
         helper.perform_actions(args[0],options,"deleted") do |host|
             host.delete
         end
     end
 
-    command :disable, 'Disbales Host', [:range,:hostid_list] do
-        helper.perform_actions(args[0],options,"unpublished") do |host|
+    enable_desc = <<-EOT.unindent
+        Enables the given Host
+    EOT
+
+    command :enable, enable_desc, [:range,:hostid_list] do
+        helper.perform_actions(args[0],options,"enabled") do |host|
+            host.enable
+        end
+    end
+
+    disable_desc = <<-EOT.unindent
+        Disables the given Host
+    EOT
+
+    command :disable, disable_desc, [:range,:hostid_list] do
+        helper.perform_actions(args[0],options,"disabled") do |host|
             host.disable
         end
     end
 
-    command :update, 'Modifies a Host attribute', :hostid do
-        helper.perform_action(args[0],options,"modified") do |host|
+    update_desc = <<-EOT.unindent
+        Launches the system editor to modify and update the template contents
+    EOT
+
+    command :update, update_desc, :hostid do
+        helper.perform_action(args[0],options,"updated") do |host|
             str = OpenNebulaHelper.update_template(args[0], host)
             host.update(str)
         end
     end
 
-    command :enable, 'Enables Host', [:range,:hostid_list] do
-        helper.perform_actions(args[0],options,"published") do |host|
-            host.enable
-        end
-    end
+    sync_desc = <<-EOT.unindent
+        Synchronizes probes in /var/lib/one/remotes ($ONE_LOCATION/var/remotes
+        in self-contained installations) with Hosts.
+        The copy is performed the next time the Host is monitored
+    EOT
 
-    command :list, 'Lists Virtual Networks in the pool', [:filterflag, nil],
-            :options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do
-        helper.list_pool(options)
-    end
-
-    command :show, 'Gets info from a Host', :hostid,
-            :options=>OpenNebulaHelper::XML do
-        helper.show_resource(args[0],options)
-    end
-
-    command :sync, 'Synchronizes probes with remote hosts' do
+    command :sync, sync_desc do
         if ONE_LOCATION
             FileUtils.touch "#{ONE_LOCATION}/var/remotes"
         else
@@ -109,7 +122,29 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         0
     end
 
-    command :top, 'Tops Hosts in the pool', [:filterflag, nil],
+    list_desc = <<-EOT.unindent
+        Lists Hosts in the pool
+    EOT
+
+    command :list, list_desc,
+            :options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do
+        helper.list_pool(options)
+    end
+
+    show_desc = <<-EOT.unindent
+        Shows information for the given Host
+    EOT
+
+    command :show, show_desc, :hostid,
+            :options=>OpenNebulaHelper::XML do
+        helper.show_resource(args[0],options)
+    end
+
+    top_desc = <<-EOT.unindent
+        Lists Hosts continuously
+    EOT
+
+    command :top, top_desc,
             :options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do
         helper.list_pool(options, true)
     end
diff --git a/src/cli/oneimage b/src/cli/oneimage
index 0e3416b60d..2d10f8c775 100755
--- a/src/cli/oneimage
+++ b/src/cli/oneimage
@@ -71,84 +71,146 @@ cmd=CommandParser::CmdParser.new(ARGV) do
     ########################################################################
     # Commands
     ########################################################################
-    command :chgrp, 'Changes the Image group',[:range, :imageid_list], :groupid do
-        helper.perform_actions(args[0],options,"User/Group changed") do |image|
-            image.chown(-1, args[1].to_i)
-        end
-    end
 
-    command :chown, 'Changes the Image owner and group', [:range, :imageid_list], :userid, [:groupid,nil] do
-        gid = args[2].nil? ? -1 : args[2].to_id
-        helper.perform_actions(args[0],options,"Group changed") do |image|
-            image.chown(args[1].to_i, gid)
-        end
-    end
+    create_desc = <<-EOT.unindent
+        Creates a new Image from the given template file
+    EOT
 
-    command :create, 'Registers an Image', :file do
+    command :create, create_desc, :file do
         helper.create_resource(options) do |image|
             template=File.read(args[0])
             image.allocate(template)
         end
     end
 
-    command :show, 'Gets info from an Image', :imageid, :options=>OpenNebulaHelper::XML do
-        helper.show_resource(args[0],options)
+    delete_desc = <<-EOT.unindent
+        Deletes the given Image
+    EOT
+
+    command :delete, delete_desc, [:range, :imageid_list] do
+        helper.perform_actions(args[0],options,"deleted") do |image|
+            image.delete
+        end
     end
 
-    command :list, 'Lists Images in the pool', [:filterflag, nil], :options=>list_options do
-        helper.list_pool(options)
-    end
-
-    command :publish, 'Publishes an Image', [:range,:imageid_list] do
+    command :publish, publish_desc, [:range,:imageid_list] do
         helper.perform_actions(args[0],options,"published") do |image|
             image.publish
         end
     end
 
-    command :unpublish, 'Unpublishes an Image', [:range,:imageid_list] do
+    unpublish_desc = <<-EOT.unindent
+        Unpublishes the given Image. A private Image can't be used by any other 
+        User
+    EOT
+
+    command :unpublish, unpublish_desc, [:range,:imageid_list] do
         helper.perform_actions(args[0],options,"unpublished") do |image|
             image.unpublish
         end
     end
 
-    command :persistent, 'Makes an Image persistent', [:range,:imageid_list] do
+    persistent_desc = <<-EOT.unindent
+        Makes the given Image persistent. A persistent Image saves the changes
+        made to the contents after the VM instance is shutdown (or in real time
+        if a shared FS is used). Persistent Images can be used by only
+        one VM instance at a time.
+    EOT
+
+    command :persistent, persistent_desc, [:range,:imageid_list] do
         helper.perform_actions(args[0],options,"made persistent") do |image|
-            image.publish
+            image.persistent
         end
     end
 
-    command :enable, 'Enable an Image', [:range,:imageid_list] do
-        helper.perform_actions(args[0],options,"enabled") do |image|
-            image.enable
-        end
-    end
+    nonpersistent_desc = <<-EOT.unindent
+        Makes the given Image non persistent. See 'oneimage persistent'
+    EOT
 
-    command :disable, 'Disable an Image', [:range,:imageid_list] do
-        helper.perform_actions(args[0],options,"disabled") do |image|
-            image.disable
-        end
-    end
-
-    command :nonpersistent, 'Make an Image non persistent', [:range,:imageid_list] do
+    command :nonpersistent, nonpersistent_desc, [:range,:imageid_list] do
         helper.perform_actions(args[0],options,"made non persistent") do |image|
-            image.unpublish
+            image.nonpersistent
         end
     end
 
-    command :update, 'Modifies an Image attribute', :imageid do
+    enable_desc = <<-EOT.unindent
+        Enables the given Image
+    EOT
+
+    update_desc = <<-EOT.unindent
+        Launches the system editor to modify and update the template contents
+    EOT
+
+    command :update, update_desc, :imageid do
         helper.perform_action(args[0],options,"modified") do |image|
             str = OpenNebulaHelper.update_template(args[0], image)
             image.update(str)
         end
     end
 
-    command :delete, 'Removes an Image', [:range, :imageid_list] do
-        helper.perform_actions(args[0],options,"deleted") do |image|
-            image.delete
+    command :enable, enable_desc, [:range,:imageid_list] do
+        helper.perform_actions(args[0],options,"enabled") do |image|
+            image.enable
         end
     end
-    
-    command :top, 'Tops Images in the pool', [:filterflag, nil], :options=>list_options do
+
+    disable_desc = <<-EOT.unindent
+        Disables the given Image
+    EOT
+
+    command :disable, disable_desc, [:range,:imageid_list] do
+        helper.perform_actions(args[0],options,"disabled") do |image|
+            image.disable
+        end
+    end
+
+    chgrp_desc = <<-EOT.unindent
+        Changes the Image group
+    EOT
+
+    command :chgrp, chgrp_desc,[:range, :imageid_list], :groupid do
+        helper.perform_actions(args[0],options,"Group changed") do |image|
+            image.chown(-1, args[1].to_i)
+        end
+    end
+
+    chown_desc = <<-EOT.unindent
+        Changes the Image owner and group
+    EOT
+
+    command :chown, chown_desc, [:range, :imageid_list], :userid, [:groupid,nil] do
+        gid = args[2].nil? ? -1 : args[2].to_id
+        helper.perform_actions(args[0],options,"Owner/Group changed") do |image|
+            image.chown(args[1].to_i, gid)
+        end
+    end
+
+    show_desc = <<-EOT.unindent
+        Shows information for the given Image
+    EOT
+
+    list_desc = <<-EOT.unindent
+        Lists Images in the pool
+    EOT
+
+    command :list, list_desc, [:filterflag, nil], :options=>list_options do
+        helper.list_pool(options)
+    end
+
+    command :show, show_desc, :imageid, :options=>OpenNebulaHelper::XML do
+        helper.show_resource(args[0],options)
+    end
+
+    publish_desc = <<-EOT.unindent
+        Publishes the given Image. A public Image can be seen and used by other
+        Users in the Image's group
+    EOT
+
+    top_desc = <<-EOT.unindent
+        Lists Images continuously
+    EOT
+
+    command :top, top_desc, [:filterflag, nil], :options=>list_options do
         helper.list_pool(options, true)
     end
 end
diff --git a/src/cli/onetemplate b/src/cli/onetemplate
index 39b8e69750..cea8fc0d1e 100755
--- a/src/cli/onetemplate
+++ b/src/cli/onetemplate
@@ -31,7 +31,7 @@ require 'command_parser'
 require 'one_helper/onetemplate_helper'
 
 cmd=CommandParser::CmdParser.new(ARGV) do
-    usage "oneimage COMMAND [args..] [options..]"
+    usage "onetemplate COMMAND [args..] [options..]"
     version OpenNebulaHelper::ONE_VERSION
 
     helper = OneTemplateHelper.new
@@ -71,66 +71,120 @@ cmd=CommandParser::CmdParser.new(ARGV) do
     ########################################################################
     # Commands
     ########################################################################
-    command :chgrp, 'Changes the Template group',[:range, :templateid_list], :groupid do
-        helper.perform_actions(args[0],options,"User/Group changed") do |t|
-            t.chown(-1, args[1].to_i)
-        end
-    end
 
-    command :chown, 'Changes the Template owner and group', [:range, :templateid_list], :userid, [:groupid,nil] do
-        gid = args[2].nil? ? -1 : args[2].to_id
-        helper.perform_actions(args[0],options,"Group changed") do |t|
-            t.chown(args[1].to_i, gid)
-        end
-    end
+    create_desc = <<-EOT.unindent
+        Creates a new Template from the given template file
+    EOT
 
-    command :create, 'Registers a Template', :file do
+    command :create, create_desc, :file do
         helper.create_resource(options) do |t|
             template=File.read(args[0])
             t.allocate(template)
         end
     end
 
-    command :update, 'Modifies a Template attribute', :templateid do
+    delete_desc = <<-EOT.unindent
+        Deletes the given Image
+    EOT
+
+    command :delete, delete_desc, [:range, :templateid_list] do
+        helper.perform_actions(args[0],options,"deleted") do |t|
+            t.delete
+        end
+    end
+
+    instantiate_desc = <<-EOT.unindent
+        Creates a new VM instance from the given Template. This VM can be
+        managed with the 'onevm' command
+    EOT
+
+    command :instantiate, instantiate_desc, [:range,:templateid_list] do
+        helper.perform_actions(args[0],options,"instantiated") do |t|
+            res = t.instantiate
+
+            if !OpenNebula.is_error?(res)
+                puts "VM ID: #{res}"
+            end
+
+            res
+        end
+    end
+
+    publish_desc = <<-EOT.unindent
+        Publishes the given Template. A public Template can be seen and
+        instantiated by other Users in the Template's group
+    EOT
+
+    command :publish, pusblish_desc, [:range,:templateid_list] do
+        helper.perform_actions(args[0],options,"published") do |t|
+            t.publish
+        end
+    end
+
+    unpublish_desc = <<-EOT.unindent
+        Unpublishes the given Template. A private Template can't be
+        instantiated by any other User
+    EOT
+
+    command :unpublish, unpublish_desc, [:range,:templateid_list] do
+        helper.perform_actions(args[0],options,"unpublished") do |t|
+            t.unpublish
+        end
+    end
+
+    chgrp_desc = <<-EOT.unindent
+        Changes the Template group
+    EOT
+
+    command :chgrp, chgrp_desc,[:range, :templateid_list], :groupid do
+        helper.perform_actions(args[0],options,"Group changed") do |t|
+            t.chown(-1, args[1].to_i)
+        end
+    end
+
+    chown_desc = <<-EOT.unindent
+        Changes the Template owner and group
+    EOT
+
+    command :chown, chown_desc, [:range, :templateid_list], :userid, [:groupid,nil] do
+        gid = args[2].nil? ? -1 : args[2].to_id
+        helper.perform_actions(args[0],options,"Owner/Group changed") do |t|
+            t.chown(args[1].to_i, gid)
+        end
+    end
+
+    update_desc = <<-EOT.unindent
+        Launches the system editor to modify and update the template contents
+    EOT
+
+    command :update, update_desc, :templateid do
         helper.perform_action(args[0],options,"modified") do |template|
             str = OpenNebulaHelper.update_template(args[0], template)
             template.update(str)
         end
     end
 
-    command :show, 'Gets info from a Template', :imageid, :options=>OpenNebulaHelper::XML do
-        helper.show_resource(args[0],options)
-    end
+    list_desc = <<-EOT.unindent
+        Lists Templates in the pool
+    EOT
 
-    command :list, 'Lists Templates in the pool', [:filterflag, nil], :options=>list_options do
+    command :list, list_desc, [:filterflag, nil], :options=>list_options do
         helper.list_pool(options)
     end
 
-    command :instantiate, 'Instantiates a Template', [:range,:templateid_list] do
-        helper.perform_actions(args[0],options,"instantiated") do |t|
-            t.instantiate
-        end
+    show_desc = <<-EOT.unindent
+        Shows information for the given Template
+    EOT
+
+    command :show, show_desc, :templateid, :options=>OpenNebulaHelper::XML do
+        helper.show_resource(args[0],options)
     end
 
-    command :publish, 'Publishes a Template', [:range,:imageid_list] do
-        helper.perform_actions(args[0],options,"published") do |t|
-            t.publish
-        end
-    end
+    top_desc = <<-EOT.unindent
+        Lists Templates continuously
+    EOT
 
-    command :unpublish, 'Unpublishes a Template', [:range,:imageid_list] do
-        helper.perform_actions(args[0],options,"unpublished") do |t|
-            t.unpublish
-        end
-    end
-
-    command :delete, 'Removes a Template', [:range, :imageid_list] do
-        helper.perform_actions(args[0],options,"deleted") do |t|
-            t.delete
-        end
-    end
-    
-    command :top, 'Tops Templatea in the pool', [:filterflag, nil], :options=>list_options do
+    command :top, top_desc, [:filterflag, nil], :options=>list_options do
         helper.list_pool(options, true)
     end
 end
diff --git a/src/cli/oneuser b/src/cli/oneuser
index 17b6e7fd32..33865930d6 100755
--- a/src/cli/oneuser
+++ b/src/cli/oneuser
@@ -76,10 +76,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         helper.list_to_id(arg)
     end
 
-    set :format, :filterflag, OneUserHelper.filterflag_to_i_desc do |arg|
-        helper.filterflag_to_i(arg)
-    end
-    
     set :format, :password, OneUserHelper.password_to_str_desc do |arg|
         OneUserHelper.password_to_str(arg, options)
     end
@@ -87,31 +83,80 @@ cmd=CommandParser::CmdParser.new(ARGV) do
     ########################################################################
     # Commands
     ########################################################################
-    command :chgrp, 'Changes the User group',[:range, :userid_list], :groupid do
-        helper.perform_actions(args[0],options,"User/Group changed") do |user|
-            user.chown(-1, args[1].to_i)
-        end
-    end
 
-    command :create, 'Creates a new User', :text, :password, :options=>create_options do
+    create_desc = <<-EOT.unindent
+        Creates a new User
+    EOT
+
+    command :create, create_desc, :username, :password, :options=>create_options do
         helper.create_resource(options) do |user|
             user.allocate(args[0], args[1])
         end
     end
 
-    command :list, 'Lists Templates in the pool', [:filterflag, nil], :options=>list_options do
-        helper.list_pool(options)
-    end
+    delete_desc = <<-EOT.unindent
+        Deletes the given User
+    EOT
 
-    command :passwd, 'Change the given Users password', :userid, :password do
-        helper.perform_action(args[0],options,"password changed") do |user|
-            user.passwd(args[1])
-        end
-    end
-
-    command :delete, 'Removes a Template', [:range, :userid_list] do
+    command :delete, delete_desc, [:range, :userid_list] do
         helper.perform_actions(args[0],options,"deleted") do |user|
             user.delete
         end
     end
+
+    passwd_desc = <<-EOT.unindent
+        Changes the given User's password
+    EOT
+
+    command :passwd, passwd_desc, :userid, :password do
+        helper.perform_action(args[0],options,"Password changed") do |user|
+            user.passwd(args[1])
+        end
+    end
+
+    chgrp_desc = <<-EOT.unindent
+        Changes the User's main group
+    EOT
+
+    command :chgrp, chgrp_desc, [:range, :userid_list], :groupid do
+        helper.perform_actions(args[0],options,"Group changed") do |user|
+            user.chown(-1, args[1].to_i)
+        end
+    end
+
+    addgroup_desc = <<-EOT.unindent
+        Adds the User to a secondary group
+    EOT
+
+    command :addgroup, addgroup_desc, [:range, :userid_list], :groupid do
+        puts "TODO"
+        -1
+    end
+
+    delgroup_desc = <<-EOT.unindent
+        Removes the User from a secondary group
+    EOT
+
+    command :delgroup, delgroup_desc, [:range, :userid_list], :groupid do
+        puts "TODO"
+        -1
+    end
+
+    list_desc = <<-EOT.unindent
+        Lists Users in the pool
+    EOT
+
+    command :list, list_desc, :options=>list_options do
+        helper.list_pool(options)
+    end
+
+    show_desc = <<-EOT.unindent
+        Shows information for the given User
+    EOT
+
+    command :show, show_desc, :userid, :options=>OpenNebulaHelper::XML do
+        puts "TODO"
+        -1
+    end
+
 end
diff --git a/src/cli/onevm b/src/cli/onevm
index 2ae6a3a67e..5e7b8d0030 100755
--- a/src/cli/onevm
+++ b/src/cli/onevm
@@ -71,40 +71,104 @@ cmd=CommandParser::CmdParser.new(ARGV) do
     ########################################################################
     # Commands
     ########################################################################
-    command :cancel, 'Cancel a Virtual Machine', [:range,:vmid_list] do
-        helper.perform_actions(args[0],options,"canceling") do |vm|
-            vm.cancel
-        end
-    end
 
-    command :chgrp, 'Changes the Virtual Machine group',[:range, :vmid_list], :groupid do
-        helper.perform_actions(args[0],options,"User/Group changed") do |vm|
-            vm.chown(-1, args[1].to_i)
-        end
-    end
+    create_desc = <<-EOT.unindent
+        Creates a new VM from the given template file. This command bypasses
+        the Template pool, which is the preferred way to instantiate new VMs.
+        See 'onetemplate create' and 'onetemplate instantiate'
+    EOT
 
-    command :chown, 'Changes the Virtual Machine owner and group', [:range, :vmid_list], :userid, [:groupid,nil] do
-        gid = args[2].nil? ? -1 : args[2].to_id
-        helper.perform_actions(args[0],options,"Group changed") do |vm|
-            vm.chown(args[1].to_i, gid)
-        end
-    end
-
-    command :create, 'Create a new Virtual Machine', :file do
+    command :create, create_desc, :file do
         helper.create_resource(options) do |vm|
             template=File.read(args[0])
             vm.allocate(template)
         end
     end
 
-    command :delete, 'Removes a Virtual Machine', [:range, :vmid_list] do
+    delete_desc = <<-EOT.unindent
+        Deletes the given VM
+
+        States: ANY
+    EOT
+
+    command :delete, delete_desc, [:range, :vmid_list] do
         helper.perform_actions(args[0],options,"deleted") do |vm|
             vm.delete
         end
     end
 
-    # TBD hostid instead of text in the second argument
-    command :deploy, 'Deploy a Virtual Machine', [:range,:vmid_list], :hostid do
+    hold_desc = <<-EOT.unindent
+        Sets the given VM on hold. A VM on hold is not scheduled until it is
+        released. It can be, however, deployed manually; see 'onevm deploy'
+
+        States: PENDING
+    EOT
+
+    command :hold, hold_desc, [:range,:vmid_list] do
+        helper.perform_actions(args[0],options,"put on hold") do |vm|
+            vm.hold
+        end
+    end
+
+    release_desc = <<-EOT.unindent
+        Releases a VM on hold. See 'onevm hold'
+
+        States: HOLD
+    EOT
+
+    command :release, release_desc, [:range,:vmid_list] do
+        helper.perform_actions(args[0],options,"released") do |vm|
+            vm.release
+        end
+    end
+
+    saveas_desc = <<-EOT.unindent
+        Sets the specified VM disk to be saved in a new Image. The Image is
+        created inmediately, but the contents are saved only if the VM is
+        shut down gracefuly (i.e., using 'onevm shutdown' and not
+        'onevm delete')
+
+        States: ANY
+    EOT
+
+    command :saveas, saveas_desc, :vmid, :img_name do
+        disk_id    = args[1].to_i
+        image_name = args[2]
+        verbose = "disk #{disk_id} prepared to be saved in " <<
+                  "the image #{image_name}"
+
+        helper.perform_action(args[0],options,verbose) do |vm|
+            res = vm.save_as(disk_id, image_name)
+
+            if !OpenNebula.is_error?(res)
+                puts "Image ID: #{res}"
+            end
+
+            res
+        end
+    end
+
+    shutdown_desc = <<-EOT.unindent
+        Shuts down the given VM.
+
+        States: RUNNING
+    EOT
+
+    command :shutdown, shutdown_desc, [:range,:vmid_list] do
+        helper.perform_actions(args[0],options,"shutting down") do |vm|
+            vm.shutdown
+        end
+    end
+
+    deploy_desc = <<-EOT.unindent
+        Deploys the given VM in the specified Host. This command forces the
+        deployment, in a standard installation the Scheduler is in charge
+        of this decision
+
+        States: PENDING
+    EOT
+
+    command :deploy, deploy_desc, [:range,:vmid_list], :hostid do
         host_id = args[1]
         verbose = "deploying in host #{host_id}"
 
@@ -113,19 +177,13 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         end
     end
 
-    command :hold, 'Hold a Virtual Machine', [:range,:vmid_list] do
-        helper.perform_actions(args[0],options,"holding") do |vm|
-            vm.hold
-        end
-    end
+    livemigrate_desc = <<-EOT.unindent
+        Migrates the given running VM to another Host without downtime
 
-    command :list, 'Lists Virtual Machine in the pool', [:filterflag, nil],
-            :options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do
-        helper.list_pool(options)
-    end
+        States: RUNNING
+    EOT
 
-    # TBD hostid instead of text in the second argument
-    command :livemigrate, 'Livemigrate a Virtual Machine', [:range,:vmid_list], :text do
+    command :livemigrate, livemigrate_desc, [:range,:vmid_list], :hostid do
         host_id = args[1]
         verbose = "live migrating to #{host_id}"
 
@@ -134,8 +192,13 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         end
     end
 
-    # TBD hostid instead of text in the second argument
-    command :migrate, 'Migrate a Virtual Machine', [:range,:vmid_list], :text do
+    migrate_desc = <<-EOT.unindent
+        Saves the given running VM and starts it again in the specified Host
+
+        States: RUNNING
+    EOT
+
+    command :migrate, migrate_desc, [:range,:vmid_list], :hostid do
         host_id = args[1]
         verbose = "migrating to #{host_id}"
 
@@ -144,59 +207,130 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         end
     end
 
-    command :release, 'Release a Virtual Machine', [:range,:vmid_list] do
-        helper.perform_actions(args[0],options,"releasing") do |vm|
-            vm.release
-        end
-    end
+    restart_desc = <<-EOT.unindent
+        Forces a re-deployment of the given VM, issuing a boot action.
 
-    command :restart, 'Restart a Virtual Machine', [:range,:vmid_list] do
+        States: UNKNOWN, BOOT
+    EOT
+
+    command :restart, restart_desc, [:range,:vmid_list] do
         helper.perform_actions(args[0],options,"restarting") do |vm|
             vm.restart
         end
     end
 
-    command :resubmit, 'Resubmit a Virtual Machine', [:range,:vmid_list] do
+    resubmit_desc = <<-EOT.unindent
+        Resubmits the VM to PENDING state. This is intented for VMs stuck in a
+        transient state. To re-deploy a fresh copy of the same VM, create a
+        Template and instantiante it, see 'onetemplate instantiate'
+
+        States: ANY, except SUSPENDED or DONE
+    EOT
+
+    command :resubmit, resubmit_desc, [:range,:vmid_list] do
         helper.perform_actions(args[0],options,"resubmiting") do |vm|
             vm.restart
         end
     end
 
-    command :resume, 'Resume a Virtual Machine', [:range,:vmid_list] do
-        helper.perform_actions(args[0],options,"resuming") do |vm|
-            vm.resume
+    cancel_desc = <<-EOT.unindent
+        Cancels the given VM. The process is checked by OpenNebula, so
+        if the process fails the VM remains in running state. If the action
+        succeeds the VMDIR in the remote machine is not deleted
+
+        States: RUNNING
+    EOT
+
+    command :cancel, cancel_desc, [:range,:vmid_list] do
+        helper.perform_actions(args[0],options,"canceling") do |vm|
+            vm.cancel
         end
     end
 
-    command :saveas, 'Save as a Virtual Machine', :vmid, :text do
-        disk_id    = args[1].to_i
-        image_name = args[2]
-        verbose = "disk #{disk_id} prepared to be saved in " <<
-                  "the image #{image_name}"
+    stop_desc = <<-EOT.unindent
+        Stops a running VM. The VM state is saved and transferred back to the
+        front-end along with the disk files
 
-        helper.perform_action(args[0],options,verbose) do |vm|
-            vm.save_as(disk_id, image_name)
-        end
-    end
+        States: RUNNING
+    EOT
 
-    command :show, 'Gets info from a Virtual Machine', :vmid,
-            :options=>OpenNebulaHelper::XML do
-        helper.show_resource(args[0],options)
-    end
-
-    command :stop, 'Stop a Virtual Machine', [:range,:vmid_list] do
+    command :stop, stop_desc, [:range,:vmid_list] do
         helper.perform_actions(args[0],options,"stopping") do |vm|
             vm.stop
         end
     end
 
-    command :suspend, 'Suspend a Virtual Machine', [:range,:vmid_list] do
+    suspend_desc = <<-EOT.unindent
+        Saves a running VM. It is the same as 'onevm stop', but the files
+        are left in the remote machine to later restart the VM there
+        (i.e. the resources are not freed and there is no need to
+        re-schedule the VM).
+
+        States: RUNNING
+    EOT
+
+    command :suspend, suspend_desc, [:range,:vmid_list] do
         helper.perform_actions(args[0],options,"suspending") do |vm|
             vm.suspend
         end
     end
 
-    command :top, 'Tops Virtual Machine in the pool', [:filterflag, nil],
+    resume_desc = <<-EOT.unindent
+        Resumes the execution of the a saved VM
+
+        States: STOPPED, SUSPENDED
+    EOT
+
+    command :resume, resume_desc, [:range,:vmid_list] do
+        helper.perform_actions(args[0],options,"resuming") do |vm|
+            vm.resume
+        end
+    end
+
+    chgrp_desc = <<-EOT.unindent
+        Changes the VM group
+    EOT
+
+    command :chgrp, chgrp_desc,[:range, :vmid_list], :groupid do
+        helper.perform_actions(args[0],options,"Group changed") do |vm|
+            vm.chown(-1, args[1].to_i)
+        end
+    end
+
+    chown_desc = <<-EOT.unindent
+        Changes the Image owner and group
+    EOT
+
+    command :chown, chown_desc, [:range, :vmid_list], :userid, [:groupid,nil] do
+        gid = args[2].nil? ? -1 : args[2].to_id
+        helper.perform_actions(args[0],options,"Owner/Group changed") do |vm|
+            vm.chown(args[1].to_i, gid)
+        end
+    end
+
+    list_desc = <<-EOT.unindent
+        Lists VMs in the pool
+    EOT
+
+    command :list, list_desc, [:filterflag, nil],
+            :options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do
+        helper.list_pool(options)
+    end
+
+    show_desc = <<-EOT.unindent
+        Shows information for the given VM
+    EOT
+
+    command :show, show_desc, :vmid,
+            :options=>OpenNebulaHelper::XML do
+        helper.show_resource(args[0],options)
+    end
+
+    top_desc = <<-EOT.unindent
+        Lists Images continuously
+    EOT
+
+    command :top, top_desc, [:filterflag, nil],
             :options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do
         helper.list_pool(options, true)
     end
diff --git a/src/cli/onevnet b/src/cli/onevnet
index ca76e7b536..030ce7cdfa 100755
--- a/src/cli/onevnet
+++ b/src/cli/onevnet
@@ -67,63 +67,106 @@ cmd=CommandParser::CmdParser.new(ARGV) do
     ########################################################################
     # Commands
     ########################################################################
-    command :create, 'Create a new Virtual Network', :file do
+
+    create_desc = <<-EOT.unindent
+        Creates a new Virtual Network from the given template file
+    EOT
+
+    command :create, create_desc, :file do
         helper.create_resource(options) do |vn|
             template=File.read(args[0])
             vn.allocate(template)
         end
     end
 
-    command :chgrp, 'Changes the Virtual Network group',[:range, :vnid_list], :groupid do
-        helper.perform_actions(args[0],options,"User/Group changed") do |vn|
-            vn.chown(-1, args[1].to_i)
+    delete_desc = <<-EOT.unindent
+        Deletes the given Virtual Network
+    EOT
+
+    command :delete, delete_desc, [:range, :vnetid_list] do
+        helper.perform_actions(args[0],options,"deleted") do |vn|
+            vn.delete
         end
     end
 
-    command :chown, 'Changes the Virtual Network owner and group', [:range, :vnid_list], :userid, [:groupid,nil] do
-        gid = args[2].nil? ? -1 : args[2].to_id
-        helper.perform_actions(args[0],options,"Group changed") do |vn|
-            vn.chown(args[1].to_i, gid)
-        end
-    end
+    addleases_desc = <<-EOT.unindent
+        Adds a lease to the Virtual Network
+    EOT
 
-    command :show, 'Gets info from a Virtual Network', :vnetid,
-            :options=>OpenNebulaHelper::XML do
-        helper.show_resource(args[0],options)
-    end
-
-    command :list, 'Lists Virtual Networks in the pool', [:filterflag, nil],
-            :options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do
-        helper.list_pool(options)
-    end
-
-    command :publish, 'Publishes a Virtual Network', [:range,:vnetid_list] do
-        helper.perform_actions(args[0],options,"published") do |vn|
-            vn.publish
-        end
-    end
-
-    command :unpublish, 'Unpublishes a Virtual Network', [:range,:vnetid_list] do
-        helper.perform_actions(args[0],options,"unpublished") do |vn|
-            vn.unpublish
-        end
-    end
-
-    command :addleases, 'Adds a lease to the Virtual Network', :vnetid, :text, [:text, nil] do
+    command :addleases, 'Adds a lease to the Virtual Network', :vnetid, :ip, [:mac, nil] do
         helper.perform_action(args[0],options,"lease added") do |vn|
             vn.addleases(args[1], args[2])
         end
     end
 
-    command :rmleases, 'Removes a lease from the Virtual Network', :vnetid, :text do
+    rmleases_desc = <<-EOT.unindent
+        Removes a lease from the Virtual Network
+    EOT
+
+    command :rmleases, rmleases_desc, :vnetid, :ip do
         helper.perform_action(args[0],options,"lease removed") do |vn|
             vn.rmleases(args[1])
         end
     end
 
-    command :delete, 'Removes a Virtual Network', [:range, :vnetid_list] do
-        helper.perform_actions(args[0],options,"deleted") do |vn|
-            vn.delete
+    publish_desc = <<-EOT.unindent
+        Publishes the given Virtual Network. A public Virtual Network can be
+        seen and used by other Users in the Virtual Network's group
+    EOT
+
+    command :publish, publish_desc, [:range,:vnetid_list] do
+        helper.perform_actions(args[0],options,"published") do |vn|
+            vn.publish
         end
     end
+
+    unpublish_desc = <<-EOT.unindent
+        Unpublishes the given Virtual Network. A private Virtual Network
+        can't be used by any other User
+    EOT
+
+    command :unpublish, unpublish_desc, [:range,:vnetid_list] do
+        helper.perform_actions(args[0],options,"unpublished") do |vn|
+            vn.unpublish
+        end
+    end
+
+    chgrp_desc = <<-EOT.unindent
+        Changes the Virtual Network group
+    EOT
+
+    command :chgrp, chgrp_desc,[:range, :vnid_list], :groupid do
+        helper.perform_actions(args[0],options,"Group changed") do |vn|
+            vn.chown(-1, args[1].to_i)
+        end
+    end
+
+    chown_desc = <<-EOT.unindent
+        Changes the Virtual Network owner and group
+    EOT
+
+    command :chown, chown_desc, [:range, :vnid_list], :userid, [:groupid,nil] do
+        gid = args[2].nil? ? -1 : args[2].to_id
+        helper.perform_actions(args[0],options,"Owner/Group changed") do |vn|
+            vn.chown(args[1].to_i, gid)
+        end
+    end
+
+    list_desc = <<-EOT.unindent
+        Lists Virtual Networks in the pool
+    EOT
+
+    command :list, list_desc, [:filterflag, nil],
+            :options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do
+        helper.list_pool(options)
+    end
+
+    show_desc = <<-EOT.unindent
+        Shows information for the given Virtual Network
+    EOT
+
+    command :show, show_desc, :vnetid,
+            :options=>OpenNebulaHelper::XML do
+        helper.show_resource(args[0],options)
+    end
 end

From e1aa008db185bab10ae58155c6ea5fd6035a360f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es>
Date: Thu, 16 Jun 2011 18:34:17 +0200
Subject: [PATCH 2/2] Feature #661: Implement onegrop and oneuser commands
 marked with "TODO"

---
 src/cli/one_helper/onegroup_helper.rb | 15 +++++++++++++++
 src/cli/one_helper/oneuser_helper.rb  | 18 ++++++++++++++++++
 src/cli/onegroup                      |  3 +--
 src/cli/oneimage                      | 18 +++++++++---------
 src/cli/oneuser                       | 17 +++++++++++------
 5 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/src/cli/one_helper/onegroup_helper.rb b/src/cli/one_helper/onegroup_helper.rb
index c20f0794a0..46c6ffbf60 100644
--- a/src/cli/one_helper/onegroup_helper.rb
+++ b/src/cli/one_helper/onegroup_helper.rb
@@ -41,6 +41,21 @@ class OneGroupHelper < OpenNebulaHelper::OneHelper
         OpenNebula::GroupPool.new(@client)
     end
 
+    def format_resource(group)
+        str="%-15s: %-20s"
+        str_h1="%-80s"
+
+        CLIHelper.print_header(str_h1 % "GROUP #{group['ID']} INFORMATION")
+        puts str % ["ID",   group.id.to_s]
+        puts str % ["NAME", group.name]
+        puts
+
+        CLIHelper.print_header(str_h1 % "USERS",false)
+        group.user_ids.each do |uid|
+            puts str % ["ID",   uid]
+        end
+    end
+
     def format_pool(pool, options, top=false)
         config_file=self.class.table_conf
         table=CLIHelper::ShowTable.new(config_file, self) do
diff --git a/src/cli/one_helper/oneuser_helper.rb b/src/cli/one_helper/oneuser_helper.rb
index af3ee481b8..5768aab7f5 100644
--- a/src/cli/one_helper/oneuser_helper.rb
+++ b/src/cli/one_helper/oneuser_helper.rb
@@ -63,6 +63,24 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
         OpenNebula::UserPool.new(@client)
     end
 
+    def format_resource(user)
+        str="%-15s: %-20s"
+        str_h1="%-80s"
+
+        CLIHelper.print_header(str_h1 % "USER #{user['ID']} INFORMATION")
+        puts str % ["ID",       user.id.to_s]
+        puts str % ["NAME",     user.name]
+        puts str % ["GROUP",    user.gid]
+        puts str % ["PASSWORD", user['PASSWORD']]
+        puts str % ["ENABLED",  user['ENABLED']]
+        puts
+
+        CLIHelper.print_header(str_h1 % "SECONDARY GROUPS",false)
+        user.group_ids.each do |gid|
+            puts str % ["ID",   uid]
+        end
+    end
+
     def format_pool(pool, options, top=false)
         config_file=self.class.table_conf
         table=CLIHelper::ShowTable.new(config_file, self) do
diff --git a/src/cli/onegroup b/src/cli/onegroup
index 662cf70dc9..14622a2790 100755
--- a/src/cli/onegroup
+++ b/src/cli/onegroup
@@ -93,8 +93,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
     EOT
 
     command :show, show_desc, :groupid, :options=>OpenNebulaHelper::XML do
-        puts "TODO"
-        -1
+        helper.show_resource(args[0],options)
     end
 
 end
diff --git a/src/cli/oneimage b/src/cli/oneimage
index 2d10f8c775..93babe60cd 100755
--- a/src/cli/oneimage
+++ b/src/cli/oneimage
@@ -93,6 +93,11 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         end
     end
 
+    publish_desc = <<-EOT.unindent
+        Publishes the given Image. A public Image can be seen and used by other
+        Users in the Image's group
+    EOT
+
     command :publish, publish_desc, [:range,:imageid_list] do
         helper.perform_actions(args[0],options,"published") do |image|
             image.publish
@@ -185,10 +190,6 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         end
     end
 
-    show_desc = <<-EOT.unindent
-        Shows information for the given Image
-    EOT
-
     list_desc = <<-EOT.unindent
         Lists Images in the pool
     EOT
@@ -197,15 +198,14 @@ cmd=CommandParser::CmdParser.new(ARGV) do
         helper.list_pool(options)
     end
 
+    show_desc = <<-EOT.unindent
+        Shows information for the given Image
+    EOT
+
     command :show, show_desc, :imageid, :options=>OpenNebulaHelper::XML do
         helper.show_resource(args[0],options)
     end
 
-    publish_desc = <<-EOT.unindent
-        Publishes the given Image. A public Image can be seen and used by other
-        Users in the Image's group
-    EOT
-
     top_desc = <<-EOT.unindent
         Lists Images continuously
     EOT
diff --git a/src/cli/oneuser b/src/cli/oneuser
index 33865930d6..bfc2a45fd8 100755
--- a/src/cli/oneuser
+++ b/src/cli/oneuser
@@ -129,8 +129,11 @@ cmd=CommandParser::CmdParser.new(ARGV) do
     EOT
 
     command :addgroup, addgroup_desc, [:range, :userid_list], :groupid do
-        puts "TODO"
-        -1
+        gid = args[1]
+
+        helper.perform_actions(args[0],options,"group added") do |user|
+            user.addgroup( gid )
+        end
     end
 
     delgroup_desc = <<-EOT.unindent
@@ -138,8 +141,11 @@ cmd=CommandParser::CmdParser.new(ARGV) do
     EOT
 
     command :delgroup, delgroup_desc, [:range, :userid_list], :groupid do
-        puts "TODO"
-        -1
+        gid = args[1]
+
+        helper.perform_actions(args[0],options,"group deleted") do |user|
+            user.delgroup( gid )
+        end
     end
 
     list_desc = <<-EOT.unindent
@@ -155,8 +161,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
     EOT
 
     command :show, show_desc, :userid, :options=>OpenNebulaHelper::XML do
-        puts "TODO"
-        -1
+        helper.show_resource(args[0],options)
     end
 
 end