You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by se...@apache.org on 2014/06/20 15:27:37 UTC
[1/7] CLOUDSTACK-6967: Now with module!
Repository: cloudstack
Updated Branches:
refs/heads/ovmsupport ed47763e2 -> 1516b041b
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Test.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Test.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Test.java
new file mode 100644
index 0000000..850daf8
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Test.java
@@ -0,0 +1,546 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+// import java.io.File;
+import java.math.BigInteger;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+
+import java.util.Map.Entry;
+
+// mport org.apache.commons.io.FileUtils;
+import org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.hypervisor.ovm3.object.Linux.FileSystem;
+
+public class Test {
+ // private static Sanitize _insane = new Sanitize();
+ /*
+ * Other trinket
+ * https://192.168.1.51:7002/ovm/core/OVMManagerCoreServlet&c=1
+ * &s=-1&lb=p&t=2
+ * &p=1dd5e891d9d0edbd81c2a69ab3d1b7ea%2C2f3b7fca202045058ae388d22f21f508'
+ */
+ public static void main(final String[] args) throws Exception {
+ boolean CheckNet = false;
+ boolean CheckNtp = false;
+ boolean CheckLinux = false;
+ boolean CheckCommon = false;
+ boolean CheckCluster = false;
+ boolean CheckRepo = false;
+ boolean CheckPool = false;
+ boolean CheckOcfs2 = false;
+ boolean CheckNFSPlugin = false;
+ boolean CheckXen = false;
+ boolean CheckVnc = false;
+
+ boolean CheckCombine = false;
+ boolean CheckVmInfo = false;
+ boolean CheckUuid = false;
+ boolean CheckBridge = false;
+ boolean CheckFs = false;
+ boolean CheckPlugin = true;
+
+
+ try {
+ Connection c;
+ Socket client;
+ String hostname = "ovm-2";
+ try{
+ client = new Socket(hostname, 8899);
+ } catch (Exception e) {
+ hostname = "localhost";
+ client = new Socket(hostname, 8899);
+ }
+ if (!client.isConnected()) {
+ System.out.println("No connection");
+ } else {
+ System.out.println("connected to: " + hostname);
+ }
+ client.close();
+ try {
+ System.out.println("trying to connect to " + hostname);
+ c = new Connection(hostname, 8899, "oracle", "test123");
+ } catch (Exception e) {
+ throw new Exception("Unable to connect to " + hostname
+ + " port seemed to listen...");
+ }
+ /*
+ * needs to be finished and implement ovs + bridge, or do we count
+ * on chef ?
+ */
+ if (CheckPlugin) {
+ CloudStackPlugin csp = new CloudStackPlugin(c);
+ try {
+ System.out.println(csp.ovsUploadSshKey("test", "testing 123"));
+// FileUtils.readFileToString(new File(""))));
+ String ip = "169.254.1.202";
+ String domain = "i-2-29-VM";
+ String pubnic = "bond0";
+ // System.out.println(csp.ovsDom0Stats(pubnic));
+ // System.out.println(csp.domrCheckPort(ip, 3922, 3, 3));
+ // System.out.println(csp.domrCheckSsh(ip));
+ System.out.println("vnc Port: "+ csp.getVncPort(domain));
+ // System.out.println(csp.domrExec(ip, "ls -l").getStdOut());
+ Map<String, String> stats = csp.ovsDomUStats(domain);
+ /* for (final Entry<String, String> stat : stats.entrySet()) {
+ System.out.println(stat.getKey() + " "
+ + Double.parseDouble(stat.getValue()));
+ } */
+ Thread.sleep(1000);
+ Map<String, String> stats2 = csp.ovsDomUStats(domain);
+ for (final Entry<String, String> stat : stats2.entrySet()) {
+ String key = stat.getKey();
+ Double delta = Double.parseDouble(stat.getValue())
+ - Double.parseDouble(stats.get(key));
+ System.out.println(stat.getKey() + ": " + delta);
+ }
+ Integer cpus = Integer.parseInt(stats.get("vcpus"));
+ Double d_cpu = Double.parseDouble(stats.get("cputime"))
+ - Double.parseDouble(stats2.get("cputime"));
+ Double d_time = Double.parseDouble(stats.get("uptime"))
+ - Double.parseDouble(stats2.get("uptime"));
+ Double cpupct = d_cpu/d_time * 100 * cpus;
+ System.out.println(cpupct);
+ } catch (Exception e) {
+ System.out.println("nooooo!!!" + e.getMessage());
+ throw new Exception(e.getMessage());
+ }
+ }
+ if (CheckFs) {
+ Linux host = new Linux(c);
+
+ Map<String, Linux.FileSystem> fsList = host
+ .getFileSystemList("nfs");
+ Linux.FileSystem fs = fsList.get("nfs");
+ System.out.println(fs + " " + fsList);
+ }
+ if (CheckUuid) {
+ System.out.println(UUID.nameUUIDFromBytes(("test@test-test")
+ .getBytes()));
+ }
+ if (CheckNet) {
+ Network net = new Network(c);
+ System.out.println(net.getInterfaceByName("c0a80100"));
+ // net.discoverNetwork();
+ System.out
+ .println(net.getInterfaceByName("c0a80100").getAddress());
+ System.out.println(net.getInterfaceByIp("192.168.1.65").getName());
+ // System.out.println(bridge.getMac());
+ }
+ if (CheckCommon == true) {
+ Common Com = new Common(c);
+ String x = Com.getApiVersion();
+ System.out.println("Api Version: " + x);
+ String y = Com.sleep(1);
+ System.out.println("Sleep: " + y);
+ String msg = Com.echo("testing 1 2 3");
+ System.out.println("Echo: " + msg);
+ /*
+ * String disp = Com.dispatch ("192.168.1.60", "hoeleboele");
+ * System.out. println("dispatch" + disp);
+ */
+ }
+ /* check stuff */
+ if (CheckLinux == true) {
+ Linux Host = new Linux(c);
+ Host.discoverHardware();
+ Host.discoverServer();
+ System.out.println("hwVMM: " + Host.hwVMM.toString());
+ System.out.println("hwSystem: " + Host.hwSystem.toString());
+ System.out.println("Cap: " + Host.Capabilities.toString());
+ System.out.println("VMM: " + Host.VMM.toString());
+ System.out.println("NTP: " + Host.NTP.toString());
+ System.out.println("DT: " + Host.DateTime.toString());
+ System.out.println("Gen: " + Host.Generic.toString());
+ System.out.println("time; " + Host.getDateTime());
+ // needs to be within bounds of 1970... *grin*
+ System.out.println("update time to 1999: "
+ + Host.setDateTime(1999, 12, 31, 12, 0, 0));
+ System.out.println("lastboot: " + Host.getLastBootTime());
+ System.out.println("time: " + Host.localTime);
+ Calendar now = Calendar.getInstance();
+ int year = now.get(Calendar.YEAR);
+ int month = now.get(Calendar.MONTH); // Note: zero based!
+ int day = now.get(Calendar.DAY_OF_MONTH);
+ int hour = now.get(Calendar.HOUR_OF_DAY);
+ int minute = now.get(Calendar.MINUTE);
+ int second = now.get(Calendar.SECOND);
+ int millis = now.get(Calendar.MILLISECOND);
+ System.out.println("set time to now: "
+ + Host.setDateTime(year, month, day, hour, minute,
+ second));
+ System.out.println("lastboot: " + Host.getLastBootTime());
+ System.out.println("time: " + Host.localTime);
+ System.out.println("update password: "
+ + Host.updateAgentPassword("oracle", "test123"));
+ System.out.println("set time zone: "
+ + Host.setTimeZone("Europe/London", false));
+ System.out.println("time zone: " + Host.getTimeZone() + ", "
+ + Host.timeZone + ", " + Host.timeUTC);
+ System.out.println("set time zone: "
+ + Host.setTimeZone("Europe/Amsterdam", true));
+ System.out.println("time zone: " + Host.getTimeZone() + ", "
+ + Host.timeZone + ", " + Host.timeUTC);
+ // System.out.println("Luns: " + Host.discoverPhysicalLuns());
+
+ }
+
+ /* setting up ntp */
+ if (CheckNtp == true) {
+ Ntp ntp = new Ntp(c);
+ ntp.getDetails();
+ System.out.println("ntp isServer: " + ntp.isServer());
+ System.out.println("ntp isRunning: " + ntp.isRunning());
+ System.out.println("ntp Servers: " + ntp.servers());
+ ntp.addServer("192.168.1.1");
+ ntp.addServer("192.168.1.61");
+ System.out.println("ntp set: " + ntp.setNtp(true));
+ System.out.println("ntp enable: " + ntp.enableNtp());
+ ntp.getDetails();
+ System.out.println("ntp isServer: " + ntp.isServer());
+ System.out.println("ntp isRunning: " + ntp.isRunning());
+ System.out.println("ntp Servers: " + ntp.servers());
+ System.out.println("ntp disable: " + ntp.disableNtp());
+ System.out.println("ntp reset: " + ntp.setNtp("", false));
+ }
+
+ if (CheckNFSPlugin == true) {
+ Linux lin = new Linux(c);
+ lin.discoverServer();
+ System.out.println(lin.getCapabilities());
+ Map<String, FileSystem> fsList = lin.getFileSystemList("nfs");
+ System.out.println(fsList);
+ System.out.println(BigInteger.valueOf(lin.getMemory()
+ .longValue()));
+ System.out.println(lin.getFreeMemory());
+ BigInteger totalmem = BigInteger.valueOf(lin.getMemory()
+ .longValue());
+ BigInteger freemem = BigInteger.valueOf(lin.getFreeMemory()
+ .longValue());
+ System.out.println(totalmem.subtract(freemem));
+ /*
+ * for (final Map.Entry<String, Linux.FileSystem> entry : fsList
+ * .entrySet()) {
+ * Linux.FileSystem fs = entry.getValue();
+ * StoragePlugin sp = new StoragePlugin(c);
+ * String propUuid = sp.deDash(fs.getUuid());
+ * String mntUuid = fs.getUuid();
+ * String fsType = "FileSys";
+ * sp.setUuid(propUuid);
+ * sp.setSsUuid(propUuid);
+ * sp.setName(propUuid);
+ * sp.setFsType(fsType);
+ * sp.setFsServer(fs.getHost());
+ * sp.setFsSourcePath(fs.getDevice());
+ * sp.storagePluginGetFileSystemInfo();
+ * }
+ */
+ /*
+ * StoragePlugin sp = new StoragePlugin(c);
+ * String propUuid = sp.deDash(sp.newUuid());
+ * String mntUuid = sp.newUuid();
+ * String nfsHost = "cs-mgmt";
+ * String nfsPath = "/volumes/cs-data/primary";
+ * String fsType = "FileSys";
+ * sp.setUuid(propUuid);
+ * sp.setName(propUuid);
+ * sp.setFsType(fsType);
+ * sp.setFsServer(nfsHost);
+ * sp.setFsSourcePath(nfsHost + ":" + nfsPath);
+ * // sp.fsTarget("/nfsmnt/" + mntUuid);
+ * sp.setFsMountPoint("/nfsmnt/" + mntUuid);
+ * sp.setMntUuid(mntUuid);
+ * sp.setSsUuid(propUuid);
+ * sp.setSsName("nfs:" + nfsPath);
+ * if (sp.storagePluginMount() != null) {
+ * lin.discoverMountedFs("nfs");
+ * // System.out.println(sp.extprops);
+ * StoragePlugin store = new StoragePlugin(c);
+ * store.setUuid(propUuid);
+ * store.setSsUuid(propUuid);
+ * store.setMntUuid(mntUuid);
+ * store.setFsHost(nfsHost);
+ * store.setFsSourcePath(nfsHost + ":" + nfsPath);
+ * // store.setFsMountPoint(pool.getPath());
+ * store.storagePluginGetFileSystemInfo();
+ * System.out.println(store.getTotalSize());
+ * sp.setFsSourcePath(nfsHost + ":" + nfsPath);
+ * sp.storagePluginUnmount();
+ * }
+ */
+ }
+
+ /* still needs to be finished! */
+ if (CheckRepo == true) {
+ Repository repo = new Repository(c);
+ String repouuid = repo.deDash(repo.newUuid());
+ String remote = "cs-mgmt:/volumes/cs-data/secondary";
+ String local = "/OVS/Repositories/" + repouuid;
+ String url = "http://nibbler/~funs/iso";
+ String iso = url + "/gentoo.iso";
+ String vhd = url + "/ovm.raw";
+ String isouuid = repo.deDash(repo.newUuid());
+ String vmuuid = repo.deDash(repo.newUuid());
+
+ repo.mountRepoFs(remote, local);
+ repo.createRepo(remote, repouuid, repouuid, "My Comment");
+ repo.discoverRepoDb();
+ // repo.discoverRepo(repouuid);
+ repo.importIso(iso, isouuid + ".iso", repouuid, "");
+ repo.importVirtualDisk(vhd, vmuuid + ".img", repouuid, "");
+ repo.deleteRepo(repouuid, true);
+ repo.unmountRepoFs(local);
+ repo.discoverRepoDb();
+ repo.discoverRepo(repouuid);
+ }
+
+ if (CheckPool == true) {
+ System.out.println("checking pool");
+ Pool pool = new Pool(c);
+ pool.discoverServerPool();
+ System.out.println(pool.getPoolAlias());
+ System.out.println(pool.getPoolId());
+ if (pool.getPoolId().contentEquals("TEST")) {
+ System.out.println("pool equals test");
+ } else {
+ System.out.println("pool" + pool.getPoolId());
+ }
+ List<String> ips = new ArrayList<String>();
+ ips.add("192.168.1.64");
+ ips.add("192.168.1.65");
+ /*
+ * pool.setPoolIps(ips);
+ * pool.setPoolMemberIpList();
+ */
+ /*
+ * if (pool.poolFsId != null) {
+ * pool.leaveServerPool(pool.poolFsId);
+ * }
+ */
+ System.out.println("pool members: "
+ + pool.getPoolMemberIpList());
+ }
+
+ if (CheckOcfs2 == true) {
+ PoolOCFS2 poolocfs = new PoolOCFS2(c);
+ poolocfs.discoverPoolFs();
+ // poolocfs.ocfs2GetMetaData();
+ }
+
+ if (CheckCluster == true) {
+ Pool pool = new Pool(c);
+ pool.discoverServerPool();
+ Cluster Clos = new Cluster(c);
+ // Clos.destroyCluster(pool.poolFsId);
+ if (pool.getPoolId() != null) {
+ // Clos.deconfigureServerForCluster(pool.poolId);
+ }
+ System.out.println("Cluster online: " + Clos.isClusterOnline());
+ System.out.println("Cluster discover: "
+ + Clos.discoverCluster());
+
+ }
+
+ if (CheckXen == true) {
+ Xen xen = new Xen(c);
+ xen.listVms();
+ xen.createVm("xx", "xx");
+ /* xen.deleteVm(repoId, vmId); */
+ }
+
+ /* check the combination of stuff */
+ if (CheckCombine == true) {
+ /* prepare host, mgr should have "steady uuid" */
+ OvmObject Go = new OvmObject();
+ String masterUuid = Go.deDash(Go.newUuid());
+
+ /* check capabilities */
+ Linux Host = new Linux(c);
+ Host.discoverServer();
+ /* setup pool and role, needs utility to be able to do shit */
+ Pool pool = new Pool(c);
+
+ /* Info comes from Linux, not the pool, but needs to be set in the pool -sigh- */
+ if (Host.Get("Server_Roles").contentEquals(
+ pool.getValidRoles().toString())) {
+ pool.setServerRoles(pool.getValidRoles());
+ }
+ if (Host.Get("Membership_State").contentEquals("Unowned")) {
+ pool.takeOwnership(masterUuid, "");
+ }
+ /* get primary storage mounted and registered */
+
+ StoragePlugin sp = new StoragePlugin(c);
+ String propUuid = sp.deDash(sp.newUuid());
+ String mntUuid = sp.newUuid();
+ String nfsHost = "cs-mgmt";
+ String nfsPath = "/volumes/cs-data/primary";
+ String fsType = "FileSys";
+ sp.setUuid(propUuid);
+ sp.setName(propUuid);
+ sp.setFsType(fsType);
+ sp.setFsServer(nfsHost);
+ sp.setFsSourcePath(nfsHost + ":" + nfsPath);
+ sp.setMntUuid(mntUuid);
+ sp.setSsUuid(propUuid);
+ sp.setSsName("nfs:" + nfsPath);
+ sp.setFsMountPoint("/nfsmnt/" + mntUuid);
+
+ /* setup a repo */
+ Repository repo = new Repository(c);
+ String repouuid = repo.deDash(repo.newUuid());
+ String remote = "cs-mgmt:/volumes/cs-data/secondary";
+ String repopath = "/OVS/Repositories/" + repouuid;
+ String url = "http://nibbler/~funs/iso";
+ String iso = url + "/gentoo.iso";
+ String vhd = url + "/ovm.raw";
+ String isouuid = repo.deDash(repo.newUuid());
+ String vmuuid = repo.deDash(repo.newUuid());
+
+ repo.discoverRepoDb();
+
+ repo.mountRepoFs(remote, repopath);
+ repo.createRepo(remote, repouuid, repouuid, "My Comment");
+ repo.discoverRepoDb();
+ // repo.discoverRepo(repouuid);
+ String isoname = isouuid + ".iso";
+ String imgname = vmuuid + ".img";
+ repo.importIso(iso, isoname, repouuid, "");
+ repo.importVirtualDisk(vhd, imgname, repouuid, "");
+
+ if (sp.storagePluginMount() != null) {
+ /* prep the VM disk to go to primary storage */
+ Linux vmDisk = new Linux(c);
+ String srcvmimg = repopath + "/VirtualDisks/" + imgname;
+ String dstvmimg = sp.getFsMountPoint() + "/" + imgname;
+ /* the "solving" of no real primary and secondary storage in OVS */
+ vmDisk.copyFile(srcvmimg, dstvmimg);
+ Xen xen = new Xen(c);
+
+ /*
+ * 'vfb':
+ * ['type=vnc,vncunused=1,vnclisten=127.0.0.1,keymap=en-us']
+ */
+ /*
+ * 'disk': [
+ * 'file:/OVS/Repositories/0004fb0000030000aeaca859e4a8f8c0/VirtualDisks/0004fb0000120000c444117fd87ea251.img,xvda,w']
+ */
+ /* 'vif': ['mac=00:21:f6:00:00:00,bridge=c0a80100'] */
+ String vmName = Go.deDash(Go.newUuid());
+
+ Xen.Vm vm = xen.getVmConfig();
+ vm.setVmName(vmName);
+ vm.setVmUuid(vmName);
+
+ vm.addRootDisk(dstvmimg);
+
+ vm.addVif(0, "c0a80100", "00:21:f6:00:00:02");
+ vm.setVnc("0.0.0.0");
+ xen.createVm(repouuid, vm.vmName);
+ xen.startVm(repouuid, vm.vmName);
+ /*
+ * vm.stopVm(repouuid, vm.vmUuid); vm.deleteVm(repouuid,
+ * vm.vmUuid);
+ */
+ System.out.println("Created VM with: " + vmName);
+ System.out.println("repo: " + repouuid);
+ System.out.println("image: " + imgname);
+ System.out.println("disk: " + dstvmimg);
+ System.out.println("master: " + masterUuid);
+ }
+ }
+ if (CheckVmInfo == true) {
+ Xen host = new Xen(c);
+ /* make an itterator */
+ // String vmId = "14fc3846-45e5-3c08-ad23-432ceb07407b";
+ // String repoId = "f12842eb-f5ed-3fe7-8da1-eb0e17f5ede8";
+ String vmName = "s-1-VM";
+ Xen.Vm vm = null;
+ Xen.Vm ovm = null;
+ try {
+ /* backwards for now: */
+ ovm = host.getRunningVmConfig(vmName);
+ System.out.println(ovm.getVmRootDiskPoolId());
+ /* new style */
+ vm = host.getVmConfig(vmName);
+ vm.addIso("test.iso");
+ if (vm.getVmUuid().equals("")) {
+ System.out.println("no vm found");
+ } else {
+ System.out.println(vm.getVmParams());
+ System.out.println(vm.getVmDisks());
+ System.out.println(vm.getVmUuid());
+ System.out.println(vm.getPrimaryPoolUuid());
+ vm.removeDisk("test.iso");
+ System.out.println(vm.getVmParams().get("disk"));
+ }
+
+ } catch (XmlRpcException e) {
+ System.out.println("Failed to get VM details for " + vmName
+ + " on " + c.getIp());
+ }
+ }
+ if (CheckVnc == true) {
+ Xen vms = new Xen(c);
+ Xen.Vm vm = vms.listVms().get("Domain-0");
+ vm.setVncAddress("0.0.0.0");
+ vm.setVncPassword("testikkel");
+ vm.setVnc();
+ System.out.println(vm._vmVnc + " " + vm.vmVnc);
+ }
+ if (CheckBridge) {
+ Network net = new Network(c);
+ for (final Map.Entry<String, Network.Interface> entry : net.getInterfaceList().entrySet()) {
+ Network.Interface iface = entry.getValue();
+ System.out.println("interface: " + iface.getName() + ", phys: " + iface.getPhysical() + ", type: " + iface.getIfType());
+ }
+ String physInterface = "bond0";
+ Integer vlanId = 2;
+ String physVlanInt = physInterface + "." + vlanId.toString();
+ String brName = "c0a80100" + "." + vlanId.toString();
+ System.out.println(net.getInterfaceByName(physVlanInt)
+ + " " + net.getInterfaceByName(brName));
+
+ if (net.getInterfaceByName(physVlanInt) == null)
+ net.startOvsVlanConfig(physInterface, vlanId);
+
+ if (net.getInterfaceByName(brName) == null)
+ net.startOvsBrConfig(brName, physVlanInt);
+
+ // net.startOvsLocalConfig("control0");
+ // net.ovsBrConfig("start", "control0", "lo");
+ // net.ovsIpConfig("control0", "static", "169.254.0.1",
+ // "255.255.0.0");
+ // execOverSsh("route del -net 169.254.0.0/16");
+ }
+ /* cleanup */
+ /*
+ * repo.deleteRepo(repouuid, true);
+ * repo.unmountRepoFs(repopath); repo.discoverRepoDb();
+ * repo.discoverRepo(repouuid); sp.storagePluginUnmount();
+ */
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.getMessage();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Xen.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Xen.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Xen.java
new file mode 100644
index 0000000..7d30cab
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Xen.java
@@ -0,0 +1,1169 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+/* contains VM related stuff too */
+
+package com.cloud.hypervisor.ovm3.object;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.xmlrpc.XmlRpcException;
+// import org.w3c.dom.Document;
+
+/*
+ * should become an interface implementation
+ */
+public class Xen extends OvmObject {
+ public Xen(Connection c) {
+ client = c;
+ }
+
+ private Map<String, Vm> vmList = null;
+
+ /*
+ * ugly for now, but just insert a "default" VM in the Xen class will strip
+ * it out later if we need to
+ */
+ private Vm vm = new Vm();
+
+ /* a vm class....
+ * Setting up a VM is different than retrieving one from OVM.
+ * retrieve with list:
+ * {state=-b----, vcpus=1, on_poweroff=destroy, cpu_weight=27500, cpus=[Ljava.lang.Object;@4239410a, cpu_cap=0, on_xend_start=ignore, description=, name=0d87b9506da945fd98fb979bb345c187, features=, bootloader_args=-q, shadow_memory=0, domid=7, pool_name=Pool-0, maxmem=256, store_mfn=873241, console_mfn=873240, status=2, builder=linux, image={pci=[Ljava.lang.Object;@3cdd197d, device_model=/usr/lib/xen/bin/qemu-dm, superpages=0, videoram=4, tsc_mode=0, nomigrate=0, notes=[Ljava.lang.Object;@57b47cc2, kernel=, expose_host_uuid=0}, bootloader=/usr/bin/pygrub, cpu_time=1.328733473, memory=256, on_crash=restart, online_vcpus=1, on_reboot=restart, device={console=[Ljava.lang.Object;@a6ad18a, vbd=[Ljava.lang.Object;@6ae2c05d, vkbd=[Ljava.lang.Object;@4cc3507d, vfb=[Ljava.lang.Object;@2ad965ea, vif=[Ljava.lang.Object;@26b1fba0}, start_time=1390033675.38, uuid=0d87b950-6da9-45fd-98fb-979bb345c187, on_xend_stop=ignore}
+ * while setting one up goes according to vmParams, boggle me.
+ * According to the python agent it should be this:
+ * (/usr/lib64/python2.4/site-packages/agent/lib/xenxm.py)
+ * VM_PARAMS = {
+ # option: setter
+ 'cpu_cap': set_cpu_cap,
+ 'cpus': set_cpus,
+ 'cpu_weight': set_cpu_weight,
+ 'disk_other_config': set_disk_other_config,
+ 'disk': set_disk,
+ 'maxmem': set_maxmem,
+ 'memory': set_memory,
+ 'name': set_name,
+ 'vcpus': set_vcpus,
+ 'vif_other_config': set_vif_other_config,
+ 'vif': set_vif
+ }
+ * or:
+ * (/usr/lib64/python2.4/site-packages/agent/lib/xenvm.py)
+ VM_CFG = {
+ # option: checker,
+ 'access_control': check_list,
+ 'acpi': check_int,
+ 'apic': check_int,
+ 'blkif': check_int,
+ 'bootargs': check_str,
+ 'bootloader': check_str,
+ 'boot': check_str,
+ 'builder': check_str,
+ 'console_autoconnect': check_int,
+ 'cpu_cap': check_int,
+ 'cpuid_check': check_list,
+ 'cpuid': check_list,
+ 'cpus': check_str_or_list,
+ 'cpu': check_int,
+ 'cpu_weight': check_int,
+ 'device_model': check_str,
+ 'dhcp': check_str,
+ 'disk_other_config': check_list,
+ 'disk': check_list,
+ 'display': check_int,
+ 'expose_host_uuid': check_int,
+ 'extra': check_str,
+ 'fda': check_str,
+ 'fdb': check_str,
+ 'features': check_str,
+ 'gateway': check_str,
+ 'guest_os_type': check_str,
+ 'hap': check_int,
+ 'hostname': check_str,
+ 'hpet': check_int,
+ 'interface': check_str,
+ 'ioports': check_list,
+ 'ip': check_str,
+ 'irq': check_list,
+ 'isa': check_int,
+ 'kernel': check_str,
+ 'keymap': check_str,
+ 'loader': check_str,
+ 'localtime': check_int,
+ 'machine_address_size': check_int,
+ 'maxmem': check_int,
+ 'maxvcpus': check_int,
+ 'memory': check_int,
+ 'monitor_path': check_str,
+ 'monitor': check_int,
+ 'name': check_str,
+ 'netif': check_int,
+ 'netmask': check_str,
+ 'nfs_root': check_str,
+ 'nfs_server': check_str,
+ 'nographic': check_int,
+ 'nomigrate': check_int,
+ 'on_crash': check_str,
+ 'on_poweroff': check_str,
+ 'on_reboot': check_str,
+ 'on_xend_start': check_str,
+ 'on_xend_stop': check_str,
+ 'opengl': check_int,
+ 'pae': check_int,
+ 'pasued': check_int,
+ 'pci_msitranslate': check_int,
+ 'pci_power_mgmt': check_int,
+ 'pci': check_list,
+ 'ramdisk': check_str,
+ 'root': check_str,
+ 'rtc_timeoffset': check_int,
+ 's3_integrity': check_int,
+ 'sdl': check_int,
+ 'serial': check_str,
+ 'shadow_memory': check_int,
+ 'soundhw': check_str,
+ 'stdvga': check_int,
+ 'superpages': check_int,
+ 'suppress_spurious_page_faults': check_int,
+ 'target': check_int,
+ 'timer_mode': check_int,
+ 'tpmif': check_int,
+ 'tsc_mode': check_int,
+ 'usbdevice': check_str,
+ 'usb': check_int,
+ 'uuid': check_str,
+ 'vcpus': check_int,
+ 'vfb': check_list,
+ 'vhpt': check_int,
+ 'videoram': check_int,
+ 'vif2': check_list,
+ 'vif_other_config': check_list,
+ 'vif': check_list,
+ 'viridian': check_int,
+ 'vncconsole': check_int,
+ 'vncdisplay': check_int,
+ 'vnclisten': check_str,
+ 'vncpasswd': check_str,
+ 'vncunused': check_int,
+ 'vnc': check_int,
+ 'vpt_align': check_int,
+ 'vscsi': check_list,
+ 'vtpm': check_list,
+ 'xauthority': check_str,
+ 'xen_platform_pci': check_int,
+ }
+ */
+ public class Vm {
+ /* vm attributes */
+ public ArrayList<String> _vmVnc = new ArrayList<String>();
+ public Map<String, String> vmVnc = new HashMap<String, String>() {
+ {
+ put(new String("type"), "vnc");
+ put(new String("vncunused"), "1");
+ put(new String("vnclisten"), "127.0.0.1");
+ put(new String("keymap"), "en-us");
+ }
+ };
+ /*
+ * 'vfb': [ 'type=vnc,vncunused=1,vnclisten=127.0.0.1,keymap=en-us']
+ */
+ public List<String> _vmDisks = new ArrayList<String>();
+ public Map<String, String> vmDisk = new HashMap<String, String>() {
+ {
+ put(new String("id"), "");
+ put(new String("uuid"), "");
+ put(new String("dev"), "");
+ put(new String("bootable"), "1");
+ put(new String("mode"), "w");
+ put(new String("VDI"), "");
+ put(new String("backend"), "0");
+ put(new String("protocol"), "x86_32-abi");
+ put(new String("uname"), "");
+ }
+ };
+ /*
+ * 'disk': [
+ * 'file:/OVS/Repositories/0004fb0000030000aeaca859e4a8f8c0/VirtualDisks/0004fb0000120000c444117fd87ea251.img,xvda,w']
+ */
+ String[] _xvmVifs = new String[6];
+ public ArrayList<String> _vmVifs = new ArrayList<String>();
+ public Map<String, String> vmVifs = new HashMap<String, String>() {
+ {
+ put(new String("id"), "");
+ put(new String("dev"), "");
+ put(new String("mac"), "");
+ put(new String("rate"), "");
+ }
+ };
+ /*
+ * 'vif': [ 'mac=00:21:f6:00:00:00,bridge=c0a80100']
+ */
+
+ public String vmSimpleName = ""; /* human readable name */
+ public String vmName = ""; /* usually vm uuid */
+ public 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 ?)
+ */
+ public String vmPrimaryPoolUuid = "";
+ public String vmOnReboot = "restart";
+ /*
+ * default weight, weight is relative to
+ * all VMs
+ */
+ public int vmCpuWeight = 27500;
+
+ public int vmMemory = 256; /* minimum memory allowed */
+ public int vmCpuCap = 0;
+ public int vmMaxVcpus = 0; /*
+ * allows for dynamic adding of vcpus if
+ * higher than vcpus
+ */
+ public int vmVcpus = 1; /* default to 1, can't be higher than maxvCpus */
+ public Boolean vmHa = false; /* high available */
+ public String vmDescription = "";
+ public String vmOnPoweroff = "destroy";
+ public String vmOnCrash = "restart";
+ public String vmBootloader = "/usr/bin/pygrub"; /* if pv ? */
+ public String vmBootArgs = "";
+ public String vmExtra = "";
+ public String vmOs = "Other Linux"; /* default to linux */
+
+ public String vmCpuCompatGroup = "";
+ public String vmDomainType = "xen_pvm"; /* pv is default */
+ public String vmState = "------";
+ private int _vmDiskZero = 97;
+ private int _vmDisk = _vmDiskZero;
+
+ public boolean isControlDomain() {
+ if (this.vmUuid
+ .contentEquals("00000000-0000-0000-0000-000000000000"))
+ return true;
+ return false;
+ }
+
+ public boolean setPrimaryPoolUuid(String poolId) {
+ this.vmPrimaryPoolUuid = poolId;
+ return true;
+ }
+
+ public String getPrimaryPoolUuid() {
+ return this.vmPrimaryPoolUuid;
+ }
+
+ public 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", _vmVnc);
+ put("vcpus", vmVcpus);
+ put("OVM_cpu_compat_group", vmCpuCompatGroup);
+ put("OVM_domain_type", vmDomainType);
+ // put("state", vmState);
+ put("extra", vmExtra);
+ // put("builder", vmBuilder);
+ };
+ };
+
+ 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 boolean setVmBootArgs(final String args) {
+ vmParams.put("bootargs", args);
+ return true;
+ }
+
+ public String getVmBootArgs() {
+ return (String) vmParams.get("bootargs");
+ }
+
+ public Boolean setVmMaxCpus(Integer val) {
+ if (getVmCpus() > val) {
+ vmParams.put("maxvcpus", getVmCpus());
+ } else {
+ vmParams.put("maxvcpus", val);
+ }
+ return true;
+ }
+ public Integer getVmMaxCpus() {
+ return (Integer) vmParams.get("maxvcpus");
+ }
+ public Boolean setVmCpus(Integer val) {
+ vmParams.put("vcpus", val);
+ if (getVmMaxCpus() < val) {
+ setVmMaxCpus(val);
+ }
+ return true;
+ }
+ 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 Long.parseLong((String) vmParams.get("memory"));
+ }
+
+ /*
+ * public Boolean setVmBuilder(String builder) {
+ * vmParams.put("builder", builder);
+ * return true;
+ * }
+ * public String getVmBuilder() {
+ * return (String) vmParams.get("builder");
+ * }
+ */
+ public Boolean setVmDomainType(String domtype) {
+ vmParams.put("OVM_domain_type", domtype);
+ return true;
+ }
+
+ /* iiiis this a good idea ? */
+ public String getVmDomainType() {
+ String domType = (String) vmParams.get("OVM_domain_type");
+ if (domType == null) {
+ String builder = (String) vmParams.get("builder");
+ if (builder.contains("linux")) {
+ domType = "xen_pvm";
+ } else {
+ domType = "hvm";
+ }
+ }
+ return domType;
+ }
+ public Boolean setVmState(String state) {
+ vmParams.put("state", state);
+ return true;
+ }
+ 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");
+ }
+
+ /* 'vfb': ['type=vnc,vncunused=1,vnclisten=127.0.0.1,keymap=en-us'] */
+ /*
+ * 'disk': [
+ * 'file:/OVS/Repositories/0004fb0000030000aeaca859e4a8f8c0/VirtualDisks/0004fb0000120000c444117fd87ea251.img,xvda,w']
+ */
+ /* 'vif': ['mac=00:21:f6:00:00:00,bridge=c0a80100'] */
+ /* TODO: splork out VIFs this is not sane, same for VFBs and */
+ public void setVmVncs(List<String> vncs) {
+ this._vmVnc.addAll(vncs);
+ }
+ public List<String> getVmVncs() {
+ return this._vmVnc;
+ }
+ 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 boolean addVif() {
+ ArrayList<String> vif = new ArrayList<String>();
+ for (final String entry : _vmVifs.get(0).split(",")) {
+ final String[] parts = entry.split("=");
+ assert (parts.length == 2) : "Invalid entry: " + entry;
+ vif.add(parts[0] + "=" + parts[1]);
+ }
+ _vmVifs.add(StringUtils.join(vif, ","));
+ return true;
+ }
+
+ public Boolean addVif(Integer id, String bridge, String mac) {
+ String vif = "mac=" + mac + ",bridge=" + bridge;
+ _xvmVifs[id] = vif;
+ // _vmVifs.add("mac=" + mac + ",bridge=" + bridge);
+ return true;
+ }
+
+ public boolean setupVifs() {
+ for (String vif : _xvmVifs) {
+ if (vif != null)
+ _vmVifs.add(vif);
+ }
+ return true;
+ }
+
+ public Boolean removeVif(String bridge, String mac) {
+ // vmVfbs.remove("mac="+mac+",bridge="+bridge);
+ 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) throws Exception {
+ Boolean ret = false;
+ if (_vmDisk > _vmDiskZero) {
+ Integer oVmDisk = _vmDisk;
+ _vmDisk = _vmDiskZero;
+ ret = addDisk(image, "w");
+ _vmDisk = oVmDisk;
+ } else {
+ ret = addDisk(image, "w");
+ }
+ return ret;
+ }
+ public Boolean addDataDisk(String image) throws Exception {
+ /*
+ * w! means we're able to share the disk is that wise, should be
+ * an option in CS ?
+ */
+ return addDisk(image, "w!");
+ }
+ public Boolean addIso(String image) throws Exception {
+ /* should we check for .iso ? */
+ return addDisk(image, "r!");
+ }
+ public Boolean addDisk(String image, String mode) throws Exception {
+ String devName = null;
+ /* better accounting then _vmDisk += 1 */
+ _vmDisk = _vmDiskZero + _vmDisks.size();
+ if (getVmDomainType() != null && getVmDomainType().contains("hvm")) {
+ _vmDisk += 2;
+ devName = Character.toString((char) _vmDisk);
+ } else {
+ devName = "xvd" + Character.toString((char) _vmDisk);
+ }
+
+ /* check for iso, force mode and additions */
+ if (image.endsWith(".iso")) {
+ devName = devName + ":cdrom";
+ mode = "r";
+ }
+ return _addDisk(image, devName, mode);
+ }
+
+ /* should be on device id too, or else we get random attaches... */
+ public Boolean _addDisk(String image, String devName, String mode) throws Exception {
+ if (getVmDomainType() == null) {
+ throw new Exception("Unable to add disk without domain type "
+ + "(hvm, xen_pvm, ldoms_pvm (sparc), default)");
+ }
+ /* TODO: needs to become "checkDisk" */
+ for (String disk : _vmDisks) {
+ if (disk.contains(image)) {
+ return true;
+ }
+ }
+ _vmDisks.add("file:" + image + "," + devName + "," + mode);
+ vmParams.put("disk", _vmDisks);
+ /* accounting is done in addDisk */
+ // _vmDisk += 1;
+ return true;
+ }
+
+ public Boolean removeDisk(String image) throws Exception {
+ for (String disk : _vmDisks) {
+ if (disk.contains(image)) {
+ return _vmDisks.remove(disk);
+ }
+ }
+ return false;
+ }
+
+ /* TODO: the conflict between getVm and getVmConfig becomes clear */
+ /* FIX: me */
+ public String getVmRootDiskPoolId() {
+ String poolId = getVmDiskPoolId(0);
+ this.setPrimaryPoolUuid(poolId);
+ return poolId;
+ }
+
+ /* TODO: need to fork out vifs, disks and vnc stuff fill them nicely too */
+ public String getVmDiskPoolId(int disk) {
+ String diskPath = "";
+ diskPath = _getVmDiskDetail(disk, "uname");
+ String st[] = diskPath.split(File.separator);
+ return st[3];
+ }
+
+ public String _getVmDiskDetail(int disk, String dest) {
+ // System.out.println(vmParams);
+ Map<String, Object[]> o = (Map<String, Object[]>) vmParams
+ .get("device");
+ vmDisk = (Map<String, String>) o.get("vbd")[disk];
+ return vmDisk.get(dest);
+ }
+
+ public Boolean removeDisk(String file, String device) {
+ //
+ // get index and remove
+ return true;
+ }
+
+ public boolean setVnc() {
+ ArrayList<String> vfb = new ArrayList<String>();
+ for (final String key : vmVnc.keySet()) {
+ vfb.add(key + "=" + vmVnc.get(key));
+ }
+ _vmVnc.add(StringUtils.join(vfb, ","));
+ return true;
+ }
+
+ public Boolean setVnc(String address) {
+ return setVnc("vnc", address, "en-us");
+ }
+
+ public Boolean setVnc(String type, String address, String map) {
+ /* unused off is domid + 5900, with unused=1 it will be "smart" */
+ vmVnc.put("type", type);
+ vmVnc.put("vncunused", this.getVncUsed());
+ vmVnc.put("vnclisten", address);
+ vmVnc.put("keymap", map);
+ setVnc();
+ return true;
+ }
+
+ 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() {
+ Integer port = getVncPort();
+ if (port == null) {
+ return null;
+ }
+ return vmVnc.get("vnclisten");
+ }
+ public Integer getVncPort() {
+ if (_getVnc("port") != null) {
+ return Integer.parseInt(_getVnc("port"));
+ }
+ String vnc = getVncLocation();
+ if (vnc.contains(":")) {
+ final String[] res = vnc.split(":");
+ vmVnc.put("vnclisten", res[0]);
+ vmVnc.put("port", res[1]);
+ return Integer.parseInt(res[1]);
+ }
+ return null;
+ }
+
+ public String getVncLocation() {
+ return _getVnc("location");
+ }
+
+ public String _getVnc(String el) {
+ Map<String, Object[]> o = (Map<String, Object[]>) vmParams
+ .get("device");
+ vmVnc = (Map<String, String>) o.get("vfb")[0];
+ return vmVnc.get(el);
+ }
+
+ public Boolean removeVfb(String type, String address, String map) {
+ // get index and remove
+ return true;
+ }
+
+ public Object get(String key) {
+ return vmParams.get(key);
+ }
+ public <T> boolean set(String key, T arg) {
+ vmParams.put(key, arg);
+ return true;
+ }
+ }
+
+ /*
+ * 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 ParserConfigurationException,
+ IOException,
+ Exception {
+ Object[] result = (Object[]) callWrapper("list_vms");
+ if (result == null) {
+ return null;
+ }
+
+ try {
+ vmList = new HashMap<String, Vm>();
+ for (Object x : result) {
+ /* put the vmparams in, as x is a hashmap */
+ // System.out.println(x);
+ Vm vm = new Vm();
+ vm.setVmParams((Map<String, Object>) x);
+ this.vmList.put((String) vm.get("name"), vm);
+
+ // System.out.println(vm.get("name") + " " + vm.get("maxmem"));
+ }
+ } catch (Exception e) {
+ System.err.println("Unable to list VMs: " + e.getMessage());
+ throw new Exception("Unable to list VMs: " + e.getMessage());
+ }
+ // System.out.println(vmList);
+ return this.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 ParserConfigurationException, IOException, Exception {
+ listVms();
+ try {
+ Xen.Vm vm = this.vmList.get(name);
+ return vm;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public Map<String, Vm> getRunningVmConfigs()
+ throws ParserConfigurationException, IOException, Exception {
+ 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 XmlRpcException {
+ Object x = callWrapper("delete_vm", repoId, vmId);
+ // System.out.println(x);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 */
+ public Boolean saveVm(String repoId, String vmId) throws XmlRpcException {
+ Object x = callWrapper("save_vm", repoId, vmId);
+ // System.out.println(x);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ vm = (Vm) callWrapper("list_vm", repoId, vmId);
+ if (vm == null)
+ 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
+ */
+ public Boolean configureVm(String repoId, String vmId,
+ Map<String, Object> params)
+ throws XmlRpcException {
+ Object x = callWrapper("configure_vm",
+ repoId,
+ vmId,
+ params);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean configureVm(String repoId, String vmId)
+ throws XmlRpcException {
+ return configureVm(repoId,
+ vmId,
+ this.vm.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 XmlRpcException {
+ Object x = callWrapper("pause_vm", repoId, vmId);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ 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 XmlRpcException {
+ 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 XmlRpcException {
+ Object x = callWrapper("migrate_vm", repoId, vmId, dest);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean migrateVm(String repoId, String vmId, String dest,
+ boolean live, boolean ssl) throws XmlRpcException {
+ 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 XmlRpcException {
+ 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 XmlRpcException {
+ Object x = callWrapper("create_vm", repoId, vmId, vm.getVmParams());
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean createVm(String repoId, String vmId,
+ Map<String, Object> vmParams) throws XmlRpcException {
+ Object x = callWrapper("create_vm", repoId, vmId, vmParams);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Object x = callWrapper("start_vm", repoId, vmId);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * unpause_vm, <class 'agent.api.hypervisor.xenxm.Xen'> argument: self -
+ * default: None argument: repo_id - default: None argument: vm_id -
+ * default: None
+ */
+ public Boolean unpauseVm(String repoId, String vmId)
+ throws XmlRpcException {
+ Object x = callWrapper("unpause_vm", repoId, vmId);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Object x = callWrapper("reboot_vm", repoId, vmId, wait);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean rebootVm(String repoId, String vmId) throws XmlRpcException {
+ 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 XmlRpcException, Exception {
+ this.vm = this.getRunningVmConfig(vmName);
+ if (vm == null)
+ return this.vm;
+ return getVmConfig(vm.getVmRootDiskPoolId(), vm.getVmUuid());
+ }
+
+ public Vm getVmConfig() {
+ return this.vm;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Xen.Vm nVm = new Xen.Vm();
+ Map<String, Object[]> x = (Map<String, Object[]>) callWrapper("get_vm_config",
+ repoId,
+ vmId);
+ if (x == null) {
+ 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.setVmVifs(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... */
+ this.vm = nVm;
+ return nVm;
+ }
+
+ /*
+ * 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
+ */
+}
[4/7] CLOUDSTACK-6967: Now with module!
Posted by se...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java
new file mode 100755
index 0000000..6b563d5
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java
@@ -0,0 +1,3211 @@
+// 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.hypervisor;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.URI;
+import java.util.ArrayList;
+// import java.net.URISyntaxException;
+/*
+ * import java.util.ArrayList;
+ */
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.net.URL;
+
+import org.apache.commons.lang.BooleanUtils;
+
+import com.google.gson.Gson;
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+
+
+
+
+// import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+// import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.AttachVolumeAnswer;
+import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+// import com.cloud.agent.api.CleanupNetworkRulesCmd;
+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.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+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.GetDomRVersionAnswer;
+import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.NetworkRulesSystemVmCommand;
+import com.cloud.agent.api.routing.DhcpEntryCommand;
+import com.cloud.agent.api.routing.SavePasswordCommand;
+import com.cloud.agent.api.routing.VmDataCommand;
+// import com.cloud.agent.api.routing.DhcpEntryAnswer;
+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.MigrateAnswer;
+import com.cloud.agent.api.MigrateCommand;
+import com.cloud.agent.api.ModifyStoragePoolAnswer;
+import com.cloud.agent.api.ModifyStoragePoolCommand;
+import com.cloud.agent.api.PingCommand;
+import com.cloud.agent.api.PingRoutingCommand;
+import com.cloud.agent.api.PingTestCommand;
+import com.cloud.agent.api.PrepareForMigrationAnswer;
+import com.cloud.agent.api.PrepareForMigrationCommand;
+// import com.cloud.agent.api.PrepareOCFS2NodesCommand;
+import com.cloud.agent.api.ReadyAnswer;
+import com.cloud.agent.api.ReadyCommand;
+import com.cloud.agent.api.RebootAnswer;
+import com.cloud.agent.api.RebootCommand;
+/*
+ * import com.cloud.agent.api.SecurityGroupRuleAnswer;
+ * import com.cloud.agent.api.SecurityGroupRulesCmd;
+ */
+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.VmStatsEntry;
+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.storage.PrimaryStorageDownloadAnswer;
+import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.routing.NetworkElementCommand;
+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.StorageFilerTO;
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.agent.api.to.VolumeTO;
+import com.cloud.agent.api.to.DataObjectType;
+import com.cloud.host.Host.Type;
+import com.cloud.host.HostVO;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkSetupInfo;
+// import com.cloud.network.NetworkModel;
+import com.cloud.resource.ServerResource;
+import com.cloud.resource.hypervisor.HypervisorResource;
+// import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.Storage.StoragePoolType;
+import com.cloud.storage.Volume;
+import com.cloud.storage.template.TemplateProp;
+import com.cloud.template.VirtualMachineTemplate.BootloaderType;
+// import com.cloud.utils.Pair;
+// import com.cloud.utils.Ternary;
+import com.cloud.utils.exception.CloudRuntimeException;
+// import com.cloud.utils.script.Script;
+import com.cloud.utils.ssh.SshHelper;
+import com.trilead.ssh2.SCPClient;
+import com.cloud.utils.ssh.SSHCmdHelper;
+import com.cloud.agent.api.check.CheckSshAnswer;
+import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineName;
+import com.cloud.vm.VirtualMachine.PowerState;
+import com.cloud.vm.VirtualMachine.State;
+import com.cloud.hypervisor.ovm3.object.Common;
+import com.cloud.hypervisor.ovm3.object.Connection;
+import com.cloud.hypervisor.ovm3.object.Linux;
+import com.cloud.hypervisor.ovm3.object.Network;
+import com.cloud.hypervisor.ovm3.object.OvmObject;
+import com.cloud.hypervisor.ovm3.object.Pool;
+import com.cloud.hypervisor.ovm3.object.PoolOCFS2;
+import com.cloud.hypervisor.ovm3.object.Repository;
+import com.cloud.hypervisor.ovm3.object.StoragePlugin;
+import com.cloud.hypervisor.ovm3.object.Xen;
+import com.cloud.hypervisor.ovm3.object.CloudStackPlugin;
+
+import org.apache.cloudstack.storage.command.CopyCommand;
+import org.apache.cloudstack.storage.command.DeleteCommand;
+import org.apache.cloudstack.storage.command.CopyCmdAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectAnswer;
+import org.apache.cloudstack.storage.command.CreateObjectCommand;
+
+import com.cloud.storage.resource.StorageProcessor;
+
+import org.apache.cloudstack.storage.command.ForgetObjectCmd;
+import org.apache.cloudstack.storage.command.IntroduceObjectCmd;
+import org.apache.cloudstack.storage.command.DettachCommand;
+// import org.apache.cloudstack.storage.command.DettachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+
+
+
+// import org.apache.cloudstack.storage.command.AttachAnswer;
+import com.cloud.storage.Storage.ImageFormat;
+/* do we need this ? */
+import com.cloud.utils.db.GlobalLock;
+import com.cloud.resource.ResourceManager;
+import com.cloud.utils.script.Script;
+
+import org.apache.commons.io.FileUtils;
+
+import javax.inject.Inject;
+
+/* TODO: Seperate these out */
+public class Ovm3ResourceBase implements ServerResource, HypervisorResource,
+ StorageProcessor {
+ private static final Logger s_logger = Logger
+ .getLogger(Ovm3ResourceBase.class);
+ private Connection c;
+ private Connection m;
+ private String _name;
+ private String _ip;
+ Long _zoneId;
+ Long _podId;
+ Long _poolId;
+ Long _clusterId;
+ String _host;
+ String _guid;
+ String _username = "root";
+ String _password;
+ String _agentUserName = "oracle";
+ String _agentPassword;
+ Integer _agentPort = 8899;
+ Boolean _agentSsl = false;
+ String _ovmSshKey = "id_rsa.cloud";
+ String _masterUuid = "d1a749d4295041fb99854f52ea4dea97";
+ Boolean _isMaster = false;
+ Boolean _hasMaster = false;
+ Boolean _ovm3pool = false;
+ Boolean _ovm3cluster = false;
+ String _ovm3vip = "";
+ protected boolean _checkHvm = false;
+ /* _clusterDetailsDao.findDetail(clusterId, getVagKey(storagePoolId)); */
+ String _privateNetworkName;
+ String _publicNetworkName;
+ String _guestNetworkName;
+ String _storageNetworkName;
+ String _controlNetworkName = "control0";
+ String _controlNetworkIp = "169.254.0.1";
+ // String _controlNetworkMask = "255.255.0.0";
+ boolean _canBridgeFirewall = false;
+ String _ovmRepo = "/OVS/Repositories";
+ String _ovmSec = "/nfsmnt";
+ OvmObject _ovmObject = new OvmObject();
+ static boolean s_isHeartBeat = false;
+ protected final int DefaultDomRSshPort = 3922;
+ String DefaultDomRPath = "/opt/cloud/bin/";
+ private Map<String, Network.Interface> _interfaces = null;
+ /* switch to concurrenthasmaps all over the place ? */
+ private final ConcurrentHashMap<String,
+ Map<String, String>> _vmStats =
+ new ConcurrentHashMap<String,
+ Map<String, String>>();
+
+ // TODO vmsync {
+ /* This is replaced by the vmList in getall VMs, and operate on that */
+ // protected HashMap<String, State> _vms = new HashMap<String, State>(250);
+ protected Map<String, Xen.Vm> _vms = new HashMap<String, Xen.Vm>();
+ protected Map<String, State> _vmstates = new HashMap<String, State>();
+
+ static HashMap<String, State> s_stateMaps;
+ static {
+ s_stateMaps = new HashMap<String, State>();
+ s_stateMaps.put("Stopping", State.Stopping);
+ s_stateMaps.put("Running", State.Running);
+ s_stateMaps.put("Stopped", State.Stopped);
+ s_stateMaps.put("Error", State.Error);
+ s_stateMaps.put("Suspended", State.Running);
+ s_stateMaps.put("Paused", State.Running);
+ s_stateMaps.put("Migrating", State.Migrating);
+ }
+
+ static HashMap<String, PowerState> s_powerStateMaps;
+ static {
+ s_powerStateMaps = new HashMap<String, PowerState>();
+ s_powerStateMaps.put("Stopping", PowerState.PowerOn);
+ s_powerStateMaps.put("Running", PowerState.PowerOn);
+ s_powerStateMaps.put("Stopped", PowerState.PowerOff);
+ s_powerStateMaps.put("Error", PowerState.PowerUnknown);
+ s_powerStateMaps.put("Suspended", PowerState.PowerOn);
+ s_powerStateMaps.put("Paused", PowerState.PowerOn);
+ /* unknown ? */
+ s_powerStateMaps.put("Migrating", PowerState.PowerOn);
+ }
+
+ @Inject
+ PrimaryDataStoreDao _storagePoolDao;
+ @Inject
+ HostDao _hostDao;
+ @Inject
+ ResourceManager _resourceMgr;
+
+ GlobalLock _exclusiveOpLock = GlobalLock.getInternLock("ovm3.exclusive.op");
+
+ /* return params we want to add, damnit */
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+ _name = name;
+ s_logger.debug("configure " + name + " with params: " + params);
+ /* do we have enough ? */
+ try {
+ _zoneId = Long.parseLong((String) params.get("zone"));
+ _podId = Long.parseLong((String) params.get("pod"));
+ _clusterId = Long.parseLong((String) params.get("cluster"));
+ _ovm3vip = String.valueOf(params.get("ovm3vip"));
+ _ovm3pool = BooleanUtils.toBoolean((String) params.get("ovm3pool"));
+ _ovm3cluster = BooleanUtils.toBoolean((String) params
+ .get("ovm3cluster"));
+ _host = (String) params.get("host");
+ _ip = (String) params.get("ip");
+ _username = (String) params.get("username");
+ _password = (String) params.get("password");
+ _guid = (String) params.get("guid");
+ _agentUserName = (String) params.get("agentusername");
+ _agentPassword = (String) params.get("agentpassword");
+ _privateNetworkName = (String) params.get("private.network.device");
+ _publicNetworkName = (String) params.get("public.network.device");
+ _guestNetworkName = (String) params.get("guest.network.device");
+ _storageNetworkName = (String) params.get("storage.network.device");
+
+ if (params.get("agentport") != null)
+ _agentPort = Integer.parseInt((String) params.get("agentport"));
+
+ // Add later
+ // _agentSsl = (Boolean)params.get("agentssl");
+ } catch (Exception e) {
+ s_logger.debug("Configure " + _host + " failed", e);
+ throw new ConfigurationException("Configure " + _host + " failed, "
+ + e.toString());
+ }
+
+ if (_podId == null) {
+ String msg = "Unable to get the pod";
+ s_logger.debug(msg);
+ throw new ConfigurationException(msg);
+ }
+
+ if (_host == null) {
+ String msg = "Unable to get the host";
+ s_logger.debug(msg);
+ throw new ConfigurationException(msg);
+ }
+
+ if (_username == null) {
+ String msg = "Unable to get the username";
+ s_logger.debug(msg);
+ throw new ConfigurationException(msg);
+ }
+
+ if (_password == null) {
+ String msg = "Unable to get the password";
+ s_logger.debug(msg);
+ throw new ConfigurationException(msg);
+ }
+
+ if (_guid == null) {
+ String msg = "Unable to get the guid";
+ s_logger.debug(msg);
+ throw new ConfigurationException(msg);
+ }
+
+ if (_agentUserName == null) {
+ String msg = "Unable to get the agent username";
+ s_logger.debug(msg);
+ throw new ConfigurationException(msg);
+ }
+
+ if (_agentPassword == null) {
+ String msg = "Unable to get the agent password";
+ s_logger.debug(msg);
+ throw new ConfigurationException(msg);
+ }
+
+ if (_agentPort == null) {
+ String msg = "Unable to get the agent port";
+ s_logger.debug(msg);
+ throw new ConfigurationException(msg);
+ }
+
+ /* TODO: Needs to be relocated */
+ if (_ovm3vip.equals("")) {
+ s_logger.debug("No VIP, Setting ovm3pool and ovm3cluster to false");
+ this._ovm3pool = false;
+ this._ovm3cluster = false;
+ this._ovm3vip = "";
+ }
+ /* if we're a cluster we have to be a pool ? */
+ if (_ovm3cluster) {
+ this._ovm3pool = true;
+ }
+
+ /* check if we're master or not and if we can connect */
+ try {
+ try {
+ c = new Connection(_host, _agentPort, _agentUserName,
+ _agentPassword);
+ } catch (XmlRpcException ex) {
+ String msg = "Unable to connect to " + _host;
+ s_logger.warn(msg + ": " + ex.getMessage());
+ throw new Exception(msg, ex);
+ }
+ this._isMaster = masterCheck();
+ } catch (Exception e) {
+ String msg = "Base checks failed for " + _host;
+ s_logger.debug(msg, e);
+ throw new ConfigurationException(msg);
+ }
+ /* setup ovm3 plugin */
+ try {
+ installOvsPlugin();
+ CloudStackPlugin cSp = new CloudStackPlugin(c);
+ cSp.ovsUploadSshKey(this._ovmSshKey,
+ FileUtils.readFileToString(getSystemVMKeyFile()));
+ } catch (Exception e) {
+ String msg = "Failed to setup server: " + _host;
+ s_logger.error(msg + ": " + e.getMessage());
+ throw new ConfigurationException(msg + ", " + e);
+ }
+
+ try {
+ try {
+ /*
+ * TODO: setup meta tags for the management interface (probably
+ * required with multiple interfaces)?
+ */
+ Network net = new Network(c);
+ _interfaces = net.getInterfaceList();
+ s_logger.debug("all interfaces: " + _interfaces);
+ if (_controlNetworkName != null
+ && !_interfaces.containsKey(_controlNetworkName)) {
+ /*
+ * TODO: find a more elegant way to do this
+ * for now we need the route del and ifconfig
+ * as loopback bridges have arp disabled by default,
+ * and zeroconf configures a route on the main bridge...
+ */
+ try {
+ net.startOvsLocalConfig(_controlNetworkName);
+ } catch (Exception e) {
+ s_logger.debug("Unable to configure"
+ + _controlNetworkName + ":" + e.getMessage());
+ }
+ /* ovs replies too "fast" so the bridge can be "busy" */
+ while (!_interfaces.containsKey(_controlNetworkName)) {
+ s_logger.debug("waiting for " + _controlNetworkName);
+ _interfaces = net.getInterfaceList();
+ Thread.sleep(1 * 1000);
+ }
+ }
+ /* The bridge is remembered upon reboot, but not the IP */
+ net.ovsIpConfig(_controlNetworkName,
+ "static",
+ _controlNetworkIp,
+ "255.255.0.0");
+ CloudStackPlugin cSp = new CloudStackPlugin(c);
+ cSp.ovsControlInterface(_controlNetworkName,
+ _controlNetworkIp + "/16");
+
+ // Missing netM = new Missing(c);
+ /* build ovs_if_meta in Net based on the following */
+ if (_privateNetworkName != null
+ && net.getBridgeByName(_privateNetworkName).getName() == null) {
+ throw new ConfigurationException(
+ "Cannot find private bridge "
+ + _privateNetworkName
+ + " on host "
+ + _host
+ + " - "
+ + net.getBridgeByName(_privateNetworkName)
+ .getName());
+ }
+ if (_publicNetworkName != null
+ && net.getBridgeByName(_publicNetworkName).getName() == null) {
+ throw new ConfigurationException(
+ "Cannot find private bridge "
+ + _publicNetworkName
+ + " on host "
+ + _host
+ + " - "
+ + net.getBridgeByName(_publicNetworkName)
+ .getName());
+ }
+ if (_guestNetworkName != null
+ && net.getBridgeByName(_guestNetworkName).getName() == null) {
+ throw new ConfigurationException(
+ "Cannot find private bridge "
+ + _guestNetworkName
+ + " on host "
+ + _host
+ + " - "
+ + net.getBridgeByName(_guestNetworkName)
+ .getName());
+ }
+ if (_storageNetworkName != null
+ && net.getBridgeByName(_storageNetworkName).getName() == null) {
+ throw new ConfigurationException(
+ "Cannot find private bridge "
+ + _storageNetworkName
+ + " on host "
+ + _host
+ + " - "
+ + net.getBridgeByName(_storageNetworkName)
+ .getName());
+ }
+ } catch (Exception e) {
+ s_logger.debug("Get bridges failed on host " + _host + ", ", e);
+ throw new ConfigurationException("Cannot get bridges on host "
+ + _host + ", " + e);
+ }
+ try {
+ prepareForPool();
+ } catch (Exception e) {
+ throw new ConfigurationException("Failed to prepare for pool "
+ + _host + ", " + e);
+ }
+
+ /*
+ * set to false so each time ModifyStoragePoolCommand will re-setup
+ * heartbeat
+ */
+ /*
+ * only required if we do cluster and then o2cb will take care of it
+ * s_isHeartBeat = false;
+ */
+
+ /*
+ * - uses iptables in XenServer, but not agent accessible for agent
+ * *should make module*
+ */
+ try {
+ _canBridgeFirewall = canBridgeFirewall();
+ } catch (XmlRpcException e) {
+ s_logger.error("Failed to detect whether the host supports security groups.",
+ e);
+ _canBridgeFirewall = false;
+ }
+
+ s_logger.debug(_canBridgeFirewall ? "OVM3 host supports security groups."
+ : "OVM3 host doesn't support security groups.");
+ /*
+ * } catch (XmlRpcException e) {
+ * String msg = "XML RPC Exception, unable to setup host: " + _host
+ * + " " + e;
+ * s_logger.debug(msg);
+ * throw new ConfigurationException(msg);
+ */
+ } catch (Exception e) {
+ String msg = "Generic Exception, failed to setup host: " + _host;
+ s_logger.debug(msg + ": " + e.getMessage());
+ throw new ConfigurationException(msg + ":" + e.getMessage());
+ } /*
+ * catch (IOException e) { s_logger.debug("Failed to setup host " +
+ * _host, e); throw new
+ * ConfigurationException("Unable to setup host"); }
+ */
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return _name;
+ }
+
+ @Override
+ public Type getType() {
+ return Type.Routing;
+ }
+
+ protected void fillHostInfo(StartupRoutingCommand cmd) {
+ try {
+ /* get data we need from parts */
+ Linux host = new Linux(c);
+ if (!host.getOvmVersion().startsWith("3.2.")) {
+ throw new CloudRuntimeException(
+ "OVM 3.2.X is only supported, not "
+ + host.getOvmVersion());
+ }
+ Xen vms = new Xen(c);
+ vms.listVms();
+ Xen.Vm dom0 = vms.getRunningVmConfig("Domain-0");
+
+ cmd.setName(host.getHostName());
+ cmd.setSpeed(host.getCpuKhz());
+ cmd.setCpus(host.getTotalThreads());
+ cmd.setCpuSockets(host.getCpuSockets());
+ cmd.setMemory(host.getMemory().longValue());
+ /*
+ * TODO: Convert Bigint to long in Linux
+ */
+ 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(_guid);
+ cmd.setDataCenter(_zoneId.toString());
+ cmd.setPod(_podId.toString());
+ // also set uuid for ownership, or else pooling/clustering will not
+ // work
+ // cmd.setOwner(host.getManagerUuid());
+ cmd.setCluster(_clusterId.toString());
+ cmd.setHypervisorVersion(host.getOvmVersion());
+ cmd.setVersion(host.getAgentVersion());
+ cmd.setHypervisorType(HypervisorType.Ovm3);
+ /* is this true ? */
+ cmd.setCaps(host.getCapabilities());
+ // TODO: Control ip, for now cheat ?
+ cmd.setPrivateIpAddress(_ip);
+ cmd.setStorageIpAddress(_ip);
+ cmd.setHostVmStateReport(HostVmStateReport());
+
+ Network net = new Network(c);
+ /* more detail -- fix -- and shouldn't matter */
+ /* should this be the bond before the bridge ?*/
+ String defaultBridge = net.getBridgeByIp(_ip).getName();
+ if (defaultBridge == null) {
+ throw new CloudRuntimeException(
+ "Unable to obtain valid bridge with " + _ip);
+ }
+
+ /* TODO: cleanup network section, this is not right */
+ if (_publicNetworkName == null) {
+ _publicNetworkName = defaultBridge;
+ }
+ if (_privateNetworkName == null) {
+ _privateNetworkName = _publicNetworkName;
+ }
+ if (_guestNetworkName == null) {
+ _guestNetworkName = _publicNetworkName;
+ }
+ /*
+ * if (_storageNetworkName == null) {
+ * _storageNetworkName = _privateNetworkName;
+ * }
+ */
+ Map<String, String> d = cmd.getHostDetails();
+ d.put("public.network.device", _publicNetworkName);
+ if (_privateNetworkName != null)
+ d.put("private.network.device", _privateNetworkName);
+ if (_guestNetworkName != null)
+ d.put("guest.network.device", _guestNetworkName);
+ if (_storageNetworkName != null)
+ d.put("storage.network.device", _storageNetworkName);
+ d.put("ismaster", this._isMaster.toString());
+ cmd.setHostDetails(d);
+ s_logger.debug("Add an Ovm3 host " + _name + ":"
+ + cmd.getHostDetails());
+ } catch (XmlRpcException e) {
+ s_logger.debug("XML RPC Exception" + e.getMessage(), e);
+ throw new CloudRuntimeException("XML RPC Exception"
+ + e.getMessage(), e);
+ } catch (Exception e) {
+ s_logger.debug("Exception " + e.getMessage(), e);
+ throw new CloudRuntimeException("Exception" + e.getMessage(), e);
+ }
+ }
+
+ /*
+ * plugs the ovm module into the ovs-agent
+ */
+ protected void installOvsPlugin() throws IOException {
+ /* ssh-copy-id anyone ? */
+ try {
+ com.trilead.ssh2.Connection sshConnection =
+ SSHCmdHelper.acquireAuthorizedConnection(_ip,
+ _username,
+ _password);
+ if (sshConnection == null) {
+ throw new ConfigurationException(String.format("Unable to "
+ + "connect to server(IP=%1$s, username=%2$s, "
+ + "password=%3$s", _ip, _username, _password));
+ }
+ SCPClient scp = new SCPClient(sshConnection);
+ String userDataScript = "scripts/vm/hypervisor/ovm3/cloudstack.py";
+ String userDataScriptPath = Script.findScript("", userDataScript);
+ if (userDataScriptPath == null) {
+ throw new ConfigurationException("Can not find "
+ + userDataScript);
+ }
+ scp.put(userDataScriptPath, "", "0755");
+ String prepareCmd = String.format("./cloudstack.py "
+ + "--ssl=" + this._agentSsl + " "
+ + "--port=" + this._agentPort);
+ if (!SSHCmdHelper.sshExecuteCmd(sshConnection, prepareCmd)) {
+ throw new ConfigurationException("Module insertion at "
+ + _host + " failed");
+ }
+ } catch (Exception es) {
+ s_logger.error("Unexpected exception ", es);
+ String msg = "Unable to install module in agent";
+ s_logger.error(msg);
+ throw new CloudRuntimeException(msg);
+ }
+ }
+
+ /* startup */
+ @Override
+ public StartupCommand[] initialize() {
+ s_logger.debug("Ovm3 resource intializing");
+ try {
+ StartupRoutingCommand srCmd = new StartupRoutingCommand();
+
+ StartupStorageCommand ssCmd = new StartupStorageCommand();
+ fillHostInfo(srCmd);
+ String pool = srCmd.getPool();
+ s_logger.debug("Ovm3 pool " + ssCmd + " " + srCmd);
+
+ Map<String, State> changes = null;
+ synchronized (_vmstates) {
+ _vmstates.clear();
+ changes = sync();
+ }
+ srCmd.setStateChanges(changes);
+ /* should not force HVM */
+ // cmd.setCaps("hvm");
+ return new StartupCommand[] { srCmd, ssCmd };
+ } catch (Exception e) {
+ s_logger.debug("Ovm3 resource initializes failed", e);
+ return null;
+ }
+ }
+
+ /* See if the agent is still up on the host */
+ @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)) {
+ HashMap<String, State> newStates = sync();
+ return new PingRoutingCommand(getType(), id, newStates,
+ HostVmStateReport());
+ }
+ } catch (XmlRpcException e) {
+ s_logger.debug("Check agent status failed", e);
+ return null;
+ } catch (Exception e) {
+ s_logger.debug("Check agent status failed", e);
+ return null;
+ }
+ return null;
+ }
+
+ /* Check if the host is in ready state for CS */
+ protected ReadyAnswer execute(ReadyCommand cmd) {
+ try {
+ Linux host = new Linux(c);
+ Pool pool = new Pool(c);
+
+ /* only interesting when doing cluster */
+ if (!host.getIsMaster() && _ovm3cluster) {
+ if (pool.getPoolMasterVip().equalsIgnoreCase(_ip)) {
+ /* check pool state here */
+ return new ReadyAnswer(cmd);
+ } else {
+ s_logger.debug("Master IP changes to "
+ + pool.getPoolMasterVip() + ", it should be " + _ip);
+ return new ReadyAnswer(cmd, "I am not the master server");
+ }
+ } else if (host.getIsMaster()) {
+ s_logger.debug("Master, not clustered " + _host);
+ return new ReadyAnswer(cmd);
+ } else {
+ s_logger.debug("No master, not clustered " + _host);
+ return new ReadyAnswer(cmd);
+ }
+ } catch (XmlRpcException e) {
+ s_logger.debug("XML RPC Exception" + e.getMessage(), e);
+ throw new CloudRuntimeException("XML RPC Exception"
+ + e.getMessage(), e);
+ } catch (Exception e) {
+ s_logger.debug("Exception" + e.getMessage(), e);
+ throw new CloudRuntimeException("Exception" + e.getMessage(), e);
+ }
+
+ }
+
+ /*
+ * Primary storage, will throw an error if ownership does not match!
+ * Pooling is a part of this, for now
+ */
+ protected boolean createRepo(StorageFilerTO cmd) throws XmlRpcException {
+ String basePath = this._ovmRepo;
+ 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) {
+ /* base repo first */
+
+ repo.mountRepoFs(mountPoint, ovsRepo);
+ s_logger.debug("NFS repository " + mountPoint + " on " + ovsRepo
+ + " requested for " + _host);
+ try {
+ repo.addRepo(mountPoint, ovsRepo);
+ } catch (Exception e) {
+ s_logger.debug("NFS repository " + mountPoint + " on "
+ + ovsRepo + " not found creating!");
+ try {
+ repo.createRepo(mountPoint,
+ ovsRepo,
+ primUuid,
+ "OVS Reposutory");
+ } catch (Exception es) {
+ msg = "NFS repository " + mountPoint + " on "
+ + ovsRepo + " create failed!";
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(
+ msg + " " + es.getMessage(), es);
+ }
+ }
+ /* add base pooling first */
+ if (this._ovm3pool) {
+ try {
+ msg = "Configuring host for pool";
+ s_logger.debug(msg);
+ setupPool(cmd);
+ msg = "Configured host for pool";
+ /* add clustering after pooling */
+ if (this._ovm3cluster) {
+ msg = "Configuring host for cluster";
+ s_logger.debug(msg);
+ /* setup cluster */
+ /*
+ * From cluster.java
+ * configure_server_for_cluster(cluster conf, fs, mount,
+ * fsuuid, poolfsbaseuuid)
+ */
+ /* create_cluster(poolfsuuid,) */
+ msg = "Configuring host for cluster";
+ }
+ } catch (Exception e) {
+ msg = "Unable to setup pool on " + ovsRepo;
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg + " " + e.getMessage(), e);
+ }
+ } else {
+ msg = "no way dude I can't stand for this";
+ s_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");
+ this.setupNfsStorage(uri, cmd.getUuid());
+ } catch (Exception e) {
+ msg = "NFS mount " + mountPoint + " on " + _ovmSec + "/"
+ + cmd.getUuid() + " create failed!";
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg + " " + e.getMessage(), e);
+ }
+ } else {
+ msg = "NFS repository " + mountPoint + " on " + ovsRepo
+ + " create failed, was type " + cmd.getType();
+ s_logger.debug(msg);
+ return false;
+ }
+
+ try {
+ /* systemvm iso is imported here */
+ prepareSecondaryStorageStore(ovsRepo);
+ } catch (Exception e) {
+ msg = "systemvm.iso copy failed to " + ovsRepo;
+ s_logger.debug(msg);
+ return false;
+ }
+ return true;
+ }
+
+ /* */
+ public void prepareSecondaryStorageStore(String storageUrl) {
+ String mountPoint = storageUrl;
+
+ GlobalLock lock = GlobalLock.getInternLock("prepare.systemvm");
+ try {
+ /* double check */
+ if (this._hasMaster && this._ovm3pool) {
+ s_logger.debug("Skip systemvm iso copy, leave it to the master");
+ return;
+ }
+ if (lock.lock(3600)) {
+ try {
+ File srcIso = getSystemVMPatchIsoFile();
+ String destPath = mountPoint + "/ISOs/";
+ String repoPath[] = mountPoint.split(File.separator);
+ String destIso = destPath + "/"
+ + getSystemVMIsoFileNameOnDatastore();
+ String result = "";
+ try {
+ StoragePlugin sp = new StoragePlugin(c);
+ // sp.storagePluginGetFileInfo(repoPath[repoPath.length],
+ // destIso);
+ if (sp.getFileSize() > 0) {
+ s_logger.info(" System VM patch ISO file already exists: "
+ + srcIso.getAbsolutePath().toString()
+ + ", destination: " + destIso);
+ }
+ } catch (Exception e) {
+ /*
+ * Cloudstack already does this at boot time:
+ * s_logger.info(
+ * "Inject SSH key pairs before copying systemvm.iso into secondary storage"
+ * );
+ */
+ s_logger.info("Copy System VM patch ISO file to secondary storage. source ISO: "
+ + srcIso.getAbsolutePath()
+ + ", destination: "
+ + destIso);
+ try {
+ /*
+ * should actualy come from importIso in
+ * Storageplugin, so craft a url that can be used
+ * for that.
+ */
+ SshHelper.scpTo(this._host,
+ 22,
+ this._username,
+ null,
+ this._password,
+ destPath,
+ srcIso.getAbsolutePath().toString(),
+ "0644");
+ } catch (Exception es) {
+ s_logger.error("Unexpected exception ", es);
+ String msg = "Unable to copy systemvm ISO on secondary storage. src location: "
+ + srcIso.toString()
+ + ", dest location: "
+ + destIso;
+ s_logger.error(msg);
+ throw new CloudRuntimeException(msg);
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+ } finally {
+ lock.releaseRef();
+ }
+ }
+
+ /* stolen from vmware impl */
+ public String getSystemVMIsoFileNameOnDatastore() {
+ String version = this.getClass().getPackage()
+ .getImplementationVersion();
+ String fileName = "systemvm-" + version + ".iso";
+ return fileName.replace(':', '-');
+ }
+
+ /* stolen from vmware impl */
+ private File getSystemVMPatchIsoFile() {
+ // locate systemvm.iso
+ String svmName = getSystemVMIsoFileNameOnDatastore();
+ URL url = this.getClass().getClassLoader()
+ .getResource("vms/" + svmName);
+ s_logger.debug(url);
+ File isoFile = null;
+ if (url != null) {
+ isoFile = new File(url.getPath());
+ }
+ if (isoFile == null || !isoFile.exists()) {
+ isoFile = new File("/usr/share/cloudstack-common/vms/" + svmName);
+ }
+
+ assert (isoFile != null);
+ if (!isoFile.exists()) {
+ s_logger.error("Unable to locate " + svmName + " in your setup at "
+ + isoFile.toString());
+ }
+ return isoFile;
+ }
+
+ /* get the key */
+ public File getSystemVMKeyFile() {
+ URL url = this.getClass().getClassLoader()
+ .getResource("scripts/vm/systemvm/" + this._ovmSshKey);
+ File keyFile = null;
+ if (url != null) {
+ keyFile = new File(url.getPath());
+ }
+ if (keyFile == null || !keyFile.exists()) {
+ keyFile = new File(
+ "/usr/share/cloudstack-common/scripts/vm/systemvm/"
+ + _ovmSshKey);
+ }
+ assert (keyFile != null);
+ if (!keyFile.exists()) {
+ s_logger.error("Unable to locate " + _ovmSshKey
+ + " in your setup at " + keyFile.toString());
+ }
+ return keyFile;
+ }
+
+ /*
+ * TODO: local OCFS2? or iSCSI OCFS2
+ */
+ protected Boolean createOCFS2Sr(StorageFilerTO pool) throws XmlRpcException {
+ /*
+ * Ovm3StoragePool.Details d = new Ovm3StoragePool.Details(); d.path =
+ * pool.getPath(); d.type = Ovm3StoragePool.OCFS2; d.uuid =
+ * pool.getUuid(); Ovm3StoragePool.create(_conn, d);
+ * s_logger.debug(String.format("Created SR (mount point:%1$s)",
+ * d.path));
+ */
+ s_logger.debug("OCFS2 Not implemented yet");
+ return false;
+ }
+
+ /* TODO: heartbeats are done by the oracle cluster when clustering */
+ private void setupHeartBeat(String poolUuid) {
+ try {
+ if (!s_isHeartBeat) {
+ // Ovm3Host.setupHeartBeat(_conn, poolUuid, _ip);
+ s_isHeartBeat = true;
+ }
+ } catch (Exception e) {
+ s_logger.debug("setup heart beat for " + _host + " failed", e);
+ s_isHeartBeat = false;
+ }
+ }
+
+ /* Setup a storage pool and also get the size */
+ protected Answer execute(ModifyStoragePoolCommand cmd) {
+ StorageFilerTO pool = cmd.getPool();
+ s_logger.debug("modifying pool " + pool);
+ try {
+ if (pool.getType() == StoragePoolType.NetworkFilesystem) {
+ /* this should actually not be here */
+ createRepo(pool);
+ } else if (pool.getType() == StoragePoolType.OCFS2) {
+ createOCFS2Sr(pool);
+ } else {
+ return new Answer(cmd, false, "The pool type: "
+ + pool.getType().name() + " is not supported.");
+ }
+
+ if (this._ovm3cluster) {
+ // setupHeartBeat(pool.getUuid());
+ }
+ /* TODO: needs to be in network fs above */
+ StoragePlugin store = new StoragePlugin(c);
+ String propUuid = store.deDash(pool.getUuid());
+ String mntUuid = pool.getUuid();
+ String nfsHost = pool.getHost();
+ String nfsPath = pool.getPath();
+ store.setUuid(propUuid);
+ store.setSsUuid(propUuid);
+ store.setMntUuid(mntUuid);
+ store.setFsHost(nfsHost);
+ store.setFsSourcePath(nfsHost + ":" + nfsPath);
+ store.storagePluginGetFileSystemInfo();
+
+ Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
+ ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd,
+ Long.parseLong(store.getTotalSize()), Long.parseLong(store
+ .getFreeSize()), tInfo);
+ return answer;
+ } catch (Exception e) {
+ s_logger.debug("ModifyStoragePoolCommand failed", e);
+ return new Answer(cmd, false, e.getMessage());
+ }
+ }
+
+ /* TODO: add iSCSI */
+ protected Answer execute(CreateStoragePoolCommand cmd) {
+ StorageFilerTO pool = cmd.getPool();
+ s_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");
+ // 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) {
+ s_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:" + _host + " pool: " + pool.getHost()
+ + pool.getPath();
+ s_logger.warn(msg, e);
+ return new Answer(cmd, false, msg);
+ }
+ return new Answer(cmd, true, "success");
+ }
+
+ /*
+ * Download some primary storage into the repository, we need the repoid to
+ * do that, but also have a uuid for the disk...
+ * TODO: check disk
+ * TODO: looks like we don't need this for now! (dead code)
+ */
+ protected 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);
+
+ /* TODO: return uuid and size */
+ return new PrimaryStorageDownloadAnswer(image);
+ } catch (Exception e) {
+ s_logger.debug("PrimaryStorageDownloadCommand failed", e);
+ return new PrimaryStorageDownloadAnswer(e.getMessage());
+ }
+ }
+
+ /*
+ * TODO: Split out in Sec to prim and prim to prim and types ?
+ * Storage mount also goes in here for secstorage
+ */
+ protected final Answer execute(final CopyCommand cmd) {
+ DataTO srcData = cmd.getSrcTO();
+ DataStoreTO srcStore = srcData.getDataStore();
+ DataTO destData = cmd.getDestTO();
+ DataStoreTO destStore = destData.getDataStore();
+
+ try {
+ /* target and source are NFS and TEMPLATE */
+ if ((srcStore instanceof NfsTO)
+ && (srcData.getObjectType() == DataObjectType.TEMPLATE)
+ && (destData.getObjectType() == DataObjectType.TEMPLATE)) {
+ NfsTO srcImageStore = (NfsTO) srcStore;
+ TemplateObjectTO srcTemplate = (TemplateObjectTO) srcData;
+ String storeUrl = srcImageStore.getUrl();
+
+ URI uri = new URI(storeUrl);
+ String secPoolUuid = setupSecondaryStorage(storeUrl);
+ String primaryPoolUuid = destData.getDataStore().getUuid();
+ String destPath = this._ovmRepo + "/"
+ + _ovmObject.deDash(primaryPoolUuid) + "/"
+ + "Templates";
+ String sourcePath = this._ovmSec + "/" + secPoolUuid;
+
+ Linux host = new Linux(c);
+ String destUuid = srcTemplate.getUuid();
+ /*
+ * TODO: add dynamic formats (tolower), it also supports VHD and
+ * QCOW2, although Ovm3.2 does not have tapdisk2 anymore so we
+ * can forget about that.
+ */
+ /* TODO: add checksumming */
+ String srcFile = sourcePath + "/" + srcData.getPath();
+ if (srcData.getPath().endsWith("/")) {
+ srcFile = sourcePath + "/" + srcData.getPath() + "/"
+ + destUuid + ".raw";
+ }
+ String destFile = destPath + "/" + destUuid + ".raw";
+ s_logger.debug("CopyFrom: " + srcData.getObjectType() + ","
+ + srcFile + " to " + destData.getObjectType() + ","
+ + destFile);
+ host.copyFile(srcFile, destFile);
+
+ TemplateObjectTO newVol = new TemplateObjectTO();
+ newVol.setUuid(destUuid);
+ newVol.setPath(destPath);
+ newVol.setFormat(ImageFormat.RAW);
+ return new CopyCmdAnswer(newVol);
+ /* we assume the cache for templates is local */
+ } else if ((srcData.getObjectType() == DataObjectType.TEMPLATE)
+ && (destData.getObjectType() == DataObjectType.VOLUME)) {
+ if (srcStore.getUrl().equals(destStore.getUrl())) {
+ TemplateObjectTO srcTemplate = (TemplateObjectTO) srcData;
+ VolumeObjectTO dstVolume = (VolumeObjectTO) destData;
+
+ String srcFile = srcTemplate.getPath() + "/"
+ + srcTemplate.getUuid() + ".raw";
+ String vDisksPath = srcTemplate.getPath()
+ .replace("Templates", "VirtualDisks");
+ String destFile = vDisksPath + "/" + dstVolume.getUuid()
+ + ".raw";
+
+ Linux host = new Linux(c);
+ s_logger.debug("CopyFrom: " + srcData.getObjectType() + ","
+ + srcFile + " to " + destData.getObjectType() + ","
+ + destFile);
+ host.copyFile(srcFile, destFile);
+ VolumeObjectTO newVol = new VolumeObjectTO();
+ newVol.setUuid(dstVolume.getUuid());
+ newVol.setPath(vDisksPath);
+ newVol.setFormat(ImageFormat.RAW);
+ return new CopyCmdAnswer(newVol);
+ } else {
+ s_logger.debug("Primary to Primary doesn't match");
+ }
+ } else {
+ String msg = "Unable to do stuff for " + srcStore.getClass()
+ + ":" + srcData.getObjectType() + " to "
+ + destStore.getClass() + ":" + destData.getObjectType();
+ s_logger.debug(msg);
+ }
+ } catch (Exception e) {
+ String msg = "Catch Exception " + e.getClass().getName()
+ + " for template due to " + e.toString();
+ s_logger.warn(msg, e);
+ return new CopyCmdAnswer(msg);
+ }
+ return new CopyCmdAnswer("not implemented yet");
+ }
+
+ protected Answer execute(DeleteCommand cmd) {
+ DataTO data = cmd.getData();
+ s_logger.debug("Deleting object: " + data.getObjectType());
+ if (data.getObjectType() == DataObjectType.VOLUME) {
+ return deleteVolume(cmd);
+ } else if (data.getObjectType() == DataObjectType.SNAPSHOT) {
+
+ } else if (data.getObjectType() == DataObjectType.TEMPLATE) {
+
+ } else {
+
+ }
+ String msg = "Delete not implemented yet for this object";
+ s_logger.debug(msg);
+ return new Answer(cmd);
+ }
+
+ /* TODO: Create a Disk from a template needs cleaning */
+ protected CreateAnswer execute(CreateCommand cmd) {
+ StorageFilerTO primaryStorage = cmd.getPool();
+ DiskProfile disk = cmd.getDiskCharacteristics();
+
+ /* disk should have a uuid */
+ String fileName = UUID.randomUUID().toString() + ".img";
+ String dst = primaryStorage.getPath() + "/" + primaryStorage.getUuid()
+ + "/" + fileName;
+
+ try {
+ StoragePlugin store = new StoragePlugin(c);
+ store.setUuid(primaryStorage.getUuid());
+ store.setName(primaryStorage.getUserInfo());
+ store.setSsUuid(primaryStorage.getUserInfo());
+ if (cmd.getTemplateUrl() != null) {
+ s_logger.debug("CreateCommand " + cmd.getTemplateUrl() + " "
+ + dst);
+ Linux host = new Linux(c);
+ host.copyFile(cmd.getTemplateUrl(), dst);
+ } else {
+ /* this is a dup with the createVolume ? */
+ s_logger.debug("CreateCommand " + dst);
+ store.storagePluginCreate(primaryStorage.getUuid(),
+ primaryStorage.getHost(),
+ dst,
+ disk.getSize());
+ }
+
+ store.storagePluginGetFileInfo(dst);
+ VolumeTO volume = new VolumeTO(cmd.getVolumeId(), disk.getType(),
+ primaryStorage.getType(), primaryStorage.getUuid(),
+ primaryStorage.getPath(), fileName, store.getFileName(),
+ store.getFileSize(), null);
+ return new CreateAnswer(cmd, volume);
+ } catch (Exception e) {
+ s_logger.debug("CreateCommand failed", e);
+ return new CreateAnswer(cmd, e.getMessage());
+ }
+ }
+
+ /*
+ * Add rootdisk, datadisk and iso's
+ */
+ protected Boolean createVbds(Xen.Vm vm, VirtualMachineTO spec) {
+ for (DiskTO volume : spec.getDisks()) {
+ try {
+ if (volume.getType() == Volume.Type.ROOT) {
+ VolumeObjectTO vol = (VolumeObjectTO) volume.getData();
+ DataStoreTO ds = (DataStoreTO) vol.getDataStore();
+ String dsk = vol.getPath() + "/" + vol.getUuid() + ".raw";
+ vm.addRootDisk(dsk);
+ /* TODO: needs to be replaced by rootdiskuuid? */
+ vm.setPrimaryPoolUuid(ds.getUuid());
+ s_logger.debug("Adding root disk: " + dsk);
+ } else if (volume.getType() == Volume.Type.ISO) {
+ DataTO isoTO = volume.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 = setupSecondaryStorage(nfsStore
+ .getUrl());
+ String isoPath = this._ovmSec + File.separator
+ + secPoolUuid + File.separator
+ + template.getPath();
+ // + template.getUuid() + ".iso";
+ vm.addIso(isoPath);
+ /* check if secondary storage is mounted */
+ s_logger.debug("Adding ISO: " + isoPath);
+ }
+ } else if (volume.getType() == Volume.Type.DATADISK) {
+ vm.addDataDisk(volume.getData().getPath());
+ s_logger.debug("Adding data disk: "
+ + volume.getData().getPath());
+ } else {
+ throw new CloudRuntimeException("Unknown volume type: "
+ + volume.getType());
+ }
+ } catch (Exception e) {
+ s_logger.debug("CreateVbds failed", e);
+ throw new CloudRuntimeException("Exception" + e.getMessage(), e);
+ }
+ }
+ return true;
+ }
+
+ /* TODO: iptables/etables logic in the supporting libs ? */
+ protected Boolean createVifs(Xen.Vm vm, VirtualMachineTO spec) {
+ NicTO[] nics = spec.getNics();
+ for (NicTO nic : nics) {
+ if (nic.isSecurityGroupEnabled()) {
+ if (spec.getType().equals(VirtualMachine.Type.User)) {
+ /*
+ * defaultNetworkRulesForUserVm(vmName, vmSpec.getId(),
+ * nic);
+ */
+ }
+ }
+ try {
+ if (getNetwork(nic) != null)
+ vm.addVif(nic.getDeviceId(), getNetwork(nic), nic.getMac());
+ } catch (Exception e) {
+ String msg = "Unable to add vif " + nic.getType() + " for "
+ + spec.getName() + " " + e.getMessage();
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+ }
+ }
+ vm.setupVifs();
+ return true;
+ }
+
+ /*
+ * TODO: ovs calls ? depending on the type of network
+ * TODO: get the bridge on a per VM base so we can throw it away?
+ */
+ private String createVlanBridge(String networkName, Integer vlanId)
+ throws XmlRpcException {
+ if (vlanId < 2 || vlanId > 4094) {
+ throw new CloudRuntimeException("Vlan " + vlanId
+ + " needs to be between 1-4095");
+ }
+ 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);
+ String physVlanInt = physInterface + "." + vlanId;
+
+ if (net.getInterfaceByName(physVlanInt) == null)
+ net.startOvsVlanConfig(physInterface, vlanId);
+
+ if (net.getInterfaceByName(brName) == null)
+ net.startOvsBrConfig(brName, physVlanInt);
+ } catch (Exception e) {
+ throw new CloudRuntimeException("Unable to create vlan "
+ + vlanId.toString() + " bridge for " + networkName
+ + e.getMessage());
+ }
+ return brName;
+ }
+
+ // TODO: complete all network support
+ protected String getNetwork(NicTO nic) throws XmlRpcException {
+ 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
+ && !vlanId.equalsIgnoreCase("untagged")) {
+ bridgeName = createVlanBridge(_guestNetworkName,
+ Integer.valueOf(vlanId));
+ } else {
+ bridgeName = _guestNetworkName;
+ }
+ } else if (nic.getType() == TrafficType.Control) {
+ bridgeName = _controlNetworkName;
+ } else if (nic.getType() == TrafficType.Public) {
+ bridgeName = _publicNetworkName;
+ } else if (nic.getType() == TrafficType.Management) {
+ bridgeName = _privateNetworkName;
+ } else if (nic.getType() == TrafficType.Storage) {
+ /* TODO: Add storage network */
+ bridgeName = _storageNetworkName;
+ } else {
+ throw new CloudRuntimeException("Unknown network traffic type:"
+ + nic.getType());
+ }
+ return bridgeName;
+ }
+
+ /* This is not create for us, but really start */
+ protected boolean startVm(String repoId, String vmId)
+ throws XmlRpcException {
+ Xen host = new Xen(c);
+ try {
+ if (host.getRunningVmConfig(vmId) == null) {
+ s_logger.error("Create VM " + vmId + " first on " + c.getIp());
+ return false;
+ } else {
+ s_logger.info("VM " + vmId + " exists on " + c.getIp());
+ }
+ host.startVm(repoId, vmId);
+ } catch (Exception e) {
+ s_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 */
+ /*
+ * for (String vif : vifs) { if (vif.bridge.startsWith("vlan")) {
+ * Network net = new Network(c); net.ovsVlanBridgeStop(br, net, vlan);
+ * // Ovm3Bridge.deleteVlanBridge(_conn, vif.bridge); } }
+ */
+ }
+
+ protected void cleanup(Xen.Vm vm) {
+ try {
+ cleanupNetwork(vm.getVmVifs());
+ } catch (XmlRpcException e) {
+ s_logger.debug("Clean up network for " + vm.getVmName() + " failed",
+ e);
+ }
+ String vmName = vm.getVmName();
+ /* should become a single entity */
+ this._vmStats.remove(vmName);
+ }
+
+ /*
+ * TODO: The actual VM provisioning start to end, we can rip this from our
+ * simple stuff
+ */
+ @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 {
+ synchronized (this._vmstates) {
+ this._vmstates.put(vmName, State.Starting);
+ }
+ 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 = Ovm3Helper.getOvm3GuestType(vmSpec.getOs());
+ if (domType == null || domType.equals("")) {
+ domType = "default";
+ s_logger.debug("VM Virt type missing setting to: " + domType);
+ } else {
+ s_logger.debug("VM Virt type set to " + domType + " for "
+ + vmSpec.getOs());
+ }
+ vm.setVmDomainType(domType);
+ /* only for none user VMs? */
+ vm.setVmExtra(vmSpec.getBootArgs().replace(" ", "%"));
+
+ /* TODO: booting from CD... */
+ if (vmSpec.getBootloader() == BootloaderType.CD) {
+ // do something with this please...
+ }
+ /*
+ * officially CD boot is only supported on HVM, although there is a
+ * simple way around it..
+ */
+ /* TODO: pool uuid now comes from here should change! */
+ createVbds(vm, vmSpec);
+
+ if (vmSpec.getType() != VirtualMachine.Type.User) {
+ String svmPath = _ovmRepo + "/"
+ + _ovmObject.deDash(vm.getPrimaryPoolUuid()) + "/ISOs";
+ String svmIso = svmPath + "/"
+ + getSystemVMIsoFileNameOnDatastore();
+ vm.addIso(svmIso);
+ }
+ /* TODO: OVS should go here! */
+ createVifs(vm, vmSpec);
+
+ /* vm migration requires a 0.0.0.0 bind */
+ vm.setVncPassword(vmSpec.getVncPassword());
+ vm.setVncAddress("0.0.0.0");
+ vm.setVnc();
+
+ /* this should be getVmRootDiskPoolId ? */
+ 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();
+ }
+ }
+
+ try {
+ CloudStackPlugin cSp = new CloudStackPlugin(c);
+ for (int count = 0; count < 60; count++) {
+ Boolean res = cSp.domrCheckSsh(controlIp);
+ s_logger.debug("connected to " + controlIp
+ + " on attempt " + count + " result: " + res);
+ Thread.sleep(5000);
+ if (res) {
+ break;
+ }
+ /*
+ * Older xend issues in, took me a while to figure this
+ * out:
+ * ../xen/xend/XendConstants.py
+ * """Minimum time between domain restarts in seconds."""
+ * MINIMUM_RESTART_TIME = 60
+ * this does NOT work!!!--^^ as we respawn within 30
+ * seconds easily.
+ * return state stopped.
+ */
+ if (_vmstates.get(vmName) == null) {
+ String msg = "VM " + vmName + " went missing on "
+ + _host + ", returning stopped";
+ s_logger.debug(msg);
+ state = State.Stopped;
+ return new StartAnswer(cmd, msg);
+ }
+ }
+ } catch (Exception x) {
+ s_logger.debug("unable to connect to " + controlIp + " "
+ + x.getMessage());
+ }
+ }
+ /*
+ * TODO: Can't remember if HA worked if we were only a pool ?
+ */
+ if (_ovm3pool && _ovm3cluster) {
+ xen.configureVmHa(_ovmObject.deDash(vm.getPrimaryPoolUuid()),
+ vm.getVmUuid(),
+ true);
+ }
+ /* should be starting no ? */
+ state = State.Running;
+ return new StartAnswer(cmd);
+ } catch (Exception e) {
+ s_logger.debug("Start vm " + vmName + " failed", e);
+ state = State.Stopped;
+ // cleanup(vmDetails);
+ return new StartAnswer(cmd, e.getMessage());
+ } finally {
+ synchronized (this._vmstates) {
+ // FIXME: where to come to Stopped???
+ this._vmstates.put(vmName, state);
+ }
+ }
+ }
+
+ /* split out domr stuff later */
+ private GetDomRVersionAnswer execute(GetDomRVersionCmd cmd) {
+ String args = this.DefaultDomRPath + "get_template_version.sh";
+ String ip = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+ try {
+ CloudStackPlugin cSp = new CloudStackPlugin(c);
+ CloudStackPlugin.ReturnCode result;
+ result = cSp.domrExec(ip, args);
+ if (!result.getRc() || result.getStdOut().isEmpty()) {
+ return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd failed");
+ }
+ String domResp = result.getStdOut();
+ String[] lines = domResp.split("&");
+ if (lines.length != 2) {
+ return new GetDomRVersionAnswer(cmd, domResp);
+ }
+ return new GetDomRVersionAnswer(cmd, domResp, lines[0], lines[1]);
+ } catch (Exception e) {
+ return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd "
+ + e.getMessage());
+ }
+ }
+
+ private Answer giveDomRAns(Command cmd, String ip, String args, String resp) {
+ CloudStackPlugin cSp = new CloudStackPlugin(c);
+ try {
+ CloudStackPlugin.ReturnCode result = cSp.domrExec(ip, args);
+ if (!result.getRc()) {
+ return new Answer(cmd, false, result.getStdOut());
+ }
+ } catch (Exception e) {
+ return new Answer(cmd, false, e.getMessage());
+ }
+ return new Answer(cmd);
+ }
+
+ protected synchronized Answer execute(final DhcpEntryCommand cmd) {
+ String args = this.DefaultDomRPath + "edithosts.sh";
+ String ip = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+ if (cmd.getVmIpAddress() != null) {
+ args += " -4 " + cmd.getVmIpAddress();
+ }
+ args += " -m " + cmd.getVmMac();
+ args += " -n " + cmd.getVmName();
+ if (cmd.getDefaultRouter() != null) {
+ args += " -d " + cmd.getDefaultRouter();
+ }
+ if (cmd.getStaticRoutes() != null) {
+ args += " -s " + cmd.getStaticRoutes();
+ }
+
+ if (cmd.getDefaultDns() != null) {
+ args += " -N " + cmd.getDefaultDns();
+ }
+
+ if (cmd.getVmIp6Address() != null) {
+ args += " -6 " + cmd.getVmIp6Address();
+ args += " -u " + cmd.getDuid();
+ }
+
+ if (!cmd.isDefault()) {
+ args += " -z";
+ }
+
+ return giveDomRAns(cmd, ip, args, "DhcpEntry failed");
+ }
+
+ protected Answer execute(final SavePasswordCommand cmd) {
+ final String password = cmd.getPassword();
+ final String ip = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+ final String vmIpAddress = cmd.getVmIpAddress();
+ String args = this.DefaultDomRPath + "savepassword.sh ";
+ args += " -v " + vmIpAddress;
+ args += " -p " + password;
+ return giveDomRAns(cmd, ip, args, "SavePassword failed");
+ }
+
+ protected Answer execute(final VmDataCommand cmd) {
+ String ip = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+ Map<String, List<String[]>> data = new HashMap<String, List<String[]>>();
+ data.put(cmd.getVmIpAddress(), cmd.getVmData());
+ String json = new Gson().toJson(data);
+ json = Base64.encodeBase64String(json.getBytes());
+ String args = this.DefaultDomRPath + "vmdata.py -d " + json;
+ return giveDomRAns(cmd, ip, args, "Set vm_data failed");
+ }
+
+ /*
+ * we don't for now, gave an error on migration though....
+ */
+ private Answer execute(NetworkRulesSystemVmCommand cmd) {
+ boolean success = true;
+ if (_canBridgeFirewall) {
+ // meh
+ }
+ 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();
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Trying port " + privateIp + ":" + cmdPort);
+ }
+ try {
+ CloudStackPlugin cSp = new CloudStackPlugin(c);
+ if (!cSp.domrCheckPort(privateIp, cmdPort, retries, interval)) {
+ s_logger.info(vmName + ":" + cmdPort + " nok");
+ return new CheckSshAnswer(cmd, "unable to connect");
+ }
+ s_logger.info(vmName + ":" + cmdPort + " ok");
+ } catch (Exception e) {
+ s_logger.error("Can not reach port on System vm " + vmName
+ + " due to exception", e);
+ return new CheckSshAnswer(cmd, e);
+ }
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Ping command port succeeded for vm " + vmName + " "
+ + cmd);
+ }
+ if (VirtualMachineName.isValidRouterName(vmName)) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Execute network usage setup command on "
+ + vmName);
+ }
+ // TODO: check this one out...
+ }
+ return new CheckSshAnswer(cmd);
+ }
+
+ protected Answer execute(GetHostStatsCommand cmd) {
+ try {
+ CloudStackPlugin cSp = new CloudStackPlugin(c);
+ Map<String, String> stats = cSp.ovsDom0Stats(this._publicNetworkName);
+ 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) {
+ s_logger.debug("Get host stats of " + cmd.getHostName() + " failed",
+ e);
+ return new Answer(cmd, false, e.getMessage());
+ }
+ }
+
+ /* TODO: Stop the VM, this means cleanup too, should this be destroy ? */
+ @Override
+ public StopAnswer execute(StopCommand cmd) {
+ String vmName = cmd.getVmName();
+ State state = State.Error;
+ synchronized (this._vmstates) {
+ state = _vmstates.get(vmName);
+ this._vmstates.put(vmName, State.Stopping);
+ }
+
+ try {
+ Xen vms = new Xen(c);
+ Xen.Vm vm = null;
+ vm = vms.getRunningVmConfig(vmName);
+
+ if (vm == null) {
+ state = State.Stopping;
+ s_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";
+ s_logger.debug(msg);
+ tries--;
+ Thread.sleep(10 * 1000);
+ }
+ vms.deleteVm(repoId, vmId);
+ /* TODO: Check cleanup */
+ this.cleanup(vm);
+
+ if (vms.getRunningVmConfig(vmName) != null) {
+ String msg = "Stop " + vmName + " failed ";
+ s_logger.debug(msg);
+ return new StopAnswer(cmd, msg, false);
+ }
+ state = State.Stopped;
+ return new StopAnswer(cmd, "success", true);
+ } catch (Exception e) {
+ /* TODO: check output of message, might be that it did get removed */
+ s_logger.debug("Stop " + vmName + " failed ", e);
+ return new StopAnswer(cmd, e.getMessage(), false);
+ } finally {
+ synchronized (this._vmstates) {
+ if (state != null) {
+ this._vmstates.put(vmName, state);
+ } else {
+ this._vmstates.remove(vmName);
+ }
+ }
+ }
+ }
+
+ /* Reboot the VM and destroy should call the same method in here ? */
+ @Override
+ public RebootAnswer execute(RebootCommand cmd) {
+ String vmName = cmd.getVmName();
+
+ synchronized (this._vmstates) {
+ this._vmstates.put(vmName, State.Starting);
+ }
+
+ try {
+ Xen xen = new Xen(c);
+ Xen.Vm vm = xen.getRunningVmConfig(vmName);
+ /* TODO: stop, start or reboot, reboot for now ? */
+ xen.rebootVm(_ovmObject.deDash(vm.getVmRootDiskPoolId()),
+ vm.getVmUuid());
+ vm = xen.getRunningVmConfig(vmName);
+ /* erh but this don't work, should point at cloudstackplugin */
+ Integer vncPort = vm.getVncPort();
+ return new RebootAnswer(cmd, null, vncPort);
+ } catch (Exception e) {
+ s_logger.debug("Reboot " + vmName + " failed", e);
+ return new RebootAnswer(cmd, e.getMessage(), false);
+ } finally {
+ synchronized (this._vmstates) {
+ this._vmstates.put(cmd.getVmName(), State.Running);
+ }
+ }
+ }
+
+ protected State convertPowerToState(PowerState ps) {
+ final State state = s_stateMaps.get(ps.toString());
+ return state == null ? State.Unknown : state;
+ }
+
+ private static PowerState convertStateToPower(State s) {
+ final PowerState state = s_powerStateMaps.get(s.toString());
+ return state == null ? PowerState.PowerUnknown : state;
+ }
+
+ /* State to power in the states */
+ protected Map<String, HostVmStateReportEntry> HostVmStateReport()
+ throws XmlRpcException {
+ final HashMap<String, HostVmStateReportEntry> vmStates = new HashMap<String, HostVmStateReportEntry>();
+ Map<String, State> vms = sync();
+ for (final Map.Entry<String, State> vm : vms.entrySet()) {
+ /* TODO: Figure out how to get xentools version in here */
+ s_logger.debug("VM " + vm.getKey() + " state: " + vm.getValue()
+ + ":" + convertStateToPower(vm.getValue()));
+ vmStates.put(vm.getKey(), new HostVmStateReportEntry(
+ convertStateToPower(vm.getValue()), c.getIp(), null));
+ }
+ return vmStates;
+ }
+
+ /* uses the running configuration, not the vm.cfg configuration */
+ protected Map<String, Xen.Vm> getAllVms() throws XmlRpcException {
+ try {
+ Xen vms = new Xen(c);
+ return vms.getRunningVmConfigs();
+ } catch (Exception e) {
+ s_logger.debug("getting VM list from " + _host + " failed", e);
+ throw new CloudRuntimeException("Exception on getting VMs from "
+ + _host + ":" + e.getMessage(), e);
+ }
+ }
+
+ /*
+ * Get all the states and set them up according to xm(1)
+ * TODO: check migrating ?
+ */
+ protected HashMap<String, State> getAllVmStates() throws XmlRpcException {
+ Map<String, Xen.Vm> vms = getAllVms();
+ final HashMap<String, State> states = new HashMap<String, State>();
+ for (final Map.Entry<String, Xen.Vm> entry : vms.entrySet()) {
+ Xen.Vm vm = entry.getValue();
+ if (vm.isControlDomain()) {
+ continue;
+ }
+ State ns = State.Running;
+ String as = vm.getVmState();
+ /* missing VM is stopped */
+ if (as == null) {
+ ns = State.Stopped;
+ 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 (this._vmstates.get(vm.getVmName()) == State.Migrating)
+ ns = State.Migrating;
+ 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;
+ }
+ s_logger.debug("state " + ns + " for " + vm.getVmName()
+ + " based on " + as);
+ states.put(vm.getVmName(), ns);
+ }
+ return states;
+ }
+
+ /* sync the state we know of with reality */
+ protected HashMap<String, State> sync() {
+ HashMap<String, State> newStates;
+ HashMap<String, State> oldStates = null;
+
+ try {
+ final HashMap<String, State> changes = new HashMap<String, State>();
+ newStates = getAllVmStates();
+ if (newStates == null) {
+ s_logger.debug("Unable to get the vm states so no state sync at this point.");
+ return null;
+ }
+
+ synchronized (_vmstates) {
+ oldStates = new HashMap<String, State>(_vmstates.size());
+ oldStates.putAll(_vmstates);
+
+ for (final Map.Entry<String, State> entry : newStates
+ .entrySet()) {
+ final String vmName = entry.getKey();
+ State newState = entry.getValue();
+ final State oldState = oldStates.remove(vmName);
+ s_logger.debug("state for " + vmName + ", old: " + oldState
+ + ", new: " + newState);
+
+ /* eurh ? */
+ if (newState == State.Stopped && oldState != State.Stopping
+ && oldState != null && oldState != State.Stopped) {
+ s_logger.debug("Getting power state....");
+ newState = State.Running;
+ }
+
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("VM "
+ + vmName
+ + ": ovm has state "
+ + newState
+ + " and we have state "
+ + (oldState != null ? oldState.toString()
+ : "null"));
+ }
+
+ /* TODO: is this really true ? should be right ? */
+ if (newState == State.Migrating) {
+ s_logger.debug(vmName
+ + " is migrating, skipping state check");
+ continue;
+ }
+
+ if (oldState == null) {
+ _vmstates.put(vmName, newState);
+ s_logger.debug("New state without old state: " + vmName);
+ changes.put(vmName, newState);
+ } else if (oldState == State.Starting) {
+ if (newState == State.Running) {
+ _vmstates.put(vmName, newState);
+ } else if (newState == State.Stopped) {
+ s_logger.debug("Ignoring vm " + vmName
+ + " because of a lag in starting the vm.");
+ }
+ } else if (oldState == State.Migrating) {
+ if (newState == State.Running) {
+ s_logger.debug("Detected that a migrating VM is now running: "
+ + vmName);
+ _vmstates.put(vmName, newState);
+ }
+ } else if (oldState == State.Stopping) {
+ if (newState == State.Stopped) {
+ _vmstates.put(vmName, newState);
+ } else if (newState == State.Running) {
+ s_logger.debug("Ignoring vm " + vmName
+ + " because of a lag in stopping the vm. ");
+ }
+ } else if (oldState != newState) {
+ _vmstates.put(vmName, newState);
+ if (newState == State.Stopped) {
+ // TODO: need to state.error here ?
+ }
+ 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) {
+ s_logger.debug("Removing VM " + vmName
+ + " in transition state stopping.");
+ _vmstates.remove(vmName);
+ } else if (oldState == State.Starting) {
+ s_logger.debug("Removing VM " + vmName
+ + " in transition state starting.");
+ _vmstates.remove(vmName);
+ } else if (oldState == State.Stopped) {
+ s_logger.debug("Stopped VM " + vmName + " removing.");
+ _vmstates.remove(vmName);
+ } else if (oldState == State.Migrating) {
+ /*
+ * do something smarter here.. newstate should
+ * say stopping already
+ */
+ s_logger.debug("Ignoring VM " + vmName
+ + " in migrating state.");
+ } else {
+ /* if it's not there name it stopping */
+ _vmstates.remove(vmName);
+ State state = State.Stopping;
+ s_logger.debug("VM "
+ + vmName
+ + " is now missing from ovm3 server so removing it");
+ /* TODO: something about killed/halted VM's in here ? */
+ changes.put(vmName, state);
+ }
+ }
+ }
+
+ return changes;
+ } catch (Exception e) {
+ s_logger.debug("Ovm3 full sync failed", e);
+ return null;
+ }
+ }
+
+ /* cleanup the storageplugin so we can use an object here */
+ protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
+ // cmd.getStorageId();
+ s_logger.debug("Getting stats for: " + cmd.getStorageId());
+ try {
+ Linux host = new Linux(c);
+
<TRUNCATED>
[5/7] CLOUDSTACK-6967: Now with module!
Posted by se...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/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..22c9fe0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/pom.xml
@@ -0,0 +1,36 @@
+<!--
+ 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.4.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>xapi</artifactId>
+ <version>${cs.xapi.version}</version>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/module.properties
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/module.properties b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/module.properties
new file mode 100644
index 0000000..69e6469
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
new file mode 100644
index 0000000..42230c9
--- /dev/null
+++ b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
@@ -0,0 +1,39 @@
+<!--
+ 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.hypervisor.Ovm3Fencer">
+ <property name="name" value="Ovm3FenceBuilder" />
+ </bean>
+
+ <bean id="Ovm3Guru" class="com.cloud.hypervisor.ovm3.hypervisor.Ovm3Guru">
+ <property name="name" value="Ovm3Guru" />
+ </bean>
+
+
+</beans>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/module.properties
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/module.properties b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/module.properties
new file mode 100644
index 0000000..025d4cf
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml
new file mode 100644
index 0000000..aa76271
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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.hypervisor.Ovm3Discoverer">
+ <property name="name" value="Ovm3Discover" />
+ </bean>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/scripts/clean_master.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/clean_master.sh b/plugins/hypervisors/ovm3/scripts/clean_master.sh
new file mode 100755
index 0000000..bbf1cd0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/scripts/clean_slave.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/clean_slave.sh b/plugins/hypervisors/ovm3/scripts/clean_slave.sh
new file mode 100755
index 0000000..6d46859
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/clean_slave.sh
@@ -0,0 +1,33 @@
+#!/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
+
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/scripts/create_pool_cluster.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/create_pool_cluster.py b/plugins/hypervisors/ovm3/scripts/create_pool_cluster.py
new file mode 100755
index 0000000..15c9a97
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/scripts/info.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/info.py b/plugins/hypervisors/ovm3/scripts/info.py
new file mode 100755
index 0000000..518aaf1
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py b/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py
new file mode 100644
index 0000000..f655760
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py
@@ -0,0 +1,344 @@
+#!/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 logging
+import time
+import re
+import os.path
+import paramiko
+import subprocess
+import socket
+
+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_domr_ssh': domrCheckSsh,
+ 'ovs_control_interface': ovsControlInterface,
+ 'ovs_mkdir': ovsMkdir,
+ 'ovs_check_file': ovsCheckFile,
+ 'ovs_upload_ssh_key': ovsUploadSshKey,
+ 'ovs_dom0_stats': ovsDom0Stats,
+ 'ovs_domU_stats': ovsDomUStats,
+ 'get_module_version': getModuleVersion,
+ 'ping': ping,
+# 'ovs_agent_set_ssl': ovsAgentSetSsl,
+# 'ovs_agent_set_port': ovsAgentSetPort,
+# 'ovs_restart_agent': ovsRestartAgent,
+ }
+
+ def getName(self):
+ return self.__class__.__name__
+
+# which version are we intended for?
+def getModuleVersion():
+ return "0.1"
+
+# call test
+def call(msg):
+ return msg
+
+# execute something on domr
+def domrExec(ip, cmd, timeout=10, username="root", port=3922, keyfile="~/.ssh/id_rsa.cloud"):
+ ssh = paramiko.SSHClient()
+ ssh.load_system_host_keys()
+ ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+ privatekeyfile = os.path.expanduser(keyfile)
+ key = paramiko.RSAKey.from_private_key_file(privatekeyfile)
+ ssh.connect(ip, port, username, pkey=key, 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()) };
+
+# check a port on domr
+def domrPort(ip, port=3922, timeout=3):
+ return domrCheckPort(ip, port, timeout=timeout)
+
+# check a port on domr
+def domrCheckPort(ip, port=3922, timeout=3):
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.settimeout(timeout)
+ s.connect((ip, port))
+ s.close()
+ return True
+ except:
+ return False
+
+# check ssh
+def domrCheckSsh(ip, port=3922, timeout=10):
+ x = domrExec(ip, "", port=port, timeout=timeout)
+ if (x.get("rc") == 0):
+ return True
+ return False
+
+def _ovsIni(setting, set):
+ ini="/etc/ovs-agent/agent.ini"
+ replaced=False
+ if os.path.isfile(ini):
+ import fileinput
+ for line in fileinput.FileInput(ini, inplace=1):
+ line=line.rstrip('\n')
+ if re.search("%s=" % setting, line):
+ line="%s=%s" % (setting, set)
+ replaced=True
+ print line
+ return replaced
+
+# 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")
+
+# 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, ipmask):
+ command = ['route', 'del', '-net', ipmask];
+ subprocess.call(command, shell=False)
+ command = ['ifconfig', dev, 'arp']
+ subprocess.call(command, shell=False)
+ return True
+
+# create a dir if we need it
+def ovsMkdir(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
+
+# upload keys
+def ovsUploadSshKey(keyfile, content):
+ keydir=os.path.expanduser("~/.ssh")
+ key="%s/%s" % (keydir, keyfile)
+ try:
+ ovsMkdir(os.path.expanduser(keydir))
+ except Error, v:
+ print "was already there %s" % keydir
+
+ try:
+ text_file = open("%s" % key, "w")
+ text_file.write("%s" % content)
+ text_file.close()
+ except Error, v:
+ print "something went wrong %s" % v
+ return False
+ return True
+
+
+# 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
+
+ # get options
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "sp::",
+ [ 'port=','ssl='])
+ except getopt.GetoptError:
+ print "Available Options: --port=, --ssl="
+ sys.exit()
+
+ for o, a in opts:
+ if o in ('-s', '--ssl'):
+ ssl = a
+ if o in ('-p', '--port'):
+ port = int(a)
+
+ # 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
+ ovsRestartAgent()
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/scripts/password.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/password.py b/plugins/hypervisors/ovm3/scripts/password.py
new file mode 100755
index 0000000..25404a9
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/scripts/repo_pool.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/repo_pool.py b/plugins/hypervisors/ovm3/scripts/repo_pool.py
new file mode 100755
index 0000000..71feca8
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/scripts/simple_pool.py
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/simple_pool.py b/plugins/hypervisors/ovm3/scripts/simple_pool.py
new file mode 100755
index 0000000..756de93
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/scripts/socat.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/socat.sh b/plugins/hypervisors/ovm3/scripts/socat.sh
new file mode 100755
index 0000000..c3fbc44
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/scripts/tail.sh
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/scripts/tail.sh b/plugins/hypervisors/ovm3/scripts/tail.sh
new file mode 100755
index 0000000..fe88bc0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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/1516b041/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java b/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java
new file mode 100644
index 0000000..980fa1f
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java
@@ -0,0 +1,81 @@
+/*
+ * 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 final static Logger s_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) {
+ Status status = isAgentAlive(host);
+ if (status == null) {
+ return null;
+ }
+ return status == Status.Up ? true : null;
+ }
+
+ @Override
+ public Status isAgentAlive(Host agent) {
+ 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) {
+ s_logger.debug("Failed to send command to host: " + neighbor.getId());
+ }
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java
new file mode 100755
index 0000000..bd1d90d
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java
@@ -0,0 +1,411 @@
+// 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.hypervisor;
+
+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 org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.agent.Listener;
+import com.cloud.agent.AgentManager;
+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.host.Status;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.ClusterDetailsDao;
+// import com.cloud.exception.DiscoveryException;
+import com.cloud.host.HostInfo;
+import com.cloud.host.HostVO;
+import com.cloud.host.Host;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.ovm3.object.Linux;
+import com.cloud.hypervisor.ovm3.object.Connection;
+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 s_logger = Logger
+ .getLogger(Ovm3Discoverer.class);
+ protected String _publicNetworkDevice;
+ protected String _privateNetworkDevice;
+ protected String _guestNetworkDevice;
+ protected String _storageNetworkDevice;
+ private String _ovsAgentPath = "/etc/ovs-agent/agent.ini";
+
+ @Inject
+ ClusterDao _clusterDao;
+ @Inject
+ ClusterDetailsDao _clusterDetailsDao;
+ @Inject
+ ResourceManager _resourceMgr;
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ HostDao _hostDao = null;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+ super.configure(name, params);
+ /* 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;
+ }
+
+ protected Ovm3Discoverer() {
+ }
+
+ @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();
+ }
+
+ @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 CloudRuntimeException {
+ Connection c = null;
+
+ if (url.getScheme().equals("http") || url.getScheme().equals("https")) {
+ String msg = "Discovering " + url
+ + ": " + _params;
+ s_logger.debug(msg);
+ } else {
+ String msg = "urlString is not http(s) so we're not taking care of the discovery for this: "
+ + url;
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ if (clusterId == null) {
+ String msg = "must specify cluster Id when add host";
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ if (podId == null) {
+ String msg = "must specify pod Id when add host";
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(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";
+ s_logger.info(msg);
+ throw new CloudRuntimeException(msg);
+ } else {
+ s_logger.info("cluster: " + cluster);
+ }
+
+ String agentUsername = _params.get("agentusername");
+ if (agentUsername == null) {
+ String msg = "Agent user name must be specified";
+ s_logger.info(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ String agentPassword = _params.get("agentpassword");
+ if (agentPassword == null) {
+ String msg = "Agent password must be specified";
+ s_logger.info(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ String agentPort = _params.get("agentport");
+ if (agentPort == null) {
+ String msg = "Agent port must be specified";
+ s_logger.info(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ try {
+ String hostname = url.getHost();
+ /* port = url.getPort(); */
+
+ InetAddress ia = InetAddress.getByName(hostname);
+ String hostIp = ia.getHostAddress();
+ String guid = UUID.nameUUIDFromBytes(hostIp.getBytes()).toString();
+
+ if (checkIfExisted(guid)) {
+ String msg = "The host " + hostIp + " has been added before";
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ s_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 = String.format("Cannot connect to Ovm3 host(IP=%1$s, username=%2$s, password=*******), discovery failed",
+ hostIp, username);
+ s_logger.warn(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ Map<String, String> details = new HashMap<String, String>();
+ Ovm3ResourceBase ovmResource = new Ovm3ResourceBase();
+ 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);
+ }
+ s_logger.warn("network devices: " + _guestNetworkDevice + " "
+ + _privateNetworkDevice + " " + _publicNetworkDevice + " "
+ + _storageNetworkDevice);
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.putAll(details);
+
+ ovmResource.configure(hostname, params);
+ ovmResource.start();
+
+ try {
+ c = new Connection(hostIp, Integer.parseInt(agentPort), agentUsername, agentPassword);
+ } catch (Exception e) {
+ String msg = String.format("Cannot connect to Ovm3 agent(IP=%1$s, Port=%1$, username=%3$s, password=*******), discovery failed",
+ hostIp, agentPort, agentUsername);
+ s_logger.warn(msg);
+ throw new CloudRuntimeException(msg);
+ }
+ /* 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<Ovm3ResourceBase, Map<String, String>> resources = new HashMap<Ovm3ResourceBase, Map<String, String>>();
+ resources.put(ovmResource, details);
+ return resources;
+ } catch (XmlRpcException e) {
+ s_logger.debug("XmlRpc exception, Unable to discover Ovm3 host: " + url.getHost(),
+ e);
+ return null;
+ } catch (UnknownHostException e) {
+ s_logger.debug(
+ "Host name resolve failed exception, Unable to discover Ovm3 host: "
+ + url.getHost(), e);
+ return null;
+ } catch (ConfigurationException e) {
+ s_logger.debug(
+ "Configure resource failed, Unable to discover Ovm3 host: " + url.getHost(),
+ e);
+ return null;
+ } catch (Exception e) {
+ s_logger.debug("Unable to discover Ovm3 host: " + url.getHost(), e);
+ return null;
+ }
+ }
+
+ @Override
+ public void postDiscovery(List<HostVO> hosts, long msId)
+ throws CloudRuntimeException {
+ // TODO Auto-generated method stub
+ s_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) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean processCommands(long agentId, long seq, Command[] commands) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public AgentControlAnswer processControlCommand(long agentId,
+ AgentControlCommand cmd) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* for reconnecting */
+ @Override
+ public void processConnect(Host host, StartupCommand cmd,
+ boolean forRebalance) {
+ }
+
+ @Override
+ public boolean processDisconnect(long agentId, Status state) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isRecurring() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public int getTimeout() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public boolean processTimeout(long agentId, long seq) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public HostVO createHostVOForDirectConnectAgent(HostVO host,
+ StartupCommand[] startup, ServerResource resource,
+ Map<String, String> details, List<String> hostTags) {
+ StartupCommand firstCmd = startup[0];
+ if (!(firstCmd instanceof StartupRoutingCommand)) {
+ return null;
+ }
+
+ StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd);
+ if (ssCmd.getHypervisorType() != HypervisorType.Ovm3) {
+ return null;
+ }
+
+ // TODO: Double check this
+ return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.Ovm3,
+ details, hostTags);
+ }
+
+ // TODO: Make sure that we cleanup when the host is removed
+ @Override
+ public DeleteHostAnswer deleteHost(HostVO host, boolean isForced,
+ boolean isForceDeleteStorage) throws UnableDeleteHostException {
+ if (host.getType() != com.cloud.host.Host.Type.Routing
+ || host.getHypervisorType() != HypervisorType.Ovm3) {
+ return null;
+ }
+
+ _resourceMgr.deleteRoutingHost(host, isForced, isForceDeleteStorage);
+ return new DeleteHostAnswer(true);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java
new file mode 100755
index 0000000..30db663
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java
@@ -0,0 +1,133 @@
+// 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.hypervisor;
+
+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 Ovm3Fencer extends AdapterBase implements FenceBuilder {
+ Map<String, Object> _params;
+ private static final Logger s_logger = Logger.getLogger(Ovm3Fencer.class);
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ ResourceManager _resourceMgr;
+
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+ _params = params;
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ public Ovm3Fencer() {
+ super();
+ }
+
+ @Override
+ public Boolean fenceOff(VirtualMachine vm, Host host) {
+ if (host.getHypervisorType() != HypervisorType.Ovm3) {
+ s_logger.debug("Don't know how to fence non Ovm3 hosts "
+ + host.getHypervisorType());
+ return null;
+ } else {
+ s_logger.debug("Fencing " + vm + " on host " + host
+ + " with params: "+ _params );
+ }
+
+ List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host
+ .getClusterId());
+ FenceCommand fence = new FenceCommand(vm, host);
+
+ for (HostVO h : hosts) {
+ if (h.getHypervisorType() != HypervisorType.Ovm3) {
+ continue;
+ }
+
+ if (h.getStatus() != Status.Up) {
+ continue;
+ }
+
+ if (h.getId() == host.getId()) {
+ continue;
+ }
+
+ FenceAnswer answer;
+ try {
+ answer = (FenceAnswer) _agentMgr.send(h.getId(), fence);
+ } catch (AgentUnavailableException e) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Moving on to the next host because "
+ + h.toString() + " is unavailable");
+ }
+ continue;
+ } catch (OperationTimedoutException e) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Moving on to the next host because "
+ + h.toString() + " is unavailable");
+ }
+ continue;
+ }
+
+ if (answer != null && answer.getResult()) {
+ return true;
+ }
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Unable to fence off " + vm.toString() + " on "
+ + host.toString());
+ }
+
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java
new file mode 100755
index 0000000..08aac30
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java
@@ -0,0 +1,65 @@
+// 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.
+
+/* shameless rip from original ovm guru */
+package com.cloud.hypervisor.ovm3.hypervisor;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+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.vm.VirtualMachineProfile;
+
+@Local(value = HypervisorGuru.class)
+public class Ovm3Guru extends HypervisorGuruBase implements HypervisorGuru {
+ // private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
+
+ @Inject
+ GuestOSDao _guestOsDao;
+
+ protected Ovm3Guru() {
+ 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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java
new file mode 100755
index 0000000..8b0b1b5
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java
@@ -0,0 +1,82 @@
+// 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.hypervisor;
+
+import java.util.HashMap;
+
+public class Ovm3Helper {
+ /* /usr/lib64/python2.4/site-packages/agent/lib/assembly */
+ private static final HashMap<String, String> s_ovmMap = new HashMap<String, String>();
+
+ public static final String HVM = "hvm";
+ public static final String PV = "xen_pvm";
+ public static final String DOMSOL = "ldoms_pvm";
+ public static final String DEFAULT = "default";
+
+ static {
+ s_ovmMap.put("Oracle Enterprise Linux 6.0 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 6.0 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.0 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.0 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.1 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.1 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.2 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.2 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.3 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.3 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.4 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.4 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.5 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.5 (64-bit)", PV);
+ s_ovmMap.put("Other Linux (32-bit)", PV);
+ s_ovmMap.put("Other Linux (64-bit)", PV);
+ s_ovmMap.put("Other PV (32-bit)", PV);
+ s_ovmMap.put("Other PV (64-bit)", PV);
+ s_ovmMap.put("Debian GNU/Linux 7(32-bit)", PV);
+ s_ovmMap.put("Debian GNU/Linux 7(64-bit)", PV);
+ s_ovmMap.put("Linux HVM (32-bit)", HVM);
+ s_ovmMap.put("Linux HVM (64-bit)", HVM);
+ s_ovmMap.put("Dos", HVM);
+ s_ovmMap.put("Windows 7 (32-bit)", HVM);
+ s_ovmMap.put("Windows 7 (64-bit)", HVM);
+ s_ovmMap.put("Windows 8 (64-bit)", HVM);
+ s_ovmMap.put("Windows Server 2003 (32-bit)", HVM);
+ s_ovmMap.put("Windows Server 2003 (64-bit)", HVM);
+ s_ovmMap.put("Windows Server 2008 (32-bit)", HVM);
+ s_ovmMap.put("Windows Server 2008 (64-bit)", HVM);
+ s_ovmMap.put("Windows Server 2008 R2 (64-bit)", HVM);
+ s_ovmMap.put("Windows Server 2012 (64-bit)", HVM);
+ s_ovmMap.put("Windows 2000 SP4 (32-bit)", HVM);
+ s_ovmMap.put("Windows Vista (32-bit)", HVM);
+ s_ovmMap.put("Windows XP SP2 (32-bit)", HVM);
+ s_ovmMap.put("Windows XP SP3 (32-bit)", HVM);
+ s_ovmMap.put("Sun Solaris 10(32-bit)", HVM);
+ s_ovmMap.put("Sun Solaris 10(64-bit)", HVM);
+ s_ovmMap.put("Sun Solaris 9(Experimental)", HVM);
+ s_ovmMap.put("Sun Solaris 8(Experimental)", HVM);
+ s_ovmMap.put("Sun Solaris 11 (32-bit)", HVM);
+ s_ovmMap.put("Sun Solaris 11 (64-bit)", HVM);
+ s_ovmMap.put("Sun Solaris PV (32-bit)", PV);
+ s_ovmMap.put("Sun Solaris PV (64-bit)", PV);
+ s_ovmMap.put("Sun Solaris Sparc (32-bit)", DOMSOL);
+ s_ovmMap.put("Sun Solaris Sparc (64-bit)", DOMSOL);
+ }
+
+ public static String getOvm3GuestType(String stdType) {
+ return s_ovmMap.get(stdType);
+ }
+}
[3/7] CLOUDSTACK-6967: Now with module!
Posted by se...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/CloudStackPlugin.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/CloudStackPlugin.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/CloudStackPlugin.java
new file mode 100644
index 0000000..94275f4
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/CloudStackPlugin.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+public class CloudStackPlugin extends OvmObject {
+
+ public CloudStackPlugin(Connection c) {
+ client = c;
+ }
+
+ public String getVncPort(String vmName) throws XmlRpcException {
+ String x = (String) callWrapper("get_vncport", vmName);
+ return x;
+ }
+
+ public boolean ovsUploadSshKey(String key, String content)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_upload_ssh_key", key, content);
+ if (x==null) {
+ return false;
+ }
+ return true;
+ }
+
+ public class ReturnCode {
+ private Map<String, Object> _rc = new HashMap<String, Object>() {
+ {
+ put("rc", null);
+ put("exit", null);
+ put("err", null);
+ put("out", null);
+ }
+ };
+ public void setValues(Map<String, String> m) {
+ this._rc.putAll(m);
+ }
+ public Boolean getRc() {
+ try {
+ Long rc = (Long) _rc.get("rc");
+ _rc.put("exit", rc);
+ if (rc != 0)
+ return false;
+ return true;
+ } catch (Exception e) {
+
+ }
+ return false;
+ }
+ public String getStdOut() {
+ return (String) _rc.get("out");
+ }
+ public String getStdErr() {
+ return (String) _rc.get("err");
+ }
+ public Integer getExit() {
+ if (_rc.get("exit") == null)
+ _rc.put("exit", _rc.get("rc"));
+ return Integer.valueOf((String) _rc.get("exit"));
+ }
+ }
+ public ReturnCode domrExec(String ip, String cmd) throws XmlRpcException {
+ ReturnCode rc = new ReturnCode();
+ rc.setValues((Map<String, String>) callWrapper("exec_domr", ip, cmd));
+ return rc;
+ }
+
+ public boolean domrCheckPort(String ip, Integer port, Integer retries, Integer interval)
+ throws XmlRpcException, InterruptedException {
+ Boolean x= false;
+ /* should deduct the interval from the timeout and sleep on it */
+ Integer sleep=interval;
+ while(x == false && retries > 0) {
+ x = (Boolean) callWrapper("check_domr_port", ip, port, interval);
+ retries--;
+ Thread.sleep(sleep * 1000);
+ }
+ return x;
+ }
+
+ public Map<String, String> ovsDom0Stats(String bridge) throws XmlRpcException {
+ Map<String, String> stats = (Map<String, String>)
+ callWrapper("ovs_dom0_stats", bridge);
+ return stats;
+ }
+
+
+ public Map<String, String> ovsDomUStats(String domain) throws XmlRpcException {
+ Map<String, String> stats = (Map<String, String>)
+ callWrapper("ovs_domU_stats", domain);
+ return stats;
+ }
+ public boolean domrCheckPort(String ip, Integer port) throws XmlRpcException {
+ Object x = callWrapper("check_domr_port", ip, port);
+ return (Boolean) x;
+ }
+
+ public boolean domrCheckSsh(String ip) throws XmlRpcException {
+ Object x = callWrapper("check_domr_ssh", ip);
+ return (Boolean) x;
+ }
+
+ public boolean ovsControlInterface(String dev, String ipmask) throws XmlRpcException {
+ Object x = callWrapper("ovs_control_interface", dev, ipmask);
+ return (Boolean) x;
+ }
+
+ public boolean ping(String host) throws XmlRpcException {
+ Object x = callWrapper("ping", host);
+ return (Boolean) x;
+ }
+
+ public boolean ovsCheckFile(String file) throws XmlRpcException {
+ Object x = callWrapper("ovs_check_file", file);
+ return (Boolean) x;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Cluster.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Cluster.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Cluster.java
new file mode 100644
index 0000000..703f8a2
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Cluster.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Cluster extends OvmObject {
+
+ public Cluster(Connection c) {
+ client = c;
+ }
+
+ /*
+ * leave_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+ * self - default: None argument: poolfsUuid - default: None
+ */
+ public Boolean leaveCluster(String poolfsUuid) throws XmlRpcException {
+ Object x = callWrapper("leave_cluster", poolfsUuid);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Object x = callWrapper("configure_server_for_cluster", poolfsUuid);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * deconfigure_server_for_cluster, <class
+ * 'agent.api.cluster.o2cb.ClusterO2CB'> argument: self - default: None
+ * argument: poolfsUuid - default: None
+ */
+ public Boolean deconfigureServerForCluster(String poolfsUuid)
+ throws XmlRpcException {
+ Object x = callWrapper("deconfigure_server_for_cluster", poolfsUuid);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * join_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument: self
+ * - default: None argument: poolfsUuid - default: None
+ */
+ public Boolean joinCLuster(String poolfsUuid) throws XmlRpcException {
+ Object x = callWrapper("join_cluster", poolfsUuid);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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>
+ */
+ /* returns xml - sigh */
+ public Boolean discoverCluster() throws XmlRpcException {
+ Object x = callWrapper("discover_cluster");
+ // System.out.println(x);
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Object x = callWrapper("update_clusterConfiguration", clusterConf);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * destroy_cluster, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+ * self - default: None argument: poolfsUuid - default: None
+ */
+ public Boolean destroyCluster(String poolfsUuid) throws XmlRpcException {
+ Object x = callWrapper("destroy_cluster", poolfsUuid);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * is_cluster_online, <class 'agent.api.cluster.o2cb.ClusterO2CB'> argument:
+ * self - default: None
+ */
+ public Boolean isClusterOnline() throws XmlRpcException {
+ 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 XmlRpcException {
+ Object x = callWrapper("create_cluster", poolfsUuid);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Common.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Common.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Common.java
new file mode 100644
index 0000000..ca24748
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Common.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Common extends OvmObject {
+ public String apiVersion;
+
+ public Common(Connection c) {
+ client = c;
+ }
+
+ /*
+ * get_api_version, <class 'agent.api.common.Common'>
+ */
+ public String getApiVersion() throws XmlRpcException {
+ return callString("get_api_version");
+
+ }
+
+ /*
+ * sleep, <class 'agent.api.common.Common'> argument: secs - default: None
+ */
+ public String sleep(int seconds) throws XmlRpcException {
+ return callString("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 XmlRpcException {
+ return callString("dispatch", url, function, args);
+ }
+
+ /*
+ * echo, <class 'agent.api.common.Common'> argument: msg - default: None
+ */
+ public String echo(String msg) throws XmlRpcException {
+ return callString("echo", msg);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Connection.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Connection.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Connection.java
new file mode 100644
index 0000000..53a8e10
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Connection.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+import java.net.URL;
+import java.util.TimeZone;
+import java.util.Vector;
+
+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;
+
+public class Connection extends XmlRpcClient {
+ private static final Logger s_logger = Logger.getLogger(Connection.class);
+ private final XmlRpcClientConfigImpl _config = new XmlRpcClientConfigImpl();
+ private XmlRpcClient _client;
+ private String _username;
+ private String _password;
+ private String _ip;
+ private Integer _port = 8898;
+ private Boolean _isSsl = false;
+ private String cert = "";
+ private String key = "";
+ private Integer timeout = 1200; /* seconds */
+ private Integer _timeout = timeout * 1000; /* native is ms */
+
+ private XmlRpcClient getXmlClient() throws XmlRpcException {
+ // check ssl boolean
+ final XmlRpcClient client = new XmlRpcClient();
+
+ URL url;
+ try {
+ // here too
+ url = new URL("http://" + _ip + ":" + _port.toString());
+ _config.setTimeZone(TimeZone.getTimeZone("UTC"));
+ _config.setServerURL(url);
+ _config.setReplyTimeout(0); // disable, we use asyncexecute to
+ // control timeout
+ _config.setConnectionTimeout(60000);
+ _config.setReplyTimeout(60 * 15000);
+ _config.setBasicUserName(_username);
+ _config.setBasicPassword(_password);
+ _config.setXmlRpcServer(null);
+ // _config.setEnabledForExtensions(true);
+ client.setConfig(_config);
+ client.setTypeFactory(new RpcTypeFactory(client));
+ } catch (Throwable e) {
+ throw new XmlRpcException(e.getMessage());
+ }
+ return client;
+ }
+
+ public Connection(String ip, Integer port, String username, String password)
+ throws XmlRpcException {
+ _ip = ip;
+ _port = port;
+ _username = username;
+ _password = password;
+ _client = getXmlClient();
+ }
+
+ public Connection(String ip, String username, String password)
+ throws XmlRpcException {
+ _ip = ip;
+ _username = username;
+ _password = password;
+ _client = getXmlClient();
+ }
+
+ public Object call(String method, Vector<?> params) throws XmlRpcException {
+ /* default timeout is 10 mins */
+ return callTimeoutInSec(method, params, this._timeout);
+ }
+
+ public Object call(String method, Vector<?> params, boolean debug)
+ throws XmlRpcException {
+ /* default timeout is 10 mins */
+ return callTimeoutInSec(method, params, this._timeout, debug);
+ }
+
+ public Object callTimeoutInSec(String method, Vector<?> params,
+ int timeout, boolean debug) throws XmlRpcException {
+ TimingOutCallback callback = new TimingOutCallback(timeout * 1000);
+ if (debug) {
+ /*
+ * some parameters including user password should not be printed in
+ * log
+ */
+ s_logger.debug("Call Ovm3 agent: " + method + " with " + params);
+ }
+
+ long startTime = System.currentTimeMillis();
+ _client.executeAsync(method, params, callback);
+ try {
+ return callback.waitForResponse();
+ } catch (TimingOutCallback.TimeoutException to) {
+ throw to;
+ } catch (Throwable e) {
+ throw new XmlRpcException(-2, e.getMessage());
+ } finally {
+ long endTime = System.currentTimeMillis();
+ float during = (endTime - startTime) / 1000; // in secs
+ s_logger.debug("Ovm3 call " + method + " finished in " + during
+ + " secs, on " + _ip + ":" + _port);
+ }
+ }
+
+ public Object callTimeoutInSec(String method, Vector<?> params, int timeout)
+ throws XmlRpcException {
+ return callTimeoutInSec(method, params, timeout, true);
+ }
+
+ public String getIp() {
+ return _ip;
+ }
+
+ public Integer getPort() {
+ return _port;
+ }
+
+ public String getUserName() {
+ return _username;
+ }
+
+ public String getPassword() {
+ return _password;
+ }
+
+ public Boolean getIsSsl() {
+ return _isSsl;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Linux.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Linux.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Linux.java
new file mode 100644
index 0000000..3be9feb
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Linux.java
@@ -0,0 +1,612 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+
+/*
+ * should become an interface implementation
+ */
+public class Linux extends OvmObject {
+ private Integer _init = 0;
+
+ /*
+ * use capabilities to match things later, perhaps also hardware discovery ?
+ * wrap getters and setters.... for Mapps...
+ */
+ public Map<String, String> Capabilities = 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}
+ */
+ public Map<String, String> VMM = new HashMap<String, String>();
+ public Map<String, String> VMMc = new HashMap<String, String>();
+ public Map<String, String> NTP = new HashMap<String, String>();
+ public Map<String, String> DateTime = new HashMap<String, String>();
+ public Map<String, String> Generic = 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}
+ */
+ public Map<String, String> hwVMM = new HashMap<String, String>();
+ public Map<String, String> hwSystem = new HashMap<String, String>();
+ public int localTime;
+ public int lastBootTime;
+ public String timeZone;
+ public String timeUTC;
+ public List<String> _mounts = null;
+
+ // public Map<String, Map> Settings = new HashMap<String, Map>();
+
+ public Linux(Connection c) {
+ client = c;
+ }
+
+ /*
+ * discover_server, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None
+ */
+ public Boolean discoverServer() throws Exception {
+ String cmd = "discover_server";
+ Object result = callWrapper(cmd);
+ if (result == null) {
+ return false;
+ }
+
+ Document xmlDocument = prepParse((String) result);
+ /* System.out.println(result); */
+ /* could be more subtle */
+ String path = "//Discover_Server_Result/Server";
+ Capabilities = xmlToMap(path + "/Capabilities", xmlDocument);
+ VMM = xmlToMap(path + "/VMM/Version", xmlDocument);
+ VMMc = xmlToMap(path + "/VMM", xmlDocument);
+ NTP = xmlToMap(path + "/NTP", xmlDocument);
+ DateTime = xmlToMap(path + "/Date_Time", xmlDocument);
+ Generic = xmlToMap(path, xmlDocument);
+
+ // System.out.println(Get("Agent_Version"));
+
+ // System.out.println(Generic.toString());
+ return true;
+ }
+
+ public String getAgentVersion() throws ParserConfigurationException, IOException, Exception {
+ return this.Get("Agent_Version");
+ }
+ public String getHostKernelRelease() throws ParserConfigurationException, IOException, Exception {
+ return this.Get("Host_Kernel_Release");
+ }
+ public String getHostOs() throws ParserConfigurationException, IOException,
+ Exception {
+ return this.Get("OS_Name");
+ }
+ public String getHostOsVersion() throws ParserConfigurationException,
+ IOException, Exception {
+ String ver = this.Get("OS_Major_Version") + "."
+ + this.Get("OS_Minor_Version");
+ return ver;
+ }
+ public String getHypervisorName() throws ParserConfigurationException, IOException, Exception {
+ return this.Get("Hypervisor_Name");
+ }
+ public String getHypervisorVersion() throws ParserConfigurationException, IOException, Exception {
+ String ver = this.getHypervisorMajor() + "."
+ + this.getHypervisorMinor() + "." + this.getHypervisorExtra();
+ return ver;
+ }
+ public String getCapabilities() throws ParserConfigurationException,
+ IOException, Exception {
+ return this.Get("Capabilities");
+ }
+ public String getHypervisorMajor() throws ParserConfigurationException, IOException, Exception {
+ return this.Get("Major");
+ }
+ public String getHypervisorMinor() throws ParserConfigurationException, IOException, Exception {
+ return this.Get("Minor");
+ }
+ public String getHypervisorExtra() throws ParserConfigurationException,
+ IOException, Exception {
+ return this.Get("Extra").replace(".", "");
+ }
+ public String getManagerUuid() throws ParserConfigurationException, IOException, Exception {
+ return this.Get("Manager_Unique_Id");
+ }
+
+ public String getMembershipState() throws ParserConfigurationException,
+ IOException, Exception {
+ return this.Get("Membership_State");
+ }
+
+ public String getServerRoles() throws ParserConfigurationException,
+ IOException, Exception {
+ return this.Get("Server_Roles");
+ }
+ public boolean getIsMaster() throws ParserConfigurationException,
+ IOException, Exception {
+ return Boolean.parseBoolean(this.Get("Is_Current_Master"));
+ }
+ public String getOvmVersion() throws ParserConfigurationException, IOException, Exception {
+ return this.Get("OVM_Version");
+ }
+ public String getHostName() throws ParserConfigurationException, IOException, Exception {
+ return this.Get("Hostname");
+ }
+ public Integer getCpuKhz() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+ return Integer.valueOf(this.Get("CPUKHz"));
+ }
+ public Integer getCpuSockets() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+ return Integer.valueOf(this.Get("SocketsPerNode"));
+ }
+ public Integer getCpuThreads() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+ return Integer.valueOf(this.Get("ThreadsPerCore"));
+ }
+ public Integer getCpuCores() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+ return Integer.valueOf(this.Get("CoresPerSocket"));
+ }
+ public Integer getTotalThreads() throws NumberFormatException, ParserConfigurationException, IOException, Exception {
+ return this.getCpuSockets() * this.getCpuCores() * this.getCpuThreads();
+ }
+
+ public Double getMemory() throws NumberFormatException,
+ ParserConfigurationException, IOException, Exception {
+ return Double.valueOf(this.Get("TotalPages")) * 4096;
+ }
+
+ public Double getFreeMemory() throws NumberFormatException,
+ ParserConfigurationException, IOException, Exception {
+ return Double.valueOf(this.Get("FreePages")) * 4096;
+ }
+ public String getUuid() throws NumberFormatException,
+ ParserConfigurationException, IOException, Exception {
+ return this.Get("Unique_Id");
+ }
+
+ public String Get(String element) throws ParserConfigurationException, IOException, Exception {
+ if (this._init == 0) {
+ this.discoverHardware();
+ this.discoverServer();
+ this._init = 1;
+ }
+ if (Generic.containsKey(element))
+ return Generic.get(element);
+ if (VMMc.containsKey(element))
+ return VMMc.get(element);
+ if (VMM.containsKey(element))
+ return VMM.get(element);
+ if (hwVMM.containsKey(element))
+ return hwVMM.get(element);
+ if (hwSystem.containsKey(element))
+ return hwSystem.get(element);
+ if (Capabilities.containsKey(element))
+ return Capabilities.get(element);
+ return "";
+ }
+
+ /*
+ * unexport_fs, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: export_uuid - default: None
+ */
+
+ /*
+ * get_last_boot_time, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None
+ */
+ public Integer getLastBootTime() throws XmlRpcException {
+ HashMap<String, Long> result = callMap("get_last_boot_time");
+ if (result == null)
+ return null;
+ this.lastBootTime = result.get("last_boot_time").intValue();
+ this.localTime = result.get("local_time").intValue();
+ return lastBootTime;
+ }
+
+ /*
+ * delete_yum_repo, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: repo_id - default: None
+ */
+
+ /*
+ * notify_manager, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: notification - default: None argument: data -
+ * default: None
+ */
+
+ /*
+ * update_core_api_bindings, <class 'agent.api.host.linux.Linux'> argument:
+ * self - default: None argument: url - default: None argument: option -
+ * default: None
+ */
+
+ /*
+ * set_datetime, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: year - default: None argument: month - default:
+ * None argument: day - default: None argument: hour - default: None
+ * argument: min - default: None argument: sec - default: None
+ */
+ public Boolean setDateTime(int year, int month, int day, int hour, int min,
+ int sec) throws XmlRpcException {
+ Object x = callWrapper("set_datetime", year, month, day, hour, min, sec);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * list_package, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: name - default: None
+ */
+
+ /*
+ * discover_physical_luns, <class 'agent.api.host.linux.Linux'> argument:
+ * self - default: None argument: args - default: None
+ */
+ public String discoverPhysicalLuns() throws XmlRpcException {
+ String x = (String) callWrapper("discover_physical_luns", "");
+ return x;
+ }
+
+ /*
+ * ovs_download_file, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: url - default: None argument: filename - default:
+ * None argument: option - default: None argument: obj - default: None
+ * argument: obj_current - default: None argument: obj_total - default: None
+ * argument: update_period - default: None
+ */
+
+ /*
+ * install_package, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: pkg_data - default: None argument: option -
+ * default: None
+ */
+
+ /*
+ * get_support_files, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None
+ */
+
+ /*
+ * export_fs, <class 'agent.api.host.linux.Linux'> argument: self - default:
+ * None argument: export_uuid - default: None argument: export_type -
+ * default: None argument: client - default: None argument: path - default:
+ * None argument: options - default: None
+ */
+
+ /*
+ * ovs_async_proc_status, <class 'agent.api.host.linux.Linux'> argument:
+ * self - default: None argument: pid - default: None
+ */
+
+ /*
+ * set_timezone, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: timezone - default: None argument: utc - default:
+ * None
+ */
+ public Boolean setTimeZone(String tz, Boolean utc) throws XmlRpcException {
+ Object x = callWrapper("set_timezone", tz, utc);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * copy_file, <class 'agent.api.host.linux.Linux'> argument: self - default:
+ * None argument: src - default: None argument: dst - default: None
+ * argument: sparse - default: None argument: update_period - default: None
+ */
+ public Boolean copyFile(String src, String dst) throws XmlRpcException {
+ Object x = callWrapper("copy_file", src, dst, false);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean copyFile(String src, String dst, Boolean sparse)
+ throws XmlRpcException {
+ Object x = callWrapper("copy_file", src, dst, sparse);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * discover_mounted_file_systems, <class 'agent.api.host.linux.Linux'>
+ * argument: self - default: None argument: args - default: None
+ */
+ /*
+ * <Discover_Mounted_File_Systems_Result> <Filesystem Type="nfs"> <Mount
+ * Dir="/nfsmnt/e080e318-91c2-47e5-a5ab-f3ab53790162">
+ * <Device>cs-mgmt:/volumes/cs-data/secondary/</Device>
+ * <Mount_Options>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</Mount_Options>
+ * </Mount> </Filesystem> ... </Discover_Mounted_File_Systems_Result>
+ */
+
+ public Boolean discoverMountedFs() throws XmlRpcException {
+ Object x = callWrapper("discover_mounted_file_systems");
+ // System.out.println(x);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /* Filesystem bits and bobs */
+ private Map<String, FileSystem> fsList = null;
+
+ public Map<String, FileSystem> getFileSystemList(String type)
+ throws ParserConfigurationException, IOException, Exception {
+ if (fsList == null)
+ this.discoverMountedFs(type);
+
+ return fsList;
+ }
+
+ public void setFileSystemList(Map<String, FileSystem> list) {
+ fsList = list;
+ }
+ public class FileSystem {
+ public Map<String, Object> _fs = new HashMap<String, Object>() {
+ {
+ put("Mount_Options", null);
+ put("Name", null);
+ put("Device", null);
+ put("Host", null);
+ put("Dir", null);
+ put("Mount_Point", null);
+ put("Uuid", null);
+ }
+ };
+
+ public String getUuid() {
+ return (String) _fs.get("Uuid");
+ }
+
+ public String setUuid(String uuid) {
+ return (String) _fs.put("Uuid", uuid);
+ }
+ public String getName() {
+ return (String) _fs.get("Name");
+ }
+
+ public String setName(String name) {
+ return (String) _fs.put("Name", name);
+ }
+
+ public String getDevice() {
+ return (String) _fs.get("Device");
+ }
+
+ public String setDevice(String dev) {
+ return (String) _fs.put("Device", dev);
+ }
+
+ public String getHost() {
+ if (getDevice() != null && getDevice().contains(":")) {
+ String spl[] = getDevice().split(":");
+ setHost(spl[0]);
+ setMountPoint(spl[1]);
+ } else {
+ return null;
+ }
+ return (String) _fs.get("Host");
+ }
+
+ public String setHost(String host) {
+ return (String) _fs.put("Host", host);
+ }
+
+ public String getDir() {
+ return (String) _fs.get("Dir");
+ }
+
+ public String setDir(String dir) {
+ return (String) _fs.put("Dir", dir);
+ }
+
+ public String getMountPoint() {
+ if (getHost() != null) {
+ return (String) _fs.get("Mount_Point");
+ }
+ return null;
+ }
+ public String setMountPoint(String pnt) {
+ return (String) _fs.put("Mount_Point", pnt);
+ }
+ };
+
+ /* should actually be called "getMountedsFsDevice" or something */
+ public Map<String, FileSystem> discoverMountedFs(String type)
+ throws ParserConfigurationException, IOException, Exception {
+ // if (postDiscovery == null) {
+ // postDiscovery = callWrapper("discover_network");
+ this.fsList = new HashMap<String, FileSystem>();
+ //}
+ Object x = callWrapper("discover_mounted_file_systems", type);
+ Document xmlDocument = prepParse((String) x);
+ // List<String> list = new ArrayList<String>();
+ 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._fs = fs;
+ String[] spl = mnt.split("/");
+ String uuid = spl[spl.length - 1];
+ // System.out.println(uuid + " " + mnt);
+ f.setUuid(uuid);
+ f.setDir(mnt);
+ fsList.put(uuid, f);
+ }
+ setFileSystemList(fsList);
+ if (x == null) {
+ return this.fsList;
+ }
+
+ return this.fsList;
+ }
+
+ /*
+ * ovs_async_proc, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: func - default: None
+ */
+
+ /*
+ * get_log, <class 'agent.api.host.linux.Linux'> argument: self - default:
+ * None argument: loglist - default: None
+ */
+
+ /*
+ * update_agent_password, <class 'agent.api.host.linux.Linux'> argument:
+ * self - default: None argument: username - default: None argument:
+ * password - default: None
+ */
+ public Boolean updateAgentPassword(String user, String pass)
+ throws XmlRpcException {
+ Object x = callWrapper("update_agent_password", user, pass);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * yum_update, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: option - default: None
+ */
+
+ /*
+ * discover_hardware, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None
+ */
+ public Boolean discoverHardware()
+ throws ParserConfigurationException, IOException, Exception {
+ Object result = callWrapper("discover_hardware");
+
+ Document xmlDocument = prepParse((String) result);
+ /* could be more subtle */
+ String path = "//Discover_Hardware_Result/NodeInformation";
+ hwVMM = xmlToMap(path + "/VMM/PhysicalInfo", xmlDocument);
+ hwSystem = xmlToMap(path + "/DMTF/System", xmlDocument);
+
+ if (result == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * uninstall_package, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: pkg_list - default: None argument: option -
+ * default: None
+ */
+
+ /*
+ * get_datetime, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None
+ */
+ public Integer getDateTime() throws XmlRpcException {
+ this.getLastBootTime();
+ return this.localTime;
+ }
+
+ /*
+ * configure_yum, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: section - default: None argument: params -
+ * default: None
+ */
+
+ /*
+ * get_yum_config, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None
+ */
+ public Boolean getYumConfig() throws XmlRpcException {
+ Object x = callWrapper("get_yum_config");
+ // System.out.println(x);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_async_proc_stop, <class 'agent.api.host.linux.Linux'> argument: self
+ * - default: None argument: pid - default: None
+ */
+
+ /*
+ * set_statistic_interval, <class 'agent.api.host.linux.Linux'> argument:
+ * interval - default: None
+ */
+ public Boolean setStatisticsInterval(int val) throws XmlRpcException {
+ Object x = callWrapper("set_statistics_interval", val);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * yum_list_package, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None argument: pkgnarrow - default: None argument: patterns -
+ * default: None argument: showdups - default: None argument: ignore_case -
+ * default: None
+ */
+
+ /*
+ * get_timezone, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None
+ */
+ public Boolean getTimeZone() throws XmlRpcException {
+ Object[] result = (Object[]) callWrapper("get_timezone");
+ if (result != null) {
+ this.timeZone = result[0].toString();
+ this.timeUTC = result[1].toString();
+ return true;
+ }
+ return false;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Network.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Network.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Network.java
new file mode 100644
index 0000000..0ae9d84
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Network.java
@@ -0,0 +1,628 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+// import java.util.Map;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+// import java.util.HashMap;
+
+/*
+ * should become an interface implementation
+ */
+public class Network extends OvmObject {
+
+ public Network(Connection c) {
+ client = c;
+ }
+
+ private Map<String, Interface> interfaceList = null;
+
+ public Map<String, Interface> getInterfaceList()
+ throws ParserConfigurationException, IOException, Exception {
+ try {
+ this.discoverNetwork();
+ } catch (Exception e) {
+ throw new Exception(e.getMessage());
+ }
+ return interfaceList;
+ }
+
+ public void setBridgeList(Map<String, Interface> list) {
+ interfaceList = list;
+ }
+
+ public class Interface {
+ private Map<String, String> _interface = 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 void setIfType(String t) {
+ this._interface.put("Type", t);
+ }
+ public String getIfType() {
+ return this._interface.get("Type");
+ }
+ public void setInterface(Map<String, String> itf) {
+ this._interface.putAll(itf);
+ }
+
+ public String getName() {
+ return _interface.get("Name");
+ }
+
+ public String getPhysical() {
+ return _interface.get("Physical");
+ }
+
+ public String getAddress() {
+ return _interface.get("Address");
+ }
+
+ public String getBroadcast() {
+ return _interface.get("Broadcast");
+ }
+
+ public String getMac() {
+ return _interface.get("MAC");
+ }
+
+ public String setName(String name) {
+ return _interface.put("Name", name);
+ }
+
+ public String setPhysical(String ph) {
+ return _interface.put("Physical", ph);
+ }
+ public String setAddress(String addr) {
+ return _interface.put("Address", addr);
+ }
+
+ public String setBroadcast(String bcast) {
+ return _interface.put("Broadcast", bcast);
+ }
+
+ public String setMac(String mac) {
+ return _interface.put("MAC", mac);
+ }
+ }
+
+ private Network.Interface _getInterface(String key, String val)
+ throws ParserConfigurationException, IOException, Exception {
+ HashMap<String, Network.Interface> ifaces = new HashMap<String, Network.Interface>();
+ ifaces = (HashMap<String, Interface>) this.getInterfaceList();
+ for (final Entry<String, Interface> iface : ifaces.entrySet()) {
+ String match = "default";
+ if (key.equals("Address"))
+ match = iface.getValue().getAddress();
+ if (key.equals("Name"))
+ match = iface.getKey();
+ // .getName();
+ if (match != null && match.equals(val))
+ return iface.getValue();
+ }
+ return null;
+ }
+
+ public Network.Interface getInterfaceByIp(String ip)
+ throws ParserConfigurationException, IOException, Exception {
+ return _getInterface("Address", ip);
+ }
+
+ public Network.Interface getInterfaceByName(String name)
+ throws ParserConfigurationException, IOException, Exception {
+ return _getInterface("Name", name);
+ }
+ /* check if it is a BRIDGE */
+ public String getPhysicalByBridgeName(String name)
+ throws ParserConfigurationException, IOException, Exception {
+ return getInterfaceByName(name).getPhysical();
+ }
+
+ public Network.Interface getBridgeByName(String name)
+ throws ParserConfigurationException, IOException, Exception {
+ if (_getInterface("Name", name).getIfType().contentEquals("Bridge")) {
+ return _getInterface("Name", name);
+ }
+ return null;
+ }
+ public Network.Interface getBridgeByIp(String ip)
+ throws ParserConfigurationException, IOException, Exception {
+ if (_getInterface("Address", ip).getIfType().contentEquals("Bridge")) {
+ return _getInterface("Address", ip);
+ }
+ return null;
+ }
+ private Object postDiscovery = null;
+
+ private List<String> netInterfaces = new ArrayList<String>();
+
+ /*
+ * ovs_bond_mode, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ Change Bond mode.
+
+ @param bond One of the logical channel bonds (bond0, bond1 ...etc)
+ @mode Current supported bonding modes (1 = active-backup, 4 = 802.3ad
+ 6 = balance-alb).
+ @return If successful, returns bond's names and its new mode
+ Raises an exception on failure
+ Restriction:
+ -bond must be one of the logical channel bonds (bond0, bond1 ...etc)
+
+ */
+ public Boolean ovsBondMode(String bond, String mode) throws XmlRpcException {
+ Object x = callWrapper("ovs_bond_mode", bond, mode);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_change_mtu, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ Changes MTU on a physical,vlan,bond,and bridge interface.
+ Changing a bond MTU will also change the MTU of its slaves.
+ Changing the MTU of an interface that is part of a bridge,
+ will cause the bridge MTU and all of the interfaces change.
+ When a Guest VIF attach to a bridge,the VIF MTU will be set
+ to the bridge MTU
+
+
+ @param interface Physical,bond,vlan, and a bridge
+ @param MTU Values are 1500 to 64000
+
+ @return If successful, returns the interface, and the new MTU
+ Raises an exception on failure
+
+ Restriction:
+ -Can not change the MTU of a bridge without interfaces.
+ -VLAN MTU must less or equal to the MTU of the underlying
+ physical interface.
+ */
+ public Boolean ovsChangeMtu(String net, int mtu) throws XmlRpcException {
+ Object x = callWrapper("ovs_change_mtu", net, mtu);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_async_bridge, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ * argument: self - default: None argument: action - default: None argument:
+ * br_name - default: None argument: net_dev - default: None
+ */
+ public Boolean ovsAsyncBridge(String action, String bridge, String netdev)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_async_bridge", action, bridge, netdev);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_bond_op, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ * argument: self - default: None argument: action - default: None argument:
+ * bond - default: None argument: backup - default: None
+ */
+ public Boolean ovsBondOp(String action, String bond, String backup)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_bond_op", action, bond, backup);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Object x = callWrapper("configure_virtual_ip", vip, baseip);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_ip_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ Assigns/flushes IP, netmask address to a physical,VLAN, and bond interfaces.
+
+ @param interface The interface on which to assign
+ @param optype (static|dynamic|flush)
+ static: Assigns the given IP, and netmask to the interface, and
+ saves the config file to /etc/sysconfig/network-scripts.
+ dynamic: Flushes current address, and creats and save the config
+ file to /etc/sysconfig/network-scripts, (BOOTPROTO=dhcp)
+ flush: flushes the interface address,routes, removes the current
+ config file from /etc/sysconfig/network-scripts.
+ Creats a new one with BOOTPROTO=static
+
+ @args Required for the static option, otherwise it is ignored
+ IP address: IPv4 address in decimal notation (101.230.112)
+ netmask: Standard netmask in a decimal notation,NOT CIDR.
+ example(255.255.255.0)
+
+ @return If successful, returns the interface, and addresses added/flushed
+ Raises an exception on failure
+
+ Restriction:
+ -Interface must be physical, VLAN, or a Bond
+ -Interface must not be a bridge port, or slave to a bond
+ -Addresses must be valid in a decimal notation
+
+ */
+ public Boolean ovsIpConfig(String net, String optype, String ip,
+ String netmask)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_ip_config", net, optype, ip, netmask);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_if_meta, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ This function creates meta data file meta-interface, and write the string
+ (METADATA=data) to it. This string is used by the manager to identify
+ networks that interfaces belong to. Dom0 does not make used of this string,
+ it just saves it and returns it during running, saved network discovery.
+
+ - If an interface already has a meta data string, then it gets
+ replace by the new one
+ - An empty meta data string, indicates to remove the existing string
+ (remove the meta-interface) file
+
+ @param interface physical,VLAN, bond ...etc interfaces
+ @param data meta data to save
+
+ @return If successful, returns the interface, and meta data
+ Raises an exception on failure
+
+ 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 ovsIfMeta(String net, String data) throws XmlRpcException {
+ Object x = callWrapper("ovs_if_meta", net, data);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+
+ /*
+ * ovs_bond_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ * argument: self - default: None argument: action - default: None argument:
+ * bond - default: None
+ */
+ public Boolean ovsBondConfig(String action, String bond)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_bond_config", action, bond);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * discover_network, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ Discover information about the current network configuration.
+ This includes the state of physical NICs, bonds, and bridges. Also return
+ information stored for this server that is needed to configure
+ the network when the OVM Manager is not available.
+
+ Discovery of the current network configuration is handled by invoking
+ a python extension that calls legacy C code from the VI agent.
+
+ @param None
+
+ @return Returns the discovery data as an XML document.
+ Raises an exception on failure.
+ * <?xml version="1.0" ?> <Discover_Network_Result>
+ * <Network><Active><Network> <Device Name="eth0">
+ * <MAC>52:54:00:24:47:70</MAC> <Flags>(0x1843) IFF_UP IFF_BROADCAST
+ * IFF_RUNNING IFF_SLAVE IFF_MULTICAST</Flags> <ETHTOOL> <Autonegotiate>
+ * <State>Complete</State> <Speed>1000baseT-FD</Speed> </Autonegotiate>
+ * <Link>ok</Link> <Capabilities>10baseT-HD 10baseT-FD 100baseT-HD
+ * 100baseT-FD 1000baseT-FD</Capabilities> <Advertising>10baseT-HD
+ * 10baseT-FD 100baseT-HD 100baseT-FD 1000baseT-FD</Advertising> </ETHTOOL>
+ * <WOL> <WakeOnLan>disabled</WakeOnLan> </WOL> <SysFS>
+ * <uevent>INTERFACE=eth0 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>0x40014ba9</features> <type>1</type> <link_mode>0</link_mode>
+ * <carrier>1</carrier> <speed>1000</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>0x8086</vendor>
+ * <device>0x100e</device> <subsystem_vendor>0x1af4</subsystem_vendor>
+ * <subsystem_device>0x1100</subsystem_device> <class>0x020000</class>
+ * </SysFSDev> </SysFS> <BootProto>none</BootProto> </Device> ....
+ * </Network> <Bonding> <Device Name="bond0">
+ * <Bonding_Mode>active-backup</Bonding_Mode> <Primary_Slave>eth0
+ * (primary_reselect always)</Primary_Slave>
+ * <Currently_Active_Slave>eth0</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="eth0">
+ * <MII_Status>up</MII_Status> <Speed>1000 Mbps</Speed>
+ * <Duplex>full</Duplex> <Link_Failure_Count>0</Link_Failure_Count>
+ * <Permanent_HW_addr>52:54:00:24:47:70</Permanent_HW_addr>
+ * </Slave_Interface> <Family Type="AF_INET"> <MAC>52:54:00:24:47:70</MAC>
+ * <mtu>1500</mtu> </Family> <BootProto>none</BootProto>
+ * <MetaData>ethernet:c0a80100
+ * {192.168.1.0}:MANAGEMENT,CLUSTER_HEARTBEAT,LIVE_MIGRATE
+ * ,VIRTUAL_MACHINE,STORAGE</MetaData> </Device> </Bonding> <Bridges>
+ * <Device Name="c0a80100"> <Family Type="AF_INET">
+ * <MAC>52:54:00:24:47:70</MAC> <Address>192.168.1.64</Address>
+ * <Netmask>255.255.255.0</Netmask> <Broadcast>192.168.1.255</Broadcast>
+ * </Family> <Interfaces> <PhyInterface>bond0</PhyInterface> </Interfaces>
+ * <BootProto>static</BootProto></Device> </Bridges> <Infiniband>
+ * </Infiniband> </Active></Network></Discover_Network_Result>
+ */
+ /* put more in when required, for now ok */
+ public Boolean discoverNetwork() throws ParserConfigurationException,
+ IOException, Exception {
+ // if (postDiscovery == null) {
+ postDiscovery = callWrapper("discover_network");
+ this.interfaceList = new HashMap<String, Interface>();
+ // }
+ // System.out.println(postDiscovery);
+ 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 ? */
+ if (postDiscovery == null)
+ return false;
+
+ return true;
+ }
+
+ /*
+ * ovs_local_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ Configure a Local Bridge ((NIC-less bridge)
+
+ @param action (start | stop)
+ start: Creates local bridge without a physical interface, and saves bridge config
+ file in /etc/sysconfig/network-scripts
+ stop: Deletes local bridge, removes bridge config file from
+ /etc/sysconfig/network-scripts
+
+ @param br_name The bridge name to add
+
+ @return If successful, returns the name of the bridge
+ Raises an exception on failure
+
+ */
+ public Boolean startOvsLocalConfig(String br)
+ throws XmlRpcException {
+ return ovsLocalConfig("start", br);
+ }
+
+ public Boolean stopOvsLocalConfig(String br)
+ throws XmlRpcException {
+ return ovsLocalConfig("stop", br);
+ }
+
+ public Boolean ovsLocalConfig(String action, String br)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_local_config", action, br);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_vlan_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ Creates a VLAN interface on a physical, or a bond interface.
+
+ @param action (add|remove)
+ add: Creates a VLAN on an interface,saves the VLAN config file in
+ /etc/sysconfig/network-scripts
+ remove: Removes a VLAN from an interfacei,removes its config file from
+ /etc/sysconfig/network-scripts
+
+ @param interface The interface on which to create a VLAN
+ @param vlanid VLAN ID (2-4095)
+
+ @return If successful, returns the interface, and VLAN created
+ Raises an exception on failure
+
+ Restriction:
+ -Interface must be physical, or bond
+ -Interface must not be member of a bridge, or slave to a bond
+ -VLAN ID must not exist on the same interface
+
+ */
+ public Boolean startOvsVlanConfig(String dev, int vlan)
+ throws XmlRpcException {
+ return ovsVlanConfig("add", dev, vlan);
+ }
+
+ public Boolean stopOvsVlanConfig(String dev, int vlan)
+ throws XmlRpcException {
+ return ovsVlanConfig("del", dev, vlan);
+ }
+ public Boolean ovsVlanConfig(String action, String net, int vlan)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_vlan_config", action, net, vlan);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_br_config, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ Configure a Standard Bridge.
+
+ @param action (start | stop)
+ start: Creates the bridge, Copies the IP and MAC addresses from netdev to bridge,
+ enslaves net_dev to bridge, and saves bridge config files in
+ /etc/sysconfig/network-scripts
+ stop: Removes net_dev from the bridge,transfers addresses, routes from bridge to
+ net_dev, deletes the bridge, and revomes bridge config files from
+ /etc/sysconfig/network-scripts
+
+ @param br_name The bridge name to add
+ @param net_dev The physical interface to add to the bridge
+
+ @return If successful, returns the names of the bridge and it's physical interface.
+ Raises an exception on failure
+ Restriction:
+ -net_dev must be physical, or bond
+ -net_dev must not be member of a bridge, or slave to a bond
+ */
+ public Boolean startOvsBrConfig(String br, String dev)
+ throws XmlRpcException {
+ return ovsBrConfig("start", br, dev);
+ }
+
+ public Boolean stopOvsBrConfig(String br, String dev)
+ throws XmlRpcException {
+ return ovsBrConfig("stop", br, dev);
+ }
+
+ public Boolean ovsBrConfig(String action, String br, String net)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_br_config", action, br, net);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_vlan_bridge, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ @param action (start | stop)
+ start: Creates the bridge, creats VLAN on net_dev,enslaves
+ the VLAN to the bridge, and saves VLAN bridge config
+ files in /etc/sysconfig/network-scripts
+ stop: Removes the VLAN from the bridge, removes the VLAN,
+ deletes the bridge, and removes VLAN bridge config files
+ from /etc/sysconfig/network-scripts
+
+ @param br_name The bridge name to add
+ @param net_dev The physical interface on which to create a VLAN.
+ @param vlan_id VLAN ID (1-4095). VLAN ID of 1 is the untagged VLAN.
+
+ @return If successful, returns the names of the bridge and it's VLAN interface
+ Raises an exception on failure
+ */
+ public Boolean stopOvsVlanBridge(String br, String net, int vlan) throws XmlRpcException {
+ return ovsVlanBridge("stop", br, net, vlan);
+ }
+
+ public Boolean startOvsVlanBridge(String br, String net, int vlan) throws XmlRpcException {
+ return ovsVlanBridge("start", br, net, vlan);
+ }
+
+ public Boolean ovsVlanBridge(String action, String br, String net, int vlan)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_vlan_bridge", action, br, net, vlan);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * deconfigure_virtual_ip, <class
+ * 'agent.api.network.linux_network.LinuxNetwork'> argument: self - default:
+ * None argument: virtual_ip - default: None
+ */
+ public Boolean deconfigureVip(String vip) throws XmlRpcException {
+ Object x = callWrapper("deconfigure_virtual_ip", vip);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ovs_async_bond, <class 'agent.api.network.linux_network.LinuxNetwork'>
+ * argument: self - default: None argument: action - default: None argument:
+ * bond - default: None
+ */
+ public Boolean ovsAsyncBond(String action, String bond)
+ throws XmlRpcException {
+ Object x = callWrapper("ovs_async_bond", action, bond);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Ntp.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Ntp.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Ntp.java
new file mode 100644
index 0000000..96b1b4e
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Ntp.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Ntp extends OvmObject {
+ private List<String> Servers = new ArrayList<String>();
+ private Boolean isServer = null;
+ private Boolean isRunning = null;
+
+ public Ntp(Connection c) {
+ client = c;
+ }
+
+ public List<String> addServer(String server) {
+ if (Servers.contains(server) == false)
+ Servers.add(server);
+
+ return Servers;
+ }
+
+ public List<String> removeServer(String server) {
+ if (Servers.contains(server))
+ Servers.remove(server);
+
+ return Servers;
+ }
+
+ public List<String> servers() {
+ return Servers;
+ }
+
+ public Boolean isRunning() {
+ return isRunning;
+ }
+
+ public Boolean isServer() {
+ return isServer;
+ }
+
+ public Boolean getDetails() throws XmlRpcException {
+ return this.getNtp();
+ }
+
+ /*
+ * get_ntp, <class 'agent.api.host.linux.Linux'> argument: self - default:
+ * None
+ */
+ public Boolean getNtp() throws XmlRpcException {
+ Object[] v = (Object[]) callWrapper("get_ntp");
+ int c = 0;
+ for (Object o : v) {
+ // System.out.println(o.getClass());
+ if (o instanceof java.lang.Boolean) {
+ if (c == 0)
+ this.isServer = (Boolean) o;
+
+ if (c == 1)
+ this.isRunning = (Boolean) o;
+
+ // should not get here
+ if (c > 1)
+ return false;
+
+ c += 1;
+ } else if (o instanceof java.lang.Object) {
+ Object[] S = (Object[]) o;
+ for (Object m : S) {
+ this.addServer((String) m);
+ }
+ }
+ }
+ return true;
+ }
+
+ /*
+ * set_ntp, <class 'agent.api.host.linux.Linux'> argument: self - default:
+ * None argument: servers - default: None argument: local_time_source -
+ * default: None argument: allow_query - default: None // right, can't be
+ * set eh
+ */
+ public Boolean setNtp(List<String> servers, Boolean running)
+ throws XmlRpcException {
+ if (callWrapper("set_ntp", servers, running) == null) {
+ return this.getNtp();
+ } else {
+ return false;
+ }
+ }
+
+ /* also cleans the vector */
+ public Boolean setNtp(String server, Boolean running)
+ throws XmlRpcException {
+ this.Servers = new ArrayList<String>();
+ this.Servers.add(server);
+ return setNtp(this.Servers, running);
+ }
+
+ public Boolean setNtp(Boolean running) throws XmlRpcException {
+ return setNtp(this.Servers, running);
+ }
+
+ /*
+ * disable_ntp, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None
+ */
+ public Boolean disableNtp() throws XmlRpcException {
+ if (callWrapper("disable_ntp") == null)
+ return true;
+ return false;
+ }
+
+ /*
+ * enable_ntp, <class 'agent.api.host.linux.Linux'> argument: self -
+ * default: None
+ */
+ public Boolean enableNtp() throws XmlRpcException {
+ if (callWrapper("enable_ntp") == null)
+ return true;
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/OvmObject.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/OvmObject.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/OvmObject.java
new file mode 100644
index 0000000..4dba83c
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/OvmObject.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+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 java.util.Vector;
+
+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.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+public class OvmObject {
+ public static Connection client = null;
+ public static Vector<?> emptyParams = new Vector<Object>();
+
+ /* remove dashes from uuids */
+ public String deDash(String str) {
+ final String x = str.replaceAll("-", "");
+ return x;
+ }
+
+ /* generate a uuid */
+ public String newUuid() {
+ final String uuid = UUID.randomUUID().toString();
+ return uuid;
+ }
+
+ /* generate a uuid */
+ public String newUuid(String str) {
+ final String uuid = UUID.nameUUIDFromBytes(str.getBytes()).toString();
+ return uuid;
+ }
+
+ /* capture most of the calls here */
+ public static Object callWrapper(String call) throws XmlRpcException {
+ try {
+ Object res = client.call(call, emptyParams);
+ return res;
+ } catch (XmlRpcException e) {
+ throw new XmlRpcException(e.getMessage());
+ }
+ }
+
+ /* nice try but doesn't work like that .. */
+ @SafeVarargs
+ public static <T> Object callWrapper(String call, T... args)
+ throws XmlRpcException {
+ Vector<T> params = new Vector<T>();
+ for (T param : args) {
+ params.add(param);
+ }
+ // return
+ Object res = client.call(call, params);
+ return res;
+ }
+
+ /* returns a single string */
+ public HashMap<String, Long> callMap(String call) throws XmlRpcException {
+ HashMap<String, Long> result = (HashMap<String, Long>) callWrapper(call);
+ return result;
+ }
+
+ public <T> String callString(String call, T... args) throws XmlRpcException {
+ Object result = callWrapper(call, args);
+ if (result == null) {
+ return null;
+ }
+ if (result instanceof String)
+ return result.toString();
+ if (result instanceof Integer)
+ return result.toString();
+ if (result instanceof Long)
+ return result.toString();
+ if (result instanceof HashMap)
+ return result.toString();
+
+ Object[] results = (Object[]) result;
+
+ if (results.length == 0)
+ // return results[0].toString();
+ 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 XPathExpressionException {
+ XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance();
+ XPath xPath = factory.newXPath();
+ // capabilities, date_time etc
+ 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) {
+ // System.out.println("multiball");
+ /*
+ * for (int i = 0; i < nodeListFor2.getLength(); i++) {
+ * String node = nodeListFor2.item(i).getNodeName(); String
+ * element = nodeListFor2.item(i).getTextContent();
+ * System.out.println("rnode: " + rnode + " -> node " + node
+ * + " ---> " + element); myMap.put(node, element); }
+ */
+ } else {
+ String element = nodeListFor.item(index).getTextContent();
+ // System.out.println("rnode " + rnode + " ---> " +
+ // element);
+ myMap.put(rnode, (E) element);
+ }
+ }
+ }
+ return myMap;
+ }
+
+ public List<String> xmlToList(String path, Document xmlDocument)
+ throws XPathExpressionException {
+ List<String> list = new ArrayList<String>();
+ XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance();
+ XPath xPath = factory.newXPath();
+
+ XPathExpression xPathExpression = xPath.compile(path);
+ NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
+ XPathConstants.NODESET);
+
+ for (int ind = 0; ind < nodeList.getLength(); ind++) {
+ // System.out.println(nodeList.item(ind).getTextContent());
+ if (!nodeList.item(ind).getTextContent().isEmpty()) {
+ list.add("" + nodeList.item(ind).getTextContent());
+ } else {
+ list.add("" + nodeList.item(ind).getNodeValue());
+ }
+ }
+ return list;
+ }
+
+ public String xmlToString(String path, Document xmlDocument)
+ throws XPathExpressionException {
+
+ XPathFactory factory = javax.xml.xpath.XPathFactory.newInstance();
+ XPath xPath = factory.newXPath();
+
+ XPathExpression xPathExpression = xPath.compile(path);
+ NodeList nodeList = (NodeList) xPathExpression.evaluate(xmlDocument,
+ XPathConstants.NODESET);
+ // put a try in here too, so we can get the subbies
+ String x = nodeList.item(0).getTextContent();
+ return x;
+ }
+
+ public Document prepParse(String input)
+ throws ParserConfigurationException, Exception, IOException {
+ DocumentBuilderFactory builderfactory = DocumentBuilderFactory
+ .newInstance();
+ builderfactory.setNamespaceAware(true);
+
+ DocumentBuilder builder = builderfactory.newDocumentBuilder();
+ Document xmlDocument = builder.parse(new InputSource(new StringReader(
+ (String) input)));
+ return xmlDocument;
+ }
+ /*
+ * returns a list of strings public <T> ArrayList<String> call(String call,
+ * T... args) throws XmlRpcException { ArrayList<String> data = new
+ * ArrayList<String>(); Object[] result = (Object[]) callWrapper(call,
+ * args);
+ *
+ * if (result[result.length] != null) return null;
+ *
+ * for(Object x : result) { data.add(x.toString()); } return data; }
+ */
+}
[7/7] git commit: updated refs/heads/ovmsupport to 1516b04
Posted by se...@apache.org.
CLOUDSTACK-6967: Now with module!
Signed-off-by: Sebastien Goasguen <ru...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1516b041
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1516b041
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1516b041
Branch: refs/heads/ovmsupport
Commit: 1516b041bc762535b8f2e74bcb1e6594e5657f86
Parents: ed47763
Author: Funs <fu...@barred.org>
Authored: Fri Jun 20 15:07:54 2014 +0200
Committer: Sebastien Goasguen <ru...@gmail.com>
Committed: Fri Jun 20 09:25:44 2014 -0400
----------------------------------------------------------------------
plugins/hypervisors/ovm3 | 1 -
plugins/hypervisors/ovm3/pom.xml | 36 +
.../cloudstack/ovm3-compute/module.properties | 18 +
.../spring-ovm3-compute-context.xml | 39 +
.../ovm3-discoverer/module.properties | 18 +
.../spring-ovm3-discoverer-context.xml | 34 +
.../hypervisors/ovm3/scripts/clean_master.sh | 43 +
plugins/hypervisors/ovm3/scripts/clean_slave.sh | 33 +
.../ovm3/scripts/create_pool_cluster.py | 271 ++
plugins/hypervisors/ovm3/scripts/info.py | 111 +
.../ovm3/scripts/ovs_agent_plugin/cloudstack.py | 344 ++
plugins/hypervisors/ovm3/scripts/password.py | 57 +
plugins/hypervisors/ovm3/scripts/repo_pool.py | 186 +
plugins/hypervisors/ovm3/scripts/simple_pool.py | 209 ++
plugins/hypervisors/ovm3/scripts/socat.sh | 2 +
plugins/hypervisors/ovm3/scripts/tail.sh | 2 +
.../ovm3/src/com/cloud/ha/Ovm3Investigator.java | 81 +
.../ovm3/hypervisor/Ovm3Discoverer.java | 411 +++
.../hypervisor/ovm3/hypervisor/Ovm3Fencer.java | 133 +
.../hypervisor/ovm3/hypervisor/Ovm3Guru.java | 65 +
.../hypervisor/ovm3/hypervisor/Ovm3Helper.java | 82 +
.../ovm3/hypervisor/Ovm3ResourceBase.java | 3211 ++++++++++++++++++
.../ovm3/object/CloudStackPlugin.java | 131 +
.../cloud/hypervisor/ovm3/object/Cluster.java | 162 +
.../cloud/hypervisor/ovm3/object/Common.java | 64 +
.../hypervisor/ovm3/object/Connection.java | 144 +
.../com/cloud/hypervisor/ovm3/object/Linux.java | 612 ++++
.../cloud/hypervisor/ovm3/object/Network.java | 628 ++++
.../com/cloud/hypervisor/ovm3/object/Ntp.java | 140 +
.../cloud/hypervisor/ovm3/object/OvmObject.java | 208 ++
.../com/cloud/hypervisor/ovm3/object/Pool.java | 362 ++
.../cloud/hypervisor/ovm3/object/PoolOCFS2.java | 157 +
.../cloud/hypervisor/ovm3/object/Remote.java | 68 +
.../hypervisor/ovm3/object/Repository.java | 205 ++
.../hypervisor/ovm3/object/RpcTypeFactory.java | 92 +
.../hypervisor/ovm3/object/StoragePlugin.java | 876 +++++
.../com/cloud/hypervisor/ovm3/object/Test.java | 546 +++
.../com/cloud/hypervisor/ovm3/object/Xen.java | 1169 +++++++
38 files changed, 10950 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
[6/7] CLOUDSTACK-6967: Now with module!
Posted by se...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3 b/plugins/hypervisors/ovm3
deleted file mode 160000
index bd64f2d..0000000
--- a/plugins/hypervisors/ovm3
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit bd64f2dbf461847a3f7056693bf34e80e4f7af73
diff --git a/plugins/hypervisors/ovm3/pom.xml b/plugins/hypervisors/ovm3/pom.xml
new file mode 100644
index 0000000..22c9fe0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/pom.xml
@@ -0,0 +1,36 @@
+<!--
+ 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.4.0-SNAPSHOT</version>
+ <relativePath>../../pom.xml</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>xapi</artifactId>
+ <version>${cs.xapi.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/module.properties b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/module.properties
new file mode 100644
index 0000000..69e6469
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
new file mode 100644
index 0000000..42230c9
--- /dev/null
+++ b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-compute/spring-ovm3-compute-context.xml
@@ -0,0 +1,39 @@
+<!--
+ 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.hypervisor.Ovm3Fencer">
+ <property name="name" value="Ovm3FenceBuilder" />
+ </bean>
+
+ <bean id="Ovm3Guru" class="com.cloud.hypervisor.ovm3.hypervisor.Ovm3Guru">
+ <property name="name" value="Ovm3Guru" />
+ </bean>
+
+
+</beans>
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/module.properties b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/module.properties
new file mode 100644
index 0000000..025d4cf
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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
diff --git a/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml b/plugins/hypervisors/ovm3/resources/META-INF/cloudstack/ovm3-discoverer/spring-ovm3-discoverer-context.xml
new file mode 100644
index 0000000..aa76271
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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.hypervisor.Ovm3Discoverer">
+ <property name="name" value="Ovm3Discover" />
+ </bean>
+
+</beans>
diff --git a/plugins/hypervisors/ovm3/scripts/clean_master.sh b/plugins/hypervisors/ovm3/scripts/clean_master.sh
new file mode 100755
index 0000000..bbf1cd0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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
diff --git a/plugins/hypervisors/ovm3/scripts/clean_slave.sh b/plugins/hypervisors/ovm3/scripts/clean_slave.sh
new file mode 100755
index 0000000..6d46859
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/clean_slave.sh
@@ -0,0 +1,33 @@
+#!/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
+
diff --git a/plugins/hypervisors/ovm3/scripts/create_pool_cluster.py b/plugins/hypervisors/ovm3/scripts/create_pool_cluster.py
new file mode 100755
index 0000000..15c9a97
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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
diff --git a/plugins/hypervisors/ovm3/scripts/info.py b/plugins/hypervisors/ovm3/scripts/info.py
new file mode 100755
index 0000000..518aaf1
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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
diff --git a/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py b/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py
new file mode 100644
index 0000000..f655760
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/ovs_agent_plugin/cloudstack.py
@@ -0,0 +1,344 @@
+#!/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 logging
+import time
+import re
+import os.path
+import paramiko
+import subprocess
+import socket
+
+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_domr_ssh': domrCheckSsh,
+ 'ovs_control_interface': ovsControlInterface,
+ 'ovs_mkdir': ovsMkdir,
+ 'ovs_check_file': ovsCheckFile,
+ 'ovs_upload_ssh_key': ovsUploadSshKey,
+ 'ovs_dom0_stats': ovsDom0Stats,
+ 'ovs_domU_stats': ovsDomUStats,
+ 'get_module_version': getModuleVersion,
+ 'ping': ping,
+# 'ovs_agent_set_ssl': ovsAgentSetSsl,
+# 'ovs_agent_set_port': ovsAgentSetPort,
+# 'ovs_restart_agent': ovsRestartAgent,
+ }
+
+ def getName(self):
+ return self.__class__.__name__
+
+# which version are we intended for?
+def getModuleVersion():
+ return "0.1"
+
+# call test
+def call(msg):
+ return msg
+
+# execute something on domr
+def domrExec(ip, cmd, timeout=10, username="root", port=3922, keyfile="~/.ssh/id_rsa.cloud"):
+ ssh = paramiko.SSHClient()
+ ssh.load_system_host_keys()
+ ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
+ privatekeyfile = os.path.expanduser(keyfile)
+ key = paramiko.RSAKey.from_private_key_file(privatekeyfile)
+ ssh.connect(ip, port, username, pkey=key, 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()) };
+
+# check a port on domr
+def domrPort(ip, port=3922, timeout=3):
+ return domrCheckPort(ip, port, timeout=timeout)
+
+# check a port on domr
+def domrCheckPort(ip, port=3922, timeout=3):
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.settimeout(timeout)
+ s.connect((ip, port))
+ s.close()
+ return True
+ except:
+ return False
+
+# check ssh
+def domrCheckSsh(ip, port=3922, timeout=10):
+ x = domrExec(ip, "", port=port, timeout=timeout)
+ if (x.get("rc") == 0):
+ return True
+ return False
+
+def _ovsIni(setting, set):
+ ini="/etc/ovs-agent/agent.ini"
+ replaced=False
+ if os.path.isfile(ini):
+ import fileinput
+ for line in fileinput.FileInput(ini, inplace=1):
+ line=line.rstrip('\n')
+ if re.search("%s=" % setting, line):
+ line="%s=%s" % (setting, set)
+ replaced=True
+ print line
+ return replaced
+
+# 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")
+
+# 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, ipmask):
+ command = ['route', 'del', '-net', ipmask];
+ subprocess.call(command, shell=False)
+ command = ['ifconfig', dev, 'arp']
+ subprocess.call(command, shell=False)
+ return True
+
+# create a dir if we need it
+def ovsMkdir(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
+
+# upload keys
+def ovsUploadSshKey(keyfile, content):
+ keydir=os.path.expanduser("~/.ssh")
+ key="%s/%s" % (keydir, keyfile)
+ try:
+ ovsMkdir(os.path.expanduser(keydir))
+ except Error, v:
+ print "was already there %s" % keydir
+
+ try:
+ text_file = open("%s" % key, "w")
+ text_file.write("%s" % content)
+ text_file.close()
+ except Error, v:
+ print "something went wrong %s" % v
+ return False
+ return True
+
+
+# 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
+
+ # get options
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "sp::",
+ [ 'port=','ssl='])
+ except getopt.GetoptError:
+ print "Available Options: --port=, --ssl="
+ sys.exit()
+
+ for o, a in opts:
+ if o in ('-s', '--ssl'):
+ ssl = a
+ if o in ('-p', '--port'):
+ port = int(a)
+
+ # 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
+ ovsRestartAgent()
diff --git a/plugins/hypervisors/ovm3/scripts/password.py b/plugins/hypervisors/ovm3/scripts/password.py
new file mode 100755
index 0000000..25404a9
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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
diff --git a/plugins/hypervisors/ovm3/scripts/repo_pool.py b/plugins/hypervisors/ovm3/scripts/repo_pool.py
new file mode 100755
index 0000000..71feca8
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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
diff --git a/plugins/hypervisors/ovm3/scripts/simple_pool.py b/plugins/hypervisors/ovm3/scripts/simple_pool.py
new file mode 100755
index 0000000..756de93
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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
diff --git a/plugins/hypervisors/ovm3/scripts/socat.sh b/plugins/hypervisors/ovm3/scripts/socat.sh
new file mode 100755
index 0000000..c3fbc44
--- /dev/null
+++ b/plugins/hypervisors/ovm3/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 &
diff --git a/plugins/hypervisors/ovm3/scripts/tail.sh b/plugins/hypervisors/ovm3/scripts/tail.sh
new file mode 100755
index 0000000..fe88bc0
--- /dev/null
+++ b/plugins/hypervisors/ovm3/scripts/tail.sh
@@ -0,0 +1,2 @@
+cd /var/log
+tail -f ovm-consoled.log devmon.log messages ovs-agent.log ovmwatch.log
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java b/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java
new file mode 100644
index 0000000..980fa1f
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/ha/Ovm3Investigator.java
@@ -0,0 +1,81 @@
+/*
+ * 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 final static Logger s_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) {
+ Status status = isAgentAlive(host);
+ if (status == null) {
+ return null;
+ }
+ return status == Status.Up ? true : null;
+ }
+
+ @Override
+ public Status isAgentAlive(Host agent) {
+ 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) {
+ s_logger.debug("Failed to send command to host: " + neighbor.getId());
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java
new file mode 100755
index 0000000..bd1d90d
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Discoverer.java
@@ -0,0 +1,411 @@
+// 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.hypervisor;
+
+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 org.apache.xmlrpc.XmlRpcException;
+
+import com.cloud.agent.Listener;
+import com.cloud.agent.AgentManager;
+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.host.Status;
+import com.cloud.agent.api.StartupCommand;
+import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.configuration.Config;
+import com.cloud.dc.ClusterVO;
+import com.cloud.dc.dao.ClusterDao;
+import com.cloud.dc.ClusterDetailsDao;
+// import com.cloud.exception.DiscoveryException;
+import com.cloud.host.HostInfo;
+import com.cloud.host.HostVO;
+import com.cloud.host.Host;
+import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.hypervisor.ovm3.object.Linux;
+import com.cloud.hypervisor.ovm3.object.Connection;
+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 s_logger = Logger
+ .getLogger(Ovm3Discoverer.class);
+ protected String _publicNetworkDevice;
+ protected String _privateNetworkDevice;
+ protected String _guestNetworkDevice;
+ protected String _storageNetworkDevice;
+ private String _ovsAgentPath = "/etc/ovs-agent/agent.ini";
+
+ @Inject
+ ClusterDao _clusterDao;
+ @Inject
+ ClusterDetailsDao _clusterDetailsDao;
+ @Inject
+ ResourceManager _resourceMgr;
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ HostDao _hostDao = null;
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+ super.configure(name, params);
+ /* 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;
+ }
+
+ protected Ovm3Discoverer() {
+ }
+
+ @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();
+ }
+
+ @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 CloudRuntimeException {
+ Connection c = null;
+
+ if (url.getScheme().equals("http") || url.getScheme().equals("https")) {
+ String msg = "Discovering " + url
+ + ": " + _params;
+ s_logger.debug(msg);
+ } else {
+ String msg = "urlString is not http(s) so we're not taking care of the discovery for this: "
+ + url;
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ if (clusterId == null) {
+ String msg = "must specify cluster Id when add host";
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ if (podId == null) {
+ String msg = "must specify pod Id when add host";
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(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";
+ s_logger.info(msg);
+ throw new CloudRuntimeException(msg);
+ } else {
+ s_logger.info("cluster: " + cluster);
+ }
+
+ String agentUsername = _params.get("agentusername");
+ if (agentUsername == null) {
+ String msg = "Agent user name must be specified";
+ s_logger.info(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ String agentPassword = _params.get("agentpassword");
+ if (agentPassword == null) {
+ String msg = "Agent password must be specified";
+ s_logger.info(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ String agentPort = _params.get("agentport");
+ if (agentPort == null) {
+ String msg = "Agent port must be specified";
+ s_logger.info(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ try {
+ String hostname = url.getHost();
+ /* port = url.getPort(); */
+
+ InetAddress ia = InetAddress.getByName(hostname);
+ String hostIp = ia.getHostAddress();
+ String guid = UUID.nameUUIDFromBytes(hostIp.getBytes()).toString();
+
+ if (checkIfExisted(guid)) {
+ String msg = "The host " + hostIp + " has been added before";
+ s_logger.debug(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ s_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 = String.format("Cannot connect to Ovm3 host(IP=%1$s, username=%2$s, password=*******), discovery failed",
+ hostIp, username);
+ s_logger.warn(msg);
+ throw new CloudRuntimeException(msg);
+ }
+
+ Map<String, String> details = new HashMap<String, String>();
+ Ovm3ResourceBase ovmResource = new Ovm3ResourceBase();
+ 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);
+ }
+ s_logger.warn("network devices: " + _guestNetworkDevice + " "
+ + _privateNetworkDevice + " " + _publicNetworkDevice + " "
+ + _storageNetworkDevice);
+
+ Map<String, Object> params = new HashMap<String, Object>();
+ params.putAll(details);
+
+ ovmResource.configure(hostname, params);
+ ovmResource.start();
+
+ try {
+ c = new Connection(hostIp, Integer.parseInt(agentPort), agentUsername, agentPassword);
+ } catch (Exception e) {
+ String msg = String.format("Cannot connect to Ovm3 agent(IP=%1$s, Port=%1$, username=%3$s, password=*******), discovery failed",
+ hostIp, agentPort, agentUsername);
+ s_logger.warn(msg);
+ throw new CloudRuntimeException(msg);
+ }
+ /* 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<Ovm3ResourceBase, Map<String, String>> resources = new HashMap<Ovm3ResourceBase, Map<String, String>>();
+ resources.put(ovmResource, details);
+ return resources;
+ } catch (XmlRpcException e) {
+ s_logger.debug("XmlRpc exception, Unable to discover Ovm3 host: " + url.getHost(),
+ e);
+ return null;
+ } catch (UnknownHostException e) {
+ s_logger.debug(
+ "Host name resolve failed exception, Unable to discover Ovm3 host: "
+ + url.getHost(), e);
+ return null;
+ } catch (ConfigurationException e) {
+ s_logger.debug(
+ "Configure resource failed, Unable to discover Ovm3 host: " + url.getHost(),
+ e);
+ return null;
+ } catch (Exception e) {
+ s_logger.debug("Unable to discover Ovm3 host: " + url.getHost(), e);
+ return null;
+ }
+ }
+
+ @Override
+ public void postDiscovery(List<HostVO> hosts, long msId)
+ throws CloudRuntimeException {
+ // TODO Auto-generated method stub
+ s_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) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean processAnswers(long agentId, long seq, Answer[] answers) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean processCommands(long agentId, long seq, Command[] commands) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public AgentControlAnswer processControlCommand(long agentId,
+ AgentControlCommand cmd) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /* for reconnecting */
+ @Override
+ public void processConnect(Host host, StartupCommand cmd,
+ boolean forRebalance) {
+ }
+
+ @Override
+ public boolean processDisconnect(long agentId, Status state) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean isRecurring() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public int getTimeout() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public boolean processTimeout(long agentId, long seq) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public HostVO createHostVOForDirectConnectAgent(HostVO host,
+ StartupCommand[] startup, ServerResource resource,
+ Map<String, String> details, List<String> hostTags) {
+ StartupCommand firstCmd = startup[0];
+ if (!(firstCmd instanceof StartupRoutingCommand)) {
+ return null;
+ }
+
+ StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd);
+ if (ssCmd.getHypervisorType() != HypervisorType.Ovm3) {
+ return null;
+ }
+
+ // TODO: Double check this
+ return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.Ovm3,
+ details, hostTags);
+ }
+
+ // TODO: Make sure that we cleanup when the host is removed
+ @Override
+ public DeleteHostAnswer deleteHost(HostVO host, boolean isForced,
+ boolean isForceDeleteStorage) throws UnableDeleteHostException {
+ if (host.getType() != com.cloud.host.Host.Type.Routing
+ || host.getHypervisorType() != HypervisorType.Ovm3) {
+ return null;
+ }
+
+ _resourceMgr.deleteRoutingHost(host, isForced, isForceDeleteStorage);
+ return new DeleteHostAnswer(true);
+ }
+
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java
new file mode 100755
index 0000000..30db663
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Fencer.java
@@ -0,0 +1,133 @@
+// 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.hypervisor;
+
+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 Ovm3Fencer extends AdapterBase implements FenceBuilder {
+ Map<String, Object> _params;
+ private static final Logger s_logger = Logger.getLogger(Ovm3Fencer.class);
+ @Inject
+ AgentManager _agentMgr;
+ @Inject
+ ResourceManager _resourceMgr;
+
+
+ @Override
+ public boolean configure(String name, Map<String, Object> params)
+ throws ConfigurationException {
+ _params = params;
+ return true;
+ }
+
+ @Override
+ public boolean start() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ @Override
+ public boolean stop() {
+ // TODO Auto-generated method stub
+ return true;
+ }
+
+ public Ovm3Fencer() {
+ super();
+ }
+
+ @Override
+ public Boolean fenceOff(VirtualMachine vm, Host host) {
+ if (host.getHypervisorType() != HypervisorType.Ovm3) {
+ s_logger.debug("Don't know how to fence non Ovm3 hosts "
+ + host.getHypervisorType());
+ return null;
+ } else {
+ s_logger.debug("Fencing " + vm + " on host " + host
+ + " with params: "+ _params );
+ }
+
+ List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(host
+ .getClusterId());
+ FenceCommand fence = new FenceCommand(vm, host);
+
+ for (HostVO h : hosts) {
+ if (h.getHypervisorType() != HypervisorType.Ovm3) {
+ continue;
+ }
+
+ if (h.getStatus() != Status.Up) {
+ continue;
+ }
+
+ if (h.getId() == host.getId()) {
+ continue;
+ }
+
+ FenceAnswer answer;
+ try {
+ answer = (FenceAnswer) _agentMgr.send(h.getId(), fence);
+ } catch (AgentUnavailableException e) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Moving on to the next host because "
+ + h.toString() + " is unavailable");
+ }
+ continue;
+ } catch (OperationTimedoutException e) {
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Moving on to the next host because "
+ + h.toString() + " is unavailable");
+ }
+ continue;
+ }
+
+ if (answer != null && answer.getResult()) {
+ return true;
+ }
+ }
+
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Unable to fence off " + vm.toString() + " on "
+ + host.toString());
+ }
+
+ return false;
+ }
+
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java
new file mode 100755
index 0000000..08aac30
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Guru.java
@@ -0,0 +1,65 @@
+// 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.
+
+/* shameless rip from original ovm guru */
+package com.cloud.hypervisor.ovm3.hypervisor;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+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.vm.VirtualMachineProfile;
+
+@Local(value = HypervisorGuru.class)
+public class Ovm3Guru extends HypervisorGuruBase implements HypervisorGuru {
+ // private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
+
+ @Inject
+ GuestOSDao _guestOsDao;
+
+ protected Ovm3Guru() {
+ 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;
+ }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java
new file mode 100755
index 0000000..8b0b1b5
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3Helper.java
@@ -0,0 +1,82 @@
+// 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.hypervisor;
+
+import java.util.HashMap;
+
+public class Ovm3Helper {
+ /* /usr/lib64/python2.4/site-packages/agent/lib/assembly */
+ private static final HashMap<String, String> s_ovmMap = new HashMap<String, String>();
+
+ public static final String HVM = "hvm";
+ public static final String PV = "xen_pvm";
+ public static final String DOMSOL = "ldoms_pvm";
+ public static final String DEFAULT = "default";
+
+ static {
+ s_ovmMap.put("Oracle Enterprise Linux 6.0 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 6.0 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.0 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.0 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.1 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.1 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.2 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.2 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.3 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.3 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.4 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.4 (64-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.5 (32-bit)", PV);
+ s_ovmMap.put("Oracle Enterprise Linux 5.5 (64-bit)", PV);
+ s_ovmMap.put("Other Linux (32-bit)", PV);
+ s_ovmMap.put("Other Linux (64-bit)", PV);
+ s_ovmMap.put("Other PV (32-bit)", PV);
+ s_ovmMap.put("Other PV (64-bit)", PV);
+ s_ovmMap.put("Debian GNU/Linux 7(32-bit)", PV);
+ s_ovmMap.put("Debian GNU/Linux 7(64-bit)", PV);
+ s_ovmMap.put("Linux HVM (32-bit)", HVM);
+ s_ovmMap.put("Linux HVM (64-bit)", HVM);
+ s_ovmMap.put("Dos", HVM);
+ s_ovmMap.put("Windows 7 (32-bit)", HVM);
+ s_ovmMap.put("Windows 7 (64-bit)", HVM);
+ s_ovmMap.put("Windows 8 (64-bit)", HVM);
+ s_ovmMap.put("Windows Server 2003 (32-bit)", HVM);
+ s_ovmMap.put("Windows Server 2003 (64-bit)", HVM);
+ s_ovmMap.put("Windows Server 2008 (32-bit)", HVM);
+ s_ovmMap.put("Windows Server 2008 (64-bit)", HVM);
+ s_ovmMap.put("Windows Server 2008 R2 (64-bit)", HVM);
+ s_ovmMap.put("Windows Server 2012 (64-bit)", HVM);
+ s_ovmMap.put("Windows 2000 SP4 (32-bit)", HVM);
+ s_ovmMap.put("Windows Vista (32-bit)", HVM);
+ s_ovmMap.put("Windows XP SP2 (32-bit)", HVM);
+ s_ovmMap.put("Windows XP SP3 (32-bit)", HVM);
+ s_ovmMap.put("Sun Solaris 10(32-bit)", HVM);
+ s_ovmMap.put("Sun Solaris 10(64-bit)", HVM);
+ s_ovmMap.put("Sun Solaris 9(Experimental)", HVM);
+ s_ovmMap.put("Sun Solaris 8(Experimental)", HVM);
+ s_ovmMap.put("Sun Solaris 11 (32-bit)", HVM);
+ s_ovmMap.put("Sun Solaris 11 (64-bit)", HVM);
+ s_ovmMap.put("Sun Solaris PV (32-bit)", PV);
+ s_ovmMap.put("Sun Solaris PV (64-bit)", PV);
+ s_ovmMap.put("Sun Solaris Sparc (32-bit)", DOMSOL);
+ s_ovmMap.put("Sun Solaris Sparc (64-bit)", DOMSOL);
+ }
+
+ public static String getOvm3GuestType(String stdType) {
+ return s_ovmMap.get(stdType);
+ }
+}
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java
new file mode 100755
index 0000000..6b563d5
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/hypervisor/Ovm3ResourceBase.java
@@ -0,0 +1,3211 @@
+// 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.hypervisor;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.net.URI;
+import java.util.ArrayList;
+// import java.net.URISyntaxException;
+/*
+ * import java.util.ArrayList;
+ */
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.net.URL;
+
+import org.apache.commons.lang.BooleanUtils;
+
+import com.google.gson.Gson;
+
+import org.apache.commons.codec.binary.Base64;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+import org.apache.xmlrpc.XmlRpcException;
+import org.apache.cloudstack.storage.to.TemplateObjectTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+
+
+
+
+// import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+// import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import com.cloud.agent.IAgentControl;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.AttachIsoCommand;
+import com.cloud.agent.api.AttachVolumeAnswer;
+import com.cloud.agent.api.AttachVolumeCommand;
+import com.cloud.agent.api.CheckNetworkAnswer;
+import com.cloud.agent.api.CheckNetworkCommand;
+import com.cloud.agent.api.CheckVirtualMachineAnswer;
+import com.cloud.agent.api.CheckVirtualMachineCommand;
+// import com.cloud.agent.api.CleanupNetworkRulesCmd;
+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.FenceAnswer;
+import com.cloud.agent.api.FenceCommand;
+import com.cloud.agent.api.GetHostStatsAnswer;
+import com.cloud.agent.api.GetHostStatsCommand;
+import com.cloud.agent.api.GetStorageStatsAnswer;
+import com.cloud.agent.api.GetStorageStatsCommand;
+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.GetDomRVersionAnswer;
+import com.cloud.agent.api.GetDomRVersionCmd;
+import com.cloud.agent.api.NetworkRulesSystemVmCommand;
+import com.cloud.a
<TRUNCATED>
[2/7] CLOUDSTACK-6967: Now with module!
Posted by se...@apache.org.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Pool.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Pool.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Pool.java
new file mode 100644
index 0000000..2b87c70
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Pool.java
@@ -0,0 +1,362 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.apache.commons.lang.StringUtils;
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * synonym to the pool python lib in the ovs-agent
+ */
+public class Pool extends OvmObject {
+ /*
+ * {Pool_Filesystem_Target=cs-mgmt:/volumes/cs-data/secondary,
+ * Pool_Filesystem_Type=nfs,
+ * Pool_Filesystem_Nfsbase_Uuid=b8ca41cb-3469-4f74-a086-dddffe37dc2d,
+ * Pool_Filesystem_Uuid=0004fb0000050000e70fbddeb802208f}
+ */
+ private List<String> validRoles = new ArrayList<String>() {
+ {
+ add("utility");
+ add("xen");
+ }
+ };
+ private Boolean _poolDisc = false;
+ public Map<String, String> poolFileSystem = new HashMap<String, String>();
+ public List<String> poolIps = new ArrayList<String>();
+ private List<String> poolRoles = new ArrayList<String>();
+ public List<String> poolMembers = new ArrayList<String>();
+ public String poolMasterVip;
+ public String poolAlias;
+ public String poolId = "";
+
+ public Pool(Connection c) throws ParserConfigurationException, IOException,
+ Exception {
+ client = c;
+ discoverServerPool();
+ }
+
+ public String getPoolMasterVip() {
+ return this.poolMasterVip;
+ }
+
+ public String getPoolAlias() {
+ return this.poolAlias;
+ }
+
+ public String getPoolId() {
+ return this.poolId;
+ }
+
+ /* TODO: check the toString for the list x,x */
+ public List<String> getValidRoles() {
+ return this.validRoles;
+ }
+
+ public void setPoolIps(List<String> ips) {
+ this.poolIps = new ArrayList<String>();
+ this.poolIps.addAll(ips);
+ }
+
+ /*
+ * create_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+ * self - default: None argument: pool_alias - default: None argument:
+ * pool_uuid - default: None argument: pool_virtual_ip - default: None
+ * argument: node_number - default: None argument: server_hostname -
+ * default: None argument: server_ip - default: None argument: roles -
+ * default: None
+ */
+ public Boolean createServerPool(String alias, String id, String vip,
+ int num, String name, String ip, List<String> roles)
+ throws XmlRpcException {
+ String role = roles.toString();
+ role = "xen,utility";
+ Object x = callWrapper("create_server_pool", alias, id, vip, num, name,
+ ip,
+ role);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean createServerPool(String alias, String id, String vip,
+ int num, String name, String ip) throws XmlRpcException {
+ return this.createServerPool(alias,
+ id,
+ vip,
+ num,
+ name,
+ ip,
+ getValidRoles());
+ }
+ public Boolean createServerPool(int num, String name, String ip)
+ throws XmlRpcException {
+ return createServerPool(poolAlias, poolId, poolMasterVip, num, name,
+ ip, poolRoles);
+ }
+
+ /*
+ * update_pool_virtual_ip, <class 'agent.api.serverpool.ServerPool'>
+ * argument: self - default: None argument: new_pool_vip - default: None
+ */
+ public Boolean updatePoolVirtualIp(String ip) throws XmlRpcException {
+ Object x = callWrapper("update_pool_virtual_ip", ip);
+ if (x == null) {
+ this.poolMasterVip = ip;
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * leave_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+ * self - default: None argument: pool_uuid - default: None
+ */
+ public Boolean leaveServerPool(String uuid) throws XmlRpcException {
+ Object x = callWrapper("leave_server_pool", uuid);
+ if (x == null)
+ return true;
+ return false;
+ }
+
+ /*
+ * set_server_pool_alias, <class 'agent.api.serverpool.ServerPool'>
+ * argument: self - default: None argument: pool_alias - default: None
+ */
+ public Boolean setServerPoolAlias(String alias) throws XmlRpcException {
+ Object x = callWrapper("set_server_pool_alias", alias);
+ if (x == null) {
+ this.poolAlias = alias;
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * take_ownership, <class 'agent.api.serverpool.ServerPool'> argument: self
+ * - default: None argument: manager_uuid - default: None argument:
+ * manager_core_api_url - default: None
+ * take_ownership('0004fb00000100000af70d20dcce7d65',
+ * 'https://2f55e3b9efa6f067ad54a7b144bb6f2e:
+ * ******@0.0.0.0:7002/ovm/core/OVMManagerCoreServlet')
+ */
+ public Boolean takeOwnership(String uuid, String apiurl)
+ throws XmlRpcException {
+ Object x = callWrapper("take_ownership", uuid, apiurl);
+ if (x == null) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * destroy_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+ * self - default: None argument: pool_uuid - default: None
+ */
+ public Boolean destroyServerPool(String uuid) throws XmlRpcException {
+ Object x = callWrapper("destroy_server_pool", uuid);
+ if (x == null) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * release_ownership, <class 'agent.api.serverpool.ServerPool'> argument:
+ * self - default: None argument: manager_uuid - default: None
+ */
+ public Boolean releaseOwnership(String uuid) throws XmlRpcException {
+ Object x = callWrapper("release_ownership", uuid);
+ if (x == null) {
+ return true;
+ }
+ return false;
+ }
+
+ /* server.discover_pool_filesystem */
+ /*
+ * discover_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+ * self - default: None
+ */
+ public Boolean discoverServerPool() throws ParserConfigurationException,
+ IOException, Exception {
+ /* forcefull rediscover for now */
+ if (this._poolDisc) {
+ return true;
+ }
+ Object x = callWrapper("discover_server_pool");
+ if (x == null) {
+ return false;
+ }
+
+ try {
+ Document xmlDocument = prepParse((String) x);
+ String path = "//Discover_Server_Pool_Result/Server_Pool";
+ this.poolId = xmlToString(path + "/Unique_Id", xmlDocument);
+ this.poolAlias = xmlToString(path + "/Pool_Alias", xmlDocument);
+ this.poolMasterVip = xmlToString(path + "/Master_Virtual_Ip",
+ xmlDocument);
+ this.poolMembers = xmlToList(path + "/Member_List", xmlDocument);
+ this.poolIps
+ .addAll(xmlToList(path + "//Registered_IP", xmlDocument));
+ this._poolDisc = true;
+ } catch (Exception e) {
+ if (e.getMessage() == null) {
+ System.err.println("No pool to discover: " + e.getMessage());
+ } else {
+ System.err.println("Error in pooldiscovery: " + e.getMessage());
+ }
+ }
+
+ return true;
+ }
+
+ /*
+ * update_server_roles, <class 'agent.api.serverpool.ServerPool'> argument:
+ * self - default: None argument: roles - default: None ?> list or sring
+ */
+ private Boolean validPoolRole(String role) throws Exception {
+ for (String r : this.validRoles) {
+ if (r.contentEquals(role)) {
+ return true;
+ }
+ }
+ throw new Exception("Illegal role: " + role);
+ }
+
+ private Boolean validPoolRole(List<String> roles) throws Exception {
+ for (String r : roles) {
+ return validPoolRole(r);
+ }
+ return false;
+ }
+
+ public Boolean setServerRoles() throws XmlRpcException, Exception {
+ validPoolRole(this.poolRoles);
+ String roles = StringUtils.join(this.poolRoles.toArray(), ",");
+ Object x = callWrapper("update_server_roles", roles);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /* do some sanity check on the valid poolroles */
+ public Boolean setServerRoles(List<String> roles) throws Exception {
+ this.poolRoles.addAll(roles);
+ return setServerRoles();
+ }
+
+
+ public void addServerRole(String role) throws Exception {
+ validPoolRole(role);
+ this.poolRoles.add(role);
+ }
+
+ public void removeServerRole(String role) {
+ this.poolRoles.remove(role);
+ }
+
+ public boolean serverHasRole(String role) {
+ for (String r : this.poolRoles) {
+ if (r.contentEquals(role)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /*
+ * join_server_pool, <class 'agent.api.serverpool.ServerPool'> argument:
+ * self - default: None argument: pool_alias - default: None argument:
+ * pool_uuid - default: None argument: pool_virtual_ip - default: None
+ * argument: node_number - default: None argument: server_hostname -
+ * default: None argument: server_ip - default: None argument: roles -
+ * default: None
+ */
+ /* allow these to be set before ? */
+ public Boolean joinServerPool(String alias, String id, String vip, int num,
+ String name, String ip, List<String> roles) throws XmlRpcException {
+ String role = StringUtils.join(roles.toArray(), ",");
+ Object x = callWrapper("join_server_pool", alias, id, vip, num, name,
+ ip,
+ role);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean joinServerPool(String alias, String id, String vip, int num,
+ String name, String ip) throws XmlRpcException {
+ return joinServerPool(alias, id, vip, num, name, ip, getValidRoles());
+ }
+
+ public Boolean joinServerPool(int num, String name, String ip)
+ throws XmlRpcException {
+ return joinServerPool(poolAlias, poolId, poolMasterVip, num, name, ip,
+ poolRoles);
+ }
+
+ /*
+ * set_pool_member_ip_list, <class 'agent.api.serverpool.ServerPool'>
+ * argument: self - default: None argument: ip_list - default: None
+ */
+ public Boolean setPoolMemberIpList() throws XmlRpcException {
+ // should throw exception if no poolIps set
+ Object x = callWrapper("set_pool_member_ip_list", this.poolIps);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public List getPoolMemberIpList() throws XmlRpcException, Exception {
+ if (poolIps.size() == 0) {
+ this.discoverServerPool();
+ }
+ return poolIps;
+ }
+
+ /* TODO: need to change the logic here */
+ public Boolean setPoolMemberIpList(String ip) throws XmlRpcException {
+ this.poolIps = new ArrayList<String>();
+ this.poolIps.add(ip);
+ return setPoolMemberIpList();
+ }
+
+ public Boolean addPoolMemberIp(String ip) throws XmlRpcException, Exception {
+ this.getPoolMemberIpList();
+ this.poolIps.add(ip);
+ return setPoolMemberIpList();
+ }
+
+ /* meh */
+ public Boolean removePoolMemberIp(String ip) throws XmlRpcException,
+ Exception {
+ this.getPoolMemberIpList();
+ this.poolIps.remove(ip);
+ return setPoolMemberIpList();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/PoolOCFS2.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/PoolOCFS2.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/PoolOCFS2.java
new file mode 100644
index 0000000..1759224
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/PoolOCFS2.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+
+/* should ingest this into Pool */
+public class PoolOCFS2 extends OvmObject {
+ public Map<String, String> poolFileSystem = new HashMap<String, String>();
+ public String poolFsTarget;
+ public String poolFsType;
+ public String poolFsNFSBaseId;
+ public String poolFsId;
+
+ public String poolFsNFSBaseId() {
+ return this.poolFsNFSBaseId;
+ }
+
+ public String poolFsId() {
+ return this.poolFsId;
+ }
+
+ public String poolFsUuid() {
+ return this.poolFsId;
+ }
+
+ public String poolFsTarget() {
+ return this.poolFsTarget;
+ }
+
+ public PoolOCFS2(Connection c) {
+ client = c;
+ }
+
+ /*
+ * destroy_pool_filesystem, <class 'agent.api.poolfs.ocfs2.PoolOCFS2'>
+ * argument: self - default: None argument: poolfs_type - default: None
+ * argument: poolfs_target - default: None argument: poolfs_uuid - default:
+ * None argument: poolfs_nfsbase_uuid - default: None
+ */
+ public Boolean destroyPoolFs(String type, String target, String uuid,
+ String nfsbaseuuid) throws ParserConfigurationException,
+ IOException, Exception {
+ // should throw exception if no poolIps set
+ Object x = callWrapper("destroy_pool_filesystem", type, target, uuid,
+ nfsbaseuuid);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean destroyPoolFs() throws ParserConfigurationException,
+ IOException, Exception {
+ // should throw exception if no poolIps set
+ Object x = callWrapper("destroy_pool_filesystem", poolFsType,
+ poolFsTarget, poolFsId, poolFsNFSBaseId);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * create_pool_filesystem, <class 'agent.api.poolfs.ocfs2.PoolOCFS2'>
+ * argument: self - default: None argument: poolfs_type - default: None
+ * argument: poolfs_target - default: None argument: cluster_name - default:
+ * None argument: poolfs_uuid - default: None argument: poolfs_nfsbase_uuid
+ * - default: None argument: manager_uuid - default: None argument:
+ * pool_uuid - default: None argument: block_size - default: None argument:
+ * cluster_size - default: None argument: journal_size - default: None
+ */
+ /*
+ * create_pool_filesystem('nfs', 'cs-mgmt:/volumes/cs-data/secondary',
+ * 'ba9aaf00ae5e2d73', '0004fb0000050000e70fbddeb802208f',
+ * 'b8ca41cb-3469-4f74-a086-dddffe37dc2d',
+ * '0004fb00000100000af70d20dcce7d65', '0004fb0000020000ba9aaf00ae5e2d73')
+ */
+ public Boolean createPoolFs(String type, String target, String clustername,
+ String fsid, String nfsbaseid, String managerid, String id)
+ throws XmlRpcException {
+ Object x = callWrapper("create_pool_filesystem", type, target,
+ clustername, fsid, nfsbaseid, managerid, id);
+ // System.out.println(x);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean createPoolFs(String type, String target, String clustername,
+ String fsid, String nfsbaseid, String managerid, String id,
+ int blocksize, int clustersize, int journalsize)
+ throws XmlRpcException {
+ Object x = callWrapper("create_pool_filesystem", type, target,
+ clustername, fsid, nfsbaseid, managerid, id, blocksize,
+ clustersize, journalsize);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * discover_pool_filesystem, <class 'agent.api.poolfs.ocfs2.PoolOCFS2'>
+ * argument: self - default: None
+ */
+ public Boolean discoverPoolFs() throws ParserConfigurationException,
+ IOException, Exception {
+ // should throw exception if no poolIps set
+ Object x = callWrapper("discover_pool_filesystem");
+ 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");
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * ocfs2_get_meta_data, <class 'agent.api.poolfs.ocfs2.PoolOCFS2'> argument:
+ * self - default: None argument: device - default: None argument: filename
+ * - default: None
+ */
+ public Boolean ocfs2GetMetaData(String device, String filename)
+ throws XmlRpcException {
+ Object x = callWrapper("ocfs2_get_meta_data", device, filename);
+ // System.out.println(x);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Remote.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Remote.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Remote.java
new file mode 100644
index 0000000..a2ae0a4
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Remote.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Remote extends OvmObject {
+
+ public Remote(Connection c) {
+ client = c;
+ }
+
+ /*
+ * sys_shutdown, <class
+ * 'agent.api.remote.linux_remote.LinuxRemoteManagement'> argument: self -
+ * default: None
+ */
+ public Boolean sysShutdown() throws XmlRpcException {
+ Object x = callWrapper("sys_shutdown");
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * remote_power_off, <class
+ * 'agent.api.remote.linux_remote.LinuxRemoteManagement'> argument: self -
+ * default: None argument: controller_type - default: None ?> figure this
+ * one out in the source argument: tgt_host - default: None argument:
+ * bmc_username - default: None argument: bmc_password - default: None
+ */
+
+ /*
+ * sys_reboot, <class 'agent.api.remote.linux_remote.LinuxRemoteManagement'>
+ * argument: self - default: None
+ */
+ public Boolean sysReboot() throws XmlRpcException {
+ Object x = callWrapper("sys_reboot");
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * remote_power_on, <class
+ * 'agent.api.remote.linux_remote.LinuxRemoteManagement'> argument: self -
+ * default: None argument: controller_type - default: None ?> same here
+ * argument: tgt - default: None argument: arg1 - default: None argument:
+ * arg2 - default: None
+ */
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Repository.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Repository.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Repository.java
new file mode 100644
index 0000000..d45f198
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/Repository.java
@@ -0,0 +1,205 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import java.util.Map;
+
+import org.apache.xmlrpc.XmlRpcException;
+
+/*
+ * should become an interface implementation
+ */
+public class Repository extends OvmObject {
+
+ public Repository(Connection c) {
+ client = c;
+ }
+
+ /*
+ * delete_repository, <class 'agent.api.repository.Repository'> argument:
+ * repo_uuid - default: None argument: erase - default: None
+ */
+ public Boolean deleteRepo(String id, Boolean erase) throws XmlRpcException {
+ Object x = callWrapper("delete_repository", id, erase);
+ if (x == 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 XmlRpcException {
+ Object x = callWrapper("import_virtual_disk", url, vdiskid, repoid, option);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+ public Boolean importVirtualDisk(String url, String vdiskid, String repoid) throws XmlRpcException {
+ Object x = callWrapper("import_virtual_disk", url, vdiskid, repoid);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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(Map<String, String> args)
+ throws XmlRpcException {
+ Object x = callWrapper("discover_repositories", args);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean discoverRepo(String id) throws XmlRpcException {
+ Object x = callWrapper("discover_repositories", id);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Object x = callWrapper("add_repository", remote, local);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * get_repository_meta_data, <class 'agent.api.repository.Repository'>
+ * argument: repo_mount_point - default: None
+ */
+ public Boolean getRepoMetaData(String local) throws XmlRpcException {
+ Object x = callWrapper("get_repository_meta_data", local);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Object x = callWrapper("mount_repository_fs", remote, local);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * unmount_repository_fs, <class 'agent.api.repository.Repository'>
+ * argument: mount_point - default: None
+ */
+ public Boolean unmountRepoFs(String local) throws XmlRpcException {
+ Object x = callWrapper("unmount_repository_fs", local);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Object x = callWrapper("create_repository", remote, local, repoid,
+ repoalias);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 XmlRpcException {
+ Object x = callWrapper("discover_repository_db");
+ // System.out.println(x);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * edit_repository_db, <class 'agent.api.repository.Repository'> argument:
+ * repo_uuid - default: None argument: db_changes - default: None
+ */
+ public Boolean editRepoDb(String repoId, Map<String, String> changes)
+ throws XmlRpcException {
+ Object x = callWrapper("edit_repository_db", repoId, changes);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * import_ISO, <class 'agent.api.repository.Repository'> argument: url -
+ * default: None argument: iso_id - default: None argument: repo_uuid -
+ * default: None argument: option - default: None ?> it throws an error when
+ * you add this...
+ */
+ /*
+ * is async, need to find a way to do something with that.... add timeout
+ * too
+ */
+ public Boolean importIso(String url, String isoId, String repoId,
+ String option) throws XmlRpcException {
+ Object x = callWrapper("import_ISO", url, isoId, repoId);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/RpcTypeFactory.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/RpcTypeFactory.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/RpcTypeFactory.java
new file mode 100644
index 0000000..240efef
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/RpcTypeFactory.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+/*
+ * Dealing with nil..... -sigh-
+ * http://libjack.com/2009/03/26/java-magento-xmlrpc-api-nil-issue/
+ *
+ * i8 - aka long
+ */
+
+package com.cloud.hypervisor.ovm3.object;
+
+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 (pLocalName.equals("i8")) {
+ 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(new Long(pResult.trim()));
+ } catch (NumberFormatException e) {
+ throw new SAXParseException("Failed to parse long value: "
+ + pResult, getDocumentLocator());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1516b041/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/StoragePlugin.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/StoragePlugin.java b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/StoragePlugin.java
new file mode 100644
index 0000000..c311523
--- /dev/null
+++ b/plugins/hypervisors/ovm3/src/com/cloud/hypervisor/ovm3/object/StoragePlugin.java
@@ -0,0 +1,876 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.cloud.hypervisor.ovm3.object;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xmlrpc.XmlRpcException;
+import org.w3c.dom.Document;
+
+/*
+ * should become an interface implementation
+ */
+public class StoragePlugin extends OvmObject {
+ /* nfs or iscsi should be an "enabled" flag */
+ /*
+ * storage_plugin_mount('oracle.generic.NFSPlugin.GenericNFSPlugin', {
+ * 'status': '', 'admin_user': '', 'admin_host': '', 'uuid':
+ * '0004fb00000900000c2461c2f62ba43e', 'total_sz': 0, 'admin_passwd':
+ * '******', 'storage_desc': '', 'free_sz': 0, 'access_host': 'cs-mgmt',
+ * 'storage_type': 'FileSys', 'alloc_sz': 0, 'access_grps': [], 'used_sz':
+ * 0, 'name': '0004fb00000900000c2461c2f62ba43e'}, { 'status': '', 'uuid':
+ * 'b8ca41cb-3469-4f74-a086-dddffe37dc2d', 'ss_uuid':
+ * '0004fb00000900000c2461c2f62ba43e', 'size': '263166853120', 'free_sz':
+ * '259377299456', 'state': 1, 'access_grp_names': [], 'access_path':
+ * 'cs-mgmt:/volumes/cs-data/secondary', 'name':
+ * 'nfs:/volumes/cs-data/secondary'},
+ * '/nfsmnt/b8ca41cb-3469-4f74-a086-dddffe37dc2d', '', True, [])
+ */
+ private String pluginType = "oracle.generic.NFSPlugin.GenericNFSPlugin";
+
+ /* TODO: subclass */
+ /*
+ * Json, but then it's xml... {'status': '', 'admin_user': '', 'admin_host':
+ * '', 'uuid': '0004fb00000900000c2461c2f62ba43e', 'total_sz': 0,
+ * 'admin_passwd': '******', 'storage_desc': '', 'free_sz': 0,
+ * 'access_host': 'cs-mgmt', 'storage_type': 'FileSys', 'alloc_sz': 0,
+ * 'access_grps': [], 'used_sz': 0, 'name':
+ * '0004fb00000900000c2461c2f62ba43e'}
+ */
+ private Map<String, Object> baseProps = new HashMap<String, Object>() {
+ {
+ put("status", ""); /* empty */
+ put("admin_user", ""); /* auth */
+ put("admin_host", ""); /* auth host */
+ put("uuid", ""); /* no dash uuid */
+ put("total_sz", "");
+ put("admin_passwd", ""); /* iscsi or fc */
+ put("storage_desc", ""); /* description */
+ put("free_sz", 0);
+ put("access_host", ""); /* remote host for fs */
+ put("storage_type", "FileSys"); /* type, guess lun ? */
+ put("alloc_size", 0);
+ put("access_groups", new ArrayList<String>());
+ put("sed_size", 0);
+ put("name", ""); /* uuid no dashes */
+ };
+ };
+
+ public String setUuid(String val) {
+ this.baseProps.put("uuid", val);
+ return val;
+ }
+
+ public String getUuid() {
+ return (String) this.baseProps.get("uuid");
+ }
+
+ public String setName(String val) {
+ this.baseProps.put("name", val);
+ return val;
+ }
+
+ public String getName() {
+ return (String) this.baseProps.get("name");
+ }
+
+ public String setFsType(String val) {
+ this.baseProps.put("storage_type", val);
+ return val;
+ }
+
+ public String getFsType() {
+ return (String) this.baseProps.get("storage_type");
+ }
+
+ public String setFsHost(String val) {
+ this.baseProps.put("access_host", val);
+ return val;
+ }
+
+ public String getFsHost() {
+ return (String) this.baseProps.get("access_host");
+ }
+
+ public String setFsServer(String val) {
+ return this.setFsHost(val);
+ }
+
+ public String getFsServer() {
+ return this.getFsHost();
+ }
+
+ /* TODO: subclass */
+ /*
+ * Meh {'status': '', 'uuid': 'b8ca41cb-3469-4f74-a086-dddffe37dc2d',
+ * 'ss_uuid': '0004fb00000900000c2461c2f62ba43e', 'size': '263166853120',
+ * 'free_sz': '259377299456', 'state': 1, 'access_grp_names': [],
+ * 'access_path': 'cs-mgmt:/volumes/cs-data/secondary', 'name':
+ * 'nfs:/volumes/cs-data/secondary'}
+ */
+ private Map<String, Object> ssProps = new HashMap<String, Object>() {
+ {
+ put("status", ""); /* empty */
+ put("uuid", ""); /* with dashes */
+ put("ss_uuid", ""); /* no dashes */
+ put("size", "");
+ put("free_sz", "");
+ put("state", 1); /* guess this is active ? */
+ put("access_grp_names", new ArrayList<String>());
+ put("access_path", ""); /* remote path */
+ put("name", ""); /* just a name */
+ put("mount_options", new ArrayList<String>()); /*
+ * array of values
+ * which match normal
+ * mount options
+ */
+ };
+ };
+
+ public String setFsSourcePath(String val) {
+ this.ssProps.put("access_path", val);
+ return val;
+ }
+
+ public String getFsSourcePath() {
+ return (String) this.ssProps.get("access_path");
+ }
+
+ public String setMntUuid(String val) {
+ this.ssProps.put("uuid", val);
+ return val;
+ }
+
+ public String getMntUuid() {
+ return (String) this.ssProps.get("uuid");
+ }
+
+ public String setSsUuid(String val) {
+ this.ssProps.put("ss_uuid", val);
+ return val;
+ }
+
+ public String getSsUuid() {
+ return (String) this.ssProps.get("ss_uuid");
+ }
+
+ public String setSsName(String val) {
+ this.ssProps.put("name", val);
+ return val;
+ }
+
+ public String getSsName() {
+ return (String) this.ssProps.get("ss_uuid");
+ }
+
+ public String getFreeSize() {
+ return this.ssProps.get("free_sz").toString();
+ }
+
+ public String getTotalSize() {
+ return this.ssProps.get("size").toString();
+ }
+
+ public String getSize() {
+ return this.ssProps.get("size").toString();
+ }
+
+ /* TODO: subclass */
+ /* {'fr_type': 'File',
+ 'ondisk_sz': '48193536',
+ 'fs_uuid': '7718562d-872f-47a7-b454-8f9cac4ffa3a',
+ 'file_path': '/nfsmnt/7718562d-872f-47a7-b454-8f9cac4ffa3a/0004fb0000060000d4a1d2ec05a5e799.img',
+ 'file_sz': '52380672'}
+ */
+ private Map<String, Object> fileProps = new HashMap<String, Object>() {
+ {
+ put("fr_type", "");
+ put("ondisk_sz", "");
+ put("fs_uuid", "");
+ put("file_path", "");
+ put("file_sz", "");
+ }
+ };
+
+ public String getFileName() {
+ return (String) this.fileProps.get("file_path");
+ }
+ public long getFileSize() {
+ return Long.parseLong((String) this.fileProps.get("file_sz"));
+ }
+ private String mountPoint = "";
+
+ public String setFsMountPoint(String val) {
+ this.mountPoint = val;
+ return val;
+ }
+
+ public String getFsMountPoint() {
+ return mountPoint;
+ }
+
+ public String unknown = ""; /* empty */
+ public Boolean active = true;
+ public List<String> someList = new ArrayList<String>(); /* empty */
+
+ public StoragePlugin(Connection c) {
+ client = c;
+ }
+
+ /*
+ * 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
+ */
+
+ /* TODO: make more generic now only for files
+ * storage_plugin_create, <class 'agent.api.storageplugin.StoragePlugin'>
+ * argument: impl_name - default: None
+ * - calls resize secretly.. after "create"
+ */
+ public Boolean storagePluginCreate(String poolUuid, String host,
+ String file, Long size) throws XmlRpcException {
+ /* this is correct ordering stuff */
+ String uuid = this.deDash(poolUuid);
+ ssProps.put("uuid", uuid);
+ ssProps.put("access_host", host);
+ ssProps.put("storage_type", "FileSys");
+ ssProps.put("name", "");
+ ssProps.put("status", "");
+ ssProps.put("admin_user", "");
+ ssProps.put("admin_passwd", "");
+ ssProps.put("admin_host", "");
+ ssProps.put("total_sz", "");
+ ssProps.put("free_sz", "");
+ ssProps.put("used_sz", "");
+ ssProps.put("access_grps", "");
+ ssProps.put("storage_desc", "");
+
+ baseProps.put("ss_uuid", uuid);
+ baseProps.put("state", 2);
+ baseProps.put("uuid", poolUuid);
+ /* some more bogus values */
+ baseProps.put("status", "");
+ baseProps.put("access_path", "");
+ baseProps.put("access_grp_names", "");
+ baseProps.put("name", "");
+ baseProps.put("size", "");
+
+ /*
+ * fileProps.put("fr_type", "File");
+ * fileProps.put("fs_uuid", ssuuid);
+ * fileProps.put("file_path", file);
+ * fileProps.put("file_sz", "");
+ * fileProps.put("ondisk_sz", "");
+ */
+ Object x = (HashMap<String, Object>)callWrapper("storage_plugin_create",
+ this.pluginType, this.ssProps, this.baseProps, file, "File", size);
+
+ if (x == null)
+ return true;
+
+ return true;
+ }
+
+ /*
+ * 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 type) throws XmlRpcException {
+ this.pluginType = type;
+ return storagePluginListFs();
+ }
+
+ public Boolean storagePluginListFs() throws XmlRpcException {
+ Map<String, String> y = new HashMap<String, String>();
+ Object x = callWrapper("storage_plugin_listFileSystems",
+ this.pluginType, y);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * 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 Boolean storagePluginMount(String nfsHost, String nfsPath,
+ String mntUuid, String mountPoint) throws XmlRpcException {
+ String propUuid = this.deDash(mntUuid);
+ this.setUuid(propUuid);
+ this.setName(propUuid);
+ this.setFsServer(nfsHost);
+ this.setFsSourcePath(nfsHost + ":" + nfsPath);
+ this.setMntUuid(mntUuid);
+ this.setSsUuid(propUuid);
+ this.setSsName("nfs:" + nfsPath);
+ this.setFsMountPoint(mountPoint);
+ this.storagePluginMount();
+ Map<String, Object> x = (Map<String, Object>) callWrapper(
+ "storage_plugin_mount", this.pluginType, this.baseProps,
+ this.ssProps, this.mountPoint, this.unknown, this.active,
+ this.someList);
+ // System.out.println(x);
+ if (x == null) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * {ss_uuid=eb1dbafadee9450d876239bb5e3b7f4a,
+ * mount_options=[Ljava.lang.Object;@2d8dea20, status=,
+ * name=nfs:/volumes/cs-data/secondary, state=1,
+ * access_path=cs-mgmt:/volumes/cs-data/secondary,
+ * uuid=6ab917b0-a070-4254-8fe2-e2163ee0e885,
+ * access_grp_names=[Ljava.lang.Object;@4005f23d, free_sz=, size=}
+ */
+ public Boolean storagePluginMount() throws XmlRpcException {
+ Map<String, Object> x = (Map<String, Object>) callWrapper(
+ "storage_plugin_mount", this.pluginType, this.baseProps,
+ this.ssProps, this.mountPoint, this.unknown, this.active,
+ this.someList);
+ // System.out.println(x);
+ if (x == null) {
+ return true;
+ }
+ // System.out.println(x);
+ /*
+ * {ss_uuid=1b8685bf625642cb92ddd4c0d7b18620,
+ * mount_options=[Ljava.lang.Object;@6f479e5f, status=,
+ * name=nfs:/volumes/cs-data/secondary, state=1,
+ * access_path=cs-mgmt:/volumes/cs-data/secondary,
+ * uuid=54d78233-508f-4632-92a6-97fc1311ca23,
+ * access_grp_names=[Ljava.lang.Object;@46eea80c, free_sz=, size=}
+ */
+
+ /*
+ * if (!x.get("ss_uuid").equals(this.ssProps.get("ss_uuid"))) { return
+ * false; } this.ssProps.put("mount_options", x.get("mount_options"));
+ * this.ssProps.put("access_grp_names", x.get("access_grp_names"));
+ */
+ return false;
+ }
+
+ /**
+ * .
+ * storage_plugin_unmount, <class 'agent.api.storageplugin.StoragePlugin'>
+ * argument: impl_name - default: None
+ * @return boolean
+ * @throws XmlRpcException
+ */
+ public final Boolean storagePluginUnmount() throws XmlRpcException {
+ Object x = callWrapper("storage_plugin_unmount", this.pluginType,
+ this.baseProps, this.ssProps, this.mountPoint, this.active);
+ if (x == null) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * 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'>
+ */
+ /*
+ * <Discover_Storage_Plugins_Result> <storage_plugin_info_list>
+ * <storage_plugin_info plugin_impl_name="oracle.ocfs2.OCFS2.OCFS2Plugin">
+ * <fs_api_version>1,2,7</fs_api_version>
+ * <generic_plugin>False</generic_plugin>
+ * <plugin_version>0.1.0-38</plugin_version>
+ * <filesys_type>LocalFS</filesys_type>
+ * <extended_api_version>None</extended_api_version> <plugin_desc>Oracle
+ * OCFS2 File system Storage Connect Plugin</plugin_desc>
+ * <cluster_required>True</cluster_required> <plugin_name>Oracle OCFS2 File
+ * system</plugin_name> <fs_extra_info_help>None</fs_extra_info_help>
+ * <required_api_vers>1,2,7</required_api_vers>
+ * <file_extra_info_help>None</file_extra_info_help>
+ * <ss_extra_info_help>None</ss_extra_info_help>
+ * <filesys_name>ocfs2</filesys_name> <vendor_name>Oracle</vendor_name>
+ * <plugin_type>ifs</plugin_type> <abilities>
+ * <resize_is_sync>YES</resize_is_sync> <clone_is_sync>YES</clone_is_sync>
+ * <access_control>NO</access_control>
+ * <custom_clone_name>YES</custom_clone_name>
+ * <require_storage_name>NO</require_storage_name>
+ * <backing_device_type>DEVICE_SINGLE</backing_device_type>
+ * <splitclone_while_open>NO</splitclone_while_open>
+ * <custom_snap_name>YES</custom_snap_name> <snapshot>ONLINE</snapshot>
+ * <splitclone>UNSUPPORTED</splitclone> <snap_is_sync>YES</snap_is_sync>
+ * <snapclone>ONLINE</snapclone> <splitclone_is_sync>NO</splitclone_is_sync>
+ * <clone>ONLINE</clone> <resize>ONLINE</resize>
+ * <snapclone_is_sync>YES</snapclone_is_sync> </abilities>
+ * </storage_plugin_info> <storage_plugin_info
+ * plugin_impl_name="oracle.generic.SCSIPlugin.GenericPlugin"> ....
+ */
+ public Boolean discoverStoragePlugins()
+ throws ParserConfigurationException, IOException, Exception {
+ Object result = callWrapper("discover_storage_plugins");
+ // System.out.println(result);
+ Document xmlDocument = prepParse((String) result);
+ /* could be more subtle */
+ String path = "//Discover_Storage_Plugins_Result/storage_plugin_info_list";
+ /*
+ * Capabilities = xmlToMap(path+"/Capabilities", xmlDocument); VMM =
+ * xmlToMap(path+"/VMM", xmlDocument); NTP = xmlToMap(path+"/NTP",
+ * xmlDocument); Date_Time = xmlToMap(path+"/Date_Time", xmlDocument);
+ * Generic = xmlToMap(path, xmlDocument);
+ */
+ if (result != null)
+ return true;
+
+ return 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
+ */
+
+ /* TODO: 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 XmlRpcException {
+ /* clean the props, the empty ones are checked, but not for content... */
+ // String uuid = this.deDash(poolUuid);
+ baseProps.put("uuid", "");
+ baseProps.put("access_host", "");
+ baseProps.put("storage_type", "FileSys");
+ ssProps.put("ss_uuid", "");
+ ssProps.put("access_path", "");
+ ssProps.put("uuid", poolUuid);
+ fileProps.put("fr_type", "File");
+ fileProps.put("fs_uuid", poolUuid);
+ fileProps.put("file_path", file);
+ fileProps.put("file_sz", "");
+ fileProps.put("ondisk_sz", "");
+ Object x = (HashMap<String, Object>) callWrapper(
+ "storage_plugin_destroy", this.pluginType, this.baseProps,
+ this.ssProps, this.fileProps);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean storagePluginDestroy() throws XmlRpcException {
+ /* clean the props */
+ Object x = (HashMap<String, Object>) callWrapper(
+ "storage_plugin_destroy", this.pluginType, this.baseProps,
+ this.ssProps, this.fileProps);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ /*
+ * storage_plugin_isSnapable, <class
+ * 'agent.api.storageplugin.StoragePlugin'> argument: impl_name - default:
+ * None
+ */
+
+ /*
+ * storage_plugin_getStorageServerInfo, <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 Boolean storagePluginGetFileInfo() throws XmlRpcException {
+ fileProps = (HashMap<String, Object>)callWrapper("storage_plugin_getFileInfo",
+ this.pluginType, this.baseProps, this.fileProps);
+ if (fileProps == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean storagePluginGetFileInfo(String file) throws XmlRpcException {
+ fileProps.put("file_path", file);
+ fileProps = (HashMap<String, Object>)callWrapper("storage_plugin_getFileInfo",
+ this.pluginType,
+ this.ssProps,
+ this.baseProps,
+ this.fileProps);
+ if (fileProps == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean storagePluginGetFileInfo(String poolUuid, String host,
+ String file) throws XmlRpcException {
+ /* file path is the full path */
+ String uuid = this.deDash(poolUuid);
+ baseProps.put("uuid", poolUuid);
+ baseProps.put("access_host", host);
+ ssProps.put("access_path", "");
+ ssProps.put("uuid", uuid);
+ ssProps.put("state", 1);
+ ssProps.put("ss_uuid", poolUuid);
+ ssProps.put("name", "");
+ fileProps.put("file_path", file);
+ fileProps = (HashMap<String, Object>)callWrapper("storage_plugin_getFileInfo",
+ this.pluginType,
+ this.ssProps,
+ this.baseProps,
+ this.fileProps);
+ if (fileProps == null)
+ return true;
+
+ return false;
+ }
+
+ /* TODO: 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 Boolean storagePluginGetFileSystemInfo(String propUuid,
+ String mntUuid, String nfsHost, String nfsPath)
+ throws XmlRpcException {
+ /* clean the props */
+ this.setUuid(propUuid);
+ this.setSsUuid(propUuid);
+ this.setMntUuid(mntUuid);
+ this.setFsHost(nfsHost);
+ this.setFsSourcePath(nfsHost + ":" + nfsPath);
+ this.setFsType("FileSys");
+ Map<String, Object> props = (HashMap<String, Object>) callWrapper(
+ "storage_plugin_getFileSystemInfo", this.pluginType,
+ this.baseProps, this.ssProps);
+ this.ssProps = props;
+ if (props == null)
+ return false;
+
+ return true;
+ }
+
+ /* TODO: double check base and ss ordering!!!! */
+ public Boolean storagePluginGetFileSystemInfo() throws XmlRpcException {
+ HashMap<String, Object> props = (HashMap<String, Object>) callWrapper(
+ "storage_plugin_getFileSystemInfo", this.pluginType,
+ this.baseProps, this.ssProps);
+ this.ssProps = props;
+ // System.out.println(props);
+ if (props == null)
+ return false;
+
+ return true;
+ }
+
+ /*
+ * 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
+ */
+ /* should really make that stuff a class as this is weird now... */
+ public Boolean storagePluginListMounts() throws XmlRpcException {
+ Object x = callWrapper("storage_plugin_listMountPoints",
+ this.pluginType, this.baseProps);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+
+ public Boolean storagePluginListMounts(String uuid) throws XmlRpcException {
+ /* should allow for putting in the uuid */
+ Object x = callWrapper("storage_plugin_listMountPoints",
+ this.pluginType, this.baseProps);
+ if (x == null)
+ return true;
+
+ return false;
+ }
+}