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

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

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

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

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