From 87a04e05083cfa680383ca8fda7722bae5ab97fb Mon Sep 17 00:00:00 2001 From: edison su Date: Wed, 10 Oct 2012 00:53:57 -0400 Subject: [PATCH] fix nonoss build --- .../com/cloud/agent/vmdata/JettyVmDataServer.java | 370 +++++++++++ build/build-cloud-plugins.xml | 14 +- build/build-cloud.xml | 4 +- build/package.xml | 10 +- client/pom.xml | 37 ++ client/tomcatconf/components.xml.in | 19 + cloud.spec | 23 +- console-proxy/pom.xml | 5 + deps/pom.xml | 25 + patches/pom.xml | 5 + .../kvm/resource/FakeComputingResource.java | 641 ++++++++++++++++++++ pom.xml | 1 + wscript_build | 6 +- 13 files changed, 1145 insertions(+), 15 deletions(-) create mode 100644 agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/FakeComputingResource.java diff --git a/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java b/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java new file mode 100644 index 0000000..fa1f8d1 --- /dev/null +++ b/agent/src/com/cloud/agent/vmdata/JettyVmDataServer.java @@ -0,0 +1,370 @@ +// 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.agent.vmdata; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.File; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; +import org.mortbay.jetty.Connector; +import org.mortbay.jetty.Handler; +import org.mortbay.jetty.Server; +import org.mortbay.jetty.handler.DefaultHandler; +import org.mortbay.jetty.handler.HandlerList; +import org.mortbay.jetty.handler.ResourceHandler; +import org.mortbay.jetty.nio.SelectChannelConnector; +import org.mortbay.jetty.servlet.Context; +import org.mortbay.jetty.servlet.ServletHolder; +import org.mortbay.thread.QueuedThreadPool; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.routing.VmDataCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.network.Networks.TrafficType; +import com.cloud.storage.JavaStorageLayer; +import com.cloud.storage.StorageLayer; +import com.cloud.utils.net.NetUtils; +import com.cloud.utils.script.Script; + +/** + * Serves vm data using embedded Jetty server + * + */ +@Local(value = { VmDataServer.class }) +public class JettyVmDataServer implements VmDataServer { + private static final Logger s_logger = Logger + .getLogger(JettyVmDataServer.class); + + public static final String USER_DATA = "user-data"; + public static final String META_DATA = "meta-data"; + protected String _vmDataDir; + protected Server _jetty; + protected String _hostIp; + protected Map _ipVmMap = new HashMap(); + protected StorageLayer _fs = new JavaStorageLayer(); + + public class VmDataServlet extends HttpServlet { + + private static final long serialVersionUID = -1640031398971742349L; + + JettyVmDataServer _vmDataServer; + String _dataType; // userdata or meta-data + + public VmDataServlet(JettyVmDataServer dataServer, String dataType) { + this._vmDataServer = dataServer; + this._dataType = dataType; + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + int port = req.getServerPort(); + if (port != 80 && port != 8000) { + resp.sendError(HttpServletResponse.SC_NOT_FOUND, + "Request not understood"); + return; + } + if (_dataType.equalsIgnoreCase(USER_DATA)) { + handleUserData(req, resp); + } else if (_dataType.equalsIgnoreCase(META_DATA)) { + handleMetaData(req, resp); + } + } + + protected void handleUserData(HttpServletRequest req, + HttpServletResponse resp) throws ServletException, IOException { + String metadataItem = req.getPathInfo(); + String requester = req.getRemoteAddr(); + resp.setContentType("text/html"); + resp.setStatus(HttpServletResponse.SC_OK); + String data = null; + if (metadataItem != null) { + String[] path = metadataItem.split("/"); + if (path.length > 1) { + metadataItem = path[1]; + } + } + + if (metadataItem != null) + data = _vmDataServer.getVmDataItem(requester, metadataItem); + + if (data != null) { + resp.getWriter().print(data); + } else { + resp.setStatus(HttpServletResponse.SC_NOT_FOUND); + resp.sendError(HttpServletResponse.SC_NOT_FOUND, + "Request not found"); + } + + } + + protected void handleMetaData(HttpServletRequest req, + HttpServletResponse resp) throws ServletException, IOException { + String metadataItem = req.getPathInfo(); + String requester = req.getRemoteAddr(); + resp.setContentType("text/html"); + resp.setStatus(HttpServletResponse.SC_OK); + String metaData = _vmDataServer.getVmDataItem(requester, + metadataItem); + if (metaData != null) { + resp.getWriter().print( + _vmDataServer.getVmDataItem(requester, metadataItem)); + } else { + resp.sendError(HttpServletResponse.SC_NOT_FOUND, + "Request not found"); + } + } + + } + + @Override + public boolean configure(String name, Map params) + throws ConfigurationException { + boolean success = true; + try { + int vmDataPort = 80; + int fileservingPort = 8000; + _vmDataDir = (String) params.get("vm.data.dir"); + String port = (String) params.get("vm.data.port"); + if (port != null) { + vmDataPort = Integer.parseInt(port); + } + port = (String) params.get("file.server.port"); + if (port != null) { + fileservingPort = Integer.parseInt(port); + } + _hostIp = (String) params.get("host.ip"); + + if (_vmDataDir == null) { + _vmDataDir = "/var/www/html"; + } + success = _fs.mkdirs(_vmDataDir); + success = success && buildIpVmMap(); + if (success) { + setupJetty(vmDataPort, fileservingPort); + } + } catch (Exception e) { + s_logger.warn("Failed to configure jetty", e); + throw new ConfigurationException("Failed to configure jetty!!"); + } + return success; + } + + protected boolean buildIpVmMap() { + String[] dirs = _fs.listFiles(_vmDataDir); + for (String dir : dirs) { + String[] path = dir.split("/"); + String vm = path[path.length - 1]; + if (vm.startsWith("i-")) { + String[] dataFiles = _fs.listFiles(dir); + for (String dfile : dataFiles) { + String path2[] = dfile.split("/"); + String ipv4file = path2[path2.length - 1]; + if (ipv4file.equalsIgnoreCase("local-ipv4")) { + try { + BufferedReader input = new BufferedReader( + new FileReader(dfile)); + String line = null; + while ((line = input.readLine()) != null) { + if (NetUtils.isValidIp(line)) { + _ipVmMap.put(line, vm); + s_logger.info("Found ip " + line + + " for vm " + vm); + } else { + s_logger.info("Invalid ip " + line + + " for vm " + vm); + } + } + } catch (FileNotFoundException e) { + s_logger.warn("Failed to find file " + dfile); + } catch (IOException e) { + s_logger.warn("Failed to get ip address of " + vm); + } + + } + } + } + } + return true; + } + + public String getVmDataItem(String requester, String dataItem) { + String vmName = _ipVmMap.get(requester); + if (vmName == null) { + return null; + } + String vmDataFile = _vmDataDir + File.separator + vmName + + File.separator + dataItem; + try { + BufferedReader input = new BufferedReader( + new FileReader(vmDataFile)); + StringBuilder result = new StringBuilder(); + String line = null; + while ((line = input.readLine()) != null) { + result.append(line); + } + input.close(); + return result.toString(); + } catch (FileNotFoundException e) { + s_logger.warn("Failed to find requested file " + vmDataFile); + return null; + } catch (IOException e) { + s_logger.warn("Failed to read requested file " + vmDataFile); + return null; + } + } + + private void setupJetty(int vmDataPort, int fileservingPort) + throws Exception { + _jetty = new Server(); + + SelectChannelConnector connector0 = new SelectChannelConnector(); + connector0.setHost(_hostIp); + connector0.setPort(fileservingPort); + connector0.setMaxIdleTime(30000); + connector0.setRequestBufferSize(8192); + + SelectChannelConnector connector1 = new SelectChannelConnector(); + connector1.setHost(_hostIp); + connector1.setPort(vmDataPort); + connector1.setThreadPool(new QueuedThreadPool(5)); + connector1.setMaxIdleTime(30000); + connector1.setRequestBufferSize(8192); + + _jetty.setConnectors(new Connector[] { connector0, connector1 }); + + Context root = new Context(_jetty, "/latest", Context.SESSIONS); + root.setResourceBase(_vmDataDir); + root.addServlet(new ServletHolder(new VmDataServlet(this, USER_DATA)), + "/*"); + + ResourceHandler resource_handler = new ResourceHandler(); + resource_handler.setResourceBase("/var/lib/images/"); + + HandlerList handlers = new HandlerList(); + handlers.setHandlers(new Handler[] { root, resource_handler, + new DefaultHandler() }); + _jetty.setHandler(handlers); + + _jetty.start(); + // _jetty.join(); + } + + @Override + public boolean start() { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return "JettyVmDataServer"; + } + + @Override + public Answer handleVmDataCommand(VmDataCommand cmd) { + String vmDataDir = _vmDataDir + File.separator + cmd.getVmName(); + + Script.runSimpleBashScript("rm -rf " + vmDataDir); + _fs.mkdirs(vmDataDir); + + for (String[] item : cmd.getVmData()) { + try { + _fs.create(vmDataDir, item[1]); + String vmDataFile = vmDataDir + File.separator + item[1]; + byte[] data; + if (item[2] != null) { + if (item[1].equals("user-data")) { + data = Base64.decodeBase64(item[2]); + } else { + data = item[2].getBytes(); + } + if (data != null && data.length > 0) { + FileOutputStream writer = new FileOutputStream( + vmDataFile); + writer.write(data); + writer.close(); + } + } + } catch (IOException e) { + s_logger.warn("Failed to write vm data item " + item[1], e); + return new Answer(cmd, false, "Failed to write vm data item " + + item[1]); + } + } + return new Answer(cmd); + + } + + @Override + public void handleVmStarted(VirtualMachineTO vm) { + for (NicTO nic : vm.getNics()) { + if (nic.getType() == TrafficType.Guest) { + if (nic.getIp() != null) { + String ipv4File = _vmDataDir + File.separator + + vm.getName() + File.separator + "local-ipv4"; + try { + _fs.create(_vmDataDir + File.separator + vm.getName(), + "local-ipv4"); + BufferedWriter writer = new BufferedWriter( + new FileWriter(ipv4File)); + writer.write(nic.getIp()); + _ipVmMap.put(nic.getIp(), vm.getName()); + writer.close(); + } catch (IOException e) { + s_logger.warn( + "Failed to create or write to local-ipv4 file " + + ipv4File, e); + } + + } + + } + } + } + + @Override + public void handleVmStopped(String vmName) { + String vmDataDir = _vmDataDir + File.separator + vmName; + Script.runSimpleBashScript("rm -rf " + vmDataDir); + } +} diff --git a/build/build-cloud-plugins.xml b/build/build-cloud-plugins.xml index 207ef71..ce7722f 100755 --- a/build/build-cloud-plugins.xml +++ b/build/build-cloud-plugins.xml @@ -179,9 +179,9 @@ - + - + @@ -193,8 +193,8 @@ - - + + @@ -212,7 +212,7 @@ - + @@ -279,8 +279,8 @@ - - + + diff --git a/build/build-cloud.xml b/build/build-cloud.xml index 1b25fac..f751820 100755 --- a/build/build-cloud.xml +++ b/build/build-cloud.xml @@ -200,7 +200,7 @@ - + @@ -480,7 +480,7 @@ - + diff --git a/build/package.xml b/build/package.xml index 09ed939..566f7f9 100755 --- a/build/package.xml +++ b/build/package.xml @@ -209,20 +209,26 @@ - + + - + + + + + + diff --git a/client/pom.xml b/client/pom.xml index c10b677..5c9d1c3 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -104,6 +104,43 @@ 5.1.21 runtime + + + org.apache.cloudstack + cloud-plugin-hypervisor-vmware + ${project.version} + + + org.apache.cloudstack + cloud-plugin-network-srx + ${project.version} + + + org.apache.cloudstack + cloud-plugin-hypervisor-kvm + ${project.version} + + + org.mortbay.jetty + jetty + + + + + org.apache.cloudstack + cloud-plugin-netapp + ${project.version} + + + org.apache.cloudstack + cloud-plugin-network-f5 + ${project.version} + + + org.apache.cloudstack + cloud-plugin-network-netscaler + ${project.version} + install diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 5730b83..44eddc8 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -114,6 +114,7 @@ under the License. + @@ -121,6 +122,7 @@ under the License. + @@ -131,6 +133,7 @@ under the License. + @@ -150,11 +153,15 @@ under the License. + + + + @@ -164,6 +171,7 @@ under the License. + @@ -171,14 +179,25 @@ under the License. + + + + + + + + + + + diff --git a/cloud.spec b/cloud.spec index 864a47b..be6f121 100644 --- a/cloud.spec +++ b/cloud.spec @@ -434,18 +434,25 @@ fi %files server %defattr(0644,root,root,0755) %{_javadir}/%{name}-server.jar +%{_javadir}/%{name}-vmware-base.jar +%{_javadir}/%{name}-vmware.jar %{_javadir}/%{name}-ovm.jar %{_javadir}/%{name}-dp-user-concentrated-pod.jar %{_javadir}/%{name}-dp-user-dispersing.jar %{_javadir}/%{name}-host-allocator-random.jar +%{_javadir}/%{name}-plugin-f5.jar +%{_javadir}/%{name}-plugin-netscaler.jar %{_javadir}/%{name}-plugin-ovs.jar +%{_javadir}/%{name}-plugin-srx.jar %{_javadir}/%{name}-storage-allocator-random.jar %{_javadir}/%{name}-user-authenticator-ldap.jar %{_javadir}/%{name}-user-authenticator-md5.jar %{_javadir}/%{name}-user-authenticator-plaintext.jar %{_javadir}/%{name}-plugin-hypervisor-xen.jar -%{_javadir}/%{name}-plugin-elb.jar +%{_javadir}/%{name}-plugin-hypervisor-kvm.jar +%{_javadir}/%{name}-plugin-netapp.jar %{_javadir}/%{name}-plugin-nicira-nvp.jar +%{_javadir}/%{name}-plugin-elb.jar %config(noreplace) %{_sysconfdir}/%{name}/server/* %doc LICENSE %doc NOTICE @@ -494,11 +501,25 @@ fi %{_javadir}/jasypt-1.*.jar %{_javadir}/commons-configuration-1.8.jar %{_javadir}/ejb-api-3.0.jar +%{_javadir}/axis-1.4.jar %{_javadir}/axis2-1.5.1.jar +%{_javadir}/axis-jaxrpc-1.4.jar +%{_javadir}/axis2-kernel-*.jar %{_javadir}/commons-discovery-0.5.jar %{_javadir}/jstl-1.2.jar %{_javadir}/javax.persistence-2.0.0.jar %{_javadir}/bcprov-jdk16-1.45.jar +%{_javadir}/commons-lang-*.jar +%{_javadir}/mysql-connector-java-5.1.21.jar +%{_javadir}/junit-4.10.jar +%{_javadir}/jetty-6.1.26.jar +%{_javadir}/jetty-util-6.1.26.jar +%{_javadir}/libvirt-0.4.9.jar +%{_javadir}/cloud-netscaler.jar +%{_javadir}/cloud-netscaler-sdx.jar +%{_javadir}/cloud-iControl.jar +%{_javadir}/cloud-manageontap.jar +%{_javadir}/vmware*.jar %doc LICENSE %doc NOTICE diff --git a/console-proxy/pom.xml b/console-proxy/pom.xml index 53884d3..1aeaa09 100644 --- a/console-proxy/pom.xml +++ b/console-proxy/pom.xml @@ -50,6 +50,11 @@ org.apache.cloudstack + cloud-vmware-base + ${project.version} + + + org.apache.cloudstack cloud-agent ${project.version} diff --git a/deps/pom.xml b/deps/pom.xml index 069da5c..9fe472b 100644 --- a/deps/pom.xml +++ b/deps/pom.xml @@ -110,6 +110,31 @@ runtime + + org.apache.cloudstack + cloud-plugin-hypervisor-vmware + ${project.version} + + + org.apache.cloudstack + cloud-plugin-network-srx + ${project.version} + + + org.apache.cloudstack + cloud-plugin-netapp + ${project.version} + + + org.apache.cloudstack + cloud-plugin-network-f5 + ${project.version} + + + org.apache.cloudstack + cloud-plugin-network-netscaler + ${project.version} + org.apache.axis2 diff --git a/patches/pom.xml b/patches/pom.xml index da78160..81c1acd 100644 --- a/patches/pom.xml +++ b/patches/pom.xml @@ -50,6 +50,11 @@ org.apache.cloudstack + cloud-vmware-base + ${project.version} + + + org.apache.cloudstack cloud-agent ${project.version} diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/FakeComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/FakeComputingResource.java new file mode 100644 index 0000000..d2a8643 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/FakeComputingResource.java @@ -0,0 +1,641 @@ +// 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 java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.InetAddress; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.AttachIsoCommand; +import com.cloud.agent.api.AttachVolumeCommand; +import com.cloud.agent.api.CheckHealthAnswer; +import com.cloud.agent.api.CheckHealthCommand; +import com.cloud.agent.api.CheckStateAnswer; +import com.cloud.agent.api.CheckStateCommand; +import com.cloud.agent.api.CheckVirtualMachineAnswer; +import com.cloud.agent.api.CheckVirtualMachineCommand; +import com.cloud.agent.api.CleanupNetworkRulesCmd; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.GetHostStatsAnswer; +import com.cloud.agent.api.GetHostStatsCommand; +import com.cloud.agent.api.GetStorageStatsAnswer; +import com.cloud.agent.api.GetStorageStatsCommand; +import com.cloud.agent.api.GetVmStatsAnswer; +import com.cloud.agent.api.GetVmStatsCommand; +import com.cloud.agent.api.ModifySshKeysCommand; +import com.cloud.agent.api.ModifyStoragePoolAnswer; +import com.cloud.agent.api.ModifyStoragePoolCommand; +import com.cloud.agent.api.PingCommand; +import com.cloud.agent.api.PingRoutingCommand; +import com.cloud.agent.api.PingTestCommand; +import com.cloud.agent.api.ReadyAnswer; +import com.cloud.agent.api.ReadyCommand; +import com.cloud.agent.api.RebootAnswer; +import com.cloud.agent.api.RebootCommand; +import com.cloud.agent.api.SecurityGroupRuleAnswer; +import com.cloud.agent.api.SecurityGroupRulesCmd; +import com.cloud.agent.api.StartAnswer; +import com.cloud.agent.api.StartCommand; +import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.StartupRoutingCommand; +import com.cloud.agent.api.StartupRoutingCommand.VmState; +import com.cloud.agent.api.StartupStorageCommand; +import com.cloud.agent.api.StopAnswer; +import com.cloud.agent.api.StopCommand; +import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.agent.api.routing.SavePasswordCommand; +import com.cloud.agent.api.routing.VmDataCommand; +import com.cloud.agent.api.storage.CreateAnswer; +import com.cloud.agent.api.storage.CreateCommand; +import com.cloud.agent.api.storage.DestroyCommand; +import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; +import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.to.NicTO; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.dhcp.DhcpSnooper; +import com.cloud.agent.dhcp.FakeDhcpSnooper; +import com.cloud.agent.mockvm.MockVm; +import com.cloud.agent.mockvm.MockVmMgr; +import com.cloud.agent.mockvm.VmMgr; +import com.cloud.agent.vmdata.JettyVmDataServer; +import com.cloud.agent.vmdata.VmDataServer; +import com.cloud.host.Host.Type; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.network.Networks.RouterPrivateIpStrategy; +import com.cloud.network.Networks.TrafficType; +import com.cloud.resource.ServerResource; +import com.cloud.resource.ServerResourceBase; +import com.cloud.storage.Storage; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.Volume; +import com.cloud.storage.template.TemplateInfo; +import com.cloud.utils.PropertiesUtil; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; +import com.cloud.vm.VirtualMachine.State; + +/** + * Pretends to be a computing resource + * + */ +@Local(value = { ServerResource.class }) +public class FakeComputingResource extends ServerResourceBase implements + ServerResource { + private static final Logger s_logger = Logger + .getLogger(FakeComputingResource.class); + private Map _params; + private VmMgr _vmManager = new MockVmMgr(); + protected HashMap _vms = new HashMap(20); + protected DhcpSnooper _dhcpSnooper = new FakeDhcpSnooper(); + protected VmDataServer _vmDataServer = new JettyVmDataServer(); + + @Override + public Type getType() { + return Type.Routing; + } + + @Override + public StartupCommand[] initialize() { + Map changes = null; + + final List info = getHostInfo(); + + 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, + RouterPrivateIpStrategy.HostLocal, changes); + fillNetworkInformation(cmd); + cmd.getHostDetails().putAll(getVersionStrings()); + cmd.setCluster(getConfiguredProperty("cluster", "1")); + StoragePoolInfo pi = initializeLocalStorage(); + StartupStorageCommand sscmd = new StartupStorageCommand(); + sscmd.setPoolInfo(pi); + sscmd.setGuid(pi.getUuid()); + sscmd.setDataCenter((String) _params.get("zone")); + sscmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL); + + return new StartupCommand[] { cmd, sscmd }; + + } + + private Map getVersionStrings() { + Map result = new HashMap(); + String hostOs = (String) _params.get("Host.OS"); + String hostOsVer = (String) _params.get("Host.OS.Version"); + String hostOsKernVer = (String) _params.get("Host.OS.Kernel.Version"); + result.put("Host.OS", hostOs == null ? "Fedora" : hostOs); + result.put("Host.OS.Version", hostOsVer == null ? "14" : hostOsVer); + result.put("Host.OS.Kernel.Version", + hostOsKernVer == null ? "2.6.35.6-45.fc14.x86_64" + : hostOsKernVer); + return result; + } + + protected void fillNetworkInformation(final StartupCommand cmd) { + + cmd.setPrivateIpAddress((String) _params.get("private.ip.address")); + cmd.setPrivateMacAddress((String) _params.get("private.mac.address")); + cmd.setPrivateNetmask((String) _params.get("private.ip.netmask")); + + cmd.setStorageIpAddress((String) _params.get("private.ip.address")); + cmd.setStorageMacAddress((String) _params.get("private.mac.address")); + cmd.setStorageNetmask((String) _params.get("private.ip.netmask")); + cmd.setGatewayIpAddress((String) _params.get("gateway.ip.address")); + + } + + protected StoragePoolInfo initializeLocalStorage() { + String hostIp = (String) _params.get("private.ip.address"); + String localStoragePath = (String) _params.get("local.storage.path"); + String lh = hostIp + localStoragePath; + String uuid = UUID.nameUUIDFromBytes(lh.getBytes()).toString(); + + String capacity = (String) _params.get("local.storage.capacity"); + String available = (String) _params.get("local.storage.avail"); + + return new StoragePoolInfo(uuid, hostIp, localStoragePath, + localStoragePath, StoragePoolType.Filesystem, + Long.parseLong(capacity), Long.parseLong(available)); + + } + + @Override + public PingCommand getCurrentStatus(long id) { + final HashMap newStates = new HashMap(); + _dhcpSnooper.syncIpAddr(); + return new PingRoutingCommand(com.cloud.host.Host.Type.Routing, id, + newStates); + } + + @Override + public Answer executeRequest(Command cmd) { + try { + if (cmd instanceof ReadyCommand) { + return execute((ReadyCommand) cmd); + } else if (cmd instanceof ModifySshKeysCommand) { + return execute((ModifySshKeysCommand) cmd);// TODO: remove + } else if (cmd instanceof GetHostStatsCommand) { + return execute((GetHostStatsCommand) cmd); + } else if (cmd instanceof PrimaryStorageDownloadCommand) { + return execute((PrimaryStorageDownloadCommand) cmd); + + } else if (cmd instanceof StopCommand) { + return execute((StopCommand) cmd); + } else if (cmd instanceof GetVmStatsCommand) { + return execute((GetVmStatsCommand) cmd); + } else if (cmd instanceof RebootCommand) { + return execute((RebootCommand) cmd); + } else if (cmd instanceof CheckStateCommand) { + return executeRequest(cmd); + } else if (cmd instanceof CheckHealthCommand) { + return execute((CheckHealthCommand) cmd); + } else if (cmd instanceof PingTestCommand) { + return execute((PingTestCommand) cmd); + } else if (cmd instanceof CheckVirtualMachineCommand) { + return execute((CheckVirtualMachineCommand) cmd); + } else if (cmd instanceof ReadyCommand) { + return execute((ReadyCommand) cmd); + } else if (cmd instanceof StopCommand) { + return execute((StopCommand) cmd); + } else if (cmd instanceof CreateCommand) { + return execute((CreateCommand) cmd); + } else if (cmd instanceof DestroyCommand) { + return execute((DestroyCommand) cmd); + } else if (cmd instanceof PrimaryStorageDownloadCommand) { + return execute((PrimaryStorageDownloadCommand) cmd); + } else if (cmd instanceof GetStorageStatsCommand) { + return execute((GetStorageStatsCommand) cmd); + } else if (cmd instanceof ModifyStoragePoolCommand) { + return execute((ModifyStoragePoolCommand) cmd); + } else if (cmd instanceof SecurityGroupRulesCmd) { + return execute((SecurityGroupRulesCmd) cmd); + } else if (cmd instanceof StartCommand) { + return execute((StartCommand) cmd); + } else if (cmd instanceof CleanupNetworkRulesCmd) { + return execute((CleanupNetworkRulesCmd) cmd); + } else if (cmd instanceof SavePasswordCommand) { + return execute((SavePasswordCommand) cmd); + } else if (cmd instanceof VmDataCommand) { + return execute((VmDataCommand) cmd); + } else { + s_logger.warn("Unsupported command "); + return Answer.createUnsupportedCommandAnswer(cmd); + } + } catch (final IllegalArgumentException e) { + return new Answer(cmd, false, e.getMessage()); + } + } + + private Answer execute(CleanupNetworkRulesCmd cmd) { + return new Answer(cmd); + } + + private Answer execute(SecurityGroupRulesCmd cmd) { + s_logger.info("Programmed network rules for vm " + cmd.getVmName() + + " guestIp=" + cmd.getGuestIp() + ",ingress numrules=" + + cmd.getIngressRuleSet().length + ",egress numrules=" + + cmd.getEgressRuleSet().length); + return new SecurityGroupRuleAnswer(cmd); + } + + private Answer execute(ModifyStoragePoolCommand cmd) { + long capacity = getConfiguredProperty("local.storage.capacity", + 10000000000L); + long used = 10000000L; + long available = capacity - used; + if (cmd.getAdd()) { + + ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, + capacity, used, new HashMap()); + + if (s_logger.isInfoEnabled()) + s_logger.info("Sending ModifyStoragePoolCommand answer with capacity: " + + capacity + + ", used: " + + used + + ", available: " + + available); + return answer; + } else { + if (s_logger.isInfoEnabled()) + s_logger.info("ModifyNetfsStoragePoolCmd is not add command, cmd: " + + cmd.toString()); + return new Answer(cmd); + } + } + + private Answer execute(GetStorageStatsCommand cmd) { + return new GetStorageStatsAnswer(cmd, getConfiguredProperty( + "local.storage.capacity", 100000000000L), 0L); + } + + protected synchronized ReadyAnswer execute(ReadyCommand cmd) { + return new ReadyAnswer(cmd); + } + + private Answer execute(PrimaryStorageDownloadCommand cmd) { + return new PrimaryStorageDownloadAnswer(cmd.getLocalPath(), 16000000L); + } + + private Answer execute(ModifySshKeysCommand cmd) { + return new Answer(cmd, true, null); + } + + @Override + protected String getDefaultScriptsDir() { + return null; + } + + protected String getConfiguredProperty(String key, String defaultValue) { + String val = (String) _params.get(key); + return val == null ? defaultValue : val; + } + + protected Long getConfiguredProperty(String key, Long defaultValue) { + String val = (String) _params.get(key); + + if (val != null) { + Long result = Long.parseLong(val); + return result; + } + return defaultValue; + } + + protected List getHostInfo() { + final ArrayList info = new ArrayList(); + long speed = getConfiguredProperty("cpuspeed", 4000L); + long cpus = getConfiguredProperty("cpus", 4L); + long ram = getConfiguredProperty("memory", 16000L * 1024L * 1024L); + long dom0ram = Math.min(ram / 10, 768 * 1024 * 1024L); + + String cap = getConfiguredProperty("capabilities", "hvm"); + info.add((int) cpus); + info.add(speed); + info.add(ram); + info.add(cap); + info.add(dom0ram); + return info; + + } + + private Map getSimulatorProperties() + throws ConfigurationException { + final File file = PropertiesUtil.findConfigFile("simulator.properties"); + if (file == null) { + throw new ConfigurationException( + "Unable to find simulator.properties."); + } + + s_logger.info("simulator.properties found at " + file.getAbsolutePath()); + Properties properties = new Properties(); + try { + properties.load(new FileInputStream(file)); + + final Map params = PropertiesUtil.toMap(properties); + + return params; + } catch (final FileNotFoundException ex) { + throw new CloudRuntimeException("Cannot find the file: " + + file.getAbsolutePath(), ex); + } catch (final IOException ex) { + throw new CloudRuntimeException("IOException in reading " + + file.getAbsolutePath(), ex); + } + } + + @Override + public boolean configure(String name, Map params) + throws ConfigurationException { + Map simProps = getSimulatorProperties(); + params.putAll(simProps); + setParams(params); + _vmManager.configure(params); + _dhcpSnooper.configure(name, params); + _vmDataServer.configure(name, params); + return true; + } + + public void setParams(Map _params) { + this._params = _params; + } + + public Map getParams() { + return _params; + } + + protected synchronized StartAnswer execute(StartCommand cmd) { + VmMgr vmMgr = getVmManager(); + + VirtualMachineTO vmSpec = cmd.getVirtualMachine(); + String vmName = vmSpec.getName(); + State state = State.Stopped; + + try { + if (!_vms.containsKey(vmName)) { + synchronized (_vms) { + _vms.put(vmName, State.Starting); + } + + MockVm vm = vmMgr.createVmFromSpec(vmSpec); + vmMgr.createVbd(vmSpec, vmName, vm); + vmMgr.createVif(vmSpec, vmName, vm); + + state = State.Running; + for (NicTO nic : cmd.getVirtualMachine().getNics()) { + if (nic.getType() == TrafficType.Guest) { + InetAddress addr = _dhcpSnooper.getIPAddr(nic.getMac(), + vmName); + nic.setIp(addr.getHostAddress()); + } + } + _vmDataServer.handleVmStarted(cmd.getVirtualMachine()); + return new StartAnswer(cmd); + } else { + String msg = "There is already a VM having the same name " + + vmName; + s_logger.warn(msg); + return new StartAnswer(cmd, msg); + } + } catch (Exception ex) { + + } finally { + synchronized (_vms) { + _vms.put(vmName, state); + } + } + return new StartAnswer(cmd); + } + + protected synchronized StopAnswer execute(StopCommand cmd) { + VmMgr vmMgr = getVmManager(); + + StopAnswer answer = null; + String vmName = cmd.getVmName(); + + Integer port = vmMgr.getVncPort(vmName); + + State state = null; + synchronized (_vms) { + state = _vms.get(vmName); + _vms.put(vmName, State.Stopping); + } + try { + String result = vmMgr.stopVM(vmName, false); + if (result != null) { + s_logger.info("Trying destroy on " + vmName); + if (result == Script.ERR_TIMEOUT) { + result = vmMgr.stopVM(vmName, true); + } + + s_logger.warn("Couldn't stop " + vmName); + + if (result != null) { + return new StopAnswer(cmd, result, false); + } + } + + answer = new StopAnswer(cmd, null, port, true); + + String result2 = vmMgr.cleanupVnet(cmd.getVnet()); + if (result2 != null) { + result = result2 + (result != null ? ("\n" + result) : ""); + answer = new StopAnswer(cmd, result, port, true); + } + + _dhcpSnooper.cleanup(vmName, null); + + return answer; + } finally { + if (answer == null || !answer.getResult()) { + synchronized (_vms) { + _vms.put(vmName, state); + } + } + } + } + + protected Answer execute(final VmDataCommand cmd) { + return _vmDataServer.handleVmDataCommand(cmd); + } + + protected Answer execute(final SavePasswordCommand cmd) { + return new Answer(cmd); + } + + protected Answer execute(RebootCommand cmd) { + VmMgr vmMgr = getVmManager(); + vmMgr.rebootVM(cmd.getVmName()); + return new RebootAnswer(cmd, "success", true); + } + + private Answer execute(PingTestCommand cmd) { + return new Answer(cmd); + } + + protected GetVmStatsAnswer execute(GetVmStatsCommand cmd) { + return null; + } + + private VmMgr getVmManager() { + return _vmManager; + } + + protected Answer execute(GetHostStatsCommand cmd) { + VmMgr vmMgr = getVmManager(); + return new GetHostStatsAnswer(cmd, vmMgr.getHostCpuUtilization(), + vmMgr.getHostFreeMemory(), vmMgr.getHostTotalMemory(), 0, 0, + "SimulatedHost"); + } + + protected CheckStateAnswer execute(CheckStateCommand cmd) { + State state = getVmManager().checkVmState(cmd.getVmName()); + return new CheckStateAnswer(cmd, state); + } + + protected CheckHealthAnswer execute(CheckHealthCommand cmd) { + return new CheckHealthAnswer(cmd, true); + } + + protected CheckVirtualMachineAnswer execute( + final CheckVirtualMachineCommand cmd) { + VmMgr vmMgr = getVmManager(); + final String vmName = cmd.getVmName(); + + final State state = vmMgr.checkVmState(vmName); + Integer vncPort = null; + if (state == State.Running) { + vncPort = vmMgr.getVncPort(vmName); + synchronized (_vms) { + _vms.put(vmName, State.Running); + } + } + return new CheckVirtualMachineAnswer(cmd, state, vncPort); + } + + protected Answer execute(final AttachVolumeCommand cmd) { + return new Answer(cmd); + } + + protected Answer execute(final AttachIsoCommand cmd) { + return new Answer(cmd); + } + + protected CreateAnswer execute(final CreateCommand cmd) { + try { + + VolumeTO vol = new VolumeTO(cmd.getVolumeId(), Volume.Type.ROOT, + com.cloud.storage.Storage.StoragePoolType.LVM, cmd + .getPool().getUuid(), "dummy", "/mountpoint", + "dummyPath", 1000L, null); + return new CreateAnswer(cmd, vol); + } catch (Throwable th) { + return new CreateAnswer(cmd, new Exception("Unexpected exception")); + } + } + + protected HashMap sync() { + Map newStates; + Map oldStates = null; + + HashMap changes = new HashMap(); + + synchronized (_vms) { + newStates = getVmManager().getVmStates(); + oldStates = new HashMap(_vms.size()); + oldStates.putAll(_vms); + + for (Map.Entry entry : newStates.entrySet()) { + String vm = entry.getKey(); + + State newState = entry.getValue(); + State oldState = oldStates.remove(vm); + + if (s_logger.isTraceEnabled()) { + s_logger.trace("VM " + vm + ": xen has state " + newState + + " and we have state " + + (oldState != null ? oldState.toString() : "null")); + } + + if (oldState == null) { + _vms.put(vm, newState); + changes.put(vm, newState); + } else if (oldState == State.Starting) { + if (newState == State.Running) { + _vms.put(vm, newState); + } else if (newState == State.Stopped) { + s_logger.debug("Ignoring vm " + vm + + " because of a lag in starting the vm."); + } + } else if (oldState == State.Stopping) { + if (newState == State.Stopped) { + _vms.put(vm, newState); + } else if (newState == State.Running) { + s_logger.debug("Ignoring vm " + vm + + " because of a lag in stopping the vm. "); + } + } else if (oldState != newState) { + _vms.put(vm, newState); + changes.put(vm, newState); + } + } + + for (Map.Entry entry : oldStates.entrySet()) { + String vm = entry.getKey(); + State oldState = entry.getValue(); + + if (s_logger.isTraceEnabled()) { + s_logger.trace("VM " + vm + + " is now missing from xen so reporting stopped"); + } + + if (oldState == State.Stopping) { + s_logger.debug("Ignoring VM " + vm + + " in transition state stopping."); + _vms.remove(vm); + } else if (oldState == State.Starting) { + s_logger.debug("Ignoring VM " + vm + + " in transition state starting."); + } else if (oldState == State.Stopped) { + _vms.remove(vm); + } else { + changes.put(entry.getKey(), State.Stopped); + } + } + } + + return changes; + } + + protected Answer execute(DestroyCommand cmd) { + return new Answer(cmd, true, null); + } +} diff --git a/pom.xml b/pom.xml index 5e93711..b6c4f9d 100644 --- a/pom.xml +++ b/pom.xml @@ -155,6 +155,7 @@ utils deps/XenServerJava plugins + vmware-base awsapi patches test diff --git a/wscript_build b/wscript_build index 1fafa26..d2c0007 100644 --- a/wscript_build +++ b/wscript_build @@ -135,7 +135,7 @@ def build_jars (): "cloud-commons-httpclient-3.1.jar", "cloud-commons-pool-1.4.jar", "cloud-servlet-api.jar", "cloud-commons-logging-1.1.1.jar", "cloud-ws-commons-util-1.0.2.jar", - "cloud-commons-collections-3.2.1.jar", "vmware*.jar", "cloud-secstorage-extras.jar", + "cloud-commons-collections-3.2.1.jar", "cloud-secstorage-extras.jar", "cloud-agent-simulator.jar", "cloud-awsapi.jar", "cloud-test.jar", "cloud-wsdl4j.jar", "cloud-console-proxy.jar"] for a in jars_str: @@ -162,8 +162,8 @@ def build_dependences (): start_path = bld.path.find_dir ("deps") - bld.install_files('${JAVADIR}',start_path.ant_glob(["CAStorSDK-*.jar", "javax.persistence-2.0.0.jar", "apache-log4j-extras-1.1.jar", "libvirt-0.4.9.jar", "axis2-1.5.1.jar", "jstl-1.2.jar", "commons-discovery-0.5.jar", "commons-codec-1.6.jar", "ejb-api-3.0.jar", "xmlrpc-client-3.1.3.jar", "commons-dbcp-1.4.jar", "commons-pool-1.6.jar", "gson-1.7.1.jar", - "netscaler-1.0.jar", "netscaler-sdx-1.0.jar", "backport-util-concurrent-3.1.jar", "ehcache-1.5.0.jar", "httpcore-4.0.jar", "log4j-1.2.16.jar", "trilead-ssh2-build213-svnkit-1.3-patch.jar", "cglib-nodep-2.2.2.jar", "xmlrpc-common-3.*.jar", + bld.install_files('${JAVADIR}',start_path.ant_glob(["axis-1.4.jar", "axis-jaxrpc-1.4.jar", "axis2-kernel*.jar", "commons-lang-*.jar", "mysql-connector-java-5.1.21.jar", "junit-4.10.jar", "jetty-6.1.26.jar", "jetty-util-6.1.26.jar", "vmware*.jar","CAStorSDK-*.jar", "javax.persistence-2.0.0.jar", "apache-log4j-extras-1.1.jar", "libvirt-0.4.9.jar", "axis2-1.5.1.jar", "jstl-1.2.jar", "commons-discovery-0.5.jar", "commons-codec-1.6.jar", "ejb-api-3.0.jar", "xmlrpc-client-3.1.3.jar", "commons-dbcp-1.4.jar", "commons-pool-1.6.jar", "gson-1.7.1.jar", + "cloud-netscaler.jar", "cloud-netscaler-sdx.jar", "backport-util-concurrent-3.1.jar", "ehcache-1.5.0.jar", "httpcore-4.0.jar", "log4j-1.2.16.jar", "trilead-ssh2-build213-svnkit-1.3-patch.jar", "cglib-nodep-2.2.2.jar", "xmlrpc-common-3.*.jar", "axiom*.jar", "axis2*.jar", "antlr*.jar", "XmlSchema*.jar", "json-simple*.jar", "neethi*.jar", "woden*.jar", "xercesImpl*.jar", "xml-apis*.jar", "dom4j*.jar", "commons-fileupload*.jar", "xmlrpc-client-3.*.jar", "wsdl4j-1.6.2.jar", "bcprov-jdk16-1.45.jar", "jsch-0.1.42.jar", "jasypt-1.9.0.jar", "commons-configuration-1.8.jar", "mail-1.4.jar", "activation-1.1.jar", "xapi-5.6.100-1-SNAPSHOT.jar"], excl = excludes), cwd=start_path) -- 1.7.1