diff --git a/NOTICE b/NOTICE
index 49f4ba2871..badbb70770 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,6 +1,8 @@
OpenNebula Open Source Project
+--------------------------------------------------------------------------------
Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org)
------------------------------------------
+Copyright 2010-2011, C12G Labs S.L. (C12G.com)
+--------------------------------------------------------------------------------
You can find more information about the project, release notes and
documentation at www.OpenNebula.org
@@ -20,6 +22,8 @@ The following people have contributed to the development of the technology
- Daniel Molina Aranda (dmolina@opennebula.org)
- Hector Sanjuan Redondo (hsanjuan@opennebula.org)
+OpenNebula Project also acknowledges the contributions of C12G Labs developers.
+
LICENSE
OpenNebula is licensed under the Apache License, Version 2.0 (the
diff --git a/SConstruct b/SConstruct
index 506738d5e5..678ff0dc7e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -189,6 +189,7 @@ build_scripts=[
'src/host/SConstruct',
'src/group/SConstruct',
'src/mad/SConstruct',
+ 'src/mad/utils/SConstruct',
'src/nebula/SConstruct',
'src/pool/SConstruct',
'src/vm/SConstruct',
diff --git a/include/ImageManager.h b/include/ImageManager.h
index 509a25f7d2..59e3f744ef 100644
--- a/include/ImageManager.h
+++ b/include/ImageManager.h
@@ -85,6 +85,14 @@ public:
* @return pointer to the image or 0 if could not be acquired
*/
Image * acquire_image(int image_id);
+
+ /**
+ * Try to acquire an image from the repository for a VM.
+ * @param name of the image
+ * @param id of owner
+ * @return pointer to the image or 0 if could not be acquired
+ */
+ Image * acquire_image(const string& name, int uid);
/**
* Releases an image and triggers any needed operations in the repo
diff --git a/include/ImagePool.h b/include/ImagePool.h
index 7eab479ddf..a19337a7a9 100644
--- a/include/ImagePool.h
+++ b/include/ImagePool.h
@@ -135,7 +135,6 @@ public:
* @return 0 on success,
* -1 error,
* -2 not using the pool,
- * -3 deprecated NAME found
*/
int disk_attribute(VectorAttribute * disk,
int disk_id,
diff --git a/include/VirtualNetworkPool.h b/include/VirtualNetworkPool.h
index 6dc2ef2c1e..8dc90e290d 100644
--- a/include/VirtualNetworkPool.h
+++ b/include/VirtualNetworkPool.h
@@ -94,8 +94,7 @@ public:
* @param vid of the VM requesting the lease
* @return 0 on success,
* -1 error,
- * -2 not using the pool,
- * -3 unsupported NETWORK attribute
+ * -2 not using the pool
*/
int nic_attribute(VectorAttribute * nic, int uid, int vid);
@@ -165,6 +164,19 @@ private:
{
return new VirtualNetwork(-1,-1,"","",0);
};
+
+ /**
+ * Function to get a VirtualNetwork by its name, as provided by a VM
+ * template
+ */
+ VirtualNetwork * get_nic_by_name(VectorAttribute * nic,
+ const string& name,
+ int _uid);
+
+ /**
+ * Function to get a VirtualNetwork by its id, as provided by a VM template
+ */
+ VirtualNetwork * get_nic_by_id(const string& id_s);
};
#endif /*VIRTUAL_NETWORK_POOL_H_*/
diff --git a/install.sh b/install.sh
index e24347fdb8..6fb7f2bcfe 100755
--- a/install.sh
+++ b/install.sh
@@ -180,14 +180,13 @@ fi
SHARE_DIRS="$SHARE_LOCATION/examples \
$SHARE_LOCATION/examples/tm"
-ETC_DIRS="$ETC_LOCATION/im_kvm \
- $ETC_LOCATION/im_xen \
- $ETC_LOCATION/im_ec2 \
+ETC_DIRS="$ETC_LOCATION/im_ec2 \
$ETC_LOCATION/vmm_ec2 \
$ETC_LOCATION/vmm_exec \
$ETC_LOCATION/tm_shared \
$ETC_LOCATION/tm_ssh \
$ETC_LOCATION/tm_dummy \
+ $ETC_LOCATION/tm_vmware \
$ETC_LOCATION/tm_lvm \
$ETC_LOCATION/hm \
$ETC_LOCATION/auth \
@@ -210,6 +209,7 @@ LIB_DIRS="$LIB_LOCATION/ruby \
$LIB_LOCATION/tm_commands/ssh \
$LIB_LOCATION/tm_commands/dummy \
$LIB_LOCATION/tm_commands/lvm \
+ $LIB_LOCATION/tm_commands/vmware \
$LIB_LOCATION/mads \
$LIB_LOCATION/sh \
$LIB_LOCATION/ruby/cli \
@@ -220,8 +220,8 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/im \
$VAR_LOCATION/remotes/im/kvm.d \
$VAR_LOCATION/remotes/im/xen.d \
+ $VAR_LOCATION/remotes/im/vmware.d \
$VAR_LOCATION/remotes/im/ganglia.d \
- $VAR_LOCATION/remotes/vmm/xen \
$VAR_LOCATION/remotes/vmm/kvm \
$VAR_LOCATION/remotes/vnm \
$VAR_LOCATION/remotes/vnm/802.1Q \
@@ -229,6 +229,8 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/vnm/ebtables \
$VAR_LOCATION/remotes/vnm/fw \
$VAR_LOCATION/remotes/vnm/ovswitch \
+ $VAR_LOCATION/remotes/vmm/xen \
+ $VAR_LOCATION/remotes/vmm/vmware \
$VAR_LOCATION/remotes/hooks \
$VAR_LOCATION/remotes/hooks/ft \
$VAR_LOCATION/remotes/image \
@@ -237,6 +239,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/auth/plain \
$VAR_LOCATION/remotes/auth/ssh \
$VAR_LOCATION/remotes/auth/x509 \
+ $VAR_LOCATION/remotes/auth/ldap \
$VAR_LOCATION/remotes/auth/server_x509 \
$VAR_LOCATION/remotes/auth/server_cipher \
$VAR_LOCATION/remotes/auth/quota \
@@ -253,6 +256,7 @@ SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \
$SUNSTONE_LOCATION/public/vendor/jQueryLayout \
$SUNSTONE_LOCATION/public/vendor/dataTables \
$SUNSTONE_LOCATION/public/vendor/jQueryUI \
+ $SUNSTONE_LOCATION/public/vendor/jQueryUI/images \
$SUNSTONE_LOCATION/public/vendor/jQuery \
$SUNSTONE_LOCATION/public/vendor/jGrowl \
$SUNSTONE_LOCATION/public/vendor/flot \
@@ -270,6 +274,7 @@ OZONES_DIRS="$OZONES_LOCATION/lib \
$OZONES_LOCATION/public/vendor/jQueryLayout \
$OZONES_LOCATION/public/vendor/dataTables \
$OZONES_LOCATION/public/vendor/jQueryUI \
+ $OZONES_LOCATION/public/vendor/jQueryUI/images \
$OZONES_LOCATION/public/vendor/jGrowl \
$OZONES_LOCATION/public/js \
$OZONES_LOCATION/public/js/plugins \
@@ -332,9 +337,11 @@ INSTALL_FILES=(
IM_PROBES_FILES:$VAR_LOCATION/remotes/im
IM_PROBES_KVM_FILES:$VAR_LOCATION/remotes/im/kvm.d
IM_PROBES_XEN_FILES:$VAR_LOCATION/remotes/im/xen.d
+ IM_PROBES_VMWARE_FILES:$VAR_LOCATION/remotes/im/vmware.d
IM_PROBES_GANGLIA_FILES:$VAR_LOCATION/remotes/im/ganglia.d
AUTH_SSH_FILES:$VAR_LOCATION/remotes/auth/ssh
AUTH_X509_FILES:$VAR_LOCATION/remotes/auth/x509
+ AUTH_LDAP_FILES:$VAR_LOCATION/remotes/auth/ldap
AUTH_SERVER_X509_FILES:$VAR_LOCATION/remotes/auth/server_x509
AUTH_SERVER_CIPHER_FILES:$VAR_LOCATION/remotes/auth/server_cipher
AUTH_DUMMY_FILES:$VAR_LOCATION/remotes/auth/dummy
@@ -342,8 +349,10 @@ INSTALL_FILES=(
AUTH_QUOTA_FILES:$VAR_LOCATION/remotes/auth/quota
VMM_EXEC_KVM_SCRIPTS:$VAR_LOCATION/remotes/vmm/kvm
VMM_EXEC_XEN_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen
+ VMM_EXEC_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/vmm/vmware
SHARED_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/shared
SSH_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/ssh
+ VMWARE_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/vmware
DUMMY_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/dummy
LVM_TM_COMMANDS_LIB_FILES:$LIB_LOCATION/tm_commands/lvm
IMAGE_DRIVER_FS_SCRIPTS:$VAR_LOCATION/remotes/image/fs
@@ -412,6 +421,7 @@ INSTALL_SUNSTONE_FILES=(
SUNSTONE_PUBLIC_VENDOR_JGROWL:$SUNSTONE_LOCATION/public/vendor/jGrowl
SUNSTONE_PUBLIC_VENDOR_JQUERY:$SUNSTONE_LOCATION/public/vendor/jQuery
SUNSTONE_PUBLIC_VENDOR_JQUERYUI:$SUNSTONE_LOCATION/public/vendor/jQueryUI
+ SUNSTONE_PUBLIC_VENDOR_JQUERYUIIMAGES:$SUNSTONE_LOCATION/public/vendor/jQueryUI/images
SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT:$SUNSTONE_LOCATION/public/vendor/jQueryLayout
SUNSTONE_PUBLIC_VENDOR_FLOT:$SUNSTONE_LOCATION/public/vendor/flot
SUNSTONE_PUBLIC_IMAGES_FILES:$SUNSTONE_LOCATION/public/images
@@ -437,6 +447,7 @@ INSTALL_OZONES_FILES=(
OZONES_PUBLIC_VENDOR_DATATABLES:$OZONES_LOCATION/public/vendor/dataTables
OZONES_PUBLIC_VENDOR_JGROWL:$OZONES_LOCATION/public/vendor/jGrowl
OZONES_PUBLIC_VENDOR_JQUERYUI:$OZONES_LOCATION/public/vendor/jQueryUI
+ OZONES_PUBLIC_VENDOR_JQUERYUIIMAGES:$OZONES_LOCATION/public/vendor/jQueryUI/images
OZONES_PUBLIC_VENDOR_JQUERYLAYOUT:$OZONES_LOCATION/public/vendor/jQueryLayout
OZONES_PUBLIC_JS_FILES:$OZONES_LOCATION/public/js
OZONES_PUBLIC_IMAGES_FILES:$OZONES_LOCATION/public/images
@@ -455,6 +466,7 @@ INSTALL_OZONES_ETC_FILES=(
INSTALL_ETC_FILES=(
ETC_FILES:$ETC_LOCATION
+ VMWARE_ETC_FILES:$ETC_LOCATION
VMM_EC2_ETC_FILES:$ETC_LOCATION/vmm_ec2
VMM_EXEC_ETC_FILES:$ETC_LOCATION/vmm_exec
IM_EC2_ETC_FILES:$ETC_LOCATION/im_ec2
@@ -462,6 +474,7 @@ INSTALL_ETC_FILES=(
TM_SSH_ETC_FILES:$ETC_LOCATION/tm_ssh
TM_DUMMY_ETC_FILES:$ETC_LOCATION/tm_dummy
TM_LVM_ETC_FILES:$ETC_LOCATION/tm_lvm
+ TM_VMWARE_ETC_FILES:$ETC_LOCATION/tm_vmware
HM_ETC_FILES:$ETC_LOCATION/hm
AUTH_ETC_FILES:$ETC_LOCATION/auth
ECO_ETC_FILES:$ETC_LOCATION
@@ -479,6 +492,7 @@ INSTALL_ETC_FILES=(
BIN_FILES="src/nebula/oned \
src/scheduler/src/sched/mm_sched \
src/cli/onevm \
+ src/cli/oneacct \
src/cli/onehost \
src/cli/onevnet \
src/cli/oneuser \
@@ -488,6 +502,7 @@ BIN_FILES="src/nebula/oned \
src/cli/oneacl \
src/onedb/onedb \
src/authm_mad/remotes/quota/onequota \
+ src/mad/utils/tty_expect \
share/scripts/one"
#-------------------------------------------------------------------------------
@@ -511,12 +526,14 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
src/mad/ruby/ssh_stream.rb \
src/vnm_mad/one_vnm.rb \
src/mad/ruby/Ganglia.rb \
+ src/mad/ruby/vmwarelib.rb \
src/oca/ruby/OpenNebula.rb \
src/tm_mad/TMScript.rb \
src/authm_mad/remotes/ssh/ssh_auth.rb \
src/authm_mad/remotes/quota/quota.rb \
src/authm_mad/remotes/server_x509/server_x509_auth.rb \
src/authm_mad/remotes/server_cipher/server_cipher_auth.rb \
+ src/authm_mad/remotes/ldap/ldap_auth.rb \
src/authm_mad/remotes/x509/x509_auth.rb"
#-----------------------------------------------------------------------------
@@ -587,21 +604,36 @@ VMM_EXEC_XEN_SCRIPTS="src/vmm_mad/remotes/xen/cancel \
src/vmm_mad/remotes/xen/poll_ganglia \
src/vmm_mad/remotes/xen/shutdown"
+#-------------------------------------------------------------------------------
+# VMM Driver VMWARE scripts, to be installed under $REMOTES_LOCATION/vmm/vmware
+#-------------------------------------------------------------------------------
+
+VMM_EXEC_VMWARE_SCRIPTS="src/vmm_mad/remotes/vmware/cancel \
+ src/vmm_mad/remotes/vmware/deploy \
+ src/vmm_mad/remotes/vmware/migrate \
+ src/vmm_mad/remotes/vmware/restore \
+ src/vmm_mad/remotes/vmware/save \
+ src/vmm_mad/remotes/vmware/poll \
+ src/vmm_mad/remotes/vmware/checkpoint \
+ src/vmm_mad/remotes/vmware/shutdown"
+
#-------------------------------------------------------------------------------
# Information Manager Probes, to be installed under $REMOTES_LOCATION/im
#-------------------------------------------------------------------------------
IM_PROBES_FILES="src/im_mad/remotes/run_probes"
-IM_PROBES_XEN_FILES="src/im_mad/remotes/xen.d/xen.rb \
- src/im_mad/remotes/xen.d/architecture.sh \
- src/im_mad/remotes/xen.d/cpu.sh \
- src/im_mad/remotes/xen.d/name.sh"
-
IM_PROBES_KVM_FILES="src/im_mad/remotes/kvm.d/kvm.rb \
- src/im_mad/remotes/kvm.d/architecture.sh \
- src/im_mad/remotes/kvm.d/cpu.sh \
- src/im_mad/remotes/kvm.d/name.sh"
+ src/im_mad/remotes/kvm.d/architecture.sh \
+ src/im_mad/remotes/kvm.d/cpu.sh \
+ src/im_mad/remotes/kvm.d/name.sh"
+
+IM_PROBES_XEN_FILES="src/im_mad/remotes/xen.d/xen.rb \
+ src/im_mad/remotes/xen.d/architecture.sh \
+ src/im_mad/remotes/xen.d/cpu.sh \
+ src/im_mad/remotes/xen.d/name.sh"
+
+IM_PROBES_VMWARE_FILES="src/im_mad/remotes/vmware.d/vmware.rb"
IM_PROBES_GANGLIA_FILES="src/im_mad/remotes/ganglia.d/ganglia_probe"
@@ -615,6 +647,8 @@ AUTH_SERVER_X509_FILES="src/authm_mad/remotes/server_x509/authenticate"
AUTH_X509_FILES="src/authm_mad/remotes/x509/authenticate"
+AUTH_LDAP_FILES="src/authm_mad/remotes/ldap/authenticate"
+
AUTH_SSH_FILES="src/authm_mad/remotes/ssh/authenticate"
AUTH_DUMMY_FILES="src/authm_mad/remotes/dummy/authenticate"
@@ -689,8 +723,12 @@ LVM_TM_COMMANDS_LIB_FILES="src/tm_mad/lvm/tm_clone.sh \
src/tm_mad/lvm/tm_mv.sh \
src/tm_mad/lvm/tm_context.sh"
+VMWARE_TM_COMMANDS_LIB_FILES="src/tm_mad/vmware/tm_clone.sh \
+ src/tm_mad/vmware/tm_ln.sh \
+ src/tm_mad/vmware/tm_mv.sh"
+
#-------------------------------------------------------------------------------
-# Image Repository drivers, to be installed under $REMOTES_LOCTION/image
+# Image Repository drivers, to be installed under $REMOTES_LOCATION/image
# - FS based Image Repository, $REMOTES_LOCATION/image/fs
#-------------------------------------------------------------------------------
IMAGE_DRIVER_FS_SCRIPTS="src/image_mad/remotes/fs/cp \
@@ -719,6 +757,8 @@ ETC_FILES="share/etc/oned.conf \
share/etc/defaultrc \
src/cli/etc/group.default"
+VMWARE_ETC_FILES="src/vmm_mad/remotes/vmware/vmwarerc"
+
#-------------------------------------------------------------------------------
# Virtualization drivers config. files, to be installed under $ETC_LOCATION
# - ec2, $ETC_LOCATION/vmm_ec2
@@ -730,7 +770,8 @@ VMM_EC2_ETC_FILES="src/vmm_mad/ec2/vmm_ec2rc \
VMM_EXEC_ETC_FILES="src/vmm_mad/exec/vmm_execrc \
src/vmm_mad/exec/vmm_exec_kvm.conf \
- src/vmm_mad/exec/vmm_exec_xen.conf"
+ src/vmm_mad/exec/vmm_exec_xen.conf \
+ src/vmm_mad/exec/vmm_exec_vmware.conf"
#-------------------------------------------------------------------------------
# Information drivers config. files, to be installed under $ETC_LOCATION
@@ -760,6 +801,8 @@ TM_DUMMY_ETC_FILES="src/tm_mad/dummy/tm_dummy.conf \
TM_LVM_ETC_FILES="src/tm_mad/lvm/tm_lvm.conf \
src/tm_mad/lvm/tm_lvmrc"
+TM_VMWARE_ETC_FILES="src/tm_mad/vmware/tm_vmware.conf"
+
#-------------------------------------------------------------------------------
# Hook Manager driver config. files, to be installed under $ETC_LOCATION/hm
#-------------------------------------------------------------------------------
@@ -772,6 +815,7 @@ HM_ETC_FILES="src/hm_mad/hmrc"
AUTH_ETC_FILES="src/authm_mad/remotes/server_x509/server_x509_auth.conf \
src/authm_mad/remotes/quota/quota.conf \
+ src/authm_mad/remotes/ldap/ldap_auth.conf \
src/authm_mad/remotes/x509/x509_auth.conf"
#-------------------------------------------------------------------------------
@@ -828,8 +872,7 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/OpenNebula/Host.rb \
src/oca/ruby/OpenNebula/GroupPool.rb \
src/oca/ruby/OpenNebula/Acl.rb \
src/oca/ruby/OpenNebula/AclPool.rb \
- src/oca/ruby/OpenNebula/XMLUtils.rb \
- src/oca/ruby/OpenNebula/Configuration.rb"
+ src/oca/ruby/OpenNebula/XMLUtils.rb"
#-------------------------------------------------------------------------------
# Common Cloud Files
@@ -1020,34 +1063,36 @@ SUNSTONE_PUBLIC_VENDOR_JGROWL="\
src/sunstone/public/vendor/jGrowl/NOTICE"
SUNSTONE_PUBLIC_VENDOR_JQUERY="\
- src/sunstone/public/vendor/jQuery/jquery-1.4.4.min.js \
+ src/sunstone/public/vendor/jQuery/jquery-1.7.1.min.js \
src/sunstone/public/vendor/jQuery/MIT-LICENSE.txt \
src/sunstone/public/vendor/jQuery/NOTICE"
SUNSTONE_PUBLIC_VENDOR_JQUERYUI="\
-src/sunstone/public/vendor/jQueryUI/ui-bg_glass_75_dadada_1x400.png \
-src/sunstone/public/vendor/jQueryUI/ui-icons_cd0a0a_256x240.png \
-src/sunstone/public/vendor/jQueryUI/jquery-ui-1.8.7.custom.css \
-src/sunstone/public/vendor/jQueryUI/ui-bg_flat_0_aaaaaa_40x100.png \
-src/sunstone/public/vendor/jQueryUI/ui-bg_flat_0_8f9392_40x100.png \
+src/sunstone/public/vendor/jQueryUI/jquery-ui-1.8.16.custom.css \
src/sunstone/public/vendor/jQueryUI/MIT-LICENSE.txt \
-src/sunstone/public/vendor/jQueryUI/jquery-ui-1.8.7.custom.min.js \
-src/sunstone/public/vendor/jQueryUI/ui-bg_highlight-soft_75_cccccc_1x100.png \
-src/sunstone/public/vendor/jQueryUI/ui-bg_glass_95_fef1ec_1x400.png \
-src/sunstone/public/vendor/jQueryUI/ui-bg_glass_55_fbf9ee_1x400.png \
-src/sunstone/public/vendor/jQueryUI/ui-icons_888888_256x240.png \
-src/sunstone/public/vendor/jQueryUI/ui-bg_glass_75_e6e6e6_1x400.png \
-src/sunstone/public/vendor/jQueryUI/ui-bg_flat_0_575c5b_40x100.png \
-src/sunstone/public/vendor/jQueryUI/ui-bg_glass_65_ffffff_1x400.png \
-src/sunstone/public/vendor/jQueryUI/ui-bg_flat_75_ffffff_40x100.png \
-src/sunstone/public/vendor/jQueryUI/ui-icons_2e83ff_256x240.png \
-src/sunstone/public/vendor/jQueryUI/ui-icons_454545_256x240.png \
+src/sunstone/public/vendor/jQueryUI/jquery-ui-1.8.16.custom.min.js \
src/sunstone/public/vendor/jQueryUI/NOTICE \
-src/sunstone/public/vendor/jQueryUI/ui-icons_222222_256x240.png \
"
+
+SUNSTONE_PUBLIC_VENDOR_JQUERYUIIMAGES="\
+src/sunstone/public/vendor/jQueryUI/images/ui-bg_flat_0_aaaaaa_40x100.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-bg_flat_75_ffffff_40x100.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-bg_glass_55_fbf9ee_1x400.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-bg_glass_65_ffffff_1x400.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-bg_glass_75_dadada_1x400.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-bg_glass_75_e6e6e6_1x400.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-bg_glass_95_fef1ec_1x400.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-bg_highlight-soft_75_cccccc_1x100.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-icons_222222_256x240.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-icons_2e83ff_256x240.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-icons_454545_256x240.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-icons_888888_256x240.png \
+src/sunstone/public/vendor/jQueryUI/images/ui-icons_cd0a0a_256x240.png \
+"
+
SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT="\
src/sunstone/public/vendor/jQueryLayout/layout-default-latest.css \
- src/sunstone/public/vendor/jQueryLayout/jquery.layout.min-1.2.0.js \
+ src/sunstone/public/vendor/jQueryLayout/jquery.layout-latest.min.js \
src/sunstone/public/vendor/jQueryLayout/NOTICE"
SUNSTONE_PUBLIC_VENDOR_FLOT="\
@@ -1119,6 +1164,8 @@ OZONES_PUBLIC_VENDOR_JGROWL=$SUNSTONE_PUBLIC_VENDOR_JGROWL
OZONES_PUBLIC_VENDOR_JQUERYUI=$SUNSTONE_PUBLIC_VENDOR_JQUERYUI
+OZONES_PUBLIC_VENDOR_JQUERYUIIMAGES=$SUNSTONE_PUBLIC_VENDOR_JQUERYUIIMAGES
+
OZONES_PUBLIC_VENDOR_JQUERYLAYOUT=$SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT
OZONES_PUBLIC_JS_FILES="src/ozones/Server/public/js/ozones.js \
@@ -1166,6 +1213,7 @@ ACCT_BIN_FILES="src/acct/oneacctd"
ACCT_LIB_FILES="src/acct/monitoring.rb \
src/acct/accounting.rb \
src/acct/acctd.rb \
+ src/acct/oneacct.rb \
src/acct/watch_helper.rb \
src/acct/watch_client.rb"
diff --git a/share/etc/init.d/one.debian b/share/etc/init.d/one.debian
index 531f8b03ae..7b75fffcaf 100755
--- a/share/etc/init.d/one.debian
+++ b/share/etc/init.d/one.debian
@@ -36,12 +36,7 @@ do_start()
{
mkdir -p /var/run/one /var/lock/one
chown oneadmin /var/run/one /var/lock/one
- ONE_AUTH_FILE=/var/lib/one/auth
- if [ ! -f $ONE_AUTH_FILE ]; then
- PASSWORD=$(cat /dev/urandom|tr -dc 'a-zA-Z0-9'|fold -w 10|head -n1)
- su oneadmin -s /bin/sh -c "echo oneadmin:$PASSWORD > $ONE_AUTH_FILE"
- fi
- ONE_AUTH=$ONE_AUTH_FILE su oneadmin -s /bin/sh -c 'one start'
+ su oneadmin -s /bin/sh -c 'one start'
}
#
diff --git a/share/etc/init.d/one.ubuntu b/share/etc/init.d/one.ubuntu
index 531f8b03ae..7b75fffcaf 100755
--- a/share/etc/init.d/one.ubuntu
+++ b/share/etc/init.d/one.ubuntu
@@ -36,12 +36,7 @@ do_start()
{
mkdir -p /var/run/one /var/lock/one
chown oneadmin /var/run/one /var/lock/one
- ONE_AUTH_FILE=/var/lib/one/auth
- if [ ! -f $ONE_AUTH_FILE ]; then
- PASSWORD=$(cat /dev/urandom|tr -dc 'a-zA-Z0-9'|fold -w 10|head -n1)
- su oneadmin -s /bin/sh -c "echo oneadmin:$PASSWORD > $ONE_AUTH_FILE"
- fi
- ONE_AUTH=$ONE_AUTH_FILE su oneadmin -s /bin/sh -c 'one start'
+ su oneadmin -s /bin/sh -c 'one start'
}
#
diff --git a/share/etc/init.d/oned.centos b/share/etc/init.d/oned.centos
index 61ed5d65f1..1eae735472 100755
--- a/share/etc/init.d/oned.centos
+++ b/share/etc/init.d/oned.centos
@@ -34,19 +34,9 @@ check() {
}
start() {
-
check
-
- ONE_AUTH_FILE=/var/lib/one/auth
- if [ ! -f $ONE_AUTH_FILE ]; then
- PASSWORD=$(cat /dev/urandom|tr -dc 'a-zA-Z0-9'|fold -w 10|head -n1)
- su oneadmin -s /bin/sh -c "echo oneadmin:$PASSWORD > $ONE_AUTH_FILE"
- fi
-
echo -n $"Starting OpenNebula daemon: "
-
-
- daemon --user oneadmin ONE_AUTH=$ONE_AUTH_FILE $ONE_BIN start
+ daemon --user oneadmin $ONE_BIN start
RETVAL=$?
echo
return $RETVAL
diff --git a/share/etc/init.d/oned.opensuse b/share/etc/init.d/oned.opensuse
index 40724aa892..071688e56d 100755
--- a/share/etc/init.d/oned.opensuse
+++ b/share/etc/init.d/oned.opensuse
@@ -34,14 +34,8 @@ rc_reset
case "$1" in
start)
- ONE_AUTH_FILE=/var/lib/one/auth
- if [ ! -f $ONE_AUTH_FILE ]; then
- PASSWORD=$(cat /dev/urandom|tr -dc 'a-zA-Z0-9'|fold -w 10|head -n1)
- su oneadmin -s /bin/sh -c "echo oneadmin:$PASSWORD > $ONE_AUTH_FILE"
- fi
-
echo -n "Starting ONE "
- ONE_AUTH=$ONE_AUTH_FILE /sbin/startproc -u oneadmin $ONE_BIN start
+ /sbin/startproc -u oneadmin $ONE_BIN start
rc_status -v
;;
diff --git a/share/etc/oned.conf b/share/etc/oned.conf
index 3c4f9f629f..65cfb004d3 100644
--- a/share/etc/oned.conf
+++ b/share/etc/oned.conf
@@ -139,6 +139,17 @@ IM_MAD = [
# arguments = "xen" ]
#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+# VMware Information Driver Manager Configuration
+# -r number of retries when monitoring a host
+# -t number of threads, i.e. number of hosts monitored at the same time
+#-------------------------------------------------------------------------------
+#IM_MAD = [
+# name = "im_vmware",
+# executable = "one_im_sh",
+# arguments = "-t 15 -r 0 vmware" ]
+#-------------------------------------------------------------------------------
+
#-------------------------------------------------------------------------------
# EC2 Information Driver Manager Configuration
#-------------------------------------------------------------------------------
@@ -218,6 +229,19 @@ VM_MAD = [
# type = "xen" ]
#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+# VMware Virtualization Driver Manager Configuration
+# -r number of retries when monitoring a host
+# -t number of threads, i.e. number of hosts monitored at the same time
+#-------------------------------------------------------------------------------
+#VM_MAD = [
+# name = "vmm_vmware",
+# executable = "one_vmm_sh",
+# arguments = "-t 15 -r 0 vmware",
+# default = "vmm_exec/vmm_exec_vmware.conf",
+# type = "vmware" ]
+#-------------------------------------------------------------------------------
+
#-------------------------------------------------------------------------------
# EC2 Virtualization Driver Manager Configuration
# arguments: default values for the EC2 driver, can be an absolute path or
@@ -289,6 +313,15 @@ TM_MAD = [
# arguments = "tm_lvm/tm_lvm.conf" ]
#-------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+# VMware DataStore Transfer Manager Driver Configuration
+#-------------------------------------------------------------------------------
+#TM_MAD = [
+# name = "tm_vmware",
+# executable = "one_tm",
+# arguments = "tm_vmware/tm_vmware.conf" ]
+#-------------------------------------------------------------------------------
+
#*******************************************************************************
# Image Manager Driver Configuration
#*******************************************************************************
@@ -428,8 +461,8 @@ HM_MAD = [
AUTH_MAD = [
executable = "one_auth_mad",
- arguments = "--authn ssh,x509,server_cipher,server_x509"
-# arguments = "--authz quota --authn ssh,x509,server_cipher,server_x509"
+ arguments = "--authn ssh,x509,ldap,server_cipher,server_x509"
+# arguments = "--authz quota --authn ssh,x509,ldap,server_cipher,server_x509"
]
SESSION_EXPIRATION_TIME = 900
diff --git a/src/acct/oneacct.rb b/src/acct/oneacct.rb
new file mode 100644
index 0000000000..2ad12cd891
--- /dev/null
+++ b/src/acct/oneacct.rb
@@ -0,0 +1,183 @@
+# --------------------------------------------------------------------------
+# Copyright 2010-2011, C12G Labs S.L.
+#
+# This file is part of OpenNebula addons.
+#
+# OpenNebula addons are free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or the hope That it will be useful, but (at your
+# option) any later version.
+#
+# OpenNebula addons are distributed in WITHOUT ANY WARRANTY;
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License
+# along with OpenNebula addons. If not, see
+#
+# --------------------------------------------------------------------------
+
+
+
+require 'acct/watch_helper'
+
+class AcctClient
+ def initialize(filters={})
+ @filters=filters
+ @deltas=[]
+ @users={}
+ end
+
+ def account(time_start=nil, time_end=nil, user_id=nil)
+ @filters[:start]=time_start if time_start
+ @filters[:end]=time_end if time_end
+ @filters[:user]=user_id if user_id
+
+ get_users_consumption
+
+ @users
+ end
+
+private
+
+ def get_users_consumption
+ # Get all the deltas that match the filters
+ @deltas=calculate_deltas.map {|q| q.values }
+
+ @users=slices_by_user
+
+ user_slices_and_deltas_to_vms
+ end
+
+ def slices_by_user
+ # Get all VM slices that match the filters
+ query=get_vm_slices(@filters)
+
+ # This hash will hold the users with the resources consumed
+ users={}
+
+ query.each do |reg|
+ vm=reg.vm
+ uid=vm.uid.to_i
+
+ # Create a new user register if it still does not exist
+ user=users[uid]||={
+ :vm_slices => [],
+ }
+
+ user[:vm_slices] << reg.values
+ end
+
+ users
+ end
+
+ def user_slices_and_deltas_to_vms
+ @users.each do |user, data|
+ # Get the VM ids array for this user
+ vms=data[:vm_slices].map {|vm| vm[:id] }.sort.uniq
+
+ data[:vms]={}
+
+ vms.each do |vm|
+ # Get the slices array for this VM
+ slices=data[:vm_slices].select {|slice| slice[:id]==vm }
+
+ data[:vms][vm]={
+ :slices => [],
+ :time => 0,
+ }
+
+ # Get the deltas sum for this VM
+ vm_delta=@deltas.find {|d| d[:vm_id]==vm }
+
+ data[:vms][vm][:network]=vm_delta
+ data[:vms][vm][:vmid]=vm
+
+ # Calculate the time consumed by the VM
+ slices.each do |slice|
+ data[:vms][vm][:slices] << slice
+
+ time=calculate_time(slice,
+ @filters[:start], @filters[:end])
+ data[:vms][vm][:time]+=time
+ end
+ end
+
+ # Delete redundant slices data
+ data.delete(:vm_slices)
+ end
+ end
+
+ def get_vm_slices(filters={})
+ vms=WatchHelper::Register
+
+ query=vms.join(:vms, :id => :vm_id)
+ query=query.filter({:vms__uid => filters[:user]}) if filters[:user]
+ query=query.filter(
+ {:retime => 0} | (:retime > filters[:start])) if filters[:start]
+ query=query.filter(:rstime <= filters[:end]) if filters[:end]
+
+ query
+ end
+
+ def get_deltas(filters={})
+ if filters[:data]
+ query=filters[:data]
+ else
+ query=WatchHelper::VmDelta
+ end
+
+ query=query.filter( :ptimestamp >= filters[:start] ) if filters[:start]
+ query=query.filter( :ptimestamp <= filters[:end] ) if filters[:end]
+ query=query.filter( { :vm_id => filters[:vmid] } ) if filters[:vmid]
+
+ query
+ end
+
+ def calculate_deltas
+ query=WatchHelper::VmDelta.select(
+ :ptimestamp, :vm_id,
+ 'sum(net_tx) AS net_tx'.lit, 'sum(net_rx) AS net_rx'.lit)
+
+ query=query.group(:vm_id)
+
+ new_filters=@filters.merge(:data => query)
+
+ get_deltas(new_filters)
+ end
+
+ def calculate_time(slice, period_start, period_end)
+ ts=slice[:rstime].to_i
+ te=slice[:retime].to_i
+
+ pstart=period_start.to_i
+ pend=period_end.to_i
+
+ pend=Time.now.to_i if pend==0
+
+ ts=pstart if tspend or te==0
+ te=pend
+ end
+
+ te-ts
+ end
+end
+
+if $0 == __FILE__
+
+ require 'json'
+
+ acct=AcctClient.new(
+ :start => 1319476322,
+ :end => 1319637455
+ )
+
+ a=acct.account()
+
+ puts JSON.pretty_generate(a)
+
+end
+
diff --git a/src/authm_mad/one_auth_mad.rb b/src/authm_mad/one_auth_mad.rb
index 7a244519e9..245c660944 100755
--- a/src/authm_mad/one_auth_mad.rb
+++ b/src/authm_mad/one_auth_mad.rb
@@ -107,9 +107,9 @@ class AuthDriver < OpenNebulaDriver
#build path for the auth action
#/var/lib/one/remotes/auth//authenticate
authN_path = File.join(@local_scripts_path, driver)
-
- command = File.join(authN_path,ACTION[:authN].downcase)
- command << ' ' << user << ' ' << password << ' ' << secret
+
+ command = File.join(authN_path,ACTION[:authN].downcase)
+ command << " '" << user.gsub("'", '\'"\'"\'') << "' '" << password.gsub("'", '\'"\'"\'') << "' " << secret
do_action(command, request_id, nil, ACTION[:authN],
:local => true)
diff --git a/src/authm_mad/remotes/ldap/authenticate b/src/authm_mad/remotes/ldap/authenticate
new file mode 100755
index 0000000000..90501553f1
--- /dev/null
+++ b/src/authm_mad/remotes/ldap/authenticate
@@ -0,0 +1,63 @@
+#!/usr/bin/ruby
+
+# ---------------------------------------------------------------------------- #
+# Copyright 2010-2011, C12G Labs S.L #
+# #
+# 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/"
+else
+ RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
+ ETC_LOCATION=ONE_LOCATION+"/etc/"
+end
+
+$: << RUBY_LIB_LOCATION
+
+require 'yaml'
+require 'ldap_auth'
+
+user=ARGV[0]
+pass=ARGV[1]
+secret=ARGV[2]
+
+options=YAML.load(File.read(ETC_LOCATION+'/auth/ldap_auth.conf'))
+
+ldap=LdapAuth.new(options)
+
+user_name=ldap.find_user(user)
+
+if !user_name
+ STDERR.puts "User #{user} not found"
+ exit(-1)
+end
+
+if options[:group]
+ if !ldap.is_in_group?(user_name, options[:group])
+ STDERR.puts "User #{user} is not in group #{options[:group]}"
+ exit(-1)
+ end
+end
+
+if ldap.authenticate(user_name, secret)
+ puts "#{user} #{user_name}"
+ exit(0)
+else
+ STDERR.puts "Bad user/password"
+ exit(-1)
+end
+
diff --git a/src/authm_mad/remotes/ldap/ldap_auth.conf b/src/authm_mad/remotes/ldap/ldap_auth.conf
new file mode 100644
index 0000000000..8504df1ce8
--- /dev/null
+++ b/src/authm_mad/remotes/ldap/ldap_auth.conf
@@ -0,0 +1,35 @@
+# ---------------------------------------------------------------------------- #
+# Copyright 2010-2011, C12G Labs S.L #
+# #
+# 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. #
+# ---------------------------------------------------------------------------- #
+
+# Ldap user able to query, if not set connects as anonymous
+#:user: 'admin'
+#:password: 'password'
+
+# Ldap authentication method
+:auth_method: :simple
+
+# Ldap server
+:host: localhost
+:port: 389
+
+# base hierarchy where to search for users and groups
+:base: 'dc=domain'
+
+# group the users need to belong to. If not set any user will do
+:group: 'cn=cloud,ou=groups,dc=domain'
+
+# field that holds the user name, if not set 'cn' will be used
+:user_field: 'cn'
diff --git a/src/authm_mad/remotes/ldap/ldap_auth.rb b/src/authm_mad/remotes/ldap/ldap_auth.rb
new file mode 100644
index 0000000000..8d30eb153e
--- /dev/null
+++ b/src/authm_mad/remotes/ldap/ldap_auth.rb
@@ -0,0 +1,96 @@
+# ---------------------------------------------------------------------------- #
+# Copyright 2010-2011, C12G Labs S.L #
+# #
+# 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 'rubygems'
+require 'net/ldap'
+
+class LdapAuth
+ def initialize(options)
+ @options={
+ :host => 'localhost',
+ :port => 389,
+ :user => nil,
+ :password => nil,
+ :base => nil,
+ :auth_method => :simple,
+ :user_field => 'cn'
+ }.merge(options)
+
+ ops={}
+
+ if @options[:user]
+ ops[:auth] = {
+ :method => @options[:auth_method],
+ :username => @options[:user],
+ :password => @options[:password]
+ }
+ end
+
+ ops[:host]=@options[:host] if @options[:host]
+ ops[:port]=@options[:port].to_i if @options[:port]
+
+ @ldap=Net::LDAP.new(ops)
+ end
+
+ def find_user(name)
+ begin
+ result=@ldap.search(
+ :base => @options[:base],
+ :filter => "#{@options[:user_field]}=#{name}")
+
+ if result && result.first
+ result.first.dn
+ else
+ result=@ldap.search(:base => name)
+
+ if result && result.first
+ name
+ else
+ nil
+ end
+ end
+ rescue
+ nil
+ end
+ end
+
+ def is_in_group?(user, group)
+ result=@ldap.search(:base => group, :filter => "(member=#{user})")
+
+ if result && result.first
+ true
+ else
+ false
+ end
+ end
+
+ def authenticate(user, password)
+ ldap=@ldap.clone
+
+ auth={
+ :method => @options[:auth_method],
+ :username => user,
+ :password => password
+ }
+
+ if ldap.bind(auth)
+ true
+ else
+ false
+ end
+ end
+end
+
diff --git a/src/authm_mad/remotes/ldap/test/ldap_auth_spec.rb b/src/authm_mad/remotes/ldap/test/ldap_auth_spec.rb
new file mode 100644
index 0000000000..13a0c43f7e
--- /dev/null
+++ b/src/authm_mad/remotes/ldap/test/ldap_auth_spec.rb
@@ -0,0 +1,70 @@
+# ---------------------------------------------------------------------------- #
+# Copyright 2010-2011, C12G Labs S.L #
+# #
+# 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 'ldap_auth'
+
+options={
+ :host => 'ubuntu-test',
+ :base => 'dc=localdomain'
+}
+
+describe LdapAuth do
+ before(:all) do
+ @ldap=LdapAuth.new(options)
+ end
+
+ it 'should find user dn' do
+ name=@ldap.find_user('user01')
+ name.should=='cn=user01,dc=localdomain'
+
+ name=@ldap.find_user('user02')
+ name.should=='cn=user02,dc=localdomain'
+
+ name=@ldap.find_user('user03')
+ name.should==nil
+
+ name=@ldap.find_user('cn=user01,dc=localdomain')
+ name.should=='cn=user01,dc=localdomain'
+ end
+
+ it 'should tell if a user is in a group' do
+ group='cn=cloud,ou=groups,dc=localdomain'
+
+ result=@ldap.is_in_group?('cn=user01,dc=localdomain', group)
+ result.should==true
+
+ result=@ldap.is_in_group?('cn=user02,dc=localdomain', group)
+ result.should==false
+ end
+
+ it 'should authenticate user' do
+ result=@ldap.authenticate('cn=user01,dc=localdomain', 'password01')
+ result.should==true
+
+ result=@ldap.authenticate('cn=user02,dc=localdomain', 'password02')
+ result.should==true
+
+ result=@ldap.authenticate('cn=user01,dc=localdomain', 'password02')
+ result.should==false
+
+ result=@ldap.authenticate('user01,dc=localdomain', 'password01')
+ result.should==false
+ end
+
+end
+
diff --git a/src/authm_mad/remotes/quota/quota.rb b/src/authm_mad/remotes/quota/quota.rb
index 4231c105ce..046bdc9493 100644
--- a/src/authm_mad/remotes/quota/quota.rb
+++ b/src/authm_mad/remotes/quota/quota.rb
@@ -78,7 +78,13 @@ class Quota
IMAGE_USAGE = {
:STORAGE => {
- :proc_info => lambda {|template| File.size(template['PATH']) },
+ :proc_info => lambda {|template|
+ if template['TYPE'] == 'DATABLOCK'
+ template['SIZE'].to_i
+ else
+ File.size(template['PATH'])
+ end
+ },
:xpath => 'SIZE'
}
}
diff --git a/src/cli/one_helper/onehost_helper.rb b/src/cli/one_helper/onehost_helper.rb
index d517978664..943e4e0010 100644
--- a/src/cli/one_helper/onehost_helper.rb
+++ b/src/cli/one_helper/onehost_helper.rb
@@ -61,6 +61,7 @@ class OneHostHelper < OpenNebulaHelper::OneHelper
puts str % ["VM_MAD", host['VM_MAD']]
puts str % ["VN_MAD", host['VN_MAD']]
puts str % ["TM_MAD", host['TM_MAD']]
+ puts str % ["LAST MONITORING TIME", host['LAST_MON_TIME']]
puts
CLIHelper.print_header(str_h1 % "HOST SHARES", false)
@@ -71,6 +72,9 @@ class OneHostHelper < OpenNebulaHelper::OneHelper
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 % ["MAX DISK", host['HOST_SHARE/MAX_DISK']]
+ puts str % ["USED DISK (REAL)", host['HOST_SHARE/USED_DISK']]
+ puts str % ["USED DISK (ALLOCATED)", host['HOST_SHARE/DISK_USAGE']]
puts str % ["RUNNING VMS", host['HOST_SHARE/RUNNING_VMS']]
puts
diff --git a/src/cli/one_helper/oneuser_helper.rb b/src/cli/one_helper/oneuser_helper.rb
index 48b87abead..15e9c9c4a9 100644
--- a/src/cli/one_helper/oneuser_helper.rb
+++ b/src/cli/one_helper/oneuser_helper.rb
@@ -37,14 +37,14 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
return -1, "Can not read file: #{arg}"
end
else
- password = arg
+ password = arg.dup
end
if options[:driver] == OpenNebula::User::X509_AUTH
password.delete!("\s")
end
- if options[:sha1]
+ if options[:sha1] || options[:driver] == OpenNebula::User::CIPHER_AUTH
require 'digest/sha1'
password = Digest::SHA1.hexdigest(password)
end
@@ -166,7 +166,7 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
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 % ["GROUP", user['GNAME']]
puts str % ["PASSWORD", user['PASSWORD']]
puts str % ["AUTH_DRIVER", user['AUTH_DRIVER']]
diff --git a/src/cli/one_helper/onevm_helper.rb b/src/cli/one_helper/onevm_helper.rb
index 9ecc4425eb..1ecdd0ac87 100644
--- a/src/cli/one_helper/onevm_helper.rb
+++ b/src/cli/one_helper/onevm_helper.rb
@@ -65,7 +65,7 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
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]
@@ -99,9 +99,10 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE TEMPLATE",false)
puts vm.template_str
- if vm['/VM/HISTORY_RECORDS/HISTORY']
+ if vm.has_elements?("/VM/HISTORY_RECORDS/")
puts
-
+
+
CLIHelper.print_header(str_h1 % "VIRTUAL MACHINE HISTORY",false)
format_history(vm)
end
diff --git a/src/cli/one_helper/onevnet_helper.rb b/src/cli/one_helper/onevnet_helper.rb
index 6abd1a60dd..7216ad6abb 100644
--- a/src/cli/one_helper/onevnet_helper.rb
+++ b/src/cli/one_helper/onevnet_helper.rb
@@ -53,6 +53,7 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
str="%-15s: %-20s"
puts str % ["ID", vn.id.to_s]
+ puts str % ["NAME", vn['NAME']]
puts str % ["USER", vn['UNAME']]
puts str % ["GROUP", vn['GNAME']]
puts str % ["PUBLIC", OpenNebulaHelper.boolean_to_str(vn['PUBLIC'])]
@@ -128,4 +129,4 @@ class OneVNetHelper < OpenNebulaHelper::OneHelper
table
end
-end
\ No newline at end of file
+end
diff --git a/src/cli/oneacct b/src/cli/oneacct
new file mode 100755
index 0000000000..065d2c09eb
--- /dev/null
+++ b/src/cli/oneacct
@@ -0,0 +1,235 @@
+#!/usr/bin/env ruby
+
+# --------------------------------------------------------------------------
+# Copyright 2010-2011, C12G Labs S.L.
+#
+# This file is part of OpenNebula addons.
+#
+# OpenNebula addons are free software: you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 3 of
+# the License, or the hope That it will be useful, but (at your
+# option) any later version.
+#
+# OpenNebula addons are distributed in WITHOUT ANY WARRANTY;
+# without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+# A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License
+# along with OpenNebula addons. If not, see
+#
+# --------------------------------------------------------------------------
+
+
+ONE_LOCATION=ENV['ONE_LOCATION']
+
+$: << ONE_LOCATION+'/lib/ruby'
+$: << ONE_LOCATION+'/lib/ruby/cli'
+
+require 'rubygems'
+
+require 'acct/oneacct'
+require 'cli/one_helper'
+require 'cli/command_parser'
+require 'json'
+
+require 'optparse'
+require 'optparse/time'
+
+REG_DATE=/((\d{4})\/)?(\d\d?)(\/(\d\d?))?/
+REG_TIME=/(\d\d?):(\d\d?)(:(\d\d?))?/
+
+class AcctHelper
+
+ def format_vm(options=nil)
+ table = CLIHelper::ShowTable.new(nil, nil) do
+ column :VMID, "VM ID", :size=>4 do |d|
+ d[:vmid]
+ end
+
+ column :MEMORY, "Consumed memory", :right, :size=>8 do |d|
+ OpenNebulaHelper.unit_to_str(
+ d[:slices].first[:mem]*1024,
+ {})
+ end
+
+ column :CPU, "Group of the User", :right, :size=>8 do |d|
+ d[:slices].first[:cpu]
+ end
+
+ column :NETRX, "Group of the User", :right, :size=>10 do |d|
+ OpenNebulaHelper.unit_to_str(
+ d[:network][:net_rx]/1024.0,
+ {})
+ end
+
+ column :NETTX, "Group of the User", :right, :size=>10 do |d|
+ OpenNebulaHelper.unit_to_str(
+ d[:network][:net_tx]/1024.0,
+ {})
+ end
+
+ column :TIME, "Group of the User", :right, :size=>15 do |d|
+ OpenNebulaHelper.time_to_str(d[:time])
+ end
+
+ default :VMID, :MEMORY, :CPU, :NETRX, :NETTX, :TIME
+ end
+
+ table
+ end
+
+ def list_vms(data)
+ format_vm().show(data)
+ end
+
+ def list_users(filters)
+ a=gen_accounting(filters)
+
+ a.each do |user, data|
+
+ CLIHelper.scr_bold
+ CLIHelper.scr_underline
+ puts "# User #{user}"
+ CLIHelper.scr_restore
+ puts
+
+ vms=data[:vms].map do |k, v|
+ v
+ end
+
+ self.list_vms(vms)
+
+ puts
+ puts
+
+ end
+ end
+
+ def gen_accounting(filters)
+ acct=AcctClient.new(filters)
+ acct.account()
+ end
+
+ def gen_json(filters)
+ begin
+ require 'json'
+ rescue LoadError
+ STDERR.puts "JSON gem is needed to give the result in this format"
+ exit(-1)
+ end
+
+ acct=gen_accounting(filters)
+ acct.to_json
+ end
+
+ def xml_tag(tag, value)
+ "<#{tag}>#{value}#{tag}>\n"
+ end
+
+ def gen_xml(filters)
+ acct=gen_accounting(filters)
+
+ xml=""
+
+ acct.each do |user, data|
+ xml<<"\n"
+
+ data[:vms].each do |vmid, vm|
+ xml<<" \n"
+
+ xml<<" "<\n"
+
+ slice.each do |key, value|
+ xml<<" "<\n"
+ end
+
+ xml<<" \n"
+ end
+
+ xml<<"\n"
+ end
+
+ xml
+ end
+end
+
+
+@options=Hash.new
+
+@options[:format]=:table
+
+opts=OptionParser.new do |opts|
+ opts.on('-s', '--start TIME', Time,
+ 'Start date and time to take into account') do |ext|
+ @options[:start]=ext
+ end
+
+ opts.on("-e", "--end TIME", Time,
+ "End date and time" ) do |ext|
+ @options[:end]=ext
+ end
+
+ opts.on("-u", "--user user", Integer,
+ "User id to make accounting" ) do |ext|
+ @options[:user]=ext.to_i
+ end
+
+ opts.on("-j", "--json",
+ "Output in json format" ) do |ext|
+ @options[:format]=:json
+ end
+
+ opts.on("-x", "--xml",
+ "Output in xml format" ) do |ext|
+ @options[:format]=:xml
+ end
+
+ opts.on()
+end
+
+
+begin
+ opts.parse!(ARGV)
+rescue OptionParser::ParseError => e
+ STDERR.puts "Error: " << e.message
+ exit(-1)
+end
+
+
+acct_helper=AcctHelper.new
+
+
+filters=Hash.new
+
+filters[:start]=@options[:start].to_i if @options[:start]
+filters[:end]=@options[:end].to_i if @options[:end]
+filters[:user]=@options[:user].to_i if @options[:user]
+
+
+case @options[:format]
+when :table
+ acct_helper.list_users(filters)
+when :json
+ puts acct_helper.gen_json(filters)
+when :xml
+ puts acct_helper.gen_xml(filters)
+end
+
+
+
+
+
+
diff --git a/src/cli/oneuser b/src/cli/oneuser
index 293ecbcac1..75501a49fe 100755
--- a/src/cli/oneuser
+++ b/src/cli/oneuser
@@ -275,11 +275,25 @@ cmd=CommandParser::CmdParser.new(ARGV) do
end
chauth_desc = <<-EOT.unindent
- Changes the User's auth driver
+ Changes the User's auth driver and its password (optional)
+ Examples:
+ oneuser chauth my_user core
+ oneuser chauth my_user core new_password
+ oneuser chauth my_user core -r /tmp/mypass
+ oneuser chauth my_user --ssh --key /home/oneadmin/.ssh/id_rsa
+ oneuser chauth my_user --ssh -r /tmp/public_key
+ oneuser chauth my_user --x509 --cert /tmp/my_cert.pem
EOT
- command :chauth, chauth_desc, :userid, :auth, [:password, nil],
+ command :chauth, chauth_desc, :userid, [:auth, nil], [:password, nil],
:options=>create_options do
+ if options[:driver]
+ driver = options[:driver]
+ elsif args[1]
+ driver = args[1]
+ else
+ exit_with_code 0, "An Auth driver should be specified"
+ end
helper = OneUserHelper.new
@@ -297,7 +311,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
helper.perform_action(args[0],
options,
"Auth driver and password changed") do |user|
- user.chauth(args[1], pass)
+ user.chauth(driver, pass)
end
end
diff --git a/src/cli/onevnet b/src/cli/onevnet
index 72ab53716a..b5101c05a6 100755
--- a/src/cli/onevnet
+++ b/src/cli/onevnet
@@ -136,7 +136,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
Changes the Virtual Network group
EOT
- command :chgrp, chgrp_desc,[:range, :vnid_list], :groupid do
+ command :chgrp, chgrp_desc,[:range, :vnetid_list], :groupid do
helper.perform_actions(args[0],options,"Group changed") do |vn|
vn.chown(-1, args[1].to_i)
end
@@ -146,7 +146,7 @@ cmd=CommandParser::CmdParser.new(ARGV) do
Changes the Virtual Network owner and group
EOT
- command :chown, chown_desc, [:range, :vnid_list], :userid,
+ command :chown, chown_desc, [:range, :vnetid_list], :userid,
[:groupid,nil] do
gid = args[2].nil? ? -1 : args[2].to_i
helper.perform_actions(args[0],options,"Owner/Group changed") do |vn|
diff --git a/src/cloud/common/CloudAuth.rb b/src/cloud/common/CloudAuth.rb
index 474fbae043..b69934dd81 100644
--- a/src/cloud/common/CloudAuth.rb
+++ b/src/cloud/common/CloudAuth.rb
@@ -44,8 +44,11 @@ class CloudAuth
def initialize(conf)
@conf = conf
+ # @token_expiration_delta: Number of seconds that will be used
+ # the same timestamp for the token generation
+ # @token_expiration_time: Current timestamp to be used in tokens.
@token_expiration_delta = @conf[:token_expiration_delta] || EXPIRE_DELTA
- @token_expiration_time = Time.now.to_i + @token_expiration_delta
+ @token_expiration_time = Time.now.to_i + @token_expiration_delta
if AUTH_MODULES.include?(@conf[:auth])
require 'CloudAuth/' + AUTH_MODULES[@conf[:auth]]
@@ -64,19 +67,29 @@ class CloudAuth
begin
require core_auth[0]
@server_auth = Kernel.const_get(core_auth[1]).new_client
-
- token = @server_auth.login_token(expiration_time)
- @oneadmin_client ||= OpenNebula::Client.new(token, @conf[:one_xmlrpc])
rescue => e
raise e.message
end
end
- def client(username)
+ # Generate a new OpenNebula client for the target User, if the username
+ # is nil the Client is generated for the server_admin
+ # ussername:: _String_ Name of the User
+ # [return] _Client_
+ def client(username=nil)
token = @server_auth.login_token(expiration_time,username)
Client.new(token,@conf[:one_xmlrpc])
end
+ def update_userpool_cache
+ @user_pool = OpenNebula::UserPool.new(client)
+
+ rc = @user_pool.info
+ if OpenNebula.is_error?(rc)
+ raise rc.message
+ end
+ end
+
protected
def expiration_time
@@ -84,6 +97,7 @@ class CloudAuth
if time_now > @token_expiration_time - EXPIRE_MARGIN
@token_expiration_time = time_now + @token_expiration_delta
+ update_userpool_cache
end
@token_expiration_time
@@ -91,15 +105,7 @@ class CloudAuth
# If @user_pool is not defined it will retrieve it from OpenNebula
def get_userpool
- if @user_pool.nil?
- @user_pool ||= OpenNebula::UserPool.new(@oneadmin_client)
-
- rc = @user_pool.info
- if OpenNebula.is_error?(rc)
- raise rc.message
- end
- end
-
+ update_userpool_cache if @user_pool.nil?
@user_pool
end
diff --git a/src/cloud/occi/lib/ImageOCCI.rb b/src/cloud/occi/lib/ImageOCCI.rb
index 11c60ae79a..cd573554c3 100755
--- a/src/cloud/occi/lib/ImageOCCI.rb
+++ b/src/cloud/occi/lib/ImageOCCI.rb
@@ -23,17 +23,15 @@ class ImageOCCI < Image
<%= self.id.to_s %><%= self.name %>
- <% if self['TEMPLATE/TYPE'] != nil %>
- <%= self['TEMPLATE/TYPE'] %>
+ <% if self['TYPE'] != nil %>
+ <%= self['TYPE'] %>
<% end %>
<% if self['TEMPLATE/DESCRIPTION'] != nil %>
<%= self['TEMPLATE/DESCRIPTION'] %>
<% end %>
- <% if size != nil %>
- <%= size.to_i / 1024 %>
- <% end %>
- <% if fstype != nil %>
- <%= fstype %>
+ <%= self['SIZE'] %>
+ <% if self['FSTYPE'] != nil %>
+ <%= self['FSTYPE'] %>
<% end %>
<%= self['PUBLIC'] == "0" ? "NO" : "YES"%><%= self['PERSISTENT'] == "0" ? "NO" : "YES"%>
@@ -84,25 +82,18 @@ class ImageOCCI < Image
# Creates the OCCI representation of an Image
def to_occi(base_url)
- size = nil
-
begin
- if self['SOURCE'] != nil and File.exists?(self['SOURCE'])
- size = File.stat(self['SOURCE']).size
- size = size / 1024
- end
-
- fstype = self['TEMPLATE/FSTYPE'] if self['TEMPLATE/FSTYPE']
+ occi_im = ERB.new(OCCI_IMAGE)
+ occi_im_text = occi_im.result(binding)
rescue Exception => e
error = OpenNebula::Error.new(e.message)
return error
end
- occi = ERB.new(OCCI_IMAGE)
- return occi.result(binding).gsub(/\n\s*/,'')
+ return occi_im_text.gsub(/\n\s*/,'')
end
- def to_one_template()
+ def to_one_template
if @image_info == nil
error_msg = "Missing STORAGE section in the XML body"
error = OpenNebula::Error.new(error_msg)
diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb
index 841f45fa49..954248d3db 100755
--- a/src/cloud/occi/lib/OCCIServer.rb
+++ b/src/cloud/occi/lib/OCCIServer.rb
@@ -504,4 +504,38 @@ class OCCIServer < CloudServer
return to_occi_xml(user, 200)
end
+
+ def get_computes_types
+ etc_location=ONE_LOCATION ? ONE_LOCATION+"/etc" : "/etc/one"
+ begin
+ xml_response = "\n"
+
+ Dir[etc_location + "/occi_templates/**"].each{| filename |
+ next if File.basename(filename) == "common.erb"
+ xml_response += "\t"
+ xml_response += "\t\t#{File.basename(filename)[0..-5]}"
+ file = File.open(filename, "r")
+ file.each_line{|line|
+ next if line.match(/^#/)
+ match=line.match(/^(.*)=(.*)/)
+ next if !match
+ case match[1].strip
+ when "NAME"
+ xml_response += "\t\t#{match[2].strip}"
+ when "CPU"
+ xml_response += "\t\t#{match[2].strip}"
+ when "MEMORY"
+ xml_response += "\t\t#{match[2].strip}"
+ end
+ }
+ xml_response += "\t"
+ }
+
+ xml_response += ""
+
+ return xml_response, 200
+ rescue Exception => e
+ return "Error getting the instance types. Reason: #{e.message}", 500
+ end
+ end
end
diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb
index 86f9a1959b..e650e861cd 100755
--- a/src/cloud/occi/lib/occi-server.rb
+++ b/src/cloud/occi/lib/occi-server.rb
@@ -105,7 +105,7 @@ before do
end
if username.nil?
- return [401, ""]
+ error 401, ""
else
client = settings.cloud_auth.client(username)
@occi_server = OCCIServer.new(client, settings.config)
@@ -172,7 +172,11 @@ end
###################################################
get '/compute/:id' do
- result,rc = @occi_server.get_compute(request, params)
+ if params[:id] == "types"
+ result,rc = @occi_server.get_computes_types
+ else
+ result,rc = @occi_server.get_compute(request, params)
+ end
treat_response(result,rc)
end
@@ -219,4 +223,4 @@ end
get '/user/:id' do
result,rc = @occi_server.get_user(request, params)
treat_response(result,rc)
-end
\ No newline at end of file
+end
diff --git a/src/im_mad/remotes/vmware.d/vmware.rb b/src/im_mad/remotes/vmware.d/vmware.rb
new file mode 100755
index 0000000000..5552818cf3
--- /dev/null
+++ b/src/im_mad/remotes/vmware.d/vmware.rb
@@ -0,0 +1,118 @@
+#!/usr/bin/env ruby
+
+# ---------------------------------------------------------------------------- #
+# Copyright 2010-2011, C12G Labs S.L #
+# #
+# 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 !defined?(ONE_LOCATION)
+
+if !ONE_LOCATION
+ ETC_LOCATION = "/etc/one" if !defined?(ETC_LOCATION)
+ RUBY_LIB_LOCATION = "/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
+else
+ ETC_LOCATION = ONE_LOCATION+"/etc" if !defined?(ETC_LOCATION)
+ RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
+end
+
+$: << RUBY_LIB_LOCATION
+
+require 'OpenNebula'
+include OpenNebula
+
+begin
+ client = Client.new()
+rescue Exception => e
+ puts "Error: #{e}"
+ exit(-1)
+end
+
+def add_info(name, value)
+ value = "0" if value.nil? or value.to_s.empty?
+ @result_str << "#{name}=#{value} "
+end
+
+def print_info
+ puts @result_str
+end
+
+@result_str = ""
+
+@host = ARGV[2]
+
+if !@host
+ exit -1
+end
+
+load ETC_LOCATION + "/vmwarerc"
+
+if USERNAME.class!=String || PASSWORD.class!=String
+ warn "Bad ESX credentials, aborting"
+ exit -1
+end
+
+data = perform_action("virsh -c #{LIBVIRT_URI} --readonly nodeinfo")
+
+data.split(/\n/).each{|line|
+ if line.match('^CPU\(s\)')
+ $total_cpu = line.split(":")[1].strip.to_i * 100
+ elsif line.match('^CPU frequency')
+ $cpu_speed = line.split(":")[1].strip.split(" ")[0]
+ elsif line.match('^Memory size')
+ $total_memory = line.split(":")[1].strip.split(" ")[0]
+ end
+}
+
+# Loop through all vms
+used_memory = 0
+used_cpu = 0
+
+vms = VirtualMachinePool.new(client)
+
+rc = vms.info
+if OpenNebula.is_error?(rc)
+ warn "Couldn't reach OpenNebula, aborting."
+ exit -1
+end
+
+vm_ids_array = vms.retrieve_elements("/VM_POOL/VM[STATE=3 or STATE=5]/HISTORY_RECORDS/HISTORY[HOSTNAME=\"#{@host}\"]/../ID")
+
+if vm_ids_array
+ vm_ids_array.each do |vm_id|
+ vm=OpenNebula::VirtualMachine.new_with_id(vm_id, client)
+ rc = vm.info
+
+ if OpenNebula.is_error?(rc)
+ warn "Couldn't reach OpenNebula, aborting."
+ exit -1
+ end
+
+ used_memory = used_memory + (vm['TEMPLATE/MEMORY'].to_i * 1024)
+ used_cpu = used_cpu + (vm['TEMPLATE/CPU'].to_f * 100)
+ end
+end
+
+# 80% of the total free calculated memory to take hypervisor into account
+free_memory = ($total_memory.to_i - used_memory) * 0.8
+# assume all the host's CPU is devoted to running Virtual Machines
+free_cpu = ($total_cpu.to_f - used_cpu)
+
+add_info("HYPERVISOR","vmware")
+add_info("TOTALCPU",$total_cpu)
+add_info("FREECPU",free_cpu.to_i)
+add_info("CPUSPEED",$cpu_speed)
+add_info("TOTALMEMORY",$total_memory)
+add_info("FREEMEMORY",free_memory.to_i)
+
+print_info
diff --git a/src/image/ImageManagerActions.cc b/src/image/ImageManagerActions.cc
index 0b625a2818..39e5ec681b 100644
--- a/src/image/ImageManagerActions.cc
+++ b/src/image/ImageManagerActions.cc
@@ -46,6 +46,31 @@ Image * ImageManager::acquire_image(int image_id)
/* -------------------------------------------------------------------------- */
+Image * ImageManager::acquire_image(const string& name, int uid)
+{
+ Image * img;
+ int rc;
+
+ img = ipool->get(name,uid,true);
+
+ if ( img == 0 )
+ {
+ return 0;
+ }
+
+ rc = acquire_image(img);
+
+ if ( rc != 0 )
+ {
+ img->unlock();
+ img = 0;
+ }
+
+ return img;
+}
+
+/* -------------------------------------------------------------------------- */
+
int ImageManager::acquire_image(Image *img)
{
int rc = 0;
diff --git a/src/image/ImagePool.cc b/src/image/ImagePool.cc
index 87ff03086a..b282e72a04 100644
--- a/src/image/ImagePool.cc
+++ b/src/image/ImagePool.cc
@@ -136,6 +136,69 @@ error_common:
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
+static int get_disk_uid(VectorAttribute * disk, int _uid)
+{
+ istringstream is;
+
+ string uid_s ;
+ string uname;
+ int uid;
+
+ if (!(uid_s = disk->vector_value("IMAGE_UID")).empty())
+ {
+ is.str(uid_s);
+ is >> uid;
+
+ if( is.fail() )
+ {
+ return -1;
+ }
+ }
+ else if (!(uname = disk->vector_value("IMAGE_UNAME")).empty())
+ {
+ User * user;
+ Nebula& nd = Nebula::instance();
+ UserPool * upool = nd.get_upool();
+
+ user = upool->get(uname,true);
+
+ if ( user == 0 )
+ {
+ return -1;
+ }
+
+ uid = user->get_oid();
+
+ user->unlock();
+ }
+ else
+ {
+ uid = _uid;
+ }
+
+ return uid;
+}
+
+/* -------------------------------------------------------------------------- */
+
+static int get_disk_id(const string& id_s)
+{
+ istringstream is;
+ int id;
+
+ is.str(id_s);
+ is >> id;
+
+ if( is.fail() )
+ {
+ return -1;
+ }
+
+ return id;
+}
+
+/* -------------------------------------------------------------------------- */
+
int ImagePool::disk_attribute(VectorAttribute * disk,
int disk_id,
int * index,
@@ -152,36 +215,44 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
Nebula& nd = Nebula::instance();
ImageManager * imagem = nd.get_imagem();
- istringstream is;
-
- source = disk->vector_value("IMAGE");
-
- if (!source.empty())
+ if (!(source = disk->vector_value("IMAGE")).empty())
{
- return -3;
- }
-
- source = disk->vector_value("IMAGE_ID");
-
- if (!source.empty())
- {
- is.str(source);
- is >> image_id;
-
- if( !is.fail() )
+ int uiid = get_disk_uid(disk,uid);
+
+ if ( uiid == -1)
{
- img = imagem->acquire_image(image_id);
+ return -1;
+ }
- if (img == 0)
- {
- return -1;
- }
+ img = imagem->acquire_image(source, uiid);
+
+ if ( img == 0 )
+ {
+ return -1;
}
}
-
- if (img == 0)
+ else if (!(source = disk->vector_value("IMAGE_ID")).empty())
{
- string type = disk->vector_value("TYPE");
+ int iid = get_disk_id(source);
+
+ if ( iid == -1)
+ {
+ return -1;
+ }
+
+ img = imagem->acquire_image(iid);
+
+ if ( img == 0 )
+ {
+ return -1;
+ }
+ }
+ else //Not using the image repository
+ {
+ string type;
+
+ rc = -2;
+ type = disk->vector_value("TYPE");
transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper);
@@ -198,13 +269,14 @@ int ImagePool::disk_attribute(VectorAttribute * disk,
disk->replace("TARGET", dev_prefix);
}
}
-
- rc = -2;
}
- else
+
+ if ( img != 0 )
{
img->disk_attribute(disk, index, img_type);
+ image_id = img->get_oid();
+
update(img);
img->unlock();
@@ -224,22 +296,27 @@ void ImagePool::authorize_disk(VectorAttribute * disk,int uid, AuthRequest * ar)
string source;
Image * img = 0;
- istringstream is;
- int image_id;
-
- source = disk->vector_value("IMAGE_ID");
-
- if (source.empty())
+ if (!(source = disk->vector_value("IMAGE")).empty())
{
- return;
+ int uiid = get_disk_uid(disk,uid);
+
+ if ( uiid == -1)
+ {
+ return;
+ }
+
+ img = get(source , uiid, true);
}
-
- is.str(source);
- is >> image_id;
-
- if( !is.fail() )
+ else if (!(source = disk->vector_value("IMAGE_ID")).empty())
{
- img = get(image_id,true);
+ int iid = get_disk_id(source);
+
+ if ( iid == -1)
+ {
+ return;
+ }
+
+ img = get(iid, true);
}
if (img == 0)
diff --git a/src/image/test/ImagePoolTest.cc b/src/image/test/ImagePoolTest.cc
index 4564f30339..3218dd3806 100644
--- a/src/image/test/ImagePoolTest.cc
+++ b/src/image/test/ImagePoolTest.cc
@@ -149,7 +149,8 @@ class ImagePoolTest : public PoolTest
CPPUNIT_TEST ( imagepool_disk_attribute );
CPPUNIT_TEST ( dump );
CPPUNIT_TEST ( dump_where );
-
+ CPPUNIT_TEST ( get_using_name );
+ CPPUNIT_TEST ( wrong_get_name );
CPPUNIT_TEST_SUITE_END ();
protected:
@@ -904,6 +905,64 @@ public:
/* ********************************************************************* */
+ void get_using_name()
+ {
+ int oid_0, oid_1;
+ ImagePool * imp = static_cast(pool);
+
+ // Allocate two objects
+ oid_0 = allocate(0);
+ oid_1 = allocate(1);
+
+ // ---------------------------------
+ // Get first object and check its integrity
+ obj = pool->get(oid_0, false);
+ CPPUNIT_ASSERT( obj != 0 );
+ check(0, obj);
+
+ // Get using its name
+ obj = imp->get(names[1], uids[1], true);
+ CPPUNIT_ASSERT( obj != 0 );
+ obj->unlock();
+
+ check(1, obj);
+
+
+ // ---------------------------------
+ // Clean the cache, forcing the pool to read the objects from the DB
+ pool->clean();
+
+ // Get first object and check its integrity
+ obj = imp->get(names[0], uids[0], false);
+ check(0, obj);
+
+ // Get using its name
+ obj = imp->get(oid_1, false);
+ check(1, obj);
+ };
+
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+
+ void wrong_get_name()
+ {
+ ImagePool * imp = static_cast(pool);
+
+ // The pool is empty
+ // Non existing name
+ obj = imp->get("Wrong name", 0, true);
+ CPPUNIT_ASSERT( obj == 0 );
+
+ // Allocate an object
+ allocate(0);
+
+ // Ask again for a non-existing name
+ obj = imp->get("Non existing name",uids[0], true);
+ CPPUNIT_ASSERT( obj == 0 );
+ }
+
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
};
/* ************************************************************************* */
diff --git a/src/image_mad/remotes/fs/cp b/src/image_mad/remotes/fs/cp
index f8c6b85b7e..bbb2a67783 100755
--- a/src/image_mad/remotes/fs/cp
+++ b/src/image_mad/remotes/fs/cp
@@ -41,8 +41,28 @@ DST=`generate_image_path`
case $SRC in
http://*)
log "Downloading $SRC to the image repository"
+
exec_and_log "$WGET -O $DST $SRC" \
"Error downloading $SRC"
+
+ exec_and_log "chmod 0660 $DST"
+ ;;
+
+vmware://*)
+ SRC=`echo $SRC|sed 's/vmware:\/\///g'`
+
+ if [ `check_restricted $SRC` -eq 1 ]; then
+ log_error "Not allowed to copy images from $RESTRICTED_DIRS"
+ error_message "Not allowed to copy image file $SRC"
+ exit -1
+ fi
+
+ log "Copying local disk folder $SRC to the image repository"
+
+ exec_and_log "cp -rf $SRC $DST" \
+ "Error copying $SRC to $DST"
+
+ exec_and_log "chmod 0770 $DST"
;;
*)
@@ -53,13 +73,16 @@ http://*)
fi
log "Copying local image $SRC to the image repository"
+
exec_and_log "cp -f $SRC $DST" \
"Error copying $SRC to $DST"
+
+ exec_and_log "chmod 0660 $DST"
;;
esac
# ---------------- Get the size of the image & fix perms ------------
-exec_and_log "chmod 0660 $DST"
+
SIZE=`fs_du $DST`
diff --git a/src/image_mad/remotes/fs/fsrc b/src/image_mad/remotes/fs/fsrc
index fb3980a2af..c8e7a58d3a 100644
--- a/src/image_mad/remotes/fs/fsrc
+++ b/src/image_mad/remotes/fs/fsrc
@@ -82,4 +82,14 @@ function check_restricted {
done
echo 0
+}
+
+# Change the permissions of all the files inside directoriers (= VMware disks)
+function fix_owner_perms {
+
+ find $IMAGE_REPOSITORY_PATH -type d \
+ -mindepth 1 \
+ -maxdepth 1 \
+ -execdir chown \
+ -R $SUDO_USER '{}' \;
}
\ No newline at end of file
diff --git a/src/image_mad/remotes/fs/mv b/src/image_mad/remotes/fs/mv
index 121bdf9e11..84c845803e 100755
--- a/src/image_mad/remotes/fs/mv
+++ b/src/image_mad/remotes/fs/mv
@@ -44,7 +44,6 @@ fi
# ------------ Move the image to the repository ------------
-
case $SRC in
http://*)
log "Downloading $SRC to the image repository"
@@ -62,7 +61,12 @@ http://*)
;;
esac
-exec_and_log "chmod 0660 $DST"
+if [ -d $DST ]; then
+ exec_and_log "chmod 0770 $DST"
+ fix_owner_perms
+else
+ exec_and_log "chmod 0660 $DST"
+fi
# ---------------- Get the size of the image ------------
SIZE=`fs_du $DST`
diff --git a/src/image_mad/remotes/fs/rm b/src/image_mad/remotes/fs/rm
index a8abe73c76..a8574e1038 100755
--- a/src/image_mad/remotes/fs/rm
+++ b/src/image_mad/remotes/fs/rm
@@ -37,6 +37,6 @@ SRC=$1
if [ -e $SRC ] ; then
log "Removing $SRC from the image repository"
- exec_and_log "rm $SRC" \
+ exec_and_log "rm -r $SRC" \
"Error deleting $SRC"
fi
diff --git a/src/mad/ruby/vmwarelib.rb b/src/mad/ruby/vmwarelib.rb
new file mode 100644
index 0000000000..a763e7f660
--- /dev/null
+++ b/src/mad/ruby/vmwarelib.rb
@@ -0,0 +1,60 @@
+# ---------------------------------------------------------------------------- #
+# Copyright 2010-2011, C12G Labs S.L #
+# #
+# 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 for the driver #
+# ---------------------------------------------------------------------------- #
+
+ONE_LOCATION = ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
+
+if !ONE_LOCATION
+ BIN_LOCATION = "/usr/bin" if !defined?(BIN_LOCATION)
+ ETC_LOCATION = "/etc/one/" if !defined?(ETC_LOCATION)
+ RUBY_LIB_LOCATION = "/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
+else
+ BIN_LOCATION = ONE_LOCATION + "/bin" if !defined?(BIN_LOCATION)
+ ETC_LOCATION = ONE_LOCATION + "/etc/" if !defined?(ETC_LOCATION)
+ if !defined?(RUBY_LIB_LOCATION)
+ RUBY_LIB_LOCATION = ONE_LOCATION + "/lib/ruby"
+ end
+end
+
+$: << RUBY_LIB_LOCATION
+
+require "OpenNebulaDriver"
+require "CommandManager"
+
+# Do host sustitution in the libvirt URI
+LIBVIRT_URI.gsub!('@HOST@', @host)
+
+# Common functions
+def perform_action(command)
+ command = BIN_LOCATION + "/tty_expect -u " + USERNAME + " -p " + PASSWORD + " " + command
+
+ action_result = LocalCommand.run(command)
+
+ if action_result.code == 0
+ return action_result.stdout
+ else
+ log(command, action_result.stderr, action_result.stdout)
+ return action_result.code
+ end
+end
+
+def log(cmd, stdout, stderr)
+ STDERR.puts "[VMWARE] cmd failed [" + cmd +
+ "]. Stderr: " + stderr + ". Stdout: " + stdout
+end
diff --git a/src/mad/utils/SConstruct b/src/mad/utils/SConstruct
new file mode 100644
index 0000000000..d99dbd44ea
--- /dev/null
+++ b/src/mad/utils/SConstruct
@@ -0,0 +1,22 @@
+# ---------------------------------------------------------------------------- #
+# Copyright 2010-2011, C12G Labs S.L #
+# #
+# 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. #
+# ---------------------------------------------------------------------------- #
+
+Import('env')
+import os
+
+env['LIBS'] = "util"
+
+env.Program('tty_expect.c')
diff --git a/src/mad/utils/tty_expect.c b/src/mad/utils/tty_expect.c
new file mode 100644
index 0000000000..3b2a7e8161
--- /dev/null
+++ b/src/mad/utils/tty_expect.c
@@ -0,0 +1,168 @@
+/* -------------------------------------------------------------------------- */
+/* Copyright 2010-2011, C12G Labs S.L. */
+/* */
+/* 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. */
+/* -------------------------------------------------------------------------- */
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+
+int expect_char(int pty, char * expected, int seconds)
+{
+ fd_set rfds;
+ struct timeval tv;
+
+ int rc;
+ char c;
+
+ do
+ {
+ if (seconds != 0)
+ {
+ FD_ZERO(&rfds);
+ FD_SET(pty, &rfds);
+
+ tv.tv_sec = seconds;
+ tv.tv_usec = 0;
+
+ rc = select(pty+1,&rfds,0,0, &tv);
+
+ if ( rc <= 0 ) // timeout
+ {
+ return -1;
+ }
+ }
+
+ rc = read(pty, (void *) &c, sizeof(char));
+
+ if ( rc > 0 )
+ {
+ if(expected == 0)
+ {
+ write(1,&c,sizeof(char));
+ }
+
+ if (expected != 0 && c == *expected)
+ {
+ return 0;
+ }
+ }
+ }
+ while ( rc > 0 );
+
+ return -1;
+}
+
+void write_answer(int pty, const char * answer)
+{
+ int len, i;
+
+ len = strlen(answer);
+
+ for (i=0; i <-u username> \n\n"
+"SYNOPSIS\n"
+" Wraps the execution of a command and sends username & password\n\n"
+"OPTIONS\n"
+"\t-h\tprints this help.\n"
+"\t-p\tthe password\n"
+"\t-u\tthe username\n"
+"\t\tcomplete virsh command\n";
+
+int main (int argc, char **argv)
+{
+ char * password = 0;
+ char * username = 0;
+
+ char expect = ':';
+
+ int opt, pty, pid, rc;
+
+ while((opt = getopt(argc,argv,"+hp:u:")) != -1)
+ switch(opt)
+ {
+ case 'h':
+ printf("%s",myexpect_usage);
+ exit(0);
+ break;
+ case 'p':
+ password = strdup(optarg);
+ break;
+ case 'u':
+ username = strdup(optarg);
+ break;
+ default:
+ fprintf(stderr,"Wrong option. Check usage\n");
+ fprintf(stderr,"%s",myexpect_usage);
+ exit(-1);
+ break;
+ }
+
+ if (password == 0 || username == 0 || optind >= argc )
+ {
+ fprintf(stderr,"Wrong number of arguments. Check usage\n");
+ fprintf(stderr,"%s",myexpect_usage);
+ exit(-1);
+ }
+
+ pid = forkpty(&pty,0,0,0);
+
+ if(pid == 0)
+ {
+ struct termios tios;
+
+ tcgetattr(pty, &tios);
+
+ tios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
+ tios.c_oflag &= ~(ONLCR);
+
+ tcsetattr(pty, TCSANOW, &tios);
+
+ execvp(argv[optind],&(argv[optind]));
+
+ exit(-1);
+ }
+ else if (pid == -1)
+ {
+ perror("fork\n");
+ }
+
+ expect_char(pty,&expect,1);
+ sleep(1);
+ write_answer(pty,username);
+ expect_char(pty,&expect,1);
+ sleep(1);
+ write_answer(pty,password);
+
+ expect_char(pty,0,0);
+
+ wait(&rc);
+
+ return WEXITSTATUS(rc);
+}
diff --git a/src/oca/ruby/OpenNebula/Configuration.rb b/src/oca/ruby/OpenNebula/Configuration.rb
deleted file mode 100644
index aab519973a..0000000000
--- a/src/oca/ruby/OpenNebula/Configuration.rb
+++ /dev/null
@@ -1,112 +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. #
-#--------------------------------------------------------------------------- #
-
-module OpenNebula
- ############################################################################
- # The Configuration Class represents a simple configuration file using
- # OpenNebula syntax. It does not check syntax.
- ############################################################################
- class Configuration
- attr_reader :conf
-
- ########################################################################
- # Patterns to parse the Configuration File
- ########################################################################
-
- NAME_REG =/[\w\d_-]+/
- VARIABLE_REG =/\s*(#{NAME_REG})\s*=\s*/
-
- SIMPLE_VARIABLE_REG =/#{VARIABLE_REG}([^\[]+?)(#.*)?/
- SINGLE_VARIABLE_REG =/^#{SIMPLE_VARIABLE_REG}$/
- ARRAY_VARIABLE_REG =/^#{VARIABLE_REG}\[(.*?)\]/m
-
- ########################################################################
- ########################################################################
-
- def initialize(str)
- parse_conf(str)
- end
-
- def self.new_from_file(file)
- conf_file = File.read(file)
- self.new(conf_file)
- end
-
- def add_value(key, value)
- if @conf[key]
- if !@conf[key].kind_of?(Array)
- @conf[key]=[@conf[key]]
- end
- @conf[key]< ops[:server],
- :port => ops[:port],
- :user => ops[:user],
- :passwd => passwd,
- :db_name => ops[:db_name]
- )
+ if ops[:backend] == :sqlite
+ @backend = BackEndSQLite.new(ops[:sqlite])
+ elsif ops[:backend] == :mysql
+ 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]
+ )
+ else
+ raise "You need to specify the SQLite or MySQL connection options."
end
end
@@ -151,32 +148,6 @@ class OneDB
private
- def from_onedconf()
- config = OpenNebula::Configuration.new_from_file("#{ETC_LOCATION}/oned.conf")
-
- if config[:db] == nil
- raise "No DB defined."
- 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
- raise "Could not load DB configuration from " <<
- "#{ETC_LOCATION}/oned.conf"
- end
-
- return 0
- end
-
def one_not_running()
if File.exists?(LOCK_FILE)
raise "First stop OpenNebula. Lock file found: #{LOCK_FILE}"
diff --git a/src/onedb/test/test_mysql.sh b/src/onedb/test/test_mysql.sh
index 8b07053057..d6f413f9d2 100755
--- a/src/onedb/test/test_mysql.sh
+++ b/src/onedb/test/test_mysql.sh
@@ -57,7 +57,7 @@ pkill -9 -P $PID oned
echo "All resources created, now 2.2 DB will be upgraded."
# dump current DB and schema
-onedb backup results/mysqldb.3.0 -v
+onedb backup results/mysqldb.3.0 -v -S localhost -P 0 -u oneadmin -p oneadmin -d onedb_test
if [ $? -ne 0 ]; then
exit -1
fi
@@ -68,13 +68,13 @@ if [ $? -ne 0 ]; then
fi
# restore 2.2
-onedb restore -v -f 2.2/mysqldb.sql
+onedb restore -v -f 2.2/mysqldb.sql -S localhost -P 0 -u oneadmin -p oneadmin -d onedb_test
if [ $? -ne 0 ]; then
exit -1
fi
# upgrade
-onedb upgrade -v --backup results/mysqldb.backup
+echo "ssh" | onedb upgrade -v --backup results/mysqldb.backup -S localhost -P 0 -u oneadmin -p oneadmin -d onedb_test
if [ $? -ne 0 ]; then
exit -1
fi
diff --git a/src/onedb/test/test_sqlite.sh b/src/onedb/test/test_sqlite.sh
index f435fbe1a4..3daae85bfd 100755
--- a/src/onedb/test/test_sqlite.sh
+++ b/src/onedb/test/test_sqlite.sh
@@ -61,7 +61,7 @@ echo "All resources created, now 2.2 DB will be upgraded."
cp $VAR_LOCATION/one.db results/one.db.3.0
cp 2.2/one.db results/one.db.upgraded
-onedb upgrade -v --sqlite results/one.db.upgraded --backup results/one.db.backup
+echo "ssh" | onedb upgrade -v --sqlite results/one.db.upgraded --backup results/one.db.backup
if [ $? -ne 0 ]; then
exit -1
diff --git a/src/ozones/Client/lib/zona.rb b/src/ozones/Client/lib/zona.rb
index abc562c84a..b94e889c7f 100644
--- a/src/ozones/Client/lib/zona.rb
+++ b/src/ozones/Client/lib/zona.rb
@@ -18,7 +18,6 @@
require 'rubygems'
require 'uri'
require 'net/https'
-require 'OpenNebula/Configuration'
require 'zona/OZonesJSON'
@@ -122,7 +121,7 @@ EOT
# @param [String] tmpl_str OpenNebula template string
# @return [String, Zona::Error] Response string or Error
def post_resource_str(kind, tmpl_str)
- tmpl_json = Zona.to_body(kind, tmpl_str)
+ tmpl_json = Zona.parse_template(kind, tmpl_str)
post_resource(kind, tmpl_json)
end
@@ -150,7 +149,7 @@ EOT
# @param [String] tmpl_str OpenNebula template string
# @return [String, Zona::Error] Response string or Error
def put_resource_str(kind, id, tmpl_str)
- tmpl_json = Client.to_body(kind, tmpl_str)
+ tmpl_json = Zona.parse_template(kind, tmpl_str)
put_resource(kind, id, tmpl_json)
end
@@ -261,7 +260,7 @@ EOT
else
if Zona.is_http_error?(value)
str = "Operating with #{kind} failed with HTTP error"
- str = " " + str + "code: #{value.code}\n"
+ str += " code: #{value.code}\n"
if value.body
# Try to extract error message
begin
@@ -281,13 +280,24 @@ EOT
end
- # Turns a OpenNebula template string into a JSON string
+ # Parses a OpenNebula template string and turns it into a JSON string
# @param [String] kind element kind
# @param [String] tmpl_str template
# @return [String, Zona::Error] JSON string or Error
- def self.to_body(kind, tmpl_str)
- tmpl = OpenNebula::Configuration.new(tmpl_str)
- res = { "#{kind.upcase}" => tmpl.conf }
+ def self.parse_template(kind, tmpl_str)
+ name_reg =/[\w\d_-]+/
+ variable_reg =/\s*(#{name_reg})\s*=\s*/
+ single_variable_reg =/^#{variable_reg}([^\[]+?)(#.*)?$/
+
+ tmpl = Hash.new
+
+ tmpl_str.scan(single_variable_reg) do | m |
+ key = m[0].strip.upcase
+ value = m[1].strip
+ tmpl[key] = value
+ end
+
+ res = { "#{kind.upcase}" => tmpl }
return OZonesJSON.to_json(res)
end
diff --git a/src/ozones/Server/ozones-server.rb b/src/ozones/Server/ozones-server.rb
index 7863c4b64a..ef34108ee0 100755
--- a/src/ozones/Server/ozones-server.rb
+++ b/src/ozones/Server/ozones-server.rb
@@ -159,7 +159,14 @@ end
before do
unless request.path=='/login' || request.path=='/'
- halt 401 unless authorized?
+
+ unless authorized?
+ rc , msg = build_session
+
+ if rc == 401
+ halt 401
+ end
+ end
@OzonesServer = OzonesServer.new(session[:key])
@pr = OZones::ProxyRules.new("apache",config[:htaccess])
diff --git a/src/ozones/Server/public/css/application.css b/src/ozones/Server/public/css/application.css
index c99f7b641e..e8212b067b 100644
--- a/src/ozones/Server/public/css/application.css
+++ b/src/ozones/Server/public/css/application.css
@@ -215,6 +215,12 @@ label{
text-align:left;
}
+.dataTables_wrapper label {
+ float: none;
+ width: auto;
+ padding: 0 0;
+ text-align:right;
+}
div.tip {
display: inline-block;
@@ -411,7 +417,7 @@ tr.even:hover{
}
.top_button {
- font-size: 0.8em;
+ font-size: 0.8em!important;
height: 25px;
margin: 3px 2px;
vertical-align: middle;
@@ -465,15 +471,15 @@ tr.even:hover{
font-size: 1.2em;
}
-.jGrowl-notification, .jGrowl-closer, .jGrowl-notify-submit {
+.jGrowl-notification, .jGrowl-notify-submit {
border: 2px #444444 solid;
- background-color: #F3F3F3;
+ background-color: #F3F3F3!important;
color: #666666;
}
.jGrowl-notify-error {
border: 2px #660000 solid;
- background-color: #F39999;
+ background-color: #F39999!important;
color: #660000;
}
@@ -578,4 +584,13 @@ ul.dd_right{
}
ul.dd_left{
+}
+
+.ui-widget{
+ font: 10pt Arial, Verdana, Geneva, Helvetica, sans-serif;
+}
+
+.ui-layout-resizer-open-hover, /* hover-color to 'resize' */
+.ui-layout-resizer-dragging {
+ background: #EEE;
}
\ No newline at end of file
diff --git a/src/ozones/Server/public/css/layout.css b/src/ozones/Server/public/css/layout.css
index e4d6e2864a..b61f0b6ea6 100644
--- a/src/ozones/Server/public/css/layout.css
+++ b/src/ozones/Server/public/css/layout.css
@@ -44,19 +44,26 @@ body {
}
#header {
- padding:0;
+ padding: 0 10px 0 10px;
background-color: #353735;
+ border:0;
}
#footer {
- padding:0;
+ padding-top: 9px;
+ font-size: 0.8em;
+ color: white;
+ text-align: center;
background-color: #353735;
+ border:0;
+
}
-#header {
- padding: 0 10px 0 10px;
- background-color: #353735;
+#footer a {
+ color: white;
+ text-decoration: underline;
}
+
#logo {
padding-top: 6px;
font-weight: bold;
@@ -87,18 +94,6 @@ body {
color: #88C140;
}
-#footer {
- padding-top: 9px;
- font-size: 0.8em;
- color: white;
- text-align: center;
-}
-
-#footer a {
- color: white;
- text-decoration: underline;
-}
-
#logo-wrapper {
float: right;
margin-top: 0px;
@@ -108,6 +103,7 @@ body {
#menu {
padding-right: 0;
padding-left: 0;
+ border:0;
border-right: 1px solid #353735;
background-image: -webkit-gradient(
linear,
diff --git a/src/ozones/Server/public/js/plugins/vdcs-tab.js b/src/ozones/Server/public/js/plugins/vdcs-tab.js
index 06ae83e6d5..d46b8edacd 100644
--- a/src/ozones/Server/public/js/plugins/vdcs-tab.js
+++ b/src/ozones/Server/public/js/plugins/vdcs-tab.js
@@ -42,7 +42,7 @@ var create_vdc_tmpl =
\
\
\
- \
+ \
\
\
@@ -51,12 +51,13 @@ var create_vdc_tmpl =
\
Allows hosts belonging to other VDCs to be re-added to this one. They will appear greyed-out in the lists.
\
\
- \
- \
+ \
+ \
+ \
\
-
\
-
\
-
\
+
\
+
\
+
\
\
\
\
';
-var images_select = "";
var dataTable_images;
var $create_image_dialog;
@@ -537,40 +536,22 @@ function imageInfoListener(){
});
}
-//Updates the select input field with an option for each image
-function updateImageSelect(){
- images_select =
- makeSelectOptions(dataTable_images,
- 1,
- 4,
- [9,9,9],
- ["DISABLED","LOCKED","ERROR"]
- );
-
- //update static selectors:
- //in the VM section
- $('div.vm_section#disks select#IMAGE_ID', $create_template_dialog).html(images_select);
-}
-
// Callback to update an element in the dataTable
function updateImageElement(request, image_json){
var id = image_json.IMAGE.ID;
var element = imageElementArray(image_json);
updateSingleElement(element,dataTable_images,'#image_'+id);
- updateImageSelect();
}
// Callback to remove an element from the dataTable
function deleteImageElement(req){
deleteElement(dataTable_images,'#image_'+req.request.data);
- updateImageSelect();
}
// Callback to add an image element
function addImageElement(request, image_json){
var element = imageElementArray(image_json);
addElement(element,dataTable_images);
- updateImageSelect();
}
// Callback to refresh the list of images
@@ -582,7 +563,6 @@ function updateImagesView(request, images_list){
});
updateView(image_list_array,dataTable_images);
- updateImageSelect();
updateDashboard("images",images_list);
}
diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js
index 82f91813dd..18c185f64a 100644
--- a/src/sunstone/public/js/plugins/templates-tab.js
+++ b/src/sunstone/public/js/plugins/templates-tab.js
@@ -195,9 +195,10 @@ var create_template_tmpl = '
\
\
\
\
-
\
\
\
@@ -267,7 +268,7 @@ var create_template_tmpl = '
\
\
\
\
- \
+ \
\
\
\
@@ -292,9 +293,10 @@ var create_template_tmpl = '