diff --git a/src/cloud/ec2/lib/EC2QueryServer.rb b/src/cloud/ec2/lib/EC2QueryServer.rb
index 7dc310fd96..12d8441b10 100644
--- a/src/cloud/ec2/lib/EC2QueryServer.rb
+++ b/src/cloud/ec2/lib/EC2QueryServer.rb
@@ -241,7 +241,7 @@ class EC2QueryServer < CloudServer
private
def render_launch_time(vm)
- return "#{Time.at(vm["STIME"].to_i).xmlschema}"
+ return "#{Time.at(vm["STIME"].to_i).utc.xmlschema}"
end
end
diff --git a/src/datastore_mad/remotes/xpath.rb b/src/datastore_mad/remotes/xpath.rb
index ec424f0e85..ce57ddb651 100755
--- a/src/datastore_mad/remotes/xpath.rb
+++ b/src/datastore_mad/remotes/xpath.rb
@@ -64,7 +64,13 @@ ARGV.each do |xpath|
values << ar.join(' ')
else
element = xml.elements[xpath.dup]
- values << element.text.to_s if !element.nil?
+ if !element.nil?
+ if element.class.method_defined?(:text)
+ values << element.text
+ else
+ values << element.to_s
+ end
+ end
end
values << "\0"
end
diff --git a/src/onedb/fsck.rb b/src/onedb/fsck.rb
index 3862d0d9f8..9f52c559ab 100644
--- a/src/onedb/fsck.rb
+++ b/src/onedb/fsck.rb
@@ -2637,7 +2637,7 @@ EOT
# Params:
# +disk+:: Nokogiri::XML::Node describing a disk used by a template
def get_image_from_name(disk)
- name = disk.at_xpath("IMAGE").content # always defined
+ name = disk.at_xpath("IMAGE") && disk.at_xpath("IMAGE").content
uid = disk.at_xpath("IMAGE_UID")
uname = disk.at_xpath("IMAGE_UNAME")
diff --git a/src/sunstone/etc/sunstone-views/admin.yaml b/src/sunstone/etc/sunstone-views/admin.yaml
index fbb43d0725..c7841aa65a 100644
--- a/src/sunstone/etc/sunstone-views/admin.yaml
+++ b/src/sunstone/etc/sunstone-views/admin.yaml
@@ -1,5 +1,6 @@
small_logo: images/opennebula-5.0.png
provision_logo: images/opennebula-5.0.png
+confirm_vms: true
enabled_tabs:
- dashboard-tab
- instances-top-tab
diff --git a/src/sunstone/etc/sunstone-views/cloud.yaml b/src/sunstone/etc/sunstone-views/cloud.yaml
index 00c5133b29..7201d6b9e9 100644
--- a/src/sunstone/etc/sunstone-views/cloud.yaml
+++ b/src/sunstone/etc/sunstone-views/cloud.yaml
@@ -1,4 +1,5 @@
provision_logo: images/opennebula-5.0.png
+confirm_vms: true
enabled_tabs:
- provision-tab
- settings-tab
diff --git a/src/sunstone/etc/sunstone-views/groupadmin.yaml b/src/sunstone/etc/sunstone-views/groupadmin.yaml
index c829ef12bc..144207051f 100644
--- a/src/sunstone/etc/sunstone-views/groupadmin.yaml
+++ b/src/sunstone/etc/sunstone-views/groupadmin.yaml
@@ -1,5 +1,6 @@
small_logo: images/opennebula-5.0.png
provision_logo: images/opennebula-5.0.png
+confirm_vms: true
enabled_tabs:
- dashboard-tab
- instances-top-tab
diff --git a/src/sunstone/public/app/sunstone-config.js b/src/sunstone/public/app/sunstone-config.js
index d1c02c1f3e..6666a9a9e9 100644
--- a/src/sunstone/public/app/sunstone-config.js
+++ b/src/sunstone/public/app/sunstone-config.js
@@ -146,10 +146,15 @@ define(function(require) {
'vmLogos': (_config['vm_logos']),
'enabledTabs': _config['view']['enabled_tabs'],
'onedConf': _config['oned_conf'],
+ 'confirmVMActions': _config['view']['confirm_vms'],
"allTabs": function() {
return Object.keys(_config['view']['tabs']);
}
+
+ /*"isConfirmVmsActionsEnable": function() {
+ Console.Log(_config['view']['confirm_vms']);
+ }*/
}
return Config;
diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/info.js b/src/sunstone/public/app/tabs/vms-tab/panels/info.js
index a7b334a711..2784b5597a 100644
--- a/src/sunstone/public/app/tabs/vms-tab/panels/info.js
+++ b/src/sunstone/public/app/tabs/vms-tab/panels/info.js
@@ -77,6 +77,8 @@ define(function(require) {
var hostnameHTML = OpenNebula.VM.hostnameStrLink(this.element);
var vrouterHTML = '--';
+ var IP = OpenNebula.VM.ipsStr(this.element);
+
if (this.element.TEMPLATE.VROUTER_ID != undefined){
vrouterHTML = Navigation.link(
OpenNebula.VirtualRouter.getName(this.element.TEMPLATE.VROUTER_ID),
@@ -122,6 +124,7 @@ define(function(require) {
'hostnameHTML': hostnameHTML,
'prettyStartTime': prettyStartTime,
'deployId': deployId,
+ 'IP': IP,
'resched': resched,
'permissionsTableHTML': permissionsTableHTML,
'templateTableHTML': templateTableHTML,
@@ -133,7 +136,6 @@ define(function(require) {
function _setup(context) {
RenameTr.setup(TAB_ID, RESOURCE, this.element.ID, context);
PermissionsTable.setup(TAB_ID, RESOURCE, this.element, context);
-
// Get rid of the unwanted (for show) SCHED_* keys
var that = this;
var strippedTemplate = {};
diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/info/html.hbs b/src/sunstone/public/app/tabs/vms-tab/panels/info/html.hbs
index 10bae54700..e19be83db1 100644
--- a/src/sunstone/public/app/tabs/vms-tab/panels/info/html.hbs
+++ b/src/sunstone/public/app/tabs/vms-tab/panels/info/html.hbs
@@ -43,6 +43,13 @@
{{{hostnameHTML}}}
+
+
+
{{tr "IP"}}
+
{{{IP}}}
+
+
+
{{tr "Start time"}}
{{prettyStartTime}}
diff --git a/src/sunstone/public/app/tabs/vms-tab/utils/datatable-common.js b/src/sunstone/public/app/tabs/vms-tab/utils/datatable-common.js
index 6e8c515d09..657edb0649 100644
--- a/src/sunstone/public/app/tabs/vms-tab/utils/datatable-common.js
+++ b/src/sunstone/public/app/tabs/vms-tab/utils/datatable-common.js
@@ -130,6 +130,7 @@ define(function(require) {
];
}
+
function _emptyElementArray(vmId) {
return [
'
+
OpenNebula Sunstone: Cloud Operations Center
@@ -60,6 +61,7 @@
<% else %>
+
<% end %>
diff --git a/src/sunstone/views/login.erb b/src/sunstone/views/login.erb
index 1aba62d546..2c4d711d2e 100644
--- a/src/sunstone/views/login.erb
+++ b/src/sunstone/views/login.erb
@@ -1,7 +1,9 @@
+
+
OpenNebula Sunstone Login
diff --git a/src/tm_mad/common/prepostmigrate b/src/tm_mad/common/prepostmigrate
index 3948c77672..44a1a18463 100755
--- a/src/tm_mad/common/prepostmigrate
+++ b/src/tm_mad/common/prepostmigrate
@@ -25,8 +25,8 @@
# - template is the template of the VM in XML and base64 encoded
# - system_ds_mad flag if called by other SYSTEM_DS TM_MAD
-SRC="$1"
-DST="$2"
+SRC_HOST="$1"
+DST_HOST="$2"
DST_PATH="$3"
VM_ID="$4"
DS_ID="$5"
diff --git a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb
index 5df05b6e00..debef85db0 100644
--- a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb
+++ b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb
@@ -2651,8 +2651,7 @@ private
vm.config.hardware.device.each{ |dv|
if is_nic?(dv)
nics.each{|nic|
- if nic.elements["MAC"].text == dv.macAddress and
- nic.elements["BRIDGE"].text == dv.deviceInfo.summary
+ if nic.elements["MAC"].text == dv.macAddress
nics.delete(nic)
end
}
diff --git a/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb
index 282d6afd0e..691ade0310 100644
--- a/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb
+++ b/src/vnm_mad/remotes/802.1Q/vlan_tag_driver.rb
@@ -51,4 +51,17 @@ class VLANTagDriver < VNMMAD::VLANDriver
OpenNebula.exec_and_log("#{command(:ip)} link set #{@nic[:vlan_dev]} up")
end
+
+ def get_interface_vlan(name)
+ text = %x(#{command(:ip)} -d link show #{name})
+ return nil if $?.exitstatus != 0
+
+ text.each_line do |line|
+ m = line.match(/vlan protocol 802.1Q id (\d+)/)
+
+ return m[1] if m
+ end
+
+ nil
+ end
end
diff --git a/src/vnm_mad/remotes/OpenNebulaNetwork.conf b/src/vnm_mad/remotes/OpenNebulaNetwork.conf
index 9c58fb556a..16ae01a7eb 100644
--- a/src/vnm_mad/remotes/OpenNebulaNetwork.conf
+++ b/src/vnm_mad/remotes/OpenNebulaNetwork.conf
@@ -14,6 +14,10 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
+# Set to true to check that no other vlans are connected to the bridge.
+# Works with 802.1Q and VXLAN.
+:validate_vlan_id: false
+
################################################################################
# Open vSwitch Options
################################################################################
diff --git a/src/vnm_mad/remotes/lib/vlan.rb b/src/vnm_mad/remotes/lib/vlan.rb
index 578ef10814..c685cbd5fd 100644
--- a/src/vnm_mad/remotes/lib/vlan.rb
+++ b/src/vnm_mad/remotes/lib/vlan.rb
@@ -46,6 +46,9 @@ module VNMMAD
# Create the bridge.
create_bridge
+ # Check that no other vlans are connected to this bridge
+ validate_vlan_id
+
# Return if vlan device is already in the bridge.
next if @bridges[@nic[:bridge]].include? @nic[:vlan_dev]
@@ -91,6 +94,9 @@ module VNMMAD
# Get the name of the vlan device.
get_vlan_dev_name
+ # Return if the bridge doesn't exist because it was already deleted (handles last vm with multiple nics on the same vlan)
+ next if !@bridges.include? @nic[:bridge]
+
# Return if the vlan device is not the only left device in the bridge.
next if @bridges[@nic[:bridge]].length > 1 or !@bridges[@nic[:bridge]].include? @nic[:vlan_dev]
@@ -149,5 +155,27 @@ module VNMMAD
bridges
end
+
+ def get_interface_vlan(name)
+ nil
+ end
+
+ def validate_vlan_id
+ @bridges[@nic[:bridge]].each do |interface|
+ vlan = get_interface_vlan(interface)
+
+ if vlan && vlan.to_s != @nic[:vlan_id]
+ OpenNebula.log_error("The interface #{interface} has "\
+ "vlan_id = #{vlan} but the network is configured "\
+ "with vlan_id = #{@nic[:vlan_id]}")
+
+ msg = "Interface with an incorrect vlan_id is already in "\
+ "the bridge"
+ OpenNebula.error_message(msg)
+
+ exit(-1)
+ end
+ end
+ end
end
end
diff --git a/src/vnm_mad/remotes/lib/vnmmad.rb b/src/vnm_mad/remotes/lib/vnmmad.rb
index 8d965bcdf9..4bf39119df 100644
--- a/src/vnm_mad/remotes/lib/vnmmad.rb
+++ b/src/vnm_mad/remotes/lib/vnmmad.rb
@@ -32,7 +32,7 @@ require 'sg_driver'
require 'vlan'
require 'scripts_common'
-Dir["vnmmad-load.d/*.rb"].each{ |f| require f }
+Dir[File.expand_path('vnmmad-load.d', File.dirname(__FILE__)) + "/*.rb"].each{ |f| require f }
include OpenNebula
diff --git a/src/vnm_mad/remotes/vxlan/vxlan_driver.rb b/src/vnm_mad/remotes/vxlan/vxlan_driver.rb
index 3ca84b1ee7..509c7c24e1 100644
--- a/src/vnm_mad/remotes/vxlan/vxlan_driver.rb
+++ b/src/vnm_mad/remotes/vxlan/vxlan_driver.rb
@@ -54,4 +54,17 @@ class VXLANDriver < VNMMAD::VLANDriver
OpenNebula.exec_and_log("#{command(:ip)} link set #{@nic[:vlan_dev]} up")
end
+
+ def get_interface_vlan(name)
+ text = %x(#{command(:ip)} -d link show #{name})
+ return nil if $?.exitstatus != 0
+
+ text.each_line do |line|
+ m = line.match(/^\s*vxlan id (\d+)/)
+
+ return m[1] if m
+ end
+
+ nil
+ end
end