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 <[email protected]> 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 <[email protected]> Authored: Wed Mar 11 18:06:18 2015 +0100 Committer: Rohit Yadav <[email protected]> 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; + } +}
