mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-27 10:50:10 +03:00
Merge branch 'feature-1427' into feature-1098
This commit is contained in:
commit
3d402140ac
@ -98,7 +98,7 @@ main_env.Append(LINKFLAGS=['-g', '-pthread'])
|
||||
# SQLITE
|
||||
sqlite_dir=ARGUMENTS.get('sqlite_dir', 'none')
|
||||
if sqlite_dir!='none':
|
||||
main_env.Append(LIBPATH=[sqlite_dir+"/lib"])
|
||||
main_env.Append(LIBPATH=[sqlite_dir+"/lib", sqlite_dir+"/lib64"])
|
||||
main_env.Append(CPPPATH=[sqlite_dir+"/include"])
|
||||
|
||||
sqlite=ARGUMENTS.get('sqlite', 'yes')
|
||||
@ -121,7 +121,7 @@ else:
|
||||
# xmlrpc
|
||||
xmlrpc_dir=ARGUMENTS.get('xmlrpc', 'none')
|
||||
if xmlrpc_dir!='none':
|
||||
main_env.Append(LIBPATH=[xmlrpc_dir+"/lib"])
|
||||
main_env.Append(LIBPATH=[xmlrpc_dir+"/lib", xmlrpc_dir+"/lib64"])
|
||||
main_env.Append(CPPPATH=[xmlrpc_dir+"/include"])
|
||||
|
||||
# build lex/bison
|
||||
|
10
install.sh
10
install.sh
@ -248,7 +248,8 @@ VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/auth/server_cipher \
|
||||
$VAR_LOCATION/remotes/auth/dummy"
|
||||
|
||||
SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \
|
||||
SUNSTONE_DIRS="$SUNSTONE_LOCATION/routes \
|
||||
$SUNSTONE_LOCATION/models \
|
||||
$SUNSTONE_LOCATION/models/OpenNebulaJSON \
|
||||
$SUNSTONE_LOCATION/public \
|
||||
$SUNSTONE_LOCATION/public/js \
|
||||
@ -919,6 +920,7 @@ DATASTORE_DRIVER_FS_SCRIPTS="src/datastore_mad/remotes/fs/cp \
|
||||
DATASTORE_DRIVER_VMWARE_SCRIPTS="src/datastore_mad/remotes/vmware/cp \
|
||||
src/datastore_mad/remotes/vmware/mkfs \
|
||||
src/datastore_mad/remotes/vmware/stat \
|
||||
src/datastore_mad/remotes/vmware/clone \
|
||||
src/datastore_mad/remotes/vmware/rm"
|
||||
|
||||
DATASTORE_DRIVER_ISCSI_SCRIPTS="src/datastore_mad/remotes/iscsi/cp \
|
||||
@ -1192,7 +1194,8 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \
|
||||
src/cli/one_helper/onevnet_helper.rb \
|
||||
src/cli/one_helper/oneacl_helper.rb \
|
||||
src/cli/one_helper/onedatastore_helper.rb \
|
||||
src/cli/one_helper/onecluster_helper.rb"
|
||||
src/cli/one_helper/onecluster_helper.rb \
|
||||
src/cli/one_helper/oneacct_helper.rb"
|
||||
|
||||
CLI_BIN_FILES="src/cli/onevm \
|
||||
src/cli/onehost \
|
||||
@ -1203,7 +1206,8 @@ CLI_BIN_FILES="src/cli/onevm \
|
||||
src/cli/onegroup \
|
||||
src/cli/oneacl \
|
||||
src/cli/onedatastore \
|
||||
src/cli/onecluster"
|
||||
src/cli/onecluster \
|
||||
src/cli/oneacct"
|
||||
|
||||
CLI_CONF_FILES="src/cli/etc/onegroup.yaml \
|
||||
src/cli/etc/onehost.yaml \
|
||||
|
@ -54,61 +54,206 @@ module CommandParser
|
||||
attr_reader :options, :args
|
||||
|
||||
def initialize(args=[], &block)
|
||||
@opts = Array.new
|
||||
@available_options = Array.new
|
||||
@commands = Hash.new
|
||||
@formats = Hash.new
|
||||
@script = nil
|
||||
|
||||
@main = nil
|
||||
|
||||
@exit_code = nil
|
||||
|
||||
@args = args
|
||||
@options = Hash.new
|
||||
|
||||
set :format, :file, "Path to a file" do |arg|
|
||||
format_file(arg)
|
||||
end
|
||||
|
||||
set :format, :range, "List of id's in the form 1,8..15" do |arg|
|
||||
format_range(arg)
|
||||
end
|
||||
|
||||
set :format, :text, "String" do |arg|
|
||||
format_text(arg)
|
||||
end
|
||||
define_default_formats
|
||||
|
||||
instance_eval(&block)
|
||||
|
||||
self.run
|
||||
end
|
||||
|
||||
# Defines the usage information of the command
|
||||
# @param [String] str
|
||||
def usage(str)
|
||||
@usage=<<EOT
|
||||
## SYNOPSIS
|
||||
|
||||
#{str}
|
||||
EOT
|
||||
@usage=str
|
||||
end
|
||||
|
||||
# Defines the version the command
|
||||
# @param [String] str
|
||||
def version(str)
|
||||
@version = str
|
||||
end
|
||||
|
||||
# Defines the additional information of the command
|
||||
# @param [String] str
|
||||
def description(str)
|
||||
@description = str
|
||||
end
|
||||
|
||||
def set(e, *args, &block)
|
||||
case e
|
||||
when :option
|
||||
add_option(args[0])
|
||||
when :format
|
||||
add_format(args[0], args[1], block)
|
||||
# Defines a block that will be used to parse the arguments
|
||||
# of the command. Formats defined using this method con be used
|
||||
# in the arguments section of the command method, when defining a new
|
||||
# action
|
||||
#
|
||||
# @param [Symbol] format name of the format
|
||||
# @param [String] description
|
||||
#
|
||||
# @yieldreturn [Array[Integer, String]] the block must return an Array
|
||||
# containing the result (0:success, 1:failure) and the
|
||||
# new value for the argument.
|
||||
def format(format, description, &block)
|
||||
@formats[format] = {
|
||||
:desc => description,
|
||||
:proc => block
|
||||
}
|
||||
end
|
||||
|
||||
# Defines a global option for the command that will be used for all the
|
||||
# actions
|
||||
# @param [Hash, Array<Hash>] options the option to be included. An
|
||||
# array of options can be also provided
|
||||
# @option options [String] :name
|
||||
# @option options [String] :short
|
||||
# @option options [String] :large
|
||||
# @option options [String] :description
|
||||
# @option options [Class] :format
|
||||
# @option options [Block] :proc The block receives the value of the
|
||||
# option and the hash of options. The block must return an Array
|
||||
# containing the result (0:success, 1:failure) and the
|
||||
# new value for the argument or nil. More than one option can be
|
||||
# specified in the block using the options hash. This hash will be
|
||||
# available inside the command block.
|
||||
#
|
||||
# @example
|
||||
# This example will define the following options:
|
||||
# options[:type] = type
|
||||
#
|
||||
# TYPE={
|
||||
# :name => "type",
|
||||
# :short => "-t type",
|
||||
# :large => "--type type",
|
||||
# :format => String,
|
||||
# :description => "Type of the new Image"
|
||||
# }
|
||||
#
|
||||
# This example will define the following options:
|
||||
# options[:check] = true
|
||||
# options[:datastore] = id
|
||||
#
|
||||
# DATASTORE = {
|
||||
# :name => "datastore",
|
||||
# :short => "-d id|name",
|
||||
# :large => "--datastore id|name" ,
|
||||
# :description => "Selects the datastore",
|
||||
# :format => String,
|
||||
# :proc => lambda { |o, options|
|
||||
# options[:check] = true
|
||||
# [0, OpenNebulaHelper.dname_to_id(o)]
|
||||
# }
|
||||
# }
|
||||
#
|
||||
def option(options)
|
||||
if options.instance_of?(Array)
|
||||
options.each { |o| @available_options << o }
|
||||
elsif options.instance_of?(Hash)
|
||||
@available_options << options
|
||||
end
|
||||
end
|
||||
|
||||
# Defines the exit code to be returned by the command
|
||||
# @param [Integer] code
|
||||
def exit_code(code)
|
||||
@exit_code = code
|
||||
end
|
||||
|
||||
def exit_with_code(code, output=nil)
|
||||
puts output if output
|
||||
exit code
|
||||
end
|
||||
|
||||
# Defines a new action for the command, several actions can be defined
|
||||
# for a command. For example: create, delete, list.
|
||||
# The options and args variables can be used inside the block, and
|
||||
# they contain the parsedarguments and options.
|
||||
#
|
||||
# @param [Symbol] name Name of the action (i.e: :create, :list)
|
||||
# @param [String] desc Description of the action
|
||||
# @param [Array<Symbol, Array<Symbol, nil>>, Hash] args_format arguments
|
||||
# or specific options for this actiion
|
||||
# Note that the first argument of the command is the
|
||||
# action and should not be defined using this parameter. The rest of
|
||||
# the argument must be defined using this parameter.
|
||||
# This parameter can use formats previously defined with the format
|
||||
# method
|
||||
# Options are specified using a hash :options => ... containing
|
||||
# the hashes representing the options. The option method doc contains
|
||||
# the hash that has to be used to specify an option
|
||||
# @yieldreturn [Integer, Array[Integer, String]] the block must
|
||||
# return the exit_code and if a String is returned it will be printed
|
||||
#
|
||||
# @example
|
||||
# Definining two arguments:
|
||||
# $ onetest test a1 a2
|
||||
#
|
||||
# CommandParser::CmdParser.new(ARGV) do
|
||||
# description "Test"
|
||||
# usage "onetest <command> <args> [options]"
|
||||
# version "1.0"
|
||||
#
|
||||
# options VERBOSE, HELP
|
||||
#
|
||||
# command :test, "Test", :test1, :test2, :options => XML do
|
||||
# puts options[:xml]
|
||||
# puts options[:verbose]
|
||||
# puts args[0]
|
||||
# puts args[1]
|
||||
# [0, "It works"]
|
||||
# end
|
||||
# end
|
||||
#
|
||||
#
|
||||
# Defining optional arguments: test1 is mandatory, test2 optional
|
||||
# $ onetest test a1 | $ onetest test a1 a2
|
||||
#
|
||||
# CommandParser::CmdParser.new(ARGV) do
|
||||
# description "Test"
|
||||
# usage "onetest <command> <args> [options]"
|
||||
# version "1.0"
|
||||
#
|
||||
# options VERBOSE, HELP
|
||||
#
|
||||
# command :test, "Test", :test1, [:test2, nil], :options => XML do
|
||||
# puts options[:xml]
|
||||
# puts options[:verbose]
|
||||
# puts args[0]
|
||||
# puts "It works"
|
||||
# 0
|
||||
# end
|
||||
# end
|
||||
#
|
||||
#
|
||||
# Defining an argument with different formats:
|
||||
# $ onetest test a1 a2 | $ onetest test a1 123
|
||||
#
|
||||
# CommandParser::CmdParser.new(ARGV) do
|
||||
# description "Test"
|
||||
# usage "onetest <command> <args> [options]"
|
||||
# version "1.0"
|
||||
#
|
||||
# options VERBOSE, HELP
|
||||
#
|
||||
# format :format1, "String to Integer" do
|
||||
# [0, arg.to_i]
|
||||
# end
|
||||
#
|
||||
# command :test, "Test", :test1, [:format1, format2], :options => XML do
|
||||
# puts options[:xml]
|
||||
# puts options[:verbose]
|
||||
# puts args[0]
|
||||
# 0
|
||||
# end
|
||||
# end
|
||||
#
|
||||
def command(name, desc, *args_format, &block)
|
||||
cmd = Hash.new
|
||||
cmd[:desc] = desc
|
||||
@ -130,28 +275,119 @@ EOT
|
||||
@commands[name.to_sym] = cmd
|
||||
end
|
||||
|
||||
def script(*args_format, &block)
|
||||
@script=Hash.new
|
||||
@script[:args_format] = Array.new
|
||||
# Defines a new action for the command, several actions can be defined
|
||||
# for a command. For example: create, delete, list.
|
||||
# The options and args variables can be used inside the block, and
|
||||
# they contain the parsedarguments and options.
|
||||
#
|
||||
# @param [Array<Symbol, Array<Symbol, nil>>] args_format arguments
|
||||
# or specific options for this actiion
|
||||
# Note that the first argument of the command is the
|
||||
# action and should not be defined using this parameter. The rest of
|
||||
# the argument must be defined using this parameter.
|
||||
# This parameter can use formats previously defined with the format
|
||||
# method
|
||||
# @yieldreturn [Integer, Array[Integer, String]] the block must
|
||||
# return the exit_code and if a String is returned it will be printed
|
||||
#
|
||||
# @example
|
||||
# Definining two arguments:
|
||||
# $ onetest a1 a2
|
||||
#
|
||||
# CommandParser::CmdParser.new(ARGV) do
|
||||
# description "Test"
|
||||
# usage "onetest <args> [options]"
|
||||
# version "1.0"
|
||||
#
|
||||
# options XML, VERBOSE, HELP
|
||||
#
|
||||
# main :test1, :test2 do
|
||||
# puts options[:xml]
|
||||
# puts options[:verbose]
|
||||
# puts args[0]
|
||||
# puts args[1]
|
||||
# [0, "It works"]
|
||||
# end
|
||||
# end
|
||||
#
|
||||
#
|
||||
# Defining optional arguments: test1 is mandatory, test2 optional
|
||||
# $ onetest a1 | $ onetest a1 a2
|
||||
#
|
||||
# CommandParser::CmdParser.new(ARGV) do
|
||||
# description "Test"
|
||||
# usage "onetest <args> [<options>]"
|
||||
# version "1.0"
|
||||
#
|
||||
# options XML, VERBOSE, HELP
|
||||
#
|
||||
# main :test1, [:test2, nil] do
|
||||
# puts options[:xml]
|
||||
# puts options[:verbose]
|
||||
# puts args[0]
|
||||
# puts "It works"
|
||||
# 0
|
||||
# end
|
||||
# end
|
||||
#
|
||||
#
|
||||
# Defining an argument with different formats:
|
||||
# $ onetest a1 a2 | $ onetest a1 123
|
||||
#
|
||||
# CommandParser::CmdParser.new(ARGV) do
|
||||
# description "Test"
|
||||
# usage "onetest <args> [<options>]"
|
||||
# version "1.0"
|
||||
#
|
||||
# options XML, VERBOSE, HELP
|
||||
#
|
||||
# format :format1, "String to Integer" do
|
||||
# [0, arg.to_i]
|
||||
# end
|
||||
#
|
||||
# main :test1, [:format1, :format2] do
|
||||
# puts options[:xml]
|
||||
# puts options[:verbose]
|
||||
# puts args[0]
|
||||
# puts args[1]
|
||||
# 0
|
||||
# end
|
||||
# end
|
||||
#
|
||||
def main(*args_format, &block)
|
||||
@main=Hash.new
|
||||
@main[:arity] = 0
|
||||
@main[:args_format] = Array.new
|
||||
args_format.collect {|args|
|
||||
if args.instance_of?(Array)
|
||||
@script[:arity]+=1 unless args.include?(nil)
|
||||
@script[:args_format] << args
|
||||
@main[:arity]+=1 unless args.include?(nil)
|
||||
@main[:args_format] << args
|
||||
elsif args.instance_of?(Hash) && args[:options]
|
||||
@opts << args[:options]
|
||||
@available_options << args[:options]
|
||||
else
|
||||
@script[:arity]+=1
|
||||
@script[:args_format] << [args]
|
||||
@main[:arity]+=1
|
||||
@main[:args_format] << [args]
|
||||
end
|
||||
}
|
||||
|
||||
@script[:proc] = block
|
||||
@main[:proc] = block
|
||||
end
|
||||
|
||||
# DEPRECATED, use format and options instead
|
||||
def set(e, *args, &block)
|
||||
case e
|
||||
when :option
|
||||
option(args[0])
|
||||
when :format
|
||||
format(args[0], args[1], &block)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def run
|
||||
comm_name=""
|
||||
if @script
|
||||
comm=@script
|
||||
if @main
|
||||
comm=@main
|
||||
elsif
|
||||
if @args[0] && !@args[0].match(/^-/)
|
||||
comm_name=@args.shift.to_sym
|
||||
@ -160,7 +396,7 @@ EOT
|
||||
end
|
||||
|
||||
if comm.nil?
|
||||
help
|
||||
print_help
|
||||
exit -1
|
||||
end
|
||||
|
||||
@ -175,133 +411,17 @@ EOT
|
||||
puts rc[1]
|
||||
exit rc.first
|
||||
else
|
||||
exit rc
|
||||
exit(@exit_code || rc)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def help
|
||||
puts @usage if @usage
|
||||
puts
|
||||
puts @description if @description
|
||||
puts
|
||||
print_options
|
||||
puts
|
||||
print_commands
|
||||
puts
|
||||
print_formatters
|
||||
puts
|
||||
if @version
|
||||
puts "## LICENSE"
|
||||
puts @version
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def print_options
|
||||
puts "## OPTIONS"
|
||||
|
||||
shown_opts = Array.new
|
||||
opt_format = "#{' '*5}%-25s %s"
|
||||
@commands.each{ |key,value|
|
||||
value[:options].flatten.each { |o|
|
||||
if shown_opts.include?(o[:name])
|
||||
next
|
||||
else
|
||||
shown_opts << o[:name]
|
||||
|
||||
str = ""
|
||||
str << o[:short].split(' ').first << ', ' if o[:short]
|
||||
str << o[:large]
|
||||
|
||||
printf opt_format, str, o[:description]
|
||||
puts
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
@opts.each{ |o|
|
||||
str = ""
|
||||
str << o[:short].split(' ').first << ', ' if o[:short]
|
||||
str << o[:large]
|
||||
|
||||
printf opt_format, str, o[:description]
|
||||
puts
|
||||
}
|
||||
end
|
||||
|
||||
def print_commands
|
||||
puts "## COMMANDS"
|
||||
|
||||
cmd_format5 = "#{' '*3}%s"
|
||||
cmd_format10 = "#{' '*8}%s"
|
||||
@commands.each{ |key,value|
|
||||
printf cmd_format5, "* #{key} "
|
||||
|
||||
args_str=value[:args_format].collect{ |a|
|
||||
if a.include?(nil)
|
||||
"[<#{a.compact.join("|")}>]"
|
||||
else
|
||||
"<#{a.join("|")}>"
|
||||
end
|
||||
}.join(' ')
|
||||
printf "#{args_str}"
|
||||
puts
|
||||
|
||||
value[:desc].split("\n").each { |l|
|
||||
printf cmd_format10, l
|
||||
puts
|
||||
}
|
||||
|
||||
unless value[:options].empty?
|
||||
opts_str=value[:options].flatten.collect{|o|
|
||||
o[:name]
|
||||
}.join(', ')
|
||||
printf cmd_format10, "valid options: #{opts_str}"
|
||||
puts
|
||||
end
|
||||
puts
|
||||
}
|
||||
end
|
||||
|
||||
def print_formatters
|
||||
puts "## ARGUMENT FORMATS"
|
||||
|
||||
cmd_format5 = "#{' '*3}%s"
|
||||
cmd_format10 = "#{' '*8}%s"
|
||||
@formats.each{ |key,value|
|
||||
printf cmd_format5, "* #{key}"
|
||||
puts
|
||||
|
||||
value[:desc].split("\n").each { |l|
|
||||
printf cmd_format10, l
|
||||
puts
|
||||
}
|
||||
|
||||
puts
|
||||
}
|
||||
end
|
||||
|
||||
def add_option(option)
|
||||
if option.instance_of?(Array)
|
||||
option.each { |o| @opts << o }
|
||||
elsif option.instance_of?(Hash)
|
||||
@opts << option
|
||||
end
|
||||
end
|
||||
|
||||
def add_format(format, description, block)
|
||||
@formats[format] = {
|
||||
:desc => description,
|
||||
:proc => block
|
||||
}
|
||||
end
|
||||
|
||||
def parse(extra_options)
|
||||
@cmdparse=OptionParser.new do |opts|
|
||||
merge = @opts
|
||||
merge = @opts + extra_options if extra_options
|
||||
merge = @available_options
|
||||
merge = @available_options + extra_options if extra_options
|
||||
merge.flatten.each do |e|
|
||||
args = []
|
||||
args << e[:short] if e[:short]
|
||||
@ -311,9 +431,16 @@ EOT
|
||||
|
||||
opts.on(*args) do |o|
|
||||
if e[:proc]
|
||||
e[:proc].call(o, @options)
|
||||
rc = e[:proc].call(o, @options)
|
||||
if rc.instance_of?(Array) && rc[0] == 0
|
||||
options[e[:name].to_sym] = rc[1]
|
||||
else
|
||||
puts rc[1]
|
||||
puts "option #{e[:name]}: Parsing error"
|
||||
exit -1
|
||||
end
|
||||
elsif e[:name]=="help"
|
||||
help
|
||||
print_help
|
||||
exit
|
||||
elsif e[:name]=="version"
|
||||
puts @version
|
||||
@ -399,7 +526,126 @@ EOT
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
# Printers
|
||||
########################################################################
|
||||
|
||||
def print_help
|
||||
if @usage
|
||||
puts "## SYNOPSIS"
|
||||
puts
|
||||
puts @usage
|
||||
puts
|
||||
end
|
||||
puts @description if @description
|
||||
puts
|
||||
print_options
|
||||
puts
|
||||
print_commands
|
||||
puts
|
||||
print_formatters
|
||||
puts
|
||||
if @version
|
||||
puts "## LICENSE"
|
||||
puts @version
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def print_options
|
||||
puts "## OPTIONS"
|
||||
|
||||
shown_opts = Array.new
|
||||
opt_format = "#{' '*5}%-25s %s"
|
||||
@commands.each{ |key,value|
|
||||
value[:options].flatten.each { |o|
|
||||
if shown_opts.include?(o[:name])
|
||||
next
|
||||
else
|
||||
shown_opts << o[:name]
|
||||
|
||||
str = ""
|
||||
str << o[:short].split(' ').first << ', ' if o[:short]
|
||||
str << o[:large]
|
||||
|
||||
printf opt_format, str, o[:description]
|
||||
puts
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
@available_options.each{ |o|
|
||||
str = ""
|
||||
str << o[:short].split(' ').first << ', ' if o[:short]
|
||||
str << o[:large]
|
||||
|
||||
printf opt_format, str, o[:description]
|
||||
puts
|
||||
}
|
||||
end
|
||||
|
||||
def print_commands
|
||||
cmd_format5 = "#{' '*3}%s"
|
||||
cmd_format10 = "#{' '*8}%s"
|
||||
|
||||
if @main
|
||||
print_command(@main)
|
||||
else
|
||||
puts "## COMMANDS"
|
||||
|
||||
@commands.each{ |key,value|
|
||||
printf cmd_format5, "* #{key} "
|
||||
|
||||
print_command(value)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def print_command(command)
|
||||
args_str=command[:args_format].collect{ |a|
|
||||
if a.include?(nil)
|
||||
"[<#{a.compact.join("|")}>]"
|
||||
else
|
||||
"<#{a.join("|")}>"
|
||||
end
|
||||
}.join(' ')
|
||||
printf "#{args_str}"
|
||||
puts
|
||||
|
||||
command[:desc].split("\n").each { |l|
|
||||
printf cmd_format10, l
|
||||
puts
|
||||
}
|
||||
|
||||
unless command[:options].empty?
|
||||
opts_str=command[:options].flatten.collect{|o|
|
||||
o[:name]
|
||||
}.join(', ')
|
||||
printf cmd_format10, "valid options: #{opts_str}"
|
||||
puts
|
||||
end
|
||||
puts
|
||||
end
|
||||
|
||||
def print_formatters
|
||||
puts "## ARGUMENT FORMATS"
|
||||
|
||||
cmd_format5 = "#{' '*3}%s"
|
||||
cmd_format10 = "#{' '*8}%s"
|
||||
@formats.each{ |key,value|
|
||||
printf cmd_format5, "* #{key}"
|
||||
puts
|
||||
|
||||
value[:desc].split("\n").each { |l|
|
||||
printf cmd_format10, l
|
||||
puts
|
||||
}
|
||||
|
||||
puts
|
||||
}
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Default Formatters for arguments
|
||||
########################################################################
|
||||
def format_text(arg)
|
||||
arg.instance_of?(String) ? [0,arg] : [-1]
|
||||
@ -432,6 +678,20 @@ EOT
|
||||
|
||||
return 0,ids.uniq
|
||||
end
|
||||
|
||||
def define_default_formats
|
||||
format :file, "Path to a file" do |arg|
|
||||
format_file(arg)
|
||||
end
|
||||
|
||||
format :range, "List of id's in the form 1,8..15" do |arg|
|
||||
format_range(arg)
|
||||
end
|
||||
|
||||
format :text, "String" do |arg|
|
||||
format_text(arg)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
179
src/cli/one_helper/oneacct_helper.rb
Normal file
179
src/cli/one_helper/oneacct_helper.rb
Normal file
@ -0,0 +1,179 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
|
||||
# #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'one_helper'
|
||||
|
||||
class AcctHelper < OpenNebulaHelper::OneHelper
|
||||
START_TIME = {
|
||||
:name => "start_time",
|
||||
:short => "-s TIME",
|
||||
:large => "--start TIME" ,
|
||||
:description => "Start date and time to take into account",
|
||||
:format => String # TODO Time
|
||||
}
|
||||
|
||||
END_TIME = {
|
||||
:name => "end_time",
|
||||
:short => "-e TIME",
|
||||
:large => "--end TIME" ,
|
||||
:description => "End date and time",
|
||||
:format => String # TODO Time
|
||||
}
|
||||
|
||||
USER = {
|
||||
:name => "user",
|
||||
:short => "-u user",
|
||||
:large => "--user user" ,
|
||||
:description => "User name or id to filter the results",
|
||||
:format => String,
|
||||
:proc => lambda { |o, options|
|
||||
OpenNebulaHelper.rname_to_id(o, "USER")
|
||||
}
|
||||
}
|
||||
|
||||
GROUP = {
|
||||
:name => "group",
|
||||
:short => "-g group",
|
||||
:large => "--group group" ,
|
||||
:description => "Group name or id to filter the results",
|
||||
:format => String,
|
||||
:proc => lambda { |o, options|
|
||||
puts o
|
||||
OpenNebulaHelper.rname_to_id(o, "GROUP")
|
||||
}
|
||||
}
|
||||
|
||||
HOST = {
|
||||
:name => "host",
|
||||
:short => "-H HOST",
|
||||
:large => "--host HOST" ,
|
||||
:description => "Host name or id to filter the results",
|
||||
:format => String,
|
||||
:proc => lambda { |o, options|
|
||||
OpenNebulaHelper.rname_to_id(o, "HOST")
|
||||
}
|
||||
}
|
||||
|
||||
XPATH = {
|
||||
:name => "xpath",
|
||||
:large => "--xpath XPATH_EXPRESSION" ,
|
||||
:description => "Xpath expression to filter the results. \
|
||||
For example: oneacct --xpath 'HISTORY[ETIME>0]'",
|
||||
:format => String
|
||||
}
|
||||
|
||||
XML = {
|
||||
:name => "xml",
|
||||
:short => "-x",
|
||||
:large => "--xml",
|
||||
:description => "Show the resource in xml format"
|
||||
}
|
||||
|
||||
JSON = {
|
||||
:name => "json",
|
||||
:short => "-j",
|
||||
:large => "--json",
|
||||
:description => "Show the resource in xml format"
|
||||
}
|
||||
|
||||
SPLIT={
|
||||
:name => "split",
|
||||
:large => "--split",
|
||||
:description => "Split the output in a table for each VM"
|
||||
}
|
||||
|
||||
ACCT_OPTIONS = [START_TIME, END_TIME, USER, GROUP, HOST, XPATH, XML, JSON, SPLIT]
|
||||
|
||||
|
||||
ACCT_TABLE = CLIHelper::ShowTable.new("oneacct.yaml", nil) do
|
||||
column :VID, "Virtual Machine ID", :size=>4 do |d|
|
||||
d["OID"]
|
||||
end
|
||||
|
||||
column :SEQ, "History record sequence number", :size=>3 do |d|
|
||||
d["SEQ"]
|
||||
end
|
||||
|
||||
column :HOSTNAME, "Host name", :left, :size=>15 do |d|
|
||||
d["HOSTNAME"]
|
||||
end
|
||||
|
||||
column :REASON, "VM state change reason", :left, :size=>4 do |d|
|
||||
VirtualMachine.get_reason d["REASON"]
|
||||
end
|
||||
|
||||
column :START_TIME, "Start time", :size=>14 do |d|
|
||||
OpenNebulaHelper.time_to_str(d['STIME'])
|
||||
end
|
||||
|
||||
column :END_TIME, "End time", :size=>14 do |d|
|
||||
OpenNebulaHelper.time_to_str(d['ETIME'])
|
||||
end
|
||||
|
||||
column :MEMORY, "Assigned memory", :size=>6 do |d|
|
||||
OpenNebulaHelper.unit_to_str(d["VM"]["TEMPLATE"]["MEMORY"].to_i, {}, 'M')
|
||||
end
|
||||
|
||||
column :CPU, "Number of CPUs", :size=>3 do |d|
|
||||
d["VM"]["TEMPLATE"]["CPU"]
|
||||
end
|
||||
|
||||
column :NET_RX, "Data received from the network", :size=>6 do |d|
|
||||
# NET is measured in bytes, unit_to_str expects KBytes
|
||||
OpenNebulaHelper.unit_to_str(d["VM"]["NET_RX"].to_i / 1024.0, {})
|
||||
end
|
||||
|
||||
column :NET_TX, "Data sent to the network", :size=>6 do |d|
|
||||
# NET is measured in bytes, unit_to_str expects KBytes
|
||||
OpenNebulaHelper.unit_to_str(d["VM"]["NET_TX"].to_i / 1024.0, {})
|
||||
end
|
||||
|
||||
default :VID, :HOSTNAME, :REASON, :START_TIME, :END_TIME, :MEMORY, :CPU, :NET_RX, :NET_TX
|
||||
end
|
||||
|
||||
def self.print_start_enc_time_header(start_time, end_time)
|
||||
print "Showing active history records from "
|
||||
|
||||
CLIHelper.scr_bold
|
||||
if ( start_time != -1 )
|
||||
print Time.at(start_time).to_s
|
||||
else
|
||||
print "-"
|
||||
end
|
||||
|
||||
CLIHelper.scr_restore
|
||||
print " to "
|
||||
|
||||
CLIHelper.scr_bold
|
||||
if ( end_time != -1 )
|
||||
print Time.at(end_time).to_s
|
||||
else
|
||||
print "-"
|
||||
end
|
||||
|
||||
CLIHelper.scr_restore
|
||||
puts
|
||||
puts
|
||||
end
|
||||
|
||||
def self.print_user_header(user_id)
|
||||
CLIHelper.scr_bold
|
||||
CLIHelper.scr_underline
|
||||
puts "# User #{user_id}".ljust(80)
|
||||
CLIHelper.scr_restore
|
||||
puts
|
||||
end
|
||||
end
|
@ -25,18 +25,10 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper
|
||||
:description => "Selects the cluster",
|
||||
:format => String,
|
||||
:proc => lambda { |o, options|
|
||||
ch = OneClusterHelper.new
|
||||
rc, cid = ch.to_id(o)
|
||||
if rc == 0
|
||||
options[:cluster] = cid
|
||||
else
|
||||
puts cid
|
||||
puts "option cluster: Parsing error"
|
||||
exit -1
|
||||
end
|
||||
OpenNebulaHelper.rname_to_id(o, "CLUSTER")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def self.rname
|
||||
"CLUSTER"
|
||||
end
|
||||
|
@ -24,15 +24,7 @@ class OneDatastoreHelper < OpenNebulaHelper::OneHelper
|
||||
:description => "Selects the datastore",
|
||||
:format => String,
|
||||
:proc => lambda { |o, options|
|
||||
ch = OneDatastoreHelper.new
|
||||
rc, dsid = ch.to_id(o)
|
||||
if rc == 0
|
||||
options[:datastore] = dsid
|
||||
else
|
||||
puts dsid
|
||||
puts "option datastore: Parsing error"
|
||||
exit -1
|
||||
end
|
||||
OpenNebulaHelper.rname_to_id(o, "DATASTORE")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,14 +32,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
:description => "Selects the image",
|
||||
:format => String,
|
||||
:proc => lambda { |o, options|
|
||||
rc, imid = OpenNebulaHelper.rname_to_id(o, "IMAGE")
|
||||
if rc == 0
|
||||
options[:image] = imid
|
||||
else
|
||||
puts imid
|
||||
puts "option image: Parsing error"
|
||||
exit -1
|
||||
end
|
||||
OpenNebulaHelper.rname_to_id(o, "IMAGE")
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,13 +181,13 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
"USED CPU" => "CPU",
|
||||
"NET_TX" => "NET_TX",
|
||||
"NET_RX" => "NET_RX"
|
||||
}
|
||||
}
|
||||
|
||||
poll_attrs.each { |k,v|
|
||||
poll_attrs.each { |k,v|
|
||||
if k == "USED CPU"
|
||||
puts str % [k,vm[v]]
|
||||
puts str % [k,vm[v]]
|
||||
elsif k == "USED MEMORY"
|
||||
puts str % [k, OpenNebulaHelper.unit_to_str(vm[v].to_i, {})]
|
||||
puts str % [k, OpenNebulaHelper.unit_to_str(vm[v].to_i, {})]
|
||||
else
|
||||
puts str % [k, OpenNebulaHelper.unit_to_str(vm[v].to_i/1024, {})]
|
||||
end
|
||||
|
390
src/cli/oneacct
390
src/cli/oneacct
@ -16,7 +16,6 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
@ -28,356 +27,87 @@ end
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'rubygems'
|
||||
require 'command_parser'
|
||||
require 'one_helper/oneacct_helper'
|
||||
|
||||
require 'cli/one_helper'
|
||||
require 'cli/command_parser'
|
||||
require 'json'
|
||||
|
||||
require 'optparse'
|
||||
require 'optparse/time'
|
||||
cmd = CommandParser::CmdParser.new(ARGV) do
|
||||
usage "`oneacct` [<options>]"
|
||||
description ""
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
|
||||
################################################################################
|
||||
# CLI Helper
|
||||
################################################################################
|
||||
option [AcctHelper::ACCT_OPTIONS + CommandParser::OPTIONS]
|
||||
|
||||
class AcctHelper < OpenNebulaHelper::OneHelper
|
||||
main do
|
||||
filter_flag = (options[:user] || VirtualMachinePool::INFO_ALL)
|
||||
start_time = options[:start] ? options[:start].to_i : -1
|
||||
end_time = options[:end] ? options[:end].to_i : -1
|
||||
|
||||
def self.conf_file
|
||||
"oneacct.yaml"
|
||||
end
|
||||
common_opts = {
|
||||
:start_time => start_time,
|
||||
:end_time => end_time,
|
||||
:host => options[:host],
|
||||
:group => options[:group],
|
||||
:xpath => options[:xpath]
|
||||
}
|
||||
|
||||
=begin
|
||||
List of <HISTORY> child elements
|
||||
client = OpenNebula::Client.new
|
||||
pool = OpenNebula::VirtualMachinePool.new(client)
|
||||
|
||||
OID
|
||||
SEQ
|
||||
HOSTNAME
|
||||
HID
|
||||
STIME
|
||||
ETIME
|
||||
VMMMAD
|
||||
VNMMAD
|
||||
PSTIME
|
||||
PETIME
|
||||
RSTIME
|
||||
RETIME
|
||||
ESTIME
|
||||
EETIME
|
||||
REASON
|
||||
=end
|
||||
|
||||
def list_history(data)
|
||||
table = CLIHelper::ShowTable.new(self.class.table_conf, self) do
|
||||
column :VID, "Virtual Machine ID", :size=>4 do |d|
|
||||
d["OID"]
|
||||
if options[:json] || options[:xml]
|
||||
xml_str = pool.accounting_xml(filter_flag, common_opts)
|
||||
if OpenNebula.is_error?(xml_str)
|
||||
puts acct_hash.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
column :SEQ, "History record sequence number", :size=>3 do |d|
|
||||
d["SEQ"]
|
||||
if options[:json]
|
||||
xmldoc = XMLElement.new
|
||||
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
|
||||
|
||||
puts xmldoc.to_hash.to_json
|
||||
elsif options[:xml]
|
||||
puts xml_str
|
||||
end
|
||||
|
||||
column :HOSTNAME, "Host name", :left, :size=>15 do |d|
|
||||
d["HOSTNAME"]
|
||||
exit_code 0
|
||||
else
|
||||
order_by = Hash.new
|
||||
order_by[:order_by_1] = 'VM/UID'
|
||||
order_by[:order_by_2] = 'VM/ID' if options[:split]
|
||||
|
||||
acct_hash = pool.accounting(filter_flag, common_opts.merge(order_by))
|
||||
if OpenNebula.is_error?(acct_hash)
|
||||
puts acct_hash.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
column :REASON, "VM state change reason", :left, :size=>4 do |d|
|
||||
VirtualMachine.get_reason d["REASON"]
|
||||
if ( start_time != -1 or end_time != -1 )
|
||||
AcctHelper.print_start_end_time_header(start_time, end_time)
|
||||
end
|
||||
|
||||
column :START_TIME, "Start time", :size=>14 do |d|
|
||||
OpenNebulaHelper.time_to_str(d['STIME'])
|
||||
end
|
||||
acct_hash.each { |user_id, value|
|
||||
AcctHelper.print_user_header(user_id)
|
||||
|
||||
column :END_TIME, "End time", :size=>14 do |d|
|
||||
OpenNebulaHelper.time_to_str(d['ETIME'])
|
||||
end
|
||||
|
||||
column :MEMORY, "Assigned memory", :size=>6 do |d|
|
||||
OpenNebulaHelper.unit_to_str(d["VM/TEMPLATE/MEMORY"].to_i, {}, 'M')
|
||||
end
|
||||
|
||||
column :CPU, "Number of CPUs", :size=>3 do |d|
|
||||
d["VM/TEMPLATE/CPU"]
|
||||
end
|
||||
|
||||
column :NET_RX, "Data received from the network", :size=>6 do |d|
|
||||
# NET is measured in bytes, unit_to_str expects KBytes
|
||||
OpenNebulaHelper.unit_to_str(d["VM/NET_RX"].to_i / 1024.0, {})
|
||||
end
|
||||
|
||||
column :NET_TX, "Data sent to the network", :size=>6 do |d|
|
||||
# NET is measured in bytes, unit_to_str expects KBytes
|
||||
OpenNebulaHelper.unit_to_str(d["VM/NET_TX"].to_i / 1024.0, {})
|
||||
end
|
||||
|
||||
default :VID, :HOSTNAME, :REASON, :START_TIME, :END_TIME, :MEMORY, :CPU, :NET_RX, :NET_TX
|
||||
end
|
||||
|
||||
table.show(data)
|
||||
end
|
||||
|
||||
public
|
||||
def list_users(xmldoc, options=nil)
|
||||
|
||||
uids = xmldoc.retrieve_elements('HISTORY/VM/UID')
|
||||
|
||||
if uids.nil?
|
||||
puts "No records found."
|
||||
exit 0
|
||||
end
|
||||
|
||||
uids.uniq!
|
||||
|
||||
history_elems = []
|
||||
|
||||
uids.each do |uid|
|
||||
CLIHelper.scr_bold
|
||||
CLIHelper.scr_underline
|
||||
|
||||
username_elems =
|
||||
xmldoc.retrieve_elements("HISTORY/VM[UID=#{uid}]/UNAME")
|
||||
|
||||
username = username_elems.nil? ? "" : username_elems.uniq
|
||||
|
||||
puts "# User #{uid} #{username}".ljust(80)
|
||||
CLIHelper.scr_restore
|
||||
puts
|
||||
|
||||
history_elems.clear
|
||||
|
||||
vm_ids = xmldoc.retrieve_elements("HISTORY/VM[UID=#{uid}]/ID")
|
||||
vm_ids = [] if vm_ids.nil?
|
||||
vm_ids.uniq!
|
||||
|
||||
vm_ids.each do |vid|
|
||||
|
||||
if ( options[:split] )
|
||||
history_elems.clear
|
||||
end
|
||||
|
||||
xmldoc.each("HISTORY[OID=#{vid}]") do |history|
|
||||
history_elems << history
|
||||
end
|
||||
|
||||
if ( options[:split] )
|
||||
list_history(history_elems)
|
||||
if options[:split]
|
||||
# Use one table for each VM
|
||||
value.each { |vm_id, history_array|
|
||||
array = history_array['HISTORY_RECORDS']['HISTORY']
|
||||
AcctHelper::ACCT_TABLE.show(array)
|
||||
puts
|
||||
}
|
||||
else
|
||||
# Use the same table for all the VMs
|
||||
array = value['HISTORY_RECORDS']['HISTORY']
|
||||
AcctHelper::ACCT_TABLE.show(array)
|
||||
puts
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
if ( !options[:split] )
|
||||
list_history(history_elems)
|
||||
puts
|
||||
end
|
||||
exit_code 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
################################################################################
|
||||
# Helper methods
|
||||
################################################################################
|
||||
|
||||
def redo_xmldoc(xmldoc, xpath_str)
|
||||
xml_str = "<HISTORY_RECORDS>"
|
||||
|
||||
xmldoc.each(xpath_str) do |history|
|
||||
xml_str << history.to_xml
|
||||
end
|
||||
|
||||
xml_str << "</HISTORY_RECORDS>"
|
||||
|
||||
xmldoc = XMLElement.new
|
||||
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
|
||||
|
||||
return xmldoc
|
||||
end
|
||||
|
||||
################################################################################
|
||||
# Main command
|
||||
################################################################################
|
||||
|
||||
options = Hash.new
|
||||
|
||||
options[:format] = :table
|
||||
|
||||
opts = OptionParser.new do |opts|
|
||||
opts.on('-s', '--start TIME', Time,
|
||||
'Start date and time to take into account') do |ext|
|
||||
options[:start]=ext
|
||||
end
|
||||
|
||||
opts.on("-e", "--end TIME", Time,
|
||||
"End date and time" ) do |ext|
|
||||
options[:end]=ext
|
||||
end
|
||||
|
||||
opts.on("-u", "--user user", String,
|
||||
"User id to filter the results" ) do |ext|
|
||||
options[:user]=ext
|
||||
end
|
||||
|
||||
opts.on("-g", "--group group", String,
|
||||
"Group id to filter the results" ) do |ext|
|
||||
options[:group]=ext
|
||||
end
|
||||
|
||||
opts.on("-H", "--host hostname", String,
|
||||
"Host id to filter the results" ) do |ext|
|
||||
options[:host]=ext
|
||||
end
|
||||
|
||||
opts.on("--xpath expression", String,
|
||||
"Xpath expression to filter the results. For example: oneacct --xpath 'HISTORY[ETIME>0]'" ) do |ext|
|
||||
options[:xpath]=ext
|
||||
end
|
||||
|
||||
opts.on("-j", "--json",
|
||||
"Output in json format" ) do |ext|
|
||||
options[:format]=:json
|
||||
end
|
||||
|
||||
opts.on("-x", "--xml",
|
||||
"Output in xml format" ) do |ext|
|
||||
options[:format]=:xml
|
||||
end
|
||||
|
||||
opts.on("--split",
|
||||
"Split the output in a table for each VM" ) do |ext|
|
||||
options[:split]=ext
|
||||
end
|
||||
|
||||
opts.on("-h", "--help", "Show this message" ) do
|
||||
puts opts
|
||||
exit
|
||||
end
|
||||
|
||||
opts.on()
|
||||
end
|
||||
|
||||
|
||||
begin
|
||||
opts.parse!(ARGV)
|
||||
rescue OptionParser::ParseError => e
|
||||
STDERR.puts "Error: " << e.message
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
|
||||
client = OpenNebula::Client.new
|
||||
|
||||
acct_helper = AcctHelper.new()
|
||||
|
||||
time_start = -1
|
||||
time_end = -1
|
||||
filter_flag = VirtualMachinePool::INFO_ALL
|
||||
|
||||
time_start = options[:start].to_i if options[:start]
|
||||
time_end = options[:end].to_i if options[:end]
|
||||
|
||||
if options[:user]
|
||||
rc = OpenNebulaHelper.rname_to_id(options[:user], "USER")
|
||||
|
||||
if rc[0] == 0
|
||||
filter_flag = rc[1]
|
||||
else
|
||||
puts rc[1]
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
xml_str = client.call("vmpool.accounting",
|
||||
filter_flag,
|
||||
time_start,
|
||||
time_end)
|
||||
|
||||
if OpenNebula.is_error?(xml_str)
|
||||
puts xml_str.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
xmldoc = XMLElement.new
|
||||
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
|
||||
|
||||
xpath = nil
|
||||
hid = nil
|
||||
gid = nil
|
||||
|
||||
if options[:host]
|
||||
rc = OpenNebulaHelper.rname_to_id(options[:host], "HOST")
|
||||
|
||||
if rc[0] == 0
|
||||
hid = rc[1]
|
||||
else
|
||||
puts rc[1]
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
if options[:group]
|
||||
rc = OpenNebulaHelper.rname_to_id(options[:group], "GROUP")
|
||||
|
||||
if rc[0] == 0
|
||||
gid = rc[1]
|
||||
else
|
||||
puts rc[1]
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
if options[:host] && options[:group]
|
||||
xpath = "HISTORY[VM/GID=#{gid} and HID=#{hid}]"
|
||||
elsif options[:host]
|
||||
xpath = "HISTORY[HID=#{hid}]"
|
||||
elsif options[:group]
|
||||
xpath = "HISTORY[VM/GID=#{gid}]"
|
||||
end
|
||||
|
||||
xmldoc = redo_xmldoc(xmldoc, xpath) if !xpath.nil?
|
||||
|
||||
|
||||
if options[:xpath]
|
||||
xmldoc = redo_xmldoc(xmldoc, options[:xpath])
|
||||
end
|
||||
|
||||
|
||||
case options[:format]
|
||||
when :table
|
||||
if ( time_start != -1 or time_end != -1 )
|
||||
print "Showing active history records from "
|
||||
|
||||
CLIHelper.scr_bold
|
||||
|
||||
if ( time_start != -1 )
|
||||
print Time.at(time_start).to_s
|
||||
else
|
||||
print "-"
|
||||
end
|
||||
|
||||
CLIHelper.scr_restore
|
||||
|
||||
print " to "
|
||||
|
||||
CLIHelper.scr_bold
|
||||
|
||||
if ( time_end != -1 )
|
||||
print Time.at(time_end).to_s
|
||||
else
|
||||
print "-"
|
||||
end
|
||||
|
||||
CLIHelper.scr_restore
|
||||
puts
|
||||
puts
|
||||
end
|
||||
|
||||
acct_helper.list_users(xmldoc, options)
|
||||
|
||||
when :xml
|
||||
puts xmldoc.to_xml
|
||||
|
||||
when :json
|
||||
puts xmldoc.to_hash.to_json
|
||||
|
||||
end
|
||||
end
|
@ -221,9 +221,9 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
Creates the Login token for authentication
|
||||
Examples:
|
||||
oneuser login my_user --ssh --key /tmp/id_rsa --time 72000
|
||||
oneuser login my_user --x509 --cert /tmp/my_cert.pem \
|
||||
oneuser login my_user --x509 --cert /tmp/my_cert.pem
|
||||
--key /tmp/my_key.pk --time 72000
|
||||
oneuser login my_user --x509_proxy --proxy /tmp/my_cert.pem \
|
||||
oneuser login my_user --x509_proxy --proxy /tmp/my_cert.pem
|
||||
--time 72000
|
||||
EOT
|
||||
|
||||
@ -232,6 +232,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
end
|
||||
|
||||
key_desc = <<-EOT.unindent
|
||||
DEPRECATED, use login to generate auth files.
|
||||
|
||||
Shows a public key from a private SSH key. Use it as password
|
||||
for the SSH authentication mechanism.
|
||||
EOT
|
||||
@ -247,7 +249,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
exit_with_code -1, e.message
|
||||
end
|
||||
|
||||
puts sshauth.public_key
|
||||
puts sshauth.password
|
||||
exit_with_code 0
|
||||
end
|
||||
|
||||
|
@ -86,7 +86,7 @@ class CloudAuth
|
||||
def client(username=nil)
|
||||
expiration_time = @lock.synchronize {
|
||||
time_now = Time.now.to_i
|
||||
|
||||
|
||||
if time_now > @token_expiration_time - EXPIRE_MARGIN
|
||||
@token_expiration_time = time_now + EXPIRE_DELTA
|
||||
end
|
||||
@ -95,8 +95,8 @@ class CloudAuth
|
||||
}
|
||||
|
||||
token = @server_auth.login_token(expiration_time,username)
|
||||
|
||||
Client.new(token,@conf[:one_xmlrpc])
|
||||
|
||||
OpenNebula::Client.new(token,@conf[:one_xmlrpc])
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -74,7 +74,7 @@ fi
|
||||
|
||||
# ------------ Create the image to the repository ------------
|
||||
|
||||
MKFS_CMD=`mkfs_command $DST $FSTYPE`
|
||||
MKFS_CMD=`mkfs_command $DST $FSTYPE $SIZE`
|
||||
|
||||
exec_and_log "$DD if=/dev/zero of=$DST bs=1 count=1 seek=${SIZE}M" \
|
||||
"Could not create image $DST"
|
||||
|
@ -313,6 +313,8 @@ void LifeCycleManager::deploy_failure_action(int vid)
|
||||
|
||||
vm->set_reason(History::ERROR);
|
||||
|
||||
vmpool->update_history(vm);
|
||||
|
||||
vm->set_previous_etime(the_time);
|
||||
|
||||
vm->set_previous_vm_info();
|
||||
|
@ -250,6 +250,10 @@ function mkfs_command {
|
||||
echo "$MKSWAP $DST"
|
||||
return 0
|
||||
;;
|
||||
"qcow2")
|
||||
echo "$QEMU_IMG create -f qcow2 $DST ${SIZE}M"
|
||||
return 0
|
||||
;;
|
||||
"vmdk_"*)
|
||||
VMWARE_DISK_TYPE=`echo $FSTYPE|cut -d'_' -f 2`
|
||||
echo "WHICH_SUDO=\$(which sudo) ; \
|
||||
|
@ -46,6 +46,8 @@ require 'OpenNebula/Datastore'
|
||||
require 'OpenNebula/DatastorePool'
|
||||
require 'OpenNebula/Cluster'
|
||||
require 'OpenNebula/ClusterPool'
|
||||
require 'OpenNebula/Document'
|
||||
require 'OpenNebula/DocumentPool'
|
||||
|
||||
module OpenNebula
|
||||
|
||||
|
@ -18,15 +18,15 @@ require 'OpenNebula/Pool'
|
||||
|
||||
module OpenNebula
|
||||
|
||||
# All subclasses must define the Document::TYPE constant.
|
||||
# All subclasses must define the DOCUMENT_TYPE constant.
|
||||
#
|
||||
# @example
|
||||
# require 'OpenNebula/Document'
|
||||
#
|
||||
# module OpenNebula
|
||||
# class CustomObject < Document
|
||||
#
|
||||
# Document::TYPE = 400
|
||||
#
|
||||
# DOCUMENT_TYPE = 400
|
||||
#
|
||||
# end
|
||||
# end
|
||||
@ -65,7 +65,7 @@ module OpenNebula
|
||||
#
|
||||
# @param [Nokogiri::XML::Node, REXML::Element] xml string
|
||||
# created by the build_xml() method
|
||||
# @param [OpenNebula::Client] client the xml-rpc client
|
||||
# @param [OpenNebula::Client] client the xml-rpc client
|
||||
#
|
||||
# @return [Document] the new object
|
||||
#
|
||||
@ -94,7 +94,7 @@ module OpenNebula
|
||||
# @return [nil, OpenNebula::Error] nil in case of success, Error
|
||||
# otherwise
|
||||
def allocate(description)
|
||||
super(DOCUMENT_METHODS[:allocate], description, TYPE)
|
||||
super(DOCUMENT_METHODS[:allocate], description, document_type)
|
||||
end
|
||||
|
||||
# Deletes the Document
|
||||
@ -187,6 +187,10 @@ module OpenNebula
|
||||
end
|
||||
end
|
||||
|
||||
def document_type
|
||||
self.class::DOCUMENT_TYPE
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_publish(published)
|
||||
|
@ -18,7 +18,7 @@ require 'OpenNebula/Pool'
|
||||
|
||||
module OpenNebula
|
||||
|
||||
# All subclasses must define the DocumentPool::TYPE constant
|
||||
# All subclasses must define the DOCUMENT_TYPE constant
|
||||
# and the factory method.
|
||||
#
|
||||
# @example
|
||||
@ -27,7 +27,7 @@ module OpenNebula
|
||||
# module OpenNebula
|
||||
# class CustomObjectPool < DocumentPool
|
||||
#
|
||||
# DocumentPool::TYPE = 400
|
||||
# DOCUMENT_TYPE = 400
|
||||
#
|
||||
# def factory(element_xml)
|
||||
# OpenNebula::CustomObject.new(element_xml, @client)
|
||||
@ -72,22 +72,26 @@ module OpenNebula
|
||||
def info(*args)
|
||||
case args.size
|
||||
when 0
|
||||
info_filter(DOCUMENT_POOL_METHODS[:info],@user_id,-1,-1, TYPE)
|
||||
info_filter(DOCUMENT_POOL_METHODS[:info],@user_id,-1,-1, document_type)
|
||||
when 3
|
||||
info_filter(DOCUMENT_POOL_METHODS[:info],args[0],args[1],args[2], TYPE)
|
||||
info_filter(DOCUMENT_POOL_METHODS[:info],args[0],args[1],args[2], document_type)
|
||||
end
|
||||
end
|
||||
|
||||
def info_all()
|
||||
return super(DOCUMENT_POOL_METHODS[:info], TYPE)
|
||||
return super(DOCUMENT_POOL_METHODS[:info], document_type)
|
||||
end
|
||||
|
||||
def info_mine()
|
||||
return super(DOCUMENT_POOL_METHODS[:info], TYPE)
|
||||
return super(DOCUMENT_POOL_METHODS[:info], document_type)
|
||||
end
|
||||
|
||||
def info_group()
|
||||
return super(DOCUMENT_POOL_METHODS[:info], TYPE)
|
||||
return super(DOCUMENT_POOL_METHODS[:info], document_type)
|
||||
end
|
||||
|
||||
def document_type
|
||||
self.class::DOCUMENT_TYPE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -26,7 +26,8 @@ module OpenNebula
|
||||
|
||||
VM_POOL_METHODS = {
|
||||
:info => "vmpool.info",
|
||||
:monitoring => "vmpool.monitoring"
|
||||
:monitoring => "vmpool.monitoring",
|
||||
:accounting => "vmpool.accounting"
|
||||
}
|
||||
|
||||
# Constants for info queries (include/RequestManagerPoolInfoFilter.h)
|
||||
@ -56,7 +57,7 @@ module OpenNebula
|
||||
#######################################################################
|
||||
|
||||
# Retrieves all or part of the VirtualMachines in the pool.
|
||||
# No arguments, returns the not-in-done VMs for the user
|
||||
# No arguments, returns the not-in-done VMs for the user
|
||||
# [user_id, start_id, end_id]
|
||||
# [user_id, start_id, end_id, state]
|
||||
def info(*args)
|
||||
@ -133,7 +134,7 @@ module OpenNebula
|
||||
# [["1337608271", "510"], ["1337608301", "510"], ["1337608331", "520"]],
|
||||
# "TEMPLATE/CUSTOM_PROBE"=>
|
||||
# []},
|
||||
#
|
||||
#
|
||||
# "0"=>
|
||||
# {"CPU"=>
|
||||
# [["1337608271", "0"], ["1337608301", "0"], ["1337608331", "0"]],
|
||||
@ -156,8 +157,160 @@ module OpenNebula
|
||||
return @client.call(VM_POOL_METHODS[:monitoring], filter_flag)
|
||||
end
|
||||
|
||||
# Retrieves the accounting data for all the VMs in the pool
|
||||
#
|
||||
# @param [Integer] filter_flag Optional filter flag to retrieve all or
|
||||
# part of the Pool. Possible values: INFO_ALL, INFO_GROUP, INFO_MINE
|
||||
# or user_id
|
||||
# @param [Hash] options
|
||||
# @option params [Integer] :start_time Start date and time to take into account,
|
||||
# if no start_time is required use -1
|
||||
# @option params [Integer] :end_time End date and time to take into account,
|
||||
# if no end_time is required use -1
|
||||
# @option params [Integer] :host Host id to filter the results
|
||||
# @option params [Integer] :group Group id to filter the results
|
||||
# @option params [String] :xpath Xpath expression to filter the results.
|
||||
# For example: HISTORY[ETIME>0]
|
||||
# @option params [String] :order_by_1 Xpath expression to group the
|
||||
# @option params [String] :order_by_2 Xpath expression to group the
|
||||
# returned hash. This will be the second level of the hash
|
||||
#
|
||||
# @return [Hash, OpenNebula::Error]
|
||||
# The first level hash uses the :order_by_1 values as keys, and
|
||||
# as value a Hash with the :order_by_2 values and the HISTORY_RECORDS
|
||||
#
|
||||
# @example
|
||||
# {"HISTORY_RECORDS"=>
|
||||
# {"HISTORY"=> [
|
||||
# {"OID"=>"0",
|
||||
# "SEQ"=>"0",
|
||||
# "HOSTNAME"=>"dummy",
|
||||
# ...
|
||||
# },
|
||||
# {"OID"=>"0",
|
||||
# "SEQ"=>"0",
|
||||
# "HOSTNAME"=>"dummy",
|
||||
#
|
||||
# @example :order_by_1 => VM/UID
|
||||
# {"0"=>
|
||||
# {"HISTORY_RECORDS"=>
|
||||
# {"HISTORY"=> [
|
||||
# {"OID"=>"0",
|
||||
# "SEQ"=>"0",
|
||||
# "HOSTNAME"=>"dummy",
|
||||
# ...
|
||||
# },
|
||||
# {"OID"=>"0",
|
||||
# "SEQ"=>"0",
|
||||
# "HOSTNAME"=>"dummy",
|
||||
#
|
||||
# @example :order_by_1 => VM/UID, :order_by_2 => VM/ID
|
||||
# {"0"=>
|
||||
# {"0"=>
|
||||
# {"HISTORY_RECORDS"=>
|
||||
# {"HISTORY"=> [
|
||||
# {"OID"=>"0",
|
||||
# "SEQ"=>"0",
|
||||
# "HOSTNAME"=>"dummy",
|
||||
# ...
|
||||
# },
|
||||
# {"OID"=>"0",
|
||||
# "SEQ"=>"0",
|
||||
# "HOSTNAME"=>"dummy",
|
||||
#
|
||||
def accounting(filter_flag=INFO_ALL, options={})
|
||||
acct_hash = Hash.new
|
||||
|
||||
rc = build_accounting(filter_flag, options) do |history|
|
||||
hash = acct_hash
|
||||
|
||||
if options[:order_by_1]
|
||||
id_1 = history[options[:order_by_1]]
|
||||
acct_hash[id_1] ||= Hash.new
|
||||
|
||||
if options[:order_by_2]
|
||||
id_2 = history[options[:order_by_2]]
|
||||
acct_hash[id_1][id_2] ||= Hash.new
|
||||
|
||||
hash = acct_hash[id_1][id_2]
|
||||
else
|
||||
hash = acct_hash[id_1]
|
||||
end
|
||||
end
|
||||
|
||||
hash["HISTORY_RECORDS"] ||= Hash.new
|
||||
hash["HISTORY_RECORDS"]["HISTORY"] ||= Array.new
|
||||
hash["HISTORY_RECORDS"]["HISTORY"] << history.to_hash['HISTORY']
|
||||
end
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
acct_hash
|
||||
end
|
||||
|
||||
# Retrieves the accounting data for all the VMs in the pool in xml
|
||||
#
|
||||
# @param [Integer] filter_flag Optional filter flag to retrieve all or
|
||||
# part of the Pool. Possible values: INFO_ALL, INFO_GROUP, INFO_MINE
|
||||
# or user_id
|
||||
# @param [Hash] options
|
||||
# @option params [Integer] :start_time Start date and time to take into account,
|
||||
# if no start_time is required use -1
|
||||
# @option params [Integer] :end_time End date and time to take into account,
|
||||
# if no end_time is required use -1
|
||||
# @option params [Integer] :host Host id to filter the results
|
||||
# @option params [Integer] :group Group id to filter the results
|
||||
# @option params [String] :xpath Xpath expression to filter the results.
|
||||
# For example: HISTORY[ETIME>0]
|
||||
#
|
||||
# @return [String] the xml representing the accounting data
|
||||
def accounting_xml(filter_flag=INFO_ALL, options={})
|
||||
acct_hash = Hash.new
|
||||
xml_str = "<HISTORY_RECORDS>\n"
|
||||
|
||||
rc = build_accounting(filter_flag, options) do |history|
|
||||
xml_str << history.to_xml
|
||||
end
|
||||
|
||||
return rc if OpenNebula.is_error?(rc)
|
||||
|
||||
xml_str << "\n</HISTORY_RECORDS>"
|
||||
xml_str
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_accounting(filter_flag=INFO_ALL, options, &block)
|
||||
xml_str = @client.call(VM_POOL_METHODS[:accounting],
|
||||
filter_flag,
|
||||
options[:start_time],
|
||||
options[:end_time])
|
||||
|
||||
return xml_str if OpenNebula.is_error?(xml_str)
|
||||
|
||||
xmldoc = XMLElement.new
|
||||
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
|
||||
|
||||
xpath_array = Array.new
|
||||
xpath_array << "HISTORY[HID=#{options[:host]}]" if options[:host]
|
||||
xpath_array << "HISTORY[VM/GID=#{options[:group]}]" if options[:group]
|
||||
xpath_array << options[:xpath] if options[:xpath]
|
||||
|
||||
if xpath_array.empty?
|
||||
xpath_str = "HISTORY"
|
||||
else
|
||||
xpath_str = xpath_array.join(' | ')
|
||||
end
|
||||
|
||||
acct_hash = Hash.new
|
||||
|
||||
xmldoc.each(xpath_str) do |history|
|
||||
block.call(history)
|
||||
end
|
||||
|
||||
acct_hash
|
||||
end
|
||||
|
||||
def info_filter(xml_method, who, start_id, end_id, state)
|
||||
return xmlrpc_info(xml_method, who, start_id, end_id, state)
|
||||
end
|
||||
|
@ -335,12 +335,33 @@ module OpenNebula
|
||||
return str
|
||||
end
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
def to_hash(hash={}, element=nil)
|
||||
element ||= @xml.document.root
|
||||
# @return [Hash] a hash representing the resource
|
||||
def to_hash
|
||||
hash = {}
|
||||
|
||||
if NOKOGIRI
|
||||
if @xml.instance_of?(Nokogiri::XML::NodeSet)
|
||||
@xml.each { |c|
|
||||
if c.element?
|
||||
build_hash(hash, c)
|
||||
end
|
||||
}
|
||||
else
|
||||
build_hash(hash, @xml)
|
||||
end
|
||||
else
|
||||
build_hash(hash, @xml)
|
||||
end
|
||||
|
||||
hash
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
def build_hash(hash, element)
|
||||
if NOKOGIRI
|
||||
array = element.children
|
||||
if array.length==1 and (array.first.text? or array.first.cdata?)
|
||||
@ -349,14 +370,14 @@ module OpenNebula
|
||||
r = {}
|
||||
array.each { |c|
|
||||
if c.element?
|
||||
to_hash(r, c)
|
||||
build_hash(r, c)
|
||||
end
|
||||
}
|
||||
end
|
||||
else
|
||||
r = {}
|
||||
if element.has_elements?
|
||||
element.each_element { |c| to_hash(r, c) }
|
||||
element.each_element { |c| build_hash(r, c) }
|
||||
elsif element.has_text?
|
||||
r = element.text
|
||||
end
|
||||
@ -376,8 +397,6 @@ module OpenNebula
|
||||
hash
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
|
@ -92,3 +92,24 @@
|
||||
# Marketplace endpoint
|
||||
#
|
||||
:marketplace_url: https://marketplace.c12g.com/appliance
|
||||
|
||||
################################################################################
|
||||
# Routes
|
||||
################################################################################
|
||||
|
||||
# Array of files containing ruby code to extend the default sunstone-server
|
||||
# routes. These files must be placed inside the custom_routes directory
|
||||
# in the sunstone root dir (/usr/lib/one/sunstone/routes)
|
||||
#
|
||||
# Example:
|
||||
# $ ls /usr/lib/one/sunstone/routes
|
||||
# custom.rb other.rb
|
||||
#
|
||||
# $ cat /usr/lib/one/sunstone/routes/example.rb
|
||||
# get '/custom' do
|
||||
# body "It works"
|
||||
# end
|
||||
#
|
||||
#:routes:
|
||||
# - custom
|
||||
# - other
|
||||
|
@ -237,6 +237,45 @@ class SunstoneServer < CloudServer
|
||||
return vnc.proxy(resource)
|
||||
end
|
||||
|
||||
# Retrieves the accounting data for all the VMs in the pool
|
||||
#
|
||||
# @param [Hash] options
|
||||
# @option params [Integer] :start_time Start date and time to take into account,
|
||||
# if no start_time is required use -1
|
||||
# @option params [Integer] :end_time End date and time to take into account,
|
||||
# if no end_time is required use -1
|
||||
# @option params [Integer] :host Host id to filter the results
|
||||
# @option params [Integer] :group Group id to filter the results
|
||||
# @option params [String] :xpath Xpath expression to filter the results.
|
||||
# For example: HISTORY[ETIME>0]
|
||||
# @option params [String] :order_by_1 Xpath expression to group the
|
||||
# returned hash. This will be the first level of the hash (i.e: VM/UID)
|
||||
# @option params [String] :order_by_2 Xpath expression to group the
|
||||
# returned hash. This will be the second level of the hash (i.e: VM/ID)
|
||||
#
|
||||
# @return [String] json representing the accounting data
|
||||
def accounting(options)
|
||||
opts = {
|
||||
:start_time => options[:start_time],
|
||||
:end_time => options[:end_time],
|
||||
:host => options[:host],
|
||||
:group => options[:group],
|
||||
:order_by_1 => options[:order_by_1],
|
||||
:order_by_2 => options[:order_by_2],
|
||||
:xpath => options[:xpath]
|
||||
}
|
||||
|
||||
pool = VirtualMachinePool.new(@client)
|
||||
acct_hash = pool.accounting(user_flag, opts)
|
||||
|
||||
if OpenNebula.is_error?(acct_hash)
|
||||
error = Error.new(acct_hash.message)
|
||||
return [500, error.to_json]
|
||||
end
|
||||
|
||||
return [201, acct_hash.to_json]
|
||||
end
|
||||
|
||||
########################################################################
|
||||
#
|
||||
########################################################################
|
||||
|
@ -205,6 +205,15 @@ after do
|
||||
end
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# Custom routes
|
||||
##############################################################################
|
||||
if settings.config[:routes]
|
||||
settings.config[:routes].each { |route|
|
||||
require "routes/#{route}"
|
||||
}
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# HTML Requests
|
||||
##############################################################################
|
||||
@ -299,6 +308,14 @@ get '/vm/:id/log' do
|
||||
@SunstoneServer.get_vm_log(params[:id])
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# Accounting
|
||||
##############################################################################
|
||||
|
||||
get '/acct' do
|
||||
@SunstoneServer.accounting(params)
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# Monitoring
|
||||
##############################################################################
|
||||
|
@ -417,27 +417,13 @@ bool Template::get(
|
||||
const string& name,
|
||||
int& value) const
|
||||
{
|
||||
string sval;
|
||||
float fvalue;
|
||||
bool rc;
|
||||
|
||||
get(name, sval);
|
||||
rc = get(name, fvalue);
|
||||
value = static_cast<int>(fvalue);
|
||||
|
||||
if ( sval == "" )
|
||||
{
|
||||
value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
istringstream iss(sval);
|
||||
|
||||
iss >> value;
|
||||
|
||||
if (iss.fail() || !iss.eof())
|
||||
{
|
||||
value = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
@ -46,20 +46,21 @@ DST_PATH=`arg_path $DST`
|
||||
DST_HOST=`arg_host $DST`
|
||||
DST_DIR=`dirname $DST_PATH`
|
||||
|
||||
if ! echo "$FSTYPE"|grep -q ^vmdk; then
|
||||
ssh_make_path $DST_HOST $DST_DIR
|
||||
else
|
||||
ssh_make_path $DST_HOST $DST_PATH
|
||||
fi
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Make the new image (file-based)
|
||||
#-------------------------------------------------------------------------------
|
||||
MKFS_CMD=`mkfs_command $DST_PATH $FSTYPE $SIZE`
|
||||
case "$FSTYPE" in
|
||||
"vmdk_"*)
|
||||
ssh_make_path $DST_HOST $DST_PATH
|
||||
CREATE_IMAGE=""
|
||||
;;
|
||||
*)
|
||||
ssh_make_path $DST_HOST $DST_DIR
|
||||
CREATE_IMAGE="$DD if=/dev/zero of=$DST_PATH bs=1 count=1 seek=${SIZE}M"
|
||||
;;
|
||||
esac
|
||||
|
||||
if ! echo "$FSTYPE"|grep -q ^vmdk; then
|
||||
CREATE_IMAGE="$DD if=/dev/zero of=$DST_PATH bs=1 count=1 seek=${SIZE}M"
|
||||
fi
|
||||
MKFS_CMD=`mkfs_command $DST_PATH $FSTYPE $SIZE`
|
||||
|
||||
MKSCRIPT=$(cat <<EOF
|
||||
export PATH=/usr/sbin:/sbin:\$PATH
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
SRC=$1
|
||||
DST=$2
|
||||
VM_ID=$3
|
||||
VM_ID=$(basename `dirname $DST`)
|
||||
DS_ID=$4
|
||||
|
||||
if [ -z "${ONE_LOCATION}" ]; then
|
||||
|
@ -43,8 +43,8 @@ DST_HOST=`arg_host $DST`
|
||||
DELETE_CMD=$(cat <<EOF
|
||||
DEV=\$(readlink $DST_PATH)
|
||||
LV=\$(basename \$DEV)
|
||||
VM=$(echo \$LV|cut -d- -f4)
|
||||
DISK_ID=$(echo \$LV|cut -d- -f5)
|
||||
VM=\$(echo \$LV|cut -d- -f4)
|
||||
DISK_ID=\$(echo \$LV|cut -d- -f5)
|
||||
|
||||
if [ -n "\$VM" -a -n "\$DISK_ID" ]; then
|
||||
$SUDO $LVREMOVE -f \$DEV
|
||||
|
Loading…
x
Reference in New Issue
Block a user