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:30 UTC
[22/50] [abbrv] CLOUDSTACK-922: LXC Support in Cloudstack.
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
new file mode 100644
index 0000000..75b007c
--- /dev/null
+++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java
@@ -0,0 +1,393 @@
+// 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.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;
+
+public abstract class LibvirtServerDiscoverer extends DiscovererBase implements Discoverer,
+Listener, ResourceStateAdapter {
+ private static final Logger s_logger = Logger.getLogger(LibvirtServerDiscoverer.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;
+
+ public abstract Hypervisor.HypervisorType getHypervisorType();
+
+ @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() != getHypervisorType()) {
+ if(s_logger.isInfoEnabled())
+ s_logger.info("invalid cluster id or cluster is not for " + getHypervisorType() + " 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, getHypervisorType());
+ 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 boolean matchHypervisor(String hypervisor) {
+ // for backwards compatibility, if not supplied, always let to try it
+ if(hypervisor == null)
+ return true;
+
+ return getHypervisorType().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() != getHypervisorType()) {
+ 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, getHypervisorType(), 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 &&
+ host.getHypervisorType() != HypervisorType.LXC)) {
+ 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();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/hypervisor/kvm/discoverer/LxcServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LxcServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LxcServerDiscoverer.java
new file mode 100644
index 0000000..0e6a82b
--- /dev/null
+++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LxcServerDiscoverer.java
@@ -0,0 +1,33 @@
+// 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.discoverer;
+
+import com.cloud.hypervisor.Hypervisor;
+import com.cloud.resource.Discoverer;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
+
+@Local(value=Discoverer.class)
+public class LxcServerDiscoverer extends LibvirtServerDiscoverer {
+ private static final Logger s_logger = Logger.getLogger(LxcServerDiscoverer.class);
+
+ public Hypervisor.HypervisorType getHypervisorType() {
+ return Hypervisor.HypervisorType.LXC;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/network/SshKeysDistriMonitor.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/SshKeysDistriMonitor.java b/server/src/com/cloud/network/SshKeysDistriMonitor.java
index fc7c882..82f72de 100755
--- a/server/src/com/cloud/network/SshKeysDistriMonitor.java
+++ b/server/src/com/cloud/network/SshKeysDistriMonitor.java
@@ -72,7 +72,8 @@ public class SshKeysDistriMonitor implements Listener {
public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
if (cmd instanceof StartupRoutingCommand) {
if (((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.KVM ||
- ((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.XenServer) {
+ ((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.XenServer ||
+ ((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.LXC) {
/*TODO: Get the private/public keys here*/
String pubKey = _configDao.getValue("ssh.publickey");
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 67c94fc..afdbbca 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -1527,9 +1527,11 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
DomainRouterVO router = deployRouter(owner, destination, plan, params, isRedundant, vrProvider, offeringId,
null, networks, false, null);
- _routerDao.addRouterToGuestNetwork(router, guestNetwork);
- routers.add(router);
- }
+ if (router != null) {
+ _routerDao.addRouterToGuestNetwork(router, guestNetwork);
+ routers.add(router);
+ }
+ }
}
} finally {
if (lock != null) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
index 46ac7af..9a4d6b0 100755
--- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
+++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java
@@ -747,7 +747,11 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
}
} else {
if (s_logger.isDebugEnabled()) {
- s_logger.debug("Zone host is ready, but secondary storage vm template: " + template.getId() + " is not ready on secondary storage: " + secHost.getId());
+ if (template == null) {
+ s_logger.debug("Zone host is ready, but secondary storage vm template does not exist");
+ } else {
+ s_logger.debug("Zone host is ready, but secondary storage vm template: " + template.getId() + " is not ready on secondary storage: " + secHost.getId());
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/template/HypervisorTemplateAdapter.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
index a0444e5..491900b 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -141,6 +141,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
&&(!url.toLowerCase().endsWith("qcow2.bz2"))&&(!url.toLowerCase().endsWith("qcow2.gz"))
&&(!url.toLowerCase().endsWith("ova"))&&(!url.toLowerCase().endsWith("ova.zip"))
&&(!url.toLowerCase().endsWith("ova.bz2"))&&(!url.toLowerCase().endsWith("ova.gz"))
+ &&(!url.toLowerCase().endsWith("tar"))&&(!url.toLowerCase().endsWith("tar.zip"))
+ &&(!url.toLowerCase().endsWith("tar.bz2"))&&(!url.toLowerCase().endsWith("tar.gz"))
&&(!url.toLowerCase().endsWith("img"))&&(!url.toLowerCase().endsWith("raw"))){
throw new InvalidParameterValueException("Please specify a valid "+ cmd.getFormat().toLowerCase());
}
@@ -148,6 +150,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
if ((cmd.getFormat().equalsIgnoreCase("vhd") && (!url.toLowerCase().endsWith("vhd") && !url.toLowerCase().endsWith("vhd.zip") && !url.toLowerCase().endsWith("vhd.bz2") && !url.toLowerCase().endsWith("vhd.gz") ))
|| (cmd.getFormat().equalsIgnoreCase("qcow2") && (!url.toLowerCase().endsWith("qcow2") && !url.toLowerCase().endsWith("qcow2.zip") && !url.toLowerCase().endsWith("qcow2.bz2") && !url.toLowerCase().endsWith("qcow2.gz") ))
|| (cmd.getFormat().equalsIgnoreCase("ova") && (!url.toLowerCase().endsWith("ova") && !url.toLowerCase().endsWith("ova.zip") && !url.toLowerCase().endsWith("ova.bz2") && !url.toLowerCase().endsWith("ova.gz")))
+ || (cmd.getFormat().equalsIgnoreCase("tar") && (!url.toLowerCase().endsWith("tar") && !url.toLowerCase().endsWith("tar.zip") && !url.toLowerCase().endsWith("tar.bz2") && !url.toLowerCase().endsWith("tar.gz")))
|| (cmd.getFormat().equalsIgnoreCase("raw") && (!url.toLowerCase().endsWith("img") && !url.toLowerCase().endsWith("raw")))) {
throw new InvalidParameterValueException("Please specify a valid URL. URL:" + url + " is an invalid for the format " + cmd.getFormat().toLowerCase());
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
index 23746ae..af22716 100755
--- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
+++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java
@@ -794,7 +794,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.info("The guru did not like the answers so stopping " + vm);
}
- StopCommand cmd = new StopCommand(vm.getInstanceName());
+ StopCommand cmd = new StopCommand(vm);
StopAnswer answer = (StopAnswer) _agentMgr.easySend(destHostId, cmd);
if (answer == null || !answer.getResult()) {
s_logger.warn("Unable to stop " + vm + " due to " + (answer != null ? answer.getDetails() : "no answers"));
@@ -876,7 +876,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
protected <T extends VMInstanceVO> boolean sendStop(VirtualMachineGuru<T> guru, VirtualMachineProfile<T> profile, boolean force) {
VMInstanceVO vm = profile.getVirtualMachine();
- StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null);
+ StopCommand stop = new StopCommand(vm);
try {
Answer answer = _agentMgr.send(vm.getHostId(), stop);
if (!answer.getResult()) {
@@ -1061,8 +1061,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
vmGuru.prepareStop(profile);
-
- StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null);
+
+ StopCommand stop = new StopCommand(vm);
boolean stopped = false;
StopAnswer answer = null;
try {
@@ -1380,7 +1380,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
if (!checkVmOnHost(vm, dstHostId)) {
s_logger.error("Unable to complete migration for " + vm);
try {
- _agentMgr.send(srcHostId, new Commands(cleanup(vm.getInstanceName())), null);
+ _agentMgr.send(srcHostId, new Commands(cleanup(vm)), null);
} catch (AgentUnavailableException e) {
s_logger.error("AgentUnavailableException while cleanup on source host: " + srcHostId);
}
@@ -1399,7 +1399,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
_alertMgr.sendAlert(alertType, fromHost.getDataCenterId(), fromHost.getPodId(), "Unable to migrate vm " + vm.getInstanceName() + " from host " + fromHost.getName() + " in zone "
+ dest.getDataCenter().getName() + " and pod " + dest.getPod().getName(), "Migrate Command failed. Please check logs.");
try {
- _agentMgr.send(dstHostId, new Commands(cleanup(vm.getInstanceName())), null);
+ _agentMgr.send(dstHostId, new Commands(cleanup(vm)), null);
} catch (AgentUnavailableException ae) {
s_logger.info("Looks like the destination Host is unavailable for cleanup");
}
@@ -1620,6 +1620,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
return guru.findById(vmId);
}
+ public Command cleanup(VirtualMachine vm) {
+ return new StopCommand(vm);
+ }
+
public Command cleanup(String vmName) {
return new StopCommand(vmName);
}
@@ -1989,7 +1993,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
*/
protected Command compareState(long hostId, VMInstanceVO vm, final AgentVmInfo info, final boolean fullSync, boolean trackExternalChange) {
State agentState = info.state;
- final String agentName = info.name;
final State serverState = vm.getState();
final String serverName = vm.getInstanceName();
@@ -2092,7 +2095,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
}
s_logger.debug("State matches but the agent said stopped so let's send a cleanup command anyways.");
- return cleanup(agentName);
+ return cleanup(vm);
}
if (agentState == State.Shutdowned) {
@@ -2110,8 +2113,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
return null;
}
} else {
- s_logger.debug("Sending cleanup to a shutdowned vm: " + agentName);
- command = cleanup(agentName);
+ s_logger.debug("Sending cleanup to a shutdowned vm: " + vm.getInstanceName());
+ command = cleanup(vm);
}
} else if (agentState == State.Stopped) {
// This state means the VM on the agent was detected previously
@@ -2129,7 +2132,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.debug("Ignoring VM in starting mode: " + vm.getInstanceName());
_haMgr.scheduleRestart(vm, false);
}
- command = cleanup(agentName);
+ command = cleanup(vm);
} else if (agentState == State.Running) {
if (serverState == State.Starting) {
if (fullSync) {
@@ -2155,7 +2158,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.debug("server VM state " + serverState + " does not meet expectation of a running VM report from agent");
// just be careful not to stop VM for things we don't handle
- // command = cleanup(agentName);
+ // command = cleanup(vm);
}
}
return command;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index 53f3c44..3dee7ae 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -393,3 +393,15 @@ CREATE VIEW `cloud`.`account_view` AS
ALTER TABLE remote_access_vpn ADD COLUMN `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id';
ALTER TABLE remote_access_vpn ADD COLUMN `uuid` varchar(40) UNIQUE;
+
+-- START: support for LXC
+
+INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled) VALUES ('LXC', 'default', 50, 1);
+ALTER TABLE `cloud`.`physical_network_traffic_types` ADD COLUMN `lxc_network_label` varchar(255) DEFAULT 'cloudbr0' COMMENT 'The network name label of the physical device dedicated to this traffic on a LXC host';
+
+UPDATE configuration SET value='KVM,XenServer,VMware,BareMetal,Ovm,LXC' WHERE name='hypervisor.list';
+
+INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, hvm, bits, account_id, url, checksum, enable_password, display_text, format, guest_os_id, featured, cross_zones, hypervisor_type)
+ VALUES (10, 'routing-10', 'SystemVM Template (LXC)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2', '2755de1f9ef2ce4d6f2bee2efbb4da92', 0, 'SystemVM Template (LXC)', 'QCOW2', 15, 0, 1, 'LXC');
+
+-- END: support for LXC
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/ui/scripts/system.js
----------------------------------------------------------------------
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
index 9d6c476..98570d2 100644
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -114,28 +114,34 @@
}
});
- if(trafficType.xennetworklabel == null || trafficType.xennetworklabel == 0)
- trafficType.xennetworklabel = dictionary['label.network.label.display.for.blank.value'];
- if(trafficType.kvmnetworklabel == null || trafficType.kvmnetworklabel == 0)
- trafficType.kvmnetworklabel = dictionary['label.network.label.display.for.blank.value'];
- if(trafficType.vmwarenetworklabel == null || trafficType.vmwarenetworklabel == 0)
- trafficType.vmwarenetworklabel = dictionary['label.network.label.display.for.blank.value'];
- if(trafficType.ovmnetworklabel == null || trafficType.ovmnetworklabel == 0)
- trafficType.ovmnetworklabel = dictionary['label.network.label.display.for.blank.value'];
+ if(trafficType.xennetworklabel == null || trafficType.xennetworklabel == 0)
+ trafficType.xennetworklabel = dictionary['label.network.label.display.for.blank.value'];
+ if(trafficType.kvmnetworklabel == null || trafficType.kvmnetworklabel == 0)
+ trafficType.kvmnetworklabel = dictionary['label.network.label.display.for.blank.value'];
+ if(trafficType.vmwarenetworklabel == null || trafficType.vmwarenetworklabel == 0)
+ trafficType.vmwarenetworklabel = dictionary['label.network.label.display.for.blank.value'];
+ if(trafficType.ovmnetworklabel == null || trafficType.ovmnetworklabel == 0)
+ trafficType.ovmnetworklabel = dictionary['label.network.label.display.for.blank.value'];
+ if(trafficType.lxcnetworklabel == null || trafficType.lxcnetworklabel == 0)
+ trafficType.lxcnetworklabel = dictionary['label.network.label.display.for.blank.value'];
+
return trafficType;
};
var updateTrafficLabels = function(trafficType, labels, complete) {
var array1 = [];
- if(labels.xennetworklabel != dictionary['label.network.label.display.for.blank.value'])
- array1.push("&xennetworklabel=" + labels.xennetworklabel);
- if(labels.kvmnetworklabel != dictionary['label.network.label.display.for.blank.value'])
- array1.push("&kvmnetworklabel=" + labels.kvmnetworklabel);
- if(labels.vmwarenetworklabel != dictionary['label.network.label.display.for.blank.value'])
- array1.push("&vmwarenetworklabel=" + labels.vmwarenetworklabel);
- if(labels.ovmnetworklabel != dictionary['label.network.label.display.for.blank.value'])
- array1.push("&ovmnetworklabel=" + labels.ovmnetworklabel);
- $.ajax({
+ if(labels.xennetworklabel != dictionary['label.network.label.display.for.blank.value'])
+ array1.push("&xennetworklabel=" + labels.xennetworklabel);
+ if(labels.kvmnetworklabel != dictionary['label.network.label.display.for.blank.value'])
+ array1.push("&kvmnetworklabel=" + labels.kvmnetworklabel);
+ if(labels.vmwarenetworklabel != dictionary['label.network.label.display.for.blank.value'])
+ array1.push("&vmwarenetworklabel=" + labels.vmwarenetworklabel);
+ if(labels.ovmnetworklabel != dictionary['label.network.label.display.for.blank.value'])
+ array1.push("&ovmnetworklabel=" + labels.ovmnetworklabel);
+ if(labels.lxcnetworklabel != dictionary['label.network.label.display.for.blank.value'])
+ array1.push("&lxcnetworklabel=" + labels.lxcnetworklabel);
+
+ $.ajax({
url: createURL('updateTrafficType' + array1.join("")),
data: {
id: trafficType.id
@@ -463,7 +469,8 @@
xennetworklabel: { label: 'label.xen.traffic.label', isEditable: true },
kvmnetworklabel: { label: 'label.kvm.traffic.label', isEditable: true },
vmwarenetworklabel: { label: 'label.vmware.traffic.label', isEditable: true },
- ovmnetworklabel: { label: 'OVM traffic label',isEditable: true }
+ ovmnetworklabel: { label: 'OVM traffic label',isEditable: true },
+ lxcnetworklabel: { label: 'label.lxc.traffic.label',isEditable: true }
}
],
@@ -483,6 +490,7 @@
selectedPublicNetworkObj.kvmnetworklabel = trafficType.kvmnetworklabel;
selectedPublicNetworkObj.vmwarenetworklabel = trafficType.vmwarenetworklabel;
selectedPublicNetworkObj.ovmnetworklabel = trafficType.ovmnetworklabel;
+ selectedPublicNetworkObj.lxcnetworklabel = trafficType.lxcnetworklabel;
args.response.success({data: selectedPublicNetworkObj});
}
@@ -636,7 +644,8 @@
xennetworklabel: { label: 'label.xen.traffic.label', isEditable: true },
kvmnetworklabel: { label: 'label.kvm.traffic.label', isEditable: true },
vmwarenetworklabel: { label: 'label.vmware.traffic.label', isEditable: true },
- ovmnetworklabel: { label: 'OVM traffic label', isEditable: true }
+ ovmnetworklabel: { label: 'OVM traffic label', isEditable: true },
+ lxcnetworklabel: { label: 'label.lxc.traffic.label', isEditable: true }
}
],
@@ -795,7 +804,8 @@
xennetworklabel: { label: 'label.xen.traffic.label', isEditable: true },
kvmnetworklabel: { label: 'label.kvm.traffic.label', isEditable: true },
vmwarenetworklabel: { label: 'label.vmware.traffic.label', isEditable: true },
- ovmnetworklabel: { label: 'OVM traffic label', isEditable: true }
+ ovmnetworklabel: { label: 'OVM traffic label', isEditable: true },
+ lxcnetworklabel: { label: 'label.lxc.traffic.label', isEditable: true }
}
],
dataProvider: function(args) {
@@ -811,6 +821,7 @@
selectedManagementNetworkObj.kvmnetworklabel = trafficType.kvmnetworklabel;
selectedManagementNetworkObj.vmwarenetworklabel = trafficType.vmwarenetworklabel;
selectedManagementNetworkObj.ovmnetworklabel = trafficType.ovmnetworklabel;
+ selectedManagementNetworkObj.lxcnetworklabel = trafficType.lxcnetworklabel;
args.response.success({ data: selectedManagementNetworkObj });
}
});
@@ -928,7 +939,8 @@
xennetworklabel: { label: 'label.xen.traffic.label', isEditable: true },
kvmnetworklabel: { label: 'label.kvm.traffic.label', isEditable: true },
vmwarenetworklabel: { label: 'label.vmware.traffic.label', isEditable: true },
- ovmnetworklabel: { label: 'OVM traffic label', isEditable: true }
+ ovmnetworklabel: { label: 'OVM traffic label', isEditable: true },
+ lxcnetworklabel: { label: 'label.lxc.traffic.label', isEditable: true }
}
],
dataProvider: function(args) { //physical network + Guest traffic type
@@ -964,6 +976,7 @@
selectedPhysicalNetworkObj["kvmnetworklabel"] = trafficType.kvmnetworklabel;
selectedPhysicalNetworkObj["vmwarenetworklabel"] = trafficType.vmwarenetworklabel;
selectedPhysicalNetworkObj["ovmnetworklabel"] = trafficType.ovmnetworklabel;
+ selectedPhysicalNetworkObj["lxcnetworklabel"] = trafficType.lxcnetworklabel;
args.response.success({
actionFilter: function() {
@@ -9491,6 +9504,13 @@
items.push({id: "ocfs2", description: "ocfs2"});
args.response.success({data: items});
}
+ else if(selectedClusterObj.hypervisortype == "LXC") {
+ var items = [];
+ items.push({id: "nfs", description: "nfs"});
+ items.push({id: "SharedMountPoint", description: "SharedMountPoint"});
+ items.push({id: "rbd", description: "RBD"});
+ args.response.success({data: items});
+ }
else {
args.response.success({data:[]});
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/ui/scripts/templates.js
----------------------------------------------------------------------
diff --git a/ui/scripts/templates.js b/ui/scripts/templates.js
index 040ce4a..6268f6b 100644
--- a/ui/scripts/templates.js
+++ b/ui/scripts/templates.js
@@ -237,6 +237,10 @@
//formatSelect.append("<option value='RAW'>RAW</option>");
items.push({id:'RAW', description: 'RAW'});
}
+ else if(args.hypervisor == "LXC") {
+ //formatSelect.append("<option value='TAR'>TAR</option>");
+ items.push({id:'TAR', description: 'TAR'});
+ }
args.response.success({data: items});
}
},
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/aa79ccf9/ui/scripts/zoneWizard.js
----------------------------------------------------------------------
diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js
index a64c86a..76fd5e9 100755
--- a/ui/scripts/zoneWizard.js
+++ b/ui/scripts/zoneWizard.js
@@ -53,6 +53,9 @@
case 'Ovm':
hypervisorAttr = 'ovmnetworklabel';
break;
+ case 'LXC':
+ hypervisorAttr = 'lxcnetworklabel';
+ break;
}
trafficLabelStr = trafficLabel ? '&' + hypervisorAttr + '=' + trafficLabel : '';
@@ -395,6 +398,7 @@
nonSupportedHypervisors["VMware"] = 1;
nonSupportedHypervisors["BareMetal"] = 1;
nonSupportedHypervisors["Ovm"] = 1;
+ nonSupportedHypervisors["LXC"] = 1;
}
if(items != null) {
@@ -1256,6 +1260,12 @@
items.push({id: "ocfs2", description: "ocfs2"});
args.response.success({data: items});
}
+ else if(selectedClusterObj.hypervisortype == "LXC") {
+ var items = [];
+ items.push({id: "nfs", description: "nfs"});
+ items.push({id: "SharedMountPoint", description: "SharedMountPoint"});
+ args.response.success({data: items});
+ }
else {
args.response.success({data:[]});
}