You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2015/03/12 07:04:53 UTC

[01/12] git commit: updated refs/heads/master to c27c694

Repository: cloudstack
Updated Branches:
  refs/heads/master ff9ab5caa -> c27c69438


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index e81dd2b..eb9e0da 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -3946,15 +3946,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
 
         if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
                 && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv)
-                && !vm.getHypervisorType().equals(HypervisorType.LXC) && !vm.getHypervisorType().equals(HypervisorType.Simulator)) {
+                && !vm.getHypervisorType().equals(HypervisorType.LXC) && !vm.getHypervisorType().equals(HypervisorType.Simulator)
+                && !vm.getHypervisorType().equals(HypervisorType.Ovm3)) {
             if (s_logger.isDebugEnabled()) {
                 s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv, cannot migrate this VM.");
             }
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv only");
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
         }
 
         if (vm.getType().equals(VirtualMachine.Type.User) && vm.getHypervisorType().equals(HypervisorType.LXC)) {
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv only");
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
         }
 
         if (isVMUsingLocalStorage(vm)) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index e4c97a0..111df93 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -407,7 +407,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
      */
     @Override
     public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
-        String simulatorLabel, String vlan, String hypervLabel) {
+        String simulatorLabel, String vlan, String hypervLabel, String ovm3Label) {
         // TODO Auto-generated method stub
         return null;
     }
@@ -425,7 +425,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
      * @see com.cloud.network.NetworkService#updatePhysicalNetworkTrafficType(java.lang.Long, java.lang.String, java.lang.String, java.lang.String)
      */
     @Override
-    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel) {
+    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3Label) {
         // TODO Auto-generated method stub
         return null;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/setup/db/db/schema-450to460.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-450to460.sql b/setup/db/db/schema-450to460.sql
index 4a5ea93..8ca4ab0 100644
--- a/setup/db/db/schema-450to460.sql
+++ b/setup/db/db/schema-450to460.sql
@@ -353,3 +353,28 @@ CREATE VIEW `cloud`.`user_vm_view` AS
         `cloud`.`user_vm_details` `custom_speed`  ON (((`custom_speed`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_speed`.`name` = 'CpuSpeed')))
            left join
         `cloud`.`user_vm_details` `custom_ram_size`  ON (((`custom_ram_size`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_ram_size`.`name` = 'memory')));
+
+-- ovm3 stuff
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ("Ovm3", 'Sun Solaris 10(32-bit)', 79);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ("Ovm3", 'Sun Solaris 10(64-bit)', 80);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ("Ovm3", 'Sun Solaris 11(32-bit)', 158);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ("Ovm3", 'Sun Solaris 11(64-bit)', 159);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ("Ovm3", 'Other Linux (32-bit)', 98);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ("Ovm3", 'Other Linux (64-bit)', 99);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ('Ovm3', 'Other PV (32-bit)', 139);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ('Ovm3', 'Other PV (64-bit)', 140);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ('Ovm3', 'DOS', 102);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ("Ovm3", 'Windows 8 (32-bit)', 165);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ("Ovm3", 'Windows 8 (64-bit)', 166);
+INSERT INTO `cloud`.`guest_os_hypervisor` (hypervisor_type, guest_os_name, guest_os_id) VALUES  ("Ovm3", 'Windows Server 2012 (64-bit)', 167);
+
+INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm3', '3.2', 25, 0);
+INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('Ovm3', '3.3', 50, 0);
+UPDATE  `cloud`.`volumes` v,  `cloud`.`storage_pool` s,  `cloud`.`cluster` c  set v.format='RAW' where v.pool_id=s.id and s.cluster_id=c.id and c.hypervisor_type='Ovm3';
+UPDATE configuration SET value='KVM,XenServer,VMware,BareMetal,Ovm,Ovm3,LXC' WHERE name='hypervisor.list';
+INSERT INTO `cloud`.`vm_template` (id, uuid, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id,featured, cross_zones, hypervisor_type, state)
+VALUES (12, UUID(), 'routing-12', 'SystemVM Template (Ovm3)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/4.6/systemvm64template.ovm.raw.bz2', '4425688804dbcf0abc9e9e56c53070d7', 0, 'SystemVM Template (Ovm3)', 'RAW', 183, 0, 1, 'Ovm3', 'Active' );
+
+INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'ManagementServer', 'ovm3.heartbeat.timeout' , '180', '120', 'Timeout value to send to the checkheartbeat script for guarding the self fencing functionality on ovm3');
+INSERT IGNORE INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `description`) VALUES ('Advanced', 'DEFAULT', 'ManagementServer', 'ovm3.heartbeat.interval' , '10', '1', 'Interval value the checkheartbeat script uses before triggering the timeout for ovm3');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'NetworkManager', 'router.template.ovm3', 'SystemVM Template (Ovm3)', 'Name of the default router template on Ovm3.','SystemVM Template (Ovm3)', NULL, NULL, 0);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/tools/appliance/build.sh
----------------------------------------------------------------------
diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh
index d298090..993b6d8 100755
--- a/tools/appliance/build.sh
+++ b/tools/appliance/build.sh
@@ -415,7 +415,7 @@ function ovm_export() {
   mv img.raw ${appliance_build_name}-ovm.raw
   bzip2 "${appliance_build_name}-ovm.raw"
   mv "${appliance_build_name}-ovm.raw.bz2" dist/
-  log INFO "${appliance} exported for OracleVM: dist/${appliance_build_name}-ovm.vhd.bz2"
+  log INFO "${appliance} exported for OracleVM: dist/${appliance_build_name}-ovm.raw.bz2"
 }
 
 function kvm_export() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/ui/dictionary2.jsp
----------------------------------------------------------------------
diff --git a/ui/dictionary2.jsp b/ui/dictionary2.jsp
index c9cb8f0..3ecffac 100644
--- a/ui/dictionary2.jsp
+++ b/ui/dictionary2.jsp
@@ -1051,6 +1051,9 @@ under the License.
 'label.of.month': '<fmt:message key="label.of.month" />',
 'label.minutes.past.hour': '<fmt:message key="label.minutes.past.hour" />',
 'label.snapshots': '<fmt:message key="label.snapshots" />',
-'label.add.private.gateway': '<fmt:message key="label.add.private.gateway" />'
+'label.add.private.gateway': '<fmt:message key="label.add.private.gateway" />',
+'label.ovm3.pool': '<fmt:message key="label.ovm3.pool" />',
+'label.ovm3.cluster': '<fmt:message key="label.ovm3.cluster" />',
+'label.ovm3.vip': '<fmt:message key="label.ovm3.vip" />'
 });
 </script>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/ui/scripts/docs.js
----------------------------------------------------------------------
diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js
index b7f2668..dea6881 100755
--- a/ui/scripts/docs.js
+++ b/ui/scripts/docs.js
@@ -1297,5 +1297,17 @@ cloudStack.docs = {
     helpVspRetryInterval: {
         desc: 'The interval of time in milliseconds to wait on failure before attempting to resend the command to Nuage VSD.  Valid values [0 - 10000].',
         externalLink: ''
+    },
+    helpOvm3pool: {
+        desc: 'Pool the Ovm3 nodes in this cluster, required for vm node migrations',
+        externalLink: ''
+    },
+    helpOvm3cluster: {
+        desc: 'Use the native Ovm3 OCFS2 clustering, required for native HA and requires pooling',
+        externalLink: ''
+    },
+    helpOvm3Vip: {
+        desc: 'The VIP used by the pool and cluster',
+        externalLink: ''
     }
 };

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/ui/scripts/system.js
----------------------------------------------------------------------
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
index 845ce52..126b1fc 100644
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -139,6 +139,8 @@
         trafficType.lxcnetworklabel = _l( 'label.network.label.display.for.blank.value');
         if (trafficType.hypervnetworklabel == null || trafficType.hypervnetworklabel == 0)
         trafficType.hypervnetworklabel = _l( 'label.network.label.display.for.blank.value');
+        if (trafficType.ovm3networklabel == null || trafficType.ovm3networklabel == 0)
+        trafficType.ovm3networklabel = _l( 'label.network.label.display.for.blank.value');
         
         return trafficType;
     };
@@ -157,6 +159,8 @@
         array1.push("&lxcnetworklabel=" + labels.lxcnetworklabel);
         if (labels.hypervnetworklabel != _l( 'label.network.label.display.for.blank.value'))
         array1.push("&hypervnetworklabel=" + labels.hypervnetworklabel);
+        if (labels.ovm3networklabel != _l( 'label.network.label.display.for.blank.value'))
+        array1.push("&ovm3networklabel=" + labels.ovm3networklabel);
         
         $.ajax({
             url: createURL('updateTrafficType' + array1.join("")),
@@ -597,6 +601,10 @@
                                     hypervnetworklabel: {
                                         label: 'label.hyperv.traffic.label',
                                         isEditable: true
+                                    },
+                                    ovm3networklabel: {
+                                        label: 'label.ovm3.traffic.label',
+                                        isEditable: true
                                     }
                                 }],
                                 
@@ -620,7 +628,7 @@
                                             selectedPublicNetworkObj.ovmnetworklabel = trafficType.ovmnetworklabel;
                                             selectedPublicNetworkObj.lxcnetworklabel = trafficType.lxcnetworklabel;
                                             selectedPublicNetworkObj.hypervnetworklabel = trafficType.hypervnetworklabel;
-                                            
+                                            selectedPublicNetworkObj.ovm3networklabel = trafficType.ovm3networklabel;
                                             args.response.success({
                                                 data: selectedPublicNetworkObj
                                             });
@@ -907,6 +915,10 @@
                                     hypervnetworklabel: {
                                         label: 'label.hyperv.traffic.label',
                                         isEditable: true
+                                    },
+                                    ovm3networklabel: {
+                                        label: 'label.ovm3.traffic.label',
+                                        isEditable: true
                                     }
                                 }],
                                 
@@ -926,7 +938,7 @@
                                             selectedPublicNetworkObj.ovmnetworklabel = trafficType.ovmnetworklabel;
                                             selectedPublicNetworkObj.lxcnetworklabel = trafficType.lxcnetworklabel;
                                             selectedPublicNetworkObj.hypervnetworklabel = trafficType.hypervnetworklabel;
-                                            
+                                            selectedPublicNetworkObj.ovm3networklabel = trafficType.ovm3networklabel;
                                             args.response.success({
                                                 data: selectedPublicNetworkObj
                                             });
@@ -1119,6 +1131,10 @@
                                     hypervnetworklabel: {
                                         label: 'label.hyperv.traffic.label',
                                         isEditable: true
+                                    },
+                                    ovm3networklabel: {
+                                        label: 'label.ovm3.traffic.label',
+                                        isEditable: true
                                     }
                                 }],
                                 dataProvider: function (args) {
@@ -1136,7 +1152,7 @@
                                             selectedManagementNetworkObj.ovmnetworklabel = trafficType.ovmnetworklabel;
                                             selectedManagementNetworkObj.lxcnetworklabel = trafficType.lxcnetworklabel;
                                             selectedManagementNetworkObj.hypervnetworklabel = trafficType.hypervnetworklabel;
-                                            
+                                            selectedManagementNetworkObj.ovm3networklabel = trafficType.ovm3networklabel;
                                             args.response.success({
                                                 data: selectedManagementNetworkObj
                                             });
@@ -1308,6 +1324,10 @@
                                     hypervnetworklabel: {
                                         label: 'label.hyperv.traffic.label',
                                         isEditable: true
+                                    },
+                                    ovm3networklabel: {
+                                        label: 'label.ovm3.traffic.label',
+                                        isEditable: true
                                     }
                                 }],
                                 dataProvider: function (args) {
@@ -1347,7 +1367,7 @@
                                             selectedPhysicalNetworkObj[ "ovmnetworklabel"] = trafficType.ovmnetworklabel;
                                             selectedPhysicalNetworkObj[ "lxcnetworklabel"] = trafficType.lxcnetworklabel;
                                             selectedPhysicalNetworkObj[ "hypervnetworklabel"] = trafficType.hypervnetworklabel;
-                                            
+                                            selectedPhysicalNetworkObj[ "ovm3networklabel"] = trafficType.ovm3networklabel;
                                             args.response.success({
                                                 actionFilter: function () {
                                                     var allowedActions =[ 'edit', 'addVlanRange', 'removeVlanRange'];
@@ -9241,12 +9261,13 @@
                                 	var array1 = [];
                                 	
                                 	// ***** non XenServer (begin) *****
-                                	var hypervisors = ["Hyperv", "KVM", "VMware", "BareMetal", "LXC"];
-                                	
+					var hypervisors = ["Hyperv", "KVM", "VMware", "BareMetal", "LXC", "Ovm3"];
+
                                         	var supportSocketHypervisors = {
-                                        		"Hyperv": 1, 
-                                        		"KVM": 1, 
-                                        		"VMware": 1
+                                                "Hyperv": 1,
+                                                "KVM": 1,
+                                                "VMware": 1,
+                                                "Ovm3": 1
                                         	};                                        	
                                         	
                                 	for (var h = 0; h < hypervisors.length; h++) {
@@ -14023,7 +14044,31 @@
                                             required: false
                                         }
                                     },
-                                    
+
+                                    //hypervisor==Ovm3 begins here
+                                    ovm3pool: {
+                                        label: 'label.ovm3.pool',
+                                        isHidden: true,
+                                        isBoolean: true,
+                                        isChecked: true,
+                                        docID: 'helpOvm3pool'
+                                    },
+                                    ovm3cluster: {
+                                        label: 'label.ovm3.cluster',
+                                        isHidden: true,
+                                        isBoolean: true,
+                                        isChecked: false,
+                                        docID: 'helpOvm3cluster'
+                                    },
+                                    ovm3vip: {
+                                        label: 'label.ovm3.vip',
+                                        isHidden: true,
+                                        docID: 'helpOvm3Vip',
+                                        validation: {
+                                            required: false
+                                        }
+                                    },
+
                                     //hypervisor==VMWare begins here
                                     vCenterHost: {
                                         label: 'label.vcenter.host',
@@ -14253,7 +14298,11 @@
                                 array1.push("&podId=" + args.data.podId);
                                 
                                 var clusterName = args.data.name;
-                                
+                                if (args.data.hypervisor == "Ovm3") {
+                                     array1.push("&ovm3pool=" + todb(args.data.ovm3pool));
+                                     array1.push("&ovm3cluster=" + todb(args.data.ovm3cluster));
+                                     array1.push("&ovm3vip=" + todb(args.data.ovm3vip));
+                                }
                                 if (args.data.hypervisor == "VMware") {
                                     array1.push("&username=" + todb(args.data.vCenterUsername));
                                     array1.push("&password=" + todb(args.data.vCenterPassword));
@@ -15243,6 +15292,14 @@
                                                     //$('li[input_group="Ovm"]', $dialogAddHost).hide();
                                                     $form.find('.form-item[rel=agentUsername]').hide();
                                                     $form.find('.form-item[rel=agentPassword]').hide();
+
+                                                    //$('li[input_group="Ovm3"]', $dialogAddHost).hide();
+                                                    $form.find('.form-item[rel=agentUsername]').hide();
+                                                    $form.find('.form-item[rel=agentPassword]').hide();
+                                                    $form.find('.form-item[rel=agentPort]').hide();
+                                                    $form.find('.form-item[rel=ovm3vip]').hide();
+                                                    $form.find('.form-item[rel=ovm3pool]').hide();
+                                                    $form.find('.form-item[rel=ovm3cluster]').hide();
                                                 } else if (selectedClusterObj.hypervisortype == "BareMetal") {
                                                     //$('li[input_group="general"]', $dialogAddHost).show();
                                                     $form.find('.form-item[rel=hostname]').css('display', 'inline-block');
@@ -15257,10 +15314,18 @@
                                                     
                                                     //$('li[input_group="vmware"]', $dialogAddHost).hide();
                                                     $form.find('.form-item[rel=vcenterHost]').hide();
-                                                    
+
                                                     //$('li[input_group="Ovm"]', $dialogAddHost).hide();
                                                     $form.find('.form-item[rel=agentUsername]').hide();
                                                     $form.find('.form-item[rel=agentPassword]').hide();
+
+                                                    //$('li[input_group="Ovm3"]', $dialogAddHost).hide();
+                                                    $form.find('.form-item[rel=agentUsername]').hide();
+                                                    $form.find('.form-item[rel=agentPassword]').hide();
+                                                    $form.find('.form-item[rel=agentPort]').hide();
+                                                    $form.find('.form-item[rel=ovm3vip]').hide();
+                                                    $form.find('.form-item[rel=ovm3pool]').hide();
+                                                    $form.find('.form-item[rel=ovm3cluster]').hide();
                                                 } else if (selectedClusterObj.hypervisortype == "Ovm") {
                                                     //$('li[input_group="general"]', $dialogAddHost).show();
                                                     $form.find('.form-item[rel=hostname]').css('display', 'inline-block');
@@ -15280,6 +15345,38 @@
                                                     $form.find('.form-item[rel=agentUsername]').css('display', 'inline-block');
                                                     $form.find('.form-item[rel=agentUsername]').find('input').val("oracle");
                                                     $form.find('.form-item[rel=agentPassword]').css('display', 'inline-block');
+
+                                                    //$('li[input_group="Ovm3"]', $dialogAddHost).hide();
+                                                    $form.find('.form-item[rel=agentUsername]').hide();
+                                                    $form.find('.form-item[rel=agentPassword]').hide();
+                                                    $form.find('.form-item[rel=agentPort]').hide();
+                                                    $form.find('.form-item[rel=ovm3vip]').hide();
+                                                    $form.find('.form-item[rel=ovm3pool]').hide();
+                                                    $form.find('.form-item[rel=ovm3cluster]').hide();
+                                                } else if (selectedClusterObj.hypervisortype == "Ovm3") {
+                                                    //$('li[input_group="general"]', $dialogAddHost).show();
+                                                    $form.find('.form-item[rel=hostname]').css('display', 'inline-block');
+                                                    $form.find('.form-item[rel=username]').css('display', 'inline-block');
+                                                    $form.find('.form-item[rel=password]').css('display', 'inline-block');
+
+                                                    //$('li[input_group="vmware"]', $dialogAddHost).hide();
+                                                    $form.find('.form-item[rel=vcenterHost]').hide();
+
+                                                    //$('li[input_group="baremetal"]', $dialogAddHost).hide();
+                                                    $form.find('.form-item[rel=baremetalCpuCores]').hide();
+                                                    $form.find('.form-item[rel=baremetalCpu]').hide();
+                                                    $form.find('.form-item[rel=baremetalMemory]').hide();
+                                                    $form.find('.form-item[rel=baremetalMAC]').hide();
+
+                                                     //$('li[input_group="Ovm3"]', $dialogAddHost).show();
+                                                    $form.find('.form-item[rel=agentUsername]').css('display', 'inline-block');
+                                                    $form.find('.form-item[rel=agentUsername]').find('input').val("oracle");
+                                                    $form.find('.form-item[rel=agentPassword]').css('display', 'inline-block');
+                                                    $form.find('.form-item[rel=agentPort]').css('display', 'inline-block');
+                                                    $form.find('.form-item[rel=agentPort]').find('input').val("8899");
+                                                    $form.find('.form-item[rel=ovm3vip]').css('display', 'inline-block');
+                                                    $form.find('.form-item[rel=ovm3pool]').css('display', 'inline-block');
+                                                    $form.find('.form-item[rel=ovm3cluster]').css('display', 'inline-block');
                                                 } else {
                                                     //$('li[input_group="general"]', $dialogAddHost).show();
                                                     $form.find('.form-item[rel=hostname]').css('display', 'inline-block');
@@ -15298,6 +15395,14 @@
                                                     //$('li[input_group="Ovm"]', $dialogAddHost).hide();
                                                     $form.find('.form-item[rel=agentUsername]').hide();
                                                     $form.find('.form-item[rel=agentPassword]').hide();
+
+                                                    //$('li[input_group="Ovm3"]', $dialogAddHost).hide();
+                                                    $form.find('.form-item[rel=agentUsername]').hide();
+                                                    $form.find('.form-item[rel=agentPassword]').hide();
+                                                    $form.find('.form-item[rel=agentPort]').hide();
+                                                    $form.find('.form-item[rel=ovm3vip]').hide();
+                                                    $form.find('.form-item[rel=ovm3pool]').hide();
+                                                    $form.find('.form-item[rel=ovm3cluster]').hide();
                                                 }
                                             });
                                             
@@ -15442,7 +15547,17 @@
                                         isPassword: true
                                     },
                                     //input_group="OVM" ends here
-                                    
+
+                                    //input_group="OVM3" starts here
+                                    agentPort: {
+                                        label: 'label.agent.port',
+                                        validation: {
+                                            required: false
+                                        },
+                                        isHidden: true
+                                    },
+                                    //input_group="OVM3" ends here
+
                                     //always appear (begin)
                                     hosttags: {
                                         label: 'label.host.tags',
@@ -15540,6 +15655,12 @@
                                             agentusername: args.data.agentUsername,
                                             agentpassword: args.data.agentPassword
                                         });
+                                    } else if (selectedClusterObj.hypervisortype == "Ovm3") {
+                                        $.extend(data, {
+                                            agentusername: args.data.agentUsername,
+                                            agentpassword: args.data.agentPassword,
+                                            agentport: args.data.agentPort,
+                                       });
                                     }
                                 }
                                 
@@ -16690,6 +16811,13 @@
                                                 args.response.success({
                                                     data: items
                                                 });
+                                            // 3.3.2 has ceph/ocfs2/iscsi etc
+                                            } else if (selectedClusterObj.hypervisortype == "Ovm3") {
+                                                var items =[];
+                                                items.push({
+                                                    id: "nfs",
+                                                    description: "nfs"
+                                                });
                                             } else {
                                                 args.response.success({
                                                     data:[]

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/ui/scripts/zoneWizard.js
----------------------------------------------------------------------
diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js
index 13bc3ab..2ae056b 100755
--- a/ui/scripts/zoneWizard.js
+++ b/ui/scripts/zoneWizard.js
@@ -91,6 +91,9 @@
             case 'LXC':
                 hypervisorAttr = 'lxcnetworklabel';
                 break;
+            case 'Ovm3':
+                hypervisorAttr = 'ovm3networklabel';
+                break;
         }
 
         trafficLabelStr = trafficLabel ? '&' + hypervisorAttr + '=' + trafficLabel : '';
@@ -494,6 +497,7 @@
                                         nonSupportedHypervisors["BareMetal"] = 1;
                                         nonSupportedHypervisors["Hyperv"] = 1;
                                         nonSupportedHypervisors["Ovm"] = 1;
+                                        nonSupportedHypervisors["Ovm3"] = 1;
                                     }
 
                                     if (args.context.zones[0]['network-model'] == "Advanced") { //CLOUDSTACK-7681: UI > zone wizard > Advanced zone > hypervisor => do not support BareMetal                                    
@@ -1006,6 +1010,13 @@
                                         $vsmFields.css('display', 'none');
                                     }
                                     //$("#cluster_name_label", $dialogAddCluster).text("vCenter Cluster:");
+                                } else if ($(this).val() == "Ovm3") {
+                                    $form.find('.form-item[rel=ovm3pool]').css('display', 'inline-block');
+                                    $form.find('.form-item[rel=ovm3pool]').find('input[type=checkbox]').removeAttr('checked');
+
+                                    $form.find('.form-item[rel=ovm3cluster]').css('display', 'inline-block');
+                                    $form.find('.form-item[rel=ovm3cluster]').find('input[type=checkbox]').removeAttr('checked');
+                                    $form.find('[rel=ovm3vip]').css('display', 'block');
                                 } else {
                                     //$('li[input_group="vmware"]', $dialogAddCluster).hide();
 
@@ -1276,6 +1287,14 @@
                         //$('li[input_group="Ovm"]', $dialogAddHost).hide();
                         $form.find('[rel=agentUsername]').hide();
                         $form.find('[rel=agentPassword]').hide();
+
+                        //$('li[input_group="Ovm3"]', $dialogAddHost).hide();
+                        $form.find('.form-item[rel=agentUsername]').hide();
+                        $form.find('.form-item[rel=agentPassword]').hide();
+                        $form.find('.form-item[rel=agentPort]').hide();
+                        $form.find('.form-item[rel=ovm3vip]').hide();
+                        $form.find('.form-item[rel=ovm3pool]').hide();
+                        $form.find('.form-item[rel=ovm3cluster]').hide();
                     } else if (selectedClusterObj.hypervisortype == "BareMetal") {
                         //$('li[input_group="general"]', $dialogAddHost).show();
                         $form.find('[rel=hostname]').css('display', 'block');
@@ -1294,6 +1313,14 @@
                         //$('li[input_group="Ovm"]', $dialogAddHost).hide();
                         $form.find('[rel=agentUsername]').hide();
                         $form.find('[rel=agentPassword]').hide();
+
+                        //$('li[input_group="Ovm3"]', $dialogAddHost).hide();
+                        $form.find('.form-item[rel=agentUsername]').hide();
+                        $form.find('.form-item[rel=agentPassword]').hide();
+                        $form.find('.form-item[rel=agentPort]').hide();
+                        $form.find('.form-item[rel=ovm3vip]').hide();
+                        $form.find('.form-item[rel=ovm3pool]').hide();
+                        $form.find('.form-item[rel=ovm3cluster]').hide();
                     } else if (selectedClusterObj.hypervisortype == "Ovm") {
                         //$('li[input_group="general"]', $dialogAddHost).show();
                         $form.find('[rel=hostname]').css('display', 'block');
@@ -1313,6 +1340,36 @@
                         $form.find('[rel=agentUsername]').css('display', 'block');
                         $form.find('[rel=agentUsername]').find('input').val("oracle");
                         $form.find('[rel=agentPassword]').css('display', 'block');
+
+                        //$('li[input_group="Ovm3"]', $dialogAddHost).hide();
+                        $form.find('.form-item[rel=agentPort]').hide();
+                        $form.find('.form-item[rel=ovm3vip]').hide();
+                        $form.find('.form-item[rel=ovm3pool]').hide();
+                        $form.find('.form-item[rel=ovm3cluster]').hide();
+                   } else if (selectedClusterObj.hypervisortype == "Ovm3") {
+                        //$('li[input_group="general"]', $dialogAddHost).show();
+                        $form.find('.form-item[rel=hostname]').css('display', 'inline-block');
+                        $form.find('.form-item[rel=username]').css('display', 'inline-block');
+                        $form.find('.form-item[rel=password]').css('display', 'inline-block');
+
+                        //$('li[input_group="vmware"]', $dialogAddHost).hide();
+                        $form.find('.form-item[rel=vcenterHost]').hide();
+
+                        //$('li[input_group="baremetal"]', $dialogAddHost).hide();
+                        $form.find('.form-item[rel=baremetalCpuCores]').hide();
+                        $form.find('.form-item[rel=baremetalCpu]').hide();
+                        $form.find('.form-item[rel=baremetalMemory]').hide();
+                        $form.find('.form-item[rel=baremetalMAC]').hide();
+
+                         //$('li[input_group="Ovm3"]', $dialogAddHost).show();
+                        $form.find('.form-item[rel=agentUsername]').css('display', 'inline-block');
+                        $form.find('.form-item[rel=agentUsername]').find('input').val("oracle");
+                        $form.find('.form-item[rel=agentPassword]').css('display', 'inline-block');
+                        $form.find('.form-item[rel=agentPort]').css('display', 'inline-block');
+                        $form.find('.form-item[rel=agentPort]').find('input').val("8899");
+                        $form.find('.form-item[rel=ovm3vip]').css('display', 'inline-block');
+                        $form.find('.form-item[rel=ovm3pool]').css('display', 'inline-block');
+                        $form.find('.form-item[rel=ovm3cluster]').css('display', 'inline-block');
                     } else {
                         //$('li[input_group="general"]', $dialogAddHost).show();
                         $form.find('[rel=hostname]').css('display', 'block');
@@ -1331,6 +1388,11 @@
                         //$('li[input_group="Ovm"]', $dialogAddHost).hide();
                         $form.find('[rel=agentUsername]').hide();
                         $form.find('[rel=agentPassword]').hide();
+                        //$('li[input_group="Ovm3"]', $dialogAddHost).hide();
+                        $form.find('.form-item[rel=agentPort]').hide();
+                        $form.find('.form-item[rel=ovm3vip]').hide();
+                        $form.find('.form-item[rel=ovm3pool]').hide();
+                        $form.find('.form-item[rel=ovm3cluster]').hide();
                     }
                 },
                 fields: {
@@ -1419,6 +1481,16 @@
                     },
                     //input_group="OVM" ends here
 
+                    //input_group="OVM3" starts here
+                    agentPort: {
+                        label: 'label.agent.port',
+                        validation: {
+                            required: false
+                        },
+                        isHidden: true
+                    },
+                    //input_group="OVM3" ends here
+
                     //always appear (begin)
                     hosttags: {
                         label: 'label.host.tags',
@@ -1583,6 +1655,15 @@
                                 args.response.success({
                                     data: items
                                 });
+                            } else if (selectedClusterObj.hypervisortype == "Ovm3") {
+                                var items = [];
+                                items.push({
+                                    id: "nfs",
+                                    description: "nfs"
+                                });
+                                args.response.success({
+                                    data: items
+                                });
                             } else {
                                 args.response.success({
                                     data: []


[10/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/StoragePlugin.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/StoragePlugin.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/StoragePlugin.java
new file mode 100644
index 0000000..24c774a
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/StoragePlugin.java
@@ -0,0 +1,882 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.w3c.dom.Document;
+
+/*
+ * should become an interface implementation
+ */
+public class StoragePlugin extends OvmObject {
+    private static final String EMPTY_STRING = "";
+    private static final String PLUGINPATH = "//Discover_Storage_Plugins_Result/storage_plugin_info_list/storage_plugin_info";
+    private static final String NFSPLUGIN = "oracle.generic.NFSPlugin.GenericNFSPlugin";
+    private static final String FILESYS = "FileSys";
+    private static final String STATUS = "status";
+    private static final String UUID = "uuid";
+    private static final String SSUUID = "ss_uuid";
+    private static final String SIZE = "size";
+    private static final String FREESIZE = "free_sz";
+    private static final String STATE = "state";
+    private static final String ACCESSGROUPNAMES = "access_grp_names";
+    private static final String ACCESSPATH = "access_path";
+    private static final String NAME = "name";
+    private static final String MOUNTOPTIONS = "mount_options";
+    private static final String ADMINUSER = "admin_user";
+    private static final String ADMINHOST = "admin_host";
+    private static final String TOTALSIZE = "total_sz";
+    private static final String ADMINPASSWORD = "admin_passwd";
+    private static final String STORAGEDESC = "storage_desc";
+    private static final String ACCESSHOST = "access_host";
+    private static final String STORAGETYPE = "storage_type";
+    private static final String ALLOCSIZE = "alloc_sz";
+    private static final String ACCESSGROUPS = "access_grps";
+    private static final String USEDSIZE = "used_sz";
+    private static final String FRTYPE = "fr_type";
+    private static final String ONDISKSIZE = "ondisk_sz";
+    private static final String FSUUID = "fs_uuid";
+    private static final String FILEPATH = "file_path";
+    private static final String FILESIZE = "file_sz";
+    private static final Boolean ACTIVE = true;
+
+    private String getPluginType = NFSPLUGIN;
+    private List<String> supportedPlugins = new ArrayList<String>();
+    private final List<String> someList = new ArrayList<String>(); /* empty */
+    private FileProperties fileProperties = new FileProperties();
+    private StorageDetails storageDetails = new StorageDetails();
+    private StorageServer storageServer = new StorageServer();
+
+    public StoragePlugin(Connection c) {
+        setClient(c);
+    }
+
+    /* uuid has dashes here!, and ss_uuid is the relation to the storage source uuid */
+    public class StorageDetails {
+        private Map<String, Object> storageDetails = new HashMap<String, Object>() {
+            {
+                put(STATUS, EMPTY_STRING);
+                put(UUID, EMPTY_STRING);
+                put(SSUUID, EMPTY_STRING);
+                put(SIZE, EMPTY_STRING);
+                put(FREESIZE, 0);
+                put(STATE, 0);
+                put(ACCESSGROUPNAMES, new ArrayList<String>());
+                put(ACCESSPATH, EMPTY_STRING);
+                put(NAME, EMPTY_STRING);
+                put(MOUNTOPTIONS, new ArrayList<String>());
+            }
+        };
+        public Map<String, Object> getDetails() {
+            return storageDetails;
+        }
+        public void setDetails(Map<String, Object> details) {
+            storageDetails = details;
+        }
+        public void setSize(String val) {
+            storageDetails.put(SIZE, val);
+        }
+        public String getSize() {
+            return (String) storageDetails.get(SIZE);
+        }
+        public void setFreeSize(String val) {
+            storageDetails.put(FREESIZE, val);
+        }
+        public String getFreeSize() {
+            return (String) storageDetails.get(FREESIZE);
+        }
+        public void setState(Integer val) {
+            storageDetails.put(STATE, val);
+        }
+        public Integer getState() {
+            return (Integer) storageDetails.get(STATE);
+        }
+        public void setStatus(String val) {
+            storageDetails.put(STATUS, val);
+        }
+        public String getStatus() {
+            return (String) storageDetails.get(STATUS);
+        }
+        /* format depends on storagesource type ? */
+        public void setAccessPath(String val) {
+            storageDetails.put(ACCESSPATH, val);
+        }
+        public String getAccessPath() {
+            return (String) storageDetails.get(ACCESSPATH);
+        }
+        public void setName(String val) {
+            storageDetails.put(NAME, val);
+        }
+        public String getName() {
+            return (String) storageDetails.get(NAME);
+        }
+        public void setUuid(String val) throws Ovm3ResourceException {
+            if (!val.contains("-")) {
+                throw new Ovm3ResourceException("Storage Details UUID should contain dashes: " + val);
+            }
+            storageDetails.put(UUID, val);
+        }
+        public String getUuid() {
+            return (String) storageDetails.get(UUID);
+        }
+        public void setDetailsRelationalUuid(String val) throws Ovm3ResourceException {
+            if (val.contains("-")) {
+                throw new Ovm3ResourceException("Storage Details UUID that relates to Storage Source should notcontain dashes: " + val);
+            }
+            storageDetails.put(SSUUID, val);
+        }
+        public String getDetailsRelationalUuid() {
+            return (String) storageDetails.get(SSUUID);
+        }
+        public void setAccessGroupNames(List<String> l) {
+            storageDetails.put(ACCESSGROUPNAMES, l);
+        }
+        public List<String> getAccessGroupNames() {
+            return (List<String>) storageDetails.get(ACCESSGROUPNAMES);
+        }
+        public void setMountOptions(List<String> l) {
+            storageDetails.put(MOUNTOPTIONS, l);
+        }
+        public List<String> getMountOptions() {
+            return (List<String>) storageDetails.get(MOUNTOPTIONS);
+        }
+    }
+
+    /* mind you uuid has NO dashes here */
+    public class StorageServer {
+        private Map<String, Object> storageSource = new HashMap<String, Object>() {
+            {
+                put(STATUS, EMPTY_STRING);
+                put(ADMINUSER, EMPTY_STRING);
+                put(ADMINHOST, EMPTY_STRING);
+                put(UUID, EMPTY_STRING);
+                put(TOTALSIZE, 0);
+                put(ADMINPASSWORD, EMPTY_STRING);
+                put(STORAGEDESC, EMPTY_STRING);
+                put(FREESIZE, 0);
+                put(ACCESSHOST, EMPTY_STRING);
+                put(STORAGETYPE, EMPTY_STRING);
+                put(ALLOCSIZE, 0);
+                put(ACCESSGROUPS,  new ArrayList<String>());
+                put(USEDSIZE, 0);
+                put(NAME, EMPTY_STRING);
+            }
+        };
+        public Map<String, Object> getDetails() {
+            return storageSource;
+        }
+        public void setDetails(Map<String, Object> details) {
+            storageSource = details;
+        }
+        public void setAccessGroups(List<String> l) {
+            storageSource.put(ACCESSGROUPS, l);
+        }
+        public List<String> getAccessGroups() {
+            return (List<String>) storageSource.get(ACCESSGROUPS);
+        }
+        public void setStatus(String val) {
+            storageSource.put(STATUS, val);
+        }
+        public String getStatus() {
+            return (String) storageSource.get(STATUS);
+        }
+        public void setAdminUser(String val) {
+            storageSource.put(ADMINUSER, val);
+        }
+        public String getAdminUser() {
+            return (String) storageSource.get(ADMINUSER);
+        }
+        public void setAdminHost(String val) {
+            storageSource.put(ADMINHOST, val);
+        }
+        public String getAdminHost() {
+            return (String) storageSource.get(ADMINHOST);
+        }
+        public void setUuid(String val) throws Ovm3ResourceException {
+            if (val.contains("-")) {
+                throw new Ovm3ResourceException("Storage Source UUID should not contain dashes: " + val);
+            }
+            storageSource.put(UUID, val);
+        }
+        public String getUuid() {
+            return (String) storageSource.get(UUID);
+        }
+        public String getTotalSize() {
+            return (String) storageSource.get(TOTALSIZE);
+        }
+        public void setTotalSize(Integer val) {
+            storageSource.put(TOTALSIZE, val);
+        }
+        public void setAdminPassword(String val) {
+            storageSource.put("admin_password", val);
+        }
+        public String getAdminPassword() {
+            return (String) storageSource.get("admin_password");
+        }
+        public void setDescription(String val) {
+            storageSource.put(STORAGEDESC, val);
+        }
+        public String getDescription() {
+            return (String) storageSource.get(STORAGEDESC);
+        }
+        public String getFreeSize() {
+            return (String) storageSource.get(FREESIZE);
+        }
+        public void setFreeSize(Integer val) {
+            storageSource.put(FREESIZE, val);
+        }
+        public void setAccessHost(String val) {
+            storageSource.put(ACCESSHOST, val);
+        }
+        public String getAccessHost() {
+            return (String) storageSource.get(ACCESSHOST);
+        }
+        public void setStorageType(String val) {
+            storageSource.put(STORAGETYPE, val);
+        }
+        public String getStorageType() {
+            return (String) storageSource.get(STORAGETYPE);
+        }
+        public void setAllocationSize(Integer val) {
+            storageSource.put(ALLOCSIZE, val);
+        }
+        public Integer getAllocationSize() {
+            return (Integer) storageSource.get(ALLOCSIZE);
+        }
+        public void setUsedSize(Integer val) {
+            storageSource.put(USEDSIZE, val);
+        }
+        public Integer getUsedSize() {
+            return (Integer) storageSource.get(USEDSIZE);
+        }
+        public void setName(String val) {
+            storageSource.put(NAME, val);
+        }
+        public String getName() {
+            return (String) storageSource.get(NAME);
+        }
+    }
+
+    public class FileProperties {
+        private Map<String, Object> fileProperties = new HashMap<String, Object>() {
+            {
+                put(FRTYPE, EMPTY_STRING);
+                put(ONDISKSIZE, EMPTY_STRING);
+                put(FSUUID, EMPTY_STRING);
+                put(FILEPATH, EMPTY_STRING);
+                put(FILESIZE, EMPTY_STRING);
+            }
+        };
+        public Map<String, Object> getProperties() {
+            return fileProperties;
+        }
+        public void setProperties(Map<String, Object> props) {
+            fileProperties = props;
+        }
+        public String getName() {
+            return (String) fileProperties.get(FILEPATH);
+        }
+        public String setName(String f) {
+            return (String) fileProperties.put(FILEPATH, f);
+        }
+        public String setType(String t) {
+            return (String) fileProperties.put(FRTYPE, t);
+        }
+        public String getType() {
+            return (String) fileProperties.get(FRTYPE);
+        }
+        public void setSize(Long t) {
+            fileProperties.put(FILESIZE, t);
+        }
+        public Long getSize() {
+            return Long.parseLong((String) fileProperties.get(FILESIZE));
+        }
+        public String setOnDiskSize(String t) {
+            return (String) fileProperties.put(ONDISKSIZE, t);
+        }
+        public String getOnDiskSize() {
+            return (String) fileProperties.get(ONDISKSIZE);
+        }
+        public String setUuid(String t) {
+            return (String) fileProperties.put(FSUUID, t);
+        }
+        public String getUuid() {
+            return (String) fileProperties.get(FSUUID);
+        }
+    }
+
+    public String getPluginType() {
+        return getPluginType;
+    }
+    private Boolean setPluginType(String val) throws Ovm3ResourceException {
+        for(String plugin : discoverStoragePlugins()) {
+            if (plugin.matches("(?i:.*"+val+".*)")) {
+                getPluginType = plugin;
+                return true;
+            }
+        }
+        return false;
+    }
+    public Boolean setISCSI() throws Ovm3ResourceException {
+        return setPluginType("SCSI");
+    }
+    public Boolean setOCFS2() throws Ovm3ResourceException {
+        return setPluginType("OCFS2");
+    }
+    public Boolean setNFS() throws Ovm3ResourceException {
+        return setPluginType("NFS");
+    }
+
+    /* Actions for the storage plugin */
+    /*
+     * storage_plugin_resizeFileSystem, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getStatus, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None meh ?
+     */
+
+    /*
+     * storage_plugin_validate, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_setQoS, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * now only for files
+     * storage_plugin_create, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None - calls resize secretly.. after "create"
+     */
+    public FileProperties storagePluginCreate(String poolUuid, String host,
+            String file, Long size, Boolean dir) throws Ovm3ResourceException{
+        /* this is correct ordering stuff and correct naming!!! */
+        String uuid = deDash(poolUuid);
+        StorageServer ss = new StorageServer();
+        StorageDetails sd = new StorageDetails();
+        FileProperties fp = new FileProperties();
+        ss.setUuid(uuid);
+        ss.setStorageType(FILESYS);
+        ss.setAccessHost(host);
+        sd.setUuid(poolUuid);
+        sd.setDetailsRelationalUuid(uuid);
+        sd.setState(2);
+        String type = "File";
+        if (dir) {
+            type = "Directory";
+        }
+        fp.setProperties((HashMap<String, Object>) callWrapper("storage_plugin_create",
+                getPluginType, ss.getDetails(),
+                sd.getDetails(), file, type, size));
+        return fp;
+    }
+
+    /*
+     * storage_plugin_createAccessGroups, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_deviceTeardown, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_startPresent, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_listFileSystems, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+    public Boolean storagePluginListFs(String host) throws Ovm3ResourceException {
+        StorageServer ss = new StorageServer();
+        ss.setAccessHost(host);
+        ss.setStorageType(FILESYS);
+        ss.setDetails((Map<String, Object>) callWrapper("storage_plugin_listFileSystems",
+                getPluginType, ss.getDetails()));
+        return true;
+    }
+
+    /*
+     * storage_plugin_getFileSystemCloneLimits, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getQoSList, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_stopPresent, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_isCloneable, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /**
+     * . storage_plugin_mount, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+    public final StorageDetails storagePluginMountNFS(String nfsHost, String nfsRemotePath,
+            String mntUuid, String mountPoint) throws Ovm3ResourceException {
+        String propUuid = deDash(mntUuid);
+        StorageServer ss = new StorageServer();
+        StorageDetails sd = new StorageDetails();
+        ss.setUuid(propUuid);
+        ss.setName(propUuid);
+        ss.setAccessHost(nfsHost);
+        sd.setDetailsRelationalUuid(propUuid);
+        sd.setUuid(mntUuid);
+        sd.setAccessPath(nfsHost + ":" + nfsRemotePath);
+        if (!mountPoint.contains(mntUuid)) {
+            mountPoint += File.separator + mntUuid;
+        }
+        sd.setDetails((HashMap<String, Object>) callWrapper(
+                "storage_plugin_mount", getPluginType, ss.getDetails(),
+                sd.getDetails(), mountPoint, EMPTY_STRING, ACTIVE,
+                someList));
+        /* this magically means it's already mounted....
+         * double check */
+        if (sd.getDetails() == null) {
+            sd = storagePluginGetFileSystemInfo(propUuid,
+                    mntUuid, nfsHost, nfsRemotePath);
+        }
+        if (EMPTY_STRING.contains(ss.getUuid())) {
+            throw new Ovm3ResourceException("Unable to mount NFS FileSystem");
+        }
+        return sd;
+    }
+
+    /**
+     * . storage_plugin_unmount, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     *
+     * @return boolean
+     *
+     */
+    public final Boolean storagePluginUnmountNFS(String nfsHost, String remotePath, String mntUuid, String localPath) throws Ovm3ResourceException {
+        StorageServer ss = new StorageServer();
+        StorageDetails sd = new StorageDetails();
+        sd.setUuid(mntUuid);
+        sd.setDetailsRelationalUuid(deDash(mntUuid));
+        ss.setUuid(deDash(mntUuid));
+        ss.setAccessHost(nfsHost);
+        sd.setAccessPath(nfsHost + ":" + remotePath);
+        sd.setState(1);
+        ss.setStorageType(FILESYS);
+        String mountPoint = localPath + File.separator + mntUuid;
+        callWrapper("storage_plugin_unmount", getPluginType,
+                ss.getDetails(), sd.getDetails(), mountPoint, ACTIVE);
+        return true;
+    }
+
+    /*
+     * storage_plugin_resize, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_deviceSizeRefresh, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+    /*
+     * storage_plugin_getStorageNames, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_splitClone, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_destroyFileSystem, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_snapRestore, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_updateSERecords, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getSnapLimits, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * discover_storage_plugins, <class 'agent.api.storageplugin.StoragePlugin'>
+     */
+    public List<String> discoverStoragePlugins() throws Ovm3ResourceException{
+        supportedPlugins = new ArrayList<String>();
+        Object result = callWrapper("discover_storage_plugins");
+        if (result == null) {
+            return supportedPlugins;
+        }
+        Document xmlDocument = prepParse((String) result);
+        supportedPlugins.addAll(xmlToList(PLUGINPATH + "/@plugin_impl_name", xmlDocument));
+        return supportedPlugins;
+    }
+
+    private Map<String,String> checkStoragePluginDetails(String plugin, Boolean ability) throws Ovm3ResourceException {
+        Object result = callWrapper("discover_storage_plugins");
+        Document xmlDocument = prepParse((String) result);
+        if (discoverStoragePlugins().contains(plugin)) {
+            String details = PLUGINPATH + "[@plugin_impl_name='" + plugin + "']";
+            if (ability) {
+                return xmlToMap(details + "/abilities", xmlDocument);
+            } else {
+                return xmlToMap(details, xmlDocument);
+            }
+        } else {
+            throw new Ovm3ResourceException("StoragePlugin should be one of: " + supportedPlugins);
+        }
+    }
+
+    private String checkStoragePluginBoth(String type, String property, Boolean ab) throws Ovm3ResourceException{
+        String val = checkStoragePluginDetails(type, ab).get(property);
+        if (val == null) {
+            throw new Ovm3ResourceException("StoragePlugin " + type + " has no " + property);
+        }
+        return val;
+    }
+
+    public String checkStoragePluginAbility(String type, String property) throws Ovm3ResourceException {
+        return checkStoragePluginBoth(type, property, true);
+    }
+    public String checkStoragePluginProperties(String type, String property) throws Ovm3ResourceException {
+        return checkStoragePluginBoth(type, property, false);
+    }
+
+    /*
+     * storage_plugin_deviceResize, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getCloneLimits, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * INFO: is used for files and dirs..., we only implement files for now...
+     * storage_plugin_destroy, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+    public Boolean storagePluginDestroy(String poolUuid, String file) throws Ovm3ResourceException {
+        String uuid = deDash(poolUuid);
+        StorageServer ss = new StorageServer();
+        StorageDetails sd = new StorageDetails();
+        FileProperties fp = new FileProperties();
+        ss.setUuid(uuid);
+        sd.setDetailsRelationalUuid(uuid);
+        sd.setUuid(poolUuid);
+        fp.setType("file");
+        fp.setUuid(poolUuid);
+        fp.setName(file);
+        return nullIsTrueCallWrapper(
+                "storage_plugin_destroy", getPluginType, ss.getDetails(),
+                sd.getDetails(), fp.getProperties());
+    }
+
+    /*
+     * storage_plugin_isSnapable, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getDetailsInfo, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_removeFromAccessGroup, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_renameAccessGroup, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_stop, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_createMultiSnap, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getCurrentSnaps, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getFileInfo, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+    public FileProperties storagePluginGetFileInfo(String poolUuid, String host,
+            String file) throws Ovm3ResourceException {
+        /* file path is the full path */
+        String uuid = deDash(poolUuid);
+        StorageServer ss = new StorageServer();
+        StorageDetails sd = new StorageDetails();
+        FileProperties fp = new FileProperties();
+        ss.setUuid(uuid);
+        ss.setAccessHost(host);
+        sd.setUuid(poolUuid);
+        sd.setDetailsRelationalUuid(uuid);
+        sd.setState(1);
+        fp.setName(file);
+        fp.setProperties((HashMap<String, Object>) callWrapper(
+                "storage_plugin_getFileInfo",
+                getPluginType,
+                ss.getDetails(),
+                sd.getDetails(),
+                fp.getProperties()));
+        if ("".equals(fp.getName())) {
+            throw new Ovm3ResourceException("Unable to get file info for " + file);
+        }
+        return fp;
+    }
+
+    /*
+     * Should do some input checking of ss and base
+     * storage_plugin_getFileSystemInfo,
+     * <class 'agent.api.storageplugin.StoragePlugin'> argument: impl_name -
+     * default: None requires a minumum of uuid, access_host, storage_type
+     * ss_uuid, access_path, uuid (the ss
+     */
+    public StorageDetails storagePluginGetFileSystemInfo(String propUuid,
+            String mntUuid, String nfsHost, String nfsRemotePath) throws Ovm3ResourceException{
+        /* clean the props */
+        StorageServer ss = new StorageServer();
+        StorageDetails sd = new StorageDetails();
+        new FileProperties();
+        ss.setUuid(propUuid);
+        sd.setDetailsRelationalUuid(propUuid);
+        sd.setUuid(mntUuid);
+        ss.setAccessHost(nfsHost);
+        if (nfsRemotePath.contains(nfsHost + ":")) {
+            sd.setAccessPath(nfsRemotePath);
+        } else {
+            sd.setAccessPath(nfsHost + ":" + nfsRemotePath);
+        }
+        ss.setStorageType(FILESYS);
+        sd.setDetails((HashMap<String, Object>) callWrapper(
+                "storage_plugin_getFileSystemInfo", getPluginType,
+                ss.getDetails(), sd.getDetails()));
+        return sd;
+    }
+    public StorageDetails getStorageDetails() {
+        return storageDetails;
+    }
+    public void setStorageDetails(StorageDetails storageDetails) {
+        this.storageDetails = storageDetails;
+    }
+    public StorageServer getStorageServer() {
+        return storageServer;
+    }
+    public void setStorageServer(StorageServer storageServer) {
+        this.storageServer = storageServer;
+    }
+    public FileProperties getFileProperties() {
+        return fileProperties;
+    }
+    public void setFileProperties(FileProperties fileProperties) {
+        this.fileProperties = fileProperties;
+    }
+
+    /*
+     * storage_plugin_clone, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_list, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_getInfo, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_snapRemove, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getCapabilities, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_createSnap, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_getFileSystemSnapLimits, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_remove, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_getCurrentClones, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_online, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_isRestorable, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_iSCSI_logoutTarget, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: target - default: None
+     * argument: portal - default: None
+     */
+
+    /*
+     * storage_plugin_discover, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_start, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_removeAccessGroups, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_refresh, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_getAccessGroups, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_iSCSI_deletePortal, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: portal - default: None
+     */
+
+    /*
+     * storage_plugin_createFileSystem, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_cloneFromSnap, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_addToAccessGroup, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+
+    /*
+     * storage_plugin_offline, <class 'agent.api.storageplugin.StoragePlugin'>
+     * argument: impl_name - default: None
+     */
+
+    /*
+     * storage_plugin_listMountPoints, <class
+     * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+     * None
+     */
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Xen.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Xen.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Xen.java
new file mode 100644
index 0000000..e582041
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Xen.java
@@ -0,0 +1,996 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+public class Xen extends OvmObject {
+    private static final Logger LOGGER = Logger.getLogger(Xen.class);
+    private static final String VNCLISTEN = "vnclisten";
+    private static final String MEMORY = "memory";
+    private static final String MAXVCPUS = "maxvcpus";
+    private static final String VCPUS = "vcpus";
+    private static final String DOMTYPE = "OVM_domain_type";
+    private static final String EXTRA = "extra";
+    private Map<String, Vm> vmList = null;
+    private Vm defVm = new Vm();
+
+    public Xen(Connection c) {
+        setClient(c);
+    }
+
+    /*
+     * a vm class.... Setting up a VM is different than retrieving one from OVM.
+     * It's either a list retrieval or
+     * /usr/lib64/python2.4/site-packages/agent/lib/xenvm.py
+     */
+    public class Vm {
+        /* 'vfb': [ 'type=vnc,vncunused=1,vnclisten=127.0.0.1,keymap=en-us'] */
+        private List<String> vmVncElement = new ArrayList<String>();
+        private Map<String, String> vmVnc = new HashMap<String, String>() {
+            {
+                put("type", "vnc");
+                put("vncunused", "1");
+                put(VNCLISTEN, "127.0.0.1");
+                put("keymap", "en-us");
+            }
+        };
+
+        /*
+         * 'disk': [
+         * 'file:/OVS/Repositories/0004fb0000030000aeaca859e4a8f8c0/VirtualDisks/0004fb0000120000c444117fd87ea251.img,xvda,w']
+         */
+        private List<String> vmDisks = new ArrayList<String>();
+        private Map<String, String> vmDisk = new HashMap<String, String>() {
+            {
+                put("id", "");
+                put("uuid", "");
+                put("dev", "");
+                put("bootable", "1");
+                put("mode", "w");
+                put("VDI", "");
+                put("backend", "0");
+                put("protocol", "x86_32-abi");
+                put("uname", "");
+            }
+        };
+
+        /* 'vif': [ 'mac=00:21:f6:00:00:00,bridge=c0a80100'] */
+        private ArrayList<String> vmVifs = new ArrayList<String>();
+        private Integer maxVifs = 7;
+        private String[] xvmVifs = new String[maxVifs -1];
+        private String vmSimpleName = "";
+        private String vmName = "";
+        private String vmUuid = "";
+        /*
+         * the pool the vm.cfg will live on, this is the same as the primary
+         * storage pool (should be unified with disk pool ?)
+         */
+        private String vmPrimaryPoolUuid = "";
+        private String vmOnReboot = "restart";
+        /* weight is relative for all VMs compared to each other */
+        private int vmCpuWeight = 27500;
+        /* minimum memory allowed */
+        private int vmMemory = 256;
+        private int vmCpuCap = 0;
+        /* dynam scaling for cpus */
+        private int vmMaxVcpus = 0;
+        /* default to 1, can't be higher than maxvCpus */
+        private int vmVcpus = 1;
+        /* high available */
+        private Boolean vmHa = false;
+        private String vmDescription = "";
+        private String vmOnPoweroff = "destroy";
+        private String vmOnCrash = "restart";
+        private String vmBootloader = "/usr/bin/pygrub";
+        private String vmBootArgs = "";
+        private String vmExtra = "";
+        /* default to linux */
+        private String vmOs = "Other Linux";
+        private String vmCpuCompatGroup = "";
+        /* pv is default */
+        private String vmDomainType = "xen_pvm";
+        /* start counting disks at A -> 0 */
+        private int diskZero = 97;
+        private int diskCount = diskZero;
+
+        private Map<String, Object> vmParams = new HashMap<String, Object>() {
+            {
+                put("vif", vmVifs);
+                put("OVM_simple_name", vmSimpleName);
+                put("disk", vmDisks);
+                put("bootargs", vmBootArgs);
+                put("uuid", vmUuid);
+                put("on_reboot", vmOnReboot);
+                put("cpu_weight", vmCpuWeight);
+                put(MEMORY, vmMemory);
+                put("cpu_cap", vmCpuCap);
+                put(MAXVCPUS, vmMaxVcpus);
+                put("OVM_high_availability", vmHa);
+                put("OVM_description", vmDescription);
+                put("on_poweroff", vmOnPoweroff);
+                put("on_crash", vmOnCrash);
+                put("bootloader", vmBootloader);
+                put("name", vmName);
+                put("guest_os_type", vmOs);
+                put("vfb", vmVncElement);
+                put(VCPUS, vmVcpus);
+                put("OVM_cpu_compat_group", vmCpuCompatGroup);
+                put(DOMTYPE, vmDomainType);
+                put(EXTRA, vmExtra);
+            }
+        };
+
+        public boolean isControlDomain() {
+            if ("Domain-0".equals(this.getVmName())) {
+                return true;
+            }
+            return false;
+        }
+
+        public boolean setPrimaryPoolUuid(String poolId) {
+            this.vmPrimaryPoolUuid = poolId;
+            return true;
+        }
+
+        public String getPrimaryPoolUuid() throws Ovm3ResourceException {
+            if ("".equals(this.vmPrimaryPoolUuid)) {
+                return this.getVmRootDiskPoolId();
+            } else {
+                return this.vmPrimaryPoolUuid;
+            }
+        }
+
+        public Map<String, Object> getVmParams() {
+            return this.vmParams;
+        }
+
+        public void setVmParams(Map<String, Object> params) {
+            this.vmParams = params;
+        }
+
+        public boolean setVmExtra(final String args) {
+            vmParams.put(EXTRA, args);
+            return true;
+        }
+
+        public String getVmExtra() {
+            return (String) vmParams.get(EXTRA);
+        }
+
+        public String getVmBootArgs() {
+            return (String) vmParams.get("bootloader_args");
+        }
+
+        public void setVmMaxCpus(Integer val) {
+            vmParams.put(MAXVCPUS, val);
+        }
+
+        public Integer getVmMaxCpus() {
+            return (Integer) vmParams.get(MAXVCPUS);
+        }
+
+        public void setVmCpus(Integer val) {
+            if (getVmMaxCpus() == 0 || getVmMaxCpus() >= val) {
+                vmParams.put(VCPUS, val);
+            } else if (getVmMaxCpus() < val) {
+                setVmCpus(getVmMaxCpus());
+            }
+        }
+
+        public Integer getVmCpus() {
+            return (Integer) vmParams.get(VCPUS);
+        }
+
+        public Boolean setVmMemory(long memory) {
+            vmParams.put(MEMORY, Long.toString(memory));
+            return true;
+        }
+
+        public long getVmMemory() {
+            return Integer.parseInt((String) vmParams.get(MEMORY));
+        }
+
+        public Boolean setVmDomainType(String domtype) {
+            vmParams.put(DOMTYPE, domtype);
+            return true;
+        }
+
+        /* iiiis this a good idea ? */
+        public String getVmDomainType() {
+            String domType = (String) vmParams.get(DOMTYPE);
+            if (domType.equals(vmDomainType)) {
+                String builder = (String) vmParams.get("builder");
+                if (builder == null || builder.contains("linux")) {
+                    domType = "xen_pvm";
+                } else {
+                    domType = "hvm";
+                }
+            }
+            return domType;
+        }
+
+        public String getVmState() {
+            return (String) vmParams.get("state");
+        }
+
+        public Boolean setVmName(String name) {
+            vmParams.put("name", name);
+            vmParams.put("OVM_simple_name", name);
+            return true;
+        }
+
+        public String getVmName() {
+            return (String) vmParams.get("name");
+        }
+
+        public Boolean setVmUuid(String uuid) {
+            vmParams.put("uuid", uuid);
+            return true;
+        }
+
+        public String getVmUuid() {
+            return (String) vmParams.get("uuid");
+        }
+
+        public void setVmVncs(List<String> vncs) {
+            this.vmVncElement.addAll(vncs);
+        }
+
+        public List<String> getVmVncs() {
+            return this.vmVncElement;
+        }
+
+        public void setVmDisks(List<String> disks) {
+            this.vmDisks.addAll(disks);
+        }
+
+        public List<String> getVmDisks() {
+            return this.vmDisks;
+        }
+
+        public void setVmVifs(List<String> vifs) {
+            this.vmVifs.addAll(vifs);
+        }
+
+        public List<String> getVmVifs() {
+            return this.vmVifs;
+        }
+
+        public Integer getVifIdByMac(String mac) {
+            Integer c = 0;
+            for (final String entry : vmVifs) {
+                final String[] parts = entry.split(",");
+                final String[] macpart = parts[0].split("=");
+                assert macpart.length == 2 : "Invalid entry: " + entry;
+                if ("mac".equals(macpart[0]) && macpart[1].equals(mac)) {
+                    return c;
+                }
+                c += 1;
+            }
+            LOGGER.debug("No vif matched mac: " + mac + " in " + vmVifs);
+            return -1;
+        }
+        public Integer getVifIdByIp(String ip) {
+            Integer c = 0;
+            for (final String entry : vmVifs) {
+                final String[] parts = entry.split(",");
+                final String[] ippart = parts[1].split("=");
+                assert ippart.length == 2 : "Invalid entry: " + entry;
+                if ("mac".equals(ippart[0]) && ippart[1].equals(ip)) {
+                    return c;
+                }
+                c += 1;
+            }
+            LOGGER.debug("No vif matched ip: " + ip + " in " + vmVifs);
+            return -1;
+        }
+
+        public Boolean addVif(Integer id, String bridge, String mac) {
+            if (getVifIdByMac(mac) > 0) {
+                LOGGER.debug("Already nic with mac present: " + mac);
+                return false;
+            }
+            String vif = "mac=" + mac + ",bridge=" + bridge;
+            xvmVifs[id] = vif;
+            return true;
+        }
+
+        public boolean setupVifs() {
+            for (String vif : xvmVifs) {
+                if (vif != null && !vmVifs.contains(vif)) {
+                    vmVifs.add(vif);
+                }
+            }
+            vmParams.put("vif", vmVifs);
+            return true;
+        }
+
+        public Boolean removeVif(String bridge, String mac) {
+            List<String> newVifs = new ArrayList<String>();
+            try {
+                String remove = "mac=" + mac + ",bridge=" + bridge;
+                for (String vif : getVmVifs()) {
+                    if (vif.equals(remove)) {
+                        LOGGER.debug("leaving out vif: " + remove);
+                    } else {
+                        LOGGER.debug("keeping vif: " + vif);
+                        newVifs.add(vif);
+                    }
+                }
+                vmParams.put("vif", newVifs);
+            } catch (Exception e) {
+                LOGGER.debug(e);
+            }
+            return true;
+        }
+
+        /* 'file:/OVS/Repositories/d5f5a4480515467ca1638554f085b278/ISOs/e14c811ebbf84f0b8221e5b7404a554e.iso,hdc:cdrom,r' */
+        /* device is coupled with vmtype enumerate and cdboot ? */
+        public Boolean addRootDisk(String image) {
+            Boolean ret = false;
+            if (diskCount > diskZero) {
+                Integer oVmDisk = diskCount;
+                diskCount = diskZero;
+                ret = addDisk(image, "w");
+                diskCount = oVmDisk;
+            } else {
+                ret = addDisk(image, "w");
+            }
+            return ret;
+        }
+
+        public Boolean addDataDisk(String image) {
+            /*
+             * w! means we're able to share the disk nice for clustered FS?
+             */
+            return addDisk(image, "w!");
+        }
+
+        public Boolean addIso(String image) {
+            return addDisk(image, "r!");
+        }
+
+        private Boolean addDisk(String image, String mode) {
+            String devName = null;
+            /* better accounting then diskCount += 1 */
+            diskCount = diskZero + vmDisks.size();
+            if (getVmDomainType().contains("hvm")) {
+                diskCount += 2;
+                devName = Character.toString((char) diskCount);
+            } else {
+                devName = "xvd" + Character.toString((char) diskCount);
+            }
+
+            /* check for iso, force mode and additions */
+            if (image.endsWith(".iso")) {
+                devName = devName + ":cdrom";
+                mode = "r";
+            }
+            return addDiskToDisks(image, devName, mode);
+        }
+
+        /* should be on device id too, or else we get random attaches... */
+        private Boolean addDiskToDisks(String image, String devName, String mode) {
+            for (String disk : vmDisks) {
+                if (disk.contains(image)) {
+                    LOGGER.debug(this.vmName + " already has disk " +image+ ":" + devName + ":" + mode);
+                    return true;
+                }
+            }
+            vmDisks.add("file:" + image + "," + devName + "," + mode);
+            vmParams.put("disk", vmDisks);
+            return true;
+        }
+
+        public Boolean removeDisk(String image) {
+            for (String disk : vmDisks) {
+                if (disk.contains(image)) {
+                    vmDisks.remove(disk);
+                    vmParams.put("disk", vmDisks);
+                    return true;
+                }
+            }
+            LOGGER.debug("No disk found corresponding to image: " + image);
+            return false;
+        }
+
+        /* The conflict between getVm and getVmConfig becomes clear */
+        public String getVmRootDiskPoolId() throws Ovm3ResourceException {
+            String poolId = getVmDiskPoolId(0);
+            this.setPrimaryPoolUuid(poolId);
+            return poolId;
+        }
+
+        private String getVmDiskPoolId(int disk) throws Ovm3ResourceException {
+            int fi = 3;
+            String diskPath = "";
+            try {
+                diskPath = getVmDiskDetailFromMap(disk, "uname");
+            } catch (NullPointerException e) {
+                throw new Ovm3ResourceException("No valid disk found for id: "
+                        + disk);
+            }
+            String[] st = diskPath.split(File.separator);
+            return st[fi];
+        }
+
+        private String getVmDiskDetailFromMap(int disk, String dest) {
+            Map<String, Object[]> o = (Map<String, Object[]>) vmParams
+                    .get("device");
+            if (o == null) {
+                LOGGER.info("No devices found" + this.vmName);
+                return null;
+            }
+            vmDisk = (Map<String, String>) o.get("vbd")[disk];
+            return vmDisk.get(dest);
+        }
+
+        private boolean setVnc() {
+            List<String> vfb = new ArrayList<String>();
+            for (final String key : vmVnc.keySet()) {
+                vfb.add(key + "=" + vmVnc.get(key));
+            }
+            vmVncElement.add(StringUtils.join(vfb, ","));
+            return true;
+        }
+
+        public Boolean setVnc(String address, String password) {
+            setVncAddress(address);
+            setVncPassword(password);
+            return setVnc();
+        }
+
+        public void setVncUsed(String used) {
+            vmVnc.put("vncused", used);
+        }
+
+        public String getVncUsed() {
+            return vmVnc.get("vncused");
+        }
+
+        public void setVncPassword(String pass) {
+            vmVnc.put("vncpasswd", pass);
+        }
+
+        public String getVncPassword() {
+            return vmVnc.get("vncpasswd");
+        }
+
+        public void setVncAddress(String address) {
+            vmVnc.put(VNCLISTEN, address);
+        }
+
+        public String getVncAddress() throws Ovm3ResourceException {
+            Integer port = getVncPort();
+            if (port == null) {
+                return null;
+            }
+            return vmVnc.get(VNCLISTEN);
+        }
+
+        public Integer getVncPort() throws Ovm3ResourceException {
+            if (getFromVncMap("port") != null) {
+                return Integer.parseInt(getFromVncMap("port"));
+            }
+            String vnc = getVncLocation();
+            if (vnc != null && vnc.contains(":")) {
+                final String[] res = vnc.split(":");
+                vmVnc.put(VNCLISTEN, res[0]);
+                vmVnc.put("port", res[1]);
+                return Integer.parseInt(res[1]);
+            }
+            throw new Ovm3ResourceException("No VNC port found");
+        }
+
+        public String getVncLocation() {
+            return getFromVncMap("location");
+        }
+
+        private String getFromVncMap(String el) {
+            Map<String, Object[]> o = (Map<String, Object[]>) vmParams
+                    .get("device");
+            if (o == null) {
+                return null;
+            }
+            vmVnc = (Map<String, String>) o.get("vfb")[0];
+            if (vmVnc.containsKey(el)) {
+                return vmVnc.get(el);
+            } else {
+                return null;
+            }
+        }
+
+        private Object get(String key) {
+            return vmParams.get(key);
+        }
+    }
+
+    /*
+     * delete_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None
+     */
+
+    /*
+     * unconfigure_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * template_id - default: None argument: params - default: None
+     */
+
+    /*
+     * sysrq_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: letter - default: None
+     */
+
+    /*
+     * list_vms, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None
+     */
+    public Map<String, Vm> listVms() throws Ovm3ResourceException {
+        Object[] result = (Object[]) callWrapper("list_vms");
+        if (result == null) {
+            LOGGER.debug("no vm results on list_vms");
+            return null;
+        }
+
+        try {
+            vmList = new HashMap<String, Vm>();
+            for (Object x : result) {
+                /* put the vmparams in, as x is a hashmap */
+                Vm vm = new Vm();
+                vm.setVmParams((Map<String, Object>) x);
+                vmList.put((String) vm.get("name"), vm);
+            }
+        } catch (Exception e) {
+            String msg = "Unable to list VMs: " + e.getMessage();
+            throw new Ovm3ResourceException(msg, e);
+        }
+        return vmList;
+    }
+
+    /*
+     * this should become getVmConfig later... getVmConfig returns the
+     * configuration file, while getVm returns the "live" configuration. It
+     * makes perfect sense if you think about it..... ....long enough
+     */
+    public Vm getRunningVmConfig(String name) throws Ovm3ResourceException {
+        return getRunningVmConfigs().get(name);
+    }
+
+    public Map<String, Vm> getRunningVmConfigs() throws Ovm3ResourceException {
+        return listVms();
+    }
+
+    /*
+     * delete_vm_core, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: core_date - default: None
+     */
+
+    /*
+     * delete_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+    public Boolean deleteVm(String repoId, String vmId)
+            throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("delete_vm", repoId, vmId);
+    }
+
+    /*
+     * save_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: checkpoint - default: None
+     *//* add checkpoint */
+
+    /*
+     * configure_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * template_id - default: None argument: params - default: None
+     */
+
+    /*
+     * create_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: template_id -
+     * default: None argument: params - default: None
+     */
+
+    /*
+     * list_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+
+    public Boolean listVm(String repoId, String vmId)
+            throws Ovm3ResourceException {
+        defVm.setVmParams((Map<String, Object>) callWrapper("list_vm", repoId,
+                vmId));
+        if (defVm.getVmParams() == null) {
+            LOGGER.debug("no vm results on list_vm");
+            return false;
+        }
+        return true;
+    }
+
+    /*
+     * dump_vm_core, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: live - default: None argument: crash - default:
+     * None argument: reset - default: None
+     */
+
+    /*
+     * assembly_del_file, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None argument: filename - default: None
+     */
+
+    /*
+     * get_template_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * template_id - default: None
+     */
+
+    /*
+     * set_assembly_config_xml, <class 'agent.api.hypervisor.xenxm.Xen'>
+     * argument: self - default: None argument: repo_id - default: None
+     * argument: assembly_id - default: None argument: cfg - default: None
+     */
+
+    /*
+     * assembly_add_file, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None argument: url - default: None argument:
+     * filename - default: None argument: option - default: None
+     */
+
+    /*
+     * send_to_guest, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: params - default: None
+     */
+
+    /*
+     * set_assembly_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None argument: cfg - default: None
+     */
+
+    /*
+     * configure_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: params - default: None
+     */
+    private Boolean configureVm(String repoId, String vmId,
+            Map<String, Object> params) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("configure_vm", repoId, vmId, params);
+    }
+
+    public Boolean configureVm(String repoId, String vmId)
+            throws Ovm3ResourceException {
+        return configureVm(repoId, vmId, this.defVm.getVmParams());
+    }
+
+    /*
+     * cleanup_migration_target, <class 'agent.api.hypervisor.xenxm.Xen'>
+     * argument: self - default: None argument: repo_id - default: None
+     * argument: vm_id - default: None
+     */
+
+    /*
+     * pause_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+    public Boolean pauseVm(String repoId, String vmId)
+            throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("pause_vm", repoId, vmId);
+    }
+
+    /*
+     * setup_migration_target, <class 'agent.api.hypervisor.xenxm.Xen'>
+     * argument: self - default: None argument: repo_id - default: None
+     * argument: vm_id - default: None
+     */
+
+    /*
+     * deploy_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None argument: to_deploy - default: None argument:
+     * target_repo_id - default: None argument: option - default: None
+     */
+
+    /*
+     * stop_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: force - default: None
+     */
+    public Boolean stopVm(String repoId, String vmId)
+            throws Ovm3ResourceException {
+        Object x = callWrapper("stop_vm", repoId, vmId, false);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean stopVm(String repoId, String vmId, Boolean force)
+            throws Ovm3ResourceException {
+        Object x = callWrapper("stop_vm", repoId, vmId, force);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * set_template_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * template_id - default: None argument: params - default: None
+     */
+
+    /*
+     * assembly_rename_file, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None argument: filename - default: None argument:
+     * new_filename - default: None
+     */
+
+    /*
+     * migrate_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: dest - default: None argument: live - default:
+     * None argument: ssl - default: None
+     */
+    public Boolean migrateVm(String repoId, String vmId, String dest)
+            throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("migrate_vm", repoId, vmId, dest);
+    }
+
+    public Boolean migrateVm(String repoId, String vmId, String dest,
+            boolean live, boolean ssl) throws Ovm3ResourceException {
+        Object x = callWrapper("migrate_vm", repoId, vmId, dest, live, ssl);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * configure_vm_ha, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: enable_ha - default: None
+     */
+    public Boolean configureVmHa(String repoId, String vmId, Boolean ha)
+            throws Ovm3ResourceException {
+        Object x = callWrapper("configure_vm_ha", repoId, vmId, ha);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * create_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: params - default: None
+     */
+    public Boolean createVm(String repoId, String vmId)
+            throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("create_vm", repoId, vmId,
+                defVm.getVmParams());
+    }
+
+    public Boolean createVm(String repoId, String vmId,
+            Map<String, Object> vmParams) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("create_vm", repoId, vmId, vmParams);
+    }
+
+    /*
+     * pack_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None
+     */
+
+    /*
+     * restore_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: paused - default: None
+     */
+
+    /*
+     * start_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+    public Boolean startVm(String repoId, String vmId)
+            throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("start_vm", repoId, vmId);
+    }
+
+    /*
+     * unpause_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+
+    /*
+     * trigger_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: name - default: None argument: vcpu - default:
+     * None
+     */
+
+    /*
+     * set_vm_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: params - default: None
+     */
+
+    /*
+     * delete_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: template_id -
+     * default: None
+     */
+
+    /*
+     * reboot_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: wait - default: None
+     */
+    public Boolean rebootVm(String repoId, String vmId, int wait)
+            throws Ovm3ResourceException {
+        Object x = callWrapper("reboot_vm", repoId, vmId, wait);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean rebootVm(String repoId, String vmId)
+            throws Ovm3ResourceException {
+        Object x = callWrapper("reboot_vm", repoId, vmId, 3);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * unpack_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None
+     */
+
+    /*
+     * get_vm_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+    public Vm getVmConfig(String vmName) throws Ovm3ResourceException {
+        defVm = this.getRunningVmConfig(vmName);
+        if (defVm == null) {
+            LOGGER.debug("Unable to retrieve running config for " + vmName);
+            return defVm;
+        }
+        return getVmConfig(defVm.getVmRootDiskPoolId(), defVm.getVmUuid());
+    }
+
+    public Vm getVmConfig() {
+        return defVm;
+    }
+
+    /*
+     * returns the configuration file contents, so we parse it for configuration
+     * alterations we might want to do (/$repo/VirtualMachines/$uuid/vm.cfg)
+     */
+    public Vm getVmConfig(String repoId, String vmId)
+            throws Ovm3ResourceException {
+        try {
+            Xen.Vm nVm = new Xen.Vm();
+            Map<String, Object[]> x = (Map<String, Object[]>) callWrapper(
+                    "get_vm_config", repoId, vmId);
+            if (x == null) {
+                LOGGER.debug("Unable to find vm with id:" + vmId + " on repoId:" + repoId);
+                return nVm;
+            }
+            nVm.setVmVifs(Arrays.asList(Arrays.copyOf(x.get("vif"),
+                    x.get("vif").length, String[].class)));
+            x.remove("vif");
+            nVm.setVmDisks(Arrays.asList(Arrays.copyOf(x.get("disk"),
+                    x.get("disk").length, String[].class)));
+            x.remove("disk");
+            nVm.setVmVncs(Arrays.asList(Arrays.copyOf(x.get("vfb"),
+                    x.get("vfb").length, String[].class)));
+            x.remove("vfb");
+            Map<String, Object> remains = new HashMap<String, Object>();
+            for (final Map.Entry<String, Object[]> not : x.entrySet()) {
+                remains.put(not.getKey(), not.getValue());
+            }
+            nVm.setVmParams(remains);
+            nVm.setPrimaryPoolUuid(repoId);
+            /* to make sure stuff doesn't blow up in our face... */
+            defVm = nVm;
+            return nVm;
+        } catch (Ovm3ResourceException e) {
+            throw e;
+        }
+    }
+
+    /*
+     * get_assembly_config_xml, <class 'agent.api.hypervisor.xenxm.Xen'>
+     * argument: self - default: None argument: repo_id - default: None
+     * argument: assembly_id - default: None
+     */
+
+    /*
+     * import_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None argument: url - default: None argument: option - default:
+     * None
+     */
+
+    /*
+     * create_assembly, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: assembly_id -
+     * default: None argument: templates - default: None
+     */
+
+    /*
+     * get_assembly_config, <class 'agent.api.hypervisor.xenxm.Xen'> argument:
+     * self - default: None argument: repo_id - default: None argument:
+     * assembly_id - default: None
+     */
+
+    /*
+     * unconfigure_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: params - default: None
+     */
+
+    /*
+     * import_template, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self
+     * - default: None argument: repo_id - default: None argument: template_id -
+     * default: None argument: url_list - default: None argument: option -
+     * default: None
+     */
+
+    /*
+     * import_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None argument: url_list - default: None argument: option -
+     * default: None
+     */
+
+    /*
+     * list_vm_core, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+     * default: None argument: repo_id - default: None argument: vm_id -
+     * default: None
+     */
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3Discoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3Discoverer.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3Discoverer.java
new file mode 100755
index 0000000..8282c1f
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3Discoverer.java
@@ -0,0 +1,406 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.Listener;
+import com.cloud.agent.api.AgentControlAnswer;
+import com.cloud.agent.api.AgentControlCommand;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterDetailsDao;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.exception.DiscoveryException;
+import com.cloud.host.Host;
+import com.cloud.host.HostInfo;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Linux;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.resource.Discoverer;
+import com.cloud.resource.DiscovererBase;
+import com.cloud.resource.ResourceManager;
+import com.cloud.resource.ResourceStateAdapter;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.UnableDeleteHostException;
+import com.cloud.utils.db.QueryBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.ssh.SSHCmdHelper;
+
+@Local(value = Discoverer.class)
+public class Ovm3Discoverer extends DiscovererBase implements Discoverer,
+        Listener, ResourceStateAdapter {
+    private static final Logger LOGGER = Logger.getLogger(Ovm3Discoverer.class);
+    protected String publicNetworkDevice;
+    protected String privateNetworkDevice;
+    protected String guestNetworkDevice;
+    protected String storageNetworkDevice;
+
+    @Inject
+    ClusterDao clusterDao;
+    @Inject
+    ClusterDetailsDao clusterDetailsDao;
+    @Inject
+    ResourceManager resourceMgr;
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    HostDao hostDao = null;
+
+    protected Ovm3Discoverer() {
+    }
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        boolean success = super.configure(name, params);
+        if (!success) {
+            return false;
+        }
+
+        /* these are in Config.java */
+        publicNetworkDevice = _params.get(Config.Ovm3PublicNetwork.key());
+        privateNetworkDevice = _params.get(Config.Ovm3PrivateNetwork.key());
+        guestNetworkDevice = _params.get(Config.Ovm3GuestNetwork.key());
+        storageNetworkDevice = _params.get(Config.Ovm3StorageNetwork.key());
+        resourceMgr.registerResourceStateAdapter(this.getClass()
+                .getSimpleName(), this);
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        resourceMgr.unregisterResourceStateAdapter(this.getClass()
+                .getSimpleName());
+        return super.stop();
+    }
+
+    private boolean checkIfExisted(String guid) {
+        QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
+        sc.and(sc.entity().getGuid(), SearchCriteria.Op.EQ, guid);
+        sc.and(sc.entity().getHypervisorType(), SearchCriteria.Op.EQ,
+                HypervisorType.Ovm3);
+        List<HostVO> hosts = sc.list();
+        return !hosts.isEmpty();
+    }
+
+    private boolean CheckUrl(URI url) throws DiscoveryException {
+        if ("http".equals(url.getScheme()) || "https".equals(url.getScheme())) {
+            String msg = "Discovering " + url + ": " + _params;
+            LOGGER.debug(msg);
+        } else {
+            String msg = "urlString is not http(s) so we're not taking care of the discovery for this: "
+                    + url;
+            LOGGER.info(msg);
+            throw new DiscoveryException(msg);
+        }
+        return true;
+    }
+
+    @Override
+    public Map<? extends ServerResource, Map<String, String>> find(long dcId,
+            Long podId, Long clusterId, URI url, String username,
+            String password, List<String> hostTags) throws DiscoveryException {
+        Connection c = null;
+
+        CheckUrl(url);
+        if (clusterId == null) {
+            String msg = "must specify cluster Id when add host";
+            LOGGER.info(msg);
+            throw new DiscoveryException(msg);
+        }
+
+        if (podId == null) {
+            String msg = "must specify pod Id when add host";
+            LOGGER.info(msg);
+            throw new DiscoveryException(msg);
+        }
+
+        ClusterVO cluster = clusterDao.findById(clusterId);
+        if (cluster == null
+                || (cluster.getHypervisorType() != HypervisorType.Ovm3)) {
+            String msg = "invalid cluster id or cluster is not for Ovm3 hypervisors";
+            LOGGER.info(msg);
+            throw new DiscoveryException(msg);
+        } else {
+            LOGGER.debug("cluster: " + cluster);
+        }
+
+        String agentUsername = _params.get("agentusername");
+        if (agentUsername == null) {
+            String msg = "Agent user name must be specified";
+            LOGGER.info(msg);
+            throw new DiscoveryException(msg);
+        }
+
+        String agentPassword = _params.get("agentpassword");
+        if (agentPassword == null) {
+            String msg = "Agent password must be specified";
+            LOGGER.info(msg);
+            throw new DiscoveryException(msg);
+        }
+
+        String agentPort = _params.get("agentport");
+        if (agentPort == null) {
+            String msg = "Agent port must be specified";
+            LOGGER.info(msg);
+            throw new DiscoveryException(msg);
+        }
+
+        try {
+            String hostname = url.getHost();
+
+            InetAddress ia = InetAddress.getByName(hostname);
+            String hostIp = ia.getHostAddress();
+            String guid = UUID.nameUUIDFromBytes(hostIp.getBytes("UTF8"))
+                    .toString();
+
+            if (checkIfExisted(guid)) {
+                String msg = "The host " + hostIp + " has been added before";
+                LOGGER.info(msg);
+                throw new DiscoveryException(msg);
+            }
+
+            LOGGER.debug("Ovm3 discover is going to disover host having guid "
+                    + guid);
+
+            ClusterVO clu = clusterDao.findById(clusterId);
+            if (clu.getGuid() == null) {
+                clu.setGuid(UUID.randomUUID().toString());
+            }
+            clusterDao.update(clusterId, clu);
+            Map<String, String> clusterDetails = clusterDetailsDao
+                    .findDetails(clusterId);
+            String ovm3vip = (clusterDetails.get("ovm3vip") == null) ? ""
+                    : clusterDetails.get("ovm3vip");
+            String ovm3pool = (clusterDetails.get("ovm3pool") == null) ? "false"
+                    : clusterDetails.get("ovm3pool");
+            String ovm3cluster = (clusterDetails.get("ovm3cluster") == null) ? "false"
+                    : clusterDetails.get("ovm3cluster");
+
+            /* should perhaps only make this connect to the agent port ? */
+            com.trilead.ssh2.Connection sshConnection = new com.trilead.ssh2.Connection(
+                    hostIp, 22);
+            sshConnection.connect(null, 60000, 60000);
+            sshConnection = SSHCmdHelper.acquireAuthorizedConnection(hostIp,
+                    username, password);
+            if (sshConnection == null) {
+                String msg = "Cannot Ssh to Ovm3 host(IP=" + hostIp
+                        + ", username=" + username
+                        + ", password=*******), discovery failed";
+                LOGGER.warn(msg);
+                throw new DiscoveryException(msg);
+            }
+
+            Map<String, String> details = new HashMap<String, String>();
+            Ovm3HypervisorResource ovmResource = new Ovm3HypervisorResource();
+            details.put("ip", hostIp);
+            details.put("host", hostname);
+            details.put("username", username);
+            details.put("password", password);
+            details.put("zone", Long.toString(dcId));
+            details.put("guid", guid);
+            details.put("pod", Long.toString(podId));
+            details.put("cluster", Long.toString(clusterId));
+            details.put("agentusername", agentUsername);
+            details.put("agentpassword", agentPassword);
+            details.put("agentport", agentPort.toString());
+            details.put("ovm3vip", ovm3vip);
+            details.put("ovm3pool", ovm3pool);
+            details.put("ovm3cluster", ovm3cluster);
+
+            if (publicNetworkDevice != null) {
+                details.put("public.network.device", publicNetworkDevice);
+            }
+            if (privateNetworkDevice != null) {
+                details.put("private.network.device", privateNetworkDevice);
+            }
+            if (guestNetworkDevice != null) {
+                details.put("guest.network.device", guestNetworkDevice);
+            }
+            if (storageNetworkDevice != null) {
+                details.put("storage.network.device", storageNetworkDevice);
+            }
+
+            Map<String, Object> params = new HashMap<String, Object>();
+            params.putAll(details);
+
+            ovmResource.configure(hostname, params);
+            ovmResource.start();
+
+            c = new Connection(hostIp, Integer.parseInt(agentPort),
+                    agentUsername, agentPassword);
+
+            /* After resource start, we are able to execute our agent api */
+            Linux host = new Linux(c);
+            details.put("agentVersion", host.getAgentVersion());
+            details.put(HostInfo.HOST_OS_KERNEL_VERSION,
+                    host.getHostKernelRelease());
+            details.put(HostInfo.HOST_OS, host.getHostOs());
+            details.put(HostInfo.HOST_OS_VERSION, host.getHostOsVersion());
+            details.put(HostInfo.HYPERVISOR_VERSION,
+                    host.getHypervisorVersion());
+
+            Map<Ovm3HypervisorResource, Map<String, String>> resources = new HashMap<Ovm3HypervisorResource, Map<String, String>>();
+            resources.put(ovmResource, details);
+            return resources;
+        } catch (UnknownHostException e) {
+            LOGGER.error(
+                    "Host name resolve failed exception, Unable to discover Ovm3 host: "
+                            + url.getHost(), e);
+            return null;
+        } catch (ConfigurationException e) {
+            LOGGER.error(
+                    "Configure resource failed, Unable to discover Ovm3 host: "
+                            + url.getHost(), e);
+            return null;
+        } catch (IOException | Ovm3ResourceException e) {
+            LOGGER.error("Unable to discover Ovm3 host: " + url.getHost(), e);
+            return null;
+        }
+    }
+
+    @Override
+    public void postDiscovery(List<HostVO> hosts, long msId)
+            throws CloudRuntimeException {
+        LOGGER.debug("postDiscovery: " + hosts);
+    }
+
+    @Override
+    public boolean matchHypervisor(String hypervisor) {
+        return HypervisorType.Ovm3.toString().equalsIgnoreCase(hypervisor);
+    }
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        return HypervisorType.Ovm3;
+    }
+
+    @Override
+    public HostVO createHostVOForConnectedAgent(HostVO host,
+            StartupCommand[] cmd) {
+        LOGGER.debug("createHostVOForConnectedAgent: " + host);
+        return null;
+    }
+
+    @Override
+    public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+        LOGGER.debug("processAnswers: " + agentId);
+        return false;
+    }
+
+    @Override
+    public boolean processCommands(long agentId, long seq, Command[] commands) {
+        LOGGER.debug("processCommands: " + agentId);
+        return false;
+    }
+
+    @Override
+    public AgentControlAnswer processControlCommand(long agentId,
+            AgentControlCommand cmd) {
+        LOGGER.debug("processControlCommand: " + agentId);
+        return null;
+    }
+
+    /* for reconnecting */
+    @Override
+    public void processConnect(Host host, StartupCommand cmd,
+            boolean forRebalance) {
+        LOGGER.debug("processConnect");
+    }
+
+    @Override
+    public boolean processDisconnect(long agentId, Status state) {
+        LOGGER.debug("processDisconnect");
+        return false;
+    }
+
+    @Override
+    public boolean isRecurring() {
+        return false;
+    }
+
+    @Override
+    public int getTimeout() {
+        LOGGER.debug("getTimeout");
+        return 0;
+    }
+
+    @Override
+    public boolean processTimeout(long agentId, long seq) {
+        LOGGER.debug("processTimeout: " + agentId);
+        return false;
+    }
+
+    @Override
+    public HostVO createHostVOForDirectConnectAgent(HostVO host,
+            StartupCommand[] startup, ServerResource resource,
+            Map<String, String> details, List<String> hostTags) {
+        LOGGER.debug("createHostVOForDirectConnectAgent: " + host);
+        StartupCommand firstCmd = startup[0];
+        if (!(firstCmd instanceof StartupRoutingCommand)) {
+            return null;
+        }
+
+        StartupRoutingCommand ssCmd = (StartupRoutingCommand) firstCmd;
+        if (ssCmd.getHypervisorType() != HypervisorType.Ovm3) {
+            return null;
+        }
+
+        return resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.Ovm3,
+                details, hostTags);
+    }
+
+    @Override
+    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced,
+            boolean isForceDeleteStorage) throws UnableDeleteHostException {
+        LOGGER.debug("deleteHost: " + host);
+        if (host.getType() != com.cloud.host.Host.Type.Routing
+                || host.getHypervisorType() != HypervisorType.Ovm3) {
+            return null;
+        }
+
+        resourceMgr.deleteRoutingHost(host, isForced, isForceDeleteStorage);
+        return new DeleteHostAnswer(true);
+    }
+
+}


[03/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResourceTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResourceTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResourceTest.java
new file mode 100644
index 0000000..e9c9029
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResourceTest.java
@@ -0,0 +1,368 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.host.Host;
+import com.cloud.hypervisor.ovm3.objects.CloudStackPluginTest;
+import com.cloud.hypervisor.ovm3.objects.ConnectionTest;
+import com.cloud.hypervisor.ovm3.objects.NetworkTest;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.OvmObject;
+import com.cloud.hypervisor.ovm3.objects.Xen;
+import com.cloud.hypervisor.ovm3.objects.XenTest;
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3ConfigurationTest;
+import com.cloud.hypervisor.ovm3.support.Ovm3SupportTest;
+import com.cloud.network.Networks;
+import com.cloud.storage.Volume;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.Type;
+
+public class Ovm3HypervisorResourceTest {
+    ConnectionTest con;
+    OvmObject ovmObject = new OvmObject();
+    XmlTestResultTest results = new XmlTestResultTest();
+    Ovm3ConfigurationTest configTest = new Ovm3ConfigurationTest();
+    Ovm3HypervisorResource hypervisor = new Ovm3HypervisorResource();
+    Ovm3SupportTest support = new Ovm3SupportTest();
+    NetworkTest net = new NetworkTest();
+    // LinuxTest linux = new LinuxTest();
+    CloudStackPluginTest csp = new CloudStackPluginTest();
+    XenTest xen = new XenTest();
+    String currentStatus = "put";
+    String vmName = "i-2-3-VM";
+
+    @Test
+    public void configureTest() throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con = support.prepConnectionResults();
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+    }
+
+    /* fails */
+    /*
+     @Test(expected = CloudRuntimeException.class)
+     public void configureFailBaseConnectionTest() throws
+         ConfigurationException {
+         hypervisor = support.prepare(configTest.getParams());
+         results.basicBooleanTest(hypervisor.configure(con.getHostName(),
+                 configTest.getParams()));
+     }
+    */
+
+    @Test
+    public void configureControlInterfaceTest() throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        String netdef = net.getDiscoverNetwork();
+        netdef = netdef.replaceAll(config.getAgentControlNetworkName(),
+                "thisisnotit0");
+        con = support.prepConnectionResults();
+        con.removeMethodResponse("discover_network");
+        con.setResult(results.simpleResponseWrapWrapper(netdef));
+        con.addResult(results.simpleResponseWrapWrapper(net
+                .getDiscoverNetwork()));
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+    }
+
+    @Test
+    public void startCommandTest() {
+    }
+
+    @Test
+    public void getCurrentStatusAndConfigureTest()
+            throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con = support.prepConnectionResults();
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+        assertNotNull(hypervisor.getCurrentStatus(1L));
+        assertNotNull(hypervisor.getCurrentStatus(1L));
+    }
+
+    @Test
+    public void getCurrentStatusFailTest() throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con = support.prepConnectionResults();
+        con.setResult(results.simpleResponseWrapWrapper("fail"));
+        con.removeMethodResponse("echo");
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+        assertNull(hypervisor.getCurrentStatus(1L));
+    }
+
+    @Test
+    public void getCurrentStatusExceptionTest() throws ConfigurationException {
+        con = new ConnectionTest();
+        hypervisor.setConnection(con);
+        assertNull(hypervisor.getCurrentStatus(1L));
+    }
+
+    /* gives an IOException on ssh */
+    @Test
+    public void initializeTest() throws Exception {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con = support.prepConnectionResults();
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+        con.setIp(config.getAgentIp());
+        for (StartupCommand start : hypervisor.initialize()) {
+            assertNotNull(start);
+        }
+    }
+
+    private Ovm3HypervisorResource vmActionPreparation()
+            throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con = support.prepConnectionResults();
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+        return hypervisor;
+    }
+
+    private Boolean rebootVm(String name) throws ConfigurationException {
+        hypervisor = vmActionPreparation();
+        con.removeMethodResponse("list_vms");
+        con.addResult(xen.getMultipleVmsListXML());
+        con.addResult(xen.getMultipleVmsListXML());
+        RebootCommand cmd = new RebootCommand(name);
+        Answer ra = hypervisor.executeRequest(cmd);
+        return ra.getResult();
+    }
+
+    @Test
+    public void rebootCommandTest() throws ConfigurationException {
+        results.basicBooleanTest(rebootVm(vmName));
+    }
+
+    @Test
+    public void rebootCommandFailTest() throws ConfigurationException {
+        results.basicBooleanTest(rebootVm("bogus"), false);
+    }
+
+    @Test
+    public void stopVmTest() throws ConfigurationException {
+        hypervisor = vmActionPreparation();
+        con.removeMethodResponse("list_vms");
+        con.setResult(xen.getMultipleVmsListXML());
+        con.addResult(xen.getMultipleVmsListXML().replace(vmName,
+                vmName + "-hide"));
+        StopCommand cmd = new StopCommand(vmName, true, true);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    /* takes too long */
+    /*
+     * @Test
+     * public void stopVmTestFail() throws ConfigurationException {
+     * stopVm();
+     * con.addResult(xen.getVmListXML().replace(vmName, vmName));
+     * StopCommand cmd = new StopCommand(vmName, true, true);
+     * StopAnswer ra = hypervisor.execute(cmd);
+     * results.basicBooleanTest(ra.getResult(), false);
+     * }
+     */
+
+    @Test
+    public void stopVmTreatAsStoppedTest() throws ConfigurationException {
+        hypervisor = vmActionPreparation();
+        con.setMethodResponse("list_vms",
+                xen.getMultipleVmsListXML().replace(vmName, vmName + "-hide"));
+        StopCommand cmd = new StopCommand(vmName, true, true);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    @Test
+    public void stopVmExceptionTest() throws ConfigurationException {
+        hypervisor = vmActionPreparation();
+        con.removeMethodResponse("list_vms");
+        StopCommand cmd = new StopCommand(vmName, true, true);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+
+    /* not relevant atm */
+    public void addNicsToSpec(VirtualMachineTO vmspec, List<String> list) {
+        for (String vif : list) {
+            String parts[] = vif.split("[,=.]+");
+            addNicToSpec(vmspec, parts[1], parts[3], parts[4]);
+        }
+    }
+
+    public void addNicToSpec(VirtualMachineTO vmspec, String mac,
+            String bridge, String vlan) {
+        ArrayList<NicTO> nics;
+        if (vmspec.getNics() != null) {
+            nics = new ArrayList<NicTO>(Arrays.asList(vmspec.getNics()));
+        } else {
+            nics = new ArrayList<NicTO>();
+        }
+        NicTO nic = new NicTO();
+
+        nic.setType(Networks.TrafficType.Guest);
+        nic.setMac(mac);
+        nic.setDeviceId(nics.size());
+        nics.add(nic);
+        vmspec.setNics(nics.toArray(new NicTO[nics.size()]));
+    }
+
+    /* hardcoded, dirty */
+    public void addDisksToSpec(VirtualMachineTO vmspec, List<String> list) {
+        for (String disk : list) {
+            String parts[] = disk.split("[:,.]+");
+            String partdeux[] = parts[1].split("/");
+            String diskuuid = partdeux[partdeux.length - 1];
+            String dsuuid = partdeux[3];
+            String path = parts[1].replace("/" + diskuuid, "");
+            addDiskToSpec(vmspec, diskuuid, dsuuid, path);
+        }
+    }
+
+    public void addDiskToSpec(VirtualMachineTO vmspec, String uuid,
+            String dsuuid, String path) {
+        ArrayList<DiskTO> disks;
+        if (vmspec.getDisks() != null) {
+            disks = new ArrayList<DiskTO>(Arrays.asList(vmspec.getDisks()));
+        } else {
+            disks = new ArrayList<DiskTO>();
+        }
+        DiskTO disk = new DiskTO();
+        VolumeObjectTO volume = new VolumeObjectTO();
+        NfsTO nfsDataStore = new NfsTO();
+        nfsDataStore.setUuid(dsuuid);
+        volume.setDataStore(nfsDataStore);
+        volume.setPath(path);
+        volume.setUuid(uuid);
+        disk.setData(volume);
+        disk.setType(Volume.Type.ROOT);
+        disks.add(disk);
+        vmspec.setDisks(disks.toArray(new DiskTO[disks.size()]));
+    }
+
+    public Host getHost(String ip) {
+        Host host = Mockito.mock(Host.class);
+        Mockito.when(host.getPrivateIpAddress()).thenReturn(ip);
+        return host;
+    }
+
+    public VirtualMachineTO createVm(String vmName) throws Ovm3ResourceException {
+        con = support.prepConnectionResults();
+        Xen vdata = new Xen(con);
+        Xen.Vm vm = vdata.getVmConfig(vmName);
+        vdata.listVm(xen.getRepoId(), xen.getVmId());
+
+        // Ovm3VmGuestTypes types = new Ovm3VmGuestTypes();
+        Long id = 1L;
+        String instanceName = vm.getVmName();
+        VirtualMachine.Type type = Type.User;
+        int cpus = 1; // vm.getVmCpus();
+        Integer speed = 0;
+        long minRam = vm.getVmMemory();
+        long maxRam = vm.getVmMemory();
+        BootloaderType bootloader = BootloaderType.PyGrub;
+        String os = "Oracle Enterprise Linux 6.0 (64-bit)";
+        boolean enableHA = true;
+        boolean limitCpuUse = false;
+        String vncPassword = "gobbeldygoo";
+        // public StartCommand(VirtualMachineTO vm, Host host, boolean
+        // executeInSequence) {
+        // ./api/src/com/cloud/agent/api/to/VirtualMachineTO.java
+        VirtualMachineTO vmspec = new VirtualMachineTO(id, instanceName, type,
+                cpus, speed, minRam, maxRam, bootloader, os, enableHA,
+                limitCpuUse, vncPassword);
+        vmspec.setBootArgs("");
+        addDisksToSpec(vmspec, vm.getVmDisks());
+        addNicsToSpec(vmspec, vm.getVmVifs());
+        return vmspec;
+    }
+
+    @Test
+    public void createVmTest() throws ConfigurationException,
+            Ovm3ResourceException {
+        VirtualMachineTO vmspec = createVm(vmName);
+        hypervisor = vmActionPreparation();
+        StartCommand cmd = new StartCommand(vmspec,
+                getHost(hypervisor.getName()), true);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    @Test
+    public void createOtherVmTest() throws ConfigurationException,
+            Ovm3ResourceException {
+        VirtualMachineTO vmspec = createVm(vmName);
+        vmspec.setOs("bogus");
+        hypervisor = vmActionPreparation();
+        StartCommand cmd = new StartCommand(vmspec,
+                getHost(hypervisor.getName()), true);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    @Test
+    public void startResourceTest() {
+        results.basicBooleanTest(hypervisor.start());
+    }
+
+    @Test
+    public void stopResourceTest() {
+        results.basicBooleanTest(hypervisor.stop());
+    }
+    @Test
+    public void readyCommandTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        ReadyCommand ready = new ReadyCommand();
+        Answer ra = hypervisor.executeRequest(ready);
+        results.basicBooleanTest(ra.getResult());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessorTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessorTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessorTest.java
new file mode 100644
index 0000000..80586cc
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessorTest.java
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.junit.Test;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.hypervisor.ovm3.objects.ConnectionTest;
+import com.cloud.hypervisor.ovm3.objects.LinuxTest;
+import com.cloud.hypervisor.ovm3.objects.OvmObject;
+import com.cloud.hypervisor.ovm3.objects.StoragePluginTest;
+import com.cloud.hypervisor.ovm3.objects.XenTest;
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3ConfigurationTest;
+import com.cloud.hypervisor.ovm3.support.Ovm3SupportTest;
+import com.cloud.storage.Volume;
+import com.cloud.vm.DiskProfile;
+
+public class Ovm3StorageProcessorTest {
+    ConnectionTest con = new ConnectionTest();
+    OvmObject ovmObject = new OvmObject();
+    XmlTestResultTest results = new XmlTestResultTest();
+    Ovm3ConfigurationTest configTest = new Ovm3ConfigurationTest();
+    Ovm3HypervisorResource hypervisor = new Ovm3HypervisorResource();
+    Ovm3SupportTest support = new Ovm3SupportTest();
+    LinuxTest linux = new LinuxTest();
+    XenTest xen = new XenTest();
+    StoragePluginTest storageplugin = new StoragePluginTest();
+
+    private ConnectionTest prepare() throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con = support.prepConnectionResults();
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+        return con;
+    }
+
+    /* these could all actually be condensed to a DiskTO */
+    private TemplateObjectTO template(final String uuid, final String dsuuid,
+            final String storeUrl, final String path) {
+        TemplateObjectTO template = new TemplateObjectTO();
+        NfsTO nfsDataStore = new NfsTO();
+        nfsDataStore.setUuid(dsuuid);
+        nfsDataStore.setUrl(storeUrl);
+        template.setDataStore(nfsDataStore);
+        template.setPath(path);
+        template.setUuid(uuid);
+        return template;
+    }
+
+    private VolumeObjectTO volume(final String uuid, final String dsuuid,
+            final String storeUrl, final String path) {
+        VolumeObjectTO volume = new VolumeObjectTO();
+        NfsTO nfsDataStore = new NfsTO();
+        nfsDataStore.setUuid(dsuuid);
+        nfsDataStore.setUrl(storeUrl);
+        volume.setDataStore(nfsDataStore);
+        volume.setPath(path);
+        volume.setUuid(uuid);
+        return volume;
+    }
+
+    private SnapshotObjectTO snapshot(final String uuid, final String dsuuid,
+            final String storeUrl, final String path) {
+        SnapshotObjectTO volume = new SnapshotObjectTO();
+        NfsTO nfsDataStore = new NfsTO();
+        nfsDataStore.setUuid(dsuuid);
+        nfsDataStore.setUrl(storeUrl);
+        volume.setDataStore(nfsDataStore);
+        volume.setPath(path);
+        // volume.setUuid(uuid);
+        return volume;
+    }
+
+    private DiskTO disk(final String uuid, final String dsuuid,
+            final String storeUrl, final String path, Volume.Type type) {
+        DiskTO disk = new DiskTO();
+        disk.setType(type);
+        disk.setPath("");
+        TemplateObjectTO template = template(uuid, dsuuid, storeUrl, path);
+        disk.setData(template);
+        return disk;
+    }
+
+    /**
+     * Copy template from primary to primary volume
+     *
+     * @throws ConfigurationException
+     */
+    @Test
+    public void copyCommandTemplateToVolumeTest() throws ConfigurationException {
+        con = prepare();
+        String voluuid = ovmObject.newUuid();
+        TemplateObjectTO src = template(ovmObject.newUuid(),
+                ovmObject.newUuid(), linux.getRepoId(), linux.getTemplatesDir());
+        VolumeObjectTO dest = volume(voluuid, ovmObject.newUuid(),
+                linux.getRepoId(), linux.getVirtualDisksDir());
+        CopyCommand copy = new CopyCommand(src, dest, 0, true);
+        CopyCmdAnswer ra = (CopyCmdAnswer) hypervisor.executeRequest(copy);
+        VolumeObjectTO vol = (VolumeObjectTO) ra.getNewData();
+        results.basicStringTest(vol.getUuid(), voluuid);
+        results.basicStringTest(vol.getPath(), voluuid);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    /**
+     * Copy template from secondary to primary template
+     *
+     * @throws ConfigurationException
+     */
+    @Test
+    public void copyCommandTemplateToTemplateTest()
+            throws ConfigurationException {
+        con = prepare();
+        con.setMethodResponse("storage_plugin_mount",
+                results.simpleResponseWrapWrapper(storageplugin
+                        .getNfsFileSystemInfo()));
+        /*
+         * because the template requires a reference to the name for the uuid...
+         * -sigh-
+         */
+        String templateid = ovmObject.newUuid();
+        String targetid = ovmObject.newUuid();
+        String templatedir = "template/tmpl/1/11" + templateid + ".raw";
+        String storeUrl = "nfs://" + linux.getRemoteHost() + "/"
+                + linux.getRemoteDir();
+        TemplateObjectTO src = template(templateid, linux.getRepoId(),
+                storeUrl, templatedir);
+        TemplateObjectTO dest = template(targetid,
+                linux.getRepoId(), linux.getRepoId(), linux.getTemplatesDir());
+        CopyCommand copy = new CopyCommand(src, dest, 0, true);
+        CopyCmdAnswer ra = (CopyCmdAnswer) hypervisor.executeRequest(copy);
+        TemplateObjectTO vol = (TemplateObjectTO) ra.getNewData();
+        results.basicStringTest(vol.getUuid(), targetid);
+        results.basicStringTest(vol.getPath(), targetid);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    /**
+     * Copy template from secondary to primary template
+     *
+     * @throws ConfigurationException
+     */
+    @Test
+    public void copyCommandBogusTest() throws ConfigurationException {
+        con = prepare();
+        VolumeObjectTO src = volume(ovmObject.newUuid(), ovmObject.newUuid(),
+                ovmObject.newUuid(linux.getRemote()), linux.getRemote());
+        VolumeObjectTO dest = volume(ovmObject.newUuid(), ovmObject.newUuid(),
+                linux.getRepoId(), linux.getVirtualDisksDir());
+        CopyCommand copy = new CopyCommand(src, dest, 0, false);
+        Answer ra = hypervisor.executeRequest(copy);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+
+    /**
+     * Delete an object
+     *
+     * @throws ConfigurationException
+     */
+    @Test
+    public void deleteCommandTest() throws ConfigurationException {
+        con = prepare();
+        VolumeObjectTO vol = volume(ovmObject.newUuid(), ovmObject.newUuid(),
+                linux.getRepoId(), linux.getVirtualDisksDir());
+        DeleteCommand delete = new DeleteCommand(vol);
+        Answer ra = hypervisor.executeRequest(delete);
+        results.basicBooleanTest(ra.getResult());
+        TemplateObjectTO template = template(ovmObject.newUuid(),
+                ovmObject.newUuid(), ovmObject.newUuid(linux.getRemote()),
+                linux.getRemote());
+        delete = new DeleteCommand(template);
+        ra = hypervisor.executeRequest(delete);
+        results.basicBooleanTest(ra.getResult(), false);
+        SnapshotObjectTO snap = snapshot(ovmObject.newUuid(),
+                ovmObject.newUuid(), ovmObject.newUuid(linux.getRemote()),
+                linux.getRemote());
+        delete = new DeleteCommand(snap);
+        ra = hypervisor.executeRequest(delete);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+
+    public DiskProfile diskProfile() {
+        DiskProfile dp = new DiskProfile(1L, Volume.Type.ROOT,
+                xen.getVmRootDiskName(), 1, storageplugin.getFileSize(),
+                new String[0], false, false, 1L);
+        return dp;
+    }
+
+    /*
+     * unused ?
+     *
+     * @Test
+     * public void createCommandTest() throws ConfigurationException {
+     * con = prepare();
+     * DiskProfile disk = diskProfile();
+     * String templateUrl = null;
+     * StoragePoolVO poolio = new StoragePoolVO();
+     * poolio.setPath(linux.getTemplatesDir());
+     * poolio.setHostAddress(linux.getRemoteHost());
+     *
+     * CreateCommand create = new CreateCommand(disk, templateUrl, poolio ,
+     * false);
+     * Answer ra = hypervisor.executeRequest(create);
+     * results.basicBooleanTest(ra.getResult());
+     * }
+     */
+    @Test
+    public void createTemplateObjectCommandTest() throws ConfigurationException {
+        con = prepare();
+        String tempuuid = ovmObject.newUuid();
+        TemplateObjectTO template = template(tempuuid, ovmObject.newUuid(),
+                ovmObject.newUuid(linux.getRemote()), linux.getRemote());
+        template.setSize(storageplugin.getFileSize());
+        String response = storageplugin.getFileCreateXml().replace(
+                storageplugin.getFileName(), tempuuid + ".raw");
+        response = response.replace(storageplugin.getPoolUuid(),
+                ovmObject.deDash(linux.getRepoId()));
+        con.setMethodResponse("storage_plugin_create",
+                results.simpleResponseWrapWrapper(response));
+        CreateObjectCommand create = new CreateObjectCommand(template);
+        Answer ra = hypervisor.executeRequest(create);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+
+    @Test
+    public void createVolumeObjectCommandTest() throws ConfigurationException {
+        con = prepare();
+        String voluuid = ovmObject.newUuid();
+        VolumeObjectTO vol = volume(voluuid, linux.getRepoId(), "",
+                linux.getVirtualDisksDir());
+        vol.setSize(storageplugin.getFileSize());
+        String response = storageplugin.getFileCreateXml().replace(
+                storageplugin.getFileName(), voluuid + ".raw");
+        response = response.replace(storageplugin.getPoolUuid(),
+                ovmObject.deDash(linux.getRepoId()));
+        con.setMethodResponse("storage_plugin_create",
+                results.simpleResponseWrapWrapper(response));
+        CreateObjectCommand create = new CreateObjectCommand(vol);
+        Answer ra = hypervisor.executeRequest(create);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    @Test
+    public void createSnapshotObjectCommandTest() throws ConfigurationException {
+        con = prepare();
+        String snapuuid = ovmObject.newUuid();
+        SnapshotObjectTO snap = snapshot(snapuuid, linux.getRepoId(), "",
+                linux.getVirtualDisksDir());
+        String response = storageplugin.getFileCreateXml().replace(
+                storageplugin.getFileName(), snapuuid + ".raw");
+        response = response.replace(storageplugin.getPoolUuid(),
+                ovmObject.deDash(linux.getRepoId()));
+        con.setMethodResponse("storage_plugin_create",
+                results.simpleResponseWrapWrapper(response));
+        CreateObjectCommand create = new CreateObjectCommand(snap);
+        Answer ra = hypervisor.executeRequest(create);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+
+    /*
+     * used ?
+     *
+     * @Test
+     * public void isoAttachTest() throws ConfigurationException {
+     * con = prepare();
+     * con.setMethodResponse("storage_plugin_mount",
+     * results.simpleResponseWrapWrapper(storageplugin.getNfsFileSystemInfo()));
+     * String diskid = ovmObject.newUuid();
+     * String storeUrl = "nfs://" + linux.getRemoteHost() + "/" +
+     * linux.getIsoDir();
+     * DiskTO disk = disk(diskid, ovmObject.newUuid(), storeUrl, "bla",
+     * Volume.Type.ISO);
+     * AttachCommand at = new AttachCommand((DiskTO) disk, xen.getVmName());
+     * Answer ra = storage.attachIso(at);
+     * System.out.println(ra);
+     * }
+     */
+    @Test
+    public void isoDettachTest() throws ConfigurationException {
+        con = prepare();
+
+    }
+
+    @Test
+    public void copyVolumeCommandTest() throws ConfigurationException {
+        con = prepare();
+        String src = linux.getVirtualDisksDir() + ovmObject.newUuid() + ".raw";
+        String dst = linux.getVirtualDisksDir() + ovmObject.newUuid() + ".raw";
+        StoragePoolVO poolio = new StoragePoolVO();
+        CopyVolumeCommand copy = new CopyVolumeCommand(0, src, poolio, dst,
+                true, 0, false);
+        Answer ra = hypervisor.executeRequest(copy);
+        results.basicBooleanTest(ra.getResult());
+        copy = new CopyVolumeCommand(0, src, poolio, dst, false, 0, false);
+        ra = hypervisor.executeRequest(copy);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    /*
+     * unused ?
+     *
+     * @Test
+     * public void destroyCommandTest() throws ConfigurationException {
+     * con = prepare();
+     * DestroyCommand destroy = new DestroyCommand(support.pool,
+     * (Volume) volume(xen.getVmRootDiskUuid(), linux.getRepoId(), "",
+     * linux.getVirtualDisksDir()),
+     * xen.getVmName());
+     * }
+     */
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResourceTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResourceTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResourceTest.java
new file mode 100644
index 0000000..2ec4bac
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResourceTest.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.ConfigurationException;
+
+import org.junit.Test;
+
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.hypervisor.ovm3.objects.CloudStackPluginTest;
+import com.cloud.hypervisor.ovm3.objects.ConnectionTest;
+import com.cloud.hypervisor.ovm3.objects.LinuxTest;
+import com.cloud.hypervisor.ovm3.objects.NetworkTest;
+import com.cloud.hypervisor.ovm3.objects.OvmObject;
+import com.cloud.hypervisor.ovm3.objects.XenTest;
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3ConfigurationTest;
+import com.cloud.hypervisor.ovm3.support.Ovm3SupportTest;
+import com.cloud.utils.ExecutionResult;
+
+public class Ovm3VirtualRoutingResourceTest {
+    ConnectionTest con;
+    OvmObject ovmObject = new OvmObject();
+    XmlTestResultTest results = new XmlTestResultTest();
+    Ovm3ConfigurationTest configTest = new Ovm3ConfigurationTest();
+    Ovm3HypervisorResource hypervisor = new Ovm3HypervisorResource();
+    Ovm3VirtualRoutingResource virtualrouting = new Ovm3VirtualRoutingResource();
+    Ovm3SupportTest support = new Ovm3SupportTest();
+    XenTest xen = new XenTest();
+    NetworkTest net = new NetworkTest();
+    LinuxTest linux = new LinuxTest();
+    CloudStackPluginTest csp = new CloudStackPluginTest();
+    String dom0Ip = csp.getDom0Ip();
+    String domrIp = csp.getDomrIp();
+    String routerip = "64.1.1.10";
+    /* cheat */
+    String cmd = "ls";
+    String args = "";
+
+    @Test
+    public void executeInVRTest() {
+        con = support.prepConnectionResults();
+        cmd = "/opt/cloud/bin/" + cmd;
+        virtualrouting.setConnection(con);
+        ExecutionResult result = virtualrouting.executeInVR(domrIp, cmd, args);
+        results.basicBooleanTest(result.isSuccess());
+    }
+
+    @Test
+    public void executeInVRFailTest() {
+        ConnectionTest con = new ConnectionTest();
+        virtualrouting.setConnection(con);
+        ExecutionResult result = virtualrouting.executeInVR(domrIp, cmd, args);
+        results.basicBooleanTest(result.isSuccess(), false);
+    }
+
+    @Test
+    public void createFileInVRTest() {
+        con = support.prepConnectionResults();
+        virtualrouting.setConnection(con);
+        ExecutionResult result = virtualrouting.createFileInVR(domrIp, "/tmp",
+                "test", "1 2 3");
+        results.basicBooleanTest(result.isSuccess());
+    }
+
+    @Test
+    public void createFileInVRFailTest() {
+        ConnectionTest con = new ConnectionTest();
+        virtualrouting.setConnection(con);
+        ExecutionResult result = virtualrouting.createFileInVR(domrIp, "/tmp",
+                "test", "1 2 3");
+        results.basicBooleanTest(result.isSuccess(), false);
+    }
+
+    private ConnectionTest prepare() throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con = support.prepConnectionResults();
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+        virtualrouting.setConnection(con);
+        return con;
+    }
+
+    @Test
+    public void prepareVpcCommandFailTest() throws ConfigurationException {
+        prepare();
+        IpAssocVpcCommand vpc = generateIpAssocVpcCommand(xen.getVmNicMac()
+                .replace("0", "A"));
+        results.basicBooleanTest(hypervisor.executeRequest(vpc).getResult(),
+                false);
+    }
+
+    @Test
+    public void prepareVpcCommandFailHeavierTest()
+            throws ConfigurationException {
+        prepare();
+        con.removeMethodResponse("list_vms");
+        IpAssocVpcCommand vpc = generateIpAssocVpcCommand(xen.getVmNicMac()
+                .replace("0", "F"));
+        results.basicBooleanTest(hypervisor.executeRequest(vpc).getResult(),
+                false);
+    }
+
+    @Test
+    public void prepareCommandTest() throws ConfigurationException {
+        prepare();
+        IpAssocCommand rvm = generateIpAssocCommand(xen.getVmNicMac());
+        results.basicBooleanTest(hypervisor.executeRequest(rvm).getResult());
+    }
+
+    /**
+     * Test is not broken, but code broke somewhere look for the mac that doesn'
+    "nics": [
+          {
+            "deviceId": 2,
+            "networkRateMbps": 200,
+            "defaultNic": true,
+            "pxeDisable": true,
+            "nicUuid": "80bd3c5b-a0f0-4de5-894a-999c83210d7c",
+            "uuid": "eec7acd1-2845-4e46-9226-bd211bb97f28",
+            "ip": "192.168.1.154",
+            "netmask": "255.255.255.0",
+            "gateway": "192.168.1.1",
+            "mac": "06:83:0c:00:00:1e",
+            "dns1": "192.168.1.60",
+            "dns2": "192.168.1.1",
+            "broadcastType": "Vlan",
+            "type": "Public",
+            "broadcastUri": "vlan://0",
+            "isolationUri": "vlan://0",
+            "isSecurityGroupEnabled": false
+          },
+    {
+    "com.cloud.agent.api.routing.IpAssocCommand": {
+      "ipAddresses": [
+        {
+          "accountId": 2,
+          "publicIp": "192.168.1.154",
+          "sourceNat": true,
+          "add": true,
+          "oneToOneNat": false,
+          "firstIP": true,
+          "broadcastUri": "vlan://0",
+          "vlanGateway": "192.168.1.1",
+          "vlanNetmask": "255.255.255.0",
+          "vifMacAddress": "06:74:f6:00:00:1e",
+          "networkRate": 200,
+          "trafficType": "Public",
+          "newNic": false
+        }
+     * @throws ConfigurationException
+     */
+    @Test
+    public void prepareCommandFailTest() throws ConfigurationException {
+        prepare();
+        IpAssocCommand rvm = generateIpAssocCommand(xen.getVmNicMac().replace(
+                "0", "F"));
+        boolean res = hypervisor.executeRequest(rvm).getResult();
+        // this should be false...
+        results.basicBooleanTest(res,
+                true);
+    }
+
+    @Test
+    public void prepareCommandFailHeavierTest() throws ConfigurationException {
+        prepare();
+        con.removeMethodResponse("list_vms");
+        IpAssocCommand rvm = generateIpAssocCommand(xen.getVmNicMac().replace(
+                "0", "F"));
+        results.basicBooleanTest(hypervisor.executeRequest(rvm).getResult(),
+                false);
+    }
+
+    @Test
+    public void prepareVpcCommandTest() throws ConfigurationException {
+        prepare();
+        IpAssocVpcCommand vpc = generateIpAssocVpcCommand(xen.getVmNicMac());
+        results.basicBooleanTest(hypervisor.executeRequest(vpc).getResult());
+    }
+
+    private IpAddressTO[] getIp(String mac) {
+        String br[] = xen.getVmNicBridge().split("[.]");
+        List<IpAddressTO> ips = new ArrayList<IpAddressTO>();
+        IpAddressTO ip = new IpAddressTO(1, routerip, true, true, true, "vlan://"
+                + br[1], "64.1.1.1", "255.255.255.0", mac, 1000, false);
+        ips.add(ip);
+        IpAddressTO[] ipArray = ips.toArray(new IpAddressTO[ips.size()]);
+        return ipArray;
+    }
+
+    private IpAssocVpcCommand generateIpAssocVpcCommand(String mac) {
+        IpAssocVpcCommand cmd = new IpAssocVpcCommand(getIp(mac));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, xen.getVmName());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerip);
+        // assertEquals(6, cmd.getAnswersCount()); // AnswersCount is clearly
+        // wrong as it doesn't know enough to tell
+        return cmd;
+    }
+
+    private IpAssocCommand generateIpAssocCommand(String mac) {
+        IpAssocCommand cmd = new IpAssocCommand(getIp(mac));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, xen.getVmName());
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerip);
+        // assertEquals(6, cmd.getAnswersCount()); // AnswersCount is clearly
+        // wrong as it doesn't know enough to tell
+        return cmd;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3ConfigurationTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3ConfigurationTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3ConfigurationTest.java
new file mode 100644
index 0000000..da0cbe2
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3ConfigurationTest.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.junit.Test;
+
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+
+public class Ovm3ConfigurationTest {
+    XmlTestResultTest results = new XmlTestResultTest();
+    private Ovm3Configuration ovm3config;
+    private static Map<String, Object> params;
+    static {
+        params = new HashMap<String, Object>();
+        params.put("agentusername", "oracle");
+        params.put("xenserver.heartbeat.interval", "60");
+        params.put("public.network.device", "xenbr0");
+        params.put("private.network.device", "xenbr0");
+        params.put("agentpassword", "unknown");
+        params.put("secondary.storage.vm", "false");
+        params.put("Hypervisor.Version", "4.1.3OVM");
+        params.put("Host.OS", "Oracle VM Server");
+        params.put("ipaddress", "192.168.1.64");
+        params.put("ovm3pool", "true");
+        params.put("password", "unknown");
+        params.put("username", "root");
+        params.put("pool", "a9c1219d-817d-4242-b23e-2607801c79d5");
+        params.put("ismaster", "false");
+        params.put("storage.network.device", "xenbr0");
+        params.put("Host.OS.Version", "5.7");
+        params.put("xenserver.nics.max", "7");
+        params.put("agentVersion", "3.2.1-183");
+        params.put("router.aggregation.command.each.timeout", "3");
+        params.put("pod", "1");
+        params.put("max.template.iso.size", "50");
+        params.put("host", "ovm-1");
+        params.put("com.cloud.network.Networks.RouterPrivateIpStrategy",
+                "DcGlobal");
+        params.put("agentport", "8899");
+        params.put("Host.OS.Kernel.Version", "2.6.39-300.22.2.el5uek");
+        params.put("migratewait", "3600");
+        params.put("storage.network.device1", "xenbr0");
+        params.put("ovm3cluster", "false");
+        params.put("ip", "192.168.1.64");
+        params.put("guid", "19e5f1e7-22f4-3b6d-8d41-c82f89c65295");
+        params.put("ovm3vip", "192.168.1.230");
+        params.put("hasmaster", "true");
+        params.put("guest.network.device", "xenbr0");
+        params.put("cluster", "1");
+        params.put("xenserver.heartbeat.timeout", "120");
+        params.put("ovm3.heartbeat.timeout", "120");
+        params.put("ovm3.heartbeat.interval", "1");
+        params.put("zone", "1");
+        params.put("istest", true);
+    }
+
+    @Test
+    public void testConfigLoad() throws ConfigurationException {
+        params.put("pod", "1");
+        ovm3config = new Ovm3Configuration(params);
+        results.basicStringTest(ovm3config.getAgentHostname(), "ovm-1");
+    }
+
+    @Test(expected = ConfigurationException.class)
+    public void testFailedParams() throws ConfigurationException {
+        Map<String, Object> par = new HashMap(params);
+        par.put("pod", null);
+        ovm3config = new Ovm3Configuration(par);
+    }
+    @Test
+    public void testValidatePool() throws ConfigurationException {
+        Map<String, Object> par = new HashMap(params);
+        par.put("cluster", "1");
+        par.put("ovm3vip", "this is not an IP!");
+        ovm3config = new Ovm3Configuration(par);
+        results.basicBooleanTest(ovm3config.getAgentInOvm3Pool(), false);
+        results.basicBooleanTest(ovm3config.getAgentInOvm3Cluster(), false);
+        results.basicStringTest(ovm3config.getOvm3PoolVip(), "");
+    }
+    @Test
+    public void testAgentPort() throws ConfigurationException {
+        Map<String, Object> par = new HashMap(params);
+        String altPort="6333";
+        par.put("agentport", altPort);
+        ovm3config = new Ovm3Configuration(par);
+        results.basicIntTest(Integer.parseInt(altPort), ovm3config.getAgentOvsAgentPort());
+    }
+    public Map<String, Object> getParams() {
+        return params;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3GuestTypesTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3GuestTypesTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3GuestTypesTest.java
new file mode 100644
index 0000000..436400d
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3GuestTypesTest.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import org.junit.Test;
+
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+
+public class Ovm3GuestTypesTest {
+    XmlTestResultTest results = new XmlTestResultTest();
+    String ora = "Oracle Enterprise Linux 6.0 (64-bit)";
+    Ovm3VmGuestTypes ovm3gt = new Ovm3VmGuestTypes();
+
+    @Test
+    public void testGetPvByOs() {
+        results.basicStringTest(ovm3gt.getOvm3GuestType(ora), "xen_pvm");
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetworkTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetworkTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetworkTest.java
new file mode 100644
index 0000000..64ada69
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetworkTest.java
@@ -0,0 +1,110 @@
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.naming.ConfigurationException;
+
+import org.junit.Test;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.hypervisor.ovm3.objects.CloudStackPluginTest;
+import com.cloud.hypervisor.ovm3.objects.ConnectionTest;
+import com.cloud.hypervisor.ovm3.objects.NetworkTest;
+import com.cloud.hypervisor.ovm3.objects.XenTest;
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+import com.cloud.hypervisor.ovm3.resources.Ovm3HypervisorResource;
+import com.cloud.hypervisor.ovm3.resources.Ovm3HypervisorResourceTest;
+import com.cloud.hypervisor.ovm3.support.Ovm3SupportTest;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+
+public class Ovm3HypervisorNetworkTest {
+    ConnectionTest con = new ConnectionTest();
+    Ovm3ConfigurationTest configTest = new Ovm3ConfigurationTest();
+    Ovm3SupportTest support = new Ovm3SupportTest();
+    Ovm3HypervisorResource hypervisor = new Ovm3HypervisorResource();
+    Ovm3HypervisorResourceTest hyperTest = new Ovm3HypervisorResourceTest();
+    CloudStackPluginTest csp = new CloudStackPluginTest();
+    XenTest xen = new XenTest();
+    NetworkTest network = new NetworkTest();
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    @Test
+    public void CheckNetworkCommandTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        List<PhysicalNetworkSetupInfo> setups = new ArrayList<PhysicalNetworkSetupInfo>();
+        PhysicalNetworkSetupInfo networkInfo = new PhysicalNetworkSetupInfo();
+        setups.add(networkInfo);
+        CheckNetworkCommand cmd = new CheckNetworkCommand(setups);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void CheckNetworkCommandGuestFailTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        List<PhysicalNetworkSetupInfo> setups = new ArrayList<PhysicalNetworkSetupInfo>();
+        PhysicalNetworkSetupInfo networkInfo = new PhysicalNetworkSetupInfo();
+        networkInfo.setGuestNetworkName(network.getInterface() + "." + 3000);
+        setups.add(networkInfo);
+        CheckNetworkCommand cmd = new CheckNetworkCommand(setups);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+    @Test
+    public void CheckNetworkCommandPublicFailTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        List<PhysicalNetworkSetupInfo> setups = new ArrayList<PhysicalNetworkSetupInfo>();
+        PhysicalNetworkSetupInfo networkInfo = new PhysicalNetworkSetupInfo();
+        networkInfo.setPublicNetworkName(network.getInterface() + "." + 3000);
+        setups.add(networkInfo);
+        CheckNetworkCommand cmd = new CheckNetworkCommand(setups);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+    @Test
+    public void CheckNetworkCommandPrivateFailTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        List<PhysicalNetworkSetupInfo> setups = new ArrayList<PhysicalNetworkSetupInfo>();
+        PhysicalNetworkSetupInfo networkInfo = new PhysicalNetworkSetupInfo();
+        networkInfo.setPrivateNetworkName(network.getInterface() + "." + 3000);
+        setups.add(networkInfo);
+        CheckNetworkCommand cmd = new CheckNetworkCommand(setups);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+    @Test
+    public void CheckNetworkCommandStorageFalseTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        List<PhysicalNetworkSetupInfo> setups = new ArrayList<PhysicalNetworkSetupInfo>();
+        PhysicalNetworkSetupInfo networkInfo = new PhysicalNetworkSetupInfo();
+        networkInfo.setStorageNetworkName(network.getInterface() + "." + 3000);
+        setups.add(networkInfo);
+        CheckNetworkCommand cmd = new CheckNetworkCommand(setups);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void PingTestCommandWeDontPingRouterTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        PingTestCommand cmd = new PingTestCommand(csp.getDom0Ip(), csp.getDomrIp());
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult(),false);
+    }
+    @Test
+    public void PingTestCommandComputeTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        PingTestCommand cmd = new PingTestCommand(csp.getDom0Ip());
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void PingTestCommandComputeFalseTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        support.getConnection().setMethodResponse("ping", results.simpleResponseWrap("boolean", "0"));
+        PingTestCommand cmd = new PingTestCommand(csp.getDom0Ip());
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupportTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupportTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupportTest.java
new file mode 100644
index 0000000..0ba27b2
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupportTest.java
@@ -0,0 +1,281 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import static org.junit.Assert.assertNull;
+
+import javax.naming.ConfigurationException;
+
+import org.junit.Test;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.hypervisor.ovm3.objects.ConnectionTest;
+import com.cloud.hypervisor.ovm3.objects.LinuxTest;
+import com.cloud.hypervisor.ovm3.objects.NetworkTest;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+import com.cloud.hypervisor.ovm3.objects.XenTest;
+import com.cloud.hypervisor.ovm3.resources.Ovm3HypervisorResource;
+import com.cloud.hypervisor.ovm3.resources.Ovm3StorageProcessor;
+import com.cloud.hypervisor.ovm3.resources.Ovm3VirtualRoutingResource;
+import com.cloud.hypervisor.ovm3.support.Ovm3SupportTest;
+import com.cloud.vm.VirtualMachine.State;
+
+public class Ovm3HypervisorSupportTest {
+    ConnectionTest con = new ConnectionTest();
+    XmlTestResultTest results = new XmlTestResultTest();
+    Ovm3ConfigurationTest configTest = new Ovm3ConfigurationTest();
+    Ovm3HypervisorResource hypervisor = new Ovm3HypervisorResource();
+    Ovm3VirtualRoutingResource virtualrouting = new Ovm3VirtualRoutingResource();
+    Ovm3SupportTest support = new Ovm3SupportTest();
+    Ovm3StorageProcessor storage;
+    Ovm3StoragePool pool;
+    XenTest xen = new XenTest();
+    String vmName = xen.getVmName();
+    String unknown = "------";
+    String running = "r-----";
+    String blocked = "-b----";
+    String paused = "--p---";
+    String shutdown = "---s--";
+    String crashed = "----c-";
+    String dying = "-----d";
+
+    /* we only want this for the xml results */
+    String dom0stats = results.simpleResponseWrapWrapper("<struct>"
+            + "<member>" + "<name>rx</name>"
+            + "<value><string>25069761</string></value>" + "</member>"
+            + "<member>" + "<name>total</name>"
+            + "<value><string>4293918720</string></value>" + "</member>"
+            + "<member>" + "<name>tx</name>"
+            + "<value><string>37932556</string></value>" + "</member>"
+            + "<member>" + "<name>cpu</name>"
+            + "<value><string>2.4</string></value>" + "</member>" + "<member>"
+            + "<name>free</name>"
+            + "<value><string>1177550848</string></value>" + "</member>"
+            + "</struct>");
+
+    private ConnectionTest prepare() throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con = support.prepConnectionResults();
+        pool = new Ovm3StoragePool(con, config);
+        storage = new Ovm3StorageProcessor(con, config, pool);
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+        virtualrouting.setConnection(con);
+        return con;
+    }
+    @Test
+    public void ReportedVmStatesTest() throws ConfigurationException,
+            Ovm3ResourceException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con.setResult(xen.getMultipleVmsListXML());
+        Ovm3HypervisorSupport hypervisor = new Ovm3HypervisorSupport(con,
+                config);
+        hypervisor.vmStateMapClear();
+
+        State vmState = hypervisor.getVmState(vmName);
+        results.basicStringTest(vmState.toString(), State.Running.toString());
+        hypervisor.setVmStateStarting(vmName);
+        results.basicStringTest(hypervisor.getVmState(vmName).toString(),
+                State.Starting.toString());
+        hypervisor.setVmState(vmName, State.Running);
+        results.basicStringTest(hypervisor.getVmState(vmName).toString(),
+                State.Running.toString());
+        hypervisor.revmoveVmState(vmName);
+        assertNull(hypervisor.getVmState(vmName));
+    }
+
+    @Test
+    public void HypervisorVmStateTest() throws ConfigurationException,
+            Ovm3ResourceException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        Ovm3HypervisorSupport hypervisor = new Ovm3HypervisorSupport(con,
+                config);
+        setHypervisorVmState(hypervisor, blocked, unknown, State.Unknown);
+        setHypervisorVmState(hypervisor, blocked, running, State.Running);
+        setHypervisorVmState(hypervisor, blocked, blocked, State.Running);
+        setHypervisorVmState(hypervisor, blocked, paused, State.Running);
+        /* TODO: ehm wtf ? */
+        setHypervisorVmState(hypervisor, blocked, shutdown, State.Running);
+        setHypervisorVmState(hypervisor, blocked, crashed, State.Error);
+        setHypervisorVmState(hypervisor, blocked, dying, State.Stopping);
+    }
+
+    @Test
+    public void CombinedVmStateTest() throws ConfigurationException,
+            Ovm3ResourceException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        con.setResult(xen.getMultipleVmsListXML());
+        Ovm3HypervisorSupport hypervisor = new Ovm3HypervisorSupport(con,
+                config);
+        hypervisor.vmStateMapClear();
+        /* test starting */
+        hypervisor.setVmState(vmName, State.Starting);
+        // System.out.println(hypervisor.getVmState(vmName));
+        hypervisor.syncState();
+        // System.out.println(hypervisor.getVmState(vmName));
+
+        // setHypervisorVmState(hypervisor, blocked, paused, State.Stopped);
+
+        hypervisor.setVmState(vmName, State.Stopping);
+        hypervisor.setVmState(vmName, State.Migrating);
+        // setHypervisorVmState(hypervisor, blocked, running, State.Running);
+        hypervisor.setVmState(vmName, State.Stopped);
+
+        // setHypervisorVmState(hypervisor, blocked, running, State.Migrating);
+
+    }
+
+    /**
+     * Sets the state, original, of the fake VM to replace.
+     *
+     * @param hypervisor
+     * @param original
+     * @param replace
+     * @param state
+     * @throws Ovm3ResourceException
+     */
+    public void setHypervisorVmState(Ovm3HypervisorSupport hypervisor,
+            String original, String replace, State state)
+            throws Ovm3ResourceException {
+        String x = xen.getMultipleVmsListXML().replaceAll(original, replace);
+        con.setResult(x);
+        hypervisor.syncState();
+        results.basicStringTest(hypervisor.getVmState(vmName).toString(),
+                state.toString());
+    }
+
+    @Test
+    public void getSystemVMKeyFileTest() throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        Ovm3HypervisorSupport hypervisor = new Ovm3HypervisorSupport(con,
+                config);
+        hypervisor.getSystemVMKeyFile(config.getAgentSshKeyFileName());
+    }
+    @Test
+    public void getSystemVMKeyFileMissingTest() throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        Ovm3HypervisorSupport hypervisor = new Ovm3HypervisorSupport(con,
+                config);
+        hypervisor.getSystemVMKeyFile("missing");
+    }
+
+    @Test
+    public void checkHealthTest() throws ConfigurationException {
+        con = prepare();
+        CheckHealthCommand cmd = new CheckHealthCommand();
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    @Test
+    public void masterCheckTest() throws ConfigurationException {
+        con = prepare();
+        // System.out.println(hypervisor.masterCheck());
+    }
+
+    @Test
+    public void GetHostStatsCommandTest() throws ConfigurationException {
+        con = prepare();
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        GetHostStatsCommand cmd = new GetHostStatsCommand(config.getCsHostGuid(),
+                config.getAgentName(), 1L);
+        con.setResult(this.dom0stats);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+
+    @Test
+    public void GetHostStatsCommandFailTest() throws ConfigurationException {
+        con = prepare();
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        GetHostStatsCommand cmd = new GetHostStatsCommand(config.getCsHostGuid(),
+                config.getAgentName(), 1L);
+        con.setNull();
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+
+    @Test
+    public void CheckVirtualMachineCommandTest() throws ConfigurationException {
+        con = prepare();
+        CheckVirtualMachineCommand cmd = new CheckVirtualMachineCommand(xen.getVmName());
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void MaintainCommandTest() throws ConfigurationException {
+        con = prepare();
+        MaintainCommand cmd = new MaintainCommand();
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void GetVncPortCommandTest() throws ConfigurationException {
+        con = prepare();
+        GetVncPortCommand cmd = new GetVncPortCommand(0, xen.getVmName());
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+    /* We can't fence yet... */
+    @Test
+    public void FenceCommandTest() throws ConfigurationException {
+        con = prepare();
+        FenceCommand cmd = new FenceCommand();
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+
+    @Test
+    public void fillHostinfoTest() throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        ConnectionTest con = new ConnectionTest();
+        con.setIp(config.getAgentIp());
+        Ovm3HypervisorSupport hypervisor = new Ovm3HypervisorSupport(con,
+                config);
+        LinuxTest linuxTest = new LinuxTest();
+        NetworkTest networkTest = new NetworkTest();
+        StartupRoutingCommand srCmd = new StartupRoutingCommand();
+        con.setResult(results.simpleResponseWrapWrapper(linuxTest
+                .getDiscoverHw()));
+        con.addResult(results.simpleResponseWrapWrapper(linuxTest
+                .getDiscoverserver()));
+        con.addResult(results.simpleResponseWrapWrapper(networkTest
+                .getDiscoverNetwork()));
+        hypervisor.fillHostInfo(srCmd);
+    }
+
+    /* @Test(expected = CloudRuntimeException.class)
+    public void setupServerTest() throws ConfigurationException, IOException {
+        Ovm3Configuration config = new Ovm3Configuration(configTest.getParams());
+        ConnectionTest con = new ConnectionTest();
+        con.setIp("127.0.0.1");
+        Ovm3HypervisorSupport hypervisor = new Ovm3HypervisorSupport(con,
+                config);
+        hypervisor.setupServer(config.getAgentSshKeyFileName());
+    } */
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VirtualRoutingSupportTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VirtualRoutingSupportTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VirtualRoutingSupportTest.java
new file mode 100644
index 0000000..6936b2d
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VirtualRoutingSupportTest.java
@@ -0,0 +1,71 @@
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import javax.naming.ConfigurationException;
+
+import org.junit.Test;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.hypervisor.ovm3.objects.CloudStackPluginTest;
+import com.cloud.hypervisor.ovm3.objects.ConnectionTest;
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+import com.cloud.hypervisor.ovm3.resources.Ovm3HypervisorResource;
+import com.cloud.hypervisor.ovm3.support.Ovm3SupportTest;
+
+public class Ovm3VirtualRoutingSupportTest {
+    ConnectionTest con = new ConnectionTest();
+    Ovm3ConfigurationTest configTest = new Ovm3ConfigurationTest();
+    Ovm3SupportTest support = new Ovm3SupportTest();
+    Ovm3HypervisorResource hypervisor = new Ovm3HypervisorResource();
+    CloudStackPluginTest csp = new CloudStackPluginTest();
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    @Test
+    public void NetworkUsageCommandTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        NetworkUsageCommand nuc = new NetworkUsageCommand(csp.getDomrIp(), "something", "", false);
+        Answer ra = hypervisor.executeRequest(nuc);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void NetworkUsageVpcCommandTest() throws ConfigurationException {
+            hypervisor = support.prepare(configTest.getParams());
+            NetworkUsageCommand nuc = new NetworkUsageCommand(csp.getDomrIp(), "something", "", true);
+            Answer ra = hypervisor.executeRequest(nuc);
+            results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void NetworkVpcGetCommandTest() throws ConfigurationException {
+        NetworkVpcCommandTest("get");
+    }
+    @Test
+    public void NetworkVpcCreateCommandTest() throws ConfigurationException {
+        NetworkVpcCommandTest("create");
+    }
+    @Test
+    public void NetworkVpcResetCommandTest() throws ConfigurationException {
+        NetworkVpcCommandTest("reset");
+    }
+    @Test
+    public void NetworkVpcVpnCommandTest() throws ConfigurationException {
+        NetworkVpcCommandTest("vpn");
+    }
+    @Test
+    public void NetworkVpcRemoveCommandTest() throws ConfigurationException {
+        NetworkVpcCommandTest("remove");
+    }
+    public void NetworkVpcCommandTest(String cmd) throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        NetworkUsageCommand nuc = new NetworkUsageCommand(csp.getDomrIp(), "something", cmd, true);
+        Answer ra = hypervisor.executeRequest(nuc);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void CheckSshCommandTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        CheckSshCommand ssh = new CheckSshCommand("name", csp.getDomrIp(), 8899);
+        Answer ra = hypervisor.executeRequest(ssh);
+        results.basicBooleanTest(ra.getResult());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmSupportTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmSupportTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmSupportTest.java
new file mode 100644
index 0000000..e6e19f4
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmSupportTest.java
@@ -0,0 +1,123 @@
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.naming.ConfigurationException;
+import org.junit.Test;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.UnPlugNicCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.hypervisor.ovm3.objects.CloudStackPluginTest;
+import com.cloud.hypervisor.ovm3.objects.ConnectionTest;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.XenTest;
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+import com.cloud.hypervisor.ovm3.resources.Ovm3HypervisorResource;
+import com.cloud.hypervisor.ovm3.resources.Ovm3HypervisorResourceTest;
+import com.cloud.hypervisor.ovm3.support.Ovm3SupportTest;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.vm.VirtualMachine;
+
+public class Ovm3VmSupportTest {
+    ConnectionTest con = new ConnectionTest();
+    Ovm3ConfigurationTest configTest = new Ovm3ConfigurationTest();
+    Ovm3SupportTest support = new Ovm3SupportTest();
+    Ovm3HypervisorResource hypervisor = new Ovm3HypervisorResource();
+    Ovm3HypervisorResourceTest hyperTest = new Ovm3HypervisorResourceTest();
+    CloudStackPluginTest csp = new CloudStackPluginTest();
+    XenTest xen = new XenTest();
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    private NicTO prepNic(String mac, Integer vlan, TrafficType type) throws URISyntaxException {
+        return prepNic(mac, vlan, type, 0);
+    }
+    private NicTO prepNic(String mac, Integer vlan, TrafficType type, Integer id) throws URISyntaxException {
+        URI iso = new URI("vlan://" + vlan.toString());
+        NicTO nic = new NicTO();
+        nic.setType(type);
+        /* Isolation is not what it seems.... */
+        /* nic.setIsolationuri(iso); */
+        nic.setBroadcastUri(iso);
+        nic.setMac(mac);
+        nic.setDeviceId(id);
+        return nic;
+    }
+    @Test
+    public void PlugNicTest() throws ConfigurationException, URISyntaxException {
+        hypervisor = support.prepare(configTest.getParams());
+        NicTO nic = prepNic(xen.getVmNicMac(), 200, TrafficType.Guest);
+        PlugNicCommand plug = new PlugNicCommand(nic,xen.getVmName(), VirtualMachine.Type.User);
+        Answer ra = hypervisor.executeRequest(plug);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void PlugNicBreakTest() throws ConfigurationException, URISyntaxException {
+        hypervisor = support.prepare(configTest.getParams());
+        NicTO nic = prepNic(xen.getVmNicMac(), 240, TrafficType.Guest);
+        PlugNicCommand plug = new PlugNicCommand(nic,xen.getVmName(), VirtualMachine.Type.User);
+        Answer ra = hypervisor.executeRequest(plug);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+    @Test
+    public void unPlugNicTest() throws ConfigurationException, URISyntaxException {
+        hypervisor = support.prepare(configTest.getParams());
+        NicTO nic = prepNic(xen.getVmNicMac(), 200, TrafficType.Guest);
+        UnPlugNicCommand plug = new UnPlugNicCommand(nic, xen.getVmName());
+        Answer ra = hypervisor.executeRequest(plug);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void unPlugNicBreakTest() throws ConfigurationException, URISyntaxException {
+        hypervisor = support.prepare(configTest.getParams());
+        NicTO nic = prepNic(xen.getVmNicMac(), 240, TrafficType.Guest);
+        UnPlugNicCommand plug = new UnPlugNicCommand(nic, xen.getVmName());
+        Answer ra = hypervisor.executeRequest(plug);
+        results.basicBooleanTest(ra.getResult(), false);
+    }
+    @Test
+    public void GetVmStatsCommandTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        Ovm3Configuration configuration = new Ovm3Configuration(configTest.getParams());
+        List<String> vms = new ArrayList<String>();
+        vms.add(xen.getVmName());
+        GetVmStatsCommand cmd = new GetVmStatsCommand(vms, configuration.getCsHostGuid(), hypervisor.getName());
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+        cmd = new GetVmStatsCommand(vms, configuration.getCsHostGuid(), hypervisor.getName());
+        ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void PrepareForMigrationCommandTest() throws ConfigurationException, Ovm3ResourceException {
+        hypervisor = support.prepare(configTest.getParams());
+        PrepareForMigrationCommand cmd = new PrepareForMigrationCommand(hyperTest.createVm(xen.getVmName()));
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+    @Test
+    public void MigrateCommandTest() throws ConfigurationException, Ovm3ResourceException {
+        Ovm3Configuration configuration = new Ovm3Configuration(configTest.getParams());
+        hypervisor = support.prepare(configTest.getParams());
+        MigrateCommand cmd = new MigrateCommand(xen.getVmName(), configuration.getAgentIp(), false, hyperTest.createVm(xen.getVmName()), false);
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+/*
+    @Test
+    public void AttachVolumeCommandTest() throws ConfigurationException {
+        hypervisor = support.prepare(configTest.getParams());
+        // boolean attach, boolean managed, String vmName, StoragePoolType pooltype,
+        // String volumePath, String volumeName, Long volumeSize, Long deviceId, String chainInfo
+        AttachVolumeCommand cmd = new AttachVolumeCommand(true, false, xen.getVmName(), StoragePoolType.NetworkFilesystem,
+                "x", "x", 0L, 0L, "x");
+        Answer ra = hypervisor.executeRequest(cmd);
+        results.basicBooleanTest(ra.getResult());
+    }
+*/
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/support/Ovm3SupportTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/support/Ovm3SupportTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/support/Ovm3SupportTest.java
new file mode 100644
index 0000000..95d8e42
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/support/Ovm3SupportTest.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.support;
+
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import com.cloud.hypervisor.ovm3.objects.CloudStackPluginTest;
+import com.cloud.hypervisor.ovm3.objects.ConnectionTest;
+import com.cloud.hypervisor.ovm3.objects.LinuxTest;
+import com.cloud.hypervisor.ovm3.objects.NetworkTest;
+import com.cloud.hypervisor.ovm3.objects.XenTest;
+import com.cloud.hypervisor.ovm3.objects.XmlTestResultTest;
+import com.cloud.hypervisor.ovm3.resources.Ovm3HypervisorResource;
+import com.cloud.hypervisor.ovm3.resources.Ovm3VirtualRoutingResource;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3ConfigurationTest;
+
+public class Ovm3SupportTest {
+    ConnectionTest con = new ConnectionTest();
+    XmlTestResultTest results = new XmlTestResultTest();
+    NetworkTest net = new NetworkTest();
+    LinuxTest linux = new LinuxTest();
+    XenTest xen = new XenTest();
+    CloudStackPluginTest csp = new CloudStackPluginTest();
+    Ovm3HypervisorResource hypervisor = new Ovm3HypervisorResource();
+    Ovm3VirtualRoutingResource virtualrouting = new Ovm3VirtualRoutingResource();
+    Ovm3ConfigurationTest configTest = new Ovm3ConfigurationTest();
+
+    public ConnectionTest prepConnectionResults() {
+        ConnectionTest con = new ConnectionTest();
+        con.setIp(con.getHostName());
+        return configureResult(con);
+    }
+
+    public Ovm3HypervisorResource prepare(Map<String, Object> params) throws ConfigurationException {
+        Ovm3Configuration config = new Ovm3Configuration(params);
+        con = prepConnectionResults();
+        hypervisor.setConnection(con);
+        results.basicBooleanTest(hypervisor.configure(config.getAgentName(),
+                configTest.getParams()));
+        return hypervisor;
+    }
+    public ConnectionTest getConnection() {
+        return con;
+    }
+
+    public ConnectionTest configureResult(ConnectionTest con) {
+        con.setMethodResponse("check_dom0_ip",
+                results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("ovs_ip_config",
+                results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("ovs_local_config",
+                results.simpleResponseWrap("string", "start"));
+        con.setMethodResponse("ovs_control_interface",
+                results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("update_server_roles",
+                results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("discover_network",
+                results.simpleResponseWrapWrapper(net.getDiscoverNetwork()));
+        con.setMethodResponse("discover_hardware",
+                results.simpleResponseWrapWrapper(linux.getDiscoverHw()));
+        con.setMethodResponse("discover_server",
+                results.simpleResponseWrapWrapper(linux.getDiscoverserver()));
+        con.setMethodResponse("discover_mounted_file_systems",
+                results.simpleResponseWrapWrapper(linux.getDiscoverFs()));
+        con.setMethodResponse("get_vncport", results.simpleResponseWrapWrapper("5900"));
+        con.setMethodResponse("echo", results.simpleResponseWrapWrapper("put"));
+        con.setMethodResponse("list_vms", xen.getMultipleVmsListXML());
+        con.setMethodResponse("list_vm", xen.getSingleVmListXML());
+        con.setMethodResponse("get_vm_config", xen.getSingleVmConfigXML());
+        con.setMethodResponse("create_vm", results.getNil());
+        con.setMethodResponse("start_vm", results.getNil());
+        con.setMethodResponse("reboot_vm", results.getNil());
+        con.setMethodResponse("stop_vm", results.getNil());
+        con.setMethodResponse("configure_vm", results.getNil());
+        con.setMethodResponse("migrate_vm", results.getNil());
+        con.setMethodResponse("copy_file", results.getNil());
+        con.setMethodResponse("storage_plugin_destroy", results.getNil());
+        con.setMethodResponse("ping",
+                results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("check_domr_ssh",
+                results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("check_domr_port",
+                results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("exec_domr", csp.getDomrExecXml());
+        con.setMethodResponse("ovs_domr_upload_file",
+                results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("ovs_domU_stats", (csp.getDomuStatsXml()));
+        con.setMethodResponse("check_dom0_status", (csp.getDom0StorageCheckXml()));
+        con.setMethodResponse("check_dom0_storage_health", results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("check_dom0_port", results.simpleResponseWrap("boolean", "1"));
+        con.setMethodResponse("check_dom0_storage_health_check",  (csp.getDom0StorageCheckXml()));
+        return con;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/log4j.properties b/plugins/hypervisors/ovm3/src/test/resources/log4j.properties
new file mode 100644
index 0000000..4579c25
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/log4j.properties
@@ -0,0 +1,8 @@
+# Root logger option
+log4j.rootLogger=DEBUG, stdout
+
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/clean_master.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/clean_master.sh b/plugins/hypervisors/ovm3/src/test/resources/scripts/clean_master.sh
new file mode 100755
index 0000000..bbf1cd0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/clean_master.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+for i in `xm list | awk '{ print $1 }' | egrep -v "Name|Domain-0"`
+do
+    xm destroy $i
+done
+rm /etc/ovs-agent/db/server
+rm /etc/ovs-agent/db/repository
+rm /etc/ocfs2/cluster.conf
+rm /nfsmnt/*/*.img
+rm /nfsmnt/*/.ovspoolfs
+rm /nfsmnt/*/.generic_fs_stamp
+rm /OVS/Repositories/*/.generic_fs_stamp
+rm /OVS/Repositories/*/.ovsrepo
+/etc/init.d/ovs-agent restart
+/etc/init.d/ocfs2 restart
+for i in `mount | grep cs-mgmt | awk '{ print $1 }'`
+do
+    umount $i
+done
+rm -rf /OVS/Repositories/*
+rm -rf /nfsmnt/*
+ip addr del 192.168.1.230 dev c0a80100
+ip addr del 192.168.1.161 dev c0a80100
+rm /etc/sysconfig/network-scripts/ifcfg-control0
+reboot

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/clean_slave.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/clean_slave.sh b/plugins/hypervisors/ovm3/src/test/resources/scripts/clean_slave.sh
new file mode 100755
index 0000000..4275ee8
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/clean_slave.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+for i in `xm list | awk '{ print $1 }' | egrep -v "Name|Domain-0"`
+do
+    xm destroy $i
+done
+rm /etc/ovs-agent/db/server
+rm /etc/ovs-agent/db/repository
+rm /etc/ocfs2/cluster.conf
+/etc/init.d/ovs-agent restart
+/etc/init.d/ocfs2 restart
+for i in `mount | grep cs-mgmt | awk '{ print $1 }'`
+do
+    umount $i
+done


[05/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/RepositoryTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/RepositoryTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/RepositoryTest.java
new file mode 100644
index 0000000..eaf6612
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/RepositoryTest.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import org.junit.Test;
+
+public class RepositoryTest {
+    ConnectionTest con = new ConnectionTest();
+    Repository repo = new Repository(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    private String REPOID = "f12842ebf5ed3fe78da1eb0e17f5ede8";
+    private String MGRID = "d1a749d4295041fb99854f52ea4dea97";
+    private String REPOALIAS = "OVS Repository";
+    private String REMOTENFS = "cs-mgmt:/volumes/cs-data/primary/ovm";
+    private String LOCALMOUNT = "/OVS/Repositories/f12842ebf5ed3fe78da1eb0e17f5ede8";
+    private String REPOVERSION = "3.0";
+    private String REPOSTATUS = "Mounted";
+    private String ISO = "systemvm.iso";
+    private String TEMPLATE = "0b53acb1-6554-41b8-b1e1-7b27a01b6acb";
+    private String DISK = "cfb5ee12-b99d-41d1-a5b2-44dea36c9de1.raw";
+    private String VM = "7efbdbe0-3d01-3b22-a8a0-1d41c6f2502f";
+    private String REPODISCOVERXML = "<string>"
+            + "&lt;?xml version=\"1.0\" ?&gt;"
+            + "&lt;Discover_Repositories_Result&gt;" + "&lt;RepositoryList&gt;"
+            + "&lt;Repository Name=\""
+            + REPOID
+            + "\"&gt;"
+            + "&lt;Version&gt;"
+            + REPOVERSION
+            + "&lt;/Version&gt;"
+            + "&lt;Manager_UUID&gt;"
+            + MGRID
+            + "&lt;/Manager_UUID&gt;"
+            + "&lt;Repository_UUID&gt;"
+            + REPOID
+            + "&lt;/Repository_UUID&gt;"
+            + "&lt;Repository_Alias&gt;"
+            + REPOALIAS
+            + "&lt;/Repository_Alias&gt;"
+            + "&lt;Assemblies/&gt;"
+            + "&lt;Templates&gt;"
+            + "&lt;Template Name=\""
+            + TEMPLATE
+            + "\"&gt;"
+            + "&lt;File&gt;"
+            + TEMPLATE
+            + ".raw&lt;/File&gt;"
+            + "&lt;/Template&gt;"
+            + "&lt;Template Name=\"7d5c29db-6343-4431-b509-9646b45cc31b\"&gt;"
+            + "&lt;File&gt;7d5c29db-6343-4431-b509-9646b45cc31b.raw&lt;/File&gt;"
+            + "&lt;/Template&gt;"
+            + "&lt;/Templates&gt;"
+            + "&lt;VirtualMachines&gt;"
+            + "&lt;VirtualMachine Name=\""
+            + VM
+            + "\"&gt;"
+            + "&lt;File&gt;vm.cfg&lt;/File&gt;"
+            + "&lt;/VirtualMachine&gt;"
+            + "&lt;VirtualMachine Name=\"pool\"&gt;"
+            + "&lt;File&gt;ovspoolfs.img&lt;/File&gt;"
+            + "&lt;/VirtualMachine&gt;"
+            + "&lt;VirtualMachine Name=\"4fb50e31-b032-3012-b70b-7e27c2acdfe2\"&gt;"
+            + "&lt;File&gt;vm.cfg&lt;/File&gt;"
+            + "&lt;/VirtualMachine&gt;"
+            + "&lt;VirtualMachine Name=\"5ffe3ddc-606d-3fec-a956-67638f7ba838\"&gt;"
+            + "&lt;File&gt;vm.cfg&lt;/File&gt;"
+            + "&lt;/VirtualMachine&gt;"
+            + "&lt;VirtualMachine Name=\"14fc3846-45e5-3c08-ad23-432ceb07407b\"&gt;"
+            + "&lt;File&gt;vm.cfg&lt;/File&gt;"
+            + "&lt;/VirtualMachine&gt;"
+            + "&lt;/VirtualMachines&gt;"
+            + "&lt;VirtualDisks&gt;"
+            + "&lt;Disk&gt;"
+            + DISK
+            + "&lt;/Disk&gt;"
+            + "&lt;Disk&gt;b92dd5c5-0f24-4cca-b86a-153ac6e950a8.raw&lt;/Disk&gt;"
+            + "&lt;Disk&gt;d144c278-0825-41d5-b9c6-8bb21f3dd1e7.raw&lt;/Disk&gt;"
+            + "&lt;Disk&gt;99650d9f-c7ee-42df-92e3-6cafc0876141.raw&lt;/Disk&gt;"
+            + "&lt;/VirtualDisks&gt;"
+            + "&lt;ISOs&gt;"
+            + "&lt;ISO&gt;"
+            + ISO
+            + "&lt;/ISO&gt;"
+            + "&lt;/ISOs&gt;"
+            + "&lt;/Repository&gt;"
+            + "&lt;/RepositoryList&gt;"
+            + "&lt;/Discover_Repositories_Result&gt;" + "</string>";
+    private String REPODBDISCOVERXML = "<string>"
+            + "&lt;?xml version=\"1.0\" ?&gt;"
+            + "&lt;Discover_Repository_Db_Result&gt;"
+            + "&lt;RepositoryDbList&gt;" + "&lt;Repository Uuid=\""
+            + REPOID
+            + "\"&gt;"
+            + "&lt;Fs_location&gt;"
+            + REMOTENFS
+            + "&lt;/Fs_location&gt;"
+            + "&lt;Mount_point&gt;"
+            + LOCALMOUNT
+            + "&lt;/Mount_point&gt;"
+            + "&lt;Filesystem_type&gt;nfs&lt;/Filesystem_type&gt;"
+            + "&lt;Version&gt;"
+            + REPOVERSION
+            + "&lt;/Version&gt;"
+            + "&lt;Alias&gt;"
+            + REPOALIAS
+            + "&lt;/Alias&gt;"
+            + "&lt;Manager_uuid&gt;"
+            + MGRID
+            + "&lt;/Manager_uuid&gt;"
+            + "&lt;Status&gt;"
+            + REPOSTATUS
+            + "&lt;/Status&gt;"
+            + "&lt;/Repository&gt;"
+            + "&lt;/RepositoryDbList&gt;"
+            + "&lt;/Discover_Repository_Db_Result&gt;" + "</string>";
+
+    /*
+     * @Test Create a test repo that mimics the above so we can test against a
+     * live box... public void testCreateRepo() throws Ovm3ResourceException {
+     * con.setResult(null); repo.createRepo(REMOTENFS, LOCALMOUNT, REPOID,
+     * REPOALIAS); }
+     */
+    @Test
+    public void testDiscoverRepoBase() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(this.REPODISCOVERXML));
+        repo.discoverRepo(REPOID);
+        results.basicStringTest(repo.getRepo(REPOID).getUuid(), REPOID);
+        results.basicStringTest(repo.getRepo(REPOID).getAlias(), REPOALIAS);
+        results.basicStringTest(repo.getRepo(REPOID).getVersion(), REPOVERSION);
+        results.basicStringTest(repo.getRepo(REPOID).getManagerUuid(), MGRID);
+    }
+
+    @Test
+    public void testDiscoverRepoDetails() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(this.REPODISCOVERXML));
+        repo.discoverRepo(REPOID);
+        results.basicBooleanTest(results.basicListHasString(repo
+                .getRepo(REPOID).getRepoVirtualDisks(), DISK), true);
+        results.basicBooleanTest(results.basicListHasString(repo
+                .getRepo(REPOID).getRepoVirtualMachines(), VM), true);
+        results.basicBooleanTest(results.basicListHasString(repo
+                .getRepo(REPOID).getRepoTemplates(), TEMPLATE + ".raw"), true);
+        results.basicBooleanTest(results.basicListHasString(repo
+                .getRepo(REPOID).getRepoISOs(), ISO), true);
+        results.basicBooleanTest(results.basicListHasString(repo
+                .getRepo(REPOID).getRepoISOs(), VM), false);
+    }
+
+    @Test
+    public void testDiscoverRepoDb() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(this.REPODBDISCOVERXML));
+        repo.discoverRepoDb();
+        results.basicStringTest(repo.getRepoDb(REPOID).getUuid(), REPOID);
+        results.basicStringTest(repo.getRepoDb(REPOID).getAlias(), REPOALIAS);
+        results.basicStringTest(repo.getRepoDb(REPOID).getVersion(),
+                REPOVERSION);
+        results.basicStringTest(repo.getRepoDb(REPOID).getManagerUuid(), MGRID);
+        results.basicStringTest(repo.getRepoDb(REPOID).getMountPoint(),
+                LOCALMOUNT);
+        results.basicStringTest(repo.getRepoDb(REPOID).getFsLocation(),
+                REMOTENFS);
+        results.basicStringTest(repo.getRepoDb(REPOID).getStatus(), REPOSTATUS);
+        results.basicStringTest(repo.getRepoDb(REPOID).getFilesystemType(),
+                "nfs");
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/StoragePluginTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/StoragePluginTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/StoragePluginTest.java
new file mode 100644
index 0000000..b041508
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/StoragePluginTest.java
@@ -0,0 +1,358 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import static org.junit.Assert.assertNotNull;
+import java.io.File;
+
+import org.junit.Test;
+
+import com.cloud.hypervisor.ovm3.objects.StoragePlugin.FileProperties;
+import com.cloud.hypervisor.ovm3.objects.StoragePlugin.StorageDetails;
+
+public class StoragePluginTest {
+    ConnectionTest con = new ConnectionTest();
+    StoragePlugin sPt = new StoragePlugin(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+    String NFSHOST = "nfs-store-1";
+    String NFSPATH = "/volumes/cs-data/primary";
+    String NFSMNT = "/nfsmnt";
+    String FSPROPUUID = sPt.deDash(sPt.newUuid());
+    String FSMNTUUID = sPt.newUuid();
+    String POOLUUID = sPt.deDash(FSMNTUUID);
+    String FILE = "a.file";
+    Long SIZE = 2096898048L;
+    String STORAGEPLUGINXML = "<string>"
+            + "&lt;?xml version=\"1.0\" ?&gt;"
+            + "&lt;Discover_Storage_Plugins_Result&gt;"
+            + "&lt;storage_plugin_info_list&gt;"
+            + "&lt;storage_plugin_info plugin_impl_name=\"oracle.ocfs2.OCFS2.OCFS2Plugin\"&gt;"
+            + "&lt;fs_api_version&gt;1,2,7&lt;/fs_api_version&gt;"
+            + "&lt;generic_plugin&gt;False&lt;/generic_plugin&gt;"
+            + "&lt;plugin_version&gt;0.1.0-38&lt;/plugin_version&gt;"
+            + "&lt;filesys_type&gt;LocalFS&lt;/filesys_type&gt;"
+            + "&lt;extended_api_version&gt;None&lt;/extended_api_version&gt;"
+            + "&lt;plugin_desc&gt;Oracle OCFS2 File system Storage Connect Plugin&lt;/plugin_desc&gt;"
+            + "&lt;cluster_required&gt;True&lt;/cluster_required&gt;"
+            + "&lt;plugin_name&gt;Oracle OCFS2 File system&lt;/plugin_name&gt;"
+            + "&lt;fs_extra_info_help&gt;None&lt;/fs_extra_info_help&gt;"
+            + "&lt;required_api_vers&gt;1,2,7&lt;/required_api_vers&gt;"
+            + "&lt;file_extra_info_help&gt;None&lt;/file_extra_info_help&gt;"
+            + "&lt;ss_extra_info_help&gt;None&lt;/ss_extra_info_help&gt;"
+            + "&lt;filesys_name&gt;ocfs2&lt;/filesys_name&gt;"
+            + "&lt;vendor_name&gt;Oracle&lt;/vendor_name&gt;"
+            + "&lt;plugin_type&gt;ifs&lt;/plugin_type&gt;"
+            + "&lt;abilities&gt;"
+            + "&lt;resize_is_sync&gt;YES&lt;/resize_is_sync&gt;"
+            + "&lt;clone_is_sync&gt;YES&lt;/clone_is_sync&gt;"
+            + "&lt;access_control&gt;NO&lt;/access_control&gt;"
+            + "&lt;custom_clone_name&gt;YES&lt;/custom_clone_name&gt;"
+            + "&lt;require_storage_name&gt;NO&lt;/require_storage_name&gt;"
+            + "&lt;backing_device_type&gt;DEVICE_SINGLE&lt;/backing_device_type&gt;"
+            + "&lt;splitclone_while_open&gt;NO&lt;/splitclone_while_open&gt;"
+            + "&lt;custom_snap_name&gt;YES&lt;/custom_snap_name&gt;"
+            + "&lt;snapshot&gt;ONLINE&lt;/snapshot&gt;"
+            + "&lt;splitclone&gt;UNSUPPORTED&lt;/splitclone&gt;"
+            + "&lt;snap_is_sync&gt;YES&lt;/snap_is_sync&gt;"
+            + "&lt;snapclone&gt;ONLINE&lt;/snapclone&gt;"
+            + "&lt;splitclone_is_sync&gt;NO&lt;/splitclone_is_sync&gt;"
+            + "&lt;clone&gt;ONLINE&lt;/clone&gt;"
+            + "&lt;resize&gt;ONLINE&lt;/resize&gt;"
+            + "&lt;snapclone_is_sync&gt;YES&lt;/snapclone_is_sync&gt;"
+            + "&lt;/abilities&gt;"
+            + "&lt;/storage_plugin_info&gt;"
+            + "&lt;storage_plugin_info plugin_impl_name=\"oracle.generic.SCSIPlugin.GenericPlugin\"&gt;"
+            + "&lt;storage_types&gt;SAN,iSCSI&lt;/storage_types&gt;"
+            + "&lt;generic_plugin&gt;True&lt;/generic_plugin&gt;"
+            + "&lt;plugin_version&gt;1.1.0&lt;/plugin_version&gt;"
+            + "&lt;extended_api_version&gt;1,2,9&lt;/extended_api_version&gt;"
+            + "&lt;plugin_desc&gt;Oracle Storage Connect Plugin for Generic FC and iSCSI&lt;/plugin_desc&gt;"
+            + "&lt;plugin_name&gt;Oracle Generic SCSI Plugin&lt;/plugin_name&gt;"
+            + "&lt;sa_api_version&gt;1,2,7&lt;/sa_api_version&gt;"
+            + "&lt;required_api_vers&gt;1,2,7&lt;/required_api_vers&gt;"
+            + "&lt;ss_extra_info_help&gt;None&lt;/ss_extra_info_help&gt;"
+            + "&lt;se_extra_info_help&gt;None&lt;/se_extra_info_help&gt;"
+            + "&lt;vendor_name&gt;Oracle&lt;/vendor_name&gt;"
+            + "&lt;plugin_type&gt;isa&lt;/plugin_type&gt;"
+            + "&lt;abilities&gt;"
+            + "&lt;resize_is_sync&gt;UNSUPPORTED&lt;/resize_is_sync&gt;"
+            + "&lt;clone_is_sync&gt;UNSUPPORTED&lt;/clone_is_sync&gt;"
+            + "&lt;access_control&gt;NO&lt;/access_control&gt;"
+            + "&lt;custom_clone_name&gt;UNSUPPORTED&lt;/custom_clone_name&gt;"
+            + "&lt;require_storage_name&gt;UNSUPPORTED&lt;/require_storage_name&gt;"
+            + "&lt;custom_snap_name&gt;UNSUPPORTED&lt;/custom_snap_name&gt;"
+            + "&lt;snapshot&gt;UNSUPPORTED&lt;/snapshot&gt;"
+            + "&lt;splitclone&gt;UNSUPPORTED&lt;/splitclone&gt;"
+            + "&lt;snap_is_sync&gt;UNSUPPORTED&lt;/snap_is_sync&gt;"
+            + "&lt;snapclone&gt;UNSUPPORTED&lt;/snapclone&gt;"
+            + "&lt;splitclone_is_sync&gt;UNSUPPORTED&lt;/splitclone_is_sync&gt;"
+            + "&lt;clone&gt;UNSUPPORTED&lt;/clone&gt;"
+            + "&lt;resize&gt;UNSUPPORTED&lt;/resize&gt;"
+            + "&lt;snapclone_is_sync&gt;UNSUPPORTED&lt;/snapclone_is_sync&gt;"
+            + "&lt;/abilities&gt;"
+            + "&lt;/storage_plugin_info&gt;"
+            + "&lt;storage_plugin_info plugin_impl_name=\"oracle.generic.NFSPlugin.GenericNFSPlugin\"&gt;"
+            + "&lt;fs_api_version&gt;1,2,7&lt;/fs_api_version&gt;"
+            + "&lt;generic_plugin&gt;True&lt;/generic_plugin&gt;"
+            + "&lt;plugin_version&gt;1.1.0&lt;/plugin_version&gt;"
+            + "&lt;filesys_type&gt;NetworkFS&lt;/filesys_type&gt;"
+            + "&lt;extended_api_version&gt;None&lt;/extended_api_version&gt;"
+            + "&lt;plugin_desc&gt;Oracle Generic Network File System Storage Connect Plugin&lt;/plugin_desc&gt;"
+            + "&lt;cluster_required&gt;False&lt;/cluster_required&gt;"
+            + "&lt;plugin_name&gt;Oracle Generic Network File System&lt;/plugin_name&gt;"
+            + "&lt;fs_extra_info_help&gt;None&lt;/fs_extra_info_help&gt;"
+            + "&lt;required_api_vers&gt;1,2,7&lt;/required_api_vers&gt;"
+            + "&lt;file_extra_info_help&gt;None&lt;/file_extra_info_help&gt;"
+            + "&lt;ss_extra_info_help&gt;None&lt;/ss_extra_info_help&gt;"
+            + "&lt;filesys_name&gt;NFS&lt;/filesys_name&gt;"
+            + "&lt;vendor_name&gt;Oracle&lt;/vendor_name&gt;"
+            + "&lt;plugin_type&gt;ifs&lt;/plugin_type&gt;"
+            + "&lt;abilities&gt;"
+            + "&lt;resize_is_sync&gt;UNSUPPORTED&lt;/resize_is_sync&gt;"
+            + "&lt;clone_is_sync&gt;UNSUPPORTED&lt;/clone_is_sync&gt;"
+            + "&lt;access_control&gt;NO&lt;/access_control&gt;"
+            + "&lt;custom_clone_name&gt;UNSUPPORTED&lt;/custom_clone_name&gt;"
+            + "&lt;require_storage_name&gt;NO&lt;/require_storage_name&gt;"
+            + "&lt;backing_device_type&gt;UNSUPPORTED&lt;/backing_device_type&gt;"
+            + "&lt;splitclone_while_open&gt;UNSUPPORTED&lt;/splitclone_while_open&gt;"
+            + "&lt;custom_snap_name&gt;UNSUPPORTED&lt;/custom_snap_name&gt;"
+            + "&lt;snapshot&gt;UNSUPPORTED&lt;/snapshot&gt;"
+            + "&lt;splitclone&gt;UNSUPPORTED&lt;/splitclone&gt;"
+            + "&lt;snap_is_sync&gt;UNSUPPORTED&lt;/snap_is_sync&gt;"
+            + "&lt;snapclone&gt;UNSUPPORTED&lt;/snapclone&gt;"
+            + "&lt;splitclone_is_sync&gt;UNSUPPORTED&lt;/splitclone_is_sync&gt;"
+            + "&lt;clone&gt;UNSUPPORTED&lt;/clone&gt;"
+            + "&lt;resize&gt;UNSUPPORTED&lt;/resize&gt;"
+            + "&lt;snapclone_is_sync&gt;UNSUPPORTED&lt;/snapclone_is_sync&gt;"
+            + "&lt;/abilities&gt;" + "&lt;/storage_plugin_info&gt;"
+            + "&lt;/storage_plugin_info_list&gt;"
+            + "&lt;/Discover_Storage_Plugins_Result&gt;" + "</string>";
+    String NFSMOUNTRESPONSEXML = "<struct>" + "<member>"
+            + "<name>status</name>" + "<value><string></string></value>"
+            + "</member>" + "<member>" + "<name>uuid</name>"
+            + "<value><string>"
+            + FSPROPUUID
+            + "</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>ss_uuid</name>"
+            + "<value><string>"
+            + FSMNTUUID
+            + "</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>size</name>"
+            + "<value><string>263166853120</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>free_sz</name>"
+            + "<value><string>259377299456</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>state</name>"
+            + "<value><string>1</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>mount_options</name>"
+            + "<value><array><data>"
+            + "</data></array></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>access_grp_names</name>"
+            + "<value><array><data>"
+            + "</data></array></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>access_path</name>"
+            + "<value><string>"
+            + NFSHOST
+            + ":"
+            + NFSPATH
+            + "</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>name</name>"
+            + "<value><string>nfs:"
+            + NFSPATH
+            + "</string></value>" + "</member>" + "</struct>";
+    public String getNfsMountResponseXml() {
+        return NFSMOUNTRESPONSEXML;
+    }
+
+    public String getNfsFileSystemInfo() {
+        return NFSFILESYSTEMINFO;
+    }
+    public String getFileCreateXml() {
+        return FILECREATEXML;
+    }
+    public Long getFileSize() {
+        return SIZE;
+    }
+    public String getPoolUuid() {
+        return POOLUUID;
+    }
+    public String getFileName() {
+        return FILE;
+    }
+    String NFSFILESYSTEMINFO = NFSMOUNTRESPONSEXML;
+    String FILECREATEXML = "<struct>" + "<member>" + "<name>fr_type</name>"
+            + "<value><string>File</string></value>" + "</member>" + "<member>"
+            + "<name>ondisk_sz</name>" + "<value><string>0</string></value>"
+            + "</member>" + "<member>" + "<name>fs_uuid</name>"
+            + "<value><string>" + FSMNTUUID + "</string></value>" + "</member>"
+            + "<member>" + "<name>file_path</name>"
+            + "<value><string>/OVS/Repositories/" + POOLUUID + "/VirtualDisks/"
+            + FILE + "</string></value>" + "</member>" + "<member>"
+            + "<name>file_sz</name>" + "<value><string>" + SIZE
+            + "</string></value>" + "</member>" + "</struct>";
+
+    @Test
+    public void testNFSStorageMountCreation() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(NFSMOUNTRESPONSEXML));
+        StorageDetails sd = sPt.storagePluginMountNFS(NFSHOST, NFSPATH,
+                FSMNTUUID, NFSMNT);
+        con.setResult(results.simpleResponseWrapWrapper(NFSMOUNTRESPONSEXML));
+        NFSMNT = NFSMNT + File.separator + FSMNTUUID;
+        sd = sPt.storagePluginMountNFS(NFSHOST, NFSPATH, FSMNTUUID, NFSMNT);
+        results.basicLongTest(Long.valueOf(sd.getSize()), 263166853120L);
+        results.basicLongTest(Long.valueOf(sd.getFreeSize()), 259377299456L);
+        results.basicStringTest(sd.getName(), "nfs:" + NFSPATH);
+        results.basicStringTest(sd.getUuid(), FSPROPUUID);
+        results.basicStringTest(sd.getDetailsRelationalUuid(),FSMNTUUID);
+    }
+
+    @Test
+    public void testNFSStorageUnmount() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(sPt.storagePluginUnmountNFS(NFSHOST, NFSPATH, FSMNTUUID, NFSMNT));
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testStoragePluginIncorrectSsUuid() throws Ovm3ResourceException {
+        sPt.getStorageDetails().setDetailsRelationalUuid(FSMNTUUID);
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testStoragePluginIncorrectMntUuid()
+            throws Ovm3ResourceException {
+        sPt.getStorageDetails().setUuid(FSPROPUUID);
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testStoragePluginIncorrectUuid() throws Ovm3ResourceException {
+        sPt.getStorageServer().setUuid(FSMNTUUID);
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testStoragePluginNFSmountInvalidUuid()
+            throws Ovm3ResourceException {
+        NFSMOUNTRESPONSEXML = NFSMOUNTRESPONSEXML.replaceAll(FSPROPUUID,
+                sPt.deDash(FSMNTUUID));
+        con.setResult(results.simpleResponseWrapWrapper(NFSMOUNTRESPONSEXML));
+        assertNotNull(sPt.storagePluginMountNFS(NFSHOST, NFSPATH,
+                FSPROPUUID, NFSMNT));
+    }
+
+    @Test
+    public void testStorageFileCreation() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(FILECREATEXML));
+        FileProperties file = sPt.storagePluginCreate(FSMNTUUID, NFSHOST, FILE,
+                SIZE, false);
+        file.getOnDiskSize();
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testStorageFileCreationFileExistS()
+            throws Ovm3ResourceException {
+        con.setResult(results
+                .errorResponseWrap("exceptions OSError:[Errno.17] File exists "
+                        + FILE));
+        FileProperties file = sPt.storagePluginCreate(FSMNTUUID, NFSHOST, FILE,
+                SIZE, false);
+        file.getSize();
+    }
+
+    @Test
+    public void testStorageFileInfo() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(FILECREATEXML));
+        FileProperties file = sPt.storagePluginGetFileInfo(FSMNTUUID, NFSHOST,
+                FILE);
+        file.getName();
+        file.getUuid();
+        file.getType();
+        file.getSize();
+    }
+
+    @Test
+    public void testDiscoverStoragePlugins() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(STORAGEPLUGINXML));
+        for (String plugin : sPt.discoverStoragePlugins()) {
+            sPt.checkStoragePluginProperties(plugin, "plugin_version");
+            sPt.checkStoragePluginAbility(plugin, "snapshot");
+        }
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testCheckStoragePluginBogusPlugin()
+            throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(STORAGEPLUGINXML));
+        sPt.checkStoragePluginProperties("bogus", "plugin_version");
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testCheckStoragePluginBogusProperty()
+            throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(STORAGEPLUGINXML));
+        sPt.checkStoragePluginAbility(sPt.getPluginType(), "blabla");
+    }
+
+    @Test
+    public void testMounts() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(NFSMOUNTRESPONSEXML));
+        sPt.storagePluginListFs(NFSHOST);
+    }
+
+    @Test
+    public void testGetFileSystemInfo() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(NFSMOUNTRESPONSEXML));
+        sPt.storagePluginGetFileSystemInfo(FSPROPUUID, FSMNTUUID, NFSHOST,
+                NFSPATH);
+    }
+
+    @Test
+    public void testStoragepluginDestroy() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        sPt.storagePluginDestroy(FSMNTUUID, FILE);
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testStoragepluginDestroyWrongUUID()
+            throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        sPt.storagePluginDestroy(FSPROPUUID, FILE);
+    }
+
+    @Test
+    public void testStoragePluginSwitch() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(STORAGEPLUGINXML));
+        sPt.setISCSI();
+        sPt.setNFS();
+        sPt.setOCFS2();
+    }
+}


[12/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
hypervisors: add OVM3 plugin that supports OVM 3.2.1/3.3.x

This is a plugin that puts in ovm3 support ranging from 3.3.1 to 3.3.2. Basic
functionality is in here, advanced networking etc..

Snapshots only work when a VM is stopped now due to the semantics of OVM's raw
image implementation (so snapshots should work on a storage level underneath the
hypervisor shrug)

This closes #113

Signed-off-by: Rohit Yadav <ro...@shapeblue.com>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/c27c6943
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/c27c6943
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/c27c6943

Branch: refs/heads/master
Commit: c27c69438ba23386bac7ae4dd651b1d809811157
Parents: ff9ab5c
Author: Funs <fu...@barred.org>
Authored: Wed Mar 11 18:06:18 2015 +0100
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Thu Mar 12 11:33:42 2015 +0530

----------------------------------------------------------------------
 api/src/com/cloud/hypervisor/Hypervisor.java    |    5 +
 api/src/com/cloud/network/NetworkService.java   |    4 +-
 .../network/PhysicalNetworkTrafficType.java     |    2 +
 .../org/apache/cloudstack/api/ApiConstants.java |    4 +
 .../command/admin/cluster/AddClusterCmd.java    |   18 +-
 .../command/admin/usage/AddTrafficTypeCmd.java  |   11 +-
 .../admin/usage/UpdateTrafficTypeCmd.java       |   11 +-
 .../api/response/ClusterResponse.java           |   12 +
 .../api/response/TrafficTypeResponse.java       |   12 +
 .../classes/resources/messages.properties       |    4 +
 client/pom.xml                                  |    5 +
 .../core/spring-core-registry-core-context.xml  |    2 +-
 .../dao/PhysicalNetworkTrafficTypeDaoImpl.java  |    9 +
 .../dao/PhysicalNetworkTrafficTypeVO.java       |   14 +-
 plugins/hypervisors/ovm3/.gitignore             |    1 +
 plugins/hypervisors/ovm3/pom.xml                |   74 +
 .../hypervisors/ovm3/sonar-project.properties   |   19 +
 .../java/com/cloud/ha/Ovm3Investigator.java     |   86 +
 .../ovm3/objects/CloudstackPlugin.java          |  186 +++
 .../cloud/hypervisor/ovm3/objects/Cluster.java  |  127 ++
 .../cloud/hypervisor/ovm3/objects/Common.java   |   61 +
 .../hypervisor/ovm3/objects/Connection.java     |  196 +++
 .../cloud/hypervisor/ovm3/objects/Linux.java    |  457 ++++++
 .../cloud/hypervisor/ovm3/objects/Network.java  |  331 ++++
 .../com/cloud/hypervisor/ovm3/objects/Ntp.java  |  120 ++
 .../ovm3/objects/Ovm3ResourceException.java     |   40 +
 .../hypervisor/ovm3/objects/OvmObject.java      |  247 +++
 .../com/cloud/hypervisor/ovm3/objects/Pool.java |  272 ++++
 .../hypervisor/ovm3/objects/PoolOCFS2.java      |  143 ++
 .../cloud/hypervisor/ovm3/objects/Remote.java   |   34 +
 .../hypervisor/ovm3/objects/Repository.java     |  334 ++++
 .../hypervisor/ovm3/objects/RpcTypeFactory.java |   88 ++
 .../hypervisor/ovm3/objects/StoragePlugin.java  |  882 +++++++++++
 .../com/cloud/hypervisor/ovm3/objects/Xen.java  |  996 ++++++++++++
 .../ovm3/resources/Ovm3Discoverer.java          |  406 +++++
 .../ovm3/resources/Ovm3FenceBuilder.java        |  120 ++
 .../ovm3/resources/Ovm3HypervisorGuru.java      |  117 ++
 .../ovm3/resources/Ovm3HypervisorResource.java  |  596 +++++++
 .../ovm3/resources/Ovm3StorageProcessor.java    |  835 ++++++++++
 .../resources/Ovm3VirtualRoutingResource.java   |  183 +++
 .../resources/helpers/Ovm3Configuration.java    |  466 ++++++
 .../helpers/Ovm3HypervisorNetwork.java          |  251 +++
 .../helpers/Ovm3HypervisorSupport.java          |  752 +++++++++
 .../ovm3/resources/helpers/Ovm3StoragePool.java |  749 +++++++++
 .../helpers/Ovm3VirtualRoutingSupport.java      |  202 +++
 .../resources/helpers/Ovm3VmGuestTypes.java     |   98 ++
 .../ovm3/resources/helpers/Ovm3VmSupport.java   |  475 ++++++
 .../cloudstack/ovm3-compute/module.properties   |   18 +
 .../spring-ovm3-compute-context.xml             |   41 +
 .../ovm3-discoverer/module.properties           |   18 +
 .../spring-ovm3-discoverer-context.xml          |   34 +
 .../ovm3/objects/CloudStackPluginTest.java      |  323 ++++
 .../hypervisor/ovm3/objects/CommonTest.java     |   54 +
 .../hypervisor/ovm3/objects/ConnectionTest.java |  164 ++
 .../hypervisor/ovm3/objects/LinuxTest.java      |  643 ++++++++
 .../hypervisor/ovm3/objects/NetworkTest.java    |  346 ++++
 .../cloud/hypervisor/ovm3/objects/NtpTest.java  |   98 ++
 .../hypervisor/ovm3/objects/PoolOCFS2Test.java  |  111 ++
 .../cloud/hypervisor/ovm3/objects/PoolTest.java |  181 +++
 .../hypervisor/ovm3/objects/RemoteTest.java     |   37 +
 .../hypervisor/ovm3/objects/RepositoryTest.java |  183 +++
 .../ovm3/objects/StoragePluginTest.java         |  358 +++++
 .../cloud/hypervisor/ovm3/objects/XenTest.java  | 1491 ++++++++++++++++++
 .../ovm3/objects/XmlTestResultTest.java         |  135 ++
 .../resources/Ovm3HypervisorResourceTest.java   |  368 +++++
 .../resources/Ovm3StorageProcessorTest.java     |  343 ++++
 .../Ovm3VirtualRoutingResourceTest.java         |  232 +++
 .../helpers/Ovm3ConfigurationTest.java          |  112 ++
 .../resources/helpers/Ovm3GuestTypesTest.java   |   34 +
 .../helpers/Ovm3HypervisorNetworkTest.java      |  110 ++
 .../helpers/Ovm3HypervisorSupportTest.java      |  281 ++++
 .../helpers/Ovm3VirtualRoutingSupportTest.java  |   71 +
 .../resources/helpers/Ovm3VmSupportTest.java    |  123 ++
 .../ovm3/support/Ovm3SupportTest.java           |  113 ++
 .../ovm3/src/test/resources/log4j.properties    |    8 +
 .../src/test/resources/scripts/clean_master.sh  |   43 +
 .../src/test/resources/scripts/clean_slave.sh   |   32 +
 .../resources/scripts/create_pool_cluster.py    |  271 ++++
 .../ovm3/src/test/resources/scripts/info.py     |  111 ++
 .../ovm3/src/test/resources/scripts/password.py |   57 +
 .../src/test/resources/scripts/repo_pool.py     |  186 +++
 .../src/test/resources/scripts/simple_pool.py   |  209 +++
 .../ovm3/src/test/resources/scripts/socat.sh    |    2 +
 .../ovm3/src/test/resources/scripts/tail.sh     |    2 +
 .../management/ManagementServerMock.java        |    6 +-
 plugins/pom.xml                                 |    1 +
 .../storage/secondary/cloud-install-sys-tmplt   |   13 +-
 scripts/vm/hypervisor/ovm3/cloudstack.py        |  588 +++++++
 scripts/vm/hypervisor/ovm3/storagehealth.py     |  259 +++
 server/src/com/cloud/configuration/Config.java  |   25 +-
 .../configuration/ConfigurationManagerImpl.java |    4 +-
 .../src/com/cloud/network/NetworkModelImpl.java |   13 +-
 .../com/cloud/network/NetworkServiceImpl.java   |    6 +-
 .../cloud/network/router/NetworkHelperImpl.java |    1 +
 .../router/VirtualNetworkApplianceManager.java  |    3 +
 .../com/cloud/network/vpc/VpcManagerImpl.java   |    1 +
 .../com/cloud/resource/ResourceManagerImpl.java |    7 +
 .../com/cloud/server/ManagementServerImpl.java  |    8 +-
 .../storage/listener/StoragePoolMonitor.java    |    2 +-
 server/src/com/cloud/vm/UserVmManagerImpl.java  |    7 +-
 .../com/cloud/vpc/MockNetworkManagerImpl.java   |    4 +-
 setup/db/db/schema-450to460.sql                 |   25 +
 tools/appliance/build.sh                        |    2 +-
 ui/dictionary2.jsp                              |    5 +-
 ui/scripts/docs.js                              |   12 +
 ui/scripts/system.js                            |  154 +-
 ui/scripts/zoneWizard.js                        |   81 +
 107 files changed, 18183 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/api/src/com/cloud/hypervisor/Hypervisor.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/hypervisor/Hypervisor.java b/api/src/com/cloud/hypervisor/Hypervisor.java
index f8b98cf..50af968 100644
--- a/api/src/com/cloud/hypervisor/Hypervisor.java
+++ b/api/src/com/cloud/hypervisor/Hypervisor.java
@@ -31,6 +31,7 @@ public class Hypervisor {
         BareMetal,
         Simulator,
         Ovm,
+        Ovm3,
         LXC,
 
         Any; /*If you don't care about the hypervisor type*/
@@ -61,6 +62,8 @@ public class Hypervisor {
                 return HypervisorType.LXC;
             } else if (hypervisor.equalsIgnoreCase("Any")) {
                 return HypervisorType.Any;
+            } else if (hypervisor.equalsIgnoreCase("Ovm3")) {
+                return HypervisorType.Ovm3;
             } else {
                 return HypervisorType.None;
             }
@@ -81,6 +84,8 @@ public class Hypervisor {
                 return ImageFormat.OVA;
             } else if (hyperType == HypervisorType.Ovm) {
                 return ImageFormat.RAW;
+            } else if (hyperType == HypervisorType.Ovm3) {
+                return ImageFormat.RAW;
             } else {
                 return null;
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/api/src/com/cloud/network/NetworkService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java
index 18b59e9..c1b68eb 100644
--- a/api/src/com/cloud/network/NetworkService.java
+++ b/api/src/com/cloud/network/NetworkService.java
@@ -111,11 +111,11 @@ public interface NetworkService {
     long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType);
 
     PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
-        String simulatorLabel, String vlan, String hypervLabel);
+        String simulatorLabel, String vlan, String hypervLabel, String ovm3label);
 
     PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id);
 
-    PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel);
+    PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3label);
 
     boolean deletePhysicalNetworkTrafficType(Long id);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/api/src/com/cloud/network/PhysicalNetworkTrafficType.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/PhysicalNetworkTrafficType.java b/api/src/com/cloud/network/PhysicalNetworkTrafficType.java
index a50aa37..9676bad 100644
--- a/api/src/com/cloud/network/PhysicalNetworkTrafficType.java
+++ b/api/src/com/cloud/network/PhysicalNetworkTrafficType.java
@@ -39,4 +39,6 @@ public interface PhysicalNetworkTrafficType extends InternalIdentity, Identity {
     String getSimulatorNetworkLabel();
 
     String getHypervNetworkLabel();
+
+    String getOvm3NetworkLabel();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index b6aed6f..72b5e64 100644
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -384,6 +384,7 @@ public class ApiConstants {
     public static final String KVM_NETWORK_LABEL = "kvmnetworklabel";
     public static final String VMWARE_NETWORK_LABEL = "vmwarenetworklabel";
     public static final String HYPERV_NETWORK_LABEL = "hypervnetworklabel";
+    public static final String OVM3_NETWORK_LABEL = "ovm3networklabel";
     public static final String NETWORK_SERVICE_PROVIDER_ID = "nspid";
     public static final String SERVICE_LIST = "servicelist";
     public static final String CAN_ENABLE_INDIVIDUAL_SERVICE = "canenableindividualservice";
@@ -614,6 +615,9 @@ public class ApiConstants {
     public static final String STRECHED_L2_SUBNET = "strechedl2subnet";
     public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans";
     public static final String PHYSICAL_SIZE = "physicalsize";
+    public static final String OVM3_POOL = "ovm3pool";
+    public static final String OVM3_CLUSTER = "ovm3cluster";
+    public static final String OVM3_VIP = "ovm3vip";
 
     public enum HostDetails {
         all, capacity, events, stats, min;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/api/src/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java b/api/src/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
index b9df18e..3d0d714 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/cluster/AddClusterCmd.java
@@ -66,7 +66,7 @@ public class AddClusterCmd extends BaseCmd {
     @Parameter(name = ApiConstants.HYPERVISOR,
                type = CommandType.STRING,
                required = true,
-               description = "hypervisor type of the cluster: XenServer,KVM,VMware,Hyperv,BareMetal,Simulator")
+               description = "hypervisor type of the cluster: XenServer,KVM,VMware,Hyperv,BareMetal,Simulator,Ovm3")
     private String hypervisor;
 
     @Parameter(name = ApiConstants.CLUSTER_TYPE, type = CommandType.STRING, required = true, description = "type of the cluster: CloudManaged, ExternalManaged")
@@ -108,6 +108,22 @@ public class AddClusterCmd extends BaseCmd {
                description = "Name of virtual switch used for public traffic in the cluster.  This would override zone wide traffic label setting.")
     private String vSwitchNamePublicTraffic;
 
+    @Parameter(name = ApiConstants.OVM3_POOL, type = CommandType.STRING, required = false, description = "Ovm3 native pooling enabled for cluster")
+    private String ovm3pool;
+    @Parameter(name = ApiConstants.OVM3_CLUSTER, type = CommandType.STRING, required = false, description = "Ovm3 native OCFS2 clustering enabled for cluster")
+    private String ovm3cluster;
+    @Parameter(name = ApiConstants.OVM3_VIP, type = CommandType.STRING, required = false,  description = "Ovm3 vip to use for pool (and cluster)")
+    private String ovm3vip;
+    public String getOvm3Pool() {
+         return ovm3pool;
+    }
+    public String getOvm3Cluster() {
+        return ovm3cluster;
+    }
+    public String getOvm3Vip() {
+        return ovm3vip;
+    }
+
     public String getVSwitchTypeGuestTraffic() {
         return vSwitchTypeGuestTraffic;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java b/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java
index 5f1188e..9e4254c 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java
@@ -75,6 +75,11 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd {
                description = "The network name label of the physical device dedicated to this traffic on a Hyperv host")
     private String hypervLabel;
 
+    @Parameter(name = ApiConstants.OVM3_NETWORK_LABEL,
+               type = CommandType.STRING,
+               description = "The network name of the physical device dedicated to this traffic on an OVM3 host")
+    private String ovm3Label;
+
     @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "The VLAN id to be used for Management traffic by VMware host")
     private String vlan;
 
@@ -115,6 +120,10 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd {
         return null;
     }
 
+    public String getOvm3Label() {
+        return ovm3Label;
+    }
+
     public void setVlan(String vlan) {
         this.vlan = vlan;
     }
@@ -162,7 +171,7 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd {
     public void create() throws ResourceAllocationException {
         PhysicalNetworkTrafficType result =
             _networkService.addTrafficTypeToPhysicalNetwork(getPhysicalNetworkId(), getTrafficType(), getIsolationMethod(), getXenLabel(), getKvmLabel(), getVmwareLabel(),
-                getSimulatorLabel(), getVlan(), getHypervLabel());
+                getSimulatorLabel(), getVlan(), getHypervLabel(), getOvm3Label());
         if (result != null) {
             setEntityId(result.getId());
             setEntityUuid(result.getUuid());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/api/src/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java b/api/src/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java
index 68a9431..6d0824c 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/usage/UpdateTrafficTypeCmd.java
@@ -65,6 +65,11 @@ public class UpdateTrafficTypeCmd extends BaseAsyncCmd {
                description = "The network name label of the physical device dedicated to this traffic on a Hyperv host")
     private String hypervLabel;
 
+    @Parameter(name = ApiConstants.OVM3_NETWORK_LABEL,
+               type = CommandType.STRING,
+               description = "The network name of the physical device dedicated to this traffic on an OVM3 host")
+    private String ovm3Label;
+
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -89,6 +94,10 @@ public class UpdateTrafficTypeCmd extends BaseAsyncCmd {
         return hypervLabel;
     }
 
+    public String getOvm3Label() {
+        return ovm3Label;
+    }
+
     /////////////////////////////////////////////////////
     /////////////// API Implementation///////////////////
     /////////////////////////////////////////////////////
@@ -105,7 +114,7 @@ public class UpdateTrafficTypeCmd extends BaseAsyncCmd {
 
     @Override
     public void execute() {
-        PhysicalNetworkTrafficType result = _networkService.updatePhysicalNetworkTrafficType(getId(), getXenLabel(), getKvmLabel(), getVmwareLabel(), getHypervLabel());
+        PhysicalNetworkTrafficType result = _networkService.updatePhysicalNetworkTrafficType(getId(), getXenLabel(), getKvmLabel(), getVmwareLabel(), getHypervLabel(), getOvm3Label());
         if (result != null) {
             TrafficTypeResponse response = _responseGenerator.createTrafficTypeResponse(result);
             response.setResponseName(getCommandName());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/api/src/org/apache/cloudstack/api/response/ClusterResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java
index 0890309..df01e09 100644
--- a/api/src/org/apache/cloudstack/api/response/ClusterResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/ClusterResponse.java
@@ -82,6 +82,10 @@ public class ClusterResponse extends BaseResponse {
     @Param(description = "The memory overcommit ratio of the cluster")
     private String memoryovercommitratio;
 
+    @SerializedName("ovm3vip")
+    @Param(description = "Ovm3 VIP to use for pooling and/or clustering")
+    private String ovm3vip;
+
     public String getId() {
         return id;
     }
@@ -185,4 +189,12 @@ public class ClusterResponse extends BaseResponse {
     public String getMemoryOvercommitRatio() {
         return memoryovercommitratio;
     }
+
+    public void setOvm3Vip(String ovm3vip) {
+        this.ovm3vip = ovm3vip;
+    }
+
+    public String getOvm3Vip() {
+        return ovm3vip;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/api/src/org/apache/cloudstack/api/response/TrafficTypeResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/TrafficTypeResponse.java b/api/src/org/apache/cloudstack/api/response/TrafficTypeResponse.java
index 84ed2e6..9a79b07 100644
--- a/api/src/org/apache/cloudstack/api/response/TrafficTypeResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/TrafficTypeResponse.java
@@ -56,6 +56,10 @@ public class TrafficTypeResponse extends BaseResponse {
     @Param(description = "The network name label of the physical device dedicated to this traffic on a HyperV host")
     private String hypervNetworkLabel;
 
+    @SerializedName(ApiConstants.OVM3_NETWORK_LABEL)
+    @Param(description = "The network name of the physical device dedicated to this traffic on an OVM3 host")
+    private String ovm3NetworkLabel;
+
     @Override
     public String getObjectId() {
         return this.id;
@@ -116,4 +120,12 @@ public class TrafficTypeResponse extends BaseResponse {
     public String getVmwareLabel() {
         return vmwareNetworkLabel;
     }
+
+    public String getOvm3Label() {
+        return ovm3NetworkLabel;
+    }
+
+    public void setOvm3Label(String ovm3Label) {
+        this.ovm3NetworkLabel = ovm3Label;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/client/WEB-INF/classes/resources/messages.properties
----------------------------------------------------------------------
diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index 553bfc6..76cbdf7 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -387,6 +387,7 @@ label.affinity.group=Affinity Group
 label.affinity.groups=Affinity Groups
 label.affinity=Affinity
 label.agent.password=Agent Password
+label.agent.port=Agent Port
 label.agent.username=Agent Username
 label.agree=Agree
 label.alert=Alert
@@ -924,6 +925,9 @@ label.optional=Optional
 label.order=Order
 label.os.preference=OS Preference
 label.os.type=OS Type
+label.ovm3.vip=Master Vip IP
+label.ovm3.pool=Native Pooling
+label.ovm3.cluster=Native Clustering
 label.owned.public.ips=Owned Public IP Addresses
 label.owner.account=Owner Account
 label.owner.domain=Owner Domain

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index 59137ca..af6b12d 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -182,6 +182,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-hypervisor-ovm3</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-plugin-hypervisor-kvm</artifactId>
       <version>${project.version}</version>
       <exclusions>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml
----------------------------------------------------------------------
diff --git a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml
index d967540..5e2dc7b 100644
--- a/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml
+++ b/core/resources/META-INF/cloudstack/core/spring-core-registry-core-context.xml
@@ -68,7 +68,7 @@
         class="org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry">
         <property name="orderConfigKey" value="ha.investigators.order" />
         <property name="orderConfigDefault"
-            value="SimpleInvestigator,XenServerInvestigator,KVMInvestigator,HypervInvestigator,VMwareInvestigator,PingInvestigator,ManagementIPSysVMInvestigator" />
+            value="SimpleInvestigator,XenServerInvestigator,KVMInvestigator,HypervInvestigator,VMwareInvestigator,PingInvestigator,ManagementIPSysVMInvestigator,Ovm3Investigator" />
         <property name="excludeKey" value="ha.investigators.exclude" />
     </bean>
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java
index 4e8e017..5f2609d 100644
--- a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java
+++ b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeDaoImpl.java
@@ -43,6 +43,7 @@ public class PhysicalNetworkTrafficTypeDaoImpl extends GenericDaoBase<PhysicalNe
     final GenericSearchBuilder<PhysicalNetworkTrafficTypeVO, String> simulatorAllFieldsSearch;
     final GenericSearchBuilder<PhysicalNetworkTrafficTypeVO, String> ovmAllFieldsSearch;
     final GenericSearchBuilder<PhysicalNetworkTrafficTypeVO, String> hypervAllFieldsSearch;
+    final GenericSearchBuilder<PhysicalNetworkTrafficTypeVO, String> ovm3AllFieldsSearch;
 
     protected PhysicalNetworkTrafficTypeDaoImpl() {
         super();
@@ -86,6 +87,12 @@ public class PhysicalNetworkTrafficTypeDaoImpl extends GenericDaoBase<PhysicalNe
         ovmAllFieldsSearch.and("trafficType", ovmAllFieldsSearch.entity().getTrafficType(), Op.EQ);
         ovmAllFieldsSearch.selectFields(ovmAllFieldsSearch.entity().getSimulatorNetworkLabel());
         ovmAllFieldsSearch.done();
+
+        ovm3AllFieldsSearch = createSearchBuilder(String.class);
+        ovm3AllFieldsSearch.and("physicalNetworkId", ovm3AllFieldsSearch.entity().getPhysicalNetworkId(), Op.EQ);
+        ovm3AllFieldsSearch.and("trafficType", ovm3AllFieldsSearch.entity().getTrafficType(), Op.EQ);
+        ovm3AllFieldsSearch.selectFields(ovm3AllFieldsSearch.entity().getSimulatorNetworkLabel());
+        ovm3AllFieldsSearch.done();
     }
 
     @Override
@@ -124,6 +131,8 @@ public class PhysicalNetworkTrafficTypeDaoImpl extends GenericDaoBase<PhysicalNe
             return null;
         } else if (hType == HypervisorType.Hyperv) {
             sc = hypervAllFieldsSearch.create();
+        } else if (hType == HypervisorType.Ovm3) {
+            sc = hypervAllFieldsSearch.create();
         } else {
             assert (false) : "We don't handle this hypervisor type";
             return null;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java
index 3fe9881..a5eff2a 100644
--- a/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java
+++ b/engine/schema/src/com/cloud/network/dao/PhysicalNetworkTrafficTypeVO.java
@@ -63,6 +63,9 @@ public class PhysicalNetworkTrafficTypeVO implements PhysicalNetworkTrafficType
     @Column(name = "hyperv_network_label")
     private String hypervNetworkLabel;
 
+    @Column(name = "ovm_network_label")
+    private String ovm3NetworkLabel;
+
     @Column(name = "vlan")
     private String vlan;
 
@@ -70,7 +73,7 @@ public class PhysicalNetworkTrafficTypeVO implements PhysicalNetworkTrafficType
     }
 
     public PhysicalNetworkTrafficTypeVO(long physicalNetworkId, TrafficType trafficType, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel,
-            String vlan, String hypervLabel) {
+            String vlan, String hypervLabel, String ovm3Label) {
         this.physicalNetworkId = physicalNetworkId;
         this.trafficType = trafficType;
         this.xenNetworkLabel = xenLabel;
@@ -78,6 +81,7 @@ public class PhysicalNetworkTrafficTypeVO implements PhysicalNetworkTrafficType
         this.vmwareNetworkLabel = vmwareLabel;
         this.simulatorNetworkLabel = simulatorLabel;
         this.hypervNetworkLabel = hypervLabel;
+        this.ovm3NetworkLabel = ovm3Label;
         this.setVlan(vlan);
         this.uuid = UUID.randomUUID().toString();
     }
@@ -160,4 +164,12 @@ public class PhysicalNetworkTrafficTypeVO implements PhysicalNetworkTrafficType
         return hypervNetworkLabel;
     }
 
+    public void setOvm3NetworkLabel(String ovm3NetworkLabel) {
+        this.ovm3NetworkLabel = ovm3NetworkLabel;
+    }
+
+    @Override
+    public String getOvm3NetworkLabel() {
+        return ovm3NetworkLabel;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/.gitignore
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/.gitignore b/plugins/hypervisors/ovm3/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/plugins/hypervisors/ovm3/.gitignore
@@ -0,0 +1 @@
+/bin/

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml
new file mode 100644
index 0000000..546e7e7
--- /dev/null
+++ b/plugins/hypervisors/ovm3/pom.xml
@@ -0,0 +1,74 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-plugin-hypervisor-ovm3</artifactId>
+  <name>Apache CloudStack Plugin - Hypervisor OracleVM3</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-plugins</artifactId>
+    <version>4.6.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+  <dependencies>
+<dependency>
+    <groupId>org.apache.xmlrpc</groupId>
+    <artifactId>xmlrpc-client</artifactId>
+    <version>3.1.3</version>
+</dependency>
+  </dependencies>
+   <build>
+    <sourceDirectory>${basedir}/src/main/java</sourceDirectory>
+    <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
+    <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
+    <outputDirectory>${basedir}/target/classes</outputDirectory>
+    <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
+    <resources>
+      <resource>
+        <directory>${basedir}/src/main/resources</directory>
+      </resource>
+    </resources>
+    <testResources>
+      <testResource>
+        <directory>${basedir}/src/test/resources</directory>
+      </testResource>
+    </testResources>
+  </build>
+  <profiles>
+    <profile>
+      <id>integration</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-failsafe-plugin</artifactId>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>integration-test</goal>
+                  <goal>verify</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/sonar-project.properties
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/sonar-project.properties b/plugins/hypervisors/ovm3/sonar-project.properties
new file mode 100644
index 0000000..fcc9184
--- /dev/null
+++ b/plugins/hypervisors/ovm3/sonar-project.properties
@@ -0,0 +1,19 @@
+# Required metadata
+sonar.projectKey=cloud-plugin-hypervisor-ovm3
+sonar.projectName=Ovm3 integration for CS
+sonar.projectVersion=1.0
+
+# Comma-separated paths to directories with sources (required)
+sonar.sources=src
+sonar.binaries=target/classes
+
+# Exclussions
+sonar.exclusions=**/*Test.java
+
+# Language
+sonar.language=java
+
+# Encoding of the source files
+sonar.sourceEncoding=UTF-8
+
+# sonar.doxygen.generateDocumentation=enable

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/ha/Ovm3Investigator.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/ha/Ovm3Investigator.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/ha/Ovm3Investigator.java
new file mode 100644
index 0000000..30fd42c
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/ha/Ovm3Investigator.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.ha;
+
+import java.util.List;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckOnHostCommand;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+
+@Local(value = Investigator.class)
+public class Ovm3Investigator extends AdapterBase implements Investigator {
+    private static final Logger LOGGER = Logger.getLogger(Ovm3Investigator.class);
+    @Inject
+    HostDao hostDao;
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    ResourceManager resourceMgr;
+
+    @Override
+    public Boolean isVmAlive(com.cloud.vm.VirtualMachine vm, Host host) {
+        LOGGER.debug("isVmAlive: " + vm.getHostName() + " on " + host.getName());
+        if (host.getHypervisorType() != Hypervisor.HypervisorType.Ovm3) {
+            return null;
+        }
+        Status status = isAgentAlive(host);
+        if (status == null) {
+            return false;
+        }
+        return status == Status.Up ? true : false;
+    }
+
+    @Override
+    public Status isAgentAlive(Host agent) {
+        LOGGER.debug("isAgentAlive: " + agent.getName());
+        if (agent.getHypervisorType() != Hypervisor.HypervisorType.Ovm3) {
+            return null;
+        }
+        CheckOnHostCommand cmd = new CheckOnHostCommand(agent);
+        List<HostVO> neighbors = resourceMgr.listHostsInClusterByStatus(agent.getClusterId(), Status.Up);
+        for (HostVO neighbor : neighbors) {
+            if (neighbor.getId() == agent.getId() || neighbor.getHypervisorType() != Hypervisor.HypervisorType.Ovm3) {
+                continue;
+            }
+            try {
+                Answer answer = agentMgr.easySend(neighbor.getId(), cmd);
+                if (answer != null) {
+                    return answer.getResult() ? Status.Down : Status.Up;
+                }
+            } catch (Exception e) {
+                LOGGER.error("Failed to send command to host: " + neighbor.getId(), e);
+            }
+        }
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/CloudstackPlugin.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/CloudstackPlugin.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/CloudstackPlugin.java
new file mode 100644
index 0000000..eab7e60
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/CloudstackPlugin.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+public class CloudstackPlugin extends OvmObject {
+    private static final Logger LOGGER = Logger
+            .getLogger(CloudstackPlugin.class);
+    private boolean checkstoragestarted = false;
+    public CloudstackPlugin(Connection c) {
+        setClient(c);
+    }
+
+    public String getVncPort(String vmName) throws Ovm3ResourceException {
+        return (String) callWrapper("get_vncport", vmName);
+    }
+
+    public boolean ovsUploadSshKey(String key, String content) throws Ovm3ResourceException{
+        return nullIsFalseCallWrapper("ovs_upload_ssh_key", key, content);
+    }
+
+    public boolean ovsUploadFile(String path, String file, String content) throws Ovm3ResourceException {
+        return nullIsFalseCallWrapper("ovs_upload_file", path, file, content);
+    }
+
+    public boolean ovsDomrUploadFile(String domr, String path, String file,
+            String content) throws Ovm3ResourceException {
+        return nullIsFalseCallWrapper("ovs_domr_upload_file", domr, path, file,
+                content);
+    }
+
+    public static class ReturnCode {
+        private Map<String, Object> returnCode = new HashMap<String, Object>() {
+            {
+                put("rc", null);
+                put("exit", null);
+                put("err", null);
+                put("out", null);
+            }
+        };
+        public ReturnCode() {
+        }
+
+        public void setValues(Map<String, String> m) {
+            returnCode.putAll(m);
+        }
+
+        public Boolean getRc() throws Ovm3ResourceException {
+            Object rc = returnCode.get("rc");
+            Long c = 1L;
+            if (rc instanceof Integer) {
+                c = new Long((Integer) rc);
+            } else if (rc instanceof Long) {
+                c = (Long) rc;
+            } else {
+                LOGGER.debug("Incorrect return code: " + rc);
+                return false;
+            }
+            returnCode.put("exit", c);
+            if (c != 0) {
+                return false;
+            }
+            return true;
+        }
+
+        public String getStdOut() {
+            return (String) returnCode.get("out");
+        }
+
+        public String getStdErr() {
+            return (String) returnCode.get("err");
+        }
+
+        public Integer getExit() {
+            if (returnCode.get("exit") == null) {
+                returnCode.put("exit", returnCode.get("rc"));
+            }
+            return ((Long) returnCode.get("exit")).intValue();
+        }
+    }
+
+    public ReturnCode domrExec(String ip, String cmd) throws Ovm3ResourceException {
+        ReturnCode rc = new ReturnCode();
+        rc.setValues((Map<String, String>) callWrapper("exec_domr", ip, cmd));
+        return rc;
+    }
+
+    /**
+     * Checks a tcp port of a host reachable from dom0
+     * @param ip
+     * @param port
+     * @param retries
+     * @param interval
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    public boolean dom0CheckPort(String ip, Integer port, Integer retries,
+            Integer interval) throws Ovm3ResourceException {
+        Boolean x = false;
+        /* should deduct the interval from the timeout and sleep on it */
+        Integer sleep = interval;
+        try {
+            while (!x && retries > 0) {
+                x = (Boolean) nullIsFalseCallWrapper("check_dom0_port", ip, port, interval);
+                retries--;
+                Thread.sleep(sleep * 1000);
+            }
+        } catch (Exception e) {
+            LOGGER.error("Dom0 port check failed: " + e);
+        }
+        return x;
+    }
+
+    public Map<String, String> ovsDom0Stats(String bridge) throws Ovm3ResourceException {
+        return (Map<String, String>) callWrapper(
+                "ovs_dom0_stats", bridge);
+    }
+
+    public Map<String, String> ovsDomUStats(String domain) throws Ovm3ResourceException {
+        return (Map<String, String>) callWrapper(
+                "ovs_domU_stats", domain);
+    }
+
+    public boolean domrCheckPort(String ip, Integer port) throws Ovm3ResourceException{
+        return (Boolean) callWrapper("check_domr_port", ip, port);
+    }
+
+    public boolean domrCheckSsh(String ip) throws Ovm3ResourceException {
+        return (Boolean) callWrapper("check_domr_ssh", ip);
+    }
+
+    public boolean ovsControlInterface(String dev, String cidr) throws Ovm3ResourceException {
+        return (Boolean) callWrapper("ovs_control_interface", dev, cidr);
+    }
+
+    public boolean ping(String host) throws Ovm3ResourceException {
+        return (Boolean) callWrapper("ping", host);
+    }
+
+    public boolean ovsCheckFile(String file) throws Ovm3ResourceException {
+        return (Boolean) callWrapper("ovs_check_file", file);
+    }
+
+    public boolean dom0HasIp(String ovm3PoolVip) throws Ovm3ResourceException {
+        return (Boolean) callWrapper("check_dom0_ip", ovm3PoolVip);
+    }
+    public boolean dom0CheckStorageHealthCheck(String path, String script, String guid, Integer timeout, Integer interval) throws Ovm3ResourceException {
+        Object[] x = (Object[]) callWrapper("check_dom0_storage_health_check", path, script, guid, timeout, interval);
+        Boolean running = (Boolean) x[0];
+        checkstoragestarted = (Boolean) x[1];
+        return running;
+    }
+    public boolean dom0CheckStorageHealthCheck() {
+        return checkstoragestarted;
+    }
+    /* return something else in the future */
+    public boolean dom0CheckStorageHealth(String path, String script, String guid, Integer timeout) throws Ovm3ResourceException {
+        return (Boolean) callWrapper("check_dom0_storage_health", path, script, guid, timeout);
+    }
+    public boolean ovsMkdirs(String dir) throws Ovm3ResourceException{
+        return (Boolean) nullIsTrueCallWrapper("ovs_mkdirs", dir);
+    }
+    public boolean ovsMkdirs(String dir, Integer mode) throws Ovm3ResourceException{
+        return (Boolean) nullIsTrueCallWrapper("ovs_mkdirs", dir, mode);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Cluster.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Cluster.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Cluster.java
new file mode 100644
index 0000000..93f5d10
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Cluster.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+public class Cluster extends OvmObject {
+    public Cluster(Connection c) {
+        setClient(c);
+    }
+
+    /*
+     * leave_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None argument: poolfsUuid - default: None
+     */
+    public Boolean leaveCluster(String poolfsUuid) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("leave_cluster", poolfsUuid);
+    }
+
+    /*
+     * configure_server_for_cluster, <class
+     * 'agent.api.cluster.o2cb.ClusterO2CB'> argument: self - default: None <( ?
+     * argument: o2cb_conf - default: None <( ? argument: clusterConf - default:
+     * None <( ? argument: poolfs_type - default: None argument: poolfs_target -
+     * default: None argument: poolfsUuid - default: None argument:
+     * poolfs_nfsbase_uuid - default: None
+     */
+    public Boolean configureServerForCluster(String poolfsUuid) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("configure_server_for_cluster", poolfsUuid);
+    }
+
+    /*
+     * deconfigure_server_for_cluster, <class
+     * 'agent.api.cluster.o2cb.ClusterO2CB'> argument: self - default: None
+     * argument: poolfsUuid - default: None
+     */
+    public Boolean deconfigureServerForCluster(String poolfsUuid) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("deconfigure_server_for_cluster", poolfsUuid);
+    }
+
+    /*
+     * join_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument: self
+     * - default: None argument: poolfsUuid - default: None
+     */
+    public Boolean joinCLuster(String poolfsUuid) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("join_cluster", poolfsUuid);
+    }
+
+    /*
+     * discover_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None
+     */
+    /*
+     * <Discover_Cluster_Result>< <O2CB_Config>
+     * <O2CB_HEARTBEAT_THRESHOLD>61</O2CB_HEARTBEAT_THRESHOLD>
+     * <O2CB_RECONNECT_DELAY_MS>2000</O2CB_RECONNECT_DELAY_MS>
+     * <O2CB_KEEPALIVE_DELAY_MS>2000</O2CB_KEEPALIVE_DELAY_MS>
+     * <O2CB_BOOTCLUSTER>ba9aaf00ae5e2d73</O2CB_BOOTCLUSTER>
+     * <O2CB_IDLE_TIMEOUT_MS>60000</O2CB_IDLE_TIMEOUT_MS>
+     * <O2CB_ENABLED>true</O2CB_ENABLED> <O2CB_STACK>o2cb</O2CB_STACK>
+     * </O2CB_Config> <Cluster_Information> <Stored> <Clusters> <Cluster>
+     * <Name>ba9aaf00ae5e2d73</Name> <Node_Count>1</Node_Count>
+     * <Heartbeat_Mode>global</Heartbeat_Mode> </Cluster> </Clusters>
+     * <Heartbeats> <Heartbeat>
+     * <Region>0004FB0000050000E70FBDDEB802208F</Region>
+     * <Cluster>ba9aaf00ae5e2d73</Cluster> </Heartbeat> </Heartbeats> <Nodes>
+     * <Node> <Number>0</Number> <IP_Port>7777</IP_Port>
+     * <IP_Address>192.168.1.64</IP_Address> <Name>ovm-1</Name>
+     * <Cluster_Name>ba9aaf00ae5e2d73</Cluster_Name> </Node> </Nodes> </Stored>
+     * </Cluster_Information> </Discover_Cluster_Result>
+     */
+    /* TODO: Intepret existing clusters... */
+    public Boolean discoverCluster() throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("discover_cluster");
+    }
+
+    /*
+     * update_clusterConfiguration, <class 'agent.api.cluster.o2cb.ClusterO2CB'>
+     * argument: self - default: None argument: cluster_conf - default: None <(
+     * ? cluster_conf can be a "dict" or a plain file: print
+     * master.update_clusterConfiguration(
+     * "heartbeat:\n\tregion = 0004FB0000050000E70FBDDEB802208F\n\tcluster = ba9aaf00ae5e2d72\n\nnode:\n\tip_port = 7777\n\tip_address = 192.168.1.64\n\tnumber = 0\n\tname = ovm-1\n\tcluster = ba9aaf00ae5e2d72\n\nnode:\n\tip_port = 7777\n\tip_address = 192.168.1.65\n\tnumber = 1\n\tname = ovm-2\n\tcluster = ba9aaf00ae5e2d72\n\ncluster:\n\tnode_count = 2\n\theartbeat_mode = global\n\tname = ba9aaf00ae5e2d72\n"
+     * )
+     */
+    public Boolean updateClusterConfiguration(String clusterConf) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("update_clusterConfiguration", clusterConf);
+    }
+
+    /*
+     * destroy_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None argument: poolfsUuid - default: None
+     */
+    public Boolean destroyCluster(String poolfsUuid) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("destroy_cluster", poolfsUuid);
+    }
+
+    /*
+     * is_cluster_online, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None
+     */
+    public Boolean isClusterOnline() throws Ovm3ResourceException {
+        Object x = callWrapper("is_cluster_online");
+        return Boolean.valueOf(x.toString());
+    }
+
+    /*
+     * create_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+     * self - default: None argument: poolfsUuid - default: None
+     */
+    public Boolean createCluster(String poolfsUuid) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("create_cluster", poolfsUuid);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Common.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Common.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Common.java
new file mode 100644
index 0000000..82be869
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Common.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+public class Common extends OvmObject {
+    public Common(Connection c) {
+        setClient(c);
+    }
+
+    /*
+     * get_api_version, <class 'agent.api.common.Common'>
+     */
+    public Integer getApiVersion() throws Ovm3ResourceException {
+        Object[] x = (Object[]) callWrapper("get_api_version");
+        return (Integer) x[0];
+    }
+
+    /*
+     * sleep, <class 'agent.api.common.Common'> argument: secs - default: None
+     */
+    public Boolean sleep(int seconds) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("sleep", seconds);
+    }
+
+    /*
+     * dispatch, <class 'agent.api.common.Common'> argument: uri - default: None
+     * argument: func - default: None
+     */
+    /*
+     * normally used to push commands to other hosts in a cluster: * dispatch
+     * function join_server_pool to server
+     * https://oracle:******@192.168.1.67:8899/api/3/
+     */
+    public <T> String dispatch(String url, String function, T... args) throws Ovm3ResourceException {
+        return callString("dispatch", url, function, args);
+    }
+
+    /*
+     * echo, <class 'agent.api.common.Common'> argument: msg - default: None
+     */
+    public String echo(String msg) throws Ovm3ResourceException {
+        return callString("echo", msg);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Connection.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Connection.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Connection.java
new file mode 100644
index 0000000..b2a4b17
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Connection.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.xmlrpc.client.TimingOutCallback;
+import org.apache.xmlrpc.client.XmlRpcClient;
+import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
+import org.apache.xmlrpc.client.XmlRpcClientRequestImpl;
+
+public class Connection extends XmlRpcClient {
+    private static final Logger LOGGER = Logger.getLogger(Connection.class);
+    private final XmlRpcClientConfigImpl xmlClientConfig = new XmlRpcClientConfigImpl();
+    private XmlRpcClient xmlClient;
+    private String hostUser = null;
+    private String hostPass = null;
+    private String hostIp;
+    private String hostName;
+    private Integer hostPort = 8899;
+    private Boolean hostUseSsl = false;
+    private String cert = "";
+    private String key = "";
+    /* default to 20 mins ? */
+    private Integer timeoutMs = 1200;
+    private Integer timeoutS = timeoutMs * 1000;
+
+    public Connection() {
+    }
+
+    public Connection(String ip, Integer port, String username, String password) {
+        hostIp = ip;
+        hostPort = port;
+        hostUser = username;
+        hostPass = password;
+        xmlClient = setupXmlClient();
+    }
+
+    public Connection(String ip, String username, String password) {
+        hostIp = ip;
+        hostUser = username;
+        hostPass = password;
+        xmlClient = setupXmlClient();
+    }
+
+    private XmlRpcClient setupXmlClient() {
+        final XmlRpcClient client = new XmlRpcClient();
+
+        URL url;
+        try {
+            /* TODO: should add SSL checking here! */
+            String prot = "http";
+            if (hostUseSsl) {
+                prot = "https";
+            }
+            url = new URL(prot + "://" + hostIp + ":" + hostPort.toString());
+            xmlClientConfig.setTimeZone(TimeZone.getTimeZone("UTC"));
+            xmlClientConfig.setServerURL(url);
+            /* disable, we use asyncexecute to control timeout */
+            xmlClientConfig.setReplyTimeout(0);
+            /* default to 60 secs */
+            xmlClientConfig.setConnectionTimeout(60000);
+            /* reply time is 5 mins */
+            xmlClientConfig.setReplyTimeout(60 * 15000);
+            if (hostUser != null && hostPass != null) {
+                LOGGER.debug("Setting username " + hostUser);
+                xmlClientConfig.setBasicUserName(hostUser);
+                xmlClientConfig.setBasicPassword(hostPass);
+            }
+            xmlClientConfig.setXmlRpcServer(null);
+            client.setConfig(xmlClientConfig);
+            client.setTypeFactory(new RpcTypeFactory(client));
+        } catch (MalformedURLException e) {
+            LOGGER.info("Incorrect URL: ", e);
+        }
+        return client;
+    }
+
+    public Object call(String method, List<?> params) throws XmlRpcException {
+        return callTimeoutInSec(method, params, this.timeoutS);
+    }
+
+    public Object call(String method, List<?> params, boolean debug)
+            throws XmlRpcException {
+        return callTimeoutInSec(method, params, this.timeoutS, debug);
+    }
+
+    public Object callTimeoutInSec(String method, List<?> params, int timeout,
+            boolean debug) throws XmlRpcException {
+        TimingOutCallback callback = new TimingOutCallback(timeout * 1000);
+        if (debug) {
+            LOGGER.debug("Call Ovm3 agent " + hostName + "(" + hostIp +"): " + method
+                    + " with " + params);
+        }
+        long startTime = System.currentTimeMillis();
+        try {
+            /* returns actual xml */
+            XmlRpcClientRequestImpl req = new XmlRpcClientRequestImpl(
+                    xmlClient.getClientConfig(), method, params);
+            xmlClient.executeAsync(req, callback);
+            return callback.waitForResponse();
+        } catch (TimingOutCallback.TimeoutException e) {
+            LOGGER.info("Timeout: ", e);
+            throw new XmlRpcException(e.getMessage());
+        } catch (XmlRpcException e) {
+            LOGGER.info("XML RPC Exception occured: ", e);
+            throw e;
+        } catch (RuntimeException e) {
+            LOGGER.info("Runtime Exception: ", e);
+            throw new XmlRpcException(e.getMessage());
+        } catch (Throwable e) {
+            LOGGER.error("Holy crap batman!: ", e);
+            throw new XmlRpcException(e.getMessage(), e);
+        } finally {
+            long endTime = System.currentTimeMillis();
+            /* in seconds */
+            float during = (endTime - startTime) / (float) 1000;
+            LOGGER.debug("Ovm3 call " + method + " finished in " + during
+                    + " secs, on " + hostIp + ":" + hostPort);
+        }
+    }
+
+    public Object callTimeoutInSec(String method, List<?> params, int timeout)
+            throws XmlRpcException {
+        return callTimeoutInSec(method, params, timeout, true);
+    }
+
+    public String getIp() {
+        return hostIp;
+    }
+
+    public Integer getPort() {
+        return hostPort;
+    }
+
+    public String getUserName() {
+        return hostUser;
+    }
+
+    public void setUserName(String s) {
+        hostUser = s;
+    }
+
+    public String getPassword() {
+        return hostPass;
+    }
+
+    public Boolean getUseSsl() {
+        return hostUseSsl;
+    }
+
+    public String getCert() {
+        return cert;
+    }
+
+    public String getKey() {
+        return key;
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    public void setHostName(String hostName) {
+        this.hostName = hostName;
+    }
+
+    public void setIp(String agentIp) {
+        hostIp = agentIp;
+    }
+
+    public void setPassword(String agentPassword) {
+        hostPass = agentPassword;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Linux.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Linux.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Linux.java
new file mode 100644
index 0000000..e1a5f19
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Linux.java
@@ -0,0 +1,457 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
+public class Linux extends OvmObject {
+    private static final Logger LOGGER = Logger
+            .getLogger(Linux.class);
+    private static final String DEVICE = "Device";
+    private static final String REMOTEDIR = "Remote_Dir";
+    private static final String MOUNTPOINT = "Mount_Point";
+    private Integer initMaps = 1;
+
+    /**
+     * use capabilities to match things later, perhaps also hardware discovery ?
+     * wrap getters and setters.... for Mapps...
+     */
+    private Map<String, String> ovmCapabilities = new HashMap<String, String>();
+    /**
+     * MAX_CONCURRENT_MIGRATION_IN=1, ALL_VM_CPU_OVERSUBSCRIBE=True,
+     * HIGH_AVAILABILITY=True, LOCAL_STORAGE_ELEMENT=True, NFS=True,
+     * MTU_CONFIGURATION=True, CONCURRENT_MIGRATION=False,
+     * VM_MEMORY_ALIGNMENT=1048576, CLUSTERS=True, VM_SUSPEND=True,
+     * BOND_MODE_LINK_AGGREGATION=True, YUM_PACKAGE_MANAGEMENT=True,
+     * VM_VNC_CONSOLE=True, BOND_MODE_ACTIVE_BACKUP=True,
+     * MAX_CONCURRENT_MIGRATION_OUT=1, MIGRATION_SETUP=False,
+     * PER_VM_CPU_OVERSUBSCRIBE=True, POWER_ON_WOL=True, FIBRE_CHANNEL=True,
+     * ISCSI=True, HVM_MAX_VNICS=8}
+     */
+    private Map<String, String> ovmHypervisorDetails = new HashMap<String, String>();
+    private Map<String, String> ovmHypervisor = new HashMap<String, String>();
+    private Map<String, String> ovmNTP = new HashMap<String, String>();
+    private Map<String, String> ovmDateTime = new HashMap<String, String>();
+    private Map<String, String> ovmGeneric = new HashMap<String, String>();
+    /**
+     * {OS_Major_Version=5, Statistic=20, Membership_State=Unowned,
+     * OVM_Version=3.2.1-517, OS_Type=Linux, Hypervisor_Name=Xen,
+     * CPU_Type=x86_64, Manager_Core_API_Version=3.2.1.516,
+     * Is_Current_Master=false, OS_Name=Oracle VM Server,
+     * Server_Roles=xen,utility, Pool_Unique_Id=none,
+     * Host_Kernel_Release=2.6.39-300.22.2.el5uek, OS_Minor_Version=7,
+     * Agent_Version=3.2.1-183, Boot_Time=1392366638, RPM_Version=3.2.1-183,
+     * Exports=, Hypervisor_Type=xen, Host_Kernel_Version=#1 SMP Fri Jan 4
+     * 12:40:29 PST 2013,
+     * Unique_Id=1d:d5:e8:91:d9:d0:ed:bd:81:c2:a6:9a:b3:d1:b7:ea,
+     * Manager_Unique_Id=none, Cluster_State=Offline, Hostname=ovm-1}
+     */
+    private Map<String, String> hwPhysicalInfo = new HashMap<String, String>();
+    private Map<String, String> hwSystemInfo = new HashMap<String, String>();
+    private int localTime;
+    private int lastBootTime;
+    private String timeZ;
+    private String timeUTC;
+    private List<String> mounts = null;
+    private Map<String, FileSystem> fsMap = null;
+
+    public Linux(Connection c) {
+        setClient(c);
+    }
+
+    /*
+     * discover_server, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Boolean discoverServer() throws Ovm3ResourceException {
+        Object result = callWrapper("discover_server");
+        if (result == null) {
+            return false;
+        }
+        Document xmlDocument = prepParse((String) result);
+        /* could be more subtle */
+        String path = "//Discover_Server_Result/Server";
+        ovmCapabilities = xmlToMap(path + "/Capabilities", xmlDocument);
+        ovmHypervisorDetails = xmlToMap(path + "/VMM/Version", xmlDocument);
+        ovmHypervisor = xmlToMap(path + "/VMM", xmlDocument);
+        ovmNTP = xmlToMap(path + "/NTP", xmlDocument);
+        ovmDateTime = xmlToMap(path + "/Date_Time", xmlDocument);
+        ovmGeneric = xmlToMap(path, xmlDocument);
+        return true;
+    }
+
+    public String getAgentVersion() throws Ovm3ResourceException {
+        return get("Agent_Version");
+    }
+
+    public String getHostKernelRelease() throws Ovm3ResourceException {
+        return get("Host_Kernel_Release");
+    }
+
+    public String getHostOs() throws Ovm3ResourceException {
+        return get("OS_Name");
+    }
+
+    public String getHostOsVersion() throws Ovm3ResourceException {
+        return get("OS_Major_Version") + "."
+                + get("OS_Minor_Version");
+    }
+
+    public String getHypervisorName() throws Ovm3ResourceException {
+        return get("Hypervisor_Name");
+    }
+
+    public String getHypervisorVersion() throws Ovm3ResourceException {
+        return getHypervisorMajor() + "."
+                + getHypervisorMinor() + "." + getHypervisorExtra();
+    }
+
+    public String getCapabilities() throws Ovm3ResourceException {
+        return get("Capabilities");
+    }
+
+    public String getHypervisorMajor() throws Ovm3ResourceException {
+        return get("Major");
+    }
+
+    public String getHypervisorMinor() throws Ovm3ResourceException{
+        return get("Minor");
+    }
+
+    public String getHypervisorExtra() throws Ovm3ResourceException {
+        return get("Extra").replace(".", "");
+    }
+
+    public String getManagerUuid() throws Ovm3ResourceException {
+        return get("Manager_Unique_Id");
+    }
+
+    public String getMembershipState() throws Ovm3ResourceException {
+        return get("Membership_State");
+    }
+
+    public String getServerRoles() throws Ovm3ResourceException{
+        return get("Server_Roles");
+    }
+
+    public boolean getIsMaster() throws Ovm3ResourceException {
+        return Boolean.parseBoolean(get("Is_Current_Master"));
+    }
+
+    public String getOvmVersion() throws Ovm3ResourceException {
+        return get("OVM_Version");
+    }
+
+    public String getHostName() throws Ovm3ResourceException {
+        return get("Hostname");
+    }
+
+    public Integer getCpuKhz() throws Ovm3ResourceException {
+        return Integer.valueOf(get("CPUKHz"));
+    }
+
+    public Integer getCpuSockets() throws Ovm3ResourceException {
+        return Integer.valueOf(get("SocketsPerNode"));
+    }
+
+    public Integer getCpuThreads() throws Ovm3ResourceException {
+        return Integer.valueOf(get("ThreadsPerCore"));
+    }
+
+    public Integer getCpuCores() throws Ovm3ResourceException {
+        return Integer.valueOf(get("CoresPerSocket"));
+    }
+
+    public Integer getTotalThreads() throws Ovm3ResourceException {
+        return getCpuSockets() * getCpuCores() * getCpuThreads();
+    }
+
+    public Double getMemory() throws Ovm3ResourceException {
+        return Double.valueOf(get("TotalPages")) * 4096;
+    }
+
+    public Double getFreeMemory() throws Ovm3ResourceException {
+        return Double.valueOf(get("FreePages")) * 4096;
+    }
+
+    public String getUuid() throws Ovm3ResourceException {
+        return get("Unique_Id");
+    }
+
+    private void initMaps() throws Ovm3ResourceException {
+        if (initMaps == 1) {
+            discoverHardware();
+            discoverServer();
+            initMaps = 0;
+        }
+    }
+
+    public String get(String element) throws Ovm3ResourceException {
+        try {
+            initMaps();
+        } catch (Ovm3ResourceException e) {
+            LOGGER.info("Unable to discover host: " + e.getMessage(), e);
+            throw e;
+        }
+        if (ovmGeneric.containsKey(element)) {
+            return ovmGeneric.get(element);
+        } else if (ovmHypervisor.containsKey(element)) {
+            return ovmHypervisor.get(element);
+        } else if (ovmHypervisorDetails.containsKey(element)) {
+            return ovmHypervisorDetails.get(element);
+        } else if (hwPhysicalInfo.containsKey(element)) {
+            return hwPhysicalInfo.get(element);
+        } else if (hwSystemInfo.containsKey(element)) {
+            return hwSystemInfo.get(element);
+        } else if (ovmCapabilities.containsKey(element)) {
+            return ovmCapabilities.get(element);
+        }
+        return "";
+    }
+
+    /*
+     * get_last_boot_time, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+    public Integer getLastBootTime() throws Ovm3ResourceException {
+        Map<String, Long> result = callMap("get_last_boot_time");
+        if (result == null) {
+            return null;
+        }
+        lastBootTime = result.get("last_boot_time").intValue();
+        localTime = result.get("local_time").intValue();
+        return lastBootTime;
+    }
+
+    /*
+     * get_support_files, <class 'agent.api.host.linux.Linux'> argument: self -
+     * default: None
+     */
+
+    public Boolean copyFile(String src, String dst) throws Ovm3ResourceException {
+        /* sparse is set to true by default ? */
+        Object x = callWrapper("copy_file", src, dst, true);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean copyFile(String src, String dst, Boolean sparse) throws Ovm3ResourceException {
+        Object x = callWrapper("copy_file", src, dst, sparse);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    public Map<String, FileSystem> getFileSystemMap(String type) throws Ovm3ResourceException {
+        if (fsMap == null) {
+            discoverMountedFs(type);
+        }
+        return fsMap;
+    }
+    public FileSystem getFileSystem(String mountpoint, String type) throws Ovm3ResourceException {
+        getFileSystemMap(type);
+        if (getFileSystemMap(type).containsKey(mountpoint)) {
+            return getFileSystemMap(type).get(mountpoint);
+        }
+        return null;
+    }
+    public FileSystem getFileSystemByUuid(String uuid, String type) throws Ovm3ResourceException {
+        getFileSystemMap(type);
+        for (final Map.Entry<String, FileSystem> fs : fsMap.entrySet()) {
+            if (fs.getValue().getUuid().matches(uuid)) {
+                return fs.getValue();
+            }
+        }
+        return null;
+    }
+    public void setFileSystemMap(Map<String, FileSystem> map) {
+        fsMap = map;
+    }
+    public List<String> getFileSystemList() {
+        return mounts;
+    }
+
+    public static class FileSystem {
+        private Map<String, Object> fileSys = new HashMap<String, Object>() {
+            {
+                put("Mount_Options", null);
+                put("Name", null);
+                put(DEVICE, null);
+                put("Host", null);
+                put(REMOTEDIR, null);
+                put(MOUNTPOINT, null);
+                put("Uuid", null);
+            }
+        };
+
+        public Boolean setDetails(Map<String, Object> fs) {
+            fileSys = fs;
+            return true;
+        }
+        public Map<String, Object> getDetails() {
+            return fileSys;
+        }
+        public String getUuid() {
+            return (String) fileSys.get("Uuid");
+        }
+
+        public String setUuid(String uuid) {
+            return (String) fileSys.put("Uuid", uuid);
+        }
+
+        public String getDevice() {
+            return (String) fileSys.get(DEVICE);
+        }
+
+        public String setDevice(String dev) {
+            return (String) fileSys.put(DEVICE, dev);
+        }
+
+        public String getHost() {
+            if (getDevice() != null && getDevice().contains(":")) {
+                String[] spl = getDevice().split(":");
+                setHost(spl[0]);
+                setRemoteDir(spl[1]);
+            } else {
+                return null;
+            }
+            return (String) fileSys.get("Host");
+        }
+
+        public String setHost(String host) {
+            return (String) fileSys.put("Host", host);
+        }
+
+        public String setRemoteDir(String dir) {
+            return (String) fileSys.put(REMOTEDIR, dir);
+        }
+
+        public String getRemoteDir() {
+            if (getHost() != null) {
+                return (String) fileSys.get(REMOTEDIR);
+            }
+            return null;
+        }
+
+        public String setMountPoint(String pnt) {
+            return (String) fileSys.put(MOUNTPOINT, pnt);
+        }
+        public String getMountPoint() {
+            return (String) fileSys.get(MOUNTPOINT);
+        }
+    }
+
+    /* should actually be called "getMountedsFsDevice" or something */
+    /* takes nfs,ext3 etc as parameter it reads from /proc/mounts */
+    public Map<String, FileSystem> discoverMountedFs(String type) throws Ovm3ResourceException {
+        fsMap = new HashMap<String, FileSystem>();
+        Object x = callWrapper("discover_mounted_file_systems", type);
+        if (x == null) {
+            return fsMap;
+        }
+        Document xmlDocument = prepParse((String) x);
+        String bpath = "//Discover_Mounted_File_Systems_Result/Filesystem";
+        String mpath = bpath + "/Mount/@Dir";
+        mounts = xmlToList(mpath, xmlDocument);
+        for (String mnt : mounts) {
+            String dpath = bpath + "/Mount[@Dir='" + mnt + "']";
+            Map<String, Object> fs = xmlToMap(dpath, xmlDocument);
+            FileSystem f = new FileSystem();
+            f.setDetails(fs);
+            String[] spl = mnt.split("/");
+            String uuid = spl[spl.length - 1];
+            f.setUuid(uuid);
+            f.setMountPoint(mnt);
+            /* sets it up per mountpoint, not the ID!!! */
+            fsMap.put(mnt, f);
+        }
+        setFileSystemMap(fsMap);
+        return fsMap;
+    }
+
+    /* TODO: in 3.3.x this changed to user, pass, oldpass */
+    public Boolean updateAgentPassword(String user, String pass) throws Ovm3ResourceException {
+        Object x = callWrapper("update_agent_password", user, pass);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean discoverHardware() throws Ovm3ResourceException {
+        Object result = callWrapper("discover_hardware");
+        if (result == null) {
+            return false;
+        }
+        Document xmlDocument;
+        xmlDocument = prepParse((String) result);
+        /* could be more subtle */
+        String path = "//Discover_Hardware_Result/NodeInformation";
+        /* we don't care a bout IO/SCSI for now..., we might care about
+         * CPUs later: NodeInformation/CPUInfo/Proc_Info/CPU[@ID=0]
+         */
+        hwPhysicalInfo = xmlToMap(path + "/VMM/PhysicalInfo", xmlDocument);
+        hwSystemInfo = xmlToMap(path + "/DMTF/System", xmlDocument);
+        return true;
+    }
+
+    public Integer getDateTime() throws Ovm3ResourceException {
+        getLastBootTime();
+        return localTime;
+    }
+
+    /* Pushes the statistics out to a url, the statistics are in the form of a dict */
+    public Boolean setStatisticsInterval(int val) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("set_statistics_interval", val);
+    }
+
+    public Boolean getTimeZone() throws Ovm3ResourceException  {
+        Object[] result = (Object[]) callWrapper("get_timezone");
+        if (result != null) {
+            setTimeZ(result[0].toString());
+            setTimeUTC(result[1].toString());
+            return true;
+        }
+        return false;
+    }
+
+    public String getTimeUTC() {
+        return timeUTC;
+    }
+
+    private void setTimeUTC(String timeUTC) {
+        this.timeUTC = timeUTC;
+    }
+
+    public String getTimeZ() {
+        return timeZ;
+    }
+
+    private void setTimeZ(String timeZ) {
+        this.timeZ = timeZ;
+    }
+}


[04/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/XenTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/XenTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/XenTest.java
new file mode 100644
index 0000000..c16e728
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/XenTest.java
@@ -0,0 +1,1491 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.util.UUID;
+
+import org.junit.Test;
+
+public class XenTest {
+    public XenTest() {
+    }
+    ConnectionTest con = new ConnectionTest();
+    Xen xEn = new Xen(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+    String DOM0VMNAME = "Domain-0";
+    String VMNAME = "i-2-3-VM";
+    String VMROOTDISKNAME = "ROOT-3";
+    public String getVMNAME() {
+        return VMNAME;
+    }
+    String REPOID = "f12842ebf5ed3fe78da1eb0e17f5ede8";
+    public String getRepoId() {
+        return REPOID;
+    }
+    public String getVmId() {
+        return VMID;
+    }
+    String VMNICMAC = "02:00:50:9a:00:01";
+    public String getVmNicMac() {
+        return VMNICMAC;
+    }
+    public String getVmNicBridge() {
+        return VMNICBR;
+    }
+    public String getVmNicUuid() {
+        return VMNICUUID;
+    }
+    String VMNICBR = "xenbr0.160";
+    String VMNICUUID = "2ad52371-af7d-32d1-ebe1-2b6a811e66c4";
+    String VMID = "868a6627-c3b0-3d9b-aea4-f279cbaa253b";
+    String VMROOTDISKUUID = "722eb520-dcf5-4113-8f45-22d67c9a2f3c";
+    public String getVmRootDiskUuid() {
+        return VMROOTDISKUUID;
+    }
+    public String getVmRootDiskName() {
+        return VMROOTDISKNAME;
+    }
+    String VMROOTDISK = VMROOTDISKUUID + ".raw";
+    String VMISO = "xentools.iso";
+    String REPOPATH = "/OVS/Repositories";
+    String VMROOTDISKPATH = REPOPATH + "/" + REPOID + "/Disks/" + VMROOTDISK;
+    String VMISOPATH = REPOPATH + "/" + REPOID + "/ISOs/" + VMISO;
+    String MULTIPLEVMSLISTXML = results
+            .simpleResponseWrapWrapper("<array><data>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>on_xend_stop</name>\n"
+                    + "<value><string>ignore</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>features</name>\n"
+                    + "<value><string></string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>image</name>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>tsc_mode</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>kernel</name>\n"
+                    + "<value><string></string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>superpages</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>nomigrate</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>expose_host_uuid</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "</struct></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>cpus</name>\n"
+                    + "<value><array><data>\n"
+                    + "<value><array><data>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>10</string></value>\n"
+                    + "<value><string>11</string></value>\n"
+                    + "<value><string>12</string></value>\n"
+                    + "<value><string>13</string></value>\n"
+                    + "<value><string>14</string></value>\n"
+                    + "<value><string>15</string></value>\n"
+                    + "<value><string>16</string></value>\n"
+                    + "<value><string>17</string></value>\n"
+                    + "<value><string>18</string></value>\n"
+                    + "<value><string>19</string></value>\n"
+                    + "<value><string>20</string></value>\n"
+                    + "<value><string>21</string></value>\n"
+                    + "<value><string>22</string></value>\n"
+                    + "<value><string>23</string></value>\n"
+                    + "<value><string>24</string></value>\n"
+                    + "<value><string>25</string></value>\n"
+                    + "<value><string>26</string></value>\n"
+                    + "<value><string>27</string></value>\n"
+                    + "<value><string>28</string></value>\n"
+                    + "<value><string>29</string></value>\n"
+                    + "<value><string>30</string></value>\n"
+                    + "<value><string>31</string></value>\n"
+                    + "<value><string>32</string></value>\n"
+                    + "<value><string>33</string></value>\n"
+                    + "<value><string>34</string></value>\n"
+                    + "<value><string>35</string></value>\n"
+                    + "<value><string>36</string></value>\n"
+                    + "<value><string>37</string></value>\n"
+                    + "<value><string>38</string></value>\n"
+                    + "<value><string>39</string></value>\n"
+                    + "<value><string>40</string></value>\n"
+                    + "<value><string>41</string></value>\n"
+                    + "<value><string>42</string></value>\n"
+                    + "<value><string>43</string></value>\n"
+                    + "<value><string>44</string></value>\n"
+                    + "<value><string>45</string></value>\n"
+                    + "<value><string>46</string></value>\n"
+                    + "<value><string>47</string></value>\n"
+                    + "<value><string>48</string></value>\n"
+                    + "<value><string>49</string></value>\n"
+                    + "<value><string>50</string></value>\n"
+                    + "<value><string>51</string></value>\n"
+                    + "<value><string>52</string></value>\n"
+                    + "<value><string>53</string></value>\n"
+                    + "<value><string>54</string></value>\n"
+                    + "<value><string>55</string></value>\n"
+                    + "<value><string>56</string></value>\n"
+                    + "<value><string>57</string></value>\n"
+                    + "<value><string>58</string></value>\n"
+                    + "<value><string>59</string></value>\n"
+                    + "<value><string>60</string></value>\n"
+                    + "<value><string>61</string></value>\n"
+                    + "<value><string>62</string></value>\n"
+                    + "<value><string>63</string></value>\n"
+                    + "<value><string>64</string></value>\n"
+                    + "<value><string>65</string></value>\n"
+                    + "<value><string>66</string></value>\n"
+                    + "<value><string>67</string></value>\n"
+                    + "<value><string>68</string></value>\n"
+                    + "<value><string>69</string></value>\n"
+                    + "<value><string>70</string></value>\n"
+                    + "<value><string>71</string></value>\n"
+                    + "<value><string>72</string></value>\n"
+                    + "<value><string>73</string></value>\n"
+                    + "<value><string>74</string></value>\n"
+                    + "<value><string>75</string></value>\n"
+                    + "<value><string>76</string></value>\n"
+                    + "<value><string>77</string></value>\n"
+                    + "<value><string>78</string></value>\n"
+                    + "<value><string>79</string></value>\n"
+                    + "<value><string>80</string></value>\n"
+                    + "<value><string>81</string></value>\n"
+                    + "<value><string>82</string></value>\n"
+                    + "<value><string>83</string></value>\n"
+                    + "<value><string>84</string></value>\n"
+                    + "<value><string>85</string></value>\n"
+                    + "<value><string>86</string></value>\n"
+                    + "<value><string>87</string></value>\n"
+                    + "<value><string>88</string></value>\n"
+                    + "<value><string>89</string></value>\n"
+                    + "<value><string>90</string></value>\n"
+                    + "<value><string>91</string></value>\n"
+                    + "<value><string>92</string></value>\n"
+                    + "<value><string>93</string></value>\n"
+                    + "<value><string>94</string></value>\n"
+                    + "<value><string>95</string></value>\n"
+                    + "<value><string>96</string></value>\n"
+                    + "<value><string>97</string></value>\n"
+                    + "<value><string>98</string></value>\n"
+                    + "<value><string>99</string></value>\n"
+                    + "<value><string>100</string></value>\n"
+                    + "<value><string>101</string></value>\n"
+                    + "<value><string>102</string></value>\n"
+                    + "<value><string>103</string></value>\n"
+                    + "<value><string>104</string></value>\n"
+                    + "<value><string>105</string></value>\n"
+                    + "<value><string>106</string></value>\n"
+                    + "<value><string>107</string></value>\n"
+                    + "<value><string>108</string></value>\n"
+                    + "<value><string>109</string></value>\n"
+                    + "<value><string>110</string></value>\n"
+                    + "<value><string>111</string></value>\n"
+                    + "<value><string>112</string></value>\n"
+                    + "<value><string>113</string></value>\n"
+                    + "<value><string>114</string></value>\n"
+                    + "<value><string>115</string></value>\n"
+                    + "<value><string>116</string></value>\n"
+                    + "<value><string>117</string></value>\n"
+                    + "<value><string>118</string></value>\n"
+                    + "<value><string>119</string></value>\n"
+                    + "<value><string>120</string></value>\n"
+                    + "<value><string>121</string></value>\n"
+                    + "<value><string>122</string></value>\n"
+                    + "<value><string>123</string></value>\n"
+                    + "<value><string>124</string></value>\n"
+                    + "<value><string>125</string></value>\n"
+                    + "<value><string>126</string></value>\n"
+                    + "<value><string>127</string></value>\n"
+                    + "<value><string>128</string></value>\n"
+                    + "<value><string>129</string></value>\n"
+                    + "<value><string>130</string></value>\n"
+                    + "<value><string>131</string></value>\n"
+                    + "<value><string>132</string></value>\n"
+                    + "<value><string>133</string></value>\n"
+                    + "<value><string>134</string></value>\n"
+                    + "<value><string>135</string></value>\n"
+                    + "<value><string>136</string></value>\n"
+                    + "<value><string>137</string></value>\n"
+                    + "<value><string>138</string></value>\n"
+                    + "<value><string>139</string></value>\n"
+                    + "<value><string>140</string></value>\n"
+                    + "<value><string>141</string></value>\n"
+                    + "<value><string>142</string></value>\n"
+                    + "<value><string>143</string></value>\n"
+                    + "<value><string>144</string></value>\n"
+                    + "<value><string>145</string></value>\n"
+                    + "<value><string>146</string></value>\n"
+                    + "<value><string>147</string></value>\n"
+                    + "<value><string>148</string></value>\n"
+                    + "<value><string>149</string></value>\n"
+                    + "<value><string>150</string></value>\n"
+                    + "<value><string>151</string></value>\n"
+                    + "<value><string>152</string></value>\n"
+                    + "<value><string>153</string></value>\n"
+                    + "<value><string>154</string></value>\n"
+                    + "<value><string>155</string></value>\n"
+                    + "<value><string>156</string></value>\n"
+                    + "<value><string>157</string></value>\n"
+                    + "<value><string>158</string></value>\n"
+                    + "<value><string>159</string></value>\n"
+                    + "</data></array></value>\n"
+                    + "<value><array><data>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "<value><string>10</string></value>\n"
+                    + "<value><string>11</string></value>\n"
+                    + "<value><string>12</string></value>\n"
+                    + "<value><string>13</string></value>\n"
+                    + "<value><string>14</string></value>\n"
+                    + "<value><string>15</string></value>\n"
+                    + "<value><string>16</string></value>\n"
+                    + "<value><string>17</string></value>\n"
+                    + "<value><string>18</string></value>\n"
+                    + "<value><string>19</string></value>\n"
+                    + "<value><string>20</string></value>\n"
+                    + "<value><string>21</string></value>\n"
+                    + "<value><string>22</string></value>\n"
+                    + "<value><string>23</string></value>\n"
+                    + "<value><string>24</string></value>\n"
+                    + "<value><string>25</string></value>\n"
+                    + "<value><string>26</string></value>\n"
+                    + "<value><string>27</string></value>\n"
+                    + "<value><string>28</string></value>\n"
+                    + "<value><string>29</string></value>\n"
+                    + "<value><string>30</string></value>\n"
+                    + "<value><string>31</string></value>\n"
+                    + "<value><string>32</string></value>\n"
+                    + "<value><string>33</string></value>\n"
+                    + "<value><string>34</string></value>\n"
+                    + "<value><string>35</string></value>\n"
+                    + "<value><string>36</string></value>\n"
+                    + "<value><string>37</string></value>\n"
+                    + "<value><string>38</string></value>\n"
+                    + "<value><string>39</string></value>\n"
+                    + "<value><string>40</string></value>\n"
+                    + "<value><string>41</string></value>\n"
+                    + "<value><string>42</string></value>\n"
+                    + "<value><string>43</string></value>\n"
+                    + "<value><string>44</string></value>\n"
+                    + "<value><string>45</string></value>\n"
+                    + "<value><string>46</string></value>\n"
+                    + "<value><string>47</string></value>\n"
+                    + "<value><string>48</string></value>\n"
+                    + "<value><string>49</string></value>\n"
+                    + "<value><string>50</string></value>\n"
+                    + "<value><string>51</string></value>\n"
+                    + "<value><string>52</string></value>\n"
+                    + "<value><string>53</string></value>\n"
+                    + "<value><string>54</string></value>\n"
+                    + "<value><string>55</string></value>\n"
+                    + "<value><string>56</string></value>\n"
+                    + "<value><string>57</string></value>\n"
+                    + "<value><string>58</string></value>\n"
+                    + "<value><string>59</string></value>\n"
+                    + "<value><string>60</string></value>\n"
+                    + "<value><string>61</string></value>\n"
+                    + "<value><string>62</string></value>\n"
+                    + "<value><string>63</string></value>\n"
+                    + "<value><string>64</string></value>\n"
+                    + "<value><string>65</string></value>\n"
+                    + "<value><string>66</string></value>\n"
+                    + "<value><string>67</string></value>\n"
+                    + "<value><string>68</string></value>\n"
+                    + "<value><string>69</string></value>\n"
+                    + "<value><string>70</string></value>\n"
+                    + "<value><string>71</string></value>\n"
+                    + "<value><string>72</string></value>\n"
+                    + "<value><string>73</string></value>\n"
+                    + "<value><string>74</string></value>\n"
+                    + "<value><string>75</string></value>\n"
+                    + "<value><string>76</string></value>\n"
+                    + "<value><string>77</string></value>\n"
+                    + "<value><string>78</string></value>\n"
+                    + "<value><string>79</string></value>\n"
+                    + "<value><string>80</string></value>\n"
+                    + "<value><string>81</string></value>\n"
+                    + "<value><string>82</string></value>\n"
+                    + "<value><string>83</string></value>\n"
+                    + "<value><string>84</string></value>\n"
+                    + "<value><string>85</string></value>\n"
+                    + "<value><string>86</string></value>\n"
+                    + "<value><string>87</string></value>\n"
+                    + "<value><string>88</string></value>\n"
+                    + "<value><string>89</string></value>\n"
+                    + "<value><string>90</string></value>\n"
+                    + "<value><string>91</string></value>\n"
+                    + "<value><string>92</string></value>\n"
+                    + "<value><string>93</string></value>\n"
+                    + "<value><string>94</string></value>\n"
+                    + "<value><string>95</string></value>\n"
+                    + "<value><string>96</string></value>\n"
+                    + "<value><string>97</string></value>\n"
+                    + "<value><string>98</string></value>\n"
+                    + "<value><string>99</string></value>\n"
+                    + "<value><string>100</string></value>\n"
+                    + "<value><string>101</string></value>\n"
+                    + "<value><string>102</string></value>\n"
+                    + "<value><string>103</string></value>\n"
+                    + "<value><string>104</string></value>\n"
+                    + "<value><string>105</string></value>\n"
+                    + "<value><string>106</string></value>\n"
+                    + "<value><string>107</string></value>\n"
+                    + "<value><string>108</string></value>\n"
+                    + "<value><string>109</string></value>\n"
+                    + "<value><string>110</string></value>\n"
+                    + "<value><string>111</string></value>\n"
+                    + "<value><string>112</string></value>\n"
+                    + "<value><string>113</string></value>\n"
+                    + "<value><string>114</string></value>\n"
+                    + "<value><string>115</string></value>\n"
+                    + "<value><string>116</string></value>\n"
+                    + "<value><string>117</string></value>\n"
+                    + "<value><string>118</string></value>\n"
+                    + "<value><string>119</string></value>\n"
+                    + "<value><string>120</string></value>\n"
+                    + "<value><string>121</string></value>\n"
+                    + "<value><string>122</string></value>\n"
+                    + "<value><string>123</string></value>\n"
+                    + "<value><string>124</string></value>\n"
+                    + "<value><string>125</string></value>\n"
+                    + "<value><string>126</string></value>\n"
+                    + "<value><string>127</string></value>\n"
+                    + "<value><string>128</string></value>\n"
+                    + "<value><string>129</string></value>\n"
+                    + "<value><string>130</string></value>\n"
+                    + "<value><string>131</string></value>\n"
+                    + "<value><string>132</string></value>\n"
+                    + "<value><string>133</string></value>\n"
+                    + "<value><string>134</string></value>\n"
+                    + "<value><string>135</string></value>\n"
+                    + "<value><string>136</string></value>\n"
+                    + "<value><string>137</string></value>\n"
+                    + "<value><string>138</string></value>\n"
+                    + "<value><string>139</string></value>\n"
+                    + "<value><string>140</string></value>\n"
+                    + "<value><string>141</string></value>\n"
+                    + "<value><string>142</string></value>\n"
+                    + "<value><string>143</string></value>\n"
+                    + "<value><string>144</string></value>\n"
+                    + "<value><string>145</string></value>\n"
+                    + "<value><string>146</string></value>\n"
+                    + "<value><string>147</string></value>\n"
+                    + "<value><string>148</string></value>\n"
+                    + "<value><string>149</string></value>\n"
+                    + "<value><string>150</string></value>\n"
+                    + "<value><string>151</string></value>\n"
+                    + "<value><string>152</string></value>\n"
+                    + "<value><string>153</string></value>\n"
+                    + "<value><string>154</string></value>\n"
+                    + "<value><string>155</string></value>\n"
+                    + "<value><string>156</string></value>\n"
+                    + "<value><string>157</string></value>\n"
+                    + "<value><string>158</string></value>\n"
+                    + "<value><string>159</string></value>\n"
+                    + "</data></array></value>\n"
+                    + "</data></array></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>uuid</name>\n"
+                    + "<value><string>00000000-0000-0000-0000-000000000000</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>on_reboot</name>\n"
+                    + "<value><string>restart</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>state</name>\n"
+                    + "<value><string>r-----</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>cpu_weight</name>\n"
+                    + "<value><string>65535</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>online_vcpus</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>memory</name>\n"
+                    + "<value><string>672</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>cpu_cap</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>status</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>pool_name</name>\n"
+                    + "<value><string>Pool-0</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>on_poweroff</name>\n"
+                    + "<value><string>destroy</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>on_xend_start</name>\n"
+                    + "<value><string>ignore</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>on_crash</name>\n"
+                    + "<value><string>restart</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>device</name>\n"
+                    + "<value><struct>\n"
+                    + "</struct></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>bootloader</name>\n"
+                    + "<value><string></string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>maxmem</name>\n"
+                    + "<value><string>672</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>cpu_time</name>\n"
+                    + "<value><string>6608.51291287</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>shadow_memory</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>name</name>\n"
+                    + "<value><string>Domain-0</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>builder</name>\n"
+                    + "<value><string>linux</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>bootloader_args</name>\n"
+                    + "<value><string></string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>domid</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>vcpus</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "</struct></value>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>on_xend_stop</name>\n"
+                    + "<value><string>ignore</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>console_mfn</name>\n"
+                    + "<value><string>873706</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>features</name>\n"
+                    + "<value><string></string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>image</name>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>tsc_mode</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>kernel</name>\n"
+                    + "<value><string></string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>videoram</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>device_model</name>\n"
+                    + "<value><string>/usr/lib/xen/bin/qemu-dm</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>notes</name>"
+                    + "<value><array><data>"
+                    + "<value><array><data>"
+                    + "<value><string>HV_START_LOW</string></value>"
+                    + "<value><string>4118806528</string></value>"
+                    + "</data></array></value>"
+                    + "<value><array><data>"
+                    + "<value><string>FEATURES</string></value>"
+                    + "<value><string>!writable_page_tables|pae_pgdir_above_4gb</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>VIRT_BASE</string></value>"
+                    + "<value><string>3221225472</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>GUEST_VERSION</string></value>"
+                    + "<value><string>2.6</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>PADDR_OFFSET</string></value>"
+                    + "<value><string>" + "</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>GUEST_OS</string></value>"
+                    + "<value><string>linux</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>HYPERCALL_PAGE</string></value>"
+                    + "<value><string>3238010880</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>LOADER</string></value>"
+                    + "<value><string>generic</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>SUSPEND_CANCEL</string></value>"
+                    + "<value><string>" + "</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>PAE_MODE</string></value>"
+                    + "<value><string>yes</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>ENTRY</string></value>"
+                    + "<value><string>3242303488</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>XEN_VERSION</string></value>"
+                    + "<value><string>xen-3.0</string></value>"
+                    + "</data></array></value>" + "</data></array></value>"
+                    + "</member>" + "<member>"
+                    + "<name>expose_host_uuid</name>" + "<value><string>"
+                    + "</string></value>" + "</member>" + "<member>"
+                    + "<name>pci</name>" + "<value><array><data>"
+                    + "</data></array></value>" + "</member>" + "<member>"
+                    + "<name>superpages</name>\n" + "<value><string>\n"
+                    + "</string></value>\n" + "</member>\n" + "<member>\n"
+                    + "<name>nomigrate</name>\n" + "<value><string>\n"
+                    + "</string></value>\n" + "</member>\n"
+                    + "</struct></value>\n" + "</member>\n" + "<member>\n"
+                    + "<name>cpus</name>\n" + "<value><array><data>\n"
+                    + "<value><array><data>\n" + "</data></array></value>\n"
+                    + "</data></array></value>\n" + "</member>\n"
+                    + "<member>\n" + "<name>store_mfn</name>\n"
+                    + "<value><string>873707</string></value>\n"
+                    + "</member>\n" + "<member>\n" + "<name>uuid</name>\n"
+                    + "<value><string>"
+                    + VMID
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>on_reboot</name>\n"
+                    + "<value><string>restart</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>state</name>\n"
+                    + "<value><string>-b----</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>cpu_weight</name>\n"
+                    + "<value><string>27500</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>online_vcpus</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>memory</name>\n"
+                    + "<value><string>512</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>cpu_cap</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>status</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>pool_name</name>\n"
+                    + "<value><string>Pool-0</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>description</name>\n"
+                    + "<value><string></string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>start_time</name>\n"
+                    + "<value><string>1408105444.17</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>on_poweroff</name>\n"
+                    + "<value><string>destroy</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>on_xend_start</name>\n"
+                    + "<value><string>ignore</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>on_crash</name>\n"
+                    + "<value><string>restart</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>device</name>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>vif</name>\n"
+                    + "<value><array><data>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>bridge</name>\n"
+                    + "<value><string>"+VMNICBR+"</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>mac</name>\n"
+                    + "<value><string>" + VMNICMAC + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>script</name>\n"
+                    + "<value><string>/etc/xen/scripts/vif-bridge</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>uuid</name>\n"
+                    + "<value><string>"+VMNICUUID+"</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>backend</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "</struct></value>\n"
+                    + "</data></array></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>vkbd</name>\n"
+                    + "<value><array><data>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>backend</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "</struct></value>\n"
+                    + "</data></array></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>console</name>\n"
+                    + "<value><array><data>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>protocol</name>\n"
+                    + "<value><string>vt100</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>location</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>uuid</name>\n"
+                    + "<value><string>9beb5016-dde7-8526-491f-e972f262a634</string></value>\n"
+                    + "</member>\n"
+                    + "</struct></value>\n"
+                    + "</data></array></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>vfb</name>\n"
+                    + "<value><array><data>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>vncunused</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>vnc</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>xauthority</name>\n"
+                    + "<value><string>/root/.Xauthority</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>vnclisten</name>\n"
+                    + "<value><string>0.0.0.0</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>vncpasswd</name>\n"
+                    + "<value><string>7693f834ca67912e</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>keymap</name>\n"
+                    + "<value><string>en-us</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>location</name>\n"
+                    + "<value><string>0.0.0.0:5900</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>uuid</name>\n"
+                    + "<value><string>78edf954-e375-b142-9c76-791ce805b6ef</string></value>\n"
+                    + "</member>\n"
+                    + "</struct></value>\n"
+                    + "</data></array></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>vbd</name>\n"
+                    + "<value><array><data>\n"
+                    + "<value><struct>\n"
+                    + "<member>\n"
+                    + "<name>protocol</name>\n"
+                    + "<value><string>x86_32-abi</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>uuid</name>\n"
+                    + "<value><string>bda35954-2596-025e-168c-b82e1cf92369</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>bootable</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>dev</name>\n"
+                    + "<value><string>xvda:disk</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>uname</name>\n"
+                    + "<value><string>file:/OVS/Repositories/"
+                    + REPOID
+                    + "/VirtualDisks/"
+                    + VMROOTDISK
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>mode</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>VDI</name>\n"
+                    + "<value><string></string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>backend</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "</struct></value>\n"
+                    + "</data></array></value>\n"
+                    + "</member>\n"
+                    + "</struct></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>bootloader</name>\n"
+                    + "<value><string>/usr/bin/pygrub</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>maxmem</name>\n"
+                    + "<value><string>512</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>cpu_time</name>\n"
+                    + "<value><string>0.152510481</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>shadow_memory</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>name</name>\n"
+                    + "<value><string>"
+                    + VMNAME
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>builder</name>\n"
+                    + "<value><string>linux</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>bootloader_args</name>\n"
+                    + "<value><string>-q</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>domid</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n"
+                    + "<member>\n"
+                    + "<name>vcpus</name>\n"
+                    + "<value><string>\n"
+                    + "</string></value>\n"
+                    + "</member>\n" + "</struct></value>\n" + "</data></array>");
+
+    public String getSingleVmListXML() {
+        return SINGLEVMLISTXML;
+    }
+    String SINGLEVMLISTXML = results
+            .simpleResponseWrapWrapper("<struct>"
+                    + "<member>"
+                    + "<name>on_xend_stop</name>"
+                    + "<value><string>ignore</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>console_mfn</name>"
+                    + "<value><string>873706</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>features</name>"
+                    + "<value><string></string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>image</name>"
+                    + "<value><struct>"
+                    + "<member>"
+                    + "<name>tsc_mode</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>kernel</name>"
+                    + "<value><string></string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>videoram</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>device_model</name>"
+                    + "<value><string>/usr/lib/xen/bin/qemu-dm</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>notes</name>"
+                    + "<value><array><data>"
+                    + "<value><array><data>"
+                    + "<value><string>HV_START_LOW</string></value>"
+                    + "<value><string>4118806528</string></value>"
+                    + "</data></array></value>"
+                    + "<value><array><data>"
+                    + "<value><string>FEATURES</string></value>"
+                    + "<value><string>!writable_page_tables|pae_pgdir_above_4gb</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>VIRT_BASE</string></value>"
+                    + "<value><string>3221225472</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>GUEST_VERSION</string></value>"
+                    + "<value><string>2.6</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>PADDR_OFFSET</string></value>"
+                    + "<value><string>" + "</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>GUEST_OS</string></value>"
+                    + "<value><string>linux</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>HYPERCALL_PAGE</string></value>"
+                    + "<value><string>3238010880</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>LOADER</string></value>"
+                    + "<value><string>generic</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>SUSPEND_CANCEL</string></value>"
+                    + "<value><string>" + "</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>PAE_MODE</string></value>"
+                    + "<value><string>yes</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>ENTRY</string></value>"
+                    + "<value><string>3242303488</string></value>"
+                    + "</data></array></value>" + "<value><array><data>"
+                    + "<value><string>XEN_VERSION</string></value>"
+                    + "<value><string>xen-3.0</string></value>"
+                    + "</data></array></value>" + "</data></array></value>"
+                    + "</member>" + "<member>"
+                    + "<name>expose_host_uuid</name>" + "<value><string>"
+                    + "</string></value>" + "</member>" + "<member>"
+                    + "<name>pci</name>" + "<value><array><data>"
+                    + "</data></array></value>" + "</member>" + "<member>"
+                    + "<name>superpages</name>" + "<value><string>"
+                    + "</string></value>" + "</member>" + "<member>"
+                    + "<name>nomigrate</name>" + "<value><string>"
+                    + "</string></value>" + "</member>" + "</struct></value>"
+                    + "</member>" + "<member>" + "<name>cpus</name>"
+                    + "<value><array><data>" + "<value><array><data>"
+                    + "</data></array></value>" + "</data></array></value>"
+                    + "</member>" + "<member>" + "<name>store_mfn</name>"
+                    + "<value><string>873707</string></value>" + "</member>"
+                    + "<member>" + "<name>uuid</name>" + "<value><string>"
+                    + VMID
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>on_reboot</name>"
+                    + "<value><string>restart</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>state</name>"
+                    + "<value><string>-b----</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>cpu_weight</name>"
+                    + "<value><string>27500</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>online_vcpus</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>memory</name>"
+                    + "<value><string>512</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>cpu_cap</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>status</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>pool_name</name>"
+                    + "<value><string>Pool-0</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>description</name>"
+                    + "<value><string></string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>start_time</name>"
+                    + "<value><string>1408105444.17</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>on_poweroff</name>"
+                    + "<value><string>destroy</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>on_xend_start</name>"
+                    + "<value><string>ignore</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>on_crash</name>"
+                    + "<value><string>restart</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>device</name>"
+                    + "<value><struct>"
+                    + "<member>"
+                    + "<name>vif</name>"
+                    + "<value><array><data>"
+                    + "<value><struct>"
+                    + "<member>"
+                    + "<name>bridge</name>"
+                    + "<value><string>"+VMNICBR+"</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>mac</name>"
+                    + "<value><string>"+VMNICMAC+"</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>script</name>"
+                    + "<value><string>/etc/xen/scripts/vif-bridge</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>uuid</name>"
+                    + "<value><string>"+VMNICUUID+"</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>backend</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "</struct></value>"
+                    + "</data></array></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>vkbd</name>"
+                    + "<value><array><data>"
+                    + "<value><struct>"
+                    + "<member>"
+                    + "<name>backend</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "</struct></value>"
+                    + "</data></array></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>console</name>"
+                    + "<value><array><data>"
+                    + "<value><struct>"
+                    + "<member>"
+                    + "<name>protocol</name>"
+                    + "<value><string>vt100</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>location</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>uuid</name>"
+                    + "<value><string>9beb5016-dde7-8526-491f-e972f262a634</string></value>"
+                    + "</member>"
+                    + "</struct></value>"
+                    + "</data></array></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>vfb</name>"
+                    + "<value><array><data>"
+                    + "<value><struct>"
+                    + "<member>"
+                    + "<name>vncunused</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>vnc</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>xauthority</name>"
+                    + "<value><string>/root/.Xauthority</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>vnclisten</name>"
+                    + "<value><string>0.0.0.0</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>vncpasswd</name>"
+                    + "<value><string>7693f834ca67912e</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>keymap</name>"
+                    + "<value><string>en-us</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>location</name>"
+                    + "<value><string>0.0.0.0:5900</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>uuid</name>"
+                    + "<value><string>78edf954-e375-b142-9c76-791ce805b6ef</string></value>"
+                    + "</member>"
+                    + "</struct></value>"
+                    + "</data></array></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>vbd</name>"
+                    + "<value><array><data>"
+                    + "<value><struct>"
+                    + "<member>"
+                    + "<name>protocol</name>"
+                    + "<value><string>x86_32-abi</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>uuid</name>"
+                    + "<value><string>bda35954-2596-025e-168c-b82e1cf92369</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>bootable</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>dev</name>"
+                    + "<value><string>xvda:disk</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>uname</name>"
+                    + "<value><string>file:/OVS/Repositories/"
+                    + REPOID
+                    + "/VirtualDisks/"
+                    + VMROOTDISK
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>mode</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>VDI</name>"
+                    + "<value><string></string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>backend</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "</struct></value>"
+                    + "</data></array></value>"
+                    + "</member>"
+                    + "</struct></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>bootloader</name>"
+                    + "<value><string>/usr/bin/pygrub</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>maxmem</name>"
+                    + "<value><string>512</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>cpu_time</name>"
+                    + "<value><string>5.627111952</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>shadow_memory</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>name</name>"
+                    + "<value><string>"
+                    + VMNAME
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>builder</name>"
+                    + "<value><string>linux</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>bootloader_args</name>"
+                    + "<value><string>-q</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>domid</name>"
+                    + "<value><string>"
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>vcpus</name>"
+                    + "<value><string>"
+                    + "</string></value>" + "</member>" + "</struct>");
+
+    public String getSingleVmConfigXML() {
+        return this.SINGLEVMCONFIGXML;
+    }
+    String SINGLEVMCONFIGXML = results
+            .simpleResponseWrapWrapper("<struct>"
+                    + "<member>"
+                    + "<name>vif</name>"
+                    + "<value><array><data>"
+                    + "<value><string>mac="+VMNICMAC+",bridge="+VMNICBR+"</string></value>"
+                    + "<value><string>mac=02:00:50:9a:00:02,bridge=xenbr0.240</string></value>"
+                    + "</data></array></value>" + "</member>" + "<member>"
+                    + "<name>extra</name>" + "<value><string></string></value>"
+                    + "</member>" + "<member>" + "<name>OVM_simple_name</name>"
+                    + "<value><string>"
+                    + VMNAME
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>disk</name>"
+                    + "<value><array><data>"
+                    + "<value><string>file:/OVS/Repositories/"
+                    + REPOID
+                    + "/VirtualDisks/"
+                    + VMROOTDISK
+                    + ",xvda,w</string></value>"
+                    + "</data></array></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>bootargs</name>"
+                    + "<value><string></string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>uuid</name>"
+                    + "<value><string>"
+                    + VMID
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>on_reboot</name>"
+                    + "<value><string>restart</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>cpu_weight</name>"
+                    + "<value><int>27500</int></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>memory</name>"
+                    + "<value><int>512</int></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>cpu_cap</name>"
+                    + "<value><int>0</int></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>maxvcpus</name>"
+                    + "<value><int>1</int></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>OVM_high_availability</name>"
+                    + "<value><boolean>0</boolean></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>OVM_description</name>"
+                    + "<value><string></string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>on_poweroff</name>"
+                    + "<value><string>destroy</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>on_crash</name>"
+                    + "<value><string>restart</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>bootloader</name>"
+                    + "<value><string>/usr/bin/pygrub</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>guest_os_type</name>"
+                    + "<value><string>Other.Linux</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>name</name>"
+                    + "<value><string>"
+                    + VMNAME
+                    + "</string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>vfb</name>"
+                    + "<value><array><data>"
+                    + "<value><string>vncunused=1,vncpasswd=7693f834ca67912e,keymap=en-us,type=vnc,vnclisten=0.0.0.0</string></value>"
+                    + "</data></array></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>vcpus</name>"
+                    + "<value><int>1</int></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>OVM_cpu_compat_group</name>"
+                    + "<value><string></string></value>"
+                    + "</member>"
+                    + "<member>"
+                    + "<name>OVM_domain_type</name>"
+                    + "<value><string>xen_pvm</string></value>"
+                    + "</member>"
+                    + "</struct>");
+
+    /* fix */
+    @Test
+    public void testListVm() throws Ovm3ResourceException {
+        con.setResult(this.SINGLEVMLISTXML);
+        results.basicBooleanTest(xEn.listVm(REPOID, VMID));
+        con.setResult(results.getNil());
+        results.basicBooleanTest(xEn.listVm(REPOID, VMID), false);
+    }
+
+    @Test
+    public void testGetRunningVmConfig() throws Ovm3ResourceException {
+        con.setResult(this.MULTIPLEVMSLISTXML);
+        Xen.Vm domU = xEn.getRunningVmConfig(VMNAME);
+
+        /* only works from a live configuration */
+        results.basicStringTest(domU.getVmRootDiskPoolId(), REPOID);
+        results.basicIntTest(domU.getVncPort(), 5900);
+        results.basicStringTest(domU.getVncAddress(), "0.0.0.0");
+    }
+
+    @Test
+    public void testGetVmConfig() throws Ovm3ResourceException {
+        con.setResult(this.SINGLEVMCONFIGXML);
+        Xen.Vm domU = xEn.getVmConfig(REPOID, VMID);
+        /* getVncPort doesn't work with live config due to a bug in the agent */
+        // results.basicIntTest(domU.getVncPort(), 5900);
+        results.basicStringTest(domU.getVmName(), VMNAME);
+        results.basicIntTest(domU.getVifIdByMac(VMNICMAC), 0);
+        results.basicIntTest(domU.getVifIdByMac("02:00:50:9a:00:02"), 1);
+        results.basicIntTest(domU.getVifIdByMac("02:00:50:9a:00:03"), -1);
+        con.setResult(results.getNil());
+        xEn.getVmConfig(REPOID, VMID);
+
+        con.setResult(results.getNil());
+    }
+
+    @Test
+    public void testRebootVM() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(xEn.rebootVm(REPOID, VMID));
+        results.basicBooleanTest(xEn.rebootVm(REPOID, VMID, 1));
+    }
+
+    @Test
+    public void testControlDomain() throws Ovm3ResourceException {
+        con.setResult(this.MULTIPLEVMSLISTXML);
+        Xen.Vm dom0 = xEn.getRunningVmConfig(DOM0VMNAME);
+        results.basicBooleanTest(dom0.isControlDomain(), true);
+        Xen.Vm domU = xEn.getRunningVmConfig(VMNAME);
+        results.basicBooleanTest(domU.isControlDomain(), false);
+        con.setResult(results.getNil());
+    }
+
+    @Test
+    public void testCreateVm() throws Ovm3ResourceException {
+        Xen.Vm domU = xEn.getVmConfig();
+        domU.setVmCpus(1);
+        domU.setVmMemory(512);
+        domU.setVmDomainType("default");
+        domU.setVmUuid(UUID.nameUUIDFromBytes(VMNAME.getBytes()).toString());
+        domU.setVmName(VMNAME);
+        domU.addRootDisk(VMROOTDISK);
+        domU.setPrimaryPoolUuid(REPOID);
+
+        domU.addVif(0, VMNICBR, VMNICMAC);
+        domU.addVif(0, "xenbr0.240", "02:00:50:9a:00:02");
+        domU.removeVif("xenbr0.240", "02:00:50:9a:00:02");
+        domU.setVnc("0.0.0.0", "gobbeldygoo");
+        con.setResult(results.getNil());
+        xEn.createVm(REPOID, VMID);
+        xEn.configureVmHa(REPOID, VMID, true);
+        xEn.startVm(REPOID, VMID);
+
+        domU.addIso(VMISO);
+        domU.addIso(VMISO);
+        xEn.configureVm(REPOID, domU.getVmUuid());
+        domU.removeDisk(VMISO);
+        domU.removeDisk("bogus");
+        domU.getVmVifs();
+        xEn.configureVm(REPOID, domU.getVmUuid());
+        xEn.stopVm(REPOID, VMID, true);
+
+        Xen.Vm domU2 = xEn.getVmConfig();
+        domU2.setVmDomainType("hvm");
+        domU2.addRootDisk(VMROOTDISK);
+        domU2.addDataDisk(VMROOTDISK);
+        domU2.getPrimaryPoolUuid();
+    }
+
+    @Test
+    public void testRemoveMissingVif() throws Ovm3ResourceException {
+        Xen.Vm domU = xEn.getVmConfig();
+        domU.removeVif("xenbr0.240", "02:00:50:9a:00:02");
+    }
+
+    @Test
+    public void testVmDomainType() throws Ovm3ResourceException {
+        Xen.Vm domU = xEn.getVmConfig();
+        domU.getVmDomainType();
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testMissingVncPort() throws Ovm3ResourceException {
+        Xen.Vm domU = xEn.getVmConfig();
+        domU.getVncPort();
+    }
+
+    @Test
+    public void testVmCpusExceedsMaxVCPUs() throws Ovm3ResourceException {
+        Xen.Vm domU = xEn.getVmConfig();
+        domU.setVmMaxCpus(2);
+        results.basicIntTest(domU.getVmMaxCpus(), 2);
+        domU.setVmCpus(4);
+        results.basicIntTest(domU.getVmCpus(), 2);
+        domU.setVmMaxCpus(12);
+        results.basicIntTest(domU.getVmCpus(), 2);
+        domU.setVmCpus(12);
+        results.basicIntTest(domU.getVmCpus(), 12);
+        domU.setVmMaxCpus(0);
+        results.basicIntTest(domU.getVmCpus(), 12);
+    }
+
+    @Test
+    public void testStopVm() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(xEn.stopVm(REPOID, VMID));
+        results.basicBooleanTest(xEn.stopVm(REPOID, VMID, true));
+    }
+
+    @Test
+    public void testPauseVm() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(xEn.pauseVm(REPOID, VMID));
+    }
+
+    public String getMultipleVmsListXML() {
+        return MULTIPLEVMSLISTXML;
+    }
+    public String getVmName() {
+        return VMNAME;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/XmlTestResultTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/XmlTestResultTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/XmlTestResultTest.java
new file mode 100644
index 0000000..a1dc49b
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/XmlTestResultTest.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringEscapeUtils;
+
+public class XmlTestResultTest {
+    private static final String NULL = "<nil/>";
+
+    private String brack(String type, String s) {
+        return "<" + type + ">" + s + "</" + type + ">";
+    }
+
+    public String escapeOrNot(String s) {
+        if (s.startsWith("<")) {
+            return StringEscapeUtils.escapeXml(s);
+        }
+        return s;
+    }
+
+    public String errorResponseWrap(String message) {
+        return errorResponseWrap(1, message);
+    }
+
+    /*
+     * example exceptions.OSError:[Errno.17].File.exists:
+     * '/OVS/Repositories/f12842ebf5ed3fe78da1eb0e17f5ede8/VilualDisks/test.raw'
+     */
+    public String errorResponseWrap(Integer faultCode, String message) {
+        String rs = "<?xml version='1.0'?>" + "<methodResponse>" + "<fault>"
+                + "<value><struct>" + "<member>" + "<name>faultCode</name>"
+                + "<value><int>" + faultCode + "</int></value>" + "</member>"
+                + "<member>" + "<name>faultString</name>" + "<value><string>"
+                + message + "</string></value>" + "</member>"
+                + "</struct></value>" + "</fault>" + "</methodResponse>";
+        return rs;
+    }
+
+    public String methodResponseWrap(String towrap) {
+        return "<?xml version='1.0'?>\n" + "<methodResponse>\n" + "<params>\n"
+                + towrap + "</params>\n" + "</methodResponse>";
+    }
+
+    public String simpleResponseWrapWrapper(String s) {
+        return methodResponseWrap("<param>\n" + "<value>" + s + "</value>\n"
+                + "</param>\n");
+    }
+
+    /* brack the entire wrap ? :) */
+    public String simpleResponseWrap(String type, String s) {
+        if (type.contentEquals(NULL)) {
+            s = NULL;
+        } else {
+            s = brack(type, s);
+        }
+        return simpleResponseWrapWrapper(s);
+    }
+
+    public String simpleResponseWrap(String s) {
+        return simpleResponseWrapWrapper(s);
+    }
+
+    public String getBoolean(boolean bool) {
+        String b = "1";
+        if (!bool) {
+            b = "0";
+        }
+        return simpleResponseWrap("boolean", b);
+    }
+
+    public String getString(String s) {
+        return simpleResponseWrap("string", s);
+    }
+
+    public String getNil() {
+        return simpleResponseWrap(NULL, NULL);
+    }
+
+    public void basicBooleanTest(boolean result) {
+        basicBooleanTest(result, true);
+    }
+
+    public void basicBooleanTest(boolean result, boolean desired) {
+        assertNotNull(result);
+        assertEquals(desired, result);
+    }
+
+    public void basicStringTest(String result, String desired) {
+        assertNotNull(result);
+        assertEquals(desired, result);
+    }
+
+    public void basicIntTest(Integer result, Integer desired) {
+        assertNotNull(result);
+        assertEquals(desired, result);
+    }
+
+    public void basicLongTest(Long result, Long desired) {
+        assertEquals(desired, result);
+    }
+
+    public Boolean basicListHasString(List<String> list, String x) {
+        for (String y : list) {
+            if (y.matches(x)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void basicDoubleTest(Double result, Double desired) {
+        assertEquals(desired, result);
+    }
+}


[06/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/CommonTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/CommonTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/CommonTest.java
new file mode 100644
index 0000000..23df823
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/CommonTest.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import org.junit.Test;
+
+public class CommonTest {
+    ConnectionTest con = new ConnectionTest();
+    Common cOm = new Common(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+    String echo = "put";
+    String remoteUrl = "http://oracle:password@ovm-2:8899";
+
+    @Test
+    public void testGetApiVersion() throws Ovm3ResourceException {
+        con.setResult(results
+                .simpleResponseWrap("<array><data>\n<value><int>3</int></value>\n</data></array>"));
+        results.basicIntTest(cOm.getApiVersion(), 3);
+    }
+
+    @Test
+    public void testSleep() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(cOm.sleep(1));
+    }
+
+    @Test
+    public void testDispatch() throws Ovm3ResourceException {
+        con.setResult(results.getString(echo));
+        results.basicStringTest(cOm.dispatch(remoteUrl, "echo", echo), echo);
+    }
+
+    @Test
+    public void testEcho() throws Ovm3ResourceException {
+        con.setResult(results.getString(echo));
+        results.basicStringTest(cOm.echo(echo), echo);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/ConnectionTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/ConnectionTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/ConnectionTest.java
new file mode 100644
index 0000000..5faaea8
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/ConnectionTest.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.xmlrpc.client.XmlRpcClient;
+import org.apache.xmlrpc.common.XmlRpcHttpRequestConfigImpl;
+import org.apache.xmlrpc.common.XmlRpcStreamConfig;
+import org.apache.xmlrpc.common.XmlRpcStreamRequestConfig;
+import org.apache.xmlrpc.parser.XmlRpcResponseParser;
+import org.apache.xmlrpc.util.SAXParsers;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+/*
+ * This is a stub for XML parsing into result sets, it also contains test for
+ * Connection
+ */
+public class ConnectionTest extends Connection {
+    private final Logger LOGGER = Logger.getLogger(ConnectionTest.class);
+    XmlTestResultTest results = new XmlTestResultTest();
+    String result;
+    List<String> multiRes = new ArrayList<String>();
+    String hostIp;
+    private Map<String, String> methodResponse = new HashMap<String, String>();
+
+    public ConnectionTest() {
+    }
+
+    @Override
+    public Object callTimeoutInSec(String method, List<?> params, int timeout,
+            boolean debug) throws XmlRpcException {
+        XmlRpcStreamConfig config = new XmlRpcHttpRequestConfigImpl();
+        XmlRpcClient client = new XmlRpcClient();
+        client.setTypeFactory(new RpcTypeFactory(client));
+        XmlRpcResponseParser parser = new XmlRpcResponseParser(
+                (XmlRpcStreamRequestConfig) config, client.getTypeFactory());
+        XMLReader xr = SAXParsers.newXMLReader();
+        xr.setContentHandler(parser);
+        try {
+            String result = null;
+            if (getMethodResponse(method) != null) {
+                result = getMethodResponse(method);
+                LOGGER.debug("methodresponse call: " + method + " - " + params);
+                LOGGER.trace("methodresponse reply: " + result);
+            }
+            if (result == null && multiRes.size() >= 0) {
+                result = getResult();
+                LOGGER.debug("getresult call: " + method + " - " + params);
+                LOGGER.trace("getresult reply: " + result);
+            }
+            xr.parse(new InputSource(new StringReader(result)));
+        } catch (Exception e) {
+            throw new XmlRpcException("Exception: " + e.getMessage(), e);
+        }
+        if (parser.getErrorCode() != 0) {
+            throw new XmlRpcException("Fault received[" + parser.getErrorCode()
+                    + "]: " + parser.getErrorMessage());
+        }
+        return parser.getResult();
+    }
+
+    public void setMethodResponse(String method, String response) {
+        methodResponse.put(method, response);
+    }
+
+    public String getMethodResponse(String method) {
+        if (methodResponse.containsKey(method)) {
+            return methodResponse.get(method);
+        }
+        return null;
+    }
+
+    public void removeMethodResponse(String method) {
+        if (methodResponse.containsKey(method)) {
+            methodResponse.remove(method);
+        }
+    }
+
+    public void setResult(String res) {
+        multiRes = new ArrayList<String>();
+        multiRes.add(0, res);
+    }
+
+    public void setResult(List<String> l) {
+        multiRes = new ArrayList<String>();
+        multiRes.addAll(l);
+    }
+
+    public void setNull() {
+        multiRes = new ArrayList<String>();
+        multiRes.add(0, null);
+    }
+
+    /* result chainsing */
+    public void addResult(String e) {
+        multiRes.add(e);
+    }
+
+    public void addNull() {
+        multiRes.add(null);
+    }
+
+    public String getResult() {
+        return popResult();
+    }
+
+    public String popResult() {
+        String res = multiRes.get(0);
+        if (multiRes.size() > 1)
+            multiRes.remove(0);
+        return res;
+    }
+
+    public List<String> resultList() {
+        return multiRes;
+    }
+
+    @Test
+    public void testConnection() {
+        String host = "ovm-1";
+        String user = "admin";
+        String pass = "password";
+        Integer port = 8899;
+        List<?> emptyParams = new ArrayList<Object>();
+        Connection con = new Connection(host, port, user, pass);
+        results.basicStringTest(con.getIp(), host);
+        results.basicStringTest(con.getUserName(), user);
+        results.basicStringTest(con.getPassword(), pass);
+        results.basicIntTest(con.getPort(), port);
+        try {
+            con.callTimeoutInSec("ping", emptyParams, 1);
+            // con.call("ping", emptyParams, 1, false);
+        } catch (XmlRpcException e) {
+            // TODO Auto-generated catch block
+            System.out.println("Exception: " + e);
+        }
+        new Connection(host, user, pass);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/LinuxTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/LinuxTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/LinuxTest.java
new file mode 100644
index 0000000..4c41960
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/LinuxTest.java
@@ -0,0 +1,643 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import org.junit.Test;
+
+public class LinuxTest {
+    public LinuxTest() {
+    }
+    ConnectionTest con = new ConnectionTest();
+    Linux lin = new Linux(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    private final String DISCOVERSERVER = "&lt;?xml version=\"1.0\" ?&gt;"
+            + "&lt;Discover_Server_Result&gt;"
+            + "&lt;Server&gt;"
+            + "&lt;Unique_Id&gt;1d:d5:e8:91:d9:d0:ed:bd:81:c2:a6:9a:b3:d1:b7:ea&lt;/Unique_Id&gt;"
+            + "&lt;Boot_Time&gt;1413834408&lt;/Boot_Time&gt;"
+            + "&lt;Date_Time&gt;"
+            + "&lt;Time_Zone&gt;Europe/Amsterdam&lt;/Time_Zone&gt;"
+            + "&lt;UTC&gt;True&lt;/UTC&gt;"
+            + "&lt;/Date_Time&gt;"
+            + "&lt;NTP&gt;"
+            + "&lt;Local_Time_Source&gt;True&lt;/Local_Time_Source&gt;"
+            + "&lt;Is_NTP_Running&gt;True&lt;/Is_NTP_Running&gt;"
+            + "&lt;/NTP&gt;"
+            + "&lt;Agent_Version&gt;3.2.1-183&lt;/Agent_Version&gt;"
+            + "&lt;RPM_Version&gt;3.2.1-183&lt;/RPM_Version&gt;"
+            + "&lt;OVM_Version&gt;3.2.1-517&lt;/OVM_Version&gt;"
+            + "&lt;CPU_Type&gt;x86_64&lt;/CPU_Type&gt;"
+            + "&lt;OS_Type&gt;Linux&lt;/OS_Type&gt;"
+            + "&lt;OS_Name&gt;Oracle VM Server&lt;/OS_Name&gt;"
+            + "&lt;OS_Major_Version&gt;5&lt;/OS_Major_Version&gt;"
+            + "&lt;OS_Minor_Version&gt;7&lt;/OS_Minor_Version&gt;"
+            + "&lt;Hypervisor_Type&gt;xen&lt;/Hypervisor_Type&gt;"
+            + "&lt;Hypervisor_Name&gt;Xen&lt;/Hypervisor_Name&gt;"
+            + "&lt;Host_Kernel_Release&gt;2.6.39-300.22.2.el5uek&lt;/Host_Kernel_Release&gt;"
+            + "&lt;Host_Kernel_Version&gt;#1 SMP Fri Jan 4 12:40:29 PST 2013&lt;/Host_Kernel_Version&gt;"
+            + "&lt;VMM&gt;"
+            + "&lt;Version&gt;"
+            + "&lt;Major&gt;4&lt;/Major&gt;"
+            + "&lt;Minor&gt;1&lt;/Minor&gt;"
+            + "&lt;Extra&gt;.3OVM&lt;/Extra&gt;"
+            + "&lt;/Version&gt;"
+            + "&lt;Compile_Information&gt;"
+            + "&lt;Compiler&gt;gcc version 4.1.2 20080704 (Red Hat 4.1.2-48)&lt;/Compiler&gt;"
+            + "&lt;By&gt;mockbuild&lt;/By&gt;"
+            + "&lt;Domain&gt;us.oracle.com&lt;/Domain&gt;"
+            + "&lt;Date&gt;Wed Dec  5 09:11:29 PST 2012&lt;/Date&gt;"
+            + "&lt;/Compile_Information&gt;"
+            + "&lt;Capabilities&gt;xen-3.0-x86_64 xen-3.0-x86_32p&lt;/Capabilities&gt;"
+            + "&lt;/VMM&gt;"
+            + "&lt;Pool_Unique_Id&gt;f12842eb-f5ed-3fe7-8da1-eb0e17f5ede8&lt;/Pool_Unique_Id&gt;"
+            + "&lt;Manager_Unique_Id&gt;d1a749d4295041fb99854f52ea4dea97&lt;/Manager_Unique_Id&gt;"
+            + "&lt;Hostname&gt;ovm-1&lt;/Hostname&gt;"
+            + "&lt;Registered_IP&gt;192.168.1.64&lt;/Registered_IP&gt;"
+            + "&lt;Node_Number&gt;1&lt;/Node_Number&gt;"
+            + "&lt;Server_Roles&gt;xen,utility&lt;/Server_Roles&gt;"
+            + "&lt;Is_Current_Master&gt;true&lt;/Is_Current_Master&gt;"
+            + "&lt;Master_Virtual_Ip&gt;192.168.1.230&lt;/Master_Virtual_Ip&gt;"
+            + "&lt;Manager_Core_API_Version&gt;3.2.1.516&lt;/Manager_Core_API_Version&gt;"
+            + "&lt;Membership_State&gt;Pooled&lt;/Membership_State&gt;"
+            + "&lt;Cluster_State&gt;Offline&lt;/Cluster_State&gt;"
+            + "&lt;Statistic&gt;"
+            + "&lt;Interval&gt;20&lt;/Interval&gt;"
+            + "&lt;/Statistic&gt;"
+            + "&lt;Exports/&gt;"
+            + "&lt;Capabilities&gt;"
+            + "&lt;ISCSI&gt;True&lt;/ISCSI&gt;"
+            + "&lt;BOND_MODE_LINK_AGGREGATION&gt;True&lt;/BOND_MODE_LINK_AGGREGATION&gt;"
+            + "&lt;POWER_ON_WOL&gt;True&lt;/POWER_ON_WOL&gt;"
+            + "&lt;ALL_VM_CPU_OVERSUBSCRIBE&gt;True&lt;/ALL_VM_CPU_OVERSUBSCRIBE&gt;"
+            + "&lt;HVM_MAX_VNICS&gt;8&lt;/HVM_MAX_VNICS&gt;"
+            + "&lt;FIBRE_CHANNEL&gt;True&lt;/FIBRE_CHANNEL&gt;"
+            + "&lt;MAX_CONCURRENT_MIGRATION_OUT&gt;1&lt;/MAX_CONCURRENT_MIGRATION_OUT&gt;"
+            + "&lt;LOCAL_STORAGE_ELEMENT&gt;True&lt;/LOCAL_STORAGE_ELEMENT&gt;"
+            + "&lt;CLUSTERS&gt;True&lt;/CLUSTERS&gt;"
+            + "&lt;CONCURRENT_MIGRATION&gt;False&lt;/CONCURRENT_MIGRATION&gt;"
+            + "&lt;VM_MEMORY_ALIGNMENT&gt;1048576&lt;/VM_MEMORY_ALIGNMENT&gt;"
+            + "&lt;MIGRATION_SETUP&gt;False&lt;/MIGRATION_SETUP&gt;"
+            + "&lt;PER_VM_CPU_OVERSUBSCRIBE&gt;True&lt;/PER_VM_CPU_OVERSUBSCRIBE&gt;"
+            + "&lt;BOND_MODE_ACTIVE_BACKUP&gt;True&lt;/BOND_MODE_ACTIVE_BACKUP&gt;"
+            + "&lt;NFS&gt;True&lt;/NFS&gt;"
+            + "&lt;VM_VNC_CONSOLE&gt;True&lt;/VM_VNC_CONSOLE&gt;"
+            + "&lt;MTU_CONFIGURATION&gt;True&lt;/MTU_CONFIGURATION&gt;"
+            + "&lt;HIGH_AVAILABILITY&gt;True&lt;/HIGH_AVAILABILITY&gt;"
+            + "&lt;MAX_CONCURRENT_MIGRATION_IN&gt;1&lt;/MAX_CONCURRENT_MIGRATION_IN&gt;"
+            + "&lt;VM_SERIAL_CONSOLE&gt;True&lt;/VM_SERIAL_CONSOLE&gt;"
+            + "&lt;BOND_MODE_ADAPTIVE_LOAD_BALANCING&gt;True&lt;/BOND_MODE_ADAPTIVE_LOAD_BALANCING&gt;"
+            + "&lt;VM_SUSPEND&gt;True&lt;/VM_SUSPEND&gt;"
+            + "&lt;YUM_PACKAGE_MANAGEMENT&gt;True&lt;/YUM_PACKAGE_MANAGEMENT&gt;"
+            + "&lt;/Capabilities&gt;" + "&lt;/Server&gt;"
+            + "&lt;/Discover_Server_Result&gt;";
+
+    public String getDiscoverserver() {
+        return DISCOVERSERVER;
+    }
+
+    public String getDiscoverHw() {
+        return DISCOVERHW;
+    }
+
+    public String getDiscoverFs() {
+        return DISCOVERFS;
+    }
+
+    private final String DISCOVERHW = "&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;"
+            + "&lt;Discover_Hardware_Result&gt;"
+            + "&lt;NodeInformation&gt;"
+            + "&lt;VMM&gt;"
+            + "&lt;PhysicalInfo&gt;"
+            + "&lt;ThreadsPerCore&gt;1&lt;/ThreadsPerCore&gt;"
+            + "&lt;CoresPerSocket&gt;1&lt;/CoresPerSocket&gt;"
+            + "&lt;SocketsPerNode&gt;2&lt;/SocketsPerNode&gt;"
+            + "&lt;Nodes&gt;1&lt;/Nodes&gt;"
+            + "&lt;CPUKHz&gt;3392400&lt;/CPUKHz&gt;"
+            + "&lt;TotalPages&gt;1048476&lt;/TotalPages&gt;"
+            + "&lt;FreePages&gt;863459&lt;/FreePages&gt;"
+            + "&lt;HW_Caps&gt;"
+            + "&lt;Item_0&gt;0x0f8bf3ff&lt;/Item_0&gt;"
+            + "&lt;Item_1&gt;0x28100800&lt;/Item_1&gt;"
+            + "&lt;Item_2&gt;0x00000000&lt;/Item_2&gt;"
+            + "&lt;Item_3&gt;0x00000040&lt;/Item_3&gt;"
+            + "&lt;Item_4&gt;0xb19a2223&lt;/Item_4&gt;"
+            + "&lt;Item_5&gt;0x00000000&lt;/Item_5&gt;"
+            + "&lt;Item_6&gt;0x00000001&lt;/Item_6&gt;"
+            + "&lt;Item_7&gt;0x00000281&lt;/Item_7&gt;"
+            + "&lt;/HW_Caps&gt;"
+            + "&lt;/PhysicalInfo&gt;"
+            + "&lt;/VMM&gt;"
+            + "&lt;CPUInfo&gt;"
+            + "&lt;Proc_Info&gt;"
+            + "&lt;CPU ID=\"0\"&gt;"
+            + "&lt;vendor_id&gt;GenuineIntel&lt;/vendor_id&gt;"
+            + "&lt;cpu_family&gt;6&lt;/cpu_family&gt;"
+            + "&lt;model&gt;2&lt;/model&gt;"
+            + "&lt;model_name&gt;Intel Core i7 9xx (Nehalem Class Core i7)&lt;/model_name&gt;"
+            + "&lt;stepping&gt;3&lt;/stepping&gt;"
+            + "&lt;cache_size&gt;4096 KB&lt;/cache_size&gt;"
+            + "&lt;flags&gt;fpu de tsc msr pae mce cx8 apic mca cmov clflush mmx fxsr sse sse2 ss syscall nx lm rep_good nopl pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt f16c hypervisor lahf_lm fsgsbase erms&lt;/flags&gt;"
+            + "&lt;/CPU&gt;"
+            + "&lt;CPU ID=\"1\"&gt;"
+            + "&lt;vendor_id&gt;GenuineIntel&lt;/vendor_id&gt;"
+            + "&lt;cpu_family&gt;6&lt;/cpu_family&gt;"
+            + "&lt;model&gt;2&lt;/model&gt;"
+            + "&lt;model_name&gt;Intel Core i7 9xx (Nehalem Class Core i7)&lt;/model_name&gt;"
+            + "&lt;stepping&gt;3&lt;/stepping&gt;"
+            + "&lt;cache_size&gt;4096 KB&lt;/cache_size&gt;"
+            + "&lt;flags&gt;fpu de tsc msr pae mce cx8 apic mca cmov clflush mmx fxsr sse sse2 ss syscall nx lm rep_good nopl pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt f16c hypervisor lahf_lm fsgsbase erms&lt;/flags&gt;"
+            + "&lt;/CPU&gt;"
+            + "&lt;/Proc_Info&gt;"
+            + "&lt;/CPUInfo&gt;"
+            + "&lt;IO&gt;"
+            + "&lt;SCSI&gt;"
+            + "&lt;SCSI_Host Num=\"0\"&gt;"
+            + "&lt;Active_Mode&gt;Initiator&lt;/Active_Mode&gt;"
+            + "&lt;Ahci_Host_Cap2&gt;0&lt;/Ahci_Host_Cap2&gt;"
+            + "&lt;Ahci_Host_Caps&gt;40141f05&lt;/Ahci_Host_Caps&gt;"
+            + "&lt;Ahci_Host_Version&gt;10000&lt;/Ahci_Host_Version&gt;"
+            + "&lt;Ahci_Port_Cmd&gt;1000c017&lt;/Ahci_Port_Cmd&gt;"
+            + "&lt;Can_Queue&gt;31&lt;/Can_Queue&gt;"
+            + "&lt;Cmd_Per_Lun&gt;1&lt;/Cmd_Per_Lun&gt;"
+            + "&lt;Em_Message_Supported&gt;&lt;/Em_Message_Supported&gt;"
+            + "&lt;Em_Message_Type&gt;0&lt;/Em_Message_Type&gt;"
+            + "&lt;Host_Busy&gt;0&lt;/Host_Busy&gt;"
+            + "&lt;Link_Power_Management_Policy&gt;max_performance&lt;/Link_Power_Management_Policy&gt;"
+            + "&lt;Proc_Name&gt;ahci&lt;/Proc_Name&gt;"
+            + "&lt;Prot_Capabilities&gt;0&lt;/Prot_Capabilities&gt;"
+            + "&lt;Prot_Guard_Type&gt;0&lt;/Prot_Guard_Type&gt;"
+            + "&lt;Sg_Prot_Tablesize&gt;0&lt;/Sg_Prot_Tablesize&gt;"
+            + "&lt;Sg_Tablesize&gt;168&lt;/Sg_Tablesize&gt;"
+            + "&lt;State&gt;running&lt;/State&gt;"
+            + "&lt;Supported_Mode&gt;Initiator&lt;/Supported_Mode&gt;"
+            + "&lt;Uevent&gt;&lt;/Uevent&gt;"
+            + "&lt;Unique_Id&gt;1&lt;/Unique_Id&gt;"
+            + "&lt;SysFSDev&gt;"
+            + "&lt;Broken_Parity_Status&gt;0&lt;/Broken_Parity_Status&gt;"
+            + "&lt;Class&gt;0x010601&lt;/Class&gt;"
+            + "&lt;Consistent_Dma_Mask_Bits&gt;32&lt;/Consistent_Dma_Mask_Bits&gt;"
+            + "&lt;Device&gt;0x2922&lt;/Device&gt;"
+            + "&lt;Dma_Mask_Bits&gt;32&lt;/Dma_Mask_Bits&gt;"
+            + "&lt;Enable&gt;1&lt;/Enable&gt;"
+            + "&lt;Irq&gt;58&lt;/Irq&gt;"
+            + "&lt;Local_Cpulist&gt;0-1&lt;/Local_Cpulist&gt;"
+            + "&lt;Msi_Bus&gt;&lt;/Msi_Bus&gt;"
+            + "&lt;Msi_Irqs&gt;58&lt;/Msi_Irqs&gt;"
+            + "&lt;Numa_Node&gt;-1&lt;/Numa_Node&gt;"
+            + "&lt;Subsystem_Device&gt;0x1100&lt;/Subsystem_Device&gt;"
+            + "&lt;Subsystem_Vendor&gt;0x1af4&lt;/Subsystem_Vendor&gt;"
+            + "&lt;Uevent&gt;DRIVER=ahci PCI_CLASS=10601 PCI_ID=8086:2922 PCI_SUBSYS_ID=1AF4:1100 PCI_SLOT_NAME=0000:00:05.0 MODALIAS=pci:v00008086d00002922sv00001AF4sd00001100bc01sc06i01&lt;/Uevent&gt;"
+            + "&lt;Vendor&gt;0x8086&lt;/Vendor&gt;"
+            + "&lt;/SysFSDev&gt;"
+            + "&lt;/SCSI_Host&gt;"
+            + "&lt;SCSI_Host Num=\"1\"&gt;"
+            + "&lt;Active_Mode&gt;Initiator&lt;/Active_Mode&gt;"
+            + "&lt;Ahci_Host_Cap2&gt;0&lt;/Ahci_Host_Cap2&gt;"
+            + "&lt;Ahci_Host_Caps&gt;40141f05&lt;/Ahci_Host_Caps&gt;"
+            + "&lt;Ahci_Host_Version&gt;10000&lt;/Ahci_Host_Version&gt;"
+            + "&lt;Ahci_Port_Cmd&gt;10004016&lt;/Ahci_Port_Cmd&gt;"
+            + "&lt;Can_Queue&gt;31&lt;/Can_Queue&gt;"
+            + "&lt;Cmd_Per_Lun&gt;1&lt;/Cmd_Per_Lun&gt;"
+            + "&lt;Em_Message_Supported&gt;&lt;/Em_Message_Supported&gt;"
+            + "&lt;Em_Message_Type&gt;0&lt;/Em_Message_Type&gt;"
+            + "&lt;Host_Busy&gt;0&lt;/Host_Busy&gt;"
+            + "&lt;Link_Power_Management_Policy&gt;max_performance&lt;/Link_Power_Management_Policy&gt;"
+            + "&lt;Proc_Name&gt;ahci&lt;/Proc_Name&gt;"
+            + "&lt;Prot_Capabilities&gt;0&lt;/Prot_Capabilities&gt;"
+            + "&lt;Prot_Guard_Type&gt;0&lt;/Prot_Guard_Type&gt;"
+            + "&lt;Sg_Prot_Tablesize&gt;0&lt;/Sg_Prot_Tablesize&gt;"
+            + "&lt;Sg_Tablesize&gt;168&lt;/Sg_Tablesize&gt;"
+            + "&lt;State&gt;running&lt;/State&gt;"
+            + "&lt;Supported_Mode&gt;Initiator&lt;/Supported_Mode&gt;"
+            + "&lt;Uevent&gt;&lt;/Uevent&gt;"
+            + "&lt;Unique_Id&gt;2&lt;/Unique_Id&gt;"
+            + "&lt;SysFSDev&gt;"
+            + "&lt;Broken_Parity_Status&gt;0&lt;/Broken_Parity_Status&gt;"
+            + "&lt;Class&gt;0x010601&lt;/Class&gt;"
+            + "&lt;Consistent_Dma_Mask_Bits&gt;32&lt;/Consistent_Dma_Mask_Bits&gt;"
+            + "&lt;Device&gt;0x2922&lt;/Device&gt;"
+            + "&lt;Dma_Mask_Bits&gt;32&lt;/Dma_Mask_Bits&gt;"
+            + "&lt;Enable&gt;1&lt;/Enable&gt;"
+            + "&lt;Irq&gt;58&lt;/Irq&gt;"
+            + "&lt;Local_Cpulist&gt;0-1&lt;/Local_Cpulist&gt;"
+            + "&lt;Msi_Bus&gt;&lt;/Msi_Bus&gt;"
+            + "&lt;Msi_Irqs&gt;58&lt;/Msi_Irqs&gt;"
+            + "&lt;Numa_Node&gt;-1&lt;/Numa_Node&gt;"
+            + "&lt;Subsystem_Device&gt;0x1100&lt;/Subsystem_Device&gt;"
+            + "&lt;Subsystem_Vendor&gt;0x1af4&lt;/Subsystem_Vendor&gt;"
+            + "&lt;Uevent&gt;DRIVER=ahci PCI_CLASS=10601 PCI_ID=8086:2922 PCI_SUBSYS_ID=1AF4:1100 PCI_SLOT_NAME=0000:00:05.0 MODALIAS=pci:v00008086d00002922sv00001AF4sd00001100bc01sc06i01&lt;/Uevent&gt;"
+            + "&lt;Vendor&gt;0x8086&lt;/Vendor&gt;"
+            + "&lt;/SysFSDev&gt;"
+            + "&lt;/SCSI_Host&gt;"
+            + "&lt;SCSI_Host Num=\"2\"&gt;"
+            + "&lt;Active_Mode&gt;Initiator&lt;/Active_Mode&gt;"
+            + "&lt;Ahci_Host_Cap2&gt;0&lt;/Ahci_Host_Cap2&gt;"
+            + "&lt;Ahci_Host_Caps&gt;40141f05&lt;/Ahci_Host_Caps&gt;"
+            + "&lt;Ahci_Host_Version&gt;10000&lt;/Ahci_Host_Version&gt;"
+            + "&lt;Ahci_Port_Cmd&gt;10004016&lt;/Ahci_Port_Cmd&gt;"
+            + "&lt;Can_Queue&gt;31&lt;/Can_Queue&gt;"
+            + "&lt;Cmd_Per_Lun&gt;1&lt;/Cmd_Per_Lun&gt;"
+            + "&lt;Em_Message_Supported&gt;&lt;/Em_Message_Supported&gt;"
+            + "&lt;Em_Message_Type&gt;0&lt;/Em_Message_Type&gt;"
+            + "&lt;Host_Busy&gt;0&lt;/Host_Busy&gt;"
+            + "&lt;Link_Power_Management_Policy&gt;max_performance&lt;/Link_Power_Management_Policy&gt;"
+            + "&lt;Proc_Name&gt;ahci&lt;/Proc_Name&gt;"
+            + "&lt;Prot_Capabilities&gt;0&lt;/Prot_Capabilities&gt;"
+            + "&lt;Prot_Guard_Type&gt;0&lt;/Prot_Guard_Type&gt;"
+            + "&lt;Sg_Prot_Tablesize&gt;0&lt;/Sg_Prot_Tablesize&gt;"
+            + "&lt;Sg_Tablesize&gt;168&lt;/Sg_Tablesize&gt;"
+            + "&lt;State&gt;running&lt;/State&gt;"
+            + "&lt;Supported_Mode&gt;Initiator&lt;/Supported_Mode&gt;"
+            + "&lt;Uevent&gt;&lt;/Uevent&gt;"
+            + "&lt;Unique_Id&gt;3&lt;/Unique_Id&gt;"
+            + "&lt;SysFSDev&gt;"
+            + "&lt;Broken_Parity_Status&gt;0&lt;/Broken_Parity_Status&gt;"
+            + "&lt;Class&gt;0x010601&lt;/Class&gt;"
+            + "&lt;Consistent_Dma_Mask_Bits&gt;32&lt;/Consistent_Dma_Mask_Bits&gt;"
+            + "&lt;Device&gt;0x2922&lt;/Device&gt;"
+            + "&lt;Dma_Mask_Bits&gt;32&lt;/Dma_Mask_Bits&gt;"
+            + "&lt;Enable&gt;1&lt;/Enable&gt;"
+            + "&lt;Irq&gt;58&lt;/Irq&gt;"
+            + "&lt;Local_Cpulist&gt;0-1&lt;/Local_Cpulist&gt;"
+            + "&lt;Msi_Bus&gt;&lt;/Msi_Bus&gt;"
+            + "&lt;Msi_Irqs&gt;58&lt;/Msi_Irqs&gt;"
+            + "&lt;Numa_Node&gt;-1&lt;/Numa_Node&gt;"
+            + "&lt;Subsystem_Device&gt;0x1100&lt;/Subsystem_Device&gt;"
+            + "&lt;Subsystem_Vendor&gt;0x1af4&lt;/Subsystem_Vendor&gt;"
+            + "&lt;Uevent&gt;DRIVER=ahci PCI_CLASS=10601 PCI_ID=8086:2922 PCI_SUBSYS_ID=1AF4:1100 PCI_SLOT_NAME=0000:00:05.0 MODALIAS=pci:v00008086d00002922sv00001AF4sd00001100bc01sc06i01&lt;/Uevent&gt;"
+            + "&lt;Vendor&gt;0x8086&lt;/Vendor&gt;"
+            + "&lt;/SysFSDev&gt;"
+            + "&lt;/SCSI_Host&gt;"
+            + "&lt;SCSI_Host Num=\"3\"&gt;"
+            + "&lt;Active_Mode&gt;Initiator&lt;/Active_Mode&gt;"
+            + "&lt;Ahci_Host_Cap2&gt;0&lt;/Ahci_Host_Cap2&gt;"
+            + "&lt;Ahci_Host_Caps&gt;40141f05&lt;/Ahci_Host_Caps&gt;"
+            + "&lt;Ahci_Host_Version&gt;10000&lt;/Ahci_Host_Version&gt;"
+            + "&lt;Ahci_Port_Cmd&gt;10004016&lt;/Ahci_Port_Cmd&gt;"
+            + "&lt;Can_Queue&gt;31&lt;/Can_Queue&gt;"
+            + "&lt;Cmd_Per_Lun&gt;1&lt;/Cmd_Per_Lun&gt;"
+            + "&lt;Em_Message_Supported&gt;&lt;/Em_Message_Supported&gt;"
+            + "&lt;Em_Message_Type&gt;0&lt;/Em_Message_Type&gt;"
+            + "&lt;Host_Busy&gt;0&lt;/Host_Busy&gt;"
+            + "&lt;Link_Power_Management_Policy&gt;max_performance&lt;/Link_Power_Management_Policy&gt;"
+            + "&lt;Proc_Name&gt;ahci&lt;/Proc_Name&gt;"
+            + "&lt;Prot_Capabilities&gt;0&lt;/Prot_Capabilities&gt;"
+            + "&lt;Prot_Guard_Type&gt;0&lt;/Prot_Guard_Type&gt;"
+            + "&lt;Sg_Prot_Tablesize&gt;0&lt;/Sg_Prot_Tablesize&gt;"
+            + "&lt;Sg_Tablesize&gt;168&lt;/Sg_Tablesize&gt;"
+            + "&lt;State&gt;running&lt;/State&gt;"
+            + "&lt;Supported_Mode&gt;Initiator&lt;/Supported_Mode&gt;"
+            + "&lt;Uevent&gt;&lt;/Uevent&gt;"
+            + "&lt;Unique_Id&gt;4&lt;/Unique_Id&gt;"
+            + "&lt;SysFSDev&gt;"
+            + "&lt;Broken_Parity_Status&gt;0&lt;/Broken_Parity_Status&gt;"
+            + "&lt;Class&gt;0x010601&lt;/Class&gt;"
+            + "&lt;Consistent_Dma_Mask_Bits&gt;32&lt;/Consistent_Dma_Mask_Bits&gt;"
+            + "&lt;Device&gt;0x2922&lt;/Device&gt;"
+            + "&lt;Dma_Mask_Bits&gt;32&lt;/Dma_Mask_Bits&gt;"
+            + "&lt;Enable&gt;1&lt;/Enable&gt;"
+            + "&lt;Irq&gt;58&lt;/Irq&gt;"
+            + "&lt;Local_Cpulist&gt;0-1&lt;/Local_Cpulist&gt;"
+            + "&lt;Msi_Bus&gt;&lt;/Msi_Bus&gt;"
+            + "&lt;Msi_Irqs&gt;58&lt;/Msi_Irqs&gt;"
+            + "&lt;Numa_Node&gt;-1&lt;/Numa_Node&gt;"
+            + "&lt;Subsystem_Device&gt;0x1100&lt;/Subsystem_Device&gt;"
+            + "&lt;Subsystem_Vendor&gt;0x1af4&lt;/Subsystem_Vendor&gt;"
+            + "&lt;Uevent&gt;DRIVER=ahci PCI_CLASS=10601 PCI_ID=8086:2922 PCI_SUBSYS_ID=1AF4:1100 PCI_SLOT_NAME=0000:00:05.0 MODALIAS=pci:v00008086d00002922sv00001AF4sd00001100bc01sc06i01&lt;/Uevent&gt;"
+            + "&lt;Vendor&gt;0x8086&lt;/Vendor&gt;"
+            + "&lt;/SysFSDev&gt;"
+            + "&lt;/SCSI_Host&gt;"
+            + "&lt;SCSI_Host Num=\"4\"&gt;"
+            + "&lt;Active_Mode&gt;Initiator&lt;/Active_Mode&gt;"
+            + "&lt;Ahci_Host_Cap2&gt;0&lt;/Ahci_Host_Cap2&gt;"
+            + "&lt;Ahci_Host_Caps&gt;40141f05&lt;/Ahci_Host_Caps&gt;"
+            + "&lt;Ahci_Host_Version&gt;10000&lt;/Ahci_Host_Version&gt;"
+            + "&lt;Ahci_Port_Cmd&gt;10004016&lt;/Ahci_Port_Cmd&gt;"
+            + "&lt;Can_Queue&gt;31&lt;/Can_Queue&gt;"
+            + "&lt;Cmd_Per_Lun&gt;1&lt;/Cmd_Per_Lun&gt;"
+            + "&lt;Em_Message_Supported&gt;&lt;/Em_Message_Supported&gt;"
+            + "&lt;Em_Message_Type&gt;0&lt;/Em_Message_Type&gt;"
+            + "&lt;Host_Busy&gt;0&lt;/Host_Busy&gt;"
+            + "&lt;Link_Power_Management_Policy&gt;max_performance&lt;/Link_Power_Management_Policy&gt;"
+            + "&lt;Proc_Name&gt;ahci&lt;/Proc_Name&gt;"
+            + "&lt;Prot_Capabilities&gt;0&lt;/Prot_Capabilities&gt;"
+            + "&lt;Prot_Guard_Type&gt;0&lt;/Prot_Guard_Type&gt;"
+            + "&lt;Sg_Prot_Tablesize&gt;0&lt;/Sg_Prot_Tablesize&gt;"
+            + "&lt;Sg_Tablesize&gt;168&lt;/Sg_Tablesize&gt;"
+            + "&lt;State&gt;running&lt;/State&gt;"
+            + "&lt;Supported_Mode&gt;Initiator&lt;/Supported_Mode&gt;"
+            + "&lt;Uevent&gt;&lt;/Uevent&gt;"
+            + "&lt;Unique_Id&gt;5&lt;/Unique_Id&gt;"
+            + "&lt;SysFSDev&gt;"
+            + "&lt;Broken_Parity_Status&gt;0&lt;/Broken_Parity_Status&gt;"
+            + "&lt;Class&gt;0x010601&lt;/Class&gt;"
+            + "&lt;Consistent_Dma_Mask_Bits&gt;32&lt;/Consistent_Dma_Mask_Bits&gt;"
+            + "&lt;Device&gt;0x2922&lt;/Device&gt;"
+            + "&lt;Dma_Mask_Bits&gt;32&lt;/Dma_Mask_Bits&gt;"
+            + "&lt;Enable&gt;1&lt;/Enable&gt;"
+            + "&lt;Irq&gt;58&lt;/Irq&gt;"
+            + "&lt;Local_Cpulist&gt;0-1&lt;/Local_Cpulist&gt;"
+            + "&lt;Msi_Bus&gt;&lt;/Msi_Bus&gt;"
+            + "&lt;Msi_Irqs&gt;58&lt;/Msi_Irqs&gt;"
+            + "&lt;Numa_Node&gt;-1&lt;/Numa_Node&gt;"
+            + "&lt;Subsystem_Device&gt;0x1100&lt;/Subsystem_Device&gt;"
+            + "&lt;Subsystem_Vendor&gt;0x1af4&lt;/Subsystem_Vendor&gt;"
+            + "&lt;Uevent&gt;DRIVER=ahci PCI_CLASS=10601 PCI_ID=8086:2922 PCI_SUBSYS_ID=1AF4:1100 PCI_SLOT_NAME=0000:00:05.0 MODALIAS=pci:v00008086d00002922sv00001AF4sd00001100bc01sc06i01&lt;/Uevent&gt;"
+            + "&lt;Vendor&gt;0x8086&lt;/Vendor&gt;"
+            + "&lt;/SysFSDev&gt;"
+            + "&lt;/SCSI_Host&gt;"
+            + "&lt;SCSI_Host Num=\"5\"&gt;"
+            + "&lt;Active_Mode&gt;Initiator&lt;/Active_Mode&gt;"
+            + "&lt;Ahci_Host_Cap2&gt;0&lt;/Ahci_Host_Cap2&gt;"
+            + "&lt;Ahci_Host_Caps&gt;40141f05&lt;/Ahci_Host_Caps&gt;"
+            + "&lt;Ahci_Host_Version&gt;10000&lt;/Ahci_Host_Version&gt;"
+            + "&lt;Ahci_Port_Cmd&gt;10004016&lt;/Ahci_Port_Cmd&gt;"
+            + "&lt;Can_Queue&gt;31&lt;/Can_Queue&gt;"
+            + "&lt;Cmd_Per_Lun&gt;1&lt;/Cmd_Per_Lun&gt;"
+            + "&lt;Em_Message_Supported&gt;&lt;/Em_Message_Supported&gt;"
+            + "&lt;Em_Message_Type&gt;0&lt;/Em_Message_Type&gt;"
+            + "&lt;Host_Busy&gt;0&lt;/Host_Busy&gt;"
+            + "&lt;Link_Power_Management_Policy&gt;max_performance&lt;/Link_Power_Management_Policy&gt;"
+            + "&lt;Proc_Name&gt;ahci&lt;/Proc_Name&gt;"
+            + "&lt;Prot_Capabilities&gt;0&lt;/Prot_Capabilities&gt;"
+            + "&lt;Prot_Guard_Type&gt;0&lt;/Prot_Guard_Type&gt;"
+            + "&lt;Sg_Prot_Tablesize&gt;0&lt;/Sg_Prot_Tablesize&gt;"
+            + "&lt;Sg_Tablesize&gt;168&lt;/Sg_Tablesize&gt;"
+            + "&lt;State&gt;running&lt;/State&gt;"
+            + "&lt;Supported_Mode&gt;Initiator&lt;/Supported_Mode&gt;"
+            + "&lt;Uevent&gt;&lt;/Uevent&gt;"
+            + "&lt;Unique_Id&gt;6&lt;/Unique_Id&gt;"
+            + "&lt;SysFSDev&gt;"
+            + "&lt;Broken_Parity_Status&gt;0&lt;/Broken_Parity_Status&gt;"
+            + "&lt;Class&gt;0x010601&lt;/Class&gt;"
+            + "&lt;Consistent_Dma_Mask_Bits&gt;32&lt;/Consistent_Dma_Mask_Bits&gt;"
+            + "&lt;Device&gt;0x2922&lt;/Device&gt;"
+            + "&lt;Dma_Mask_Bits&gt;32&lt;/Dma_Mask_Bits&gt;"
+            + "&lt;Enable&gt;1&lt;/Enable&gt;"
+            + "&lt;Irq&gt;58&lt;/Irq&gt;"
+            + "&lt;Local_Cpulist&gt;0-1&lt;/Local_Cpulist&gt;"
+            + "&lt;Msi_Bus&gt;&lt;/Msi_Bus&gt;"
+            + "&lt;Msi_Irqs&gt;58&lt;/Msi_Irqs&gt;"
+            + "&lt;Numa_Node&gt;-1&lt;/Numa_Node&gt;"
+            + "&lt;Subsystem_Device&gt;0x1100&lt;/Subsystem_Device&gt;"
+            + "&lt;Subsystem_Vendor&gt;0x1af4&lt;/Subsystem_Vendor&gt;"
+            + "&lt;Uevent&gt;DRIVER=ahci PCI_CLASS=10601 PCI_ID=8086:2922 PCI_SUBSYS_ID=1AF4:1100 PCI_SLOT_NAME=0000:00:05.0 MODALIAS=pci:v00008086d00002922sv00001AF4sd00001100bc01sc06i01&lt;/Uevent&gt;"
+            + "&lt;Vendor&gt;0x8086&lt;/Vendor&gt;"
+            + "&lt;/SysFSDev&gt;"
+            + "&lt;/SCSI_Host&gt;"
+            + "&lt;SCSI_Host Num=\"6\"&gt;"
+            + "&lt;Active_Mode&gt;Initiator&lt;/Active_Mode&gt;"
+            + "&lt;Can_Queue&gt;1&lt;/Can_Queue&gt;"
+            + "&lt;Cmd_Per_Lun&gt;1&lt;/Cmd_Per_Lun&gt;"
+            + "&lt;Host_Busy&gt;0&lt;/Host_Busy&gt;"
+            + "&lt;Proc_Name&gt;ata_piix&lt;/Proc_Name&gt;"
+            + "&lt;Prot_Capabilities&gt;0&lt;/Prot_Capabilities&gt;"
+            + "&lt;Prot_Guard_Type&gt;0&lt;/Prot_Guard_Type&gt;"
+            + "&lt;Sg_Prot_Tablesize&gt;0&lt;/Sg_Prot_Tablesize&gt;"
+            + "&lt;Sg_Tablesize&gt;128&lt;/Sg_Tablesize&gt;"
+            + "&lt;State&gt;running&lt;/State&gt;"
+            + "&lt;Supported_Mode&gt;Initiator&lt;/Supported_Mode&gt;"
+            + "&lt;Uevent&gt;&lt;/Uevent&gt;"
+            + "&lt;Unique_Id&gt;7&lt;/Unique_Id&gt;"
+            + "&lt;SysFSDev&gt;"
+            + "&lt;Broken_Parity_Status&gt;0&lt;/Broken_Parity_Status&gt;"
+            + "&lt;Class&gt;0x010180&lt;/Class&gt;"
+            + "&lt;Consistent_Dma_Mask_Bits&gt;32&lt;/Consistent_Dma_Mask_Bits&gt;"
+            + "&lt;Device&gt;0x7010&lt;/Device&gt;"
+            + "&lt;Dma_Mask_Bits&gt;32&lt;/Dma_Mask_Bits&gt;"
+            + "&lt;Enable&gt;1&lt;/Enable&gt;"
+            + "&lt;Irq&gt;0&lt;/Irq&gt;"
+            + "&lt;Local_Cpulist&gt;0-1&lt;/Local_Cpulist&gt;"
+            + "&lt;Msi_Bus&gt;&lt;/Msi_Bus&gt;"
+            + "&lt;Msi_Irqs&gt;&lt;/Msi_Irqs&gt;"
+            + "&lt;Numa_Node&gt;-1&lt;/Numa_Node&gt;"
+            + "&lt;Subsystem_Device&gt;0x1100&lt;/Subsystem_Device&gt;"
+            + "&lt;Subsystem_Vendor&gt;0x1af4&lt;/Subsystem_Vendor&gt;"
+            + "&lt;Uevent&gt;DRIVER=ata_piix PCI_CLASS=10180 PCI_ID=8086:7010 PCI_SUBSYS_ID=1AF4:1100 PCI_SLOT_NAME=0000:00:01.1 MODALIAS=pci:v00008086d00007010sv00001AF4sd00001100bc01sc01i80&lt;/Uevent&gt;"
+            + "&lt;Vendor&gt;0x8086&lt;/Vendor&gt;"
+            + "&lt;/SysFSDev&gt;"
+            + "&lt;/SCSI_Host&gt;"
+            + "&lt;SCSI_Host Num=\"7\"&gt;"
+            + "&lt;Active_Mode&gt;Initiator&lt;/Active_Mode&gt;"
+            + "&lt;Can_Queue&gt;1&lt;/Can_Queue&gt;"
+            + "&lt;Cmd_Per_Lun&gt;1&lt;/Cmd_Per_Lun&gt;"
+            + "&lt;Host_Busy&gt;0&lt;/Host_Busy&gt;"
+            + "&lt;Proc_Name&gt;ata_piix&lt;/Proc_Name&gt;"
+            + "&lt;Prot_Capabilities&gt;0&lt;/Prot_Capabilities&gt;"
+            + "&lt;Prot_Guard_Type&gt;0&lt;/Prot_Guard_Type&gt;"
+            + "&lt;Sg_Prot_Tablesize&gt;0&lt;/Sg_Prot_Tablesize&gt;"
+            + "&lt;Sg_Tablesize&gt;128&lt;/Sg_Tablesize&gt;"
+            + "&lt;State&gt;running&lt;/State&gt;"
+            + "&lt;Supported_Mode&gt;Initiator&lt;/Supported_Mode&gt;"
+            + "&lt;Uevent&gt;&lt;/Uevent&gt;"
+            + "&lt;Unique_Id&gt;8&lt;/Unique_Id&gt;"
+            + "&lt;SysFSDev&gt;"
+            + "&lt;Broken_Parity_Status&gt;0&lt;/Broken_Parity_Status&gt;"
+            + "&lt;Class&gt;0x010180&lt;/Class&gt;"
+            + "&lt;Consistent_Dma_Mask_Bits&gt;32&lt;/Consistent_Dma_Mask_Bits&gt;"
+            + "&lt;Device&gt;0x7010&lt;/Device&gt;"
+            + "&lt;Dma_Mask_Bits&gt;32&lt;/Dma_Mask_Bits&gt;"
+            + "&lt;Enable&gt;1&lt;/Enable&gt;"
+            + "&lt;Irq&gt;0&lt;/Irq&gt;"
+            + "&lt;Local_Cpulist&gt;0-1&lt;/Local_Cpulist&gt;"
+            + "&lt;Msi_Bus&gt;&lt;/Msi_Bus&gt;"
+            + "&lt;Msi_Irqs&gt;&lt;/Msi_Irqs&gt;"
+            + "&lt;Numa_Node&gt;-1&lt;/Numa_Node&gt;"
+            + "&lt;Subsystem_Device&gt;0x1100&lt;/Subsystem_Device&gt;"
+            + "&lt;Subsystem_Vendor&gt;0x1af4&lt;/Subsystem_Vendor&gt;"
+            + "&lt;Uevent&gt;DRIVER=ata_piix PCI_CLASS=10180 PCI_ID=8086:7010 PCI_SUBSYS_ID=1AF4:1100 PCI_SLOT_NAME=0000:00:01.1 MODALIAS=pci:v00008086d00007010sv00001AF4sd00001100bc01sc01i80&lt;/Uevent&gt;"
+            + "&lt;Vendor&gt;0x8086&lt;/Vendor&gt;"
+            + "&lt;/SysFSDev&gt;"
+            + "&lt;/SCSI_Host&gt;"
+            + "&lt;ISCSI_Node&gt;"
+            + "&lt;Initiatorname&gt;iqn.1988-12.com.oracle:3b3f5e2f59cb&lt;/Initiatorname&gt;"
+            + "&lt;/ISCSI_Node&gt;"
+            + "&lt;/SCSI&gt;"
+            + "&lt;IDE&gt;"
+            + "&lt;/IDE&gt;"
+            + "&lt;/IO&gt;"
+            + "&lt;DMTF&gt;"
+            + "&lt;SMBIOS Version=\"2.4.0\"&gt;"
+            + "&lt;MaxSize&gt;48&lt;/MaxSize&gt;"
+            + "&lt;/SMBIOS&gt;"
+            + "&lt;DMI Version=\"2.4\"&gt;"
+            + "&lt;TableLength&gt;346&lt;/TableLength&gt;"
+            + "&lt;Items&gt;13&lt;/Items&gt;"
+            + "&lt;Buffer&gt;"
+            + "ABgAAAECAOgDAAgAAAAAAAAAAAQBAP//Qm9jaHMAQm9jaHMAMDEvMDEvMjAxMQAAARsAAQEC"
+            + "AAAd1eiR2dDtvYHCppqz0bfqBgAAQm9jaHMAQm9jaHMAAAMUAAMBAQAAAAMDAwIAAAAAAAAA"
+            + "Qm9jaHMAAAQgAQQBAwECIwYAAP/7iw8AAAAA0AfQB0EB////////Q1BVIDEAQm9jaHMAAAQg"
+            + "AgQBAwECIwYAAP/7iw8AAAAA0AfQB0EB////////Q1BVIDIAQm9jaHMAABAPABABAwYAAEAA"
+            + "/v8BAAAAERUAEQAQAwBAAEAAABAJAAEABwAARElNTSAwAAATDwATAAAAAP//NwAAEAEAABMP"
+            + "ARMAAEAA//9HAAAQAQAAFBMAFAAAAAD//zcAABEAEwEAAAAAFBMBFAAAQAD//0cAABEBEwEA"
+            + "AAAAIAsAIAAAAAAAAAAAAH8EAH8AAA=="
+            + "&lt;/Buffer&gt;"
+            + "&lt;/DMI&gt;"
+            + "&lt;BIOS Type=\"0\" Item=\"0\" Handle=\"0x0\"&gt;"
+            + "&lt;Vendor&gt;Bochs&lt;/Vendor&gt;"
+            + "&lt;Version&gt;Bochs&lt;/Version&gt;"
+            + "&lt;ReleaseDate&gt;01/01/2011&lt;/ReleaseDate&gt;"
+            + "&lt;/BIOS&gt;"
+            + "&lt;System Type=\"1\" Item=\"1\" Handle=\"0x100\"&gt;"
+            + "&lt;UUID&gt;1d:d5:e8:91:d9:d0:ed:bd:81:c2:a6:9a:b3:d1:b7:ea&lt;/UUID&gt;"
+            + "&lt;Manufacturer&gt;Bochs&lt;/Manufacturer&gt;"
+            + "&lt;ProductName&gt;Bochs&lt;/ProductName&gt;"
+            + "&lt;/System&gt;"
+            + "&lt;Chassis Type=\"3\" Item=\"2\" Handle=\"0x300\"&gt;"
+            + "&lt;Height&gt;0U&lt;/Height&gt;"
+            + "&lt;Manufacturer&gt;Bochs&lt;/Manufacturer&gt;"
+            + "&lt;/Chassis&gt;"
+            + "&lt;/DMTF&gt;"
+            + "&lt;/NodeInformation&gt;"
+            + "&lt;/Discover_Hardware_Result&gt;";
+    private final String FSTYPE = "nfs";
+    private final String REMOTEHOST = "cs-mgmt";
+    private final String REMOTEDIR = "/volumes/cs-data/primary/ovm";
+    public String getFsType() {
+        return FSTYPE;
+    }
+
+    public String getRemoteHost() {
+        return REMOTEHOST;
+    }
+
+    public String getRemoteDir() {
+        return REMOTEDIR;
+    }
+
+    public String getRemote() {
+        return REMOTE;
+    }
+
+    public String getRepoId() {
+        return REPOID;
+    }
+
+    public String getRepoMnt() {
+        return REPOMNT;
+    }
+    public String getVirtualDisksDir() {
+        return REPOMNT + "/VirtualDisks";
+    }
+    public String getTemplatesDir() {
+        return REPOMNT + "/Templates";
+    }
+    public String getIsoDir() {
+        return REPOMNT + "/ISOs";
+    }
+    private final String REMOTE = REMOTEHOST + ":" + REMOTEDIR;
+    private final String REPOID = "f12842eb-f5ed-3fe7-8da1-eb0e17f5ede8";
+    private final String DDREPOID = lin.deDash(REPOID);
+    private final String REPOMNT = "/OVS/Repositories/" + DDREPOID;
+    private final String VMMNT = "/nfsmnt/" + REPOID;
+    private final String DISCOVERFS = "&lt;?xml version=\"1.0\" ?&gt;"
+            + "&lt;Discover_Mounted_File_Systems_Result&gt;"
+            + "&lt;Filesystem Type=\""
+            + FSTYPE
+            + "\"&gt;"
+            + "&lt;Mount Dir=\""
+            + REPOMNT
+            + "\"&gt;"
+            + "&lt;Device&gt;"
+            + REMOTE
+            + "&lt;/Device&gt;"
+            + "&lt;Mount_Options&gt;rw,relatime,vers=3,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=65535,timeo=600,retrans=2,sec=sys,local_lock=none,addr=192.168.1.61&lt;/Mount_Options&gt;"
+            + "&lt;/Mount&gt;"
+            + "&lt;Mount Dir=\""
+            + VMMNT
+            + "\"&gt;"
+            + "&lt;Device&gt;"
+            + REMOTE
+            + "/VirtualMachines&lt;/Device&gt;"
+            + "&lt;Mount_Options&gt;rw,relatime,vers=3,rsize=524288,wsize=524288,namlen=255,hard,proto=tcp,port=65535,timeo=600,retrans=2,sec=sys,local_lock=none,addr=192.168.1.61&lt;/Mount_Options&gt;"
+            + "&lt;/Mount&gt;" + "&lt;/Filesystem&gt;"
+            + "&lt;/Discover_Mounted_File_Systems_Result&gt;";
+    private final String LASTBOOT = "<struct>" + "<member>"
+            + "<name>last_boot_time</name>"
+            + "<value><i8>1413834408</i8></value>" + "</member>" + "<member>"
+            + "<name>local_time</name>" + "<value><i8>1414082517</i8></value>"
+            + "</member>" + "</struct>";
+    private final String TIMEZONE = "<array><data>"
+            + "<value><string>Europe/Amsterdam</string></value>"
+            + "<value><boolean>1</boolean></value>" + "</data></array>";
+
+    @Test
+    public void testDiscoverServer() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERSERVER));
+        results.basicStringTest(lin.getMembershipState(), "Pooled");
+        lin.discoverServer();
+        results.basicStringTest(lin.getCapabilities(),
+                "xen-3.0-x86_64 xen-3.0-x86_32p");
+        results.basicStringTest(lin.getOvmVersion(), "3.2.1-517");
+        results.basicStringTest(lin.getHypervisorVersion(), "4.1.3OVM");
+        results.basicStringTest(lin.get("MAX_CONCURRENT_MIGRATION_IN"), "1");
+    }
+
+    @Test
+    public void testGetTimeZone() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(TIMEZONE));
+        results.basicBooleanTest(lin.getTimeZone());
+    }
+
+    @Test
+    public void testLastBootTime() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(LASTBOOT));
+        results.basicIntTest(lin.getLastBootTime(), 1413834408);
+    }
+
+    @Test
+    public void testDiscoverHardware() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERHW));
+        lin.discoverHardware();
+        results.basicDoubleTest(lin.getMemory(),
+                Double.valueOf("1048476") * 4096);
+        results.basicDoubleTest(lin.getFreeMemory(),
+                Double.valueOf("863459") * 4096);
+        results.basicStringTest(lin.get("UUID"),
+                "1d:d5:e8:91:d9:d0:ed:bd:81:c2:a6:9a:b3:d1:b7:ea");
+    }
+
+    @Test
+    public void testDiscoverMountedFileSystems() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERFS));
+        lin.discoverMountedFs(FSTYPE);
+        results.basicBooleanTest(
+                results.basicListHasString(lin.getFileSystemList(), REPOMNT),
+                true);
+        results.basicBooleanTest(
+                results.basicListHasString(lin.getFileSystemList(), VMMNT),
+                true);
+        results.basicBooleanTest(
+                results.basicListHasString(lin.getFileSystemList(), REMOTE),
+                false);
+        results.basicStringTest(lin.getFileSystem(VMMNT, FSTYPE)
+                .getMountPoint(), VMMNT);
+        results.basicStringTest(lin.getFileSystem(VMMNT, FSTYPE).getHost(),
+                REMOTEHOST);
+        results.basicStringTest(lin.getFileSystem(VMMNT, FSTYPE).getUuid(),
+                REPOID);
+        results.basicStringTest(lin.getFileSystem(REPOMNT, FSTYPE).getUuid(),
+                DDREPOID);
+        results.basicStringTest(lin.getFileSystem(REPOMNT, FSTYPE)
+                .getRemoteDir(), REMOTEDIR);
+        results.basicBooleanTest(lin.getFileSystem(VMMNT, FSTYPE).getDetails()
+                .containsKey("Uuid"), true);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/NetworkTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/NetworkTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/NetworkTest.java
new file mode 100644
index 0000000..c45fd40
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/NetworkTest.java
@@ -0,0 +1,346 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import org.junit.Test;
+
+public class NetworkTest {
+    ConnectionTest con = new ConnectionTest();
+    Network net = new Network(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    private String IP = "192.168.1.64";
+    private String BR = "192.168.1.255";
+    private String MAC = "52:54:00:24:47:70";
+    private String INT = "xenbr0";
+    private String PHY = "bond0";
+    private String VLANBR = "bond0";
+    public String getBroadcast() {
+        return BR;
+    }
+
+    public String getMac() {
+        return MAC;
+    }
+
+    public String getInterface() {
+        return INT;
+    }
+
+    public String getPhysical() {
+        return PHY;
+    }
+
+    public String getVlanBridge() {
+        return VLANBR;
+    }
+
+    public String getVlanInterface() {
+        return VLANINT;
+    }
+
+    public Integer getVlan() {
+        return VLAN;
+    }
+
+    public String getControl() {
+        return CONTROL;
+    }
+
+    private String VLANINT = "xenbr0";
+    private Integer VLAN = 200;
+    private String CONTROL = "control0";
+    private String CONTROLMAC = "B2:D1:75:69:8C:58";
+    private String EMPTY = results.escapeOrNot("<?xml version=\"1.0\" ?>"
+            + "<Discover_Network_Result>" + "</Discover_Network_Result>");
+    private String DISCOVERNETWORK = results
+            .escapeOrNot("<?xml version=\"1.0\" ?>"
+                    + "<Discover_Network_Result>" + "  <Network>"
+                    + "    <Active>" + "      <Network>"
+                    + "        <Device Name=\""
+                    + PHY
+                    + "\">"
+                    + "          <MAC>52:54:00:24:47:70</MAC>"
+                    + "          <Flags>(0x1043) IFF_UP IFF_BROADCAST IFF_RUNNING IFF_MULTICAST</Flags>"
+                    + "          <MII>"
+                    + "            <Autonegotiate>"
+                    + "              <State>Incomplete</State>"
+                    + "              <Speed>100baseT-FD</Speed>"
+                    + "            </Autonegotiate>"
+                    + "            <Link>ok</Link>"
+                    + "            <Product>"
+                    + "              <Vendor>00:00:00</Vendor>"
+                    + "              <Model>0</Model>"
+                    + "              <Revision>0</Revision>"
+                    + "            </Product>"
+                    + "            <Status>autonegotiation complete </Status>"
+                    + "            <Capabilities>100baseT-FD 100baseT-HD 10baseT-FD 10baseT-HD</Capabilities>"
+                    + "            <Advertising>100baseT-FD 100baseT-HD 10baseT-FD 10baseT-HD</Advertising>"
+                    + "            <LinkPartner>100baseT-FD 100baseT-HD 10baseT-FD 10baseT-HD</LinkPartner>"
+                    + "          </MII>"
+                    + "          <WOL>"
+                    + "            <WakeOnLan>disabled</WakeOnLan>"
+                    + "          </WOL>"
+                    + "          <SysFS>"
+                    + "            <uevent>INTERFACE="
+                    + PHY
+                    + "IFINDEX=2</uevent>"
+                    + "            <addr_assign_type>0</addr_assign_type>"
+                    + "            <addr_len>6</addr_len>"
+                    + "            <dev_id>0x0</dev_id>"
+                    + "            <ifalias/>"
+                    + "            <iflink>2</iflink>"
+                    + "            <ifindex>2</ifindex>"
+                    + "            <features>0x200041a0</features>"
+                    + "            <type>1</type>"
+                    + "            <link_mode>0</link_mode>"
+                    + "            <carrier>1</carrier>"
+                    + "            <speed>100</speed>"
+                    + "            <duplex>full</duplex>"
+                    + "            <dormant>0</dormant>"
+                    + "            <operstate>up</operstate>"
+                    + "            <mtu>1500</mtu>"
+                    + "            <flags>0x1103</flags>"
+                    + "            <tx_queue_len>1000</tx_queue_len>"
+                    + "            <netdev_group>0</netdev_group>"
+                    + "            <SysFSDev>"
+                    + "              <vendor>0x10ec</vendor>"
+                    + "              <device>0x8139</device>"
+                    + "              <subsystem_vendor>0x1af4</subsystem_vendor>"
+                    + "              <subsystem_device>0x1100</subsystem_device>"
+                    + "              <class>0x020000</class>"
+                    + "            </SysFSDev>"
+                    + "          </SysFS>"
+                    + "          <BootProto>none</BootProto>"
+                    + "          <MetaData>ethernet:c0a80100{192.168.1.0}:MANAGEMENT,CLUSTER_HEARTBEAT,LIVE_MIGRATE,VIRTUAL_MACHINE,STORAGE</MetaData>"
+                    + "        </Device>"
+                    + "        <Device Name=\"eth1\">"
+                    + "          <MAC>52:54:00:26:7F:A0</MAC>"
+                    + "          <Flags>(0x1843) IFF_UP IFF_BROADCAST IFF_RUNNING IFF_SLAVE IFF_MULTICAST</Flags>"
+                    + "          <MII>"
+                    + "            <Autonegotiate>"
+                    + "              <State>Incomplete</State>"
+                    + "              <Speed>100baseT-FD</Speed>"
+                    + "            </Autonegotiate>"
+                    + "            <Link>ok</Link>"
+                    + "            <Product>"
+                    + "              <Vendor>00:00:00</Vendor>"
+                    + "              <Model>0</Model>"
+                    + "              <Revision>0</Revision>"
+                    + "            </Product>"
+                    + "            <Status>autonegotiation complete </Status>"
+                    + "            <Capabilities>100baseT-FD 100baseT-HD 10baseT-FD 10baseT-HD</Capabilities>"
+                    + "            <Advertising>100baseT-FD 100baseT-HD 10baseT-FD 10baseT-HD</Advertising>"
+                    + "            <LinkPartner>100baseT-FD 100baseT-HD 10baseT-FD 10baseT-HD</LinkPartner>"
+                    + "          </MII>"
+                    + "          <WOL>"
+                    + "            <WakeOnLan>disabled</WakeOnLan>"
+                    + "          </WOL>"
+                    + "          <SysFS>"
+                    + "            <uevent>INTERFACE=eth1"
+                    + "IFINDEX=3</uevent>"
+                    + "            <addr_assign_type>0</addr_assign_type>"
+                    + "            <addr_len>6</addr_len>"
+                    + "            <dev_id>0x0</dev_id>"
+                    + "            <ifalias/>"
+                    + "            <iflink>3</iflink>"
+                    + "            <ifindex>3</ifindex>"
+                    + "            <features>0x200041a0</features>"
+                    + "            <type>1</type>"
+                    + "            <link_mode>0</link_mode>"
+                    + "            <carrier>1</carrier>"
+                    + "            <speed>100</speed>"
+                    + "            <duplex>full</duplex>"
+                    + "            <dormant>0</dormant>"
+                    + "            <operstate>up</operstate>"
+                    + "            <mtu>1500</mtu>"
+                    + "            <flags>0x1903</flags>"
+                    + "            <tx_queue_len>1000</tx_queue_len>"
+                    + "            <netdev_group>0</netdev_group>"
+                    + "            <SysFSDev>"
+                    + "              <vendor>0x10ec</vendor>"
+                    + "              <device>0x8139</device>"
+                    + "              <subsystem_vendor>0x1af4</subsystem_vendor>"
+                    + "              <subsystem_device>0x1100</subsystem_device>"
+                    + "              <class>0x020000</class>"
+                    + "            </SysFSDev>"
+                    + "          </SysFS>"
+                    + "          <BootProto>none</BootProto>"
+                    + "        </Device>"
+                    + "      </Network>"
+                    + "      <Bonding>"
+                    + "        <Device Name=\"bond1\">"
+                    + "          <Bonding_Mode>active-backup</Bonding_Mode>"
+                    + "          <Primary_Slave>eth1 (primary_reselect always)</Primary_Slave>"
+                    + "          <Currently_Active_Slave>eth1</Currently_Active_Slave>"
+                    + "          <MII_Status>up</MII_Status>"
+                    + "          <MII_Polling_Interval>250</MII_Polling_Interval>"
+                    + "          <Up_Delay>500</Up_Delay>"
+                    + "          <Down_Delay>500</Down_Delay>"
+                    + "          <Slave_Interface Name=\"eth1\">"
+                    + "            <MII_Status>up</MII_Status>"
+                    + "            <Speed>100 Mbps</Speed>"
+                    + "            <Duplex>full</Duplex>"
+                    + "            <Link_Failure_Count>0</Link_Failure_Count>"
+                    + "            <Permanent_HW_addr>52:54:00:26:7f:a0</Permanent_HW_addr>"
+                    + "          </Slave_Interface>"
+                    + "          <Family Type=\"AF_INET\">"
+                    + "            <MAC>52:54:00:26:7F:A0</MAC>"
+                    + "            <mtu>1500</mtu>"
+                    + "          </Family>"
+                    + "          <BootProto>none</BootProto>"
+                    + "        </Device>"
+                    + "      </Bonding>"
+                    + "      <Bridges>"
+                    + "        <Device Name=\""
+                    + INT
+                    + "\">"
+                    + "          <Family Type=\"AF_INET\">"
+                    + "            <MAC>"
+                    + MAC
+                    + "</MAC>"
+                    + "            <Address>"
+                    + IP
+                    + "</Address>"
+                    + "            <Netmask>255.255.255.0</Netmask>"
+                    + "            <Broadcast>"
+                    + BR
+                    + "</Broadcast>"
+                    + "          </Family>"
+                    + "          <Interfaces>"
+                    + "            <PhyInterface>"
+                    + PHY
+                    + "</PhyInterface>"
+                    + "          </Interfaces>"
+                    + "          <BootProto>static</BootProto>"
+                    + "        </Device>"
+                    + "        <Device Name=\"xenbr1\">"
+                    + "          <Family Type=\"AF_INET\">"
+                    + "            <MAC>52:54:00:26:7F:A0</MAC>"
+                    + "          </Family>"
+                    + "          <Interfaces>"
+                    + "            <PhyInterface>bond1</PhyInterface>"
+                    + "          </Interfaces>"
+                    + "          <BootProto>none</BootProto>"
+                    + "        </Device>"
+                    + "        <Device Name=\""
+                    + CONTROL
+                    + "\">"
+                    + "          \"<Family Type=\"AF_INET\">"
+                    + "            <MAC>"
+                    + CONTROLMAC
+                    + "</MAC>"
+                    + "          </Family>"
+                    + "          <Interfaces>"
+                    + "          </Interfaces>"
+                    + "          <BootProto>none</BootProto>"
+                    + "        </Device>"
+                    + "        <Device Name=\"xenbr0.200\">"
+                    + "          <Family Type=\"AF_INET\">"
+                    + "            <MAC>52:54:00:26:7F:A0</MAC>"
+                    + "          </Family>"
+                    + "          <Interfaces>"
+                    + "            <PhyInterface>bond1.200</PhyInterface>"
+                    + "          </Interfaces>"
+                    + "         <BootProto>none</BootProto>"
+                    + "        </Device>"
+                    + "      </Bridges>"
+                    + "      <Infiniband>"
+                    + "      </Infiniband>"
+                    + "    </Active>"
+                    + "  </Network>"
+                    + "</Discover_Network_Result>");
+
+    public String getDiscoverNetwork() {
+        return DISCOVERNETWORK;
+    }
+
+    @Test
+    public void testDiscoverNetwork() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(net.discoverNetwork(), false);
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERNETWORK));
+        results.basicBooleanTest(net.discoverNetwork());
+        results.basicStringTest(net.getBridgeByIp(IP).getName(), INT);
+        results.basicStringTest(net.getBridgeByName(INT).getAddress(), IP);
+        results.basicStringTest(net.getInterfaceByName(CONTROL).getMac(), CONTROLMAC);
+        net.getBridgeByIp("");
+        results.basicBooleanTest(net.getSuccess(), false);
+        net.getBridgeByName("");
+        results.basicBooleanTest(net.getSuccess(), false);
+        // results.basicStringTest(net.getBridgeByIp("").getName(), INT);
+        results.basicStringTest(net.getInterfaceByIp(IP).getName(), INT);
+        results.basicStringTest(net.getInterfaceByName(INT).getAddress(), IP);
+        results.basicStringTest(net.getInterfaceByName(INT).getBroadcast(), BR);
+        results.basicStringTest(net.getInterfaceByName(INT).getMac(), MAC);
+        results.basicStringTest(net.getPhysicalByBridgeName(INT), PHY);
+
+    }
+
+    @Test
+    public void testInterfacesNotFound() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(net.discoverNetwork(), false);
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERNETWORK));
+        results.basicBooleanTest(net.discoverNetwork());
+        if (net.getInterfaceByName(CONTROL+ "xx") == null) {
+            System.out.println("yay!");
+        };
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testLocalBreak() throws Ovm3ResourceException {
+        con.setResult(results
+                .errorResponseWrap(
+                        1,
+                        "exceptions.RuntimeError:Command: ['/etc/xen/scripts/linuxbridge/ovs-local-bridge', 'start', 'bridge=control0'] failed (1): stderr: Start local network: Bridge control0 Is Busy"));
+        results.basicBooleanTest(net.startOvsLocalConfig(CONTROL), false);
+    }
+
+    @Test
+    public void testLocal() throws Ovm3ResourceException {
+        String resp = "local bridge " + CONTROL;
+        con.setResult(results.simpleResponseWrap("start " + resp));
+        results.basicBooleanTest(net.startOvsLocalConfig(CONTROL));
+        con.setResult(results.simpleResponseWrap("stop " + resp));
+        results.basicBooleanTest(net.stopOvsLocalConfig(CONTROL));
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testVlanBridgeBreak() throws Ovm3ResourceException {
+        con.setResult(results
+                .errorResponseWrap(
+                        1,
+                        "exceptions.RuntimeError:Command: ['/etc/xen/scripts/linuxbridge/ovs-local-bridge', 'start', 'bridge=control0'] failed (1): stderr: Start local network: Bridge control0 Is Busy"));
+        results.basicBooleanTest(net.startOvsVlanBridge(
+                VLANINT + "." + VLAN.toString(), VLANBR, VLAN), false);
+    }
+
+    @Test
+    public void testVlanBridge() throws Ovm3ResourceException {
+        String resp = "bridge=" + VLANINT + "." + VLAN.toString() + " netdev="
+                + VLANBR + " vlan " + VLAN.toString();
+        con.setResult(results.simpleResponseWrap("start " + resp));
+        results.basicBooleanTest(net.startOvsVlanBridge(
+                VLANINT + "." + VLAN.toString(), VLANBR, VLAN));
+        con.setResult(results.simpleResponseWrap("stop " + resp));
+        results.basicBooleanTest(net.stopOvsVlanBridge(
+                VLANINT + "." + VLAN.toString(), VLANBR, VLAN));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/NtpTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/NtpTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/NtpTest.java
new file mode 100644
index 0000000..1c5d374
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/NtpTest.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+public class NtpTest {
+    ConnectionTest con = new ConnectionTest();
+    Ntp nTp = new Ntp(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+    String details = results.simpleResponseWrapWrapper("<array>\n"
+            + "<data>\n"
+            + "<value>\n"
+            + "<array>\n"
+            + "<data>\n"
+            + "<value><string>ovm-1</string></value>\n"
+            + "<value><string>ovm-2</string></value>\n"
+            + "</data>\n"
+            + "</array>\n"
+            + "</value>\n"
+            + "<value><boolean>1</boolean></value>\n"
+            + "<value><boolean>1</boolean></value>\n"
+            + "</data>\n"
+            + "</array>\n");
+
+    public void testGetNtp() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(nTp.getDetails());
+    }
+
+    @Test
+    public void testEnableNtp() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(nTp.enableNtp());
+    }
+    @Test
+    public void testDisableNtp() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(nTp.disableNtp());
+    }
+
+    @Test
+    public void testGetDetails() throws Ovm3ResourceException {
+        con.setResult(details);
+        results.basicBooleanTest(nTp.getDetails());
+        results.basicBooleanTest(nTp.isRunning());
+        results.basicBooleanTest(nTp.isServer());
+    }
+
+    @Test
+    public void testSetNTP() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(nTp.setNtp("ovm-1", true));
+        con.setResult(details);
+        results.basicBooleanTest(nTp.getDetails());
+        List<String> ntpHosts = new ArrayList<String>();
+        nTp.setServers(ntpHosts);
+        results.basicBooleanTest(nTp.setNtp(true), false);
+    }
+
+    @Test
+    public void testServerAdditionRemoval() throws Ovm3ResourceException {
+        List<String> ntpHosts = new ArrayList<String>();
+        con.setResult(details);
+        nTp.getDetails();
+        ntpHosts = nTp.getServers();
+        assertEquals(ntpHosts.size(), 2);
+        nTp.removeServer("ovm-2");
+        ntpHosts = nTp.getServers();
+        assertEquals(ntpHosts.size(), 1);
+        nTp.removeServer("ovm-2");
+        ntpHosts = nTp.getServers();
+        assertEquals(ntpHosts.size(), 1);
+        nTp.addServer("ovm-1");
+        ntpHosts = nTp.getServers();
+        assertEquals(ntpHosts.size(), 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/PoolOCFS2Test.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/PoolOCFS2Test.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/PoolOCFS2Test.java
new file mode 100644
index 0000000..eed26da
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/PoolOCFS2Test.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import org.junit.Test;
+
+public class PoolOCFS2Test {
+    ConnectionTest con = new ConnectionTest();
+    PoolOCFS2 poolfs = new PoolOCFS2(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    private String TYPE = "nfs";
+    private String UUID = "f12842eb-f5ed-3fe7-8da1-eb0e17f5ede8";
+    private String BOGUSUUID = "deadbeef-dead-beef-dead-beef0000002d";
+    private String TARGET = "cs-mgmt:/volumes/cs-data/primary/ovm/VirtualMachines";
+    private String BASE = "f12842ebf5ed3fe78da1eb0e17f5ede8";
+    private String MANAGER = "d1a749d4295041fb99854f52ea4dea97";
+    private String CLUSTER = MANAGER.substring(0, 15);
+    private String VERSION = "3.0";
+    private String POOLUUID = "f12842eb-f5ed-3fe7-8da1-eb0e17f5ede8";
+    private String EMPTY = results.escapeOrNot("<?xml version=\"1.0\" ?>"
+            + "<Discover_Pool_Filesystem_Result>"
+            + "</Discover_Pool_Filesystem_Result>");
+    private String DISCOVERPOOLFS = results
+            .escapeOrNot("<?xml version=\"1.0\" ?>"
+                    + "<Discover_Pool_Filesystem_Result>" + "<Pool_Filesystem>"
+                    + "<Pool_Filesystem_Type>"
+                    + TYPE
+                    + "</Pool_Filesystem_Type>"
+                    + "<Pool_Filesystem_Target>"
+                    + TARGET
+                    + "</Pool_Filesystem_Target>"
+                    + "<Pool_Filesystem_Uuid>"
+                    + UUID
+                    + "</Pool_Filesystem_Uuid>"
+                    + "<Pool_Filesystem_Nfsbase_Uuid>"
+                    + BASE
+                    + "</Pool_Filesystem_Nfsbase_Uuid>"
+                    + "<Pool_Filesystem_Manager_Uuid>"
+                    + MANAGER
+                    + "</Pool_Filesystem_Manager_Uuid>"
+                    + "<Pool_Filesystem_Version>"
+                    + VERSION
+                    + "</Pool_Filesystem_Version>"
+                    + "<Pool_Filesystem_Pool_Uuid>"
+                    + POOLUUID
+                    + "</Pool_Filesystem_Pool_Uuid>"
+                    + "</Pool_Filesystem>"
+                    + "</Discover_Pool_Filesystem_Result>");
+
+    @Test
+    public void testDiscoverPoolFS() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(EMPTY));
+        results.basicBooleanTest(poolfs.hasAPoolFs(), false);
+        results.basicBooleanTest(poolfs.hasPoolFs(BOGUSUUID), false);
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOLFS));
+        poolfs.discoverPoolFs();
+        results.basicStringTest(poolfs.getPoolFsId(), UUID);
+        results.basicStringTest(poolfs.getPoolFsManagerUuid(), MANAGER);
+        results.basicStringTest(poolfs.getPoolFsNFSBaseId(), BASE);
+        results.basicStringTest(poolfs.getPoolFsTarget(), TARGET);
+        results.basicStringTest(poolfs.getPoolFsUuid(), UUID);
+        results.basicStringTest(poolfs.getPoolFsVersion(), VERSION);
+        results.basicStringTest(poolfs.getPoolPoolFsId(), POOLUUID);
+        results.basicStringTest(poolfs.getPoolFsType(), TYPE);
+        results.basicBooleanTest(poolfs.hasAPoolFs());
+        results.basicBooleanTest(poolfs.hasPoolFs(UUID));
+    }
+
+    @Test
+    public void testCreatePoolFS() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        poolfs.createPoolFs(TYPE, TARGET, CLUSTER, UUID, BASE, MANAGER);
+
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOLFS));
+        results.basicBooleanTest(poolfs.hasPoolFs(UUID));
+        poolfs.createPoolFs(TYPE, TARGET, CLUSTER, UUID, BASE, MANAGER);
+    }
+
+    @Test
+    public void testDestroyPoolFS() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        poolfs.destroyPoolFs(TYPE, TARGET, UUID, BASE);
+
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOLFS));
+        results.basicBooleanTest(poolfs.hasPoolFs(UUID));
+        poolfs.createPoolFs(TYPE, TARGET, CLUSTER, UUID, BASE, MANAGER);
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testCreatePoolFSError() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOLFS));
+        poolfs.createPoolFs(TYPE, TARGET, CLUSTER, BOGUSUUID, BASE, MANAGER);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/PoolTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/PoolTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/PoolTest.java
new file mode 100644
index 0000000..db4e340
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/PoolTest.java
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+public class PoolTest {
+    ConnectionTest con = new ConnectionTest();
+    Pool pool = new Pool(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    private String UUID = "0004fb0000020000ba9aaf00ae5e2d73";
+    private String BOGUSUUID = "deadbeefdeadbeefdeadbeefdeadbeef";
+    private String VIP = "192.168.1.230";
+    private String ALIAS = "Pool 0";
+    private String HOST = "ovm-1";
+    private String HOST2 = "ovm-2";
+    private String IP = "192.168.1.64";
+    private String IP2 = "192.168.1.65";
+    private String EMPTY = results.escapeOrNot("<?xml version=\"1.0\" ?>"
+            + "<Discover_Server_Pool_Result/>");
+    private String DISCOVERPOOL = results
+            .escapeOrNot("<?xml version=\"1.0\" ?>"
+                    + "<Discover_Server_Pool_Result>" + "  <Server_Pool>"
+                    + "    <Unique_Id>"
+                    + UUID
+                    + "</Unique_Id>"
+                    + "    <Pool_Alias>"
+                    + ALIAS
+                    + "</Pool_Alias>"
+                    + "    <Master_Virtual_Ip>"
+                    + VIP
+                    + "</Master_Virtual_Ip>"
+                    + "    <Member_List>"
+                    + "      <Member>"
+                    + "        <Registered_IP>"
+                    + IP
+                    + "</Registered_IP>"
+                    + "      </Member>"
+                    + "      <Member>"
+                    + "        <Registered_IP>"
+                    + IP2
+                    + "</Registered_IP>"
+                    + "      </Member>"
+                    + "    </Member_List>"
+                    + "  </Server_Pool>" + "</Discover_Server_Pool_Result>");
+
+
+    @Test
+    public void testDiscoverServerPool() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(EMPTY));
+        results.basicBooleanTest(pool.isInAPool(), false);
+        results.basicBooleanTest(pool.isInPool(UUID), false);
+        results.basicBooleanTest(pool.discoverServerPool(), false);
+        results.basicBooleanTest(pool.isInPool(UUID), false);
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOL));
+        results.basicBooleanTest(pool.discoverServerPool());
+        results.basicBooleanTest(pool.isInAPool(), true);
+        results.basicBooleanTest(pool.isInPool(UUID), true);
+        results.basicStringTest(pool.getPoolId(), UUID);
+        results.basicStringTest(pool.getPoolId(), UUID);
+        results.basicStringTest(pool.getPoolAlias(), ALIAS);
+        results.basicStringTest(pool.getPoolMasterVip(), VIP);
+        results.basicBooleanTest(pool.getPoolMemberList().contains(IP));
+        results.basicBooleanTest(pool.getPoolMemberList().contains(IP2));
+    }
+
+    @Test
+    public void poolMembers() throws Ovm3ResourceException {
+        List<String> poolHosts = new ArrayList<String>();
+        poolHosts.add(IP);
+        poolHosts.add(IP2);
+        con.setResult(results.simpleResponseWrapWrapper(EMPTY));
+        results.basicBooleanTest(pool.getPoolMemberList().contains(IP), false);
+
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOL));
+        results.basicBooleanTest(pool.discoverServerPool());
+        con.setResult(results.getNil());
+        results.basicBooleanTest(pool.removePoolMember(IP), true);
+        results.basicBooleanTest(pool.addPoolMember(IP), true);
+        results.basicBooleanTest(pool.setPoolMemberList(poolHosts), true);
+    }
+
+    @Test
+    public void testCreateServerPool() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(
+                pool.createServerPool(ALIAS, UUID, VIP, 1, HOST, IP), true);
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOL));
+        results.basicBooleanTest(pool.discoverServerPool());
+        results.basicBooleanTest(
+                pool.createServerPool(ALIAS, UUID, VIP, 1, HOST, IP), true);
+
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testCreateServerPoolFail1() throws Ovm3ResourceException {
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOL));
+        results.basicBooleanTest(
+                pool.createServerPool(ALIAS, BOGUSUUID, VIP, 1, HOST, IP),
+                false);
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testCreateServerPoolFail2() throws Ovm3ResourceException {
+        con.setResult(results.errorResponseWrap(1,
+                "exceptions.Exception:Repository already exists"));
+        results.basicBooleanTest(
+                pool.createServerPool(ALIAS, UUID, VIP, 1, HOST, IP), false);
+    }
+
+    @Test
+    public void testJoinServerPool() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        Integer poolsize = 2;
+        results.basicBooleanTest(
+                pool.joinServerPool(ALIAS, UUID, VIP, poolsize, HOST2, IP2),
+                true);
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOL));
+        results.basicBooleanTest(pool.discoverServerPool());
+        results.basicBooleanTest(
+                pool.joinServerPool(ALIAS, UUID, VIP, poolsize, HOST2, IP2),
+                true);
+    }
+    @Test(expected = Ovm3ResourceException.class)
+    public void testJoinServerPoolFail1() throws Ovm3ResourceException {
+        Integer poolsize = 2;
+        con.setResult(results.simpleResponseWrapWrapper(DISCOVERPOOL));
+        results.basicBooleanTest(pool.joinServerPool(ALIAS, BOGUSUUID, VIP,
+                poolsize, HOST2, IP2), false);
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testJoinServerPoolFail() throws Ovm3ResourceException {
+        con.setResult(results
+                .errorResponseWrap(1,
+                        "exceptions.Exception:Server already a member of pool: "
+                                + UUID));
+        Integer poolsize = 2;
+        results.basicBooleanTest(pool.joinServerPool(ALIAS, UUID, VIP, poolsize,
+                HOST2, IP2), false);
+    }
+
+    @Test
+    public void testValidPoolRoles() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(pool.setServerRoles(pool.getValidRoles()),
+                true);
+
+    }
+
+    @Test(expected = Ovm3ResourceException.class)
+    public void testValidPoolRolesInvalid() throws Ovm3ResourceException {
+        String broken = "broken_token";
+        con.setResult(results
+                .errorResponseWrap(1,
+                "exceptions.Exception:Invalid roles: set(['xen', '" + broken
+                        + "', 'utility'])"));
+        results.basicBooleanTest(pool.setServerRoles(pool.getValidRoles()),
+                false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/RemoteTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/RemoteTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/RemoteTest.java
new file mode 100644
index 0000000..a5952ab
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/RemoteTest.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+import org.junit.Test;
+
+public class RemoteTest {
+    ConnectionTest con = new ConnectionTest();
+    Remote rEm = new Remote(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    @Test
+    public void TestSysShutdown() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(rEm.sysShutdown());
+    }
+    @Test
+    public void TestSysReboot() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(rEm.sysReboot());
+    }
+}


[08/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java
new file mode 100644
index 0000000..9950e4d
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3Configuration.java
@@ -0,0 +1,466 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.commons.lang.BooleanUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.hypervisor.ovm3.objects.Network;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.net.NetUtils;
+
+/* holds config data for the Ovm3 Hypervisor */
+public class Ovm3Configuration {
+    private static final Logger LOGGER = Logger
+            .getLogger(Ovm3Configuration.class);
+    private String agentIp;
+    private Long agentZoneId;
+    private Long agentPodId;
+    private String agentPoolId;
+    private Long agentClusterId;
+    private String agentHostname;
+    private String csHostGuid;
+    private String agentSshUserName = "root";
+    private String agentSshPassword;
+    private String agentOvsAgentUser = "oracle";
+    private String agentOvsAgentPassword;
+    private Integer agentOvsAgentPort = 8899;
+    private Boolean agentOvsAgentSsl = false;
+    private String agentSshKeyFile = "id_rsa.cloud";
+    private String agentOwnedByUuid = "d1a749d4295041fb99854f52ea4dea97";
+    private Boolean agentIsMaster = false;
+    private Boolean agentHasMaster = false;
+    private Boolean agentInOvm3Pool = false;
+    private Boolean agentInOvm3Cluster = false;
+    private String ovm3PoolVip = "";
+    private String agentPrivateNetworkName;
+    private String agentPublicNetworkName;
+    private String agentGuestNetworkName;
+    private String agentStorageNetworkName;
+    private String agentControlNetworkName = "control0";
+    private String agentOvmRepoPath = "/OVS/Repositories";
+    private String agentSecStoragePath = "/nfsmnt";
+    private String agentScript = "cloudstack.py";
+    private String agentCheckStorageScript = "storagehealth.py";
+    private Integer agentStorageCheckTimeout = 120;
+    private Integer agentStorageCheckInterval = 1;
+    private List<String> agentScripts = Arrays.asList(agentCheckStorageScript, agentScript);
+    private String agentScriptsDir = "/opt/cloudstack/bin";
+    private int domRSshPort = 3922;
+    private String domRCloudPath = "/opt/cloud/bin/";
+    private String virtualdiskdir = "VirtualDisks";
+    private String templatedir = "Templates";
+    private Map<String, Network.Interface> agentInterfaces = null;
+    private Boolean istest = false;
+    private Map<String, Object> rawParams = new HashMap<String, Object>();
+
+    public Ovm3Configuration(Map<String, Object> params)
+            throws ConfigurationException {
+        setAgentZoneId(Long.parseLong((String) params.get("zone")));
+        setAgentPodId(Long.parseLong(validateParam("PodId",
+                (String) params.get("pod"))));
+        setAgentClusterId(Long.parseLong((String) params.get("cluster")));
+        setOvm3PoolVip(String.valueOf(params.get("ovm3vip")));
+        setAgentInOvm3Pool(BooleanUtils.toBoolean((String) params
+                .get("ovm3pool")));
+        setAgentInOvm3Cluster(BooleanUtils.toBoolean((String) params
+                .get("ovm3cluster")));
+        setAgentHostname(validateParam("Hostname", (String) params.get("host")));
+        setAgentIp((String) params.get("ip"));
+        if (params.get("agentport") != null) {
+            setAgentOvsAgentPort(Integer.parseInt((String) params
+                    .get("agentport")));
+        }
+        setAgentSshUserName(validateParam("Username",
+                (String) params.get("username")));
+        setAgentSshPassword(validateParam("Password",
+                (String) params.get("password")));
+        setCsHostGuid(validateParam("Cloudstack Host GUID", (String) params.get("guid")));
+        setAgentOvsAgentUser(validateParam("OVS Username",
+                (String) params.get("agentusername")));
+        setAgentOvsAgentPassword(validateParam("OVS Password",
+                (String) params.get("agentpassword")));
+        setAgentPrivateNetworkName((String) params
+                .get("private.network.device"));
+        setAgentPublicNetworkName((String) params.get("public.network.device"));
+        setAgentGuestNetworkName((String) params.get("guest.network.device"));
+        setAgentStorageNetworkName((String) params
+                .get("storage.network.device1"));
+        this.setAgentStorageCheckTimeout(NumbersUtil.parseInt(
+                (String) params.get("ovm3.heartbeat.timeout"),
+                agentStorageCheckTimeout));
+        this.setAgentStorageCheckInterval(NumbersUtil.parseInt(
+                (String) params.get("ovm3.heartbeat.interval"),
+                agentStorageCheckInterval));
+        validatePoolAndCluster();
+        if (params.containsKey("istest")) {
+            setIsTest((Boolean) params.get("istest"));
+        }
+    }
+
+    /**
+     * validatePoolAndCluster:
+     * A cluster is impossible with a  pool.
+     * A pool is impossible without a vip.
+     */
+    private void validatePoolAndCluster() {
+        if (agentInOvm3Cluster) {
+            LOGGER.debug("Clustering requires a pool, setting pool to true");
+            agentInOvm3Pool = true;
+        }
+        if (!NetUtils.isValidIp(ovm3PoolVip)) {
+            LOGGER.debug("No VIP, Setting ovm3pool and ovm3cluster to false");
+            agentInOvm3Pool = false;
+            agentInOvm3Cluster = false;
+            ovm3PoolVip = "";
+        }
+    }
+
+    public String getAgentName() {
+        return agentHostname;
+    }
+
+    public void setAgentName(String agentName) {
+        this.agentHostname = agentName;
+    }
+
+    public String getAgentIp() {
+        return agentIp;
+    }
+
+    public void setAgentIp(String agentIp) {
+        this.agentIp = agentIp;
+    }
+
+    public Long getAgentZoneId() {
+        return agentZoneId;
+    }
+
+    public void setAgentZoneId(Long agentZoneId) {
+        this.agentZoneId = agentZoneId;
+    }
+
+    public Long getAgentPodId() {
+        return agentPodId;
+    }
+
+    public void setAgentPodId(Long agentPodId) {
+        this.agentPodId = agentPodId;
+    }
+
+    public String getAgentPoolId() {
+        return agentPoolId;
+    }
+
+    public void setAgentPoolId(String agentPoolId) {
+        this.agentPoolId = agentPoolId;
+    }
+
+    public Long getAgentClusterId() {
+        return agentClusterId;
+    }
+
+    public void setAgentClusterId(Long agentClusterId) {
+        this.agentClusterId = agentClusterId;
+    }
+
+    public String getAgentHostname() {
+        return agentHostname;
+    }
+
+    public void setAgentHostname(String agentHostname) {
+        this.agentHostname = agentHostname;
+    }
+
+    public String getCsHostGuid() {
+        return csHostGuid;
+    }
+
+    public void setCsHostGuid(String csHostGuid) {
+        this.csHostGuid = csHostGuid;
+    }
+
+    public String getAgentSshUserName() {
+        return agentSshUserName;
+    }
+
+    public void setAgentSshUserName(String agentSshUserName) {
+        this.agentSshUserName = agentSshUserName;
+    }
+
+    public String getAgentSshPassword() {
+        return agentSshPassword;
+    }
+
+    public void setAgentSshPassword(String agentSshPassword) {
+        this.agentSshPassword = agentSshPassword;
+    }
+
+    public String getAgentOvsAgentUser() {
+        return agentOvsAgentUser;
+    }
+
+    public void setAgentOvsAgentUser(String agentOvsAgentUser) {
+        this.agentOvsAgentUser = agentOvsAgentUser;
+    }
+
+    public String getAgentOvsAgentPassword() {
+        return agentOvsAgentPassword;
+    }
+
+    public void setAgentOvsAgentPassword(String agentOvsAgentPassword) {
+        this.agentOvsAgentPassword = agentOvsAgentPassword;
+    }
+
+    public Integer getAgentOvsAgentPort() {
+        return agentOvsAgentPort;
+    }
+
+    public void setAgentOvsAgentPort(Integer agentOvsAgentPort) {
+        this.agentOvsAgentPort = agentOvsAgentPort;
+    }
+
+    public Boolean getAgentOvsAgentSsl() {
+        return agentOvsAgentSsl;
+    }
+
+    public void setAgentOvsAgentSsl(Boolean agentOvsAgentSsl) {
+        this.agentOvsAgentSsl = agentOvsAgentSsl;
+    }
+
+    public String getAgentSshKeyFileName() {
+        return agentSshKeyFile;
+    }
+
+    public void setAgentSshKeyFileName(String agentSshFile) {
+        this.agentSshKeyFile = agentSshFile;
+    }
+
+    public String getAgentOwnedByUuid() {
+        return agentOwnedByUuid;
+    }
+
+    public void setAgentOwnedByUuid(String agentOwnedByUuid) {
+        this.agentOwnedByUuid = agentOwnedByUuid;
+    }
+
+    public Boolean getAgentIsMaster() {
+        return agentIsMaster;
+    }
+
+    public void setAgentIsMaster(Boolean agentIsMaster) {
+        this.agentIsMaster = agentIsMaster;
+    }
+
+    public Boolean getAgentHasMaster() {
+        return agentHasMaster;
+    }
+
+    public void setAgentHasMaster(Boolean agentHasMaster) {
+        this.agentHasMaster = agentHasMaster;
+    }
+
+    public Boolean getAgentInOvm3Pool() {
+        return agentInOvm3Pool;
+    }
+
+    public void setAgentInOvm3Pool(Boolean agentInOvm3Pool) {
+        this.agentInOvm3Pool = agentInOvm3Pool;
+    }
+
+    public Boolean getAgentInOvm3Cluster() {
+        return agentInOvm3Cluster;
+    }
+
+    public void setAgentInOvm3Cluster(Boolean agentInOvm3Cluster) {
+        this.agentInOvm3Cluster = agentInOvm3Cluster;
+    }
+
+    public String getOvm3PoolVip() {
+        return ovm3PoolVip;
+    }
+
+    public void setOvm3PoolVip(String ovm3PoolVip) {
+        this.ovm3PoolVip = ovm3PoolVip;
+    }
+
+    public String getAgentPrivateNetworkName() {
+        return agentPrivateNetworkName;
+    }
+
+    public void setAgentPrivateNetworkName(String agentPrivateNetworkName) {
+        this.agentPrivateNetworkName = agentPrivateNetworkName;
+    }
+
+    public String getAgentPublicNetworkName() {
+        return agentPublicNetworkName;
+    }
+
+    public void setAgentPublicNetworkName(String agentPublicNetworkName) {
+        this.agentPublicNetworkName = agentPublicNetworkName;
+    }
+
+    public String getAgentGuestNetworkName() {
+        return agentGuestNetworkName;
+    }
+
+    public void setAgentGuestNetworkName(String agentGuestNetworkName) {
+        this.agentGuestNetworkName = agentGuestNetworkName;
+    }
+
+    public String getAgentStorageNetworkName() {
+        return agentStorageNetworkName;
+    }
+
+    public void setAgentStorageNetworkName(String agentStorageNetworkName) {
+        this.agentStorageNetworkName = agentStorageNetworkName;
+    }
+
+    public String getAgentControlNetworkName() {
+        return agentControlNetworkName;
+    }
+
+    public void setAgentControlNetworkName(String agentControlNetworkName) {
+        this.agentControlNetworkName = agentControlNetworkName;
+    }
+
+    public String getAgentOvmRepoPath() {
+        return agentOvmRepoPath;
+    }
+
+    public void setAgentOvmRepoPath(String agentOvmRepoPath) {
+        this.agentOvmRepoPath = agentOvmRepoPath;
+    }
+
+    public String getAgentSecStoragePath() {
+        return agentSecStoragePath;
+    }
+
+    public void setAgentSecStoragePath(String agentSecStoragePath) {
+        this.agentSecStoragePath = agentSecStoragePath;
+    }
+
+    public int getDomRSshPort() {
+        return domRSshPort;
+    }
+
+    public void setDomRSshPort(int domRSshPort) {
+        this.domRSshPort = domRSshPort;
+    }
+
+    public String getDomRCloudPath() {
+        return domRCloudPath;
+    }
+
+    public void setDomRCloudPath(String domRCloudPath) {
+        this.domRCloudPath = domRCloudPath;
+    }
+    public Boolean getIsTest() {
+        return istest;
+    }
+    public void setIsTest(Boolean t) {
+        istest = t;
+    }
+    public String getAgentScript() {
+        return agentScript;
+    }
+
+    public void setAgentScript(String agentScript) {
+        this.agentScript = agentScript;
+    }
+
+    public String getAgentScriptsDir() {
+        return agentScriptsDir;
+    }
+
+    public void setAgentScriptsDir(String agentScriptsDir) {
+        this.agentScriptsDir = agentScriptsDir;
+    }
+
+    public Map<String, Network.Interface> getAgentInterfaces() {
+        return agentInterfaces;
+    }
+
+    public void setAgentInterfaces(Map<String, Network.Interface> agentInterfaces) {
+        this.agentInterfaces = agentInterfaces;
+    }
+    public List<String> getAgentScripts() {
+        return agentScripts;
+    }
+
+    public void setAgentScripts(List<String> agentScripts) {
+        this.agentScripts = agentScripts;
+    }
+    public String getAgentCheckStorageScript() {
+        return agentCheckStorageScript;
+    }
+
+    public void setAgentCheckStorageScript(String agentCheckStorageScript) {
+        this.agentCheckStorageScript = agentCheckStorageScript;
+    }
+    public Integer getAgentStorageCheckTimeout() {
+        return agentStorageCheckTimeout;
+    }
+    public void setAgentStorageCheckTimeout(Integer agentStorageCheckTimeout) {
+        this.agentStorageCheckTimeout = agentStorageCheckTimeout;
+    }
+
+    public Integer getAgentStorageCheckInterval() {
+        return agentStorageCheckInterval;
+    }
+
+    public void setAgentStorageCheckInterval(Integer agentStorageCheckInterval) {
+        this.agentStorageCheckInterval = agentStorageCheckInterval;
+    }
+    public String getVirtualDiskDir() {
+        return this.virtualdiskdir;
+    }
+    public String getTemplateDir() {
+        return this.templatedir;
+    }
+    /**
+     * ValidateParam: Validate the input for configure
+     * @param name
+     * @param param
+     * @return param
+     * @throws ConfigurationException
+     */
+    private String validateParam(String name, String param) throws ConfigurationException {
+        if (param == null) {
+            String msg = "Unable to get " + name + " params are null";
+            LOGGER.debug(msg);
+            throw new ConfigurationException(msg);
+        }
+        return param;
+    }
+
+    public Map<String, Object> getRawParams() {
+        return rawParams;
+    }
+    public void setRawParams(Map<String, Object> params) {
+        rawParams.putAll(params);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetwork.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetwork.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetwork.java
new file mode 100644
index 0000000..d688b0b
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorNetwork.java
@@ -0,0 +1,251 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import java.util.List;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Network;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+
+public class Ovm3HypervisorNetwork {
+    private static final Logger LOGGER = Logger
+            .getLogger(Ovm3HypervisorNetwork.class);
+    private Connection c;
+    private Ovm3Configuration config;
+    public Ovm3HypervisorNetwork(Connection conn, Ovm3Configuration ovm3config) {
+        c = conn;
+        config = ovm3config;
+    }
+
+    public void configureNetworking() throws ConfigurationException {
+        /* TODO: setup meta tags for the management interface (probably
+        * required with multiple interfaces)?
+        */
+        try {
+           Network net = new Network(c);
+           String controlIface = config.getAgentControlNetworkName();
+           if (controlIface != null
+                   && net.getInterfaceByName(controlIface) == null) {
+               LOGGER.debug("starting " + controlIface);
+               net.startOvsLocalConfig(controlIface);
+               /* ovs replies too "fast" so the bridge can be "busy" */
+               int contCount = 0;
+               while (net.getInterfaceByName(controlIface) == null) {
+                   LOGGER.debug("waiting for " + controlIface);
+                   Thread.sleep(1 * 1000);
+                   if (contCount > 9) {
+                       throw new ConfigurationException("Unable to configure "
+                               + controlIface + " on host "
+                               + config.getAgentHostname());
+                   }
+                   contCount++;
+               }
+           } else {
+               LOGGER.debug("already have " + controlIface);
+           }
+           /*
+            * The bridge is remembered upon reboot, but not the IP or the
+            * config. Zeroconf also adds the route again by default.
+            */
+           net.ovsIpConfig(controlIface, "static",
+                   NetUtils.getLinkLocalGateway(),
+                   NetUtils.getLinkLocalNetMask());
+           CloudstackPlugin cSp = new CloudstackPlugin(c);
+           cSp.ovsControlInterface(controlIface,
+                   NetUtils.getLinkLocalCIDR());
+        } catch (InterruptedException e) {
+            LOGGER.error("interrupted?", e);
+        } catch (Ovm3ResourceException e) {
+            String msg = "Basic configuration failed on " + config.getAgentHostname();
+            LOGGER.error(msg, e);
+            throw new ConfigurationException(msg + ", " + e.getMessage());
+        }
+    }
+
+    /**/
+    private boolean isNetworkSetupByName(String nameTag) {
+        if (nameTag != null) {
+            LOGGER.debug("Looking for network setup by name " + nameTag);
+
+            try {
+                Network net = new Network(c);
+                net.getInterfaceList();
+                if (net.getBridgeByName(nameTag) != null) {
+                    LOGGER.debug("Found bridge with name: " + nameTag);
+                    return true;
+                }
+            } catch (Ovm3ResourceException e) {
+                LOGGER.debug("Unxpected error looking for name: " + nameTag, e);
+                return false;
+            }
+        }
+        LOGGER.debug("No bridge with name: " + nameTag);
+        return false;
+    }
+
+    /* this might have to change in the future, works for now... */
+    public CheckNetworkAnswer execute(CheckNetworkCommand cmd) {
+        LOGGER.debug("Checking if network name setup is done on "
+                    + config.getAgentHostname());
+
+        List<PhysicalNetworkSetupInfo> infoList = cmd
+                .getPhysicalNetworkInfoList();
+        /* here we assume all networks are set */
+        for (PhysicalNetworkSetupInfo info : infoList) {
+            if (info.getGuestNetworkName() == null) {
+                info.setGuestNetworkName(config.getAgentGuestNetworkName());
+            }
+            if (info.getPublicNetworkName() == null) {
+                info.setPublicNetworkName(config.getAgentPublicNetworkName());
+            }
+            if (info.getPrivateNetworkName() == null) {
+                info.setPrivateNetworkName(config.getAgentPrivateNetworkName());
+            }
+            if (info.getStorageNetworkName() == null) {
+                info.setStorageNetworkName(config.getAgentStorageNetworkName());
+            }
+
+            if (!isNetworkSetupByName(info.getGuestNetworkName())) {
+                String msg = "Guest Physical Network id:"
+                        + info.getPhysicalNetworkId()
+                        + ", Guest Network is not configured on the backend by name "
+                        + info.getGuestNetworkName();
+                LOGGER.error(msg);
+                return new CheckNetworkAnswer(cmd, false, msg);
+            }
+            if (!isNetworkSetupByName(info.getPrivateNetworkName())) {
+                String msg = "Private Physical Network id:"
+                        + info.getPhysicalNetworkId()
+                        + ", Private Network is not configured on the backend by name "
+                        + info.getPrivateNetworkName();
+                LOGGER.error(msg);
+                return new CheckNetworkAnswer(cmd, false, msg);
+            }
+            if (!isNetworkSetupByName(info.getPublicNetworkName())) {
+                String msg = "Public Physical Network id:"
+                        + info.getPhysicalNetworkId()
+                        + ", Public Network is not configured on the backend by name "
+                        + info.getPublicNetworkName();
+                LOGGER.error(msg);
+                return new CheckNetworkAnswer(cmd, false, msg);
+            }
+            /* Storage network is optional, will revert to private otherwise */
+        }
+
+        return new CheckNetworkAnswer(cmd, true,
+                "Network Setup check by names is done");
+
+    }
+
+    public Answer execute(PingTestCommand cmd) {
+        try {
+            if (cmd.getComputingHostIp() != null) {
+                CloudstackPlugin cSp = new CloudstackPlugin(c);
+                if (!cSp.ping(cmd.getComputingHostIp())) {
+                    return new Answer(cmd, false, "ping failed");
+                }
+            } else {
+                return new Answer(cmd, false, "why asks me to ping a router???");
+            }
+            return new Answer(cmd, true, "success");
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug("Ping " + cmd.getComputingHostIp() + " failed", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    private String createVlanBridge(String networkName, Integer vlanId)
+            throws Ovm3ResourceException {
+        if (vlanId < 1 || vlanId > 4094) {
+            String msg = "Incorrect vlan " + vlanId
+                    + ", needs to be between 1 and 4094";
+            LOGGER.error(msg);
+            throw new CloudRuntimeException(msg);
+        }
+        Network net = new Network(c);
+        /* figure out if our bridged vlan exists, if not then create */
+        String brName = networkName + "." + vlanId.toString();
+        try {
+            String physInterface = net.getPhysicalByBridgeName(networkName);
+            if (net.getInterfaceByName(brName) == null) {
+                net.startOvsVlanBridge(brName, physInterface, vlanId);
+            } else {
+                LOGGER.debug("Interface " + brName + " already exists");
+            }
+        } catch (Ovm3ResourceException e) {
+            String msg = "Unable to create vlan " + vlanId.toString()
+                    + " bridge for " + networkName;
+            LOGGER.warn(msg + ": " + e);
+            throw new CloudRuntimeException(msg + ":" + e.getMessage());
+        }
+        return brName;
+    }
+    /* getNetwork needs to be split in pure retrieval versus creation */
+    public String getNetwork(NicTO nic) throws Ovm3ResourceException {
+        String vlanId = null;
+        String bridgeName = null;
+        if (nic.getBroadcastType() == BroadcastDomainType.Vlan) {
+            vlanId = BroadcastDomainType.getValue(nic.getBroadcastUri());
+        }
+
+        if (nic.getType() == TrafficType.Guest) {
+            if (nic.getBroadcastType() == BroadcastDomainType.Vlan
+                    && !"untagged".equalsIgnoreCase(vlanId)) {
+                /* This is completely the wrong place for this, we should NEVER
+                 * create a network when we're just trying to figure out if it's there
+                 * The name of this is misleading and wrong.
+                 */
+                bridgeName = createVlanBridge(config.getAgentGuestNetworkName(),
+                        Integer.valueOf(vlanId));
+            } else {
+                bridgeName = config.getAgentGuestNetworkName();
+            }
+
+            /* VLANs for other mgmt traffic ? */
+        } else if (nic.getType() == TrafficType.Control) {
+            bridgeName = config.getAgentControlNetworkName();
+        } else if (nic.getType() == TrafficType.Public) {
+            bridgeName = config.getAgentPublicNetworkName();
+        } else if (nic.getType() == TrafficType.Management) {
+            bridgeName = config.getAgentPrivateNetworkName();
+        } else if (nic.getType() == TrafficType.Storage) {
+            bridgeName = config.getAgentStorageNetworkName();
+        } else {
+            throw new CloudRuntimeException("Unknown network traffic type:"
+                    + nic.getType());
+        }
+        return bridgeName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupport.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupport.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupport.java
new file mode 100644
index 0000000..a9d8130
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3HypervisorSupport.java
@@ -0,0 +1,752 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CheckHealthAnswer;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckOnHostAnswer;
+import com.cloud.agent.api.CheckOnHostCommand;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.HostStatsEntry;
+import com.cloud.agent.api.HostVmStateReportEntry;
+import com.cloud.agent.api.MaintainAnswer;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Common;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Linux;
+import com.cloud.hypervisor.ovm3.objects.Network;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.Pool;
+import com.cloud.hypervisor.ovm3.objects.Xen;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.cloud.vm.VirtualMachine.State;
+import com.trilead.ssh2.SCPClient;
+
+public class Ovm3HypervisorSupport {
+    private final Logger LOGGER = Logger.getLogger(Ovm3HypervisorSupport.class);
+    private Connection c;
+    private Ovm3Configuration config;
+
+    public Ovm3HypervisorSupport(Connection conn, Ovm3Configuration ovm3config) {
+        c = conn;
+        config = ovm3config;
+    }
+
+    /* statemap bounces */
+    private Map<String, PowerState> powerStateMaps;
+    {
+        powerStateMaps = new HashMap<String, PowerState>();
+        powerStateMaps.put("Stopping", PowerState.PowerOn);
+        powerStateMaps.put("Running", PowerState.PowerOn);
+        powerStateMaps.put("Stopped", PowerState.PowerOff);
+        powerStateMaps.put("Error", PowerState.PowerUnknown);
+        powerStateMaps.put("Suspended", PowerState.PowerOn);
+        powerStateMaps.put("Paused", PowerState.PowerOn);
+        /* unknown ? */
+        powerStateMaps.put("Migrating", PowerState.PowerOn);
+    }
+    private Map<String, State> vmStateMap = new HashMap<String, State>();
+    private Map<String, State> stateMaps;
+    {
+        stateMaps = new HashMap<String, State>();
+        stateMaps.put("Stopping", State.Stopping);
+        stateMaps.put("Running", State.Running);
+        stateMaps.put("Stopped", State.Stopped);
+        stateMaps.put("Error", State.Error);
+        stateMaps.put("Suspended", State.Running);
+        stateMaps.put("Paused", State.Running);
+        stateMaps.put("Migrating", State.Migrating);
+    }
+
+    /**
+     * removeVmState: get rid of the state of a VM
+     *
+     * @param vmName
+     */
+    public void revmoveVmState(String vmName) {
+        vmStateMap.remove(vmName);
+    }
+
+    /**
+     * vmStateMapClear: clear out the statemap and repopulate it.
+     *
+     * @throws Ovm3ResourceException
+     */
+    public void vmStateMapClear() throws Ovm3ResourceException {
+        synchronized (vmStateMap) {
+            vmStateMap.clear();
+            syncState(this.vmStateMap);
+        }
+    }
+
+    /**
+     * vmStateStarting: set the state of a vm to starting
+     *
+     * @param vmName
+     */
+    public void setVmStateStarting(String vmName) {
+        setVmState(vmName, State.Starting);
+    }
+
+    /**
+     * getVmState: get the state for a vm
+     *
+     * @param vmName
+     * @return
+     */
+    public State getVmState(String vmName) {
+        return vmStateMap.get(vmName);
+    }
+
+    /**
+     * vmStateChange: set the state of a vm to state
+     *
+     * @param vmName
+     * @param state
+     */
+    public void setVmState(String vmName, State state) {
+        synchronized (vmStateMap) {
+            vmStateMap.put(vmName, state);
+        }
+    }
+
+    /**
+     * getSystemVMKeyFile:
+     * Figure out where the cloud keyfile lives for access to the systemvm.
+     *
+     * @param filename
+     * @return keyfileURI
+     */
+    public File getSystemVMKeyFile(String filename) {
+        String keyPath = Script.findScript("", "scripts/vm/systemvm/"
+                + filename);
+        File keyFile = null;
+        if (keyPath != null) {
+            LOGGER.debug("found SshKey " + keyPath);
+            keyFile = new File(keyPath);
+        }
+        if (keyFile == null || !keyFile.exists()) {
+            String key = "client/target/generated-webapp/WEB-INF/classes/scripts/vm/systemvm/"
+                    + filename;
+            LOGGER.warn("findScript failed, going for generated " + key);
+            keyFile = new File(key);
+        }
+        if (keyFile == null || !keyFile.exists()) {
+            String key = "/usr/share/cloudstack-common/scripts/vm/systemvm/"
+                    + filename;
+            LOGGER.warn("generated key retrieval failed " + key);
+            keyFile = new File(key);
+        }
+        return keyFile;
+    }
+
+    /**
+     * fillHostInfo: Startup the routing for the host.
+     *
+     * @param cmd
+     */
+    public void fillHostInfo(StartupRoutingCommand cmd) {
+        try {
+            /* get data we need from parts */
+            Linux host = new Linux(c);
+            if (!host.getOvmVersion().startsWith("3.2.") && !host.getOvmVersion().startsWith("3.3.")) {
+                LOGGER.error("Hypervisor not supported: " + host.getOvmVersion());
+                throw new CloudRuntimeException(
+                        "OVM 3.2. or 3.3. are only supported, not "
+                                + host.getOvmVersion());
+            } else {
+                LOGGER.debug("Hypervisor version: " + host.getOvmVersion());
+            }
+            cmd.setName(host.getHostName());
+            cmd.setSpeed(host.getCpuKhz());
+            cmd.setCpus(host.getTotalThreads());
+            cmd.setCpuSockets(host.getCpuSockets());
+            cmd.setMemory(host.getMemory().longValue());
+            BigInteger totalmem = BigInteger.valueOf(host.getMemory()
+                    .longValue());
+            BigInteger freemem = BigInteger.valueOf(host.getFreeMemory()
+                    .longValue());
+            cmd.setDom0MinMemory(totalmem.subtract(freemem).longValue());
+            // setPoolSync and setCaps.
+            cmd.setGuid(config.getCsHostGuid());
+            cmd.setDataCenter(config.getAgentZoneId().toString());
+            cmd.setPod(config.getAgentPodId().toString());
+            /* TODO: cmd.setOwner(host.getManagerUuid()); */
+            cmd.setCluster(config.getAgentClusterId().toString());
+            cmd.setHypervisorVersion(host.getOvmVersion());
+            cmd.setVersion(host.getAgentVersion());
+            cmd.setHypervisorType(HypervisorType.Ovm3);
+            cmd.setCaps(host.getCapabilities());
+            cmd.setPrivateIpAddress(c.getIp());
+            cmd.setStorageIpAddress(c.getIp());
+            Network net = new Network(c);
+            String defaultBridge = net.getBridgeByIp(c.getIp()).getName();
+            if (defaultBridge == null) {
+                throw new CloudRuntimeException(
+                        "Unable to obtain valid bridge with " + c.getIp());
+            }
+
+            if (config.getAgentPublicNetworkName() == null) {
+                config.setAgentPublicNetworkName(defaultBridge);
+            }
+            if (config.getAgentPrivateNetworkName() == null) {
+                config.setAgentPrivateNetworkName(config
+                        .getAgentPublicNetworkName());
+            }
+            if (config.getAgentGuestNetworkName() == null) {
+                config.setAgentGuestNetworkName(config
+                        .getAgentPublicNetworkName());
+            }
+            if (config.getAgentStorageNetworkName() == null) {
+                config.setAgentStorageNetworkName(config
+                        .getAgentPrivateNetworkName());
+            }
+            Map<String, String> d = cmd.getHostDetails();
+            d.put("public.network.device", config.getAgentPublicNetworkName());
+            d.put("private.network.device", config.getAgentPrivateNetworkName());
+            d.put("guest.network.device", config.getAgentGuestNetworkName());
+            d.put("storage.network.device", config.getAgentStorageNetworkName());
+            d.put("ismaster", config.getAgentIsMaster().toString());
+            d.put("hasmaster", config.getAgentHasMaster().toString());
+            cmd.setHostDetails(d);
+            LOGGER.debug("Add an Ovm3 host " + config.getAgentHostname() + ":"
+                    + cmd.getHostDetails());
+        } catch (Ovm3ResourceException e) {
+            throw new CloudRuntimeException("Ovm3ResourceException: "
+                    + e.getMessage(), e);
+        }
+    }
+
+    /**
+     * setupServer:
+     * Add the cloudstack plugin and setup the agent.
+     * Add the ssh keys to the host.
+     *
+     * @param c
+     * @throws IOException
+     */
+    public Boolean setupServer(String key) throws IOException {
+        LOGGER.debug("Setup all bits on agent: " + config.getAgentHostname());
+        /* version dependent patching ? */
+        try {
+            com.trilead.ssh2.Connection sshConnection = SSHCmdHelper
+                    .acquireAuthorizedConnection(config.getAgentIp(),
+                            config.getAgentSshUserName(),
+                            config.getAgentSshPassword());
+            if (sshConnection == null) {
+                throw new ConfigurationException(String.format("Unable to "
+                        + "connect to server(IP=%1$s, username=%2$s, "
+                        + "password=%3$s", config.getAgentIp(),
+                        config.getAgentSshUserName(),
+                        config.getAgentSshPassword()));
+            }
+            SCPClient scp = new SCPClient(sshConnection);
+            String userDataScriptDir = "scripts/vm/hypervisor/ovm3/";
+            String userDataScriptPath = Script.findScript("", userDataScriptDir);
+            if (userDataScriptPath == null) {
+                throw new ConfigurationException("Can not find "
+                        + userDataScriptDir);
+            }
+            String mkdir = "mkdir -p " + config.getAgentScriptsDir();
+            if (!SSHCmdHelper.sshExecuteCmd(sshConnection, mkdir)) {
+                throw new ConfigurationException("Failed " + mkdir + " on "
+                        + config.getAgentHostname());
+            }
+            for (String script : config.getAgentScripts()) {
+                script = userDataScriptPath + "/" + script;
+                scp.put(script, config.getAgentScriptsDir(), "0755");
+            }
+            String prepareCmd = String.format(config.getAgentScriptsDir() + "/"
+                    + config.getAgentScript() + " --ssl=" + c.getUseSsl() + " "
+                    + "--port=" + c.getPort());
+            if (!SSHCmdHelper.sshExecuteCmd(sshConnection, prepareCmd)) {
+                throw new ConfigurationException("Failed to insert module on "
+                        + config.getAgentHostname());
+            } else {
+                /* because of OVM 3.3.1 (might be 2000) */
+                Thread.sleep(5000);
+            }
+            CloudstackPlugin cSp = new CloudstackPlugin(c);
+            cSp.ovsUploadSshKey(config.getAgentSshKeyFileName(),
+                    FileUtils.readFileToString(getSystemVMKeyFile(key)));
+            cSp.dom0CheckStorageHealthCheck(config.getAgentScriptsDir(),
+                    config.getAgentCheckStorageScript(),
+                    config.getCsHostGuid(),
+                    config.getAgentStorageCheckTimeout(),
+                    config.getAgentStorageCheckInterval());
+        } catch (Exception es) {
+            LOGGER.error("Unexpected exception ", es);
+            String msg = "Unable to install module in agent";
+            throw new CloudRuntimeException(msg);
+        }
+        return true;
+    }
+
+    /**
+     * Get all the VMs
+     *
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    private Map<String, Xen.Vm> getAllVms() throws Ovm3ResourceException {
+        try {
+            Xen vms = new Xen(c);
+            return vms.getRunningVmConfigs();
+        } catch (Exception e) {
+            LOGGER.debug("getting VM list from " + config.getAgentHostname()
+                    + " failed", e);
+            throw new CloudRuntimeException("Exception on getting VMs from "
+                    + config.getAgentHostname() + ":" + e.getMessage(), e);
+        }
+    }
+
+    /**
+     * getAllVmStates: Get the state of all the VMs
+     *
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    private Map<String, State> getAllVmStates(Map<String, State> vmStateMap)
+            throws Ovm3ResourceException {
+        Map<String, Xen.Vm> vms = getAllVms();
+        final Map<String, State> states = new HashMap<String, State>();
+        for (final Map.Entry<String, Xen.Vm> entry : vms.entrySet()) {
+            Xen.Vm vm = entry.getValue();
+            State ns = State.Running;
+            String as = vm.getVmState();
+            if (vm.isControlDomain() || as == null) {
+                continue;
+            }
+            /* The domain is currently running on a CPU */
+            /* need a more exact match! */
+            if (as.contains("r")) {
+                ns = State.Running;
+                /* The domain is blocked, and not running or runnable. */
+            } else if (as.contains("b")) {
+                ns = State.Running;
+                /* The domain has been paused */
+            } else if (as.contains("p")) {
+                ns = State.Running;
+                /* The guest has requested to be shutdown, still migrating... */
+            } else if (as.contains("s")) {
+                if (vmStateMap.get(vm.getVmName()) == State.Migrating) {
+                    ns = State.Migrating;
+                } else {
+                    ns = State.Stopped;
+                }
+                /* The domain has crashed */
+            } else if (as.contains("c")) {
+                ns = State.Error;
+                /*
+                 * The domain is in process of dying (if we see this twice we
+                 * have a problem ?)
+                 */
+            } else if (as.contains("d")) {
+                ns = State.Stopping;
+            } else {
+                ns = State.Unknown;
+            }
+            LOGGER.trace("state " + ns + " for " + vm.getVmName()
+                    + " based on " + as);
+            states.put(vm.getVmName(), ns);
+        }
+        return states;
+    }
+
+    /**
+     * syncState: Sync the state the VMs are in on the hypervisor.
+     *
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    public Map<String, State> syncState() throws Ovm3ResourceException {
+        return syncState(this.vmStateMap);
+    }
+
+    private Map<String, State> syncState(Map<String, State> vmStateMap)
+            throws Ovm3ResourceException {
+        Map<String, State> newStates;
+        Map<String, State> oldStates = null;
+        final Map<String, State> changes = new HashMap<String, State>();
+        try {
+            newStates = getAllVmStates(vmStateMap);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.error("Ovm3 full sync failed: ", e);
+            throw e;
+        }
+        synchronized (vmStateMap) {
+            oldStates = new HashMap<String, State>(vmStateMap.size());
+            oldStates.putAll(vmStateMap);
+
+            for (final Map.Entry<String, State> entry : newStates.entrySet()) {
+                final String vmName = entry.getKey();
+                State newState = entry.getValue();
+                final State oldState = oldStates.remove(vmName);
+                LOGGER.trace("state for " + vmName + ", old: " + oldState
+                        + ", new: " + newState);
+
+                /* eurh ? */
+                if (newState == State.Stopped && oldState != State.Stopping
+                        && oldState != null && oldState != State.Stopped) {
+                    LOGGER.trace("Getting power state....");
+                    newState = State.Running;
+                }
+
+                if (LOGGER.isTraceEnabled()) {
+                    LOGGER.trace("VM " + vmName + ": ovm has state " + newState
+                            + " and we have state "
+                            + (oldState != null ? oldState.toString() : "null"));
+                }
+
+                if (newState == State.Migrating) {
+                    LOGGER.trace(vmName + " is migrating, skipping state check");
+                    continue;
+                }
+
+                if (oldState == null) {
+                    vmStateMap.put(vmName, newState);
+                    LOGGER.debug("New state without old state: " + vmName);
+                    changes.put(vmName, newState);
+                } else if (oldState == State.Starting) {
+                    if (newState == State.Running) {
+                        vmStateMap.put(vmName, newState);
+                    } else if (newState == State.Stopped) {
+                        LOGGER.debug("Ignoring vm " + vmName
+                                + " because of a lag in starting the vm.");
+                    }
+                } else if (oldState == State.Migrating) {
+                    if (newState == State.Running) {
+                        LOGGER.debug("Detected that a migrating VM is now running: "
+                                + vmName);
+                        vmStateMap.put(vmName, newState);
+                    }
+                } else if (oldState == State.Stopping) {
+                    if (newState == State.Stopped) {
+                        vmStateMap.put(vmName, newState);
+                    } else if (newState == State.Running) {
+                        LOGGER.debug("Ignoring vm " + vmName
+                                + " because of a lag in stopping the vm. ");
+                        /* should kill it hard perhaps ? */
+                    }
+                } else if (oldState != newState) {
+                    vmStateMap.put(vmName, newState);
+                    if (newState == State.Stopped) {
+                        // For now leave it be.
+                    }
+                    changes.put(vmName, newState);
+                }
+            }
+
+            for (final Map.Entry<String, State> entry : oldStates.entrySet()) {
+                final String vmName = entry.getKey();
+                final State oldState = entry.getValue();
+
+                if (oldState == State.Stopping) {
+                    LOGGER.debug("Removing VM " + vmName
+                            + " in transition state stopping.");
+                    vmStateMap.remove(vmName);
+                } else if (oldState == State.Starting) {
+                    LOGGER.debug("Removing VM " + vmName
+                            + " in transition state starting.");
+                    vmStateMap.remove(vmName);
+                } else if (oldState == State.Stopped) {
+                    LOGGER.debug("Stopped VM " + vmName + " removing.");
+                    vmStateMap.remove(vmName);
+                } else if (oldState == State.Migrating) {
+                    /*
+                     * do something smarter here.. newstate should say stopping
+                     * already
+                     */
+                    LOGGER.debug("Ignoring VM " + vmName
+                            + " in migrating state.");
+                } else {
+                    /* if it's not there name it stopping */
+                    State state = State.Stopping;
+                    LOGGER.debug("VM " + vmName
+                            + " is now missing from ovm3 server so removing it");
+                    changes.put(vmName, state);
+                    vmStateMap.remove(vmName);
+                    vmStateMap.put(vmName, state);
+                }
+            }
+        }
+        return changes;
+    }
+
+    /**
+     * convertStateToPower: Convert a state, running, starting, stopped etc to a
+     * power state.
+     *
+     * @param s
+     * @param powerStateMap
+     * @return
+     */
+    private PowerState convertStateToPower(State s) {
+        final PowerState state = powerStateMaps.get(s.toString());
+        return state == null ? PowerState.PowerUnknown : state;
+    }
+
+    /**
+     * hostVmStateReport: Get all the VM states.
+     *
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    public Map<String, HostVmStateReportEntry> hostVmStateReport()
+            throws Ovm3ResourceException {
+        final Map<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
+        for (final Map.Entry<String, State> vm : vmStateMap.entrySet()) {
+            LOGGER.debug("VM " + vm.getKey() + " state: " + vm.getValue() + ":"
+                    + convertStateToPower(vm.getValue()));
+            vmStates.put(vm.getKey(), new HostVmStateReportEntry(
+                    convertStateToPower(vm.getValue()), c.getIp()));
+        }
+        return vmStates;
+    }
+
+    /**
+     * CheckHealthAnwer: Check the health of an agent on the hypervisor.
+     * TODO: should elaborate here with checks...
+     *
+     * @param cmd
+     * @return
+     */
+    public CheckHealthAnswer execute(CheckHealthCommand cmd) {
+        Common test = new Common(c);
+        String ping = "put";
+        String pong;
+        try {
+            pong = test.echo(ping);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug("CheckHealth went wrong: " + config.getAgentHostname()
+                    + ", " + e.getMessage(), e);
+            return new CheckHealthAnswer(cmd, false);
+        }
+        if (ping.contentEquals(pong)) {
+            return new CheckHealthAnswer(cmd, true);
+        }
+        LOGGER.debug("CheckHealth did not receive " + ping + " but got " + pong
+                + " from " + config.getAgentHostname());
+        return new CheckHealthAnswer(cmd, false);
+    }
+
+    /**
+     * materCheck
+     *
+     * @return
+     */
+    public boolean masterCheck() {
+        if ("".equals(config.getOvm3PoolVip())) {
+            LOGGER.debug("No cluster vip, not checking for master");
+            return false;
+        }
+
+        try {
+            CloudstackPlugin cSp = new CloudstackPlugin(c);
+            if (cSp.dom0HasIp(config.getOvm3PoolVip())) {
+                LOGGER.debug(config.getAgentHostname()
+                        + " is a master, already has vip "
+                        + config.getOvm3PoolVip());
+                config.setAgentIsMaster(true);
+            } else if (cSp.ping(config.getOvm3PoolVip())) {
+                LOGGER.debug(config.getAgentHostname()
+                        + " has a master, someone has vip "
+                        + config.getOvm3PoolVip());
+                config.setAgentHasMaster(true);
+            } else {
+                LOGGER.debug(config.getAgentHostname()
+                        + " becomes a master, no one has vip "
+                        + config.getOvm3PoolVip());
+                config.setAgentIsMaster(true);
+            }
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug(config.getAgentHostname()
+                    + " can't reach master: " + e.getMessage());
+            config.setAgentHasMaster(false);
+        }
+        return config.getAgentIsMaster();
+    }
+
+    /* Check if the host is in ready state for CS */
+    public ReadyAnswer execute(ReadyCommand cmd) {
+        try {
+            Linux host = new Linux(c);
+            Pool pool = new Pool(c);
+
+            /* only interesting when doing cluster */
+            if (!host.getIsMaster() && config.getAgentInOvm3Cluster()) {
+                if (pool.getPoolMasterVip().equalsIgnoreCase(c.getIp())) {
+                    /* check pool state here */
+                    return new ReadyAnswer(cmd);
+                } else {
+                    LOGGER.debug("Master IP changes to "
+                            + pool.getPoolMasterVip() + ", it should be "
+                            + c.getIp());
+                    return new ReadyAnswer(cmd, "I am not the master server");
+                }
+            } else if (host.getIsMaster()) {
+                LOGGER.debug("Master, not clustered "
+                        + config.getAgentHostname());
+                return new ReadyAnswer(cmd);
+            } else {
+                LOGGER.debug("No master, not clustered "
+                        + config.getAgentHostname());
+                return new ReadyAnswer(cmd);
+            }
+        } catch (CloudRuntimeException | Ovm3ResourceException e) {
+            LOGGER.debug("XML RPC Exception" + e.getMessage(), e);
+            throw new CloudRuntimeException("XML RPC Exception"
+                    + e.getMessage(), e);
+        }
+
+    }
+
+    /* check "the" virtual machine */
+    public CheckVirtualMachineAnswer execute(
+            final CheckVirtualMachineCommand cmd) {
+        LOGGER.debug("CheckVirtualMachineCommand: " + cmd.getVmName());
+        String vmName = cmd.getVmName();
+        try {
+            CloudstackPlugin plug = new CloudstackPlugin(c);
+            Integer vncPort = Integer.valueOf(plug.getVncPort(vmName));
+            if (vncPort == 0) {
+                LOGGER.warn("No VNC port for " + vmName);
+            }
+            /* we already have the state ftw */
+            Map<String, State> states = getAllVmStates(vmStateMap);
+            State vmState = states.get(vmName);
+            if (vmState == null) {
+                LOGGER.warn("Check state of " + vmName
+                        + " return null in CheckVirtualMachineCommand");
+                vmState = State.Stopped;
+            }
+            synchronized (vmStateMap) {
+                vmStateMap.put(vmName, State.Running);
+            }
+            return new CheckVirtualMachineAnswer(cmd,
+                    convertStateToPower(vmState), vncPort);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug("Check migration for " + vmName + " failed", e);
+            return new CheckVirtualMachineAnswer(cmd,
+                    convertStateToPower(State.Stopped), null);
+        }
+    }
+
+    /*
+     * TODO: leave cluster, leave pool, release ownership, cleanout and
+     * start over ?
+     * For now leave it as we're not clustering in OVM terms.
+     */
+    public MaintainAnswer execute(MaintainCommand cmd) {
+        LOGGER.debug("MaintainCommand");
+        /*
+         * try {
+         * Network net = new Network(c);
+         * net.stopOvsLocalConfig(config.getAgentControlNetworkName());
+         * } catch (Ovm3ResourceException e) {
+         * LOGGER.debug("unable to disable " +
+         * config.getAgentControlNetworkName(), e);
+         * }
+         */
+        return new MaintainAnswer(cmd);
+    }
+
+    public Answer execute(GetHostStatsCommand cmd) {
+        try {
+            CloudstackPlugin cSp = new CloudstackPlugin(c);
+            Map<String, String> stats = cSp.ovsDom0Stats(config
+                    .getAgentPublicNetworkName());
+            Double cpuUtil = Double.parseDouble(stats.get("cpu"));
+            Double rxBytes = Double.parseDouble(stats.get("rx"));
+            Double txBytes = Double.parseDouble(stats.get("tx"));
+            Double totalMemory = Double.parseDouble(stats.get("total"));
+            Double freeMemory = Double.parseDouble(stats.get("free"));
+            HostStatsEntry hostStats = new HostStatsEntry(cmd.getHostId(),
+                    cpuUtil, rxBytes, txBytes, "host", totalMemory, freeMemory,
+                    0, 0);
+            return new GetHostStatsAnswer(cmd, hostStats);
+        } catch (Exception e) {
+            LOGGER.debug("Unable to get host stats for: " + cmd.getHostName(),
+                    e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    /*
+     * We rely on storage health with CheckOnHostCommand....
+     */
+    public FenceAnswer execute(FenceCommand cmd) {
+        LOGGER.debug("FenceCommand");
+        try {
+            Boolean res = false;
+            return new FenceAnswer(cmd, res, res.toString());
+        } catch (Exception e) {
+            LOGGER.error("Unable to fence" + cmd.getHostIp(), e);
+            return new FenceAnswer(cmd, false, e.getMessage());
+        }
+    }
+
+    public CheckOnHostAnswer execute(CheckOnHostCommand cmd) {
+        LOGGER.debug("CheckOnHostCommand");
+        CloudstackPlugin csp = new CloudstackPlugin(c);
+        try {
+            Boolean alive = csp.dom0CheckStorageHealth(config.getAgentScriptsDir(),
+                    config.getAgentCheckStorageScript(),
+                    cmd.getHost().getGuid(),
+                    config.getAgentStorageCheckTimeout());
+            String msg = "";
+            if (alive == null) {
+                    msg = "storage check failed for " + cmd.getHost().getGuid();
+            } else if (alive) {
+                    msg = "storage check ok for " + cmd.getHost().getGuid();
+            } else {
+                    msg = "storage dead for " + cmd.getHost().getGuid();
+            }
+            LOGGER.debug(msg);
+            return new CheckOnHostAnswer(cmd, alive, msg);
+        } catch (Ovm3ResourceException e) {
+            return new CheckOnHostAnswer(cmd, false, "Error while checking storage for " +cmd.getHost().getGuid() +": " + e.getMessage());
+        }
+    }
+}


[02/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/create_pool_cluster.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/create_pool_cluster.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/create_pool_cluster.py
new file mode 100755
index 0000000..6c39851
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/create_pool_cluster.py
@@ -0,0 +1,271 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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 os, sys, subprocess
+from xml.dom.minidom import parseString
+
+from xmlrpclib import ServerProxy, Error
+
+server = ServerProxy("http://localhost:8899")
+
+pooledFs = 1
+normalRepo = 0
+
+try:
+  if normalRepo:
+    print "normal repo"
+    # this litterally throws EVERYTHING away on the repo
+    repoDom = parseString(server.discover_repository_db())
+    for node in repoDom.getElementsByTagName('Repository'):
+        repoUuid = node.attributes['Uuid']
+        remoteMount = node.getElementsByTagName('Fs_location')[0].firstChild.nodeValue
+        localMount = node.getElementsByTagName('Mount_point')[0].firstChild.nodeValue
+
+        # there is a "strong" relation between repo's and VMs
+        # onfortunately there is no reference in the vm.cfg
+        # or any known info in the configuration of the VM
+        # in which repo it lives....
+        for dirname, dirnames, filenames in os.walk('%s/VirtualMachines/' % localMount):
+            for vm in dirnames:
+                print "Destroying vm: %s on repo %s" % (vm, repoUuid.value)
+                try:
+                    mVm = server.list_vm(repoUuid.value, vm)
+                    if mVm != None:
+                        print server.stop_vm(repoUuid.value, vm)
+                        print server.delete_vm(repoUuid.value, vm)
+                    else:
+                        print "%s already not in repo %s" % (repoUuid.value, vm)
+                except Error, v:
+                    print "Unable to destroy: %s" % (v)
+                    continue
+
+        # VMs = server.list_vms()
+        # for vm in VMs:
+        #    if vm['domid'] != '0':
+        #        print vm
+        #        print server.delete_vm(repoUuid.value, vm['uuid'])
+
+        rc = server.delete_repository(repoUuid.value, True)
+        # Set to false if you want to keep data:      ^^^^
+        print "Repository: %s" % repoUuid.value
+        if (rc == None):
+            print "Ok repo: %s destroyed!" % repoUuid.value
+            # now unmount the FS
+            # print server.unmount_repository_fs(localMount)
+        else:
+            print "Failed repo: %s not destroyed!" % repoUuid.value
+
+    # for now only treat NFS stuff as we're testing with that..
+    nfsHost = 'cs-mgmt'
+    nfsDom = server.storage_plugin_listMountPoints(
+        'oracle.generic.NFSPlugin.GenericNFSPlugin',
+            { 'status': '',
+                'admin_user': '',
+                'admin_host': '',
+                'uuid': '',
+                'total_sz': 0,
+                'admin_passwd': '',
+                'free_sz': 0,
+                'name': '',
+                'access_host': nfsHost,
+                'storage_type': 'FileSys',
+                'alloc_sz': 0,
+                'access_grps': [],
+                'used_sz': 0,
+                'storage_desc': ''
+            })
+    for node in nfsDom:
+        props = {'status': node['status'],
+            'uuid': '',
+            'access_host': nfsHost,
+            'storage_type': 'FileSys',
+            'name': '' }
+        extprops = {'status': node['status'],
+            'uuid': node['fs_uuid'],
+            'ss_uuid': '',
+            'size': 0,
+            'free_sz': '',
+            'state': 1,
+            'access_grp_names': [],
+            'access_path': nfsHost + ':' + '/volumes/cs-data/secondary',
+            'name': ''}
+        # rc = server.storage_plugin_unmount('oracle.generic.NFSPlugin.GenericNFSPlugin', props, extprops, nfsMnt, True)
+        # print rc
+
+    nfsDom = parseString(server.discover_mounted_file_systems('nfs'))
+    for node in nfsDom.getElementsByTagName('Mount'):
+        nfsMnt = node.attributes['Dir'].value
+        print 'Mountpoint: %s' % (nfsMnt)
+        fsStamp = '%s/.generic_fs_stamp' % nfsMnt
+        # remove this so we don't cock up next run
+        if os.path.isfile(fsStamp):
+            print "Stamp found: %s" % fsStamp
+            os.unlink(fsStamp)
+
+        rc = server.storage_plugin_unmount('oracle.generic.NFSPlugin.GenericNFSPlugin', props, extprops, nfsMnt, True)
+        print rc
+
+
+  if pooledFs:
+    print "pooling"
+    # pool stuff
+    poolalias = "ItsMyPool"
+    poolmvip = "192.168.1.161"
+    poolfirsthost = {
+        'ip': "192.168.1.64",
+        'hn': "ovm-1",
+        'id': 0,
+        'role': 'utility,xen'
+    }
+    fstype = "nfs"
+    fstarget = "cs-mgmt:/volumes/cs-data/primary"
+    poolid = "0004fb0000020000ba9aaf00ae5e2d73"
+    clusterid = "ba9aaf00ae5e2d72"
+    poolfsuuid = "0004fb0000050000e70fbddeb802208f"
+    poolfsnfsbaseuuid = "b8ca41cb-3469-4f74-a086-dddffe37dc2d"
+    manageruuid = "0004fb00000100000af70d20dcce7d65"
+    pooluuid = "0004fb0000020000ba9aaf00ae5e2d73"
+    blocksize = ""
+    clustersize = ""
+    journalesize = ""
+
+    # o2cb is the problem.... /etc/init.d/o2cb
+    #   sets it's config in /etc/sysconfig/o2cb (can be removed)
+    #   dmsetup requires the stopping of o2cb first,
+    #   then the removal of the config, after which dmsetup
+    #   can remove the device from /dev/mapper/
+    # eventually cluster cleanup can be done by removing
+    #   stuff from /etc/ovs-agent/db
+    #   also clean /etc/ocfs2/cluster.conf
+    print server.create_pool_filesystem(
+        fstype,
+        fstarget,
+        clusterid,
+        poolfsuuid,
+        poolfsnfsbaseuuid,
+        manageruuid,
+        pooluuid
+    )
+
+    # poolDom = server.discover_server_pool()
+    # print poolDom
+    # poolDom = parseString(server.discover_server_pool())
+    # if poolDom.getElementsByTagName('Server_Pool'):
+    # get unique id
+    cluster = server.is_cluster_online()
+    if cluster == True:
+        print "clean up pool"
+        # print server.destroy_cluster(poolfsuuid)
+        # deconfigure cluster
+        # print server.destroy_server_pool(poolid)
+
+    if cluster == False:
+        print "create_server_pool"
+        # first take ownership. without an owner nothing happens
+        print server.take_ownership(manageruuid, "")
+        # we need to add the first host first to the pool....
+        poolDom = server.discover_server_pool()
+        print poolDom
+        poolDom = parseString(server.discover_server_pool())
+        if poolDom.getElementsByTagName('Server_Pool'):
+            print server.destroy_server_pool(pooluuid)
+
+        print server.create_pool_filesystem(
+            fstype,
+            fstarget,
+            clusterid,
+            poolfsuuid,
+            poolfsnfsbaseuuid,
+            manageruuid,
+            pooluuid
+        )
+        print server.create_server_pool(poolalias,
+            pooluuid,
+            poolmvip,
+            poolfirsthost['id'],
+            poolfirsthost['hn'],
+            poolfirsthost['ip'],
+            poolfirsthost['role'])
+
+        print "configure_virtual_ip"
+        server.configure_virtual_ip(poolmvip, poolfirsthost['ip'])
+        server.set_pool_member_ip_list(['192.168.1.64', '192.168.1.65'],)
+        print "configure for cluster"
+        server.configure_server_for_cluster(
+            {
+                'O2CB_HEARTBEAT_THRESHOLD': '61',
+                'O2CB_RECONNECT_DELAY_MS': '2000',
+                'O2CB_KEEPALIVE_DELAY_MS': '2000',
+                'O2CB_BOOTCLUSTER': clusterid,
+                'O2CB_IDLE_TIMEOUT_MS': '60000',
+                'O2CB_ENABLED': 'true',
+                'O2CB_STACK': 'o2cb'
+            },
+            {
+                'node': [
+                    {
+                        'ip_port': 7777,
+                        'cluster': clusterid,
+                        'ip_address': poolfirsthost['ip'],
+                        'name': poolfirsthost['hn'],
+                        'number': poolfirsthost['id']
+                    }
+                ],
+                'heartbeat': [
+                    {
+                        'cluster': clusterid,
+                        # uppercase poolfsuuid
+                        'region': '0004FB0000050000E70FBDDEB802208F'
+                    }
+                ],
+                'cluster': [
+                    {
+                        'heartbeat_mode': 'global',
+                        'node_count': 1,
+                        'name': clusterid
+                    }
+                ]
+            },
+            'nfs',
+            'cs-mgmt:/volumes/cs-data/primary',
+            poolfsuuid,
+            poolfsnfsbaseuuid
+        )
+        print "create cluster"
+        server.create_cluster(poolfsuuid,)
+
+    poolDom = parseString(server.discover_server_pool())
+    for node in poolDom.getElementsByTagName('Server_Pool'):
+        id = node.getElementsByTagName('Unique_Id')[0].firstChild.nodeValue
+        alias = node.getElementsByTagName('Pool_Alias')[0].firstChild.nodeValue
+        mvip = node.getElementsByTagName('Master_Virtual_Ip')[0].firstChild.nodeValue
+        print "pool: %s, %s, %s" % (id, mvip, alias)
+        members = node.getElementsByTagName('Member')
+        for member in members:
+            mip = member.getElementsByTagName('Registered_IP')[0].firstChild.nodeValue
+            print "member: %s" % (mip)
+
+    print server.is_cluster_online()
+    print server.discover_cluster()
+    print server.discover_pool_filesystem()
+    print server.discover_server_pool()
+    # server.destroy_server_pool(pooluuid)
+
+except Error, v:
+    print "ERROR", v

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/info.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/info.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/info.py
new file mode 100755
index 0000000..19ff71e
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/info.py
@@ -0,0 +1,111 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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 os, sys, subprocess, socket,fcntl, struct
+from socket import gethostname
+import errno
+from socket import error as socket_error
+from xml.dom.minidom import parseString
+
+from xmlrpclib import ServerProxy, Error
+
+def spCon(proto, auth, host, port):
+    print "trying %s on %s@%s:%s" % (proto, auth, host, port)
+    try:
+        x=ServerProxy("%s://%s@%s:%s" % (proto, auth, host, port))
+        x.echo(proto)
+        return x
+    except Error, v:
+        return
+    except socket_error, serr:
+        return
+
+def getCon(auth, host, port):
+    try:
+        server = spCon("http", auth, host, port)
+        if server:
+            return server
+        else:
+            server = spCon("https", auth, host, port)
+    except Error, v:
+        print "ERROR", v
+    return server
+
+def get_ip_address(ifname):
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    return socket.inet_ntoa(fcntl.ioctl(
+        s.fileno(),
+        0x8915,  # SIOCGIFADDR
+        struct.pack('256s', ifname[:15])
+    )[20:24])
+
+def is_it_up(host, port):
+    try:
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.settimeout(1)
+        s.connect((host, port))
+        s.close()
+    except:
+        print "host: %s:%s DOWN" % (host, port)
+        return False
+
+    print "host: %s:%s UP" % (host, port)
+    return True
+
+# hmm master actions don't apply to a slave
+master="192.168.1.161"
+port=8899
+user = "oracle"
+password = "test123"
+auth = "%s:%s" % (user, password)
+server = getCon(auth, 'localhost', port)
+mserver = getCon(auth, master, port)
+poolNode=True
+interface = "c0a80100"
+role='xen,utility'
+hostname=gethostname()
+ip = get_ip_address(interface)
+poolMembers = []
+xserver = server
+poolCount = 0
+
+try:
+    print server.discover_pool_filesystem()
+    print
+    print server.discover_server_pool()
+    poolDom = parseString(server.discover_server_pool())
+    for node in poolDom.getElementsByTagName('Server_Pool'):
+        id = node.getElementsByTagName('Unique_Id')[0].firstChild.nodeValue
+        alias = node.getElementsByTagName('Pool_Alias')[0].firstChild.nodeValue
+        mvip = node.getElementsByTagName('Master_Virtual_Ip')[0].firstChild.nodeValue
+        print "pool: %s, %s, %s" % (id, mvip, alias)
+        members = node.getElementsByTagName('Member')
+        for member in members:
+            poolCount = poolCount + 1
+            mip = member.getElementsByTagName('Registered_IP')[0].firstChild.nodeValue
+            print "member: %s" % (mip)
+            if mip == ip:
+               pooled = True
+            else:
+               poolMembers.append(mip)
+
+    # print server.discover_server()
+
+except Error, v:
+    print "ERROR", v

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/password.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/password.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/password.py
new file mode 100755
index 0000000..748023d
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/password.py
@@ -0,0 +1,57 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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 os, sys, subprocess, socket, fcntl, struct
+from socket import gethostname
+from xml.dom.minidom import parseString
+
+from xmlrpclib import ServerProxy, Error
+
+def spCon(proto, host, port):
+    print "trying %s on %s:%s" % (proto, host, port)
+    try:
+        x = ServerProxy("%s://%s:%s" % (proto, host, port))
+        x.echo(proto)
+        return x
+    except Error, v:
+        print "ERROR", v
+        return
+
+def getCon(host, port):
+    try:
+        server = spCon("http", host, port)
+    except Error, v:
+        print "ERROR", v
+        server = spCon("https", host, port)
+
+    return server
+
+# hmm master actions don't apply to a slave
+port = 8899
+user = "oracle"
+password = "test123"
+auth = "%s:%s" % (user, password)
+host = "localhost"
+
+print "setting up password"
+try:
+    con = getCon(host, port)
+    print con.update_agent_password(user, password)
+except Error, v:
+    print "ERROR", v

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/repo_pool.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/repo_pool.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/repo_pool.py
new file mode 100755
index 0000000..3886164
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/repo_pool.py
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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 os, sys, subprocess, socket, fcntl, struct
+from socket import gethostname
+from xml.dom.minidom import parseString
+
+from xmlrpclib import ServerProxy, Error
+
+def get_ip_address(ifname):
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    return socket.inet_ntoa(fcntl.ioctl(
+        s.fileno(),
+        0x8915,  # SIOCGIFADDR
+        struct.pack('256s', ifname[:15])
+    )[20:24])
+
+def is_it_up(host, port):
+    try:
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.settimeout(1)
+        s.connect((host, port))
+        s.close()
+    except:
+        print "host: %s:%s DOWN" % (host, port)
+        return False
+
+    print "host: %s:%s UP" % (host, port)
+    return True
+
+# hmm master actions don't apply to a slave
+master = "192.168.1.161"
+port = 8899
+user = "oracle"
+password = "*******"
+auth = "%s:%s" % (user, password)
+server = ServerProxy("http://%s:%s" % ("localhost", port))
+mserver = ServerProxy("http://%s@%s:%s" % (auth, master, port))
+poolNode = True
+interface = "c0a80100"
+role = 'xen,utility'
+hostname = gethostname()
+ip = get_ip_address(interface)
+poolMembers = []
+xserver = server
+
+print "setting up password"
+server.update_agent_password(user, password)
+
+if (is_it_up(master, port)):
+    print "master seems to be up, slaving"
+    xserver = mserver
+else:
+    print "no master yet, will become master"
+
+# other mechanism must be used to make interfaces equal...
+try:
+    # pooling related same as primary storage!
+    poolalias = "Pool 0"
+    poolid = "0004fb0000020000ba9aaf00ae5e2d73"
+    poolfsnfsbaseuuid = "7718562d-872f-47a7-b454-8f9cac4ffa3a"
+    pooluuid = poolid
+    poolfsuuid = poolid
+    clusterid = "ba9aaf00ae5e2d72"
+    mgr = "d1a749d4295041fb99854f52ea4dea97"
+    poolmvip = master
+
+    poolfsnfsbaseuuid = "6824e646-5908-48c9-ba44-bb1a8a778084"
+    repoid = "6824e646590848c9ba44bb1a8a778084"
+    poolid = repoid
+    repo = "/OVS/Repositories/%s" % (repoid)
+    repomount = "cs-mgmt:/volumes/cs-data/secondary"
+
+    # primary
+    primuuid = "7718562d872f47a7b4548f9cac4ffa3a"
+    ssuuid = "7718562d-872f-47a7-b454-8f9cac4ffa3a"
+    fshost = "cs-mgmt"
+    fstarget = "/volumes/cs-data/primary"
+    fstype = "nfs"
+    fsname = "Primary storage"
+    fsmntpoint = "%s:%s" % (fshost, fstarget)
+    fsmnt = "/nfsmnt/%s" % (ssuuid)
+    fsplugin = "oracle.generic.NFSPlugin.GenericNFSPlugin"
+
+    # set the basics we require to "operate"
+    print server.take_ownership(mgr, '')
+    print server.update_server_roles(role,)
+
+    # if we're pooling pool...
+    if (poolNode == True):
+        poolCount = 0
+        pooled = False
+
+        # check pooling
+        try:
+            poolDom = parseString(xserver.discover_server_pool())
+            print xserver.discover_server_pool()
+            for node in poolDom.getElementsByTagName('Server_Pool'):
+                id = node.getElementsByTagName('Unique_Id')[0].firstChild.nodeValue
+                alias = node.getElementsByTagName('Pool_Alias')[0].firstChild.nodeValue
+                mvip = node.getElementsByTagName('Master_Virtual_Ip')[0].firstChild.nodeValue
+                print "pool: %s, %s, %s" % (id, mvip, alias)
+                members = node.getElementsByTagName('Member')
+                for member in members:
+                    poolCount = poolCount + 1
+                    mip = member.getElementsByTagName('Registered_IP')[0].firstChild.nodeValue
+                    print "member: %s" % (mip)
+                    if mip == ip:
+                        pooled = True
+                    else:
+                        poolMembers.append(mip)
+
+        except Error, v:
+            print "no master will become master, %s" % v
+
+        if (pooled == False):
+            # setup the repository
+            print "setup repo"
+            print server.mount_repository_fs(repomount, repo)
+            try:
+                print "adding repo"
+                print server.add_repository(repomount, repo)
+            except Error, v:
+                print "will create the repo, as it's not there", v
+                print server.create_repository(repomount, repo, repoid, "repo")
+
+            print "not pooled!"
+            if (poolCount == 0):
+                print "no pool yet, create it"
+                # check if a pool exists already if not create
+                # pool if so add us to the pool
+                print "create pool fs"
+                print server.create_pool_filesystem(
+                    fstype,
+                    "%s/VirtualMachines/" % repomount,
+                    clusterid,
+                    poolfsuuid,
+                    poolfsnfsbaseuuid,
+                    mgr,
+                    pooluuid
+                )
+                print "create pool"
+                print server.create_server_pool(poolalias,
+                    pooluuid,
+                    poolmvip,
+                    poolCount,
+                    hostname,
+                    ip,
+                    role
+                )
+            else:
+                print "join the pool"
+                print server.join_server_pool(poolalias,
+                    pooluuid,
+                    poolmvip,
+                    poolCount,
+                    hostname,
+                    ip,
+                    role
+                )
+
+        # add member to ip list ?
+        poolMembers.append(ip)
+        print "mambers for pool: %s" % poolMembers
+        print xserver.set_pool_member_ip_list(poolMembers)
+
+    print server.discover_server_pool()
+
+except Error, v:
+    print "ERROR", v

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/simple_pool.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/simple_pool.py b/plugins/hypervisors/ovm3/src/test/resources/scripts/simple_pool.py
new file mode 100755
index 0000000..33789a2
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/simple_pool.py
@@ -0,0 +1,209 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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 os, sys, subprocess, socket, fcntl, struct
+from socket import gethostname
+from xml.dom.minidom import parseString
+import errno
+from socket import error as socket_error
+
+from xmlrpclib import ServerProxy, Error
+
+def spCon(proto, auth, host, port):
+    print "trying %s on %s@%s:%s" % (proto, auth, host, port)
+    try:
+        x = ServerProxy("%s://%s@%s:%s" % (proto, auth, host, port))
+        x.echo(proto)
+        return x
+    except Error, v:
+        return
+    except socket_error, serr:
+        return
+
+def getCon(auth, host, port):
+    try:
+        server = spCon("http", auth, host, port)
+        if server:
+            return server
+        else:
+            server = spCon("https", auth, host, port)
+    except Error, v:
+        print "ERROR", v
+    return server
+
+def get_ip_address(ifname):
+    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+    return socket.inet_ntoa(fcntl.ioctl(
+        s.fileno(),
+        0x8915,  # SIOCGIFADDR
+        struct.pack('256s', ifname[:15])
+    )[20:24])
+
+# hmm master actions don't apply to a slave
+master = "192.168.1.161"
+port = 8899
+passw = 'test123'
+user = 'oracle'
+auth = "%s:%s" % (user, passw)
+server = getCon(auth, "localhost", port)
+mserver = getCon(auth, master, port)
+try:
+    mserver.echo("test")
+except AttributeError, v:
+    print "no mserver, becoming mserver"
+    mserver = server
+
+poolNode = True
+interface = "c0a80100"
+role = 'xen,utility'
+hostname = gethostname()
+ip = get_ip_address(interface)
+nodes = []
+
+try:
+    # pooling related same as primary storage!
+    poolalias = "Pool 0"
+    clusterid = "ba9aaf00ae5e2d72"
+    mgr = "d1a749d4295041fb99854f52ea4dea97"
+    poolmvip = master
+
+    # primary
+    primuuid = "7718562d872f47a7b4548f9cac4ffa3a"
+    ssuuid = "7718562d-872f-47a7-b454-8f9cac4ffa3a"
+    fshost = "cs-mgmt"
+    fstarget = "/volumes/cs-data/primary/ovm"
+    fstype = "nfs"
+    fsname = "Primary storage"
+    fsmntpoint = "%s:%s" % (fshost, fstarget)
+    fsmntpoint2 = "%s:%s" % (fshost, "/volumes/cs-data/secondary")
+    fsmntpoint = "%s/VirtualMachines" % (fsmntpoint2)
+    fsmnt = "/nfsmnt/%s" % (ssuuid)
+    fsplugin = "oracle.generic.NFSPlugin.GenericNFSPlugin"
+    repo = "/OVS/Repositories/%s" % (primuuid)
+
+    # set the basics we require to "operate"
+    print server.take_ownership(mgr, '')
+    print server.update_server_roles(role,)
+
+    # setup the repository
+    print server.mount_repository_fs(fsmntpoint2, repo)
+    try:
+        print server.add_repository(fsmntpoint2, repo)
+    except Error, v:
+        print "will create the repo, as it's not there", v
+        print server.create_repository(fsmntpoint2, repo, primuuid, "A repository")
+
+    # if we're pooling pool...
+    if (poolNode == True):
+        poolCount = 0
+        pooled = False
+
+        # check pooling
+        poolDom = parseString(mserver.discover_server_pool())
+        for node in poolDom.getElementsByTagName('Server_Pool'):
+            id = node.getElementsByTagName('Unique_Id')[0].firstChild.nodeValue
+            alias = node.getElementsByTagName('Pool_Alias')[0].firstChild.nodeValue
+            mvip = node.getElementsByTagName('Master_Virtual_Ip')[0].firstChild.nodeValue
+            print "pool: %s, %s, %s" % (id, mvip, alias)
+            members = node.getElementsByTagName('Member')
+            for member in members:
+                poolCount = poolCount + 1
+                mip = member.getElementsByTagName('Registered_IP')[0].firstChild.nodeValue
+                if (mip == ip):
+                    pooled = True
+                else:
+                    nodes.append(mip)
+                print "member: %s" % (mip)
+
+        # if (pooled == False):
+        try:
+            if (poolCount == 0):
+                print "master"
+                # check if a pool exists already if not create
+                # pool if so add us to the pool
+                print server.configure_virtual_ip(master, ip)
+                print server.create_pool_filesystem(
+                    fstype,
+                    fsmntpoint,
+                    clusterid,
+                    primuuid,
+                    ssuuid,
+                    mgr,
+                    primuuid
+                )
+                print server.create_server_pool(poolalias,
+                    primuuid,
+                    poolmvip,
+                    poolCount,
+                    hostname,
+                    ip,
+                    role
+                )
+            else:
+                try:
+                    print "slave"
+                    print server.join_server_pool(poolalias,
+                        primuuid,
+                        poolmvip,
+                        poolCount,
+                        hostname,
+                        ip,
+                        role
+                    )
+                except Error, v:
+                    print "host already part of pool?: %s" % (v)
+
+            nodes.append(ip)
+            for node in nodes:
+                # con = getCon(auth, node, port)
+                # print con.set_pool_member_ip_list(nodes);
+                print mserver.dispatch("http://%s@%s:%s/api/3" % (auth, node, port), "set_pool_member_ip_list", nodes)
+            # print server.configure_virtual_ip(master, ip)
+        except Error, e:
+            print "something went wrong: %s" % (e)
+
+    # sys.exit()
+    # mount the primary fs
+    print server.storage_plugin_mount(
+        fsplugin,
+        {
+            'uuid': primuuid,
+            'storage_desc': fsname,
+            'access_host': fshost,
+            'storage_type': 'FileSys',
+            'name':primuuid
+       },
+        {
+            'status': '',
+            'uuid': ssuuid,
+            'ss_uuid': primuuid,
+            'size': 0,
+            'state': 1,
+            'access_grp_names': [],
+            'access_path': fsmntpoint,
+            'name': fsname
+        },
+        fsmnt,
+        '',
+        True,
+        []
+    )
+
+except Error, v:
+    print "ERROR", v

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/socat.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/socat.sh b/plugins/hypervisors/ovm3/src/test/resources/scripts/socat.sh
new file mode 100755
index 0000000..c3fbc44
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/socat.sh
@@ -0,0 +1,2 @@
+CERT="/etc/ovs-agent/cert"
+socat OPENSSL-LISTEN:8899,reuseaddr,fork,verify=0,key=$CERT/key.pem,cert=$CERT/certificate.pem TCP:localhost:8898 &

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/resources/scripts/tail.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/resources/scripts/tail.sh b/plugins/hypervisors/ovm3/src/test/resources/scripts/tail.sh
new file mode 100755
index 0000000..8b36123
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/resources/scripts/tail.sh
@@ -0,0 +1,2 @@
+cd /var/log
+tail -f ovm-consoled.log devmon.log messages ovs-agent.log ovmwatch.log

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
index 3dfcc0f..db06c88 100644
--- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
@@ -327,7 +327,7 @@ public class ManagementServerMock {
             _znet = _networkService.getPhysicalNetwork(id);
             List<PhysicalNetworkVO> nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public);
             if (nets == null || nets.isEmpty()) {
-                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null);
+                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null, null);
             }
         } catch (InvalidParameterValueException e) {
             List<String> isolationMethods = new ArrayList<String>();
@@ -337,7 +337,7 @@ public class ManagementServerMock {
                     "znet");
             List<PhysicalNetworkVO> nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public);
             if (nets == null || nets.isEmpty()) {
-                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null);
+                _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null, null);
             }
         }
         if (_znet.getState() != PhysicalNetwork.State.Enabled) {
@@ -353,7 +353,7 @@ public class ManagementServerMock {
             }
         }
         if (!found) {
-            _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), "vlan", null, null, null, null, null, null);
+            _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), "vlan", null, null, null, null, null, null, null);
         }
 
         Pair<List<? extends PhysicalNetworkServiceProvider>, Integer> providers =

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/pom.xml b/plugins/pom.xml
index 8034bd1..ccda955 100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@ -58,6 +58,7 @@
     <module>hypervisors/baremetal</module>
     <module>hypervisors/ucs</module>
     <module>hypervisors/hyperv</module>
+    <module>hypervisors/ovm3</module>
     <module>network-elements/elastic-loadbalancer</module>
     <module>network-elements/ovs</module>
     <module>network-elements/juniper-contrail</module>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/scripts/storage/secondary/cloud-install-sys-tmplt
----------------------------------------------------------------------
diff --git a/scripts/storage/secondary/cloud-install-sys-tmplt b/scripts/storage/secondary/cloud-install-sys-tmplt
index d31377a..25a7dae 100755
--- a/scripts/storage/secondary/cloud-install-sys-tmplt
+++ b/scripts/storage/secondary/cloud-install-sys-tmplt
@@ -20,9 +20,9 @@
 
 
 usage() {
-  printf "Usage: %s: -m <secondary storage mount point> -f <system vm template file> [-h <hypervisor name: kvm|vmware|xenserver|hyperv> ] [ -s <mgmt server secret key, if you specified any when running cloudstack-setup-database, default is password>][-u <Url to system vm template>] [-F <clean up system templates of specified hypervisor>] [-e <Template suffix, e.g vhd, ova, qcow2>] [-o <Database server hostname or ip, e.g localhost>] [-r <Database user name, e.g root>] [-d <Database password. Fllowed by nothing if the password is empty>]\n" $(basename $0) >&2
+  printf "Usage: %s: -m <secondary storage mount point> -f <system vm template file> [-h <hypervisor name: kvm|vmware|xenserver|hyperv|ovm3> ] [ -s <mgmt server secret key, if you specified any when running cloudstack-setup-database, default is password>][-u <Url to system vm template>] [-F <clean up system templates of specified hypervisor>] [-e <Template suffix, e.g vhd, ova, qcow2>] [-o <Database server hostname or ip, e.g localhost>] [-r <Database user name, e.g root>] [-d <Database password. Fllowed by nothing if the password is empty>]\n" $(basename $0) >&2
   printf "or\n" >&2
-  printf "%s: -m <secondary storage mount point> -u <http url for system vm template> [-h <hypervisor name: kvm|vmware|xenserver|hyperv> ] [ -s <mgmt server secret key>]\n" $(basename $0) >&2
+  printf "%s: -m <secondary storage mount point> -u <http url for system vm template> [-h <hypervisor name: kvm|vmware|xenserver|hyperv|ovm3> ] [ -s <mgmt server secret key>]\n" $(basename $0) >&2
 }
 
 failed() {
@@ -165,6 +165,10 @@ then
    then
       ext="vhd"
       templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"Hyperv\" and removed is null"`)
+   elif [ "$hyper" == "ovm3" ]
+   then
+      ext="raw"
+      templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"Ovm3\" and removed is null"`)
    else
       usage
       failed 2
@@ -177,7 +181,10 @@ then
 	failed 8
 fi
 
-localfile=$(uuidgen).$ext
+_uuid=$(uuidgen)
+localfile=$_uuid.$ext
+
+_res=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "update cloud.vm_template set uuid=\"$_uuid\" where id=\"$templateId\""`)
 
 mntpoint=`echo "$mntpoint" | sed 's|/*$||'`
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/scripts/vm/hypervisor/ovm3/cloudstack.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/ovm3/cloudstack.py b/scripts/vm/hypervisor/ovm3/cloudstack.py
new file mode 100644
index 0000000..e82863e
--- /dev/null
+++ b/scripts/vm/hypervisor/ovm3/cloudstack.py
@@ -0,0 +1,588 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+# TODO: Needs cleaning and sanitazation.
+#
+import logging
+import time
+import re
+import os.path
+import paramiko
+import subprocess
+import socket
+import tempfile
+import logging
+import logging.handlers
+
+from xen.util.xmlrpcclient import ServerProxy
+from xmlrpclib import Error
+from xen.xend import XendClient
+from agent.api.base import Agent
+from agent.lib.settings import get_api_version
+from xen.xend import sxp
+
+class CloudStack(Agent):
+    """
+    Cloudstack plugin for OVM3.2.x.
+    """
+
+    # exposed services
+    def get_services(self, version=None):
+        return {
+            'call': call,
+            'get_vncport': getVncPort,
+            'exec_domr': domrExec,
+            'check_domr_port': domrCheckPort,
+            'check_dom0_port': dom0CheckPort,
+            'check_domr_ssh': domrCheckSsh,
+            'check_dom0_ip': dom0CheckIp,
+            # rename to dom0StorageStatusCheck
+            'check_dom0_storage_health_check': dom0CheckStorageHealthCheck,
+            # dom0StorageStatus
+            'check_dom0_storage_health': dom0CheckStorageHealth,
+            'ovs_domr_upload_file': ovsDomrUploadFile,
+            'ovs_control_interface': ovsControlInterface,
+            'ovs_mkdirs': ovsMkdirs,
+            'ovs_check_file': ovsCheckFile,
+            'ovs_upload_ssh_key': ovsUploadSshKey,
+            'ovs_upload_file': ovsUploadFile,
+            'ovs_dom0_stats': ovsDom0Stats,
+            'ovs_domU_stats': ovsDomUStats,
+            'get_module_version': getModuleVersion,
+            'get_ovs_version': ovmVersion,
+            'ping': ping,
+#            'patch': ovmCsPatch,
+#            'ovs_agent_set_ssl': ovsAgentSetSsl,
+#            'ovs_agent_set_port': ovsAgentSetPort,
+#            'ovs_restart_agent': ovsRestartAgent,
+        }
+
+    def getName(self):
+        return self.__class__.__name__
+
+domrPort = 3922
+domrKeyFile = os.path.expanduser("~/.ssh/id_rsa.cloud")
+domrRoot = "root"
+domrTimeout = 10
+
+""" The logger is here """
+def Logger(level=logging.DEBUG):
+    logger = logging.getLogger('cloudstack-agent')
+    logger.setLevel(level)
+    handler = logging.handlers.SysLogHandler(address = '/dev/log')
+    logger.addHandler(handler)
+    return logger
+
+# which version are we intended for?
+def getModuleVersion():
+    return "0.1"
+
+# call test
+def call(msg):
+    return msg
+
+def paramikoOpts(con, keyfile=domrKeyFile):
+    con.load_system_host_keys()
+    con.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+    privatekeyfile = os.path.expanduser(keyfile)
+    key = paramiko.RSAKey.from_private_key_file(privatekeyfile)
+    return key
+
+# execute something on domr
+def domrExec(host, cmd, timeout=10, username=domrRoot, port=domrPort, keyfile=domrKeyFile):
+    ssh = paramiko.SSHClient()
+    pkey = paramikoOpts(ssh, keyfile)
+    ssh.connect(host, port, username, pkey=pkey, timeout=timeout)
+    ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(cmd)
+    exit_status = ssh_stdout.channel.recv_exit_status()
+    ssh.close()
+    return { "rc": exit_status,
+        "out": ''.join(ssh_stdout.readlines()),
+        "err": ''.join(ssh_stderr.readlines()) };
+
+# too bad sftp is missing.... Oh no it isn't it's just wrong in the svm config...
+# root@s-1-VM:/var/cache/cloud# grep sftp /etc/ssh/sshd_config
+# Subsystem   sftp    /usr/libexec/openssh/sftp-server
+# root@s-1-VM:/var/cache/cloud# find / -name sftp-server -type f
+# /usr/lib/openssh/sftp-server
+#
+def domrSftp(host, localfile, remotefile, timeout=10, username=domrRoot, port=domrPort, keyfile=domrKeyFile):
+    try:
+        paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)
+        ssh = paramiko.SSHClient()
+        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+        pkey = paramikoOpts(ssh, keyfile)
+        ssh.connect(host, port, username, pkey=pkey, timeout=timeout)
+        sftp = ssh.open_sftp()
+        # either:
+        sftp.put(localfile, remotefile)
+        # or:
+        # rf = sftp.open(remotefile, 'w')
+        # rf.write(content)
+        # rf.close()
+        sftp.close()
+        ssh.close()
+    except Exception, e:
+        raise e
+    return True
+
+def domrScp(host, localfile, remotefile, timeout=10, username=domrRoot, port=domrPort, keyfile=domrKeyFile):
+    try:
+        target = "%s@%s:%s" % (username, host, remotefile)
+        cmd = ['scp', '-P', str(port), '-q', '-o', 'StrictHostKeyChecking=no', '-i', os.path.expanduser(keyfile), localfile, target]
+        rc = subprocess.call(cmd, shell=False)
+        if rc == 0:
+            return True
+    except Exception, e:
+        raise e
+    return False
+
+# check a port on dom0
+def dom0CheckPort(ip, port=domrPort, timeout=3):
+    return domrCheckPort(ip, port, timeout=timeout)
+
+# check a port on domr
+def domrCheckPort(ip, port=domrPort, timeout=3):
+    try:
+        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        s.settimeout(timeout)
+        s.connect((ip, port))
+        s.close()
+    except:
+        return False
+    return True
+
+# check ssh
+def domrCheckSsh(ip, port=domrPort, timeout=10):
+    x = domrExec(ip, "", port=port, timeout=timeout)
+    if (x.get("rc") == 0):
+        return True
+    return False
+
+def grep(file, string):
+    c = 0
+    for line in open(file):
+        if string in line:
+           c = c + 1
+    return c
+
+def ovmVersion():
+    path = "/etc/ovs-release"
+    return re.findall("[\d\.]+$", open(path).readline())[0]
+
+# fix known bugs....
+def ovmCsPatch(version="3.2.1"):
+    path = "/etc/xen/scripts"
+    netcom = "%s/xen-network-common.sh" % path
+    netbr = "%s/linuxbridge/ovs-vlan-bridge" % path
+    func = "setup_bridge_port"
+    # on 3.3.1 this moved to python2.6, but the restart time is already good
+    xendConst = "/usr/lib64/python2.4/site-packages/xen/xend/XendConstants.py"
+    xendRtime = "MINIMUM_RESTART_TIME"
+    netconf = "/etc/sysconfig/network"
+    netzero = "NOZEROCONF"
+    version = ovmVersion()
+
+    # this bug is present from 3.2.1 till 3.3.2
+    if grep(netcom, "_%s" % func) == 3 and grep(netbr, "_%s" % func) < 1:
+        _replaceInFile(netbr, func, "_%s" % func, True)
+
+    # zeroconf is in the way for local loopback, as it introduces a route
+    # on every interface that conflicts with what we want
+    if grep(netconf, "%s" % netzero) == 0:
+        text_file = open("%s" % netconf, "a")
+        text_file.write("%s=no\n" % netzero)
+        text_file.close()
+    else:
+        _replaceInFile(netconf,
+            netzero,
+            "no",
+            False)
+
+    # this is fixed in 3.3.1 and onwards
+    if version == "3.2.1":
+        if grep(xendConst, "%s = %s" % (xendRtime, 60)) == 1:
+            _replaceInFile(xendConst,
+                "%s = %s" % (xendRtime, 60),
+                "%s = %s" % (xendRtime, 10),
+                True)
+            ovsRestartXend()
+
+    return True
+
+def _replaceInFile(file, orig, set, full=False):
+    replaced = False
+    if os.path.isfile(file):
+        import fileinput
+        for line in fileinput.FileInput(file, inplace=1):
+            line = line.rstrip('\n')
+            if full == False:
+                if re.search("%s=" % orig, line):
+                    line = "%s=%s" % (orig, set)
+                    replaced = True
+            else:
+                if re.search(orig, line):
+                    line = line.replace(orig, set)
+                    replaced = True
+            print line
+    return replaced
+
+def _ovsIni(setting, change):
+    ini = "/etc/ovs-agent/agent.ini"
+    return _replaceInFile(ini, setting, change)
+
+# enable/disable ssl for the agent
+def ovsAgentSetSsl(state):
+    ena = "disable"
+    if state and state != "disable" and state.lower() != "false":
+        ena = "enable"
+    return _ovsIni("ssl", ena)
+
+def ovsAgentSetPort(port):
+    return _ovsIni("port", port)
+
+def ovsRestartAgent():
+    return restartService("ovs-agent")
+
+def ovsRestartXend():
+    return restartService("xend")
+
+# replace with popen
+def restartService(service):
+    command = ['service', service, 'restart']
+    subprocess.call(command, shell=False)
+    return True
+
+# sets the control interface and removes the route net entry
+def ovsControlInterface(dev, cidr):
+    controlRoute = False
+    command = ['ip route show'];
+    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+    while True:
+        line = p.stdout.readline()
+        if line == '' and p.poll() != None:
+            break
+        if line != '':
+            if re.search("%s" % (cidr), line) and not re.search("%s" % (dev), line):
+                command = ['ip', 'route', 'del', cidr]
+                subprocess.call(command, shell=False)
+                print "removed: %s" % (line)
+            elif re.search("%s" % (cidr), line) and re.search("%s" % (dev), line):
+                controlRoute = True
+
+    if controlRoute == False:
+        command = ['ip', 'route', 'add', cidr, 'dev', dev];
+        subprocess.call(command, shell=False)
+
+    command = ['ifconfig', dev, 'arp']
+    subprocess.call(command, shell=False)
+    # because OVM creates this and it breaks stuff if we're rebooted sometimes...
+    control = "/etc/sysconfig/network-scripts/ifcfg-%s" % (dev)
+    command = ['rm', control]
+    subprocess.call(command, shell=False)
+    return True
+
+def dom0CheckIp(ip):
+    command = ['ip addr show']
+    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+    while True:
+        line = p.stdout.readline()
+        if line != '':
+            if re.search("%s/" % (ip), line):
+                return True
+        else:
+            break
+    return False
+
+def dom0CheckStorageHealthCheck(path, script, guid, timeout, interval):
+    storagehealth="storagehealth.py"
+    path="/opt/cloudstack/bin"
+    running = False
+    started = False
+    c = 0
+    log = Logger()
+    command = ["pgrep -fl %s | grep -v cloudstack.py" % (storagehealth)]
+
+    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+    for x in p.stdout:
+        if x:
+            log.debug("%s is running %s" % (storagehealth, x.rstrip('\n')))
+            running = True
+            c = c + 1
+    if c < 1:
+        started = True
+        command = ["%s/%s -g %s -t %d -i %d" % (path, storagehealth, guid, timeout, interval)]
+        log.warning("%s started: %s/%s for %s with timeout %d and interval %d"
+                    % (storagehealth, path, storagehealth, guid, timeout, interval))
+        subprocess.call(command, shell=True, close_fds=True)
+
+    return [running, started]
+
+def dom0CheckStorageHealth(path, script, guid, timeout):
+    response = None
+    delay = timeout
+    log = Logger()
+    command = ["%s/%s -g %s -t %s -s" % (path, script, guid, timeout)]
+    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+    p.wait()
+    if p.returncode == 0:
+        log.warning("primary storage is accessible for %s" % (guid))
+        return True
+    else:
+        log.warning("primary storage NOT is accessible for %s" % (guid))
+        return False
+    # while True:
+    #    line = p.stdout.readline()
+    #   if line != '':
+    #        if re.search("False", line):
+    #            log.debug("primary storage NOT is accessible for %s, %s" % (guid, line))
+    #            return False
+    #    else:
+    #        break
+    # return True
+
+# create a dir if we need it
+def ovsMkdirs(dir, mode=0700):
+    if not os.path.exists(dir):
+        return os.makedirs(dir, mode)
+    return True
+
+# if a file exists, easy
+def ovsCheckFile(file):
+    if os.path.isfile(file):
+        return True
+    return False
+
+def ovsUploadFile(path, filename, content):
+    file = "%s/%s" % (path, filename)
+    try:
+        ovsMkdirs(os.path.expanduser(path))
+    except Error, v:
+        print "path was already there %s" % path
+
+    try:
+        text_file = open("%s" % file, "w")
+        text_file.write("%s" % content)
+        text_file.close()
+    except Error, v:
+        print "something went wrong creating %s: %s" % (file, v)
+        return False
+    return True
+
+def ovsDomrUploadFile(domr, path, file, content):
+    remotefile = "%s/%s" % (path, file)
+    try:
+        temp = tempfile.NamedTemporaryFile()
+        temp.write(content)
+        temp.flush()
+        # domrSftp(domr, temp.name, remotefile)
+        domrScp(domr, temp.name, remotefile)
+        temp.close
+    except Exception, e:
+        print "problem uploading file %s/%s to %s, %s" % (path, file, domr, e)
+        raise e
+    return True
+
+# upload keys
+def ovsUploadSshKey(keyfile, content):
+    keydir = os.path.expanduser("~/.ssh")
+    return ovsUploadFile(keydir, keyfile, content)
+
+# older python,
+def ovsDom0Stats(bridge):
+    stats = {}
+    stats['cpu'] = "%s" % (100 - float(os.popen("top -b -n 1 | grep Cpu\(s\): | cut -d% -f4|cut -d, -f2").read()))
+    stats['free'] = "%s" % (1048576 * int(os.popen("xm info | grep free_memory | awk '{ print $3 }'").read()))
+    stats['total'] = "%s" % (1048576 * int(os.popen("xm info | grep total_memory | awk '{ print $3 }'").read()))
+    stats['tx'] = os.popen("netstat -in | grep %s | head -1 | awk '{print $4 }'" % bridge).read()
+    stats['rx'] = os.popen("netstat -in | grep %s | head -1 | awk '{print $8 }'" % bridge).read()
+    return stats
+
+def getVncPort(domain):
+    port = "0"
+    if re.search("\w-(\d+-)?\d+-VM", domain):
+        server = ServerProxy(XendClient.uri)
+        dom = server.xend.domain(domain, 1)
+        devices = [child for child in sxp.children(dom)
+            if len(child) > 0 and child[0] == "device"]
+        vfbs_sxp = map(lambda x: x[1], [device for device in devices
+            if device[1][0] == "vfb"])[0]
+        loc = [child for child in vfbs_sxp
+            if child[0] == "location"][0][1]
+        listner, port = loc.split(":")
+    else:
+        print "no valid domain: %s" % domain
+    return port
+
+def get_child_by_name(exp, childname, default=None):
+    try:
+        return [child for child in sxp.children(exp)
+                if child[0] == childname][0][1]
+    except:
+        return default
+
+def ovsDomUStats(domain):
+    _rd_bytes = 0
+    _wr_bytes = 0
+    _rd_ops = 0
+    _wr_ops = 0
+    _tx_bytes = 0
+    _rx_bytes = 0
+    stats = {}
+    server = ServerProxy(XendClient.uri)
+    dominfo = server.xend.domain(domain, 1)
+    domid = get_child_by_name(dominfo, "domid")
+
+    # vbds
+    devs = server.xend.domain.getDeviceSxprs(domain, 'vbd')
+    devids = [dev[0] for dev in devs]
+    for dev in devids:
+        sys_path = "/sys/devices/%s-%s-%s/statistics" % ("vbd", domid, dev)
+        _rd_bytes += long(open("%s/rd_sect" % sys_path).readline().strip())
+        _wr_bytes += long(open("%s/wr_sect" % sys_path).readline().strip())
+        _rd_ops += long(open("%s/rd_req" % sys_path).readline().strip())
+        _wr_ops += long(open("%s/wr_req" % sys_path).readline().strip())
+
+    # vifs
+    devs = server.xend.domain.getDeviceSxprs(domain, 'vif')
+    devids = [dev[0] for dev in devs]
+    for dev in devids:
+        vif = "vif%s.%s" % (domid, dev)
+        sys_path = "/sys/devices/%s-%s-%s/net/%s/statistics" % ("vif", domid, dev, vif)
+        _tx_bytes += long(open("%s/tx_bytes" % sys_path).readline().strip())
+        _rx_bytes += long(open("%s/rx_bytes" % sys_path).readline().strip())
+
+    epoch = time.time()
+    stats['rd_bytes'] = "%s" % (_rd_bytes * 512)
+    stats['wr_bytes'] = "%s" % (_wr_bytes * 512)
+    stats['rd_ops'] = "%s" % (_rd_ops)
+    stats['wr_ops'] = "%s" % (_wr_ops)
+    stats['tx_bytes'] = "%s" % (_tx_bytes)
+    stats['rx_bytes'] = "%s" % (_rx_bytes)
+    stats['cputime'] = "%s" % get_child_by_name(dominfo, "cpu_time")
+    stats['uptime'] = "%s" % (epoch - get_child_by_name(dominfo, "start_time"))
+    stats['vcpus'] = "%s" % get_child_by_name(dominfo, "online_vcpus")
+    return stats
+
+def ping(host, count=3):
+    if os.system("ping -c %s %s " % (count, host)) == 0:
+        return True
+    return False
+
+# add SystemVM stuff here....
+#
+
+#
+# Self deploy and integration, not de-integration
+# should return False if fails
+#
+# install us if we are missing in:
+# /usr/lib64/python2.4/site-packages/agent/api
+# and add our hooks in:
+# /usr/lib64/python2.4/site-packages/agent/target/api.py
+if __name__ == '__main__':
+    from distutils.sysconfig import get_python_lib
+    from agent.target.api import MODULES
+    from shutil import copyfile
+    import inspect, os, hashlib, getopt, sys
+
+    # default vars
+    exist = False
+    agentpath = "%s/agent" % (get_python_lib(1))
+    api = "%s/target/api.py" % (agentpath)
+    modpath = "%s/api" % (agentpath)
+    ssl = "disable"
+    port = 0
+    exec_sub = ""
+    exec_opts = ""
+
+    # get options
+    try:
+        opts, args = getopt.getopt(sys.argv[1:], "eosp::",
+            [ 'port=', 'ssl=', 'exec=', 'opts='])
+    except getopt.GetoptError:
+        print "Available Options: --port=<number>, --ssl=<true|false>, --exec=<method>, --opts=<arg1,arg2..>"
+        sys.exit()
+
+    for o, a in opts:
+        if o in ('-s', '--ssl'):
+            ssl = a
+        if o in ('-p', '--port'):
+            port = int(a)
+        if o in ('-e', '--exec'):
+            exec_sub = a
+        if o in ('-o', '--opts'):
+            exec_opts = a
+
+    if exec_sub != "":
+        func = "%s(%s)" % (exec_sub, exec_opts)
+        print "exec: %s" % (func)
+        if exec_opts:
+            opts = exec_opts.split(',')
+        else:
+            opts = ""
+        print locals()[exec_sub](*opts)
+        sys.exit()
+
+    # check if we're in the modules already
+    cs = CloudStack()
+    for mod in MODULES:
+        if re.search(cs.getName(), "%s" % (mod)):
+            exist = True
+
+    # if we're not:
+    if not exist:
+        if os.path.isfile(api):
+            import fileinput
+            for line in fileinput.FileInput(api, inplace=1):
+                line = line.rstrip('\n')
+                if re.search("import common", line):
+                    line = "%s, cloudstack" % (line)
+                if re.search("MODULES", line):
+                    n = cs.getName()
+                    line = "%s\n\t%s.%s," % (line, n.lower(), n)
+                print line
+            print "Api inserted, %s in %s" % (cs.getName(), api)
+        else:
+            print "Api missing, %s" % (api)
+    else:
+        print "Api present, %s in %s" % (cs.getName(), api)
+
+    # either way check our version and install if checksum differs
+    modfile = "%s/%s.py" % (modpath, cs.getName().lower())
+    me = os.path.abspath(__file__)
+    if os.path.isfile(modfile):
+        if hashlib.md5(open(me).read()).hexdigest() != hashlib.md5(open(modfile).read()).hexdigest():
+            print "Module copy, %s" % (modfile)
+            copyfile(me, modfile)
+        else:
+            print "Module correct, %s" % (modfile)
+    else:
+        print "Module copy, %s" % (modfile)
+        copyfile(me, modfile)
+
+    # setup ssl and port
+    if ssl:
+        ovsAgentSetSsl(ssl)
+    if port > 1024:
+        ovsAgentSetPort(port)
+
+    # restart either way
+    ovmCsPatch()
+    ovsRestartAgent()

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/scripts/vm/hypervisor/ovm3/storagehealth.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/ovm3/storagehealth.py b/scripts/vm/hypervisor/ovm3/storagehealth.py
new file mode 100755
index 0000000..353ca5e
--- /dev/null
+++ b/scripts/vm/hypervisor/ovm3/storagehealth.py
@@ -0,0 +1,259 @@
+#!/usr/bin/python
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+# TODO:
+# add multipath -ll
+# add iscsiadm output
+#
+import time
+import socket
+import getopt
+import sys
+import subprocess, threading
+import logging
+import logging.handlers
+import re
+import shutil
+import os
+
+""" a class to do checks with as a thread so we can have nice timeouts """
+class Check(object):
+    def __init__(self, cmd="", failcmd="", primary="",
+            file="", timeout="120", interval=1, logger="",
+            check=False):
+        self.file=file
+        self.cmd=cmd
+        self.failcmd=failcmd
+        self.primary=primary
+        self.timeout=timeout
+        self.interval=interval
+        self.process=None
+        self.logger=logger
+        self.check=check
+        self.ok=None
+        self.results={}
+
+    def readhb(self,file=""):
+        if os.path.isfile(file):
+            text_file = open("%s" % file, "r")
+            line=text_file.readline()
+            text_file.close()
+            return line
+        return 0
+
+    def writehb(self,file=""):
+        if file:
+            nfile="%s.new" % (file)
+            epoch=time.time()
+            text_file = open("%s" % nfile, "w")
+            text_file.write("%s" % epoch)
+            text_file.close()
+            shutil.move(nfile,file)
+            self.logger.debug('Worked on file %s for %s' %
+                 (file, (time.time() - epoch)))
+
+    """ We only want mounted nfs filesystems """
+    def nfsoutput(self):
+        command="mount -v -t nfs"
+        p=subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
+        lines=map(lambda line: line.split()[2], p.stdout.readlines())
+        test=re.compile("^%s" % (primary))
+        lines=filter(test.search, lines)
+        return lines
+
+    """
+        The main run for all checks we do,
+        everything is in here on purpose.
+
+        the other FSs to heartbeat should be added to filesystems...!
+    """
+    def run(self, timeout):
+        def target():
+            filesystems=[]
+            filesystems.extend(self.nfsoutput())
+            for fs in filesystems:
+                if self.file:
+                    if self.check==False:
+                        self.writehb("%s/%s" % (fs,file))
+                    else:
+                        res=self.readhb("%s/%s" % (fs,file))
+                        delay = time.time() - float(res)
+                        if (delay < timeout) and self.ok == None:
+                            self.logger.info("%s/%s is ok %s with %s" % (fs,file,timeout,delay))
+                            self.ok = True
+                        elif (delay > timeout):
+                            self.logger.warning("%s/%s exceeded timeout %s with %s" % (fs,file,timeout, delay))
+                            self.ok = False
+                        self.results[fs] = [self.ok, delay]
+
+            epoch=time.time()
+            if self.cmd:
+                self.logger.debug('Executing: %s' % (cmd))
+                self.process = subprocess.Popen(self.cmd, shell=True)
+                self.process.communicate()
+                self.logger.info('Executed: %s in %s' %
+                    (cmd, (time.time() - epoch)))
+
+        thread = threading.Thread(target=target)
+        thread.start()
+        thread.join(self.timeout)
+        if thread.isAlive() and self.check == False:
+            self.logger.critical('Critical: thread timeout; %s' % (timeout))
+            if self.failcmd:
+                self.logger.critical('Critical: executing; %s' % (failcmd))
+                p=subprocess.Popen(failcmd, shell=True, stdout=subprocess.PIPE)
+
+""" here we figure out what we're running on more or less """
+def figureOutPrimary():
+    redhat="/etc/redhat-release"
+    if os.path.isfile(redhat):
+        for line in open(redhat):
+            if "XenServer" in line:
+                return "/var/run/sr-mount"
+            if "Oracle VM server" in line:
+                return "/OVS/Repositories/"
+    print "Unknown hypervisor, consider adding it, exiting"
+    sys.exit(42)
+
+""" The logger is here """
+def Logger(level=logging.DEBUG):
+    logger = logging.getLogger('cs-heartbeat')
+    logger.setLevel(level)
+    handler = logging.handlers.SysLogHandler(address = '/dev/log')
+    logger.addHandler(handler)
+    return logger
+
+""" main for preso-dent """
+if __name__ == '__main__':
+    me=os.path.basename(__file__)
+    timeout=120
+    interval=1
+    hostname=socket.gethostname()
+    file=".hb-%s" % (hostname)
+    cmd=""
+    level=logging.DEBUG
+    primary=""
+    checkstate=False
+    failcmd=("echo 1 > /proc/sys/kernel/sysrq "
+        "&& "
+        "echo c > /proc/sysrq-trigger")
+
+    # xenserver:
+    if me == "heartbeat":
+        #  String result = callHostPluginPremium(conn, "heartbeat",
+        #  "host", _host.uuid,
+        #  "timeout", Integer.toString(_heartbeatTimeout),
+        #  "interval", Integer.toString(_heartbeatInterval));
+        # if (result == null || !result.contains("> DONE <")) {
+        try:
+            opts, args = getopt.getopt(sys.argv[1:], "h:y:i:s",
+                [ 'host', 'timeout', 'interval', 'state'])
+        except getopt.GetoptError:
+            print """Usage:
+                host: host guid.
+                timeout: timeout to fail on
+                interval: time between checks
+                state: check the state"""
+            sys.exit()
+        for o, a in opts:
+            if o in ('host'):
+                file="hb-%s" % (a)
+            if o in ('timeout'):
+                timeout=a
+            if o in ('interval'):
+                interval=a
+            if o in ('state'):
+                checkstate=True
+    # OVM3:
+    else:
+        # get options
+        try:
+            opts, args = getopt.getopt(sys.argv[1:], "g:p:f:c:t:i:s",
+                [ 'guid=', 'primary=','failcmd=','cmd=','timeout=','interval', 'state'])
+        except getopt.GetoptError:
+            print """Usage:
+                    --guid|-g: guid of the host to check
+                    --primary|-p: match for primary storage to monitor.
+                    --failcmd|-f: executed on timeout.
+                    --cmd|-c: command to execute next to hb file(s) on primary.
+                    --timeout|-t: excute failcmd after timeout(s) is hit.
+                    --interval|-i: run the checks every %ss>
+                    --state|-s check state"""
+            sys.exit()
+
+        for o, a in opts:
+            if o in ('-g', '--guid'):
+                file=".hb-%s" % (a)
+            if o in ('-p', '--primary'):
+                primary=a
+            if o in ('-f', '--failcmd'):
+                failcmd=a
+            if o in ('-c', '--cmd'):
+                cmd=a
+            if o in ('-t', '--timeout'):
+                timeout=int(a)
+            if o in ('-i', '--interval'):
+                interval=int(a)
+            if o in ('-s', '--state'):
+                checkstate=True
+
+    if primary == "":
+        primary=figureOutPrimary()
+
+    logger=Logger(level=level)
+    if checkstate == False:
+        os.chdir("/")
+        # os.setsid()
+        os.umask(0)
+        try:
+            pid = os.fork()
+            if pid > 0:
+                # exit first parent
+                if me == "heartbeat":
+                    print "> DONE <"
+                sys.exit(0)
+        except OSError, e:
+            print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
+            sys.exit(1)
+
+    checker=Check(cmd=cmd,
+        failcmd=failcmd,
+        file=file,
+        timeout=timeout,
+        interval=interval,
+        logger=logger,
+        check=checkstate);
+
+    while True:
+        start=time.time()
+        checker.run(timeout)
+        runtime=time.time() - start
+        logger.debug("cmd time: %s" % (runtime))
+        if checkstate:
+            for fs in checker.results:
+                print "%s: %s" % (fs, checker.results[fs])
+            if checker.ok == False:
+                sys.exit(1)
+            else:
+                sys.exit(0)
+        if runtime > interval:
+            logger.warning('Warning: runtime %s bigger than interval %s' %
+                (runtime, interval))
+        else:
+            time.sleep(interval)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index 982958e..e48e0b3 100644
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -724,7 +724,7 @@ public enum Config {
             String.class,
             "hypervisor.list",
             HypervisorType.Hyperv + "," + HypervisorType.KVM + "," + HypervisorType.XenServer + "," + HypervisorType.VMware + "," + HypervisorType.BareMetal + "," +
-                HypervisorType.Ovm + "," + HypervisorType.LXC,
+                HypervisorType.Ovm + "," + HypervisorType.LXC + "," + HypervisorType.Ovm3,
             "The list of hypervisors that this deployment will use.",
             "hypervisorList"),
     ManagementNetwork("Advanced", ManagementServer.class, String.class, "management.network.cidr", null, "The cidr of management server network", null),
@@ -1077,6 +1077,29 @@ public enum Config {
     OvmPrivateNetwork("Hidden", ManagementServer.class, String.class, "ovm.private.network.device", null, "Specify the private bridge on host for private network", null),
     OvmGuestNetwork("Hidden", ManagementServer.class, String.class, "ovm.guest.network.device", null, "Specify the private bridge on host for private network", null),
 
+    // Ovm3
+    Ovm3PublicNetwork("Hidden", ManagementServer.class, String.class, "ovm3.public.network.device", null, "Specify the public bridge on host for public network", null),
+    Ovm3PrivateNetwork("Hidden", ManagementServer.class, String.class, "ovm3.private.network.device", null, "Specify the private bridge on host for private network", null),
+    Ovm3GuestNetwork("Hidden", ManagementServer.class, String.class, "ovm3.guest.network.device", null, "Specify the guest bridge on host for guest network", null),
+    Ovm3StorageNetwork("Hidden", ManagementServer.class, String.class, "ovm3.storage.network.device", null, "Specify the storage bridge on host for storage network", null),
+    Ovm3HeartBeatTimeout(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "ovm3.heartbeat.timeout",
+            "120",
+            "timeout used for primary storage check, upon timeout a panic is triggered.",
+            null),
+    Ovm3HeartBeatInterval(
+            "Advanced",
+            ManagementServer.class,
+            Integer.class,
+            "ovm3.heartbeat.interval",
+            "1",
+            "interval used to check primary storage availability.",
+            null),
+
+
     // XenServer
     XenServerPublicNetwork(
             "Hidden",

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index d1a0887..ecd28e8 100644
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -369,6 +369,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         configValuesForValidation.add("wait");
         configValuesForValidation.add("xenserver.heartbeat.interval");
         configValuesForValidation.add("xenserver.heartbeat.timeout");
+        configValuesForValidation.add("ovm3.heartbeat.interval");
+        configValuesForValidation.add("ovm3.heartbeat.timeout");
         configValuesForValidation.add("incorrect.login.attempts.allowed");
         configValuesForValidation.add("vm.password.length");
     }
@@ -1768,7 +1770,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
                                 PhysicalNetworkTrafficTypeVO mgmtTraffic = _trafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management);
                                 _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), "vlan", mgmtTraffic.getXenNetworkLabel(),
                                         mgmtTraffic.getKvmNetworkLabel(), mgmtTraffic.getVmwareNetworkLabel(), mgmtTraffic.getSimulatorNetworkLabel(), mgmtTraffic.getVlan(),
-                                        mgmtTraffic.getHypervNetworkLabel());
+                                        mgmtTraffic.getHypervNetworkLabel(), mgmtTraffic.getOvm3NetworkLabel());
                                 s_logger.info("No storage traffic type was specified by admin, create default storage traffic on physical network " + mgmtPhyNetwork.getId()
                                         + " with same configure of management traffic type");
                     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/NetworkModelImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java
index 6088212..4db7141 100644
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ b/server/src/com/cloud/network/NetworkModelImpl.java
@@ -1226,6 +1226,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
                     case Hyperv:
                         label = mgmtTraffic.getHypervNetworkLabel();
                         break;
+                    case Ovm3:
+                        label = mgmtTraffic.getOvm3NetworkLabel();
+                        break;
                 }
                 return label;
             }
@@ -1258,6 +1261,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
                     case Hyperv:
                         label = storageTraffic.getHypervNetworkLabel();
                         break;
+                    case Ovm3:
+                        label = storageTraffic.getOvm3NetworkLabel();
+                        break;
                 }
                 return label;
             }
@@ -1618,6 +1624,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
                     case Hyperv:
                         label = publicTraffic.getHypervNetworkLabel();
                         break;
+                    case Ovm3:
+                        label = publicTraffic.getOvm3NetworkLabel();
+                        break;
                 }
                 return label;
             }
@@ -1650,7 +1659,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
                     case Hyperv:
                         label = guestTraffic.getHypervNetworkLabel();
                         break;
-
+                    case Ovm3:
+                        label = guestTraffic.getOvm3NetworkLabel();
+                        break;
                 }
                 return label;
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index 4f60c1a..f00d502 100644
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -3584,7 +3584,7 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", create = true)
     public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel,
-            String simulatorLabel, String vlan, String hypervLabel) {
+            String simulatorLabel, String vlan, String hypervLabel, String ovm3Label) {
 
         // verify input parameters
         PhysicalNetworkVO network = _physicalNetworkDao.findById(physicalNetworkId);
@@ -3636,7 +3636,7 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
                 xenLabel = getDefaultXenNetworkLabel(trafficType);
             }
             PhysicalNetworkTrafficTypeVO pNetworktrafficType = new PhysicalNetworkTrafficTypeVO(physicalNetworkId, trafficType, xenLabel, kvmLabel, vmwareLabel, simulatorLabel,
-                    vlan, hypervLabel);
+                    vlan, hypervLabel, ovm3Label);
             pNetworktrafficType = _pNTrafficTypeDao.persist(pNetworktrafficType);
 
             // For public traffic, get isolation method of physical network and update the public network accordingly
@@ -3696,7 +3696,7 @@ public class NetworkServiceImpl extends ManagerBase implements  NetworkService {
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_UPDATE, eventDescription = "Updating physical network TrafficType", async = true)
-    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel) {
+    public PhysicalNetworkTrafficType updatePhysicalNetworkTrafficType(Long id, String xenLabel, String kvmLabel, String vmwareLabel, String hypervLabel, String ovm3Label) {
 
         PhysicalNetworkTrafficTypeVO trafficType = _pNTrafficTypeDao.findById(id);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/router/NetworkHelperImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/NetworkHelperImpl.java b/server/src/com/cloud/network/router/NetworkHelperImpl.java
index 2cec4c8..852a223 100644
--- a/server/src/com/cloud/network/router/NetworkHelperImpl.java
+++ b/server/src/com/cloud/network/router/NetworkHelperImpl.java
@@ -160,6 +160,7 @@ public class NetworkHelperImpl implements NetworkHelper {
         hypervisorsMap.put(HypervisorType.VMware, VirtualNetworkApplianceManager.RouterTemplateVmware);
         hypervisorsMap.put(HypervisorType.Hyperv, VirtualNetworkApplianceManager.RouterTemplateHyperV);
         hypervisorsMap.put(HypervisorType.LXC, VirtualNetworkApplianceManager.RouterTemplateLxc);
+        hypervisorsMap.put(HypervisorType.Ovm3, VirtualNetworkApplianceManager.RouterTemplateOvm3);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
index 989dd84..a502018 100644
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
@@ -41,6 +41,7 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
     static final String RouterTemplateVmwareCK = "router.template.vmware";
     static final String RouterTemplateHyperVCK = "router.template.hyperv";
     static final String RouterTemplateLxcCK = "router.template.lxc";
+    static final String RouterTemplateOvm3CK = "router.template.ovm3";
     static final String SetServiceMonitorCK = "network.router.EnableServiceMonitoring";
     static final String RouterAlertsCheckIntervalCK = "router.alerts.check.interval";
 
@@ -54,6 +55,8 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
             "Name of the default router template on Hyperv.", true, ConfigKey.Scope.Zone, null);
     static final ConfigKey<String> RouterTemplateLxc = new ConfigKey<String>(String.class, RouterTemplateLxcCK, "Advanced", "SystemVM Template (LXC)",
             "Name of the default router template on LXC.", true, ConfigKey.Scope.Zone, null);
+    static final ConfigKey<String> RouterTemplateOvm3 = new ConfigKey<String>(String.class, RouterTemplateOvm3CK, "Advanced", "SystemVM Template (Ovm3)",
+            "Name of the default router template on Ovm3.", true, ConfigKey.Scope.Zone, null);
 
     static final ConfigKey<String> SetServiceMonitor = new ConfigKey<String>(String.class, SetServiceMonitorCK, "Advanced", "true",
             "service monitoring in router enable/disable option, default true", true, ConfigKey.Scope.Zone, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index e5d3630..99f3aa1 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -226,6 +226,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         this.hTypes.add(HypervisorType.Simulator);
         this.hTypes.add(HypervisorType.LXC);
         this.hTypes.add(HypervisorType.Hyperv);
+        this.hTypes.add(HypervisorType.Ovm3);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/resource/ResourceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index 6beea23..2f6e199 100644
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -484,6 +484,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
 
         if (clusterType == Cluster.ClusterType.CloudManaged) {
             Map<String, String> details = new HashMap<String, String>();
+            // should do this nicer perhaps ?
+            if (hypervisorType == HypervisorType.Ovm3) {
+                Map<String, String> allParams = cmd.getFullUrlParams();
+                details.put("ovm3vip", allParams.get("ovm3vip"));
+                details.put("ovm3pool", allParams.get("ovm3pool"));
+                details.put("ovm3cluster", allParams.get("ovm3cluster"));
+            }
             details.put("cpuOvercommitRatio", CapacityManager.CpuOverprovisioningFactor.value().toString());
             details.put("memoryOvercommitRatio", CapacityManager.MemOverprovisioningFactor.value().toString());
             _clusterDetailsDao.persist(cluster.getId(), details);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index eabaf23..1723c1e 100644
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -1128,15 +1128,15 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
 
         if (!vm.getHypervisorType().equals(HypervisorType.XenServer) && !vm.getHypervisorType().equals(HypervisorType.VMware) && !vm.getHypervisorType().equals(HypervisorType.KVM)
                 && !vm.getHypervisorType().equals(HypervisorType.Ovm) && !vm.getHypervisorType().equals(HypervisorType.Hyperv) && !vm.getHypervisorType().equals(HypervisorType.LXC)
-                && !vm.getHypervisorType().equals(HypervisorType.Simulator)) {
+                && !vm.getHypervisorType().equals(HypervisorType.Simulator) && !vm.getHypervisorType().equals(HypervisorType.Ovm3)) {
             if (s_logger.isDebugEnabled()) {
-                s_logger.debug(vm + " is not XenServer/VMware/KVM/OVM/Hyperv, cannot migrate this VM.");
+                s_logger.debug(vm + " is not XenServer/VMware/KVM/Ovm/Hyperv/Ovm3, cannot migrate this VM.");
             }
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm/Hyperv only");
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for VM migration, we support " + "XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
         }
 
         if (vm.getType().equals(VirtualMachine.Type.User) && vm.getHypervisorType().equals(HypervisorType.LXC)) {
-            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv only");
+            throw new InvalidParameterValueException("Unsupported Hypervisor Type for User VM migration, we support XenServer/VMware/KVM/Ovm/Hyperv/Ovm3 only");
         }
 
         long srcHostId = vm.getHostId();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
index afe141f..ad65bd6 100644
--- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
+++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java
@@ -77,7 +77,7 @@ public class StoragePoolMonitor implements Listener {
             if (scCmd.getHypervisorType() == HypervisorType.XenServer || scCmd.getHypervisorType() ==  HypervisorType.KVM ||
                 scCmd.getHypervisorType() == HypervisorType.VMware || scCmd.getHypervisorType() ==  HypervisorType.Simulator ||
                 scCmd.getHypervisorType() == HypervisorType.Ovm || scCmd.getHypervisorType() == HypervisorType.Hyperv ||
-                scCmd.getHypervisorType() == HypervisorType.LXC ) {
+                scCmd.getHypervisorType() == HypervisorType.LXC || scCmd.getHypervisorType() == HypervisorType.Ovm3) {
                 List<StoragePoolVO> pools = _poolDao.listBy(host.getDataCenterId(), host.getPodId(), host.getClusterId(), ScopeType.CLUSTER);
                 List<StoragePoolVO> zoneStoragePoolsByTags = _poolDao.findZoneWideStoragePoolsByTags(host.getDataCenterId(), null);
                 List<StoragePoolVO> zoneStoragePoolsByHypervisor = _poolDao.findZoneWideStoragePoolsByHypervisor(host.getDataCenterId(), scCmd.getHypervisorType());


[07/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3StoragePool.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3StoragePool.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3StoragePool.java
new file mode 100644
index 0000000..1f7726a
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3StoragePool.java
@@ -0,0 +1,749 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.ModifyStoragePoolAnswer;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Linux;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.OvmObject;
+import com.cloud.hypervisor.ovm3.objects.Pool;
+import com.cloud.hypervisor.ovm3.objects.PoolOCFS2;
+import com.cloud.hypervisor.ovm3.objects.Repository;
+import com.cloud.hypervisor.ovm3.objects.StoragePlugin;
+import com.cloud.hypervisor.ovm3.objects.StoragePlugin.FileProperties;
+import com.cloud.hypervisor.ovm3.objects.StoragePlugin.StorageDetails;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SshHelper;
+
+public class Ovm3StoragePool {
+    private static final Logger LOGGER = Logger
+            .getLogger(Ovm3StoragePool.class);
+    private Connection c;
+    private Ovm3Configuration config;
+    private OvmObject ovmObject = new OvmObject();
+
+    public Ovm3StoragePool(Connection conn, Ovm3Configuration ovm3config) {
+        c = conn;
+        config = ovm3config;
+    }
+
+    /**
+     * Setting up the roles on a host, we set all roles on all hosts!
+     *
+     * @param pool
+     * @throws ConfigurationException
+     */
+    private void setRoles(Pool pool) throws ConfigurationException {
+        try {
+            pool.setServerRoles(pool.getValidRoles());
+        } catch (Ovm3ResourceException e) {
+            String msg = "Failed to set server role for host "
+                    + config.getAgentHostname() + ": " + e.getMessage();
+            LOGGER.error(msg);
+            throw new ConfigurationException(msg);
+        }
+    }
+
+    /**
+     * If you don't own the host you can't fiddle with it.
+     *
+     * @param pool
+     * @throws ConfigurationException
+     */
+    private void takeOwnership(Pool pool) throws ConfigurationException {
+        try {
+            LOGGER.debug("Take ownership of host " + config.getAgentHostname());
+            pool.takeOwnership(config.getAgentOwnedByUuid(), "");
+        } catch (Ovm3ResourceException e) {
+            String msg = "Failed to take ownership of host "
+                    + config.getAgentHostname();
+            LOGGER.error(msg);
+            throw new ConfigurationException(msg);
+        }
+    }
+
+    /**
+     * If you don't own the host you can't fiddle with it.
+     *
+     * @param pool
+     * @throws ConfigurationException
+     */
+    /* FIXME: Placeholders for now, implement later!!!! */
+    private void takeOwnership33x(Pool pool) throws ConfigurationException {
+        try {
+            LOGGER.debug("Take ownership of host " + config.getAgentHostname());
+            String event = "http://localhost:10024/event";
+            String stats = "http://localhost:10024/stats";
+            String mgrCert = "None";
+            String signCert = "None";
+            pool.takeOwnership33x(config.getAgentOwnedByUuid(),
+                    event,
+                    stats,
+                    mgrCert,
+                    signCert);
+        } catch (Ovm3ResourceException e) {
+            String msg = "Failed to take ownership of host "
+                    + config.getAgentHostname();
+            LOGGER.error(msg);
+            throw new ConfigurationException(msg);
+        }
+    }
+    /**
+     * Prepare a host to become part of a pool, the roles and ownership are
+     * important here.
+     *
+     * @return
+     * @throws ConfigurationException
+     */
+    public boolean prepareForPool() throws ConfigurationException {
+        /* need single master uuid */
+        try {
+            Linux host = new Linux(c);
+            Pool pool = new Pool(c);
+
+            /* setup pool and role, needs utility to be able to do things */
+            if (host.getServerRoles().contentEquals(
+                    pool.getValidRoles().toString())) {
+                LOGGER.info("Server role for host " + config.getAgentHostname()
+                        + " is ok");
+            } else {
+                setRoles(pool);
+            }
+            if (host.getMembershipState().contentEquals("Unowned")) {
+                if (host.getOvmVersion().startsWith("3.2.")) {
+                    takeOwnership(pool);
+                } else if (host.getOvmVersion().startsWith("3.3.")) {
+                    takeOwnership33x(pool);
+                }
+            } else {
+                if (host.getManagerUuid().equals(config.getAgentOwnedByUuid())) {
+                    String msg = "Host " + config.getAgentHostname()
+                            + " owned by us";
+                    LOGGER.debug(msg);
+                    return true;
+                } else {
+                    String msg = "Host " + config.getAgentHostname()
+                            + " already part of a pool, and not owned by us";
+                    LOGGER.error(msg);
+                    throw new ConfigurationException(msg);
+                }
+            }
+        } catch (ConfigurationException | Ovm3ResourceException es) {
+            String msg = "Failed to prepare " + config.getAgentHostname()
+                    + " for pool: " + es.getMessage();
+            LOGGER.error(msg);
+            throw new ConfigurationException(msg);
+        }
+        return true;
+    }
+
+    /**
+     * Setup a pool in general, this creates a repo if it doesn't exist yet, if
+     * it does however we mount it.
+     *
+     * @param cmd
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    private Boolean setupPool(StorageFilerTO cmd) throws Ovm3ResourceException {
+        String primUuid = cmd.getUuid();
+        String ssUuid = ovmObject.deDash(primUuid);
+        String fsType = "nfs";
+        String clusterUuid = config.getAgentOwnedByUuid().substring(0, 15);
+        String managerId = config.getAgentOwnedByUuid();
+        String poolAlias = cmd.getHost() + ":" + cmd.getPath();
+        String mountPoint = String.format("%1$s:%2$s", cmd.getHost(),
+                cmd.getPath())
+                + "/VirtualMachines";
+        Integer poolSize = 0;
+
+        Pool poolHost = new Pool(c);
+        PoolOCFS2 poolFs = new PoolOCFS2(c);
+        if (config.getAgentIsMaster()) {
+            try {
+                LOGGER.debug("Create poolfs on " + config.getAgentHostname()
+                        + " for repo " + primUuid);
+                /* double check if we're not overwritting anything here!@ */
+                poolFs.createPoolFs(fsType, mountPoint, clusterUuid, primUuid,
+                        ssUuid, managerId);
+            } catch (Ovm3ResourceException e) {
+                throw e;
+            }
+            try {
+                poolHost.createServerPool(poolAlias, primUuid,
+                        config.getOvm3PoolVip(), poolSize + 1,
+                        config.getAgentHostname(), c.getIp());
+            } catch (Ovm3ResourceException e) {
+                throw e;
+            }
+        } else if (config.getAgentHasMaster()) {
+            try {
+                poolHost.joinServerPool(poolAlias, primUuid,
+                        config.getOvm3PoolVip(), poolSize + 1,
+                        config.getAgentHostname(), c.getIp());
+            } catch (Ovm3ResourceException e) {
+                throw e;
+            }
+        }
+        try {
+            /* should contain check if we're in an OVM pool or not */
+            CloudstackPlugin csp = new CloudstackPlugin(c);
+            Boolean vip = csp.dom0CheckPort(config.getOvm3PoolVip(), 22, 60, 1);
+            if (!vip) {
+                throw new Ovm3ResourceException(
+                        "Unable to reach Ovm3 Pool VIP "
+                                + config.getOvm3PoolVip());
+            }
+            /*
+             * should also throw exception, we need to stop pool creation here,
+             * or is the manual addition fine?
+             */
+            if (!addMembers()) {
+                return false;
+            }
+        } catch (Ovm3ResourceException e) {
+            throw new Ovm3ResourceException("Unable to add members to pool"
+                    + e.getMessage());
+        }
+        return true;
+    }
+
+    /**
+     * Adding members to a pool, this is seperate from cluster configuration in
+     * OVM.
+     *
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    private Boolean addMembers() throws Ovm3ResourceException {
+        List<String> members = new ArrayList<String>();
+        try {
+            Connection m = new Connection(config.getOvm3PoolVip(), c.getPort(),
+                    c.getUserName(), c.getPassword());
+            Pool poolMaster = new Pool(m);
+            if (poolMaster.isInAPool()) {
+                members.addAll(poolMaster.getPoolMemberList());
+                if (!poolMaster.getPoolMemberList().contains(c.getIp())
+                        && c.getIp().equals(config.getOvm3PoolVip())) {
+                    members.add(c.getIp());
+                }
+            } else {
+                LOGGER.warn(c.getIp() + " noticed master "
+                        + config.getOvm3PoolVip() + " is not part of pool");
+                return false;
+            }
+            /* a cluster shares usernames and passwords */
+            for (String member : members) {
+                Connection x = new Connection(member, c.getPort(),
+                        c.getUserName(), c.getPassword());
+                Pool poolM = new Pool(x);
+                if (poolM.isInAPool()) {
+                    poolM.setPoolMemberList(members);
+                    LOGGER.debug("Added " + members + " to pool "
+                            + poolM.getPoolId() + " on member " + member);
+                } else {
+                    LOGGER.warn(member
+                            + " unable to be member of a pool it's not in");
+                    return false;
+                }
+            }
+        } catch (Exception e) {
+            throw new Ovm3ResourceException("Unable to add members: "
+                    + e.getMessage(), e);
+        }
+        return true;
+    }
+
+    /**
+     * Get a host out of a pool/cluster, this should unmount all FSs though.
+     *
+     * @param cmd
+     * @return
+     */
+    public Answer execute(DeleteStoragePoolCommand cmd) {
+        try {
+            Pool pool = new Pool(c);
+            pool.leaveServerPool(cmd.getPool().getUuid());
+            /* also connect to the master and update the pool list ? */
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug(
+                    "Delete storage pool on host "
+                            + config.getAgentHostname()
+                            + " failed, however, we leave to user for cleanup and tell managment server it succeeded",
+                    e);
+        }
+
+        return new Answer(cmd);
+    }
+
+    /**
+     * Create primary storage, which is a repository in OVM. Pooling is part of
+     * this too and clustering should be in the future.
+     *
+     * @param cmd
+     * @return
+     * @throws XmlRpcException
+     */
+    private boolean createRepo(StorageFilerTO cmd) throws XmlRpcException {
+        String basePath = config.getAgentOvmRepoPath();
+        Repository repo = new Repository(c);
+        String primUuid = repo.deDash(cmd.getUuid());
+        String ovsRepo = basePath + "/" + primUuid;
+        /* should add port ? */
+        String mountPoint = String.format("%1$s:%2$s", cmd.getHost(),
+                cmd.getPath());
+        String msg;
+
+        if (cmd.getType() == StoragePoolType.NetworkFilesystem) {
+            Boolean repoExists = false;
+            /* base repo first */
+            try {
+                repo.mountRepoFs(mountPoint, ovsRepo);
+            } catch (Ovm3ResourceException e) {
+                LOGGER.debug("Unable to mount NFS repository " + mountPoint
+                        + " on " + ovsRepo + " requested for "
+                        + config.getAgentHostname() + ": " + e.getMessage());
+            }
+            try {
+                repo.addRepo(mountPoint, ovsRepo);
+                repoExists = true;
+            } catch (Ovm3ResourceException e) {
+                LOGGER.debug("NFS repository " + mountPoint + " on " + ovsRepo
+                        + " not found creating repo: " + e.getMessage());
+            }
+            if (!repoExists) {
+                try {
+                    /*
+                     * a mount of the NFS fs by the createrepo actually
+                     * generates a null if it is already mounted... -sigh-
+                     */
+                    repo.createRepo(mountPoint, ovsRepo, primUuid,
+                            "OVS Repository");
+                } catch (Ovm3ResourceException e) {
+                    msg = "NFS repository " + mountPoint + " on " + ovsRepo
+                            + " create failed!";
+                    LOGGER.debug(msg);
+                    throw new CloudRuntimeException(msg + " " + e.getMessage(),
+                            e);
+                }
+            }
+
+            /* add base pooling first */
+            if (config.getAgentInOvm3Pool()) {
+                try {
+                    msg = "Configuring " + config.getAgentHostname() + "("
+                            + config.getAgentIp() + ") for pool";
+                    LOGGER.debug(msg);
+                    setupPool(cmd);
+                    msg = "Configured host for pool";
+                    /* add clustering after pooling */
+                    if (config.getAgentInOvm3Cluster()) {
+                        msg = "Setup " + config.getAgentHostname() + "("
+                                + config.getAgentIp() + ")  for cluster";
+                        LOGGER.debug(msg);
+                        /* setup cluster */
+                        /*
+                         * From cluster.java
+                         * configure_server_for_cluster(cluster conf, fs, mount,
+                         * fsuuid, poolfsbaseuuid)
+                         */
+                        /* create_cluster(poolfsuuid,) */
+                    }
+                } catch (Ovm3ResourceException e) {
+                    msg = "Unable to setup pool on  "
+                            + config.getAgentHostname() + "("
+                            + config.getAgentIp() + ") for " + ovsRepo;
+                    throw new CloudRuntimeException(msg + " " + e.getMessage(),
+                            e);
+                }
+            } else {
+                msg = "no way dude I can't stand for this";
+                LOGGER.debug(msg);
+            }
+            /*
+             * this is to create the .generic_fs_stamp else we're not allowed to
+             * create any data\disks on this thing
+             */
+            try {
+                URI uri = new URI(cmd.getType() + "://" + cmd.getHost() + ":"
+                        + +cmd.getPort() + cmd.getPath() + "/VirtualMachines");
+                setupNfsStorage(uri, cmd.getUuid());
+            } catch (Exception e) {
+                msg = "NFS mount " + mountPoint + " on "
+                        + config.getAgentSecStoragePath() + "/" + cmd.getUuid()
+                        + " create failed!";
+                throw new CloudRuntimeException(msg + " " + e.getMessage(), e);
+            }
+        } else {
+            msg = "NFS repository " + mountPoint + " on " + ovsRepo
+                    + " create failed, was type " + cmd.getType();
+            LOGGER.debug(msg);
+            return false;
+        }
+
+        try {
+            /* systemvm iso is imported here */
+            prepareSecondaryStorageStore(ovsRepo, cmd.getUuid(), cmd.getHost());
+        } catch (Exception e) {
+            msg = "systemvm.iso copy failed to " + ovsRepo;
+            LOGGER.debug(msg, e);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Copy the systemvm.iso in if it doesn't exist or the size differs.
+     *
+     * @param storageUrl
+     * @param poolUuid
+     * @param host
+     */
+    private void prepareSecondaryStorageStore(String storageUrl,
+            String poolUuid, String host) {
+        String mountPoint = storageUrl;
+
+        GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm");
+        try {
+            /* double check */
+            if (config.getAgentHasMaster() && config.getAgentInOvm3Pool()) {
+                LOGGER.debug("Skip systemvm iso copy, leave it to the master");
+                return;
+            }
+            if (lock.lock(3600)) {
+                try {
+                    /*
+                     * save src iso real name for reuse, so we don't depend on
+                     * other happy little accidents.
+                     */
+                    File srcIso = getSystemVMPatchIsoFile();
+                    String destPath = mountPoint + "/ISOs/";
+                    try {
+                        StoragePlugin sp = new StoragePlugin(c);
+                        FileProperties fp = sp.storagePluginGetFileInfo(
+                                poolUuid, host, destPath + File.separator
+                                        + srcIso.getName());
+                        if (fp.getSize() != srcIso.getTotalSpace()) {
+                            LOGGER.info(" System VM patch ISO file already exists: "
+                                    + srcIso.getAbsolutePath().toString()
+                                    + ", destination: " + destPath);
+                        }
+                    } catch (Exception e) {
+                        LOGGER.info("Copy System VM patch ISO file to secondary storage. source ISO: "
+                                + srcIso.getAbsolutePath()
+                                + ", destination: "
+                                + destPath);
+                        try {
+                            /* Perhaps use a key instead ? */
+                            SshHelper
+                                    .scpTo(c.getIp(), 22, config
+                                            .getAgentSshUserName(), null,
+                                            config.getAgentSshPassword(),
+                                            destPath, srcIso.getAbsolutePath()
+                                                    .toString(), "0644");
+                        } catch (Exception es) {
+                            LOGGER.error("Unexpected exception ", es);
+                            String msg = "Unable to copy systemvm ISO on secondary storage. src location: "
+                                    + srcIso.toString()
+                                    + ", dest location: "
+                                    + destPath;
+                            LOGGER.error(msg);
+                            throw new CloudRuntimeException(msg, es);
+                        }
+                    }
+                } finally {
+                    lock.unlock();
+                }
+            }
+        } finally {
+            lock.releaseRef();
+        }
+    }
+
+    /**
+     * The secondary storage mountpoint is a uuid based on the host combined
+     * with the path.
+     *
+     * @param url
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    public String setupSecondaryStorage(String url)
+            throws Ovm3ResourceException {
+        URI uri = URI.create(url);
+        if (uri.getHost() == null) {
+            throw new Ovm3ResourceException(
+                    "Secondary storage host can not be empty!");
+        }
+        String uuid = ovmObject.newUuid(uri.getHost() + ":" + uri.getPath());
+        LOGGER.info("Secondary storage with uuid: " + uuid);
+        return setupNfsStorage(uri, uuid);
+    }
+
+    /**
+     * Sets up NFS Storage
+     *
+     * @param uri
+     * @param uuid
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    private String setupNfsStorage(URI uri, String uuid)
+            throws Ovm3ResourceException {
+        String fsUri = "nfs";
+        String msg = "";
+        String mountPoint = config.getAgentSecStoragePath() + "/" + uuid;
+        Linux host = new Linux(c);
+
+        Map<String, Linux.FileSystem> fsList = host.getFileSystemMap(fsUri);
+        Linux.FileSystem fs = fsList.get(uuid);
+        if (fs == null || !fs.getRemoteDir().equals(mountPoint)) {
+            try {
+                StoragePlugin sp = new StoragePlugin(c);
+                sp.storagePluginMountNFS(uri.getHost(), uri.getPath(), uuid,
+                        mountPoint);
+                msg = "Nfs storage " + uri + " mounted on " + mountPoint;
+                return uuid;
+            } catch (Ovm3ResourceException ec) {
+                msg = "Nfs storage " + uri + " mount on " + mountPoint
+                        + " FAILED " + ec.getMessage();
+                LOGGER.error(msg);
+                throw ec;
+            }
+        } else {
+            msg = "NFS storage " + uri + " already mounted on " + mountPoint;
+            return uuid;
+        }
+    }
+
+    /**
+     * Gets statistics for storage.
+     *
+     * @param cmd
+     * @return
+     */
+    public GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+        LOGGER.debug("Getting stats for: " + cmd.getStorageId());
+        try {
+            Linux host = new Linux(c);
+            Linux.FileSystem fs = host.getFileSystemByUuid(cmd.getStorageId(),
+                    "nfs");
+            StoragePlugin store = new StoragePlugin(c);
+            String propUuid = store.deDash(cmd.getStorageId());
+            String mntUuid = cmd.getStorageId();
+            if (store == null || propUuid == null || mntUuid == null
+                    || fs == null) {
+                String msg = "Null returned when retrieving stats for "
+                        + cmd.getStorageId();
+                LOGGER.error(msg);
+                return new GetStorageStatsAnswer(cmd, msg);
+            }
+            /* or is it mntUuid ish ? */
+            StorageDetails sd = store.storagePluginGetFileSystemInfo(propUuid,
+                    mntUuid, fs.getHost(), fs.getDevice());
+            /*
+             * FIXME: cure me or kill me, this needs to trigger a reinit of
+             * primary storage, actually the problem is more deeprooted, as when
+             * the hypervisor reboots it looses partial context and needs to be
+             * reinitiated.... actually a full configure round... how to trigger
+             * that ?
+             */
+            if ("".equals(sd.getSize())) {
+                String msg = "No size when retrieving stats for "
+                        + cmd.getStorageId();
+                LOGGER.debug(msg);
+                return new GetStorageStatsAnswer(cmd, msg);
+            }
+            long total = Long.parseLong(sd.getSize());
+            long used = total - Long.parseLong(sd.getFreeSize());
+            return new GetStorageStatsAnswer(cmd, total, used);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug("GetStorageStatsCommand for " + cmd.getStorageId()
+                    + " failed", e);
+            return new GetStorageStatsAnswer(cmd, e.getMessage());
+        }
+    }
+
+    /**
+     * Try to figure out where the systemvm.iso resides on the fs of the
+     * management server
+     *
+     * @return
+     */
+    public File getSystemVMPatchIsoFile() {
+        String iso = "systemvm.iso";
+        String systemVmIsoPath = Script.findScript("", "vms/" + iso);
+        File isoFile = null;
+        if (systemVmIsoPath != null) {
+            LOGGER.debug("found systemvm patch iso " + systemVmIsoPath);
+            isoFile = new File(systemVmIsoPath);
+        }
+        if (isoFile == null || !isoFile.exists()) {
+            String svm = "client/target/generated-webapp/WEB-INF/classes/vms/"
+                    + iso;
+            LOGGER.debug("last resort for systemvm patch iso " + svm);
+            isoFile = new File(svm);
+        }
+        assert isoFile != null;
+        if (!isoFile.exists()) {
+            LOGGER.error("Unable to locate " + iso + " in your setup at "
+                    + isoFile.toString());
+        }
+        return isoFile;
+    }
+
+    /**
+     * Create and OCFS2 filesystem (not implemented)
+     *
+     * @param pool
+     * @return
+     * @throws XmlRpcException
+     */
+    private Boolean createOCFS2Sr(StorageFilerTO pool) throws XmlRpcException {
+        LOGGER.debug("OCFS2 Not implemented yet");
+        return false;
+    }
+
+    /**
+     * Gets the details of a storage pool, size etc
+     *
+     * @param cmd
+     * @return
+     */
+    public Answer execute(ModifyStoragePoolCommand cmd) {
+        StorageFilerTO pool = cmd.getPool();
+        LOGGER.debug("modifying pool " + pool);
+        try {
+            if (config.getAgentInOvm3Cluster()) {
+                // no native ovm cluster for now, I got to break it in horrible
+                // ways
+            }
+            if (pool.getType() == StoragePoolType.NetworkFilesystem) {
+                createRepo(pool);
+                StoragePlugin store = new StoragePlugin(c);
+                String propUuid = store.deDash(pool.getUuid());
+                String mntUuid = pool.getUuid();
+                String nfsHost = pool.getHost();
+                String nfsPath = pool.getPath();
+                StorageDetails ss = store.storagePluginGetFileSystemInfo(
+                        propUuid, mntUuid, nfsHost, nfsPath);
+
+                Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
+                return new ModifyStoragePoolAnswer(cmd, Long.parseLong(ss
+                        .getSize()), Long.parseLong(ss.getFreeSize()), tInfo);
+            } else if (pool.getType() == StoragePoolType.OCFS2) {
+                createOCFS2Sr(pool);
+            }
+            return new Answer(cmd, false, "The pool type: "
+                    + pool.getType().name() + " is not supported.");
+        } catch (Exception e) {
+            LOGGER.debug("ModifyStoragePoolCommand failed", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    /**
+     * Create the primary storage pool, should add iSCSI and OCFS2
+     *
+     * @param cmd
+     * @return
+     */
+    public Answer execute(CreateStoragePoolCommand cmd) {
+        StorageFilerTO pool = cmd.getPool();
+        LOGGER.debug("creating pool " + pool);
+        try {
+            if (pool.getType() == StoragePoolType.NetworkFilesystem) {
+                createRepo(pool);
+            } else if (pool.getType() == StoragePoolType.IscsiLUN) {
+                return new Answer(cmd, false,
+                        "iSCSI is unsupported at the moment");
+                /*
+                 * iScsi like so: getIscsiSR(conn, pool.getUuid(),
+                 * pool.getHost(), pool.getPath(), null, null, false);
+                 */
+            } else if (pool.getType() == StoragePoolType.OCFS2) {
+                return new Answer(cmd, false,
+                        "OCFS2 is unsupported at the moment");
+            } else if (pool.getType() == StoragePoolType.PreSetup) {
+                LOGGER.warn("pre setup for pool " + pool);
+            } else {
+                return new Answer(cmd, false, "The pool type: "
+                        + pool.getType().name() + " is not supported.");
+            }
+        } catch (Exception e) {
+            String msg = "Catch Exception " + e.getClass().getName()
+                    + ", create StoragePool failed due to " + e.toString()
+                    + " on host:" + config.getAgentHostname() + " pool: "
+                    + pool.getHost() + pool.getPath();
+            LOGGER.warn(msg, e);
+            return new Answer(cmd, false, msg);
+        }
+        return new Answer(cmd, true, "success");
+    }
+
+    /**
+     * Download from template url into primary storage ?.. is this relevant ?
+     *
+     * @param cmd
+     * @return
+     */
+    public PrimaryStorageDownloadAnswer execute(
+            final PrimaryStorageDownloadCommand cmd) {
+        try {
+            Repository repo = new Repository(c);
+            String tmplturl = cmd.getUrl();
+            String poolName = cmd.getPoolUuid();
+            String image = repo.deDash(repo.newUuid()) + ".raw";
+
+            /* url to download from, image name, and repo to copy it to */
+            repo.importVirtualDisk(tmplturl, image, poolName);
+            return new PrimaryStorageDownloadAnswer(image);
+        } catch (Exception e) {
+            LOGGER.debug("PrimaryStorageDownloadCommand failed", e);
+            return new PrimaryStorageDownloadAnswer(e.getMessage());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VirtualRoutingSupport.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VirtualRoutingSupport.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VirtualRoutingSupport.java
new file mode 100644
index 0000000..72578fa
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VirtualRoutingSupport.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.NetworkRulesSystemVmCommand;
+import com.cloud.agent.api.NetworkUsageAnswer;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.resources.Ovm3VirtualRoutingResource;
+import com.cloud.utils.ExecutionResult;
+
+public class Ovm3VirtualRoutingSupport {
+    private static final Logger LOGGER = Logger
+            .getLogger(Ovm3VirtualRoutingSupport.class);
+    private static final String CREATE = "create";
+    private static final String SUCCESS = "success";
+    private Connection c;
+    private Ovm3VirtualRoutingResource vrr;
+    private Ovm3Configuration config;
+    public Ovm3VirtualRoutingSupport(Connection conn, Ovm3Configuration ovm3config, Ovm3VirtualRoutingResource ovm3vrr) {
+        c = conn;
+        vrr = ovm3vrr;
+        config = ovm3config;
+    }
+
+    /* copy paste, why isn't this just generic in the VirtualRoutingResource ? */
+    public Answer execute(NetworkUsageCommand cmd) {
+        if (cmd.isForVpc()) {
+            return vpcNetworkUsage(cmd);
+        }
+        if (LOGGER.isInfoEnabled()) {
+            LOGGER.info("Executing resource NetworkUsageCommand " + cmd);
+        }
+        if (cmd.getOption() != null && CREATE.equals(cmd.getOption())) {
+            String result = networkUsage(cmd.getPrivateIP(), CREATE, null);
+            return new NetworkUsageAnswer(cmd, result, 0L, 0L);
+        }
+        long[] stats = getNetworkStats(cmd.getPrivateIP());
+
+        return new NetworkUsageAnswer(cmd, "", stats[0], stats[1]);
+    }
+
+    /* copy paste, why isn't this just generic in the VirtualRoutingResource ? */
+    private String networkUsage(final String privateIpAddress,
+            final String option, final String ethName) {
+        String args = null;
+        if ("get".equals(option)) {
+            args = "-g";
+        } else if (CREATE.equals(option)) {
+            args = "-c";
+        } else if ("reset".equals(option)) {
+            args = "-r";
+        } else if ("addVif".equals(option)) {
+            args = "-a";
+            args += ethName;
+        } else if ("deleteVif".equals(option)) {
+            args = "-d";
+            args += ethName;
+        }
+        ExecutionResult result = vrr.executeInVR(privateIpAddress, "netusage.sh",
+                args);
+
+        if (result == null || !result.isSuccess()) {
+            return null;
+        }
+
+        return result.getDetails();
+    }
+
+    /* copy paste, why isn't this just generic in the VirtualRoutingResource ? */
+    private long[] getNetworkStats(String privateIP) {
+        String result = networkUsage(privateIP, "get", null);
+        long[] stats = new long[2];
+        if (result != null) {
+            try {
+                String[] splitResult = result.split(":");
+                int i = 0;
+                while (i < splitResult.length - 1) {
+                    stats[0] += (Long.valueOf(splitResult[i++])).longValue();
+                    stats[1] += (Long.valueOf(splitResult[i++])).longValue();
+                }
+            } catch (Exception e) {
+                LOGGER.warn(
+                        "Unable to parse return from script return of network usage command: "
+                                + e.toString(), e);
+            }
+        }
+        return stats;
+    }
+
+    /* copy paste, why isn't this just generic in the VirtualRoutingResource ? */
+    private NetworkUsageAnswer vpcNetworkUsage(NetworkUsageCommand cmd) {
+        String privateIp = cmd.getPrivateIP();
+        String option = cmd.getOption();
+        String publicIp = cmd.getGatewayIP();
+
+        String args = "-l " + publicIp + " ";
+        if ("get".equals(option)) {
+            args += "-g";
+        } else if (CREATE.equals(option)) {
+            args += "-c";
+            String vpcCIDR = cmd.getVpcCIDR();
+            args += " -v " + vpcCIDR;
+        } else if ("reset".equals(option)) {
+            args += "-r";
+        } else if ("vpn".equals(option)) {
+            args += "-n";
+        } else if ("remove".equals(option)) {
+            args += "-d";
+        } else {
+            return new NetworkUsageAnswer(cmd, SUCCESS, 0L, 0L);
+        }
+
+        ExecutionResult callResult = vrr.executeInVR(privateIp, "vpc_netusage.sh",
+                args);
+
+        if (!callResult.isSuccess()) {
+            LOGGER.error("Unable to execute NetworkUsage command on DomR ("
+                    + privateIp
+                    + "), domR may not be ready yet. failure due to "
+                    + callResult.getDetails());
+        }
+
+        if ("get".equals(option) || "vpn".equals(option)) {
+            String result = callResult.getDetails();
+            if (result == null || result.isEmpty()) {
+                LOGGER.error(" vpc network usage get returns empty ");
+            }
+            long[] stats = new long[2];
+            if (result != null) {
+                String[] splitResult = result.split(":");
+                int i = 0;
+                while (i < splitResult.length - 1) {
+                    stats[0] += (Long.valueOf(splitResult[i++])).longValue();
+                    stats[1] += (Long.valueOf(splitResult[i++])).longValue();
+                }
+                return new NetworkUsageAnswer(cmd, SUCCESS, stats[0],
+                        stats[1]);
+            }
+        }
+        return new NetworkUsageAnswer(cmd, SUCCESS, 0L, 0L);
+    }
+
+    /*
+     * we don't for now, gave an error on migration though....
+     */
+    public Answer execute(NetworkRulesSystemVmCommand cmd) {
+        boolean success = true;
+        return new Answer(cmd, success, "");
+    }
+
+    public CheckSshAnswer execute(CheckSshCommand cmd) {
+        String vmName = cmd.getName();
+        String privateIp = cmd.getIp();
+        int cmdPort = cmd.getPort();
+        int interval = cmd.getInterval();
+        int retries = cmd.getRetries();
+
+        try {
+            CloudstackPlugin cSp = new CloudstackPlugin(c);
+            if (!cSp.dom0CheckPort(privateIp, cmdPort, retries, interval)) {
+                String msg = "Port " + cmdPort + " not reachable for " + vmName
+                        + ": " + config.getAgentHostname();
+                LOGGER.info(msg);
+                return new CheckSshAnswer(cmd, msg);
+            }
+        } catch (Exception e) {
+            String msg = "Can not reach port " + cmdPort + " on System vm "
+                    + vmName + ": " + config.getAgentHostname()
+                    + " due to exception: " + e;
+            LOGGER.error(msg);
+            return new CheckSshAnswer(cmd, msg);
+        }
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("Ping " + cmdPort + " succeeded for vm " + vmName
+                    + ": " + config.getAgentHostname() + " " + cmd);
+        }
+        return new CheckSshAnswer(cmd);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmGuestTypes.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmGuestTypes.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmGuestTypes.java
new file mode 100755
index 0000000..e2906e6
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmGuestTypes.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you 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.
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Ovm3VmGuestTypes {
+    /* /usr/lib64/python2.4/site-packages/agent/lib/assembly */
+    private static final Map<String, String> OVMHELPERMAP = new HashMap<String, String>();
+    private static final String HVM = "hvm";
+    private static final String PV = "xen_pvm";
+    private static final String DOMSOL = "ldoms_pvm";
+    {
+        OVMHELPERMAP.put("Oracle Enterprise Linux 6.0 (32-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 6.0 (64-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.0 (32-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.0 (64-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.1 (32-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.1 (64-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.2 (32-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.2 (64-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.3 (32-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.3 (64-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.4 (32-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.4 (64-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.5 (32-bit)", PV);
+        OVMHELPERMAP.put("Oracle Enterprise Linux 5.5 (64-bit)", PV);
+        OVMHELPERMAP.put("Other Linux (32-bit)", PV);
+        OVMHELPERMAP.put("Other Linux (64-bit)", PV);
+        OVMHELPERMAP.put("Other PV (32-bit)", PV);
+        OVMHELPERMAP.put("Other PV (64-bit)", PV);
+        OVMHELPERMAP.put("Debian GNU/Linux 7(32-bit)", PV);
+        OVMHELPERMAP.put("Debian GNU/Linux 7(64-bit)", PV);
+        OVMHELPERMAP.put("Linux HVM (32-bit)", HVM);
+        OVMHELPERMAP.put("Linux HVM (64-bit)", HVM);
+        OVMHELPERMAP.put("Dos", HVM);
+        OVMHELPERMAP.put("Windows 7 (32-bit)", HVM);
+        OVMHELPERMAP.put("Windows 7 (64-bit)", HVM);
+        OVMHELPERMAP.put("Windows 8 (64-bit)", HVM);
+        OVMHELPERMAP.put("Windows Server 2003 (32-bit)", HVM);
+        OVMHELPERMAP.put("Windows Server 2003 (64-bit)", HVM);
+        OVMHELPERMAP.put("Windows Server 2008 (32-bit)", HVM);
+        OVMHELPERMAP.put("Windows Server 2008 (64-bit)", HVM);
+        OVMHELPERMAP.put("Windows Server 2008 R2 (64-bit)", HVM);
+        OVMHELPERMAP.put("Windows Server 2012 (64-bit)", HVM);
+        OVMHELPERMAP.put("Windows 2000 SP4 (32-bit)", HVM);
+        OVMHELPERMAP.put("Windows Vista (32-bit)", HVM);
+        OVMHELPERMAP.put("Windows XP SP2 (32-bit)", HVM);
+        OVMHELPERMAP.put("Windows XP SP3 (32-bit)", HVM);
+        OVMHELPERMAP.put("Sun Solaris 10(32-bit)", HVM);
+        OVMHELPERMAP.put("Sun Solaris 10(64-bit)", HVM);
+        OVMHELPERMAP.put("Sun Solaris 9(Experimental)", HVM);
+        OVMHELPERMAP.put("Sun Solaris 8(Experimental)", HVM);
+        OVMHELPERMAP.put("Sun Solaris 11 (32-bit)", HVM);
+        OVMHELPERMAP.put("Sun Solaris 11 (64-bit)", HVM);
+        OVMHELPERMAP.put("Sun Solaris PV (32-bit)", PV);
+        OVMHELPERMAP.put("Sun Solaris PV (64-bit)", PV);
+        OVMHELPERMAP.put("Sun Solaris Sparc (32-bit)", DOMSOL);
+        OVMHELPERMAP.put("Sun Solaris Sparc (64-bit)", DOMSOL);
+    }
+
+    public String getOvm3GuestType(String stdType) {
+        return OVMHELPERMAP.get(stdType);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmSupport.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmSupport.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmSupport.java
new file mode 100644
index 0000000..fcff316
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/helpers/Ovm3VmSupport.java
@@ -0,0 +1,475 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources.helpers;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.agent.api.Answer;
+// import com.cloud.agent.api.AttachVolumeAnswer;
+// import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.agent.api.GetVmStatsAnswer;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.GetVncPortAnswer;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.MigrateAnswer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.PlugNicAnswer;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.PrepareForMigrationAnswer;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.UnPlugNicAnswer;
+import com.cloud.agent.api.UnPlugNicCommand;
+import com.cloud.agent.api.VmStatsEntry;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.host.HostVO;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.OvmObject;
+import com.cloud.hypervisor.ovm3.objects.Xen;
+import com.cloud.hypervisor.ovm3.resources.Ovm3StorageProcessor;
+import com.cloud.resource.ResourceManager;
+import com.cloud.storage.Volume;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine.State;
+
+public class Ovm3VmSupport {
+    private final Logger LOGGER = Logger.getLogger(Ovm3VmSupport.class);
+    private OvmObject ovmObject = new OvmObject();
+    private ResourceManager resourceMgr;
+    private Connection c;
+    private Ovm3HypervisorNetwork network;
+    private Ovm3Configuration config;
+    private Ovm3HypervisorSupport hypervisor;
+    private Ovm3StorageProcessor processor;
+    private Ovm3StoragePool pool;
+    private final Map<String, Map<String, String>> vmStats = new ConcurrentHashMap<String, Map<String, String>>();
+    public Ovm3VmSupport(Connection conn,
+            Ovm3Configuration ovm3config,
+            Ovm3HypervisorSupport ovm3hyper,
+            Ovm3StorageProcessor ovm3stp,
+            Ovm3StoragePool ovm3sp,
+            Ovm3HypervisorNetwork ovm3hvn) {
+        c = conn;
+        config = ovm3config;
+        hypervisor = ovm3hyper;
+        pool = ovm3sp;
+        processor = ovm3stp;
+        network = ovm3hvn;
+    }
+    public Boolean createVifs(Xen.Vm vm, VirtualMachineTO spec)
+            throws Ovm3ResourceException {
+        if (spec.getNics() != null) {
+            NicTO[] nics = spec.getNics();
+            return createVifs(vm, nics);
+        } else {
+            LOGGER.info("No nics for vm " + spec.getName());
+            return false;
+        }
+    }
+
+    private Boolean createVifs(Xen.Vm vm, NicTO[] nics)
+            throws Ovm3ResourceException {
+        for (NicTO nic : nics) {
+            if (!createVif(vm, nic)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /* should add bitrates and latency... */
+    private Boolean createVif(Xen.Vm vm, NicTO nic)
+            throws Ovm3ResourceException {
+        try {
+            String net = network.getNetwork(nic);
+            if (net != null) {
+                LOGGER.debug("Adding vif " + nic.getDeviceId() + " "
+                        + nic.getMac() + " " + net + " to " + vm.getVmName());
+                vm.addVif(nic.getDeviceId(), net, nic.getMac());
+            } else {
+                LOGGER.debug("Unable to add vif " + nic.getDeviceId()
+                        + " no network for " + vm.getVmName());
+                return false;
+            }
+        } catch (Exception e) {
+            String msg = "Unable to add vif " + nic.getType() + " for "
+                    + vm.getVmName() + " " + e.getMessage();
+            LOGGER.debug(msg);
+            throw new Ovm3ResourceException(msg);
+        }
+        return true;
+    }
+    private Boolean deleteVif(Xen.Vm vm, NicTO nic)
+            throws Ovm3ResourceException {
+        /* here we should use the housekeeping of VLANs/Networks etc..
+         * so we can clean after the last VM is gone
+         */
+        try {
+            String net = network.getNetwork(nic);
+            if (net != null) {
+                LOGGER.debug("Removing vif " + nic.getDeviceId() + " " + " "
+                        + nic.getMac() + " " + net + " from " + vm.getVmName());
+                vm.removeVif(net, nic.getMac());
+            } else {
+                LOGGER.debug("Unable to remove vif " + nic.getDeviceId()
+                        + " no network for " + vm.getVmName());
+                return false;
+            }
+        } catch (Exception e) {
+            String msg = "Unable to remove vif " + nic.getType() + " for "
+                    + vm.getVmName() + " " + e.getMessage();
+            LOGGER.debug(msg);
+            throw new Ovm3ResourceException(msg);
+        }
+        return true;
+    }
+/*
+    public AttachVolumeAnswer execute(AttachVolumeCommand cmd) {
+        return new AttachVolumeAnswer(cmd, "You must stop " + cmd.getVmName()
+                + " first, Ovm3 doesn't support hotplug datadisk");
+    }
+*/
+    /* Migration should make sure both HVs are the same ? */
+    public PrepareForMigrationAnswer execute(PrepareForMigrationCommand cmd) {
+        VirtualMachineTO vm = cmd.getVirtualMachine();
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("Preparing host for migrating " + vm.getName());
+        }
+        NicTO[] nics = vm.getNics();
+        try {
+            for (NicTO nic : nics) {
+                network.getNetwork(nic);
+            }
+            hypervisor.setVmState(vm.getName(), State.Migrating);
+            LOGGER.debug("VM " + vm.getName() + " is in Migrating state");
+            return new PrepareForMigrationAnswer(cmd);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.error("Catch Exception " + e.getClass().getName()
+                    + " prepare for migration failed due to: " + e.getMessage());
+            return new PrepareForMigrationAnswer(cmd, e);
+        }
+    }
+
+    /* do migrations of VMs in a simple way just inside a cluster for now */
+    public MigrateAnswer execute(final MigrateCommand cmd) {
+        final String vmName = cmd.getVmName();
+        String destUuid = cmd.getHostGuid();
+        String destIp = cmd.getDestinationIp();
+        State state = State.Error;
+        /*
+         * TODO: figure out non pooled migration, works from CLI but not from
+         * the agent... perhaps pause the VM and then migrate it ? for now just
+         * stop the VM.
+         */
+        String msg = "Migrating " + vmName + " to " + destIp;
+        LOGGER.info(msg);
+        if (!config.getAgentInOvm3Cluster() && !config.getAgentInOvm3Pool()) {
+            try {
+                Xen xen = new Xen(c);
+                Xen.Vm vm = xen.getRunningVmConfig(vmName);
+                HostVO destHost = resourceMgr.findHostByGuid(destUuid);
+                if (destHost == null) {
+                    msg = "Unable to find migration target host in DB "
+                            + destUuid + " with ip " + destIp;
+                    LOGGER.info(msg);
+                    return new MigrateAnswer(cmd, false, msg, null);
+                }
+                xen.stopVm(ovmObject.deDash(vm.getVmRootDiskPoolId()),
+                        vm.getVmUuid());
+                msg = destHost.toString();
+                state = State.Stopping;
+                return new MigrateAnswer(cmd, false, msg, null);
+            } catch (Ovm3ResourceException e) {
+                msg = "Unpooled VM Migrate of " + vmName + " to " + destUuid
+                        + " failed due to: " + e.getMessage();
+                LOGGER.debug(msg, e);
+                return new MigrateAnswer(cmd, false, msg, null);
+            } finally {
+                /* shouldn't we just reinitialize completely as a last resort ? */
+                hypervisor.setVmState(vmName, state);
+            }
+        } else {
+            try {
+                Xen xen = new Xen(c);
+                Xen.Vm vm = xen.getRunningVmConfig(vmName);
+                if (vm == null) {
+                    state = State.Stopped;
+                    msg = vmName + " is no running on " + config.getAgentHostname();
+                    return new MigrateAnswer(cmd, false, msg, null);
+                }
+                /* not a storage migration!!! */
+                xen.migrateVm(ovmObject.deDash(vm.getVmRootDiskPoolId()),
+                        vm.getVmUuid(), destIp);
+                state = State.Stopping;
+                msg = "Migration of " + vmName + " successfull";
+                return new MigrateAnswer(cmd, true, msg, null);
+            } catch (Ovm3ResourceException e) {
+                msg = "Pooled VM Migrate" + ": Migration of " + vmName + " to "
+                        + destIp + " failed due to " + e.getMessage();
+                LOGGER.debug(msg, e);
+                return new MigrateAnswer(cmd, false, msg, null);
+            } finally {
+                hypervisor.setVmState(vmName, state);
+            }
+        }
+    }
+
+    /*
+     */
+    public GetVncPortAnswer execute(GetVncPortCommand cmd) {
+        try {
+            Xen host = new Xen(c);
+            Xen.Vm vm = host.getRunningVmConfig(cmd.getName());
+            Integer vncPort = vm.getVncPort();
+            LOGGER.debug("get vnc port for " + cmd.getName() + ": " + vncPort);
+            return new GetVncPortAnswer(cmd, c.getIp(), vncPort);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug("get vnc port for " + cmd.getName() + " failed", e);
+            return new GetVncPortAnswer(cmd, e.getMessage());
+        }
+    }
+
+    private VmStatsEntry getVmStat(String vmName) {
+        CloudstackPlugin cSp = new CloudstackPlugin(c);
+        Map<String, String> oldVmStats = null;
+        Map<String, String> newVmStats = null;
+        VmStatsEntry stats = new VmStatsEntry();
+        try {
+            if (vmStats.containsKey(vmName)) {
+                oldVmStats = new HashMap<String, String>();
+                oldVmStats.putAll(vmStats.get(vmName));
+            }
+            newVmStats = cSp.ovsDomUStats(vmName);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.info("Unable to retrieve stats from " + vmName, e);
+            return stats;
+        }
+        if (oldVmStats == null) {
+            LOGGER.debug("No old stats retrieved stats from " + vmName);
+            stats.setNumCPUs(1);
+            stats.setNetworkReadKBs(0);
+            stats.setNetworkWriteKBs(0);
+            stats.setDiskReadKBs(0);
+            stats.setDiskWriteKBs(0);
+            stats.setDiskReadIOs(0);
+            stats.setDiskWriteIOs(0);
+            stats.setCPUUtilization(0);
+            stats.setEntityType("vm");
+        } else {
+            LOGGER.debug("Retrieved new stats from " + vmName);
+            int cpus = Integer.parseInt(newVmStats.get("vcpus"));
+            stats.setNumCPUs(cpus);
+            stats.setNetworkReadKBs(doubleMin(newVmStats.get("rx_bytes"), oldVmStats.get("rx_bytes")));
+            stats.setNetworkWriteKBs(doubleMin(newVmStats.get("tx_bytes"), oldVmStats.get("tx_bytes")));
+            stats.setDiskReadKBs(doubleMin(newVmStats.get("rd_bytes"), oldVmStats.get("rd_bytes")));
+            stats.setDiskWriteKBs(doubleMin(newVmStats.get("rw_bytes"), oldVmStats.get("rw_bytes")));
+            stats.setDiskReadIOs(doubleMin(newVmStats.get("rd_ops"), oldVmStats.get("rd_ops")));
+            stats.setDiskWriteIOs(doubleMin(newVmStats.get("rw_ops"), oldVmStats.get("rw_ops")));
+            Double dCpu = doubleMin(newVmStats.get("cputime"), oldVmStats.get("cputime"));
+            Double dTime = doubleMin(newVmStats.get("uptime"), oldVmStats.get("uptime"));
+            Double cpupct = dCpu / dTime * 100 * cpus;
+            stats.setCPUUtilization(cpupct);
+            stats.setEntityType("vm");
+        }
+        ((ConcurrentHashMap<String, Map<String, String>>) vmStats).put(
+                vmName, newVmStats);
+        return stats;
+    }
+    private Double doubleMin(String x, String y) {
+        try {
+            return (Double.parseDouble(x) - Double.parseDouble(y));
+        } catch (NullPointerException e) {
+            return 0D;
+        }
+    }
+
+    public GetVmStatsAnswer execute(GetVmStatsCommand cmd) {
+        List<String> vmNames = cmd.getVmNames();
+        Map<String, VmStatsEntry> vmStatsNameMap = new HashMap<String, VmStatsEntry>();
+        for (String vmName : vmNames) {
+            VmStatsEntry e = getVmStat(vmName);
+            vmStatsNameMap.put(vmName, e);
+        }
+        return new GetVmStatsAnswer(cmd,
+                (HashMap<String, VmStatsEntry>) vmStatsNameMap);
+    }
+
+    /* This is not create for us, but really start */
+/*
+    public boolean startVm(String repoId, String vmId) throws XmlRpcException {
+        Xen host = new Xen(c);
+        try {
+            if (host.getRunningVmConfig(vmId) == null) {
+                LOGGER.error("Create VM " + vmId + " first on " + c.getIp());
+                return false;
+            } else {
+                LOGGER.info("VM " + vmId + " exists on " + c.getIp());
+            }
+            host.startVm(repoId, vmId);
+        } catch (Exception e) {
+            LOGGER.error("Failed to start VM " + vmId + " on " + c.getIp()
+                    + " " + e.getMessage());
+            return false;
+        }
+        return true;
+    }
+*/
+    /*
+     * TODO: OVM already cleans stuff up, just not the extra bridges which we
+     * don't want right now, as we'd have to keep a state table of which vlans
+     * need to stay on the host!? A map with vlanid -> list-o-hosts
+     */
+    private void cleanupNetwork(List<String> vifs) throws XmlRpcException {
+        /* peel out vif info for vlan stuff */
+    }
+
+    public void cleanup(Xen.Vm vm) {
+        try {
+            cleanupNetwork(vm.getVmVifs());
+        } catch (XmlRpcException e) {
+            LOGGER.info("Clean up network for " + vm.getVmName() + " failed", e);
+        }
+        String vmName = vm.getVmName();
+        /* should become a single entity */
+        vmStats.remove(vmName);
+    }
+
+    /*
+     * Add rootdisk, datadisk and iso's
+     */
+    public Boolean createVbds(Xen.Vm vm, VirtualMachineTO spec) {
+        if (spec.getDisks() == null) {
+            LOGGER.info("No disks defined for " + vm.getVmName());
+            return false;
+        }
+        for (DiskTO disk : spec.getDisks()) {
+            try {
+                if (disk.getType() == Volume.Type.ROOT) {
+                    VolumeObjectTO vol = (VolumeObjectTO) disk.getData();
+                    String diskFile = processor.getVirtualDiskPath(vol.getUuid(),  vol.getDataStore().getUuid());
+                    vm.addRootDisk(diskFile);
+                    vm.setPrimaryPoolUuid(vol.getDataStore().getUuid());
+                    LOGGER.debug("Adding root disk: " + diskFile);
+                } else if (disk.getType() == Volume.Type.ISO) {
+                    DataTO isoTO = disk.getData();
+                    if (isoTO.getPath() != null) {
+                        TemplateObjectTO template = (TemplateObjectTO) isoTO;
+                        DataStoreTO store = template.getDataStore();
+                        if (!(store instanceof NfsTO)) {
+                            throw new CloudRuntimeException(
+                                    "unsupported protocol");
+                        }
+                        NfsTO nfsStore = (NfsTO) store;
+                        String secPoolUuid = pool.setupSecondaryStorage(nfsStore
+                                .getUrl());
+                        String isoPath = config.getAgentSecStoragePath() + File.separator
+                                + secPoolUuid + File.separator
+                                + template.getPath();
+                        vm.addIso(isoPath);
+                        /* check if secondary storage is mounted */
+                        LOGGER.debug("Adding ISO: " + isoPath);
+                    }
+                } else if (disk.getType() == Volume.Type.DATADISK) {
+                    VolumeObjectTO vol = (VolumeObjectTO) disk.getData();
+                    String diskFile = processor.getVirtualDiskPath(vol.getUuid(),  vol.getDataStore().getUuid());
+                    vm.addDataDisk(diskFile);
+                    LOGGER.debug("Adding data disk: "
+                            + diskFile);
+                } else {
+                    throw new CloudRuntimeException("Unknown disk type: "
+                            + disk.getType());
+                }
+            } catch (Exception e) {
+                LOGGER.debug("CreateVbds failed", e);
+                throw new CloudRuntimeException("Exception" + e.getMessage(), e);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Implements the unplug and plug feature for Nics, the boolan decides
+     * to either plug (true) or unplug (false)
+     *
+     * @param nic
+     * @param vmName
+     * @param plug
+     * @return
+     */
+    private Answer plugNunplugNic(NicTO nic, String vmName, Boolean plug) {
+        try {
+            Xen xen = new Xen(c);
+            Xen.Vm vm = xen.getVmConfig(vmName);
+            /* check running */
+            if (vm == null) {
+                return new Answer(null, false,
+                        "Unable to execute command due to missing VM");
+            }
+            // setup the NIC in the VM config.
+            if (plug) {
+                createVif(vm, nic);
+                vm.setupVifs();
+            } else {
+                deleteVif(vm, nic);
+            }
+            // execute the change
+            xen.configureVm(ovmObject.deDash(vm.getPrimaryPoolUuid()),
+                    vm.getVmUuid());
+        } catch (Ovm3ResourceException e) {
+            String msg = "Unable to execute command due to " + e.toString();
+            LOGGER.debug(msg);
+            return new Answer(null, false, msg);
+        }
+        return new Answer(null, true, "success");
+    }
+    /**
+     * PlugNicAnswer: plug a network interface into a VM
+     * @param cmd
+     * @return
+     */
+    public PlugNicAnswer execute(PlugNicCommand cmd) {
+        Answer ans = plugNunplugNic(cmd.getNic(), cmd.getVmName(), true);
+        return new PlugNicAnswer(cmd, ans.getResult(), ans.getDetails());
+    }
+
+    /**
+     * UnPlugNicAnswer: remove a nic from a VM
+     * @param cmd
+     * @return
+     */
+    public UnPlugNicAnswer execute(UnPlugNicCommand cmd) {
+        Answer ans = plugNunplugNic(cmd.getNic(), cmd.getVmName(), false);
+        return new UnPlugNicAnswer(cmd, ans.getResult(), ans.getDetails());
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-compute/module.properties
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-compute/module.properties b/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-compute/module.properties
new file mode 100644
index 0000000..69e6469
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-compute/module.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+name=ovm3-compute
+parent=compute

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml b/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
new file mode 100644
index 0000000..308015e
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
@@ -0,0 +1,41 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+                      >
+
+    <bean id="Ovm3Fencer" class="com.cloud.hypervisor.ovm3.resources.Ovm3FenceBuilder">
+        <property name="name" value="Ovm3FenceBuilder" />
+    </bean>
+
+    <bean id="Ovm3Guru" class="com.cloud.hypervisor.ovm3.resources.Ovm3HypervisorGuru">
+        <property name="name" value="Ovm3Guru" />
+    </bean>
+
+    <bean id="Ovm3Investigator" class="com.cloud.ha.Ovm3Investigator">
+        <property name="name" value="Ovm3Investigator" />
+    </bean>
+</beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-discoverer/module.properties
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-discoverer/module.properties b/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-discoverer/module.properties
new file mode 100644
index 0000000..025d4cf
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-discoverer/module.properties
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+name=ovm3-discoverer
+parent=discoverer

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml b/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml
new file mode 100644
index 0000000..a28a2fc
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml
@@ -0,0 +1,34 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you 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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+                      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+                      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
+                      http://www.springframework.org/schema/context
+                      http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+                      >
+
+    <bean id="Ovm3Discoverer" class="com.cloud.hypervisor.ovm3.resources.Ovm3Discoverer">
+        <property name="name" value="Ovm3Discover" />
+    </bean>
+
+</beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/CloudStackPluginTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/CloudStackPluginTest.java b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/CloudStackPluginTest.java
new file mode 100644
index 0000000..87e0580
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/test/java/com/cloud/hypervisor/ovm3/objects/CloudStackPluginTest.java
@@ -0,0 +1,323 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Map;
+
+import org.junit.Test;
+
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin.ReturnCode;
+
+public class CloudStackPluginTest {
+    private static final String VMNAME = "test";
+    String domrIp = "169.254.3.2";
+    public String getDomrIp() {
+        return domrIp;
+    }
+
+    public String getDom0Ip() {
+        return dom0Ip;
+    }
+
+    public Integer getDomrPort() {
+        return domrPort;
+    }
+
+    String dom0Ip = "192.168.1.64";
+    Integer domrPort = 3922;
+    String host = "ovm-1";
+    String path = "/tmp";
+    String dirpath = "/tmp/testing";
+    String filename = "test.txt";
+    String content = "This is some content";
+    String bridge = "xenbr0";
+    String vncPort = "5900";
+    Integer port = 8899;
+    Integer retries = 1;
+    Integer interval = 1;
+    Integer timeout = 120;
+
+    ConnectionTest con = new ConnectionTest();
+    CloudstackPlugin cSp = new CloudstackPlugin(con);
+    XmlTestResultTest results = new XmlTestResultTest();
+
+    String domrExecXml = "<?xml version='1.0'?>"
+            + "<methodResponse>"
+            + "<params>"
+            + "<param>"
+            + "<value><struct>"
+            + "<member>"
+            + "<name>out</name>"
+            + "<value><string>clearUsageRules.sh func.sh hv-kvp-daemon_3.1_amd64.deb monitorServices.py reconfigLB.sh redundant_router</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>err</name>"
+            + "<value><string></string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>rc</name>"
+            + "<value><i8>0</i8></value>"
+            + "</member>"
+            + "</struct></value>"
+            + "</param>"
+            + "</params>"
+            + "</methodResponse>";
+    String dom0StatsXml = "<?xml version='1.0'?>\n" +
+            "<methodResponse>\n" +
+            "<params>\n" +
+            "<param>\n" +
+            "<value><struct>\n" +
+            "<member>\n" +
+            "<name>rx</name>\n" +
+            "<value><string>11631523\n" +
+            "</string></value>\n" +
+            "</member>\n" +
+            "<member>\n" +
+            "<name>total</name>\n" +
+            "<value><string>4293918720</string></value>\n" +
+            "</member>\n" +
+            "<member>\n" +
+            "<name>tx</name>\n" +
+            "<value><string>16927399\n" +
+            "</string></value>\n" +
+            "</member>\n" +
+            "<member>\n" +
+            "<name>cpu</name>\n" +
+            "<value><string>1.5</string></value>\n" +
+            "</member>\n" +
+            "<member>\n" +
+            "<name>free</name>\n" +
+            "<value><string>3162505216</string></value>\n" +
+            "</member>\n" +
+            "</struct></value>\n" +
+            "</param>\n" +
+            "</params>\n" +
+            "</methodResponse>";
+    String domuStatsXml = "<?xml version='1.0'?>"
+            + "<methodResponse>"
+            + "<params>"
+            + "<param>"
+            + "<value><struct>"
+            + "<member>"
+            + "<name>uptime</name>"
+            + "<value><string>862195495455</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>rx_bytes</name>"
+            + "<value><string>52654010</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>wr_ops</name>"
+            + "<value><string>521674</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>vcpus</name>"
+            + "<value><string>1</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>cputime</name>"
+            + "<value><string>295303661496</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>rd_ops</name>"
+            + "<value><string>14790</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>rd_bytes</name>"
+            + "<value><string>250168320</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>tx_bytes</name>"
+            + "<value><string>161389183</string></value>"
+            + "</member>"
+            + "<member>"
+            + "<name>wr_bytes</name>"
+            + "<value><string>1604468736</string></value>"
+            + "</member>"
+            + "</struct></value>"
+            + "</param>"
+            + "</params>"
+            + "</methodResponse>";
+    private String dom0StorageCheckXml = "<?xml version='1.0'?>"
+            + "<methodResponse>"
+            + "<params>"
+            + "<param>"
+            + "<value><array><data>"
+            + "<value><boolean>1</boolean></value>"
+            + "<value><boolean>0</boolean></value>"
+            + "</data></array></value>"
+            + "</param>"
+            + "</params>"
+            + "</methodResponse>";
+    public String getDom0StorageCheckXml() {
+        return dom0StorageCheckXml;
+    }
+    public String getDomrExecXml() {
+        return domrExecXml;
+    }
+
+    public String getDom0StatsXml() {
+        return dom0StatsXml;
+    }
+
+    public String getDomuStatsXml() {
+        return domuStatsXml;
+    }
+
+    @Test
+    public void testDom0CheckStorageHealthCheck() throws Ovm3ResourceException {
+        con.setResult(dom0StorageCheckXml);
+        results.basicBooleanTest(cSp.dom0CheckStorageHealthCheck("", "", "", 120, 1));
+        results.basicBooleanTest(cSp.dom0CheckStorageHealthCheck(), false);
+    }
+    @Test
+    public void testOvsUploadFile() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.ovsUploadFile(path, filename, content));
+    }
+
+    @Test
+    public void testOvsUploadSshKey() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.ovsUploadSshKey(path, content));
+    }
+
+    @Test
+    public void testOvsDomrUploadFile() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.ovsDomrUploadFile(VMNAME, path, filename, content));
+    }
+
+    @Test
+    public void testGetVncPort() throws Ovm3ResourceException {
+        con.setResult(results.getString(vncPort));
+        results.basicStringTest(cSp.getVncPort(VMNAME), vncPort);
+    }
+
+    @Test
+    public void testDom0CheckPort() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.dom0CheckPort(host, port, retries, interval));
+        /* test nothing */
+        con.setNull();
+        results.basicBooleanTest(
+                cSp.dom0CheckPort(host, port, retries, interval), false);
+        /* for the last test we need to fake the timeout... */
+    }
+
+    @Test
+    public void testDom0Ip() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.dom0HasIp(dom0Ip));
+        con.setResult(results.getBoolean(false));
+        results.basicBooleanTest(cSp.dom0HasIp(dom0Ip), false);
+    }
+
+    @Test
+    public void testDomrExec() throws Ovm3ResourceException {
+        con.setResult(domrExecXml);
+        ReturnCode x = cSp.domrExec(domrIp, "ls");
+        assertNotNull(x);
+        assertEquals(x.getExit(), (Integer) 0);
+        assertEquals(x.getRc(), true);
+        assertEquals(x.getExit(), (Integer) 0);
+        assertNotNull(x.getStdOut());
+
+        /* failed */
+        domrExecXml = domrExecXml.replace("<i8>0</i8>", "<i8>1</i8>");
+        domrExecXml = domrExecXml.replace("<value><string></string></value>", "<value><string>Something went wrong!</string></value>");
+        con.setResult(domrExecXml);
+        ReturnCode y = cSp.domrExec(domrIp, "ls");
+        assertNotNull(y);
+        assertEquals(y.getRc(), false);
+        assertEquals(y.getExit(), (Integer) 1);
+        assertNotNull(x.getStdErr());
+    }
+
+    @Test
+    public void testOvsDom0Stats() throws Ovm3ResourceException {
+        con.setResult(dom0StatsXml);
+        Map<String, String> stats = cSp.ovsDom0Stats(bridge);
+        results.basicStringTest(stats.get("cpu"), "1.5");
+    }
+
+    @Test
+    public void TestOvsDomUStats() throws Ovm3ResourceException {
+        con.setResult(domuStatsXml);
+        Map<String, String> stats = cSp.ovsDomUStats(VMNAME);
+        results.basicStringTest(stats.get("cputime"), "295303661496");
+    }
+
+    @Test
+    public void TestDomrCheckPort() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.domrCheckPort(domrIp, domrPort));
+    }
+
+    @Test
+    public void TestDomrCheckSsh() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.domrCheckSsh(domrIp));
+    }
+
+    @Test
+    public void TestOvsControlInterface() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.ovsControlInterface("control0", "169.254.0.1/16"));
+    }
+
+    @Test
+    public void TestPing() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.ping(host));
+    }
+
+    @Test
+    public void TestOvsCheckFile() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.ovsCheckFile(filename));
+    }
+
+    @Test
+    public void dom0CheckStorageHealth() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.dom0CheckStorageHealth("", "", "", 120));
+        con.setResult(results.getBoolean(false));
+        results.basicBooleanTest(cSp.dom0CheckStorageHealth("", "", "", 120), false);
+    }
+    @Test
+    public void TestovsMkdirs() throws Ovm3ResourceException {
+        con.setResult(results.getNil());
+        results.basicBooleanTest(cSp.ovsMkdirs(dirpath));
+    }
+    @Test
+    public void TestovsMkdirsDirExists() throws Ovm3ResourceException {
+        con.setResult(results.getBoolean(true));
+        results.basicBooleanTest(cSp.ovsMkdirs(dirpath), false);
+    }
+    @Test
+    public void TestovsMkdirs2() throws Ovm3ResourceException {
+            con.setResult(results.getNil());
+            results.basicBooleanTest(cSp.ovsMkdirs(dirpath, 755));
+    }
+
+}


[11/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Network.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Network.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Network.java
new file mode 100644
index 0000000..0759c5a
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Network.java
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
+public class Network extends OvmObject {
+    private static final Logger LOGGER = Logger.getLogger(Network.class);
+    private static final String START = "start";
+    private static final String BRIDGE = "Bridge";
+    private static final String ADDRESS = "Address";
+    private static final String PHYSICAL = "Physical";
+    private Map<String, Interface> interfaceList = null;
+    private Object postDiscovery = null;
+    private List<String> netInterfaces = new ArrayList<String>();
+
+    public Network(Connection c) {
+        setClient(c);
+    }
+
+    public Map<String, Interface> getInterfaceList()
+            throws Ovm3ResourceException {
+        discoverNetwork();
+        return interfaceList;
+    }
+
+    public static class Interface {
+        private final Map<String, String> iFace = new HashMap<String, String>() {
+            {
+                put("Type", null);
+                put(PHYSICAL, null);
+                put("Name", null);
+                put(ADDRESS, null);
+                put("Broadcast", null);
+                put("MAC", null);
+                put("Vlan", null);
+            }
+        };
+
+        public Interface() {
+        }
+
+        public void setIfType(String t) {
+            iFace.put("Type", t);
+        }
+
+        public String getIfType() {
+            return iFace.get("Type");
+        }
+
+        public void setInterface(Map<String, String> itf) {
+            iFace.putAll(itf);
+        }
+
+        public String getName() {
+            return iFace.get("Name");
+        }
+
+        public String getPhysical() {
+            return iFace.get(PHYSICAL);
+        }
+
+        public String getAddress() {
+            return iFace.get(ADDRESS);
+        }
+
+        public String getBroadcast() {
+            return iFace.get("Broadcast");
+        }
+
+        public String getMac() {
+            return iFace.get("MAC");
+        }
+
+        public String setName(String name) {
+            return iFace.put("Name", name);
+        }
+
+        public String setPhysical(String ph) {
+            return iFace.put(PHYSICAL, ph);
+        }
+
+        public String setMac(String mac) {
+            return iFace.put("MAC", mac);
+        }
+    }
+
+    private Network.Interface getNetIface(String key, String val)
+            throws Ovm3ResourceException {
+        Map<String, Network.Interface> ifaces = getInterfaceList();
+        for (final Entry<String, Interface> iface : ifaces.entrySet()) {
+            String match = "default";
+            if (ADDRESS.equals(key)) {
+                match = iface.getValue().getAddress();
+            }
+            if ("Name".equals(key)) {
+                match = iface.getKey();
+            }
+            if (match != null && match.equals(val)) {
+                return iface.getValue();
+            }
+        }
+        LOGGER.debug("Unable to find " + key + " Interface by value: " + val);
+        setSuccess(false);
+        return null;
+    }
+
+    public Network.Interface getInterfaceByIp(String ip)
+            throws Ovm3ResourceException {
+        return getNetIface(ADDRESS, ip);
+    }
+
+    public Network.Interface getInterfaceByName(String name)
+            throws Ovm3ResourceException {
+        return getNetIface("Name", name);
+    }
+
+    /* check if it is a BRIDGE */
+    public String getPhysicalByBridgeName(String name)
+            throws Ovm3ResourceException {
+        return getInterfaceByName(name).getPhysical();
+    }
+
+    public Network.Interface getBridgeByName(String name)
+            throws Ovm3ResourceException {
+        if (getNetIface("Name", name) != null
+                && getNetIface("Name", name).getIfType().contentEquals(BRIDGE)) {
+            return getNetIface("Name", name);
+        }
+        LOGGER.debug("Unable to find bridge by name: " + name);
+        setSuccess(false);
+        return null;
+    }
+
+    public Network.Interface getBridgeByIp(String ip)
+            throws Ovm3ResourceException {
+        if (getNetIface(ADDRESS, ip) != null
+                && getNetIface(ADDRESS, ip).getIfType().contentEquals(BRIDGE)) {
+            return getNetIface(ADDRESS, ip);
+        }
+        LOGGER.debug("Unable to find bridge by ip: " + ip);
+        setSuccess(false);
+        return null;
+    }
+
+    /*
+     * configure_virtual_ip, <class
+     * 'agent.api.network.linux_network.LinuxNetwork'> argument: self - default:
+     * None argument: virtual_ip - default: None argument: base_ip - default:
+     * None
+     */
+    public Boolean configureVip(String vip, String baseip)
+            throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("configure_virtual_ip", vip, baseip);
+    }
+
+    public Boolean ovsIpConfig(String net, String optype, String ip,
+            String netmask) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("ovs_ip_config", net, optype, ip, netmask);
+    }
+
+    /*
+     * Restriction: - data string that starts with leading spaces will be
+     * rejected ovs_if_meta('bond0',
+     * 'ethernet:c0a80100{192.168.1.0}:MANAGEMENT,CLUSTER_HEARTBEAT,LIVE_MIGRATE,VIRTUAL_MACHINE,STORAGE')
+     */
+
+    public Boolean discoverNetwork() throws Ovm3ResourceException {
+        postDiscovery = callWrapper("discover_network");
+        if (postDiscovery == null) {
+            return false;
+        }
+        interfaceList = new HashMap<String, Interface>();
+        Document xmlDocument = prepParse((String) postDiscovery);
+        String path = "//Discover_Network_Result/Network/Active";
+        String bpath = path + "/Bridges/Device";
+
+        netInterfaces = new ArrayList<String>();
+        netInterfaces.addAll(xmlToList(bpath + "/@Name", xmlDocument));
+        for (String b : netInterfaces) {
+            Map<String, String> br = xmlToMap(bpath + "[@Name='" + b
+                    + "']/Family", xmlDocument);
+            /* vifs are here too */
+            String phyInt = (String) this.xmlToMap(
+                    bpath + "[@Name='" + b + "']/Interfaces", xmlDocument).get(
+                    "PhyInterface");
+            Interface iface = new Interface();
+            iface.setInterface(br);
+            iface.setName(b);
+            iface.setIfType(BRIDGE);
+            if (phyInt == null) {
+                iface.setIfType("Local");
+            }
+            iface.setPhysical(phyInt);
+            interfaceList.put(b, iface);
+        }
+        /* add "physical" interfaces */
+        bpath = path + "/Network/Device";
+        netInterfaces = new ArrayList<String>();
+        netInterfaces.addAll(xmlToList(bpath + "/@Name", xmlDocument));
+        for (String p : netInterfaces) {
+            Map<String, String> nf = xmlToMap("//Device[@Name='" + p + "']",
+                    xmlDocument);
+            Interface iface = new Interface();
+            iface.setPhysical(nf.get("Basename"));
+            iface.setName(p);
+            iface.setMac(nf.get("MAC"));
+            iface.setIfType(PHYSICAL);
+            interfaceList.put(p, iface);
+        }
+        /* add virtual interfaces ? */
+        return true;
+    }
+
+    public Boolean startOvsLocalConfig(String br) throws Ovm3ResourceException {
+        String s = (String) ovsLocalConfig(START, br);
+        if (s.startsWith(START)) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean stopOvsLocalConfig(String br) throws Ovm3ResourceException {
+        String s = (String) ovsLocalConfig("stop", br);
+        if (s.startsWith("stop")) {
+            return true;
+        }
+        return false;
+    }
+
+    private Object ovsLocalConfig(String action, String br)
+            throws Ovm3ResourceException {
+        return callWrapper("ovs_local_config", action, br);
+    }
+
+    public Boolean startOvsVlanConfig(String dev, int vlan)
+            throws Ovm3ResourceException {
+        return ovsVlanConfig("add", dev, vlan);
+    }
+
+    public Boolean stopOvsVlanConfig(String dev, int vlan)
+            throws Ovm3ResourceException {
+        return ovsVlanConfig("remove", dev, vlan);
+    }
+
+    private Boolean ovsVlanConfig(String action, String net, int vlan)
+            throws Ovm3ResourceException {
+        Object x = callWrapper("ovs_vlan_config", action, net, vlan);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean startOvsBrConfig(String br, String dev)
+            throws Ovm3ResourceException {
+        String s = (String) ovsBrConfig(START, br, dev);
+        if (s.startsWith(START)) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean stopOvsBrConfig(String br, String dev)
+            throws Ovm3ResourceException {
+        String s = (String) ovsBrConfig("stop", br, dev);
+        if (s.startsWith("stop")) {
+            return true;
+        }
+        return false;
+    }
+
+    public Object ovsBrConfig(String action, String br, String net)
+            throws Ovm3ResourceException {
+        return (Object) callWrapper("ovs_br_config", action, br, net);
+    }
+
+    /* 1 is untagged, goes till 4095 */
+    public Boolean stopOvsVlanBridge(String br, String net, int vlan)
+            throws Ovm3ResourceException {
+        String s = (String) ovsVlanBridge("stop", br, net, vlan);
+        if (s.startsWith("stop")) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean startOvsVlanBridge(String br, String net, int vlan)
+            throws Ovm3ResourceException {
+        String s = (String) ovsVlanBridge(START, br, net, vlan);
+        /* 3.2.1 uses start, 3.3.1 and up uses added... */
+        if (s.startsWith(START) || s.startsWith("Added")) {
+            return true;
+        }
+        return false;
+    }
+
+    private Object ovsVlanBridge(String action, String br, String net, int vlan)
+            throws Ovm3ResourceException {
+        return (Object) callWrapper("ovs_vlan_bridge", action, br, net, vlan);
+    }
+
+    /*
+     * deconfigure_virtual_ip, <class
+     * 'agent.api.network.linux_network.LinuxNetwork'> argument: self - default:
+     * None argument: virtual_ip - default: None
+     */
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Ntp.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Ntp.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Ntp.java
new file mode 100644
index 0000000..2402bf5
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Ntp.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Ntp extends OvmObject {
+    private List<String> ntpHosts = new ArrayList<String>();
+    private Boolean isServer = null;
+    private Boolean isRunning = null;
+
+    public Ntp(Connection c) {
+        setClient(c);
+    }
+
+    public List<String> addServer(String server) {
+        if (!ntpHosts.contains(server)) {
+            ntpHosts.add(server);
+        }
+        return ntpHosts;
+    }
+
+    public List<String> removeServer(String server) {
+        if (ntpHosts.contains(server)) {
+            ntpHosts.remove(server);
+        }
+        return ntpHosts;
+    }
+
+    public List<String> getServers() {
+        return ntpHosts;
+    }
+    public void setServers(List<String> s) {
+        ntpHosts = s;
+    }
+
+    public Boolean isRunning() {
+        return isRunning;
+    }
+
+    public Boolean isServer() {
+        return isServer;
+    }
+
+    public Boolean getDetails() throws Ovm3ResourceException {
+        return getNtp();
+    }
+
+    /*
+     * get_ntp, <class 'agent.api.host.linux.Linux'> argument: self - default:
+     * None
+     */
+    public Boolean getNtp() throws Ovm3ResourceException {
+        Object[] v = (Object[]) callWrapper("get_ntp");
+        int c = 0;
+        for (Object o : v) {
+            if (o instanceof java.lang.Boolean) {
+                if (c == 0) {
+                    isServer = (Boolean) o;
+                }
+                if (c == 1) {
+                    isRunning = (Boolean) o;
+                }
+                c += 1;
+            } else if (o instanceof java.lang.Object) {
+                Object[] s = (Object[]) o;
+                for (Object m : s) {
+                    addServer((String) m);
+                }
+            }
+        }
+        return true;
+    }
+
+    public Boolean setNtp(List<String> ntpHosts, Boolean running)
+            throws Ovm3ResourceException {
+        if (ntpHosts.isEmpty()) {
+            return false;
+        }
+        return nullIsTrueCallWrapper("set_ntp", ntpHosts, running);
+    }
+
+    /* also cleans the vector */
+    public Boolean setNtp(String server, Boolean running)
+            throws Ovm3ResourceException {
+        ntpHosts = new ArrayList<String>();
+        ntpHosts.add(server);
+        return setNtp(ntpHosts, running);
+    }
+
+    public Boolean setNtp(Boolean running) throws Ovm3ResourceException {
+        return setNtp(ntpHosts, running);
+    }
+
+    public Boolean disableNtp() throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("disable_ntp");
+
+    }
+
+    public Boolean enableNtp() throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("enable_ntp");
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Ovm3ResourceException.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Ovm3ResourceException.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Ovm3ResourceException.java
new file mode 100644
index 0000000..a04a242
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Ovm3ResourceException.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+public class Ovm3ResourceException extends Exception {
+    private static final long serialVersionUID = 1L;
+    private static final Throwable CAUSE = null;
+    public Ovm3ResourceException() {
+        super();
+    }
+
+    public Ovm3ResourceException(String message) {
+        super(message);
+    }
+
+    public Ovm3ResourceException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    @Override
+    public Throwable getCause() {
+        return CAUSE;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/OvmObject.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/OvmObject.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/OvmObject.java
new file mode 100644
index 0000000..32bd12a
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/OvmObject.java
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class OvmObject {
+    private volatile Connection client;
+    private static List<?> emptyParams = new ArrayList<Object>();
+    private static final Logger LOGGER = Logger
+            .getLogger(OvmObject.class);
+    private boolean success = false;
+
+    public OvmObject() {
+    }
+
+    public Connection getClient() {
+        return client;
+    }
+
+    public synchronized void setClient(Connection c) {
+        client = c;
+    }
+
+    /* remove dashes from uuids */
+    public String deDash(String str) {
+        return str.replaceAll("-", "");
+    }
+    /* generate a uuid */
+    public String newUuid() {
+        return UUID.randomUUID().toString();
+    }
+
+    /* generate a uuid */
+    public String newUuid(String str) {
+        return UUID.nameUUIDFromBytes(str.getBytes()).toString();
+    }
+
+    /* capture most of the calls here */
+    public Object callWrapper(String call) throws Ovm3ResourceException {
+        try {
+            return client.call(call, emptyParams);
+        } catch (XmlRpcException e) {
+            String msg = "Client call " + call  + " to " +  client.getIp() + " went wrong: " + e.getMessage();
+            throw new Ovm3ResourceException(msg, e);
+        }
+    }
+
+    public void setSuccess(boolean s) {
+        success = s;
+    }
+
+    public Boolean getSuccess() {
+        return success;
+    }
+
+    /* nice try but doesn't work like that .. */
+    @SafeVarargs
+    public final <T> Object callWrapper(String call, T... args)
+            throws Ovm3ResourceException {
+        List<T> params = new ArrayList<T>();
+        for (T param : args) {
+            params.add(param);
+        }
+        try {
+            return client.call(call, params);
+        } catch (XmlRpcException e) {
+            String msg = "Client call " + call  + " to " +  client.getIp() + " with " + params + " went wrong: " + e.getMessage();
+            throw new Ovm3ResourceException(msg, e);
+        }
+    }
+
+    /* should check on nil ? */
+    @SafeVarargs
+    public final <T> Boolean nullCallWrapper(String call, Boolean nullReturn, T... args) throws Ovm3ResourceException {
+        Object x = callWrapper(call, args);
+        if (x == null) {
+            return nullReturn;
+        } else if (!nullReturn) {
+            return true;
+        }
+        return false;
+    }
+
+    @SafeVarargs
+    public final <T> Boolean nullIsFalseCallWrapper(String call, T... args) throws Ovm3ResourceException {
+        return nullCallWrapper(call, false, args);
+    }
+    @SafeVarargs
+    public final <T> Boolean nullIsTrueCallWrapper(String call, T... args) throws Ovm3ResourceException {
+        return nullCallWrapper(call, true, args);
+    }
+
+    /* returns a single string */
+    public Map<String, Long> callMap(String call) throws Ovm3ResourceException {
+        return (HashMap<String, Long>) callWrapper(call);
+    }
+
+    public <T> String callString(String call, T... args) throws Ovm3ResourceException {
+        Object result = callWrapper(call, args);
+        if (result == null) {
+            return null;
+        }
+        if (result instanceof String || result instanceof Integer || result instanceof Long || result instanceof HashMap) {
+            return result.toString();
+        }
+
+        Object[] results = (Object[]) result;
+
+        if (results.length == 0) {
+            return null;
+        }
+        if (results.length == 1) {
+            return results[0].toString();
+        }
+        return null;
+    }
+
+    /* was String, Object before */
+    public <E> Map<String, E> xmlToMap(String path, Document xmlDocument)
+            throws Ovm3ResourceException {
+        XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance();
+        XPath xPath = factory.newXPath();
+        try {
+            XPathExpression xPathExpression = xPath.compile(path);
+            NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
+                    XPathConstants.NODESET);
+            Map<String, E> myMap = new HashMap<String, E>();
+            for (int ind = 0; ind < nodeList.getLength(); ind++) {
+                NodeList nodeListFor = nodeList.item(ind).getChildNodes();
+                for (int index = 0; index < nodeListFor.getLength(); index++) {
+                    String rnode = nodeListFor.item(index).getNodeName();
+                    NodeList nodeListFor2 = nodeListFor.item(index).getChildNodes();
+                    if (nodeListFor2.getLength() > 1) {
+                        /* Do we need to figure out all the sub elements here and put them in a map? */
+                    } else {
+                        String element = nodeListFor.item(index).getTextContent();
+                        myMap.put(rnode, (E) element);
+                    }
+                }
+            }
+            return myMap;
+        } catch (XPathExpressionException e) {
+            throw new Ovm3ResourceException("Problem parsing XML to Map:", e);
+        }
+    }
+
+    public List<String> xmlToList(String path, Document xmlDocument)
+            throws Ovm3ResourceException {
+        List<String> list = new ArrayList<String>();
+        XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance();
+        XPath xPath = factory.newXPath();
+        try {
+            XPathExpression xPathExpression = xPath.compile(path);
+            NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
+                    XPathConstants.NODESET);
+            for (int ind = 0; ind < nodeList.getLength(); ind++) {
+                if (!nodeList.item(ind).getTextContent().isEmpty()) {
+                    list.add("" + nodeList.item(ind).getTextContent());
+                } else {
+                    list.add("" + nodeList.item(ind).getNodeValue());
+                }
+            }
+            return list;
+        } catch (XPathExpressionException e) {
+            throw new Ovm3ResourceException("Problem parsing XML to List: ", e);
+        }
+    }
+
+    public String xmlToString(String path, Document xmlDocument)
+            throws Ovm3ResourceException {
+        XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance();
+        XPath xPath = factory.newXPath();
+        try {
+            XPathExpression xPathExpression = xPath.compile(path);
+            NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
+                    XPathConstants.NODESET);
+            return nodeList.item(0).getTextContent();
+        } catch (NullPointerException e) {
+            LOGGER.info("Got no items back from parsing, returning null: " + e);
+            return null;
+        } catch (XPathExpressionException e) {
+            throw new Ovm3ResourceException("Problem parsing XML to String: ", e);
+        }
+    }
+
+    public Document prepParse(String input)
+            throws Ovm3ResourceException {
+        DocumentBuilderFactory builderfactory = DocumentBuilderFactory
+                .newInstance();
+        builderfactory.setNamespaceAware(true);
+
+        DocumentBuilder builder;
+        try {
+            builder = builderfactory.newDocumentBuilder();
+        } catch (ParserConfigurationException e) {
+            throw new Ovm3ResourceException("Unable to create document Builder: ", e);
+        }
+        Document xmlDocument;
+        try {
+            xmlDocument = builder.parse(new InputSource(new StringReader(
+                    input)));
+        } catch (SAXException | IOException e) {
+            LOGGER.info(e.getClass() + ": ", e);
+            throw new Ovm3ResourceException("Unable to parse XML: ", e);
+        }
+        return xmlDocument;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Pool.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Pool.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Pool.java
new file mode 100644
index 0000000..84fa965
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Pool.java
@@ -0,0 +1,272 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
+/*
+ * synonym to the pool python lib in the ovs-agent
+ */
+public class Pool extends OvmObject {
+    private static final Logger LOGGER = Logger
+            .getLogger(Pool.class);
+
+    private final List<String> validRoles = new ArrayList<String>() {
+        {
+            add("xen");
+            add("utility");
+        }
+    };
+    private List<String> poolHosts = new ArrayList<String>();
+    private final List<String> poolRoles = new ArrayList<String>();
+    private String poolMasterVip;
+    private String poolAlias;
+    private String poolId = null;
+
+    public Pool(Connection c) {
+        setClient(c);
+    }
+
+    public String getPoolMasterVip() {
+        return poolMasterVip;
+    }
+
+    public String getPoolAlias() {
+        return poolAlias;
+    }
+
+    public String getPoolId() {
+        return poolId;
+    }
+
+    public List<String> getValidRoles() {
+        return validRoles;
+    }
+
+    public Boolean isInPool(String id) throws Ovm3ResourceException {
+        if (poolId == null) {
+            discoverServerPool();
+        }
+        if (poolId == null) {
+            return false;
+        }
+        if (isInAPool() && poolId.equals(id)) {
+            return true;
+        }
+        return false;
+    }
+
+    public Boolean isInAPool() throws Ovm3ResourceException {
+        if (poolId == null) {
+            discoverServerPool();
+        }
+        if (poolId == null) {
+            return false;
+        }
+        return true;
+    }
+
+    private Boolean createServerPool(String alias, String id, String vip,
+            int num, String name, String host, List<String> roles) throws Ovm3ResourceException{
+        String role = StringUtils.join(roles, ",");
+        if (!isInAPool()) {
+            Object x = callWrapper("create_server_pool", alias, id, vip, num, name,
+                    host, role);
+            if (x == null) {
+                return true;
+            }
+            return false;
+        } else if (isInPool(id)) {
+            return true;
+        } else {
+            throw new Ovm3ResourceException("Unable to add host is already in  a pool with id : " + poolId);
+        }
+    }
+
+    public Boolean createServerPool(String alias, String id, String vip,
+            int num, String name, String ip) throws Ovm3ResourceException {
+        return createServerPool(alias, id, vip, num, name, ip,
+                getValidRoles());
+    }
+
+    /*
+     * public Boolean updatePoolVirtualIp(String ip) throws
+     * Ovm3ResourceException { Object x = callWrapper("update_pool_virtual_ip",
+     * ip); if (x == null) { poolMasterVip = ip; return true; } return false; }
+     */
+
+    public Boolean leaveServerPool(String uuid) throws Ovm3ResourceException{
+        return nullIsTrueCallWrapper("leave_server_pool", uuid);
+    }
+    /**
+     * Ownership prior to 3.3.x used to be simpler....
+     * @param uuid
+     * @param apiurl
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    public Boolean takeOwnership(String uuid, String apiurl) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("take_ownership", uuid, apiurl);
+    }
+    /**
+     * New style ownership, we need a dict to go in.
+     *  manager_uuid
+     *  manager_event_url
+     *  manager_statistic_url
+     *  manager_certificate
+     *  signed_server_certificate
+     * @param uuid
+     * @param apiurl
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    public Boolean takeOwnership33x(final String uuid,
+            final String eventUrl,
+            final String statUrl,
+            final String managerCert,
+            final String signedCert) throws Ovm3ResourceException {
+        final Map<String, String> mgrConfig = new HashMap<String, String>() {
+            {
+                put("manager_uuid", uuid);
+                put("manager_event_url", eventUrl);
+                put("manager_statistic_url", statUrl);
+                put("manager_certificate", managerCert);
+                put("signed_server_certificate", signedCert);
+            }
+        };
+        Boolean rc = nullIsTrueCallWrapper("take_ownership", mgrConfig);
+        /* because it restarts when it's done.... 2000? -sigh- */
+        try {
+            Thread.sleep(2000);
+        } catch (InterruptedException e) {
+            throw new Ovm3ResourceException(e.getMessage());
+        }
+        return rc;
+    }
+
+    /*
+     * destroy_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None argument: pool_uuid - default: None
+     */
+    public Boolean destroyServerPool(String uuid) throws Ovm3ResourceException{
+        return nullIsTrueCallWrapper("destroy_server_pool", uuid);
+    }
+
+    /*
+     * release_ownership, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None argument: manager_uuid - default: None
+     */
+    public Boolean releaseOwnership(String uuid) throws Ovm3ResourceException{
+        return nullIsTrueCallWrapper("release_ownership", uuid);
+    }
+
+    /* server.discover_pool_filesystem */
+    /*
+     * discover_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+     * self - default: None
+     */
+    public Boolean discoverServerPool() throws Ovm3ResourceException {
+        Object x = callWrapper("discover_server_pool");
+        if (x == null) {
+            return false;
+        }
+
+        Document xmlDocument = prepParse((String) x);
+        String path = "//Discover_Server_Pool_Result/Server_Pool";
+        poolId = xmlToString(path + "/Unique_Id", xmlDocument);
+        poolAlias = xmlToString(path + "/Pool_Alias", xmlDocument);
+        poolMasterVip = xmlToString(path + "/Master_Virtual_Ip",
+                xmlDocument);
+        poolHosts.addAll(xmlToList(path + "//Registered_IP", xmlDocument));
+        if (poolId == null) {
+            return false;
+        }
+        return true;
+    }
+
+    private Boolean setServerRoles() throws Ovm3ResourceException{
+        String roles = StringUtils.join(poolRoles.toArray(), ",");
+        return nullIsTrueCallWrapper("update_server_roles", roles);
+    }
+
+    /* do some sanity check on the valid poolroles */
+    public Boolean setServerRoles(List<String> roles) throws Ovm3ResourceException {
+        poolRoles.addAll(roles);
+        return setServerRoles();
+    }
+
+    private Boolean joinServerPool(String alias, String id, String vip, int num,
+            String name, String host, List<String> roles) throws Ovm3ResourceException{
+        String role = StringUtils.join(roles.toArray(), ",");
+        if (!isInAPool()) {
+            Object x = callWrapper("join_server_pool", alias, id, vip, num, name,
+                    host, role);
+            if (x == null) {
+                return true;
+            }
+            return false;
+        } else if (isInPool(id)) {
+            return true;
+        } else {
+            throw new Ovm3ResourceException("Unable to add host is already in  a pool with id : " + poolId);
+        }
+    }
+
+    public Boolean joinServerPool(String alias, String id, String vip, int num,
+            String name, String host) throws Ovm3ResourceException {
+        return joinServerPool(alias, id, vip, num, name, host, getValidRoles());
+    }
+
+    private Boolean setPoolMemberList() throws Ovm3ResourceException {
+        // should throw exception if no poolHosts set
+        return nullIsTrueCallWrapper("set_pool_member_ip_list", poolHosts);
+    }
+
+    public List<String> getPoolMemberList() throws Ovm3ResourceException {
+        if (poolId == null) {
+            discoverServerPool();
+        }
+        return poolHosts;
+    }
+
+    public Boolean setPoolMemberList(List<String> hosts) throws Ovm3ResourceException {
+        poolHosts = new ArrayList<String>();
+        poolHosts.addAll(hosts);
+        return setPoolMemberList();
+    }
+
+    public Boolean addPoolMember(String host) throws Ovm3ResourceException {
+        getPoolMemberList();
+        poolHosts.add(host);
+        return setPoolMemberList();
+    }
+
+    public Boolean removePoolMember(String host) throws Ovm3ResourceException {
+        getPoolMemberList();
+        poolHosts.remove(host);
+        return setPoolMemberList();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/PoolOCFS2.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/PoolOCFS2.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/PoolOCFS2.java
new file mode 100644
index 0000000..c5425ac
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/PoolOCFS2.java
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
+public class PoolOCFS2 extends OvmObject {
+    private static final Logger LOGGER = Logger
+            .getLogger(PoolOCFS2.class);
+    private Map<String, String> poolFileSystem = new HashMap<String, String>();
+    private String poolFsTarget;
+    private String poolFsType;
+    private String poolFsNFSBaseId;
+    private String poolFsId;
+    private String poolFsVersion;
+    private String poolFsManagerUuid;
+    private String poolPoolFsId;
+
+    public PoolOCFS2(Connection c) {
+        setClient(c);
+    }
+
+    public String getPoolFsNFSBaseId() {
+        return poolFsNFSBaseId;
+    }
+
+    public String getPoolFsId() {
+        return poolFsId;
+    }
+
+    public String getPoolFsUuid() {
+        return poolFsId;
+    }
+
+    public String getPoolFsTarget() {
+        return poolFsTarget;
+    }
+    public String getPoolFsManagerUuid() {
+        return poolFsManagerUuid;
+    }
+    public String getPoolFsVersion() {
+        return poolFsVersion;
+    }
+    public String getPoolPoolFsId() {
+        return poolPoolFsId;
+    }
+    public String getPoolFsType() {
+        return poolFsType;
+    }
+    public Boolean hasPoolFs(String id) throws Ovm3ResourceException {
+        if (poolFsId == null) {
+            discoverPoolFs();
+        }
+        if (hasAPoolFs() && poolFsId.equals(id)) {
+            return true;
+        }
+        return false;
+    }
+    public Boolean hasAPoolFs() throws Ovm3ResourceException {
+        if (poolFsId == null) {
+            discoverPoolFs();
+        }
+        if (poolFsId == null) {
+            return false;
+        }
+        return true;
+    }
+
+    public Boolean destroyPoolFs(String type, String target, String uuid,
+            String nfsbaseuuid) throws Ovm3ResourceException {
+        // should throw exception if no poolIps set
+        return nullIsTrueCallWrapper("destroy_pool_filesystem", type, target, uuid,
+                nfsbaseuuid);
+    }
+
+    public Boolean destroyPoolFs() throws Ovm3ResourceException {
+        // should throw exception if no poolIps set
+        return nullIsTrueCallWrapper("destroy_pool_filesystem", poolFsType,
+                poolFsTarget, poolFsId, poolFsNFSBaseId);
+    }
+
+    public Boolean createPoolFs(String type, String target, String clustername,
+            String fsid, String nfsbaseid, String managerid) throws Ovm3ResourceException {
+        if (!hasAPoolFs()) {
+            return nullIsTrueCallWrapper("create_pool_filesystem", type, target,
+                    clustername, fsid, nfsbaseid, managerid, fsid);
+        } else if (hasPoolFs(fsid)) {
+            LOGGER.debug("PoolFs already exists on this host: " + fsid);
+            return true;
+        } else {
+            throw new Ovm3ResourceException("Unable to add pool filesystem to host, "+
+                    "pool filesystem with other id found: " + poolFsId);
+        }
+    }
+
+    /* Assume a single pool can be used for a host... */
+    public Boolean discoverPoolFs() throws Ovm3ResourceException{
+        // should throw exception if no poolIps set
+        Object x = callWrapper("discover_pool_filesystem");
+        if (x == null) {
+            return false;
+        }
+        Document xmlDocument = prepParse((String) x);
+        String path = "//Discover_Pool_Filesystem_Result";
+        poolFileSystem = xmlToMap(path + "/Pool_Filesystem", xmlDocument);
+        poolFsTarget = poolFileSystem.get("Pool_Filesystem_Target");
+        poolFsType = poolFileSystem.get("Pool_Filesystem_Type");
+        poolFsNFSBaseId = poolFileSystem.get("Pool_Filesystem_Nfsbase_Uuid");
+        poolFsId = poolFileSystem.get("Pool_Filesystem_Uuid");
+        poolPoolFsId = poolFileSystem.get("Pool_Filesystem_Pool_Uuid");
+        poolFsManagerUuid = poolFileSystem.get("Pool_Filesystem_Manager_Uuid");
+        poolFsVersion = poolFileSystem.get("Pool_Filesystem_Version");
+        return true;
+    }
+
+    public Boolean ocfs2GetMetaData(String device, String filename) throws Ovm3ResourceException {
+        Object x = callWrapper("ocfs2_get_meta_data", device, filename);
+        if (x == null) {
+            return true;
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Remote.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Remote.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Remote.java
new file mode 100644
index 0000000..adfa239
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Remote.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+public class Remote extends OvmObject {
+
+    public Remote(Connection c) {
+        setClient(c);
+    }
+
+    public Boolean sysShutdown() throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("sys_shutdown");
+    }
+
+    public Boolean sysReboot() throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("sys_reboot");
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Repository.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Repository.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Repository.java
new file mode 100644
index 0000000..7e842ce
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/Repository.java
@@ -0,0 +1,334 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+
+public class Repository extends OvmObject {
+    private static final Logger LOGGER = Logger.getLogger(Repository.class);
+    private static final String VERSION = "Version";
+    private static final String NAMETAG = "[@Name='";
+    private Object postDiscovery = null;
+    private Object postDbDiscovery = null;
+    private Map<String, RepoDbDetails> repoDbs = new HashMap<String, RepoDbDetails>();
+    private Map<String, RepoDetails> repos = new HashMap<String, RepoDetails>();
+    private List<String> repoDbList = new ArrayList<String>();
+    private List<String> repoList = new ArrayList<String>();
+
+    public Repository(Connection c) {
+        setClient(c);
+    }
+
+    public RepoDbDetails getRepoDb(String id) throws Ovm3ResourceException {
+        if (repoDbs.containsKey(id)) {
+            return repoDbs.get(id);
+        }
+        return null;
+    }
+
+    public List<String> getRepoDbList() throws Ovm3ResourceException {
+        return repoDbList;
+    }
+
+    public RepoDetails getRepo(String id) throws Ovm3ResourceException {
+        if (repos.containsKey(id)) {
+            return repos.get(id);
+        }
+        return null;
+    }
+
+    public List<String> getRepoList() throws Ovm3ResourceException {
+        return repoList;
+    }
+
+    public static class RepoDbDetails {
+        private final Map<String, String> dbEntry = new HashMap<String, String>() {
+            {
+                put("Uuid", null);
+                put("Fs_location", null);
+                put("Mount_point", null);
+                put("Filesystem_type", null);
+                put(VERSION, null);
+                put("Alias", null);
+                put("Manager_uuid", null);
+                put("Status", null);
+            }
+        };
+
+        public RepoDbDetails() {
+        }
+
+        public void setRepoDbDetails(Map<String, String> det) {
+            dbEntry.putAll(det);
+        }
+
+        public void setUuid(String id) {
+            dbEntry.put("Uuid", id);
+        }
+
+        public String getStatus() {
+            return dbEntry.get("Status");
+        }
+
+        public String getManagerUuid() {
+            return dbEntry.get("Manager_uuid");
+        }
+
+        public String getAlias() {
+            return dbEntry.get("Alias");
+        }
+
+        public String getVersion() {
+            return dbEntry.get(VERSION);
+        }
+
+        public String getFilesystemType() {
+            return dbEntry.get("Filesystem_type");
+        }
+
+        public String getMountPoint() {
+            return dbEntry.get("Mount_point");
+        }
+
+        public String getFsLocation() {
+            return dbEntry.get("Fs_location");
+        }
+
+        public String getUuid() {
+            return dbEntry.get("Uuid");
+        }
+
+    }
+
+    public static class RepoDetails {
+        private List<String> templates = new ArrayList<String>();
+        private List<String> virtualMachines = new ArrayList<String>();
+        private List<String> virtualDisks = new ArrayList<String>();
+        private List<String> isos = new ArrayList<String>();
+        private final Map<String, String> dbEntry = new HashMap<String, String>() {
+            {
+                put("Repository_UUID", null);
+                put(VERSION, null);
+                put("Repository_Alias", null);
+                put("Manager_UUID", null);
+            }
+        };
+
+        public RepoDetails() {
+        }
+
+        public String getManagerUuid() {
+            return dbEntry.get("Manager_UUID");
+        }
+
+        public String getAlias() {
+            return dbEntry.get("Repository_Alias");
+        }
+
+        public String getVersion() {
+            return dbEntry.get(VERSION);
+        }
+
+        public String getUuid() {
+            return dbEntry.get("Repository_UUID");
+        }
+
+        public void setRepoDetails(Map<String, String> det) {
+            dbEntry.putAll(det);
+        }
+
+        public void setRepoTemplates(List<String> temp) {
+            templates.addAll(temp);
+        }
+
+        public List<String> getRepoTemplates() {
+            return templates;
+        }
+
+        public void setRepoVirtualMachines(List<String> vms) {
+            virtualMachines.addAll(vms);
+        }
+
+        public List<String> getRepoVirtualMachines() {
+            return virtualMachines;
+        }
+
+        public void setRepoVirtualDisks(List<String> disks) {
+            virtualDisks.addAll(disks);
+        }
+
+        public List<String> getRepoVirtualDisks() {
+            return virtualDisks;
+        }
+
+        public void setRepoISOs(List<String> isolist) {
+            isos.addAll(isolist);
+        }
+
+        public List<String> getRepoISOs() {
+            return isos;
+        }
+    }
+
+    /*
+     * delete_repository, <class 'agent.api.repository.Repository'> argument:
+     * repo_uuid - default: None argument: erase - default: None
+     */
+    public Boolean deleteRepo(String id, Boolean erase)
+            throws Ovm3ResourceException {
+        Object res = callWrapper("delete_repository", id, erase);
+        if (res == null) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * import_virtual_disk, <class 'agent.api.repository.Repository'> argument:
+     * url - default: None argument: virtual_disk_id - default: None argument:
+     * repo_uuid - default: None argument: option - default: None
+     */
+    /* should add timeout ? */
+    public Boolean importVirtualDisk(String url, String vdiskid, String repoid,
+            String option) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("import_virtual_disk", url, vdiskid,
+                repoid, option);
+    }
+
+    public Boolean importVirtualDisk(String url, String vdiskid, String repoid)
+            throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("import_virtual_disk", url, vdiskid,
+                repoid);
+    }
+
+    /*
+     * discover_repositories, <class 'agent.api.repository.Repository'>
+     * argument: args - default: None
+     */
+    /*
+     * args are repo ids <Discover_Repositories_Result> <RepositoryList/>
+     * </Discover_Repositories_Result>
+     */
+    public Boolean discoverRepo(String id) throws Ovm3ResourceException {
+        postDiscovery = callWrapper("discover_repositories", id);
+        if (postDiscovery == null) {
+            return false;
+        }
+        Document xmlDocument = prepParse((String) postDiscovery);
+        String path = "//Discover_Repositories_Result/RepositoryList/Repository";
+        repoList = new ArrayList<String>();
+        repoList.addAll(xmlToList(path + "/@Name", xmlDocument));
+        for (String name : repoList) {
+            RepoDetails repo = new RepoDetails();
+            repo.setRepoTemplates(xmlToList(path + NAMETAG + id
+                    + "']/Templates/Template/File", xmlDocument));
+            repo.setRepoVirtualMachines(xmlToList(path + NAMETAG + id
+                    + "']/VirtualMachines/VirtualMachine/@Name", xmlDocument));
+            repo.setRepoVirtualDisks(xmlToList(path + NAMETAG + name
+                    + "']/VirtualDisks/Disk", xmlDocument));
+            repo.setRepoISOs(xmlToList(
+                    path + NAMETAG + name + "']/ISOs/ISO", xmlDocument));
+            Map<String, String> details = xmlToMap(path + NAMETAG + name
+                    + "']", xmlDocument);
+            repo.setRepoDetails(details);
+            repos.put(name, repo);
+        }
+        return true;
+    }
+
+    /*
+     * add_repository, <class 'agent.api.repository.Repository'> argument:
+     * fs_location - default: None argument: mount_point - default: None
+     */
+    public Boolean addRepo(String remote, String local)
+            throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("add_repository", remote, local);
+    }
+
+    /**
+     * is the same as discoverRepoDb in principle (takes an id or mountpoint)
+     * get_repository_meta_data, <class 'agent.api.repository.Repository'>
+     * argument: repo_mount_point - default: None
+     */
+
+    /*
+     * mount_repository_fs, <class 'agent.api.repository.Repository'> argument:
+     * fs_location - default: None argument: mount_point - default: None
+     */
+    public Boolean mountRepoFs(String remote, String local)
+            throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("mount_repository_fs", remote, local);
+    }
+
+    /*
+     * unmount_repository_fs, <class 'agent.api.repository.Repository'>
+     * argument: mount_point - default: None
+     */
+    public Boolean unmountRepoFs(String local) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("unmount_repository_fs", local);
+    }
+
+    /*
+     * create_repository, <class 'agent.api.repository.Repository'> argument:
+     * fs_location - default: None argument: mount_point - default: None
+     * argument: repo_uuid - default: None argument: repo_alias - default: None
+     */
+    public Boolean createRepo(String remote, String local, String repoid,
+            String repoalias) throws Ovm3ResourceException {
+        return nullIsTrueCallWrapper("create_repository", remote, local,
+                repoid, repoalias);
+    }
+
+    /*
+     * discover_repository_db, <class 'agent.api.repository.Repository'>
+     * <Discover_Repository_Db_Result> <RepositoryDbList> <Repository
+     * Uuid="0004fb0000030000aeaca859e4a8f8c0">
+     * <Fs_location>cs-mgmt:/volumes/cs-data/primary</Fs_location>
+     * <Mount_point>/
+     * OVS/Repositories/0004fb0000030000aeaca859e4a8f8c0</Mount_point>
+     * <Filesystem_type>nfs</Filesystem_type> <Version>3.0</Version>
+     * <Alias>MyRepo</Alias>
+     * <Manager_uuid>0004fb00000100000af70d20dcce7d65</Manager_uuid>
+     * <Status>Unmounted</Status> </Repository> <Repository> ... </Repository>
+     * </RepositoryDbList> </Discover_Repository_Db_Result>
+     */
+    public Boolean discoverRepoDb() throws Ovm3ResourceException {
+        postDbDiscovery = callWrapper("discover_repository_db");
+        Document xmlDocument = prepParse((String) postDbDiscovery);
+        String path = "//Discover_Repository_Db_Result/RepositoryDbList/Repository";
+        repoDbList = new ArrayList<String>();
+        repoDbList.addAll(xmlToList(path + "/@Uuid", xmlDocument));
+        for (String id : repoDbList) {
+            RepoDbDetails repoDb = new RepoDbDetails();
+            Map<String, String> rep = xmlToMap(path + "[@Uuid='" + id + "']",
+                    xmlDocument);
+            repoDb.setRepoDbDetails(rep);
+            repoDb.setUuid(id);
+            repoDbs.put(id, repoDb);
+        }
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/RpcTypeFactory.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/RpcTypeFactory.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/RpcTypeFactory.java
new file mode 100644
index 0000000..1078e6e
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/objects/RpcTypeFactory.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.objects;
+
+import org.apache.ws.commons.util.NamespaceContextImpl;
+import org.apache.xmlrpc.common.TypeFactoryImpl;
+import org.apache.xmlrpc.common.XmlRpcController;
+import org.apache.xmlrpc.common.XmlRpcStreamConfig;
+import org.apache.xmlrpc.parser.NullParser;
+import org.apache.xmlrpc.parser.TypeParser;
+import org.apache.xmlrpc.parser.AtomicParser;
+import org.apache.xmlrpc.serializer.NullSerializer;
+import org.apache.xmlrpc.serializer.TypeSerializer;
+import org.apache.xmlrpc.serializer.TypeSerializerImpl;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ContentHandler;
+
+public class RpcTypeFactory extends TypeFactoryImpl {
+
+    public RpcTypeFactory(XmlRpcController pController) {
+        super(pController);
+    }
+
+    @Override
+    public TypeParser getParser(XmlRpcStreamConfig pConfig,
+            NamespaceContextImpl pContext, String pURI, String pLocalName) {
+        if ("".equals(pURI) && NullSerializer.NIL_TAG.equals(pLocalName)) {
+            return new NullParser();
+        } else if ("i8".equals(pLocalName)) {
+            return new LongTypeParser();
+        } else {
+            return super.getParser(pConfig, pContext, pURI, pLocalName);
+        }
+    }
+
+    public TypeSerializer getSerializer(XmlRpcStreamConfig pConfig,
+            Object pObject) throws SAXException {
+        if (pObject instanceof Long) {
+            return new LongTypeSerializer();
+        } else {
+            return super.getSerializer(pConfig, pObject);
+        }
+    }
+
+    private class LongTypeSerializer extends TypeSerializerImpl {
+        /*
+         * Tag name of an i8 value.
+         */
+        public static final String I8_TAG = "i8";
+        /*
+         * Fully qualified name of an i8 value.
+         */
+        public static final String EX_I8_TAG = "i8";
+        @Override
+        public void write(ContentHandler pHandler, Object pObject)
+                throws SAXException {
+            write(pHandler, I8_TAG, EX_I8_TAG, pObject.toString());
+        }
+    }
+
+    private class LongTypeParser extends AtomicParser {
+        protected void setResult(String pResult) throws SAXException {
+            try {
+                super.setResult(Long.valueOf(pResult.trim()));
+            } catch (NumberFormatException e) {
+                throw new SAXParseException("Failed to parse long value: "
+                        + pResult, getDocumentLocator());
+            }
+        }
+    }
+}


[09/12] git commit: updated refs/heads/master to c27c694

Posted by bh...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3FenceBuilder.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3FenceBuilder.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3FenceBuilder.java
new file mode 100755
index 0000000..b297cc9
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3FenceBuilder.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.AgentManager;
+import com.cloud.agent.api.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.exception.AgentUnavailableException;
+import com.cloud.exception.OperationTimedoutException;
+import com.cloud.ha.FenceBuilder;
+import com.cloud.host.Host;
+import com.cloud.host.HostVO;
+import com.cloud.host.Status;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.VirtualMachine;
+
+@Local(value = FenceBuilder.class)
+public class Ovm3FenceBuilder extends AdapterBase implements FenceBuilder {
+    Map<String, Object> fenceParams;
+    private static final Logger LOGGER = Logger.getLogger(Ovm3FenceBuilder.class);
+    @Inject
+    AgentManager agentMgr;
+    @Inject
+    ResourceManager resourceMgr;
+
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        fenceParams = params;
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        /* start the agent here ? */
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        /* stop the agent here ? */
+        return true;
+    }
+
+    public Ovm3FenceBuilder() {
+        super();
+    }
+
+    @Override
+    public Boolean fenceOff(VirtualMachine vm, Host host) {
+        if (host.getHypervisorType() != HypervisorType.Ovm3) {
+            LOGGER.debug("Don't know how to fence non Ovm3 hosts "
+                    + host.getHypervisorType());
+            return null;
+        } else {
+            LOGGER.debug("Fencing " + vm + " on host " + host
+                    + " with params: "+ fenceParams );
+        }
+
+        List<HostVO> hosts = resourceMgr.listAllHostsInCluster(host
+                .getClusterId());
+        FenceCommand fence = new FenceCommand(vm, host);
+
+        for (HostVO h : hosts) {
+            if (h.getHypervisorType() == HypervisorType.Ovm3 &&
+                    h.getStatus() == Status.Up &&
+                    h.getId() != host.getId()) {
+                FenceAnswer answer;
+                try {
+                    answer = (FenceAnswer) agentMgr.send(h.getId(), fence);
+                } catch (AgentUnavailableException | OperationTimedoutException e) {
+                    if (LOGGER.isDebugEnabled()) {
+                        LOGGER.debug("Moving on to the next host because "
+                                + h.toString() + " is unavailable", e);
+                    }
+                    continue;
+                }
+                if (answer != null && answer.getResult()) {
+                    return true;
+                }
+            }
+        }
+
+        if (LOGGER.isDebugEnabled()) {
+            LOGGER.debug("Unable to fence off " + vm.toString() + " on "
+                    + host.toString());
+        }
+
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorGuru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorGuru.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorGuru.java
new file mode 100755
index 0000000..526b061
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorGuru.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
+import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
+import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.HypervisorGuru;
+import com.cloud.hypervisor.HypervisorGuruBase;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.utils.Pair;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value = HypervisorGuru.class)
+public class Ovm3HypervisorGuru extends HypervisorGuruBase implements HypervisorGuru {
+    private final Logger LOGGER = Logger.getLogger(Ovm3HypervisorGuru.class);
+    @Inject
+    GuestOSDao guestOsDao;
+    @Inject
+    EndPointSelector endPointSelector;
+    @Inject
+    HostDao hostDao;
+
+    protected Ovm3HypervisorGuru() {
+        super();
+    }
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        return HypervisorType.Ovm3;
+    }
+
+    @Override
+    public VirtualMachineTO implement(VirtualMachineProfile vm) {
+        VirtualMachineTO to = toVirtualMachineTO(vm);
+        to.setBootloader(vm.getBootLoaderType());
+
+        // Determine the VM's OS description
+        GuestOSVO guestOS = guestOsDao.findById(vm.getVirtualMachine()
+                .getGuestOSId());
+        to.setOs(guestOS.getDisplayName());
+
+        return to;
+    }
+
+    @Override
+    public boolean trackVmHostChange() {
+        return true;
+    }
+
+    /* I dislike the notion of having to place this here, and not being able to just override
+     *
+     * (non-Javadoc)
+     * @see com.cloud.hypervisor.HypervisorGuruBase#getCommandHostDelegation(long, com.cloud.agent.api.Command)
+     */
+    public Pair<Boolean, Long> getCommandHostDelegation(long hostId, Command cmd) {
+        LOGGER.debug("getCommandHostDelegation: " + cmd.getClass());
+        if (cmd instanceof StorageSubSystemCommand) {
+            StorageSubSystemCommand c = (StorageSubSystemCommand)cmd;
+            c.setExecuteInSequence(true);
+        }
+        if (cmd instanceof CopyCommand) {
+            CopyCommand cpyCommand = (CopyCommand)cmd;
+            DataTO srcData = cpyCommand.getSrcTO();
+            DataTO destData = cpyCommand.getDestTO();
+
+            if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) {
+                LOGGER.debug("Snapshot to Template: " + cmd);
+                DataStoreTO srcStore = srcData.getDataStore();
+                DataStoreTO destStore = destData.getDataStore();
+                if (srcStore instanceof NfsTO && destStore instanceof NfsTO) {
+                    HostVO host = hostDao.findById(hostId);
+                    EndPoint ep = endPointSelector.selectHypervisorHost(new ZoneScope(host.getDataCenterId()));
+                    host = hostDao.findById(ep.getId());
+                    hostDao.loadDetails(host);
+                    // String snapshotHotFixVersion = host.getDetail(XenserverConfigs.XS620HotFix);
+                    // if (snapshotHotFixVersion != null && snapshotHotFixVersion.equalsIgnoreCase(XenserverConfigs.XSHotFix62ESP1004)) {
+                    return new Pair<Boolean, Long>(Boolean.TRUE,  Long.valueOf(ep.getId()));
+                }
+            }
+        }
+        return new Pair<Boolean, Long>(Boolean.FALSE, Long.valueOf(hostId));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java
new file mode 100644
index 0000000..dac8f1c
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3HypervisorResource.java
@@ -0,0 +1,596 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+// import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.agent.api.CheckHealthCommand;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckOnHostCommand;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.CreateStoragePoolCommand;
+import com.cloud.agent.api.DeleteStoragePoolCommand;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetStorageStatsCommand;
+import com.cloud.agent.api.GetVmStatsCommand;
+import com.cloud.agent.api.GetVncPortCommand;
+import com.cloud.agent.api.MaintainCommand;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.NetworkRulesSystemVmCommand;
+import com.cloud.agent.api.NetworkUsageCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PlugNicCommand;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.RebootAnswer;
+import com.cloud.agent.api.RebootCommand;
+import com.cloud.agent.api.StartAnswer;
+import com.cloud.agent.api.StartCommand;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.StartupStorageCommand;
+import com.cloud.agent.api.StopAnswer;
+import com.cloud.agent.api.StopCommand;
+import com.cloud.agent.api.UnPlugNicCommand;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource;
+import com.cloud.host.Host.Type;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Common;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.OvmObject;
+import com.cloud.hypervisor.ovm3.objects.Xen;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3HypervisorNetwork;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3StoragePool;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3VirtualRoutingSupport;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3VmGuestTypes;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3VmSupport;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3HypervisorSupport;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.resource.ServerResourceBase;
+import com.cloud.resource.hypervisor.HypervisorResource;
+import com.cloud.storage.resource.StorageSubsystemCommandHandler;
+import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
+/**
+ * Hypervisor related
+ */
+@Local(value = HypervisorResource.class)
+public class Ovm3HypervisorResource extends ServerResourceBase implements
+        HypervisorResource {
+    private static final Logger LOGGER = Logger
+            .getLogger(Ovm3HypervisorResource.class);
+    @Inject
+    private VirtualRoutingResource vrResource;
+    private StorageSubsystemCommandHandler storageHandler;
+    private Connection c;
+    private Ovm3StoragePool storagepool;
+    private Ovm3StorageProcessor storageprocessor;
+    private Ovm3HypervisorSupport hypervisorsupport;
+    private Ovm3VmSupport vmsupport;
+    private Ovm3HypervisorNetwork hypervisornetwork;
+    private Ovm3VirtualRoutingResource virtualroutingresource;
+    private Ovm3VirtualRoutingSupport virtualroutingsupport;
+    private Ovm3Configuration configuration;
+    private Ovm3VmGuestTypes guesttypes;
+    private OvmObject ovmObject = new OvmObject();
+
+    /*
+     * TODO: Add a network map, so we know which tagged interfaces we can remove
+     * and switch to ConcurrentHashMap
+     */
+    private Map<String, Xen.Vm> vmMap = new HashMap<String, Xen.Vm>();
+
+    @Override
+    public Type getType() {
+        return Type.Routing;
+    }
+
+    /*
+     * configure is called before this, does setup of the connection and
+     * gets the params.
+     *
+     * @see com.cloud.resource.ServerResource#initialize()
+     */
+    @Override
+    public StartupCommand[] initialize() {
+        LOGGER.debug("Ovm3 resource intializing");
+        try {
+            StartupRoutingCommand srCmd = new StartupRoutingCommand();
+            StartupStorageCommand ssCmd = new StartupStorageCommand();
+
+            /* here stuff gets completed, but where should state live ? */
+            hypervisorsupport.fillHostInfo(srCmd);
+            hypervisorsupport.vmStateMapClear();
+            LOGGER.debug("Ovm3 pool " + ssCmd + " " + srCmd);
+            return new StartupCommand[] { srCmd, ssCmd };
+        } catch (Exception e) {
+            LOGGER.debug("Ovm3 resource initializes failed", e);
+            return new StartupCommand[] {};
+        }
+    }
+
+    @Override
+    public PingCommand getCurrentStatus(long id) {
+        try {
+            /* feels useless somehow */
+            Common test = new Common(c);
+            String ping = "put";
+            String pong = test.echo(ping);
+            if (pong.contains(ping)) {
+                hypervisorsupport.syncState();
+                CloudstackPlugin cSp = new CloudstackPlugin(c);
+                if (!cSp.dom0CheckStorageHealthCheck(configuration .getAgentScriptsDir(),
+                        configuration.getAgentCheckStorageScript(),
+                        configuration.getCsHostGuid(),
+                        configuration.getAgentStorageCheckTimeout(),
+                        configuration.getAgentStorageCheckInterval())
+                        && !cSp.dom0CheckStorageHealthCheck()) {
+                    LOGGER.error("Storage health check not running on "
+                            + configuration.getAgentHostname());
+                } else if (cSp.dom0CheckStorageHealthCheck()) {
+                    LOGGER.error("Storage health check started on "
+                            + configuration.getAgentHostname());
+                } else {
+                    LOGGER.debug("Storage health check running on "
+                            + configuration.getAgentHostname());
+                }
+                return new PingRoutingCommand(getType(), id,
+                        hypervisorsupport.hostVmStateReport());
+            } else {
+                LOGGER.debug("Agent did not respond correctly: " + ping
+                        + " but got " + pong);
+            }
+
+        } catch (Ovm3ResourceException | NullPointerException e) {
+            LOGGER.debug("Check agent status failed", e);
+            return null;
+        }
+        return null;
+    }
+
+    @Override
+    public Answer executeRequest(Command cmd) {
+        Class<? extends Command> clazz = cmd.getClass();
+        LOGGER.debug("executeRequest called: " + cmd.getClass());
+        if (cmd instanceof NetworkElementCommand) {
+            return vrResource.executeRequest((NetworkElementCommand) cmd);
+        } else if (clazz == NetworkRulesSystemVmCommand.class) {
+            return virtualroutingsupport
+                    .execute((NetworkRulesSystemVmCommand) cmd);
+        } else if (clazz == CheckSshCommand.class) {
+            return virtualroutingsupport.execute((CheckSshCommand) cmd);
+        } else if (clazz == NetworkUsageCommand.class) {
+            return virtualroutingsupport.execute((NetworkUsageCommand) cmd);
+        /* double check order! */
+        } else if (clazz == CopyCommand.class) {
+            return storageprocessor.execute((CopyCommand) cmd);
+        } else if (cmd instanceof StorageSubSystemCommand) {
+            return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd);
+        } else if (clazz == DeleteCommand.class) {
+            return storageprocessor.execute((DeleteCommand) cmd);
+        } else if (clazz == CreateCommand.class) {
+            return storageprocessor.execute((CreateCommand) cmd);
+        } else if (clazz == CreateObjectCommand.class) {
+            return storageprocessor.execute((CreateObjectCommand) cmd);
+        } else if (clazz == AttachIsoCommand.class) {
+            return storageprocessor.attachIso((AttachCommand) cmd);
+         } else if (clazz == DettachCommand.class) {
+            return storageprocessor.execute((DettachCommand) cmd);
+         } else if (clazz == AttachCommand.class) {
+            return storageprocessor.execute((AttachCommand) cmd);
+         } else if (clazz == CreatePrivateTemplateFromVolumeCommand.class) {
+             return storageprocessor
+                     .execute((CreatePrivateTemplateFromVolumeCommand) cmd);
+         } else if (clazz == DestroyCommand.class) {
+             return storageprocessor.execute((DestroyCommand) cmd);
+         } else if (clazz == CopyVolumeCommand.class) {
+             return storageprocessor.execute((CopyVolumeCommand) cmd);
+        } else if (clazz == CreateStoragePoolCommand.class) {
+            return storagepool.execute((CreateStoragePoolCommand) cmd);
+        } else if (clazz == ModifyStoragePoolCommand.class) {
+            return storagepool.execute((ModifyStoragePoolCommand) cmd);
+        } else if (clazz == PrimaryStorageDownloadCommand.class) {
+            return storagepool.execute((PrimaryStorageDownloadCommand) cmd);
+        } else if (clazz == DeleteStoragePoolCommand.class) {
+            return storagepool.execute((DeleteStoragePoolCommand) cmd);
+        } else if (clazz == GetStorageStatsCommand.class) {
+            return storagepool.execute((GetStorageStatsCommand) cmd);
+        } else if (clazz == GetHostStatsCommand.class) {
+            return hypervisorsupport.execute((GetHostStatsCommand) cmd);
+        } else if (clazz == CheckVirtualMachineCommand.class) {
+            return hypervisorsupport.execute((CheckVirtualMachineCommand) cmd);
+        } else if (clazz == MaintainCommand.class) {
+            return hypervisorsupport.execute((MaintainCommand) cmd);
+        } else if (clazz == CheckHealthCommand.class) {
+            return hypervisorsupport.execute((CheckHealthCommand) cmd);
+        } else if (clazz == ReadyCommand.class) {
+            return hypervisorsupport.execute((ReadyCommand) cmd);
+        } else if (clazz == FenceCommand.class) {
+            return hypervisorsupport.execute((FenceCommand) cmd);
+        } else if (clazz == CheckOnHostCommand.class) {
+            return hypervisorsupport.execute((CheckOnHostCommand)cmd);
+        } else if (clazz == PingTestCommand.class) {
+            return hypervisornetwork.execute((PingTestCommand) cmd);
+        } else if (clazz == CheckNetworkCommand.class) {
+            return hypervisornetwork.execute((CheckNetworkCommand) cmd);
+        } else if (clazz == GetVmStatsCommand.class) {
+            return vmsupport.execute((GetVmStatsCommand) cmd);
+        } else if (clazz == PrepareForMigrationCommand.class) {
+            return vmsupport.execute((PrepareForMigrationCommand) cmd);
+        } else if (clazz == MigrateCommand.class) {
+            return vmsupport.execute((MigrateCommand) cmd);
+        } else if (clazz == GetVncPortCommand.class) {
+            return vmsupport.execute((GetVncPortCommand) cmd);
+        } else if (clazz == PlugNicCommand.class) {
+            return vmsupport.execute((PlugNicCommand) cmd);
+        } else if (clazz == UnPlugNicCommand.class) {
+            return vmsupport.execute((UnPlugNicCommand) cmd);
+        } else if (clazz == StartCommand.class) {
+            return execute((StartCommand) cmd);
+        } else if (clazz == StopCommand.class) {
+            return execute((StopCommand) cmd);
+        } else if (clazz == RebootCommand.class) {
+            return execute((RebootCommand) cmd);
+        }
+        LOGGER.debug("Can't find class for executeRequest " + cmd.getClass() +", is your direct call missing?");
+        return Answer.createUnsupportedCommandAnswer(cmd);
+    }
+
+    @Override
+    public void disconnected() {
+        LOGGER.debug("disconnected seems unused everywhere else");
+    }
+
+    @Override
+    public IAgentControl getAgentControl() {
+        LOGGER.debug("we don't use IAgentControl");
+        return null;
+    }
+
+    @Override
+    public void setAgentControl(IAgentControl agentControl) {
+        LOGGER.debug("No use in setting IAgentControl");
+    }
+
+    @Override
+    public String getName() {
+        return configuration.getAgentName();
+    }
+
+    @Override
+    public void setName(String name) {
+        configuration.setAgentName(name);
+    }
+
+    @Override
+    public void setConfigParams(Map<String, Object> params) {
+        configuration.setRawParams(params);
+    }
+
+    @Override
+    public Map<String, Object> getConfigParams() {
+        return configuration.getRawParams();
+    }
+
+    @Override
+    public int getRunLevel() {
+        return 0;
+    }
+
+    @Override
+    public void setRunLevel(int level) {
+        LOGGER.debug("runlevel seems unused in other hypervisors");
+    }
+
+    /**
+     * Base configuration of the plugins components.
+     */
+    @Override
+    public boolean configure(String name, Map<String, Object> params)
+            throws ConfigurationException {
+        LOGGER.debug("configure " + name + " with params: " + params);
+        /* check if we're master or not and if we can connect */
+        try {
+            configuration = new Ovm3Configuration(params);
+            if (!configuration.getIsTest()) {
+                c = new Connection(configuration.getAgentIp(),
+                        configuration.getAgentOvsAgentPort(),
+                        configuration.getAgentOvsAgentUser(),
+                        configuration.getAgentOvsAgentPassword());
+                c.setHostName(configuration.getAgentHostname());
+            }
+            hypervisorsupport = new Ovm3HypervisorSupport(c, configuration);
+            if (!configuration.getIsTest()) {
+                hypervisorsupport.setupServer(configuration
+                        .getAgentSshKeyFileName());
+            }
+            hypervisorsupport.masterCheck();
+        } catch (Exception e) {
+            throw new CloudRuntimeException("Base checks failed for "
+                    + configuration.getAgentHostname(), e);
+        }
+        hypervisornetwork = new Ovm3HypervisorNetwork(c, configuration);
+        hypervisornetwork.configureNetworking();
+        virtualroutingresource = new Ovm3VirtualRoutingResource(c);
+        storagepool = new Ovm3StoragePool(c, configuration);
+        storagepool.prepareForPool();
+        storageprocessor = new Ovm3StorageProcessor(c, configuration,
+                storagepool);
+        vmsupport = new Ovm3VmSupport(c, configuration, hypervisorsupport,
+                storageprocessor, storagepool, hypervisornetwork);
+        vrResource = new VirtualRoutingResource(virtualroutingresource);
+        if (!vrResource.configure(name, params)) {
+            throw new ConfigurationException(
+                    "Unable to configure VirtualRoutingResource");
+        }
+        guesttypes = new Ovm3VmGuestTypes();
+        storageHandler = new StorageSubsystemCommandHandlerBase(storageprocessor);
+        virtualroutingsupport = new Ovm3VirtualRoutingSupport(c, configuration,
+                virtualroutingresource);
+        this.setConfigParams(params);
+        return true;
+    }
+
+    public void setConnection(Connection con) {
+        LOGGER.debug("override connection: " + con.getIp());
+        c = con;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+    @Override
+    public synchronized StartAnswer execute(StartCommand cmd) {
+        VirtualMachineTO vmSpec = cmd.getVirtualMachine();
+        String vmName = vmSpec.getName();
+        State state = State.Stopped;
+        Xen xen = new Xen(c);
+
+        try {
+            hypervisorsupport.setVmStateStarting(vmName);
+            Xen.Vm vm = xen.getVmConfig();
+            /* max and min ? */
+            vm.setVmCpus(vmSpec.getCpus());
+            /* in mb not in bytes */
+            vm.setVmMemory(vmSpec.getMinRam() / 1024 / 1024);
+            vm.setVmUuid(UUID.nameUUIDFromBytes(vmSpec.getName().getBytes())
+                    .toString());
+            vm.setVmName(vmName);
+
+            String domType = guesttypes.getOvm3GuestType(vmSpec.getOs());
+            if (domType == null || domType.isEmpty()) {
+                domType = "default";
+                LOGGER.debug("VM Virt type missing setting to: " + domType);
+            } else {
+                LOGGER.debug("VM Virt type set to " + domType + " for "
+                        + vmSpec.getOs());
+            }
+            vm.setVmDomainType(domType);
+
+            if (vmSpec.getBootloader() == BootloaderType.CD) {
+                LOGGER.warn("CD booting is not supported");
+            }
+            /*
+             * officially CD boot is only supported on HVM, although there is a
+             * simple way around it..
+             */
+            vmsupport.createVbds(vm, vmSpec);
+
+            if (vmSpec.getType() != VirtualMachine.Type.User) {
+                // double check control network if we run a non user VM
+                hypervisornetwork.configureNetworking();
+                vm.setVmExtra(vmSpec.getBootArgs().replace(" ", "%"));
+                String svmPath = configuration.getAgentOvmRepoPath() + "/"
+                        + ovmObject.deDash(vm.getPrimaryPoolUuid()) + "/ISOs";
+                String svmIso = svmPath + "/"
+                        + storagepool.getSystemVMPatchIsoFile().getName();
+                vm.addIso(svmIso);
+            }
+            /* OVS/Network stuff should go here! */
+            vmsupport.createVifs(vm, vmSpec);
+            vm.setupVifs();
+
+            vm.setVnc("0.0.0.0", vmSpec.getVncPassword());
+            xen.createVm(ovmObject.deDash(vm.getPrimaryPoolUuid()),
+                    vm.getVmUuid());
+            xen.startVm(ovmObject.deDash(vm.getPrimaryPoolUuid()),
+                    vm.getVmUuid());
+            state = State.Running;
+
+            if (vmSpec.getType() != VirtualMachine.Type.User) {
+                String controlIp = null;
+                for (NicTO nic : vmSpec.getNics()) {
+                    if (nic.getType() == TrafficType.Control) {
+                        controlIp = nic.getIp();
+                    }
+                }
+                /* fix is in cloudstack.py for xend restart timer */
+                for (int count = 0; count < 60; count++) {
+                    CloudstackPlugin cSp = new CloudstackPlugin(c);
+                    /* skip a beat to make sure we didn't miss start */
+                    if (hypervisorsupport.getVmState(vmName) == null && count > 1) {
+                        String msg = "VM " + vmName + " went missing on "
+                                + configuration.getAgentHostname()
+                                + ", returning stopped";
+                        LOGGER.debug(msg);
+                        state = State.Stopped;
+                        return new StartAnswer(cmd, msg);
+                    }
+                    /* creative fix? */
+                    try {
+                        Boolean res = cSp.domrCheckSsh(controlIp);
+                        LOGGER.debug("connected to " + controlIp
+                                + " on attempt " + count + " result: " + res);
+                        if (res) {
+                            break;
+                        }
+                    } catch (Exception x) {
+                        LOGGER.trace(
+                                "unable to connect to " + controlIp
+                                        + " on attempt " + count + " "
+                                        + x.getMessage(), x);
+                    }
+                    Thread.sleep(5000);
+                }
+            }
+            /*
+             * Can't remember if HA worked if we were only a pool ?
+             */
+            if (configuration.getAgentInOvm3Pool()
+                    && configuration.getAgentInOvm3Cluster()) {
+                xen.configureVmHa(ovmObject.deDash(vm.getPrimaryPoolUuid()),
+                        vm.getVmUuid(), true);
+            }
+            /* should be starting no ? */
+            state = State.Running;
+            return new StartAnswer(cmd);
+        } catch (Exception e) {
+            LOGGER.debug("Start vm " + vmName + " failed", e);
+            state = State.Stopped;
+            return new StartAnswer(cmd, e.getMessage());
+        } finally {
+            hypervisorsupport.setVmState(vmName, state);
+        }
+    }
+
+    /**
+     * Removes the vm and its configuration from the hypervisor.
+     */
+    @Override
+    public StopAnswer execute(StopCommand cmd) {
+        String vmName = cmd.getVmName();
+        State state = State.Error;
+        hypervisorsupport.setVmState(vmName, State.Stopping);
+
+        try {
+            Xen vms = new Xen(c);
+            Xen.Vm vm = null;
+            vm = vms.getRunningVmConfig(vmName);
+
+            if (vm == null) {
+                state = State.Stopping;
+                LOGGER.debug("Unable to get details of vm: " + vmName
+                        + ", treating it as Stopping");
+                return new StopAnswer(cmd, "success", true);
+            }
+            String repoId = ovmObject.deDash(vm.getVmRootDiskPoolId());
+            String vmId = vm.getVmUuid();
+            /* can we do without the poolId ? */
+            vms.stopVm(repoId, vmId);
+            int tries = 30;
+            while (vms.getRunningVmConfig(vmName) != null && tries > 0) {
+                String msg = "Waiting for " + vmName + " to stop";
+                LOGGER.debug(msg);
+                tries--;
+                Thread.sleep(10 * 1000);
+            }
+            vms.deleteVm(repoId, vmId);
+            vmsupport.cleanup(vm);
+
+            if (vms.getRunningVmConfig(vmName) != null) {
+                String msg = "Stop " + vmName + " failed ";
+                LOGGER.debug(msg);
+                return new StopAnswer(cmd, msg, false);
+            }
+            state = State.Stopped;
+            return new StopAnswer(cmd, "success", true);
+        } catch (Exception e) {
+            LOGGER.debug("Stop " + vmName + " failed ", e);
+            return new StopAnswer(cmd, e.getMessage(), false);
+        } finally {
+            if (state != null) {
+                hypervisorsupport.setVmState(vmName, state);
+            } else {
+                hypervisorsupport.revmoveVmState(vmName);
+            }
+        }
+    }
+
+    @Override
+    public RebootAnswer execute(RebootCommand cmd) {
+        String vmName = cmd.getVmName();
+        hypervisorsupport.setVmStateStarting(vmName);
+        try {
+            Xen xen = new Xen(c);
+            Xen.Vm vm = xen.getRunningVmConfig(vmName);
+            if (vm == null) {
+                return new RebootAnswer(cmd, vmName + " not present", false);
+            }
+            xen.rebootVm(ovmObject.deDash(vm.getVmRootDiskPoolId()),
+                    vm.getVmUuid());
+            vm = xen.getRunningVmConfig(vmName);
+            Integer vncPort = vm.getVncPort();
+            return new RebootAnswer(cmd, null, vncPort);
+        } catch (Exception e) {
+            LOGGER.debug("Reboot " + vmName + " failed", e);
+            return new RebootAnswer(cmd, e.getMessage(), false);
+        } finally {
+            hypervisorsupport.setVmState(vmName, State.Running);
+        }
+    }
+
+    @Override
+    protected String getDefaultScriptsDir() {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java
new file mode 100644
index 0000000..b1a92bb
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3StorageProcessor.java
@@ -0,0 +1,835 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.UUID;
+
+import org.apache.cloudstack.storage.command.AttachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.DettachCommand;
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer;
+import org.apache.cloudstack.storage.command.SnapshotAndCopyCommand;
+import org.apache.cloudstack.storage.to.SnapshotObjectTO;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
+import com.cloud.agent.api.storage.CopyVolumeAnswer;
+import com.cloud.agent.api.storage.CopyVolumeCommand;
+import com.cloud.agent.api.storage.CreateAnswer;
+import com.cloud.agent.api.storage.CreateCommand;
+import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
+import com.cloud.agent.api.storage.DestroyCommand;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.agent.api.to.DataStoreTO;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.api.to.NfsTO;
+import com.cloud.agent.api.to.StorageFilerTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Linux;
+import com.cloud.hypervisor.ovm3.objects.Ovm3ResourceException;
+import com.cloud.hypervisor.ovm3.objects.OvmObject;
+import com.cloud.hypervisor.ovm3.objects.StoragePlugin;
+import com.cloud.hypervisor.ovm3.objects.Xen;
+import com.cloud.hypervisor.ovm3.objects.StoragePlugin.FileProperties;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3Configuration;
+import com.cloud.hypervisor.ovm3.resources.helpers.Ovm3StoragePool;
+import com.cloud.storage.Volume;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.resource.StorageProcessor;
+import com.cloud.vm.DiskProfile;
+
+/**
+ * Storage related bits
+ */
+public class Ovm3StorageProcessor implements StorageProcessor {
+    private final Logger LOGGER = Logger.getLogger(Ovm3StorageProcessor.class);
+    private Connection c;
+    private OvmObject ovmObject = new OvmObject();
+    private Ovm3StoragePool pool;
+    private Ovm3Configuration config;
+
+    public Ovm3StorageProcessor(Connection conn, Ovm3Configuration ovm3config,
+            Ovm3StoragePool ovm3pool) {
+        c = conn;
+        config = ovm3config;
+        pool = ovm3pool;
+    }
+
+    public final Answer execute(final CopyCommand cmd) {
+        LOGGER.debug("execute: "+ cmd.getClass());
+        DataTO srcData = cmd.getSrcTO();
+        DataStoreTO srcStore = srcData.getDataStore();
+        DataTO destData = cmd.getDestTO();
+        DataStoreTO destStore = destData.getDataStore();
+        String msg = "Not implemented yet";
+        try {
+            /* target and source are NFS and TEMPLATE */
+            if ((srcStore instanceof NfsTO)
+                    && (srcData.getObjectType() == DataObjectType.TEMPLATE)
+                    && (destData.getObjectType() == DataObjectType.TEMPLATE)) {
+                return copyTemplateToPrimaryStorage(cmd);
+                /* we assume the cache for templates is local */
+            } else if ((srcData.getObjectType() == DataObjectType.TEMPLATE)
+                    && (destData.getObjectType() == DataObjectType.VOLUME)) {
+                if (srcStore.getUrl().equals(destStore.getUrl())) {
+                    return cloneVolumeFromBaseTemplate(cmd);
+                } else {
+                    msg = "Primary to Primary doesn't match";
+                    LOGGER.debug(msg);
+                }
+            } else if ((srcData.getObjectType() == DataObjectType.SNAPSHOT)
+                    && (destData.getObjectType() == DataObjectType.SNAPSHOT)) {
+                return backupSnapshot(cmd);
+            } else if ((srcData.getObjectType() == DataObjectType.SNAPSHOT)
+                    && (destData.getObjectType() == DataObjectType.TEMPLATE)) {
+                return createTemplateFromSnapshot(cmd);
+            } else {
+                msg = "Unable to do stuff for " + srcStore.getClass() + ":"
+                        + srcData.getObjectType() + " to "
+                        + destStore.getClass() + ":" + destData.getObjectType();
+                LOGGER.debug(msg);
+            }
+        } catch (Exception e) {
+            msg = "Catch Exception " + e.getClass().getName()
+                    + " for template due to " + e.toString();
+            LOGGER.warn(msg, e);
+            return new CopyCmdAnswer(msg);
+        }
+        LOGGER.warn(msg + " " + cmd.getClass());
+        return new CopyCmdAnswer(msg);
+    }
+
+    public Answer execute(DeleteCommand cmd) {
+        DataTO data = cmd.getData();
+        String msg;
+        LOGGER.debug("Deleting object: " + data.getObjectType());
+        if (data.getObjectType() == DataObjectType.VOLUME) {
+            return deleteVolume(cmd);
+        } else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
+            return deleteSnapshot(cmd);
+        } else if (data.getObjectType() == DataObjectType.TEMPLATE) {
+            msg = "Template deletion is not implemented yet.";
+            LOGGER.info(msg);
+        } else {
+            msg = data.getObjectType() + " deletion is not implemented yet.";
+            LOGGER.info(msg);
+        }
+        return new Answer(cmd, false, msg);
+    }
+
+    public CreateAnswer execute(CreateCommand cmd) {
+        LOGGER.debug("execute: "+ cmd.getClass());
+        StorageFilerTO primaryStorage = cmd.getPool();
+        DiskProfile disk = cmd.getDiskCharacteristics();
+        /* disk should have a uuid */
+        // should also be replaced with getVirtualDiskPath ?
+        String fileName = UUID.randomUUID().toString() + ".raw";
+        String dst = primaryStorage.getPath() + File.separator
+                + primaryStorage.getUuid() + File.separator + fileName;
+        try {
+            StoragePlugin store = new StoragePlugin(c);
+            if (cmd.getTemplateUrl() != null) {
+                LOGGER.debug("CreateCommand " + cmd.getTemplateUrl() + " "
+                        + dst);
+                Linux host = new Linux(c);
+                host.copyFile(cmd.getTemplateUrl(), dst);
+            } else {
+                /* this is a dup with the createVolume ? */
+                LOGGER.debug("CreateCommand " + dst);
+                store.storagePluginCreate(primaryStorage.getUuid(),
+                        primaryStorage.getHost(), dst, disk.getSize(), false);
+            }
+            FileProperties fp = store.storagePluginGetFileInfo(
+                    primaryStorage.getUuid(), primaryStorage.getHost(), dst);
+            VolumeTO volume = new VolumeTO(cmd.getVolumeId(), disk.getType(),
+                    primaryStorage.getType(), primaryStorage.getUuid(),
+                    primaryStorage.getPath(), fileName, fp.getName(),
+                    fp.getSize(), null);
+            return new CreateAnswer(cmd, volume);
+        } catch (Exception e) {
+            LOGGER.debug("CreateCommand failed", e);
+            return new CreateAnswer(cmd, e.getMessage());
+        }
+    }
+
+    /**
+     * src is Nfs and Template from secondary storage to primary
+     */
+    @Override
+    public CopyCmdAnswer copyTemplateToPrimaryStorage(CopyCommand cmd) {
+        LOGGER.debug("execute copyTemplateToPrimaryStorage: "+ cmd.getClass());
+        DataTO srcData = cmd.getSrcTO();
+        DataStoreTO srcStore = srcData.getDataStore();
+        DataTO destData = cmd.getDestTO();
+        NfsTO srcImageStore = (NfsTO) srcStore;
+        TemplateObjectTO destTemplate = (TemplateObjectTO) destData;
+        try {
+            String secPoolUuid = pool.setupSecondaryStorage(srcImageStore.getUrl());
+            String primaryPoolUuid = destData.getDataStore().getUuid();
+            String destPath = config.getAgentOvmRepoPath() + File.separator
+                    + ovmObject.deDash(primaryPoolUuid) + File.separator
+                    + config.getTemplateDir();
+            String sourcePath = config.getAgentSecStoragePath()
+                    + File.separator + secPoolUuid;
+            Linux host = new Linux(c);
+            String destUuid = destTemplate.getUuid();
+            /*
+             * Would love to add dynamic formats (tolower), to also support
+             * VHD and QCOW2, although Ovm3.2 does not have tapdisk2 anymore
+             * so we can forget about that.
+             */
+            /* TODO: add checksumming */
+            String srcFile = sourcePath + File.separator
+                    + srcData.getPath();
+            if (srcData.getPath().endsWith(File.separator)) {
+                srcFile = sourcePath + File.separator + srcData.getPath()
+                        + File.separator + destUuid + ".raw";
+            }
+            String destFile = destPath + File.separator + destUuid + ".raw";
+            LOGGER.debug("CopyFrom: " + srcData.getObjectType() + ","
+                    + srcFile + " to " + destData.getObjectType() + ","
+                    + destFile);
+            host.copyFile(srcFile, destFile);
+            TemplateObjectTO newVol = new TemplateObjectTO();
+            newVol.setUuid(destUuid);
+            // was destfile
+            newVol.setPath(destUuid);
+            newVol.setFormat(ImageFormat.RAW);
+            return new CopyCmdAnswer(newVol);
+        } catch (Ovm3ResourceException e) {
+            String msg = "Error while copying template to primary storage: " + e.getMessage();
+            LOGGER.info(msg);
+            return new CopyCmdAnswer(msg);
+        }
+    }
+    /**
+     * Only copies in case of dest is NfsTO, xenserver also unmounts secstorage
+     */
+    @Override
+    public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) {
+        LOGGER.debug("execute copyVolumeFromPrimaryToSecondary: "+ cmd.getClass());
+        return new Answer(cmd);
+    }
+    /**
+     * dest is VolumeObject, src is a template
+     */
+    @Override
+    public CopyCmdAnswer cloneVolumeFromBaseTemplate(CopyCommand cmd) {
+        LOGGER.debug("execute cloneVolumeFromBaseTemplate: "+ cmd.getClass());
+        try {
+            // src
+            DataTO srcData = cmd.getSrcTO();
+            TemplateObjectTO src = (TemplateObjectTO) srcData;
+            String srcFile = getVirtualDiskPath(src.getUuid(), src.getDataStore().getUuid());
+            srcFile = srcFile.replace(config.getVirtualDiskDir(), config.getTemplateDir());
+
+            DataTO destData = cmd.getDestTO();
+            VolumeObjectTO dest = (VolumeObjectTO) destData;
+            String destFile = getVirtualDiskPath(dest.getUuid(), dest.getDataStore().getUuid());
+            Linux host = new Linux(c);
+            LOGGER.debug("CopyFrom: " + srcData.getObjectType() + ","
+                    + srcFile + " to " + destData.getObjectType() + ","
+                    + destFile);
+            host.copyFile(srcFile, destFile);
+            VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setUuid(dest.getUuid());
+            // was destfile
+            newVol.setPath(dest.getUuid());
+            newVol.setFormat(ImageFormat.RAW);
+            return new CopyCmdAnswer(newVol);
+        } catch (Ovm3ResourceException e) {
+            String msg = "Error cloneVolumeFromBaseTemplate: " + e.getMessage();
+            LOGGER.info(msg);
+            return new CopyCmdAnswer(msg);
+        }
+    }
+    /**
+     * createprivatetemplate, also needs template.properties
+     */
+    @Override
+    public Answer createTemplateFromVolume(CopyCommand cmd) {
+        LOGGER.debug("execute createTemplateFromVolume: "+ cmd.getClass());
+        return new Answer(cmd);
+    }
+    /**
+     * Volume to Volume from NfsTO
+     */
+    @Override
+    public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) {
+        LOGGER.debug("execute copyVolumeFromImageCacheToPrimary: "+ cmd.getClass());
+        return new Answer(cmd);
+    }
+    /**
+     * Copies from secondary to secondary
+     */
+    @Override
+    public Answer createTemplateFromSnapshot(CopyCommand cmd) {
+        LOGGER.debug("execute createTemplateFromSnapshot: "+ cmd.getClass());
+        try {
+            // src.getPath contains the uuid of the snapshot.
+            DataTO srcData = cmd.getSrcTO();
+            SnapshotObjectTO srcSnap = (SnapshotObjectTO) srcData;
+            String secPoolUuid = pool.setupSecondaryStorage(srcData.getDataStore().getUrl());
+            String srcFile = config.getAgentSecStoragePath()
+                    + File.separator + secPoolUuid + File.separator
+                    + srcSnap.getPath();
+            // dest
+            DataTO destData = cmd.getDestTO();
+            TemplateObjectTO destTemplate = (TemplateObjectTO) destData;
+            String secPoolUuidTemplate = pool.setupSecondaryStorage(destData.getDataStore().getUrl());
+            String destDir = config.getAgentSecStoragePath()
+                    + File.separator + secPoolUuidTemplate + File.separator
+                    + destTemplate.getPath();
+            String destFile = destDir + File.separator
+                    + destTemplate.getUuid() + ".raw";
+            CloudstackPlugin csp = new CloudstackPlugin(c);
+            csp.ovsMkdirs(destDir);
+
+            Linux host = new Linux(c);
+            host.copyFile(srcFile, destFile);
+            TemplateObjectTO newVol = new TemplateObjectTO();
+            newVol.setUuid(destTemplate.getUuid());
+            newVol.setPath(destTemplate.getUuid());
+            newVol.setFormat(ImageFormat.RAW);
+            return new CopyCmdAnswer(newVol);
+        } catch (Ovm3ResourceException e) {
+            String msg = "Error backupSnapshot: " + e.getMessage();
+            LOGGER.info(msg);
+            return new CopyCmdAnswer(msg);
+        }
+    }
+
+    /**
+     * use the cache, or the normal nfs, also delete the leftovers for us
+     * also contains object store storage in xenserver.
+     */
+    @Override
+    public CopyCmdAnswer backupSnapshot(CopyCommand cmd) {
+        LOGGER.debug("execute backupSnapshot: "+ cmd.getClass());
+        try {
+            DataTO srcData = cmd.getSrcTO();
+            DataTO destData = cmd.getDestTO();
+            SnapshotObjectTO src = (SnapshotObjectTO) srcData;
+            SnapshotObjectTO dest = (SnapshotObjectTO) destData;
+
+            // src.getPath contains the uuid of the snapshot.
+            String srcFile = getVirtualDiskPath(src.getPath(), src.getDataStore().getUuid());
+
+            // destination
+            String storeUrl = dest.getDataStore().getUrl();
+            String secPoolUuid = pool.setupSecondaryStorage(storeUrl);
+            String destDir = config.getAgentSecStoragePath()
+                    + File.separator + secPoolUuid + File.separator
+                    + dest.getPath();
+            String destFile =  destDir + File.separator + src.getPath();
+            destFile = destFile.concat(".raw");
+            // copy
+            Linux host = new Linux(c);
+            CloudstackPlugin csp = new CloudstackPlugin(c);
+            csp.ovsMkdirs(destDir);
+            LOGGER.debug("CopyFrom: " + srcData.getObjectType() + ","
+                    + srcFile + " to " + destData.getObjectType() + ","
+                    + destFile);
+            host.copyFile(srcFile, destFile);
+            StoragePlugin sp = new StoragePlugin(c);
+            sp.storagePluginDestroy(secPoolUuid, srcFile);
+
+            SnapshotObjectTO newSnap = new SnapshotObjectTO();
+            // newSnap.setPath(destFile);
+            // damnit frickin crap, no reference whatsoever... could use parent ?
+            newSnap.setPath(dest.getPath() + File.separator + src.getPath() + ".raw");
+            newSnap.setParentSnapshotPath(null);
+            return new CopyCmdAnswer(newSnap);
+        } catch (Ovm3ResourceException e) {
+            String msg = "Error backupSnapshot: " + e.getMessage();
+            LOGGER.info(msg);
+            return new CopyCmdAnswer(msg);
+        }
+    }
+
+    public Answer execute(CreateObjectCommand cmd) {
+        LOGGER.debug("execute: "+ cmd.getClass());
+        DataTO data = cmd.getData();
+        if (data.getObjectType() == DataObjectType.VOLUME) {
+            return createVolume(cmd);
+        } else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
+            return createSnapshot(cmd);
+        } else if (data.getObjectType() == DataObjectType.TEMPLATE) {
+            LOGGER.debug("Template object creation not supported.");
+        }
+        return new CreateObjectAnswer(data.getObjectType()
+                + " object creation not supported");
+    }
+    /**
+     * Attach an iso
+     */
+    @Override
+    public AttachAnswer attachIso(AttachCommand cmd) {
+        LOGGER.debug("execute attachIso: "+ cmd.getClass());
+        String vmName = cmd.getVmName();
+        DiskTO disk = cmd.getDisk();
+        return attachDetach(cmd, vmName, disk, true);
+    }
+    /**
+     * Detach an iso
+     */
+    @Override
+    public AttachAnswer dettachIso(DettachCommand cmd) {
+        LOGGER.debug("execute dettachIso: "+ cmd.getClass());
+        String vmName = cmd.getVmName();
+        DiskTO disk = cmd.getDisk();
+        return attachDetach(cmd, vmName, disk, false);
+    }
+
+    /**
+     * Iso specific path return.
+     * @param disk
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    private String getIsoPath(DiskTO disk) throws Ovm3ResourceException {
+        TemplateObjectTO isoTO = (TemplateObjectTO) disk.getData();
+        DataStoreTO store = isoTO.getDataStore();
+        NfsTO nfsStore = (NfsTO) store;
+        String secPoolUuid = pool.setupSecondaryStorage(nfsStore.getUrl());
+        return config.getAgentSecStoragePath() + File.separator
+                + secPoolUuid + File.separator + isoTO.getPath();
+    }
+
+    /**
+     * Returns the disk path
+     * @param diskUuid
+     * @return
+     * @throws Ovm3ResourceException
+     */
+    public String getVirtualDiskPath(String diskUuid, String storeUuid) throws Ovm3ResourceException {
+        String d = config.getAgentOvmRepoPath() +
+                File.separator +
+                ovmObject.deDash(storeUuid) +
+                File.separator +
+                config.getVirtualDiskDir() +
+                File.separator +
+                diskUuid;
+        if (!d.endsWith(".raw")) {
+            d = d.concat(".raw");
+        }
+        return d;
+    }
+    public String getVirtualDiskPath(DiskTO disk, String storeUuid) throws Ovm3ResourceException {
+        return getVirtualDiskPath(disk.getPath(), storeUuid);
+    }
+
+    /**
+     * Generic disk attach/detach.
+     * @param cmd
+     * @param vmName
+     * @param disk
+     * @param isAttach
+     * @return
+     */
+    private AttachAnswer attachDetach(Command cmd, String vmName, DiskTO disk,
+            boolean isAttach) {
+        Xen xen = new Xen(c);
+        String doThis = (isAttach) ? "Attach" : "Dettach";
+        LOGGER.debug(doThis + " volume type " + disk.getType() + "  " + vmName);
+        String msg = "";
+        String path = "";
+        try {
+            Xen.Vm vm = xen.getVmConfig(vmName);
+            /* check running */
+            if (vm == null) {
+                msg = doThis + " can't find VM " + vmName;
+                LOGGER.debug(msg);
+                return new AttachAnswer(msg);
+            }
+            if (disk.getType() == Volume.Type.ISO) {
+                path = getIsoPath(disk);
+            } else if (disk.getType() == Volume.Type.DATADISK) {
+                path = getVirtualDiskPath(disk, vm.getPrimaryPoolUuid());
+            }
+            if ("".equals(path)) {
+                msg = doThis + " can't do anything with an empty path.";
+                LOGGER.debug(msg);
+                return new AttachAnswer(msg);
+            }
+            if (isAttach) {
+                if (disk.getType() == Volume.Type.ISO) {
+                    vm.addIso(path);
+                } else {
+                    vm.addDataDisk(path);
+                }
+            } else {
+                if (!vm.removeDisk(path)) {
+                    msg = doThis + " failed for " + vmName + disk.getType()
+                            + "  was not attached " + path;
+                    LOGGER.debug(msg);
+                    return new AttachAnswer(msg);
+                }
+            }
+            xen.configureVm(ovmObject.deDash(vm.getPrimaryPoolUuid()),
+                    vm.getVmUuid());
+            return new AttachAnswer(disk);
+        } catch (Ovm3ResourceException e) {
+            msg = doThis + " failed for " + vmName + " " + e.getMessage();
+            LOGGER.warn(msg, e);
+            return new AttachAnswer(msg);
+        }
+    }
+    /**
+     * Attach a volume
+     */
+    @Override
+    public AttachAnswer attachVolume(AttachCommand cmd) {
+        LOGGER.debug("execute attachVolume: "+ cmd.getClass());
+        String vmName = cmd.getVmName();
+        DiskTO disk = cmd.getDisk();
+        return attachDetach(cmd, vmName, disk, true);
+    }
+    /**
+     * Detach a volume
+     */
+    @Override
+    public AttachAnswer dettachVolume(DettachCommand cmd) {
+        LOGGER.debug("execute dettachVolume: "+ cmd.getClass());
+        String vmName = cmd.getVmName();
+        DiskTO disk = cmd.getDisk();
+        return attachDetach(cmd, vmName, disk, false);
+    }
+
+    /**
+     * Creates a volume, just a normal empty volume.
+     */
+    @Override
+    public Answer createVolume(CreateObjectCommand cmd) {
+        LOGGER.debug("execute createVolume: "+ cmd.getClass());
+        DataTO data = cmd.getData();
+        VolumeObjectTO volume = (VolumeObjectTO) data;
+        try {
+            /*
+             * public Boolean storagePluginCreate(String uuid, String ssuuid,
+             * String host, String file, Integer size)
+             */
+            String poolUuid = data.getDataStore().getUuid();
+            String storeUrl = data.getDataStore().getUrl();
+            URI uri = new URI(storeUrl);
+            String host = uri.getHost();
+            String file = getVirtualDiskPath(volume.getUuid(), poolUuid);
+            Long size = volume.getSize();
+            StoragePlugin sp = new StoragePlugin(c);
+            FileProperties fp = sp.storagePluginCreate(poolUuid, host, file,
+                    size, false);
+            if (!fp.getName().equals(file)) {
+                return new CreateObjectAnswer("Filename mismatch: "
+                        + fp.getName() + " != " + file);
+            }
+            VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setName(volume.getName());
+            newVol.setSize(fp.getSize());
+            newVol.setPath(volume.getUuid());
+            return new CreateObjectAnswer(newVol);
+        } catch (Ovm3ResourceException | URISyntaxException e) {
+            LOGGER.info("Volume creation failed: " + e.toString(), e);
+            return new CreateObjectAnswer(e.toString());
+        }
+    }
+
+    /**
+     * Creates a snapshot from a volume, but only if the VM is stopped.
+     * This due qemu not being able to snap raw volumes.
+     *
+     * if stopped yes, if running ... no, unless we have ocfs2 when
+     * using raw partitions (file:) if using tap:aio we cloud...
+     * The "ancient" way:
+     * We do however follow the "two stage" approach, of "snap"
+     * on primary first, with the create object... and then
+     * backup the snapshot with the copycmd....
+     * (should transfer to createSnapshot, backupSnapshot)
+     */
+    @Override
+    public Answer createSnapshot(CreateObjectCommand cmd) {
+        LOGGER.debug("execute createSnapshot: "+ cmd.getClass());
+        DataTO data = cmd.getData();
+        Xen xen = new Xen(c);
+        SnapshotObjectTO snap = (SnapshotObjectTO) data;
+        VolumeObjectTO vol = snap.getVolume();
+        try {
+            Xen.Vm vm = xen.getVmConfig(snap.getVmName());
+            if (vm != null) {
+                return new CreateObjectAnswer(
+                        "Snapshot object creation not supported for running VMs."
+                                + snap.getVmName());
+            }
+            Linux host = new Linux(c);
+            String uuid = host.newUuid();
+            /* for root volumes this works... */
+            String src = vol.getPath() + File.separator + vol.getUuid()
+                    + ".raw";
+            String dest = vol.getPath() + File.separator + uuid + ".raw";
+            /* seems that sometimes the path is already contains a file
+             * in case, we just replace it.... (Seems to happen if not ROOT)
+             */
+            if (vol.getPath().contains(vol.getUuid())) {
+                src = getVirtualDiskPath(vol.getUuid(),data.getDataStore().getUuid());
+                dest = src.replace(vol.getUuid(), uuid);
+            }
+            LOGGER.debug("Snapshot " + src + " to " + dest);
+            host.copyFile(src, dest);
+            SnapshotObjectTO nsnap = new SnapshotObjectTO();
+            // nsnap.setPath(dest);
+            // move to something that looks the same as xenserver.
+            nsnap.setPath(uuid);
+            return new CreateObjectAnswer(nsnap);
+        } catch (Ovm3ResourceException e) {
+            return new CreateObjectAnswer(
+                    "Snapshot object creation failed. " + e.getMessage());
+        }
+    }
+
+    @Override
+    public Answer deleteVolume(DeleteCommand cmd) {
+        LOGGER.debug("execute deleteVolume: "+ cmd.getClass());
+        DataTO data = cmd.getData();
+        VolumeObjectTO volume = (VolumeObjectTO) data;
+        try {
+            String poolUuid = data.getDataStore().getUuid();
+            String uuid = volume.getUuid();
+            String path = getVirtualDiskPath(uuid, poolUuid);
+            StoragePlugin sp = new StoragePlugin(c);
+            sp.storagePluginDestroy(poolUuid, path);
+            LOGGER.debug("Volume deletion success: " + path);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.info("Volume deletion failed: " + e.toString(), e);
+            return new CreateObjectAnswer(e.toString());
+        }
+        return new Answer(cmd);
+    }
+
+    /*
+     * CopyVolumeCommand gets the storage_pool should use that for
+     * bumper bowling.
+     */
+    public CopyVolumeAnswer execute(CopyVolumeCommand cmd) {
+        LOGGER.debug("execute: "+ cmd.getClass());
+        String volumePath = cmd.getVolumePath();
+        /* is a repository */
+        String secondaryStorageURL = cmd.getSecondaryStorageURL();
+        int wait = cmd.getWait();
+        if (wait == 0) {
+            wait = 7200;
+        }
+
+        try {
+            Linux host = new Linux(c);
+
+            /* to secondary storage */
+            if (cmd.toSecondaryStorage()) {
+                LOGGER.debug("Copy to  secondary storage " + volumePath
+                        + " to " + secondaryStorageURL);
+                host.copyFile(volumePath, secondaryStorageURL);
+                /* from secondary storage */
+            } else {
+                LOGGER.debug("Copy from secondary storage "
+                        + secondaryStorageURL + " to " + volumePath);
+                host.copyFile(secondaryStorageURL, volumePath);
+            }
+            /* check the truth of this */
+            return new CopyVolumeAnswer(cmd, true, null, null, null);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug("Copy volume failed", e);
+            return new CopyVolumeAnswer(cmd, false, e.getMessage(), null, null);
+        }
+    }
+
+    /* Destroy a volume (image) */
+    public Answer execute(DestroyCommand cmd) {
+        LOGGER.debug("execute: "+ cmd.getClass());
+        VolumeTO vol = cmd.getVolume();
+        String vmName = cmd.getVmName();
+        try {
+            StoragePlugin store = new StoragePlugin(c);
+            store.storagePluginDestroy(vol.getPoolUuid(), vol.getPath());
+            return new Answer(cmd, true, "Success");
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug("Destroy volume " + vol.getName() + " failed for "
+                    + vmName + " ", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    /* check if a VM is running should be added */
+    public CreatePrivateTemplateAnswer execute(
+            final CreatePrivateTemplateFromVolumeCommand cmd) {
+        LOGGER.debug("execute: "+ cmd.getClass());
+        String volumePath = cmd.getVolumePath();
+        Long accountId = cmd.getAccountId();
+        Long templateId = cmd.getTemplateId();
+        int wait = cmd.getWait();
+        if (wait == 0) {
+            /* Defaut timeout 2 hours */
+            wait = 7200;
+        }
+
+        try {
+            /* missing uuid */
+            String installPath = config.getAgentOvmRepoPath() + File.separator
+                    + config.getTemplateDir() + File.separator
+                    + accountId + File.separator + templateId;
+            Linux host = new Linux(c);
+            host.copyFile(volumePath, installPath);
+            return new CreatePrivateTemplateAnswer(cmd, true, installPath);
+        } catch (Exception e) {
+            LOGGER.debug("Create template failed", e);
+            return new CreatePrivateTemplateAnswer(cmd, false, e.getMessage());
+        }
+    }
+
+    /**
+     * SnapshotObjectTO secondary to VolumeObjectTO primary in xenserver,
+     */
+    @Override
+    public Answer createVolumeFromSnapshot(CopyCommand cmd) {
+        LOGGER.debug("execute createVolumeFromSnapshot: "+ cmd.getClass());
+        try {
+            DataTO srcData = cmd.getSrcTO();
+            DataStoreTO srcStore = srcData.getDataStore();
+            NfsTO srcImageStore = (NfsTO) srcStore;
+
+            // source, should contain snap dir/filename
+            SnapshotObjectTO srcSnap = (SnapshotObjectTO) srcData;
+            String secPoolUuid = pool.setupSecondaryStorage(srcImageStore.getUrl());
+            String srcFile = config.getAgentSecStoragePath()
+                    + File.separator + secPoolUuid + File.separator
+                    + srcSnap.getPath();
+
+            // dest
+            DataTO destData = cmd.getDestTO();
+            VolumeObjectTO destVol = (VolumeObjectTO) destData;
+            String primaryPoolUuid = destData.getDataStore().getUuid();
+            String destFile = getVirtualDiskPath(destVol.getUuid(), ovmObject.deDash(primaryPoolUuid));
+
+            Linux host = new Linux(c);
+            host.copyFile(srcFile, destFile);
+
+            VolumeObjectTO newVol = new VolumeObjectTO();
+            newVol.setUuid(destVol.getUuid());
+            // newVol.setPath(destFile);
+            newVol.setPath(destVol.getUuid());
+            newVol.setFormat(ImageFormat.RAW);
+            return new CopyCmdAnswer(newVol);
+            /* we assume the cache for templates is local */
+        } catch (Ovm3ResourceException e) {
+            LOGGER.debug("Failed to createVolumeFromSnapshot: ", e);
+            return new CopyCmdAnswer(e.toString());
+        }
+    }
+
+    /**
+     * Is not used in normal operation, the SSVM takes care of this.
+     */
+    @Override
+    public Answer deleteSnapshot(DeleteCommand cmd) {
+        LOGGER.debug("execute deleteSnapshot: "+ cmd.getClass());
+        DataTO data = cmd.getData();
+        SnapshotObjectTO snap = (SnapshotObjectTO) data;
+        String storeUrl = data.getDataStore().getUrl();
+        String snapUuid = snap.getPath();
+        try {
+            // snapshots/accountid/volumeid
+            String secPoolUuid = pool.setupSecondaryStorage(storeUrl);
+            String filePath = config.getAgentSecStoragePath()
+                    + File.separator + secPoolUuid + File.separator
+                    + snapUuid + ".raw";
+            StoragePlugin sp = new StoragePlugin(c);
+            sp.storagePluginDestroy(secPoolUuid, filePath);
+            LOGGER.debug("Snapshot deletion success: " + filePath);
+            return new Answer(cmd, true, "Deleted Snapshot " + filePath);
+        } catch (Ovm3ResourceException e) {
+            LOGGER.info("Snapshot deletion failed: " + e.toString(), e);
+            return new CreateObjectAnswer(e.toString());
+        }
+    }
+    /**
+     * SR scan in xenserver
+     */
+    @Override
+    public Answer introduceObject(IntroduceObjectCmd cmd) {
+        LOGGER.debug("execute introduceObject: "+ cmd.getClass());
+        return new Answer(cmd, false, "not implemented yet");
+    }
+    /**
+     * used as unmount for VDIs in xenserver
+     */
+    @Override
+    public Answer forgetObject(ForgetObjectCmd cmd) {
+        LOGGER.debug("execute forgetObject: "+ cmd.getClass());
+        return new Answer(cmd, false, "not implemented yet");
+    }
+
+    /**
+     * make sure both mounts are there, snapshot source image
+     * copy snap to dest image, remove source snap and unmount
+     * iSCSI?
+     */
+    @Override
+    public Answer snapshotAndCopy(SnapshotAndCopyCommand cmd) {
+        LOGGER.debug("execute snapshotAndCopy: "+ cmd.getClass());
+        return new SnapshotAndCopyAnswer("not implemented yet");
+    }
+
+    /**
+     * Attach disks
+     * @param cmd
+     * @return
+     */
+    public Answer execute(AttachCommand cmd) {
+        LOGGER.debug("execute: "+ cmd.getClass());
+        String vmName = cmd.getVmName();
+        DiskTO disk = cmd.getDisk();
+        return attachDetach(cmd, vmName, disk, true);
+    }
+
+    /**
+     * Detach disks, calls a middle man which calls attachDetach for volumes.
+     * @param cmd
+     * @return
+     */
+    public Answer execute(DettachCommand cmd) {
+        LOGGER.debug("execute: "+ cmd.getClass());
+        String vmName = cmd.getVmName();
+        DiskTO disk = cmd.getDisk();
+        return attachDetach(cmd, vmName, disk, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c27c6943/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResource.java b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResource.java
new file mode 100644
index 0000000..52409b1
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/main/java/com/cloud/hypervisor/ovm3/resources/Ovm3VirtualRoutingResource.java
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.resources;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.routing.IpAssocCommand;
+import com.cloud.agent.api.routing.IpAssocVpcCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+import com.cloud.agent.api.routing.SetSourceNatCommand;
+import com.cloud.agent.api.to.IpAddressTO;
+import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer;
+import com.cloud.hypervisor.ovm3.objects.CloudstackPlugin;
+import com.cloud.hypervisor.ovm3.objects.Connection;
+import com.cloud.hypervisor.ovm3.objects.Xen;
+import com.cloud.utils.ExecutionResult;
+
+@Local(value = VirtualRouterDeployer.class)
+public class Ovm3VirtualRoutingResource implements VirtualRouterDeployer {
+    private final Logger logger = Logger
+            .getLogger(Ovm3VirtualRoutingResource.class);
+    private String domRCloudPath = "/opt/cloud/bin/";
+    private int vrTimeout = 600;
+    private Connection c;
+    private String agentName;
+    public Ovm3VirtualRoutingResource() {
+    }
+    public Ovm3VirtualRoutingResource(Connection conn) {
+        c = conn;
+        agentName=c.getIp();
+    }
+    public void setConnection(Connection conn) {
+        c = conn;
+    }
+    @Override
+    public ExecutionResult executeInVR(String routerIp, String script,
+            String args) {
+        return executeInVR(routerIp, script, args, vrTimeout);
+    }
+
+    @Override
+    public ExecutionResult executeInVR(String routerIp, String script,
+            String args, int timeout) {
+        if (!script.contains(domRCloudPath)) {
+            script = domRCloudPath + "/" + script;
+        }
+        String cmd = script + " " + args;
+        logger.debug("executeInVR via " + agentName + " on " + routerIp + ": "
+                + cmd);
+        try {
+            CloudstackPlugin cSp = new CloudstackPlugin(c);
+            CloudstackPlugin.ReturnCode result;
+            result = cSp.domrExec(routerIp, cmd);
+            return new ExecutionResult(result.getRc(), result.getStdOut());
+        } catch (Exception e) {
+            logger.error("executeInVR FAILED via " + agentName + " on "
+                    + routerIp + ":" + cmd + ", " + e.getMessage(), e);
+        }
+        return new ExecutionResult(false, "");
+    }
+
+    @Override
+    public ExecutionResult createFileInVR(String routerIp, String path,
+            String filename, String content) {
+        String error = null;
+        logger.debug("createFileInVR via " + agentName + " on " + routerIp
+                + ": " + path + "/" + filename + ", content: " + content);
+        try {
+            CloudstackPlugin cSp = new CloudstackPlugin(c);
+            boolean result = cSp.ovsDomrUploadFile(routerIp, path, filename,
+                    content);
+            return new ExecutionResult(result, "");
+        } catch (Exception e) {
+            error = e.getMessage();
+            logger.warn(
+                    "createFileInVR failed for " + path + "/" + filename
+                            + " in VR " + routerIp + " via " + agentName + ": "
+                            + error, e);
+        }
+        return new ExecutionResult(error == null, error);
+    }
+
+    @Override
+    public ExecutionResult prepareCommand(NetworkElementCommand cmd) {
+        // Update IP used to access router
+        cmd.setRouterAccessIp(cmd
+                .getAccessDetail(NetworkElementCommand.ROUTER_IP));
+        assert cmd.getRouterAccessIp() != null;
+
+        if (cmd instanceof IpAssocVpcCommand) {
+            return prepareNetworkElementCommand((IpAssocVpcCommand) cmd);
+        } else if (cmd instanceof IpAssocCommand) {
+            return prepareNetworkElementCommand((IpAssocCommand) cmd);
+        } else if (cmd instanceof SetupGuestNetworkCommand) {
+            return prepareNetworkElementCommand((SetupGuestNetworkCommand) cmd);
+        } else if (cmd instanceof SetSourceNatCommand) {
+            return prepareNetworkElementCommand((SetSourceNatCommand) cmd);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    @Override
+    public ExecutionResult cleanupCommand(NetworkElementCommand cmd) {
+        if (cmd instanceof IpAssocCommand
+                && !(cmd instanceof IpAssocVpcCommand)) {
+            return cleanupNetworkElementCommand((IpAssocCommand) cmd);
+        }
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult cleanupNetworkElementCommand(IpAssocCommand cmd) {
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(
+            SetupGuestNetworkCommand cmd) {
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) {
+        return prepNetBoth(cmd
+                .getAccessDetail(NetworkElementCommand.ROUTER_NAME),
+                cmd.getIpAddresses(), "IpAssocVpcCommand");
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) {
+        return new ExecutionResult(true, null);
+    }
+
+    private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) {
+        return prepNetBoth(cmd
+                .getAccessDetail(NetworkElementCommand.ROUTER_NAME),
+                cmd.getIpAddresses(), "IpAssocCommand");
+    }
+
+    private ExecutionResult prepNetBoth(String routerName, IpAddressTO[] ips, String type) {
+        Xen xen = new Xen(c);
+        try {
+            Xen.Vm vm = xen.getVmConfig(routerName);
+            for (IpAddressTO ip : ips) {
+                Integer devId = vm.getVifIdByMac(ip.getVifMacAddress());
+                if (devId < 0 && "IpAssocVpcCommand".equals(type)) {
+                    String msg = "No valid Nic devId found for " + vm.getVmName()
+                            + " with " + ip.getVifMacAddress();
+                    logger.error(msg);
+                    return new ExecutionResult(false, msg);
+                } else if (devId < 0 && "IpAssocCommand".equals(type)) {
+                    // vm.get
+                    String msg = "No valid Nic devId found for " + vm.getVmName()
+                            + " with " + ip.getVifMacAddress() + " "
+                            + " Ignoring for now (routervm)";
+                    logger.debug(msg);
+                    devId=2;
+                }
+                ip.setNicDevId(devId);
+            }
+        } catch (Exception e) {
+            String msg = type + " failure on applying one ip due to exception:  " + e;
+            logger.error(msg);
+            return new ExecutionResult(false, msg);
+        }
+        return new ExecutionResult(true, null);
+    }
+}