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

[23/50] [abbrv] git commit: updated refs/heads/kvm-vnc-listen to 3890860

CLOUDSTACK-922: LXC Support in Cloudstack.

Signed-off-by: Edison Su <su...@gmail.com>


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

Branch: refs/heads/kvm-vnc-listen
Commit: aa79ccf985a172603a9ff15fbaa71dbfb3dad99d
Parents: 6eac422
Author: Phong Nguyen <pn...@gilt.com>
Authored: Mon Apr 1 15:40:21 2013 -0700
Committer: Edison Su <su...@gmail.com>
Committed: Mon Apr 1 15:41:42 2013 -0700

----------------------------------------------------------------------
 agent/conf/agent.properties                        |    9 +
 api/src/com/cloud/agent/api/Command.java           |    2 +
 api/src/com/cloud/agent/api/RebootCommand.java     |    1 +
 api/src/com/cloud/agent/api/StopCommand.java       |    7 +-
 api/src/com/cloud/hypervisor/Hypervisor.java       |    3 +
 api/src/com/cloud/storage/Storage.java             |    3 +-
 client/tomcatconf/applicationContext.xml.in        |    8 +
 client/tomcatconf/componentContext.xml.in          |    1 +
 .../hypervisor/kvm/resource/DirectVifDriver.java   |   65 +++
 .../kvm/resource/LibvirtComputingResource.java     |  156 ++++--
 .../hypervisor/kvm/resource/LibvirtConnection.java |   52 ++-
 .../kvm/resource/LibvirtDomainXMLParser.java       |   21 +-
 .../kvm/resource/LibvirtStorageVolumeDef.java      |    6 +-
 .../hypervisor/kvm/resource/LibvirtVMDef.java      |   71 +++-
 .../hypervisor/kvm/storage/KVMPhysicalDisk.java    |    2 +-
 .../kvm/storage/KVMStoragePoolManager.java         |    4 +
 .../kvm/storage/LibvirtStorageAdaptor.java         |   37 ++-
 .../hypervisor/kvm/resource/LibvirtVMDefTest.java  |   14 +
 scripts/storage/secondary/cloud-install-sys-tmplt  |    4 +
 .../consoleproxy/ConsoleProxyManagerImpl.java      |   12 +-
 server/src/com/cloud/hypervisor/LXCGuru.java       |   58 +++
 .../kvm/discoverer/KvmServerDiscoverer.java        |  371 +--------------
 .../kvm/discoverer/LibvirtServerDiscoverer.java    |  393 +++++++++++++++
 .../kvm/discoverer/LxcServerDiscoverer.java        |   33 ++
 .../com/cloud/network/SshKeysDistriMonitor.java    |    3 +-
 .../router/VirtualNetworkApplianceManagerImpl.java |    8 +-
 .../secondary/SecondaryStorageManagerImpl.java     |    6 +-
 .../cloud/template/HypervisorTemplateAdapter.java  |    3 +
 .../com/cloud/vm/VirtualMachineManagerImpl.java    |   27 +-
 setup/db/db/schema-410to420.sql                    |   12 +
 ui/scripts/system.js                               |   62 ++-
 ui/scripts/templates.js                            |    4 +
 ui/scripts/zoneWizard.js                           |   10 +
 33 files changed, 984 insertions(+), 484 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/agent/conf/agent.properties
----------------------------------------------------------------------
diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties
index f7eac67..e49afbf 100644
--- a/agent/conf/agent.properties
+++ b/agent/conf/agent.properties
@@ -80,3 +80,12 @@ domr.scripts.dir=scripts/network/domr/kvm
 # native = com.cloud.hypervisor.kvm.resource.BridgeVifDriver
 # openvswitch = com.cloud.hypervisor.kvm.resource.OvsBridgeDriver
 #libvirt.vif.driver=com.cloud.hypervisor.kvm.resource.BridgeVifDriver
+
+# set the hypervisor type, values are: kvm, lxc
+# hypervisor.type=kvm
+
+# settings to enable direct networking in libvirt, should not be used
+# on hosts that run system vms, values for mode are: private, bridge, vepa
+# libvirt.vif.driver=com.cloud.hypervisor.kvm.resource.DirectVifDriver
+# network.direct.source.mode=private
+# network.direct.device=eth0

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/api/src/com/cloud/agent/api/Command.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/Command.java b/api/src/com/cloud/agent/api/Command.java
index 9cd6749..aadbeaf 100755
--- a/api/src/com/cloud/agent/api/Command.java
+++ b/api/src/com/cloud/agent/api/Command.java
@@ -27,6 +27,8 @@ import com.cloud.agent.api.LogLevel.Log4jLevel;
  */
 public abstract class Command {
 
+    public static final String HYPERVISOR_TYPE = "hypervisorType";
+
     // allow command to carry over hypervisor or other environment related context info
     @LogLevel(Log4jLevel.Trace)
     protected Map<String, String> contextMap = new HashMap<String, String>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/api/src/com/cloud/agent/api/RebootCommand.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/RebootCommand.java b/api/src/com/cloud/agent/api/RebootCommand.java
index 299e61b..49712b6 100755
--- a/api/src/com/cloud/agent/api/RebootCommand.java
+++ b/api/src/com/cloud/agent/api/RebootCommand.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.agent.api;
 
+import com.cloud.hypervisor.Hypervisor;
 import com.cloud.vm.VirtualMachine;
 
 public class RebootCommand extends Command {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/api/src/com/cloud/agent/api/StopCommand.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/StopCommand.java b/api/src/com/cloud/agent/api/StopCommand.java
index 9ee7ce3..1c67f38 100755
--- a/api/src/com/cloud/agent/api/StopCommand.java
+++ b/api/src/com/cloud/agent/api/StopCommand.java
@@ -38,10 +38,9 @@ public class StopCommand extends RebootCommand {
         super(vm);
         this.vnet = vnet;
     }
-
-    public StopCommand(VirtualMachine vm, String vmName, String vnet) {
-        super(vmName);
-        this.vnet = vnet;
+    
+    public StopCommand(VirtualMachine vm) {
+        super(vm);
     }
 
     public StopCommand(String vmName) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/api/src/com/cloud/hypervisor/Hypervisor.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/hypervisor/Hypervisor.java b/api/src/com/cloud/hypervisor/Hypervisor.java
index 2e0012d..a4ee5b9 100644
--- a/api/src/com/cloud/hypervisor/Hypervisor.java
+++ b/api/src/com/cloud/hypervisor/Hypervisor.java
@@ -29,6 +29,7 @@ public class Hypervisor {
         BareMetal,
         Simulator,
         Ovm,
+        LXC,
 
         Any; /*If you don't care about the hypervisor type*/
 
@@ -54,6 +55,8 @@ public class Hypervisor {
                 return HypervisorType.Simulator;
             } else if (hypervisor.equalsIgnoreCase("Ovm")) {
                 return HypervisorType.Ovm;
+            } else if (hypervisor.equalsIgnoreCase("LXC")) {
+                return HypervisorType.LXC;
             } else if (hypervisor.equalsIgnoreCase("Any")) {
                 return HypervisorType.Any;
             } else {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/api/src/com/cloud/storage/Storage.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/com/cloud/storage/Storage.java
index fba12b6..c130fe2 100755
--- a/api/src/com/cloud/storage/Storage.java
+++ b/api/src/com/cloud/storage/Storage.java
@@ -26,7 +26,8 @@ public class Storage {
         VHD(true, true, true),
         ISO(false, false, false),
         OVA(true, true, true, "ova"),
-        BAREMETAL(false, false, false);
+        BAREMETAL(false, false, false),
+        TAR(false, false, false);
 
         private final boolean thinProvisioned;
         private final boolean supportSparse;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index ca6b402..636eac2 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -499,6 +499,10 @@
     <property name="name" value="KVM Agent"/>
   </bean>
 
+  <bean id="LxcServerDiscoverer" class="com.cloud.hypervisor.kvm.discoverer.LxcServerDiscoverer">
+    <property name="name" value="Lxc Discover"/>
+  </bean>
+
   <bean id="HypervServerDiscoverer" class="com.cloud.hypervisor.hyperv.HypervServerDiscoverer">
     <property name="name" value="SCVMMServer"/>
   </bean>
@@ -568,6 +572,10 @@
     <property name="name" value="KVMGuru"/>
   </bean>
 
+  <bean id="LXCGuru" class="com.cloud.hypervisor.LXCGuru">
+    <property name="name" value="LXCGuru"/>
+  </bean>
+
   <bean id="OvmGuru" class="com.cloud.ovm.hypervisor.OvmGuru">
     <property name="name" value="OvmGuru"/>
   </bean>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/client/tomcatconf/componentContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in
index 9d95e15..fea1d0f 100644
--- a/client/tomcatconf/componentContext.xml.in
+++ b/client/tomcatconf/componentContext.xml.in
@@ -106,6 +106,7 @@
           <ref bean="XcpServerDiscoverer"/>
           <ref bean="SecondaryStorageDiscoverer"/>
           <ref bean="KvmServerDiscoverer"/>
+          <ref bean="LxcServerDiscoverer"/>
           
   <!--
           <ref bean="BareMetalDiscoverer"/>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.java
new file mode 100644
index 0000000..1946d74
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/DirectVifDriver.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.
+ */
+
+package com.cloud.hypervisor.kvm.resource;
+
+import com.cloud.agent.api.to.NicTO;
+import com.cloud.exception.InternalErrorException;
+import com.cloud.network.Networks;
+import org.apache.log4j.Logger;
+import org.libvirt.LibvirtException;
+
+import javax.naming.ConfigurationException;
+import java.util.Map;
+
+public class DirectVifDriver extends VifDriverBase {
+
+    private static final Logger s_logger = Logger.getLogger(DirectVifDriver.class);
+
+    /**
+     * Experimental driver to configure direct networking in libvirt. This should only
+     * be used on an LXC cluster that does not run any system VMs.
+     *
+     * @param nic
+     * @param guestOsType
+     * @return
+     * @throws InternalErrorException
+     * @throws LibvirtException
+     */
+    public LibvirtVMDef.InterfaceDef plug(NicTO nic, String guestOsType) throws InternalErrorException,
+            LibvirtException {
+        LibvirtVMDef.InterfaceDef intf = new LibvirtVMDef.InterfaceDef();
+
+        if (nic.getType() == Networks.TrafficType.Guest) {
+            intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType),
+                    _libvirtComputingResource.getNetworkDirectSourceMode());
+
+        } else if (nic.getType() == Networks.TrafficType.Public) {
+            intf.defDirectNet(_libvirtComputingResource.getNetworkDirectDevice(), null, nic.getMac(), getGuestNicModel(guestOsType),
+                    _libvirtComputingResource.getNetworkDirectSourceMode());
+        }
+
+        return intf;
+    }
+
+    public void unplug(LibvirtVMDef.InterfaceDef iface) {
+        // not needed, libvirt will cleanup
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 7b70b62..d30e8f8 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -182,6 +182,7 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DevicesDef;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef.diskProtocol;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FeaturesDef;
+import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.FilesystemDef;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GraphicDef;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestDef;
 import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.GuestResourceDef;
@@ -323,9 +324,11 @@ ServerResource {
                     + "            <uuid>{1}</uuid>" + "        </domain>"
                     + "    </domainsnapshot>");
 
-    protected String _hypervisorType;
+    protected HypervisorType _hypervisorType;
     protected String _hypervisorURI;
     protected String _hypervisorPath;
+    protected String _networkDirectSourceMode;
+    protected String _networkDirectDevice;
     protected String _sysvmISOPath;
     protected String _privNwName;
     protected String _privBridgeName;
@@ -392,6 +395,7 @@ ServerResource {
 
     private Map<String, Object> getDeveloperProperties()
             throws ConfigurationException {
+
         final File file = PropertiesUtil.findConfigFile("developer.properties");
         if (file == null) {
             throw new ConfigurationException(
@@ -447,6 +451,14 @@ ServerResource {
         return "scripts/network/domr/kvm";
     }
 
+    protected String getNetworkDirectSourceMode() {
+        return _networkDirectSourceMode;
+    }
+
+    protected String getNetworkDirectDevice() {
+        return _networkDirectDevice;
+    }
+
     @Override
     public boolean configure(String name, Map<String, Object> params)
             throws ConfigurationException {
@@ -586,15 +598,19 @@ ServerResource {
 
         String instance = (String) params.get("instance");
 
-        _hypervisorType = (String) params.get("hypervisor.type");
-        if (_hypervisorType == null) {
-            _hypervisorType = "kvm";
+        _hypervisorType = HypervisorType.getType((String) params.get("hypervisor.type"));
+        if (_hypervisorType == HypervisorType.None) {
+            _hypervisorType = HypervisorType.KVM;
         }
 
         _hypervisorURI = (String) params.get("hypervisor.uri");
         if (_hypervisorURI == null) {
-            _hypervisorURI = "qemu:///system";
+            _hypervisorURI = LibvirtConnection.getHypervisorURI(_hypervisorType.toString());
         }
+
+        _networkDirectSourceMode = (String) params.get("network.direct.source.mode");
+        _networkDirectDevice = (String) params.get("network.direct.device");
+
         String startMac = (String) params.get("private.macaddr.start");
         if (startMac == null) {
             startMac = "00:16:3e:77:e2:a0";
@@ -680,12 +696,14 @@ ServerResource {
             throw new CloudRuntimeException(e.getMessage());
         }
 
-        /* Does node support HVM guest? If not, exit */
-        if (!IsHVMEnabled(conn)) {
-            throw new ConfigurationException(
-                    "NO HVM support on this machine, please make sure: "
-                            + "1. VT/SVM is supported by your CPU, or is enabled in BIOS. "
-                            + "2. kvm modules are loaded (kvm, kvm_amd|kvm_intel)");
+        if (HypervisorType.KVM == _hypervisorType) {
+            /* Does node support HVM guest? If not, exit */
+            if (!IsHVMEnabled(conn)) {
+                throw new ConfigurationException(
+                        "NO HVM support on this machine, please make sure: "
+                                + "1. VT/SVM is supported by your CPU, or is enabled in BIOS. "
+                                + "2. kvm modules are loaded (kvm, kvm_amd|kvm_intel)");
+            }
         }
 
         _hypervisorPath = getHypervisorPath(conn);
@@ -1514,7 +1532,7 @@ ServerResource {
         NicTO nic = cmd.getNic();
         String vmName = cmd.getVmName();
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
             Domain vm = getDomain(conn, vmName);
             List<InterfaceDef> pluggedNics = getInterfaces(conn, vmName);
             Integer nicnum = 0;
@@ -1543,7 +1561,7 @@ ServerResource {
         NicTO nic = cmd.getNic();
         String vmName = cmd.getInstanceName();
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByVmName(vmName);
             Domain vm = getDomain(conn, vmName);
             List<InterfaceDef> pluggedNics = getInterfaces(conn, vmName);
             for (InterfaceDef pluggedNic : pluggedNics) {
@@ -1581,7 +1599,7 @@ ServerResource {
         }
 
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByVmName(routerName);
             Domain vm = getDomain(conn, routerName);
             List<InterfaceDef> pluggedNics = getInterfaces(conn, routerName);
             InterfaceDef routerNic = null;
@@ -1622,7 +1640,7 @@ ServerResource {
         String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
 
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByVmName(routerName);
             Domain vm = getDomain(conn, routerName);
             String [][] rules = cmd.generateFwRules();
             String[] aclRules = rules[0];
@@ -1661,7 +1679,7 @@ ServerResource {
         IpAddressTO pubIP = cmd.getIpAddress();
 
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByVmName(routerName);
             Domain vm = getDomain(conn, routerName);
             Integer devNum = 0;
             String pubVlan = pubIP.getVlanId();
@@ -1707,7 +1725,7 @@ ServerResource {
         String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
 
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByVmName(routerName);
             IpAddressTO[] ips = cmd.getIpAddresses();
             Domain vm = getDomain(conn, routerName);
             Integer devNum = 0;
@@ -1755,7 +1773,7 @@ ServerResource {
         String[] results = new String[cmd.getIpAddresses().length];
         Connect conn;
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByVmName(routerName);
             List<InterfaceDef> nics = getInterfaces(conn, routerName);
             Map<String, Integer> vlanAllocatedToVM = new HashMap<String, Integer>();
             Integer nicPos = 0;
@@ -1812,7 +1830,7 @@ ServerResource {
         String snapshotPath = cmd.getSnapshotPath();
         String vmName = cmd.getVmName();
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
             DomainInfo.DomainState state = null;
             Domain vm = null;
             if (vmName != null) {
@@ -1901,7 +1919,7 @@ ServerResource {
         String vmName = cmd.getVmName();
         KVMStoragePool secondaryStoragePool = null;
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
 
             secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(
                     secondaryStoragePoolUrl);
@@ -2170,7 +2188,7 @@ ServerResource {
         KVMStoragePool secondaryStorage = null;
         KVMStoragePool primary = null;
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
             String templateFolder = cmd.getAccountId() + File.separator
                     + cmd.getTemplateId() + File.separator;
             String templateInstallFolder = "/template/tmpl/" + templateFolder;
@@ -2357,7 +2375,7 @@ ServerResource {
         String vif = null;
         String brname = null;
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
             List<InterfaceDef> nics = getInterfaces(conn, cmd.getVmName());
             vif = nics.get(0).getDevName();
             brname = nics.get(0).getBrName();
@@ -2391,7 +2409,7 @@ ServerResource {
 
     protected GetVncPortAnswer execute(GetVncPortCommand cmd) {
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getName());
             Integer vncPort = getVncPort(conn, cmd.getName());
             return new GetVncPortAnswer(cmd, _privateIp, 5900 + vncPort);
         } catch (LibvirtException e) {
@@ -2462,7 +2480,7 @@ ServerResource {
 
     private Answer execute(AttachIsoCommand cmd) {
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
             attachOrDetachISO(conn, cmd.getVmName(), cmd.getIsoPath(),
                     cmd.isAttach());
         } catch (LibvirtException e) {
@@ -2478,7 +2496,7 @@ ServerResource {
 
     private AttachVolumeAnswer execute(AttachVolumeCommand cmd) {
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
             KVMStoragePool primary = _storagePoolMgr.getStoragePool(
                     cmd.getPooltype(),
                     cmd.getPoolUuid());
@@ -2530,7 +2548,7 @@ ServerResource {
 
     private Answer execute(CheckVirtualMachineCommand cmd) {
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
             final State state = getVmState(conn, cmd.getVmName());
             Integer vncPort = null;
             if (state == State.Running) {
@@ -2599,7 +2617,7 @@ ServerResource {
         Domain destDomain = null;
         Connect conn = null;
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
             ifaces = getInterfaces(conn, vmName);
             dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName
                     .getBytes()));
@@ -2659,7 +2677,7 @@ ServerResource {
 
         NicTO[] nics = vm.getNics();
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(vm.getName());
             for (NicTO nic : nics) {
                 getVifDriver(nic.getType()).plug(nic, null);
             }
@@ -2854,7 +2872,7 @@ ServerResource {
         }
 
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
             final String result = rebootVM(conn, cmd.getVmName());
             if (result == null) {
                 Integer vncPort = null;
@@ -2892,8 +2910,8 @@ ServerResource {
         List<String> vmNames = cmd.getVmNames();
         try {
             HashMap<String, VmStatsEntry> vmStatsNameMap = new HashMap<String, VmStatsEntry>();
-            Connect conn = LibvirtConnection.getConnection();
             for (String vmName : vmNames) {
+                Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
                 VmStatsEntry statEntry = getVmStat(conn, vmName);
                 if (statEntry == null) {
                     continue;
@@ -2917,7 +2935,7 @@ ServerResource {
             _vms.put(vmName, State.Stopping);
         }
         try {
-            Connect conn = LibvirtConnection.getConnection();
+            Connect conn = LibvirtConnection.getConnectionByVmName(vmName);
 
             List<DiskDef> disks = getDisks(conn, vmName);
             List<InterfaceDef> ifaces = getInterfaces(conn, vmName);
@@ -3047,14 +3065,22 @@ ServerResource {
 
     protected LibvirtVMDef createVMFromSpec(VirtualMachineTO vmTO) {
         LibvirtVMDef vm = new LibvirtVMDef();
-        vm.setHvsType(_hypervisorType);
         vm.setDomainName(vmTO.getName());
         vm.setDomUUID(UUID.nameUUIDFromBytes(vmTO.getName().getBytes())
                 .toString());
         vm.setDomDescription(vmTO.getOs());
 
         GuestDef guest = new GuestDef();
-        guest.setGuestType(GuestDef.guestType.KVM);
+
+        if (HypervisorType.LXC == _hypervisorType &&
+            VirtualMachine.Type.User == vmTO.getType()) {
+            // LXC domain is only valid for user VMs. Use KVM for system VMs.
+            guest.setGuestType(GuestDef.guestType.LXC);
+            vm.setHvsType(HypervisorType.LXC.toString().toLowerCase());
+        } else {
+            guest.setGuestType(GuestDef.guestType.KVM);
+            vm.setHvsType(HypervisorType.KVM.toString().toLowerCase());
+        }
         guest.setGuestArch(vmTO.getArch());
         guest.setMachineType("pc");
         guest.setBootOrder(GuestDef.bootOrder.CDROM);
@@ -3115,6 +3141,7 @@ ServerResource {
 
         DevicesDef devices = new DevicesDef();
         devices.setEmulatorPath(_hypervisorPath);
+        devices.setGuestType(guest.getGuestType());
 
         SerialDef serial = new SerialDef("pty", null, (short) 0);
         devices.addDevice(serial);
@@ -3160,13 +3187,14 @@ ServerResource {
         State state = State.Stopped;
         Connect conn = null;
         try {
-            conn = LibvirtConnection.getConnection();
             synchronized (_vms) {
                 _vms.put(vmName, State.Starting);
             }
 
             vm = createVMFromSpec(vmSpec);
 
+            conn = LibvirtConnection.getConnectionByType(vm.getHvsType());
+
             createVbd(conn, vmSpec, vmName, vm);
 
             createVifs(vmSpec, vm);
@@ -3331,6 +3359,22 @@ ServerResource {
                 vm.getDevices().addDevice(iso);
             }
         }
+
+        // For LXC, find and add the root filesystem
+        if (HypervisorType.LXC.toString().toLowerCase().equals(vm.getHvsType())) {
+            for (VolumeTO volume : disks) {
+                if (volume.getType() == Volume.Type.ROOT) {
+                    KVMStoragePool pool = _storagePoolMgr.getStoragePool(
+                            volume.getPoolType(),
+                            volume.getPoolUuid());
+                    KVMPhysicalDisk physicalDisk = pool.getPhysicalDisk(volume.getPath());
+                    FilesystemDef rootFs = new FilesystemDef(physicalDisk.getPath(), "/");
+                    vm.getDevices().addDevice(rootFs);
+                    break;
+                }
+            }
+        }
+
     }
 
     private VolumeTO getVolume(VirtualMachineTO vmSpec, Volume.Type type) {
@@ -3565,7 +3609,7 @@ ServerResource {
 
         final StartupRoutingCommand cmd = new StartupRoutingCommand(
                 (Integer) info.get(0), (Long) info.get(1), (Long) info.get(2),
-                (Long) info.get(4), (String) info.get(3), HypervisorType.KVM,
+                (Long) info.get(4), (String) info.get(3), _hypervisorType,
                 RouterPrivateIpStrategy.HostLocal);
         cmd.setStateChanges(changes);
         fillNetworkInformation(cmd);
@@ -3721,7 +3765,7 @@ ServerResource {
         Domain dm = null;
         for (; i < 5; i++) {
             try {
-                Connect conn = LibvirtConnection.getConnection();
+                Connect conn = LibvirtConnection.getConnectionByVmName(vm);
                 dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vm
                         .getBytes()));
                 DomainInfo.DomainState vps = dm.getInfo().state;
@@ -3793,17 +3837,31 @@ ServerResource {
 
     private HashMap<String, State> getAllVms() {
         final HashMap<String, State> vmStates = new HashMap<String, State>();
-
-        String[] vms = null;
-        int[] ids = null;
         Connect conn = null;
+
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByType(HypervisorType.LXC.toString());
+            vmStates.putAll(getAllVms(conn));
+        } catch (LibvirtException e) {
+            s_logger.debug("Failed to get connection: " + e.getMessage());
+        }
+
+        try {
+            conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString());
+            vmStates.putAll(getAllVms(conn));
         } catch (LibvirtException e) {
             s_logger.debug("Failed to get connection: " + e.getMessage());
-            return vmStates;
         }
 
+        return vmStates;
+    }
+
+    private HashMap<String, State> getAllVms(Connect conn) {
+        final HashMap<String, State> vmStates = new HashMap<String, State>();
+
+        String[] vms = null;
+        int[] ids = null;
+
         try {
             ids = conn.listDomains();
         } catch (final LibvirtException e) {
@@ -4253,9 +4311,11 @@ ServerResource {
     }
 
     private void cleanupVMNetworks(Connect conn, List<InterfaceDef> nics) {
-        for (InterfaceDef nic : nics) {
-            if (nic.getHostNetType() == hostNicType.VNET) {
-                cleanupVnet(conn, getVnetIdFromBrName(nic.getBrName()));
+        if (nics != null) {
+            for (InterfaceDef nic : nics) {
+                if (nic.getHostNetType() == hostNicType.VNET) {
+                    cleanupVnet(conn, getVnetIdFromBrName(nic.getBrName()));
+                }
             }
         }
     }
@@ -4467,7 +4527,7 @@ ServerResource {
         }
 
         List<InterfaceDef> intfs = getInterfaces(conn, vmName);
-        if (intfs.size() < nic.getDeviceId()) {
+        if (intfs.size() == 0 || intfs.size() < nic.getDeviceId()) {
             return false;
         }
 
@@ -4565,7 +4625,7 @@ ServerResource {
         cmd.add("--vif", vif);
         cmd.add("--brname", brname);
         cmd.add("--nicsecips", secIps);
-        if (rules != null) {
+        if (newRules != null && !newRules.isEmpty()) {
             cmd.add("--rules", newRules);
         }
         String result = cmd.execute();
@@ -4673,7 +4733,7 @@ ServerResource {
         boolean success = false;
         Connect conn;
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
             success = default_network_rules_for_systemvm(conn, cmd.getVmName());
         } catch (LibvirtException e) {
             s_logger.trace("Ignoring libvirt error.", e);
@@ -4686,7 +4746,7 @@ ServerResource {
         boolean success = false;
         Connect conn;
         try {
-            conn = LibvirtConnection.getConnection();
+            conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
             success = network_rules_vmSecondaryIp(conn, cmd.getVmName(), cmd.getVmSecIp(), cmd.getAction());
         } catch (LibvirtException e) {
             // TODO Auto-generated catch block

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java
index 981d343..2ad1616 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java
@@ -16,33 +16,75 @@
 // under the License.
 package com.cloud.hypervisor.kvm.resource;
 
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import org.apache.log4j.Logger;
 import org.libvirt.Connect;
 import org.libvirt.LibvirtException;
 
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
 public class LibvirtConnection {
     private static final Logger s_logger = Logger
             .getLogger(LibvirtConnection.class);
+    static private Map<String, Connect> _connections = new HashMap<String, Connect>();
+
     static private Connect _connection;
     static private String _hypervisorURI;
 
     static public Connect getConnection() throws LibvirtException {
-        if (_connection == null) {
-            _connection = new Connect(_hypervisorURI, false);
+        return getConnection(_hypervisorURI);
+    }
+
+    static public Connect getConnection(String hypervisorURI) throws LibvirtException {
+        Connect conn = _connections.get(hypervisorURI);
+
+        if (conn == null) {
+            conn = new Connect(hypervisorURI, false);
+            _connections.put(hypervisorURI, conn);
         } else {
             try {
-                _connection.getVersion();
+                conn.getVersion();
             } catch (LibvirtException e) {
                 s_logger.debug("Connection with libvirtd is broken, due to "
                         + e.getMessage());
-                _connection = new Connect(_hypervisorURI, false);
+                conn = new Connect(hypervisorURI, false);
+                _connections.put(hypervisorURI, conn);
             }
         }
 
-        return _connection;
+        return conn;
+    }
+
+    static public Connect getConnectionByVmName(String vmName) throws LibvirtException {
+        HypervisorType[] hypervisors = new HypervisorType[] {HypervisorType.KVM, Hypervisor.HypervisorType.LXC};
+
+        for (HypervisorType hypervisor : hypervisors) {
+          Connect conn = LibvirtConnection.getConnectionByType(hypervisor.toString());
+          if (conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName.getBytes())) != null) {
+             return conn;
+          }
+        }
+
+        // return the default connection
+        return getConnection();
+    }
+
+    static public Connect getConnectionByType(String hypervisorType) throws LibvirtException {
+        return getConnection(getHypervisorURI(hypervisorType));
     }
 
     static void initialize(String hypervisorURI) {
         _hypervisorURI = hypervisorURI;
     }
+
+    static String getHypervisorURI(String hypervisorType) {
+        if ("LXC".equalsIgnoreCase(hypervisorType)) {
+            return "lxc:///";
+        } else {
+            return "qemu:///system";
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
index b622b6d..61a75ba 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
@@ -116,17 +116,20 @@ public class LibvirtDomainXMLParser {
 
             Element graphic = (Element) devices
                     .getElementsByTagName("graphics").item(0);
-            String port = graphic.getAttribute("port");
-            if (port != null) {
-                try {
-                    vncPort = Integer.parseInt(port);
-                    if (vncPort != -1) {
-                        vncPort = vncPort - 5900;
-                    } else {
+
+            if (graphic != null) {
+                String port = graphic.getAttribute("port");
+                if (port != null) {
+                    try {
+                        vncPort = Integer.parseInt(port);
+                        if (vncPort != -1) {
+                            vncPort = vncPort - 5900;
+                        } else {
+                            vncPort = null;
+                        }
+                    } catch (NumberFormatException nfe) {
                         vncPort = null;
                     }
-                } catch (NumberFormatException nfe) {
-                    vncPort = null;
                 }
             }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeDef.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeDef.java
index d5cd91a..7f9ceeb 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeDef.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtStorageVolumeDef.java
@@ -18,7 +18,7 @@ package com.cloud.hypervisor.kvm.resource;
 
 public class LibvirtStorageVolumeDef {
     public enum volFormat {
-        RAW("raw"), QCOW2("qcow2"), DIR("dir");
+        RAW("raw"), QCOW2("qcow2"), DIR("dir"), TAR("tar");
         private String _format;
 
         volFormat(String format) {
@@ -38,6 +38,10 @@ public class LibvirtStorageVolumeDef {
                 return RAW;
             } else if (format.equalsIgnoreCase("qcow2")) {
                 return QCOW2;
+            } else if (format.equalsIgnoreCase("dir")) {
+                return DIR;
+            } else if (format.equalsIgnoreCase("tar")) {
+                return TAR;
             }
             return null;
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
index 3d896a7..63133a8 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
@@ -31,7 +31,7 @@ public class LibvirtVMDef {
 
     public static class GuestDef {
         enum guestType {
-            KVM, XEN, EXE
+            KVM, XEN, EXE, LXC
         }
 
         enum bootOrder {
@@ -62,6 +62,10 @@ public class LibvirtVMDef {
             _type = type;
         }
 
+        public guestType getGuestType() {
+            return _type;
+        }
+
         public void setGuestArch(String arch) {
             _arch = arch;
         }
@@ -106,8 +110,16 @@ public class LibvirtVMDef {
                 }
                 guestDef.append("</os>\n");
                 return guestDef.toString();
-            } else
+            } else if (_type == guestType.LXC) {
+                StringBuilder guestDef = new StringBuilder();
+                guestDef.append("<os>\n");
+                guestDef.append("<type>exe</type>\n");
+                guestDef.append("<init>/sbin/init</init>\n");
+                guestDef.append("</os>\n");
+                return guestDef.toString();
+             } else {
                 return null;
+            }
         }
     }
 
@@ -279,6 +291,7 @@ public class LibvirtVMDef {
 
     public static class DevicesDef {
         private String _emulator;
+        private GuestDef.guestType _guestType;
         private final Map<String, List<?>> devices = new HashMap<String, List<?>>();
 
         public boolean addDevice(Object device) {
@@ -298,6 +311,10 @@ public class LibvirtVMDef {
             _emulator = emulator;
         }
 
+        public void setGuestType(GuestDef.guestType guestType) {
+            _guestType = guestType;
+        }
+
         @Override
         public String toString() {
             StringBuilder devicesBuilder = new StringBuilder();
@@ -309,6 +326,13 @@ public class LibvirtVMDef {
 
             for (List<?> devs : devices.values()) {
                 for (Object dev : devs) {
+                    if (_guestType == GuestDef.guestType.LXC) {
+                        if (dev instanceof GraphicDef ||
+                            dev instanceof InputDef ||
+                            dev instanceof DiskDef) {
+                            continue;
+                        }
+                    }
                     devicesBuilder.append(dev.toString());
                 }
             }
@@ -610,7 +634,7 @@ public class LibvirtVMDef {
 
     public static class InterfaceDef {
         enum guestNetType {
-            BRIDGE("bridge"), NETWORK("network"), USER("user"), ETHERNET(
+            BRIDGE("bridge"), DIRECT("direct"), NETWORK("network"), USER("user"), ETHERNET(
                     "ethernet"), INTERNAL("internal");
             String _type;
 
@@ -648,6 +672,7 @@ public class LibvirtVMDef {
                                          * internal
                                          */
         private hostNicType _hostNetType; /* Only used by agent java code */
+        private String _netSourceMode;
         private String _sourceName;
         private String _networkName;
         private String _macAddr;
@@ -667,6 +692,16 @@ public class LibvirtVMDef {
             _model = model;
         }
 
+        public void defDirectNet(String sourceName, String targetName,
+                                 String macAddr, nicModel model, String sourceMode) {
+            _netType = guestNetType.DIRECT;
+            _netSourceMode = sourceMode;
+            _sourceName = sourceName;
+            _networkName = targetName;
+            _macAddr = macAddr;
+            _model = model;
+        }
+
         public void defPrivateNet(String networkName, String targetName,
                 String macAddr, nicModel model) {
             _netType = guestNetType.NETWORK;
@@ -699,6 +734,10 @@ public class LibvirtVMDef {
             return _netType;
         }
 
+        public String getNetSourceMode() {
+            return _netSourceMode;
+        }
+
         public String getDevName() {
             return _networkName;
         }
@@ -739,6 +778,8 @@ public class LibvirtVMDef {
                 netBuilder.append("<source bridge='" + _sourceName + "'/>\n");
             } else if (_netType == guestNetType.NETWORK) {
                 netBuilder.append("<source network='" + _sourceName + "'/>\n");
+            } else if (_netType == guestNetType.DIRECT) {
+                netBuilder.append("<source dev='" + _sourceName + "' mode='" + _netSourceMode + "'/>\n");
             }
             if (_networkName != null) {
                 netBuilder.append("<target dev='" + _networkName + "'/>\n");
@@ -934,10 +975,34 @@ public class LibvirtVMDef {
         }
     }
 
+    public static class FilesystemDef {
+        private final String _sourcePath;
+        private final String _targetPath;
+
+        public FilesystemDef(String sourcePath, String targetPath) {
+            _sourcePath = sourcePath;
+            _targetPath = targetPath;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder fsBuilder = new StringBuilder();
+            fsBuilder.append("<filesystem type='mount'>\n");
+            fsBuilder.append("  <source dir='" + _sourcePath + "'/>\n");
+            fsBuilder.append("  <target dir='" + _targetPath + "'/>\n");
+            fsBuilder.append("</filesystem>\n");
+            return fsBuilder.toString();
+        }
+    }
+
     public void setHvsType(String hvs) {
         _hvsType = hvs;
     }
 
+    public String getHvsType() {
+        return _hvsType;
+    }
+
     public void setDomainName(String domainName) {
         _domName = domainName;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
index 08f51a4..f359713 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMPhysicalDisk.java
@@ -22,7 +22,7 @@ public class KVMPhysicalDisk {
     private KVMStoragePool pool;
 
     public static enum PhysicalDiskFormat {
-        RAW("raw"), QCOW2("qcow2");
+        RAW("raw"), QCOW2("qcow2"), TAR("tar"), DIR("dir");
         String format;
 
         private PhysicalDiskFormat(String format) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
index c2bfad9..f6db3f1 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java
@@ -139,6 +139,10 @@ public class KVMStoragePoolManager {
             return adaptor.createDiskFromTemplate(template, name,
                                        KVMPhysicalDisk.PhysicalDiskFormat.RAW, template.getSize(),
                                        destPool);
+        } else if (template.getFormat() == KVMPhysicalDisk.PhysicalDiskFormat.DIR) {
+            return adaptor.createDiskFromTemplate(template, name,
+                    KVMPhysicalDisk.PhysicalDiskFormat.DIR,
+                    template.getSize(), destPool);
         } else {
             return adaptor.createDiskFromTemplate(template, name,
                     KVMPhysicalDisk.PhysicalDiskFormat.QCOW2,

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
index 5e83ef6..cee2aae 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java
@@ -390,7 +390,14 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
             disk.setSize(vol.getInfo().allocation);
             disk.setVirtualSize(vol.getInfo().capacity);
             if (voldef.getFormat() == null) {
-                disk.setFormat(pool.getDefaultFormat());
+                File diskDir = new File(disk.getPath());
+                if (diskDir.exists() && diskDir.isDirectory()) {
+                    disk.setFormat(PhysicalDiskFormat.DIR);
+                } else if (volumeUuid.endsWith("tar") || volumeUuid.endsWith(("TAR"))) {
+                    disk.setFormat(PhysicalDiskFormat.TAR);
+                } else {
+                    disk.setFormat(pool.getDefaultFormat());
+                }
             } else if (pool.getType() == StoragePoolType.RBD) {
                 disk.setFormat(KVMPhysicalDisk.PhysicalDiskFormat.RAW);
             } else if (voldef.getFormat() == LibvirtStorageVolumeDef.volFormat.QCOW2) {
@@ -590,6 +597,10 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
             libvirtformat = LibvirtStorageVolumeDef.volFormat.QCOW2;
         } else if (format == PhysicalDiskFormat.RAW) {
             libvirtformat = LibvirtStorageVolumeDef.volFormat.RAW;
+        } else if (format == PhysicalDiskFormat.DIR) {
+            libvirtformat = LibvirtStorageVolumeDef.volFormat.DIR;
+        } else if (format == PhysicalDiskFormat.TAR) {
+            libvirtformat = LibvirtStorageVolumeDef.volFormat.TAR;
         }
 
         LibvirtStorageVolumeDef volDef = new LibvirtStorageVolumeDef(name,
@@ -640,7 +651,13 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
         if (destPool.getType() != StoragePoolType.RBD) {
             disk = destPool.createPhysicalDisk(newUuid, format, template.getVirtualSize());
 
-            if (format == PhysicalDiskFormat.QCOW2) {
+            if (template.getFormat() == PhysicalDiskFormat.TAR) {
+                Script.runSimpleBashScript("tar -x -f " + template.getPath() + " -C " + disk.getPath());
+            } else if (template.getFormat() == PhysicalDiskFormat.DIR) {
+                Script.runSimpleBashScript("mkdir -p " + disk.getPath());
+                Script.runSimpleBashScript("chmod 755 " + disk.getPath());
+                Script.runSimpleBashScript("cp -p -r " + template.getPath() + "/* " + disk.getPath());
+            } else if (format == PhysicalDiskFormat.QCOW2) {
                 Script.runSimpleBashScript("qemu-img create -f "
                         + template.getFormat() + " -b  " + template.getPath() + " "
                         + disk.getPath());
@@ -724,7 +741,11 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
 
         KVMPhysicalDisk newDisk;
         if (destPool.getType() != StoragePoolType.RBD) {
-            newDisk = destPool.createPhysicalDisk(name, disk.getVirtualSize());
+            if (disk.getFormat() == PhysicalDiskFormat.TAR) {
+                newDisk = destPool.createPhysicalDisk(name, PhysicalDiskFormat.DIR, disk.getVirtualSize());
+            } else {
+                newDisk = destPool.createPhysicalDisk(name, disk.getVirtualSize());
+            }
         } else {
             newDisk = new KVMPhysicalDisk(destPool.getSourceDir() + "/" + name, name, destPool);
             newDisk.setFormat(PhysicalDiskFormat.RAW);
@@ -739,7 +760,15 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
         PhysicalDiskFormat destFormat = newDisk.getFormat();
 
         if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() != StoragePoolType.RBD)) {
-            if (sourceFormat.equals(destFormat) && 
+            if (sourceFormat == PhysicalDiskFormat.TAR) {
+                Script.runSimpleBashScript("tar -x -f " + sourcePath + " -C " + destPath);
+
+            } else if (sourceFormat == PhysicalDiskFormat.DIR) {
+                Script.runSimpleBashScript("mkdir -p " + destPath);
+                Script.runSimpleBashScript("chmod 755 " + destPath);
+                Script.runSimpleBashScript("cp -p -r " + sourcePath + "/* " + destPath);
+
+            } else if (sourceFormat.equals(destFormat) &&
                 Script.runSimpleBashScript("qemu-img info " + sourcePath + "|grep backing") == null) {
                 Script.runSimpleBashScript("cp -f " + sourcePath + " " + destPath);
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
index b723875..2c0ff8d 100644
--- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
+++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtVMDefTest.java
@@ -35,4 +35,18 @@ public class LibvirtVMDefTest extends TestCase {
 
         assertEquals(expected, ifDef.toString());
     }
+
+    public void testInterfaceDirectNet() {
+        LibvirtVMDef.InterfaceDef ifDef = new LibvirtVMDef.InterfaceDef();
+        ifDef.defDirectNet("targetDeviceName", null, "00:11:22:aa:bb:dd", LibvirtVMDef.InterfaceDef.nicModel.VIRTIO, "private");
+
+        String expected = "<interface type='" + LibvirtVMDef.InterfaceDef.guestNetType.DIRECT + "'>\n" +
+                "<source dev='targetDeviceName' mode='private'/>\n" +
+                "<mac address='00:11:22:aa:bb:dd'/>\n" +
+                "<model type='virtio'/>\n" +
+                "</interface>\n";
+
+        assertEquals(expected, ifDef.toString());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/scripts/storage/secondary/cloud-install-sys-tmplt
----------------------------------------------------------------------
diff --git a/scripts/storage/secondary/cloud-install-sys-tmplt b/scripts/storage/secondary/cloud-install-sys-tmplt
index bcdc4c4..7237ffa 100755
--- a/scripts/storage/secondary/cloud-install-sys-tmplt
+++ b/scripts/storage/secondary/cloud-install-sys-tmplt
@@ -157,6 +157,10 @@ then
    then
       ext="ova"
       templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"VMware\" and removed is null"`)
+   elif [ "$hyper" == "lxc" ]
+   then
+      ext="qcow2"
+      templateId=(`mysql -h $dbHost --user=$dbUser --password=$dbPassword --skip-column-names -U cloud -e "select max(id) from cloud.vm_template where type = \"SYSTEM\" and hypervisor_type = \"LXC\" and removed is null"`)
    else
       usage
       failed 2

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
index 544a803..1edd869 100755
--- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
+++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java
@@ -1194,11 +1194,13 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
                 }
             } else {
                 if (s_logger.isDebugEnabled()) {
-                    if (secondaryStorageHost != null) {
-                        s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() +  " is not ready on secondary storage: " + secondaryStorageHost.getId());
-                    } else {
-                        s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() +  " is not ready on secondary storage.");
-                    }
+                    if (template == null) {
+                        s_logger.debug("Zone host is ready, but console proxy template is null");
+                    } else if (secondaryStorageHost != null) {
+			s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() +  " is not ready on secondary storage: " + secondaryStorageHost.getId());
+		    } else {
+			s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() +  " is not ready on secondary storage.");
+		    }
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/hypervisor/LXCGuru.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/LXCGuru.java b/server/src/com/cloud/hypervisor/LXCGuru.java
new file mode 100644
index 0000000..7a530b5
--- /dev/null
+++ b/server/src/com/cloud/hypervisor/LXCGuru.java
@@ -0,0 +1,58 @@
+// 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;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+
+import com.cloud.agent.api.to.VirtualMachineTO;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.storage.GuestOSVO;
+import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value=HypervisorGuru.class)
+public class LXCGuru extends HypervisorGuruBase implements HypervisorGuru {
+    @Inject GuestOSDao _guestOsDao;
+
+    @Override
+    public HypervisorType getHypervisorType() {
+        return HypervisorType.LXC;
+    }
+
+    protected LXCGuru() {
+        super();
+    }
+
+    @Override
+    public <T extends VirtualMachine> VirtualMachineTO implement(
+            VirtualMachineProfile<T> vm) {
+        VirtualMachineTO to = toVirtualMachineTO(vm);
+
+        // Determine the VM's OS description
+        GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
+        to.setOs(guestOS.getDisplayName());
+
+        return to;
+    }
+
+    @Override
+    public boolean trackVmHostChange() {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
index 75e00ad..da26370 100644
--- a/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
+++ b/server/src/com/cloud/hypervisor/kvm/discoverer/KvmServerDiscoverer.java
@@ -16,380 +16,21 @@
 // under the License.
 package com.cloud.hypervisor.kvm.discoverer;
 
-import java.net.InetAddress;
-import java.net.URI;
-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.ShutdownCommand;
-import com.cloud.agent.api.StartupCommand;
-import com.cloud.agent.api.StartupRoutingCommand;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.dao.ConfigurationDao;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.exception.AgentUnavailableException;
-import com.cloud.exception.DiscoveredWithErrorException;
-import com.cloud.exception.DiscoveryException;
-import com.cloud.exception.OperationTimedoutException;
-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.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.network.NetworkModel;
-import com.cloud.network.PhysicalNetworkSetupInfo;
 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.ssh.SSHCmdHelper;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
 
 @Local(value=Discoverer.class)
-public class KvmServerDiscoverer extends DiscovererBase implements Discoverer,
-Listener, ResourceStateAdapter {
+public class KvmServerDiscoverer extends LibvirtServerDiscoverer {
     private static final Logger s_logger = Logger.getLogger(KvmServerDiscoverer.class);
-    private String _hostIp;
-    private final int _waitTime = 5; /*wait for 5 minutes*/
-    private String _kvmPrivateNic;
-    private String _kvmPublicNic;
-    private String _kvmGuestNic;
-    @Inject HostDao _hostDao = null;
-    @Inject ClusterDao _clusterDao;
-    @Inject ResourceManager _resourceMgr;
-    @Inject AgentManager _agentMgr;
-    @Inject ConfigurationDao _configDao;
-    @Inject NetworkModel _networkMgr;
-
-    @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;
-    }
-
-    @Override
-    public void processConnect(HostVO 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 Map<? extends ServerResource, Map<String, String>> find(long dcId,
-            Long podId, Long clusterId, URI uri, String username,
-            String password, List<String> hostTags) throws DiscoveryException {
-
-        ClusterVO cluster = _clusterDao.findById(clusterId);
-        if(cluster == null || cluster.getHypervisorType() != HypervisorType.KVM) {
-            if(s_logger.isInfoEnabled())
-                s_logger.info("invalid cluster id or cluster is not for KVM hypervisors"); 
-            return null;
-        }
-
-        Map<KvmDummyResourceBase, Map<String, String>> resources = new HashMap<KvmDummyResourceBase, Map<String, String>>();
-        Map<String, String> details = new HashMap<String, String>();
-        if (!uri.getScheme().equals("http")) {
-            String msg = "urlString is not http so we're not taking care of the discovery for this: " + uri;
-            s_logger.debug(msg);
-            return null;
-        }
-        com.trilead.ssh2.Connection sshConnection = null;
-        String agentIp = null;
-        try {
-
-            String hostname = uri.getHost();
-            InetAddress ia = InetAddress.getByName(hostname);
-            agentIp = ia.getHostAddress();
-            String guid = UUID.nameUUIDFromBytes(agentIp.getBytes()).toString();
-            String guidWithTail = guid + "-LibvirtComputingResource";/*tail added by agent.java*/
-            if (_resourceMgr.findHostByGuid(guidWithTail) != null) {
-                s_logger.debug("Skipping " + agentIp + " because " + guidWithTail + " is already in the database.");
-                return null;
-            }       
-
-            sshConnection = new com.trilead.ssh2.Connection(agentIp, 22);
-
-            sshConnection.connect(null, 60000, 60000);
-            if (!sshConnection.authenticateWithPassword(username, password)) {
-                s_logger.debug("Failed to authenticate");
-                throw new DiscoveredWithErrorException("Authentication error");
-            }
-
-            if (!SSHCmdHelper.sshExecuteCmd(sshConnection, "lsmod|grep kvm", 3)) {
-                s_logger.debug("It's not a KVM enabled machine");
-                return null;
-            }
-
-            List <PhysicalNetworkSetupInfo> netInfos = _networkMgr.getPhysicalNetworkInfo(dcId, HypervisorType.KVM);
-            String kvmPrivateNic = null;
-            String kvmPublicNic = null;
-            String kvmGuestNic = null;
-
-            for (PhysicalNetworkSetupInfo info : netInfos) {
-                if (info.getPrivateNetworkName() != null) {
-                    kvmPrivateNic = info.getPrivateNetworkName();
-                }
-                if (info.getPublicNetworkName() != null) {
-                    kvmPublicNic = info.getPublicNetworkName();
-                }
-                if (info.getGuestNetworkName() != null) {
-                    kvmGuestNic = info.getGuestNetworkName();
-                }
-            }
-
-            if (kvmPrivateNic == null && kvmPublicNic == null && kvmGuestNic == null) {
-                kvmPrivateNic = _kvmPrivateNic;
-                kvmPublicNic = _kvmPublicNic;
-                kvmGuestNic = _kvmGuestNic;
-            } 
-
-            if (kvmPublicNic == null) {
-                kvmPublicNic = (kvmGuestNic != null) ? kvmGuestNic : kvmPrivateNic;
-            }
-
-            if (kvmPrivateNic == null) {
-                kvmPrivateNic = (kvmPublicNic != null) ? kvmPublicNic : kvmGuestNic;
-            }
-
-            if (kvmGuestNic == null) {
-                kvmGuestNic = (kvmPublicNic != null) ? kvmPublicNic : kvmPrivateNic;
-            }
-
-            String parameters = " -m " + _hostIp + " -z " + dcId + " -p " + podId + " -c " + clusterId + " -g " + guid + " -a";
-
-            parameters += " --pubNic=" + kvmPublicNic;
-            parameters += " --prvNic=" + kvmPrivateNic;
-            parameters += " --guestNic=" + kvmGuestNic;
 
-            SSHCmdHelper.sshExecuteCmd(sshConnection, "cloudstack-setup-agent " + parameters, 3);
-
-            KvmDummyResourceBase kvmResource = new KvmDummyResourceBase();
-            Map<String, Object> params = new HashMap<String, Object>();
-
-            params.put("zone", Long.toString(dcId));
-            params.put("pod", Long.toString(podId));
-            params.put("cluster",  Long.toString(clusterId));
-            params.put("guid", guid); 
-            params.put("agentIp", agentIp);
-            kvmResource.configure("kvm agent", params);
-            resources.put(kvmResource, details);
-
-            HostVO connectedHost = waitForHostConnect(dcId, podId, clusterId, guidWithTail);
-            if (connectedHost == null)
-                return null;
-
-            details.put("guid", guidWithTail);
-
-            // place a place holder guid derived from cluster ID
-            if (cluster.getGuid() == null) {
-                cluster.setGuid(UUID.nameUUIDFromBytes(String.valueOf(clusterId).getBytes()).toString());
-                _clusterDao.update(clusterId, cluster);
-            }
-
-            //save user name and password
-            _hostDao.loadDetails(connectedHost);
-            Map<String, String> hostDetails = connectedHost.getDetails();
-            hostDetails.put("password", password);
-            hostDetails.put("username", username);
-            _hostDao.saveDetails(connectedHost);
-            return resources;
-        } catch (DiscoveredWithErrorException e){ 
-            throw e;
-        }catch (Exception e) {
-            String msg = " can't setup agent, due to " + e.toString() + " - " + e.getMessage();
-            s_logger.warn(msg);
-        } finally {
-            if (sshConnection != null)
-                sshConnection.close();
-        }
-
-        return null;
-    }
-
-    private HostVO waitForHostConnect(long dcId, long podId, long clusterId, String guid) {
-        for (int i = 0; i < _waitTime *2; i++) {
-            List<HostVO> hosts = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.Routing, clusterId, podId, dcId);
-            for (HostVO host : hosts) {
-                if (host.getGuid().equalsIgnoreCase(guid)) {
-                    return host;
-                }
-            }
-            try {
-                Thread.sleep(30000);
-            } catch (InterruptedException e) {
-                s_logger.debug("Failed to sleep: " + e.toString());
-            }
-        }
-        s_logger.debug("Timeout, to wait for the host connecting to mgt svr, assuming it is failed");
-        List<HostVO> hosts = _resourceMgr.findHostByGuid(dcId, guid);
-        if (hosts.size() == 1) {
-            return hosts.get(0);
-        } else {
-            return null;
-        }
-    }
-
-    @Override
-    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
-//        _setupAgentPath = Script.findScript(getPatchPath(), "setup_agent.sh");
-        _kvmPrivateNic = _configDao.getValue(Config.KvmPrivateNetwork.key());
-        if (_kvmPrivateNic == null) {
-            _kvmPrivateNic = "cloudbr0";
-        }
-
-        _kvmPublicNic = _configDao.getValue(Config.KvmPublicNetwork.key());
-        if (_kvmPublicNic == null) {
-            _kvmPublicNic = _kvmPrivateNic;
-        }
-
-        _kvmGuestNic = _configDao.getValue(Config.KvmGuestNetwork.key());
-        if (_kvmGuestNic == null) {
-            _kvmGuestNic = _kvmPrivateNic;
-        }
-
-        _hostIp = _configDao.getValue("host");
-        if (_hostIp == null) {
-            throw new ConfigurationException("Can't get host IP");
-        }
-        _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
-        return true;
-    }
-
-    protected String getPatchPath() {
-        return "scripts/vm/hypervisor/kvm/";
-    }
-
-    @Override
-    public void postDiscovery(List<HostVO> hosts, long msId)
-            throws DiscoveryException {
-        // TODO Auto-generated method stub
-    }
-
-    @Override
     public Hypervisor.HypervisorType getHypervisorType() {
         return Hypervisor.HypervisorType.KVM;
     }
 
-    @Override
-    public boolean matchHypervisor(String hypervisor) {
-        // for backwards compatibility, if not supplied, always let to try it
-        if(hypervisor == null)
-            return true;
-
-        return Hypervisor.HypervisorType.KVM.toString().equalsIgnoreCase(hypervisor);
-    }
-
-    @Override
-    public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) {
-        StartupCommand firstCmd = cmd[0];
-        if (!(firstCmd instanceof StartupRoutingCommand)) {
-            return null;
-        }
-
-        StartupRoutingCommand ssCmd = ((StartupRoutingCommand) firstCmd);
-        if (ssCmd.getHypervisorType() != HypervisorType.KVM) {
-            return null;
-        }
-
-        /* KVM requires host are the same in cluster */
-        ClusterVO clusterVO = _clusterDao.findById(host.getClusterId());
-        List<HostVO> hostsInCluster = _resourceMgr.listAllHostsInCluster(clusterVO.getId());
-        if (!hostsInCluster.isEmpty()) {
-            HostVO oneHost = hostsInCluster.get(0);
-            _hostDao.loadDetails(oneHost);
-            String hostOsInCluster = oneHost.getDetail("Host.OS");
-            String hostOs = ssCmd.getHostDetails().get("Host.OS");
-            if (!hostOsInCluster.equalsIgnoreCase(hostOs)) {
-                throw new IllegalArgumentException("Can't add host: " + firstCmd.getPrivateIpAddress() + " with hostOS: " + hostOs + " into a cluster,"
-                        + "in which there are " + hostOsInCluster + " hosts added");
-            }
-        }
-
-        _hostDao.loadDetails(host);
-
-        return _resourceMgr.fillRoutingHostVO(host, ssCmd, HypervisorType.KVM, host.getDetails(), null);
-    }
-
-    @Override
-    public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details,
-            List<String> hostTags) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException {
-        if (host.getType() != Host.Type.Routing || host.getHypervisorType() != HypervisorType.KVM) {
-            return null;
-        }
-
-        _resourceMgr.deleteRoutingHost(host, isForced, isForceDeleteStorage);
-        try {
-            ShutdownCommand cmd = new ShutdownCommand(ShutdownCommand.DeleteHost, null);
-            _agentMgr.send(host.getId(), cmd);
-        } catch (AgentUnavailableException e) {
-            s_logger.warn("Sending ShutdownCommand failed: ", e);
-        } catch (OperationTimedoutException e) {
-            s_logger.warn("Sending ShutdownCommand failed: ", e);
-        }
-
-        return new DeleteHostAnswer(true);
-    }
-
-    @Override
-    public boolean stop() {
-        _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName());
-        return super.stop();
+    protected String getPatchPath() {
+        return "scripts/vm/hypervisor/kvm/";
     }
 }