mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-21 14:50:08 +03:00
Merge branch 'feature-661'
Conflicts: install.sh src/cli/client_utilities.rb src/cli/onegroup src/cli/onehost src/cli/oneimage src/cli/onetemplate src/cli/oneuser src/cli/onevm src/cli/onevnet src/oca/ruby/OpenNebula/VirtualNetwork.rb src/onedb/1.rb
This commit is contained in:
commit
e9b2b5804e
114
install.sh
114
install.sh
@ -86,6 +86,8 @@ done
|
||||
# Definition of locations
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
CONF_LOCATION="$HOME/.one"
|
||||
|
||||
if [ -z "$ROOT" ] ; then
|
||||
BIN_LOCATION="/usr/bin"
|
||||
LIB_LOCATION="/usr/lib/one"
|
||||
@ -107,7 +109,8 @@ if [ -z "$ROOT" ] ; then
|
||||
|
||||
CHOWN_DIRS=""
|
||||
elif [ "$SUNSTONE" = "yes" ]; then
|
||||
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $VAR_LOCATION $SUNSTONE_LOCATION"
|
||||
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $VAR_LOCATION \
|
||||
$SUNSTONE_LOCATION $ETC_LOCATION"
|
||||
|
||||
DELETE_DIRS="$MAKE_DIRS"
|
||||
|
||||
@ -136,11 +139,12 @@ else
|
||||
MAN_LOCATION="$ROOT/share/man/man1"
|
||||
|
||||
if [ "$CLIENT" = "yes" ]; then
|
||||
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION"
|
||||
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $CONF_LOCATION"
|
||||
|
||||
DELETE_DIRS="$MAKE_DIRS"
|
||||
elif [ "$SUNSTONE" = "yes" ]; then
|
||||
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $VAR_LOCATION $SUNSTONE_LOCATION"
|
||||
MAKE_DIRS="$BIN_LOCATION $LIB_LOCATION $VAR_LOCATION \
|
||||
$SUNSTONE_LOCATION $ETC_LOCATION"
|
||||
|
||||
DELETE_DIRS="$MAKE_DIRS"
|
||||
else
|
||||
@ -172,7 +176,8 @@ ETC_DIRS="$ETC_LOCATION/im_kvm \
|
||||
$ETC_LOCATION/hm \
|
||||
$ETC_LOCATION/auth \
|
||||
$ETC_LOCATION/ec2query_templates \
|
||||
$ETC_LOCATION/occi_templates"
|
||||
$ETC_LOCATION/occi_templates \
|
||||
$ETC_LOCATION/cli"
|
||||
|
||||
LIB_DIRS="$LIB_LOCATION/ruby \
|
||||
$LIB_LOCATION/ruby/OpenNebula \
|
||||
@ -187,7 +192,9 @@ LIB_DIRS="$LIB_LOCATION/ruby \
|
||||
$LIB_LOCATION/tm_commands/dummy \
|
||||
$LIB_LOCATION/tm_commands/lvm \
|
||||
$LIB_LOCATION/mads \
|
||||
$LIB_LOCATION/sh"
|
||||
$LIB_LOCATION/sh \
|
||||
$LIB_LOCATION/ruby/cli \
|
||||
$LIB_LOCATION/ruby/cli/one_helper"
|
||||
|
||||
VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/im \
|
||||
@ -229,12 +236,14 @@ LIB_OCCI_CLIENT_DIRS="$LIB_LOCATION/ruby \
|
||||
LIB_OCA_CLIENT_DIRS="$LIB_LOCATION/ruby \
|
||||
$LIB_LOCATION/ruby/OpenNebula"
|
||||
|
||||
LIB_CLI_DIRS="$LIB_LOCATION/ruby \
|
||||
$LIB_LOCATION/ruby/OpenNebula"
|
||||
LIB_CLI_CLIENT_DIRS="$LIB_LOCATION/ruby/cli \
|
||||
$LIB_LOCATION/ruby/cli/one_helper"
|
||||
|
||||
CONF_CLI_DIRS="$CONF_LOCATION/cli"
|
||||
|
||||
if [ "$CLIENT" = "yes" ]; then
|
||||
MAKE_DIRS="$MAKE_DIRS $LIB_ECO_CLIENT_DIRS $LIB_OCCI_CLIENT_DIRS \
|
||||
$LIB_CLI_DIRS"
|
||||
$LIB_OCA_CLIENT_DIRS $LIB_CLI_CLIENT_DIRS $CONF_CLI_DIRS"
|
||||
elif [ "$SUNSTONE" = "yes" ]; then
|
||||
MAKE_DIRS="$MAKE_DIRS $SUNSTONE_DIRS $LIB_OCA_CLIENT_DIRS"
|
||||
else
|
||||
@ -256,7 +265,7 @@ INSTALL_FILES=(
|
||||
MAD_RUBY_LIB_FILES:$VAR_LOCATION/remotes
|
||||
MAD_SH_LIB_FILES:$LIB_LOCATION/sh
|
||||
MAD_SH_LIB_FILES:$VAR_LOCATION/remotes
|
||||
ONEDB_MIGRATOR_FILES:$LIB_LOCATION/onedb
|
||||
ONEDB_MIGRATOR_FILES:$LIB_LOCATION/ruby/onedb
|
||||
MADS_LIB_FILES:$LIB_LOCATION/mads
|
||||
IM_PROBES_FILES:$VAR_LOCATION/remotes/im
|
||||
IM_PROBES_KVM_FILES:$VAR_LOCATION/remotes/im/kvm.d
|
||||
@ -284,6 +293,8 @@ INSTALL_FILES=(
|
||||
OCCI_LIB_FILES:$LIB_LOCATION/ruby/cloud/occi
|
||||
OCCI_BIN_FILES:$BIN_LOCATION
|
||||
MAN_FILES:$MAN_LOCATION
|
||||
CLI_LIB_FILES:$LIB_LOCATION/ruby/cli
|
||||
ONE_CLI_LIB_FILES:$LIB_LOCATION/ruby/cli/one_helper
|
||||
)
|
||||
|
||||
INSTALL_CLIENT_FILES=(
|
||||
@ -294,18 +305,22 @@ INSTALL_CLIENT_FILES=(
|
||||
OCCI_LIB_CLIENT_FILES:$LIB_LOCATION/ruby/cloud/occi
|
||||
OCCI_BIN_CLIENT_FILES:$BIN_LOCATION
|
||||
CLI_BIN_FILES:$BIN_LOCATION
|
||||
CLI_LIB_FILES:$LIB_LOCATION/ruby
|
||||
CLI_LIB_FILES:$LIB_LOCATION/ruby/cli
|
||||
ONE_CLI_LIB_FILES:$LIB_LOCATION/ruby/cli/one_helper
|
||||
CLI_CONF_FILES:$CONF_LOCATION/cli
|
||||
OCA_LIB_FILES:$LIB_LOCATION/ruby
|
||||
RUBY_OPENNEBULA_LIB_FILES:$LIB_LOCATION/ruby/OpenNebula
|
||||
)
|
||||
|
||||
INSTALL_SUNSTONE_RUBY_FILES=(
|
||||
SUNSTONE_RUBY_LIB_FILES:$LIB_LOCATION/ruby
|
||||
RUBY_OPENNEBULA_LIB_FILES:$LIB_LOCATION/ruby/OpenNebula
|
||||
OCA_LIB_FILES:$LIB_LOCATION/ruby
|
||||
)
|
||||
|
||||
INSTALL_SUNSTONE_FILES=(
|
||||
SUNSTONE_FILES:$SUNSTONE_LOCATION
|
||||
SUNSTONE_BIN_FILES:$BIN_LOCATION
|
||||
SUNSTONE_ETC_FILES:$ETC_LOCATION
|
||||
SUNSTONE_MODELS_FILES:$SUNSTONE_LOCATION/models
|
||||
SUNSTONE_MODELS_JSON_FILES:$SUNSTONE_LOCATION/models/OpenNebulaJSON
|
||||
SUNSTONE_TEMPLATE_FILES:$SUNSTONE_LOCATION/templates
|
||||
@ -338,6 +353,7 @@ INSTALL_ETC_FILES=(
|
||||
OCCI_ETC_FILES:$ETC_LOCATION
|
||||
OCCI_ETC_TEMPLATE_FILES:$ETC_LOCATION/occi_templates
|
||||
SUNSTONE_ETC_FILES:$ETC_LOCATION
|
||||
CLI_CONF_FILES:$ETC_LOCATION/cli
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -351,9 +367,9 @@ BIN_FILES="src/nebula/oned \
|
||||
src/cli/onevnet \
|
||||
src/cli/oneuser \
|
||||
src/cli/oneimage \
|
||||
src/cli/onetemplate \
|
||||
src/cli/onegroup \
|
||||
src/cli/onedb \
|
||||
src/cli/onetemplate \
|
||||
src/onedb/onedb \
|
||||
share/scripts/one \
|
||||
src/authm_mad/oneauth"
|
||||
|
||||
@ -375,8 +391,6 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
|
||||
src/mad/ruby/OpenNebulaDriver.rb \
|
||||
src/mad/ruby/VirtualMachineDriver.rb \
|
||||
src/mad/ruby/Ganglia.rb \
|
||||
src/cli/client_utilities.rb \
|
||||
src/cli/command_parse.rb \
|
||||
src/oca/ruby/OpenNebula.rb \
|
||||
src/tm_mad/TMScript.rb \
|
||||
src/authm_mad/one_usage.rb \
|
||||
@ -385,24 +399,6 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
|
||||
src/authm_mad/simple_permissions.rb \
|
||||
src/authm_mad/ssh_auth.rb"
|
||||
|
||||
RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \
|
||||
src/oca/ruby/OpenNebula/HostPool.rb \
|
||||
src/oca/ruby/OpenNebula/Pool.rb \
|
||||
src/oca/ruby/OpenNebula/User.rb \
|
||||
src/oca/ruby/OpenNebula/UserPool.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualMachine.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualMachinePool.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualNetwork.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualNetworkPool.rb \
|
||||
src/oca/ruby/OpenNebula/Image.rb \
|
||||
src/oca/ruby/OpenNebula/ImagePool.rb \
|
||||
src/oca/ruby/OpenNebula/Template.rb \
|
||||
src/oca/ruby/OpenNebula/TemplatePool.rb \
|
||||
src/oca/ruby/OpenNebula/Group.rb \
|
||||
src/oca/ruby/OpenNebula/GroupPool.rb \
|
||||
src/oca/ruby/OpenNebula/XMLUtils.rb"
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# MAD Script library files, to be installed under $LIB_LOCATION/<script lang>
|
||||
# and remotes directory
|
||||
@ -539,7 +535,9 @@ IMAGE_DRIVER_FS_SCRIPTS="src/image_mad/remotes/fs/cp \
|
||||
#-------------------------------------------------------------------------------
|
||||
# Migration scripts for onedb command, to be installed under $LIB_LOCATION
|
||||
#-------------------------------------------------------------------------------
|
||||
ONEDB_MIGRATOR_FILES="src/onedb/1.rb"
|
||||
ONEDB_MIGRATOR_FILES="src/onedb/1.rb \
|
||||
src/onedb/onedb.rb \
|
||||
src/onedb/onedb_backend.rb"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Configuration files for OpenNebula, to be installed under $ETC_LOCATION
|
||||
@ -633,6 +631,28 @@ HOOK_SHARE_FILES="share/hooks/ebtables-xen \
|
||||
|
||||
INSTALL_NOVNC_SHARE_FILE="share/install_novnc.sh"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# OCA Files
|
||||
#-------------------------------------------------------------------------------
|
||||
OCA_LIB_FILES="src/oca/ruby/OpenNebula.rb"
|
||||
|
||||
RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \
|
||||
src/oca/ruby/OpenNebula/HostPool.rb \
|
||||
src/oca/ruby/OpenNebula/Pool.rb \
|
||||
src/oca/ruby/OpenNebula/User.rb \
|
||||
src/oca/ruby/OpenNebula/UserPool.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualMachine.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualMachinePool.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualNetwork.rb \
|
||||
src/oca/ruby/OpenNebula/VirtualNetworkPool.rb \
|
||||
src/oca/ruby/OpenNebula/Image.rb \
|
||||
src/oca/ruby/OpenNebula/ImagePool.rb \
|
||||
src/oca/ruby/OpenNebula/Template.rb \
|
||||
src/oca/ruby/OpenNebula/TemplatePool.rb \
|
||||
src/oca/ruby/OpenNebula/Group.rb \
|
||||
src/oca/ruby/OpenNebula/GroupPool.rb \
|
||||
src/oca/ruby/OpenNebula/XMLUtils.rb"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Common Cloud Files
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -716,10 +736,17 @@ OCCI_ETC_TEMPLATE_FILES="src/cloud/occi/etc/templates/common.erb \
|
||||
# CLI files
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
CLI_LIB_FILES="src/mad/ruby/CommandManager.rb \
|
||||
src/cli/client_utilities.rb \
|
||||
src/cli/command_parse.rb \
|
||||
src/oca/ruby/OpenNebula.rb"
|
||||
CLI_LIB_FILES="src/cli/cli_helper.rb \
|
||||
src/cli/command_parser.rb \
|
||||
src/cli/one_helper.rb"
|
||||
|
||||
ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \
|
||||
src/cli/one_helper/onehost_helper.rb \
|
||||
src/cli/one_helper/oneimage_helper.rb \
|
||||
src/cli/one_helper/onetemplate_helper.rb \
|
||||
src/cli/one_helper/oneuser_helper.rb \
|
||||
src/cli/one_helper/onevm_helper.rb \
|
||||
src/cli/one_helper/onevnet_helper.rb"
|
||||
|
||||
CLI_BIN_FILES="src/cli/onevm \
|
||||
src/cli/onehost \
|
||||
@ -729,6 +756,14 @@ CLI_BIN_FILES="src/cli/onevm \
|
||||
src/cli/onetemplate \
|
||||
src/cli/onegroup"
|
||||
|
||||
CLI_CONF_FILES="src/cli/etc/onegroup.yaml \
|
||||
src/cli/etc/onehost.yaml \
|
||||
src/cli/etc/oneimage.yaml \
|
||||
src/cli/etc/onetemplate.yaml \
|
||||
src/cli/etc/oneuser.yaml \
|
||||
src/cli/etc/onevm.yaml \
|
||||
src/cli/etc/onevnet.yaml"
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Sunstone files
|
||||
#-----------------------------------------------------------------------------
|
||||
@ -845,9 +880,6 @@ SUNSTONE_PUBLIC_IMAGES_FILES="src/sunstone/public/images/ajax-loader.gif \
|
||||
src/sunstone/public/images/vnc_off.png \
|
||||
src/sunstone/public/images/vnc_on.png"
|
||||
|
||||
SUNSTONE_RUBY_LIB_FILES="src/mad/ruby/CommandManager.rb \
|
||||
src/oca/ruby/OpenNebula.rb"
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# MAN files
|
||||
#-----------------------------------------------------------------------------
|
||||
|
@ -37,115 +37,76 @@ require 'rubygems'
|
||||
require 'sequel'
|
||||
require 'quota'
|
||||
require 'ssh_auth'
|
||||
require 'client_utilities'
|
||||
require 'command_parse'
|
||||
require 'yaml'
|
||||
|
||||
require 'cli/command_parser'
|
||||
require 'cli/one_helper'
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
Usage:
|
||||
oneauth <command> [<parameters>]
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
usage "oneauth COMMAND [args..]"
|
||||
|
||||
description "This command contains a set of utilities to " <<
|
||||
"manage authorization module."
|
||||
|
||||
Description:
|
||||
set :option, CommandParser::OPTIONS
|
||||
|
||||
This command contains a set of utilities to manage authorization module.
|
||||
set :format, :userid, OpenNebulaHelper.name_to_id_desc("USER") do |arg|
|
||||
OpenNebulaHelper.name_to_id(arg, "USER")
|
||||
end
|
||||
|
||||
# Helpers
|
||||
def get_database
|
||||
config_data=File.read(ETC_LOCATION+'/auth/auth.conf')
|
||||
config=YAML::load(config_data)
|
||||
|
||||
Commands:
|
||||
database_url=config[:database]
|
||||
db=Sequel.connect(database_url)
|
||||
end
|
||||
|
||||
* quota set (sets quota for a user)
|
||||
oneauth quota set <id> <cpu> <memory> <num_vms>
|
||||
|
||||
* login (generates authentication proxy)
|
||||
oneauth login <username> [<expire time in seconds>]
|
||||
|
||||
* key (gets public key)
|
||||
oneauth key
|
||||
|
||||
* help (prints help)
|
||||
oneauth help
|
||||
def add_quota(uid, cpu, memory, num_vms=nil)
|
||||
db=get_database
|
||||
quota=Quota.new(db, OpenNebula::Client.new)
|
||||
quota.set(uid.to_i, cpu.to_f, memory.to_i, num_vms)
|
||||
end
|
||||
|
||||
EOT
|
||||
# Commands
|
||||
quotaset_desc = <<-EOT.unindent
|
||||
Sets CPU, MEMORY and NUM_VMs quota for a given user
|
||||
EOT
|
||||
|
||||
def print_help
|
||||
puts COMMANDS_HELP
|
||||
end
|
||||
|
||||
def get_database
|
||||
config_data=File.read(ETC_LOCATION+'/auth/auth.conf')
|
||||
config=YAML::load(config_data)
|
||||
|
||||
database_url=config[:database]
|
||||
db=Sequel.connect(database_url)
|
||||
end
|
||||
|
||||
def add_quota(uid, cpu, memory, num_vms=nil)
|
||||
db=get_database
|
||||
quota=Quota.new(db, OpenNebula::Client.new)
|
||||
quota.set(uid.to_i, cpu.to_f, memory.to_i, num_vms)
|
||||
end
|
||||
|
||||
|
||||
result=[false, "Unknown error"]
|
||||
|
||||
command=ARGV.shift
|
||||
|
||||
case command
|
||||
when "quota"
|
||||
check_parameters("quota", 1)
|
||||
|
||||
case ARGV[0].downcase
|
||||
when 'set'
|
||||
check_parameters("quota set", 3)
|
||||
command 'quota-set', quotaset_desc , :userid, :cpu, :memory, :num_vms do
|
||||
Dir.chdir VAR_LOCATION
|
||||
|
||||
begin
|
||||
add_quota(*ARGV[1..4])
|
||||
add_quota(*args[1..4])
|
||||
rescue Exception => e
|
||||
puts "Error starting server: #{e}"
|
||||
exit(-1)
|
||||
exit_with_code -1, "Error starting server: #{e}"
|
||||
end
|
||||
else
|
||||
#default
|
||||
exit_with_code 0
|
||||
end
|
||||
|
||||
exit 0
|
||||
|
||||
when "login"
|
||||
check_parameters("login", 1)
|
||||
|
||||
user=ARGV[0]
|
||||
time=ARGV[1]
|
||||
|
||||
if time
|
||||
time=time.to_i
|
||||
else
|
||||
time=3600
|
||||
end
|
||||
|
||||
ssh=SshAuth.new
|
||||
ssh.login(user, time)
|
||||
|
||||
when "key"
|
||||
ssh=SshAuth.new
|
||||
puts ssh.extract_public_key
|
||||
|
||||
exit 0
|
||||
|
||||
when "help"
|
||||
print_help
|
||||
exit 0
|
||||
|
||||
when "--version"
|
||||
puts CommandParse::ONE_VERSION
|
||||
|
||||
else
|
||||
print_help
|
||||
exit -1
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(result)
|
||||
puts "Error: " + result.message
|
||||
exit -1
|
||||
end
|
||||
login_desc = <<-EOT.unindent
|
||||
Generates authentication proxy. The last argument specifies
|
||||
the expiration time in seconds
|
||||
EOT
|
||||
|
||||
command 'login', login_desc, :userid, :text do
|
||||
user=args[0]
|
||||
time=args[1]
|
||||
pp args
|
||||
if time
|
||||
time=time.to_i
|
||||
else
|
||||
time=3600
|
||||
end
|
||||
|
||||
ssh=SshAuth.new
|
||||
ssh.login(user, time)
|
||||
exit_with_code 0
|
||||
end
|
||||
|
||||
command 'key', 'Gets public key' do
|
||||
ssh=SshAuth.new
|
||||
puts ssh.extract_public_key
|
||||
exit_with_code 0
|
||||
end
|
||||
end
|
232
src/cli/cli_helper.rb
Normal file
232
src/cli/cli_helper.rb
Normal file
@ -0,0 +1,232 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
module CLIHelper
|
||||
LIST = {
|
||||
:name => "list",
|
||||
:short => "-l x,y,z",
|
||||
:large => "--list x,y,z",
|
||||
:format => Array,
|
||||
:description => "Selects columns to display with list command"
|
||||
}
|
||||
|
||||
#ORDER = {
|
||||
# :name => "order",
|
||||
# :short => "-o x,y,z",
|
||||
# :large => "--order x,y,z",
|
||||
# :format => Array,
|
||||
# :description => "Order by these columns, column starting with - means decreasing order"
|
||||
#}
|
||||
#
|
||||
#FILTER = {
|
||||
# :name => "filter",
|
||||
# :short => "-f x,y,z",
|
||||
# :large => "--filter x,y,z",
|
||||
# :format => Array,
|
||||
# :description => "Filter data. An array is specified with column=value pairs."
|
||||
#}
|
||||
#
|
||||
#HEADER = {
|
||||
# :name => "header",
|
||||
# :short => "-H",
|
||||
# :large => "--header",
|
||||
# :description => "Shows the header of the table"
|
||||
#}
|
||||
|
||||
DELAY = {
|
||||
:name => "delay",
|
||||
:short => "-d x",
|
||||
:large => "--delay x",
|
||||
:format => Integer,
|
||||
:description => "Sets the delay in seconds for top command"
|
||||
}
|
||||
|
||||
#OPTIONS = [LIST, ORDER, FILTER, HEADER, DELAY]
|
||||
OPTIONS = [LIST, DELAY]
|
||||
|
||||
# Sets bold font
|
||||
def CLIHelper.scr_bold
|
||||
print "\33[1m"
|
||||
end
|
||||
|
||||
# Sets underline
|
||||
def CLIHelper.scr_underline
|
||||
print "\33[4m"
|
||||
end
|
||||
|
||||
# Restore normal font
|
||||
def CLIHelper.scr_restore
|
||||
print "\33[0m"
|
||||
end
|
||||
|
||||
# Clears screen
|
||||
def CLIHelper.scr_cls
|
||||
print "\33[2J\33[H"
|
||||
end
|
||||
|
||||
# Moves the cursor
|
||||
def CLIHelper.scr_move(x,y)
|
||||
print "\33[#{x};#{y}H"
|
||||
end
|
||||
|
||||
# Print header
|
||||
def CLIHelper.print_header(str, underline=true)
|
||||
scr_bold
|
||||
scr_underline if underline
|
||||
print str
|
||||
scr_restore
|
||||
puts
|
||||
end
|
||||
|
||||
class ShowTable
|
||||
require 'yaml'
|
||||
|
||||
def initialize(conf=nil, ext=nil, &block)
|
||||
# merge del conf con la table
|
||||
@columns = Hash.new
|
||||
@default_columns = Array.new
|
||||
|
||||
@ext = ext
|
||||
@conf = conf
|
||||
|
||||
instance_eval(&block)
|
||||
end
|
||||
|
||||
def helper
|
||||
@ext
|
||||
end
|
||||
|
||||
def column(name, desc, *conf, &block)
|
||||
column = Hash.new
|
||||
column[:desc] = desc
|
||||
column[:size] = 5
|
||||
conf.each{|c|
|
||||
if c.instance_of?(Symbol)
|
||||
column[c]=true
|
||||
elsif c.instance_of?(Hash)
|
||||
c.each{|key,value|
|
||||
column[key]=value
|
||||
}
|
||||
end
|
||||
}
|
||||
column[:proc] = block
|
||||
@columns[name.to_sym] = column
|
||||
@default_columns<<name
|
||||
end
|
||||
|
||||
def default(*args)
|
||||
@default_columns=args
|
||||
end
|
||||
|
||||
def show(data, options={})
|
||||
update_columns(options)
|
||||
print_table(data, options)
|
||||
end
|
||||
|
||||
def top(data, options={})
|
||||
update_columns(options)
|
||||
delay=options[:delay] ? options[:delay] : 1
|
||||
|
||||
begin
|
||||
while true
|
||||
CLIHelper.scr_cls
|
||||
CLIHelper.scr_move(0,0)
|
||||
show(data, options)
|
||||
sleep delay
|
||||
end
|
||||
rescue Exception => e
|
||||
puts e.message
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def print_table(data, options)
|
||||
CLIHelper.print_header(header_str)
|
||||
print_data(data, options)
|
||||
end
|
||||
|
||||
def print_data(data, options)
|
||||
ncolumns=@default_columns.length
|
||||
res_data=data_array(data, options)
|
||||
print res_data.collect{|l|
|
||||
(0..ncolumns-1).collect{ |i|
|
||||
dat=l[i]
|
||||
col=@default_columns[i]
|
||||
format_str(col, dat)
|
||||
}.join(' ')
|
||||
}.join("\n")
|
||||
puts
|
||||
end
|
||||
|
||||
def data_array(data, options)
|
||||
res_data=data.collect {|d|
|
||||
@default_columns.collect {|c|
|
||||
@columns[c][:proc].call(d).to_s if @columns[c]
|
||||
}
|
||||
}
|
||||
|
||||
if options
|
||||
filter_data!(res_data, options[:filter]) if options[:filter]
|
||||
sort_data!(res_data, options[:order]) if options[:order]
|
||||
end
|
||||
|
||||
res_data
|
||||
end
|
||||
|
||||
def format_str(field, data)
|
||||
if @columns[field]
|
||||
minus=( @columns[field][:left] ? "-" : "" )
|
||||
size=@columns[field][:size]
|
||||
return "%#{minus}#{size}.#{size}s" % [ data.to_s ]
|
||||
else
|
||||
puts "Column not defined"
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
def update_columns(options)
|
||||
begin
|
||||
config = YAML.load_file(@conf)
|
||||
|
||||
default = config.delete(:default)
|
||||
@default_columns = default unless default.empty?
|
||||
|
||||
@columns.merge!(config) { |key, oldval, newval|
|
||||
oldval.merge(newval)
|
||||
}
|
||||
rescue Exception => e
|
||||
end
|
||||
|
||||
@default_columns = options[:list].collect{|o| o.to_sym} if options[:list]
|
||||
end
|
||||
|
||||
def header_str
|
||||
@default_columns.collect {|c|
|
||||
if @columns[c]
|
||||
format_str(c, c.to_s)
|
||||
else
|
||||
puts "Column not defined"
|
||||
exit -1
|
||||
end
|
||||
}.compact.join(' ')
|
||||
end
|
||||
|
||||
# TBD def filter_data!
|
||||
|
||||
# TBD def sort_data!
|
||||
end
|
||||
end
|
@ -1,381 +0,0 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 'OpenNebula'
|
||||
|
||||
#####################
|
||||
# CONSOLE UTILITIES #
|
||||
#####################
|
||||
|
||||
BinarySufix = ["K", "M", "G", "T" ]
|
||||
|
||||
def humanize_size(value)
|
||||
i=0
|
||||
|
||||
while value > 1024 && i < 3 do
|
||||
value /= 1024.0
|
||||
i+=1
|
||||
end
|
||||
|
||||
value = (value * 10).round / 10.0
|
||||
|
||||
value = value.to_i if value - value.round == 0
|
||||
st = value.to_s + BinarySufix[i]
|
||||
|
||||
return st
|
||||
end
|
||||
|
||||
# Sets bold font
|
||||
def scr_bold
|
||||
print "\33[1m"
|
||||
end
|
||||
|
||||
# Sets underline
|
||||
def scr_underline
|
||||
print "\33[4m"
|
||||
end
|
||||
|
||||
# Restore normal font
|
||||
def scr_restore
|
||||
print "\33[0m"
|
||||
end
|
||||
|
||||
# Clears screen
|
||||
def scr_cls
|
||||
print "\33[2J\33[H"
|
||||
end
|
||||
|
||||
# Moves the cursor
|
||||
def scr_move(x,y)
|
||||
print "\33[#{x};#{y}H"
|
||||
end
|
||||
|
||||
# Print header
|
||||
def print_header(format_str, str, underline)
|
||||
scr_bold
|
||||
scr_underline if underline
|
||||
print format_str % str
|
||||
scr_restore
|
||||
puts
|
||||
end
|
||||
|
||||
##################################
|
||||
# Class show configurable tables #
|
||||
##################################
|
||||
|
||||
ShowTableExample={
|
||||
:id => {
|
||||
:name => "ID",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e| d["OID"] }
|
||||
},
|
||||
:name => {
|
||||
:name => "NAME",
|
||||
:size => 8,
|
||||
:proc => lambda {|d,e| d["DEPLOY_ID"] }
|
||||
},
|
||||
:stat => {
|
||||
:name => "STAT",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e| e[:vm].get_state(d) }
|
||||
},
|
||||
:default => [:id, :name, :stat]
|
||||
}
|
||||
|
||||
# Class to print tables
|
||||
class ShowTable
|
||||
attr_accessor :ext, :columns
|
||||
|
||||
# table => definition of the table to print
|
||||
# ext => external variables (Hash), @ext
|
||||
def initialize(table, ext=nil)
|
||||
@table=table
|
||||
@ext=Hash.new
|
||||
@ext=ext if ext.kind_of?(Hash)
|
||||
@columns=@table[:default]
|
||||
end
|
||||
|
||||
# Returns a formated string for header
|
||||
def header_str
|
||||
@columns.collect {|c|
|
||||
if @table[c]
|
||||
#{}"%#{@table[c][:size]}s" % [@table[c][:name]]
|
||||
format_data(c, @table[c][:name])
|
||||
else
|
||||
nil
|
||||
end
|
||||
}.compact.join(' ')
|
||||
end
|
||||
|
||||
# Returns an array with header titles
|
||||
def header_array
|
||||
@columns.collect {|c|
|
||||
if @table[c]
|
||||
@table[c][:name].to_s
|
||||
else
|
||||
""
|
||||
end
|
||||
}.compact
|
||||
end
|
||||
|
||||
def data_str(data, options=nil)
|
||||
# TODO: Use data_array so it can be ordered and/or filtered
|
||||
res_data=data_array(data, options)
|
||||
|
||||
res_data.collect {|d|
|
||||
(0..(@columns.length-1)).collect {|c|
|
||||
dat=d[c]
|
||||
col=@columns[c]
|
||||
|
||||
dat = humanize_size( Float(dat) ) if( @table[col][:kbytes] )
|
||||
|
||||
format_data(col, dat) if @table[col]
|
||||
}.join(' ')
|
||||
}.join("\n")
|
||||
|
||||
#data.collect {|d|
|
||||
# @columns.collect {|c|
|
||||
# format_data(c, @table[c][:proc].call(d, @ext)) if @table[c]
|
||||
# }.join(' ')
|
||||
#}.join("\n")
|
||||
end
|
||||
|
||||
def data_array(data, options=nil)
|
||||
res_data=data.collect {|d|
|
||||
@columns.collect {|c|
|
||||
@table[c][:proc].call(d, @ext).to_s if @table[c]
|
||||
}
|
||||
}
|
||||
|
||||
if options
|
||||
filter_data!(res_data, options[:filter]) if options[:filter]
|
||||
sort_data!(res_data, options[:order]) if options[:order]
|
||||
end
|
||||
|
||||
res_data
|
||||
end
|
||||
|
||||
def format_data(field, data)
|
||||
minus=( @table[field][:left] ? "-" : "" )
|
||||
size=@table[field][:size]
|
||||
"%#{minus}#{size}.#{size}s" % [ data.to_s ]
|
||||
end
|
||||
|
||||
def get_order_column(column)
|
||||
desc=column.match(/^-/)
|
||||
col_name=column.gsub(/^-/, '')
|
||||
index=@columns.index(col_name.to_sym)
|
||||
[index, desc]
|
||||
end
|
||||
|
||||
def sort_data!(data, order)
|
||||
data.sort! {|a,b|
|
||||
# rows are equal by default
|
||||
res=0
|
||||
order.each {|o|
|
||||
# compare
|
||||
pos, dec=get_order_column(o)
|
||||
break if !pos
|
||||
|
||||
r = (b[pos]<=>a[pos])
|
||||
|
||||
# if diferent set res (return value) and exit loop
|
||||
if r!=0
|
||||
# change sign if the order is decreasing
|
||||
r=-r if dec
|
||||
res=r
|
||||
break
|
||||
end
|
||||
}
|
||||
res
|
||||
}
|
||||
end
|
||||
|
||||
def filter_data!(data, filters)
|
||||
filters.each {|key, value|
|
||||
pos=@columns.index(key.downcase.to_sym)
|
||||
if pos
|
||||
data.reject! {|d|
|
||||
if !d[pos]
|
||||
true
|
||||
else
|
||||
!d[pos].downcase.match(value.downcase)
|
||||
end
|
||||
}
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def print_help
|
||||
text=[]
|
||||
@table.each {|option, data|
|
||||
next if option==:default
|
||||
text << "%9s (%2d) => %s" % [option, data[:size], data[:desc]]
|
||||
}
|
||||
text.join("\n")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
################
|
||||
# Miscelaneous #
|
||||
################
|
||||
|
||||
def get_one_client(session=nil)
|
||||
OpenNebula::Client.new(session)
|
||||
end
|
||||
|
||||
def is_error?(result)
|
||||
OpenNebula.is_error?(result)
|
||||
end
|
||||
|
||||
def is_successful?(result)
|
||||
!OpenNebula.is_error?(result)
|
||||
end
|
||||
|
||||
def check_parameters(name, number)
|
||||
if ARGV.length < number
|
||||
print "Command #{name} requires "
|
||||
if number>1
|
||||
puts "#{number} parameters to run."
|
||||
else
|
||||
puts "one parameter to run"
|
||||
end
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def get_entity_id(name, pool_class)
|
||||
return name if name.match(/^[0123456789]+$/)
|
||||
|
||||
# TODO: get vm's from the actual user
|
||||
pool=pool_class.new(get_one_client)
|
||||
result=pool.info
|
||||
|
||||
class_name=pool_class.name.split('::').last.gsub(/Pool$/, '')
|
||||
|
||||
if( OpenNebula.is_error?(result) )
|
||||
puts "Error: #{class_name} Pool info could not be retrieved. " +
|
||||
result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
objects=pool.select {|object| object.name==name }
|
||||
|
||||
if objects.length>0
|
||||
if objects.length>1
|
||||
puts "There are multiple #{class_name}s with name #{name}."
|
||||
exit -1
|
||||
else
|
||||
result=objects.first.id
|
||||
end
|
||||
else
|
||||
puts "#{class_name} named #{name} not found."
|
||||
exit -1
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def get_vm_id(name)
|
||||
get_entity_id(name, OpenNebula::VirtualMachinePool)
|
||||
end
|
||||
|
||||
def get_host_id(name)
|
||||
get_entity_id(name, OpenNebula::HostPool)
|
||||
end
|
||||
|
||||
def get_vn_id(name)
|
||||
get_entity_id(name, OpenNebula::VirtualNetworkPool)
|
||||
end
|
||||
|
||||
def get_user_id(name)
|
||||
get_entity_id(name, OpenNebula::UserPool)
|
||||
end
|
||||
|
||||
def get_image_id(name)
|
||||
get_entity_id(name, OpenNebula::ImagePool)
|
||||
end
|
||||
|
||||
def get_template_id(name)
|
||||
get_entity_id(name, OpenNebula::TemplatePool)
|
||||
end
|
||||
|
||||
def get_group_id(name)
|
||||
get_entity_id(name, OpenNebula::GroupPool)
|
||||
end
|
||||
|
||||
def str_running_time(data)
|
||||
stime=Time.at(data["STIME"].to_i)
|
||||
if data["ETIME"]=="0"
|
||||
etime=Time.now
|
||||
else
|
||||
etime=Time.at(data["ETIME"].to_i)
|
||||
end
|
||||
dtime=Time.at(etime-stime).getgm
|
||||
|
||||
"%02d %02d:%02d:%02d" % [dtime.yday-1, dtime.hour, dtime.min, dtime.sec]
|
||||
end
|
||||
|
||||
def str_register_time(data)
|
||||
regtime=Time.at(data["REGTIME"].to_i).getgm
|
||||
regtime.strftime("%b %d, %Y %H:%M")
|
||||
end
|
||||
|
||||
|
||||
REG_RANGE=/(.*)\[(\d+)([+-])(\d+)\](.*)/
|
||||
|
||||
def expand_range(param)
|
||||
if match=param.match(REG_RANGE)
|
||||
pre=match[1]
|
||||
start=match[2]
|
||||
operator=match[3]
|
||||
last=match[4]
|
||||
post=match[5]
|
||||
size=0
|
||||
|
||||
result=Array.new
|
||||
|
||||
if operator=='-'
|
||||
range=(start.to_i..last.to_i)
|
||||
size=last.size
|
||||
elsif operator=='+'
|
||||
size=(start.to_i+last.to_i-1).to_s.size
|
||||
range=(start.to_i..(start.to_i+last.to_i-1))
|
||||
end
|
||||
|
||||
if start[0]==?0
|
||||
range.each do |num|
|
||||
result<<sprintf("%s%0#{size}d%s", pre, num, post)
|
||||
end
|
||||
else
|
||||
range.each do |num|
|
||||
result<<sprintf("%s%d%s", pre, num, post)
|
||||
end
|
||||
end
|
||||
|
||||
result
|
||||
else
|
||||
param
|
||||
end
|
||||
end
|
||||
|
||||
def expand_args(args)
|
||||
args.collect {|arg| expand_range(arg) }.flatten
|
||||
end
|
@ -1,170 +0,0 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 'optparse'
|
||||
|
||||
class CommandParse
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
Commands:
|
||||
|
||||
EOT
|
||||
|
||||
USAGE_BANNER=<<-EOT
|
||||
Usage:
|
||||
onevm [<options>] <command> [<parameters>]
|
||||
|
||||
Options:
|
||||
EOT
|
||||
|
||||
ONE_VERSION=<<-EOT
|
||||
OpenNebula 2.3.0
|
||||
Copyright 2002-2011, 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
|
||||
EOT
|
||||
|
||||
def initialize(standard_options=nil)
|
||||
@options=Hash.new
|
||||
if standard_options
|
||||
@standard_options=standard_options
|
||||
else
|
||||
@standard_options=[:list, :top, :xml]
|
||||
end
|
||||
|
||||
@cmdparse=OptionParser.new do |opts|
|
||||
opts.banner=text_banner
|
||||
|
||||
execute_standard_options(opts, @options)
|
||||
special_options(opts, @options)
|
||||
|
||||
opts.on("-v", "--verbose",
|
||||
"Tells more information if the command",
|
||||
"is successful") do |o|
|
||||
@options[:verbose]=true
|
||||
end
|
||||
|
||||
opts.on_tail("-h", "--help", "Shows this help message") do |o|
|
||||
print_help
|
||||
exit
|
||||
end
|
||||
|
||||
opts.on_tail("--version",
|
||||
"Shows version and copyright information") do |o|
|
||||
puts text_version
|
||||
exit
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def parse(args)
|
||||
begin
|
||||
@cmdparse.parse!(args)
|
||||
rescue => e
|
||||
puts e.message
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
def opts_list(opts, options)
|
||||
opts.on("-l x,y,z", "--list x,y,z", Array,
|
||||
"Selects columns to display with list", "command") do |o|
|
||||
options[:list]=o.collect {|c| c.to_sym }
|
||||
end
|
||||
|
||||
opts.on("--list-columns", "Information about the columns available",
|
||||
"to display, order or filter") do |o|
|
||||
puts list_options
|
||||
exit
|
||||
end
|
||||
|
||||
opts.on("-o x,y,z", "--order x,y,z", Array,
|
||||
"Order by these columns, column starting",
|
||||
"with - means decreasing order") do |o|
|
||||
options[:order]=o
|
||||
end
|
||||
|
||||
opts.on("-f x,y,z", "--filter x,y,z", Array,
|
||||
"Filter data. An array is specified", "with column=value pairs.") do |o|
|
||||
options[:filter]=Hash.new
|
||||
o.each {|i|
|
||||
k,v=i.split('=')
|
||||
options[:filter][k]=v
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def opts_top(opts, options)
|
||||
opts.on("-d seconds", "--delay seconds", Integer,
|
||||
"Sets the delay in seconds for top", "command") do |o|
|
||||
options[:delay]=o
|
||||
end
|
||||
end
|
||||
|
||||
def opts_xml(opts, options)
|
||||
opts.on("-x", "--xml",
|
||||
"Returns xml instead of human readable text") do |o|
|
||||
options[:xml]=true
|
||||
end
|
||||
end
|
||||
|
||||
def set_standard_options(options)
|
||||
@standard_options=options
|
||||
end
|
||||
|
||||
def execute_standard_options(opts, options)
|
||||
@standard_options.each do |op|
|
||||
sym="opts_#{op}".to_sym
|
||||
self.send(sym, opts, options) if self.respond_to?(sym)
|
||||
end
|
||||
end
|
||||
|
||||
def special_options(opts, options)
|
||||
end
|
||||
|
||||
def options
|
||||
@options
|
||||
end
|
||||
|
||||
def print_help
|
||||
puts @cmdparse
|
||||
puts
|
||||
puts text_commands
|
||||
end
|
||||
|
||||
def text_commands
|
||||
COMMANDS_HELP
|
||||
end
|
||||
|
||||
def text_command_name
|
||||
"onevm"
|
||||
end
|
||||
|
||||
def text_banner
|
||||
USAGE_BANNER.gsub("onevm", text_command_name)
|
||||
end
|
||||
|
||||
def text_version
|
||||
ONE_VERSION
|
||||
end
|
||||
|
||||
def list_options
|
||||
"<list options>\n\n"
|
||||
end
|
||||
end
|
||||
|
399
src/cli/command_parser.rb
Executable file
399
src/cli/command_parser.rb
Executable file
@ -0,0 +1,399 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 'optparse'
|
||||
require 'pp'
|
||||
|
||||
class String
|
||||
def unindent(spaces=nil)
|
||||
unless spaces
|
||||
m = self.match(/^(\s*)/)
|
||||
spaces = m[1].size
|
||||
end
|
||||
|
||||
self.gsub!(/^ {#{spaces}}/, '')
|
||||
end
|
||||
end
|
||||
|
||||
module CommandParser
|
||||
OPTIONS = [
|
||||
VERBOSE={
|
||||
:name => "verbose",
|
||||
:short => "-v",
|
||||
:large => "--verbose",
|
||||
:description => "Verbose mode"
|
||||
},
|
||||
HELP={
|
||||
:name => "help",
|
||||
:short => "-h",
|
||||
:large => "--help",
|
||||
:description => "Show this message"
|
||||
},
|
||||
VERSION={
|
||||
:name => "version",
|
||||
:short => "-V",
|
||||
:large => "--version",
|
||||
:description => "Show version and copyright information",
|
||||
}
|
||||
]
|
||||
|
||||
class CmdParser
|
||||
attr_reader :options, :args
|
||||
|
||||
def initialize(args=[], &block)
|
||||
@opts = Array.new
|
||||
@commands = Hash.new
|
||||
@formats = Hash.new
|
||||
@script = nil
|
||||
|
||||
@args = args
|
||||
@options = Hash.new
|
||||
|
||||
set :format, :file, "" do |arg| format_file(arg) ; end
|
||||
set :format, :range, "" do |arg| format_range(arg) ; end
|
||||
set :format, :text, "" do |arg| format_text(arg) ; end
|
||||
|
||||
instance_eval(&block)
|
||||
|
||||
self.run
|
||||
end
|
||||
|
||||
def usage(str)
|
||||
@usage = "Usage: #{str}"
|
||||
end
|
||||
|
||||
def version(str)
|
||||
@version = str
|
||||
end
|
||||
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
def exit_with_code(code, output=nil)
|
||||
puts output if output
|
||||
exit code
|
||||
end
|
||||
|
||||
def command(name, desc, *args_format, &block)
|
||||
cmd = Hash.new
|
||||
cmd[:desc] = desc
|
||||
cmd[:arity] = 0
|
||||
cmd[:options] = []
|
||||
cmd[:args_format] = Array.new
|
||||
args_format.each {|args|
|
||||
if args.instance_of?(Array)
|
||||
cmd[:arity]+=1 unless args.include?(nil)
|
||||
cmd[:args_format] << args
|
||||
elsif args.instance_of?(Hash) && args[:options]
|
||||
cmd[:options] << args[:options]
|
||||
else
|
||||
cmd[:arity]+=1
|
||||
cmd[:args_format] << [args]
|
||||
end
|
||||
}
|
||||
cmd[:proc] = block
|
||||
@commands[name.to_sym] = cmd
|
||||
end
|
||||
|
||||
def script(*args_format, &block)
|
||||
@script=Hash.new
|
||||
@script[:args_format] = Array.new
|
||||
args_format.collect {|args|
|
||||
if args.instance_of?(Array)
|
||||
@script[:arity]+=1 unless args.include?(nil)
|
||||
@script[:args_format] << args
|
||||
elsif args.instance_of?(Hash) && args[:options]
|
||||
@opts << args[:options]
|
||||
else
|
||||
@script[:arity]+=1
|
||||
@script[:args_format] << [args]
|
||||
end
|
||||
}
|
||||
|
||||
@script[:proc] = block
|
||||
end
|
||||
|
||||
def run
|
||||
comm_name=""
|
||||
if @script
|
||||
comm=@script
|
||||
elsif
|
||||
if @args[0] && !@args[0].match(/^-/)
|
||||
comm_name=@args.shift.to_sym
|
||||
comm=@commands[comm_name]
|
||||
end
|
||||
end
|
||||
|
||||
if comm.nil?
|
||||
help
|
||||
exit -1
|
||||
end
|
||||
|
||||
extra_options = comm[:options] if comm
|
||||
parse(extra_options)
|
||||
if comm
|
||||
check_args!(comm_name, comm[:arity], comm[:args_format])
|
||||
|
||||
begin
|
||||
rc = comm[:proc].call
|
||||
rescue Exception =>e
|
||||
#puts e.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
if rc.instance_of?(Array)
|
||||
puts rc[1]
|
||||
exit rc.first
|
||||
else
|
||||
exit 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]
|
||||
short = o[:short].split(' ').first
|
||||
printf opt_format, "#{short}, #{o[:large]}", o[:description]
|
||||
puts
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
@opts.each{ |o|
|
||||
printf opt_format, "#{o[:short]}, #{o[:large]}", 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, "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
|
||||
}
|
||||
}
|
||||
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.flatten.each do |e|
|
||||
opts.on(e[:short],e[:large], e[:format],e[:description]) do |o|
|
||||
if e[:proc]
|
||||
e[:proc].call(o, @options)
|
||||
elsif e[:name]=="help"
|
||||
help
|
||||
exit
|
||||
elsif e[:name]=="version"
|
||||
puts @version
|
||||
exit
|
||||
else
|
||||
@options[e[:name].to_sym]=o
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
@cmdparse.parse!(@args)
|
||||
rescue => e
|
||||
puts e.message
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
def check_args!(name, arity, args_format)
|
||||
if @args.length < arity
|
||||
print "Command #{name} requires "
|
||||
if arity>1
|
||||
puts "#{args_format.length} parameters to run."
|
||||
else
|
||||
puts "one parameter to run"
|
||||
end
|
||||
exit -1
|
||||
else
|
||||
id=0
|
||||
@args.collect!{|arg|
|
||||
unless format=args_format[id]
|
||||
args_str=args_format.collect{ |a|
|
||||
if a.include?(nil)
|
||||
"[#{a.compact.join("|")}]"
|
||||
else
|
||||
"<#{a.join("|")}>"
|
||||
end
|
||||
}.join(' ')
|
||||
|
||||
puts "Wrong number of arguments"
|
||||
puts "The arguments should be: #{args_str}"
|
||||
exit -1
|
||||
end
|
||||
|
||||
format = args_format[id]
|
||||
argument = nil
|
||||
error_msg = nil
|
||||
format.each { |f|
|
||||
format_hash = @formats[f] ? @formats[f] : @formats[:text]
|
||||
rc = format_hash[:proc].call(arg)
|
||||
if rc[0]==0
|
||||
argument=rc[1]
|
||||
break
|
||||
else
|
||||
error_msg=rc[1]
|
||||
next
|
||||
end
|
||||
}
|
||||
|
||||
unless argument
|
||||
puts error_msg if error_msg
|
||||
puts "command #{name}: argument #{id} must be one of #{format.join(', ')}"
|
||||
exit -1
|
||||
end
|
||||
|
||||
id+=1
|
||||
argument
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
def format_text(arg)
|
||||
arg.instance_of?(String) ? [0,arg] : [-1]
|
||||
end
|
||||
|
||||
def format_file(arg)
|
||||
File.exists?(arg) ? [0,arg] : [-1]
|
||||
end
|
||||
|
||||
REG_RANGE=/^(?:(?:\d+\.\.\d+|\d+),)*(?:\d+\.\.\d+|\d+)$/
|
||||
|
||||
def format_range(arg)
|
||||
arg_s = arg.gsub(" ","").to_s
|
||||
return [-1] unless arg_s.match(REG_RANGE)
|
||||
|
||||
ids = Array.new
|
||||
arg_s.split(',').each { |e|
|
||||
if e.match(/^\d+$/)
|
||||
ids << e.to_i
|
||||
elsif m = e.match(/^(\d+)\.\.(\d+)$/)
|
||||
ids += (m[1].to_i..m[2].to_i).to_a
|
||||
else
|
||||
return [-1]
|
||||
end
|
||||
}
|
||||
|
||||
return 0,ids.uniq
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
19
src/cli/etc/onegroup.yaml
Normal file
19
src/cli/etc/onegroup.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: ONE identifier for the Group
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the Group
|
||||
:size: 15
|
||||
:left: true
|
||||
|
||||
:USER:
|
||||
:desc: Username of the Group owner
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :USER
|
||||
- :NAME
|
53
src/cli/etc/onehost.yaml
Normal file
53
src/cli/etc/onehost.yaml
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: ONE identifier for Host
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the Host
|
||||
:size: 15
|
||||
:left: true
|
||||
|
||||
:RVM:
|
||||
:desc: Number of Virtual Machines running
|
||||
:size: 6
|
||||
|
||||
:TCPU:
|
||||
:desc: Total CPU percentage
|
||||
:size: 6
|
||||
|
||||
:FCPU:
|
||||
:desc: Free CPU percentage
|
||||
:size: 6
|
||||
|
||||
:ACPU:
|
||||
:desc: Available cpu percentage (not reserved by VMs)
|
||||
:size: 6
|
||||
|
||||
:TMEM:
|
||||
:desc: Total Memory
|
||||
:size: 6
|
||||
|
||||
:FMEM:
|
||||
:desc: Free Memory
|
||||
:size: 6
|
||||
|
||||
:AMEM:
|
||||
:desc: Available Memory (not reserved by VMs)
|
||||
:size: 6
|
||||
|
||||
:STAT:
|
||||
:desc: Host status
|
||||
:size: 6
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :NAME
|
||||
- :RVM
|
||||
- :TCPU
|
||||
- :FCPU
|
||||
- :ACPU
|
||||
- :TMEM
|
||||
- :FMEM
|
||||
- :AMEM
|
||||
- :STAT
|
55
src/cli/etc/oneimage.yaml
Normal file
55
src/cli/etc/oneimage.yaml
Normal file
@ -0,0 +1,55 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: ONE identifier for the Image
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the Image
|
||||
:size: 15
|
||||
:left: true
|
||||
|
||||
:USER:
|
||||
:desc: Username of the Virtual Machine owner
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:GROUP:
|
||||
:desc: Group of the Virtual Machine
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:TYPE:
|
||||
:desc: Type of the Image
|
||||
:size: 4
|
||||
|
||||
:REGTIME:
|
||||
:desc: Registration time of the Image
|
||||
:size: 20
|
||||
|
||||
:PUBLIC:
|
||||
:desc: Whether the Image is public or not
|
||||
:size: 3
|
||||
|
||||
:PERSISTENT:
|
||||
:desc: Whether the Image is persistent or not
|
||||
:size: 3
|
||||
|
||||
:STAT:
|
||||
:desc: State of the Image
|
||||
:size: 4
|
||||
|
||||
:RVMS:
|
||||
:desc: Number of VMs currently running from this Image
|
||||
:size: 5
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :USER
|
||||
- :GROUP
|
||||
- :NAME
|
||||
- :TYPE
|
||||
- :REGTIME
|
||||
- :PUBLIC
|
||||
- :PERSISTENT
|
||||
- :STAT
|
||||
- :RVMS
|
35
src/cli/etc/onetemplate.yaml
Normal file
35
src/cli/etc/onetemplate.yaml
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: ONE identifier for the Template
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the Template
|
||||
:size: 15
|
||||
:left: true
|
||||
|
||||
:USER:
|
||||
:desc: Username of the Template owner
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:GROUP:
|
||||
:desc: Group of the Template
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:REGTIME:
|
||||
:desc: Registration time of the Template
|
||||
:size: 20
|
||||
|
||||
:PUBLIC:
|
||||
:desc: Whether the Template is public or not
|
||||
:size: 3
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :USER
|
||||
- :GROUP
|
||||
- :NAME
|
||||
- :REGTIME
|
||||
- :PUBLIC
|
24
src/cli/etc/oneuser.yaml
Normal file
24
src/cli/etc/oneuser.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: ONE identifier for the Template
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the Template
|
||||
:size: 15
|
||||
:left: true
|
||||
|
||||
:GROUP:
|
||||
:desc: Group of the Template
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:PASSWORD:
|
||||
:desc: Password of the User
|
||||
:size: 50
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :GROUP
|
||||
- :NAME
|
||||
- :PASSWORD
|
50
src/cli/etc/onevm.yaml
Normal file
50
src/cli/etc/onevm.yaml
Normal file
@ -0,0 +1,50 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: ONE identifier for Virtual Machine
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the Virtual Machine
|
||||
:size: 15
|
||||
:left: true
|
||||
|
||||
:USER:
|
||||
:desc: Username of the Virtual Machine owner
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:GROUP:
|
||||
:desc: Group of the Virtual Machine
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:STAT:
|
||||
:desc: Actual status
|
||||
:size: 4
|
||||
|
||||
:CPU:
|
||||
:desc: CPU percentage used by the VM
|
||||
:size: 3
|
||||
|
||||
:MEM:
|
||||
:desc: Memory used by the VM
|
||||
:size: 7
|
||||
|
||||
:HOSTNAME:
|
||||
:desc: Host where the VM is running
|
||||
:size: 15
|
||||
|
||||
:TIME:
|
||||
:desc: Time since the VM was submitted
|
||||
:size: 11
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :USER
|
||||
- :GROUP
|
||||
- :NAME
|
||||
- :STAT
|
||||
- :CPU
|
||||
- :MEM
|
||||
- :HOSTNAME
|
||||
- :TIME
|
49
src/cli/etc/onevnet.yaml
Normal file
49
src/cli/etc/onevnet.yaml
Normal file
@ -0,0 +1,49 @@
|
||||
---
|
||||
:ID:
|
||||
:desc: ONE identifier for Virtual Network
|
||||
:size: 4
|
||||
|
||||
:NAME:
|
||||
:desc: Name of the Virtual Network
|
||||
:size: 15
|
||||
:left: true
|
||||
|
||||
:USER:
|
||||
:desc: Username of the Virtual Network owner
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:GROUP:
|
||||
:desc: Group of the Virtual Network
|
||||
:size: 8
|
||||
:left: true
|
||||
|
||||
:TYPE:
|
||||
:desc: Type of Virtual Network
|
||||
:size: 6
|
||||
|
||||
:SIZE:
|
||||
:desc: Size of the Virtual Network
|
||||
:size: 6
|
||||
|
||||
:BRIDGE:
|
||||
:desc: Bridge associated to the Virtual Network
|
||||
:size: 6
|
||||
|
||||
:PUBLIC:
|
||||
:desc: Whether the Virtual Network is public or not
|
||||
:size: 1
|
||||
|
||||
:LEASES:
|
||||
:desc: Number of this Virtual Networks given leases
|
||||
:size: 7
|
||||
|
||||
:default:
|
||||
- :ID
|
||||
- :USER
|
||||
- :GROUP
|
||||
- :NAME
|
||||
- :TYPE
|
||||
- :BRIDGE
|
||||
- :PUBLIC
|
||||
- :LEASES
|
356
src/cli/one_helper.rb
Normal file
356
src/cli/one_helper.rb
Normal file
@ -0,0 +1,356 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 'cli_helper'
|
||||
|
||||
require 'OpenNebula'
|
||||
include OpenNebula
|
||||
|
||||
module OpenNebulaHelper
|
||||
ONE_VERSION=<<-EOT
|
||||
OpenNebula 2.3.0
|
||||
Copyright 2002-2011, 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
|
||||
EOT
|
||||
|
||||
if ONE_LOCATION
|
||||
TABLE_CONF_PATH=ONE_LOCATION+"/etc/cli"
|
||||
else
|
||||
TABLE_CONF_PATH="/etc/one/cli"
|
||||
end
|
||||
|
||||
EDITOR_PATH='/usr/bin/vi'
|
||||
|
||||
########################################################################
|
||||
# Options
|
||||
########################################################################
|
||||
XML={
|
||||
:name => "xml",
|
||||
:short => "-x",
|
||||
:large => "--xml",
|
||||
:description => "Show the resource in xml format"
|
||||
}
|
||||
|
||||
NUMERIC={
|
||||
:name => "numeric",
|
||||
:short => "-n",
|
||||
:large => "--numeric",
|
||||
:description => "Do not translate user and group IDs"
|
||||
}
|
||||
|
||||
KILOBYTES={
|
||||
:name => "kilobytes",
|
||||
:short => "-k",
|
||||
:large => "--kilobytes",
|
||||
:description => "Show units in kilobytes"
|
||||
}
|
||||
|
||||
OPTIONS = XML, NUMERIC, KILOBYTES
|
||||
|
||||
class OneHelper
|
||||
def initialize
|
||||
@client = OpenNebula::Client.new
|
||||
@translation_hash = nil
|
||||
end
|
||||
|
||||
def create_resource(options, &block)
|
||||
resource = factory
|
||||
|
||||
rc = block.call(resource)
|
||||
if OpenNebula.is_error?(rc)
|
||||
return -1, rc.message
|
||||
else
|
||||
puts "ID: #{resource.id.to_s}" if options[:verbose]
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
def list_pool(options, top=false)
|
||||
user_flag = options[:filter_flag] ? options[:filter_flag] : -2
|
||||
pool = factory_pool(user_flag)
|
||||
|
||||
rc = pool.info
|
||||
return -1, rc.message if OpenNebula.is_error?(rc)
|
||||
|
||||
if options[:xml]
|
||||
return 0, pool.to_xml(true)
|
||||
else
|
||||
format_pool(pool, options, top)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
def show_resource(id, options)
|
||||
resource = retrieve_resource(id)
|
||||
return -1, resource.message if OpenNebula.is_error?(resource)
|
||||
|
||||
if options[:xml]
|
||||
return 0, resource.to_xml(true)
|
||||
else
|
||||
format_resource(resource)
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
def perform_action(id, options, verbose, &block)
|
||||
resource = retrieve_resource(id)
|
||||
return -1, resource.message if OpenNebula.is_error?(resource)
|
||||
|
||||
rc = block.call(resource)
|
||||
if OpenNebula.is_error?(rc)
|
||||
return -1, rc.message
|
||||
else
|
||||
puts "#{self.class.rname} #{id}: #{verbose}" if options[:verbose]
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
def perform_actions(ids,options,verbose,&block)
|
||||
exit_code = 0
|
||||
ids.each do |id|
|
||||
rc = perform_action(id,options,verbose,&block)
|
||||
|
||||
unless rc[0]==0
|
||||
puts rc[1]
|
||||
exit_code=rc[0]
|
||||
end
|
||||
end
|
||||
|
||||
exit_code
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Id translation
|
||||
########################################################################
|
||||
def uid_to_str(uid, options)
|
||||
rid_to_str(:users, uid, options)
|
||||
end
|
||||
|
||||
def gid_to_str(gid, options)
|
||||
rid_to_str(:groups, gid, options)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
def to_id(name)
|
||||
return 0, name if name.match(/^[0123456789]+$/)
|
||||
|
||||
user_flag = -2
|
||||
pool = factory_pool(user_flag)
|
||||
poolname = self.class.rname
|
||||
|
||||
self.class.id_to_name(name, pool, poolname)
|
||||
end
|
||||
|
||||
def self.to_id_desc
|
||||
"OpenNebula #{self.rname} name or id"
|
||||
end
|
||||
|
||||
def list_to_id(names)
|
||||
user_flag = -2
|
||||
pool = factory_pool(user_flag)
|
||||
|
||||
rc = pool.info
|
||||
return -1, rc.message if OpenNebula.is_error?(rc)
|
||||
|
||||
result = names.split(',').collect { |name|
|
||||
rc = to_id(name)
|
||||
unless rc.first==0
|
||||
return rc
|
||||
end
|
||||
rc[1]
|
||||
}
|
||||
|
||||
return 0, result
|
||||
end
|
||||
|
||||
def self.list_to_id_desc
|
||||
"Comma-separated list of OpenNebula #{self.rname} names or ids"
|
||||
end
|
||||
|
||||
def filterflag_to_i(str)
|
||||
filter_flag = case str
|
||||
when "a", "all" then "-2"
|
||||
when "m", "mine" then "-3"
|
||||
when "g", "group" then "-1"
|
||||
else
|
||||
if str.match(/^[0123456789]+$/)
|
||||
str
|
||||
else
|
||||
user = translation_hash[:users].select { |k,v| v==str }
|
||||
user.length > 0 ? user.first.first : "-2"
|
||||
end
|
||||
end
|
||||
|
||||
return 0, filter_flag
|
||||
end
|
||||
|
||||
def self.filterflag_to_i_desc
|
||||
desc=<<-EOT
|
||||
a, all all the known #{self.rname}s
|
||||
m, mine the #{self.rname} belonging to the user in ONE_AUTH
|
||||
g, group 'mine' plus the #{self.rname} belonging to the groups
|
||||
the user is member of
|
||||
uid #{self.rname} of the user identified by this uid
|
||||
user #{self.rname} of the user identified by the username
|
||||
EOT
|
||||
end
|
||||
|
||||
def self.table_conf
|
||||
path = "#{ENV["HOME"]}/.one/cli/#{self.conf_file}"
|
||||
|
||||
if File.exists?(path)
|
||||
return path
|
||||
else
|
||||
return "#{TABLE_CONF_PATH}/#{self.conf_file}"
|
||||
end
|
||||
end
|
||||
|
||||
def self.id_to_name(name, pool, ename)
|
||||
rc = pool.info
|
||||
return -1, rc.message if OpenNebula.is_error?(rc)
|
||||
|
||||
objects=pool.select {|object| object.name==name }
|
||||
|
||||
if objects.length>0
|
||||
if objects.length>1
|
||||
return -1, "There are multiple #{ename}s with name #{name}."
|
||||
else
|
||||
result = objects.first.id
|
||||
end
|
||||
else
|
||||
return -1, "#{ename} named #{name} not found."
|
||||
end
|
||||
|
||||
return 0, result
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def retrieve_resource(id)
|
||||
resource = factory(id)
|
||||
|
||||
rc = resource.info
|
||||
OpenNebula.is_error?(rc) ? rc : resource
|
||||
end
|
||||
|
||||
def translation_hash
|
||||
@translation_hash ||= {
|
||||
:users => generate_resource_translation(UserPool),
|
||||
:groups => generate_resource_translation(GroupPool)
|
||||
}
|
||||
end
|
||||
|
||||
def generate_resource_translation(pool)
|
||||
p = pool.new(@client)
|
||||
p.info
|
||||
|
||||
hash = Hash.new
|
||||
p.each { |r| hash[r["ID"]]=r["NAME"] }
|
||||
hash
|
||||
end
|
||||
|
||||
def rid_to_str(resource, id, options)
|
||||
if options[:numeric]
|
||||
id
|
||||
else
|
||||
if name = translation_hash[resource][id]
|
||||
name
|
||||
else
|
||||
id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def OpenNebulaHelper.name_to_id(name, poolname, user_flag=-2)
|
||||
client = OpenNebula::Client.new
|
||||
# TBD user_flag
|
||||
pool = case poolname
|
||||
when "HOST" then OpenNebula::HostPool.new(client)
|
||||
when "GROUP" then OpenNebula::GroupPool.new(client)
|
||||
when "USER" then OpenNebula::UserPool.new(client)
|
||||
end
|
||||
|
||||
OneHelper.id_to_name(name, pool, poolname)
|
||||
end
|
||||
|
||||
def OpenNebulaHelper.name_to_id_desc(poolname)
|
||||
"OpenNebula #{poolname} name or id"
|
||||
end
|
||||
def OpenNebulaHelper.public_to_str(str)
|
||||
if str.to_i == 1
|
||||
public_str = "Y"
|
||||
else
|
||||
public_str = "N"
|
||||
end
|
||||
end
|
||||
|
||||
def OpenNebulaHelper.time_to_str(time)
|
||||
value=time.to_i
|
||||
if value==0
|
||||
value='-'
|
||||
else
|
||||
value=Time.at(value).strftime("%m/%d %H:%M:%S")
|
||||
end
|
||||
end
|
||||
|
||||
BinarySufix = ["K", "M", "G", "T" ]
|
||||
|
||||
def OpenNebulaHelper.unit_to_str(value, options)
|
||||
if options[:kilobytes]
|
||||
value
|
||||
else
|
||||
i=0
|
||||
|
||||
while value > 1024 && i < 3 do
|
||||
value /= 1024.0
|
||||
i+=1
|
||||
end
|
||||
|
||||
value = (value * 10).round / 10.0
|
||||
|
||||
value = value.to_i if value - value.round == 0
|
||||
st = value.to_s + BinarySufix[i]
|
||||
end
|
||||
end
|
||||
|
||||
def OpenNebulaHelper.update_template(id, resource)
|
||||
require 'tempfile'
|
||||
|
||||
tmp = Tempfile.new(id)
|
||||
path = tmp.path
|
||||
|
||||
tmp << resource.template_str
|
||||
tmp.flush
|
||||
|
||||
editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : EDITOR_PATH
|
||||
system("#{editor_path} #{path}")
|
||||
unless $?==0
|
||||
puts "Editor not defined"
|
||||
exit -1
|
||||
end
|
||||
|
||||
tmp.close
|
||||
|
||||
str = File.read(path)
|
||||
str
|
||||
end
|
||||
end
|
83
src/cli/one_helper/onegroup_helper.rb
Normal file
83
src/cli/one_helper/onegroup_helper.rb
Normal file
@ -0,0 +1,83 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 OneGroupHelper < OpenNebulaHelper::OneHelper
|
||||
def self.rname
|
||||
"GROUP"
|
||||
end
|
||||
|
||||
def self.conf_file
|
||||
"onegroup.yaml"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
if id
|
||||
OpenNebula::Group.new_with_id(id, @client)
|
||||
else
|
||||
xml=OpenNebula::Group.build_xml
|
||||
OpenNebula::Group.new(xml, @client)
|
||||
end
|
||||
end
|
||||
|
||||
def factory_pool(user_flag=-2)
|
||||
#TBD OpenNebula::UserPool.new(@client, user_flag)
|
||||
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
|
||||
column :ID, "ONE identifier for the Group", :size=>4 do |d|
|
||||
d["ID"]
|
||||
end
|
||||
|
||||
column :NAME, "Name of the Group", :left, :size=>15 do |d|
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :USER, "Username of the Group owner", :left, :size=>8 do |d|
|
||||
helper.uid_to_str(d["UID"], options)
|
||||
end
|
||||
|
||||
default :ID, :USER, :NAME
|
||||
end
|
||||
|
||||
if top
|
||||
table.top(pool, options)
|
||||
else
|
||||
table.show(pool, options)
|
||||
end
|
||||
end
|
||||
end
|
129
src/cli/one_helper/onehost_helper.rb
Normal file
129
src/cli/one_helper/onehost_helper.rb
Normal file
@ -0,0 +1,129 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 OneHostHelper < OpenNebulaHelper::OneHelper
|
||||
def self.rname
|
||||
"HOST"
|
||||
end
|
||||
|
||||
def self.conf_file
|
||||
"onehost.yaml"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
if id
|
||||
OpenNebula::Host.new_with_id(id, @client)
|
||||
else
|
||||
xml=OpenNebula::Host.build_xml
|
||||
OpenNebula::Host.new(xml, @client)
|
||||
end
|
||||
end
|
||||
|
||||
def factory_pool(user_flag=-2)
|
||||
#TBD OpenNebula::HostPool.new(@client, user_flag)
|
||||
OpenNebula::HostPool.new(@client)
|
||||
end
|
||||
|
||||
def format_resource(host)
|
||||
str = "%-22s: %-20s"
|
||||
str_h1 = "%-80s"
|
||||
|
||||
CLIHelper.print_header(str_h1 % "HOST #{host.id.to_s} INFORMATION", true)
|
||||
|
||||
puts str % ["ID", host.id.to_s]
|
||||
puts str % ["NAME", host.name]
|
||||
puts str % ["STATE", host.state_str]
|
||||
puts str % ["IM_MAD", host['IM_MAD']]
|
||||
puts str % ["VM_MAD", host['VM_MAD']]
|
||||
puts str % ["TM_MAD", host['TM_MAD']]
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "HOST SHARES", false)
|
||||
|
||||
puts str % ["MAX MEM", host['HOST_SHARE/MAX_MEM']]
|
||||
puts str % ["USED MEM (REAL)", host['HOST_SHARE/USED_MEM']]
|
||||
puts str % ["USED MEM (ALLOCATED)", host['HOST_SHARE/MEM_USAGE']]
|
||||
puts str % ["MAX CPU", host['HOST_SHARE/MAX_CPU']]
|
||||
puts str % ["USED CPU (REAL)", host['HOST_SHARE/USED_CPU']]
|
||||
puts str % ["USED CPU (ALLOCATED)", host['HOST_SHARE/CPU_USAGE']]
|
||||
puts str % ["RUNNING VMS", host['HOST_SHARE/RUNNING_VMS']]
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "MONITORING INFORMATION", false)
|
||||
|
||||
puts host.template_str
|
||||
end
|
||||
|
||||
def format_pool(pool, options, top=false)
|
||||
config_file=self.class.table_conf
|
||||
table=CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, "ONE identifier for Host", :size=>4 do |d|
|
||||
d["ID"]
|
||||
end
|
||||
|
||||
column :NAME, "Name of the Host", :left, :size=>15 do |d|
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :RVM, "Number of Virtual Machines running", :size=>6 do |d|
|
||||
d["HOST_SHARE/RUNNING_VMS"]
|
||||
end
|
||||
|
||||
column :TCPU, "Total CPU percentage", :size=>6 do |d|
|
||||
d["HOST_SHARE/MAX_CPU"]
|
||||
end
|
||||
|
||||
column :FCPU, "Free CPU percentage", :size=>6 do |d|
|
||||
d["HOST_SHARE/MAX_CPU"].to_i-d["HOST_SHARE/USED_CPU"].to_i
|
||||
end
|
||||
|
||||
column :ACPU, "Available cpu percentage (not reserved by VMs)", :size=>6 do |d|
|
||||
max_cpu=d["HOST_SHARE/MAX_CPU"].to_i
|
||||
max_cpu=100 if max_cpu==0
|
||||
max_cpu-d["HOST_SHARE/CPU_USAGE"].to_i
|
||||
end
|
||||
|
||||
column :TMEM, "Total Memory", :size=>6 do |d|
|
||||
OpenNebulaHelper.unit_to_str(d["HOST_SHARE/MAX_MEM"].to_i,options)
|
||||
end
|
||||
|
||||
column :FMEM, "Free Memory", :size=>6 do |d|
|
||||
OpenNebulaHelper.unit_to_str(d["HOST_SHARE/FREE_MEM"].to_i,options)
|
||||
end
|
||||
|
||||
column :AMEM, "Available Memory (not reserved by VMs)", :size=>6 do |d|
|
||||
acpu=d["HOST_SHARE/MAX_MEM"].to_i-d["HOST_SHARE/MEM_USAGE"].to_i
|
||||
OpenNebulaHelper.unit_to_str(acpu,options)
|
||||
end
|
||||
|
||||
column :STAT, "Host status", :size=>6 do |d|
|
||||
d.short_state_str
|
||||
end
|
||||
|
||||
default :ID, :NAME, :RVM, :TCPU, :FCPU, :ACPU, :TMEM, :FMEM, :AMEM, :STAT
|
||||
end
|
||||
|
||||
if top
|
||||
table.top(pool, options)
|
||||
else
|
||||
table.show(pool, options)
|
||||
end
|
||||
end
|
||||
end
|
121
src/cli/one_helper/oneimage_helper.rb
Normal file
121
src/cli/one_helper/oneimage_helper.rb
Normal file
@ -0,0 +1,121 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 OneImageHelper < OpenNebulaHelper::OneHelper
|
||||
def self.rname
|
||||
"IMAGE"
|
||||
end
|
||||
|
||||
def self.conf_file
|
||||
"oneimage.yaml"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
if id
|
||||
OpenNebula::Image.new_with_id(id, @client)
|
||||
else
|
||||
xml=OpenNebula::Image.build_xml
|
||||
OpenNebula::Image.new(xml, @client)
|
||||
end
|
||||
end
|
||||
|
||||
def factory_pool(user_flag=-2)
|
||||
OpenNebula::ImagePool.new(@client, user_flag)
|
||||
end
|
||||
|
||||
def format_resource(image)
|
||||
str="%-15s: %-20s"
|
||||
str_h1="%-80s"
|
||||
|
||||
CLIHelper.print_header(str_h1 % "IMAGE #{image['ID']} INFORMATION")
|
||||
puts str % ["ID", image.id.to_s]
|
||||
puts str % ["NAME", image.name]
|
||||
puts str % ["TYPE", image.type_str]
|
||||
puts str % ["REGISTER TIME", OpenNebulaHelper.time_to_str(image['REGTIME'])]
|
||||
puts str % ["PUBLIC", OpenNebulaHelper.public_to_str(image['PUBLIC'])]
|
||||
puts str % ["PERSISTENT", OneImageHelper.persistent_to_str(image["PERSISTENT"])]
|
||||
puts str % ["SOURCE", image['SOURCE']]
|
||||
puts str % ["STATE", image.short_state_str]
|
||||
puts str % ["RUNNING_VMS", image['RUNNING_VMS']]
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "IMAGE TEMPLATE",false)
|
||||
puts image.template_str
|
||||
end
|
||||
|
||||
def format_pool(pool, options, top=false)
|
||||
config_file=self.class.table_conf
|
||||
table=CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, "ONE identifier for the Image", :size=>4 do |d|
|
||||
d["ID"]
|
||||
end
|
||||
|
||||
column :NAME, "Name of the Image", :left, :size=>15 do |d|
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :USER, "Username of the Virtual Machine owner", :left, :size=>8 do |d|
|
||||
helper.uid_to_str(d["UID"], options)
|
||||
end
|
||||
|
||||
column :GROUP, "Group of the Virtual Machine", :left, :size=>8 do |d|
|
||||
helper.gid_to_str(d["GID"], options)
|
||||
end
|
||||
|
||||
column :TYPE, "Type of the Image", :size=>4 do |d,e|
|
||||
d.short_type_str
|
||||
end
|
||||
|
||||
column :REGTIME, "Registration time of the Image", :size=>20 do |d|
|
||||
OpenNebulaHelper.time_to_str(d["REGTIME"])
|
||||
end
|
||||
|
||||
column :PUBLIC, "Whether the Image is public or not", :size=>3 do |d|
|
||||
OpenNebulaHelper.public_to_str(d["PUBLIC"])
|
||||
end
|
||||
|
||||
column :PERSISTENT, "Whether the Image is persistent or not", :size=>3 do |d|
|
||||
OneImageHelper.persistent_to_str(d["PERSISTENT"])
|
||||
end
|
||||
|
||||
column :STAT, "State of the Image", :size=>4 do |d|
|
||||
d.short_state_str
|
||||
end
|
||||
|
||||
column :RVMS, "Number of VMs currently running from this Image", :size=>5 do |d|
|
||||
d['RUNNING_VMS']
|
||||
end
|
||||
|
||||
default :ID, :USER, :GROUP, :NAME, :TYPE, :REGTIME, :PUBLIC, :PERSISTENT , :STAT, :RVMS
|
||||
end
|
||||
|
||||
if top
|
||||
table.top(pool, options)
|
||||
else
|
||||
table.show(pool, options)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.persistent_to_str(str)
|
||||
str.to_i==1 ? "Yes" : "No"
|
||||
end
|
||||
end
|
94
src/cli/one_helper/onetemplate_helper.rb
Normal file
94
src/cli/one_helper/onetemplate_helper.rb
Normal file
@ -0,0 +1,94 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 OneTemplateHelper < OpenNebulaHelper::OneHelper
|
||||
def self.rname
|
||||
"TEMPLATE"
|
||||
end
|
||||
|
||||
def self.conf_file
|
||||
"onetemplate.yaml"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
if id
|
||||
OpenNebula::Template.new_with_id(id, @client)
|
||||
else
|
||||
xml=OpenNebula::Template.build_xml
|
||||
OpenNebula::Template.new(xml, @client)
|
||||
end
|
||||
end
|
||||
|
||||
def factory_pool(user_flag=-2)
|
||||
OpenNebula::TemplatePool.new(@client, user_flag)
|
||||
end
|
||||
|
||||
def format_resource(template)
|
||||
str="%-15s: %-20s"
|
||||
str_h1="%-80s"
|
||||
|
||||
CLIHelper.print_header(str_h1 % "TEMPLATE #{template['ID']} INFORMATION")
|
||||
puts str % ["ID", template.id.to_s]
|
||||
puts str % ["NAME", template.name]
|
||||
puts str % ["REGISTER TIME", OpenNebulaHelper.time_to_str(template['REGTIME'])]
|
||||
puts str % ["PUBLIC", OpenNebulaHelper.public_to_str(template['PUBLIC'])]
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "TEMPLATE CONTENTS",false)
|
||||
puts template.template_str
|
||||
end
|
||||
|
||||
def format_pool(pool, options, top=false)
|
||||
config_file=self.class.table_conf
|
||||
table=CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, "ONE identifier for the Template", :size=>4 do |d|
|
||||
d["ID"]
|
||||
end
|
||||
|
||||
column :NAME, "Name of the Template", :left, :size=>15 do |d|
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :USER, "Username of the Template owner", :left, :size=>8 do |d|
|
||||
helper.uid_to_str(d["UID"], options)
|
||||
end
|
||||
|
||||
column :GROUP, "Group of the Template", :left, :size=>8 do |d|
|
||||
helper.gid_to_str(d["GID"], options)
|
||||
end
|
||||
|
||||
column :REGTIME, "Registration time of the Template", :size=>20 do |d|
|
||||
OpenNebulaHelper.time_to_str(d["REGTIME"])
|
||||
end
|
||||
|
||||
column :PUBLIC, "Whether the Template is public or not", :size=>3 do |d|
|
||||
OpenNebulaHelper.public_to_str(d["PUBLIC"])
|
||||
end
|
||||
|
||||
default :ID, :USER, :GROUP, :NAME, :REGTIME, :PUBLIC
|
||||
end
|
||||
|
||||
if top
|
||||
table.top(pool, options)
|
||||
else
|
||||
table.show(pool, options)
|
||||
end
|
||||
end
|
||||
end
|
112
src/cli/one_helper/oneuser_helper.rb
Normal file
112
src/cli/one_helper/oneuser_helper.rb
Normal file
@ -0,0 +1,112 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 OneUserHelper < OpenNebulaHelper::OneHelper
|
||||
def self.rname
|
||||
"USER"
|
||||
end
|
||||
|
||||
def self.conf_file
|
||||
"oneuser.yaml"
|
||||
end
|
||||
|
||||
def self.password_to_str_desc
|
||||
"TBD"
|
||||
end
|
||||
|
||||
def self.password_to_str(arg, options)
|
||||
if options[:read_file]
|
||||
begin
|
||||
password = File.read(arg).split("\n").first
|
||||
rescue
|
||||
return -1, "Can not read file: #{arg}"
|
||||
end
|
||||
else
|
||||
if options[:plain]
|
||||
password = arg.gsub(/\s/, '')
|
||||
else
|
||||
password = Digest::SHA1.hexdigest(arg)
|
||||
end
|
||||
end
|
||||
|
||||
return 0, password
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
if id
|
||||
OpenNebula::User.new_with_id(id, @client)
|
||||
else
|
||||
xml=OpenNebula::User.build_xml
|
||||
OpenNebula::User.new(xml, @client)
|
||||
end
|
||||
end
|
||||
|
||||
def factory_pool(user_flag=-2)
|
||||
#TBD OpenNebula::UserPool.new(@client, user_flag)
|
||||
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
|
||||
column :ID, "ONE identifier for the User", :size=>4 do |d|
|
||||
d["ID"]
|
||||
end
|
||||
|
||||
column :NAME, "Name of the User", :left, :size=>15 do |d|
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :GROUP, "Group of the User", :left, :size=>8 do |d|
|
||||
helper.gid_to_str(d["GID"], options)
|
||||
end
|
||||
|
||||
column :PASSWORD, "Password of the User", :size=>50 do |d|
|
||||
d['PASSWORD']
|
||||
end
|
||||
|
||||
default :ID, :GROUP, :NAME, :PASSWORD
|
||||
end
|
||||
|
||||
if top
|
||||
table.top(pool, options)
|
||||
else
|
||||
table.show(pool, options)
|
||||
end
|
||||
end
|
||||
end
|
123
src/cli/one_helper/onevm_helper.rb
Normal file
123
src/cli/one_helper/onevm_helper.rb
Normal file
@ -0,0 +1,123 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 OneVMHelper < OpenNebulaHelper::OneHelper
|
||||
def self.rname
|
||||
"VM"
|
||||
end
|
||||
|
||||
def self.conf_file
|
||||
"onevm.yaml"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
if id
|
||||
OpenNebula::VirtualMachine.new_with_id(id, @client)
|
||||
else
|
||||
xml=OpenNebula::VirtualMachine.build_xml
|
||||
OpenNebula::VirtualMachine.new(xml, @client)
|
||||
end
|
||||
end
|
||||
|
||||
def factory_pool(user_flag=-2)
|
||||
OpenNebula::VirtualMachinePool.new(@client, user_flag)
|
||||
end
|
||||
|
||||
def format_resource(vm)
|
||||
str_h1="%-80s"
|
||||
str="%-20s: %-20s"
|
||||
|
||||
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE #{vm['ID']} INFORMATION")
|
||||
puts str % ["ID", vm.id.to_s]
|
||||
puts str % ["NAME", vm.name]
|
||||
puts str % ["STATE", vm.state_str]
|
||||
puts str % ["LCM_STATE", vm.lcm_state_str]
|
||||
puts str % ["START TIME", OpenNebulaHelper.time_to_str(vm['STIME'])]
|
||||
puts str % ["END TIME", OpenNebulaHelper.time_to_str(vm['ETIME'])]
|
||||
value=vm['DEPLOY_ID']
|
||||
puts str % ["DEPLOY ID:", value=="" ? "-" : value]
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE MONITORING",false)
|
||||
poll_attrs = {
|
||||
"USED MEMORY" => "MEMORY",
|
||||
"USED CPU" => "CPU",
|
||||
"NET_TX" => "NET_TX",
|
||||
"NET_RX" => "NET_RX"
|
||||
}
|
||||
poll_attrs.each { |k,v| puts str % [k,vm[v]] }
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE TEMPLATE",false)
|
||||
puts vm.template_str
|
||||
end
|
||||
|
||||
def format_pool(pool, options, top=false)
|
||||
config_file=self.class.table_conf
|
||||
table=CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, "ONE identifier for Virtual Machine", :size=>4 do |d|
|
||||
d["ID"]
|
||||
end
|
||||
|
||||
column :NAME, "Name of the Virtual Machine", :left, :size=>15 do |d|
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :USER, "Username of the Virtual Machine owner", :left, :size=>8 do |d|
|
||||
helper.uid_to_str(d["UID"], options)
|
||||
end
|
||||
|
||||
column :GROUP, "Group of the Virtual Machine", :left, :size=>8 do |d|
|
||||
helper.gid_to_str(d["GID"], options)
|
||||
end
|
||||
|
||||
column :STAT, "Actual status", :size=>4 do |d,e|
|
||||
d.status
|
||||
end
|
||||
|
||||
column :CPU, "CPU percentage used by the VM", :size=>3 do |d|
|
||||
d["CPU"]
|
||||
end
|
||||
|
||||
column :MEM, "Memory used by the VM", :size=>7 do |d|
|
||||
OpenNebulaHelper.unit_to_str(d["MEMORY"].to_i, options)
|
||||
end
|
||||
|
||||
column :HOSTNAME, "Host where the VM is running", :size=>15 do |d|
|
||||
d["HISTORY/HOSTNAME"]
|
||||
end
|
||||
|
||||
column :TIME, "Time since the VM was submitted", :size=>11 do |d|
|
||||
stime = Time.at(d["STIME"].to_i)
|
||||
etime = d["ETIME"]=="0" ? Time.now : Time.at(d["ETIME"].to_i)
|
||||
dtime = Time.at(etime-stime).getgm
|
||||
"%02d %02d:%02d:%02d" % [dtime.yday-1, dtime.hour, dtime.min, dtime.sec]
|
||||
end
|
||||
|
||||
default :ID, :USER, :GROUP, :NAME, :STAT, :CPU, :MEM, :HOSTNAME, :TIME
|
||||
end
|
||||
|
||||
if top
|
||||
table.top(pool, options)
|
||||
else
|
||||
table.show(pool, options)
|
||||
end
|
||||
end
|
||||
end
|
113
src/cli/one_helper/onevnet_helper.rb
Normal file
113
src/cli/one_helper/onevnet_helper.rb
Normal file
@ -0,0 +1,113 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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 OneVNetHelper < OpenNebulaHelper::OneHelper
|
||||
def self.rname
|
||||
"VNET"
|
||||
end
|
||||
|
||||
def self.conf_file
|
||||
"onevnet.yaml"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def factory(id=nil)
|
||||
if id
|
||||
OpenNebula::VirtualNetwork.new_with_id(id, @client)
|
||||
else
|
||||
xml=OpenNebula::VirtualNetwork.build_xml
|
||||
OpenNebula::VirtualNetwork.new(xml, @client)
|
||||
end
|
||||
end
|
||||
|
||||
def factory_pool(user_flag=-2)
|
||||
OpenNebula::VirtualNetworkPool.new(@client, user_flag)
|
||||
end
|
||||
|
||||
def format_resource(vn)
|
||||
str_h1="%-80s"
|
||||
CLIHelper.print_header(str_h1 % ["VIRTUAL NETWORK #{vn.id.to_s} INFORMATION"])
|
||||
|
||||
str="%-10s: %-20s"
|
||||
puts str % ["ID: ", vn.id.to_s]
|
||||
puts str % ["UID: ", vn["UID"]]
|
||||
puts str % ["PUBLIC", OpenNebulaHelper.public_to_str(vn['PUBLIC'])]
|
||||
puts
|
||||
CLIHelper.print_header(str_h1 % ["VIRTUAL NETWORK TEMPLATE"], false)
|
||||
|
||||
puts vn.template_str(false)
|
||||
|
||||
leases_str = vn.template_like_str('/VNET/LEASES', false)
|
||||
|
||||
if !leases_str.empty?
|
||||
puts
|
||||
CLIHelper.print_header(str_h1 % ["LEASES INFORMATION"], false)
|
||||
puts leases_str
|
||||
end
|
||||
end
|
||||
|
||||
def format_pool(pool, options, top=false)
|
||||
config_file=self.class.table_conf
|
||||
table=CLIHelper::ShowTable.new(config_file, self) do
|
||||
column :ID, "ONE identifier for Virtual Network", :size=>4 do |d|
|
||||
d["ID"]
|
||||
end
|
||||
|
||||
column :NAME, "Name of the Virtual Network", :left, :size=>15 do |d|
|
||||
d["NAME"]
|
||||
end
|
||||
|
||||
column :USER, "Username of the Virtual Network owner", :left, :size=>8 do |d|
|
||||
helper.uid_to_str(d["UID"], options)
|
||||
end
|
||||
|
||||
column :GROUP, "Group of the Virtual Network", :left, :size=>8 do |d|
|
||||
helper.gid_to_str(d["GID"], options)
|
||||
end
|
||||
|
||||
column :TYPE, "Type of Virtual Network", :size=>6 do |d|
|
||||
d.type_str
|
||||
end
|
||||
|
||||
column :SIZE, "Size of the Virtual Network", :size=>6 do |d|
|
||||
d["SIZE"]
|
||||
end
|
||||
|
||||
column :BRIDGE, "Bridge associated to the Virtual Network", :size=>6 do |d|
|
||||
d["BRIDGE"]
|
||||
end
|
||||
|
||||
column :PUBLIC, "Whether the Virtual Network is public or not", :size=>1 do |d|
|
||||
OpenNebulaHelper.public_to_str(d['PUBLIC'])
|
||||
end
|
||||
|
||||
column :LEASES, "Number of this Virtual Network's given leases", :size=>7 do |d|
|
||||
d["TOTAL_LEASES"]
|
||||
end
|
||||
|
||||
default :ID, :USER, :GROUP, :NAME, :TYPE, :BRIDGE, :PUBLIC, :LEASES
|
||||
end
|
||||
|
||||
if top
|
||||
table.top(pool, options)
|
||||
else
|
||||
table.show(pool, options)
|
||||
end
|
||||
end
|
||||
end
|
614
src/cli/onedb
614
src/cli/onedb
@ -1,614 +0,0 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- */
|
||||
# Copyright 2002-2011, 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. */
|
||||
# -------------------------------------------------------------------------- */
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Set up the environment
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
ONE_LOCATION = ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
LIB_LOCATION = "/usr/lib/one"
|
||||
RUBY_LIB_LOCATION = LIB_LOCATION + "/ruby"
|
||||
VAR_LOCATION = "/var/lib/one"
|
||||
ETC_LOCATION = "/etc/one"
|
||||
LOCK_FILE = "/var/lock/one/one"
|
||||
else
|
||||
LIB_LOCATION = ONE_LOCATION + "/lib"
|
||||
RUBY_LIB_LOCATION = LIB_LOCATION + "/ruby"
|
||||
VAR_LOCATION = ONE_LOCATION + "/var"
|
||||
ETC_LOCATION = ONE_LOCATION + "/etc"
|
||||
LOCK_FILE = VAR_LOCATION + "/.lock"
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
|
||||
|
||||
require 'OpenNebula'
|
||||
require 'command_parse'
|
||||
|
||||
# TODO: Move the Configuration file to OpenNebula ruby lib?
|
||||
require "#{RUBY_LIB_LOCATION}/cloud/Configuration"
|
||||
|
||||
require 'rubygems'
|
||||
require 'sequel'
|
||||
|
||||
class MigratorBase
|
||||
attr_reader :db_version
|
||||
attr_reader :one_version
|
||||
@verbose
|
||||
|
||||
def initialize(db, verbose)
|
||||
@db = db
|
||||
@verbose = verbose
|
||||
end
|
||||
|
||||
def up
|
||||
puts "Method up not implemented for version #{@version}"
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
class OneDBParse < CommandParse
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
DB Connection options:
|
||||
|
||||
By default, onedb reads the connection data from oned.conf
|
||||
If any of these options is set, oned.conf is ignored (i.e. if you set MySQL's
|
||||
port onedb won't look for the rest of the options in oned.conf)
|
||||
|
||||
Description:
|
||||
|
||||
This command enables the user to manage the OpenNebula database. It provides
|
||||
information about the DB version, means to upgrade it to the latest version, and
|
||||
backup tools.
|
||||
|
||||
Commands:
|
||||
|
||||
* upgrade (Upgrades the DB to the latest version)
|
||||
onedb upgrade [<version>]
|
||||
|
||||
where <version> : DB version (e.g. 1, 3) to upgrade. By default the DB is
|
||||
upgraded to the latest version
|
||||
|
||||
* version (Prints the current DB version. Use -v flag to see also OpenNebula version)
|
||||
onedb version
|
||||
|
||||
* history (Prints the upgrades history)
|
||||
onedb history
|
||||
|
||||
* backup (Dumps the DB to a file)
|
||||
onedb backup [<output_file>]
|
||||
|
||||
where <output_file> : Same as --backup
|
||||
|
||||
* restore (Restores the DB from a backup file. Only restores backups generated
|
||||
from the same backend (SQLite or MySQL))
|
||||
onedb restore [<backup_file>]
|
||||
|
||||
where <backup_file> : Same as --backup
|
||||
|
||||
EOT
|
||||
|
||||
def text_commands
|
||||
COMMANDS_HELP
|
||||
end
|
||||
|
||||
def text_command_name
|
||||
"onedb"
|
||||
end
|
||||
|
||||
def special_options(opts, options)
|
||||
opts.on_tail("-f", "--force", "Forces the backup even if the DB exists") do |o|
|
||||
options[:force] = true
|
||||
end
|
||||
|
||||
opts.on_tail("--backup file", "Use this file to store/read SQL dump", String) do |o|
|
||||
options[:backup] = o
|
||||
end
|
||||
|
||||
opts.on_tail("-s file", "--sqlite file", "SQLite DB file", String) do |o|
|
||||
options[:backend] = :sqlite
|
||||
options[:sqlite] = o
|
||||
end
|
||||
|
||||
opts.on_tail("--server host", "MySQL server hostname or IP. Defaults "<<
|
||||
"to localhost", String) do |o|
|
||||
options[:backend] = :mysql
|
||||
options[:server] = o
|
||||
end
|
||||
|
||||
opts.on_tail("--port port", "MySQL server port. Defaults to 3306", Integer) do |o|
|
||||
options[:backend] = :mysql
|
||||
options[:port] = o
|
||||
end
|
||||
|
||||
opts.on_tail("--user username", "MySQL username", String) do |o|
|
||||
options[:backend] = :mysql
|
||||
options[:user] = o
|
||||
end
|
||||
|
||||
opts.on_tail("--passwd password", "MySQL password. Leave unset to be "<<
|
||||
"prompted for it", String) do |o|
|
||||
options[:backend] = :mysql
|
||||
options[:passwd] = o
|
||||
end
|
||||
|
||||
opts.on_tail("--dbname name", "MySQL DB name for OpenNebula", String) do |o|
|
||||
options[:backend] = :mysql
|
||||
options[:dbname] = o
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
################################################################################
|
||||
# Helpers
|
||||
################################################################################
|
||||
|
||||
def connection_params()
|
||||
if( @ops[:backend] == nil )
|
||||
read_onedconf()
|
||||
else
|
||||
@backend = @ops[:backend]
|
||||
if( @backend == :sqlite )
|
||||
@sqlite_file = @ops[:sqlite]
|
||||
|
||||
else
|
||||
@server = @ops[:server]
|
||||
@port = @ops[:port]
|
||||
@user = @ops[:user]
|
||||
@passwd = @ops[:passwd]
|
||||
@db_name = @ops[:dbname]
|
||||
|
||||
# Check for errors:
|
||||
error = false
|
||||
missing = ""
|
||||
|
||||
(error = true; missing = "--user" ) if @user == nil
|
||||
(error = true; missing = "--dbname") if @db_name == nil
|
||||
|
||||
if error
|
||||
puts "MySQL option #{missing} is needed"
|
||||
exit -1
|
||||
end
|
||||
|
||||
# Check for defaults:
|
||||
@server = "localhost" if @server == nil
|
||||
@port = 0 if @port == nil
|
||||
|
||||
if @passwd == nil
|
||||
# Hide input characters
|
||||
`stty -echo`
|
||||
print "MySQL Password: "
|
||||
@passwd = STDIN.gets.strip
|
||||
`stty echo`
|
||||
puts ""
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def read_onedconf()
|
||||
|
||||
config = Configuration.new("#{ETC_LOCATION}/oned.conf")
|
||||
|
||||
if config[:db] == nil
|
||||
puts "No DB defined."
|
||||
exit -1
|
||||
end
|
||||
|
||||
if config[:db]["BACKEND"].upcase.include? "SQLITE"
|
||||
@backend = :sqlite
|
||||
@sqlite_file = "#{VAR_LOCATION}/one.db"
|
||||
|
||||
elsif config[:db]["BACKEND"].upcase.include? "MYSQL"
|
||||
@backend = :mysql
|
||||
|
||||
@server = config[:db]["SERVER"]
|
||||
@port = config[:db]["PORT"]
|
||||
@user = config[:db]["USER"]
|
||||
@passwd = config[:db]["PASSWD"]
|
||||
@db_name = config[:db]["DB_NAME"]
|
||||
|
||||
# In OpenNebula 2.0 PORT wasn't present in oned.conf, set default
|
||||
@port = "0" if @port == nil
|
||||
|
||||
# Check for errors:
|
||||
error = false
|
||||
missing = ""
|
||||
|
||||
(error = true; missing = "SERVER" ) if @server == nil
|
||||
(error = true; missing = "USER" ) if @user == nil
|
||||
(error = true; missing = "PASSWD" ) if @passwd == nil
|
||||
(error = true; missing = "DB_NAME") if @db_name == nil
|
||||
|
||||
if error
|
||||
puts "MySQL attribute #{missing} not found in " +
|
||||
"#{ETC_LOCATION}/oned.conf"
|
||||
|
||||
exit -1
|
||||
end
|
||||
|
||||
# Clean leading and trailing quotes, if any
|
||||
@server = @server [1..-2] if @server [0] == ?"
|
||||
@port = @port [1..-2] if @port [0] == ?"
|
||||
@user = @user [1..-2] if @user [0] == ?"
|
||||
@passwd = @passwd [1..-2] if @passwd [0] == ?"
|
||||
@db_name = @db_name[1..-2] if @db_name[0] == ?"
|
||||
|
||||
else
|
||||
puts "Could not load DB configuration from #{ETC_LOCATION}/oned.conf"
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
def get_bck_file()
|
||||
bck_file = ""
|
||||
|
||||
if( @ops[:backup] != nil )
|
||||
bck_file = @ops[:backup]
|
||||
elsif @backend == :sqlite
|
||||
bck_file = "#{VAR_LOCATION}/one.db.bck"
|
||||
elsif @backend == :mysql
|
||||
bck_file = "#{VAR_LOCATION}/mysql_#{@server}_#{@db_name}.sql"
|
||||
end
|
||||
|
||||
return bck_file
|
||||
end
|
||||
|
||||
def backup_db()
|
||||
bck_file = get_bck_file()
|
||||
|
||||
if( !@ops[:force] && File.exists?(bck_file) )
|
||||
puts "File #{bck_file} exists, backup aborted. Use -f to overwrite."
|
||||
exit -1
|
||||
end
|
||||
|
||||
case @backend
|
||||
when :sqlite
|
||||
if( ! File.exists?(@sqlite_file) )
|
||||
puts "File #{@sqlite_file} doesn't exist, backup aborted."
|
||||
exit -1
|
||||
end
|
||||
|
||||
FileUtils.cp(@sqlite_file, "#{bck_file}")
|
||||
puts "Sqlite database backup stored in #{bck_file}"
|
||||
puts "Use 'onedb restore' or copy the file back to restore the DB."
|
||||
|
||||
when :mysql
|
||||
cmd = "mysqldump -u #{@user} -p#{@passwd} -h #{@server} " +
|
||||
"-P #{@port} #{@db_name} > #{bck_file}"
|
||||
|
||||
rc = system(cmd)
|
||||
|
||||
if( !rc )
|
||||
puts "Unknown error running '#{cmd}'"
|
||||
exit -1
|
||||
end
|
||||
|
||||
puts "MySQL dump stored in #{bck_file}"
|
||||
puts "Use 'onedb restore' or restore the DB using the mysql command:"
|
||||
puts "mysql -u user -h server -P port db_name < backup_file"
|
||||
|
||||
else
|
||||
puts "Unknown DB #{@backend}"
|
||||
exit -1
|
||||
end
|
||||
|
||||
puts ""
|
||||
end
|
||||
|
||||
def connect_db()
|
||||
case @backend
|
||||
when :sqlite
|
||||
if( ! File.exists?(@sqlite_file) )
|
||||
puts "File #{@sqlite_file} doesn't exist."
|
||||
exit -1
|
||||
end
|
||||
@db = Sequel.sqlite(@sqlite_file)
|
||||
|
||||
when :mysql
|
||||
@db = Sequel.connect(
|
||||
"mysql://#{@user}:#{@passwd}@#{@server}:#{@port}/#{@db_name}")
|
||||
|
||||
else
|
||||
puts "Unknown DB #{@backend}"
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
def read_db_version()
|
||||
version = 0
|
||||
timestamp = 0
|
||||
comment = ""
|
||||
|
||||
@db.fetch("SELECT version, timestamp, comment FROM db_versioning " +
|
||||
"WHERE oid=(SELECT MAX(oid) FROM db_versioning)") do |row|
|
||||
version = row[:version]
|
||||
timestamp = row[:timestamp]
|
||||
comment = row[:comment]
|
||||
end
|
||||
|
||||
return [version.to_i, timestamp, comment]
|
||||
|
||||
rescue
|
||||
# If the DB doesn't have db_versioning table, it means it is empty or a 2.x
|
||||
# OpenNebula DB
|
||||
begin
|
||||
# User with ID 0 (oneadmin) always exists
|
||||
@db.fetch("SELECT * FROM user_pool WHERE oid=0") do |row|
|
||||
end
|
||||
rescue
|
||||
puts "Database schema does not look to be created by OpenNebula:"
|
||||
puts "table user_pool is missing or empty."
|
||||
|
||||
exit -1
|
||||
end
|
||||
|
||||
begin
|
||||
# Table image_pool is present only in 2.X DBs
|
||||
@db.fetch("SELECT * FROM image_pool") do |row|
|
||||
end
|
||||
rescue
|
||||
puts "Database schema looks to be created by OpenNebula 1.X."
|
||||
puts "This tool only works with databases created by 2.X versions."
|
||||
|
||||
exit -1
|
||||
end
|
||||
|
||||
comment = "Could not read any previous db_versioning data, assuming it is "+
|
||||
"an OpenNebula 2.0 or 2.2 DB."
|
||||
|
||||
return [0, 0, comment]
|
||||
end
|
||||
|
||||
def one_not_running()
|
||||
if File.exists?(LOCK_FILE)
|
||||
puts "First stop OpenNebula. Lock file found: #{LOCK_FILE}"
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
################################################################################
|
||||
################################################################################
|
||||
|
||||
|
||||
onedb_opts = OneDBParse.new([])
|
||||
onedb_opts.parse(ARGV)
|
||||
@ops = onedb_opts.options
|
||||
|
||||
@verbose = @ops[:verbose]
|
||||
|
||||
command = ARGV.shift
|
||||
|
||||
case command
|
||||
when "upgrade"
|
||||
# Check opennebula is not running
|
||||
one_not_running()
|
||||
|
||||
# Get DB connection parameters, from oned.conf or command arguments
|
||||
connection_params()
|
||||
|
||||
# Connect to DB
|
||||
connect_db()
|
||||
|
||||
# Read DB's version
|
||||
version, timestamp, comment = read_db_version()
|
||||
|
||||
if( @verbose )
|
||||
puts "Version read:"
|
||||
puts "#{version} : #{comment}"
|
||||
puts ""
|
||||
end
|
||||
|
||||
# Upgrade, using the scripts in $LIB_LOCATION/onedb/xx.rb
|
||||
|
||||
max_version = nil
|
||||
if( ARGV[0] )
|
||||
max_version = ARGV[0].to_i
|
||||
end
|
||||
|
||||
migrator_version = version + 1
|
||||
migrator = nil
|
||||
file = "#{LIB_LOCATION}/onedb/#{migrator_version}.rb"
|
||||
|
||||
if( File.exists?(file) &&
|
||||
(max_version == nil || migrator_version <= max_version) )
|
||||
|
||||
# At least one upgrade will be executed, make DB backup
|
||||
backup_db()
|
||||
end
|
||||
|
||||
while( File.exists?(file) &&
|
||||
(max_version == nil || migrator_version <= max_version) )
|
||||
|
||||
puts " > Running migrator #{file}" if @verbose
|
||||
|
||||
load(file)
|
||||
migrator = Migrator.new(@db, @verbose)
|
||||
result = migrator.up
|
||||
|
||||
if( !result )
|
||||
puts "Error while upgrading from #{migrator_version-1} to #{migrator.db_version}"
|
||||
return -1
|
||||
end
|
||||
|
||||
puts " > Done" if @verbose
|
||||
puts "" if @verbose
|
||||
|
||||
migrator_version += 1
|
||||
file = "#{LIB_LOCATION}/onedb/#{migrator_version}.rb"
|
||||
end
|
||||
|
||||
# Modify db_versioning table
|
||||
if( migrator != nil )
|
||||
comment = "Database migrated from #{version} to #{migrator.db_version}"+
|
||||
" (#{migrator.one_version}) by onedb command."
|
||||
|
||||
max_oid = nil
|
||||
@db.fetch("SELECT MAX(oid) FROM db_versioning") do |row|
|
||||
max_oid = row[:"MAX(oid)"].to_i
|
||||
end
|
||||
|
||||
max_oid = 0 if max_oid == nil
|
||||
|
||||
@db.run "INSERT INTO db_versioning (oid, version, timestamp, comment) "+
|
||||
"VALUES (" +
|
||||
"#{max_oid+1}, " +
|
||||
"'#{migrator.db_version}', " +
|
||||
"#{Time.new.to_i}, " +
|
||||
"'#{comment}')"
|
||||
|
||||
puts comment
|
||||
else
|
||||
puts "Database already uses version #{version}"
|
||||
end
|
||||
|
||||
when "version"
|
||||
connection_params()
|
||||
connect_db()
|
||||
|
||||
version, timestamp, comment = read_db_version()
|
||||
|
||||
if(@verbose)
|
||||
puts "Version: #{version}"
|
||||
|
||||
time = version == 0 ? Time.now : Time.at(timestamp)
|
||||
# TODO: UTC or Local time?
|
||||
puts "Timestamp: #{time.getgm.strftime("%b %d, %Y %H:%M")}"
|
||||
|
||||
puts "Comment: #{comment}"
|
||||
else
|
||||
puts version
|
||||
end
|
||||
|
||||
when "history"
|
||||
connection_params()
|
||||
connect_db()
|
||||
|
||||
begin
|
||||
@db.fetch("SELECT version, timestamp, comment FROM db_versioning") do |row|
|
||||
puts "Version: #{row[:version]}"
|
||||
|
||||
time = version == 0 ? Time.now : Time.at(row[:timestamp])
|
||||
# TODO: UTC or Local time?
|
||||
puts "Timestamp: #{time.getgm.strftime("%b %d, %Y %H:%M")}"
|
||||
|
||||
puts "Comment: #{row[:comment]}"
|
||||
|
||||
puts ""
|
||||
end
|
||||
rescue Exception => e
|
||||
puts "No version records found. Error message:"
|
||||
puts e.message
|
||||
end
|
||||
|
||||
when "backup"
|
||||
if( ARGV[0] != nil )
|
||||
@ops[:backup] = ARGV[0]
|
||||
end
|
||||
|
||||
connection_params()
|
||||
backup_db()
|
||||
|
||||
when "restore"
|
||||
if( ARGV[0] != nil )
|
||||
@ops[:backup] = ARGV[0]
|
||||
end
|
||||
|
||||
connection_params()
|
||||
|
||||
# Source sql dump file
|
||||
bck_file = get_bck_file()
|
||||
|
||||
if( ! File.exists?(bck_file) )
|
||||
puts "File #{bck_file} doesn't exist, backup restoration aborted."
|
||||
exit -1
|
||||
end
|
||||
|
||||
one_not_running()
|
||||
|
||||
case @backend
|
||||
when :sqlite
|
||||
if( !@ops[:force] && File.exists?(@sqlite_file) )
|
||||
puts "File #{@sqlite_file} exists, use -f to overwrite."
|
||||
exit -1
|
||||
end
|
||||
|
||||
FileUtils.cp(bck_file, @sqlite_file)
|
||||
puts "Sqlite database backup restored in #{@sqlite_file}"
|
||||
|
||||
when :mysql
|
||||
|
||||
connect_db()
|
||||
|
||||
# Check if target database exists
|
||||
exists = false
|
||||
begin
|
||||
# User with ID 0 (oneadmin) always exists
|
||||
@db.fetch("SELECT * FROM user_pool WHERE oid=0") do |row|
|
||||
end
|
||||
exists = true
|
||||
rescue
|
||||
end
|
||||
|
||||
if( !@ops[:force] && exists )
|
||||
puts "MySQL database #{@db_name} at #{@server} exists, use -f to overwrite."
|
||||
exit -1
|
||||
end
|
||||
|
||||
mysql_cmd = "mysql -u #{@user} -p#{@passwd} -h #{@server} " +
|
||||
"-P #{@port} "
|
||||
|
||||
rc = system( mysql_cmd + "-e 'DROP DATABASE IF EXISTS #{@db_name};'")
|
||||
if( !rc )
|
||||
puts "Error dropping MySQL DB #{@db_name} at #{@server}."
|
||||
exit -1
|
||||
end
|
||||
|
||||
rc = system( mysql_cmd + "-e 'CREATE DATABASE IF NOT EXISTS #{@db_name};'")
|
||||
if( !rc )
|
||||
puts "Error creating MySQL DB #{@db_name} at #{@server}."
|
||||
exit -1
|
||||
end
|
||||
|
||||
rc = system( mysql_cmd + "#{@db_name} < #{bck_file}")
|
||||
if( !rc )
|
||||
puts "Error while restoring MySQL DB #{@db_name} at #{@server}."
|
||||
exit -1
|
||||
end
|
||||
|
||||
puts "MySQL DB #{@db_name} at #{@server} restored."
|
||||
|
||||
else
|
||||
puts "Unknown DB #{@backend}"
|
||||
exit -1
|
||||
end
|
||||
|
||||
else
|
||||
onedb_opts.print_help
|
||||
|
||||
exit -1
|
||||
end
|
||||
|
||||
|
||||
exit 0
|
193
src/cli/onegroup
193
src/cli/onegroup
@ -25,162 +25,75 @@ else
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'command_parser'
|
||||
require 'one_helper/onegroup_helper'
|
||||
|
||||
require 'OpenNebula'
|
||||
require 'client_utilities'
|
||||
require 'command_parse'
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
usage "onegroup COMMAND [args..] [options..]"
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
helper = OneGroupHelper.new
|
||||
|
||||
ShowTableUP={
|
||||
:id => {
|
||||
:name => "ID",
|
||||
:desc => "ONE identifier for group",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d.id
|
||||
}
|
||||
},
|
||||
:uid => {
|
||||
:name => "OWNER",
|
||||
:desc => "Owner of the group",
|
||||
:size => 5,
|
||||
:proc => lambda {|d,e|
|
||||
d.uid
|
||||
}
|
||||
},
|
||||
:name => {
|
||||
:name => "NAME",
|
||||
:desc => "Name of the group",
|
||||
:size => 16,
|
||||
:proc => lambda {|d,e|
|
||||
d.name
|
||||
}
|
||||
},
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
set :option, CommandParser::OPTIONS
|
||||
|
||||
:default => [:id, :uid, :name]
|
||||
}
|
||||
list_options = CLIHelper::OPTIONS
|
||||
list_options << OpenNebulaHelper::XML
|
||||
list_options << OpenNebulaHelper::NUMERIC
|
||||
|
||||
class UPShow
|
||||
def initialize
|
||||
@grouppool=OpenNebula::GroupPool.new(get_one_client)
|
||||
@table=ShowTable.new(ShowTableUP)
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
set :format, :groupid, OneGroupHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
def header_up_small
|
||||
scr_bold
|
||||
scr_underline
|
||||
print @table.header_str
|
||||
scr_restore
|
||||
puts ""
|
||||
set :format, :groupid_list, OneGroupHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
def list_short(options=nil)
|
||||
res=@grouppool.info
|
||||
if options
|
||||
@table.columns=options[:columns] if options[:columns]
|
||||
end
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
|
||||
if OpenNebula.is_error?(res)
|
||||
result=res
|
||||
else
|
||||
result=res
|
||||
header_up_small
|
||||
create_desc = <<-EOT.unindent
|
||||
Creates a new Group
|
||||
EOT
|
||||
|
||||
puts @table.data_str(@grouppool, options)
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class OneUPParse < CommandParse
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
|
||||
Description:
|
||||
|
||||
This command enables the OpenNebula administrator to manage groups.
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
* create (Creates a new group)
|
||||
onegroup create groupname
|
||||
|
||||
* delete (Removes a group)
|
||||
onegroup delete <id>
|
||||
|
||||
* list (Lists all the groups in the pool)
|
||||
onegroup list
|
||||
|
||||
EOT
|
||||
|
||||
def text_commands
|
||||
COMMANDS_HELP
|
||||
end
|
||||
|
||||
def text_command_name
|
||||
"onegroup"
|
||||
end
|
||||
|
||||
def list_options
|
||||
table=ShowTable.new(ShowTableUP)
|
||||
table.print_help
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
oneup_opts=OneUPParse.new([:list, :xml])
|
||||
oneup_opts.parse(ARGV)
|
||||
ops=oneup_opts.options
|
||||
|
||||
result=[false, "Unknown error"]
|
||||
|
||||
command=ARGV.shift
|
||||
|
||||
case command
|
||||
when "create"
|
||||
check_parameters("create", 1)
|
||||
group=OpenNebula::Group.new(OpenNebula::Group.build_xml, get_one_client)
|
||||
result=group.allocate(ARGV[0])
|
||||
|
||||
if is_successful?(result)
|
||||
puts "ID: " + group.id.to_s if ops[:verbose]
|
||||
exit 0
|
||||
end
|
||||
|
||||
when "delete"
|
||||
check_parameters("delete", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
group_id=get_group_id(param)
|
||||
group=OpenNebula::Group.new(
|
||||
OpenNebula::Group.build_xml(group_id), get_one_client)
|
||||
result=group.delete
|
||||
if !OpenNebula.is_error?(result)
|
||||
puts "Group deleted" if ops[:verbose]
|
||||
break
|
||||
command :create, create_desc, :name do
|
||||
helper.create_resource(options) do |group|
|
||||
group.allocate(args[0])
|
||||
end
|
||||
end
|
||||
|
||||
when "list"
|
||||
if !ops[:xml]
|
||||
uplist=UPShow.new
|
||||
ops[:columns]=ops[:list] if ops[:list]
|
||||
result=uplist.list_short(ops)
|
||||
else
|
||||
grouppool=OpenNebula::GroupPool.new(get_one_client)
|
||||
grouppool.info
|
||||
puts grouppool.to_xml(true)
|
||||
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
|
||||
|
||||
else
|
||||
oneup_opts.print_help
|
||||
exit -1
|
||||
end
|
||||
list_desc = <<-EOT.unindent
|
||||
Lists Groups 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 Group
|
||||
EOT
|
||||
|
||||
command :show, show_desc, :groupid, :options=>OpenNebulaHelper::XML do
|
||||
helper.show_resource(args[0],options)
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(result)
|
||||
puts "Error: " + result.message
|
||||
exit -1
|
||||
end
|
||||
|
475
src/cli/onehost
475
src/cli/onehost
@ -24,393 +24,128 @@ else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
|
||||
end
|
||||
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'command_parser'
|
||||
require 'one_helper/onehost_helper'
|
||||
|
||||
require 'OpenNebula'
|
||||
require 'client_utilities'
|
||||
require 'command_parse'
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
usage "onehost COMMAND [args..] [options..]"
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
ShowTableHost={
|
||||
:id => {
|
||||
:name => "ID",
|
||||
:desc => "ONE identifier for host",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e| d.id }
|
||||
},
|
||||
:name => {
|
||||
:name => "NAME",
|
||||
:desc => "Hostname",
|
||||
:size => 17,
|
||||
:left => true,
|
||||
:proc => lambda {|d,e| d.name }
|
||||
},
|
||||
# TODO
|
||||
:cid => {
|
||||
:name => "CID",
|
||||
:desc => "Cluster ID",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e| d.cluster_id }
|
||||
},
|
||||
:cluster => {
|
||||
:name => "CLUSTER",
|
||||
:desc => "Clustername",
|
||||
:size => 8,
|
||||
:left => true,
|
||||
:proc => lambda { "TODO" }
|
||||
},
|
||||
:rvm => {
|
||||
:name => "RVM",
|
||||
:desc => "Number of virtual machines running",
|
||||
:size => 3,
|
||||
:proc => lambda {|d,e| d["HOST_SHARE/RUNNING_VMS"] }
|
||||
},
|
||||
:tcpu => {
|
||||
:name => "TCPU",
|
||||
:desc => "Total cpu percentage",
|
||||
:size => 6,
|
||||
:proc => lambda {|d,e| d["HOST_SHARE/MAX_CPU"] }
|
||||
},
|
||||
:fcpu => {
|
||||
:name => "FCPU",
|
||||
:desc => "Free cpu percentage",
|
||||
:size => 6,
|
||||
:proc => lambda {|d,e|
|
||||
d["HOST_SHARE/MAX_CPU"].to_i-d["HOST_SHARE/USED_CPU"].to_i
|
||||
}
|
||||
},
|
||||
:acpu => {
|
||||
:name => "ACPU",
|
||||
:desc => "Available cpu percentage (not reserved by VMs)",
|
||||
:size => 6,
|
||||
:proc => lambda {|d,e|
|
||||
max_cpu=d["HOST_SHARE/MAX_CPU"].to_i
|
||||
max_cpu=100 if max_cpu==0
|
||||
max_cpu-d["HOST_SHARE/CPU_USAGE"].to_i
|
||||
}
|
||||
},
|
||||
:tmem => {
|
||||
:name => "TMEM",
|
||||
:desc => "Total memory",
|
||||
:size => 7,
|
||||
:kbytes => true,
|
||||
:proc => lambda {|d,e| d["HOST_SHARE/MAX_MEM"] }
|
||||
},
|
||||
:fmem => {
|
||||
:name => "FMEM",
|
||||
:desc => "Free memory",
|
||||
:size => 7,
|
||||
:kbytes => true,
|
||||
:proc => lambda {|d,e| d["HOST_SHARE/FREE_MEM"] }
|
||||
},
|
||||
:stat => {
|
||||
:name => "STAT",
|
||||
:desc => "Host status",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d.short_state_str()
|
||||
}
|
||||
},
|
||||
helper = OneHostHelper.new
|
||||
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
set :option, CommandParser::OPTIONS
|
||||
|
||||
:default => [:id, :name, :rvm, :tcpu, :fcpu, :acpu, :tmem, :fmem, :stat]
|
||||
}
|
||||
|
||||
class HostShow
|
||||
def initialize(client)
|
||||
@hostpool=OpenNebula::HostPool.new(client)
|
||||
@table=ShowTable.new(ShowTableHost)
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
set :format, :hostid, OneHostHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
def header_host_small
|
||||
scr_bold
|
||||
scr_underline
|
||||
print @table.header_str
|
||||
scr_restore
|
||||
puts ""
|
||||
set :format, :hostid_list, OneHostHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
def list_short(options=nil)
|
||||
res=@hostpool.info
|
||||
if options
|
||||
@table.columns=options[:columns] if options[:columns]
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
|
||||
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
|
||||
|
||||
if OpenNebula.is_error?(res)
|
||||
result=res
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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 :sync, sync_desc do
|
||||
if ONE_LOCATION
|
||||
FileUtils.touch "#{ONE_LOCATION}/var/remotes"
|
||||
else
|
||||
result=[true,""]
|
||||
header_host_small
|
||||
if options
|
||||
puts @table.data_str(@hostpool, options)
|
||||
else
|
||||
puts @table.data_str(@hostpool)
|
||||
end
|
||||
result
|
||||
FileUtils.touch "/var/lib/one/remotes"
|
||||
end
|
||||
0
|
||||
end
|
||||
|
||||
def top(options=nil)
|
||||
delay=1
|
||||
delay=options[:delay] if options && options[:delay]
|
||||
list_desc = <<-EOT.unindent
|
||||
Lists Hosts in the pool
|
||||
EOT
|
||||
|
||||
result=nil
|
||||
command :list, list_desc,
|
||||
:options=>CLIHelper::OPTIONS+OpenNebulaHelper::OPTIONS do
|
||||
helper.list_pool(options)
|
||||
end
|
||||
|
||||
begin
|
||||
while true
|
||||
scr_cls
|
||||
scr_move(0,0)
|
||||
result=list_short(options)
|
||||
sleep delay
|
||||
end
|
||||
rescue Exception
|
||||
end
|
||||
result
|
||||
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
|
||||
end
|
||||
|
||||
class OnehostParse < CommandParse
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
|
||||
Description:
|
||||
|
||||
This command enables the user to manage hosts in the Open Nebula server. It
|
||||
provides functionality to allocate, get information and delete a particular
|
||||
host or to list all the available hosts.
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
* create (Adds a new machine to the pool)
|
||||
onehost create <hostname> <im_mad> <vmm_mad> <tm_mad>
|
||||
|
||||
* show (Gets info from a host)
|
||||
onehost show <host_id>
|
||||
|
||||
* delete (Removes a machine from the pool)
|
||||
onehost delete <host_id>
|
||||
|
||||
* list (Lists machines in the pool)
|
||||
onehost list
|
||||
|
||||
* enable (Enables host)
|
||||
onehost enable <host_id>
|
||||
|
||||
* disable (Disables host)
|
||||
onehost disable <host_id>
|
||||
|
||||
* top (Lists hosts continuously)
|
||||
onehost top
|
||||
|
||||
* sync (synchronizes probes with remote hosts)
|
||||
onehost sync
|
||||
|
||||
|
||||
Information Columns:
|
||||
|
||||
* HID Host ID
|
||||
* NAME Host name
|
||||
* RVM Number of running VMs
|
||||
* TCPU Total CPU (percentage)
|
||||
* FCPU Free CPU (percentage)
|
||||
* ACPU Available CPU (not allocated by VMs)
|
||||
* TMEM Total memory
|
||||
* FMEM Free memory
|
||||
* STAT Host status
|
||||
|
||||
|
||||
EOT
|
||||
|
||||
def text_commands
|
||||
COMMANDS_HELP
|
||||
end
|
||||
|
||||
def text_command_name
|
||||
"onehost"
|
||||
end
|
||||
|
||||
def list_options
|
||||
table=ShowTable.new(ShowTableHost)
|
||||
table.print_help
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Returns true if there are non DONE VM's in a host, false otherwise
|
||||
def vms_in_host?(host_id)
|
||||
|
||||
host = OpenNebula::Host.new_with_id(host_id,get_one_client)
|
||||
|
||||
rc = host.info
|
||||
|
||||
if OpenNebula::is_error?(rc)
|
||||
puts rc.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
host['HOST_SHARE/RUNNING_VMS'].to_i
|
||||
|
||||
end
|
||||
|
||||
|
||||
onehost_opts=OnehostParse.new
|
||||
onehost_opts.parse(ARGV)
|
||||
ops=onehost_opts.options
|
||||
|
||||
result=[false, "Unknown error"]
|
||||
|
||||
command=ARGV.shift
|
||||
|
||||
case command
|
||||
when "add", "create"
|
||||
check_parameters("create", 4)
|
||||
host=OpenNebula::Host.new(OpenNebula::Host.build_xml, get_one_client)
|
||||
result=host.allocate(ARGV[0], ARGV[1], ARGV[2], ARGV[3])
|
||||
|
||||
if is_successful?(result)
|
||||
puts "ID: " + host.id.to_s if ops[:verbose]
|
||||
exit 0
|
||||
end
|
||||
|
||||
when "show"
|
||||
check_parameters("show", 1)
|
||||
#args=expand_args(ARGV)
|
||||
|
||||
host_id=get_host_id(ARGV[0])
|
||||
|
||||
host=OpenNebula::Host.new_with_id(host_id, get_one_client)
|
||||
|
||||
result=host.info
|
||||
if is_successful?(result)
|
||||
if !ops[:xml]
|
||||
str = "%-22s: %-20s"
|
||||
str_h1 = "%-80s"
|
||||
|
||||
print_header(str_h1, "HOST #{host_id} INFORMATION", true)
|
||||
|
||||
puts str % ["ID", host.id.to_s]
|
||||
puts str % ["NAME", host.name]
|
||||
|
||||
# TODO
|
||||
puts str % ["CLUSTER", "TODO"]
|
||||
# puts str % ["CLUSTER", host['CLUSTER']]
|
||||
puts str % ["STATE", host.state_str]
|
||||
puts str % ["IM_MAD", host['IM_MAD']]
|
||||
puts str % ["VM_MAD", host['VM_MAD']]
|
||||
puts str % ["TM_MAD", host['TM_MAD']]
|
||||
puts
|
||||
|
||||
print_header(str_h1, "HOST SHARES", false)
|
||||
|
||||
puts str % ["MAX MEM", host['HOST_SHARE/MAX_MEM']]
|
||||
puts str % ["USED MEM (REAL)", host['HOST_SHARE/USED_MEM']]
|
||||
puts str % ["USED MEM (ALLOCATED)", host['HOST_SHARE/MEM_USAGE']]
|
||||
puts str % ["MAX CPU", host['HOST_SHARE/MAX_CPU']]
|
||||
puts str % ["USED CPU (REAL)", host['HOST_SHARE/USED_CPU']]
|
||||
puts str % ["USED CPU (ALLOCATED)", host['HOST_SHARE/CPU_USAGE']]
|
||||
puts str % ["RUNNING VMS", host['HOST_SHARE/RUNNING_VMS']]
|
||||
puts
|
||||
|
||||
print_header(str_h1, "MONITORING INFORMATION", false)
|
||||
|
||||
puts host.template_str
|
||||
else
|
||||
puts host.to_xml(true)
|
||||
end
|
||||
end
|
||||
|
||||
when "delete"
|
||||
check_parameters("delete", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
host_id=get_host_id(param)
|
||||
|
||||
host = OpenNebula::Host.new_with_id(host_id,get_one_client)
|
||||
|
||||
rc = host.info
|
||||
|
||||
if OpenNebula::is_error?(rc)
|
||||
puts rc.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
if host['HOST_SHARE/RUNNING_VMS'].to_i != 0
|
||||
puts "Host still has associated VMs, aborting delete."
|
||||
else
|
||||
result=host.delete
|
||||
if is_successful?(result)
|
||||
puts "Host deleted" if ops[:verbose]
|
||||
exit 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
when "list"
|
||||
if !ops[:xml]
|
||||
hostlist=HostShow.new(get_one_client)
|
||||
ops[:columns]=ops[:list] if ops[:list]
|
||||
result=hostlist.list_short(ops)
|
||||
else
|
||||
hostpool=OpenNebula::HostPool.new(get_one_client)
|
||||
hostpool.info
|
||||
puts hostpool.to_xml(true)
|
||||
end
|
||||
|
||||
when "top"
|
||||
hostlist=HostShow.new(get_one_client)
|
||||
ops[:columns]=ops[:list] if ops[:list]
|
||||
result=hostlist.top(ops)
|
||||
|
||||
when "enable"
|
||||
check_parameters("enable", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
host_id=get_host_id(param)
|
||||
host = OpenNebula::Host.new_with_id(host_id,get_one_client)
|
||||
result=host.enable
|
||||
if is_successful?(result)
|
||||
puts "Host enabled" if ops[:verbose]
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
when "disable"
|
||||
check_parameters("disable", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
host_id=get_host_id(param)
|
||||
host = OpenNebula::Host.new_with_id(host_id,get_one_client)
|
||||
result=host.disable
|
||||
if is_successful?(result)
|
||||
puts "Host disabled" if ops[:verbose]
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
when "sync"
|
||||
check_parameters("sync", 0)
|
||||
if ONE_LOCATION
|
||||
FileUtils.touch "#{ONE_LOCATION}/var/remotes"
|
||||
else
|
||||
FileUtils.touch "/var/lib/one/remotes"
|
||||
end
|
||||
|
||||
else
|
||||
onehost_opts.print_help
|
||||
exit -1
|
||||
end
|
||||
|
||||
if is_error?(result)
|
||||
puts "Error: " + result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
exit 0
|
||||
|
||||
|
700
src/cli/oneimage
700
src/cli/oneimage
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env ruby
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) #
|
||||
@ -25,548 +25,192 @@ else
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'command_parser'
|
||||
require 'one_helper/oneimage_helper'
|
||||
|
||||
require 'OpenNebula'
|
||||
require 'CommandManager'
|
||||
require 'client_utilities'
|
||||
require 'command_parse'
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
usage "oneimage COMMAND [args..] [options..]"
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
ShowTableImage={
|
||||
:id => {
|
||||
:name => "ID",
|
||||
:desc => "ONE identifier for the Image",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e| d.id }
|
||||
},
|
||||
:user=> {
|
||||
:name => "USER",
|
||||
:desc => "Name of the owner",
|
||||
:size => 8,
|
||||
:proc => lambda {|d,e|
|
||||
"TODO"
|
||||
}
|
||||
},
|
||||
:uid=> {
|
||||
:name => "UID",
|
||||
:desc => "Id of the owner",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d["UID"]
|
||||
}
|
||||
},
|
||||
:gid=> {
|
||||
:name => "GID",
|
||||
:desc => "Id of the group",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d.gid
|
||||
}
|
||||
},
|
||||
:name => {
|
||||
:name => "NAME",
|
||||
:desc => "Name of the Image",
|
||||
:size => 20,
|
||||
:proc => lambda {|d,e|
|
||||
d.name
|
||||
}
|
||||
},
|
||||
:type => {
|
||||
:name => "TYPE",
|
||||
:desc => "Type of the Image",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d.short_type_str
|
||||
}
|
||||
},
|
||||
:regtime => {
|
||||
:name => "REGTIME",
|
||||
:desc => "Registration time of the Image",
|
||||
:size => 20,
|
||||
:proc => lambda {|d,e|
|
||||
str_register_time(d)
|
||||
}
|
||||
},
|
||||
:public => {
|
||||
:name => "PUBLIC",
|
||||
:desc => "Whether the Image is public or not",
|
||||
:size => 3,
|
||||
:proc => lambda {|d,e|
|
||||
if d["PUBLIC"].to_i == 1 then "Yes" else "No" end}
|
||||
},
|
||||
:persistent => {
|
||||
:name => "PERSISTENT",
|
||||
:desc => "Whether the Image is persistent or not",
|
||||
:size => 3,
|
||||
:proc => lambda {|d,e|
|
||||
if d["PERSISTENT"].to_i == 1 then "Yes" else "No" end}
|
||||
},
|
||||
:state => {
|
||||
:name => "STAT",
|
||||
:desc => "State of the Image",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d.short_state_str
|
||||
}
|
||||
},
|
||||
:runningvms => {
|
||||
:name => "#VMS",
|
||||
:desc => "Number of VMs currently running from this Image",
|
||||
:size => 5,
|
||||
:proc => lambda {|d,e| d['RUNNING_VMS'] }
|
||||
},
|
||||
helper = OneImageHelper.new
|
||||
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
set :option, CommandParser::OPTIONS
|
||||
|
||||
:default => [:id, :user, :name, :type, :regtime,
|
||||
:public, :persistent, :state, :runningvms]
|
||||
}
|
||||
list_options = CLIHelper::OPTIONS
|
||||
list_options << OpenNebulaHelper::XML
|
||||
list_options << OpenNebulaHelper::NUMERIC
|
||||
|
||||
|
||||
|
||||
class ImageShow
|
||||
|
||||
def initialize(client, filter_flag="-2")
|
||||
@imagepool=OpenNebula::ImagePool.new(client, filter_flag.to_i)
|
||||
@table=ShowTable.new(ShowTableImage)
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
set :format, :groupid, OpenNebulaHelper.name_to_id_desc("GROUP") do |arg|
|
||||
OpenNebulaHelper.name_to_id(arg, "GROUP")
|
||||
end
|
||||
|
||||
def header_image_small
|
||||
scr_bold
|
||||
scr_underline
|
||||
print @table.header_str
|
||||
scr_restore
|
||||
puts ""
|
||||
|
||||
set :format, :userid, OpenNebulaHelper.name_to_id_desc("USER") do |arg|
|
||||
OpenNebulaHelper.name_to_id(arg, "USER")
|
||||
end
|
||||
|
||||
def top(options=nil)
|
||||
delay=1
|
||||
delay=options[:delay] if options && options[:delay]
|
||||
|
||||
result=nil
|
||||
|
||||
begin
|
||||
while true
|
||||
scr_cls
|
||||
scr_move(0,0)
|
||||
result=list_short(options)
|
||||
sleep delay
|
||||
end
|
||||
rescue Exception
|
||||
end
|
||||
result
|
||||
|
||||
set :format, :imageid, OneImageHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
def list_short(options=nil)
|
||||
res=@imagepool.info()
|
||||
|
||||
if options
|
||||
@table.columns=options[:columns] if options[:columns]
|
||||
end
|
||||
set :format, :imageid_list, OneImageHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(res)
|
||||
result=res
|
||||
puts res.message
|
||||
exit -1
|
||||
else
|
||||
set :format, :filterflag, OneImageHelper.filterflag_to_i_desc do |arg|
|
||||
helper.filterflag_to_i(arg)
|
||||
end
|
||||
|
||||
if options[:filter_flag]
|
||||
vms=@imagepool.select{|element|
|
||||
element['USERNAME']==options[:filter_flag] }
|
||||
else
|
||||
vms=@imagepool
|
||||
end
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
|
||||
result=[true, ""]
|
||||
header_image_small
|
||||
create_desc = <<-EOT.unindent
|
||||
Creates a new Image from the given template file
|
||||
EOT
|
||||
|
||||
if options
|
||||
puts @table.data_str(vms, options)
|
||||
else
|
||||
puts @table.data_str(vms)
|
||||
end
|
||||
|
||||
result
|
||||
command :create, create_desc, :file do
|
||||
helper.create_resource(options) do |image|
|
||||
template=File.read(args[0])
|
||||
image.allocate(template)
|
||||
end
|
||||
end
|
||||
|
||||
def top(options=nil)
|
||||
delay=1
|
||||
delay=options[:delay] if options && options[:delay]
|
||||
|
||||
result=nil
|
||||
|
||||
begin
|
||||
while true
|
||||
scr_cls
|
||||
scr_move(0,0)
|
||||
result=list_short(options)
|
||||
sleep delay
|
||||
end
|
||||
rescue Exception
|
||||
|
||||
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
|
||||
result
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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.persistent
|
||||
end
|
||||
end
|
||||
|
||||
nonpersistent_desc = <<-EOT.unindent
|
||||
Makes the given Image non persistent. See 'oneimage persistent'
|
||||
EOT
|
||||
|
||||
command :nonpersistent, nonpersistent_desc, [:range,:imageid_list] do
|
||||
helper.perform_actions(args[0],options,"made non persistent") do |image|
|
||||
image.nonpersistent
|
||||
end
|
||||
end
|
||||
|
||||
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 :enable, enable_desc, [:range,:imageid_list] do
|
||||
helper.perform_actions(args[0],options,"enabled") do |image|
|
||||
image.enable
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
##########################
|
||||
## COMMAND LINE PARSING ##
|
||||
##########################
|
||||
|
||||
class OneImageParse < CommandParse
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
|
||||
Description:
|
||||
|
||||
This command enables the user to manage images.
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
* register (Registers an image, copying it to the repository if it applies)
|
||||
oneimage register <template>
|
||||
|
||||
template is a file name where the Image description is located
|
||||
|
||||
* addattr (Add a new image attribute)
|
||||
oneimage addattr <image_id> <attribute_name> <attribute_value>
|
||||
|
||||
* update (Lets the user edit and replace the image template)
|
||||
oneimage update <image_id>
|
||||
|
||||
* enable (Enabled an Image)
|
||||
oneimage enable <image_id>
|
||||
|
||||
* disable (Disabled an Image)
|
||||
oneimage disable <image_id>
|
||||
|
||||
* publish (Publish an Image)
|
||||
oneimage publish <image_id>
|
||||
|
||||
* unpublish (Unpublish an Image)
|
||||
oneimage unpublish <image_id>
|
||||
|
||||
* persistent (Makes an Image persistent)
|
||||
oneimage persistent <image_id>
|
||||
|
||||
* nonpersistent (Makes an Image non persistent)
|
||||
oneimage nonpersistent <image_id>
|
||||
|
||||
* chown (Changes the Image owner and group)
|
||||
oneimage chown <image_id> <owner_id> [<group_id>]
|
||||
|
||||
* chgrp (Changes the Image group)
|
||||
oneimage chgrp <image_id> <group_id>
|
||||
|
||||
* list (Shows Images in the pool)
|
||||
oneimage list <filter_flag>
|
||||
|
||||
where filter_flag can be
|
||||
a, all --> all the known Images
|
||||
m, mine --> the Images belonging to the user in ONE_AUTH
|
||||
g, group --> 'mine' plus the Images belonging to the groups
|
||||
the user is member of
|
||||
uid --> Images of the user identified by this uid
|
||||
user --> Images of the user identified by the username
|
||||
|
||||
* top (Lists Images continuously)
|
||||
oneimage top
|
||||
|
||||
* show (Gets information about an specific Image)
|
||||
oneimage show <image_id>
|
||||
|
||||
* delete (Deletes an already deployed Image)
|
||||
oneimage delete <image_id>
|
||||
|
||||
EOT
|
||||
|
||||
def text_commands
|
||||
COMMANDS_HELP
|
||||
end
|
||||
|
||||
def text_command_name
|
||||
"oneimage"
|
||||
end
|
||||
|
||||
def list_options
|
||||
table=ShowTable.new(ShowTableImage)
|
||||
table.print_help
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def get_user_flags
|
||||
ops=Hash.new
|
||||
if ARGV[0]
|
||||
case ARGV[0]
|
||||
when "a", "all"
|
||||
ops[:filter_user]="-2"
|
||||
when "m", "mine"
|
||||
ops[:filter_user]="-3"
|
||||
when "g", "group"
|
||||
ops[:filter_user]="-1"
|
||||
else
|
||||
if !ARGV[0].match(/^[0123456789]+$/)
|
||||
ops[:filter_user]="-2"
|
||||
ops[:filter_flag]=ARGV[0]
|
||||
else
|
||||
ops[:filter_user]=ARGV[0]
|
||||
end
|
||||
end
|
||||
else
|
||||
ops[:filter_user]="-2"
|
||||
end
|
||||
|
||||
ops
|
||||
end
|
||||
|
||||
def get_template(template_path)
|
||||
begin
|
||||
template = File.read(ARGV[0])
|
||||
rescue
|
||||
result = OpenNebula::Error.new("Can not read template: #{ARGV[0]}")
|
||||
end
|
||||
|
||||
if !is_successful?(result)
|
||||
puts result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
return template
|
||||
end
|
||||
|
||||
oneimage_opts=OneImageParse.new
|
||||
oneimage_opts.parse(ARGV)
|
||||
ops=oneimage_opts.options
|
||||
|
||||
result=[false, "Unknown error"]
|
||||
|
||||
command=ARGV.shift
|
||||
|
||||
case command
|
||||
when "register", "create", "add"
|
||||
check_parameters("register", 1)
|
||||
template = get_template(ARGV[0])
|
||||
|
||||
image = OpenNebula::Image.new(OpenNebula::Image.build_xml, get_one_client)
|
||||
|
||||
result = image.allocate(template)
|
||||
if is_successful?(result)
|
||||
puts "ID: " + image.id.to_s if ops[:verbose]
|
||||
end
|
||||
|
||||
when "update"
|
||||
check_parameters("update", 1)
|
||||
image_id=get_image_id(ARGV[0])
|
||||
|
||||
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
rc = image.info
|
||||
if is_successful?(result)
|
||||
file = File.open('/tmp/template', "w")
|
||||
file << image.template_str
|
||||
file.close
|
||||
|
||||
system "vim /tmp/template"
|
||||
str = File.read('/tmp/test')
|
||||
|
||||
result = image.update( str )
|
||||
|
||||
if is_successful?(result)
|
||||
puts "Modified image" if ops[:verbose]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
when "enable"
|
||||
check_parameters("enable", 1)
|
||||
image_id=get_image_id(ARGV[0])
|
||||
|
||||
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
|
||||
result=image.enable
|
||||
if is_successful?(result)
|
||||
puts "Image enabled" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "disable"
|
||||
check_parameters("disable", 1)
|
||||
image_id=get_image_id(ARGV[0])
|
||||
|
||||
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
|
||||
result=image.disable
|
||||
if is_successful?(result)
|
||||
puts "Image disabled" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "publish"
|
||||
check_parameters("publish", 1)
|
||||
image_id=get_image_id(ARGV[0])
|
||||
|
||||
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
|
||||
result=image.publish
|
||||
if is_successful?(result)
|
||||
puts "Image published" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "unpublish"
|
||||
check_parameters("unpublish", 1)
|
||||
image_id=get_image_id(ARGV[0])
|
||||
|
||||
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
|
||||
result=image.unpublish
|
||||
if is_successful?(result)
|
||||
puts "Image unpublished" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "persistent"
|
||||
check_parameters("publish", 1)
|
||||
image_id=get_image_id(ARGV[0])
|
||||
|
||||
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
|
||||
result=image.persistent
|
||||
if is_successful?(result)
|
||||
puts "Image made persistent" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "nonpersistent"
|
||||
check_parameters("nonpersistent", 1)
|
||||
image_id=get_image_id(ARGV[0])
|
||||
|
||||
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
|
||||
result=image.nonpersistent
|
||||
if is_successful?(result)
|
||||
puts "Image made nonpersistent" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "chown"
|
||||
check_parameters("chown", 2)
|
||||
|
||||
image_id = get_image_id(ARGV[0])
|
||||
new_uid = ARGV[1].to_i
|
||||
new_gid = ( ARGV.length > 2 ) ? ARGV[2].to_i : -1
|
||||
|
||||
image = OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
|
||||
result = image.chown( new_uid, new_gid )
|
||||
if is_successful?(result)
|
||||
puts "Image user/group changed" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "chgrp"
|
||||
check_parameters("chgrp", 2)
|
||||
|
||||
image_id = get_image_id(ARGV[0])
|
||||
new_uid = -1
|
||||
new_gid = ARGV[1].to_i
|
||||
|
||||
image = OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
|
||||
result = image.chown( new_uid, new_gid )
|
||||
if is_successful?(result)
|
||||
puts "Image group changed" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "list"
|
||||
ops.merge!(get_user_flags)
|
||||
if !ops[:xml]
|
||||
imagelist=ImageShow.new(get_one_client, ops[:filter_user].to_i)
|
||||
ops[:columns]=ops[:list] if ops[:list]
|
||||
result=imagelist.list_short(ops)
|
||||
else
|
||||
imagepool=OpenNebula::ImagePool.new(get_one_client,
|
||||
ops[:filter_user].to_i)
|
||||
imagepool.info
|
||||
puts imagepool.to_xml
|
||||
end
|
||||
|
||||
when "top"
|
||||
ops.merge!(get_user_flags)
|
||||
imagelist=ImageShow.new(get_one_client, ops[:filter_user].to_i)
|
||||
ops[:columns]=ops[:list] if ops[:list]
|
||||
result=imagelist.top(ops)
|
||||
|
||||
when "show"
|
||||
check_parameters("get_info", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
image_id=get_image_id(param)
|
||||
|
||||
image=OpenNebula::Image.new_with_id(image_id, get_one_client)
|
||||
result = image.info
|
||||
|
||||
if is_successful?(result)
|
||||
if !ops[:xml]
|
||||
str="%-15s: %-20s"
|
||||
str_h1="%-80s"
|
||||
|
||||
print_header(str_h1, "IMAGE #{image[:id]} INFORMATION", true)
|
||||
|
||||
puts str % ["ID", image.id.to_s]
|
||||
puts str % ["NAME", image.name]
|
||||
puts str % ["TYPE", image.type_str]
|
||||
|
||||
value=image['REGTIME'].to_i
|
||||
if value==0
|
||||
value='-'
|
||||
else
|
||||
value=Time.at(value).strftime("%m/%d %H:%M:%S")
|
||||
end
|
||||
puts str % ["REGISTER TIME", value]
|
||||
if image['PUBLIC'].to_i == 1
|
||||
public_str = "Yes"
|
||||
else
|
||||
public_str = "No"
|
||||
end
|
||||
puts str % ["PUBLIC", public_str]
|
||||
|
||||
persistent_str=(image["PERSISTENT"].to_i==1 ? "Yes" : "No")
|
||||
puts str % ["PERSISTENT", persistent_str]
|
||||
|
||||
puts str % ["SOURCE", image['SOURCE']]
|
||||
puts str % ["STATE", image.short_state_str]
|
||||
puts str % ["RUNNING_VMS", image['RUNNING_VMS']]
|
||||
|
||||
puts
|
||||
|
||||
print_header(str_h1,"IMAGE TEMPLATE",false)
|
||||
|
||||
puts image.template_str
|
||||
else
|
||||
puts image.to_xml
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
when "delete"
|
||||
check_parameters("delete", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
image_id = get_image_id(param)
|
||||
image = OpenNebula::Image.new(
|
||||
OpenNebula::Image.build_xml(image_id),
|
||||
get_one_client)
|
||||
|
||||
result = image.delete
|
||||
if is_successful?(result)
|
||||
puts "Image correctly deleted" if ops[:verbose]
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
oneimage_opts.print_help
|
||||
exit -1
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(result)
|
||||
puts "Error: " + result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
|
||||
|
@ -25,429 +25,166 @@ else
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'command_parser'
|
||||
require 'one_helper/onetemplate_helper'
|
||||
|
||||
require 'OpenNebula'
|
||||
require 'CommandManager'
|
||||
require 'client_utilities'
|
||||
require 'command_parse'
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
usage "onetemplate COMMAND [args..] [options..]"
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
ShowTableTemplate={
|
||||
:id => {
|
||||
:name => "ID",
|
||||
:desc => "ONE identifier for the Template",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e| d.id }
|
||||
},
|
||||
:user=> {
|
||||
:name => "USER",
|
||||
:desc => "Name of the owner",
|
||||
:size => 8,
|
||||
:proc => lambda {|d,e|
|
||||
"TODO"
|
||||
}
|
||||
},
|
||||
:uid=> {
|
||||
:name => "UID",
|
||||
:desc => "Id of the owner",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d["UID"]
|
||||
}
|
||||
},
|
||||
:gid=> {
|
||||
:name => "GID",
|
||||
:desc => "Id of the group",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d.gid
|
||||
}
|
||||
},
|
||||
:name => {
|
||||
:name => "NAME",
|
||||
:desc => "Name of the Template",
|
||||
:size => 20,
|
||||
:proc => lambda {|d,e|
|
||||
d.name
|
||||
}
|
||||
},
|
||||
:regtime => {
|
||||
:name => "REGTIME",
|
||||
:desc => "Registration time of the Template",
|
||||
:size => 20,
|
||||
:proc => lambda {|d,e|
|
||||
str_register_time(d)
|
||||
}
|
||||
},
|
||||
:public => {
|
||||
:name => "PUBLIC",
|
||||
:desc => "Whether the Template is public or not",
|
||||
:size => 3,
|
||||
:proc => lambda {|d,e|
|
||||
if d["PUBLIC"].to_i == 1 then "Yes" else "No" end}
|
||||
},
|
||||
helper = OneTemplateHelper.new
|
||||
|
||||
:default => [:id, :user, :name, :regtime, :public]
|
||||
}
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
set :option, CommandParser::OPTIONS
|
||||
|
||||
list_options = CLIHelper::OPTIONS
|
||||
list_options << OpenNebulaHelper::XML
|
||||
list_options << OpenNebulaHelper::NUMERIC
|
||||
|
||||
|
||||
|
||||
class TemplateShow
|
||||
|
||||
def initialize(client, filter_flag="-2")
|
||||
@templatepool=OpenNebula::TemplatePool.new(client, filter_flag.to_i)
|
||||
@table=ShowTable.new(ShowTableTemplate)
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
set :format, :groupid, OpenNebulaHelper.name_to_id_desc("GROUP") do |arg|
|
||||
OpenNebulaHelper.name_to_id(arg, "GROUP")
|
||||
end
|
||||
|
||||
def header_template_small
|
||||
scr_bold
|
||||
scr_underline
|
||||
print @table.header_str
|
||||
scr_restore
|
||||
puts ""
|
||||
set :format, :userid, OpenNebulaHelper.name_to_id_desc("USER") do |arg|
|
||||
OpenNebulaHelper.name_to_id(arg, "USER")
|
||||
end
|
||||
|
||||
def top(options=nil)
|
||||
delay=1
|
||||
delay=options[:delay] if options && options[:delay]
|
||||
set :format, :templateid, OneTemplateHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
result=nil
|
||||
set :format, :templateid_list, OneTemplateHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
begin
|
||||
while true
|
||||
scr_cls
|
||||
scr_move(0,0)
|
||||
result=list_short(options)
|
||||
sleep delay
|
||||
end
|
||||
rescue Exception
|
||||
set :format, :filterflag, OneTemplateHelper.filterflag_to_i_desc do |arg|
|
||||
helper.filterflag_to_i(arg)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
|
||||
create_desc = <<-EOT.unindent
|
||||
Creates a new Template from the given template file
|
||||
EOT
|
||||
|
||||
command :create, create_desc, :file do
|
||||
helper.create_resource(options) do |t|
|
||||
template=File.read(args[0])
|
||||
t.allocate(template)
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
def list_short(options=nil)
|
||||
res=@templatepool.info()
|
||||
delete_desc = <<-EOT.unindent
|
||||
Deletes the given Image
|
||||
EOT
|
||||
|
||||
if options
|
||||
@table.columns=options[:columns] if options[:columns]
|
||||
command :delete, delete_desc, [:range, :templateid_list] do
|
||||
helper.perform_actions(args[0],options,"deleted") do |t|
|
||||
t.delete
|
||||
end
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(res)
|
||||
result=res
|
||||
puts res.message
|
||||
exit -1
|
||||
else
|
||||
instantiate_desc = <<-EOT.unindent
|
||||
Creates a new VM instance from the given Template. This VM can be
|
||||
managed with the 'onevm' command
|
||||
EOT
|
||||
|
||||
if options[:filter_flag]
|
||||
objs=@templatepool.select{|element|
|
||||
element['USERNAME']==options[:filter_flag] }
|
||||
else
|
||||
objs=@templatepool
|
||||
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
|
||||
|
||||
result=[true, ""]
|
||||
header_template_small
|
||||
|
||||
if options
|
||||
puts @table.data_str(objs, options)
|
||||
else
|
||||
puts @table.data_str(objs)
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
##########################
|
||||
## COMMAND LINE PARSING ##
|
||||
##########################
|
||||
|
||||
class OneTemplateParse < CommandParse
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
|
||||
Description:
|
||||
|
||||
This command enables the user to manage templates.
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
* create (Registers a Template from a template file)
|
||||
onetemplate create <file>
|
||||
|
||||
file is a file name where the Template description is located
|
||||
|
||||
* instantiate (Creates a VM instance from a Template)
|
||||
onetemplate instantiate <template_id>
|
||||
|
||||
* update (Lets the user edit and replace the Template contents)
|
||||
onetemplate update <template_id>
|
||||
|
||||
* publish (Publish a Template)
|
||||
onetemplate publish <template_id>
|
||||
|
||||
* unpublish (Unpublish an Template)
|
||||
onetemplate unpublish <template_id>
|
||||
|
||||
* chown (Changes the Template owner and group)
|
||||
onetemplate chown <template_id> <owner_id> [<group_id>]
|
||||
|
||||
* chgrp (Changes the Template group)
|
||||
onetemplate chgrp <template_id> <group_id>
|
||||
|
||||
* list (Shows Templates in the pool)
|
||||
onetemplate list <filter_flag>
|
||||
|
||||
where filter_flag can be
|
||||
a, all --> all the known Templates
|
||||
m, mine --> the Templates belonging to the user in ONE_AUTH
|
||||
g, group --> 'mine' plus the Templates belonging to the groups
|
||||
the user is member of
|
||||
uid --> Templates of the user identified by this uid
|
||||
user --> Templates of the user identified by the username
|
||||
|
||||
* top (Lists Templates continuously)
|
||||
onetemplate top
|
||||
|
||||
* show (Gets information about an specific Template)
|
||||
onetemplate show <template_id>
|
||||
|
||||
* delete (Deletes a Template)
|
||||
onetemplate delete <template_id>
|
||||
|
||||
EOT
|
||||
|
||||
def text_commands
|
||||
COMMANDS_HELP
|
||||
end
|
||||
|
||||
def text_command_name
|
||||
"onetemplate"
|
||||
end
|
||||
|
||||
def list_options
|
||||
table=ShowTable.new(ShowTableTemplate)
|
||||
table.print_help
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def get_user_flags
|
||||
ops=Hash.new
|
||||
if ARGV[0]
|
||||
case ARGV[0]
|
||||
when "a", "all"
|
||||
ops[:filter_user]="-2"
|
||||
when "m", "mine"
|
||||
ops[:filter_user]="-3"
|
||||
when "g", "group"
|
||||
ops[:filter_user]="-1"
|
||||
else
|
||||
if !ARGV[0].match(/^[0123456789]+$/)
|
||||
ops[:filter_user]="-2"
|
||||
ops[:filter_flag]=ARGV[0]
|
||||
else
|
||||
ops[:filter_user]=ARGV[0]
|
||||
end
|
||||
end
|
||||
else
|
||||
ops[:filter_user]="-2"
|
||||
end
|
||||
|
||||
ops
|
||||
end
|
||||
|
||||
def get_template(template_path)
|
||||
begin
|
||||
template = File.read(ARGV[0])
|
||||
rescue
|
||||
result = OpenNebula::Error.new("Can not read template: #{ARGV[0]}")
|
||||
end
|
||||
|
||||
if !is_successful?(result)
|
||||
puts result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
return template
|
||||
end
|
||||
|
||||
onetemplate_opts=OneTemplateParse.new
|
||||
onetemplate_opts.parse(ARGV)
|
||||
ops=onetemplate_opts.options
|
||||
|
||||
result=[false, "Unknown error"]
|
||||
|
||||
command=ARGV.shift
|
||||
|
||||
case command
|
||||
when "create", "register", "add"
|
||||
check_parameters("create", 1)
|
||||
template_contents = get_template(ARGV[0])
|
||||
|
||||
template = OpenNebula::Template.new(OpenNebula::Template.build_xml, get_one_client)
|
||||
|
||||
result=template.allocate(template_contents)
|
||||
if !OpenNebula.is_error?(result)
|
||||
puts "ID: " + template.id.to_s if ops[:verbose]
|
||||
exit 0
|
||||
end
|
||||
|
||||
when "instantiate"
|
||||
check_parameters("instantiate", 1)
|
||||
template_id = get_template_id(ARGV[0])
|
||||
|
||||
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
|
||||
|
||||
result = template.instantiate
|
||||
if is_successful?(result)
|
||||
puts "Template instantiated." if ops[:verbose]
|
||||
end
|
||||
|
||||
when "update"
|
||||
puts "TODO"
|
||||
|
||||
when "publish"
|
||||
check_parameters("publish", 1)
|
||||
template_id = get_template_id(ARGV[0])
|
||||
|
||||
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
|
||||
|
||||
result = template.publish
|
||||
if is_successful?(result)
|
||||
puts "Template published" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "unpublish"
|
||||
check_parameters("unpublish", 1)
|
||||
template_id = get_template_id(ARGV[0])
|
||||
|
||||
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
|
||||
|
||||
result = template.unpublish
|
||||
if is_successful?(result)
|
||||
puts "Template unpublished" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "chown"
|
||||
check_parameters("chown", 2)
|
||||
|
||||
obj_id = get_template_id(ARGV[0])
|
||||
new_uid = ARGV[1].to_i
|
||||
new_gid = ( ARGV.length > 2 ) ? ARGV[2].to_i : -1
|
||||
|
||||
obj = OpenNebula::Template.new_with_id(obj_id, get_one_client)
|
||||
|
||||
result = obj.chown( new_uid, new_gid )
|
||||
if is_successful?(result)
|
||||
puts "Template user/group changed" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "chgrp"
|
||||
check_parameters("chgrp", 2)
|
||||
|
||||
obj_id = get_template_id(ARGV[0])
|
||||
new_uid = -1
|
||||
new_gid = ARGV[1].to_i
|
||||
|
||||
obj = OpenNebula::Template.new_with_id(obj_id, get_one_client)
|
||||
|
||||
result = obj.chown( new_uid, new_gid )
|
||||
if is_successful?(result)
|
||||
puts "Template group changed" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "list"
|
||||
ops.merge!(get_user_flags)
|
||||
if !ops[:xml]
|
||||
templatelist = TemplateShow.new(get_one_client, ops[:filter_user].to_i)
|
||||
ops[:columns] = ops[:list] if ops[:list]
|
||||
result = templatelist.list_short(ops)
|
||||
else
|
||||
templatepool = OpenNebula::TemplatePool.new(get_one_client,
|
||||
ops[:filter_user].to_i)
|
||||
templatepool.info
|
||||
puts templatepool.to_xml
|
||||
end
|
||||
|
||||
when "top"
|
||||
ops.merge!(get_user_flags)
|
||||
templatelist = TemplateShow.new(get_one_client, ops[:filter_user].to_i)
|
||||
ops[:columns] = ops[:list] if ops[:list]
|
||||
result = templatelist.top(ops)
|
||||
|
||||
when "show"
|
||||
check_parameters("get_info", 1)
|
||||
args = expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
template_id = get_template_id(param)
|
||||
|
||||
template = OpenNebula::Template.new_with_id(template_id, get_one_client)
|
||||
result = template.info
|
||||
|
||||
if is_successful?(result)
|
||||
if !ops[:xml]
|
||||
str="%-15s: %-20s"
|
||||
str_h1="%-80s"
|
||||
|
||||
print_header(str_h1, "TEMPLATE #{template[:id]} INFORMATION", true)
|
||||
|
||||
puts str % ["ID", template.id.to_s]
|
||||
puts str % ["NAME", template.name]
|
||||
|
||||
value = template['REGTIME'].to_i
|
||||
if value==0
|
||||
value='-'
|
||||
else
|
||||
value=Time.at(value).strftime("%m/%d %H:%M:%S")
|
||||
end
|
||||
puts str % ["REGISTER TIME", value]
|
||||
if template['PUBLIC'].to_i == 1
|
||||
public_str = "Yes"
|
||||
else
|
||||
public_str = "No"
|
||||
end
|
||||
puts str % ["PUBLIC", public_str]
|
||||
|
||||
puts
|
||||
|
||||
print_header(str_h1,"TEMPLATE CONTENTS",false)
|
||||
|
||||
puts template.template_str
|
||||
else
|
||||
puts template.to_xml
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
when "delete"
|
||||
check_parameters("delete", 1)
|
||||
args = expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
template_id = get_template_id(param)
|
||||
template = OpenNebula::Template.new(
|
||||
OpenNebula::Template.build_xml(template_id),
|
||||
get_one_client)
|
||||
|
||||
result = template.delete
|
||||
if is_successful?(result)
|
||||
puts "Template correctly deleted" if ops[:verbose]
|
||||
res
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
onetemplate_opts.print_help
|
||||
exit -1
|
||||
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
|
||||
|
||||
list_desc = <<-EOT.unindent
|
||||
Lists Templates in the pool
|
||||
EOT
|
||||
|
||||
command :list, list_desc, [:filterflag, nil], :options=>list_options do
|
||||
helper.list_pool(options)
|
||||
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
|
||||
|
||||
top_desc = <<-EOT.unindent
|
||||
Lists Templates continuously
|
||||
EOT
|
||||
|
||||
command :top, top_desc, [:filterflag, nil], :options=>list_options do
|
||||
helper.list_pool(options, true)
|
||||
end
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(result)
|
||||
puts "Error: " + result.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
|
||||
|
428
src/cli/oneuser
428
src/cli/oneuser
@ -25,311 +25,143 @@ else
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'command_parser'
|
||||
require 'one_helper/oneuser_helper'
|
||||
|
||||
require 'OpenNebula'
|
||||
require 'client_utilities'
|
||||
require 'command_parse'
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
usage "oneuser COMMAND [args..] [options..]"
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
helper = OneUserHelper.new
|
||||
|
||||
ShowTableUP={
|
||||
:id => {
|
||||
:name => "ID",
|
||||
:desc => "ONE identifier for user",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e| d.id }
|
||||
},
|
||||
:gid=> {
|
||||
:name => "GID",
|
||||
:desc => "Id of the group",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d.gid
|
||||
}
|
||||
},
|
||||
:user => {
|
||||
:name => "USER",
|
||||
:desc => "name of the user",
|
||||
:size => 15,
|
||||
:left => true,
|
||||
:proc => lambda {|d,e| d.name }
|
||||
},
|
||||
:password => {
|
||||
:name => "PASSWORD",
|
||||
:desc => "password of the user",
|
||||
:size => 50,
|
||||
:left => true,
|
||||
:proc => lambda {|d,e| d['PASSWORD'] }
|
||||
},
|
||||
|
||||
:default => [:id, :gid, :user, :password]
|
||||
}
|
||||
|
||||
class UPShow
|
||||
def initialize
|
||||
@userpool=OpenNebula::UserPool.new(get_one_client)
|
||||
@table=ShowTable.new(ShowTableUP)
|
||||
end
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
set :option, CommandParser::OPTIONS
|
||||
|
||||
def header_up_small
|
||||
scr_bold
|
||||
scr_underline
|
||||
print @table.header_str
|
||||
scr_restore
|
||||
puts ""
|
||||
end
|
||||
list_options = CLIHelper::OPTIONS
|
||||
list_options << OpenNebulaHelper::XML
|
||||
list_options << OpenNebulaHelper::NUMERIC
|
||||
|
||||
def list_short(options=nil)
|
||||
res=@userpool.info
|
||||
if options
|
||||
@table.columns=options[:columns] if options[:columns]
|
||||
end
|
||||
READ_FILE={
|
||||
:name => "read_file",
|
||||
:short => "-r",
|
||||
:large => "--read-file",
|
||||
:description => "Read password from file"
|
||||
}
|
||||
|
||||
if OpenNebula.is_error?(res)
|
||||
result=res
|
||||
else
|
||||
result=res
|
||||
header_up_small
|
||||
|
||||
puts @table.data_str(@userpool, options)
|
||||
result
|
||||
PLAIN={
|
||||
:name => "plain",
|
||||
:short => "-p",
|
||||
:large => "--plain-password",
|
||||
:description => "Store plain password"
|
||||
}
|
||||
|
||||
create_options = [READ_FILE, PLAIN]
|
||||
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
set :format, :groupid, OpenNebulaHelper.name_to_id_desc("GROUP") do |arg|
|
||||
OpenNebulaHelper.name_to_id(arg, "GROUP")
|
||||
end
|
||||
|
||||
set :format, :userid, OneUserHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :userid_list, OneUserHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :password, OneUserHelper.password_to_str_desc do |arg|
|
||||
OneUserHelper.password_to_str(arg, options)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
class OneUPParse < CommandParse
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
|
||||
Description:
|
||||
|
||||
This command enables the OpenNebula administrator to manage users, adding,
|
||||
listing and deleting them.
|
||||
|
||||
The create and passwd commands accept the [-r, --read-file] option. Use this
|
||||
option to store the contents of a file (without hashing it) as the password.
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
* create (Creates a new user)
|
||||
oneuser create username password
|
||||
|
||||
* delete (Removes a user)
|
||||
oneuser delete <id>
|
||||
|
||||
* list (Lists all the users in the pool)
|
||||
oneuser list
|
||||
|
||||
* passwd (Changes the given user's password)
|
||||
oneuser passwd <id> password
|
||||
|
||||
* chgrp (Changes the User group)
|
||||
oneuser chgrp <id> <group_id>
|
||||
|
||||
* addgroup (Adds a secondary group)
|
||||
oneuser addgroup <id> <group_id>
|
||||
|
||||
* delgroup (Deletes a secondary group. Fails if the group is the main one)
|
||||
oneuser delgroup <id> <group_id>
|
||||
|
||||
Information Columns:
|
||||
|
||||
* UID User ID
|
||||
* NAME Name of the user
|
||||
* PASSWORD SHA1 encrypted password
|
||||
* ENABLE Whether the user is enabled or not
|
||||
|
||||
|
||||
EOT
|
||||
|
||||
def text_commands
|
||||
COMMANDS_HELP
|
||||
end
|
||||
|
||||
def text_command_name
|
||||
"oneuser"
|
||||
end
|
||||
|
||||
def list_options
|
||||
table=ShowTable.new(ShowTableUP)
|
||||
table.print_help
|
||||
end
|
||||
|
||||
def special_options(opts, options)
|
||||
opts.on_tail("-n", "--no-hash", "Store plain password "<<
|
||||
"into the database") do |o|
|
||||
options[:no_hash]=true
|
||||
end
|
||||
opts.on_tail("-r", "--read-file", "Read password from file") do |o|
|
||||
options[:read_file]=true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
oneup_opts=OneUPParse.new([:list, :xml])
|
||||
oneup_opts.parse(ARGV)
|
||||
ops=oneup_opts.options
|
||||
|
||||
result=[false, "Unknown error"]
|
||||
|
||||
command=ARGV.shift
|
||||
|
||||
case command
|
||||
when "create"
|
||||
check_parameters("create", 2)
|
||||
user=OpenNebula::User.new(
|
||||
OpenNebula::User.build_xml, get_one_client)
|
||||
|
||||
if ops[:read_file]
|
||||
begin
|
||||
password = File.read(ARGV[1]).split("\n").first
|
||||
rescue
|
||||
puts "Can not read file: #{ARGV[1]}"
|
||||
exit -1
|
||||
end
|
||||
else
|
||||
if ops[:no_hash]
|
||||
password = ARGV[1].gsub(/\s/, '')
|
||||
else
|
||||
password = Digest::SHA1.hexdigest(ARGV[1])
|
||||
end
|
||||
end
|
||||
|
||||
result=user.allocate(ARGV[0], password)
|
||||
if !OpenNebula.is_error?(result)
|
||||
puts "ID: " + user.id.to_s if ops[:verbose]
|
||||
exit 0
|
||||
end
|
||||
|
||||
when "delete"
|
||||
check_parameters("delete", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
user_id=get_user_id(param)
|
||||
|
||||
# Check if the user has defined VM's
|
||||
vms=false
|
||||
vmpool=OpenNebula::VirtualMachinePool.new(
|
||||
get_one_client, user_id.to_i)
|
||||
vmpool.info
|
||||
vmpool.each{ vms=true ; break }
|
||||
|
||||
if vms
|
||||
puts "The user #{param} still has VMs defined, "+
|
||||
"aborting user delete."
|
||||
exit -1
|
||||
end
|
||||
|
||||
# Check if the user has defined VN's
|
||||
vns=false
|
||||
vnpool=OpenNebula::VirtualNetworkPool.new(
|
||||
get_one_client, user_id.to_i)
|
||||
|
||||
vnpool.info
|
||||
vnpool.each{ vns=true ; break }
|
||||
|
||||
if vns
|
||||
puts "The user #{param} still has Virtual Networks defined, "+
|
||||
"aborting user delete."
|
||||
exit -1
|
||||
end
|
||||
|
||||
user=OpenNebula::User.new(
|
||||
OpenNebula::User.build_xml(user_id), get_one_client)
|
||||
result=user.delete
|
||||
if !OpenNebula.is_error?(result)
|
||||
puts "User deleted" if ops[:verbose]
|
||||
end
|
||||
end
|
||||
|
||||
when "passwd"
|
||||
check_parameters("passwd", 2)
|
||||
|
||||
user_id=get_user_id(ARGV[0])
|
||||
|
||||
user=OpenNebula::User.new_with_id(user_id, get_one_client)
|
||||
|
||||
if ops[:read_file]
|
||||
begin
|
||||
password = File.read(ARGV[1]).split("\n").first
|
||||
rescue
|
||||
puts "Can not read file: #{ARGV[1]}"
|
||||
exit -1
|
||||
end
|
||||
else
|
||||
if ops[:no_hash]
|
||||
password = ARGV[1].gsub(/\s/, '')
|
||||
else
|
||||
password = Digest::SHA1.hexdigest(ARGV[1])
|
||||
end
|
||||
end
|
||||
result=user.passwd(password)
|
||||
|
||||
if !OpenNebula.is_error?(result)
|
||||
puts "Password changed" if ops[:verbose]
|
||||
else
|
||||
puts
|
||||
end
|
||||
|
||||
when "chgrp"
|
||||
check_parameters("chgrp", 2)
|
||||
|
||||
obj_id = get_user_id(ARGV[0])
|
||||
new_gid = ARGV[1].to_i
|
||||
|
||||
obj = OpenNebula::User.new_with_id(obj_id, get_one_client)
|
||||
|
||||
result = obj.chgrp( new_gid )
|
||||
if is_successful?(result)
|
||||
puts "User group changed" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "addgroup"
|
||||
check_parameters("addgroup", 2)
|
||||
|
||||
obj_id = get_user_id(ARGV[0])
|
||||
new_gid = ARGV[1].to_i
|
||||
|
||||
obj = OpenNebula::User.new_with_id(obj_id, get_one_client)
|
||||
|
||||
result = obj.addgroup( new_gid )
|
||||
if is_successful?(result)
|
||||
puts "User group added" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "delgroup"
|
||||
check_parameters("delgroup", 2)
|
||||
|
||||
obj_id = get_user_id(ARGV[0])
|
||||
new_gid = ARGV[1].to_i
|
||||
|
||||
obj = OpenNebula::User.new_with_id(obj_id, get_one_client)
|
||||
|
||||
result = obj.delgroup( new_gid )
|
||||
if is_successful?(result)
|
||||
puts "User group deleted" if ops[:verbose]
|
||||
end
|
||||
|
||||
|
||||
when "list"
|
||||
if !ops[:xml]
|
||||
uplist=UPShow.new
|
||||
ops[:columns]=ops[:list] if ops[:list]
|
||||
result=uplist.list_short(ops)
|
||||
else
|
||||
userpool=OpenNebula::UserPool.new(get_one_client)
|
||||
userpool.info
|
||||
puts userpool.to_xml(true)
|
||||
end
|
||||
|
||||
else
|
||||
oneup_opts.print_help
|
||||
exit -1
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(result)
|
||||
puts "Error: " + result.message
|
||||
exit -1
|
||||
|
||||
delete_desc = <<-EOT.unindent
|
||||
Deletes the given User
|
||||
EOT
|
||||
|
||||
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
|
||||
gid = args[1]
|
||||
|
||||
helper.perform_actions(args[0],options,"group added") do |user|
|
||||
user.addgroup( gid )
|
||||
end
|
||||
end
|
||||
|
||||
delgroup_desc = <<-EOT.unindent
|
||||
Removes the User from a secondary group
|
||||
EOT
|
||||
|
||||
command :delgroup, delgroup_desc, [:range, :userid_list], :groupid do
|
||||
gid = args[1]
|
||||
|
||||
helper.perform_actions(args[0],options,"group deleted") do |user|
|
||||
user.delgroup( gid )
|
||||
end
|
||||
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
|
||||
helper.show_resource(args[0],options)
|
||||
end
|
||||
|
||||
end
|
||||
|
1041
src/cli/onevm
1041
src/cli/onevm
File diff suppressed because it is too large
Load Diff
517
src/cli/onevnet
517
src/cli/onevnet
@ -25,395 +25,148 @@ else
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'command_parser'
|
||||
require 'one_helper/onevnet_helper'
|
||||
|
||||
require 'OpenNebula'
|
||||
require 'client_utilities'
|
||||
require 'command_parse'
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
usage "onevnet COMMAND [args..] [options..]"
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
helper = OneVNetHelper.new
|
||||
|
||||
ShowTableVN={
|
||||
:id => {
|
||||
:name => "ID",
|
||||
:desc => "ONE identifier for virtual network",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e| d.id }
|
||||
},
|
||||
:name => {
|
||||
:name => "NAME",
|
||||
:desc => "name of the virtual network",
|
||||
:size => 15,
|
||||
:left => true,
|
||||
:proc => lambda {|d,e| d.name }
|
||||
},
|
||||
:user => {
|
||||
:name => "USER",
|
||||
:desc => "Username of the virtual network owner",
|
||||
:size => 8,
|
||||
:left => true,
|
||||
:proc => lambda {|d,e| "TODO" }
|
||||
},
|
||||
:uid=> {
|
||||
:name => "UID",
|
||||
:desc => "Id of the owner",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d["UID"]
|
||||
}
|
||||
},
|
||||
:gid=> {
|
||||
:name => "GID",
|
||||
:desc => "Id of the group",
|
||||
:size => 4,
|
||||
:proc => lambda {|d,e|
|
||||
d.gid
|
||||
}
|
||||
},
|
||||
:type => {
|
||||
:name => "TYPE",
|
||||
:desc => "NType of virtual network",
|
||||
:size => 6,
|
||||
:proc => lambda {|d,e|
|
||||
if(d["TYPE"] == "0")
|
||||
return "Ranged"
|
||||
else
|
||||
if (d["TYPE"] == "1")
|
||||
return "Fixed"
|
||||
end
|
||||
end
|
||||
}
|
||||
},
|
||||
:size => {
|
||||
:name => "SIZE",
|
||||
:desc => "Number of hosts (free + used) in the virtual network",
|
||||
:size => 6,
|
||||
:proc => lambda {|d,e| d["SIZE"] }
|
||||
},
|
||||
:bridge => {
|
||||
:name => "BRIDGE",
|
||||
:desc => "Bridge associated to the virtual network",
|
||||
:size => 6,
|
||||
:proc => lambda {|d,e| d["BRIDGE"] }
|
||||
},
|
||||
:public => {
|
||||
:name => "PUBLIC",
|
||||
:desc => "Whether the Image is public or not",
|
||||
:size => 1,
|
||||
:proc => lambda {|d,e| if d["PUBLIC"].to_i == 1 then "Y" else "N" end}
|
||||
},
|
||||
:totalleases => {
|
||||
:name => "#LEASES",
|
||||
:desc => "Number of this virtual network's given leases",
|
||||
:size => 7,
|
||||
:proc => lambda {|d,e| d["TOTAL_LEASES"] }
|
||||
},
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
set :option, CommandParser::OPTIONS
|
||||
|
||||
:default => [:id, :user, :name, :type, :bridge, :public, :totalleases]
|
||||
}
|
||||
|
||||
class VNShow
|
||||
def initialize(filter_flag="-2")
|
||||
@vnpool=OpenNebula::VirtualNetworkPool.new(get_one_client,
|
||||
filter_flag.to_i)
|
||||
@table=ShowTable.new(ShowTableVN)
|
||||
########################################################################
|
||||
# Formatters for arguments
|
||||
########################################################################
|
||||
set :format, :groupid, OpenNebulaHelper.name_to_id_desc("GROUP") do |arg|
|
||||
OpenNebulaHelper.name_to_id(arg, "GROUP")
|
||||
end
|
||||
|
||||
def header_vn_small
|
||||
scr_bold
|
||||
scr_underline
|
||||
print @table.header_str
|
||||
scr_restore
|
||||
puts ""
|
||||
end
|
||||
|
||||
def list_short(options=nil)
|
||||
res=@vnpool.info
|
||||
if options
|
||||
@table.columns=options[:columns] if options[:columns]
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(res)
|
||||
result=res
|
||||
else
|
||||
result=res
|
||||
header_vn_small
|
||||
if options[:filter_flag]
|
||||
vns=@vnpool.select{|element|
|
||||
element["USERNAME"]==options[:filter_flag]
|
||||
}
|
||||
else
|
||||
vns=@vnpool
|
||||
end
|
||||
puts @table.data_str(vns, options)
|
||||
result
|
||||
set :format, :userid, OpenNebulaHelper.name_to_id_desc("USER") do |arg|
|
||||
OpenNebulaHelper.name_to_id(arg, "USER")
|
||||
end
|
||||
|
||||
set :format, :vnetid, OneVNetHelper.to_id_desc do |arg|
|
||||
helper.to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :vnetid_list, OneVNetHelper.list_to_id_desc do |arg|
|
||||
helper.list_to_id(arg)
|
||||
end
|
||||
|
||||
set :format, :filterflag, OneVNetHelper.filterflag_to_i_desc do |arg|
|
||||
helper.filterflag_to_i(arg)
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
addleases_desc = <<-EOT.unindent
|
||||
Adds a lease to the Virtual Network
|
||||
EOT
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
class OneVNParse < CommandParse
|
||||
|
||||
COMMANDS_HELP=<<-EOT
|
||||
|
||||
Description:
|
||||
|
||||
This command enables the user to manage virtual networks in the OpenNebula
|
||||
server. It provides functionality to create, get information and delete a
|
||||
particular network or to list available and used IP's.
|
||||
|
||||
|
||||
Commands:
|
||||
|
||||
* create (Creates a new virtual network)
|
||||
onevnet create <template>
|
||||
|
||||
template is a filename where the virtual network is described
|
||||
|
||||
* show (Gets info from a virtual network)
|
||||
onevnet show <network_id>
|
||||
|
||||
* publish (Publish a virtual network)
|
||||
onevnet publish <network_id>
|
||||
|
||||
* unpublish (Unpublish a virtual network)
|
||||
onevnet unpublish <network_id>
|
||||
|
||||
* delete (Removes a virtual network)
|
||||
onevnet delete <network_id>
|
||||
|
||||
* addleases (Adds a lease to the virtual network)
|
||||
onevnet addleases <network_id> <IP> [<MAC>]
|
||||
|
||||
* rmleases (Removes a lease fom the virtual network)
|
||||
onevnet rmleases <network_id> <IP>
|
||||
|
||||
* chown (Changes the virtual network owner and group)
|
||||
onevnet chown <network_id> <owner_id> [<group_id>]
|
||||
|
||||
* chgrp (Changes the virtual network group)
|
||||
onevnet chgrp <network_id> <group_id>
|
||||
|
||||
* list (Lists virtual networks in the pool)
|
||||
onevnet list <filter_flag>
|
||||
|
||||
where filter_flag can be
|
||||
a, all --> all the known VNets
|
||||
m, mine --> the VNets belonging to the user in ONE_AUTH
|
||||
g, group --> 'mine' plus the VNets belonging to the groups
|
||||
the user is member of
|
||||
uid --> VNets of the user identified by this uid
|
||||
user --> VNets of the user identified by the username
|
||||
|
||||
Information columns:
|
||||
|
||||
* NID Network ID
|
||||
* NAME Name of the virtual network
|
||||
* TYPE Type of virtual network (0=ranged, 1=fixed)
|
||||
* BRIDGE Bridge associated to the virtual network
|
||||
* LEASES Number of leases used from this virtual network
|
||||
|
||||
EOT
|
||||
|
||||
def text_commands
|
||||
COMMANDS_HELP
|
||||
end
|
||||
|
||||
def text_command_name
|
||||
"onevnet"
|
||||
end
|
||||
|
||||
def list_options
|
||||
table=ShowTable.new(ShowTableVN)
|
||||
table.print_help
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
onevn_opts=OneVNParse.new([:list, :xml])
|
||||
onevn_opts.parse(ARGV)
|
||||
ops=onevn_opts.options
|
||||
|
||||
result=[false, "Unknown error"]
|
||||
|
||||
command=ARGV.shift
|
||||
|
||||
case command
|
||||
when "create"
|
||||
check_parameters("create", 1)
|
||||
vn=OpenNebula::VirtualNetwork.new(
|
||||
OpenNebula::VirtualNetwork.build_xml, get_one_client)
|
||||
template=File.read(ARGV[0])
|
||||
result=vn.allocate(template)
|
||||
if !OpenNebula.is_error?(result)
|
||||
puts "ID: " + vn.id.to_s if ops[:verbose]
|
||||
exit 0
|
||||
end
|
||||
|
||||
when "show"
|
||||
check_parameters("show", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
vn_id=get_vn_id(param)
|
||||
vn=OpenNebula::VirtualNetwork.new_with_id(vn_id, get_one_client)
|
||||
result=vn.info
|
||||
if is_successful?(result)
|
||||
if !ops[:xml]
|
||||
str_h1="%-80s"
|
||||
str="%-10s: %-20s"
|
||||
print_header(str_h1,
|
||||
"VIRTUAL NETWORK #{vn.id.to_s} INFORMATION",true)
|
||||
|
||||
puts str % ["ID: ",vn.id.to_s]
|
||||
puts str % ["UID: ",vn["UID"]]
|
||||
if vn['PUBLIC'].to_i == 1
|
||||
public_str = "Y"
|
||||
else
|
||||
public_str = "N"
|
||||
end
|
||||
puts str % ["PUBLIC", public_str]
|
||||
puts
|
||||
print_header(str_h1,"VIRTUAL NETWORK TEMPLATE",false)
|
||||
|
||||
puts vn.template_str(false)
|
||||
|
||||
leases_str = vn.template_like_str('/VNET/LEASES', false)
|
||||
|
||||
if !leases_str.empty?
|
||||
puts
|
||||
print_header(str_h1,"LEASES INFORMATION",false)
|
||||
puts leases_str
|
||||
end
|
||||
else
|
||||
puts vn.to_xml(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
when "publish"
|
||||
check_parameters("publish", 1)
|
||||
vn_id=get_vn_id(ARGV[0])
|
||||
|
||||
vn=OpenNebula::VirtualNetwork.new_with_id(vn_id, get_one_client)
|
||||
|
||||
result=vn.publish
|
||||
if is_successful?(result)
|
||||
puts "VirtualNetwork published" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "unpublish"
|
||||
check_parameters("unpublish", 1)
|
||||
vn_id=get_vn_id(ARGV[0])
|
||||
|
||||
vn=OpenNebula::VirtualNetwork.new_with_id(vn_id, get_one_client)
|
||||
|
||||
result=vn.unpublish
|
||||
if is_successful?(result)
|
||||
puts "VirtualNetwork unpublished" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "delete"
|
||||
check_parameters("delete", 1)
|
||||
args=expand_args(ARGV)
|
||||
|
||||
args.each do |param|
|
||||
vn_id=get_vn_id(param)
|
||||
vn=OpenNebula::VirtualNetwork.new(
|
||||
OpenNebula::VirtualNetwork.build_xml(vn_id), get_one_client)
|
||||
result=vn.delete
|
||||
if !OpenNebula.is_error?(result)
|
||||
puts "Virtual Network deleted" if ops[:verbose]
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
when "addleases"
|
||||
check_parameters("addleases", 2)
|
||||
vn_id = get_vn_id(ARGV[0])
|
||||
|
||||
vn = OpenNebula::VirtualNetwork.new_with_id(vn_id, get_one_client)
|
||||
|
||||
result = vn.addleases(ARGV[1], ARGV[2])
|
||||
if is_successful?(result)
|
||||
puts "Leases added" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "rmleases"
|
||||
check_parameters("rmleases", 2)
|
||||
vn_id = get_vn_id(ARGV[0])
|
||||
|
||||
vn = OpenNebula::VirtualNetwork.new_with_id(vn_id, get_one_client)
|
||||
|
||||
result = vn.rmleases(ARGV[1])
|
||||
if is_successful?(result)
|
||||
puts "Leases removed" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "chown"
|
||||
check_parameters("chown", 2)
|
||||
|
||||
obj_id = get_vn_id(ARGV[0])
|
||||
new_uid = ARGV[1].to_i
|
||||
new_gid = ( ARGV.length > 2 ) ? ARGV[2].to_i : -1
|
||||
|
||||
obj = OpenNebula::VirtualNetwork.new_with_id(obj_id, get_one_client)
|
||||
|
||||
result = obj.chown( new_uid, new_gid )
|
||||
if is_successful?(result)
|
||||
puts "Virtual Network user/group changed" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "chgrp"
|
||||
check_parameters("chgrp", 2)
|
||||
|
||||
obj_id = get_vn_id(ARGV[0])
|
||||
new_uid = -1
|
||||
new_gid = ARGV[1].to_i
|
||||
|
||||
obj = OpenNebula::VirtualNetwork.new_with_id(obj_id, get_one_client)
|
||||
|
||||
result = obj.chown( new_uid, new_gid )
|
||||
if is_successful?(result)
|
||||
puts "Virtual Network group changed" if ops[:verbose]
|
||||
end
|
||||
|
||||
when "list"
|
||||
if ARGV[0]
|
||||
case ARGV[0]
|
||||
when "a", "all"
|
||||
filter_flag="-2"
|
||||
when "m", "mine"
|
||||
filter_flag="-3"
|
||||
when "g", "group"
|
||||
filter_flag="-1"
|
||||
else
|
||||
if !ARGV[0].match(/^[0123456789]+$/)
|
||||
filter_flag="-2"
|
||||
ops[:filter_flag]=ARGV[0]
|
||||
else
|
||||
filter_flag=ARGV[0]
|
||||
end
|
||||
end
|
||||
else
|
||||
filter_flag="-2"
|
||||
end
|
||||
|
||||
if !ops[:xml]
|
||||
vnlist=VNShow.new(filter_flag)
|
||||
ops[:columns]=ops[:list] if ops[:list]
|
||||
result=vnlist.list_short(ops)
|
||||
else
|
||||
vnpool=OpenNebula::VirtualNetworkPool.new(get_one_client,
|
||||
filter_flag.to_i)
|
||||
vnpool.info
|
||||
puts vnpool.to_xml(true)
|
||||
end
|
||||
|
||||
else
|
||||
onevn_opts.print_help
|
||||
exit -1
|
||||
end
|
||||
|
||||
if OpenNebula.is_error?(result)
|
||||
puts "Error: " + result.message
|
||||
exit -1
|
||||
end
|
||||
|
@ -31,6 +31,13 @@ module OpenNebula
|
||||
:chown => "vn.chown"
|
||||
}
|
||||
|
||||
NETWORK_TYPES=%w{RANGED FIXED}
|
||||
|
||||
SHORT_NETWORK_TYPES={
|
||||
"RANGED" => "R",
|
||||
"FIXED" => "F"
|
||||
}
|
||||
|
||||
# Creates a VirtualNetwork description with just its identifier
|
||||
# this method should be used to create plain VirtualNetwork objects.
|
||||
# +id+ the id of the network
|
||||
@ -130,6 +137,21 @@ module OpenNebula
|
||||
self['GID'].to_i
|
||||
end
|
||||
|
||||
# Returns the type of the Virtual Network (numeric value)
|
||||
def type
|
||||
self['TYPE'].to_i
|
||||
end
|
||||
|
||||
# Returns the type of the Virtual Network (string value)
|
||||
def type_str
|
||||
NETWORK_TYPES[type]
|
||||
end
|
||||
|
||||
# Returns the state of the Virtual Network (string value)
|
||||
def short_type_str
|
||||
SHORT_NETWORK_TYPES[type_str]
|
||||
end
|
||||
|
||||
private
|
||||
def set_publish(published)
|
||||
return Error.new('ID not defined') if !@pe_id
|
||||
|
@ -15,16 +15,16 @@
|
||||
|
||||
require "rexml/document"
|
||||
|
||||
class Migrator < MigratorBase
|
||||
module Migrator
|
||||
def db_version
|
||||
1
|
||||
end
|
||||
|
||||
def initialize(db, verbose)
|
||||
super(db, verbose)
|
||||
@db_version = 1
|
||||
@one_version = "OpenNebula 2.3.0"
|
||||
def one_version
|
||||
"OpenNebula 2.3.0"
|
||||
end
|
||||
|
||||
def up
|
||||
|
||||
########################################################################
|
||||
# Users
|
||||
########################################################################
|
||||
|
206
src/onedb/onedb
Executable file
206
src/onedb/onedb
Executable file
@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2011, 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
|
||||
ETC_LOCATION="/etc/one/"
|
||||
VAR_LOCATION="/var/lib/one"
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
|
||||
ETC_LOCATION=ONE_LOCATION+"/etc/"
|
||||
VAR_LOCATION="#{ONE_LOCATION}/var"
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+'/onedb'
|
||||
|
||||
require 'cli/command_parser'
|
||||
require 'onedb'
|
||||
|
||||
FORCE={
|
||||
:name => "force",
|
||||
:short => "-f",
|
||||
:large => "--force",
|
||||
:description => "Forces the backup even if the DB exists"
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# SQLite options
|
||||
###############################################################################
|
||||
SQLITE={
|
||||
:name => "sqlite",
|
||||
:short => "-s file",
|
||||
:large => "--sqlite file",
|
||||
:format => String,
|
||||
:description => "SQLite DB file",
|
||||
:proc => lambda { |o, options|
|
||||
options[:backend] = :sqlite
|
||||
options[:sqlite] = o
|
||||
}
|
||||
}
|
||||
|
||||
###############################################################################
|
||||
# MySQL options
|
||||
###############################################################################
|
||||
SERVER={
|
||||
:name => "server",
|
||||
:short => "-S host",
|
||||
:large => "--server host",
|
||||
:format => String,
|
||||
:description => "MySQL server hostname or IP. Defaults to localhost",
|
||||
:proc => lambda { |o, options|
|
||||
options[:backend] = :mysql
|
||||
options[:server] = o
|
||||
}
|
||||
}
|
||||
|
||||
PORT={
|
||||
:name => "port",
|
||||
:short => "-P port",
|
||||
:large => "--port port",
|
||||
:format => String,
|
||||
:description => "MySQL server port. Defaults to 3306",
|
||||
:proc => lambda { |o, options|
|
||||
options[:backend] = :mysql
|
||||
options[:port] = o
|
||||
}
|
||||
}
|
||||
|
||||
USERNAME={
|
||||
:name => "username",
|
||||
:short => "-u user",
|
||||
:large => "--username user",
|
||||
:format => String,
|
||||
:description => "MySQL username",
|
||||
:proc => lambda { |o, options|
|
||||
options[:backend] = :mysql
|
||||
options[:username] = o
|
||||
}
|
||||
}
|
||||
|
||||
PASSWORD={
|
||||
:name => "password",
|
||||
:short => "-p pass",
|
||||
:large => "--password pass",
|
||||
:format => String,
|
||||
:description => "MySQL password. Leave unset to be prompted for it",
|
||||
:proc => lambda { |o, options|
|
||||
options[:backend] = :mysql
|
||||
options[:password] = o
|
||||
}
|
||||
}
|
||||
|
||||
DBNAME={
|
||||
:name => "dbname",
|
||||
:short => "-d dbname",
|
||||
:large => "--dbname dbname",
|
||||
:format => String,
|
||||
:description => "MySQL DB name for OpenNebula",
|
||||
:proc => lambda { |o, options|
|
||||
options[:backend] = :mysql
|
||||
options[:dbname] = o
|
||||
}
|
||||
}
|
||||
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
description <<-EOT.unindent
|
||||
DB Connection options:
|
||||
|
||||
By default, onedb reads the connection data from oned.conf
|
||||
If any of these options is set, oned.conf is ignored (i.e. if you set
|
||||
MySQL's port onedb won't look for the rest of the options in oned.conf)
|
||||
|
||||
Description:
|
||||
|
||||
This command enables the user to manage the OpenNebula database. It
|
||||
provides information about the DB version, means to upgrade it to the
|
||||
latest version, and backup tools.
|
||||
EOT
|
||||
|
||||
###########################################################################
|
||||
# Global options
|
||||
###########################################################################
|
||||
set :option, CommandParser::OPTIONS
|
||||
set :option, [SQLITE, SERVER, PORT, USERNAME, PASSWORD, DBNAME]
|
||||
|
||||
###########################################################################
|
||||
# Backup
|
||||
###########################################################################
|
||||
backup_desc = <<-EOT.unindent
|
||||
Dumps the DB to a file specified in the argument
|
||||
EOT
|
||||
|
||||
command :backup, backup_desc, [:output_file, nil], :options=>FORCE do
|
||||
helper = OneDB.new(options)
|
||||
helper.backup(args[0], options)
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Version
|
||||
###########################################################################
|
||||
version_desc = <<-EOT.unindent
|
||||
Prints the current DB version.
|
||||
Use -v flag to see also OpenNebula version
|
||||
EOT
|
||||
|
||||
command :version , version_desc do
|
||||
helper = OneDB.new(options)
|
||||
helper.version(options)
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# History
|
||||
###########################################################################
|
||||
history_desc = <<-EOT.unindent
|
||||
Prints the upgrades history
|
||||
EOT
|
||||
|
||||
command :history , history_desc do
|
||||
helper = OneDB.new(options)
|
||||
helper.history
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Restore
|
||||
###########################################################################
|
||||
restore_desc = <<-EOT.unindent
|
||||
Restores the DB from a backup file. Only restores backups generated
|
||||
from the same backend (SQLite or MySQL)
|
||||
EOT
|
||||
|
||||
command :restore , restore_desc, [:backup_file, nil], :options=>FORCE do
|
||||
helper = OneDB.new(options)
|
||||
helper.restore(args[0], options)
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Upgrade
|
||||
###########################################################################
|
||||
upgrade_desc = <<-EOT.unindent
|
||||
Upgrades the DB to the latest version
|
||||
where <version> : DB version (e.g. 1, 3) to upgrade.
|
||||
By default the DB is upgraded to the latest version
|
||||
EOT
|
||||
|
||||
command :upgrade , upgrade_desc, [:version, nil] do
|
||||
helper = OneDB.new(options)
|
||||
helper.upgrade(args[0], options)
|
||||
end
|
||||
end
|
180
src/onedb/onedb.rb
Normal file
180
src/onedb/onedb.rb
Normal file
@ -0,0 +1,180 @@
|
||||
ONE_LOCATION = ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
LIB_LOCATION = "/usr/lib/one"
|
||||
RUBY_LIB_LOCATION = LIB_LOCATION + "/ruby"
|
||||
VAR_LOCATION = "/var/lib/one"
|
||||
ETC_LOCATION = "/etc/one"
|
||||
LOCK_FILE = "/var/lock/one/one"
|
||||
else
|
||||
LIB_LOCATION = ONE_LOCATION + "/lib"
|
||||
RUBY_LIB_LOCATION = LIB_LOCATION + "/ruby"
|
||||
VAR_LOCATION = ONE_LOCATION + "/var"
|
||||
ETC_LOCATION = ONE_LOCATION + "/etc"
|
||||
LOCK_FILE = VAR_LOCATION + "/.lock"
|
||||
end
|
||||
|
||||
require 'cloud/Configuration'
|
||||
require 'onedb_backend'
|
||||
|
||||
class OneDB
|
||||
def initialize(ops)
|
||||
if ops[:backend]==nil
|
||||
@backend = from_onedconf
|
||||
else
|
||||
if ops[:backend] == :sqlite
|
||||
@backend = BackEndSQLite.new(ops[:sqlite])
|
||||
else
|
||||
passwd = ops[:passwd]
|
||||
if !passwd
|
||||
# Hide input characters
|
||||
`stty -echo`
|
||||
print "MySQL Password: "
|
||||
passwd = STDIN.gets.strip
|
||||
`stty echo`
|
||||
puts ""
|
||||
end
|
||||
|
||||
@backend = BackEndMySQL.new(
|
||||
:server => ops[:server],
|
||||
:port => ops[:port],
|
||||
:user => ops[:user],
|
||||
:passwd => passwd,
|
||||
:db_name => ops[:db_name]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def backup(bck_file, ops)
|
||||
bck_file = @backend.bck_file if bck_file.nil?
|
||||
|
||||
if !ops[:force] && File.exists?(bck_file)
|
||||
puts "File #{bck_file} exists, backup aborted. Use -f to overwrite."
|
||||
exit -1
|
||||
end
|
||||
|
||||
@backend.backup(bck_file)
|
||||
end
|
||||
|
||||
def restore(bck_file, ops)
|
||||
bck_file = @backend.bck_file if bck_file.nil?
|
||||
|
||||
if !File.exists?(bck_file)
|
||||
puts "File #{bck_file} doesn't exist, backup restoration aborted."
|
||||
exit -1
|
||||
end
|
||||
|
||||
one_not_running
|
||||
|
||||
@backend.restore(bck_file, ops[:force])
|
||||
end
|
||||
|
||||
def version(ops)
|
||||
version, timestamp, comment = @backend.read_db_version
|
||||
|
||||
if(ops[:verbose])
|
||||
puts "Version: #{version}"
|
||||
|
||||
time = version == 0 ? Time.now : Time.at(timestamp)
|
||||
puts "Timestamp: #{time.strftime("%m/%d %H:%M:%S")}"
|
||||
puts "Comment: #{comment}"
|
||||
else
|
||||
puts version
|
||||
end
|
||||
end
|
||||
|
||||
def history
|
||||
@backend.history
|
||||
end
|
||||
|
||||
def upgrade(max_version, ops)
|
||||
version, timestamp, comment = @backend.read_db_version
|
||||
|
||||
if ops[:verbose]
|
||||
puts "Version read:"
|
||||
puts "#{version} : #{comment}"
|
||||
puts ""
|
||||
end
|
||||
|
||||
migrator_version = version + 1
|
||||
result = nil
|
||||
file = "#{LIB_LOCATION}/onedb/#{migrator_version}.rb"
|
||||
|
||||
if File.exists?(file) &&
|
||||
(max_version == nil || migrator_version <= max_version)
|
||||
# At least one upgrade will be executed, make DB backup
|
||||
if ops[:backup]
|
||||
bck_file = ops[:backup]
|
||||
else
|
||||
bck_file = @backend.bck_file(VAR_LOCATION)
|
||||
end
|
||||
|
||||
@backend.backup(bck_file)
|
||||
end
|
||||
|
||||
while File.exists?(file) &&
|
||||
(max_version == nil || migrator_version <= max_version)
|
||||
|
||||
puts " > Running migrator #{file}" if ops[:verbose]
|
||||
|
||||
load(file)
|
||||
@backend.extend Migrator
|
||||
result = @backend.up
|
||||
|
||||
if !result
|
||||
puts "Error while upgrading from #{migrator_version-1} to " <<
|
||||
" #{@backend.db_version}"
|
||||
return -1
|
||||
end
|
||||
|
||||
puts " > Done" if ops[:verbose]
|
||||
puts "" if ops[:verbose]
|
||||
|
||||
migrator_version += 1
|
||||
file = "#{LIB_LOCATION}/onedb/#{migrator_version}.rb"
|
||||
end
|
||||
|
||||
# Modify db_versioning table
|
||||
if result != nil
|
||||
@backend.update_db_version(version)
|
||||
else
|
||||
puts "Database already uses version #{version}"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def from_onedconf()
|
||||
config = Configuration.new("#{ETC_LOCATION}/oned.conf")
|
||||
|
||||
if config[:db] == nil
|
||||
puts "No DB defined."
|
||||
exit -1
|
||||
end
|
||||
|
||||
if config[:db]["BACKEND"].upcase.include? "SQLITE"
|
||||
sqlite_file = "#{VAR_LOCATION}/one.db"
|
||||
@backend = BackEndSQLite.new(sqlite_file)
|
||||
elsif config[:db]["BACKEND"].upcase.include? "MYSQL"
|
||||
@backend = BackEndMySQL.new(
|
||||
:server => config[:db]["SERVER"],
|
||||
:port => config[:db]["PORT"],
|
||||
:user => config[:db]["USER"],
|
||||
:passwd => config[:db]["PASSWD"],
|
||||
:db_name => config[:db]["DB_NAME"]
|
||||
)
|
||||
else
|
||||
puts "Could not load DB configuration from " <<
|
||||
"#{ETC_LOCATION}/oned.conf"
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
def one_not_running()
|
||||
if File.exists?(LOCK_FILE)
|
||||
puts "First stop OpenNebula. Lock file found: #{LOCK_FILE}"
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
end
|
235
src/onedb/onedb_backend.rb
Normal file
235
src/onedb/onedb_backend.rb
Normal file
@ -0,0 +1,235 @@
|
||||
require 'rubygems'
|
||||
require 'sequel'
|
||||
|
||||
class OneDBBacKEnd
|
||||
def read_db_version
|
||||
connect_db
|
||||
|
||||
version = 0
|
||||
timestamp = 0
|
||||
comment = ""
|
||||
|
||||
@db.fetch("SELECT version, timestamp, comment FROM db_versioning " +
|
||||
"WHERE oid=(SELECT MAX(oid) FROM db_versioning)") do |row|
|
||||
version = row[:version]
|
||||
timestamp = row[:timestamp]
|
||||
comment = row[:comment]
|
||||
end
|
||||
|
||||
return [version.to_i, timestamp, comment]
|
||||
|
||||
rescue
|
||||
# If the DB doesn't have db_version table, it means it is empty or a 2.x
|
||||
if !db_exists?
|
||||
puts "Database schema does not look to be created by OpenNebula:"
|
||||
puts "table user_pool is missing or empty."
|
||||
exit -1
|
||||
end
|
||||
|
||||
begin
|
||||
# Table image_pool is present only in 2.X DBs
|
||||
@db.fetch("SELECT * FROM image_pool") { |row| }
|
||||
rescue
|
||||
puts "Database schema looks to be created by OpenNebula 1.X."
|
||||
puts "This tool only works with databases created by 2.X versions."
|
||||
exit -1
|
||||
end
|
||||
|
||||
comment = "Could not read any previous db_versioning data, " <<
|
||||
"assuming it is an OpenNebula 2.0 or 2.2 DB."
|
||||
|
||||
return [0, 0, comment]
|
||||
end
|
||||
|
||||
def history
|
||||
connect_db
|
||||
|
||||
begin
|
||||
query = "SELECT version, timestamp, comment FROM db_versioning"
|
||||
@db.fetch(query) do |row|
|
||||
puts "Version: #{row[:version]}"
|
||||
|
||||
time = Time.at(row[:timestamp])
|
||||
puts "Timestamp: #{time.strftime("%m/%d %H:%M:%S")}"
|
||||
|
||||
puts "Comment: #{row[:comment]}"
|
||||
|
||||
puts ""
|
||||
end
|
||||
rescue Exception => e
|
||||
puts "No version records found. Error message:"
|
||||
puts e.message
|
||||
end
|
||||
end
|
||||
|
||||
def update_db_version(version)
|
||||
comment = "Database migrated from #{version} to #{db_version}"+
|
||||
" (#{one_version}) by onedb command."
|
||||
|
||||
max_oid = nil
|
||||
@db.fetch("SELECT MAX(oid) FROM db_versioning") do |row|
|
||||
max_oid = row[:"MAX(oid)"].to_i
|
||||
end
|
||||
|
||||
max_oid = 0 if max_oid.nil?
|
||||
|
||||
query =
|
||||
@db.run(
|
||||
"INSERT INTO db_versioning (oid, version, timestamp, comment) "<<
|
||||
"VALUES (" <<
|
||||
"#{max_oid+1}, " <<
|
||||
"'#{db_version}', " <<
|
||||
"#{Time.new.to_i}, " <<
|
||||
"'#{comment}')"
|
||||
)
|
||||
|
||||
puts comment
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def db_exists?
|
||||
begin
|
||||
# User with ID 0 (oneadmin) always exists
|
||||
@db.fetch("SELECT * FROM user_pool WHERE oid=0") { |row| }
|
||||
return true
|
||||
rescue
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class OneDBBackEndMySQL < OneDBBacKEnd
|
||||
def initialize(opts={})
|
||||
@server = ops[:server]
|
||||
@port = ops[:port]
|
||||
@user = ops[:user]
|
||||
@passwd = ops[:passwd]
|
||||
@db_name = ops[:db_name]
|
||||
|
||||
# Check for errors:
|
||||
error = false
|
||||
|
||||
(error = true; missing = "USER" ) if @user == nil
|
||||
(error = true; missing = "DBNAME") if @db_name == nil
|
||||
|
||||
if error
|
||||
puts "MySQL option #{missing} is needed"
|
||||
exit -1
|
||||
end
|
||||
|
||||
# Check for defaults:
|
||||
@server = "localhost" if @server.nil?
|
||||
@port = 0 if @port.nil?
|
||||
|
||||
# Clean leading and trailing quotes, if any
|
||||
@server = @server [1..-2] if @server [0] == ?"
|
||||
@port = @port [1..-2] if @port [0] == ?"
|
||||
@user = @user [1..-2] if @user [0] == ?"
|
||||
@passwd = @passwd [1..-2] if @passwd [0] == ?"
|
||||
@db_name = @db_name[1..-2] if @db_name[0] == ?"
|
||||
end
|
||||
|
||||
def bck_file(var_location)
|
||||
"#{var_location}/mysql_#{@server}_#{@db_name}.sql"
|
||||
end
|
||||
|
||||
def backup(bck_file)
|
||||
cmd = "mysqldump -u #{@user} -p#{@passwd} -h #{@server} " +
|
||||
"-P #{@port} #{@db_name} > #{bck_file}"
|
||||
|
||||
rc = system(cmd)
|
||||
if !rc
|
||||
puts "Unknown error running '#{cmd}'"
|
||||
exit -1
|
||||
end
|
||||
|
||||
puts "MySQL dump stored in #{bck_file}"
|
||||
puts "Use 'onedb restore' or restore the DB using the mysql command:"
|
||||
puts "mysql -u user -h server -P port db_name < backup_file"
|
||||
end
|
||||
|
||||
def restore(bck_file, force=nil)
|
||||
connect_db
|
||||
|
||||
if !force && db_exists?
|
||||
puts "MySQL database #{@db_name} at #{@server} exists," <<
|
||||
" use -f to overwrite."
|
||||
exit -1
|
||||
end
|
||||
|
||||
mysql_cmd = "mysql -u #{@user} -p#{@passwd} -h #{@server} -P #{@port} "
|
||||
|
||||
drop_cmd = mysql_cmd + "-e 'DROP DATABASE IF EXISTS #{@db_name};'"
|
||||
rc = system(drop_cmd)
|
||||
if !rc
|
||||
puts "Error dropping MySQL DB #{@db_name} at #{@server}."
|
||||
exit -1
|
||||
end
|
||||
|
||||
create_cmd = mysql_cmd+"-e 'CREATE DATABASE IF NOT EXISTS #{@db_name};'"
|
||||
rc = system(create_cnd)
|
||||
if !rc
|
||||
puts "Error creating MySQL DB #{@db_name} at #{@server}."
|
||||
exit -1
|
||||
end
|
||||
|
||||
restore_cmd = mysql_cmd + "#{@db_name} < #{bck_file}"
|
||||
rc = system(restore_cmd)
|
||||
if !rc
|
||||
puts "Error while restoring MySQL DB #{@db_name} at #{@server}."
|
||||
exit -1
|
||||
end
|
||||
|
||||
puts "MySQL DB #{@db_name} at #{@server} restored."
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def connect_db
|
||||
endpoint = "mysql://#{@user}:#{@passwd}@#{@server}:#{@port}/#{@db_name}"
|
||||
@db = Sequel.connect(endpoint)
|
||||
end
|
||||
end
|
||||
|
||||
class BackEndSQLite < OneDBBacKEnd
|
||||
def initialize(file)
|
||||
@sqlite_file = file
|
||||
end
|
||||
|
||||
def bck_file(var_location)
|
||||
"#{var_location}/one.db.bck"
|
||||
end
|
||||
|
||||
def backup(bck_file)
|
||||
if !File.exists?(@sqlite_file)
|
||||
puts "File #{@sqlite_file} doesn't exist, backup aborted."
|
||||
exit -1
|
||||
end
|
||||
|
||||
FileUtils.cp(@sqlite_file, "#{bck_file}")
|
||||
puts "Sqlite database backup stored in #{bck_file}"
|
||||
puts "Use 'onedb restore' or copy the file back to restore the DB."
|
||||
end
|
||||
|
||||
def restore(bck_file, force=nil)
|
||||
if !force && File.exists?(@sqlite_file)
|
||||
puts "File #{@sqlite_file} exists, use -f to overwrite."
|
||||
exit -1
|
||||
end
|
||||
|
||||
FileUtils.cp(bck_file, @sqlite_file)
|
||||
puts "Sqlite database backup restored in #{@sqlite_file}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def connect_db
|
||||
if !File.exists?(@sqlite_file)
|
||||
puts "File #{@sqlite_file} doesn't exist."
|
||||
exit -1
|
||||
end
|
||||
|
||||
@db = Sequel.sqlite(@sqlite_file)
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user