From 5747b8012496148e106672c02028b06e863371d7 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Wed, 22 Jan 2014 21:52:12 +0100 Subject: [PATCH 001/126] test: Add UnitTest for Libvirt Storage Pool definitions --- .../resource/LibvirtStoragePoolDefTest.java | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java new file mode 100644 index 00000000000..687432b3d71 --- /dev/null +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtStoragePoolDefTest.java @@ -0,0 +1,84 @@ +/* + * 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 junit.framework.TestCase; +import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.poolType; +import com.cloud.hypervisor.kvm.resource.LibvirtStoragePoolDef.authType; + +public class LibvirtStoragePoolDefTest extends TestCase { + + public void testSetGetStoragePool() { + poolType type = poolType.NETFS; + String name = "myNFSPool"; + String uuid = "d7846cb0-f610-4a5b-8d38-ee6e8d63f37b"; + String host = "127.0.0.1"; + String dir = "/export/primary"; + String targetPath = "/mnt/" + uuid; + int port = 1234; + + LibvirtStoragePoolDef pool = new LibvirtStoragePoolDef(type, name, uuid, host, port, dir, targetPath); + + assertEquals(type, pool.getPoolType()); + assertEquals(name, pool.getPoolName()); + assertEquals(host, pool.getSourceHost()); + assertEquals(port, pool.getSourcePort()); + assertEquals(dir, pool.getSourceDir()); + assertEquals(targetPath, pool.getTargetPath()); + } + + public void testNfsStoragePool() { + poolType type = poolType.NETFS; + String name = "myNFSPool"; + String uuid = "89a605bc-d470-4637-b3df-27388be452f5"; + String host = "127.0.0.1"; + String dir = "/export/primary"; + String targetPath = "/mnt/" + uuid; + + LibvirtStoragePoolDef pool = new LibvirtStoragePoolDef(type, name, uuid, host, dir, targetPath); + + String expectedXml = "\n" + name + "\n" + uuid + "\n" + + "\n\n\n\n\n" + + "" + targetPath + "\n\n\n"; + + assertEquals(expectedXml, pool.toString()); + } + + public void testRbdStoragePool() { + poolType type = poolType.RBD; + String name = "myRBDPool"; + String uuid = "921ef8b2-955a-4c18-a697-66bb9adf6131"; + String host = "127.0.0.1"; + String dir = "cloudstackrbdpool"; + String authUsername = "admin"; + String secretUuid = "08c2fa02-50d0-4a78-8903-b742d3f34934"; + authType auth = authType.CEPH; + int port = 6789; + + LibvirtStoragePoolDef pool = new LibvirtStoragePoolDef(type, name, uuid, host, port, dir, authUsername, auth, secretUuid); + + String expectedXml = "\n" + name + "\n" + uuid + "\n" + + "\n\n" + dir + "\n" + + "\n\n" + + "\n\n\n"; + + assertEquals(expectedXml, pool.toString()); + } +} \ No newline at end of file From 1b89ae7acbaed3902e9b2efe69bac421fab5a742 Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Wed, 22 Jan 2014 16:50:50 -0800 Subject: [PATCH 002/126] CLOUDSTACK-5478: Publish uuid for deployvm action event. --- server/src/com/cloud/event/ActionEventUtils.java | 5 ++++- server/src/com/cloud/vm/UserVmManagerImpl.java | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java index 0363a0d81dd..d435381b69b 100755 --- a/server/src/com/cloud/event/ActionEventUtils.java +++ b/server/src/com/cloud/event/ActionEventUtils.java @@ -25,6 +25,7 @@ import java.util.Map; import javax.annotation.PostConstruct; import javax.inject.Inject; +import com.cloud.vm.VirtualMachine; import org.apache.log4j.Logger; import org.springframework.beans.factory.NoSuchBeanDefinitionException; @@ -181,7 +182,7 @@ public class ActionEventUtils { } org.apache.cloudstack.framework.events.Event event = - new org.apache.cloudstack.framework.events.Event(ManagementService.Name, eventCategory, eventType, EventTypes.getEntityForEvent(eventType), null); + new org.apache.cloudstack.framework.events.Event(ManagementService.Name, eventCategory, eventType, EventTypes.getEntityForEvent(eventType), entityUuid); Map eventDescription = new HashMap(); Account account = s_accountDao.findById(accountId); @@ -233,6 +234,8 @@ public class ActionEventUtils { else if (eventType.startsWith("USER.")) { return User.class; + }else if (eventType.startsWith("VM.")){ + return VirtualMachine.class; } return null; diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index fc0ec0e4117..85f35275933 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2971,6 +2971,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir long vmId = cmd.getEntityId(); Long hostId = cmd.getHostId(); UserVmVO vm = _vmDao.findById(vmId); + CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid()); Pair> vmParamPair = null; try { From 206c35c620a8e7a707f371e5a9e5dfd795912f5b Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 22 Jan 2014 17:44:21 -0800 Subject: [PATCH 003/126] Vmware is broken due to commit b20add810e5751f53946f695b6223a8016f104a5. --- .../cloud/hypervisor/vmware/util/VmwareClient.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java index e81665f71b7..9284569da32 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareClient.java @@ -263,12 +263,12 @@ public class VmwareClient { props.add(propertyName); List objContent = retrieveMoRefProperties(mor, props); - T propertyValue = null; + Object propertyValue = null; if (objContent != null && objContent.size() > 0) { List dynamicProperty = objContent.get(0).getPropSet(); if (dynamicProperty != null && dynamicProperty.size() > 0) { DynamicProperty dp = dynamicProperty.get(0); - propertyValue = (T)dp.getVal(); + propertyValue = dp.getVal(); /* * If object is ArrayOfXXX object, then get the XXX[] by * invoking getXXX() on the object. @@ -276,17 +276,17 @@ public class VmwareClient { * ArrayOfManagedObjectReference.getManagedObjectReference() * returns ManagedObjectReference[] array. */ - Class dpCls = propertyValue.getClass(); + Class dpCls = propertyValue.getClass(); String dynamicPropertyName = dpCls.getName(); if (dynamicPropertyName.indexOf("ArrayOf") != -1) { String methodName = "get" + dynamicPropertyName.substring(dynamicPropertyName.indexOf("ArrayOf") + "ArrayOf".length(), dynamicPropertyName.length()); - Method getMorMethod = dpCls.getDeclaredMethod(methodName, (Class)null); - propertyValue = (T)getMorMethod.invoke(propertyValue, (Object[])null); + Method getMorMethod = dpCls.getDeclaredMethod(methodName, null); + propertyValue = getMorMethod.invoke(propertyValue, (Object[])null); } } } - return propertyValue; + return (T)propertyValue; } private List retrieveMoRefProperties(ManagedObjectReference mObj, List props) throws Exception { From 5941ac46d2ffc3069752195303f2beab45c1bb61 Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Tue, 31 Dec 2013 00:56:27 +0530 Subject: [PATCH 004/126] CLOUDSTACK-5344 commit for console proxy rdp for hyperv --- .../HypervResourceController.cs | 39 +++ .../com/cloud/server/ManagementServer.java | 3 + .../cloud/server/ManagementServerImpl.java | 5 + .../servlet/ConsoleProxyClientParam.java | 47 ++- .../cloud/servlet/ConsoleProxyServlet.java | 49 ++- .../main/java/common/BufferedImageCanvas.java | 6 +- .../java/common/adapter/AwtCanvasAdapter.java | 4 +- .../src/main/java/rdpclient/RdpClient.java | 15 +- services/console-proxy/server/pom.xml | 5 + .../com/cloud/consoleproxy/ConsoleProxy.java | 20 +- .../consoleproxy/ConsoleProxyAjaxHandler.java | 6 + .../consoleproxy/ConsoleProxyClientParam.java | 32 +- .../ConsoleProxyHttpHandlerHelper.java | 34 +- .../consoleproxy/ConsoleProxyRdpClient.java | 318 ++++++++++++++++++ .../consoleproxy/rdp/KeysymToKeycode.java | 115 +++++++ .../rdp/RdpBufferedImageCanvas.java | 103 ++++++ 16 files changed, 765 insertions(+), 36 deletions(-) create mode 100644 services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java create mode 100644 services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java create mode 100644 services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index a1c91a5b642..6daadeefaac 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -2000,6 +2000,45 @@ namespace HypervResource } } + // POST api/HypervResource/GetVncPortCommand + [HttpPost] + [ActionName(CloudStackTypes.GetVncPortCommand)] + public JContainer GetVncPortCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.GetVncPortCommand + cmd.ToString()); + + string details = null; + bool result = false; + string address = null; + int port = -9; + + try + { + string vmName = (string)cmd.name; + var sys = wmiCallsV2.GetComputerSystem(vmName); + address = "instanceId=" + sys.Name ; + result = true; + } + catch (Exception sysEx) + { + details = CloudStackTypes.GetVncPortAnswer + " failed due to " + sysEx.Message; + logger.Error(details, sysEx); + } + + object ansContent = new + { + result = result, + details = details, + address = address, + port = port + }; + + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVncPortAnswer); + } + } + public static System.Net.NetworkInformation.NetworkInterface GetNicInfoFromIpAddress(string ipAddress, out string subnet) { System.Net.NetworkInformation.NetworkInterface[] nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces(); diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index 5a6ca78a9eb..3b5f5ff206a 100755 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.server; +import com.cloud.host.DetailVO; import com.cloud.host.HostVO; import com.cloud.storage.GuestOSVO; import com.cloud.utils.Pair; @@ -47,6 +48,8 @@ public interface ManagementServer extends ManagementService, PluggableService { */ HostVO getHostBy(long hostId); + DetailVO findDetail(long hostId, String name); + String getConsoleAccessUrlRoot(long vmId); GuestOSVO getGuestOs(Long guestOsId); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index bbb31cfbb6c..4bffa3f60dd 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -854,6 +854,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return _hostDao.findById(hostId); } + @Override + public DetailVO findDetail(long hostId, String name) { + return _detailsDao.findDetail(hostId, name); + } + @Override public long getId() { return MacAddress.getMacAddress().toLong(); diff --git a/server/src/com/cloud/servlet/ConsoleProxyClientParam.java b/server/src/com/cloud/servlet/ConsoleProxyClientParam.java index e9793373c16..ce06a9624a9 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyClientParam.java +++ b/server/src/com/cloud/servlet/ConsoleProxyClientParam.java @@ -27,7 +27,11 @@ public class ConsoleProxyClientParam { private String clientTunnelUrl; private String clientTunnelSession; + private String hypervHost; + private String ajaxSessionId; + private String username; + private String password; public ConsoleProxyClientParam() { clientHostPort = 0; @@ -89,26 +93,51 @@ public class ConsoleProxyClientParam { this.clientTunnelSession = clientTunnelSession; } - public String getLocale() { - return this.locale; - } - - public void setLocale(String locale) { - this.locale = locale; - } - public String getAjaxSessionId() { - return this.ajaxSessionId; + return ajaxSessionId; } public void setAjaxSessionId(String ajaxSessionId) { this.ajaxSessionId = ajaxSessionId; } + public String getLocale() { + return locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + public String getClientMapKey() { if (clientTag != null && !clientTag.isEmpty()) return clientTag; return clientHostAddress + ":" + clientHostPort; } + + public void setHypervHost(String host) { + hypervHost = host; + } + + public String getHypervHost() { + return hypervHost; + } + + public void setUsername(String username) { + this.username = username; + + } + + public String getUsername() { + return username; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } } diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index e0deaa21a49..5edd95d8dbd 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -328,15 +328,21 @@ public class ConsoleProxyServlet extends HttpServlet { s_logger.info("Parse host info returned from executing GetVNCPortCommand. host info: " + hostInfo); - if (hostInfo != null && hostInfo.startsWith("consoleurl")) { - String tokens[] = hostInfo.split("&"); + if (hostInfo != null) { + if (hostInfo.startsWith("consoleurl")) { + String tokens[] = hostInfo.split("&"); - if (hostInfo.length() > 19 && hostInfo.indexOf('/', 19) > 19) { - host = hostInfo.substring(19, hostInfo.indexOf('/', 19)).trim(); - tunnelUrl = tokens[0].substring("consoleurl=".length()); - tunnelSession = tokens[1].split("=")[1]; + if (hostInfo.length() > 19 && hostInfo.indexOf('/', 19) > 19) { + host = hostInfo.substring(19, hostInfo.indexOf('/', 19)).trim(); + tunnelUrl = tokens[0].substring("consoleurl=".length()); + tunnelSession = tokens[1].split("=")[1]; + } else { + host = ""; + } + } else if (hostInfo.startsWith("instanceId")) { + host = hostInfo.substring(hostInfo.indexOf('=') + 1); } else { - host = ""; + host = hostInfo; } } else { host = hostInfo; @@ -389,28 +395,49 @@ public class ConsoleProxyServlet extends HttpServlet { private String composeConsoleAccessUrl(String rootUrl, VirtualMachine vm, HostVO hostVo) { StringBuffer sb = new StringBuffer(rootUrl); String host = hostVo.getPrivateIpAddress(); + String username = _ms.findDetail(hostVo.getId(), "username").getValue(); + String password = _ms.findDetail(hostVo.getId(), "password").getValue(); Pair portInfo = _ms.getVncPort(vm); if (s_logger.isDebugEnabled()) s_logger.debug("Port info " + portInfo.first()); Ternary parsedHostInfo = parseHostInfo(portInfo.first()); + int port = -1; + String sid; + + if (portInfo.second() == -9) { + //for hyperv + port = 2179; + } else { + port = portInfo.second(); + } + sid = vm.getVncPassword(); UserVmDetailVO details = _userVmDetailsDao.findDetail(vm.getId(), "keyboard"); - String sid = vm.getVncPassword(); + String tag = vm.getUuid(); - String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag); + + String ticket = genAccessTicket(parsedHostInfo.first(), String.valueOf(port), sid, tag); ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(getEncryptorPassword()); ConsoleProxyClientParam param = new ConsoleProxyClientParam(); param.setClientHostAddress(parsedHostInfo.first()); - param.setClientHostPort(portInfo.second()); + param.setClientHostPort(port); param.setClientHostPassword(sid); param.setClientTag(tag); param.setTicket(ticket); + if (details != null) { param.setLocale(details.getValue()); } - if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) { + + if (portInfo.second() == -9) { + //For Hyperv Clinet Host Address will send Instance id + param.setHypervHost(host); + param.setUsername(username); + param.setPassword(password); + } + if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) { param.setClientTunnelUrl(parsedHostInfo.second()); param.setClientTunnelSession(parsedHostInfo.third()); } diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java index 43abb273477..9cb523137ec 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/BufferedImageCanvas.java @@ -30,7 +30,7 @@ public class BufferedImageCanvas extends Canvas { private static final long serialVersionUID = 1L; // Offline screen buffer - private BufferedImage offlineImage; + protected BufferedImage offlineImage; // Cached Graphics2D object for offline screen buffer private Graphics2D graphics; @@ -76,4 +76,8 @@ public class BufferedImageCanvas extends Canvas { return graphics; } + public void updateFrameBuffer(int x, int y, int w, int h) { + //this method will be used to mark the dirty tiles + } + } diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java index 55ca8fdbf64..f3a73d70dbd 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/common/adapter/AwtCanvasAdapter.java @@ -77,13 +77,14 @@ public class AwtCanvasAdapter extends BaseElement { } private void handleCopyRect(CopyRectOrder order, ByteBuffer buf) { - // TODO Auto-generated method stub // Copy image canvas.getOfflineGraphics().copyArea(order.srcX, order.srcY, order.width, order.height, order.x - order.srcX, order.y - order.srcY); // Request update of repainted area + canvas.updateFrameBuffer(order.x, order.y, order.width, order.height); canvas.repaint(order.x, order.y, order.width, order.height); + } private void handleBitmap(BitmapOrder order, ByteBuffer buf) { @@ -137,6 +138,7 @@ public class AwtCanvasAdapter extends BaseElement { g.drawImage(rectImage, x, y, null); // Request update of repainted area + canvas.updateFrameBuffer(x, y, width, height); canvas.repaint(x, y, width, height); } diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java index afde70698e3..a3db165c2fa 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/RdpClient.java @@ -63,6 +63,9 @@ import common.adapter.AwtCanvasAdapter; public class RdpClient extends PipelineImpl { + AwtMouseEventSource mouseEventSource = null; + AwtKeyEventSource keyEventSource = null; + /** * Name of last OneTimePacket in handshake sequence. */ @@ -333,8 +336,8 @@ public class RdpClient extends PipelineImpl { // Main network // - AwtMouseEventSource mouseEventSource = new AwtMouseEventSource("mouse"); - AwtKeyEventSource keyEventSource = new AwtKeyEventSource("keyboard"); + mouseEventSource = new AwtMouseEventSource("mouse"); + keyEventSource = new AwtKeyEventSource("keyboard"); // Subscribe packet sender to various events canvas.addMouseListener(mouseEventSource); @@ -390,4 +393,12 @@ public class RdpClient extends PipelineImpl { link("client_x224_data_queue", "client_tpkt_queue", "client_tpkt_queue< queue"); } + + public AwtMouseEventSource getMouseEventSource() { + return mouseEventSource; + } + + public AwtKeyEventSource getKeyEventSource() { + return keyEventSource; + } } diff --git a/services/console-proxy/server/pom.xml b/services/console-proxy/server/pom.xml index bc780a70fb5..5d0b3bc9565 100644 --- a/services/console-proxy/server/pom.xml +++ b/services/console-proxy/server/pom.xml @@ -44,6 +44,11 @@ cloud-utils ${project.version} + + rdpclient + cloudstack-service-console-proxy-rdpclient + ${project.version} + diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java index f889cdbf05b..02fda6424be 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxy.java @@ -196,8 +196,8 @@ public class ConsoleProxy { Object result; try { result = - authMethod.invoke(ConsoleProxy.context, param.getClientHostAddress(), String.valueOf(param.getClientHostPort()), param.getClientTag(), - param.getClientHostPassword(), param.getTicket(), new Boolean(reauthentication)); + authMethod.invoke(ConsoleProxy.context, param.getClientHostAddress(), String.valueOf(param.getClientHostPort()), param.getClientTag(), + param.getClientHostPassword(), param.getTicket(), new Boolean(reauthentication)); } catch (IllegalAccessException e) { s_logger.error("Unable to invoke authenticateConsoleAccess due to IllegalAccessException" + " for vm: " + param.getClientTag(), e); authResult.setSuccess(false); @@ -407,7 +407,7 @@ public class ConsoleProxy { synchronized (connectionMap) { viewer = connectionMap.get(clientKey); if (viewer == null) { - viewer = new ConsoleProxyVncClient(); + viewer = getClient(param); viewer.initClient(param); connectionMap.put(clientKey, viewer); s_logger.info("Added viewer object " + viewer); @@ -418,7 +418,7 @@ public class ConsoleProxy { viewer.initClient(param); } else if (!param.getClientHostPassword().equals(viewer.getClientHostPassword())) { s_logger.warn("Bad sid detected(VNC port may be reused). sid in session: " + viewer.getClientHostPassword() + ", sid in request: " + - param.getClientHostPassword()); + param.getClientHostPassword()); viewer.initClient(param); } } @@ -442,7 +442,7 @@ public class ConsoleProxy { ConsoleProxyClient viewer = connectionMap.get(clientKey); if (viewer == null) { authenticationExternally(param); - viewer = new ConsoleProxyVncClient(); + viewer = getClient(param); viewer.initClient(param); connectionMap.put(clientKey, viewer); @@ -457,7 +457,7 @@ public class ConsoleProxy { } if (param.getClientHostPassword() == null || param.getClientHostPassword().isEmpty() || - !param.getClientHostPassword().equals(viewer.getClientHostPassword())) + !param.getClientHostPassword().equals(viewer.getClientHostPassword())) throw new AuthenticationException("Cannot use the existing viewer " + viewer + ": bad sid"); if (!viewer.isFrontEndAlive()) { @@ -479,6 +479,14 @@ public class ConsoleProxy { } } + private static ConsoleProxyClient getClient(ConsoleProxyClientParam param) { + if (param.getHypervHost() != null) { + return new ConsoleProxyRdpClient(); + } else { + return new ConsoleProxyVncClient(); + } + } + public static void removeViewer(ConsoleProxyClient viewer) { synchronized (connectionMap) { for (Map.Entry entry : connectionMap.entrySet()) { diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java index 18d97d250af..fa0bd06c09e 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyAjaxHandler.java @@ -80,6 +80,9 @@ public class ConsoleProxyAjaxHandler implements HttpHandler { String console_url = queryMap.get("consoleurl"); String console_host_session = queryMap.get("sessionref"); String vm_locale = queryMap.get("locale"); + String hypervHost = queryMap.get("hypervHost"); + String username = queryMap.get("username"); + String password = queryMap.get("password"); if (tag == null) tag = ""; @@ -128,6 +131,9 @@ public class ConsoleProxyAjaxHandler implements HttpHandler { param.setClientTunnelUrl(console_url); param.setClientTunnelSession(console_host_session); param.setLocale(vm_locale); + param.setHypervHost(hypervHost); + param.setUsername(username); + param.setPassword(password); viewer = ConsoleProxy.getAjaxVncViewer(param, ajaxSessionIdStr); } catch (Exception e) { diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java index a04dd306960..e62ac4531b9 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyClientParam.java @@ -33,6 +33,10 @@ public class ConsoleProxyClientParam { private String locale; private String ajaxSessionId; + private String hypervHost; + private String username; + private String password; + public ConsoleProxyClientParam() { clientHostPort = 0; } @@ -94,7 +98,7 @@ public class ConsoleProxyClientParam { } public String getAjaxSessionId() { - return this.ajaxSessionId; + return ajaxSessionId; } public void setAjaxSessionId(String ajaxSessionId) { @@ -102,7 +106,7 @@ public class ConsoleProxyClientParam { } public String getLocale() { - return this.locale; + return locale; } public void setLocale(String locale) { @@ -115,4 +119,28 @@ public class ConsoleProxyClientParam { return clientHostAddress + ":" + clientHostPort; } + + public void setHypervHost(String hypervHost) { + this.hypervHost = hypervHost; + } + + public String getHypervHost() { + return hypervHost; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getPassword() { + return password; + } } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java index 7811d5030cf..51a703ae4b4 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyHttpHandlerHelper.java @@ -54,14 +54,29 @@ public class ConsoleProxyHttpHandlerHelper { // make sure we get information from token only guardUserInput(map); if (param != null) { - if (param.getClientHostAddress() != null) + if (param.getClientHostAddress() != null) { + s_logger.debug("decode token. host: " + param.getClientHostAddress()); map.put("host", param.getClientHostAddress()); - if (param.getClientHostPort() != 0) + } else { + s_logger.error("decode token. host info is not found!"); + } + if (param.getClientHostPort() != 0) { + s_logger.debug("decode token. port: " + param.getClientHostPort()); map.put("port", String.valueOf(param.getClientHostPort())); - if (param.getClientTag() != null) + } else { + s_logger.error("decode token. port info is not found!"); + } + if (param.getClientTag() != null) { + s_logger.debug("decode token. tag: " + param.getClientTag()); map.put("tag", param.getClientTag()); - if (param.getClientHostPassword() != null) + } else { + s_logger.error("decode token. tag info is not found!"); + } + if (param.getClientHostPassword() != null) { map.put("sid", param.getClientHostPassword()); + } else { + s_logger.error("decode token. sid info is not found!"); + } if (param.getClientTunnelUrl() != null) map.put("consoleurl", param.getClientTunnelUrl()); if (param.getClientTunnelSession() != null) @@ -70,6 +85,14 @@ public class ConsoleProxyHttpHandlerHelper { map.put("ticket", param.getTicket()); if (param.getLocale() != null) map.put("locale", param.getLocale()); + if (param.getHypervHost() != null) + map.put("hypervHost", param.getHypervHost()); + if (param.getUsername() != null) + map.put("username", param.getUsername()); + if (param.getPassword() != null) + map.put("password", param.getPassword()); + } else { + s_logger.error("Unable to decode token"); } } else { // we no longer accept information from parameter other than token @@ -88,5 +111,8 @@ public class ConsoleProxyHttpHandlerHelper { map.remove("sessionref"); map.remove("ticket"); map.remove("locale"); + map.remove("hypervHost"); + map.remove("username"); + map.remove("password"); } } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java new file mode 100644 index 00000000000..73c00be86d2 --- /dev/null +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java @@ -0,0 +1,318 @@ +// 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.consoleproxy; + +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.apache.log4j.Logger; + +import rdpclient.RdpClient; +import streamer.Pipeline; +import streamer.PipelineImpl; +import streamer.SocketWrapper; +import streamer.apr.AprSocketWrapperImpl; +import streamer.ssl.SSLState; + +import com.cloud.consoleproxy.rdp.KeysymToKeycode; +import com.cloud.consoleproxy.rdp.RdpBufferedImageCanvas; +import com.cloud.consoleproxy.vnc.FrameBufferCanvas; + +import common.AwtKeyEventSource; +import common.AwtMouseEventSource; +import common.ScreenDescription; +import common.SizeChangeListener; + +public class ConsoleProxyRdpClient extends ConsoleProxyClientBase { + + private static final Logger s_logger = Logger.getLogger(ConsoleProxyRdpClient.class); + + private static final int SHIFT_KEY_MASK = 64; + private static final int CTRL_KEY_MASK = 128; + private static final int META_KEY_MASK = 256; + private static final int ALT_KEY_MASK = 512; + + private RdpClient _client; + private ScreenDescription _screen; + private SocketWrapper _socket = null; + private RdpBufferedImageCanvas _canvas = null; + + private Thread _worker; + private volatile boolean _workerDone = false; + + private int _lastModifierStates = 0; + + private AwtMouseEventSource _mouseEventSource = null; + private AwtKeyEventSource _keyEventSource = null; + + public RdpBufferedImageCanvas getCanvas() { + return _canvas; + } + + public void setCanvas(RdpBufferedImageCanvas canvas) { + _canvas = canvas; + } + + @Override + public void onClientConnected() { + // TODO Auto-generated method stub + } + + @Override + public void onClientClose() { + s_logger.info("Received client close indication. remove viewer from map."); + ConsoleProxy.removeViewer(this); + } + + @Override + public boolean isHostConnected() { + //FIXME + return true; + } + + @Override + public boolean isFrontEndAlive() { + if (_socket != null) { + if (_workerDone || System.currentTimeMillis() - getClientLastFrontEndActivityTime() > ConsoleProxy.VIEWER_LINGER_SECONDS * 1000) { + s_logger.info("Front end has been idle for too long"); + _socket.shutdown(); + return false; + } else { + return true; + } + } else { + return false; + } + } + + @Override + public void sendClientRawKeyboardEvent(InputEventType event, int code, int modifiers) { + if (_client == null) + return; + + updateFrontEndActivityTime(); + + KeyEvent keyEvent = map(event, code, modifiers); + switch (event) { + case KEY_DOWN: + _keyEventSource.keyPressed(keyEvent); + break; + + case KEY_UP: + _keyEventSource.keyReleased(keyEvent); + break; + + case KEY_PRESS: + break; + + default: + assert (false); + break; + } + } + + private KeyEvent map(InputEventType event, int code, int modifiers) { + int keycode = KeysymToKeycode.getKeycode(code); + char keyChar = (char)keycode; + + KeyEvent keyEvent = null; + int modifier = mapModifier(modifiers); + + switch (event) { + case KEY_DOWN: + keyEvent = new KeyEvent(_canvas, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), modifier, keycode, keyChar); + break; + + case KEY_UP: + keyEvent = new KeyEvent(_canvas, KeyEvent.KEY_RELEASED, System.currentTimeMillis(), modifier, keycode, keyChar); + break; + + case KEY_PRESS: + break; + + default: + assert (false); + break; + } + return keyEvent; + } + + @Override + public void sendClientMouseEvent(InputEventType event, int x, int y, int code, int modifiers) { + if (_client == null) + return; + updateFrontEndActivityTime(); + + int mousecode = mapMouseButton(code); + int modifier = mapMouseModifier(code, modifiers); + + /*if (event == InputEventType.MOUSE_DOWN) { + _mouseEventSource.mousePressed(new MouseEvent(_canvas, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), modifier, x, y, 1, false, mousecode)); + } + + if (event == InputEventType.MOUSE_UP) { + _mouseEventSource.mouseReleased((new MouseEvent(_canvas, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), modifier, x, y, 1, false, mousecode))); + } + + if (event == InputEventType.MOUSE_DBLCLICK) { + _mouseEventSource.mouseReleased((new MouseEvent(_canvas, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), modifier, x, y, 2, false, mousecode))); + }*/ + } + + public int mapMouseModifier(int code, int modifiers) { + int mod = mapModifier(modifiers); + switch (code) { + case 0: + return mod = mod | MouseEvent.BUTTON1_DOWN_MASK; + case 2: + return mod = mod | MouseEvent.BUTTON3_DOWN_MASK; + default: + } + return mod; + } + + private int mapModifier(int modifiers) { + int mod = 0; + if ((modifiers & SHIFT_KEY_MASK) != (_lastModifierStates & SHIFT_KEY_MASK)) { + if ((modifiers & SHIFT_KEY_MASK) != 0) + mod = mod | InputEvent.SHIFT_DOWN_MASK; + } + + if ((modifiers & CTRL_KEY_MASK) != (_lastModifierStates & CTRL_KEY_MASK)) { + if ((modifiers & CTRL_KEY_MASK) != 0) + mod = mod | InputEvent.CTRL_DOWN_MASK; + } + + if ((modifiers & META_KEY_MASK) != (_lastModifierStates & META_KEY_MASK)) { + if ((modifiers & META_KEY_MASK) != 0) + mod = mod | InputEvent.META_DOWN_MASK; + } + + if ((modifiers & ALT_KEY_MASK) != (_lastModifierStates & ALT_KEY_MASK)) { + if ((modifiers & ALT_KEY_MASK) != 0) + mod = mod | InputEvent.ALT_DOWN_MASK; + } + _lastModifierStates = mod; + return mod; + } + + public int mapMouseButton(int code) { + switch (code) { + case 0: + return MouseEvent.BUTTON1; + case 2: + return MouseEvent.BUTTON3; + default: + return MouseEvent.BUTTON2; + } + + } + + @Override + public void initClient(final ConsoleProxyClientParam param) { + _workerDone = false; + + int canvasWidth = 1024; + int canvasHeight = 768; + setClientParam(param); + + final String host = param.getHypervHost(); + final String password = param.getPassword(); + final String instanceId = param.getClientHostAddress(); + final int port = param.getClientHostPort(); + + _screen = new ScreenDescription(); + _canvas = new RdpBufferedImageCanvas(this, canvasWidth, canvasHeight); + onFramebufferSizeChange(canvasWidth, canvasHeight); + + _screen.addSizeChangeListener(new SizeChangeListener() { + @Override + public void sizeChanged(int width, int height) { + if (_canvas != null) { + _canvas.setCanvasSize(width, height); + } + } + }); + + final SSLState sslState = new SSLState(); + + final String username = param.getUsername(); + String name = null; + String domain = null; + if (username.contains("\\")) { + String[] tokens = username.split("\\\\"); + name = tokens[1]; + domain = tokens[0]; + } else { + name = username; + domain = "Workgroup"; + } + + _client = new RdpClient("client", host, domain, name, password, instanceId, _screen, _canvas, + sslState); + + _mouseEventSource = _client.getMouseEventSource(); + _keyEventSource = _client.getKeyEventSource(); + + _worker = new Thread(new Runnable() { + @Override + public void run() { + _socket = new AprSocketWrapperImpl("socket", sslState); + Pipeline pipeline = new PipelineImpl("Client"); + pipeline.add(_socket, _client); + pipeline.link("socket", _client.getId(), "socket"); + pipeline.validate(); + + InetSocketAddress address = new InetSocketAddress(host, port); + ConsoleProxy.ensureRoute(host); + + try { + // Connect socket to remote server and run main loop(s) + _socket.connect(address); + } catch (IOException e) { + e.printStackTrace(); + } finally { + shutdown(); + } + + s_logger.info("Receiver thread stopped."); + _workerDone = true; + } + }); + _worker.setDaemon(true); + _worker.start(); + } + + @Override + public void closeClient() { + _workerDone = true; + shutdown(); + } + + @Override + protected FrameBufferCanvas getFrameBufferCavas() { + return _canvas; + } + + protected void shutdown() { + if (_socket != null) + _socket.shutdown(); + } +} diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java new file mode 100644 index 00000000000..10282ad0af3 --- /dev/null +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java @@ -0,0 +1,115 @@ +// 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.consoleproxy.rdp; + +import java.awt.event.KeyEvent; + +public class KeysymToKeycode { + + // this keymap is taken from http://openwonderland.googlecode.com/svn/trunk/modules/foundation/xremwin/src/classes/org/jdesktop/wonderland/modules/xremwin/client/KeycodeToKeysym.java + private final static int[][] map = { + /* XK_BackSpace */{0xFF08, KeyEvent.VK_BACK_SPACE}, + /* XK_Tab */{0xFF09, KeyEvent.VK_TAB}, + /* XK_Clear */{0xFF0B, KeyEvent.VK_CLEAR}, + /* XK_Return */{0xFF0D, KeyEvent.VK_ENTER}, + /* XK_Pause */{0xFF13, KeyEvent.VK_PAUSE}, + /* XK_Scroll_Lock */{0xFF14, KeyEvent.VK_SCROLL_LOCK}, + /* XK_Escape */{0xFF1B, KeyEvent.VK_ESCAPE}, + /* XK_Delete */{0xFFFF, KeyEvent.VK_DELETE}, + /* XK_Home */{0xFF50, KeyEvent.VK_HOME}, + /* XK_Left */{0xFF51, KeyEvent.VK_LEFT}, + /* XK_Up */{0xFF52, KeyEvent.VK_UP}, + /* XK_Right */{0xFF53, KeyEvent.VK_RIGHT}, + /* XK_Down */{0xFF54, KeyEvent.VK_DOWN}, + /* XK_Page_Up */{0xFF55, KeyEvent.VK_PAGE_UP}, + /* XK_Page_Down */{0xFF56, KeyEvent.VK_PAGE_DOWN}, + /* XK_End */{0xFF57, KeyEvent.VK_END}, + /* XK_Print */{0xFF61, KeyEvent.VK_PRINTSCREEN}, + /* XK_Insert */{0xFF63, KeyEvent.VK_INSERT}, + /* XK_Undo */{0xFF65, KeyEvent.VK_UNDO}, + /* XK_Find */{0xFF68, KeyEvent.VK_FIND}, + /* XK_Cancel */{0xFF69, KeyEvent.VK_CANCEL}, + /* XK_Help */{0xFF6A, KeyEvent.VK_HELP}, + /* XK_Mode_switch */{0xFF7E, KeyEvent.VK_MODECHANGE}, + /* XK_Num_Lock */{0xFF7F, KeyEvent.VK_NUM_LOCK}, + /* XK_F1 */{0xFFBE, KeyEvent.VK_F1}, + /* XK_F2 */{0xFFBF, KeyEvent.VK_F2}, + /* XK_F3 */{0xFFC0, KeyEvent.VK_F3}, + /* XK_F4 */{0xFFC1, KeyEvent.VK_F4}, + /* XK_F5 */{0xFFC2, KeyEvent.VK_F5}, + /* XK_F6 */{0xFFC3, KeyEvent.VK_F6}, + /* XK_F7 */{0xFFC4, KeyEvent.VK_F7}, + /* XK_F8 */{0xFFC5, KeyEvent.VK_F8}, + /* XK_F9 */{0xFFC6, KeyEvent.VK_F9}, + /* XK_F10 */{0xFFC7, KeyEvent.VK_F10}, + /* XK_F11 */{0xFFC8, KeyEvent.VK_F11}, + /* XK_F12 */{0xFFC9, KeyEvent.VK_F12}, + /* XK_F13 */{0xFFCA, KeyEvent.VK_F13}, + /* XK_F14 */{0xFFCB, KeyEvent.VK_F14}, + /* XK_F15 */{0xFFCC, KeyEvent.VK_F15}, + /* XK_F16 */{0xFFCD, KeyEvent.VK_F16}, + /* XK_F17 */{0xFFCE, KeyEvent.VK_F17}, + /* XK_F18 */{0xFFCF, KeyEvent.VK_F18}, + /* XK_F19 */{0xFFD0, KeyEvent.VK_F19}, + /* XK_F20 */{0xFFD1, KeyEvent.VK_F20}, + /* XK_F21 */{0xFFD2, KeyEvent.VK_F21}, + /* XK_F22 */{0xFFD3, KeyEvent.VK_F22}, + /* XK_F23 */{0xFFD4, KeyEvent.VK_F23}, + /* XK_F24 */{0xFFD5, KeyEvent.VK_F24}, + /* XK_Shift_L */{0xFFE1, KeyEvent.VK_SHIFT}, + /* XK_Control_L */{0xFFE3, KeyEvent.VK_CONTROL}, + /* XK_Caps_Lock */{0xFFE5, KeyEvent.VK_CAPS_LOCK}, + /* XK_Meta_L */{0xFFE7, KeyEvent.VK_META}, + /* XK_Alt_L */{0xFFE9, KeyEvent.VK_ALT}, + /* XK_a */{0x0061, KeyEvent.VK_A}, + /* XK_b */{0x0062, KeyEvent.VK_B}, + /* XK_c */{0x0063, KeyEvent.VK_C}, + /* XK_d */{0x0064, KeyEvent.VK_D}, + /* XK_e */{0x0065, KeyEvent.VK_E}, + /* XK_f */{0x0066, KeyEvent.VK_F}, + /* XK_g */{0x0067, KeyEvent.VK_G}, + /* XK_h */{0x0068, KeyEvent.VK_H}, + /* XK_i */{0x0069, KeyEvent.VK_I}, + /* XK_j */{0x006a, KeyEvent.VK_J}, + /* XK_k */{0x006b, KeyEvent.VK_K}, + /* XK_l */{0x006c, KeyEvent.VK_L}, + /* XK_m */{0x006d, KeyEvent.VK_M}, + /* XK_n */{0x006e, KeyEvent.VK_N}, + /* XK_o */{0x006f, KeyEvent.VK_O}, + /* XK_p */{0x0070, KeyEvent.VK_P}, + /* XK_q */{0x0071, KeyEvent.VK_Q}, + /* XK_r */{0x0072, KeyEvent.VK_R}, + /* XK_s */{0x0073, KeyEvent.VK_S}, + /* XK_t */{0x0074, KeyEvent.VK_T}, + /* XK_u */{0x0075, KeyEvent.VK_U}, + /* XK_v */{0x0076, KeyEvent.VK_V}, + /* XK_w */{0x0077, KeyEvent.VK_W}, + /* XK_x */{0x0078, KeyEvent.VK_X}, + /* XK_y */{0x0079, KeyEvent.VK_Y}, + /* XK_z */{0x007a, KeyEvent.VK_Z}, + }; + + public static int getKeycode(int keysym) { + for (int i = 0; i < (map.length - 1); i++) { + if (map[i][0] == keysym) { + return map[i][1]; + } + } + return keysym; + } + +} diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java new file mode 100644 index 00000000000..6dabe056ac4 --- /dev/null +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java @@ -0,0 +1,103 @@ +// 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.consoleproxy.rdp; + +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.List; + +import com.cloud.consoleproxy.ConsoleProxyRdpClient; +import com.cloud.consoleproxy.util.ImageHelper; +import com.cloud.consoleproxy.util.TileInfo; +import com.cloud.consoleproxy.vnc.FrameBufferCanvas; + +import common.BufferedImageCanvas; + +public class RdpBufferedImageCanvas extends BufferedImageCanvas implements FrameBufferCanvas { + /** + * + */ + private static final long serialVersionUID = 1L; + + private final ConsoleProxyRdpClient _rdpClient; + + public RdpBufferedImageCanvas(ConsoleProxyRdpClient client, int width, int height) { + super(width, height); + _rdpClient = client; + } + + @Override + public Image getFrameBufferScaledImage(int width, int height) { + if (offlineImage != null) + return offlineImage.getScaledInstance(width, height, Image.SCALE_DEFAULT); + return null; + } + + @Override + public byte[] getFrameBufferJpeg() { + int width = offlineImage.getWidth(); + int height = offlineImage.getHeight(); + + BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = bufferedImage.createGraphics(); + synchronized (offlineImage) { + g.drawImage(offlineImage, 0, 0, width, height, 0, 0, width, height, null); + g.dispose(); + } + + byte[] imgBits = null; + try { + imgBits = ImageHelper.jpegFromImage(bufferedImage); + } catch (IOException e) { + } + + return imgBits; + } + + @Override + public byte[] getTilesMergedJpeg(List tileList, int tileWidth, int tileHeight) { + int width = Math.max(tileWidth, tileWidth * tileList.size()); + + BufferedImage bufferedImage = new BufferedImage(width, tileHeight, BufferedImage.TYPE_3BYTE_BGR); + Graphics2D g = bufferedImage.createGraphics(); + + synchronized (offlineImage) { + int i = 0; + for (TileInfo tile : tileList) { + Rectangle rc = tile.getTileRect(); + g.drawImage(offlineImage, i * tileWidth, 0, i * tileWidth + rc.width, rc.height, rc.x, rc.y, rc.x + rc.width, rc.y + rc.height, null); + i++; + } + } + + byte[] imgBits = null; + try { + imgBits = ImageHelper.jpegFromImage(bufferedImage); + } catch (IOException e) { + } + return imgBits; + } + + @Override + public void updateFrameBuffer(int x, int y, int w, int h) { + _rdpClient.onFramebufferUpdate(x, y, w, h); + } + +} From 3e2f7dda9eee384e85e7b2bc3cecc91b233b0bf2 Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Wed, 1 Jan 2014 12:16:23 +0530 Subject: [PATCH 005/126] CLOUDSTACK-5702: Fixed mouse doesn't work for console --- .../consoleproxy/ConsoleProxyRdpClient.java | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java index 73c00be86d2..6b317ffc66a 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java @@ -161,22 +161,23 @@ public class ConsoleProxyRdpClient extends ConsoleProxyClientBase { updateFrontEndActivityTime(); int mousecode = mapMouseButton(code); - int modifier = mapMouseModifier(code, modifiers); - /*if (event == InputEventType.MOUSE_DOWN) { - _mouseEventSource.mousePressed(new MouseEvent(_canvas, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), modifier, x, y, 1, false, mousecode)); + if (event == InputEventType.MOUSE_DOWN) { + _mouseEventSource.mousePressed(new MouseEvent(_canvas, MouseEvent.MOUSE_PRESSED, System.currentTimeMillis(), mapMouseDownModifier(code, modifiers), x, y, 1, false, + mousecode)); } if (event == InputEventType.MOUSE_UP) { - _mouseEventSource.mouseReleased((new MouseEvent(_canvas, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), modifier, x, y, 1, false, mousecode))); + _mouseEventSource.mouseReleased((new MouseEvent(_canvas, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), mapMouseUpModifier(code, modifiers), x, y, 1, false, + mousecode))); } - if (event == InputEventType.MOUSE_DBLCLICK) { - _mouseEventSource.mouseReleased((new MouseEvent(_canvas, MouseEvent.MOUSE_RELEASED, System.currentTimeMillis(), modifier, x, y, 2, false, mousecode))); - }*/ + if (event == InputEventType.MOUSE_MOVE) { + _mouseEventSource.mouseMoved(new MouseEvent(_canvas, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(), mapModifier(modifiers), x, y, 0, false)); + } } - public int mapMouseModifier(int code, int modifiers) { + public int mapMouseDownModifier(int code, int modifiers) { int mod = mapModifier(modifiers); switch (code) { case 0: @@ -188,6 +189,18 @@ public class ConsoleProxyRdpClient extends ConsoleProxyClientBase { return mod; } + public int mapMouseUpModifier(int code, int modifiers) { + int mod = mapModifier(modifiers); + switch (code) { + case 0: + return mod = mod | MouseEvent.BUTTON1_MASK; + case 2: + return mod = mod | MouseEvent.BUTTON3_MASK; + default: + } + return mod; + } + private int mapModifier(int modifiers) { int mod = 0; if ((modifiers & SHIFT_KEY_MASK) != (_lastModifierStates & SHIFT_KEY_MASK)) { From b2de225f54f80e48598c9327d19c276186682299 Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Wed, 1 Jan 2014 14:15:31 +0530 Subject: [PATCH 006/126] CLOUDSTACK-5703: putting rdp server port value in host details --- .../HypervResource/HypervResourceController.cs | 1 + .../src/com/cloud/servlet/ConsoleProxyServlet.java | 13 +++++-------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index 6daadeefaac..76336e996cc 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -1921,6 +1921,7 @@ namespace HypervResource string productVersion = System.Environment.OSVersion.Version.Major.ToString() + "." + System.Environment.OSVersion.Version.Minor.ToString(); details.Add("product_version", productVersion); + details.Add("rdp.server.port", 2179); } // Detect CPUs, speed, memory diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index 5edd95d8dbd..a6b179a6ddc 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -395,25 +395,22 @@ public class ConsoleProxyServlet extends HttpServlet { private String composeConsoleAccessUrl(String rootUrl, VirtualMachine vm, HostVO hostVo) { StringBuffer sb = new StringBuffer(rootUrl); String host = hostVo.getPrivateIpAddress(); - String username = _ms.findDetail(hostVo.getId(), "username").getValue(); - String password = _ms.findDetail(hostVo.getId(), "password").getValue(); Pair portInfo = _ms.getVncPort(vm); if (s_logger.isDebugEnabled()) s_logger.debug("Port info " + portInfo.first()); Ternary parsedHostInfo = parseHostInfo(portInfo.first()); + int port = -1; - String sid; - if (portInfo.second() == -9) { //for hyperv - port = 2179; + port = Integer.parseInt(_ms.findDetail(hostVo.getId(), "rdp.server.port").getValue()); } else { port = portInfo.second(); } - sid = vm.getVncPassword(); + String sid = vm.getVncPassword(); UserVmDetailVO details = _userVmDetailsDao.findDetail(vm.getId(), "keyboard"); String tag = vm.getUuid(); @@ -434,8 +431,8 @@ public class ConsoleProxyServlet extends HttpServlet { if (portInfo.second() == -9) { //For Hyperv Clinet Host Address will send Instance id param.setHypervHost(host); - param.setUsername(username); - param.setPassword(password); + param.setUsername(_ms.findDetail(hostVo.getId(), "username").getValue()); + param.setPassword(_ms.findDetail(hostVo.getId(), "password").getValue()); } if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) { param.setClientTunnelUrl(parsedHostInfo.second()); From 513f1dba36d0d66acd973ebec3126dc48b4a0042 Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Wed, 1 Jan 2014 14:42:19 +0530 Subject: [PATCH 007/126] CLOUDSTACK-5705: fixed the thumbnail not wrking for hyperv --- .../com/cloud/servlet/ConsoleProxyServlet.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/servlet/ConsoleProxyServlet.java b/server/src/com/cloud/servlet/ConsoleProxyServlet.java index a6b179a6ddc..6a5c6a9060d 100644 --- a/server/src/com/cloud/servlet/ConsoleProxyServlet.java +++ b/server/src/com/cloud/servlet/ConsoleProxyServlet.java @@ -369,7 +369,16 @@ public class ConsoleProxyServlet extends HttpServlet { String sid = vm.getVncPassword(); String tag = vm.getUuid(); - String ticket = genAccessTicket(host, String.valueOf(portInfo.second()), sid, tag); + + int port = -1; + if (portInfo.second() == -9) { + //for hyperv + port = Integer.parseInt(_ms.findDetail(hostVo.getId(), "rdp.server.port").getValue()); + } else { + port = portInfo.second(); + } + + String ticket = genAccessTicket(parsedHostInfo.first(), String.valueOf(port), sid, tag); ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(getEncryptorPassword()); ConsoleProxyClientParam param = new ConsoleProxyClientParam(); @@ -378,6 +387,12 @@ public class ConsoleProxyServlet extends HttpServlet { param.setClientHostPassword(sid); param.setClientTag(tag); param.setTicket(ticket); + if (portInfo.second() == -9) { + //For Hyperv Clinet Host Address will send Instance id + param.setHypervHost(host); + param.setUsername(_ms.findDetail(hostVo.getId(), "username").getValue()); + param.setPassword(_ms.findDetail(hostVo.getId(), "password").getValue()); + } if (parsedHostInfo.second() != null && parsedHostInfo.third() != null) { param.setClientTunnelUrl(parsedHostInfo.second()); param.setClientTunnelSession(parsedHostInfo.third()); From 6ebbec239d15f64d07d6e9cc90e6bbdd43046c78 Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Fri, 3 Jan 2014 17:03:36 +0530 Subject: [PATCH 008/126] CLOUDSTACK-5716: fixed can't type special character in console view --- .../adapter/AwtRdpKeyboardAdapter.java | 2 +- .../consoleproxy/ConsoleProxyRdpClient.java | 29 +++++++------------ .../consoleproxy/rdp/KeysymToKeycode.java | 27 +++++++++++++++-- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java index f2b19e1af49..2d1e8fca6c3 100755 --- a/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java +++ b/services/console-proxy-rdp/rdpconsole/src/main/java/rdpclient/adapter/AwtRdpKeyboardAdapter.java @@ -343,7 +343,7 @@ public class AwtRdpKeyboardAdapter extends BaseElement { default: System.err.println("Key is not mapped: " + event + "."); - return 57; // Space + return event.getKeyCode(); } } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java index 6b317ffc66a..d5a3fcd3639 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/ConsoleProxyRdpClient.java @@ -57,8 +57,6 @@ public class ConsoleProxyRdpClient extends ConsoleProxyClientBase { private Thread _worker; private volatile boolean _workerDone = false; - private int _lastModifierStates = 0; - private AwtMouseEventSource _mouseEventSource = null; private AwtKeyEventSource _keyEventSource = null; @@ -203,26 +201,19 @@ public class ConsoleProxyRdpClient extends ConsoleProxyClientBase { private int mapModifier(int modifiers) { int mod = 0; - if ((modifiers & SHIFT_KEY_MASK) != (_lastModifierStates & SHIFT_KEY_MASK)) { - if ((modifiers & SHIFT_KEY_MASK) != 0) - mod = mod | InputEvent.SHIFT_DOWN_MASK; - } - if ((modifiers & CTRL_KEY_MASK) != (_lastModifierStates & CTRL_KEY_MASK)) { - if ((modifiers & CTRL_KEY_MASK) != 0) - mod = mod | InputEvent.CTRL_DOWN_MASK; - } + if ((modifiers & SHIFT_KEY_MASK) != 0) + mod = mod | InputEvent.SHIFT_DOWN_MASK; - if ((modifiers & META_KEY_MASK) != (_lastModifierStates & META_KEY_MASK)) { - if ((modifiers & META_KEY_MASK) != 0) - mod = mod | InputEvent.META_DOWN_MASK; - } + if ((modifiers & CTRL_KEY_MASK) != 0) + mod = mod | InputEvent.CTRL_DOWN_MASK; + + if ((modifiers & META_KEY_MASK) != 0) + mod = mod | InputEvent.META_DOWN_MASK; + + if ((modifiers & ALT_KEY_MASK) != 0) + mod = mod | InputEvent.ALT_DOWN_MASK; - if ((modifiers & ALT_KEY_MASK) != (_lastModifierStates & ALT_KEY_MASK)) { - if ((modifiers & ALT_KEY_MASK) != 0) - mod = mod | InputEvent.ALT_DOWN_MASK; - } - _lastModifierStates = mod; return mod; } diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java index 10282ad0af3..f13dfe6c419 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/KeysymToKeycode.java @@ -20,7 +20,7 @@ import java.awt.event.KeyEvent; public class KeysymToKeycode { - // this keymap is taken from http://openwonderland.googlecode.com/svn/trunk/modules/foundation/xremwin/src/classes/org/jdesktop/wonderland/modules/xremwin/client/KeycodeToKeysym.java + // some of this keymap is taken from http://openwonderland.googlecode.com/svn/trunk/modules/foundation/xremwin/src/classes/org/jdesktop/wonderland/modules/xremwin/client/KeycodeToKeysym.java private final static int[][] map = { /* XK_BackSpace */{0xFF08, KeyEvent.VK_BACK_SPACE}, /* XK_Tab */{0xFF09, KeyEvent.VK_TAB}, @@ -101,10 +101,33 @@ public class KeysymToKeycode { /* XK_x */{0x0078, KeyEvent.VK_X}, /* XK_y */{0x0079, KeyEvent.VK_Y}, /* XK_z */{0x007a, KeyEvent.VK_Z}, + {0x0060, KeyEvent.VK_BACK_QUOTE}, + {0x007e, KeyEvent.VK_BACK_QUOTE}, + {0x0021, KeyEvent.VK_1}, + {0x0040, KeyEvent.VK_2}, + {0x0023, KeyEvent.VK_3}, + {0x0024, KeyEvent.VK_4}, + {0x0025, KeyEvent.VK_5}, + {0x005e, KeyEvent.VK_6}, + {0x0026, KeyEvent.VK_7}, + {0x002A, KeyEvent.VK_8}, + {0x0028, KeyEvent.VK_9}, + {0x0029, KeyEvent.VK_0}, + {0x005f, KeyEvent.VK_MINUS}, + {0x002b, KeyEvent.VK_EQUALS}, + {0x007b, KeyEvent.VK_OPEN_BRACKET}, + {0x007d, KeyEvent.VK_CLOSE_BRACKET}, + {0x007c, KeyEvent.VK_BACK_SLASH}, + {0x003a, KeyEvent.VK_SEMICOLON}, + {0x0027, KeyEvent.VK_QUOTE}, + {0x0022, KeyEvent.VK_QUOTE}, + {0x003c, KeyEvent.VK_COMMA}, + {0x003e, KeyEvent.VK_PERIOD}, + {0x003f, KeyEvent.VK_SLASH}, }; public static int getKeycode(int keysym) { - for (int i = 0; i < (map.length - 1); i++) { + for (int i = 0; i < (map.length); i++) { if (map[i][0] == keysym) { return map[i][1]; } From 62ef61794d5944bd4ff618eba299ee2b525394dc Mon Sep 17 00:00:00 2001 From: Anshul Gangwar Date: Wed, 22 Jan 2014 12:16:59 +0530 Subject: [PATCH 009/126] Fixed check style error --- .../src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java index 6dabe056ac4..4214574a7e5 100644 --- a/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java +++ b/services/console-proxy/server/src/com/cloud/consoleproxy/rdp/RdpBufferedImageCanvas.java @@ -32,7 +32,7 @@ import common.BufferedImageCanvas; public class RdpBufferedImageCanvas extends BufferedImageCanvas implements FrameBufferCanvas { /** - * + * */ private static final long serialVersionUID = 1L; From d19157fbb169eec029d1efee9ddd06e6b6aad9a4 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 23 Jan 2014 07:59:43 +0100 Subject: [PATCH 010/126] Fix a bug found by findbug, compare Long objects with equals instead of == --- utils/src/com/cloud/utils/net/NetUtils.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index 8e994f1baec..f64b2302a5b 100755 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -41,13 +41,14 @@ import org.apache.commons.lang.SystemUtils; import org.apache.commons.net.util.SubnetUtils; import org.apache.log4j.Logger; -import com.cloud.utils.IteratorUtil; -import com.cloud.utils.Pair; -import com.cloud.utils.script.Script; import com.googlecode.ipv6.IPv6Address; import com.googlecode.ipv6.IPv6AddressRange; import com.googlecode.ipv6.IPv6Network; +import com.cloud.utils.IteratorUtil; +import com.cloud.utils.Pair; +import com.cloud.utils.script.Script; + public class NetUtils { protected final static Logger s_logger = Logger.getLogger(NetUtils.class); public final static String HTTP_PORT = "80"; @@ -832,7 +833,7 @@ public class NetUtils { if (cidrALong[1] < cidrBLong[1]) { //this implies cidrA is super set of cidrB return supersetOrSubset.isSuperset; - } else if (cidrALong[1] == cidrBLong[1]) { + } else if (cidrALong[1].equals(cidrBLong[1])) { //this implies both the cidrs are equal return supersetOrSubset.sameSubnet; } @@ -1209,7 +1210,7 @@ public class NetUtils { public static boolean isValidIpv6(String ip) { try { - IPv6Address address = IPv6Address.fromString(ip); + IPv6Address.fromString(ip); } catch (IllegalArgumentException ex) { return false; } @@ -1218,7 +1219,7 @@ public class NetUtils { public static boolean isValidIp6Cidr(String ip6Cidr) { try { - IPv6Network network = IPv6Network.fromString(ip6Cidr); + IPv6Network.fromString(ip6Cidr); } catch (IllegalArgumentException ex) { return false; } From 9d735dd28828cd87489e5e10d0db6d68ed0287f9 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 23 Jan 2014 09:03:22 +0100 Subject: [PATCH 011/126] Add a profile that enables findbugs checks at build time. Use -Penablefindbugs to enable findbugs. Add a bit of reporting configuration so the mvn site target includes javadoc and a findbugs report --- pom.xml | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/pom.xml b/pom.xml index 8fd1f54219c..8d8426186fb 100644 --- a/pom.xml +++ b/pom.xml @@ -469,6 +469,19 @@ + + org.codehaus.mojo + findbugs-maven-plugin + + + cloudstack-findbugs + none + + check + + + + @@ -577,6 +590,15 @@ + + org.apache.maven.plugins + maven-site-plugin + 3.3 + + 9000 + ${basedir}/target/site/tempdir + + @@ -840,9 +862,44 @@ + + org.codehaus.mojo + findbugs-maven-plugin + 2.5.3 + + Max + High + true + false + + + + cloudstack-findbugs + + check + + + + + + + + org.codehaus.mojo + findbugs-maven-plugin + + Low + Default + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + awsapi @@ -916,5 +973,23 @@ + + enablefindbugs + + + + org.codehaus.mojo + findbugs-maven-plugin + + + cloudstack-findbugs + process-classes + true + + + + + + From c2da2803476d55e814ec0d849482bd07c4f9f8f1 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 23 Jan 2014 09:06:00 +0100 Subject: [PATCH 012/126] Add a zipped version of the hyperv image that we can store in the archives on the jenkins server --- .../storage/motion/XenServerStorageMotionStrategy.java | 8 ++++---- tools/appliance/build.sh | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java index f2bf47262ca..e8217f7216f 100644 --- a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java +++ b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java @@ -106,7 +106,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { try { VMInstanceVO instance = instanceDao.findById(vmTo.getId()); if (instance != null) { - if (srcHost.getClusterId() == destHost.getClusterId()) { + if (srcHost.getClusterId().equals(destHost.getClusterId())) { answer = migrateVmWithVolumesWithinCluster(instance, vmTo, srcHost, destHost, volumeMap); } else { answer = migrateVmWithVolumesAcrossCluster(instance, vmTo, srcHost, destHost, volumeMap); @@ -126,7 +126,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { @@ -153,7 +153,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } MigrateWithStorageSendCommand sendCmd = - new MigrateWithStorageSendCommand(to, receiveAnswer.getVolumeToSr(), receiveAnswer.getNicToNetwork(), receiveAnswer.getToken()); + new MigrateWithStorageSendCommand(to, receiveAnswer.getVolumeToSr(), receiveAnswer.getNicToNetwork(), receiveAnswer.getToken()); MigrateWithStorageSendAnswer sendAnswer = (MigrateWithStorageSendAnswer)agentMgr.send(srcHost.getId(), sendCmd); if (sendAnswer == null) { s_logger.error("Migration with storage of vm " + vm + " to host " + destHost + " failed."); @@ -184,7 +184,7 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesWithinCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { diff --git a/tools/appliance/build.sh b/tools/appliance/build.sh index ddcaec9e43c..2e8bc88d903 100644 --- a/tools/appliance/build.sh +++ b/tools/appliance/build.sh @@ -101,9 +101,9 @@ echo "$appliance exported for VMWare: dist/$appliance-$build_date-$branch-vmware # Export for HyperV vboxmanage clonehd $hdd_uuid $appliance-$build_date-$branch-hyperv.vhd --format VHD -# HyperV doesn't support import a zipped image from S3 -#bzip2 $appliance-$build_date-$branch-hyperv.vhd +# HyperV doesn't support import a zipped image from S3, but we create a zipped version to save space on the jenkins box +zip $appliance-$build_date-$branch-hyperv.vhd.zip $appliance-$build_date-$branch-hyperv.vhd echo "$appliance exported for HyperV: dist/$appliance-$build_date-$branch-hyperv.vhd" -mv *-hyperv.vhd *.bz2 *.ova dist/ +mv *-hyperv.vhd *-hyperv.vhd.zip *.bz2 *.ova dist/ From 538092b73e3fc3a87087c2d0e1890c2bea379519 Mon Sep 17 00:00:00 2001 From: Devdeep Singh Date: Thu, 23 Jan 2014 19:00:27 +0530 Subject: [PATCH 013/126] Hyper-V agent should log to the event viewer. Changed the default log appender for the agent. --- .../ServerResource/AgentShell/AgentService.Designer.cs | 2 +- .../hyperv/DotNet/ServerResource/AgentShell/App.config | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs index 854427732aa..4bf424fa4b9 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/AgentService.Designer.cs @@ -45,7 +45,7 @@ namespace CloudStack.Plugin.AgentShell private void InitializeComponent() { components = new System.ComponentModel.Container(); - this.ServiceName = "CloudStack ServerResource"; + this.ServiceName = Program.serviceName; } #endregion diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config index 68ab80ee555..b783dfecd63 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config @@ -10,9 +10,9 @@ - + - + @@ -25,13 +25,14 @@ + - + From f999a01837e60f0c51ef0eb4ad19c29e43ca3037 Mon Sep 17 00:00:00 2001 From: Santhosh Edukulla Date: Thu, 23 Jan 2014 17:24:43 +0530 Subject: [PATCH 014/126] Added Fix for CLOUDSTACK-5875 Added fix for exception and listing. Mentioned details under bug. Post the fix, simulator works fine. Signed-off-by: Santhosh Edukulla Signed-off-by: Koushik Das --- .../src/com/cloud/agent/manager/MockAgentManagerImpl.java | 7 +++++++ setup/db/templates.simulator.sql | 8 ++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java index 85f7e856f80..0eeef82c055 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockAgentManagerImpl.java @@ -32,6 +32,8 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.user.AccountManager; +import org.apache.cloudstack.context.CallContext; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -87,6 +89,7 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage MockStorageManager _storageMgr = null; @Inject ResourceManager _resourceMgr; + @Inject private AccountManager _accountMgr; SimulatorSecondaryDiscoverer discoverer; @Inject @@ -303,8 +306,10 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage @Override @DB public void run() { + CallContext.register(_accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); if (this.mode.equalsIgnoreCase("Stop")) { handleSystemVMStop(); + CallContext.unregister(); return; } @@ -359,10 +364,12 @@ public class MockAgentManagerImpl extends ManagerBase implements MockAgentManage _resourceMgr.discoverHosts(cmd); } catch (DiscoveryException e) { s_logger.debug("Failed to discover host: " + e.toString()); + CallContext.unregister(); return; } } catch (ConfigurationException e) { s_logger.debug("Failed to load secondary storage resource: " + e.toString()); + CallContext.unregister(); return; } } diff --git a/setup/db/templates.simulator.sql b/setup/db/templates.simulator.sql index 5f9b67d1f7e..25e91bd9c5f 100755 --- a/setup/db/templates.simulator.sql +++ b/setup/db/templates.simulator.sql @@ -16,7 +16,7 @@ -- under the License. -INSERT INTO `cloud`.`vm_template` (id, uuid, 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 (100, UUID(), 'simulator-domR', 'SystemVM Template (simulator)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/routing/debian/latest/systemvm.vhd.bz2', '', 0, 'SystemVM Template (simulator)', 'VHD', 15, 0, 1, 'Simulator'); -INSERT INTO `cloud`.`vm_template` (id, uuid, 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 (111, UUID(), 'simulator-Centos', 'CentOS 5.3(64-bit) no GUI (Simulator)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/centos53-x86_64/latest/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', '', 0, 'CentOS 5.3(64-bit) no GUI (Simulator)', 'VHD', 11, 1, 1, 'Simulator'); +INSERT INTO `cloud`.`vm_template` (id, uuid, 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, state) + VALUES (100, UUID(), 'simulator-domR', 'SystemVM Template (simulator)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/routing/debian/latest/systemvm.vhd.bz2', '', 0, 'SystemVM Template (simulator)', 'VHD', 15, 0, 1, 'Simulator','Active'); +INSERT INTO `cloud`.`vm_template` (id, uuid, 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,state) + VALUES (111, UUID(), 'simulator-Centos', 'CentOS 5.3(64-bit) no GUI (Simulator)', 1, now(), 'BUILTIN', 0, 64, 1, 'http://nfs1.lab.vmops.com/templates/centos53-x86_64/latest/f59f18fb-ae94-4f97-afd2-f84755767aca.vhd.bz2', '', 0, 'CentOS 5.3(64-bit) no GUI (Simulator)', 'VHD', 11, 1, 1, 'Simulator','Active'); From 4b3784a98e57bc22bc0a8dd53462d452c322cb8c Mon Sep 17 00:00:00 2001 From: Jayapal Date: Thu, 23 Jan 2014 16:33:37 +0530 Subject: [PATCH 015/126] CLOUDSTACK-5938 Failing add host in security group enabled zone, when CSP is not installed --- .../cloud/hypervisor/xen/resource/CitrixResourceBase.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index ed9eec1dda3..853fd42c408 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -4986,6 +4986,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (_securityGroupEnabled) { _canBridgeFirewall = can_bridge_firewall(conn); + if (!_canBridgeFirewall) { + String msg = "Failed to configure brige firewall"; + s_logger.warn(msg); + s_logger.warn("Check host " + _host.ip +" for CSP is installed or not and check network mode for bridge"); + return new SetupAnswer(cmd, msg); + } + } String result = callHostPluginPremium(conn, "heartbeat", "host", _host.uuid, "interval", Integer.toString(_heartbeatInterval)); From 4925b9f6a126454215531998c461bf376ac6ab67 Mon Sep 17 00:00:00 2001 From: Damodar Reddy Date: Thu, 23 Jan 2014 17:35:37 +0530 Subject: [PATCH 016/126] CLOUDSTACK-2031:support for number of ips per nic limit needs to be added for the multiple ip address per nic --- .../api/command/user/vm/AddIpToVmNicCmd.java | 2 +- .../src/com/cloud/vm/dao/NicSecondaryIpDao.java | 2 ++ .../src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java | 13 +++++++++++++ server/src/com/cloud/configuration/Config.java | 4 ++++ .../src/com/cloud/network/NetworkServiceImpl.java | 8 ++++++++ setup/db/db/schema-430to440.sql | 2 +- 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java index c0e8d3e16a6..439879add9b 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vm/AddIpToVmNicCmd.java @@ -130,7 +130,7 @@ public class AddIpToVmNicCmd extends BaseAsyncCmd { try { result = _networkService.allocateSecondaryGuestIP(getNicId(), getIpaddress()); } catch (InsufficientAddressCapacityException e) { - throw new InvalidParameterValueException("Allocating guest ip for nic failed"); + throw new InvalidParameterValueException("Allocating guest ip for nic failed : " + e.getMessage()); } if (result != null) { diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java index 9fbfa279089..39b8470b8c2 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java +++ b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDao.java @@ -51,4 +51,6 @@ public interface NicSecondaryIpDao extends GenericDao { NicSecondaryIpVO findByIp4AddressAndNetworkIdAndInstanceId(long networkId, Long vmId, String vmIp); List getSecondaryIpAddressesForNic(long nicId); + + Long countByNicId(long nicId); } diff --git a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java index 2f3cc290b40..29af0198b47 100644 --- a/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/NicSecondaryIpDaoImpl.java @@ -35,6 +35,7 @@ import com.cloud.utils.db.SearchCriteria.Op; public class NicSecondaryIpDaoImpl extends GenericDaoBase implements NicSecondaryIpDao { private final SearchBuilder AllFieldsSearch; private final GenericSearchBuilder IpSearch; + protected GenericSearchBuilder CountByNicId; protected NicSecondaryIpDaoImpl() { super(); @@ -50,6 +51,11 @@ public class NicSecondaryIpDaoImpl extends GenericDaoBase sc = CountByNicId.create(); + sc.setParameters("nic", nicId); + return customSearch(sc, null).get(0); + } } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 9117bc45e9d..6ba67749aef 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -402,6 +402,10 @@ public enum Config { "10", "The maximum number of subnets per customer gateway", null), + MaxNumberOfSecondaryIPsPerNIC( + "Network", ManagementServer.class, Integer.class, + "vm.network.nic.max.secondary.ipaddresses", "256", + "Specify the number of secondary ip addresses per nic per vm", null), // Console Proxy ConsoleProxyCapacityStandby( diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 056190f1c4a..399f08681d1 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -669,6 +669,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Invalid network id is given"); } + int maxAllowedIpsPerNic = NumbersUtil.parseInt(_configDao.getValue(Config.MaxNumberOfSecondaryIPsPerNIC.key()), 10); + Long nicWiseIpCount = _nicSecondaryIpDao.countByNicId(nicId); + if(nicWiseIpCount.intValue() >= maxAllowedIpsPerNic) { + s_logger.error("Maximum Number of Ips \"vm.network.nic.max.secondary.ipaddresses = \"" + maxAllowedIpsPerNic + " per Nic has been crossed for the nic " + nicId + "."); + throw new InsufficientAddressCapacityException("Maximum Number of Ips per Nic has been crossed.", Nic.class, nicId); + } + + s_logger.debug("Calling the ip allocation ..."); String ipaddr = null; //Isolated network can exist in Basic zone only, so no need to verify the zone type diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index 1b6a9ab420f..0ce92023811 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -443,4 +443,4 @@ CREATE VIEW `cloud`.`user_vm_view` AS left join `cloud`.`user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_ram_size`.`name` = 'memory'))); - +INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('NetworkManager', 'DEFAULT', 'management-server', 'vm.network.nic.max.secondary.ipaddresses', NULL, 'Specify the number of secondary ip addresses per nic per vm', '256') ON DUPLICATE KEY UPDATE category='NetworkManager'; \ No newline at end of file From c53778c33306f4a87387b932d9d9a9cb6069bdd5 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Thu, 23 Jan 2014 18:13:45 +0530 Subject: [PATCH 017/126] CLOUDSTACK-5810 updated null checks and preparestmt and resultset close Closing the prepare statement and result set and assigning null to the object after close. --- .../cloud/upgrade/dao/Upgrade430to440.java | 78 +++++++------------ 1 file changed, 28 insertions(+), 50 deletions(-) diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java index 052c56cda02..3b967e79dc5 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade430to440.java @@ -126,43 +126,17 @@ public class Upgrade430to440 implements DbUpgrade { } } - - - if (networkRs != null) { - try { - networkRs.close(); - } catch (SQLException e) { - } - } - - - if (pstmtNw != null) { - try { - pstmtNw.close(); - - } catch (SQLException e) { - } - } - + networkRs.close(); + networkRs = null; + pstmtNw.close(); + pstmtNw = null; } } //if - - if (vmRs != null) { - try { - vmRs.close(); - } catch (SQLException e) { - } - } - - if (networkRs != null) { - try { - networkRs.close(); - } catch (SQLException e) { - } - } - - + pstmtVm.close(); + pstmtVm = null; + vmRs.close(); + vmRs = null; } // while @@ -179,22 +153,6 @@ public class Upgrade430to440 implements DbUpgrade { } - if (pstmtVm != null) { - try { - pstmtVm.close(); - } catch (SQLException e) { - } - } - - - if (pstmtNw != null) { - try { - pstmtNw.close(); - - } catch (SQLException e) { - } - } - if (rs1 != null) { try { rs1.close(); @@ -202,6 +160,15 @@ public class Upgrade430to440 implements DbUpgrade { } } + + + if (pstmtVm != null) { + try { + pstmtVm.close(); + } catch (SQLException e) { + } + } + if (vmRs != null) { try { vmRs.close(); @@ -209,6 +176,17 @@ public class Upgrade430to440 implements DbUpgrade { } } + + + if (pstmtNw != null) { + try { + pstmtNw.close(); + + } catch (SQLException e) { + } + } + + if (networkRs != null) { try { networkRs.close(); From e668c3f4e5cd7b1ea38ff5b8b5808b6c0879cb55 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 23 Jan 2014 14:42:54 +0000 Subject: [PATCH 018/126] Add configuration to the reporting section of the pom so we have findbugs and cobertura output in the site output. --- pom.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pom.xml b/pom.xml index 8d8426186fb..76ac0464f2f 100644 --- a/pom.xml +++ b/pom.xml @@ -897,6 +897,25 @@ org.apache.maven.plugins maven-javadoc-plugin + + 128m + 1g + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + 2.7 + + + org.codehaus.mojo + cobertura-maven-plugin + 2.6 + + + org.apache.maven.plugins + maven-site-plugin + 3.3 From 86df2c1f8022bbd4417a06aea22693f14b1db733 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 23 Jan 2014 14:44:02 +0000 Subject: [PATCH 019/126] Findbugs finding: Fix potential NPE --- .../src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java index 21b3026154b..363b91f9c68 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java @@ -32,6 +32,7 @@ import com.vmware.vim25.PropertySpec; import com.vmware.vim25.SelectionSpec; import com.vmware.vim25.TraversalSpec; +import com.cloud.exception.CloudException; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.utils.Pair; @@ -181,7 +182,7 @@ public class DatastoreMO extends BaseMO { } public boolean copyDatastoreFile(String srcFilePath, ManagedObjectReference morSrcDc, ManagedObjectReference morDestDs, String destFilePath, - ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception { + ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception { String srcDsName = getName(); DatastoreMO destDsMo = new DatastoreMO(_context, morDestDs); @@ -209,7 +210,7 @@ public class DatastoreMO extends BaseMO { } public boolean moveDatastoreFile(String srcFilePath, ManagedObjectReference morSrcDc, ManagedObjectReference morDestDs, String destFilePath, - ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception { + ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception { String srcDsName = getName(); DatastoreMO destDsMo = new DatastoreMO(_context, morDestDs); @@ -342,6 +343,10 @@ public class DatastoreMO extends BaseMO { ArrayList results = browserMo.searchDatastoreSubFolders("[" + getName() + "]", fileName, caseInsensitive); if (results != null && results.size() > 1) { s_logger.warn("Multiple files with name " + fileName + " exists in datastore " + datastorePath + ". Trying to choose first file found in search attempt."); + } else if (results == null) { + String msg = "No file found with name " + fileName + " found in datastore " + datastorePath; + s_logger.error(msg); + throw new CloudException(msg); } for (HostDatastoreBrowserSearchResults result : results) { List info = result.getFile(); From ecdee7da9afd7c3d7f1588ae18dd8c6b6fc73b1a Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 23 Jan 2014 15:43:50 +0000 Subject: [PATCH 020/126] Findbugs finding: Fix incorrect comparison, .equalsi() will always be false and should be .equals() --- .../xen/resource/CitrixResourceBase.java | 328 +++++++++--------- 1 file changed, 166 insertions(+), 162 deletions(-) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 853fd42c408..811d0563b00 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -16,6 +16,75 @@ // under the License. package com.cloud.hypervisor.xen.resource; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringReader; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Queue; +import java.util.Random; +import java.util.Set; +import java.util.UUID; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +import com.google.gson.Gson; +import com.trilead.ssh2.SCPClient; +import com.xensource.xenapi.Bond; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Console; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.HostCpu; +import com.xensource.xenapi.HostMetrics; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PBD; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Pool; +import com.xensource.xenapi.SR; +import com.xensource.xenapi.Session; +import com.xensource.xenapi.Task; +import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.BadServerResponse; +import com.xensource.xenapi.Types.VmPowerState; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; +import com.xensource.xenapi.VBDMetrics; +import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VIF; +import com.xensource.xenapi.VLAN; +import com.xensource.xenapi.VM; +import com.xensource.xenapi.VMGuestMetrics; +import com.xensource.xenapi.XenAPIObject; + +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; + import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; @@ -207,71 +276,6 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.snapshot.VMSnapshot; -import com.google.gson.Gson; -import com.trilead.ssh2.SCPClient; -import com.xensource.xenapi.Bond; -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Console; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.HostCpu; -import com.xensource.xenapi.HostMetrics; -import com.xensource.xenapi.Network; -import com.xensource.xenapi.PBD; -import com.xensource.xenapi.PIF; -import com.xensource.xenapi.Pool; -import com.xensource.xenapi.SR; -import com.xensource.xenapi.Session; -import com.xensource.xenapi.Task; -import com.xensource.xenapi.Types; -import com.xensource.xenapi.Types.BadServerResponse; -import com.xensource.xenapi.Types.VmPowerState; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VBD; -import com.xensource.xenapi.VBDMetrics; -import com.xensource.xenapi.VDI; -import com.xensource.xenapi.VIF; -import com.xensource.xenapi.VLAN; -import com.xensource.xenapi.VM; -import com.xensource.xenapi.VMGuestMetrics; -import com.xensource.xenapi.XenAPIObject; -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; -import org.apache.cloudstack.storage.to.TemplateObjectTO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; -import org.apache.xmlrpc.XmlRpcException; -import org.w3c.dom.Document; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; -import javax.xml.parsers.DocumentBuilderFactory; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Queue; -import java.util.Random; -import java.util.Set; -import java.util.UUID; /** @@ -626,11 +630,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private String getPerfMon(Connection conn, Map params, - int wait) { + int wait) { String result = null; try { result = callHostPluginAsync(conn, "vmopspremium", "asmonitor", 60, - params); + params); if (result != null) return result; } catch (Exception e) { @@ -640,7 +644,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected String callHostPluginAsync(Connection conn, String plugin, - String cmd, int wait, Map params) { + String cmd, int wait, Map params) { int timeout = wait * 1000; Map args = new HashMap(); Task task = null; @@ -650,7 +654,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (s_logger.isTraceEnabled()) { s_logger.trace("callHostPlugin executing for command " + cmd - + " with " + getArgsString(args)); + + " with " + getArgsString(args)); } Host host = Host.getByUuid(conn, _host.uuid); task = host.callPluginAsync(conn, plugin, cmd, args); @@ -662,29 +666,29 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.trace("callHostPlugin Result: " + result); } return result.replace("", "").replace("", "") - .replace("\n", ""); + .replace("\n", ""); } catch (Types.HandleInvalid e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd - + " with args " + getArgsString(args) - + " due to HandleInvalid clazz:" + e.clazz + ", handle:" - + e.handle); + + " with args " + getArgsString(args) + + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + + e.handle); } catch (XenAPIException e) { s_logger.warn( - "callHostPlugin failed for cmd: " + cmd + " with args " - + getArgsString(args) + " due to " + e.toString(), - e); + "callHostPlugin failed for cmd: " + cmd + " with args " + + getArgsString(args) + " due to " + e.toString(), + e); } catch (XmlRpcException e) { s_logger.warn( - "callHostPlugin failed for cmd: " + cmd + " with args " - + getArgsString(args) + " due to " + e.getMessage(), - e); + "callHostPlugin failed for cmd: " + cmd + " with args " + + getArgsString(args) + " due to " + e.getMessage(), + e); } finally { if (task != null) { try { task.destroy(conn); } catch (Exception e1) { s_logger.warn("unable to destroy task(" + task.toString() - + ") on host(" + _host.uuid + ") due to ", e1); + + ") on host(" + _host.uuid + ") due to ", e1); } } } @@ -699,7 +703,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Long newDynamicMemoryMax = vmSpec.getMaxRam(); if (staticMemoryMin > newDynamicMemoryMin || newDynamicMemoryMax > staticMemoryMax) { throw new CloudRuntimeException("Cannot scale up the vm because of memory constraint violation: " + "0 <= memory-static-min(" + staticMemoryMin + - ") <= memory-dynamic-min(" + newDynamicMemoryMin + ") <= memory-dynamic-max(" + newDynamicMemoryMax + ") <= memory-static-max(" + staticMemoryMax + ")"); + ") <= memory-dynamic-min(" + newDynamicMemoryMin + ") <= memory-dynamic-max(" + newDynamicMemoryMax + ") <= memory-static-max(" + staticMemoryMax + ")"); } vm.setMemoryDynamicRange(conn, newDynamicMemoryMin, newDynamicMemoryMax); @@ -739,7 +743,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // If DMC is not enable then don't execute this command. if (!isDmcEnabled(conn, host)) { throw new CloudRuntimeException("Unable to scale the vm: " + vmName + " as DMC - Dynamic memory control is not enabled for the XenServer:" + _host.uuid + - " ,check your license and hypervisor version."); + " ,check your license and hypervisor version."); } // stop vm which is running on this host or is in halted state @@ -749,7 +753,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe VM.Record vmr = vm.getRecord(conn); if ((vmr.powerState == VmPowerState.HALTED) || - (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid))) { + (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid))) { iter.remove(); } } @@ -856,11 +860,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private String revertToSnapshot(Connection conn, VM vmSnapshot, String vmName, String oldVmUuid, Boolean snapshotMemory, String hostUUID) throws XenAPIException, - XmlRpcException { + XmlRpcException { String results = - callHostPluginAsync(conn, "vmopsSnapshot", "revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID", vmSnapshot.getUuid(conn), "vmName", vmName, "oldVmUuid", - oldVmUuid, "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID); + callHostPluginAsync(conn, "vmopsSnapshot", "revert_memory_snapshot", 10 * 60 * 1000, "snapshotUUID", vmSnapshot.getUuid(conn), "vmName", vmName, "oldVmUuid", + oldVmUuid, "snapshotMemory", snapshotMemory.toString(), "hostUUID", hostUUID); String errMsg = null; if (results == null || results.isEmpty()) { errMsg = "revert_memory_snapshot return null"; @@ -1040,9 +1044,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!is_xcp()) enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key); String result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge, - "key", String.valueOf(key), - "xs_nw_uuid", nw.getUuid(conn), - "cs_host_id", ((Long)hostId).toString()); + "key", String.valueOf(key), + "xs_nw_uuid", nw.getUuid(conn), + "cs_host_id", ((Long)hostId).toString()); //Note down the fact that the ovs bridge has been setup String[] res = result.split(":"); if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) { @@ -1690,8 +1694,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String result = null; if (cmd.getType() == PvlanSetupCommand.Type.DHCP) { result = - callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, - "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac); + callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-dhcp", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, + "dhcp-name", dhcpName, "dhcp-ip", dhcpIp, "dhcp-mac", dhcpMac); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program pvlan for dhcp server with mac " + dhcpMac); return new Answer(cmd, false, result); @@ -1700,8 +1704,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } else if (cmd.getType() == PvlanSetupCommand.Type.VM) { result = - callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, - "vm-mac", vmMac); + callHostPlugin(conn, "ovs-pvlan", "setup-pvlan-vm", "op", op, "nw-label", nwNameLabel, "primary-pvlan", primaryPvlan, "isolated-pvlan", isolatedPvlan, + "vm-mac", vmMac); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program pvlan for vm with mac " + vmMac); return new Answer(cmd, false, result); @@ -1776,7 +1780,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (nic.getBroadcastType() == Networks.BroadcastDomainType.Vswitch) { HashMap args = parseDefaultOvsRuleComamnd(BroadcastDomainType.getValue(nic.getBroadcastUri())); OvsSetTagAndFlowCommand flowCmd = - new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"), args.get("seqno"), Long.parseLong(args.get("vmId"))); + new OvsSetTagAndFlowCommand(args.get("vmName"), args.get("tag"), args.get("vlans"), args.get("seqno"), Long.parseLong(args.get("vmId"))); OvsSetTagAndFlowAnswer r = execute(flowCmd); if (!r.getResult()) { s_logger.warn("Failed to set flow for VM " + r.getVmId()); @@ -1795,7 +1799,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe boolean secGrpEnabled = false; for (NicTO nic : nics) { if (nic.isSecurityGroupEnabled() || - (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString()))) { + (nic.getIsolationUri() != null && nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString()))) { secGrpEnabled = true; break; } @@ -1814,7 +1818,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe NicTO[] nics = vmSpec.getNics(); for (NicTO nic : nics) { if (nic.isSecurityGroupEnabled() || nic.getIsolationUri() != null && - nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { + nic.getIsolationUri().getScheme().equalsIgnoreCase(IsolationType.Ec2.toString())) { List nicSecIps = nic.getNicSecIps(); String secIpsStr; StringBuilder sb = new StringBuilder(); @@ -1827,8 +1831,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe secIpsStr = "0:"; } result = - callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", - Long.toString(vmSpec.getId()), "secIps", secIpsStr); + callHostPlugin(conn, "vmops", "default_network_rules", "vmName", vmName, "vmIP", nic.getIp(), "vmMAC", nic.getMac(), "vmID", + Long.toString(vmSpec.getId()), "secIps", secIpsStr); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program default network rules for " + vmName + " on nic with ip:" + nic.getIp() + " mac:" + nic.getMac()); @@ -2027,7 +2031,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesCommand cmd) { - Connection conn = getConnection(); + getConnection(); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; @@ -2081,7 +2085,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (cmd.getVpcId() != null) { return SetVPCStaticNatRules(cmd); } - Connection conn = getConnection(); + getConnection(); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; @@ -2349,8 +2353,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected void assignPublicIpAddress(Connection conn, String vmName, String privateIpAddress, String publicIpAddress, boolean add, boolean firstIP, - boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, Integer networkRate, TrafficType trafficType, String name) - throws InternalErrorException { + boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, Integer networkRate, TrafficType trafficType, String name) + throws InternalErrorException { try { VM router = getVM(conn, vmName); @@ -2548,7 +2552,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (IpAddressTO ip : ips) { assignPublicIpAddress(conn, routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), ip.getNetworkRate(), ip.getTrafficType(), ip.getNetworkName()); + ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), ip.getNetworkRate(), ip.getTrafficType(), ip.getNetworkName()); results[i++] = ip.getPublicIp() + " - success"; } } catch (InternalErrorException e) { @@ -2941,7 +2945,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String startTime = String.valueOf(currentDate.getTime() / 1000 - 1000); return callHostPlugin(conn, "vmops", "gethostvmstats", "collectHostStats", String.valueOf("true"), "consolidationFunction", _consolidationFunction, "interval", - String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); + String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); } protected String getVmStatsRawXML(Connection conn) { @@ -2949,7 +2953,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String startTime = String.valueOf(currentDate.getTime() / 1000 - 1000); return callHostPlugin(conn, "vmops", "gethostvmstats", "collectHostStats", String.valueOf("false"), "consolidationFunction", _consolidationFunction, "interval", - String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); + String.valueOf(_pollingIntervalInSeconds), "startTime", startTime); } protected State convertToState(Types.VmPowerState ps) { @@ -3163,8 +3167,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String createTemplateFromSnapshot(Connection conn, String templatePath, String snapshotPath, int wait) { String tmpltLocalDir = UUID.randomUUID().toString(); String results = - callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath, - "tmpltLocalDir", tmpltLocalDir); + callHostPluginAsync(conn, "vmopspremium", "create_privatetemplate_from_snapshot", wait, "templatePath", templatePath, "snapshotPath", snapshotPath, + "tmpltLocalDir", tmpltLocalDir); String errMsg = null; if (results == null || results.isEmpty()) { errMsg = "create_privatetemplate_from_snapshot return null"; @@ -3215,7 +3219,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String copy_vhd_from_secondarystorage(Connection conn, String mountpoint, String sruuid, int wait) { String nameLabel = "cloud-" + UUID.randomUUID().toString(); String results = - callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel", nameLabel); + callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel", nameLabel); String errMsg = null; if (results == null || results.isEmpty()) { errMsg = "copy_vhd_from_secondarystorage return null"; @@ -3400,7 +3404,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Set vbds = vm.getVBDs(conn); for (VBD vbd : vbds) { VBD.Record vbdRec = vbd.getRecord(conn); - if (vbdRec.type.equals(Types.VbdType.CD.toString()) && !vbdRec.empty) { + if (vbdRec.type.equals(Types.VbdType.CD) && !vbdRec.empty) { vbd.eject(conn); break; } @@ -3668,7 +3672,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe long beginTime = System.currentTimeMillis(); if (s_logger.isTraceEnabled()) { s_logger.trace("Task " + task.getNameLabel(c) + " (" + task.getUuid(c) + ") sent to " + c.getSessionReference() + " is pending completion with a " + timeout + - "ms timeout"); + "ms timeout"); } while (task.getStatus(c) == Types.TaskStatusType.PENDING) { try { @@ -3911,7 +3915,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return result.replace("", "").replace("", "").replace("\n", ""); } catch (Types.HandleInvalid e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + - e.handle); + e.handle); } catch (XenAPIException e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); } catch (XmlRpcException e) { @@ -4194,7 +4198,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (rec.management) { if (rec.VLAN != null && rec.VLAN != -1) { String msg = - new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) + new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) .append("; pif=") .append(rec.uuid) .append("; vlan=") @@ -4219,7 +4223,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Bond bond = mgmtPifRec.bondSlaveOf; if (!isRefNull(bond)) { String msg = - "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.uuid + + "Management interface is on slave(" + mgmtPifRec.uuid + ") of bond(" + bond.getUuid(conn) + ") on host(" + _host.uuid + "), please move management interface to bond!"; s_logger.warn(msg); throw new CloudRuntimeException(msg); @@ -5026,7 +5030,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (rec.management) { if (rec.VLAN != null && rec.VLAN != -1) { String msg = - new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) + new StringBuilder("Unsupported configuration. Management network is on a VLAN. host=").append(_host.uuid) .append("; pif=") .append(rec.uuid) .append("; vlan=") @@ -5060,7 +5064,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (pr.VLAN != null && pr.VLAN != -1) { String msg = - new StringBuilder("Unsupported configuration. Network cloud-private is on a VLAN. Network=").append(network.uuid) + new StringBuilder("Unsupported configuration. Network cloud-private is on a VLAN. Network=").append(network.uuid) .append(" ; pif=") .append(pr.uuid) .toString(); @@ -5070,7 +5074,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!pr.management && pr.bondMasterOf != null && pr.bondMasterOf.size() > 0) { if (pr.bondMasterOf.size() > 1) { String msg = - new StringBuilder("Unsupported configuration. Network cloud-private has more than one bond. Network=").append(network.uuid) + new StringBuilder("Unsupported configuration. Network cloud-private has more than one bond. Network=").append(network.uuid) .append("; pif=") .append(pr.uuid) .toString(); @@ -5084,8 +5088,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (spr.management) { if (!transferManagementNetwork(conn, host, slave, spr, pif)) { String msg = - new StringBuilder("Unable to transfer management network. slave=" + spr.uuid + "; master=" + pr.uuid + "; host=" + - _host.uuid).toString(); + new StringBuilder("Unable to transfer management network. slave=" + spr.uuid + "; master=" + pr.uuid + "; host=" + + _host.uuid).toString(); s_logger.warn(msg); return new SetupAnswer(cmd, msg); } @@ -5243,22 +5247,22 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (PhysicalNetworkSetupInfo info : infoList) { if (!isNetworkSetupByName(info.getGuestNetworkName())) { msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Guest Network is not configured on the backend by name " + - info.getGuestNetworkName(); + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Guest Network is not configured on the backend by name " + + info.getGuestNetworkName(); errorout = true; break; } if (!isNetworkSetupByName(info.getPrivateNetworkName())) { msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Private Network is not configured on the backend by name " + - info.getPrivateNetworkName(); + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Private Network is not configured on the backend by name " + + info.getPrivateNetworkName(); errorout = true; break; } if (!isNetworkSetupByName(info.getPublicNetworkName())) { msg = - "For Physical Network id:" + info.getPhysicalNetworkId() + ", Public Network is not configured on the backend by name " + - info.getPublicNetworkName(); + "For Physical Network id:" + info.getPhysicalNetworkId() + ", Public Network is not configured on the backend by name " + + info.getPublicNetworkName(); errorout = true; break; } @@ -5427,8 +5431,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd, true, "success"); } catch (Exception e) { String msg = - "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + - pool.getHost() + pool.getPath(); + "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + + pool.getHost() + pool.getPath(); s_logger.warn(msg, e); return new Answer(cmd, false, msg); } @@ -5458,7 +5462,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return result.replace("\n", ""); } catch (Types.HandleInvalid e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to HandleInvalid clazz:" + e.clazz + ", handle:" + - e.handle); + e.handle); } catch (XenAPIException e) { s_logger.warn("callHostPlugin failed for cmd: " + cmd + " with args " + getArgsString(args) + " due to " + e.toString(), e); } catch (XmlRpcException e) { @@ -5617,8 +5621,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getKey()); bridge = nw.getBridge(conn); String result = - callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey().toString(), "from", - cmd.getFrom().toString(), "to", cmd.getTo().toString()); + callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey().toString(), "from", + cmd.getFrom().toString(), "to", cmd.getTo().toString()); String[] res = result.split(":"); if (res.length == 2 && res[0].equalsIgnoreCase("SUCCESS")) { return new OvsCreateTunnelAnswer(cmd, true, result, res[1], bridge); @@ -5691,8 +5695,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe * plugin side */ String result = - callHostPlugin(conn, "ovsgre", "ovs_set_tag_and_flow", "bridge", bridge, "vmName", cmd.getVmName(), "tag", cmd.getTag(), "vlans", cmd.getVlans(), - "seqno", cmd.getSeqNo()); + callHostPlugin(conn, "ovsgre", "ovs_set_tag_and_flow", "bridge", bridge, "vmName", cmd.getVmName(), "tag", cmd.getTag(), "vlans", cmd.getVlans(), + "seqno", cmd.getSeqNo()); s_logger.debug("set flow for " + cmd.getVmName() + " " + result); if (result.equalsIgnoreCase("SUCCESS")) { @@ -5749,8 +5753,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe bridge = nw.getBridge(conn); String result = - callHostPlugin(conn, "ovsgre", "ovs_create_gre", "bridge", bridge, "remoteIP", cmd.getRemoteIp(), "greKey", cmd.getKey(), "from", - Long.toString(cmd.getFrom()), "to", Long.toString(cmd.getTo())); + callHostPlugin(conn, "ovsgre", "ovs_create_gre", "bridge", bridge, "remoteIP", cmd.getRemoteIp(), "greKey", cmd.getKey(), "from", + Long.toString(cmd.getFrom()), "to", Long.toString(cmd.getTo())); String[] res = result.split(":"); if (res.length != 2 || (res.length == 2 && res[1].equalsIgnoreCase("[]"))) { return new OvsCreateGreTunnelAnswer(cmd, false, result, _host.ip, bridge); @@ -5777,20 +5781,20 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!_canBridgeFirewall) { s_logger.warn("Host " + _host.ip + " cannot do bridge firewalling"); return new SecurityGroupRuleAnswer(cmd, false, "Host " + _host.ip + " cannot do bridge firewalling", - SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); + SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); } String result = - callHostPlugin(conn, "vmops", "network_rules", "vmName", cmd.getVmName(), "vmIP", cmd.getGuestIp(), "vmMAC", cmd.getGuestMac(), "vmID", - Long.toString(cmd.getVmId()), "signature", cmd.getSignature(), "seqno", Long.toString(cmd.getSeqNum()), "deflated", "true", "rules", - cmd.compressStringifiedRules(), "secIps", cmd.getSecIpsString()); + callHostPlugin(conn, "vmops", "network_rules", "vmName", cmd.getVmName(), "vmIP", cmd.getGuestIp(), "vmMAC", cmd.getGuestMac(), "vmID", + Long.toString(cmd.getVmId()), "signature", cmd.getSignature(), "seqno", Long.toString(cmd.getSeqNum()), "deflated", "true", "rules", + cmd.compressStringifiedRules(), "secIps", cmd.getSecIpsString()); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { s_logger.warn("Failed to program network rules for vm " + cmd.getVmName()); return new SecurityGroupRuleAnswer(cmd, false, "programming network rules failed"); } else { s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " guestIp=" + cmd.getGuestIp() + ", ingress numrules=" + cmd.getIngressRuleSet().length + - ", egress numrules=" + cmd.getEgressRuleSet().length); + ", egress numrules=" + cmd.getEgressRuleSet().length); return new SecurityGroupRuleAnswer(cmd); } } @@ -6073,7 +6077,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid); VolumeTO vol = - new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, pool.getPath(), vdir.uuid, vdir.virtualSize, null); + new VolumeTO(cmd.getVolumeId(), dskch.getType(), pool.getType(), pool.getUuid(), vdir.nameLabel, pool.getPath(), vdir.uuid, vdir.virtualSize, null); return new CreateAnswer(cmd, vol); } catch (Exception e) { s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: " + dskch, e); @@ -6143,8 +6147,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Host host = Host.getByUuid(conn, _host.uuid); SR sr = - SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, - new HashMap()); + SR.create(conn, host, deviceConfig, new Long(0), name, uri.getHost() + uri.getPath(), SRType.NFS.toString(), "user", shared, + new HashMap()); if (!checkSR(conn, sr)) { throw new Exception("no attached PBD"); } @@ -6233,7 +6237,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected SR getIscsiSR(Connection conn, String srNameLabel, String target, String path, String chapInitiatorUsername, String chapInitiatorPassword, - boolean ignoreIntroduceException) { + boolean ignoreIntroduceException) { synchronized (srNameLabel.intern()) { Map deviceConfig = new HashMap(); try { @@ -6276,7 +6280,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) { throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" + dc.get("targetIQN") + - ", lunid:" + dc.get("lunid") + " for pool " + srNameLabel + "on host:" + _host.uuid); + ", lunid:" + dc.get("lunid") + " for pool " + srNameLabel + "on host:" + _host.uuid); } } deviceConfig.put("target", target); @@ -6407,7 +6411,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) { throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" + dc.get("serverpath") + - " for pool " + pool.getUuid() + "on host:" + _host.uuid); + " for pool " + pool.getUuid() + "on host:" + _host.uuid); } } @@ -6415,8 +6419,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe deviceConfig.put("serverpath", serverpath); Host host = Host.getByUuid(conn, _host.uuid); SR sr = - SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, - new HashMap()); + SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, + new HashMap()); sr.scan(conn); return sr; } catch (XenAPIException e) { @@ -6534,7 +6538,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (cmd.getAttach() && cmd.isManaged()) { SR sr = - getIscsiSR(conn, cmd.get_iScsiName(), cmd.getStorageHost(), cmd.get_iScsiName(), cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(), true); + getIscsiSR(conn, cmd.get_iScsiName(), cmd.getStorageHost(), cmd.get_iScsiName(), cmd.getChapInitiatorUsername(), cmd.getChapInitiatorPassword(), true); vdi = getVDIbyUuid(conn, cmd.getVolumePath(), false); @@ -6562,7 +6566,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (isHVM && !pvDrvInstalled) { s_logger.warn(errorMsg + ": You attempted an operation on a VM which requires PV drivers to be installed but the drivers were not detected"); return new AttachVolumeAnswer(cmd, - "You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso."); + "You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso."); } if (attach) { // Figure out the disk number to attach the VM to @@ -6809,11 +6813,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private VM createWorkingVM(Connection conn, String vmName, String guestOSType, List listVolumeTo) throws BadServerResponse, Types.VmBadPowerState, Types.SrFull, - Types.OperationNotAllowed, XenAPIException, XmlRpcException { + Types.OperationNotAllowed, XenAPIException, XmlRpcException { String guestOsTypeName = getGuestOsType(guestOSType, false); if (guestOsTypeName == null) { String msg = - " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + ". you can choose 'Other install media' to run it as HVM"; + " Hypervisor " + this.getClass().getName() + " doesn't support guest OS type " + guestOSType + ". you can choose 'Other install media' to run it as HVM"; s_logger.warn(msg); throw new CloudRuntimeException(msg); } @@ -7204,7 +7208,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } protected boolean postCreatePrivateTemplate(Connection conn, String templatePath, String tmpltFilename, String templateName, String templateDescription, - String checksum, long size, long virtualSize, long templateId) { + String checksum, long size, long virtualSize, long templateId) { if (templateDescription == null) { templateDescription = ""; @@ -7215,9 +7219,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } String result = - callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, "templateName", - templateName, "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), - "templateId", String.valueOf(templateId)); + callHostPlugin(conn, "vmopsSnapshot", "post_create_private_template", "templatePath", templatePath, "templateFilename", tmpltFilename, "templateName", + templateName, "templateDescription", templateDescription, "checksum", checksum, "size", String.valueOf(size), "virtualSize", String.valueOf(virtualSize), + "templateId", String.valueOf(templateId)); boolean success = false; if (result != null && !result.isEmpty()) { @@ -7236,8 +7240,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected String getVhdParent(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) { String parentUuid = - callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", - isISCSI.toString()); + callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", + isISCSI.toString()); if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) { s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid); @@ -7251,8 +7255,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe // If anybody modifies the formatting below again, I'll skin them String result = - callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(), - "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath); + callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "dcId", dcId.toString(), "accountId", accountId.toString(), + "volumeId", volumeId.toString(), "secondaryStorageMountPath", secondaryStorageMountPath); return result; } @@ -7468,8 +7472,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Connection conn = getConnection(); String result = - callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", cmd.getVmName(), "vmMac", cmd.getVmMac(), "vmSecIp", cmd.getVmSecIp(), "action", - cmd.getAction()); + callHostPlugin(conn, "vmops", "network_rules_vmSecondaryIp", "vmName", cmd.getVmName(), "vmMac", cmd.getVmMac(), "vmSecIp", cmd.getVmSecIp(), "action", + cmd.getAction()); if (result == null || result.isEmpty() || !Boolean.parseBoolean(result)) { success = false; } @@ -7501,7 +7505,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) { String[] results = new String[cmd.getRules().length]; String callResult; - Connection conn = getConnection(); + getConnection(); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); FirewallRuleTO[] allrules = cmd.getRules(); @@ -7793,7 +7797,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { Connection conn = getConnection(); NicTO nic = cmd.getNic(); - String domrIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); From 5fc03211ffc2205c4e94ba87bafaa7cd87070691 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 23 Jan 2014 15:52:46 +0000 Subject: [PATCH 021/126] Findbugs finding: the collections should have been made static --- .../src/com/cloud/network/nicira/NiciraNvpApi.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java index d398844d344..83d00752665 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java @@ -102,11 +102,11 @@ public class NiciraNvpApi { private final Gson gson; - protected static Map prefixMap; + protected final static Map prefixMap; - protected static Map listTypeMap; + protected final static Map listTypeMap; - protected static Map defaultListParams; + protected final static Map defaultListParams; static { prefixMap = new HashMap(); From 5e0d61bf98ecf41fda6e41d073abd66fa08a94cf Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 23 Jan 2014 15:53:26 +0000 Subject: [PATCH 022/126] Findbugs finding: Fix object comparison with == instead of equals --- .../cloud/hypervisor/vmware/resource/VmwareResource.java | 3 +-- .../storage/motion/VmwareStorageMotionStrategy.java | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 69543cea623..a6baa02ad03 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -3317,7 +3317,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa public int compare(DiskTO arg0, DiskTO arg1) { if (arg0.getDiskSeq() < arg1.getDiskSeq()) { return -1; - } else if (arg0.getDiskSeq() == arg1.getDiskSeq()) { + } else if (arg0.getDiskSeq().equals(arg1.getDiskSeq())) { return 0; } @@ -4182,7 +4182,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa volume = entry.getKey(); filerTo = entry.getValue(); - volume.getPoolUuid().replace("-", ""); tgtDsName = filerTo.getUuid().replace("-", ""); tgtDsNfsHost = filerTo.getHost(); tgtDsNfsPath = filerTo.getPath(); diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java index 3930d8ec68d..e1527f96b15 100644 --- a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java +++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java @@ -99,7 +99,7 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { try { VMInstanceVO instance = instanceDao.findById(vmTo.getId()); if (instance != null) { - if (srcHost.getClusterId() == destHost.getClusterId()) { + if (srcHost.getClusterId().equals(destHost.getClusterId())) { answer = migrateVmWithVolumesWithinCluster(instance, vmTo, srcHost, destHost, volumeMap); } else { answer = migrateVmWithVolumesAcrossCluster(instance, vmTo, srcHost, destHost, volumeMap); @@ -119,7 +119,7 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesAcrossCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { @@ -157,7 +157,7 @@ public class VmwareStorageMotionStrategy implements DataMotionStrategy { } private Answer migrateVmWithVolumesWithinCluster(VMInstanceVO vm, VirtualMachineTO to, Host srcHost, Host destHost, Map volumeToPool) - throws AgentUnavailableException { + throws AgentUnavailableException { // Initiate migration of a virtual machine with it's volumes. try { From 50b6de471417d93b7d50e53c3db47de9ea39b155 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 23 Jan 2014 16:14:56 +0000 Subject: [PATCH 023/126] Findbugs finding : Fix potential NPE --- .../kvm/storage/LibvirtStorageAdaptor.java | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) 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 fafbee08e36..bbd1c24ac99 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 @@ -386,7 +386,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool; try { - StorageVol vol = this.getVolume(libvirtPool.getPool(), volumeUuid); + StorageVol vol = getVolume(libvirtPool.getPool(), volumeUuid); KVMPhysicalDisk disk; LibvirtStorageVolumeDef voldef = getStorageVolumeDef(libvirtPool.getPool().getConnect(), vol); disk = new KVMPhysicalDisk(vol.getPath(), vol.getName(), pool); @@ -471,7 +471,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { String targetPath = pdef.getTargetPath(); if (targetPath != null && targetPath.equals(path)) { s_logger.debug("Storage pool utilizing path '" + path + "' already exists as pool " + poolname + - ", undefining so we can re-define with correct name " + name); + ", undefining so we can re-define with correct name " + name); if (p.isPersistent() == 1) { p.destroy(); p.undefine(); @@ -527,8 +527,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { String error = e.toString(); if (error.contains("Storage source conflict")) { throw new CloudRuntimeException("A pool matching this location already exists in libvirt, " + - " but has a different UUID/Name. Cannot create new pool without first " + " removing it. Check for inactive pools via 'virsh pool-list --all'. " + - error); + " but has a different UUID/Name. Cannot create new pool without first " + " removing it. Check for inactive pools via 'virsh pool-list --all'. " + + error); } else { throw new CloudRuntimeException(error); } @@ -556,7 +556,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { /* * Some storage pools, like RBD also have 'secret' information stored in libvirt * Destroy them if they exist - */ + */ try { s = conn.secretLookupByUUIDString(uuid); } catch (LibvirtException e) { @@ -580,7 +580,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { if (e.toString().contains("exit status 16")) { String targetPath = _mountPoint + File.separator + uuid; s_logger.error("deleteStoragePool removed pool from libvirt, but libvirt had trouble" + "unmounting the pool. Trying umount location " + targetPath + - "again in a few seconds"); + "again in a few seconds"); String result = Script.runSimpleBashScript("sleep 5 && umount " + targetPath); if (result == null) { s_logger.error("Succeeded in unmounting " + targetPath); @@ -624,7 +624,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { IoCTX io = r.ioCtxCreate(pool.getSourceDir()); Rbd rbd = new Rbd(io); - rbd.create(name, size, this.rbdFeatures, this.rbdOrder); + rbd.create(name, size, rbdFeatures, rbdOrder); r.ioCtxDestroy(io); } catch (RadosException e) { @@ -702,7 +702,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { try { Connect conn = LibvirtConnection.getConnection(); - StoragePool pool = conn.storagePoolLookupByUUIDString(poolUuid); + conn.storagePoolLookupByUUIDString(poolUuid); deleteStoragePool(poolUuid); @@ -753,7 +753,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { LibvirtStoragePool libvirtPool = (LibvirtStoragePool)pool; try { - StorageVol vol = this.getVolume(libvirtPool.getPool(), uuid); + StorageVol vol = getVolume(libvirtPool.getPool(), uuid); deleteVol(libvirtPool, vol); vol.free(); return true; @@ -784,7 +784,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { So for RBD we don't create the image, but let qemu-img do that for us. We then create a KVMPhysicalDisk object that we can return - */ + */ try { if (destPool.getType() != StoragePoolType.RBD) { disk = destPool.createPhysicalDisk(newUuid, format, template.getVirtualSize()); @@ -815,8 +815,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { QemuImg qemu = new QemuImg(timeout); QemuImgFile srcFile; QemuImgFile destFile = - new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(), - destPool.getAuthSecret(), disk.getPath())); + new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(destPool.getSourceHost(), destPool.getSourcePort(), destPool.getAuthUserName(), + destPool.getAuthSecret(), disk.getPath())); destFile.setFormat(format); if (srcPool.getType() != StoragePoolType.RBD) { @@ -850,9 +850,9 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { if (srcImage.isOldFormat()) { /* The source image is RBD format 1, we have to do a regular copy */ s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() + - " is RBD format 1. We have to perform a regular copy (" + template.getVirtualSize() + " bytes)"); + " is RBD format 1. We have to perform a regular copy (" + template.getVirtualSize() + " bytes)"); - rbd.create(disk.getName(), template.getVirtualSize(), this.rbdFeatures, this.rbdOrder); + rbd.create(disk.getName(), template.getVirtualSize(), rbdFeatures, rbdOrder); RbdImage destImage = rbd.open(disk.getName()); s_logger.debug("Starting to copy " + srcImage.getName() + " to " + destImage.getName() + " in Ceph pool " + srcPool.getSourceDir()); @@ -862,10 +862,10 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { rbd.close(destImage); } else { s_logger.debug("The source image " + srcPool.getSourceDir() + "/" + template.getName() + - " is RBD format 2. We will perform a RBD clone using snapshot " + this.rbdTemplateSnapName); + " is RBD format 2. We will perform a RBD clone using snapshot " + rbdTemplateSnapName); /* The source image is format 2, we can do a RBD snapshot+clone (layering) */ - rbd.clone(template.getName(), this.rbdTemplateSnapName, io, disk.getName(), this.rbdFeatures, this.rbdOrder); - s_logger.debug("Succesfully cloned " + template.getName() + "@" + this.rbdTemplateSnapName + " to " + disk.getName()); + rbd.clone(template.getName(), rbdTemplateSnapName, io, disk.getName(), rbdFeatures, rbdOrder); + s_logger.debug("Succesfully cloned " + template.getName() + "@" + rbdTemplateSnapName + " to " + disk.getName()); } rbd.close(srcImage); @@ -893,14 +893,14 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { Rbd dRbd = new Rbd(dIO); s_logger.debug("Creating " + disk.getName() + " on the destination cluster " + rDest.confGet("mon_host") + " in pool " + - destPool.getSourceDir()); - dRbd.create(disk.getName(), template.getVirtualSize(), this.rbdFeatures, this.rbdOrder); + destPool.getSourceDir()); + dRbd.create(disk.getName(), template.getVirtualSize(), rbdFeatures, rbdOrder); RbdImage srcImage = sRbd.open(template.getName()); RbdImage destImage = dRbd.open(disk.getName()); s_logger.debug("Copying " + template.getName() + " from Ceph cluster " + rSrc.confGet("mon_host") + " to " + disk.getName() + " on cluster " + - rDest.confGet("mon_host")); + rDest.confGet("mon_host")); sRbd.copy(srcImage, destImage); sRbd.close(srcImage); @@ -923,7 +923,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } if (disk == null) { - throw new CloudRuntimeException("Failed to create " + disk.getPath() + " from template " + template.getName()); + throw new CloudRuntimeException("Failed to create disk from template " + template.getName()); } return disk; @@ -942,7 +942,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { try { String[] vols = virtPool.listVolumes(); for (String volName : vols) { - KVMPhysicalDisk disk = this.getPhysicalDisk(volName, pool); + KVMPhysicalDisk disk = getPhysicalDisk(volName, pool); disks.add(disk); } return disks; @@ -1036,11 +1036,11 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } } else if ((srcPool.getType() != StoragePoolType.RBD) && (destPool.getType() == StoragePoolType.RBD)) { /** - * Qemu doesn't support writing to RBD format 2 directly, so we have to write to a temporary RAW file first - * which we then convert to RBD format 2. - * - * A HUGE performance gain can be achieved here if QCOW2 -> RBD format 2 can be done in one step - */ + * Qemu doesn't support writing to RBD format 2 directly, so we have to write to a temporary RAW file first + * which we then convert to RBD format 2. + * + * A HUGE performance gain can be achieved here if QCOW2 -> RBD format 2 can be done in one step + */ s_logger.debug("The source image is not RBD, but the destination is. We will convert into RBD format 2"); String sourceFile; boolean useTmpFile = false; @@ -1069,7 +1069,7 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { Rbd rbd = new Rbd(io); s_logger.debug("Creating RBD image " + name + " in Ceph pool " + destPool.getSourceDir() + " with RBD format 2"); - rbd.create(name, disk.getVirtualSize(), this.rbdFeatures, this.rbdOrder); + rbd.create(name, disk.getVirtualSize(), rbdFeatures, rbdOrder); RbdImage image = rbd.open(name); @@ -1098,10 +1098,10 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { } /* Snapshot the image and protect that snapshot so we can clone (layer) from it */ - s_logger.debug("Creating RBD snapshot " + this.rbdTemplateSnapName + " on image " + name); - image.snapCreate(this.rbdTemplateSnapName); - s_logger.debug("Protecting RBD snapshot " + this.rbdTemplateSnapName + " on image " + name); - image.snapProtect(this.rbdTemplateSnapName); + s_logger.debug("Creating RBD snapshot " + rbdTemplateSnapName + " on image " + name); + image.snapCreate(rbdTemplateSnapName); + s_logger.debug("Protecting RBD snapshot " + rbdTemplateSnapName + " on image " + name); + image.snapProtect(rbdTemplateSnapName); rbd.close(image); r.ioCtxDestroy(io); @@ -1125,8 +1125,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { it doesn't benefit us. It's better to keep the current code in place which works */ srcFile = - new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(), - sourcePath)); + new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(srcPool.getSourceHost(), srcPool.getSourcePort(), srcPool.getAuthUserName(), srcPool.getAuthSecret(), + sourcePath)); srcFile.setFormat(sourceFormat); destFile = new QemuImgFile(destPath); destFile.setFormat(destFormat); From dad98ef4de9a1acf72a94854048b57cd51ae28d6 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Thu, 23 Jan 2014 21:09:25 +0100 Subject: [PATCH 024/126] test: Add UnitTest for LibvirtSecretDef --- .../kvm/resource/LibvirtSecretDefTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java new file mode 100644 index 00000000000..54036b3c848 --- /dev/null +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtSecretDefTest.java @@ -0,0 +1,55 @@ +/* + * 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 junit.framework.TestCase; +import com.cloud.hypervisor.kvm.resource.LibvirtSecretDef.usage; + +public class LibvirtSecretDefTest extends TestCase { + + public void testVolumeSecretDef() { + String uuid = "db66f42b-a79e-4666-9910-9dfc8a024427"; + String name = "myEncryptedQCOW2"; + usage use = usage.VOLUME; + + LibvirtSecretDef def = new LibvirtSecretDef(use, uuid); + def.setVolumeVolume(name); + + String expectedXml = "\n" + uuid + "\n" + + "\n" + name + "\n\n\n"; + + assertEquals(expectedXml, def.toString()); + } + + public void testCephSecretDef() { + String uuid = "a9febe83-ac5c-467a-bf19-eb75325ec23c"; + String name = "admin"; + usage use = usage.CEPH; + + LibvirtSecretDef def = new LibvirtSecretDef(use, uuid); + def.setCephName(name); + + String expectedXml = "\n" + uuid + "\n" + + "\n" + name + "\n\n\n"; + + assertEquals(expectedXml, def.toString()); + } + +} \ No newline at end of file From aab881be2107a41db766e5a45d6fa05a990d8908 Mon Sep 17 00:00:00 2001 From: Devdeep Singh Date: Fri, 24 Jan 2014 20:53:42 +0530 Subject: [PATCH 025/126] CLOUDSTACK-5942: The agent at places logs the password of the user. It should mask the password from the message string before writing to the log. Made a change to do so. --- .../HypervResource/CloudStackTypes.cs | 4 ++-- .../HypervResourceController.cs | 22 +++++++++---------- .../ServerResource/HypervResource/Utils.cs | 10 +++++++++ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index 847380cb115..d54295ccdaa 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -254,7 +254,7 @@ namespace HypervResource // Assert if (result.dataStore == null || (result.primaryDataStore == null && result.nfsDataStore == null)) { - String errMsg = "VolumeObjectTO missing dataStore in spec " + volumeObjectTOJson.ToString(); + String errMsg = "VolumeObjectTO missing dataStore in spec " + Utils.CleanString(volumeObjectTOJson.ToString()); logger.Error(errMsg); throw new ArgumentNullException(errMsg); } @@ -292,7 +292,7 @@ namespace HypervResource } else { - String errMsg = "VolumeObjectTO missing dataStore in spec " + volInfo.ToString(); + String errMsg = "VolumeObjectTO missing dataStore in spec " + Utils.CleanString(volInfo.ToString()); logger.Error(errMsg); throw new ArgumentNullException(errMsg); } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index 76336e996cc..f7787c32c52 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -207,7 +207,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.AttachCommand + cmd.ToString()); + logger.Info(CloudStackTypes.AttachCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -268,7 +268,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.DettachCommand + cmd.ToString()); + logger.Info(CloudStackTypes.DettachCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -485,7 +485,7 @@ namespace HypervResource { JObject ansObj = Utils.CreateCloudStackObject(ansType, ansContent); JArray answer = new JArray(ansObj); - logger.Info(ansObj.ToString()); + logger.Info(Utils.CleanString(ansObj.ToString())); return answer; } @@ -496,7 +496,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.CreateCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CreateCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -603,7 +603,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.PrimaryStorageDownloadCommand + cmd.ToString()); + logger.Info(CloudStackTypes.PrimaryStorageDownloadCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; long size = 0; @@ -871,7 +871,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.CreateStoragePoolCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CreateStoragePoolCommand + Utils.CleanString(cmd.ToString())); object ansContent = new { result = true, @@ -889,7 +889,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.ModifyStoragePoolCommand + cmd.ToString()); + logger.Info(CloudStackTypes.ModifyStoragePoolCommand + Utils.CleanString(cmd.ToString())); string details = null; string localPath; StoragePoolType poolType; @@ -1045,7 +1045,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.StartCommand + cmd.ToString()); // TODO: Security hole? VM data printed to log + logger.Info(CloudStackTypes.StartCommand + Utils.CleanString(cmd.ToString())); string details = null; bool result = false; @@ -1144,7 +1144,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.CreateObjectCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CreateObjectCommand + Utils.CleanString(cmd.ToString())); bool result = false; string details = null; @@ -1315,7 +1315,7 @@ namespace HypervResource using (log4net.NDC.Push(Guid.NewGuid().ToString())) { // Log command *after* we've removed security details from the command. - logger.Info(CloudStackTypes.CopyCommand + cmd.ToString()); + logger.Info(CloudStackTypes.CopyCommand + Utils.CleanString(cmd.ToString())); bool result = false; string details = null; @@ -1691,7 +1691,7 @@ namespace HypervResource { using (log4net.NDC.Push(Guid.NewGuid().ToString())) { - logger.Info(CloudStackTypes.GetStorageStatsCommand + cmd.ToString()); + logger.Info(CloudStackTypes.GetStorageStatsCommand + Utils.CleanString(cmd.ToString())); bool result = false; string details = null; long capacity = 0; diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs index c4b39ba24c2..6ebc5bf7f23 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/Utils.cs @@ -164,6 +164,16 @@ namespace HypervResource capacity = totalNumberOfBytes > 0 ? (long)totalNumberOfBytes : 0; } + public static string CleanString(string stringToClean) + { + string cleanString = null; + string regexQueryString = "(&|%26)?(password|accesskey|secretkey)(=|%3D).*?(?=(%26|[&'\"]))"; + string regexJson = "\"(password|accesskey|secretkey)\":\".*?\",?"; + cleanString = System.Text.RegularExpressions.Regex.Replace(stringToClean, regexQueryString, ""); + cleanString = System.Text.RegularExpressions.Regex.Replace(cleanString, regexJson, ""); + return cleanString; + } + // from http://stackoverflow.com/a/2541569/939250 #region imports [DllImport("advapi32.dll", SetLastError = true)] From 417b8e089faadc14cc9748d62fdd876aacd01383 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Fri, 24 Jan 2014 11:02:27 -0800 Subject: [PATCH 026/126] VM snapshots: Only show quiescevm checkbox if hypervisor is VMware --- ui/scripts/instances.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 9430fe4b9bb..989d9a81d1b 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -45,7 +45,10 @@ quiescevm: { label: 'label.quiesce.vm', isBoolean: true, - isChecked: false + isChecked: false, + isHidden: function(args) { + return args.context.instances[0].hypervisor !== 'VMware'; + } } } }, From 2d100f1269e44de927be32faed32e31c62afa57b Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Fri, 24 Jan 2014 14:54:11 -0800 Subject: [PATCH 027/126] CLOUDSTACK-5779: Generalize calling to execute or create file for Xen --- .../VirtualRoutingResource.java | 58 ++--- .../vmware/resource/VmwareResource.java | 38 ++-- .../xen/resource/CitrixResourceBase.java | 206 +++++++++--------- .../xen/resource/XenServer56Resource.java | 44 ++-- scripts/vm/hypervisor/xenserver/vmops | 15 +- .../src/com/cloud/utils/ExecutionResult.java | 44 ++++ 6 files changed, 221 insertions(+), 184 deletions(-) create mode 100644 utils/src/com/cloud/utils/ExecutionResult.java diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 732d7b4e385..b27ed55c7a3 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -177,7 +177,7 @@ public class VirtualRoutingResource implements Manager { args += "-u "; args += userpwd.getUsernamePassword(); } - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpn_l2tp.sh", args); if (result != null) { return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername()); } @@ -204,7 +204,7 @@ public class VirtualRoutingResource implements Manager { } args += " -C " + cmd.getLocalCidr(); args += " -i " + cmd.getPublicInterface(); - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpn_l2tp.sh", args); if (result != null) { return new Answer(cmd, false, "Configure VPN failed"); } @@ -252,9 +252,9 @@ public class VirtualRoutingResource implements Manager { String result = null; if (trafficType == FirewallRule.TrafficType.Egress) { - result = routerProxy("firewall_egress.sh", routerIp, args); + result = executeInVR(routerIp, "firewall_egress.sh", args); } else { - result = routerProxy("firewall_ingress.sh", routerIp, args); + result = executeInVR(routerIp, "firewall_ingress.sh", args); } if (result != null) { @@ -278,7 +278,7 @@ public class VirtualRoutingResource implements Manager { args.append(" -r ").append(rule.getDstIp()); args.append(" -d ").append(rule.getStringDstPortRange()); - String result = routerProxy("firewall_nat.sh", routerIp, args.toString()); + String result = executeInVR(routerIp, "firewall_nat.sh", args.toString()); if (result == null || result.isEmpty()) { results[i++] = "Failed"; @@ -302,7 +302,7 @@ public class VirtualRoutingResource implements Manager { args += " -l " + rule.getSrcIp(); args += " -r " + rule.getDstIp(); - String result = routerProxy("vpc_staticnat.sh", routerIp, args); + String result = executeInVR(routerIp, "vpc_staticnat.sh", args); if (result == null) { results[i++] = null; @@ -337,7 +337,7 @@ public class VirtualRoutingResource implements Manager { args.append(" -d ").append(rule.getStringSrcPortRange()); args.append(" -G "); - String result = routerProxy("firewall_nat.sh", routerIp, args.toString()); + String result = executeInVR(routerIp, "firewall_nat.sh", args.toString()); if (result == null || result.isEmpty()) { results[i++] = "Failed"; @@ -420,10 +420,10 @@ public class VirtualRoutingResource implements Manager { if (cmd.getVpcId() == null) { args = " -i " + routerIp + args; - result = routerProxy("loadbalancer.sh", routerIp, args); + result = executeInVR(routerIp, "loadbalancer.sh", args); } else { args = " -i " + cmd.getNic().getIp() + args; - result = routerProxy("vpc_loadbalancer.sh", routerIp, args); + result = executeInVR(routerIp, "vpc_loadbalancer.sh", args); } if (result != null) { @@ -449,7 +449,7 @@ public class VirtualRoutingResource implements Manager { String args = "-d " + json; - final String result = routerProxy("vmdata.py", routerIp, args); + final String result = executeInVR(routerIp, "vmdata.py", args); if (result != null) { return new Answer(cmd, false, "VmDataCommand failed, check agent logs"); } @@ -485,7 +485,7 @@ public class VirtualRoutingResource implements Manager { String args = "-v " + vmIpAddress; args += " -p " + password; - String result = routerProxy("savepassword.sh", routerPrivateIPAddress, args); + String result = executeInVR(routerPrivateIPAddress, "savepassword.sh", args); if (result != null) { return new Answer(cmd, false, "Unable to save password to DomR."); } @@ -520,7 +520,7 @@ public class VirtualRoutingResource implements Manager { args += " -N"; } - final String result = routerProxy("edithosts.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + final String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "edithosts.sh", args); return new Answer(cmd, result == null, result); } @@ -531,7 +531,7 @@ public class VirtualRoutingResource implements Manager { for (IpAliasTO ipaliasto : ipAliasTOs) { args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; } - final String result = routerProxy("createipAlias.sh", routerIp, args); + final String result = executeInVR(routerIp, "createipAlias.sh", args); return new Answer(cmd, result == null, result); } @@ -547,7 +547,7 @@ public class VirtualRoutingResource implements Manager { for (IpAliasTO ipAliasTO : activeIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; } - final String result = routerProxy("deleteipAlias.sh", routerIp, args); + final String result = executeInVR(routerIp, "deleteipAlias.sh", args); return new Answer(cmd, result == null, result); } @@ -558,7 +558,7 @@ public class VirtualRoutingResource implements Manager { for (DhcpTO dhcpTo : dhcpTos) { args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; } - final String result = routerProxy("dnsmasq.sh", routerIp, args); + final String result = executeInVR(routerIp, "dnsmasq.sh", args); return new Answer(cmd, result == null, result); } @@ -589,14 +589,14 @@ public class VirtualRoutingResource implements Manager { args += " " + ip; } - final String result = routerProxy("checkbatchs2svpn.sh", routerIP, args); + final String result = executeInVR(routerIP, "checkbatchs2svpn.sh", args); if (result == null || result.isEmpty()) { return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); } return new CheckS2SVpnConnectionsAnswer(cmd, true, result); } - public String routerProxy(String script, String routerIP, String args) { + public String executeInVR(String routerIP, String script, String args) { final Script command = new Script(_routerProxyPath, _timeout, s_logger); command.add(script); command.add(routerIP); @@ -617,7 +617,7 @@ public class VirtualRoutingResource implements Manager { } protected Answer execute(BumpUpPriorityCommand cmd) { - String result = routerProxy("bumpup_priority.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), null); + String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "bumpup_priority.sh", null); if (result != null) { return new Answer(cmd, false, "BumpUpPriorityCommand failed due to " + result); } @@ -692,7 +692,7 @@ public class VirtualRoutingResource implements Manager { args += " -N "; args += cmd.getPeerGuestCidrList(); } - String result = routerProxy("ipsectunnel.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "ipsectunnel.sh", args); if (result != null) { return new Answer(cmd, false, "Configure site to site VPN failed due to " + result); } @@ -740,7 +740,7 @@ public class VirtualRoutingResource implements Manager { public String configureMonitor(final String routerIP, final String config) { String args = " -c " + config; - return routerProxy("monitor_service.sh", routerIP, args); + return executeInVR(routerIP, "monitor_service.sh", args); } public String assignGuestNetwork(final String dev, final String routerIP, final String routerGIP, final String gateway, final String cidr, final String netmask, @@ -758,19 +758,19 @@ public class VirtualRoutingResource implements Manager { if (domainName != null && !domainName.isEmpty()) { args += " -e " + domainName; } - return routerProxy("vpc_guestnw.sh", routerIP, args); + return executeInVR(routerIP, "vpc_guestnw.sh", args); } public String assignNetworkACL(final String routerIP, final String dev, final String routerGIP, final String netmask, final String rule, String privateGw) { String args = " -d " + dev; if (privateGw != null) { args += " -a " + rule; - return routerProxy("vpc_privategw_acl.sh", routerIP, args); + return executeInVR(routerIP, "vpc_privategw_acl.sh", args); } else { args += " -i " + routerGIP; args += " -m " + netmask; args += " -a " + rule; - return routerProxy("vpc_acl.sh", routerIP, args); + return executeInVR(routerIP, "vpc_acl.sh", args); } } @@ -780,7 +780,7 @@ public class VirtualRoutingResource implements Manager { args += pubIP; args += " -c "; args += dev; - return routerProxy("vpc_snat.sh", routerIP, args); + return executeInVR(routerIP, "vpc_snat.sh", args); } private SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { @@ -797,7 +797,7 @@ public class VirtualRoutingResource implements Manager { args += " -r " + rule.getDstIp(); args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - String result = routerProxy("vpc_portforwarding.sh", routerIp, args); + String result = executeInVR(routerIp, "vpc_portforwarding.sh", args); if (result != null) { results[i++] = "Failed"; @@ -833,7 +833,7 @@ public class VirtualRoutingResource implements Manager { args += " -n "; args += subnet; - String result = routerProxy("vpc_ipassoc.sh", routerIP, args); + String result = executeInVR(routerIP, "vpc_ipassoc.sh", args); if (result != null) { throw new InternalErrorException("KVM plugin \"vpc_ipassoc\" failed:" + result); } @@ -841,7 +841,7 @@ public class VirtualRoutingResource implements Manager { snatArgs += " -l " + pubIP; snatArgs += " -c " + nicname; - result = routerProxy("vpc_privateGateway.sh", routerIP, snatArgs); + result = executeInVR(routerIP, "vpc_privateGateway.sh", snatArgs); if (result != null) { throw new InternalErrorException("KVM plugin \"vpc_privateGateway\" failed:" + result); } @@ -862,7 +862,7 @@ public class VirtualRoutingResource implements Manager { } String args = " -a " + sb.toString(); - String result = routerProxy("vpc_staticroute.sh", routerIP, args); + String result = executeInVR(routerIP, "vpc_staticroute.sh", args); if (result != null) { for (int i = 0; i < results.length; i++) { @@ -923,7 +923,7 @@ public class VirtualRoutingResource implements Manager { args += " -n"; } - return routerProxy("ipassoc.sh", privateIpAddress, args); + return executeInVR(privateIpAddress, "ipassoc.sh", args); } private void deleteBridge(String brName) { diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index a6baa02ad03..982031bf8c4 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1954,6 +1954,19 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new IpAssocAnswer(cmd, results); } + protected Pair executeInVR(String script, String routerIP, String args) { + Pair result; + try { + VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + result = SshHelper.sshExecute(routerIP, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args); + } catch (Exception e) { + String msg = "Command failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg); + result = new Pair(false, msg); + } + return result; + } + protected Answer execute(SavePasswordCommand cmd) { if (s_logger.isInfoEnabled()) { @@ -1975,27 +1988,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -p " + password; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/savepassword.sh " + args); - - if (!result.first()) { - s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "SavePassword failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("savepassword command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "SavePasswordCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + Pair result = executeInVR("savepassword.sh", controlIp, args); + if (!result.first()) { + s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second()); + return new Answer(cmd, false, "SavePassword failed due to " + result.second()); } - return new Answer(cmd); + return new Answer(cmd); } protected Answer execute(DhcpEntryCommand cmd) { diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 811d0563b00..05311b8c446 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -264,6 +264,7 @@ import com.cloud.storage.resource.StorageSubsystemCommandHandler; import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; import com.cloud.storage.template.TemplateProp; import com.cloud.template.VirtualMachineTemplate.BootloaderType; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; @@ -614,12 +615,21 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - public String routerProxy(String script, String routerIP, String args) { + public ExecutionResult executeInVR(String routerIP, String script, String args) { Connection conn = getConnection(); - String proxyArgs = script + " " + routerIP + " " + args; - return callHostPlugin(conn, "vmops", "routerProxy", "args", proxyArgs); + String rc = callHostPlugin(conn, "vmops", "routerProxy", "args", script + " " + routerIP + " " + args); + // Fail case would be start with "fail#" + return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5)); } + protected ExecutionResult createFileInVR(String routerIp, String path, String content) { + Connection conn = getConnection(); + String rc = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "filepath", path, "filecontents", content); + // Fail case would be start with "fail#" + return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5)); + } + + private Answer execute(PerformanceMonitorCommand cmd) { Connection conn = getConnection(); String perfMon = getPerfMon(conn, cmd.getParams(), cmd.getWait()); @@ -1968,31 +1978,31 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (String ip : cmd.getVpnIps()) { args += ip + " "; } - String result = routerProxy("checkbatchs2svpn.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "checkbatchs2svpn.sh", args); + if (!result.isSuccess()) { return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result); + return new CheckS2SVpnConnectionsAnswer(cmd, true, result.getDetails()); } private CheckRouterAnswer execute(CheckRouterCommand cmd) { - String result = routerProxy("checkrouter.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), null); - if (result == null || result.isEmpty()) { + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "checkrouter.sh", null); + if (!result.isSuccess()) { return new CheckRouterAnswer(cmd, "CheckRouterCommand failed"); } - return new CheckRouterAnswer(cmd, result, true); + return new CheckRouterAnswer(cmd, result.getDetails(), true); } private GetDomRVersionAnswer execute(GetDomRVersionCmd cmd) { - String result = routerProxy("get_template_version.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), null); - if (result == null || result.isEmpty()) { + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "get_template_version.sh", null); + if (!result.isSuccess()) { return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd failed"); } - String[] lines = result.split("&"); + String[] lines = result.getDetails().split("&"); if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result); + return new GetDomRVersionAnswer(cmd, result.getDetails()); } - return new GetDomRVersionAnswer(cmd, result, lines[0], lines[1]); + return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]); } private Answer execute(BumpUpPriorityCommand cmd) { @@ -2032,7 +2042,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesCommand cmd) { getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; @@ -2047,10 +2056,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args.append(" -r ").append(rule.getDstIp()); args.append(" -d ").append(rule.getStringDstPortRange()); - String result = routerProxy("firewall_nat.sh", routerIp, args.toString()); + ExecutionResult result = executeInVR(routerIp, "firewall_nat.sh", args.toString()); - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; + if (!result.isSuccess()) { + results[i++] = "Failed: " + result.getDetails(); endResult = false; } else { results[i++] = null; @@ -2069,10 +2078,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String args = rule.revoked() ? "-D" : "-A"; args += " -l " + rule.getSrcIp(); args += " -r " + rule.getDstIp(); - String result = routerProxy("vpc_staticnat.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_staticnat.sh", args); - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; + if (!result.isSuccess()) { + results[i++] = "Failed: " + result.getDetails(); endResult = false; } else { results[i++] = null; @@ -2105,10 +2114,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args.append(" -d ").append(rule.getStringSrcPortRange()); args.append(" -G "); - String result = routerProxy("firewall_nat.sh", routerIp, args.toString()); + ExecutionResult result = executeInVR(routerIp, "firewall_nat.sh", args.toString()); - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; + if (!result.isSuccess()) { + results[i++] = "Failed:" + result.getDetails(); endResult = false; } else { results[i++] = null; @@ -2125,9 +2134,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (IpAliasTO ipaliasto : ipAliasTOs) { args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; } - String result = routerProxy("createipAlias.sh", routerIp, args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "CreateIPAliasCommand failed\n"); + ExecutionResult result = executeInVR(routerIp, "createipAlias.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "CreateIPAliasCommand failed due to " + result.getDetails()); } return new Answer(cmd); @@ -2146,9 +2155,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (IpAliasTO ipAliasTO : activeIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; } - String result = routerProxy("deleteipAlias", routerIp, args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "DeleteipAliasCommand failed\n"); + ExecutionResult result = executeInVR(routerIp, "deleteipAlias", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "DeleteipAliasCommand failed due to " + result.getDetails()); } return new Answer(cmd); @@ -2162,19 +2171,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; } - String result = routerProxy("dnsmasq.sh", routerIp, args); + ExecutionResult result = executeInVR(routerIp, "dnsmasq.sh", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "DnsMasqconfigCommand failed"); + if (!result.isSuccess()) { + return new Answer(cmd, false, "DnsMasqconfigCommand failed due to " + result.getDetails()); } return new Answer(cmd); - - } - - protected String createFileInVR(String routerIp, String path, String content) { - Connection conn = getConnection(); - return callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "filepath", path, "filecontents", content); } protected Answer execute(final LoadBalancerConfigCommand cmd) { @@ -2192,10 +2195,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe tmpCfgFileContents += "\n"; } String tmpCfgFilePath = "/etc/haproxy/haproxy.cfg.new"; - String result = createFileInVR(routerIp, tmpCfgFilePath, tmpCfgFileContents); + ExecutionResult result = createFileInVR(routerIp, tmpCfgFilePath, tmpCfgFileContents); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed to create HA proxy cfg file."); + if (!result.isSuccess()) { + return new Answer(cmd, false, "LoadBalancerConfigCommand failed to create HA proxy cfg file: " + result.getDetails()); } String[][] rules = cfgtr.generateFwRules(cmd); @@ -2235,14 +2238,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (cmd.getVpcId() == null) { args = " -i " + routerIp + args; - result = routerProxy("loadbalancer.sh", routerIp, args); + result = executeInVR(routerIp, "loadbalancer.sh", args); } else { args = " -i " + cmd.getNic().getIp() + args; - result = routerProxy("vpc_loadbalancer.sh", routerIp, args); + result = executeInVR(routerIp, "vpc_loadbalancer.sh", args); } - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed"); + if (!result.isSuccess()) { + return new Answer(cmd, false, "LoadBalancerConfigCommand failed: " + result.getDetails()); } return new Answer(cmd); } @@ -2275,9 +2278,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -N"; } - String result = routerProxy("edithosts.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "DhcpEntry failed"); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "edithosts.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "DhcpEntry failed: " + result.getDetails()); } return new Answer(cmd); } @@ -2296,9 +2299,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } args += " -C " + cmd.getLocalCidr(); args += " -i " + cmd.getPublicInterface(); - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "Configure VPN failed"); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpn_l2tp.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Configure VPN failed" + result.getDetails()); } return new Answer(cmd); } @@ -2311,9 +2314,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } else { args += " -u " + userpwd.getUsernamePassword(); } - String result = routerProxy("vpn_l2tp.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername()); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpn_l2tp.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername() + ":" + result.getDetails()); } } @@ -2328,10 +2331,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String args = "-d " + json; - String result = routerProxy("vmdata.py", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vmdata.py", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "vm_data failed"); + if (!result.isSuccess()) { + return new Answer(cmd, false, "vm_data failed:" + result.getDetails()); } else { return new Answer(cmd); } @@ -2344,10 +2347,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String args = " -v " + vmIpAddress; args += " -p " + password; - String result = routerProxy("savepassword.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "savepassword.sh", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "savePassword failed"); + if (!result.isSuccess()) { + return new Answer(cmd, false, "savePassword failed:" + result.getDetails()); } return new Answer(cmd); } @@ -2439,10 +2442,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -n"; } - String result = routerProxy("ipassoc.sh", privateIpAddress, args); + ExecutionResult result = executeInVR(privateIpAddress, "ipassoc.sh", args); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"ipassoc\" failed."); + if (!result.isSuccess()) { + throw new InternalErrorException("Xen plugin \"ipassoc\" failed." + result.getDetails()); } if (removeVif) { @@ -2511,18 +2514,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -n "; args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - String result = routerProxy("vpc_ipassoc.sh", routerIp, args); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"vpc_ipassoc\" failed."); + ExecutionResult result = executeInVR(routerIp, "vpc_ipassoc.sh", args); + if (!result.isSuccess()) { + throw new InternalErrorException("Xen plugin \"vpc_ipassoc\" failed." + result.getDetails()); } if (ip.isSourceNat()) { snatArgs += " -l " + ip.getPublicIp(); snatArgs += " -c " + "eth" + correctVif.getDevice(conn); - result = routerProxy("vpc_privateGateway.sh", routerIp, snatArgs); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"vpc_privateGateway\" failed."); + result = executeInVR(routerIp, "vpc_privateGateway.sh", snatArgs); + if (!result.isSuccess()) { + throw new InternalErrorException("Xen plugin \"vpc_privateGateway\" failed." + result.getDetails()); } } @@ -7493,9 +7496,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe String args = " -c " + config; - String result = routerProxy("monitor_service.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "SetMonitorServiceCommand failed to create cfg file."); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "monitor_service.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "SetMonitorServiceCommand failed to create cfg file." + result.getDetails()); } return new Answer(cmd, success, ""); @@ -7504,8 +7507,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) { String[] results = new String[cmd.getRules().length]; - String callResult; - getConnection(); + ExecutionResult callResult; String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); FirewallRuleTO[] allrules = cmd.getRules(); @@ -7536,15 +7538,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } if (trafficType == FirewallRule.TrafficType.Egress) { - callResult = routerProxy("firewall_egress.sh", routerIp, args); + callResult = executeInVR(routerIp, "firewall_egress.sh", args); } else { - callResult = routerProxy("firewall_ingress.sh", routerIp, args); + callResult = executeInVR(routerIp, "firewall_ingress.sh", args); } - if (callResult == null || callResult.isEmpty()) { + if (!callResult.isSuccess()) { //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; + results[i] = "Failed: " + callResult.getDetails(); } return new SetFirewallRulesAnswer(cmd, false, results); } @@ -7844,9 +7846,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (domainName != null && !domainName.isEmpty()) { args += " -e " + domainName; } - String result = routerProxy("vpc_guestnw.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new SetupGuestNetworkAnswer(cmd, false, "creating guest network failed due to " + ((result == null) ? "null" : result)); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_guestnw.sh", args); + if (!result.isSuccess()) { + return new SetupGuestNetworkAnswer(cmd, false, "creating guest network failed due to " + result.getDetails()); } return new SetupGuestNetworkAnswer(cmd, true, "success"); } catch (Exception e) { @@ -7919,9 +7921,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -N "; args += cmd.getPeerGuestCidrList(); } - String result = routerProxy("ipsectunnel.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "Configure site to site VPN failed! "); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "ipsectunnel.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Configure site to site VPN failed! " + result.getDetails()); } return new Answer(cmd); } @@ -7944,9 +7946,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -c "; args += "eth" + correctVif.getDevice(conn); - String result = routerProxy("vpc_snat.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (result == null || result.isEmpty()) { - throw new InternalErrorException("Xen plugin \"vpc_snat\" failed."); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_snat.sh", args); + if (!result.isSuccess()) { + throw new InternalErrorException("Xen plugin \"vpc_snat\" failed." + result.getDetails()); } return new SetSourceNatAnswer(cmd, true, "success"); } catch (Exception e) { @@ -7958,7 +7960,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { String[] results = new String[cmd.getRules().length]; - String callResult; + ExecutionResult callResult; Connection conn = getConnection(); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); @@ -7985,11 +7987,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -d " + "eth" + vif.getDevice(conn); args += " -a " + sb.toString(); - callResult = routerProxy("vpc_privategw_acl.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (callResult == null || callResult.isEmpty()) { + callResult = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_privategw_acl.sh", args); + if (!callResult.isSuccess()) { //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; + results[i] = "Failed:" + callResult.getDetails(); } return new SetNetworkACLAnswer(cmd, false, results); } @@ -8000,11 +8002,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); args += " -a " + sb.toString(); - callResult = routerProxy("vpc_acl.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (callResult == null || callResult.isEmpty()) { + callResult = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_acl.sh", args); + if (!callResult.isSuccess()) { //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; + results[i] = "Failed:" + callResult.getDetails(); } return new SetNetworkACLAnswer(cmd, false, results); } @@ -8031,10 +8033,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe args += " -r " + rule.getDstIp(); args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - String result = routerProxy("vpc_portforwarding.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); + ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_portforwarding.sh", args); - if (result == null || result.isEmpty()) { - results[i++] = "Failed"; + if (!result.isSuccess()) { + results[i++] = "Failed:" + result.getDetails(); endResult = false; } else { results[i++] = null; @@ -8044,7 +8046,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { - String callResult; + ExecutionResult callResult; try { String[] results = new String[cmd.getStaticRoutes().length]; String[][] rules = cmd.generateSRouteRules(); @@ -8054,11 +8056,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe sb.append(srRules[i]).append(','); } String args = "-a " + sb.toString(); - callResult = routerProxy("vpc_staticroute.sh", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args); - if (callResult == null || callResult.isEmpty()) { + callResult = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_staticroute.sh", args); + if (!callResult.isSuccess()) { //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; + results[i] = "Failed:" + callResult.getDetails(); } return new SetStaticRouteAnswer(cmd, false, results); } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java index df43430d481..7e26a5cdb22 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56Resource.java @@ -16,25 +16,6 @@ // under the License. package com.cloud.hypervisor.xen.resource; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import javax.ejb.Local; - -import org.apache.log4j.Logger; -import org.apache.xmlrpc.XmlRpcException; - -import com.xensource.xenapi.Connection; -import com.xensource.xenapi.Host; -import com.xensource.xenapi.Network; -import com.xensource.xenapi.PIF; -import com.xensource.xenapi.Types.IpConfigurationMode; -import com.xensource.xenapi.Types.XenAPIException; -import com.xensource.xenapi.VLAN; -import com.xensource.xenapi.VM; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; @@ -47,6 +28,22 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.resource.ServerResource; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.xensource.xenapi.Connection; +import com.xensource.xenapi.Host; +import com.xensource.xenapi.Network; +import com.xensource.xenapi.PIF; +import com.xensource.xenapi.Types.IpConfigurationMode; +import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VLAN; +import com.xensource.xenapi.VM; +import org.apache.log4j.Logger; +import org.apache.xmlrpc.XmlRpcException; + +import javax.ejb.Local; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; @Local(value = ServerResource.class) public class XenServer56Resource extends CitrixResourceBase { @@ -127,7 +124,7 @@ public class XenServer56Resource extends CitrixResourceBase { @Override protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { - String args = "netusage.sh " + privateIpAddress + " "; + String args = ""; if (option.equals("get")) { args += "-g"; } else if (option.equals("create")) { @@ -142,7 +139,7 @@ public class XenServer56Resource extends CitrixResourceBase { args += vif; } - return callHostPlugin(conn, "vmops", "routerProxy", "args", args); + return executeInVR(privateIpAddress, "netusage.sh", args).getDetails(); } protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) { @@ -151,8 +148,7 @@ public class XenServer56Resource extends CitrixResourceBase { String option = cmd.getOption(); String publicIp = cmd.getGatewayIP(); - String args = "vpc_netusage.sh " + cmd.getPrivateIP(); - args += " -l " + publicIp + " "; + String args = " -l " + publicIp + " "; if (option.equals("get")) { args += "-g"; } else if (option.equals("create")) { @@ -169,7 +165,7 @@ public class XenServer56Resource extends CitrixResourceBase { return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); + String result = executeInVR(cmd.getPrivateIP(), "vpc_netusage.sh", args).getDetails(); if (option.equals("get") || option.equals("vpn")) { long[] stats = new long[2]; if (result != null) { diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 96b786630f2..2f0f347c783 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -230,12 +230,10 @@ def routerProxy(session, args): cmd.insert(0, "/bin/bash") try: txt = util.pread2(cmd) - if txt is None or len(txt) == 0 : - txt = 'success' + txt = 'succ#' + txt except: logging.debug("routerProxy command " + sargs + " failed " ) - txt = '' - + txt = 'fail#' + txt return txt @echo @@ -265,13 +263,12 @@ def createFileInDomr(session, args): f.write(file_contents) f.close() target = "root@" + domrip + ":" + file_path - util.pread2(['scp','-P','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',tmpfile, target]) + txt = util.pread2(['scp','-P','3922','-q','-o','StrictHostKeyChecking=no','-i','/root/.ssh/id_rsa.cloud',tmpfile, target]) util.pread2(['rm',tmpfile]) - txt = 'success' + txt = 'succ#' + txt except: - logging.debug(" failed to create HA proxy cfg file ") - txt = '' - + logging.debug("failed to create file " + file_path + " in VR, contain: " + file_contents) + txt = 'fail#' + txt return txt @echo diff --git a/utils/src/com/cloud/utils/ExecutionResult.java b/utils/src/com/cloud/utils/ExecutionResult.java new file mode 100644 index 00000000000..8edb55b93f3 --- /dev/null +++ b/utils/src/com/cloud/utils/ExecutionResult.java @@ -0,0 +1,44 @@ +// 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.utils; + +public class ExecutionResult { + private Boolean success; + private String details; + + public ExecutionResult(Boolean success, String details) { + this.success = success; + this.details = details; + } + + public Boolean isSuccess() { + return success; + } + + public void setSuccess(Boolean success) { + this.success = success; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } +} From 2d3022594c94b0359ddced70907c8a95014eec96 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Mon, 20 Jan 2014 12:03:06 -0800 Subject: [PATCH 028/126] CLOUDSTACK-5779: Generalize calling to execute or create file for Vmware --- .../vmware/resource/VmwareResource.java | 778 +++++------------- 1 file changed, 216 insertions(+), 562 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 982031bf8c4..e5158cb1bb7 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -312,6 +312,7 @@ import com.cloud.storage.resource.VmwareStorageProcessor; import com.cloud.storage.resource.VmwareStorageSubsystemCommandHandler; import com.cloud.storage.template.TemplateProp; import com.cloud.utils.DateUtil; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; @@ -705,10 +706,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String controlIp = getRouterSshControlIp(cmd); String args = ""; String[] results = new String[cmd.getStaticRoutes().length]; + String[][] rules = cmd.generateSRouteRules(); int i = 0; - // Extract and build the arguments for the command to be sent to the VR. - String[][] rules = cmd.generateSRouteRules(); StringBuilder sb = new StringBuilder(); String[] srRules = rules[0]; for (int j = 0; j < srRules.length; j++) { @@ -716,25 +716,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } args += " -a " + sb.toString(); - // Send over the command for execution, via ssh, to the VR. - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_staticroute.sh " + args); + ExecutionResult result = executeInVR(controlIp, "vpc_staticroute.sh", args); - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/vpc_staticroute.sh " + args); - - if (!result.first()) { - s_logger.error("SetStaticRouteCommand failure on setting one rule. args: " + args); + if (!result.isSuccess()) { + s_logger.error("SetStaticRouteCommand failure on setting one rule. args: " + args); + while (i < results.length) { results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; } - } catch (Throwable e) { - s_logger.error("SetStaticRouteCommand(args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); - results[i++] = "Failed"; endResult = false; } return new SetStaticRouteAnswer(cmd, endResult, results); @@ -762,41 +750,28 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } else { return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - try { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing /opt/cloud/bin/vpc_netusage.sh " + args + " on DomR " + privateIp); + + ExecutionResult callResult = executeInVR(privateIp, "vpc_netusage.sh", args); + + if (!callResult.isSuccess()) { + s_logger.error("Unable to execute NetworkUsage command on DomR (" + privateIp + "), domR may not be ready yet. failure due to " + callResult.getDetails()); + } + + if (option.equals("get") || option.equals("vpn")) { + String result = callResult.getDetails(); + if (result == null || result.isEmpty()) { + s_logger.error(" vpc network usage get returns empty "); } - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - Pair resultPair = - SshHelper.sshExecute(privateIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_netusage.sh " + args); - - if (!resultPair.first()) { - throw new Exception(" vpc network usage plugin call failed "); - - } - - if (option.equals("get") || option.equals("vpn")) { - String result = resultPair.second(); - if (result == null || result.isEmpty()) { - throw new Exception(" vpc network usage get returns empty "); - } - long[] stats = new long[2]; - if (result != null) { - String[] splitResult = result.split(":"); - int i = 0; - while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); - } - return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]); + long[] stats = new long[2]; + if (result != null) { + String[] splitResult = result.split(":"); + int i = 0; + while (i < splitResult.length - 1) { + stats[0] += (new Long(splitResult[i++])).longValue(); + stats[1] += (new Long(splitResult[i++])).longValue(); } + return new NetworkUsageAnswer(cmd, "success", stats[0], stats[1]); } - return new NetworkUsageAnswer(cmd, "success", 0L, 0L); - } catch (Throwable e) { - - s_logger.error( - "Unable to execute NetworkUsage command on DomR (" + privateIp + "), domR may not be ready yet. failure due to " + VmwareHelper.getExceptionMessage(e), e); } return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } @@ -813,23 +788,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -c " + config; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/monitor_service.sh " + args); - - if (!result.first()) { - String msg = "monitor_service.sh failed on domain router " + controlIp + " failed " + result.second(); - s_logger.error(msg); - return new Answer(cmd, false, msg); - } - - return new Answer(cmd); - - } catch (Throwable e) { - s_logger.error("Unexpected exception: " + e.toString(), e); - return new Answer(cmd, false, "SetMonitorServiceCommand failed due to " + VmwareHelper.getExceptionMessage(e)); + ExecutionResult result = executeInVR(controlIp, "monitor_service.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); } + return new Answer(cmd); } protected Answer execute(SetPortForwardingRulesCommand cmd) { @@ -851,24 +814,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -r " + rule.getDstIp(); args += " -d " + rule.getStringDstPortRange(); - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/firewall_nat.sh " + args); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/firewall_nat.sh " + args); - - if (!result.first()) { - s_logger.error("SetPortForwardingRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetPortForwardingRulesCommand(args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); + ExecutionResult result = executeInVR(controlIp, "firewall_nat.sh", args); + if (!result.isSuccess()) { + s_logger.error("SetPortForwardingRulesCommand failure on setting one rule. args: " + args); results[i++] = "Failed"; endResult = false; + } else { + results[i++] = null; } } @@ -905,40 +857,21 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -a " + sb.toString(); } - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + ExecutionResult result = null; - Pair result = null; + if (trafficType == FirewallRule.TrafficType.Egress) { + result = executeInVR(controlIp, "firewall_egress.sh", args); + } else { + result = executeInVR(controlIp, "firewall_ingress.sh", args); + } - if (trafficType == FirewallRule.TrafficType.Egress) { - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/firewall_egress.sh " + args); - } else { - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/firewall_ingress.sh " + args); - } - - if (s_logger.isDebugEnabled()) { - if (trafficType == FirewallRule.TrafficType.Egress) { - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/firewall_egress.sh " + args); - } else { - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/firewall_ingress.sh " + args); - } - } - - if (!result.first()) { - s_logger.error("SetFirewallRulesCommand failure on setting one rule. args: " + args); - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - - return new SetFirewallRulesAnswer(cmd, false, results); - } - } catch (Throwable e) { - s_logger.error("SetFirewallRulesCommand(args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); + if (!result.isSuccess()) { + s_logger.error("SetFirewallRulesCommand failure on setting one rule. args: " + args); //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails for (int i = 0; i < results.length; i++) { results[i] = "Failed"; } + return new SetFirewallRulesAnswer(cmd, false, results); } @@ -951,37 +884,24 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } String[] results = new String[cmd.getRules().length]; - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); String controlIp = getRouterSshControlIp(cmd); int i = 0; boolean endResult = true; for (StaticNatRuleTO rule : cmd.getRules()) { - // Prepare command to be send to VPC VR String args = ""; args += rule.revoked() ? " -D" : " -A"; args += " -l " + rule.getSrcIp(); args += " -r " + rule.getDstIp(); - // Invoke command on VPC VR. - try { - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_staticnat.sh " + args); + ExecutionResult result = executeInVR(controlIp, "vpc_staticnat.sh", args); - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/vpc_staticnat.sh " + args); - - if (!result.first()) { - s_logger.error("SetVPCStaticNatRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetVPCStaticNatRulesCommand (args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); + if (!result.isSuccess()) { + s_logger.error("SetVPCStaticNatRulesCommand failure on setting one rule. args: " + args); results[i++] = "Failed"; endResult = false; + } else { + results[i++] = null; } } return new SetStaticNatRulesAnswer(cmd, results, endResult); @@ -1015,25 +935,15 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -d " + rule.getStringSrcPortRange(); args += " -G "; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/firewall_nat.sh " + args); + String controlIp = getRouterSshControlIp(cmd); + ExecutionResult result = executeInVR(controlIp, "firewall_nat.sh", args); - if (s_logger.isDebugEnabled()) - s_logger.debug("Executing script on domain router " + controlIp + ": /opt/cloud/bin/firewall_nat.sh " + args); - - if (!result.first()) { - s_logger.error("SetStaticNatRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Throwable e) { - s_logger.error("SetStaticNatRulesCommand (args: " + args + ") failed on setting one rule due to " + VmwareHelper.getExceptionMessage(e), e); + if (!result.isSuccess()) { + s_logger.error("SetStaticNatRulesCommand failure on setting one rule. args: " + args); results[i++] = "Failed"; endResult = false; + } else { + results[i++] = null; } } return new SetStaticNatRulesAnswer(cmd, results, endResult); @@ -1076,67 +986,61 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new Answer(cmd, false, "Fail to create LB config file in VR"); } - try { + String[][] rules = cfgtr.generateFwRules(cmd); - String[][] rules = cfgtr.generateFwRules(cmd); + String[] addRules = rules[LoadBalancerConfigurator.ADD]; + String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; + String[] statRules = rules[LoadBalancerConfigurator.STATS]; - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String args = ""; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); + String args = ""; + StringBuilder sb = new StringBuilder(); + if (addRules.length > 0) { + for (int i = 0; i < addRules.length; i++) { + sb.append(addRules[i]).append(','); } - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - Pair result; - if (cmd.getVpcId() == null) { - args = " -i " + routerIp + args; - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/loadbalancer.sh " + args); - } else { - args = " -i " + cmd.getNic().getIp() + args; - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_loadbalancer.sh " + args); - } - // Invoke the command - - if (!result.first()) { - String msg = "LoadBalancerConfigCommand on domain router " + routerIp + " failed. message: " + result.second(); - s_logger.error(msg); - - return new Answer(cmd, false, msg); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("LoadBalancerConfigCommand on domain router " + routerIp + " completed"); - } - return new Answer(cmd); - } catch (Throwable e) { - s_logger.error("Unexpected exception: " + e.toString(), e); - return new Answer(cmd, false, "LoadBalancerConfigCommand failed due to " + VmwareHelper.getExceptionMessage(e)); + args += " -a " + sb.toString(); } + + sb = new StringBuilder(); + if (removeRules.length > 0) { + for (int i = 0; i < removeRules.length; i++) { + sb.append(removeRules[i]).append(','); + } + + args += " -d " + sb.toString(); + } + + sb = new StringBuilder(); + if (statRules.length > 0) { + for (int i = 0; i < statRules.length; i++) { + sb.append(statRules[i]).append(','); + } + + args += " -s " + sb.toString(); + } + + ExecutionResult result; + if (cmd.getVpcId() == null) { + args = " -i " + routerIp + args; + result = executeInVR(controlIp, "loadbalancer.sh", args); + } else { + args = " -i " + cmd.getNic().getIp() + args; + result = executeInVR(controlIp, "vpc_loadbalancer.sh", args); + } + // Invoke the command + + if (!result.isSuccess()) { + String msg = "LoadBalancerConfigCommand on domain router " + routerIp + " failed. message: " + result.getDetails(); + s_logger.error(msg); + + return new Answer(cmd, false, msg); + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("LoadBalancerConfigCommand on domain router " + routerIp + " completed"); + } + return new Answer(cmd); } // @@ -1246,13 +1150,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -e " + domainName; } - Pair result = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_guestnw.sh " + args); + ExecutionResult result = executeInVR(routerIp, "vpc_guestnw.sh", args); - if (!result.first()) { - String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); + if (!result.isSuccess()) { + String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.getDetails(); s_logger.error(msg); - return new SetupGuestNetworkAnswer(cmd, false, msg); } @@ -1303,6 +1205,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); IpAddressTO pubIp = cmd.getIpAddress(); + try { int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress()); String args = ""; @@ -1313,11 +1216,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -c "; args += "eth" + ethDeviceNum; - Pair result = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_snat.sh " + args); + ExecutionResult result = executeInVR(routerIp, "vpc_snat.sh", args); - if (!result.first()) { - String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.second(); + if (!result.isSuccess()) { + String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.getDetails(); s_logger.error(msg); return new SetSourceNatAnswer(cmd, false, msg); @@ -1357,16 +1259,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa NicTO nic = cmd.getNic(); int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, nic.getMac()); String args = ""; - Pair result; + ExecutionResult result; if (privateGw != null) { s_logger.debug("Private gateway configuration is set"); args += " -d " + "eth" + ethDeviceNum; args += " -a " + sb.toString(); - result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_privategw_acl.sh " + args); + result = executeInVR(routerIp, "vpc_privategw_acl.sh", args); - if (!result.first()) { - String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.second(); + if (!result.isSuccess()) { + String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.getDetails(); s_logger.error(msg); return new SetNetworkACLAnswer(cmd, false, results); } @@ -1377,10 +1279,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); args += " -a " + sb.toString(); - result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_acl.sh " + args); + result = executeInVR(routerIp, "vpc_acl.sh", args); - if (!result.first()) { - String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.second(); + if (!result.isSuccess()) { + String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.getDetails(); s_logger.error(msg); return new SetNetworkACLAnswer(cmd, false, results); @@ -1417,19 +1319,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -r " + rule.getDstIp(); args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - try { - Pair sshResult = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_portforwarding.sh " + args); + ExecutionResult sshResult = executeInVR(routerIp, "vpc_portforwarding.sh", args); - if (!sshResult.first()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } catch (Exception e) { + if (!sshResult.isSuccess()) { results[i++] = "Failed"; endResult = false; + } else { + results[i++] = null; } } return new SetPortForwardingRulesAnswer(cmd, results, endResult); @@ -1486,25 +1382,19 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += cmd.getPeerGuestCidrList(); } - Pair result; - try { - result = SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/ipsectunnel.sh " + args); + ExecutionResult result = executeInVR(routerIp, "ipsectunnel.sh", args); - if (!result.first()) { - s_logger.error("Setup site2site VPN " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); + if (!result.isSuccess()) { + s_logger.error("Setup site2site VPN " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.getDetails()); - return new Answer(cmd, false, "Setup site2site VPN falied due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("setup site 2 site vpn on router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "Setup site2site VPN falied due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, "Setup site2site VPN failed due to " + VmwareHelper.getExceptionMessage(e)); + return new Answer(cmd, false, "Setup site2site VPN falied due to " + result.getDetails()); } - return new Answer(cmd, true, result.second()); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("setup site 2 site vpn on router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); + } + + return new Answer(cmd, true, result.getDetails()); } private PlugNicAnswer execute(PlugNicCommand cmd) { @@ -1687,10 +1577,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -n "; args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - Pair result = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_ipassoc.sh " + args); + ExecutionResult result = executeInVR(routerIp, "vpc_ipassoc.sh", args); - if (!result.first()) { + if (!result.isSuccess()) { throw new InternalErrorException("Unable to assign public IP address"); } @@ -1700,10 +1589,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa snatArgs += " -c "; snatArgs += "eth" + ethDeviceNum; - Pair result_gateway = - SshHelper.sshExecute(routerIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpc_privateGateway.sh " + snatArgs); + ExecutionResult result_gateway = executeInVR(routerIp, "vpc_privateGateway.sh", snatArgs); - if (!result_gateway.first()) { + if (!result_gateway.isSuccess()) { throw new InternalErrorException("Unable to configure source NAT for public IP address."); } } @@ -1787,21 +1675,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -n "; } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + privateIpAddress + ", /opt/cloud/bin/ipassoc.sh " + args); - } + ExecutionResult result = executeInVR(privateIpAddress, "ipassoc.sh", args); - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - Pair result = - SshHelper.sshExecute(privateIpAddress, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args); - - if (!result.first()) { - s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second()); - throw new Exception("ipassoc failed due to " + result.second()); + if (!result.isSuccess()) { + s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.getDetails()); + throw new Exception("ipassoc failed due to " + result.getDetails()); } if (removeVif) { - String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK); int nicMasks = Integer.parseInt(nicMasksStr); nicMasks &= ~(1 << publicNicInfo.first().intValue()); @@ -1954,8 +1835,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new IpAssocAnswer(cmd, results); } - protected Pair executeInVR(String script, String routerIP, String args) { + protected ExecutionResult executeInVR(String routerIP, String script, String args) { Pair result; + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args); + } + try { VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); result = SshHelper.sshExecute(routerIP, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/" + script + " " + args); @@ -1964,12 +1850,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.error(msg); result = new Pair(false, msg); } - return result; + if (s_logger.isDebugEnabled()) { + s_logger.debug(script + " execution result: " + result.first().toString()); + } + return new ExecutionResult(result.first(), result.second()); } protected Answer execute(SavePasswordCommand cmd) { if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SavePasswordCommand. vmName: " + cmd.getVmName() + ", vmIp: " + cmd.getVmIpAddress() + ", password: " + StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); } @@ -1978,7 +1866,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa final String password = cmd.getPassword(); final String vmIpAddress = cmd.getVmIpAddress(); - // Run save_password_to_domr.sh String args = " -v " + vmIpAddress; if (s_logger.isDebugEnabled()) { @@ -1988,19 +1875,17 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -p " + password; - Pair result = executeInVR("savepassword.sh", controlIp, args); - if (!result.first()) { - s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.second()); - return new Answer(cmd, false, "SavePassword failed due to " + result.second()); + //TODO: Password should be masked, cannot output to log directly + ExecutionResult result = executeInVR(controlIp, "savepassword.sh", args); + if (!result.isSuccess()) { + s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.getDetails()); + return new Answer(cmd, false, result.getDetails()); } - return new Answer(cmd); + + return new Answer(cmd); } protected Answer execute(DhcpEntryCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource DhcpEntryCommand: " + _gson.toJson(cmd)); - } - // ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/root/edithosts.sh $mac $ip $vm $dfltrt $ns $staticrt" >/dev/null String args = " -m " + cmd.getVmMac(); @@ -2030,68 +1915,29 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -N"; } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/edithosts.sh " + args); - } + String controlIp = getRouterSshControlIp(cmd); + ExecutionResult result = executeInVR(controlIp, "edithosts.sh", args); - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/edithosts.sh " + args); - - if (!result.first()) { - s_logger.error("dhcp_entry command on domR " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "DhcpEntry failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("dhcp_entry command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "DhcpEntryCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); } return new Answer(cmd); } protected Answer execute(final CreateIpAliasCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing createIpAlias command: " + _gson.toJson(cmd)); - } cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); List ipAliasTOs = cmd.getIpAliasList(); String args = ""; for (IpAliasTO ipaliasto : ipAliasTOs) { args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/createIpAlias " + args); - } - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/createIpAlias.sh " + args); + String controlIp = getRouterSshControlIp(cmd); + ExecutionResult result = executeInVR(controlIp, "createIpAlias.sh", args); - if (!result.first()) { - s_logger.error("CreateIpAlias command on domr " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "createipAlias failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("createIpAlias command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "createIpAlias failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); } return new Answer(cmd); @@ -2101,9 +1947,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); List activeIpAliasTOs = cmd.getCreateIpAliasTos(); - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing deleteIpAlias command: " + _gson.toJson(cmd)); - } String args = ""; for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; @@ -2112,39 +1955,18 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa for (IpAliasTO ipAliasTO : activeIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/deleteIpAlias " + args); - } - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/deleteIpAlias.sh " + args); + String controlIp = getRouterSshControlIp(cmd); + ExecutionResult result = executeInVR(controlIp, "deleteIpAlias.sh", args); - if (!result.first()) { - s_logger.error("deleteIpAlias command on domr " + controlIp + " failed, message: " + result.second()); - - return new Answer(cmd, false, "deleteIpAlias failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("deleteIpAlias command on domain router " + controlIp + " completed"); - } - - } catch (Throwable e) { - String msg = "deleteIpAlias failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); } return new Answer(cmd); } protected Answer execute(final DnsMasqConfigCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing dnsmasqConfig command: " + _gson.toJson(cmd)); - } String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String controlIp = getRouterSshControlIp(cmd); @@ -2155,166 +1977,68 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa for (DhcpTO dhcpTo : dhcpTos) { args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; } - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - mgr.getSystemVMKeyFile(); - try { - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/dnsmasq.sh " + args); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + routerIp + ", /opt/cloud/bin/dnsmasq.sh"); - } + ExecutionResult result = executeInVR(controlIp, "dnsmasq.sh", args); - if (!result.first()) { - s_logger.error("Unable update dnsmasq config file"); - return new Answer(cmd, false, "dnsmasq config update failed due to: " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("dnsmasq config command on domain router " + routerIp + " completed"); - } - } catch (Throwable e) { - String msg = "Dnsmasqconfig command failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); } return new Answer(cmd); } protected CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource CheckS2SVpnConnectionsCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/checkbatchs2svpn.sh "); + String controlIp = getRouterSshControlIp(cmd); + String args = ""; + for (String ip : cmd.getVpnIps()) { + args += ip + " "; } - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - String cmdline = "/opt/cloud/bin/checkbatchs2svpn.sh "; - for (String ip : cmd.getVpnIps()) { - cmdline += " " + ip; - } + ExecutionResult result = executeInVR(controlIp, "checkbatchs2svpn.sh", args); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, cmdline); - - if (!result.first()) { - s_logger.error("check site-to-site vpn connections command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + - result.second()); - - return new CheckS2SVpnConnectionsAnswer(cmd, false, result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("check site-to-site vpn connections command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "CheckS2SVpnConnectionsCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); + if (!result.isSuccess()) { + return new CheckS2SVpnConnectionsAnswer(cmd, false, result.getDetails()); } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result.second()); + + return new CheckS2SVpnConnectionsAnswer(cmd, true, result.getDetails()); } protected Answer execute(CheckRouterCommand cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource CheckRouterCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/checkrouter.sh "); + String controlIp = getRouterSshControlIp(cmd); + ExecutionResult result = executeInVR(controlIp, "checkrouter.sh", null); + + if (!result.isSuccess()) { + return new CheckRouterAnswer(cmd, result.getDetails()); } - - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/checkrouter.sh "); - - if (!result.first()) { - s_logger.error("check router command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new CheckRouterAnswer(cmd, "CheckRouter failed due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("check router command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "CheckRouterCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new CheckRouterAnswer(cmd, msg); - } - return new CheckRouterAnswer(cmd, result.second(), true); + return new CheckRouterAnswer(cmd, result.getDetails(), true); } protected Answer execute(GetDomRVersionCmd cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource GetDomRVersionCmd: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/get_template_version.sh "); + String controlIp = getRouterSshControlIp(cmd); + ExecutionResult result = executeInVR(controlIp, "get_template_version.sh", null); + + if (!result.isSuccess()) { + return new GetDomRVersionAnswer(cmd, result.getDetails()); } - - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/get_template_version.sh "); - - if (!result.first()) { - s_logger.error("GetDomRVersionCmd on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("GetDomRVersionCmd on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "GetDomRVersionCmd failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new GetDomRVersionAnswer(cmd, msg); - } - String[] lines = result.second().split("&"); + String[] lines = result.getDetails().split("&"); if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result.second()); + return new GetDomRVersionAnswer(cmd, result.getDetails()); } - return new GetDomRVersionAnswer(cmd, result.second(), lines[0], lines[1]); + return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]); } protected Answer execute(BumpUpPriorityCommand cmd) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing resource BumpUpPriorityCommand: " + _gson.toJson(cmd)); - s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/bumpup_priority.sh "); + String controlIp = getRouterSshControlIp(cmd); + ExecutionResult result = executeInVR(controlIp, "bumpup_priority.sh", null); + + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); } - Pair result; - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); - result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/bumpup_priority.sh "); - - if (!result.first()) { - s_logger.error("BumpUpPriority command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second()); - - return new Answer(cmd, false, "BumpUpPriorityCommand failed due to " + result.second()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("BumpUpPriorityCommand on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - } catch (Throwable e) { - String msg = "BumpUpPriorityCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); - } - if (result.second() == null || result.second().isEmpty()) { - return new Answer(cmd, true, result.second()); - } - return new Answer(cmd, false, result.second()); + return new Answer(cmd); } protected Answer execute(VmDataCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource VmDataCommand: " + _gson.toJson(cmd)); - } - String controlIp = getRouterSshControlIp(cmd); Map> data = new HashMap>(); data.put(cmd.getVmIpAddress(), cmd.getVmData()); @@ -2326,23 +2050,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String args = "-d " + json; - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + ExecutionResult result = executeInVR(controlIp, "vmdata.py", args); - try { - Pair result = SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vmdata.py " + args); - if (!result.first()) { - s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second()); - return new Answer(cmd, false, "VmDataCommand failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("vm_data command on domain router " + controlIp + " completed"); - } - } catch (Throwable e) { - String msg = "VmDataCommand failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); } + return new Answer(cmd); } @@ -3588,44 +3301,19 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa argsBuf.append(" -C ").append(cmd.getLocalCidr()); argsBuf.append(" -i ").append(cmd.getPublicInterface()); - try { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing /opt/cloud/bin/vpn_lt2p.sh "); - } + ExecutionResult result = executeInVR(controlIp, "vpn_l2tp.sh", argsBuf.toString()); - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpn_l2tp.sh " + argsBuf.toString()); - - if (!result.first()) { - s_logger.error("RemoteAccessVpnCfg command on domR failed, message: " + result.second()); - - return new Answer(cmd, false, "RemoteAccessVpnCfg command failed due to " + result.second()); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("RemoteAccessVpnCfg command on domain router " + argsBuf.toString() + " completed"); - } - - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "RemoteAccessVpnCfg command failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); } return new Answer(cmd); } protected Answer execute(final VpnUsersCfgCommand cmd) { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String controlIp = getRouterSshControlIp(cmd); + for (VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) { StringBuffer argsBuf = new StringBuffer(); if (!userpwd.isAdd()) { @@ -3634,29 +3322,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa argsBuf.append(" -u ").append(userpwd.getUsernamePassword()); } - try { + ExecutionResult result = executeInVR(controlIp, "vpn_l2tp.sh", argsBuf.toString()); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Executing /opt/cloud/bin/vpn_lt2p.sh "); - } - - Pair result = - SshHelper.sshExecute(controlIp, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/vpn_l2tp.sh " + argsBuf.toString()); - - if (!result.first()) { - s_logger.error("VpnUserCfg command on domR failed, message: " + result.second()); - - return new Answer(cmd, false, "VpnUserCfg command failed due to " + result.second()); - } - } catch (Throwable e) { - if (e instanceof RemoteException) { - s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); - invalidateServiceContext(); - } - - String msg = "VpnUserCfg command failed due to " + VmwareHelper.getExceptionMessage(e); - s_logger.error(msg, e); - return new Answer(cmd, false, msg); + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); } } @@ -6519,28 +6188,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += ethName; } - try { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Executing /opt/cloud/bin/netusage.sh " + args + " on DomR " + privateIpAddress); - } + ExecutionResult result = executeInVR(privateIpAddress, "netusage.sh", args); - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - Pair result = - SshHelper.sshExecute(privateIpAddress, DefaultDomRSshPort, "root", mgr.getSystemVMKeyFile(), null, "/opt/cloud/bin/netusage.sh " + args); - - if (!result.first()) { - return null; - } - - return result.second(); - } catch (Throwable e) { - s_logger.error( - "Unable to execute NetworkUsage command on DomR (" + privateIpAddress + "), domR may not be ready yet. failure due to " + - VmwareHelper.getExceptionMessage(e), e); + if (!result.isSuccess()) { + return null; } - return null; + return result.getDetails(); } private long[] getNetworkStats(String privateIP) { From 285f23f11be9d7908e9e3b087d977dc0e223f4fe Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Mon, 20 Jan 2014 12:03:06 -0800 Subject: [PATCH 029/126] CLOUDSTACK-5779: Generalize calling to execute or create file for KVM --- .../com/cloud/agent/api/to/IpAddressTO.java | 17 + .../api/routing/NetworkElementCommand.java | 13 +- .../virtualnetwork/VirtualRouterDeployer.java | 27 + .../VirtualRoutingResource.java | 824 +++++++----------- .../resource/LibvirtComputingResource.java | 316 +++---- .../cloud/utils/script/OutputInterpreter.java | 4 +- utils/src/com/cloud/utils/script/Script.java | 15 +- 7 files changed, 498 insertions(+), 718 deletions(-) create mode 100644 core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java diff --git a/api/src/com/cloud/agent/api/to/IpAddressTO.java b/api/src/com/cloud/agent/api/to/IpAddressTO.java index 5f31313eba9..1169820e19a 100644 --- a/api/src/com/cloud/agent/api/to/IpAddressTO.java +++ b/api/src/com/cloud/agent/api/to/IpAddressTO.java @@ -33,6 +33,8 @@ public class IpAddressTO { private Integer networkRate; private TrafficType trafficType; private String networkName; + private Integer nicDevId; + private boolean newNic; public IpAddressTO(long accountId, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String broadcastUri, String vlanGateway, String vlanNetmask, String vifMacAddress, Integer networkRate, boolean isOneToOneNat) { @@ -116,4 +118,19 @@ public class IpAddressTO { return networkRate; } + public Integer getNicDevId() { + return nicDevId; + } + + public void setNicDevId(Integer nicDevId) { + this.nicDevId = nicDevId; + } + + public boolean isNewNic() { + return newNic; + } + + public void setNewNic(boolean newNic) { + this.newNic = newNic; + } } diff --git a/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java b/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java index 9a2bea875b4..217e962d18a 100644 --- a/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java +++ b/core/src/com/cloud/agent/api/routing/NetworkElementCommand.java @@ -16,10 +16,10 @@ // under the License. package com.cloud.agent.api.routing; -import java.util.HashMap; - import com.cloud.agent.api.Command; +import java.util.HashMap; + public abstract class NetworkElementCommand extends Command { HashMap accessDetails = new HashMap(0); @@ -35,6 +35,8 @@ public abstract class NetworkElementCommand extends Command { public static final String VPC_PRIVATE_GATEWAY = "vpc.gateway.private"; public static final String FIREWALL_EGRESS_DEFAULT = "firewall.egress.default"; + private String routerAccessIp; + protected NetworkElementCommand() { super(); } @@ -52,4 +54,11 @@ public abstract class NetworkElementCommand extends Command { return false; } + public String getRouterAccessIp() { + return routerAccessIp; + } + + public void setRouterAccessIp(String routerAccessIp) { + this.routerAccessIp = routerAccessIp; + } } diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java new file mode 100644 index 00000000000..243098abeab --- /dev/null +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRouterDeployer.java @@ -0,0 +1,27 @@ +// 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.resource.virtualnetwork; + +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.utils.ExecutionResult; + +public interface VirtualRouterDeployer { + ExecutionResult executeInVR(String routerIp, String script, String args); + ExecutionResult createFileInVR(String routerIp, String path, String filename, String content); + ExecutionResult prepareCommand(NetworkElementCommand cmd); + ExecutionResult cleanupCommand(NetworkElementCommand cmd); +} diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index b27ed55c7a3..f63824e2e8b 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -25,9 +25,8 @@ import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; -import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; -import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; -import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; +import com.cloud.agent.api.SetupGuestNetworkAnswer; +import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.routing.CreateIpAliasCommand; import com.cloud.agent.api.routing.DeleteIpAliasCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; @@ -35,6 +34,7 @@ import com.cloud.agent.api.routing.DnsMasqConfigCommand; import com.cloud.agent.api.routing.IpAliasTO; import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; +import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; @@ -42,9 +42,13 @@ import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetFirewallRulesAnswer; import com.cloud.agent.api.routing.SetFirewallRulesCommand; import com.cloud.agent.api.routing.SetMonitorServiceCommand; +import com.cloud.agent.api.routing.SetNetworkACLAnswer; +import com.cloud.agent.api.routing.SetNetworkACLCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; +import com.cloud.agent.api.routing.SetSourceNatAnswer; +import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.SetStaticRouteAnswer; @@ -55,33 +59,22 @@ import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; -import com.cloud.exception.InternalErrorException; import com.cloud.network.HAProxyConfigurator; import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.rules.FirewallRule; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; -import com.cloud.utils.component.ComponentLifecycle; -import com.cloud.utils.component.Manager; import com.cloud.utils.net.NetUtils; -import com.cloud.utils.script.OutputInterpreter; -import com.cloud.utils.script.Script; -import com.cloud.utils.ssh.SshHelper; import com.google.gson.Gson; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; -import javax.ejb.Local; import javax.naming.ConfigurationException; -import java.io.BufferedReader; -import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.net.InetSocketAddress; -import java.net.URL; -import java.net.URLConnection; import java.nio.channels.SocketChannel; import java.util.HashMap; import java.util.List; @@ -95,24 +88,27 @@ import java.util.Map; * || Param Name | Description | Values | Default || * } **/ -@Local(value = {VirtualRoutingResource.class}) -public class VirtualRoutingResource implements Manager { +public class VirtualRoutingResource { private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class); - private String _publicIpAddress; - private String _publicEthIf; - private String _privateEthIf; - private String _routerProxyPath; + private VirtualRouterDeployer _vrDeployer; - private int _timeout; - private int _startTimeout; - private String _scriptsDir; private String _name; private int _sleep; private int _retry; private int _port; + public VirtualRoutingResource(VirtualRouterDeployer deployer) { + this._vrDeployer = deployer; + } + public Answer executeRequest(final Command cmd) { try { + ExecutionResult rc = _vrDeployer.prepareCommand((NetworkElementCommand)cmd); + if (!rc.isSuccess()) { + s_logger.error("Failed to prepare VR command due to " + rc.getDetails()); + return new Answer(cmd, false, rc.getDetails()); + } + if (cmd instanceof SetPortForwardingRulesVpcCommand) { return execute((SetPortForwardingRulesVpcCommand)cmd); } else if (cmd instanceof SetPortForwardingRulesCommand) { @@ -123,12 +119,6 @@ public class VirtualRoutingResource implements Manager { return execute((SetStaticNatRulesCommand)cmd); } else if (cmd instanceof LoadBalancerConfigCommand) { return execute((LoadBalancerConfigCommand)cmd); - } else if (cmd instanceof IpAssocCommand) { - return execute((IpAssocCommand)cmd); - } else if (cmd instanceof CheckConsoleProxyLoadCommand) { - return execute((CheckConsoleProxyLoadCommand)cmd); - } else if (cmd instanceof WatchConsoleProxyLoadCommand) { - return execute((WatchConsoleProxyLoadCommand)cmd); } else if (cmd instanceof SavePasswordCommand) { return execute((SavePasswordCommand)cmd); } else if (cmd instanceof DhcpEntryCommand) { @@ -158,12 +148,27 @@ public class VirtualRoutingResource implements Manager { } else if (cmd instanceof CheckS2SVpnConnectionsCommand) { return execute((CheckS2SVpnConnectionsCommand)cmd); } else if (cmd instanceof SetMonitorServiceCommand) { - return execute((SetMonitorServiceCommand) cmd); + return execute((SetMonitorServiceCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return execute((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return execute((SetNetworkACLCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return execute((SetSourceNatCommand)cmd); + } else if (cmd instanceof IpAssocVpcCommand) { + return execute((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return execute((IpAssocCommand)cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } } catch (final IllegalArgumentException e) { return new Answer(cmd, false, e.getMessage()); + } finally { + ExecutionResult rc = _vrDeployer.cleanupCommand((NetworkElementCommand)cmd); + if (!rc.isSuccess()) { + s_logger.error("Failed to cleanup VR command due to " + rc.getDetails()); + } } } @@ -177,9 +182,9 @@ public class VirtualRoutingResource implements Manager { args += "-u "; args += userpwd.getUsernamePassword(); } - String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpn_l2tp.sh", args); - if (result != null) { - return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername()); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpn_l2tp.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername() + ":" + result.getDetails()); } } return new Answer(cmd); @@ -204,11 +209,8 @@ public class VirtualRoutingResource implements Manager { } args += " -C " + cmd.getLocalCidr(); args += " -i " + cmd.getPublicInterface(); - String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpn_l2tp.sh", args); - if (result != null) { - return new Answer(cmd, false, "Configure VPN failed"); - } - return new Answer(cmd); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpn_l2tp.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } private Answer execute(SetFirewallRulesCommand cmd) { @@ -216,10 +218,10 @@ public class VirtualRoutingResource implements Manager { for (int i = 0; i < cmd.getRules().length; i++) { results[i] = "Failed"; } - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String routerAccessIp = cmd.getRouterAccessIp(); String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - if (routerIp == null) { + if (routerAccessIp == null) { return new SetFirewallRulesAnswer(cmd, false, results); } @@ -230,7 +232,7 @@ public class VirtualRoutingResource implements Manager { String args = " -F"; if (trafficType == FirewallRule.TrafficType.Egress) { - args += "-E"; + args += " -E"; if (egressDefault.equals("true")) { args += " -P 1"; } else if (egressDefault.equals("System")) { @@ -249,15 +251,15 @@ public class VirtualRoutingResource implements Manager { args += " -a " + sb.toString(); } - String result = null; + ExecutionResult result; if (trafficType == FirewallRule.TrafficType.Egress) { - result = executeInVR(routerIp, "firewall_egress.sh", args); + result = _vrDeployer.executeInVR(routerAccessIp, "firewall_egress.sh", args); } else { - result = executeInVR(routerIp, "firewall_ingress.sh", args); + result = _vrDeployer.executeInVR(routerAccessIp, "firewall_ingress.sh", args); } - if (result != null) { + if (!result.isSuccess()) { return new SetFirewallRulesAnswer(cmd, false, results); } return new SetFirewallRulesAnswer(cmd, true, null); @@ -265,7 +267,6 @@ public class VirtualRoutingResource implements Manager { } private Answer execute(SetPortForwardingRulesCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; @@ -278,9 +279,9 @@ public class VirtualRoutingResource implements Manager { args.append(" -r ").append(rule.getDstIp()); args.append(" -d ").append(rule.getStringDstPortRange()); - String result = executeInVR(routerIp, "firewall_nat.sh", args.toString()); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "firewall_nat.sh", args.toString()); - if (result == null || result.isEmpty()) { + if (!result.isSuccess()) { results[i++] = "Failed"; endResult = false; } else { @@ -292,7 +293,6 @@ public class VirtualRoutingResource implements Manager { } protected Answer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; @@ -302,9 +302,9 @@ public class VirtualRoutingResource implements Manager { args += " -l " + rule.getSrcIp(); args += " -r " + rule.getDstIp(); - String result = executeInVR(routerIp, "vpc_staticnat.sh", args); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_staticnat.sh", args); - if (result == null) { + if (!result.isSuccess()) { results[i++] = null; } else { results[i++] = "Failed"; @@ -319,7 +319,6 @@ public class VirtualRoutingResource implements Manager { if (cmd.getVpcId() != null) { return SetVPCStaticNatRules(cmd); } - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; @@ -337,9 +336,9 @@ public class VirtualRoutingResource implements Manager { args.append(" -d ").append(rule.getStringSrcPortRange()); args.append(" -G "); - String result = executeInVR(routerIp, "firewall_nat.sh", args.toString()); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "firewall_nat.sh", args.toString()); - if (result == null || result.isEmpty()) { + if (!result.isSuccess()) { results[i++] = "Failed"; endResult = false; } else { @@ -350,19 +349,6 @@ public class VirtualRoutingResource implements Manager { return new SetStaticNatRulesAnswer(cmd, results, endResult); } - protected boolean createFileInVR(String routerIp, String path, String filename, String content) { - File permKey = new File("/root/.ssh/id_rsa.cloud"); - boolean result = true; - - try { - SshHelper.scpTo(routerIp, 3922, "root", permKey, null, path, content.getBytes(), filename, null); - } catch (Exception e) { - s_logger.warn("Fail to create file " + path + filename + " in VR " + routerIp, e); - result = false; - } - return result; - } - private Answer execute(LoadBalancerConfigCommand cmd) { String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); @@ -378,67 +364,58 @@ public class VirtualRoutingResource implements Manager { tmpCfgFileContents += "\n"; } - if (!createFileInVR(routerIp, "/etc/haproxy/", "haproxy.cfg.new", tmpCfgFileContents)) { + if (!_vrDeployer.createFileInVR(cmd.getRouterAccessIp(), "/etc/haproxy/", "haproxy.cfg.new", tmpCfgFileContents).isSuccess()) { return new Answer(cmd, false, "Fail to copy LB config file to VR"); } - try { - String[][] rules = cfgtr.generateFwRules(cmd); + String[][] rules = cfgtr.generateFwRules(cmd); - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; + String[] addRules = rules[LoadBalancerConfigurator.ADD]; + String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; + String[] statRules = rules[LoadBalancerConfigurator.STATS]; - String args = ""; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - args += " -a " + sb.toString(); + String args = ""; + StringBuilder sb = new StringBuilder(); + if (addRules.length > 0) { + for (int i = 0; i < addRules.length; i++) { + sb.append(addRules[i]).append(','); } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - String result; - - if (cmd.getVpcId() == null) { - args = " -i " + routerIp + args; - result = executeInVR(routerIp, "loadbalancer.sh", args); - } else { - args = " -i " + cmd.getNic().getIp() + args; - result = executeInVR(routerIp, "vpc_loadbalancer.sh", args); - } - - if (result != null) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed"); - } - return new Answer(cmd); - - } catch (Exception e) { - return new Answer(cmd, e); + args += " -a " + sb.toString(); } + + sb = new StringBuilder(); + if (removeRules.length > 0) { + for (int i = 0; i < removeRules.length; i++) { + sb.append(removeRules[i]).append(','); + } + + args += " -d " + sb.toString(); + } + + sb = new StringBuilder(); + if (statRules.length > 0) { + for (int i = 0; i < statRules.length; i++) { + sb.append(statRules[i]).append(','); + } + + args += " -s " + sb.toString(); + } + + ExecutionResult result; + + if (cmd.getVpcId() == null) { + args = " -i " + routerIp + args; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "loadbalancer.sh", args); + } else { + args = " -i " + cmd.getNic().getIp() + args; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_loadbalancer.sh", args); + } + + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(VmDataCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); Map> data = new HashMap>(); data.put(cmd.getVmIpAddress(), cmd.getVmData()); @@ -449,32 +426,8 @@ public class VirtualRoutingResource implements Manager { String args = "-d " + json; - final String result = executeInVR(routerIp, "vmdata.py", args); - if (result != null) { - return new Answer(cmd, false, "VmDataCommand failed, check agent logs"); - } - return new Answer(cmd); - } - - protected Answer execute(final IpAssocCommand cmd) { - IpAddressTO[] ips = cmd.getIpAddresses(); - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; - String result = null; - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - for (IpAddressTO ip : ips) { - result = - assignPublicIpAddress(routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(), - ip.getVlanNetmask(), ip.getVifMacAddress(), 2, false); - if (result != null) { - results[i++] = IpAssocAnswer.errorResult; - } else { - results[i++] = ip.getPublicIp() + " - success"; - ; - } - } - return new IpAssocAnswer(cmd, results); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vmdata.py", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final SavePasswordCommand cmd) { @@ -485,11 +438,8 @@ public class VirtualRoutingResource implements Manager { String args = "-v " + vmIpAddress; args += " -p " + password; - String result = executeInVR(routerPrivateIPAddress, "savepassword.sh", args); - if (result != null) { - return new Answer(cmd, false, "Unable to save password to DomR."); - } - return new Answer(cmd); + ExecutionResult result = _vrDeployer.executeInVR(routerPrivateIPAddress, "savepassword.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final DhcpEntryCommand cmd) { @@ -520,23 +470,21 @@ public class VirtualRoutingResource implements Manager { args += " -N"; } - final String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "edithosts.sh", args); - return new Answer(cmd, result == null, result); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "edithosts.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final CreateIpAliasCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); List ipAliasTOs = cmd.getIpAliasList(); String args = ""; for (IpAliasTO ipaliasto : ipAliasTOs) { args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; } - final String result = executeInVR(routerIp, "createipAlias.sh", args); - return new Answer(cmd, result == null, result); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "createipAlias.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final DeleteIpAliasCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String args = ""; List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { @@ -547,38 +495,18 @@ public class VirtualRoutingResource implements Manager { for (IpAliasTO ipAliasTO : activeIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; } - final String result = executeInVR(routerIp, "deleteipAlias.sh", args); - return new Answer(cmd, result == null, result); + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "deleteipAlias.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(final DnsMasqConfigCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); List dhcpTos = cmd.getIps(); String args = ""; for (DhcpTO dhcpTo : dhcpTos) { args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; } - final String result = executeInVR(routerIp, "dnsmasq.sh", args); - return new Answer(cmd, result == null, result); - } - - public String getRouterStatus(String routerIP) { - return routerProxyWithParser("checkrouter.sh", routerIP, null); - } - - public String routerProxyWithParser(String script, String routerIP, String args) { - final Script command = new Script(_routerProxyPath, _timeout, s_logger); - final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser(); - command.add(script); - command.add(routerIP); - if (args != null) { - command.add(args); - } - String result = command.execute(parser); - if (result == null) { - return parser.getLine(); - } - return null; + final ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "dnsmasq.sh", args); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { @@ -589,65 +517,37 @@ public class VirtualRoutingResource implements Manager { args += " " + ip; } - final String result = executeInVR(routerIP, "checkbatchs2svpn.sh", args); - if (result == null || result.isEmpty()) { - return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); - } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result); - } - - public String executeInVR(String routerIP, String script, String args) { - final Script command = new Script(_routerProxyPath, _timeout, s_logger); - command.add(script); - command.add(routerIP); - if (args != null) { - command.add(args); - } - return command.execute(); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "checkbatchs2svpn.sh", args); + return new CheckS2SVpnConnectionsAnswer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(CheckRouterCommand cmd) { final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final String result = getRouterStatus(routerPrivateIPAddress); - if (result == null || result.isEmpty()) { - return new CheckRouterAnswer(cmd, "CheckRouterCommand failed"); + final ExecutionResult result = _vrDeployer.executeInVR(routerPrivateIPAddress, "checkrouter.sh", null); + if (!result.isSuccess()) { + return new CheckRouterAnswer(cmd, result.getDetails()); } - return new CheckRouterAnswer(cmd, result, true); + return new CheckRouterAnswer(cmd, result.getDetails(), true); } protected Answer execute(BumpUpPriorityCommand cmd) { - String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "bumpup_priority.sh", null); - if (result != null) { - return new Answer(cmd, false, "BumpUpPriorityCommand failed due to " + result); - } - return new Answer(cmd, true, null); - } - - protected String getDomRVersion(String routerIP) { - return routerProxyWithParser("get_template_version.sh", routerIP, null); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "bumpup_priority.sh", null); + return new Answer(cmd, result.isSuccess(), result.getDetails()); } protected Answer execute(GetDomRVersionCmd cmd) { final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - final String result = getDomRVersion(routerPrivateIPAddress); - if (result == null || result.isEmpty()) { + final ExecutionResult result = _vrDeployer.executeInVR(routerPrivateIPAddress, "get_template_version.sh", null); + if (!result.isSuccess()) { return new GetDomRVersionAnswer(cmd, "GetDomRVersionCmd failed"); } - String[] lines = result.split("&"); + String[] lines = result.getDetails().split("&"); if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result); + return new GetDomRVersionAnswer(cmd, result.getDetails()); } - return new GetDomRVersionAnswer(cmd, result, lines[0], lines[1]); - } - - protected Answer execute(final CheckConsoleProxyLoadCommand cmd) { - return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); - } - - protected Answer execute(final WatchConsoleProxyLoadCommand cmd) { - return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort()); + return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]); } protected Answer execute(Site2SiteVpnCfgCommand cmd) { @@ -692,59 +592,45 @@ public class VirtualRoutingResource implements Manager { args += " -N "; args += cmd.getPeerGuestCidrList(); } - String result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "ipsectunnel.sh", args); - if (result != null) { - return new Answer(cmd, false, "Configure site to site VPN failed due to " + result); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "ipsectunnel.sh", args); + if (!result.isSuccess()) { + return new Answer(cmd, false, "Configure site to site VPN failed due to " + result.getDetails()); } return new Answer(cmd); } - private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) { - String result = null; - - final StringBuffer sb = new StringBuffer(); - sb.append("http://").append(proxyManagementIp).append(":" + cmdPort).append("/cmd/getstatus"); - - boolean success = true; - try { - final URL url = new URL(sb.toString()); - final URLConnection conn = url.openConnection(); - - final InputStream is = conn.getInputStream(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - final StringBuilder sb2 = new StringBuilder(); - String line = null; - try { - while ((line = reader.readLine()) != null) { - sb2.append(line + "\n"); - } - result = sb2.toString(); - } catch (final IOException e) { - success = false; - } finally { - try { - is.close(); - } catch (final IOException e) { - s_logger.warn("Exception when closing , console proxy address : " + proxyManagementIp); - success = false; - } - } - } catch (final IOException e) { - s_logger.warn("Unable to open console proxy command port url, console proxy address : " + proxyManagementIp); - success = false; - } - - return new ConsoleProxyLoadAnswer(cmd, proxyVmId, proxyVmName, success, result); - } - - public String configureMonitor(final String routerIP, final String config) { + protected Answer execute(SetMonitorServiceCommand cmd) { + String config = cmd.getConfiguration(); String args = " -c " + config; - return executeInVR(routerIP, "monitor_service.sh", args); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "monitor_service.sh", args); + + if (!result.isSuccess()) { + return new Answer(cmd, false, result.getDetails()); + } + return new Answer(cmd); } - public String assignGuestNetwork(final String dev, final String routerIP, final String routerGIP, final String gateway, final String cidr, final String netmask, - final String dns, final String domainName) { + protected SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + NicTO nic = cmd.getNic(); + String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String routerGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); + String gateway = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); + String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + String domainName = cmd.getNetworkDomain(); + String dns = cmd.getDefaultDns1(); + + if (dns == null || dns.isEmpty()) { + dns = cmd.getDefaultDns2(); + } else { + String dns2 = cmd.getDefaultDns2(); + if (dns2 != null && !dns2.isEmpty()) { + dns += "," + dns2; + } + } + + String dev = "eth" + nic.getDeviceId(); + String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); String args = " -C"; args += " -d " + dev; @@ -758,33 +644,74 @@ public class VirtualRoutingResource implements Manager { if (domainName != null && !domainName.isEmpty()) { args += " -e " + domainName; } - return executeInVR(routerIP, "vpc_guestnw.sh", args); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_guestnw.sh", args); + + if (!result.isSuccess()) { + return new SetupGuestNetworkAnswer(cmd, false, "Creating guest network failed due to " + result.getDetails()); + } + return new SetupGuestNetworkAnswer(cmd, true, "success"); } - public String assignNetworkACL(final String routerIP, final String dev, final String routerGIP, final String netmask, final String rule, String privateGw) { - String args = " -d " + dev; - if (privateGw != null) { - args += " -a " + rule; - return executeInVR(routerIP, "vpc_privategw_acl.sh", args); - } else { - args += " -i " + routerGIP; - args += " -m " + netmask; - args += " -a " + rule; - return executeInVR(routerIP, "vpc_acl.sh", args); + private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { + String[] results = new String[cmd.getRules().length]; + + String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); + + try { + String[][] rules = cmd.generateFwRules(); + String[] aclRules = rules[0]; + NicTO nic = cmd.getNic(); + String dev = "eth" + nic.getDeviceId(); + String netmask = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < aclRules.length; i++) { + sb.append(aclRules[i]).append(','); + } + + String rule = sb.toString(); + ExecutionResult result; + + String args = " -d " + dev; + if (privateGw != null) { + args += " -a " + rule; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_privategw_acl.sh", args); + } else { + args += " -i " + nic.getIp(); + args += " -m " + netmask; + args += " -a " + rule; + result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_acl.sh", args); + } + + if (!result.isSuccess()) { + for (int i = 0; i < results.length; i++) { + results[i] = "Failed"; + } + return new SetNetworkACLAnswer(cmd, false, results); + } + + return new SetNetworkACLAnswer(cmd, true, results); + } catch (Exception e) { + String msg = "SetNetworkACL failed due to " + e.toString(); + s_logger.error(msg, e); + return new SetNetworkACLAnswer(cmd, false, results); } } - public String assignSourceNat(final String routerIP, final String pubIP, final String dev) { + protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + IpAddressTO pubIP = cmd.getIpAddress(); + String dev = "eth" + pubIP.getNicDevId(); String args = " -A "; args += " -l "; - args += pubIP; + args += pubIP.getPublicIp(); args += " -c "; args += dev; - return executeInVR(routerIP, "vpc_snat.sh", args); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_snat.sh", args); + return new SetSourceNatAnswer(cmd, result.isSuccess(), result.getDetails()); } private SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String[] results = new String[cmd.getRules().length]; int i = 0; @@ -797,9 +724,9 @@ public class VirtualRoutingResource implements Manager { args += " -r " + rule.getDstIp(); args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - String result = executeInVR(routerIp, "vpc_portforwarding.sh", args); + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "vpc_portforwarding.sh", args); - if (result != null) { + if (!result.isSuccess()) { results[i++] = "Failed"; endResult = false; } else { @@ -809,44 +736,56 @@ public class VirtualRoutingResource implements Manager { return new SetPortForwardingRulesAnswer(cmd, results, endResult); } - public void assignVpcIpToRouter(final String routerIP, final boolean add, final String pubIP, final String nicname, final String gateway, final String netmask, - final String subnet, boolean sourceNat) throws InternalErrorException { + public IpAssocAnswer execute(IpAssocVpcCommand cmd) { + String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + String[] results = new String[cmd.getIpAddresses().length]; String args = ""; String snatArgs = ""; - - if (add) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; + for (int i = 0; i < cmd.getIpAddresses().length; i ++) { + results[i] = "Failed"; } - args += " -l "; - args += pubIP; - args += " -c "; - args += nicname; - args += " -g "; - args += gateway; - args += " -m "; - args += netmask; - args += " -n "; - args += subnet; - - String result = executeInVR(routerIP, "vpc_ipassoc.sh", args); - if (result != null) { - throw new InternalErrorException("KVM plugin \"vpc_ipassoc\" failed:" + result); - } - if (sourceNat) { - snatArgs += " -l " + pubIP; - snatArgs += " -c " + nicname; - - result = executeInVR(routerIP, "vpc_privateGateway.sh", snatArgs); - if (result != null) { - throw new InternalErrorException("KVM plugin \"vpc_privateGateway\" failed:" + result); + int i = 0; + for (IpAddressTO ip : cmd.getIpAddresses()) { + if (ip.isAdd()) { + args += " -A "; + snatArgs += " -A "; + } else { + args += " -D "; + snatArgs += " -D "; } + args += " -l "; + args += ip.getPublicIp(); + String nicName = "eth" + ip.getNicDevId(); + args += " -c "; + args += nicName; + args += " -g "; + args += ip.getVlanGateway(); + args += " -m "; + args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + args += " -n "; + args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); + + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_ipassoc.sh", args); + if (!result.isSuccess()) { + results[i++] = ip.getPublicIp() + " - vpc_ipassoc failed:" + result.getDetails(); + break; + } + + if (ip.isSourceNat()) { + snatArgs += " -l " + ip.getPublicIp(); + snatArgs += " -c " + nicName; + + result = _vrDeployer.executeInVR(routerIP, "vpc_privateGateway.sh", snatArgs); + if (result != null) { + results[i++] = ip.getPublicIp() + " - vpc_privateGateway failed:" + result.getDetails(); + break; + } + } + results[i++] = ip.getPublicIp() + " - success "; } + return new IpAssocAnswer(cmd, results); } private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { @@ -862,9 +801,9 @@ public class VirtualRoutingResource implements Manager { } String args = " -a " + sb.toString(); - String result = executeInVR(routerIP, "vpc_staticroute.sh", args); + ExecutionResult result = _vrDeployer.executeInVR(routerIP, "vpc_staticroute.sh", args); - if (result != null) { + if (!result.isSuccess()) { for (int i = 0; i < results.length; i++) { results[i] = "Failed"; } @@ -879,161 +818,56 @@ public class VirtualRoutingResource implements Manager { } } - private Answer execute(SetMonitorServiceCommand cmd) { - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String config = cmd.getConfiguration(); - - String result = configureMonitor(routerIp, config); - - if (result != null) { - return new Answer(cmd, false, "SetMonitorServiceCommand failed"); - } - return new Answer(cmd); - - } - - public String assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, - final boolean sourceNat, final String broadcastUri, final String vlanGateway, final String vlanNetmask, final String vifMacAddress, int nicNum, boolean newNic) { - - String args = ""; - if (add) { - args += "-A"; - } else { - args += "-D"; - } - String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - if (sourceNat) { - args += " -s"; - } - if (firstIP) { - args += " -f"; - } - args += " -l "; - args += publicIpAddress + "/" + cidrSize; - - String publicNic = "eth" + nicNum; - args += " -c "; - args += publicNic; - - args += " -g "; - args += vlanGateway; - - if (newNic) { - args += " -n"; + public Answer execute(IpAssocCommand cmd) { + String[] results = new String[cmd.getIpAddresses().length]; + for (int i = 0; i < results.length; i++) { + results[i] = IpAssocAnswer.errorResult; } - return executeInVR(privateIpAddress, "ipassoc.sh", args); - } + int i = 0; + for (IpAddressTO ip: cmd.getIpAddresses()) { + String args = ""; + if (ip.isAdd()) { + args += "-A"; + } else { + args += "-D"; + } + String cidrSize = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); + if (ip.isSourceNat()) { + args += " -s"; + } + if (ip.isFirstIP()) { + args += " -f"; + } + args += " -l "; + args += ip.getPublicIp() + "/" + cidrSize; - private void deleteBridge(String brName) { - Script cmd = new Script("/bin/sh", _timeout); - cmd.add("-c"); - cmd.add("ifconfig " + brName + " down;brctl delbr " + brName); - cmd.execute(); - } + String publicNic = "eth" + ip.getNicDevId(); + args += " -c "; + args += publicNic; - private boolean isDNSmasqRunning(String dnsmasqName) { - Script cmd = new Script("/bin/sh", _timeout); - cmd.add("-c"); - cmd.add("ls -l /var/run/libvirt/network/" + dnsmasqName + ".pid"); - String result = cmd.execute(); - if (result != null) { - return false; - } else { - return true; + args += " -g "; + args += ip.getVlanGateway(); + + if (ip.isNewNic()) { + args += " -n"; + } + + ExecutionResult result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "ipassoc.sh", args); + if (result.isSuccess()) { + results[i++] = ip.getPublicIp() + " - success"; + } else { + results[i++] = ip.getPublicIp() + " - failed:" + result.getDetails(); + break; + } } + return new IpAssocAnswer(cmd, results); } - private void stopDnsmasq(String dnsmasqName) { - Script cmd = new Script("/bin/sh", _timeout); - cmd.add("-c"); - cmd.add("kill -9 `cat /var/run/libvirt/network/" + dnsmasqName + ".pid`"); - cmd.execute(); - } - - // protected Answer execute(final SetFirewallRuleCommand cmd) { - // String args; - // if(cmd.getProtocol().toLowerCase().equals(NetUtils.NAT_PROTO)){ - // //1:1 NAT needs instanceip;publicip;domrip;op - // if(cmd.isCreate()) { - // args = "-A"; - // } else { - // args = "-D"; - // } - // - // args += " -l " + cmd.getPublicIpAddress(); - // args += " -i " + cmd.getRouterIpAddress(); - // args += " -r " + cmd.getPrivateIpAddress(); - // args += " -G " + cmd.getProtocol(); - // }else{ - // if (cmd.isEnable()) { - // args = "-A"; - // } else { - // args = "-D"; - // } - // - // args += " -P " + cmd.getProtocol().toLowerCase(); - // args += " -l " + cmd.getPublicIpAddress(); - // args += " -p " + cmd.getPublicPort(); - // args += " -n " + cmd.getRouterName(); - // args += " -i " + cmd.getRouterIpAddress(); - // args += " -r " + cmd.getPrivateIpAddress(); - // args += " -d " + cmd.getPrivatePort(); - // args += " -N " + cmd.getVlanNetmask(); - // - // String oldPrivateIP = cmd.getOldPrivateIP(); - // String oldPrivatePort = cmd.getOldPrivatePort(); - // - // if (oldPrivateIP != null) { - // args += " -w " + oldPrivateIP; - // } - // - // if (oldPrivatePort != null) { - // args += " -x " + oldPrivatePort; - // } - // } - // - // final Script command = new Script(_firewallPath, _timeout, s_logger); - // String [] argsArray = args.split(" "); - // for (String param : argsArray) { - // command.add(param); - // } - // String result = command.execute(); - // return new Answer(cmd, result == null, result); - // } - - protected String getDefaultScriptsDir() { - return "scripts/network/domr/dom0"; - } - - protected String findScript(final String script) { - return Script.findScript(_scriptsDir, script); - } - - @Override public boolean configure(final String name, final Map params) throws ConfigurationException { _name = name; - _scriptsDir = (String)params.get("domr.scripts.dir"); - if (_scriptsDir == null) { - if (s_logger.isInfoEnabled()) { - s_logger.info("VirtualRoutingResource _scriptDir can't be initialized from domr.scripts.dir param, use default"); - } - _scriptsDir = getDefaultScriptsDir(); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("VirtualRoutingResource _scriptDir to use: " + _scriptsDir); - } - - String value = (String)params.get("scripts.timeout"); - _timeout = NumbersUtil.parseInt(value, 120) * 1000; - - value = (String)params.get("start.script.timeout"); - _startTimeout = NumbersUtil.parseInt(value, 360) * 1000; - - value = (String)params.get("ssh.sleep"); + String value = (String)params.get("ssh.sleep"); _sleep = NumbersUtil.parseInt(value, 10) * 1000; value = (String)params.get("ssh.retry"); @@ -1042,26 +876,8 @@ public class VirtualRoutingResource implements Manager { value = (String)params.get("ssh.port"); _port = NumbersUtil.parseInt(value, 3922); - _publicIpAddress = (String)params.get("public.ip.address"); - if (_publicIpAddress != null) { - s_logger.warn("Incoming public ip address is overriden. Will always be using the same ip address: " + _publicIpAddress); - } - - _publicEthIf = (String)params.get("public.network.device"); - if (_publicEthIf == null) { - _publicEthIf = "xenbr1"; - } - _publicEthIf = _publicEthIf.toLowerCase(); - - _privateEthIf = (String)params.get("private.network.device"); - if (_privateEthIf == null) { - _privateEthIf = "xenbr0"; - } - _privateEthIf = _privateEthIf.toLowerCase(); - - _routerProxyPath = findScript("router_proxy.sh"); - if (_routerProxyPath == null) { - throw new ConfigurationException("Unable to find router_proxy.sh"); + if (_vrDeployer == null) { + throw new ConfigurationException("Unable to find the resource for VirtualRouterDeployer!"); } return true; } @@ -1141,50 +957,4 @@ public class VirtualRoutingResource implements Manager { return false; } - - @Override - public String getName() { - return _name; - } - - @Override - public void setName(String name) { - _name = name; - } - - @Override - public boolean start() { - return true; - } - - @Override - public boolean stop() { - return true; - } - - @Override - public int getRunLevel() { - return ComponentLifecycle.RUN_LEVEL_COMPONENT; - } - - public void setRunLevel() { - } - - @Override - public void setConfigParams(Map params) { - // TODO Auto-generated method stub - - } - - @Override - public Map getConfigParams() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setRunLevel(int level) { - // TODO Auto-generated method stub - - } } 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 c40cd75c831..fa0d99f1a30 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 @@ -16,73 +16,12 @@ // under the License. package com.cloud.hypervisor.kvm.resource; -import java.io.BufferedOutputStream; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLConnection; -import java.text.DateFormat; -import java.text.MessageFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.commons.io.FileUtils; -import org.apache.log4j.Logger; -import org.libvirt.Connect; -import org.libvirt.Domain; -import org.libvirt.DomainBlockStats; -import org.libvirt.DomainInfo; -import org.libvirt.DomainInterfaceStats; -import org.libvirt.DomainSnapshot; -import org.libvirt.LibvirtException; -import org.libvirt.NodeInfo; - import com.ceph.rados.IoCTX; import com.ceph.rados.Rados; import com.ceph.rados.RadosException; import com.ceph.rbd.Rbd; import com.ceph.rbd.RbdException; import com.ceph.rbd.RbdImage; - -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; -import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.cloudstack.utils.qemu.QemuImg; -import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; -import org.apache.cloudstack.utils.qemu.QemuImgException; -import org.apache.cloudstack.utils.qemu.QemuImgFile; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; @@ -155,7 +94,6 @@ import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.RebootRouterCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; -import com.cloud.agent.api.SetupGuestNetworkAnswer; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -174,13 +112,9 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; -import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.SetNetworkACLAnswer; -import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetSourceNatAnswer; import com.cloud.agent.api.routing.SetSourceNatCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; @@ -201,6 +135,7 @@ import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.dc.Vlan; import com.cloud.exception.InternalErrorException; @@ -250,17 +185,77 @@ import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; import com.cloud.storage.template.TemplateLocation; import com.cloud.storage.template.TemplateProp; +import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.OutputInterpreter; +import com.cloud.utils.script.OutputInterpreter.AllLinesParser; import com.cloud.utils.script.Script; +import com.cloud.utils.ssh.SshHelper; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachine.State; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.cloudstack.utils.qemu.QemuImg; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.cloudstack.utils.qemu.QemuImgException; +import org.apache.cloudstack.utils.qemu.QemuImgFile; +import org.apache.commons.io.FileUtils; +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.DomainBlockStats; +import org.libvirt.DomainInfo; +import org.libvirt.DomainInterfaceStats; +import org.libvirt.DomainSnapshot; +import org.libvirt.LibvirtException; +import org.libvirt.NodeInfo; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.text.DateFormat; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * LibvirtComputingResource execute requests on the computing/routing host using @@ -285,7 +280,7 @@ import com.cloud.vm.VirtualMachine.State; * pool | the parent of the storage pool hierarchy * } **/ @Local(value = {ServerResource.class}) -public class LibvirtComputingResource extends ServerResourceBase implements ServerResource { +public class LibvirtComputingResource extends ServerResourceBase implements ServerResource, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(LibvirtComputingResource.class); private String _modifyVlanPath; @@ -322,6 +317,58 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv protected static final String DEFAULT_OVS_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.OvsVifDriver"; protected static final String DEFAULT_BRIDGE_VIF_DRIVER_CLASS_NAME = "com.cloud.hypervisor.kvm.resource.BridgeVifDriver"; + @Override + public ExecutionResult executeInVR(String routerIp, String script, String args) { + final Script command = new Script(_routerProxyPath, _timeout, s_logger); + final AllLinesParser parser = new AllLinesParser(); + command.add(script); + command.add(routerIp); + if (args != null) { + command.add(args); + } + String details = command.execute(parser); + if (details == null) { + details = parser.getLines(); + } + return new ExecutionResult(command.getExitValue() == 0, details); + } + + @Override + public ExecutionResult createFileInVR(String routerIp, String path, String filename, String content) { + File permKey = new File("/root/.ssh/id_rsa.cloud"); + String error = null; + + try { + SshHelper.scpTo(routerIp, 3922, "root", permKey, null, path, content.getBytes(), filename, null); + } catch (Exception e) { + s_logger.warn("Fail to create file " + path + filename + " in VR " + routerIp, e); + error = e.getMessage(); + } + return new ExecutionResult(error == null, error); + } + + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } + return new ExecutionResult(true, null); + } + + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + return new ExecutionResult(true, null); + } + private static final class KeyValueInterpreter extends OutputInterpreter { private final Map map = new HashMap(); @@ -537,7 +584,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv params.put("domr.scripts.dir", domrScriptsDir); - _virtRouterResource = new VirtualRoutingResource(); + _virtRouterResource = new VirtualRoutingResource(this); success = _virtRouterResource.configure(name, params); if (!success) { @@ -1258,16 +1305,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv return execute((PlugNicCommand)cmd); } else if (cmd instanceof UnPlugNicCommand) { return execute((UnPlugNicCommand)cmd); - } else if (cmd instanceof SetupGuestNetworkCommand) { - return execute((SetupGuestNetworkCommand)cmd); - } else if (cmd instanceof SetNetworkACLCommand) { - return execute((SetNetworkACLCommand)cmd); - } else if (cmd instanceof SetSourceNatCommand) { - return execute((SetSourceNatCommand)cmd); - } else if (cmd instanceof IpAssocVpcCommand) { - return execute((IpAssocVpcCommand)cmd); - } else if (cmd instanceof IpAssocCommand) { - return execute((IpAssocCommand)cmd); } else if (cmd instanceof NetworkElementCommand) { return _virtRouterResource.executeRequest(cmd); } else if (cmd instanceof CheckSshCommand) { @@ -1977,25 +2014,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } - private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { Connect conn; NicTO nic = cmd.getNic(); - String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String routerGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String gateway = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } try { conn = LibvirtConnection.getConnectionByVmName(routerName); @@ -2010,62 +2032,18 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } if (routerNic == null) { - return new SetupGuestNetworkAnswer(cmd, false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName); + return new ExecutionResult(false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName); } - String dev = "eth" + nic.getDeviceId(); - String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); - String result = _virtRouterResource.assignGuestNetwork(dev, routerIP, routerGIP, gateway, cidr, netmask, dns, domainName); - - if (result != null) { - return new SetupGuestNetworkAnswer(cmd, false, "Creating guest network failed due to " + result); - } - return new SetupGuestNetworkAnswer(cmd, true, "success"); + return new ExecutionResult(true, null); } catch (LibvirtException e) { String msg = "Creating guest network failed due to " + e.toString(); s_logger.warn(msg, e); - return new SetupGuestNetworkAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } } - - private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { - String[] results = new String[cmd.getRules().length]; - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); - - try { - String[][] rules = cmd.generateFwRules(); - String[] aclRules = rules[0]; - NicTO nic = cmd.getNic(); - String dev = "eth" + nic.getDeviceId(); - String netmask = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - String rule = sb.toString(); - String result = _virtRouterResource.assignNetworkACL(routerIp, dev, nic.getIp(), netmask, rule, privateGw); - - if (result != null) { - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - return new SetNetworkACLAnswer(cmd, false, results); - } - - return new SetNetworkACLAnswer(cmd, true, results); - } catch (Exception e) { - String msg = "SetNetworkACL failed due to " + e.toString(); - s_logger.error(msg, e); - return new SetNetworkACLAnswer(cmd, false, results); - } - } - - protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { Connect conn; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); @@ -2086,7 +2064,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv /*skip over, no physical bridge device exists*/ } else if (pluggedVlanId == null) { /*this should only be true in the case of link local bridge*/ - return new SetSourceNatAnswer(cmd, false, "unable to find the vlan id for bridge " + pluggedVlanBr + " when attempting to set up" + pubVlan + + return new ExecutionResult(false, "unable to find the vlan id for bridge " + pluggedVlanBr + " when attempting to set up" + pubVlan + " on router " + routerName); } else if (pluggedVlanId.equals(pubVlan)) { break; @@ -2094,26 +2072,20 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv devNum++; } - String dev = "eth" + devNum; - String result = _virtRouterResource.assignSourceNat(routerIP, pubIP.getPublicIp(), dev); + pubIP.setNicDevId(devNum); - if (result != null) { - return new SetSourceNatAnswer(cmd, false, "KVM plugin \"vpc_snat\" failed:" + result); - } - return new SetSourceNatAnswer(cmd, true, "success"); + return new ExecutionResult(true, "success"); } catch (LibvirtException e) { String msg = "Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); - return new SetSourceNatAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } } - protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { Connect conn; - String[] results = new String[cmd.getIpAddresses().length]; int i = 0; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); try { conn = LibvirtConnection.getConnectionByVmName(routerName); @@ -2136,31 +2108,19 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } for (IpAddressTO ip : ips) { - String nicName = "eth" + broadcastUriToNicNum.get(ip.getBroadcastUri()); - String netmask = Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - String subnet = NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - _virtRouterResource.assignVpcIpToRouter(routerIP, ip.isAdd(), ip.getPublicIp(), nicName, ip.getVlanGateway(), netmask, subnet, ip.isSourceNat()); - results[i++] = ip.getPublicIp() + " - success"; + ip.setNicDevId(broadcastUriToNicNum.get(ip.getBroadcastUri())); } + return new ExecutionResult(true, null); } catch (LibvirtException e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; - } catch (InternalErrorException e) { - s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + return new ExecutionResult(false, e.getMessage()); } - - return new IpAssocAnswer(cmd, results); } - public Answer execute(IpAssocCommand cmd) { + public ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String[] results = new String[cmd.getIpAddresses().length]; - for (int i = 0; i < results.length; i++) { - results[i] = IpAssocAnswer.errorResult; - } Connect conn; try { conn = LibvirtConnection.getConnectionByVmName(routerName); @@ -2182,11 +2142,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv nicPos++; } IpAddressTO[] ips = cmd.getIpAddresses(); - int i = 0; - String result = null; int nicNum = 0; - boolean newNic = false; for (IpAddressTO ip : ips) { + boolean newNic = false; if (!broadcastUriAllocatedToVM.containsKey(ip.getBroadcastUri())) { /* plug a vif into router */ VifHotPlug(conn, routerName, ip.getBroadcastUri(), ip.getVifMacAddress()); @@ -2195,21 +2153,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } nicNum = broadcastUriAllocatedToVM.get(ip.getBroadcastUri()); networkUsage(routerIp, "addVif", "eth" + nicNum); - result = - _virtRouterResource.assignPublicIpAddress(routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), nicNum, newNic); - if (result == null) { - results[i++] = ip.getPublicIp() + " - success"; - } + ip.setNicDevId(nicNum); + ip.setNewNic(newNic); } - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } catch (LibvirtException e) { s_logger.error("ipassoccmd failed", e); - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(false, e.getMessage()); } catch (InternalErrorException e) { s_logger.error("ipassoccmd failed", e); - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(false, e.getMessage()); } } diff --git a/utils/src/com/cloud/utils/script/OutputInterpreter.java b/utils/src/com/cloud/utils/script/OutputInterpreter.java index 5af607e4590..5845c9ca0ff 100755 --- a/utils/src/com/cloud/utils/script/OutputInterpreter.java +++ b/utils/src/com/cloud/utils/script/OutputInterpreter.java @@ -16,11 +16,11 @@ // under the License. package com.cloud.utils.script; +import org.apache.log4j.Logger; + import java.io.BufferedReader; import java.io.IOException; -import org.apache.log4j.Logger; - /** */ public abstract class OutputInterpreter { diff --git a/utils/src/com/cloud/utils/script/Script.java b/utils/src/com/cloud/utils/script/Script.java index 91f32dedeb7..8dad697feae 100755 --- a/utils/src/com/cloud/utils/script/Script.java +++ b/utils/src/com/cloud/utils/script/Script.java @@ -16,6 +16,11 @@ // under the License. package com.cloud.utils.script; +import com.cloud.utils.PropertiesUtil; +import com.cloud.utils.concurrency.NamedThreadFactory; +import com.cloud.utils.script.OutputInterpreter.TimedOutLogger; +import org.apache.log4j.Logger; + import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -35,12 +40,6 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -import org.apache.log4j.Logger; - -import com.cloud.utils.PropertiesUtil; -import com.cloud.utils.concurrency.NamedThreadFactory; -import com.cloud.utils.script.OutputInterpreter.TimedOutLogger; - public class Script implements Callable { private static final Logger s_logger = Logger.getLogger(Script.class); @@ -61,6 +60,10 @@ public class Script implements Callable { Process _process; Thread _thread; + public int getExitValue() { + return _process.exitValue(); + } + public Script(String command, long timeout, Logger logger) { _command = new ArrayList(); _command.add(command); From 069bc3686e29c6a683a41fe2beca687ce22d4186 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Mon, 20 Jan 2014 12:03:07 -0800 Subject: [PATCH 030/126] CLOUDSTACK-5779: Make CitrixResource to use VirtualRoutingResource --- .../VirtualRoutingResource.java | 30 +- .../xen/resource/CitrixResourceBase.java | 1120 +++-------------- 2 files changed, 214 insertions(+), 936 deletions(-) diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index f63824e2e8b..1ed38644536 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -215,9 +215,6 @@ public class VirtualRoutingResource { private Answer execute(SetFirewallRulesCommand cmd) { String[] results = new String[cmd.getRules().length]; - for (int i = 0; i < cmd.getRules().length; i++) { - results[i] = "Failed"; - } String routerAccessIp = cmd.getRouterAccessIp(); String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); @@ -260,9 +257,13 @@ public class VirtualRoutingResource { } if (!result.isSuccess()) { + //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails + for (int i = 0; i < results.length; i++) { + results[i] = "Failed: " + result.getDetails(); + } return new SetFirewallRulesAnswer(cmd, false, results); } - return new SetFirewallRulesAnswer(cmd, true, null); + return new SetFirewallRulesAnswer(cmd, true, results); } @@ -292,7 +293,7 @@ public class VirtualRoutingResource { return new SetPortForwardingRulesAnswer(cmd, results, endResult); } - protected Answer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { + protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { String[] results = new String[cmd.getRules().length]; int i = 0; boolean endResult = true; @@ -315,7 +316,7 @@ public class VirtualRoutingResource { } - private Answer execute(SetStaticNatRulesCommand cmd) { + private SetStaticNatRulesAnswer execute(SetStaticNatRulesCommand cmd) { if (cmd.getVpcId() != null) { return SetVPCStaticNatRules(cmd); } @@ -364,7 +365,11 @@ public class VirtualRoutingResource { tmpCfgFileContents += "\n"; } - if (!_vrDeployer.createFileInVR(cmd.getRouterAccessIp(), "/etc/haproxy/", "haproxy.cfg.new", tmpCfgFileContents).isSuccess()) { + String tmpCfgFilePath = "/etc/haproxy/"; + String tmpCfgFileName = "haproxy.cfg.new"; + ExecutionResult result = _vrDeployer.createFileInVR(cmd.getRouterAccessIp(), tmpCfgFilePath, tmpCfgFileName, tmpCfgFileContents); + + if (!result.isSuccess()) { return new Answer(cmd, false, "Fail to copy LB config file to VR"); } @@ -401,8 +406,6 @@ public class VirtualRoutingResource { args += " -s " + sb.toString(); } - ExecutionResult result; - if (cmd.getVpcId() == null) { args = " -i " + routerIp + args; result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), "loadbalancer.sh", args); @@ -490,6 +493,7 @@ public class VirtualRoutingResource { for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; } + //this is to ensure that thre is some argument passed to the deleteipAlias script when there are no revoked rules. args = args + "- "; List activeIpAliasTOs = cmd.getCreateIpAliasTos(); for (IpAliasTO ipAliasTO : activeIpAliasTOs) { @@ -514,7 +518,7 @@ public class VirtualRoutingResource { String args = ""; for (String ip : cmd.getVpnIps()) { - args += " " + ip; + args += ip + " "; } ExecutionResult result = _vrDeployer.executeInVR(routerIP, "checkbatchs2svpn.sh", args); @@ -551,9 +555,9 @@ public class VirtualRoutingResource { } protected Answer execute(Site2SiteVpnCfgCommand cmd) { - String args; + String args = ""; if (cmd.isCreate()) { - args = "-A"; + args += "-A"; args += " -l "; args += cmd.getLocalPublicIp(); args += " -n "; @@ -584,7 +588,7 @@ public class VirtualRoutingResource { args += " -p "; } } else { - args = "-D"; + args += "-D"; args += " -r "; args += cmd.getPeerGatewayIp(); args += " -n "; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 05311b8c446..a817e2696a1 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -45,7 +45,6 @@ import javax.ejb.Local; import javax.naming.ConfigurationException; import javax.xml.parsers.DocumentBuilderFactory; -import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import org.w3c.dom.Document; @@ -53,7 +52,6 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; -import com.google.gson.Gson; import com.trilead.ssh2.SCPClient; import com.xensource.xenapi.Bond; import com.xensource.xenapi.Connection; @@ -90,17 +88,12 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; import com.cloud.agent.api.AttachVolumeCommand; -import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.CheckRouterAnswer; -import com.cloud.agent.api.CheckRouterCommand; -import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer; -import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; @@ -113,8 +106,6 @@ import com.cloud.agent.api.CreateVMSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.DeleteVMSnapshotAnswer; import com.cloud.agent.api.DeleteVMSnapshotCommand; -import com.cloud.agent.api.GetDomRVersionAnswer; -import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetHostStatsAnswer; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsAnswer; @@ -174,7 +165,6 @@ import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; -import com.cloud.agent.api.SetupGuestNetworkAnswer; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -194,35 +184,11 @@ import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; -import com.cloud.agent.api.routing.CreateIpAliasCommand; -import com.cloud.agent.api.routing.DeleteIpAliasCommand; -import com.cloud.agent.api.routing.DhcpEntryCommand; -import com.cloud.agent.api.routing.DnsMasqConfigCommand; -import com.cloud.agent.api.routing.IpAliasTO; -import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.SetFirewallRulesAnswer; -import com.cloud.agent.api.routing.SetFirewallRulesCommand; -import com.cloud.agent.api.routing.SetMonitorServiceCommand; -import com.cloud.agent.api.routing.SetNetworkACLAnswer; import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; -import com.cloud.agent.api.routing.SetSourceNatAnswer; import com.cloud.agent.api.routing.SetSourceNatCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.routing.SetStaticRouteAnswer; -import com.cloud.agent.api.routing.SetStaticRouteCommand; -import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; -import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; @@ -232,28 +198,23 @@ import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; -import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.DiskTO; -import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.HAProxyConfigurator; -import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PhysicalNetworkSetupInfo; -import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; import com.cloud.resource.hypervisor.HypervisorResource; import com.cloud.storage.Storage; @@ -292,7 +253,7 @@ import com.cloud.vm.snapshot.VMSnapshot; * */ @Local(value = ServerResource.class) -public abstract class CitrixResourceBase implements ServerResource, HypervisorResource { +public abstract class CitrixResourceBase implements ServerResource, HypervisorResource, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(CitrixResourceBase.class); protected static final XenServerConnectionPool ConnPool = XenServerConnectionPool.getInstance(); protected String _name; @@ -339,6 +300,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected StorageSubsystemCommandHandler storageHandler; protected int _maxNics = 7; + protected VirtualRoutingResource _vrResource; + public enum SRType { NFS, LVM, ISCSI, ISO, LVMOISCSI, LVMOHBA, EXT, FILE; @@ -448,30 +411,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Class clazz = cmd.getClass(); if (clazz == CreateCommand.class) { return execute((CreateCommand)cmd); - } else if (clazz == SetPortForwardingRulesCommand.class) { - return execute((SetPortForwardingRulesCommand)cmd); - } else if (clazz == SetStaticNatRulesCommand.class) { - return execute((SetStaticNatRulesCommand)cmd); - } else if (clazz == LoadBalancerConfigCommand.class) { - return execute((LoadBalancerConfigCommand)cmd); - } else if (clazz == IpAssocCommand.class) { - return execute((IpAssocCommand)cmd); + } else if (cmd instanceof NetworkElementCommand) { + return _vrResource.executeRequest(cmd); } else if (clazz == CheckConsoleProxyLoadCommand.class) { return execute((CheckConsoleProxyLoadCommand)cmd); } else if (clazz == WatchConsoleProxyLoadCommand.class) { return execute((WatchConsoleProxyLoadCommand)cmd); - } else if (clazz == SavePasswordCommand.class) { - return execute((SavePasswordCommand)cmd); - } else if (clazz == DhcpEntryCommand.class) { - return execute((DhcpEntryCommand)cmd); - } else if (clazz == CreateIpAliasCommand.class) { - return execute((CreateIpAliasCommand)cmd); - } else if (clazz == DnsMasqConfigCommand.class) { - return execute((DnsMasqConfigCommand)cmd); - } else if (clazz == DeleteIpAliasCommand.class) { - return execute((DeleteIpAliasCommand)cmd); - } else if (clazz == VmDataCommand.class) { - return execute((VmDataCommand)cmd); } else if (clazz == ReadyCommand.class) { return execute((ReadyCommand)cmd); } else if (clazz == GetHostStatsCommand.class) { @@ -530,10 +475,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((PoolEjectCommand)cmd); } else if (clazz == StartCommand.class) { return execute((StartCommand)cmd); - } else if (clazz == RemoteAccessVpnCfgCommand.class) { - return execute((RemoteAccessVpnCfgCommand)cmd); - } else if (clazz == VpnUsersCfgCommand.class) { - return execute((VpnUsersCfgCommand)cmd); } else if (clazz == CheckSshCommand.class) { return execute((CheckSshCommand)cmd); } else if (clazz == SecurityGroupRulesCmd.class) { @@ -560,54 +501,28 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((OvsDestroyTunnelCommand)cmd); } else if (clazz == UpdateHostPasswordCommand.class) { return execute((UpdateHostPasswordCommand)cmd); - } else if (cmd instanceof CheckRouterCommand) { - return execute((CheckRouterCommand)cmd); - } else if (cmd instanceof SetFirewallRulesCommand) { - return execute((SetFirewallRulesCommand)cmd); - } else if (cmd instanceof BumpUpPriorityCommand) { - return execute((BumpUpPriorityCommand)cmd); } else if (cmd instanceof ClusterSyncCommand) { return execute((ClusterSyncCommand)cmd); - } else if (cmd instanceof GetDomRVersionCmd) { - return execute((GetDomRVersionCmd)cmd); } else if (clazz == CheckNetworkCommand.class) { return execute((CheckNetworkCommand)cmd); - } else if (clazz == SetupGuestNetworkCommand.class) { - return execute((SetupGuestNetworkCommand)cmd); } else if (clazz == PlugNicCommand.class) { return execute((PlugNicCommand)cmd); } else if (clazz == UnPlugNicCommand.class) { return execute((UnPlugNicCommand)cmd); - } else if (clazz == IpAssocVpcCommand.class) { - return execute((IpAssocVpcCommand)cmd); - } else if (clazz == SetSourceNatCommand.class) { - return execute((SetSourceNatCommand)cmd); - } else if (clazz == SetNetworkACLCommand.class) { - return execute((SetNetworkACLCommand)cmd); - } else if (clazz == SetPortForwardingRulesVpcCommand.class) { - return execute((SetPortForwardingRulesVpcCommand)cmd); - } else if (clazz == SetStaticRouteCommand.class) { - return execute((SetStaticRouteCommand)cmd); - } else if (clazz == Site2SiteVpnCfgCommand.class) { - return execute((Site2SiteVpnCfgCommand)cmd); - } else if (clazz == CheckS2SVpnConnectionsCommand.class) { - return execute((CheckS2SVpnConnectionsCommand)cmd); } else if (cmd instanceof StorageSubSystemCommand) { - return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); + return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); } else if (clazz == CreateVMSnapshotCommand.class) { - return execute((CreateVMSnapshotCommand)cmd); + return execute((CreateVMSnapshotCommand) cmd); } else if (clazz == DeleteVMSnapshotCommand.class) { - return execute((DeleteVMSnapshotCommand)cmd); + return execute((DeleteVMSnapshotCommand) cmd); } else if (clazz == RevertToVMSnapshotCommand.class) { - return execute((RevertToVMSnapshotCommand)cmd); + return execute((RevertToVMSnapshotCommand) cmd); } else if (clazz == NetworkRulesVmSecondaryIpCommand.class) { - return execute((NetworkRulesVmSecondaryIpCommand)cmd); + return execute((NetworkRulesVmSecondaryIpCommand) cmd); } else if (clazz == ScaleVmCommand.class) { return execute((ScaleVmCommand)cmd); } else if (clazz == PvlanSetupCommand.class) { return execute((PvlanSetupCommand)cmd); - } else if (clazz == SetMonitorServiceCommand.class) { - return execute((SetMonitorServiceCommand)cmd); } else if (clazz == PerformanceMonitorCommand.class) { return execute((PerformanceMonitorCommand)cmd); } else { @@ -615,6 +530,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } + @Override public ExecutionResult executeInVR(String routerIP, String script, String args) { Connection conn = getConnection(); String rc = callHostPlugin(conn, "vmops", "routerProxy", "args", script + " " + routerIP + " " + args); @@ -622,13 +538,40 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5)); } - protected ExecutionResult createFileInVR(String routerIp, String path, String content) { + @Override + public ExecutionResult createFileInVR(String routerIp, String path, String filename, String content) { Connection conn = getConnection(); - String rc = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "filepath", path, "filecontents", content); + String rc = callHostPlugin(conn, "vmops", "createFileInDomr", "domrip", routerIp, "filepath", path + filename, "filecontents", content); // Fail case would be start with "fail#" return new ExecutionResult(rc.startsWith("succ#"), rc.substring(5)); } + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return prepareNetworkElementCommand((SetNetworkACLCommand)cmd); + } + return new ExecutionResult(true, null); + } + + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + if (cmd instanceof IpAssocCommand && !(cmd instanceof IpAssocVpcCommand)) { + cleanupNetworkElementCommand((IpAssocCommand)cmd); + } + return new ExecutionResult(true, null); + } private Answer execute(PerformanceMonitorCommand cmd) { Connection conn = getConnection(); @@ -1973,48 +1916,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd); } - private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { - String args = ""; - for (String ip : cmd.getVpnIps()) { - args += ip + " "; - } - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "checkbatchs2svpn.sh", args); - if (!result.isSuccess()) { - return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed"); - } - return new CheckS2SVpnConnectionsAnswer(cmd, true, result.getDetails()); - } - - private CheckRouterAnswer execute(CheckRouterCommand cmd) { - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "checkrouter.sh", null); - if (!result.isSuccess()) { - return new CheckRouterAnswer(cmd, "CheckRouterCommand failed"); - } - return new CheckRouterAnswer(cmd, result.getDetails(), true); - } - - private GetDomRVersionAnswer execute(GetDomRVersionCmd cmd) { - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "get_template_version.sh", null); - if (!result.isSuccess()) { - return new GetDomRVersionAnswer(cmd, "getDomRVersionCmd failed"); - } - String[] lines = result.getDetails().split("&"); - if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result.getDetails()); - } - return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]); - } - - private Answer execute(BumpUpPriorityCommand cmd) { - Connection conn = getConnection(); - String args = "bumpup_priority.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args); - if (result == null || result.isEmpty()) { - return new Answer(cmd, false, "BumpUpPriorityCommand failed"); - } - return new Answer(cmd, true, result); - } - protected MaintainAnswer execute(MaintainCommand cmd) { Connection conn = getConnection(); try { @@ -2040,511 +1941,87 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesCommand cmd) { - getConnection(); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - StringBuilder args = new StringBuilder(); - args.append(rule.revoked() ? " -D " : " -A "); - args.append(" -P ").append(rule.getProtocol().toLowerCase()); - args.append(" -l ").append(rule.getSrcIp()); - args.append(" -p ").append(rule.getStringSrcPortRange()); - args.append(" -r ").append(rule.getDstIp()); - args.append(" -d ").append(rule.getStringDstPortRange()); - - ExecutionResult result = executeInVR(routerIp, "firewall_nat.sh", args.toString()); - - if (!result.isSuccess()) { - results[i++] = "Failed: " + result.getDetails(); - endResult = false; - } else { - results[i++] = null; - } - } - - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { - //String args = routerIp; - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - String args = rule.revoked() ? "-D" : "-A"; - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_staticnat.sh", args); - - if (!result.isSuccess()) { - results[i++] = "Failed: " + result.getDetails(); - endResult = false; - } else { - results[i++] = null; - } - } - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected SetStaticNatRulesAnswer execute(SetStaticNatRulesCommand cmd) { - if (cmd.getVpcId() != null) { - return SetVPCStaticNatRules(cmd); - } - getConnection(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - //1:1 NAT needs instanceip;publicip;domrip;op - StringBuilder args = new StringBuilder(); - args.append(rule.revoked() ? " -D " : " -A "); - args.append(" -l ").append(rule.getSrcIp()); - args.append(" -r ").append(rule.getDstIp()); - - if (rule.getProtocol() != null) { - args.append(" -P ").append(rule.getProtocol().toLowerCase()); - } - - args.append(" -d ").append(rule.getStringSrcPortRange()); - args.append(" -G "); - - ExecutionResult result = executeInVR(routerIp, "firewall_nat.sh", args.toString()); - - if (!result.isSuccess()) { - results[i++] = "Failed:" + result.getDetails(); - endResult = false; - } else { - results[i++] = null; - } - } - - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected Answer execute(final CreateIpAliasCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List ipAliasTOs = cmd.getIpAliasList(); - String args = ""; - for (IpAliasTO ipaliasto : ipAliasTOs) { - args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; - } - ExecutionResult result = executeInVR(routerIp, "createipAlias.sh", args); - if (!result.isSuccess()) { - return new Answer(cmd, false, "CreateIPAliasCommand failed due to " + result.getDetails()); - } - - return new Answer(cmd); - } - - protected Answer execute(final DeleteIpAliasCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); - String args = ""; - for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - //this is to ensure that thre is some argument passed to the deleteipAlias script when there are no revoked rules. - args = args + "- "; - List activeIpAliasTOs = cmd.getCreateIpAliasTos(); - for (IpAliasTO ipAliasTO : activeIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - ExecutionResult result = executeInVR(routerIp, "deleteipAlias", args); - if (!result.isSuccess()) { - return new Answer(cmd, false, "DeleteipAliasCommand failed due to " + result.getDetails()); - } - - return new Answer(cmd); - } - - protected Answer execute(final DnsMasqConfigCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List dhcpTos = cmd.getIps(); - String args = ""; - for (DhcpTO dhcpTo : dhcpTos) { - args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; - } - - ExecutionResult result = executeInVR(routerIp, "dnsmasq.sh", args); - - if (!result.isSuccess()) { - return new Answer(cmd, false, "DnsMasqconfigCommand failed due to " + result.getDetails()); - } - - return new Answer(cmd); - } - - protected Answer execute(final LoadBalancerConfigCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - - if (routerIp == null) { - return new Answer(cmd); - } - - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - String[] config = cfgtr.generateConfiguration(cmd); - String tmpCfgFileContents = ""; - for (int i = 0; i < config.length; i++) { - tmpCfgFileContents += config[i]; - tmpCfgFileContents += "\n"; - } - String tmpCfgFilePath = "/etc/haproxy/haproxy.cfg.new"; - ExecutionResult result = createFileInVR(routerIp, tmpCfgFilePath, tmpCfgFileContents); - - if (!result.isSuccess()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed to create HA proxy cfg file: " + result.getDetails()); - } - - String[][] rules = cfgtr.generateFwRules(cmd); - - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String ip = cmd.getNic().getIp(); - String args = " -i " + ip; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - if (cmd.getVpcId() == null) { - args = " -i " + routerIp + args; - result = executeInVR(routerIp, "loadbalancer.sh", args); - } else { - args = " -i " + cmd.getNic().getIp() + args; - result = executeInVR(routerIp, "vpc_loadbalancer.sh", args); - } - - if (!result.isSuccess()) { - return new Answer(cmd, false, "LoadBalancerConfigCommand failed: " + result.getDetails()); - } - return new Answer(cmd); - } - - protected synchronized Answer execute(final DhcpEntryCommand cmd) { - String args = " -m " + cmd.getVmMac(); - if (cmd.getVmIpAddress() != null) { - args += " -4 " + cmd.getVmIpAddress(); - } - args += " -h " + cmd.getVmName(); - - if (cmd.getDefaultRouter() != null) { - args += " -d " + cmd.getDefaultRouter(); - } - - if (cmd.getDefaultDns() != null) { - args += " -n " + cmd.getDefaultDns(); - } - - if (cmd.getStaticRoutes() != null) { - args += " -s " + cmd.getStaticRoutes(); - } - - if (cmd.getVmIp6Address() != null) { - args += " -6 " + cmd.getVmIp6Address(); - args += " -u " + cmd.getDuid(); - } - - if (!cmd.isDefault()) { - args += " -N"; - } - - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "edithosts.sh", args); - if (!result.isSuccess()) { - return new Answer(cmd, false, "DhcpEntry failed: " + result.getDetails()); - } - return new Answer(cmd); - } - - protected synchronized Answer execute(final RemoteAccessVpnCfgCommand cmd) { - String args = ""; - if (cmd.isCreate()) { - args += " -r " + cmd.getIpRange(); - args += " -p " + cmd.getPresharedKey(); - args += " -s " + cmd.getVpnServerIp(); - args += " -l " + cmd.getLocalIp(); - args += " -c "; - } else { - args += " -d "; - args += " -s " + cmd.getVpnServerIp(); - } - args += " -C " + cmd.getLocalCidr(); - args += " -i " + cmd.getPublicInterface(); - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpn_l2tp.sh", args); - if (!result.isSuccess()) { - return new Answer(cmd, false, "Configure VPN failed" + result.getDetails()); - } - return new Answer(cmd); - } - - protected synchronized Answer execute(final VpnUsersCfgCommand cmd) { - for (VpnUsersCfgCommand.UsernamePassword userpwd: cmd.getUserpwds()) { - String args = ""; - if (!userpwd.isAdd()) { - args += " -U " + userpwd.getUsername(); - } else { - args += " -u " + userpwd.getUsernamePassword(); - } - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpn_l2tp.sh", args); - if (!result.isSuccess()) { - return new Answer(cmd, false, "Configure VPN user failed for user " + userpwd.getUsername() + ":" + result.getDetails()); - } - } - - return new Answer(cmd); - } - - protected Answer execute(final VmDataCommand cmd) { - Map> data = new HashMap>(); - data.put(cmd.getVmIpAddress(), cmd.getVmData()); - String json = new Gson().toJson(data); - json = Base64.encodeBase64String(json.getBytes()); - - String args = "-d " + json; - - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vmdata.py", args); - - if (!result.isSuccess()) { - return new Answer(cmd, false, "vm_data failed:" + result.getDetails()); - } else { - return new Answer(cmd); - } - - } - - protected Answer execute(final SavePasswordCommand cmd) { - final String password = cmd.getPassword(); - final String vmIpAddress = cmd.getVmIpAddress(); - - String args = " -v " + vmIpAddress; - args += " -p " + password; - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "savepassword.sh", args); - - if (!result.isSuccess()) { - return new Answer(cmd, false, "savePassword failed:" + result.getDetails()); - } - return new Answer(cmd); - } - - protected void assignPublicIpAddress(Connection conn, String vmName, String privateIpAddress, String publicIpAddress, boolean add, boolean firstIP, - boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, Integer networkRate, TrafficType trafficType, String name) - throws InternalErrorException { - - try { - VM router = getVM(conn, vmName); - - NicTO nic = new NicTO(); - nic.setMac(vifMacAddress); - nic.setType(trafficType); - if (vlanId == null) { - nic.setBroadcastType(BroadcastDomainType.Native); - } else { - URI uri = BroadcastDomainType.fromString(vlanId); - nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); - nic.setBroadcastUri(uri); - } - nic.setDeviceId(0); - nic.setNetworkRateMbps(networkRate); - nic.setName(name); - - Network network = getNetwork(conn, nic); - - // Determine the correct VIF on DomR to associate/disassociate the - // IP address with - VIF correctVif = getCorrectVif(conn, router, network); - - // If we are associating an IP address and DomR doesn't have a VIF - // for the specified vlan ID, we need to add a VIF - // If we are disassociating the last IP address in the VLAN, we need - // to remove a VIF - boolean addVif = false; - boolean removeVif = false; - if (add && correctVif == null) { - addVif = true; - } - - if (addVif) { - // Add a new VIF to DomR - String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router); - - if (vifDeviceNum == null) { - throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn)); - } - - nic.setDeviceId(Integer.parseInt(vifDeviceNum)); - - correctVif = createVif(conn, vmName, router, null, nic); - correctVif.plug(conn); - // Add iptables rule for network usage - networkUsage(conn, privateIpAddress, "addVif", "eth" + correctVif.getDevice(conn)); - } - - if (correctVif == null) { - throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); - } - - String args = ""; - - if (add) { - args += " -A "; - } else { - args += " -D "; - } - - if (sourceNat) { - args += " -s"; - } - if (firstIP) { - args += " -f"; - } - - String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - args += " -l "; - args += publicIpAddress + "/" + cidrSize; - - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - - args += " -g "; - args += vlanGateway; - - if (addVif) { - //To indicate this is new interface created - args += " -n"; - } - - ExecutionResult result = executeInVR(privateIpAddress, "ipassoc.sh", args); - - if (!result.isSuccess()) { - throw new InternalErrorException("Xen plugin \"ipassoc\" failed." + result.getDetails()); - } - - if (removeVif) { - network = correctVif.getNetwork(conn); - - // Mark this vif to be removed from network usage - networkUsage(conn, privateIpAddress, "deleteVif", "eth" + correctVif.getDevice(conn)); - - // Remove the VIF from DomR - correctVif.unplug(conn); - correctVif.destroy(conn); - - // Disable the VLAN network if necessary - disableVlanNetwork(conn, network); - } - - } catch (XenAPIException e) { - String msg = "Unable to assign public IP address due to " + e.toString(); - s_logger.warn(msg, e); - throw new InternalErrorException(msg); - } catch (final XmlRpcException e) { - String msg = "Unable to assign public IP address due to " + e.getMessage(); - s_logger.warn(msg, e); - throw new InternalErrorException(msg); - } - } - - protected void assignVPCPublicIpAddress(Connection conn, String vmName, String routerIp, IpAddressTO ip) throws Exception { - - try { - VM router = getVM(conn, vmName); - - VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress()); - if (correctVif == null) { - if (ip.isAdd()) { - throw new InternalErrorException("Failed to find DomR VIF to associate IP with."); - } else { - s_logger.debug("VIF to deassociate IP with does not exist, return success"); - return; - } - } - - String args = ""; - String snatArgs = ""; - - if (ip.isAdd()) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; - } - - args += " -l "; - args += ip.getPublicIp(); - - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - - args += " -g "; - args += ip.getVlanGateway(); - - args += " -m "; - args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - - args += " -n "; - args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - - ExecutionResult result = executeInVR(routerIp, "vpc_ipassoc.sh", args); - if (!result.isSuccess()) { - throw new InternalErrorException("Xen plugin \"vpc_ipassoc\" failed." + result.getDetails()); - } - - if (ip.isSourceNat()) { - snatArgs += " -l " + ip.getPublicIp(); - snatArgs += " -c " + "eth" + correctVif.getDevice(conn); - - result = executeInVR(routerIp, "vpc_privateGateway.sh", snatArgs); - if (!result.isSuccess()) { - throw new InternalErrorException("Xen plugin \"vpc_privateGateway\" failed." + result.getDetails()); - } - } - - } catch (Exception e) { - String msg = "Unable to assign public IP address due to " + e.toString(); - s_logger.warn(msg, e); - throw new Exception(msg); - } - } - protected String networkUsage(Connection conn, final String privateIpAddress, final String option, final String vif) { - if (option.equals("get")) { return "0:0"; } return null; } - protected Answer execute(IpAssocCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { + Connection conn = getConnection(); + int i = 0; + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); + + try { + IpAddressTO[] ips = cmd.getIpAddresses(); + for (IpAddressTO ip : ips) { + + VM router = getVM(conn, routerName); + + NicTO nic = new NicTO(); + nic.setMac(ip.getVifMacAddress()); + nic.setType(ip.getTrafficType()); + if (ip.getBroadcastUri()== null) { + nic.setBroadcastType(BroadcastDomainType.Native); + } else { + URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); + nic.setBroadcastUri(uri); + } + nic.setDeviceId(0); + nic.setNetworkRateMbps(ip.getNetworkRate()); + nic.setName(ip.getNetworkName()); + + Network network = getNetwork(conn, nic); + + // Determine the correct VIF on DomR to associate/disassociate the + // IP address with + VIF correctVif = getCorrectVif(conn, router, network); + + // If we are associating an IP address and DomR doesn't have a VIF + // for the specified vlan ID, we need to add a VIF + // If we are disassociating the last IP address in the VLAN, we need + // to remove a VIF + boolean addVif = false; + if (ip.isAdd() && correctVif == null) { + addVif = true; + } + + if (addVif) { + // Add a new VIF to DomR + String vifDeviceNum = getLowestAvailableVIFDeviceNum(conn, router); + + if (vifDeviceNum == null) { + throw new InternalErrorException("There were no more available slots for a new VIF on router: " + router.getNameLabel(conn)); + } + + nic.setDeviceId(Integer.valueOf(vifDeviceNum)); + + correctVif = createVif(conn, routerName, router, null, nic); + correctVif.plug(conn); + // Add iptables rule for network usage + networkUsage(conn, routerIp, "addVif", "eth" + correctVif.getDevice(conn)); + } + + if (correctVif == null) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } + + ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); + ip.setNewNic(addVif); + } + } catch (InternalErrorException e) { + s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); + return new ExecutionResult(false, e.getMessage()); + } catch (Exception e) { + return new ExecutionResult(false, e.getMessage()); + } + return new ExecutionResult(true, null); + } + + protected ExecutionResult cleanupNetworkElementCommand(IpAssocCommand cmd) { Connection conn = getConnection(); String[] results = new String[cmd.getIpAddresses().length]; int i = 0; @@ -2554,16 +2031,57 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { - assignPublicIpAddress(conn, routerName, routerIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress(), ip.getNetworkRate(), ip.getTrafficType(), ip.getNetworkName()); - results[i++] = ip.getPublicIp() + " - success"; + VM router = getVM(conn, routerName); + + NicTO nic = new NicTO(); + nic.setMac(ip.getVifMacAddress()); + nic.setType(ip.getTrafficType()); + if (ip.getBroadcastUri()== null) { + nic.setBroadcastType(BroadcastDomainType.Native); + } else { + URI uri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + nic.setBroadcastType(BroadcastDomainType.getSchemeValue(uri)); + nic.setBroadcastUri(uri); + } + nic.setDeviceId(0); + nic.setNetworkRateMbps(ip.getNetworkRate()); + nic.setName(ip.getNetworkName()); + + Network network = getNetwork(conn, nic); + + // Determine the correct VIF on DomR to associate/disassociate the + // IP address with + VIF correctVif = getCorrectVif(conn, router, network); + + // If we are disassociating the last IP address in the VLAN, we need + // to remove a VIF + boolean removeVif = false; + + if (correctVif == null) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } + + if (removeVif) { + network = correctVif.getNetwork(conn); + + // Mark this vif to be removed from network usage + networkUsage(conn, routerIp, "deleteVif", "eth" + correctVif.getDevice(conn)); + + // Remove the VIF from DomR + correctVif.unplug(conn); + correctVif.destroy(conn); + + // Disable the VLAN network if necessary + disableVlanNetwork(conn, network); + } } } catch (InternalErrorException e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + return new ExecutionResult(false, e.getMessage()); + } catch (Exception e) { + return new ExecutionResult(false, e.getMessage()); } - - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } protected GetVncPortAnswer execute(GetVncPortCommand cmd) { @@ -6013,8 +5531,12 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe CheckXenHostInfo(); storageHandler = getStorageHandler(); - return true; + _vrResource = new VirtualRoutingResource(this); + if (!_vrResource.configure(name, params)) { + throw new ConfigurationException("Unable to configure VirtualRoutingResource"); + } + return true; } protected StorageSubsystemCommandHandler getStorageHandler() { @@ -7484,75 +7006,6 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return new Answer(cmd, success, ""); } - private Answer execute(SetMonitorServiceCommand cmd) { - boolean success = true; - - String config = cmd.getConfiguration(); - - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - if (routerIp == null) { - return new Answer(cmd); - } - - String args = " -c " + config; - - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "monitor_service.sh", args); - if (!result.isSuccess()) { - return new Answer(cmd, false, "SetMonitorServiceCommand failed to create cfg file." + result.getDetails()); - } - - return new Answer(cmd, success, ""); - - } - - protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) { - String[] results = new String[cmd.getRules().length]; - ExecutionResult callResult; - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - FirewallRuleTO[] allrules = cmd.getRules(); - FirewallRule.TrafficType trafficType = allrules[0].getTrafficType(); - if (routerIp == null) { - return new SetFirewallRulesAnswer(cmd, false, results); - } - - String[][] rules = cmd.generateFwRules(); - String args = " -F"; - if (trafficType == FirewallRule.TrafficType.Egress) { - args += " -E"; - if (egressDefault.equals("true")) { - args += " -P 1"; - } else if (egressDefault.equals("System")) { - args += " -P 2"; - } else { - args += " -P 0"; - } - } - StringBuilder sb = new StringBuilder(); - String[] fwRules = rules[0]; - if (fwRules.length > 0) { - for (int i = 0; i < fwRules.length; i++) { - sb.append(fwRules[i]).append(','); - } - args += " -a " + sb.toString(); - } - - if (trafficType == FirewallRule.TrafficType.Egress) { - callResult = executeInVR(routerIp, "firewall_egress.sh", args); - } else { - callResult = executeInVR(routerIp, "firewall_ingress.sh", args); - } - - if (!callResult.isSuccess()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed: " + callResult.getDetails(); - } - return new SetFirewallRulesAnswer(cmd, false, results); - } - return new SetFirewallRulesAnswer(cmd, true, results); - } - protected Answer execute(final ClusterSyncCommand cmd) { Connection conn = getConnection(); //check if this is master @@ -7796,28 +7249,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe * @param cmd * @return */ - private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { + private ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { Connection conn = getConnection(); NicTO nic = cmd.getNic(); - cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } try { Set vms = VM.getByNameLabel(conn, domrName); if (vms == null || vms.isEmpty()) { - return new SetupGuestNetworkAnswer(cmd, false, "Can not find VM " + domrName); + return new ExecutionResult(false, "Can not find VM " + domrName); } VM vm = vms.iterator().next(); String mac = nic.getMac(); @@ -7830,105 +7269,46 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } if (domrVif == null) { - return new SetupGuestNetworkAnswer(cmd, false, "Can not find vif with mac " + mac + " for VM " + domrName); + return new ExecutionResult(false, "Can not find vif with mac " + mac + " for VM " + domrName); } - String args = (cmd.isAdd()?" -C":" -D"); - String dev = "eth" + domrVif.getDevice(conn); - args += " -d " + dev; - args += " -i " + domrGIP; - args += " -g " + gw; - args += " -m " + cidr; - args += " -n " + NetUtils.getSubNet(domrGIP, nic.getNetmask()); - if (dns != null && !dns.isEmpty()) { - args += " -s " + dns; - } - if (domainName != null && !domainName.isEmpty()) { - args += " -e " + domainName; - } - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_guestnw.sh", args); - if (!result.isSuccess()) { - return new SetupGuestNetworkAnswer(cmd, false, "creating guest network failed due to " + result.getDetails()); - } - return new SetupGuestNetworkAnswer(cmd, true, "success"); + nic.setDeviceId(Integer.valueOf(domrVif.getDevice(conn))); } catch (Exception e) { String msg = "Creating guest network failed due to " + e.toString(); s_logger.warn(msg, e); - return new SetupGuestNetworkAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { Connection conn = getConnection(); - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); try { IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { - assignVPCPublicIpAddress(conn, routerName, routerIp, ip); - results[i++] = ip.getPublicIp() + " - success"; + VM router = getVM(conn, routerName); + + VIF correctVif = getVifByMac(conn, router, ip.getVifMacAddress()); + if (correctVif == null) { + if (ip.isAdd()) { + throw new InternalErrorException("Failed to find DomR VIF to associate IP with."); + } else { + s_logger.debug("VIF to deassociate IP with does not exist, return success"); + } + } + ip.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); } } catch (Exception e) { s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + return new ExecutionResult(false, e.getMessage()); } - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } - protected Answer execute(Site2SiteVpnCfgCommand cmd) { - String args = ""; - if (cmd.isCreate()) { - args += " -A"; - args += " -l "; - args += cmd.getLocalPublicIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -g "; - args += cmd.getLocalPublicGateway(); - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - args += " -e "; - args += "\"" + cmd.getEspPolicy() + "\""; - args += " -i "; - args += "\"" + cmd.getIkePolicy() + "\""; - args += " -t "; - args += Long.toString(cmd.getIkeLifetime()); - args += " -T "; - args += Long.toString(cmd.getEspLifetime()); - args += " -s "; - args += "\"" + cmd.getIpsecPsk() + "\""; - args += " -d "; - if (cmd.getDpd()) { - args += "1"; - } else { - args += "0"; - } - if (cmd.isPassive()) { - args += " -p "; - } - } else { - args += " -D"; - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - } - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "ipsectunnel.sh", args); - if (!result.isSuccess()) { - return new Answer(cmd, false, "Configure site to site VPN failed! " + result.getDetails()); - } - return new Answer(cmd); - } - - protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { Connection conn = getConnection(); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); IpAddressTO pubIp = cmd.getIpAddress(); @@ -7937,139 +7317,33 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe VIF correctVif = getCorrectVif(conn, router, pubIp); - String args = ""; + pubIp.setNicDevId(Integer.valueOf(correctVif.getDevice(conn))); - args += " -A "; - args += " -l "; - args += pubIp.getPublicIp(); - - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_snat.sh", args); - if (!result.isSuccess()) { - throw new InternalErrorException("Xen plugin \"vpc_snat\" failed." + result.getDetails()); - } - return new SetSourceNatAnswer(cmd, true, "success"); } catch (Exception e) { String msg = "Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); - return new SetSourceNatAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { - String[] results = new String[cmd.getRules().length]; - ExecutionResult callResult; + protected ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) { Connection conn = getConnection(); String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); try { VM router = getVM(conn, routerName); - String[][] rules = cmd.generateFwRules(); - StringBuilder sb = new StringBuilder(); - String[] aclRules = rules[0]; - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - if (privateGw != null) { - s_logger.debug("Private gateway configuration is set"); - } NicTO nic = cmd.getNic(); VIF vif = getVifByMac(conn, router, nic.getMac()); - if (privateGw != null) { - s_logger.debug("Private gateway configuration is set"); - String args = ""; - args += " -d " + "eth" + vif.getDevice(conn); - args += " -a " + sb.toString(); - - callResult = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_privategw_acl.sh", args); - if (!callResult.isSuccess()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed:" + callResult.getDetails(); - } - return new SetNetworkACLAnswer(cmd, false, results); - } - } else { - String args = ""; - args += " -d " + "eth" + vif.getDevice(conn); - args += " -i " + nic.getIp(); - args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - args += " -a " + sb.toString(); - - callResult = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_acl.sh", args); - if (!callResult.isSuccess()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed:" + callResult.getDetails(); - } - return new SetNetworkACLAnswer(cmd, false, results); - } - } - return new SetNetworkACLAnswer(cmd, true, results); + nic.setDeviceId(Integer.valueOf(vif.getDevice(conn))); } catch (Exception e) { - String msg = "SetNetworkACL failed due to " + e.toString(); + String msg = "Prepare SetNetworkACL failed due to " + e.toString(); s_logger.error(msg, e); - return new SetNetworkACLAnswer(cmd, false, results); - } - } - - protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - String args = ""; - args += rule.revoked() ? " -D" : " -A"; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - - ExecutionResult result = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_portforwarding.sh", args); - - if (!result.isSuccess()) { - results[i++] = "Failed:" + result.getDetails(); - endResult = false; - } else { - results[i++] = null; - } - } - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { - ExecutionResult callResult; - try { - String[] results = new String[cmd.getStaticRoutes().length]; - String[][] rules = cmd.generateSRouteRules(); - StringBuilder sb = new StringBuilder(); - String[] srRules = rules[0]; - for (int i = 0; i < srRules.length; i++) { - sb.append(srRules[i]).append(','); - } - String args = "-a " + sb.toString(); - callResult = executeInVR(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), "vpc_staticroute.sh", args); - if (!callResult.isSuccess()) { - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed:" + callResult.getDetails(); - } - return new SetStaticRouteAnswer(cmd, false, results); - } - return new SetStaticRouteAnswer(cmd, true, results); - } catch (Exception e) { - String msg = "SetStaticRoute failed due to " + e.toString(); - s_logger.error(msg, e); - return new SetStaticRouteAnswer(cmd, false, null); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } @Override From cb8cf1eb18778e8cdd1bd3b870e1a2422a3d04e5 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Fri, 24 Jan 2014 18:23:42 -0800 Subject: [PATCH 031/126] CLOUDSTACK-5614: UI - Infrastructure > Sockets > listView > (1) split "XenServer" into "XenServer 6.2.0" and "XenServer"(prior to 6.2.0). (2) change label of Hyperv to Hyper-V. --- ui/scripts/system.js | 113 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 22 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 64e4f5c959f..870b4338bdd 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -404,7 +404,7 @@ var returnedHostCount = 0; var returnedHostCpusocketsSum = 0; - var callListHostsWithPage = function (setTotalHostCount) { + var callListHostsWithPage = function() { $.ajax({ url: createURL('listHosts'), async: false, @@ -419,9 +419,7 @@ return; } - if (setTotalHostCount) { totalHostCount = json.listhostsresponse.count; - } returnedHostCount += json.listhostsresponse.host.length; var items = json.listhostsresponse.host; @@ -433,13 +431,13 @@ if (returnedHostCount < totalHostCount) { currentPage++; - callListHostsWithPage(false); + callListHostsWithPage(); } } }); } - callListHostsWithPage(true); + callListHostsWithPage(); socketCount += returnedHostCpusocketsSum; }) @@ -8419,30 +8417,30 @@ } }, dataProvider: function (args) { - $.ajax({ - url: createURL('listHypervisors'), - success: function (json) { + var array1 = []; + + // ***** non XenServer (begin) ***** + var hypervisors = ["Hyperv", "KVM", "VMware", "BareMetal", "Ovm", "LXC"]; + var supportSocketHypervisors = { "Hyperv": 1, "KVM": 1, - "XenServer": 1, "VMware": 1 }; - args.response.success({ - data: $(json.listhypervisorsresponse.hypervisor).map(function (index, hypervisor) { + for (var h = 0; h < hypervisors.length; h++) { var totalHostCount = 0; var currentPage = 1; var returnedHostCount = 0; var returnedHostCpusocketsSum = 0; - var callListHostsWithPage = function (setTotalHostCount) { + var callListHostsWithPage = function() { $.ajax({ url: createURL('listHosts'), async: false, data: { type: 'routing', - hypervisor: hypervisor.name, + hypervisor: hypervisors[h], page: currentPage, pagesize: pageSize //global variable }, @@ -8451,9 +8449,7 @@ return; } - if (setTotalHostCount) { totalHostCount = json.listhostsresponse.count; - } returnedHostCount += json.listhostsresponse.host.length; var items = json.listhostsresponse.host; @@ -8465,27 +8461,100 @@ if (returnedHostCount < totalHostCount) { currentPage++; - callListHostsWithPage(false); + callListHostsWithPage(); } } }); } - callListHostsWithPage(true); + callListHostsWithPage(); - if ((hypervisor.name in supportSocketHypervisors) == false) { + if ((hypervisors[h] in supportSocketHypervisors) == false) { returnedHostCpusocketsSum = 'N/A'; } - return { - hypervisor: hypervisor.name, + var hypervisorName = hypervisors[h]; + if (hypervisorName == "Hyperv") { + hypervisorName = "Hyper-V"; + } + + array1.push({ + hypervisor: hypervisorName, hosts: totalHostCount, sockets: returnedHostCpusocketsSum - }; - }) }); } + // ***** non XenServer (end) ***** + + + // ***** XenServer (begin) ***** + var totalHostCount = 0; + var currentPage = 1; + var returnedHostCount = 0; + + var returnedHostCountForXenServer = 0; + var returnedHostCountForXenServer620 = 0; + var returnedHostCpusocketsSumForXenServer620 = 0; + + var callListHostsWithPage = function() { + $.ajax({ + url: createURL('listHosts'), + async: false, + data: { + type: 'routing', + hypervisor: 'XenServer', + page: currentPage, + pagesize: pageSize //global variable + }, + success: function(json) { + if (json.listhostsresponse.count == undefined) { + return; + } + + totalHostCount = json.listhostsresponse.count; + returnedHostCount += json.listhostsresponse.host.length; + + var items = json.listhostsresponse.host; + for (var i = 0; i < items.length; i++) { + //"hypervisorversion" == "6.2.0" + if (items[i].hypervisorversion == "6.2.0") { + returnedHostCountForXenServer620 ++; + if (items[i].cpusockets != undefined && isNaN(items[i].cpusockets) == false) { + returnedHostCpusocketsSumForXenServer620 += items[i].cpusockets; + } + } else { + returnedHostCountForXenServer++; + } + } + + if (returnedHostCount < totalHostCount) { + currentPage++; + callListHostsWithPage(); + } + } + }); + } + + callListHostsWithPage(); + + array1.push({ + hypervisor: 'XenServer', + hosts: returnedHostCountForXenServer, + sockets: 'N/A' }); + + array1.push({ + hypervisor: 'XenServer 6.2.0', + hosts: returnedHostCountForXenServer620, + sockets: returnedHostCpusocketsSumForXenServer620 + }); + // ***** XenServer (end) ***** + + + args.response.success({ + data: array1 + }); + } }; From 3c955c3659c3e29491833a9574c96a35a5591aa8 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Mon, 20 Jan 2014 12:03:07 -0800 Subject: [PATCH 032/126] CLOUDSTACK-5779: Make VmwareResource use VirtualRoutingResource --- .../resource/LibvirtComputingResource.java | 1 + .../vmware/resource/VmwareResource.java | 1268 +++-------------- .../xen/resource/CitrixResourceBase.java | 1 + 3 files changed, 207 insertions(+), 1063 deletions(-) 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 fa0d99f1a30..ab374462ace 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 @@ -351,6 +351,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv public ExecutionResult prepareCommand(NetworkElementCommand cmd) { //Update IP used to access router cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + assert cmd.getRouterAccessIp() != null; if (cmd instanceof IpAssocVpcCommand) { return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index e5158cb1bb7..407327592bc 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -44,7 +44,6 @@ import java.util.concurrent.TimeUnit; import javax.naming.ConfigurationException; -import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.apache.log4j.NDC; @@ -115,17 +114,12 @@ import com.cloud.agent.api.AttachVolumeAnswer; import com.cloud.agent.api.AttachVolumeCommand; import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.agent.api.BackupSnapshotCommand; -import com.cloud.agent.api.BumpUpPriorityCommand; import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; import com.cloud.agent.api.CheckOnHostAnswer; import com.cloud.agent.api.CheckOnHostCommand; -import com.cloud.agent.api.CheckRouterAnswer; -import com.cloud.agent.api.CheckRouterCommand; -import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer; -import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.Command; @@ -139,8 +133,6 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.DeleteVMSnapshotAnswer; import com.cloud.agent.api.DeleteVMSnapshotCommand; -import com.cloud.agent.api.GetDomRVersionAnswer; -import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetHostStatsAnswer; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.GetStorageStatsAnswer; @@ -186,7 +178,6 @@ import com.cloud.agent.api.ScaleVmAnswer; import com.cloud.agent.api.ScaleVmCommand; import com.cloud.agent.api.SetupAnswer; import com.cloud.agent.api.SetupCommand; -import com.cloud.agent.api.SetupGuestNetworkAnswer; import com.cloud.agent.api.SetupGuestNetworkCommand; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; @@ -206,35 +197,11 @@ import com.cloud.agent.api.ValidateSnapshotCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; -import com.cloud.agent.api.routing.CreateIpAliasCommand; -import com.cloud.agent.api.routing.DeleteIpAliasCommand; -import com.cloud.agent.api.routing.DhcpEntryCommand; -import com.cloud.agent.api.routing.DnsMasqConfigCommand; -import com.cloud.agent.api.routing.IpAliasTO; -import com.cloud.agent.api.routing.IpAssocAnswer; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.IpAssocVpcCommand; -import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.NetworkElementCommand; -import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand; -import com.cloud.agent.api.routing.SavePasswordCommand; -import com.cloud.agent.api.routing.SetFirewallRulesAnswer; -import com.cloud.agent.api.routing.SetFirewallRulesCommand; -import com.cloud.agent.api.routing.SetMonitorServiceCommand; -import com.cloud.agent.api.routing.SetNetworkACLAnswer; import com.cloud.agent.api.routing.SetNetworkACLCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer; -import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; -import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; -import com.cloud.agent.api.routing.SetSourceNatAnswer; import com.cloud.agent.api.routing.SetSourceNatCommand; -import com.cloud.agent.api.routing.SetStaticNatRulesAnswer; -import com.cloud.agent.api.routing.SetStaticNatRulesCommand; -import com.cloud.agent.api.routing.SetStaticRouteAnswer; -import com.cloud.agent.api.routing.SetStaticRouteCommand; -import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand; -import com.cloud.agent.api.routing.VmDataCommand; -import com.cloud.agent.api.routing.VpnUsersCfgCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateAnswer; @@ -248,17 +215,15 @@ import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DhcpTO; import com.cloud.agent.api.to.DiskTO; -import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.api.to.PortForwardingRuleTO; -import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.resource.virtualnetwork.VirtualRouterDeployer; +import com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource; import com.cloud.configuration.Config; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.Vlan; @@ -293,13 +258,10 @@ import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostResourceSummary; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareGuestOsMapper; import com.cloud.hypervisor.vmware.util.VmwareHelper; -import com.cloud.network.HAProxyConfigurator; -import com.cloud.network.LoadBalancerConfigurator; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.VmwareTrafficLabel; -import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; import com.cloud.serializer.GsonHelper; import com.cloud.storage.Storage; @@ -331,7 +293,7 @@ import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineName; import com.cloud.vm.VmDetailConstants; -public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService { +public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(VmwareResource.class); protected String _name; @@ -380,6 +342,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa protected StorageSubsystemCommandHandler storageHandler; + protected VirtualRoutingResource _vrResource; + protected static HashMap s_powerStatesTable; static { s_powerStatesTable = new HashMap(); @@ -429,26 +393,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa Class clz = cmd.getClass(); if (clz == CreateCommand.class) { answer = execute((CreateCommand)cmd); - } else if (clz == SetPortForwardingRulesCommand.class) { - answer = execute((SetPortForwardingRulesCommand)cmd); - } else if (clz == SetStaticNatRulesCommand.class) { - answer = execute((SetStaticNatRulesCommand)cmd); - } else if (clz == LoadBalancerConfigCommand.class) { - answer = execute((LoadBalancerConfigCommand)cmd); - } else if (clz == IpAssocCommand.class) { - answer = execute((IpAssocCommand)cmd); - } else if (clz == SavePasswordCommand.class) { - answer = execute((SavePasswordCommand)cmd); - } else if (clz == DhcpEntryCommand.class) { - answer = execute((DhcpEntryCommand)cmd); - } else if (clz == CreateIpAliasCommand.class) { - return execute((CreateIpAliasCommand)cmd); - } else if (clz == DnsMasqConfigCommand.class) { - return execute((DnsMasqConfigCommand)cmd); - } else if (clz == DeleteIpAliasCommand.class) { - return execute((DeleteIpAliasCommand)cmd); - } else if (clz == VmDataCommand.class) { - answer = execute((VmDataCommand)cmd); + } else if (cmd instanceof NetworkElementCommand) { + return _vrResource.executeRequest(cmd); } else if (clz == ReadyCommand.class) { answer = execute((ReadyCommand)cmd); } else if (clz == GetHostStatsCommand.class) { @@ -525,62 +471,32 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa answer = execute((NetworkUsageCommand)cmd); } else if (clz == StartCommand.class) { answer = execute((StartCommand)cmd); - } else if (clz == RemoteAccessVpnCfgCommand.class) { - answer = execute((RemoteAccessVpnCfgCommand)cmd); - } else if (clz == VpnUsersCfgCommand.class) { - answer = execute((VpnUsersCfgCommand)cmd); } else if (clz == CheckSshCommand.class) { answer = execute((CheckSshCommand)cmd); - } else if (clz == CheckRouterCommand.class) { - answer = execute((CheckRouterCommand)cmd); - } else if (clz == SetFirewallRulesCommand.class) { - answer = execute((SetFirewallRulesCommand)cmd); - } else if (clz == BumpUpPriorityCommand.class) { - answer = execute((BumpUpPriorityCommand)cmd); - } else if (clz == GetDomRVersionCmd.class) { - answer = execute((GetDomRVersionCmd)cmd); } else if (clz == CheckNetworkCommand.class) { answer = execute((CheckNetworkCommand)cmd); - } else if (clz == SetupGuestNetworkCommand.class) { - answer = execute((SetupGuestNetworkCommand)cmd); - } else if (clz == IpAssocVpcCommand.class) { - answer = execute((IpAssocVpcCommand)cmd); } else if (clz == PlugNicCommand.class) { answer = execute((PlugNicCommand)cmd); } else if (clz == UnPlugNicCommand.class) { answer = execute((UnPlugNicCommand)cmd); - } else if (clz == SetSourceNatCommand.class) { - answer = execute((SetSourceNatCommand)cmd); - } else if (clz == SetNetworkACLCommand.class) { - answer = execute((SetNetworkACLCommand)cmd); } else if (cmd instanceof CreateVMSnapshotCommand) { return execute((CreateVMSnapshotCommand)cmd); } else if (cmd instanceof DeleteVMSnapshotCommand) { return execute((DeleteVMSnapshotCommand)cmd); } else if (cmd instanceof RevertToVMSnapshotCommand) { return execute((RevertToVMSnapshotCommand)cmd); - } else if (clz == SetPortForwardingRulesVpcCommand.class) { - answer = execute((SetPortForwardingRulesVpcCommand)cmd); - } else if (clz == Site2SiteVpnCfgCommand.class) { - answer = execute((Site2SiteVpnCfgCommand)cmd); - } else if (clz == CheckS2SVpnConnectionsCommand.class) { - answer = execute((CheckS2SVpnConnectionsCommand)cmd); } else if (clz == ResizeVolumeCommand.class) { return execute((ResizeVolumeCommand)cmd); } else if (clz == UnregisterVMCommand.class) { - return execute((UnregisterVMCommand)cmd); + return execute((UnregisterVMCommand) cmd); } else if (cmd instanceof StorageSubSystemCommand) { - return storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); + return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd); } else if (clz == ScaleVmCommand.class) { return execute((ScaleVmCommand)cmd); } else if (clz == PvlanSetupCommand.class) { return execute((PvlanSetupCommand)cmd); - } else if (clz == SetStaticRouteCommand.class) { - answer = execute((SetStaticRouteCommand)cmd); } else if (clz == UnregisterNicCommand.class) { answer = execute((UnregisterNicCommand)cmd); - } else if (clz == SetMonitorServiceCommand.class) { - answer = execute((SetMonitorServiceCommand)cmd); } else { answer = Answer.createUnsupportedCommandAnswer(cmd); } @@ -696,39 +612,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return answer; } - private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetStaticRouteCommand: " + _gson.toJson(cmd)); - } - - boolean endResult = true; - - String controlIp = getRouterSshControlIp(cmd); - String args = ""; - String[] results = new String[cmd.getStaticRoutes().length]; - String[][] rules = cmd.generateSRouteRules(); - int i = 0; - - StringBuilder sb = new StringBuilder(); - String[] srRules = rules[0]; - for (int j = 0; j < srRules.length; j++) { - sb.append(srRules[j]).append(','); - } - args += " -a " + sb.toString(); - - ExecutionResult result = executeInVR(controlIp, "vpc_staticroute.sh", args); - - if (!result.isSuccess()) { - s_logger.error("SetStaticRouteCommand failure on setting one rule. args: " + args); - while (i < results.length) { - results[i++] = "Failed"; - } - endResult = false; - } - return new SetStaticRouteAnswer(cmd, endResult, results); - - } - protected NetworkUsageAnswer VPCNetworkUsage(NetworkUsageCommand cmd) { String privateIp = cmd.getPrivateIP(); String option = cmd.getOption(); @@ -776,180 +659,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new NetworkUsageAnswer(cmd, "success", 0L, 0L); } - protected Answer execute(SetMonitorServiceCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetMonitorServiceCommand: " + _gson.toJson(cmd)); - } - - String controlIp = getRouterSshControlIp(cmd); - String config = cmd.getConfiguration(); - - String args = ""; - - args += " -c " + config; - - ExecutionResult result = executeInVR(controlIp, "monitor_service.sh", args); - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } - return new Answer(cmd); - } - - protected Answer execute(SetPortForwardingRulesCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetPortForwardingRulesCommand: " + _gson.toJson(cmd)); - } - - String controlIp = getRouterSshControlIp(cmd); - String args = ""; - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - args += rule.revoked() ? " -D " : " -A "; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange(); - - ExecutionResult result = executeInVR(controlIp, "firewall_nat.sh", args); - if (!result.isSuccess()) { - s_logger.error("SetPortForwardingRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - String[] results = new String[cmd.getRules().length]; - FirewallRuleTO[] allrules = cmd.getRules(); - FirewallRule.TrafficType trafficType = allrules[0].getTrafficType(); - String egressDefault = cmd.getAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT); - - String[][] rules = cmd.generateFwRules(); - String args = ""; - args += " -F "; - if (trafficType == FirewallRule.TrafficType.Egress) { - args += " -E "; - if (egressDefault.equals("true")) { - args += " -P 1 "; - } else if (egressDefault.equals("System")) { - args += " -P 2 "; - } else { - args += " -P 0 "; - } - } - - StringBuilder sb = new StringBuilder(); - String[] fwRules = rules[0]; - if (fwRules.length > 0) { - for (int i = 0; i < fwRules.length; i++) { - sb.append(fwRules[i]).append(','); - } - args += " -a " + sb.toString(); - } - - ExecutionResult result = null; - - if (trafficType == FirewallRule.TrafficType.Egress) { - result = executeInVR(controlIp, "firewall_egress.sh", args); - } else { - result = executeInVR(controlIp, "firewall_ingress.sh", args); - } - - if (!result.isSuccess()) { - s_logger.error("SetFirewallRulesCommand failure on setting one rule. args: " + args); - //FIXME - in the future we have to process each rule separately; now we temporarily set every rule to be false if single rule fails - for (int i = 0; i < results.length; i++) { - results[i] = "Failed"; - } - - return new SetFirewallRulesAnswer(cmd, false, results); - } - - return new SetFirewallRulesAnswer(cmd, true, results); - } - - protected SetStaticNatRulesAnswer SetVPCStaticNatRules(SetStaticNatRulesCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetVPCStaticNatRulesCommand: " + _gson.toJson(cmd)); - } - - String[] results = new String[cmd.getRules().length]; - String controlIp = getRouterSshControlIp(cmd); - - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - String args = ""; - args += rule.revoked() ? " -D" : " -A"; - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - - ExecutionResult result = executeInVR(controlIp, "vpc_staticnat.sh", args); - - if (!result.isSuccess()) { - s_logger.error("SetVPCStaticNatRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected Answer execute(SetStaticNatRulesCommand cmd) { - - if (cmd.getVpcId() != null) { - return SetVPCStaticNatRules(cmd); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetFirewallRuleCommand: " + _gson.toJson(cmd)); - } - - String args = null; - String[] results = new String[cmd.getRules().length]; - int i = 0; - boolean endResult = true; - for (StaticNatRuleTO rule : cmd.getRules()) { - // 1:1 NAT needs instanceip;publicip;domrip;op - args = rule.revoked() ? " -D " : " -A "; - - args += " -l " + rule.getSrcIp(); - args += " -r " + rule.getDstIp(); - - if (rule.getProtocol() != null) { - args += " -P " + rule.getProtocol().toLowerCase(); - } - - args += " -d " + rule.getStringSrcPortRange(); - args += " -G "; - - String controlIp = getRouterSshControlIp(cmd); - ExecutionResult result = executeInVR(controlIp, "firewall_nat.sh", args); - - if (!result.isSuccess()) { - s_logger.error("SetStaticNatRulesCommand failure on setting one rule. args: " + args); - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - return new SetStaticNatRulesAnswer(cmd, results, endResult); - } - - protected boolean createFileInVR(String routerIp, String filePath, String fileName, String content) { + @Override + public ExecutionResult createFileInVR(String routerIp, String filePath, String fileName, String content) { VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); File keyFile = mgr.getSystemVMKeyFile(); boolean result = true; @@ -958,89 +669,34 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa SshHelper.scpTo(routerIp, 3922, "root", keyFile, null, filePath, content.getBytes(), fileName, null); } catch (Exception e) { s_logger.warn("Fail to create file " + filePath + fileName + " in VR " + routerIp, e); - result = false; + return new ExecutionResult(false, e.getMessage()); } - return result; + return new ExecutionResult(true, null); } - protected Answer execute(final LoadBalancerConfigCommand cmd) { - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + @Override + public ExecutionResult prepareCommand(NetworkElementCommand cmd) { + //Update IP used to access router + cmd.setRouterAccessIp(getRouterSshControlIp(cmd)); + assert cmd.getRouterAccessIp() != null; - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String controlIp = getRouterSshControlIp(cmd); - - assert (controlIp != null); - - LoadBalancerConfigurator cfgtr = new HAProxyConfigurator(); - String[] config = cfgtr.generateConfiguration(cmd); - - String tmpCfgFileContents = ""; - String tmpCfgFileName = "haproxy.cfg.new"; - String tmpCfgFilePath = "/etc/haproxy/"; - for (int i = 0; i < config.length; i++) { - tmpCfgFileContents += config[i]; - tmpCfgFileContents += "\n"; + if (cmd instanceof IpAssocVpcCommand) { + return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); + } else if (cmd instanceof IpAssocCommand) { + return prepareNetworkElementCommand((IpAssocCommand)cmd); + } else if (cmd instanceof SetSourceNatCommand) { + return prepareNetworkElementCommand((SetSourceNatCommand)cmd); + } else if (cmd instanceof SetupGuestNetworkCommand) { + return prepareNetworkElementCommand((SetupGuestNetworkCommand)cmd); + } else if (cmd instanceof SetNetworkACLCommand) { + return prepareNetworkElementCommand((SetNetworkACLCommand)cmd); } + return new ExecutionResult(true, null); + } - if (!createFileInVR(controlIp, tmpCfgFilePath, tmpCfgFileName, tmpCfgFileContents)) { - return new Answer(cmd, false, "Fail to create LB config file in VR"); - } - - String[][] rules = cfgtr.generateFwRules(cmd); - - String[] addRules = rules[LoadBalancerConfigurator.ADD]; - String[] removeRules = rules[LoadBalancerConfigurator.REMOVE]; - String[] statRules = rules[LoadBalancerConfigurator.STATS]; - - String args = ""; - StringBuilder sb = new StringBuilder(); - if (addRules.length > 0) { - for (int i = 0; i < addRules.length; i++) { - sb.append(addRules[i]).append(','); - } - - args += " -a " + sb.toString(); - } - - sb = new StringBuilder(); - if (removeRules.length > 0) { - for (int i = 0; i < removeRules.length; i++) { - sb.append(removeRules[i]).append(','); - } - - args += " -d " + sb.toString(); - } - - sb = new StringBuilder(); - if (statRules.length > 0) { - for (int i = 0; i < statRules.length; i++) { - sb.append(statRules[i]).append(','); - } - - args += " -s " + sb.toString(); - } - - ExecutionResult result; - if (cmd.getVpcId() == null) { - args = " -i " + routerIp + args; - result = executeInVR(controlIp, "loadbalancer.sh", args); - } else { - args = " -i " + cmd.getNic().getIp() + args; - result = executeInVR(controlIp, "vpc_loadbalancer.sh", args); - } - // Invoke the command - - if (!result.isSuccess()) { - String msg = "LoadBalancerConfigCommand on domain router " + routerIp + " failed. message: " + result.getDetails(); - s_logger.error(msg); - - return new Answer(cmd, false, msg); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("LoadBalancerConfigCommand on domain router " + routerIp + " completed"); - } - return new Answer(cmd); + @Override + public ExecutionResult cleanupCommand(NetworkElementCommand cmd) { + return new ExecutionResult(true, null); } // @@ -1108,75 +764,26 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return null; } - private SetupGuestNetworkAnswer execute(SetupGuestNetworkCommand cmd) { - - s_logger.info("Executing resource SetupGuestNetworkCommand " + _gson.toJson(cmd)); - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - + protected ExecutionResult prepareNetworkElementCommand(SetupGuestNetworkCommand cmd) { NicTO nic = cmd.getNic(); - String routerIp = getRouterSshControlIp(cmd); - String domrGIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP); - String domrName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String gw = cmd.getAccessDetail(NetworkElementCommand.GUEST_NETWORK_GATEWAY); - String cidr = Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - String domainName = cmd.getNetworkDomain(); - String dns = cmd.getDefaultDns1(); - if (dns == null || dns.isEmpty()) { - dns = cmd.getDefaultDns2(); - } else { - String dns2 = cmd.getDefaultDns2(); - if (dns2 != null && !dns2.isEmpty()) { - dns += "," + dns2; - } - } + String domrName = + cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); try { - int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, nic.getMac()); - s_logger.info("find interface index. routerIp: " + routerIp + ", mac: " + nic.getMac() + ", index: " + ethDeviceNum); - - String args = (cmd.isAdd() ? "-C" : "-D"); - String dev = "eth" + ethDeviceNum; - args += " -d " + dev; - args += " -i " + domrGIP; - args += " -g " + gw; - args += " -m " + cidr; - args += " -n " + NetUtils.getSubNet(domrGIP, nic.getNetmask()); - if (dns != null && !dns.isEmpty()) { - args += " -s " + dns; - } - if (domainName != null && !domainName.isEmpty()) { - args += " -e " + domainName; - } - - ExecutionResult result = executeInVR(routerIp, "vpc_guestnw.sh", args); - - if (!result.isSuccess()) { - String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.getDetails(); - s_logger.error(msg); - return new SetupGuestNetworkAnswer(cmd, false, msg); - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("SetupGuestNetworkCommand on domain router " + routerIp + " completed"); - } - - return new SetupGuestNetworkAnswer(cmd, true, "success"); + int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, + nic.getMac()); + nic.setDeviceId(ethDeviceNum); } catch (Exception e) { - String msg = "SetupGuestNetwork failed due to " + e.toString(); + String msg = "Prepare SetupGuestNetwork failed due to " + e.toString(); s_logger.warn(msg, e); - return new SetupGuestNetworkAnswer(cmd, false, msg); + return new ExecutionResult(false, msg); } + return new ExecutionResult(true, null); } - protected IpAssocAnswer execute(IpAssocVpcCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource IpAssocVpcCommand " + _gson.toJson(cmd)); - } - String[] results = new String[cmd.getIpAddresses().length]; - int i = 0; + private ExecutionResult prepareNetworkElementCommand(IpAssocVpcCommand cmd) { String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); @@ -1184,217 +791,58 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa IpAddressTO[] ips = cmd.getIpAddresses(); for (IpAddressTO ip : ips) { - assignVPCPublicIpAddress(routerName, routerIp, ip); - results[i++] = ip.getPublicIp() + " - success"; + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, ip.getVifMacAddress()); + if (ethDeviceNum < 0) { + if (ip.isAdd()) { + throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); + } else { + s_logger.debug("VIF to deassociate IP with does not exist, return success"); + continue; + } + } + + ip.setNicDevId(ethDeviceNum); } } catch (Exception e) { - s_logger.error("Ip Assoc failure on applying one ip due to exception: ", e); - results[i++] = IpAssocAnswer.errorResult; + s_logger.error("Prepare Ip Assoc failure on applying one ip due to exception: ", e); + return new ExecutionResult(false, e.toString()); } - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } - protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetSourceNatCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - + protected ExecutionResult prepareNetworkElementCommand(SetSourceNatCommand cmd) { String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); IpAddressTO pubIp = cmd.getIpAddress(); try { int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, pubIp.getVifMacAddress()); - String args = ""; - args += " -A "; - args += " -l "; - args += pubIp.getPublicIp(); - - args += " -c "; - args += "eth" + ethDeviceNum; - - ExecutionResult result = executeInVR(routerIp, "vpc_snat.sh", args); - - if (!result.isSuccess()) { - String msg = "SetupGuestNetworkCommand on domain router " + routerIp + " failed. message: " + result.getDetails(); - s_logger.error(msg); - - return new SetSourceNatAnswer(cmd, false, msg); - } - - return new SetSourceNatAnswer(cmd, true, "success"); + pubIp.setNicDevId(ethDeviceNum); } catch (Exception e) { - String msg = "Ip SNAT failure due to " + e.toString(); + String msg = "Prepare Ip SNAT failure due to " + e.toString(); s_logger.error(msg, e); - return new SetSourceNatAnswer(cmd, false, msg); + return new ExecutionResult(false, e.toString()); } + return new ExecutionResult(true, null); } - private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetNetworkACLCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); - String privateGw = cmd.getAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY); + private ExecutionResult prepareNetworkElementCommand(SetNetworkACLCommand cmd) { + NicTO nic = cmd.getNic(); + String routerName = + cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); String routerIp = getRouterSshControlIp(cmd); - String[] results = new String[cmd.getRules().length]; try { - String[][] rules = cmd.generateFwRules(); - StringBuilder sb = new StringBuilder(); - String[] aclRules = rules[0]; - if (aclRules.length == 0) { - return new SetNetworkACLAnswer(cmd, true, results); - } - - for (int i = 0; i < aclRules.length; i++) { - sb.append(aclRules[i]).append(','); - } - - NicTO nic = cmd.getNic(); - int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, nic.getMac()); - String args = ""; - ExecutionResult result; - - if (privateGw != null) { - s_logger.debug("Private gateway configuration is set"); - args += " -d " + "eth" + ethDeviceNum; - args += " -a " + sb.toString(); - result = executeInVR(routerIp, "vpc_privategw_acl.sh", args); - - if (!result.isSuccess()) { - String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.getDetails(); - s_logger.error(msg); - return new SetNetworkACLAnswer(cmd, false, results); - } - } else { - args = ""; - args += " -d " + "eth" + ethDeviceNum; - args += " -i " + nic.getIp(); - args += " -m " + Long.toString(NetUtils.getCidrSize(nic.getNetmask())); - args += " -a " + sb.toString(); - - result = executeInVR(routerIp, "vpc_acl.sh", args); - - if (!result.isSuccess()) { - String msg = "SetNetworkACLAnswer on domain router " + routerIp + " failed. message: " + result.getDetails(); - s_logger.error(msg); - - return new SetNetworkACLAnswer(cmd, false, results); - } - } - - return new SetNetworkACLAnswer(cmd, true, results); + int ethDeviceNum = findRouterEthDeviceIndex(routerName, routerIp, + nic.getMac()); + nic.setDeviceId(ethDeviceNum); } catch (Exception e) { - String msg = "SetNetworkACL failed due to " + e.toString(); + String msg = "Prepare SetNetworkACL failed due to " + e.toString(); s_logger.error(msg, e); - return new SetNetworkACLAnswer(cmd, false, results); + return new ExecutionResult(false, msg); } - } - - protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SetPortForwardingRulesVpcCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - String routerIp = getRouterSshControlIp(cmd); - - String[] results = new String[cmd.getRules().length]; - int i = 0; - - boolean endResult = true; - for (PortForwardingRuleTO rule : cmd.getRules()) { - String args = ""; - args += rule.revoked() ? " -D" : " -A"; - args += " -P " + rule.getProtocol().toLowerCase(); - args += " -l " + rule.getSrcIp(); - args += " -p " + rule.getStringSrcPortRange(); - args += " -r " + rule.getDstIp(); - args += " -d " + rule.getStringDstPortRange().replace(":", "-"); - - ExecutionResult sshResult = executeInVR(routerIp, "vpc_portforwarding.sh", args); - - if (!sshResult.isSuccess()) { - results[i++] = "Failed"; - endResult = false; - } else { - results[i++] = null; - } - } - return new SetPortForwardingRulesAnswer(cmd, results, endResult); - } - - protected Answer execute(Site2SiteVpnCfgCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource Site2SiteVpnCfgCommand " + _gson.toJson(cmd)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - String routerIp = getRouterSshControlIp(cmd); - - String args = ""; - if (cmd.isCreate()) { - args += " -A"; - args += " -l "; - args += cmd.getLocalPublicIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -g "; - args += cmd.getLocalPublicGateway(); - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - args += " -e "; - args += "\"" + cmd.getEspPolicy() + "\""; - args += " -i "; - args += "\"" + cmd.getIkePolicy() + "\""; - args += " -t "; - args += Long.toString(cmd.getIkeLifetime()); - args += " -T "; - args += Long.toString(cmd.getEspLifetime()); - args += " -s "; - args += "\"" + cmd.getIpsecPsk() + "\""; - args += " -d "; - if (cmd.getDpd()) { - args += "1"; - } else { - args += "0"; - } - if (cmd.isPassive()) { - args += " -p "; - } - } else { - args += " -D"; - args += " -r "; - args += cmd.getPeerGatewayIp(); - args += " -n "; - args += cmd.getLocalGuestCidr(); - args += " -N "; - args += cmd.getPeerGuestCidrList(); - } - - ExecutionResult result = executeInVR(routerIp, "ipsectunnel.sh", args); - - if (!result.isSuccess()) { - s_logger.error("Setup site2site VPN " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.getDetails()); - - return new Answer(cmd, false, "Setup site2site VPN falied due to " + result.getDetails()); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("setup site 2 site vpn on router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed"); - } - - return new Answer(cmd, true, result.getDetails()); + return new ExecutionResult(true, null); } private PlugNicAnswer execute(PlugNicCommand cmd) { @@ -1534,176 +982,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - protected void assignVPCPublicIpAddress(String domrName, String routerIp, IpAddressTO ip) throws Exception { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource assignVPCPublicIpAddress. domrName: " + domrName + ", routerIp: " + routerIp + ", ip: " + _gson.toJson(ip)); - } - - VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME); - - int ethDeviceNum = findRouterEthDeviceIndex(domrName, routerIp, ip.getVifMacAddress()); - if (ethDeviceNum < 0) { - if (ip.isAdd()) { - throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); - } else { - s_logger.debug("VIF to deassociate IP with does not exist, return success"); - return; - } - } - - String args = ""; - String snatArgs = ""; - - if (ip.isAdd()) { - args += " -A "; - snatArgs += " -A "; - } else { - args += " -D "; - snatArgs += " -D "; - } - - args += " -l "; - args += ip.getPublicIp(); - - args += " -c "; - args += "eth" + ethDeviceNum; - - args += " -g "; - args += ip.getVlanGateway(); - - args += " -m "; - args += Long.toString(NetUtils.getCidrSize(ip.getVlanNetmask())); - - args += " -n "; - args += NetUtils.getSubNet(ip.getPublicIp(), ip.getVlanNetmask()); - - ExecutionResult result = executeInVR(routerIp, "vpc_ipassoc.sh", args); - - if (!result.isSuccess()) { - throw new InternalErrorException("Unable to assign public IP address"); - } - - if (ip.isSourceNat()) { - snatArgs += " -l "; - snatArgs += ip.getPublicIp(); - snatArgs += " -c "; - snatArgs += "eth" + ethDeviceNum; - - ExecutionResult result_gateway = executeInVR(routerIp, "vpc_privateGateway.sh", snatArgs); - - if (!result_gateway.isSuccess()) { - throw new InternalErrorException("Unable to configure source NAT for public IP address."); - } - } - } - - protected void assignPublicIpAddress(VirtualMachineMO vmMo, final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, - final boolean firstIP, final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) - throws Exception { - - /** - * TODO support other networks - */ - URI broadcastUri = BroadcastDomainType.fromString(broadcastId); - if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { - throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + broadcastId); - } - String vlanId = BroadcastDomainType.getValue(broadcastUri); - - String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); - Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first()); - } - - boolean addVif = false; - boolean removeVif = false; - if (add && publicNicInfo.first().intValue() == -1) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress); - } - - addVif = true; - } else if (!add && firstIP) { - removeVif = true; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unplug NIC " + publicNicInfo.first()); - } - } - - if (addVif) { - plugPublicNic(vmMo, vlanId, vifMacAddress); - publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); - if (publicNicInfo.first().intValue() >= 0) { - networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo.first()); - } - } - - if (publicNicInfo.first().intValue() < 0) { - String msg = "Failed to find DomR VIF to associate/disassociate IP with."; - s_logger.error(msg); - throw new InternalErrorException(msg); - } - - String args = null; - - if (add) { - args = " -A "; - } else { - args = " -D "; - } - - if (sourceNat) { - args += " -s "; - } - if (firstIP) { - args += " -f "; - } - String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask)); - args += " -l "; - args += publicIpAddress + "/" + cidrSize; - - args += " -c "; - args += "eth" + publicNicInfo.first(); - - args += " -g "; - args += vlanGateway; - - if (addVif) { - args += " -n "; - } - - ExecutionResult result = executeInVR(privateIpAddress, "ipassoc.sh", args); - - if (!result.isSuccess()) { - s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.getDetails()); - throw new Exception("ipassoc failed due to " + result.getDetails()); - } - - if (removeVif) { - String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK); - int nicMasks = Integer.parseInt(nicMasksStr); - nicMasks &= ~(1 << publicNicInfo.first().intValue()); - vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks)); - - HostMO hostMo = vmMo.getRunningHost(); - List networks = vmMo.getNetworksWithDetails(); - for (NetworkDetails netDetails : networks) { - if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { - if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { - cleanupNetwork(hostMo, netDetails); - } - } - } - } - - if (s_logger.isInfoEnabled()) { - s_logger.info("ipassoc command on domain router " + privateIpAddress + " completed"); - } - } - private void plugPublicNic(VirtualMachineMO vmMo, final String vlanId, final String vifMacAddress) throws Exception { // TODO : probably need to set traffic shaping Pair networkInfo = null; @@ -1786,11 +1064,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa throw new Exception("Could not allocate a free public NIC"); } - protected Answer execute(IpAssocCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource IPAssocCommand: " + _gson.toJson(cmd)); - } - + private ExecutionResult prepareNetworkElementCommand(IpAssocCommand cmd) { int i = 0; String[] results = new String[cmd.getIpAddresses().length]; @@ -1820,24 +1094,142 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } for (IpAddressTO ip : ips) { - assignPublicIpAddress(vmMo, routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), - ip.getVlanGateway(), ip.getVlanNetmask(), ip.getVifMacAddress()); - results[i++] = ip.getPublicIp() + " - success"; + /** + * TODO support other networks + */ + URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri()); + } + String vlanId = BroadcastDomainType.getValue(broadcastUri); + + String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); + Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first()); + } + + boolean addVif = false; + if (ip.isAdd() && publicNicInfo.first().intValue() == -1) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Plug new NIC to associate" + controlIp + " to " + ip.getPublicIp()); + } + addVif = true; + } + + if (addVif) { + plugPublicNic(vmMo, vlanId, ip.getVifMacAddress()); + publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); + if (publicNicInfo.first().intValue() >= 0) { + networkUsage(controlIp, "addVif", "eth" + publicNicInfo.first()); + } + } + + if (publicNicInfo.first().intValue() < 0) { + String msg = "Failed to find DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } + ip.setNicDevId(publicNicInfo.first().intValue()); + ip.setNewNic(addVif); } } catch (Throwable e) { s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e); - - for (; i < cmd.getIpAddresses().length; i++) { - results[i++] = IpAssocAnswer.errorResult; - } + return new ExecutionResult(false, e.toString()); } - - return new IpAssocAnswer(cmd, results); + return new ExecutionResult(true, null); } - protected ExecutionResult executeInVR(String routerIP, String script, String args) { + private ExecutionResult NetworkElementCommandnup(IpAssocCommand cmd) { + String[] results = new String[cmd.getIpAddresses().length]; + + VmwareContext context = getServiceContext(); + try { + VmwareHypervisorHost hyperHost = getHyperHost(context); + + IpAddressTO[] ips = cmd.getIpAddresses(); + String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String controlIp = VmwareResource.getRouterSshControlIp(cmd); + + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(routerName); + + // command may sometimes be redirect to a wrong host, we relax + // the check and will try to find it within cluster + if (vmMo == null) { + if (hyperHost instanceof HostMO) { + ClusterMO clusterMo = new ClusterMO(hyperHost.getContext(), ((HostMO)hyperHost).getParentMor()); + vmMo = clusterMo.findVmOnHyperHost(routerName); + } + } + + if (vmMo == null) { + String msg = "Router " + routerName + " no longer exists to execute IPAssoc command"; + s_logger.error(msg); + throw new Exception(msg); + } + + for (IpAddressTO ip : ips) { + /** + * TODO support other networks + */ + URI broadcastUri = BroadcastDomainType.fromString(ip.getBroadcastUri()); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + ip.getBroadcastUri()); + } + String vlanId = BroadcastDomainType.getValue(broadcastUri); + + String publicNeworkName = HypervisorHostHelper.getPublicNetworkNamePrefix(vlanId); + Pair publicNicInfo = vmMo.getNicDeviceIndex(publicNeworkName); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Find public NIC index, public network name: " + publicNeworkName + ", index: " + publicNicInfo.first()); + } + + boolean removeVif = false; + if (!ip.isAdd() && ip.isFirstIP()) { + removeVif = true; + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unplug NIC " + publicNicInfo.first()); + } + } + + if (publicNicInfo.first().intValue() < 0) { + String msg = "Failed to find DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } + + if (removeVif) { + String nicMasksStr = vmMo.getCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK); + int nicMasks = Integer.parseInt(nicMasksStr); + nicMasks &= ~(1 << publicNicInfo.first().intValue()); + vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMasks)); + + HostMO hostMo = vmMo.getRunningHost(); + List networks = vmMo.getNetworksWithDetails(); + for (NetworkDetails netDetails : networks) { + if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { + if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { + cleanupNetwork(hostMo, netDetails); + } + } + } + } + } + } catch (Throwable e) { + s_logger.error("Unexpected exception: " + e.toString() + " will shortcut rest of IPAssoc commands", e); + return new ExecutionResult(false, e.toString()); + } + return new ExecutionResult(true, null); + } + + @Override + public ExecutionResult executeInVR(String routerIP, String script, String args) { Pair result; + //TODO: Password should be masked, cannot output to log directly if (s_logger.isDebugEnabled()) { s_logger.debug("Run command on VR: " + routerIP + ", script: " + script + " with args: " + args); } @@ -1856,209 +1248,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new ExecutionResult(result.first(), result.second()); } - protected Answer execute(SavePasswordCommand cmd) { - if (s_logger.isInfoEnabled()) { - s_logger.info("Executing resource SavePasswordCommand. vmName: " + cmd.getVmName() + ", vmIp: " + cmd.getVmIpAddress() + ", password: " + - StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); - } - - String controlIp = getRouterSshControlIp(cmd); - final String password = cmd.getPassword(); - final String vmIpAddress = cmd.getVmIpAddress(); - - String args = " -v " + vmIpAddress; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run command on domain router " + controlIp + ", /opt/cloud/bin/savepassword.sh " + args + " -p " + - StringUtils.getMaskedPasswordForDisplay(cmd.getPassword())); - } - - args += " -p " + password; - - //TODO: Password should be masked, cannot output to log directly - ExecutionResult result = executeInVR(controlIp, "savepassword.sh", args); - if (!result.isSuccess()) { - s_logger.error("savepassword command on domain router " + controlIp + " failed, message: " + result.getDetails()); - return new Answer(cmd, false, result.getDetails()); - } - - return new Answer(cmd); - } - - protected Answer execute(DhcpEntryCommand cmd) { - // ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/root/edithosts.sh $mac $ip $vm $dfltrt $ns $staticrt" >/dev/null - - String args = " -m " + cmd.getVmMac(); - if (cmd.getVmIpAddress() != null) { - args += " -4 " + cmd.getVmIpAddress(); - } - args += " -h " + cmd.getVmName(); - - if (cmd.getDefaultRouter() != null) { - args += " -d " + cmd.getDefaultRouter(); - } - - if (cmd.getDefaultDns() != null) { - args += " -n " + cmd.getDefaultDns(); - } - - if (cmd.getStaticRoutes() != null) { - args += " -s " + cmd.getStaticRoutes(); - } - - if (cmd.getVmIp6Address() != null) { - args += " -6 " + cmd.getVmIp6Address(); - args += " -u " + cmd.getDuid(); - } - - if (!cmd.isDefault()) { - args += " -N"; - } - - String controlIp = getRouterSshControlIp(cmd); - ExecutionResult result = executeInVR(controlIp, "edithosts.sh", args); - - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } - - return new Answer(cmd); - } - - protected Answer execute(final CreateIpAliasCommand cmd) { - cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List ipAliasTOs = cmd.getIpAliasList(); - String args = ""; - for (IpAliasTO ipaliasto : ipAliasTOs) { - args = args + ipaliasto.getAlias_count() + ":" + ipaliasto.getRouterip() + ":" + ipaliasto.getNetmask() + "-"; - } - - String controlIp = getRouterSshControlIp(cmd); - ExecutionResult result = executeInVR(controlIp, "createIpAlias.sh", args); - - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } - - return new Answer(cmd); - } - - protected Answer execute(final DeleteIpAliasCommand cmd) { - cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - List revokedIpAliasTOs = cmd.getDeleteIpAliasTos(); - List activeIpAliasTOs = cmd.getCreateIpAliasTos(); - String args = ""; - for (IpAliasTO ipAliasTO : revokedIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - args = args + "- "; - for (IpAliasTO ipAliasTO : activeIpAliasTOs) { - args = args + ipAliasTO.getAlias_count() + ":" + ipAliasTO.getRouterip() + ":" + ipAliasTO.getNetmask() + "-"; - } - - String controlIp = getRouterSshControlIp(cmd); - ExecutionResult result = executeInVR(controlIp, "deleteIpAlias.sh", args); - - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } - - return new Answer(cmd); - } - - protected Answer execute(final DnsMasqConfigCommand cmd) { - String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); - String controlIp = getRouterSshControlIp(cmd); - - assert (controlIp != null); - - List dhcpTos = cmd.getIps(); - String args = ""; - for (DhcpTO dhcpTo : dhcpTos) { - args = args + dhcpTo.getRouterIp() + ":" + dhcpTo.getGateway() + ":" + dhcpTo.getNetmask() + ":" + dhcpTo.getStartIpOfSubnet() + "-"; - } - - ExecutionResult result = executeInVR(controlIp, "dnsmasq.sh", args); - - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } - - return new Answer(cmd); - } - - protected CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - String args = ""; - for (String ip : cmd.getVpnIps()) { - args += ip + " "; - } - - ExecutionResult result = executeInVR(controlIp, "checkbatchs2svpn.sh", args); - - if (!result.isSuccess()) { - return new CheckS2SVpnConnectionsAnswer(cmd, false, result.getDetails()); - } - - return new CheckS2SVpnConnectionsAnswer(cmd, true, result.getDetails()); - } - - protected Answer execute(CheckRouterCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - ExecutionResult result = executeInVR(controlIp, "checkrouter.sh", null); - - if (!result.isSuccess()) { - return new CheckRouterAnswer(cmd, result.getDetails()); - } - return new CheckRouterAnswer(cmd, result.getDetails(), true); - } - - protected Answer execute(GetDomRVersionCmd cmd) { - String controlIp = getRouterSshControlIp(cmd); - ExecutionResult result = executeInVR(controlIp, "get_template_version.sh", null); - - if (!result.isSuccess()) { - return new GetDomRVersionAnswer(cmd, result.getDetails()); - } - String[] lines = result.getDetails().split("&"); - if (lines.length != 2) { - return new GetDomRVersionAnswer(cmd, result.getDetails()); - } - return new GetDomRVersionAnswer(cmd, result.getDetails(), lines[0], lines[1]); - } - - protected Answer execute(BumpUpPriorityCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - ExecutionResult result = executeInVR(controlIp, "bumpup_priority.sh", null); - - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } - - return new Answer(cmd); - } - - protected Answer execute(VmDataCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - Map> data = new HashMap>(); - data.put(cmd.getVmIpAddress(), cmd.getVmData()); - - String json = new Gson().toJson(data); - s_logger.debug("VM data JSON IS:" + json); - - json = Base64.encodeBase64String(json.getBytes()); - - String args = "-d " + json; - - ExecutionResult result = executeInVR(controlIp, "vmdata.py", args); - - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } - - return new Answer(cmd); - } - protected CheckSshAnswer execute(CheckSshCommand cmd) { String vmName = cmd.getName(); String privateIp = cmd.getIp(); @@ -3281,57 +2470,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - protected Answer execute(final RemoteAccessVpnCfgCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - StringBuffer argsBuf = new StringBuffer(); - if (cmd.isCreate()) { - argsBuf.append(" -r ") - .append(cmd.getIpRange()) - .append(" -p ") - .append(cmd.getPresharedKey()) - .append(" -s ") - .append(cmd.getVpnServerIp()) - .append(" -l ") - .append(cmd.getLocalIp()) - .append(" -c "); - - } else { - argsBuf.append(" -d ").append(" -s ").append(cmd.getVpnServerIp()); - } - argsBuf.append(" -C ").append(cmd.getLocalCidr()); - argsBuf.append(" -i ").append(cmd.getPublicInterface()); - - - ExecutionResult result = executeInVR(controlIp, "vpn_l2tp.sh", argsBuf.toString()); - - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } - - return new Answer(cmd); - } - - protected Answer execute(final VpnUsersCfgCommand cmd) { - String controlIp = getRouterSshControlIp(cmd); - - for (VpnUsersCfgCommand.UsernamePassword userpwd : cmd.getUserpwds()) { - StringBuffer argsBuf = new StringBuffer(); - if (!userpwd.isAdd()) { - argsBuf.append(" -U ").append(userpwd.getUsername()); - } else { - argsBuf.append(" -u ").append(userpwd.getUsernamePassword()); - } - - ExecutionResult result = executeInVR(controlIp, "vpn_l2tp.sh", argsBuf.toString()); - - if (!result.isSuccess()) { - return new Answer(cmd, false, result.getDetails()); - } - } - - return new Answer(cmd); - } - private VirtualMachineMO takeVmFromOtherHyperHost(VmwareHypervisorHost hyperHost, String vmName) throws Exception { VirtualMachineMO vmMo = hyperHost.findVmOnPeerHyperHost(vmName); @@ -6439,6 +5577,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa new VmwareStorageProcessor((VmwareHostService)this, _fullCloneFlag, (VmwareStorageMount)mgr, timeout, this, _shutdownWaitMs, null); storageHandler = new VmwareStorageSubsystemCommandHandler(storageProcessor); + _vrResource = new VirtualRoutingResource(this); + if (!_vrResource.configure(name, params)) { + throw new ConfigurationException("Unable to configure VirtualRoutingResource"); + } return true; } finally { recycleServiceContext(); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index a817e2696a1..200a72ff219 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -550,6 +550,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe public ExecutionResult prepareCommand(NetworkElementCommand cmd) { //Update IP used to access router cmd.setRouterAccessIp(cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP)); + assert cmd.getRouterAccessIp() != null; if (cmd instanceof IpAssocVpcCommand) { return prepareNetworkElementCommand((IpAssocVpcCommand)cmd); From ebf57654e7507f72e31c8b9db9328209c3a668c4 Mon Sep 17 00:00:00 2001 From: Laszlo Hornyak Date: Sat, 25 Jan 2014 15:01:03 +0100 Subject: [PATCH 033/126] replaced Long instantiations with Autoboxing Signed-off-by: Laszlo Hornyak --- .../cloud/vm/VirtualMachineManagerImpl.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 8fd542b9669..b71252879fc 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -4317,7 +4317,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4368,7 +4368,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4421,7 +4421,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4470,7 +4470,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4525,7 +4525,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4578,7 +4578,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4630,7 +4630,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4679,7 +4679,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4728,7 +4728,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4777,7 +4777,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4828,7 +4828,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac _jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId()); } - return new Object[] {workJob, new Long(workJob.getId())}; + return new Object[] {workJob, workJob.getId()}; } }); @@ -4918,7 +4918,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac NicProfile nic = orchestrateAddVmToNetwork(vm, network, work.getRequestedNicProfile()); - return new Pair(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(new Long(nic.getId()))); + return new Pair(JobInfo.Status.SUCCEEDED, _jobMgr.marshallResultObject(nic.getId())); } private Pair orchestrateRemoveNicFromVm(VmWorkRemoveNicFromVm work) throws Exception { From 884e8c65107ca4f36f7328637f54797b7e9b775b Mon Sep 17 00:00:00 2001 From: Laszlo Hornyak Date: Sat, 25 Jan 2014 16:11:51 +0100 Subject: [PATCH 034/126] replaced Long instantiation with parseLong Signed-off-by: Laszlo Hornyak --- .../hypervisor/kvm/resource/LibvirtComputingResource.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 ab374462ace..70975fa9e9f 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 @@ -3098,8 +3098,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv String[] splitResult = result.split(":"); int i = 0; while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); + stats[0] += Long.parseLong(splitResult[i++]); + stats[1] += Long.parseLong(splitResult[i++]); } } return stats; @@ -3140,8 +3140,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv String[] splitResult = result.split(":"); int i = 0; while (i < splitResult.length - 1) { - stats[0] += (new Long(splitResult[i++])).longValue(); - stats[1] += (new Long(splitResult[i++])).longValue(); + stats[0] += Long.parseLong(splitResult[i++]); + stats[1] += Long.parseLong(splitResult[i++]); } } return stats; From e4da3775c99847deee22073a662b95777b2ac285 Mon Sep 17 00:00:00 2001 From: Laszlo Hornyak Date: Sat, 25 Jan 2014 19:47:48 +0100 Subject: [PATCH 035/126] removed redundant Long, Short, Double, Float and Boolean instantiations - Added unit tests - Added javadoc Signed-off-by: Laszlo Hornyak --- .../com/cloud/utils/db/GenericDaoBase.java | 38 ++++-- .../cloud/utils/db/GenericDaoBaseTest.java | 118 ++++++++++++++++++ 2 files changed, 143 insertions(+), 13 deletions(-) create mode 100644 framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java diff --git a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java index 503d7591135..f282428b8de 100755 --- a/framework/db/src/com/cloud/utils/db/GenericDaoBase.java +++ b/framework/db/src/com/cloud/utils/db/GenericDaoBase.java @@ -658,9 +658,21 @@ public abstract class GenericDaoBase extends Compone } } + /** + * Get a value from a result set. + * + * @param type + * the expected type of the result + * @param rs + * the result set + * @param index + * the index of the column + * @return the result in the requested type + * @throws SQLException + */ @DB() @SuppressWarnings("unchecked") - protected M getObject(Class type, ResultSet rs, int index) throws SQLException { + protected static M getObject(Class type, ResultSet rs, int index) throws SQLException { if (type == String.class) { byte[] bytes = rs.getBytes(index); if (bytes != null) { @@ -681,12 +693,12 @@ public abstract class GenericDaoBase extends Compone return (M)new Integer(rs.getInt(index)); } } else if (type == long.class) { - return (M)new Long(rs.getLong(index)); + return (M) (Long) rs.getLong(index); } else if (type == Long.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Long(rs.getLong(index)); + return (M) (Long) rs.getLong(index); } } else if (type == Date.class) { final Object data = rs.getDate(index); @@ -696,44 +708,44 @@ public abstract class GenericDaoBase extends Compone return (M)DateUtil.parseDateString(s_gmtTimeZone, rs.getString(index)); } } else if (type == short.class) { - return (M)new Short(rs.getShort(index)); + return (M) (Short) rs.getShort(index); } else if (type == Short.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Short(rs.getShort(index)); + return (M) (Short) rs.getShort(index); } } else if (type == boolean.class) { - return (M)new Boolean(rs.getBoolean(index)); + return (M) (Boolean) rs.getBoolean(index); } else if (type == Boolean.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Boolean(rs.getBoolean(index)); + return (M) (Boolean) rs.getBoolean(index); } } else if (type == float.class) { - return (M)new Float(rs.getFloat(index)); + return (M) (Float) rs.getFloat(index); } else if (type == Float.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Float(rs.getFloat(index)); + return (M) (Float) rs.getFloat(index); } } else if (type == double.class) { - return (M)new Double(rs.getDouble(index)); + return (M) (Double) rs.getDouble(index); } else if (type == Double.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Double(rs.getDouble(index)); + return (M) (Double) rs.getDouble(index); } } else if (type == byte.class) { - return (M)new Byte(rs.getByte(index)); + return (M) (Byte) rs.getByte(index); } else if (type == Byte.class) { if (rs.getObject(index) == null) { return null; } else { - return (M)new Byte(rs.getByte(index)); + return (M) (Byte) rs.getByte(index); } } else if (type == Calendar.class) { final Object data = rs.getDate(index); diff --git a/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java b/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java new file mode 100644 index 00000000000..7363d43d1a5 --- /dev/null +++ b/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java @@ -0,0 +1,118 @@ +package com.cloud.utils.db; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import junit.framework.Assert; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class GenericDaoBaseTest { + @Mock + ResultSet resultSet; + + @Test + public void getObjectBoolean() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(false); + Mockito.when(resultSet.getBoolean(1)).thenReturn(false); + Assert.assertFalse(GenericDaoBase + .getObject(Boolean.class, resultSet, 1)); + Mockito.verify(resultSet).getBoolean(1); + } + + @Test + public void getObjectPrimitiveBoolean() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(false); + Mockito.when(resultSet.getBoolean(1)).thenReturn(false); + Assert.assertFalse(GenericDaoBase + .getObject(boolean.class, resultSet, 1)); + Mockito.verify(resultSet).getBoolean(1); + } + + @Test + public void getObjectPrimitiveShort() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn((short) 1); + Mockito.when(resultSet.getShort(1)).thenReturn((short) 1); + Assert.assertEquals(Short.valueOf((short) 1), + GenericDaoBase.getObject(short.class, resultSet, 1)); + Mockito.verify(resultSet).getShort(1); + } + + @Test + public void getObjectShort() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn((short) 1); + Mockito.when(resultSet.getShort(1)).thenReturn((short) 1); + Assert.assertEquals(Short.valueOf((short) 1), + GenericDaoBase.getObject(Short.class, resultSet, 1)); + Mockito.verify(resultSet).getShort(1); + } + + @Test + public void getObjectFloat() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1f); + Mockito.when(resultSet.getFloat(1)).thenReturn(0.1f); + Assert.assertEquals(0.1f, + GenericDaoBase.getObject(Float.class, resultSet, 1)); + Mockito.verify(resultSet).getFloat(1); + } + + @Test + public void getObjectPrimitiveFloat() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1f); + Mockito.when(resultSet.getFloat(1)).thenReturn(0.1f); + Assert.assertEquals(0.1f, + GenericDaoBase.getObject(float.class, resultSet, 1)); + Mockito.verify(resultSet).getFloat(1); + } + + @Test + public void getObjectPrimitiveDouble() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1d); + Mockito.when(resultSet.getDouble(1)).thenReturn(0.1d); + Assert.assertEquals(0.1d, + GenericDaoBase.getObject(double.class, resultSet, 1)); + Mockito.verify(resultSet).getDouble(1); + } + + @Test + public void getObjectDouble() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(0.1d); + Mockito.when(resultSet.getDouble(1)).thenReturn(0.1d); + Assert.assertEquals(0.1d, + GenericDaoBase.getObject(Double.class, resultSet, 1)); + Mockito.verify(resultSet).getDouble(1); + } + + @Test + public void getObjectLong() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(1l); + Mockito.when(resultSet.getLong(1)).thenReturn(1l); + Assert.assertEquals((Long) 1l, + GenericDaoBase.getObject(Long.class, resultSet, 1)); + Mockito.verify(resultSet).getLong(1); + } + + @Test + public void getObjectPrimitiveLong() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn(1l); + Mockito.when(resultSet.getLong(1)).thenReturn(1l); + Assert.assertEquals((Long) 1l, + GenericDaoBase.getObject(long.class, resultSet, 1)); + Mockito.verify(resultSet).getLong(1); + } + + @Test + public void getObjectPrimitiveByte() throws SQLException { + Mockito.when(resultSet.getObject(1)).thenReturn((byte) 1); + Mockito.when(resultSet.getByte(1)).thenReturn((byte) 1); + Assert.assertTrue((byte) 1 == GenericDaoBase.getObject(byte.class, + resultSet, 1)); + Mockito.verify(resultSet).getByte(1); + } + +} From dea320f7b94ce737ced1bd6ed3ddeb5400e69948 Mon Sep 17 00:00:00 2001 From: Laszlo Hornyak Date: Sat, 25 Jan 2014 20:50:14 +0100 Subject: [PATCH 036/126] RAT fix added license header to test --- .../com/cloud/utils/db/GenericDaoBaseTest.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java b/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java index 7363d43d1a5..b7febcb8994 100644 --- a/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java +++ b/framework/db/test/com/cloud/utils/db/GenericDaoBaseTest.java @@ -1,3 +1,19 @@ +// 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.utils.db; import java.sql.ResultSet; From a0f21ff6bff452b0762d3accdd54ad8540a77a9d Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Mon, 27 Jan 2014 15:23:28 +0530 Subject: [PATCH 037/126] CLOUDSTACK-5949: Remove unused field vnc_password from user_vm_view Removed unused field. This will ensure that list VM queries are not blocked. --- .../com/cloud/api/query/vo/UserVmJoinVO.java | 9 - setup/db/db/schema-421to430.sql | 199 ++++++++++++++++++ 2 files changed, 199 insertions(+), 9 deletions(-) diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java index 472a8cba2af..2df49ec14d1 100644 --- a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java +++ b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java @@ -34,7 +34,6 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; -import com.cloud.utils.db.Encrypt; import com.cloud.utils.db.GenericDao; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @@ -121,10 +120,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name = "ha_enabled", updatable = true, nullable = true) private boolean haEnabled; - @Encrypt - @Column(name = "vnc_password", updatable = true, nullable = false, length = 255) - protected String vncPassword; - @Column(name = "limit_cpu_use", updatable = true, nullable = true) private boolean limitCpuUse; @@ -537,10 +532,6 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { return haEnabled; } - public String getVncPassword() { - return vncPassword; - } - public String getPrivateIpAddress() { return privateIpAddress; } diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index ccff7c1f5b2..fcf9b9fcc6e 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -900,3 +900,202 @@ ALTER TABLE `cloud`.`network_acl_item` modify `cidr` varchar(2048); INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "api.servlet.endpoint", "http://localhost:8080/client/api?", "API end point. Can be used by CS components/services deployed remotely, for sending CS API requests", "http://localhost:8080/client/api?", NULL,NULL,0); +DROP VIEW IF EXISTS `cloud`.`user_vm_view`; +CREATE VIEW `cloud`.`user_vm_view` AS + select + vm_instance.id id, + vm_instance.name name, + user_vm.display_name display_name, + user_vm.user_data user_data, + account.id account_id, + account.uuid account_uuid, + account.account_name account_name, + account.type account_type, + domain.id domain_id, + domain.uuid domain_uuid, + domain.name domain_name, + domain.path domain_path, + projects.id project_id, + projects.uuid project_uuid, + projects.name project_name, + instance_group.id instance_group_id, + instance_group.uuid instance_group_uuid, + instance_group.name instance_group_name, + vm_instance.uuid uuid, + vm_instance.last_host_id last_host_id, + vm_instance.vm_type type, + vm_instance.limit_cpu_use limit_cpu_use, + vm_instance.created created, + vm_instance.state state, + vm_instance.removed removed, + vm_instance.ha_enabled ha_enabled, + vm_instance.hypervisor_type hypervisor_type, + vm_instance.instance_name instance_name, + vm_instance.guest_os_id guest_os_id, + vm_instance.display_vm display_vm, + guest_os.uuid guest_os_uuid, + vm_instance.pod_id pod_id, + host_pod_ref.uuid pod_uuid, + vm_instance.private_ip_address private_ip_address, + vm_instance.private_mac_address private_mac_address, + vm_instance.vm_type vm_type, + data_center.id data_center_id, + data_center.uuid data_center_uuid, + data_center.name data_center_name, + data_center.is_security_group_enabled security_group_enabled, + data_center.networktype data_center_type, + host.id host_id, + host.uuid host_uuid, + host.name host_name, + vm_template.id template_id, + vm_template.uuid template_uuid, + vm_template.name template_name, + vm_template.display_text template_display_text, + vm_template.enable_password password_enabled, + iso.id iso_id, + iso.uuid iso_uuid, + iso.name iso_name, + iso.display_text iso_display_text, + service_offering.id service_offering_id, + disk_offering.uuid service_offering_uuid, + Case + When (`cloud`.`service_offering`.`cpu` is null) then (`custom_cpu`.`value`) + Else ( `cloud`.`service_offering`.`cpu`) + End as `cpu`, + Case + When (`cloud`.`service_offering`.`speed` is null) then (`custom_speed`.`value`) + Else ( `cloud`.`service_offering`.`speed`) + End as `speed`, + Case + When (`cloud`.`service_offering`.`ram_size` is null) then (`custom_ram_size`.`value`) + Else ( `cloud`.`service_offering`.`ram_size`) + END as `ram_size`, + disk_offering.name service_offering_name, + storage_pool.id pool_id, + storage_pool.uuid pool_uuid, + storage_pool.pool_type pool_type, + volumes.id volume_id, + volumes.uuid volume_uuid, + volumes.device_id volume_device_id, + volumes.volume_type volume_type, + security_group.id security_group_id, + security_group.uuid security_group_uuid, + security_group.name security_group_name, + security_group.description security_group_description, + nics.id nic_id, + nics.uuid nic_uuid, + nics.network_id network_id, + nics.ip4_address ip_address, + nics.ip6_address ip6_address, + nics.ip6_gateway ip6_gateway, + nics.ip6_cidr ip6_cidr, + nics.default_nic is_default_nic, + nics.gateway gateway, + nics.netmask netmask, + nics.mac_address mac_address, + nics.broadcast_uri broadcast_uri, + nics.isolation_uri isolation_uri, + vpc.id vpc_id, + vpc.uuid vpc_uuid, + networks.uuid network_uuid, + networks.name network_name, + networks.traffic_type traffic_type, + networks.guest_type guest_type, + user_ip_address.id public_ip_id, + user_ip_address.uuid public_ip_uuid, + user_ip_address.public_ip_address public_ip_address, + ssh_keypairs.keypair_name keypair_name, + resource_tags.id tag_id, + resource_tags.uuid tag_uuid, + resource_tags.key tag_key, + resource_tags.value tag_value, + resource_tags.domain_id tag_domain_id, + resource_tags.account_id tag_account_id, + resource_tags.resource_id tag_resource_id, + resource_tags.resource_uuid tag_resource_uuid, + resource_tags.resource_type tag_resource_type, + resource_tags.customer tag_customer, + async_job.id job_id, + async_job.uuid job_uuid, + async_job.job_status job_status, + async_job.account_id job_account_id, + affinity_group.id affinity_group_id, + affinity_group.uuid affinity_group_uuid, + affinity_group.name affinity_group_name, + affinity_group.description affinity_group_description, + vm_instance.dynamically_scalable dynamically_scalable, + all_details.name detail_name, + all_details.value detail_value + from + `cloud`.`user_vm` + inner join + `cloud`.`vm_instance` ON vm_instance.id = user_vm.id + and vm_instance.removed is NULL + inner join + `cloud`.`account` ON vm_instance.account_id = account.id + inner join + `cloud`.`domain` ON vm_instance.domain_id = domain.id + left join + `cloud`.`guest_os` ON vm_instance.guest_os_id = guest_os.id + left join + `cloud`.`host_pod_ref` ON vm_instance.pod_id = host_pod_ref.id + left join + `cloud`.`projects` ON projects.project_account_id = account.id + left join + `cloud`.`instance_group_vm_map` ON vm_instance.id = instance_group_vm_map.instance_id + left join + `cloud`.`instance_group` ON instance_group_vm_map.group_id = instance_group.id + left join + `cloud`.`data_center` ON vm_instance.data_center_id = data_center.id + left join + `cloud`.`host` ON vm_instance.host_id = host.id + left join + `cloud`.`vm_template` ON vm_instance.vm_template_id = vm_template.id + left join + `cloud`.`vm_template` iso ON iso.id = user_vm.iso_id + left join + `cloud`.`service_offering` ON vm_instance.service_offering_id = service_offering.id + left join + `cloud`.`disk_offering` ON vm_instance.service_offering_id = disk_offering.id + left join + `cloud`.`volumes` ON vm_instance.id = volumes.instance_id + left join + `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id + left join + `cloud`.`security_group_vm_map` ON vm_instance.id = security_group_vm_map.instance_id + left join + `cloud`.`security_group` ON security_group_vm_map.security_group_id = security_group.id + left join + `cloud`.`nics` ON vm_instance.id = nics.instance_id and nics.removed is null + left join + `cloud`.`networks` ON nics.network_id = networks.id + left join + `cloud`.`vpc` ON networks.vpc_id = vpc.id and vpc.removed is null + left join + `cloud`.`user_ip_address` ON user_ip_address.vm_id = vm_instance.id + left join + `cloud`.`user_vm_details` as ssh_details ON ssh_details.vm_id = vm_instance.id + and ssh_details.name = 'SSH.PublicKey' + left join + `cloud`.`ssh_keypairs` ON ssh_keypairs.public_key = ssh_details.value + left join + `cloud`.`resource_tags` ON resource_tags.resource_id = vm_instance.id + and resource_tags.resource_type = 'UserVm' + left join + `cloud`.`async_job` ON async_job.instance_id = vm_instance.id + and async_job.instance_type = 'VirtualMachine' + and async_job.job_status = 0 + left join + `cloud`.`affinity_group_vm_map` ON vm_instance.id = affinity_group_vm_map.instance_id + left join + `cloud`.`affinity_group` ON affinity_group_vm_map.affinity_group_id = affinity_group.id + left join + `cloud`.`user_vm_details` as all_details ON all_details.vm_id = vm_instance.id + left join + `cloud`.`user_vm_details` `custom_cpu` ON (((`custom_cpu`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_cpu`.`name` = 'CpuNumber'))) + left join + `cloud`.`user_vm_details` `custom_speed` ON (((`custom_speed`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_speed`.`name` = 'CpuSpeed'))) + left join + `cloud`.`user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_ram_size`.`name` = 'memory'))); + + From 49a29ce0cfe0fca535037d0d7e15e399e76ea49f Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Mon, 27 Jan 2014 10:03:39 +0100 Subject: [PATCH 038/126] Switch to Java 7 We now require at least Java 7 to build and run CloudStack. Both the DEB and RPM packaging now also require Java 7 during installation of the packages. --- debian/control | 6 +++--- packaging/centos63/cloud.spec | 8 ++++---- pom.xml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/debian/control b/debian/control index c756dcd0d8e..ab4644badd2 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: cloudstack Section: libs Priority: extra Maintainer: Wido den Hollander -Build-Depends: debhelper (>= 7), openjdk-6-jdk | openjdk-7-jdk, tomcat6, genisoimage, +Build-Depends: debhelper (>= 7), openjdk-7-jdk, tomcat6, genisoimage, python-mysqldb, maven3 | maven (>= 3), python (>= 2.6.6-3~) Standards-Version: 3.8.1 Homepage: http://www.cloudstack.org/ @@ -22,7 +22,7 @@ Description: CloudStack server library Package: cloudstack-agent Architecture: all -Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset, python-libvirt, ethtool, iptables +Depends: openjdk-7-jre, cloudstack-common (= ${source:Version}), lsb-base (>= 3.2), libcommons-daemon-java, openssh-client, libvirt0, sysvinit-utils, qemu-kvm, libvirt-bin, uuid-runtime, rsync, grep, iproute, perl-base, perl-modules, ebtables, vlan, wget, jsvc, ipset, python-libvirt, ethtool, iptables Conflicts: cloud-agent, cloud-agent-libs, cloud-agent-deps, cloud-agent-scripts Description: CloudStack agent The CloudStack agent is in charge of managing shared computing resources in @@ -31,7 +31,7 @@ Description: CloudStack agent Package: cloudstack-usage Architecture: all -Depends: openjdk-6-jre | openjdk-7-jre, cloudstack-common (= ${source:Version}), jsvc +Depends: openjdk-7-jre, cloudstack-common (= ${source:Version}), jsvc Description: CloudStack usage monitor The CloudStack usage monitor provides usage accounting across the entire cloud for cloud operators to charge based on usage parameters. diff --git a/packaging/centos63/cloud.spec b/packaging/centos63/cloud.spec index 8029b61cc31..83c598b07a7 100644 --- a/packaging/centos63/cloud.spec +++ b/packaging/centos63/cloud.spec @@ -43,7 +43,7 @@ Group: System Environment/Libraries Source0: %{name}-%{_maventag}.tgz BuildRoot: %{_tmppath}/%{name}-%{_maventag}-%{release}-build -BuildRequires: java-1.6.0-openjdk-devel +BuildRequires: java-1.7.0-openjdk-devel BuildRequires: tomcat6 BuildRequires: ws-commons-util BuildRequires: jpackage-utils @@ -60,7 +60,7 @@ intelligent IaaS cloud implementation. %package management Summary: CloudStack management server UI Requires: tomcat6 -Requires: java >= 1.6.0 +Requires: java >= 1.7.0 Requires: python Requires: bash Requires: bzip2 @@ -112,7 +112,7 @@ The Apache CloudStack files shared between agent and management server %package agent Summary: CloudStack Agent for KVM hypervisors Requires: openssh-clients -Requires: java >= 1.6.0 +Requires: java >= 1.7.0 Requires: %{name}-common = %{_ver} Requires: libvirt Requires: bridge-utils @@ -138,7 +138,7 @@ The CloudStack agent for KVM hypervisors %package usage Summary: CloudStack Usage calculation server -Requires: java >= 1.6.0 +Requires: java >= 1.7.0 Requires: jsvc Requires: jakarta-commons-daemon Requires: jakarta-commons-daemon-jsvc diff --git a/pom.xml b/pom.xml index 76ac0464f2f..01ddf111906 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ - 1.6 + 1.7 UTF-8 1.2.16 From b25ee92c348118d084fbc4d6103f3fb81fab0e68 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Mon, 27 Jan 2014 14:18:53 +0530 Subject: [PATCH 039/126] CS-5950: Wrong storage tags are used for ISO deployed VMs. --- .../com/cloud/deploy/DeploymentPlanningManagerImpl.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index 8cad796d966..ec20067db25 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.deploy; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -91,6 +92,7 @@ import com.cloud.org.Grouping; import com.cloud.resource.ResourceState; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.ScopeType; +import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; @@ -1202,8 +1204,12 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy s_logger.debug("Calling StoragePoolAllocators to find suitable pools"); DiskOfferingVO diskOffering = _diskOfferingDao.findById(toBeCreated.getDiskOfferingId()); - DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); + if (vmProfile.getTemplate().getFormat() == Storage.ImageFormat.ISO && vmProfile.getServiceOffering().getTagsArray().length != 0) { + diskOffering.setTagsArray(Arrays.asList(vmProfile.getServiceOffering().getTagsArray())); + } + + DiskProfile diskProfile = new DiskProfile(toBeCreated, diskOffering, vmProfile.getHypervisorType()); boolean useLocalStorage = false; if (vmProfile.getType() != VirtualMachine.Type.User) { String ssvmUseLocalStorage = _configDao.getValue(Config.SystemVMUseLocalStorage.key()); From a735de8f85cc969d4b03b56eb7584955db9096f0 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Mon, 27 Jan 2014 22:50:40 +0530 Subject: [PATCH 040/126] CLOUDSTACK-5953: In hypervisor_capabilities, max_guests_limit are not correct for XS 6.2 or other specific version hypervisor. --- setup/db/db/schema-430to440.sql | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index 0ce92023811..3fa34029fb7 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -24,6 +24,9 @@ SET foreign_key_checks = 0; ALTER TABLE `cloud`.`disk_offering` ADD `cache_mode` VARCHAR( 16 ) DEFAULT 'none' COMMENT 'The disk cache mode to use for disks created with this offering'; +UPDATE `cloud`.`hypervisor_capabilities` set max_guests_limit='150' WHERE hypervisor_version='6.1.0'; +UPDATE `cloud`.`hypervisor_capabilities` set max_guests_limit='500' WHERE hypervisor_version='6.2.0'; + DROP VIEW IF EXISTS `cloud`.`disk_offering_view`; CREATE VIEW `cloud`.`disk_offering_view` AS select @@ -443,4 +446,4 @@ CREATE VIEW `cloud`.`user_vm_view` AS left join `cloud`.`user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_ram_size`.`name` = 'memory'))); -INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('NetworkManager', 'DEFAULT', 'management-server', 'vm.network.nic.max.secondary.ipaddresses', NULL, 'Specify the number of secondary ip addresses per nic per vm', '256') ON DUPLICATE KEY UPDATE category='NetworkManager'; \ No newline at end of file +INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('NetworkManager', 'DEFAULT', 'management-server', 'vm.network.nic.max.secondary.ipaddresses', NULL, 'Specify the number of secondary ip addresses per nic per vm', '256') ON DUPLICATE KEY UPDATE category='NetworkManager'; From daeea46da0fb7ba49d8c18334d9427fb9b06d524 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Mon, 27 Jan 2014 11:04:05 -0700 Subject: [PATCH 041/126] CLOUDSTACK-5956 remove persist flag during live migration --- .../hypervisor/kvm/resource/LibvirtComputingResource.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 70975fa9e9f..1ea0989ee71 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 @@ -2927,10 +2927,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv dconn = new Connect("qemu+tcp://" + cmd.getDestinationIp() + "/system"); /* - * Hard code lm flags: VIR_MIGRATE_LIVE(1<<0) and - * VIR_MIGRATE_PERSIST_DEST(1<<3) + * Hard code lm flag: VIR_MIGRATE_LIVE(1<<0) */ - destDomain = dm.migrate(dconn, (1 << 0) | (1 << 3), xmlDesc, vmName, "tcp:" + cmd.getDestinationIp(), _migrateSpeed); + destDomain = dm.migrate(dconn, (1 << 0), xmlDesc, vmName, "tcp:" + cmd.getDestinationIp(), _migrateSpeed); _storagePoolMgr.disconnectPhysicalDisksViaVmSpec(cmd.getVirtualMachine()); } catch (LibvirtException e) { From 0502d2f375ad1325de0d59023bdf7beb6ef7eaaa Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Mon, 27 Jan 2014 12:10:42 -0700 Subject: [PATCH 042/126] CLOUDSTACK-5697 This patchset fixes a bug with the recently merged vxlan code. Users can set a physical network to isolation type 'vxlan', put public traffic on that physical network, and it will still attempt to use 'vlan' isolation on the KVM hosts. This is going to be an issue for other isolation types as well, but I'm not familiar with them, so I'm just fixing vxlan for now. --- api/src/com/cloud/network/NetworkService.java | 2 +- api/src/com/cloud/network/Networks.java | 17 ++++++++++++++++- .../org/apache/cloudstack/api/ApiConstants.java | 1 + .../command/admin/usage/AddTrafficTypeCmd.java | 14 +++++++++++++- .../management/ManagementServerMock.java | 6 +++--- .../configuration/ConfigurationManagerImpl.java | 2 +- .../com/cloud/network/NetworkServiceImpl.java | 16 +++++++++++++++- .../cloud/network/guru/PublicNetworkGuru.java | 14 ++++++++++---- .../VirtualNetworkApplianceManagerImpl.java | 14 +++++++++++--- .../com/cloud/vpc/MockNetworkManagerImpl.java | 4 ++-- 10 files changed, 73 insertions(+), 17 deletions(-) diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 250121e452b..1731b119d5e 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -110,7 +110,7 @@ public interface NetworkService { long findPhysicalNetworkId(long zoneId, String tag, TrafficType trafficType); - PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String xenLabel, String kvmLabel, String vmwareLabel, + PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan, String hypervLabel); PhysicalNetworkTrafficType getPhysicalNetworkTrafficType(Long id); diff --git a/api/src/com/cloud/network/Networks.java b/api/src/com/cloud/network/Networks.java index b2c04cda00c..1e4d2294641 100755 --- a/api/src/com/cloud/network/Networks.java +++ b/api/src/com/cloud/network/Networks.java @@ -94,7 +94,22 @@ public class Networks { return uri.getSchemeSpecificPart(); } }, - Mido("mido", String.class), Pvlan("pvlan", String.class), Vxlan("vxlan", Long.class), UnDecided(null, null), OpenDaylight("opendaylight", String.class); + Mido("mido", String.class), Pvlan("pvlan", String.class), + Vxlan("vxlan", Long.class) { + @Override + public URI toUri(T value) { + try { + if (value.toString().contains("://")) + return new URI(value.toString()); + else + return new URI("vxlan://" + value.toString()); + } catch (URISyntaxException e) { + throw new CloudRuntimeException( + "Unable to convert to broadcast URI: " + value); + } + } + }, + UnDecided(null, null), OpenDaylight("opendaylight", String.class); private final String scheme; private final Class type; diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 287fff3035b..d500303bcac 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -344,6 +344,7 @@ public class ApiConstants { public static final String CAPACITY_IOPS = "capacityiops"; public static final String NETWORK_SPEED = "networkspeed"; public static final String BROADCAST_DOMAIN_RANGE = "broadcastdomainrange"; + public static final String ISOLATION_METHOD = "isolationmethod"; public static final String ISOLATION_METHODS = "isolationmethods"; public static final String PHYSICAL_NETWORK_ID = "physicalnetworkid"; public static final String DEST_PHYSICAL_NETWORK_ID = "destinationphysicalnetworkid"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java b/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java index e6e18cb9ffa..0fcb8f87e54 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/usage/AddTrafficTypeCmd.java @@ -77,6 +77,10 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd { @Parameter(name = ApiConstants.VLAN, type = CommandType.STRING, description = "The VLAN id to be used for Management traffic by VMware host") private String vlan; + @Parameter(name=ApiConstants.ISOLATION_METHOD, type=CommandType.STRING, description="Used if physical network has multiple isolation types and traffic type is public." + + " Choose which isolation method. Valid options currently 'vlan' or 'vxlan', defaults to 'vlan'.") + private String isolationMethod; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -118,6 +122,14 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd { return vlan; } + public String getIsolationMethod() { + if (isolationMethod != null && !isolationMethod.isEmpty()) { + return isolationMethod; + } else { + return "vlan"; + } + } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -148,7 +160,7 @@ public class AddTrafficTypeCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException { PhysicalNetworkTrafficType result = - _networkService.addTrafficTypeToPhysicalNetwork(getPhysicalNetworkId(), getTrafficType(), getXenLabel(), getKvmLabel(), getVmwareLabel(), + _networkService.addTrafficTypeToPhysicalNetwork(getPhysicalNetworkId(), getTrafficType(), getIsolationMethod(), getXenLabel(), getKvmLabel(), getVmwareLabel(), getSimulatorLabel(), getVlan(), getHypervLabel()); if (result != null) { setEntityId(result.getId()); diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java index e16eedbe6b6..50419ea1b36 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java @@ -327,7 +327,7 @@ public class ManagementServerMock { _znet = _networkService.getPhysicalNetwork(id); List nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public); if (nets == null || nets.isEmpty()) { - _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), null, null, null, null, null, null); + _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null); } } catch (InvalidParameterValueException e) { List isolationMethods = new ArrayList(); @@ -337,7 +337,7 @@ public class ManagementServerMock { "znet"); List nets = _physicalNetworkDao.listByZoneAndTrafficType(_zone.getId(), TrafficType.Public); if (nets == null || nets.isEmpty()) { - _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), null, null, null, null, null, null); + _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Public.toString(), "vlan", null, null, null, null, null, null); } } if (_znet.getState() != PhysicalNetwork.State.Enabled) { @@ -353,7 +353,7 @@ public class ManagementServerMock { } } if (!found) { - _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), null, null, null, null, null, null); + _networkService.addTrafficTypeToPhysicalNetwork(_znet.getId(), TrafficType.Guest.toString(), "vlan", null, null, null, null, null, null); } Pair, Integer> providers = diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 9d148faa6db..f0c7f354dec 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -1689,7 +1689,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(zoneId, TrafficType.Storage); } catch (InvalidParameterValueException noStorage) { PhysicalNetworkTrafficTypeVO mgmtTraffic = _trafficTypeDao.findBy(mgmtPhyNetwork.getId(), TrafficType.Management); - _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), mgmtTraffic.getXenNetworkLabel(), + _networkSvc.addTrafficTypeToPhysicalNetwork(mgmtPhyNetwork.getId(), TrafficType.Storage.toString(), "vlan", mgmtTraffic.getXenNetworkLabel(), mgmtTraffic.getKvmNetworkLabel(), mgmtTraffic.getVmwareNetworkLabel(), mgmtTraffic.getSimulatorNetworkLabel(), mgmtTraffic.getVlan(), mgmtTraffic.getHypervNetworkLabel()); s_logger.info("No storage traffic type was specified by admin, create default storage traffic on physical network " + mgmtPhyNetwork.getId() diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 399f08681d1..d02f1760e1d 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -3534,7 +3534,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { @Override @DB @ActionEvent(eventType = EventTypes.EVENT_TRAFFIC_TYPE_CREATE, eventDescription = "Creating Physical Network TrafficType", create = true) - public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String xenLabel, String kvmLabel, String vmwareLabel, + public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficTypeStr, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan, String hypervLabel) { // verify input parameters @@ -3590,6 +3590,20 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { vlan, hypervLabel); pNetworktrafficType = _pNTrafficTypeDao.persist(pNetworktrafficType); + // For public traffic, get isolation method of physical network and update the public network accordingly + // each broadcast type will individually need to be qualified for support of public traffic + List isolationMethods = network.getIsolationMethods(); + if ((isolationMethods.size() == 1 && isolationMethods.get(0).toLowerCase().equals("vxlan")) + || (isolationMethod != null && isolationMethods.contains(isolationMethod) && isolationMethod.toLowerCase().equals("vxlan"))) { + // find row in networks table that is defined as 'Public', created when zone was deployed + NetworkVO publicNetwork = _networksDao.listByZoneAndTrafficType(network.getDataCenterId(),TrafficType.Public).get(0); + if (publicNetwork != null) { + s_logger.debug("setting public network " + publicNetwork + " to broadcast type vxlan"); + publicNetwork.setBroadcastDomainType(BroadcastDomainType.Vxlan); + _networksDao.persist(publicNetwork); + } + } + return pNetworktrafficType; } catch (Exception ex) { s_logger.warn("Exception: ", ex); diff --git a/server/src/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/com/cloud/network/guru/PublicNetworkGuru.java index 34e97d34423..95d7790f2cb 100755 --- a/server/src/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PublicNetworkGuru.java @@ -103,7 +103,7 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { if (offering.getTrafficType() == TrafficType.Public) { NetworkVO ntwk = - new NetworkVO(offering.getTrafficType(), Mode.Static, BroadcastDomainType.Vlan, offering.getId(), State.Setup, plan.getDataCenterId(), + new NetworkVO(offering.getTrafficType(), Mode.Static, network.getBroadcastDomainType(), offering.getId(), State.Setup, plan.getDataCenterId(), plan.getPhysicalNetworkId()); return ntwk; } else { @@ -122,9 +122,15 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { nic.setIp4Address(ip.getAddress().toString()); nic.setGateway(ip.getGateway()); nic.setNetmask(ip.getNetmask()); - nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); - nic.setBroadcastType(BroadcastDomainType.Vlan); + if (network.getBroadcastDomainType() == BroadcastDomainType.Vxlan) { + nic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag())); + nic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vxlan); + } else { + nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); + nic.setBroadcastType(BroadcastDomainType.Vlan); + } nic.setFormat(AddressFormat.Ip4); nic.setReservationId(String.valueOf(ip.getVlanTag())); nic.setMacAddress(ip.getMacAddress()); diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index d7c7310411f..13291d057a5 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1834,9 +1834,17 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V defaultNic.setGateway(sourceNatIp.getGateway()); defaultNic.setNetmask(sourceNatIp.getNetmask()); defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + // get broadcast from public network + Network pubNet = _networkDao.findById(sourceNatIp.getNetworkId()); + if (pubNet.getBroadcastDomainType() == BroadcastDomainType.Vxlan) { + defaultNic.setBroadcastType(BroadcastDomainType.Vxlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); + } else { + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + } if (hasGuestNetwork) { defaultNic.setDeviceId(2); } diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 846e2f58d8e..226788370e6 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -404,10 +404,10 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches } /* (non-Javadoc) - * @see com.cloud.network.NetworkService#addTrafficTypeToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) + * @see com.cloud.network.NetworkService#addTrafficTypeToPhysicalNetwork(java.lang.Long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) */ @Override - public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String xenLabel, String kvmLabel, String vmwareLabel, + public PhysicalNetworkTrafficType addTrafficTypeToPhysicalNetwork(Long physicalNetworkId, String trafficType, String isolationMethod, String xenLabel, String kvmLabel, String vmwareLabel, String simulatorLabel, String vlan, String hypervLabel) { // TODO Auto-generated method stub return null; From b7d64958924c7d9445b195b595f7bc00555de2d5 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Mon, 27 Jan 2014 12:33:46 -0800 Subject: [PATCH 043/126] Plugin API: Support multiple JS includes per plugin For any plugin/module, allow including additional JS dependencies via new plugin syntax. To include JS files, instead of passing a function directly, pass an array with the first element being a sub-list of the includes: cloudStack.plugin.myPlugin = [ ['file1', 'file2', 'fileN' ...], // These will be loaded before // plugin is executed function(plugin) { // The plugin entry point ... } ]; -- Where each item represents a JS file relative to the plugin folder and without the .js extension. Sub-folders are also supported, i.e., 'subfolder/file1' --- ui/scripts/plugins.js | 49 ++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/ui/scripts/plugins.js b/ui/scripts/plugins.js index afeae7c7eaf..82d92429a7d 100644 --- a/ui/scripts/plugins.js +++ b/ui/scripts/plugins.js @@ -98,15 +98,37 @@ } // Execute module - cloudStack[type][id]( - $.extend(true, {}, cloudStack.pluginAPI, { - pluginAPI: { - extend: function(api) { - cloudStack.pluginAPI[id] = api; + var target = cloudStack[type][id]; + + if ($.isArray(target)) { // Load additional JS includes + pluginTotal += target[0].length; + require( + $(target[0]).map(function(index, val) { + return basePath + val; + }).toArray(), + function() { + loadedPlugins = loadedPlugins + target[0].length; + target[1]( + $.extend(true, {}, cloudStack.pluginAPI, { + pluginAPI: { + extend: function(api) { + cloudStack.pluginAPI[id] = api; + } + } + }) + ); + }); + } else { + target( + $.extend(true, {}, cloudStack.pluginAPI, { + pluginAPI: { + extend: function(api) { + cloudStack.pluginAPI[id] = api; + } } - } - }) - ); + }) + ); + } if (pluginDictionary) { // Callback for extending the dictionary with new entries @@ -133,13 +155,16 @@ loadedPlugins = loadedPlugins + 1; - if (loadedPlugins === pluginTotal) { - $(window).trigger('cloudStack.pluginReady'); - } - loadCSS(css); }); } ); }); + + var loadTimer = setInterval(function() { + if (loadedPlugins === pluginTotal) { + clearInterval(loadTimer); + $(window).trigger('cloudStack.pluginReady'); + } + }, 100); }(jQuery, cloudStack, require)); From cfe7864618ad9a64e4ef294bc3b292f458815cbd Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 27 Jan 2014 11:54:38 -0800 Subject: [PATCH 044/126] CLOUDSTACK-5960: Domain admin or user cannot register a template using S3/Swift object store. --- server/src/com/cloud/template/TemplateAdapterBase.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 59aab3b64b7..0ac434c8ea3 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -176,8 +176,14 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat } boolean isAdmin = _accountDao.findById(templateOwner.getId()).getType() == Account.ACCOUNT_TYPE_ADMIN; - - if (!isAdmin && zoneId == null) { + boolean isRegionStore = false; + List stores = _imgStoreDao.findRegionImageStores(); + if (stores != null && stores.size() > 0) { + isRegionStore = true; + } + + if (!isAdmin && zoneId == null && !isRegionStore ) { + // domain admin and user should also be able to register template on a region store throw new InvalidParameterValueException("Please specify a valid zone Id."); } From f77974b5d2e8c2164327da9f7cc744a38f8959a9 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 27 Jan 2014 13:31:13 -0800 Subject: [PATCH 045/126] Fix trailing whitespace from cherry-pick --- server/src/com/cloud/template/TemplateAdapterBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 0ac434c8ea3..e3999122b53 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -181,7 +181,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat if (stores != null && stores.size() > 0) { isRegionStore = true; } - + if (!isAdmin && zoneId == null && !isRegionStore ) { // domain admin and user should also be able to register template on a region store throw new InvalidParameterValueException("Please specify a valid zone Id."); From 9f18b075a9de166dfee222ae1ef68f0e81af8247 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Mon, 27 Jan 2014 13:30:37 -0800 Subject: [PATCH 046/126] List view: Fix advanced search not popping up with multiple panels --- ui/scripts/ui/widgets/listView.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index d94744d5222..cb4544c7af0 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -877,7 +877,7 @@ $('
').attr({ id: 'advanced_search' }) - .addClass('button search') + .addClass('button search advanced-search') .append($('
').addClass('icon')) ); } @@ -1872,11 +1872,11 @@ }; var closeAdvancedSearch = function() { - $('#advanced_search .form-container:visible').remove(); + $listView.find('.advanced-search .form-container:visible').remove(); }; - $listView.find('.button.search#advanced_search .icon').bind('click', function(event) { - if ($('#advanced_search .form-container:visible').size()) { + $listView.find('.advanced-search .icon').bind('click', function(event) { + if ($listView.find('.advanced-search .form-container:visible').size()) { closeAdvancedSearch(); return false; @@ -1897,7 +1897,7 @@ var $formContainer = form.$formContainer; var $form = $formContainer.find('form'); - $formContainer.hide().appendTo('#advanced_search').show(); + $formContainer.hide().appendTo($listView.find('.advanced-search')).show(); $form.find('.form-item:first input').focus(); $form.find('input[type=submit]') .show() From c4b3e4c0cc8cf87de0e166fa7ae424ae9be76c63 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Mon, 27 Jan 2014 13:38:02 -0800 Subject: [PATCH 047/126] Enable static NAT dialog: Fix search filter not working --- ui/scripts/network.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 4e1ce05ff91..291def0c9dc 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -2382,6 +2382,7 @@ listView: $.extend(true, {}, cloudStack.sections.instances, { listView: { + advSearchFields: null, // Not supported in dialogs right now due to display issues filters: false, subselect: { label: 'label.use.vm.ip', @@ -2394,6 +2395,10 @@ listAll: true }; + if (args.filterBy.search.value) { + data.name = args.filterBy.search.value; + } + var $tierSelect = $(".ui-dialog-content").find('.tier-select select'); // if $tierSelect is not initialized, return; tierSelect() will refresh listView and come back here later From ce0dc3b306c4bd9917255769f9b8014ff23c21b7 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Mon, 27 Jan 2014 13:41:11 -0800 Subject: [PATCH 048/126] Enable static NAT dialog search: Use 'keyword' instead of 'name' --- ui/scripts/network.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 291def0c9dc..e4cd8b00db7 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -2396,7 +2396,7 @@ }; if (args.filterBy.search.value) { - data.name = args.filterBy.search.value; + data.keyword = args.filterBy.search.value; } var $tierSelect = $(".ui-dialog-content").find('.tier-select select'); From 807dc091382fbf6fbd4b8fc53e7cdb414078ea2e Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Tue, 28 Jan 2014 06:40:47 +0530 Subject: [PATCH 049/126] CLOUDSTACK-5561 Support of multiple public vlans on VR running in HyperV --- .../cloud/agent/api/GetVmConfigAnswer.java | 68 +++++ .../cloud/agent/api/GetVmConfigCommand.java | 46 ++++ .../agent/api/ModifyVmNicConfigAnswer.java | 36 +++ .../agent/api/ModifyVmNicConfigCommand.java | 42 +++ .../ServerResource/AgentShell/App.config | 2 +- .../HypervResource/CloudStackTypes.cs | 18 ++ .../HypervResourceController.cs | 100 +++++++ .../HypervResource/IWmiCallsV2.cs | 1 + .../HypervResource/WmiCallsV2.cs | 62 +++++ .../hypervisor/hyperv/guru/HypervGuru.java | 113 ++++++++ .../hyperv/manager/HypervManager.java | 1 + .../hyperv/manager/HypervManagerImpl.java | 20 +- .../resource/HypervDirectConnectResource.java | 258 +++++++++++++----- .../VirtualNetworkApplianceManagerImpl.java | 2 +- .../debian/config/opt/cloud/bin/ipassoc.sh | 3 +- 15 files changed, 697 insertions(+), 75 deletions(-) create mode 100644 core/src/com/cloud/agent/api/GetVmConfigAnswer.java create mode 100644 core/src/com/cloud/agent/api/GetVmConfigCommand.java create mode 100644 core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java create mode 100644 core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java diff --git a/core/src/com/cloud/agent/api/GetVmConfigAnswer.java b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java new file mode 100644 index 00000000000..46e003ecae3 --- /dev/null +++ b/core/src/com/cloud/agent/api/GetVmConfigAnswer.java @@ -0,0 +1,68 @@ +// 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.api; + +import java.util.List; + +public class GetVmConfigAnswer extends Answer { + + String vmName; + List nics; + + protected GetVmConfigAnswer() { + } + + public GetVmConfigAnswer(String vmName, List nics) { + this.vmName = vmName; + this.nics = nics; + } + + public String getVmName() { + return vmName; + } + + public List getNics() { + return nics; + } + + public class NicDetails { + String macAddress; + int vlanid; + + public NicDetails() { + } + + public NicDetails(String macAddress, int vlanid) { + this.macAddress = macAddress; + this.vlanid = vlanid; + } + + public String getMacAddress() { + return macAddress; + } + + public int getVlanid() { + return vlanid; + } + + } + + @Override + public boolean executeInSequence() { + return false; + } +} \ No newline at end of file diff --git a/core/src/com/cloud/agent/api/GetVmConfigCommand.java b/core/src/com/cloud/agent/api/GetVmConfigCommand.java new file mode 100644 index 00000000000..9133bd6b2c3 --- /dev/null +++ b/core/src/com/cloud/agent/api/GetVmConfigCommand.java @@ -0,0 +1,46 @@ +// 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.api; + + +import java.util.List; + +import com.cloud.agent.api.to.NicTO; + +public class GetVmConfigCommand extends Command { + String vmName; + List nics; + protected GetVmConfigCommand() { + } + + public GetVmConfigCommand(String vmName) { + this.vmName = vmName; + } + + public String getVmName() { + return vmName; + } + + public void setNics(List nics){ + this.nics = nics; + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java new file mode 100644 index 00000000000..1140485c67c --- /dev/null +++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigAnswer.java @@ -0,0 +1,36 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.agent.api; + +public class ModifyVmNicConfigAnswer extends Answer { + String vmName; + protected ModifyVmNicConfigAnswer() { + } + + public ModifyVmNicConfigAnswer(String vmName) { + this.vmName = vmName; + } + + public String getVmName() { + return vmName; + } + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java new file mode 100644 index 00000000000..0230beca732 --- /dev/null +++ b/core/src/com/cloud/agent/api/ModifyVmNicConfigCommand.java @@ -0,0 +1,42 @@ +// 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.api; + + +public class ModifyVmNicConfigCommand extends Command { + String vmName; + int vlan; + String macAddress; + protected ModifyVmNicConfigCommand() { + } + + public ModifyVmNicConfigCommand(String vmName, int vlan, String macAddress) { + this.vmName = vmName; + this.vlan = vlan; + this.macAddress = macAddress; + } + + public String getVmName() { + return vmName; + } + + + @Override + public boolean executeInSequence() { + return false; + } +} diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config index b783dfecd63..3ec08bd29c9 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/AgentShell/App.config @@ -96,7 +96,7 @@ 2048 - 10.102.192.150 + 0.0.0.0 diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index d54295ccdaa..c336a3821e3 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -690,6 +690,20 @@ namespace HypervResource public String entityType; } + public class NicDetails + { + [JsonProperty("macAddress")] + public string macaddress; + [JsonProperty("vlanid")] + public int vlanid; + public NicDetails() { } + public NicDetails(String macaddress, int vlanid) + { + this.macaddress = macaddress; + this.vlanid = vlanid; + } + } + /// /// Fully qualified named for a number of types used in CloudStack. Used to specify the intended type for JSON serialised objects. /// @@ -738,6 +752,10 @@ namespace HypervResource public const string GetVmDiskStatsCommand = "com.cloud.agent.api.GetVmDiskStatsCommand"; public const string GetVmStatsAnswer = "com.cloud.agent.api.GetVmStatsAnswer"; public const string GetVmStatsCommand = "com.cloud.agent.api.GetVmStatsCommand"; + public const string GetVmConfigCommand = "com.cloud.agent.api.GetVmConfigCommand"; + public const string GetVmConfigAnswer = "com.cloud.agent.api.GetVmConfigAnswer"; + public const string ModifyVmNicConfigCommand = "com.cloud.agent.api.ModifyVmNicConfigCommand"; + public const string ModifyVmNicConfigAnswer = "com.cloud.agent.api.ModifyVmNicConfigAnswer"; public const string GetVncPortAnswer = "com.cloud.agent.api.GetVncPortAnswer"; public const string GetVncPortCommand = "com.cloud.agent.api.GetVncPortCommand"; public const string HostStatsEntry = "com.cloud.agent.api.HostStatsEntry"; diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index f7787c32c52..ebb3bce2cf8 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -982,6 +982,24 @@ namespace HypervResource return true; } + // POST api/HypervResource/PlugNicCommand + [HttpPost] + [ActionName(CloudStackTypes.PlugNicCommand)] + public JContainer PlugNicCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.PlugNicCommand + cmd.ToString()); + object ansContent = new + { + result = true, + details = "instead of plug, change he network settings", + contextMap = contextMap + }; + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.PlugNicAnswer); + } + } + // POST api/HypervResource/CleanupNetworkRulesCmd [HttpPost] @@ -1264,6 +1282,88 @@ namespace HypervResource } } + // POST api/HypervResource/ModifyVmVnicVlanCommand + [HttpPost] + [ActionName(CloudStackTypes.ModifyVmNicConfigCommand)] + public JContainer ModifyVmNicConfigCommand([FromBody]dynamic cmd) + { + + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.ModifyVmNicConfigCommand + cmd.ToString()); + bool result = false; + String vmName = cmd.vmName; + uint vlan = (uint)cmd.vlan; + string macAddress = cmd.macAddress; + wmiCallsV2.ModifyVmVLan(vmName, vlan, macAddress); + + result = true; + + object ansContent = new + { + vmName = vmName, + result = result, + contextMap = contextMap + }; + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.ModifyVmNicConfigAnswer); + } + + } + + // POST api/HypervResource/GetVmConfigCommand + [HttpPost] + [ActionName(CloudStackTypes.GetVmConfigCommand)] + public JContainer GetVmConfigCommand([FromBody]dynamic cmd) + { + using (log4net.NDC.Push(Guid.NewGuid().ToString())) + { + logger.Info(CloudStackTypes.GetVmConfigCommand + cmd.ToString()); + bool result = false; + String vmName = cmd.vmName; + ComputerSystem vm = wmiCallsV2.GetComputerSystem(vmName); + List nicDetails = new List(); + var nicSettingsViaVm = wmiCallsV2.GetEthernetPortSettings(vm); + NicDetails nic = null; + String[] macAddress = new String[nicSettingsViaVm.Length]; + int index = 0; + foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm) + { + macAddress[index++] = item.Address; + } + + index = 0; + var ethernetConnections = wmiCallsV2.GetEthernetConnections(vm); + int vlanid = 1; + foreach (EthernetPortAllocationSettingData item in ethernetConnections) + { + EthernetSwitchPortVlanSettingData vlanSettings = wmiCallsV2.GetVlanSettings(item); + if (vlanSettings == null) + { + vlanid = -1; + } + else + { + vlanid = vlanSettings.AccessVlanId; + } + nic = new NicDetails(macAddress[index++], vlanid); + nicDetails.Add(nic); + } + + result = true; + + object ansContent = new + { + vmName = vmName, + nics = nicDetails, + result = result, + contextMap = contextMap + }; + return ReturnCloudStackTypedJArray(ansContent, CloudStackTypes.GetVmConfigAnswer); + } + } + + + // POST api/HypervResource/GetVmStatsCommand [HttpPost] [ActionName(CloudStackTypes.GetVmStatsCommand)] diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs index 5f814c59535..9042d7c5e12 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/IWmiCallsV2.cs @@ -66,5 +66,6 @@ namespace HypervResource void patchSystemVmIso(string vmName, string systemVmIso); void SetState(ComputerSystem vm, ushort requiredState); Dictionary GetVmSync(String privateIpAddress); + void ModifyVmVLan(string vmName, uint vlanid, string mac); } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs index 2e3aca59675..b9694f00eca 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/WmiCallsV2.cs @@ -443,6 +443,7 @@ namespace HypervResource nicCount++; } + // pass the boot args for the VM using KVP component. // We need to pass the boot args to system vm's to get them configured with cloudstack configuration. // Add new user data @@ -909,6 +910,37 @@ namespace HypervResource return new ResourceAllocationSettingData((ManagementBaseObject)defaultDiskDriveSettings.LateBoundObject.Clone()); } + + // Modify the systemvm nic's VLAN id + public void ModifyVmVLan(string vmName, uint vlanid, String mac) + { + ComputerSystem vm = GetComputerSystem(vmName); + SyntheticEthernetPortSettingData[] nicSettingsViaVm = GetEthernetPortSettings(vm); + // Obtain controller for Hyper-V virtualisation subsystem + VirtualSystemManagementService vmMgmtSvc = GetVirtualisationSystemManagementService(); + string normalisedMAC = string.Join("", (mac.Split(new char[] { ':' }))); + int index = 0; + foreach (SyntheticEthernetPortSettingData item in nicSettingsViaVm) + { + if (normalisedMAC.ToLower().Equals(item.Address.ToLower())) + { + break; + } + index++; + } + + //TODO: make sure the index wont be out of range. + + EthernetPortAllocationSettingData[] ethernetConnections = GetEthernetConnections(vm); + EthernetSwitchPortVlanSettingData vlanSettings = GetVlanSettings(ethernetConnections[index]); + + //Assign configuration to new NIC + vlanSettings.LateBoundObject["AccessVlanId"] = vlanid; + vlanSettings.LateBoundObject["OperationMode"] = 1; + ModifyFeatureVmResources(vmMgmtSvc, vm, new String[] { + vlanSettings.LateBoundObject.GetText(TextFormat.CimDtd20)}); + } + public void AttachIso(string displayName, string iso) { logger.DebugFormat("Got request to attach iso {0} to vm {1}", iso, displayName); @@ -1420,6 +1452,36 @@ namespace HypervResource return vSwitch; } + + private static void ModifyFeatureVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings) + { + // Resource settings are changed through the management service + System.Management.ManagementPath jobPath; + System.Management.ManagementPath[] results; + + var ret_val = vmMgmtSvc.ModifyFeatureSettings( + resourceSettings, + out jobPath, + out results); + + // If the Job is done asynchronously + if (ret_val == ReturnCode.Started) + { + JobCompleted(jobPath); + } + else if (ret_val != ReturnCode.Completed) + { + var errMsg = string.Format( + "Failed to update VM {0} (GUID {1}) due to {2} (ModifyVirtualSystem call), existing VM not deleted", + vm.ElementName, + vm.Name, + ReturnCode.ToString(ret_val)); + var ex = new WmiException(errMsg); + logger.Error(errMsg, ex); + throw ex; + } + } + private static void ModifyVmResources(VirtualSystemManagementService vmMgmtSvc, ComputerSystem vm, string[] resourceSettings) { // Resource settings are changed through the management service diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java index 5845038bbff..1d9e7f619f9 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/guru/HypervGuru.java @@ -16,15 +16,30 @@ // under the License. package com.cloud.hypervisor.hyperv.guru; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + import javax.ejb.Local; import javax.inject.Inject; +import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuru; import com.cloud.hypervisor.HypervisorGuruBase; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.GuestOSDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.hypervisor.hyperv.manager.HypervManager; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.NicProfile; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; /** @@ -35,6 +50,9 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { @Inject private GuestOSDao _guestOsDao; + @Inject HypervManager _hypervMgr; + @Inject NetworkDao _networkDao; + @Inject NetworkModel _networkMgr; @Override public final HypervisorType getHypervisorType() { @@ -51,6 +69,78 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { @Override public final VirtualMachineTO implement(VirtualMachineProfile vm) { VirtualMachineTO to = toVirtualMachineTO(vm); + List nicProfiles = vm.getNics(); + + if(vm.getVirtualMachine().getType() == VirtualMachine.Type.DomainRouter) { + + NicProfile publicNicProfile = null; + for(NicProfile nicProfile : nicProfiles) { + if(nicProfile.getTrafficType() == TrafficType.Public) { + publicNicProfile = nicProfile; + break; + } + } + + if(publicNicProfile != null) { + NicTO[] nics = to.getNics(); + + // reserve extra NICs + NicTO[] expandedNics = new NicTO[nics.length + _hypervMgr.getRouterExtraPublicNics()]; + int i = 0; + int deviceId = -1; + for(i = 0; i < nics.length; i++) { + expandedNics[i] = nics[i]; + if(nics[i].getDeviceId() > deviceId) + deviceId = nics[i].getDeviceId(); + } + deviceId++; + + long networkId = publicNicProfile.getNetworkId(); + NetworkVO network = _networkDao.findById(networkId); + + for(; i < nics.length + _hypervMgr.getRouterExtraPublicNics(); i++) { + NicTO nicTo = new NicTO(); + nicTo.setDeviceId(deviceId++); + nicTo.setBroadcastType(publicNicProfile.getBroadcastType()); + nicTo.setType(publicNicProfile.getTrafficType()); + nicTo.setIp("0.0.0.0"); + nicTo.setNetmask("255.255.255.255"); + nicTo.setName(publicNicProfile.getName()); + + try { + String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId); + nicTo.setMac(mac); + } catch (InsufficientAddressCapacityException e) { + throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId); + } + nicTo.setDns1(publicNicProfile.getDns1()); + nicTo.setDns2(publicNicProfile.getDns2()); + if (publicNicProfile.getGateway() != null) { + nicTo.setGateway(publicNicProfile.getGateway()); + } else { + nicTo.setGateway(network.getGateway()); + } + nicTo.setDefaultNic(false); + nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri()); + nicTo.setIsolationuri(publicNicProfile.getIsolationUri()); + + Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null); + nicTo.setNetworkRateMbps(networkRate); + + expandedNics[i] = nicTo; + } + to.setNics(expandedNics); + } + + StringBuffer sbMacSequence = new StringBuffer(); + for(NicTO nicTo : sortNicsByDeviceId(to.getNics())) { + sbMacSequence.append(nicTo.getMac()).append("|"); + } + sbMacSequence.deleteCharAt(sbMacSequence.length() - 1); + String bootArgs = to.getBootArgs(); + to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString()); + + } // Determine the VM's OS description GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); @@ -59,6 +149,29 @@ public class HypervGuru extends HypervisorGuruBase implements HypervisorGuru { return to; } + private NicTO[] sortNicsByDeviceId(NicTO[] nics) { + + List listForSort = new ArrayList(); + for (NicTO nic : nics) { + listForSort.add(nic); + } + Collections.sort(listForSort, new Comparator() { + + @Override + public int compare(NicTO arg0, NicTO arg1) { + if (arg0.getDeviceId() < arg1.getDeviceId()) { + return -1; + } else if (arg0.getDeviceId() == arg1.getDeviceId()) { + return 0; + } + + return 1; + } + }); + + return listForSort.toArray(new NicTO[0]); + } + @Override public final boolean trackVmHostChange() { return false; diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java index 9030e29e7a4..5821fe4dcae 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManager.java @@ -21,4 +21,5 @@ import com.cloud.utils.component.Manager; public interface HypervManager extends Manager { public String prepareSecondaryStorageStore(long zoneId); + int getRouterExtraPublicNics(); } diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java index a30eb7df005..71a619a0ad5 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/manager/HypervManagerImpl.java @@ -45,6 +45,8 @@ import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.GlobalLock; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.VMInstanceDao; @Local(value = {HypervManager.class}) public class HypervManagerImpl implements HypervManager { @@ -60,10 +62,11 @@ public class HypervManagerImpl implements HypervManager { Map _storageMounts = new HashMap(); StorageLayer _storage; - @Inject - ConfigurationDao _configDao; - @Inject - DataStoreManager _dataStoreMgr; + @Inject ConfigurationDao _configDao; + @Inject DataStoreManager _dataStoreMgr; + @Inject VMInstanceDao _vminstanceDao; + @Inject NicDao _nicDao; + int _routerExtraPublicNics = 2; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -77,7 +80,7 @@ public class HypervManagerImpl implements HypervManager { _storage = new JavaStorageLayer(); _storage.configure("StorageLayer", params); } - + _routerExtraPublicNics = NumbersUtil.parseInt(_configDao.getValue(Config.RouterExtraPublicNics.key()), 2); return true; } @@ -373,4 +376,9 @@ public class HypervManagerImpl implements HypervManager { } } } -} + + @Override + public int getRouterExtraPublicNics() { + return _routerExtraPublicNics; + } +} \ No newline at end of file diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java index d6ffa1db5c2..e9647ad4a81 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java @@ -71,7 +71,12 @@ import com.cloud.agent.api.CheckS2SVpnConnectionsCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; +import com.cloud.agent.api.GetVmConfigAnswer; +import com.cloud.agent.api.GetVmConfigAnswer.NicDetails; +import com.cloud.agent.api.GetVmConfigCommand; import com.cloud.agent.api.HostVmStateReportEntry; +import com.cloud.agent.api.ModifyVmNicConfigAnswer; +import com.cloud.agent.api.ModifyVmNicConfigCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.PingCommand; @@ -117,11 +122,13 @@ import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.exception.InternalErrorException; import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.hyperv.manager.HypervManager; import com.cloud.network.HAProxyConfigurator; import com.cloud.network.LoadBalancerConfigurator; +import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.network.rules.FirewallRule; import com.cloud.resource.ServerResource; @@ -133,6 +140,8 @@ import com.cloud.utils.net.NetUtils; import com.cloud.utils.ssh.SshHelper; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineName; + + /** * Implementation of dummy resource to be returned from discoverer. **/ @@ -706,65 +715,6 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } } - // - // find mac address of a specified ethx device - // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2 - // returns - // eth0:xx.xx.xx.xx - - // - // list IP with eth devices - // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' - // | awk -F: '{ print $1 ": " $3 }' - // - // returns - // eth0:xx.xx.xx.xx - // - // - - private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception { - - s_logger.info("findRouterEthDeviceIndex. mac: " + mac); - - // TODO : this is a temporary very inefficient solution, will refactor it later - Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "ls /proc/sys/net/ipv4/conf"); - - // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS - // we use a waiting loop here as a workaround to synchronize activities in systems - long startTick = System.currentTimeMillis(); - while (System.currentTimeMillis() - startTick < 15000) { - if (result.first()) { - String[] tokens = result.second().split("\\s+"); - for (String token : tokens) { - if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { - String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); - - if (s_logger.isDebugEnabled()) - s_logger.debug("Run domr script " + cmd); - Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, - // TODO need to find the dev index inside router based on IP address - cmd); - if (s_logger.isDebugEnabled()) - s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); - - if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) - return Integer.parseInt(token.substring(3)); - } - } - } - - s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry..."); - - try { - Thread.currentThread(); - Thread.sleep(1000); - } catch (InterruptedException e) { - } - } - - return -1; - } - protected Answer execute(SetPortForwardingRulesCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource SetPortForwardingRulesCommand: " + s_gson.toJson(cmd)); @@ -1170,7 +1120,6 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource VmDataCommand: " + s_gson.toJson(cmd)); } - String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String controlIp = getRouterSshControlIp(cmd); @@ -1386,6 +1335,102 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S return new Answer(cmd); } + // + // find mac address of a specified ethx device + // ip address show ethx | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2 + // returns + // eth0:xx.xx.xx.xx + + // + // list IP with eth devices + // ifconfig ethx |grep -B1 "inet addr" | awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' + // | awk -F: '{ print $1 ": " $3 }' + // + // returns + // eth0:xx.xx.xx.xx + // + // + + private int findRouterEthDeviceIndex(String domrName, String routerIp, String mac) throws Exception { + + s_logger.info("findRouterEthDeviceIndex. mac: " + mac); + + // TODO : this is a temporary very inefficient solution, will refactor it later + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + "ls /proc/sys/net/ipv4/conf"); + + // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS + // we use a waiting loop here as a workaround to synchronize activities in systems + long startTick = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTick < 15000) { + if (result.first()) { + String[] tokens = result.second().split("\\s+"); + for (String token : tokens) { + if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { + String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + + if (s_logger.isDebugEnabled()) + s_logger.debug("Run domr script " + cmd); + Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + // TODO need to find the dev index inside router based on IP address + cmd); + if (s_logger.isDebugEnabled()) + s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); + + if (result2.first() && result2.second().trim().equalsIgnoreCase(mac.trim())) + return Integer.parseInt(token.substring(3)); + } + } + } + + s_logger.warn("can not find intereface associated with mac: " + mac + ", guest OS may still at loading state, retry..."); + + } + + return -1; + } + + private Pair findRouterFreeEthDeviceIndex(String routerIp) throws Exception { + + s_logger.info("findRouterFreeEthDeviceIndex. mac: "); + + // TODO : this is a temporary very inefficient solution, will refactor it later + Pair result = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + "ip address | grep DOWN| cut -f2 -d :"); + + // when we dynamically plug in a new NIC into virtual router, it may take time to show up in guest OS + // we use a waiting loop here as a workaround to synchronize activities in systems + long startTick = System.currentTimeMillis(); + while (System.currentTimeMillis() - startTick < 15000) { + if (result.first() && !result.second().isEmpty()) { + String[] tokens = result.second().split("\\n"); + for (String token : tokens) { + if (!("all".equalsIgnoreCase(token) || "default".equalsIgnoreCase(token) || "lo".equalsIgnoreCase(token))) { + //String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + //TODO: don't check for eth0,1,2, as they will be empty by default. + //String cmd = String.format("ip address show %s ", token); + String cmd = String.format("ip address show %s | grep link/ether | sed -e 's/^[ \t]*//' | cut -d' ' -f2", token); + if (s_logger.isDebugEnabled()) + s_logger.debug("Run domr script " + cmd); + Pair result2 = SshHelper.sshExecute(routerIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, + // TODO need to find the dev index inside router based on IP address + cmd); + if (s_logger.isDebugEnabled()) + s_logger.debug("result: " + result2.first() + ", output: " + result2.second()); + + if (result2.first() && result2.second().trim().length() > 0) + return new Pair(Integer.parseInt(token.trim().substring(3)), result2.second().trim()) ; + } + } + } + + //s_logger.warn("can not find intereface associated with mac: , guest OS may still at loading state, retry..."); + + } + + return new Pair(-1, ""); + } + protected Answer execute(IpAssocCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource IPAssocCommand: " + s_gson.toJson(cmd)); @@ -1401,7 +1446,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S String controlIp = getRouterSshControlIp(cmd); for (IpAddressTO ip : ips) { assignPublicIpAddress(routerName, controlIp, ip.getPublicIp(), ip.isAdd(), ip.isFirstIP(), ip.isSourceNat(), ip.getBroadcastUri(), ip.getVlanGateway(), - ip.getVlanNetmask(), ip.getVifMacAddress()); + ip.getVlanNetmask(), ip.getVifMacAddress()); results[i++] = ip.getPublicIp() + " - success"; } @@ -1419,16 +1464,97 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S return new IpAssocAnswer(cmd, results); } + protected int getVmNics(String vmName, int vlanid) { + GetVmConfigCommand vmConfig = new GetVmConfigCommand(vmName); + URI agentUri = null; + int nicposition = -1; + try { + String cmdName = GetVmConfigCommand.class.getName(); + agentUri = + new URI("https", null, _agentIp, _port, + "/api/HypervResource/" + cmdName, null, null); + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for Hyper-V agent"; + s_logger.error(errMsg, e); + } + String ansStr = postHttpRequest(s_gson.toJson(vmConfig), agentUri); + Answer[] result = s_gson.fromJson(ansStr, Answer[].class); + s_logger.debug("executeRequest received response " + + s_gson.toJson(result)); + if (result.length > 0) { + GetVmConfigAnswer ans = ((GetVmConfigAnswer)result[0]); + List nics = ans.getNics(); + for (NicDetails nic : nics) { + if (nic.getVlanid() == vlanid) { + nicposition = nics.indexOf(nic); + break; + } + } + } + return nicposition; + } + + protected void modifyNicVlan(String vmName, int vlanId, String macAddress) { + ModifyVmNicConfigCommand modifynic = new ModifyVmNicConfigCommand(vmName, vlanId, macAddress); + URI agentUri = null; + try { + String cmdName = ModifyVmNicConfigCommand.class.getName(); + agentUri = + new URI("https", null, _agentIp, _port, + "/api/HypervResource/" + cmdName, null, null); + } catch (URISyntaxException e) { + String errMsg = "Could not generate URI for Hyper-V agent"; + s_logger.error(errMsg, e); + } + String ansStr = postHttpRequest(s_gson.toJson(modifynic), agentUri); + Answer[] result = s_gson.fromJson(ansStr, Answer[].class); + s_logger.debug("executeRequest received response " + + s_gson.toJson(result)); + if (result.length > 0) { + ModifyVmNicConfigAnswer ans = ((ModifyVmNicConfigAnswer)result[0]); + } + } + protected void assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, - final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception { + final boolean sourceNat, final String broadcastId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws Exception { + + URI broadcastUri = BroadcastDomainType.fromString(broadcastId); + if (BroadcastDomainType.getSchemeValue(broadcastUri) != BroadcastDomainType.Vlan) { + throw new InternalErrorException("Unable to assign a public IP to a VIF on network " + broadcastId); + } + int vlanId = Integer.parseInt(BroadcastDomainType.getValue(broadcastUri)); + + int publicNicInfo = -1; + publicNicInfo = getVmNics(vmName, vlanId); boolean addVif = false; - if (add) { + if (add && publicNicInfo == -1) { if (s_logger.isDebugEnabled()) { s_logger.debug("Plug new NIC to associate" + privateIpAddress + " to " + publicIpAddress); } addVif = true; } else if (!add && firstIP) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Unplug NIC " + publicNicInfo); + } + } + + if (addVif) { + Pair nicdevice = findRouterFreeEthDeviceIndex(privateIpAddress); + publicNicInfo = nicdevice.first(); + if (publicNicInfo > 0) { + modifyNicVlan(vmName, vlanId, nicdevice.second()); + // After modifying the vnic on VR, check the VR VNics config in the host and get the device position + publicNicInfo = getVmNics(vmName, vlanId); + // As a new nic got activated in the VR. add the entry in the NIC's table. + networkUsage(privateIpAddress, "addVif", "eth" + publicNicInfo); + } + else { + // we didn't find any eth device available in VR to configure the ip range with new VLAN + String msg = "No Nic is available on DomR VIF to associate/disassociate IP with."; + s_logger.error(msg); + throw new InternalErrorException(msg); + } } String args = null; @@ -1450,8 +1576,8 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S args += publicIpAddress + "/" + cidrSize; args += " -c "; - args += "eth" + "2"; // currently hardcoding to eth 2 (which is default public ipd)//publicNicInfo.first(); + args += "eth" + publicNicInfo; args += " -g "; args += vlanGateway; @@ -1464,7 +1590,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S } Pair result = - SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args); + SshHelper.sshExecute(privateIpAddress, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/ipassoc.sh " + args); if (!result.first()) { s_logger.error("ipassoc command on domain router " + privateIpAddress + " failed. message: " + result.second()); @@ -1840,7 +1966,7 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S sch.connect(addr); return null; } catch (IOException e) { - s_logger.info("Could not connect to " + ipAddress + " due to " + e.toString()); + s_logger.info("Could] not connect to " + ipAddress + " due to " + e.toString()); if (e instanceof ConnectException) { // if connection is refused because of VM is being started, // we give it more sleep time diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 13291d057a5..bf2516a24a9 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -2125,7 +2125,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V buf.append(" dnssearchorder=").append(domain_suffix); } - if (profile.getHypervisorType() == HypervisorType.VMware) { + if (profile.getHypervisorType() == HypervisorType.VMware || profile.getHypervisorType() == HypervisorType.Hyperv) { buf.append(" extra_pubnics=" + _routerExtraPublicNics); } diff --git a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh index ae2d7e4296c..2a9d7807743 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/ipassoc.sh @@ -254,10 +254,11 @@ remove_first_ip() { if [ $? -gt 0 -a $? -ne 2 ] then remove_routing $1 + sudo ip link set $ethDev down return 1 fi remove_routing $1 - + sudo ip link set $ethDev down return $? } From 7ac48934f77c3b9a72c05300163088a4c198ebf2 Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Tue, 28 Jan 2014 06:42:54 +0530 Subject: [PATCH 050/126] CLOUDSTACK-5821 systemvmiso is locked by systevmvm in hyperv --- .../patches/debian/config/etc/init.d/cloud-early-config | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config index d6dc8f02031..df80a289c2d 100755 --- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config +++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config @@ -135,7 +135,7 @@ get_boot_params() { virtualpc|hyperv) # Hyper-V is recognized as virtualpc hypervisor type. Boot args are passed using KVP Daemon #waiting for the hv_kvp_daemon to start up - #sleep 30 need to fix the race condition of hv_kvp_daemon and cloud-early-config + #sleep need to fix the race condition of hv_kvp_daemon and cloud-early-config sleep 5 cp -f /var/opt/hyperv/.kvp_pool_0 /var/cache/cloud/cmdline cat /dev/null > /var/opt/hyperv/.kvp_pool_0 @@ -1211,6 +1211,10 @@ start() { patch_log4j parse_cmd_line change_password + if [ "$hyp" == "hyperv" ]; then + # eject the systemvm.iso + eject + fi case $TYPE in router) [ "$NAME" == "" ] && NAME=router From 39447cce6ec973e84abc04e3af96f2a027a4632a Mon Sep 17 00:00:00 2001 From: Rajesh Battala Date: Tue, 28 Jan 2014 07:02:11 +0530 Subject: [PATCH 051/126] CLOUDSTACK-5941 User Vm deployment on HyperV is failing due to change in the userdata script location and moved to json model --- .../resource/HypervDirectConnectResource.java | 62 ++++--------------- 1 file changed, 12 insertions(+), 50 deletions(-) diff --git a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java index e9647ad4a81..2f645906317 100644 --- a/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java +++ b/plugins/hypervisors/hyperv/src/com/cloud/hypervisor/hyperv/resource/HypervDirectConnectResource.java @@ -36,13 +36,13 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; import javax.annotation.PostConstruct; import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringEscapeUtils; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; @@ -1120,73 +1120,35 @@ public class HypervDirectConnectResource extends ServerResourceBase implements S if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource VmDataCommand: " + s_gson.toJson(cmd)); } - String routerPrivateIpAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); String controlIp = getRouterSshControlIp(cmd); + Map> data = new HashMap>(); + data.put(cmd.getVmIpAddress(), cmd.getVmData()); - String vmIpAddress = cmd.getVmIpAddress(); - List vmData = cmd.getVmData(); - String[] vmDataArgs = new String[vmData.size() * 2 + 4]; - vmDataArgs[0] = "routerIP"; - vmDataArgs[1] = routerPrivateIpAddress; - vmDataArgs[2] = "vmIP"; - vmDataArgs[3] = vmIpAddress; - int i = 4; - for (String[] vmDataEntry : vmData) { - String folder = vmDataEntry[0]; - String file = vmDataEntry[1]; - String contents = (vmDataEntry[2] != null) ? vmDataEntry[2] : "none"; + String json = new Gson().toJson(data); + s_logger.debug("VM data JSON IS:" + json); - vmDataArgs[i] = folder + "," + file; - vmDataArgs[i + 1] = contents; - i += 2; - } + json = Base64.encodeBase64String(json.getBytes()); - String content = encodeDataArgs(vmDataArgs); - String tmpFileName = UUID.randomUUID().toString(); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Run vm_data command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", data: " + content); - } + String args = "-d " + json; try { - SshHelper.scpTo(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/tmp", content.getBytes(), tmpFileName, null); - - try { - Pair result = - SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/root/userdata.py " + tmpFileName); - - if (!result.first()) { - s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second()); - return new Answer(cmd, false, "VmDataCommand failed due to " + result.second()); - } - } finally { - - SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "rm /tmp/" + tmpFileName); + Pair result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", getSystemVMKeyFile(), null, "/opt/cloud/bin/vmdata.py " + args); + if (!result.first()) { + s_logger.error("vm_data command on domain router " + controlIp + " failed. messge: " + result.second()); + return new Answer(cmd, false, "VmDataCommand failed due to " + result.second()); } if (s_logger.isInfoEnabled()) { s_logger.info("vm_data command on domain router " + controlIp + " completed"); } - } catch (Throwable e) { - String msg = "VmDataCommand failed due to " + e; + String msg = "VmDataCommand failed due to " + e.getMessage(); s_logger.error(msg, e); return new Answer(cmd, false, msg); } return new Answer(cmd); } - private String encodeDataArgs(String[] dataArgs) { - StringBuilder sb = new StringBuilder(); - - for (String arg : dataArgs) { - sb.append(arg); - sb.append("\n"); - } - - return sb.toString(); - } - protected Answer execute(DhcpEntryCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource DhcpEntryCommand: " + s_gson.toJson(cmd)); From 4583bac05bb3c2df2e7f199599765eb297023bf8 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Mon, 27 Jan 2014 17:52:16 +0530 Subject: [PATCH 052/126] CLOUDSTACK-5796. [VMware] Size column is not getting updated in snapshot_store_ref table when a snapshot is backed up in secondary storage. Calculate and update the size of a backed up snapshot. This snapshot size is in turn used to update the secondary_storage count for an account. --- .../resource/VmwareStorageProcessor.java | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index 0ed09c4c82b..6157bd681c4 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -957,7 +957,7 @@ public class VmwareStorageProcessor implements StorageProcessor { String backupUuid = UUID.randomUUID().toString(); Pair snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName); - return new Ternary(backupUuid + "/" + backupUuid, snapshotInfo.first(), snapshotInfo.second()); + return new Ternary(backupUuid, snapshotInfo.first(), snapshotInfo.second()); } @Override @@ -1040,8 +1040,25 @@ public class VmwareStorageProcessor implements StorageProcessor { answer = new CopyCmdAnswer(details); } else { details = "Successfully backedUp the snapshot with Uuid: " + snapshotUuid + " to secondary storage."; + + // Get snapshot physical size + long physicalSize = 0l; + String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl); + String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid; + File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles(); + if(files != null) { + for(File file : files) { + String fileName = file.getName(); + if(fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) { + physicalSize = new File(secondaryMountPoint + "/" + snapshotDir + "/" + fileName).length(); + break; + } + } + } + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); - newSnapshot.setPath(destSnapshot.getPath() + "/" + snapshotBackupUuid); + newSnapshot.setPath(snapshotDir + "/" + snapshotBackupUuid); + newSnapshot.setPhysicalSize(physicalSize); answer = new CopyCmdAnswer(newSnapshot); } } finally { From cc98125067575f305ea7621df28c70785128750a Mon Sep 17 00:00:00 2001 From: Sachchidanand Vaidya Date: Wed, 8 Jan 2014 00:26:46 -0800 Subject: [PATCH 053/126] These are additional fixes to make Juniper Contrail plugin work --- .../network-elements/juniper-contrail/pom.xml | 6 + .../cloudstack/contrail/module.properties | 18 +++ .../contrail/spring-contrail-context.xml | 50 +++++++ .../management/ContrailElementImpl.java | 7 - .../IntegrationTestConfiguration.java | 73 ++++++++-- .../management/MockAccountManager.java | 3 - .../test/resources/commonContext.xml | 136 ++++++------------ 7 files changed, 177 insertions(+), 116 deletions(-) create mode 100644 plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties create mode 100644 plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml index ae6961e10a2..8c6877dfb90 100644 --- a/plugins/network-elements/juniper-contrail/pom.xml +++ b/plugins/network-elements/juniper-contrail/pom.xml @@ -82,6 +82,12 @@ cloud-framework-events ${project.version} + + org.apache.cloudstack + cloud-framework-spring-lifecycle + ${project.version} + test + com.google.guava guava diff --git a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties new file mode 100644 index 00000000000..ced0f3addc7 --- /dev/null +++ b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/module.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +name=contrail +parent=network \ No newline at end of file diff --git a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml new file mode 100644 index 00000000000..4614af79a4b --- /dev/null +++ b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java index 092e4bc7365..05723b04447 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java @@ -26,7 +26,6 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; -import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -90,12 +89,6 @@ public class ContrailElementImpl extends AdapterBase ServerDBSync _dbSync; private static final Logger s_logger = Logger.getLogger(ContrailElement.class); - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - s_logger.debug("configure"); - return true; - } - // PluggableService @Override public List> getCommands() { diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java index 416653d0a53..1a53c173d9f 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/IntegrationTestConfiguration.java @@ -45,14 +45,17 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDaoImpl; import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDaoImpl; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.datacenter.entity.api.db.dao.DcDetailsDaoImpl; +import org.apache.cloudstack.engine.orchestration.NetworkOrchestrator; import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService; import org.apache.cloudstack.engine.service.api.OrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.framework.config.ConfigDepot; import org.apache.cloudstack.framework.config.ConfigDepotAdmin; import org.apache.cloudstack.framework.config.dao.ConfigurationDaoImpl; @@ -65,6 +68,7 @@ import org.apache.cloudstack.framework.jobs.impl.AsyncJobManagerImpl; import org.apache.cloudstack.framework.jobs.impl.AsyncJobMonitor; import org.apache.cloudstack.framework.jobs.impl.SyncQueueManager; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDaoImpl; +import org.apache.cloudstack.network.element.InternalLoadBalancerElement; import org.apache.cloudstack.network.lb.ApplicationLoadBalancerService; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMManager; import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; @@ -73,6 +77,9 @@ import org.apache.cloudstack.region.PortableIpDaoImpl; import org.apache.cloudstack.region.PortableIpRangeDaoImpl; import org.apache.cloudstack.region.RegionManager; import org.apache.cloudstack.region.dao.RegionDaoImpl; +import org.apache.cloudstack.spring.lifecycle.registry.ExtensionRegistry; +import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; import org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl; import org.apache.cloudstack.storage.image.db.TemplateDataStoreDaoImpl; @@ -120,6 +127,7 @@ import com.cloud.dc.dao.AccountVlanMapDaoImpl; import com.cloud.dc.dao.ClusterDaoImpl; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterDaoImpl; +import com.cloud.dc.dao.DataCenterDetailsDaoImpl; import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl; import com.cloud.dc.dao.DataCenterVnetDaoImpl; @@ -141,11 +149,11 @@ import com.cloud.host.dao.HostDetailsDaoImpl; import com.cloud.host.dao.HostTagsDaoImpl; import com.cloud.hypervisor.HypervisorGuruManagerImpl; import com.cloud.hypervisor.dao.HypervisorCapabilitiesDaoImpl; +import com.cloud.hypervisor.XenServerGuru; import com.cloud.network.ExternalDeviceUsageManager; import com.cloud.network.IpAddress; import com.cloud.network.IpAddressManagerImpl; import com.cloud.network.Ipv6AddressManagerImpl; -import com.cloud.network.NetworkModelImpl; import com.cloud.network.NetworkServiceImpl; import com.cloud.network.NetworkUsageService; import com.cloud.network.StorageNetworkManager; @@ -161,6 +169,7 @@ import com.cloud.network.as.dao.CounterDaoImpl; import com.cloud.network.dao.AccountGuestVlanMapDaoImpl; import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; import com.cloud.network.dao.FirewallRulesDaoImpl; +import com.cloud.network.dao.IPAddressDaoImpl; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LBHealthCheckPolicyDaoImpl; import com.cloud.network.dao.LBStickinessPolicyDaoImpl; @@ -183,7 +192,11 @@ import com.cloud.network.dao.Site2SiteVpnGatewayDaoImpl; import com.cloud.network.dao.UserIpv6AddressDaoImpl; import com.cloud.network.dao.VirtualRouterProviderDaoImpl; import com.cloud.network.dao.VpnUserDaoImpl; +import com.cloud.network.element.FirewallServiceProvider; +import com.cloud.network.element.NetworkACLServiceProvider; +import com.cloud.network.element.PortForwardingServiceProvider; import com.cloud.network.element.Site2SiteVpnServiceProvider; +import com.cloud.network.element.VpcProvider; import com.cloud.network.firewall.FirewallManagerImpl; import com.cloud.network.lb.LoadBalancingRulesManagerImpl; import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl; @@ -234,7 +247,7 @@ import com.cloud.storage.VolumeApiService; import com.cloud.storage.dao.DiskOfferingDaoImpl; import com.cloud.storage.dao.GuestOSCategoryDaoImpl; import com.cloud.storage.dao.GuestOSDaoImpl; -import com.cloud.storage.dao.LaunchPermissionDao; +import com.cloud.storage.dao.LaunchPermissionDaoImpl; import com.cloud.storage.dao.SnapshotDaoImpl; import com.cloud.storage.dao.SnapshotPolicyDaoImpl; import com.cloud.storage.dao.StoragePoolDetailsDaoImpl; @@ -271,10 +284,13 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.db.TransactionCallbackNoReturn; import com.cloud.utils.db.TransactionStatus; import com.cloud.vm.ItWorkDaoImpl; +import com.cloud.vm.UserVmManagerImpl; +import com.cloud.vm.VirtualMachineManagerImpl; import com.cloud.vm.dao.ConsoleProxyDaoImpl; import com.cloud.vm.dao.DomainRouterDaoImpl; import com.cloud.vm.dao.InstanceGroupDaoImpl; import com.cloud.vm.dao.InstanceGroupVMMapDaoImpl; +import com.cloud.vm.dao.NicDaoImpl; import com.cloud.vm.dao.NicIpAliasDaoImpl; import com.cloud.vm.dao.NicSecondaryIpDaoImpl; import com.cloud.vm.dao.SecondaryStorageVmDaoImpl; @@ -291,19 +307,19 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; AsyncJobJournalDaoImpl.class, AsyncJobManagerImpl.class, AutoScalePolicyConditionMapDaoImpl.class, AutoScalePolicyDaoImpl.class, AutoScaleVmGroupDaoImpl.class, AutoScaleVmGroupPolicyMapDaoImpl.class, AutoScaleVmProfileDaoImpl.class, CapacityDaoImpl.class, ClusterDaoImpl.class, ClusterDetailsDaoImpl.class, ConditionDaoImpl.class, ConfigurationDaoImpl.class, ConfigurationManagerImpl.class, ConfigurationServerImpl.class, ConsoleProxyDaoImpl.class, - ContrailElementImpl.class, ContrailGuru.class, ContrailManagerImpl.class, CounterDaoImpl.class, DataCenterDaoImpl.class, DataCenterIpAddressDaoImpl.class, + ContrailElementImpl.class, ContrailGuru.class, ContrailManagerImpl.class, CounterDaoImpl.class, DataCenterDaoImpl.class, DataCenterDetailsDaoImpl.class, DataCenterIpAddressDaoImpl.class, DataCenterJoinDaoImpl.class, DataCenterLinkLocalIpAddressDaoImpl.class, DataCenterVnetDaoImpl.class, DcDetailsDaoImpl.class, DedicatedResourceDaoImpl.class, DiskOfferingDaoImpl.class, DiskOfferingJoinDaoImpl.class, DomainDaoImpl.class, DomainManagerImpl.class, DomainRouterDaoImpl.class, DomainRouterJoinDaoImpl.class, - EventDaoImpl.class, EventJoinDaoImpl.class, EventUtils.class, EventUtils.class, FirewallManagerImpl.class, FirewallRulesCidrsDaoImpl.class, + EventDaoImpl.class, EventJoinDaoImpl.class, EventUtils.class, ExtensionRegistry.class, FirewallManagerImpl.class, FirewallRulesCidrsDaoImpl.class, FirewallRulesDaoImpl.class, GuestOSCategoryDaoImpl.class, GuestOSDaoImpl.class, HostDaoImpl.class, HostDetailsDaoImpl.class, HostJoinDaoImpl.class, HostPodDaoImpl.class, HostTagsDaoImpl.class, HostTransferMapDaoImpl.class, HypervisorCapabilitiesDaoImpl.class, HypervisorGuruManagerImpl.class, ImageStoreDaoImpl.class, ImageStoreJoinDaoImpl.class, InstanceGroupDaoImpl.class, InstanceGroupJoinDaoImpl.class, - InstanceGroupVMMapDaoImpl.class, IpAddressManagerImpl.class, Ipv6AddressManagerImpl.class, ItWorkDaoImpl.class, LBHealthCheckPolicyDaoImpl.class, - LBStickinessPolicyDaoImpl.class, LaunchPermissionDao.class, LoadBalancerDaoImpl.class, LoadBalancerVMMapDaoImpl.class, LoadBalancingRulesManagerImpl.class, + InstanceGroupVMMapDaoImpl.class, InternalLoadBalancerElement.class, IPAddressDaoImpl.class, IpAddressManagerImpl.class, Ipv6AddressManagerImpl.class, ItWorkDaoImpl.class, LBHealthCheckPolicyDaoImpl.class, + LBStickinessPolicyDaoImpl.class, LaunchPermissionDaoImpl.class, LoadBalancerDaoImpl.class, LoadBalancerVMMapDaoImpl.class, LoadBalancingRulesManagerImpl.class, ManagementServerHostDaoImpl.class, MockAccountManager.class, NetworkACLDaoImpl.class, NetworkACLItemDaoImpl.class, NetworkACLManagerImpl.class, - NetworkAccountDaoImpl.class, NetworkDaoImpl.class, NetworkDomainDaoImpl.class, NetworkModelImpl.class, NetworkOfferingDaoImpl.class, - NetworkOfferingDetailsDaoImpl.class, NetworkOfferingServiceMapDaoImpl.class, NetworkOpDaoImpl.class, NetworkRuleConfigDaoImpl.class, NetworkServiceImpl.class, - NetworkServiceMapDaoImpl.class, NicIpAliasDaoImpl.class, NicSecondaryIpDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkServiceProviderDaoImpl.class, + NetworkAccountDaoImpl.class, NetworkDaoImpl.class, NetworkDomainDaoImpl.class, NetworkOfferingDaoImpl.class, + NetworkOfferingDetailsDaoImpl.class, NetworkOfferingServiceMapDaoImpl.class, NetworkOpDaoImpl.class, NetworkOrchestrator.class, NetworkRuleConfigDaoImpl.class, NetworkServiceImpl.class, + NetworkServiceMapDaoImpl.class, NicDaoImpl.class, NicIpAliasDaoImpl.class, NicSecondaryIpDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkServiceProviderDaoImpl.class, PhysicalNetworkTrafficTypeDaoImpl.class, PlannerHostReservationDaoImpl.class, PodVlanDaoImpl.class, PodVlanMapDaoImpl.class, PortForwardingRulesDaoImpl.class, PortableIpDaoImpl.class, PortableIpRangeDaoImpl.class, PrimaryDataStoreDaoImpl.class, PrivateIpDaoImpl.class, ProjectAccountDaoImpl.class, ProjectAccountJoinDaoImpl.class, ProjectInvitationDaoImpl.class, ProjectDaoImpl.class, ProjectInvitationJoinDaoImpl.class, ProjectJoinDaoImpl.class, @@ -315,11 +331,11 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; SnapshotDaoImpl.class, SnapshotPolicyDaoImpl.class, StaticRouteDaoImpl.class, StatsCollector.class, StoragePoolDetailsDaoImpl.class, StoragePoolHostDaoImpl.class, StoragePoolJoinDaoImpl.class, SyncQueueItemDaoImpl.class, TemplateDataStoreDaoImpl.class, TemplateJoinDaoImpl.class, UploadDaoImpl.class, UsageEventDaoImpl.class, UserAccountJoinDaoImpl.class, UserDaoImpl.class, UserIpv6AddressDaoImpl.class, UserStatisticsDaoImpl.class, UserStatsLogDaoImpl.class, - UserVmCloneSettingDaoImpl.class, UserVmDaoImpl.class, UserVmDetailsDaoImpl.class, UserVmJoinDaoImpl.class, VMInstanceDaoImpl.class, VMSnapshotDaoImpl.class, - VMTemplateDaoImpl.class, VMTemplateDetailsDaoImpl.class, VMTemplateHostDaoImpl.class, VMTemplateZoneDaoImpl.class, VirtualRouterProviderDaoImpl.class, + UserVmCloneSettingDaoImpl.class, UserVmDaoImpl.class, UserVmDetailsDaoImpl.class, UserVmJoinDaoImpl.class, UserVmManagerImpl.class, VMInstanceDaoImpl.class, VMSnapshotDaoImpl.class, + VMTemplateDaoImpl.class, VMTemplateDetailsDaoImpl.class, VMTemplateHostDaoImpl.class, VMTemplateZoneDaoImpl.class, VirtualMachineManagerImpl.class, VirtualRouterProviderDaoImpl.class, VlanDaoImpl.class, VmDiskStatisticsDaoImpl.class, VmRulesetLogDaoImpl.class, VolumeDaoImpl.class, VolumeHostDaoImpl.class, VolumeJoinDaoImpl.class, VpcDaoImpl.class, VpcGatewayDaoImpl.class, VpcManagerImpl.class, VpcOfferingDaoImpl.class, VpcOfferingServiceMapDaoImpl.class, VpcServiceMapDaoImpl.class, - VpcVirtualNetworkApplianceManagerImpl.class, VpnUserDaoImpl.class}, includeFilters = {@Filter(value = IntegrationTestConfiguration.ComponentFilter.class, + VpcVirtualNetworkApplianceManagerImpl.class, VpnUserDaoImpl.class, XenServerGuru.class}, includeFilters = {@Filter(value = IntegrationTestConfiguration.ComponentFilter.class, type = FilterType.CUSTOM)}, useDefaultFilters = false) @Configuration public class IntegrationTestConfiguration { @@ -711,5 +727,36 @@ public class IntegrationTestConfiguration { public VolumeOrchestrationService volumeOrchestrationService() { return Mockito.mock(VolumeOrchestrationService.class); } - + @Bean + public FirewallServiceProvider firewallServiceProvider() { + return Mockito.mock(FirewallServiceProvider.class); + } + @Bean + public PortForwardingServiceProvider portForwardingServiceProvider() { + return Mockito.mock(PortForwardingServiceProvider.class); + } + @Bean + public NetworkACLServiceProvider networkACLServiceProvider() { + return Mockito.mock(NetworkACLServiceProvider.class); + } + @Bean + public VpcProvider vpcProvier() { + return Mockito.mock(VpcProvider.class); + } + @Bean + public VolumeService volumeService() { + return Mockito.mock(VolumeService.class); + } + @Bean + public PrimaryDataStoreProviderManager privateDataStoreProviderManager() { + return Mockito.mock(PrimaryDataStoreProviderManager.class); + } + @Bean + public ImageStoreProviderManager imageStoreProviderManager() { + return Mockito.mock(ImageStoreProviderManager.class); + } + @Bean + public DataStoreProvider dataStoreProvider() { + return Mockito.mock(DataStoreProvider.class); + } } diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java index 2f81688c0f8..fa7be5827c5 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/MockAccountManager.java @@ -34,7 +34,6 @@ import org.apache.cloudstack.api.command.admin.user.RegisterCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd; import org.apache.cloudstack.context.CallContext; -import com.cloud.api.query.dao.AccountJoinDao; import com.cloud.api.query.vo.ControlledViewEntity; import com.cloud.configuration.ResourceLimit; import com.cloud.configuration.dao.ResourceCountDao; @@ -68,8 +67,6 @@ public class MockAccountManager extends ManagerBase implements AccountManager { @Inject ResourceCountDao _resourceCountDao; - @Inject - AccountJoinDao _accountJoinDao; @Inject UserDao _userDao; diff --git a/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml b/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml index eef908ff15b..6f46f6dde4e 100644 --- a/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml +++ b/plugins/network-elements/juniper-contrail/test/resources/commonContext.xml @@ -23,6 +23,7 @@ + - - - + + + + + - + + - - - - - - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + class="org.apache.cloudstack.network.contrail.management.IntegrationTestConfiguration"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + From 3bd38eb17e4b51bd57e3db2d204105387bfdc7a8 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 24 Jan 2014 11:58:53 +0000 Subject: [PATCH 054/126] Findbugs finding : Incorrect use of equality --- .../src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index 3cd7a9f0e9e..e6ecbc9adbc 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -166,7 +166,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Discoverer _clusterDetailsDao.persist(clusterId, clusterDetails); } String updatedInventoryPath = validateCluster(url, vmwareDc); - if (url.getPath() != updatedInventoryPath) { + if (!url.getPath().equals(updatedInventoryPath)) { // If url from API doesn't specify DC then update url in database with DC associated with this zone. clusterDetails.put("url", url.getScheme() + "://" + url.getHost() + updatedInventoryPath); _clusterDetailsDao.persist(clusterId, clusterDetails); From 997c0f8d154cf8d9530ebb3b96c30170faa454c0 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Tue, 28 Jan 2014 10:33:31 +0100 Subject: [PATCH 055/126] Fix the exclusion for opensaml1, this should take care of the repository dependencies causing grief on the jenkins slaves. --- awsapi/pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/awsapi/pom.xml b/awsapi/pom.xml index d9f562735a3..4a6c89c9e5f 100644 --- a/awsapi/pom.xml +++ b/awsapi/pom.xml @@ -142,7 +142,7 @@ org.opensaml - opensaml + opensaml1 @@ -162,7 +162,7 @@ org.opensaml - opensaml + opensaml1 @@ -178,7 +178,7 @@ org.opensaml - opensaml + opensaml1 @@ -194,7 +194,7 @@ org.opensaml - opensaml + opensaml1 @@ -210,7 +210,7 @@ org.opensaml - opensaml + opensaml1 From 95bd04e449c346aec0d9bdc30061ad27ea70d75b Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Tue, 28 Jan 2014 16:01:19 +0530 Subject: [PATCH 056/126] CLOUDSTACK-5965. VM displayname is not returned by API. If user doesn't supply a display name during VM launch, default it to VM name(uuid) in listVM response. --- server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java index 07449a23e3d..08478e2958b 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java @@ -99,7 +99,11 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem userVmResponse.setId(userVm.getUuid()); userVmResponse.setName(userVm.getName()); - userVmResponse.setDisplayName(userVm.getDisplayName()); + if (userVm.getDisplayName() != null) { + userVmResponse.setDisplayName(userVm.getDisplayName()); + } else { + userVmResponse.setDisplayName(userVm.getName()); + } if (userVm.getAccountType() == Account.ACCOUNT_TYPE_PROJECT) { userVmResponse.setProjectId(userVm.getProjectUuid()); From 4f6638d7c7436cd638c653d0e08e6fa2023420e8 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 13:49:14 +0100 Subject: [PATCH 057/126] findbugs: nullpointer dereference guarded(cherry picked from commit 43ba36f97950aa8d09399a28bb50c6a22209f15e) --- .../impl/UserConcentratedAllocator.java | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java index b67eccbd2d7..946eee6da49 100755 --- a/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java @@ -243,35 +243,36 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat // List vms = _vmInstanceDao.listByLastHostId(hostId); List vms = null; long usedCapacity = 0; - for (VMInstanceVO vm : vms) { - if (skipCalculation(vm)) { - continue; - } - - ServiceOffering so = null; - - if (vm.getType() == VirtualMachine.Type.User) { - UserVmVO userVm = _vmDao.findById(vm.getId()); - if (userVm == null) { + if (vms != null) { + for (VMInstanceVO vm : vms) { + if (skipCalculation(vm)) { continue; } - } - so = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()); + ServiceOffering so = null; - if (capacityType == Capacity.CAPACITY_TYPE_MEMORY) { - usedCapacity += so.getRamSize() * 1024L * 1024L; - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Counting memory capacity used by vm: " + vm.getId() + ", size: " + so.getRamSize() + "MB, host: " + hostId + ", currently counted: " + - usedCapacity + " Bytes"); + if (vm.getType() == VirtualMachine.Type.User) { + UserVmVO userVm = _vmDao.findById(vm.getId()); + if (userVm == null) { + continue; + } } - } else if (capacityType == Capacity.CAPACITY_TYPE_CPU) { - usedCapacity += so.getCpu() * so.getSpeed(); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Counting cpu capacity used by vm: " + vm.getId() + ", cpu: " + so.getCpu() + ", speed: " + so.getSpeed() + ", currently counted: " + - usedCapacity + " Bytes"); + so = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId()); + if (capacityType == Capacity.CAPACITY_TYPE_MEMORY) { + usedCapacity += so.getRamSize() * 1024L * 1024L; + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Counting memory capacity used by vm: " + vm.getId() + ", size: " + so.getRamSize() + "MB, host: " + hostId + ", currently counted: " + + usedCapacity + " Bytes"); + } + } else if (capacityType == Capacity.CAPACITY_TYPE_CPU) { + usedCapacity += so.getCpu() * so.getSpeed(); + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Counting cpu capacity used by vm: " + vm.getId() + ", cpu: " + so.getCpu() + ", speed: " + so.getSpeed() + ", currently counted: " + + usedCapacity + " Bytes"); + } } } } From 60e8d131cf27834f4cbbcbccf0174a273cd570c3 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 14:14:47 +0100 Subject: [PATCH 058/126] findbugs: moved call on static object to synchronized block(cherry picked from commit f3529a19a9aad36dbd92e311018643629f19c748) --- server/src/com/cloud/api/ApiDispatcher.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/api/ApiDispatcher.java b/server/src/com/cloud/api/ApiDispatcher.java index 9f4f766fc45..55ef53ae2b9 100755 --- a/server/src/com/cloud/api/ApiDispatcher.java +++ b/server/src/com/cloud/api/ApiDispatcher.java @@ -427,8 +427,8 @@ public class ApiDispatcher { } } else { DateFormat format = BaseCmd.INPUT_FORMAT; - format.setLenient(false); synchronized (format) { + format.setLenient(false); field.set(cmdObj, format.parse(paramObj.toString())); } } From 1c7361756cb41091deb7798377ae5ed04b7de8d9 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 14:24:21 +0100 Subject: [PATCH 059/126] Findbugs: scariest issues in ApiResponseHelper fixed (cherry picked from commit 9a1b882d0eb871c64fe0f0f3fbafbabae89188fa) --- .../com/cloud/network/rules/FirewallRule.java | 3 ++- api/src/com/cloud/network/vpc/StaticRoute.java | 3 ++- .../src/com/cloud/api/ApiResponseHelper.java | 18 ++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/api/src/com/cloud/network/rules/FirewallRule.java b/api/src/com/cloud/network/rules/FirewallRule.java index 4cfa42b3770..274242ad394 100644 --- a/api/src/com/cloud/network/rules/FirewallRule.java +++ b/api/src/com/cloud/network/rules/FirewallRule.java @@ -36,7 +36,8 @@ public interface FirewallRule extends ControlledEntity, Identity, InternalIdenti Staged, // Rule been created but has never got through network rule conflict detection. Rules in this state can not be sent to network elements. Add, // Add means the rule has been created and has gone through network rule conflict detection. Active, // Rule has been sent to the network elements and reported to be active. - Revoke // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database. + Revoke, // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database. + Deleting // rule has been revoked and is scheduled for deletion } enum TrafficType { diff --git a/api/src/com/cloud/network/vpc/StaticRoute.java b/api/src/com/cloud/network/vpc/StaticRoute.java index ccdbec899b8..5707ca14024 100644 --- a/api/src/com/cloud/network/vpc/StaticRoute.java +++ b/api/src/com/cloud/network/vpc/StaticRoute.java @@ -25,7 +25,8 @@ public interface StaticRoute extends ControlledEntity, Identity, InternalIdentit Staged, // route been created but has never got through network rule conflict detection. Routes in this state can not be sent to VPC virtual router. Add, // Add means the route has been created and has gone through network rule conflict detection. Active, // Route has been sent to the VPC router and reported to be active. - Revoke // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database. + Revoke, // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database. + Deleting // rule has been revoked and is scheduled for deletion } /** diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index c9e5581865f..a50b3eeffb2 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -384,8 +384,9 @@ public class ApiResponseHelper implements ResponseGenerator { populateDomain(resourceLimitResponse, accountTemp.getDomainId()); } resourceLimitResponse.setResourceType(Integer.valueOf(limit.getType().getOrdinal()).toString()); + if ((limit.getType() == ResourceType.primary_storage || limit.getType() == ResourceType.secondary_storage) && limit.getMax() >= 0) { - resourceLimitResponse.setMax((long)Math.ceil(limit.getMax() / ResourceType.bytesToGiB)); + resourceLimitResponse.setMax((long)Math.ceil((double)limit.getMax() / ResourceType.bytesToGiB)); } else { resourceLimitResponse.setMax(limit.getMax()); } @@ -1804,8 +1805,6 @@ public class ApiResponseHelper implements ResponseGenerator { public SecurityGroupResponse createSecurityGroupResponseFromSecurityGroupRule(List securityRules) { SecurityGroupResponse response = new SecurityGroupResponse(); Map securiytGroupAccounts = new HashMap(); - Map allowedSecurityGroups = new HashMap(); - Map allowedSecuriytGroupAccounts = new HashMap(); if ((securityRules != null) && !securityRules.isEmpty()) { SecurityGroupJoinVO securityGroup = ApiDBUtils.findSecurityGroupViewById(securityRules.get(0).getSecurityGroupId()).get(0); @@ -3008,11 +3007,10 @@ public class ApiResponseHelper implements ResponseGenerator { response.setCidr(result.getCidr()); StaticRoute.State state = result.getState(); - String stateToSet = state.toString(); - if (state.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; + if (state.equals(StaticRoute.State.Revoke)) { + state = StaticRoute.State.Deleting; } - response.setState(stateToSet); + response.setState(state.toString()); populateAccount(response, result.getAccountId()); populateDomain(response, result.getDomainId()); @@ -3501,11 +3499,11 @@ public class ApiResponseHelper implements ResponseGenerator { ApplicationLoadBalancerRuleResponse ruleResponse = new ApplicationLoadBalancerRuleResponse(); ruleResponse.setInstancePort(lb.getDefaultPortStart()); ruleResponse.setSourcePort(lb.getSourcePortStart()); - String stateToSet = lb.getState().toString(); + FirewallRule.State stateToSet = lb.getState(); if (stateToSet.equals(FirewallRule.State.Revoke)) { - stateToSet = "Deleting"; + stateToSet = FirewallRule.State.Deleting; } - ruleResponse.setState(stateToSet); + ruleResponse.setState(stateToSet.toString()); ruleResponse.setObjectName("loadbalancerrule"); ruleResponses.add(ruleResponse); lbResponse.setLbRules(ruleResponses); From a71871d11ce97216d0e50c01bcd84cc59d3d18dc Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 14:47:06 +0100 Subject: [PATCH 060/126] findbugs: fixes for ApiServer, ApiSerializerHelper and ApiXmlDocWriter(cherry picked from commit 9aced41d708acd22b43ef0e512fa2cc657a6c0a2) --- .../com/cloud/api/ApiSerializerHelper.java | 2 +- server/src/com/cloud/api/ApiServer.java | 29 +++++++++++++------ server/src/com/cloud/api/ApiServlet.java | 2 +- .../cloud/api/EncodedStringTypeAdapter.java | 2 +- server/src/com/cloud/api/doc/Alert.java | 12 ++++++-- server/src/com/cloud/api/doc/Command.java | 11 +++++-- .../api/response/ApiResponseSerializer.java | 2 +- 7 files changed, 41 insertions(+), 19 deletions(-) diff --git a/server/src/com/cloud/api/ApiSerializerHelper.java b/server/src/com/cloud/api/ApiSerializerHelper.java index cd5c7e65fdc..7426d9f1675 100644 --- a/server/src/com/cloud/api/ApiSerializerHelper.java +++ b/server/src/com/cloud/api/ApiSerializerHelper.java @@ -24,7 +24,7 @@ import org.apache.cloudstack.api.ResponseObject; public class ApiSerializerHelper { public static final Logger s_logger = Logger.getLogger(ApiSerializerHelper.class.getName()); - public static String token = "/"; + private static String token = "/"; public static String toSerializedString(Object result) { if (result != null) { diff --git a/server/src/com/cloud/api/ApiServer.java b/server/src/com/cloud/api/ApiServer.java index 71a1b8d3658..d715db65c67 100755 --- a/server/src/com/cloud/api/ApiServer.java +++ b/server/src/com/cloud/api/ApiServer.java @@ -159,11 +159,10 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer private static final Logger s_logger = Logger.getLogger(ApiServer.class.getName()); private static final Logger s_accessLogger = Logger.getLogger("apiserver." + ApiServer.class.getName()); - public static boolean encodeApiResponse = false; - public static String jsonContentType = "text/javascript"; - public static String controlCharacters = "[\000-\011\013-\014\016-\037\177]"; // Non-printable ASCII characters - numbers 0 to 31 and 127 decimal - @Inject - ApiDispatcher _dispatcher; + private static boolean encodeApiResponse = false; + private static String jsonContentType = "text/javascript"; + private static String controlCharacters = "[\000-\011\013-\014\016-\037\177]"; // Non-printable ASCII characters - numbers 0 to 31 and 127 decimal + @Inject ApiDispatcher _dispatcher; @Inject private AccountManager _accountMgr; @@ -241,7 +240,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer s_apiNameCmdClassMap.put(apiName, cmdClass); } - encodeApiResponse = Boolean.valueOf(_configDao.getValue(Config.EncodeApiResponse.key())); + setEncodeApiResponse(Boolean.valueOf(_configDao.getValue(Config.EncodeApiResponse.key()))); String jsonType = _configDao.getValue(Config.JavaScriptDefaultContentType.key()); if (jsonType != null) { jsonContentType = jsonType; @@ -379,7 +378,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer buildAuditTrail(auditTrailSb, command[0], response); } else { if (!command[0].equalsIgnoreCase("login") && !command[0].equalsIgnoreCase("logout")) { - String errorString = "Unknown API command: " + ((command == null) ? "null" : command[0]); + String errorString = "Unknown API command: " + command[0]; s_logger.warn(errorString); auditTrailSb.append(" " + errorString); throw new ServerApiException(ApiErrorCode.UNSUPPORTED_ACTION_ERROR, errorString); @@ -1102,7 +1101,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer @Inject public void setPluggableServices(List pluggableServices) { - this._pluggableServices = pluggableServices; + _pluggableServices = pluggableServices; } public List getApiAccessCheckers() { @@ -1111,6 +1110,18 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer @Inject public void setApiAccessCheckers(List apiAccessCheckers) { - this._apiAccessCheckers = apiAccessCheckers; + _apiAccessCheckers = apiAccessCheckers; + } + + public static boolean isEncodeApiResponse() { + return encodeApiResponse; + } + + private static void setEncodeApiResponse(boolean encodeApiResponse) { + ApiServer.encodeApiResponse = encodeApiResponse; + } + + public static String getJsonContentType() { + return jsonContentType; } } diff --git a/server/src/com/cloud/api/ApiServlet.java b/server/src/com/cloud/api/ApiServlet.java index 6a33c14baaf..46f7eba8bee 100755 --- a/server/src/com/cloud/api/ApiServlet.java +++ b/server/src/com/cloud/api/ApiServlet.java @@ -375,7 +375,7 @@ public class ApiServlet extends HttpServlet { private void writeResponse(HttpServletResponse resp, String response, int responseCode, String responseType) { try { if (BaseCmd.RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) { - resp.setContentType(ApiServer.jsonContentType + "; charset=UTF-8"); + resp.setContentType(ApiServer.getJsonContentType() + "; charset=UTF-8"); } else { resp.setContentType("text/xml; charset=UTF-8"); } diff --git a/server/src/com/cloud/api/EncodedStringTypeAdapter.java b/server/src/com/cloud/api/EncodedStringTypeAdapter.java index cde144830aa..50dbd0d48cd 100644 --- a/server/src/com/cloud/api/EncodedStringTypeAdapter.java +++ b/server/src/com/cloud/api/EncodedStringTypeAdapter.java @@ -37,7 +37,7 @@ public class EncodedStringTypeAdapter implements JsonSerializer { } private static String encodeString(String value) { - if (!ApiServer.encodeApiResponse) { + if (!ApiServer.isEncodeApiResponse()) { return value; } try { diff --git a/server/src/com/cloud/api/doc/Alert.java b/server/src/com/cloud/api/doc/Alert.java index e73cb0e5351..3e61d0ba268 100644 --- a/server/src/com/cloud/api/doc/Alert.java +++ b/server/src/com/cloud/api/doc/Alert.java @@ -16,9 +16,15 @@ // under the License. package com.cloud.api.doc; -public class Alert { - private String type; - private int value; +import java.io.Serializable; + +public class Alert implements Serializable{ + /** + * + */ + private static final long serialVersionUID = 960408026527837920L; + private final String type; + private final int value; public Alert(String type, int value) { this.type = type; diff --git a/server/src/com/cloud/api/doc/Command.java b/server/src/com/cloud/api/doc/Command.java index 998b39fefab..549ca291ffe 100644 --- a/server/src/com/cloud/api/doc/Command.java +++ b/server/src/com/cloud/api/doc/Command.java @@ -16,10 +16,15 @@ // under the License. package com.cloud.api.doc; +import java.io.Serializable; import java.util.ArrayList; -public class Command { +public class Command implements Serializable{ + /** + * + */ + private static final long serialVersionUID = -4318310162503004975L; private String name; private String description; private String usage; @@ -85,7 +90,7 @@ public class Command { } public Argument getReqArgByName(String name) { - for (Argument a : this.getRequest()) { + for (Argument a : getRequest()) { if (a.getName().equals(name)) { return a; } @@ -94,7 +99,7 @@ public class Command { } public Argument getResArgByName(String name) { - for (Argument a : this.getResponse()) { + for (Argument a : getResponse()) { if (a.getName().equals(name)) { return a; } diff --git a/server/src/com/cloud/api/response/ApiResponseSerializer.java b/server/src/com/cloud/api/response/ApiResponseSerializer.java index d8b728a9f3a..f276e89d5e1 100644 --- a/server/src/com/cloud/api/response/ApiResponseSerializer.java +++ b/server/src/com/cloud/api/response/ApiResponseSerializer.java @@ -291,7 +291,7 @@ public class ApiResponseSerializer { } private static String encodeParam(String value) { - if (!ApiServer.encodeApiResponse) { + if (!ApiServer.isEncodeApiResponse()) { return value; } try { From 53feecaa76b7c4a10e1bbe8280b6f28c638b18f8 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 14:53:11 +0100 Subject: [PATCH 061/126] findbugs: null check for gateway and netmask instead of gateway twice(cherry picked from commit d30ddf6d59732fa30855811e7fe0aa639ee3849a) --- .../com/cloud/configuration/ConfigurationManagerImpl.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index f0c7f354dec..20037167487 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -36,6 +36,8 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -83,7 +85,6 @@ import org.apache.cloudstack.region.dao.RegionDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.log4j.Logger; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; @@ -2640,8 +2641,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } return NetUtils.supersetOrSubset.neitherSubetNorSuperset; - } else if (newVlanGateway == null || newVlanGateway == null) { - throw new InvalidParameterValueException("either both netmask and gateway should be passed or both should me omited."); + } else if (newVlanGateway == null || newVlanNetmask == null) { + throw new InvalidParameterValueException( + "either both netmask and gateway should be passed or both should me omited."); } else { if (!NetUtils.sameSubnet(startIP, newVlanGateway, newVlanNetmask)) { throw new InvalidParameterValueException("The start ip and gateway do not belong to the same subnet"); From d7ee7a74315fd13b1fd3e4701e8810788aa1e680 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Tue, 28 Jan 2014 19:09:26 +0530 Subject: [PATCH 062/126] CLOUDSTACK-5900: Failed to delete template/ISO that failed to download. --- .../resource/NfsSecondaryStorageResource.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 30722e2fdd0..4d11dd38e79 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -1716,16 +1716,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S parent += File.separator; } String absoluteTemplatePath = parent + relativeTemplatePath; - File tmpltParent = new File(absoluteTemplatePath).getParentFile(); + File tmpltDir = new File(absoluteTemplatePath); String details = null; - if (!tmpltParent.exists()) { - details = "template parent directory " + tmpltParent.getName() + " doesn't exist"; + if (!tmpltDir.exists()) { + details = "template parent directory " + tmpltDir.getName() + " doesn't exist"; s_logger.debug(details); return new Answer(cmd, true, details); } - File[] tmpltFiles = tmpltParent.listFiles(); + File[] tmpltFiles = tmpltDir.listFiles(); if (tmpltFiles == null || tmpltFiles.length == 0) { - details = "No files under template parent directory " + tmpltParent.getName(); + details = "No files under template parent directory " + tmpltDir.getName(); s_logger.debug(details); } else { boolean found = false; @@ -1751,12 +1751,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } if (!found) { - details = "Can not find template.properties under " + tmpltParent.getName(); + details = "Can not find template.properties under " + tmpltDir.getName(); s_logger.debug(details); } } - if (!tmpltParent.delete()) { - details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + relativeTemplatePath; + if (!tmpltDir.delete()) { + details = "Unable to delete directory " + tmpltDir.getName() + " under Template path " + relativeTemplatePath; s_logger.debug(details); return new Answer(cmd, false, details); } From fe262caa7561c23098cc8fc9674ff8d0e59e1c25 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 15:36:40 +0100 Subject: [PATCH 063/126] findbugs: retrieve the objects to remove from the collection(s) --- .../deploy/DeploymentPlanningManagerImpl.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index ec20067db25..35a0b39acb2 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -165,7 +165,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setStoragePoolAllocators(List storagePoolAllocators) { - this._storagePoolAllocators = storagePoolAllocators; + _storagePoolAllocators = storagePoolAllocators; } protected List _hostAllocators; @@ -175,7 +175,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setHostAllocators(List hostAllocators) { - this._hostAllocators = hostAllocators; + _hostAllocators = hostAllocators; } @Inject @@ -221,7 +221,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setPlanners(List planners) { - this._planners = planners; + _planners = planners; } protected List _affinityProcessors; @@ -231,7 +231,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } public void setAffinityGroupProcessors(List affinityProcessors) { - this._affinityProcessors = affinityProcessors; + _affinityProcessors = affinityProcessors; } @Override @@ -1142,9 +1142,9 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy List suitablePools = new ArrayList(); StoragePool pool = null; if (toBeCreated.getPoolId() != null) { - pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId()); + pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(toBeCreated.getPoolId()); } else { - pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(plan.getPoolId()); + pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(plan.getPoolId()); } if (!pool.isInMaintenance()) { @@ -1156,7 +1156,7 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy if (plan.getDataCenterId() == exstPoolDcId && plan.getPodId() == exstPoolPodId && plan.getClusterId() == exstPoolClusterId) { canReusePool = true; } else if (plan.getDataCenterId() == exstPoolDcId) { - DataStore dataStore = this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + DataStore dataStore = dataStoreMgr.getPrimaryDataStore(pool.getId()); if (dataStore != null && dataStore.getScope() != null && dataStore.getScope().getScopeType() == ScopeType.ZONE) { canReusePool = true; } @@ -1259,9 +1259,14 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy } } - if (suitableVolumeStoragePools.values() != null) { - poolsToAvoidOutput.removeAll(suitableVolumeStoragePools.values()); + HashSet toRemove = new HashSet(); + for (List lsp : suitableVolumeStoragePools.values()) { + for (StoragePool sp : lsp) { + toRemove.add(sp.getId()); + } } + poolsToAvoidOutput.removeAll(toRemove); + if (avoid.getPoolsToAvoid() != null) { avoid.getPoolsToAvoid().addAll(poolsToAvoidOutput); } From 44bc2beb143992b10ad9a92642dfa1882e48c4d8 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 15:44:04 +0100 Subject: [PATCH 064/126] findbugs: null-checks(cherry picked from commit c58e509924e97dfced80981da5c27b9f3aae9b33) --- server/src/com/cloud/acl/DomainChecker.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/acl/DomainChecker.java b/server/src/com/cloud/acl/DomainChecker.java index 2e43da3b1da..31b273ff2d0 100755 --- a/server/src/com/cloud/acl/DomainChecker.java +++ b/server/src/com/cloud/acl/DomainChecker.java @@ -307,7 +307,9 @@ public class DomainChecker extends AdapterBase implements SecurityChecker { } } //didn't find in upper tree - if (zoneDomainRecord.getPath().contains(accountDomainRecord.getPath())) { + if (zoneDomainRecord != null && + accountDomainRecord != null && + zoneDomainRecord.getPath().contains(accountDomainRecord.getPath())) { return true; } } From a16759a9b17fb7b2bbdda3595cd11c5bc5b83c79 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Sun, 26 Jan 2014 16:38:53 +0100 Subject: [PATCH 065/126] findbugs: byte[].toString -> Arrays.toString(byte[])(cherry picked from commit 23a3d99fc0836839a88584d7aa6a978d99c5d126) Signed-off-by: Daan Hoogland --- server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 8d76b8ae345..813888707a3 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.consoleproxy; import java.nio.charset.Charset; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -483,7 +484,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy byte[] details = proxy.getSessionDetails(); status = gson.fromJson(details != null ? new String(details, Charset.forName("US-ASCII")) : null, ConsoleProxyStatus.class); } catch (Throwable e) { - s_logger.warn("Unable to parse proxy session details : " + proxy.getSessionDetails()); + s_logger.warn("Unable to parse proxy session details : " + Arrays.toString(proxy.getSessionDetails())); } if (status != null && status.getConnections() != null) { From 0daca84efff98e74a4d800441d52a55067e31518 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Sun, 26 Jan 2014 16:49:18 +0100 Subject: [PATCH 066/126] findbugs: removed fields injected in parent(cherry picked from commit 866a539b067663b346bd8d087c578987a86fe834) Signed-off-by: Daan Hoogland --- .../kvm/discoverer/LibvirtServerDiscoverer.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java index da1bb88bbba..770099c65fd 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java @@ -28,8 +28,6 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; - import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@ -41,7 +39,6 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.configuration.Config; import com.cloud.dc.ClusterVO; -import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.DiscoveredWithErrorException; import com.cloud.exception.DiscoveryException; @@ -49,10 +46,8 @@ 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; @@ -70,17 +65,9 @@ public abstract class LibvirtServerDiscoverer extends DiscovererBase implements 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 abstract Hypervisor.HypervisorType getHypervisorType(); From fae05560218ef3bcb962bd424ae5dbf5cb8ede68 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 16:30:04 +0100 Subject: [PATCH 067/126] Findbugs: different issues solved(cherry picked from commit 0b13f8e59db1e681e1dff0baa828bb0711842e9f) --- .../com/cloud/api/query/vo/UserVmJoinVO.java | 23 +++---- .../com/cloud/consoleproxy/AgentHookBase.java | 5 +- .../src/com/cloud/dc/DedicatedResourceVO.java | 15 +++-- .../cloud/network/IpAddressManagerImpl.java | 60 ++++++++++--------- .../com/cloud/network/NetworkModelImpl.java | 7 ++- .../network/guru/ControlNetworkGuru.java | 4 +- .../com/cloud/network/vpc/VpcManagerImpl.java | 4 +- .../cloud/template/TemplateManagerImpl.java | 4 +- 8 files changed, 70 insertions(+), 52 deletions(-) diff --git a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java index 2df49ec14d1..9e4fc21caeb 100644 --- a/server/src/com/cloud/api/query/vo/UserVmJoinVO.java +++ b/server/src/com/cloud/api/query/vo/UserVmJoinVO.java @@ -35,6 +35,7 @@ import com.cloud.server.ResourceTag.ResourceObjectType; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; import com.cloud.utils.db.GenericDao; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; @@ -47,10 +48,10 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private long id; @Column(name = "name", updatable = false, nullable = false, length = 255) - private String name = null; + private final String name = null; @Column(name = "display_name", updatable = false, nullable = false, length = 255) - private String displayName = null; + private final String displayName = null; @Column(name = "account_id") private long accountId; @@ -59,7 +60,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String accountUuid; @Column(name = "account_name") - private String accountName = null; + private final String accountName = null; @Column(name = "account_type") private short accountType; @@ -71,10 +72,10 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String domainUuid; @Column(name = "domain_name") - private String domainName = null; + private final String domainName = null; @Column(name = "domain_path") - private String domainPath = null; + private final String domainPath = null; @Column(name = "instance_group_id") private long instanceGroupId; @@ -96,7 +97,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { */ @Enumerated(value = EnumType.STRING) @Column(name = "state", updatable = true, nullable = false, length = 32) - private State state = null; + private final State state = null; @Column(name = GenericDao.CREATED_COLUMN) private Date created; @@ -148,7 +149,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String dataCenterUuid; @Column(name = "data_center_name") - private String dataCenterName = null; + private final String dataCenterName = null; @Column(name = "security_group_enabled") private boolean securityGroupEnabled; @@ -233,7 +234,7 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { private String volumeUuid; @Column(name = "volume_device_id") - private Long volumeDeviceId = null; + private final Long volumeDeviceId = null; @Column(name = "volume_type") @Enumerated(EnumType.STRING) @@ -745,9 +746,11 @@ public class UserVmJoinVO extends BaseViewVO implements ControlledViewEntity { } public String getDetail(String name) { - assert (details != null) : "Did you forget to load the details?"; + if (details == null) { + throw new CloudRuntimeException("No details to get. Did you forget to load the details?"); + } - return details != null ? details.get(name) : null; + return details.get(name); } public String getUserData() { diff --git a/server/src/com/cloud/consoleproxy/AgentHookBase.java b/server/src/com/cloud/consoleproxy/AgentHookBase.java index 9dfffd4b98f..2e0bada3abb 100644 --- a/server/src/com/cloud/consoleproxy/AgentHookBase.java +++ b/server/src/com/cloud/consoleproxy/AgentHookBase.java @@ -49,6 +49,7 @@ import com.cloud.host.dao.HostDao; import com.cloud.servlet.ConsoleProxyPasswordBasedEncryptor; import com.cloud.servlet.ConsoleProxyServlet; import com.cloud.utils.Ternary; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.VMInstanceDao; @@ -192,7 +193,9 @@ public abstract class AgentHookBase implements AgentHook { assert (ksBits != null); if (ksBits == null) { - s_logger.error("Could not find and construct a valid SSL certificate"); + String msg = "Could not find and construct a valid SSL certificate"; + s_logger.error(msg); + throw new CloudRuntimeException(msg); } cmd = new StartConsoleProxyAgentHttpHandlerCommand(ksBits, storePassword); cmd.setEncryptorPassword(getEncryptorPassword()); diff --git a/server/src/com/cloud/dc/DedicatedResourceVO.java b/server/src/com/cloud/dc/DedicatedResourceVO.java index 9948f504158..41bdfec2c05 100644 --- a/server/src/com/cloud/dc/DedicatedResourceVO.java +++ b/server/src/com/cloud/dc/DedicatedResourceVO.java @@ -29,6 +29,11 @@ import javax.persistence.Table; @Table(name = "dedicated_resources") public class DedicatedResourceVO implements DedicatedResources { + /** + * + */ + private static final long serialVersionUID = -6659510127145101917L; + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") @@ -59,7 +64,7 @@ public class DedicatedResourceVO implements DedicatedResources { private long affinityGroupId; public DedicatedResourceVO() { - this.uuid = UUID.randomUUID().toString(); + uuid = UUID.randomUUID().toString(); } public DedicatedResourceVO(Long dataCenterId, Long podId, Long clusterId, Long hostId, Long domainId, Long accountId, long affinityGroupId) { @@ -69,7 +74,7 @@ public class DedicatedResourceVO implements DedicatedResources { this.hostId = hostId; this.domainId = domainId; this.accountId = accountId; - this.uuid = UUID.randomUUID().toString(); + uuid = UUID.randomUUID().toString(); this.affinityGroupId = affinityGroupId; } @@ -115,7 +120,7 @@ public class DedicatedResourceVO implements DedicatedResources { } public DedicatedResourceVO(long dedicatedResourceId) { - this.id = dedicatedResourceId; + id = dedicatedResourceId; } @Override @@ -138,7 +143,7 @@ public class DedicatedResourceVO implements DedicatedResources { @Override public String getUuid() { - return this.uuid; + return uuid; } public void setUuid(String uuid) { @@ -153,7 +158,7 @@ public class DedicatedResourceVO implements DedicatedResources { @Override public boolean equals(Object obj) { if (obj instanceof DedicatedResourceVO) { - return ((DedicatedResourceVO)obj).getId() == this.getId(); + return ((DedicatedResourceVO)obj).getId() == getId(); } else { return false; } diff --git a/server/src/com/cloud/network/IpAddressManagerImpl.java b/server/src/com/cloud/network/IpAddressManagerImpl.java index 6596074ad34..09f73a4d17a 100644 --- a/server/src/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/com/cloud/network/IpAddressManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.network; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -28,6 +29,8 @@ import java.util.UUID; import javax.inject.Inject; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.context.CallContext; @@ -39,7 +42,6 @@ import org.apache.cloudstack.region.PortableIp; import org.apache.cloudstack.region.PortableIpDao; import org.apache.cloudstack.region.PortableIpVO; import org.apache.cloudstack.region.Region; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.alert.AlertManager; @@ -570,8 +572,9 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage IPAddressVO ip = markIpAsUnavailable(addrId); - assert (ip != null) : "Unable to mark the ip address id=" + addrId + " as unavailable."; if (ip == null) { + String msg = "Unable to mark the ip address id=" + addrId + " as unavailable."; + s_logger.error(msg); return true; } @@ -684,10 +687,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage if (dedicatedVlanDbIds != null && !dedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = true; sc.setParameters("vlanId", dedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + dedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray())); } else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); } else { if (podId != null) { InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId); @@ -727,7 +730,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) { fetchFromDedicatedRange = false; sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray()); - errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray()); + errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray())); addrs = _ipAddressDao.lockRows(sc, filter, true); } } @@ -852,6 +855,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage public PublicIp assignDedicateIpAddress(Account owner, final Long guestNtwkId, final Long vpcId, final long dcId, final boolean isSourceNat) throws ConcurrentOperationException, InsufficientAddressCapacityException { + if (owner == null) { + s_logger.error("No account to assign an ip to."); + return null; + } + final long ownerId = owner.getId(); PublicIp ip = null; @@ -883,13 +891,11 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage return ip; } finally { - if (owner != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Releasing lock account " + ownerId); - } - - _accountDao.releaseFromLockTable(ownerId); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Releasing lock account " + ownerId); } + _accountDao.releaseFromLockTable(ownerId); + if (ip == null) { s_logger.error("Unable to get source nat ip address for account " + ownerId); } @@ -1218,7 +1224,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage s_logger.debug("Associating ip " + ipToAssoc + " to network " + network); - IPAddressVO ip = _ipAddressDao.findById(ipId); + IPAddressVO ip = ipToAssoc; //_ipAddressDao.findById(ipId); //update ip address with networkId ip.setAssociatedWithNetworkId(networkId); ip.setSourceNat(isSourceNat); @@ -1235,18 +1241,16 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage return ip; } finally { if (!success && releaseOnFailure) { - if (ip != null) { - try { - s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip); - _ipAddressDao.markAsUnavailable(ip.getId()); - if (!applyIpAssociations(network, true)) { - // if fail to apply ip assciations again, unassign ip address without updating resource - // count and generating usage event as there is no need to keep it in the db - _ipAddressDao.unassignIpAddress(ip.getId()); - } - } catch (Exception e) { - s_logger.warn("Unable to disassociate ip address for recovery", e); + try { + s_logger.warn("Failed to associate ip address, so releasing ip from the database " + ip); + _ipAddressDao.markAsUnavailable(ip.getId()); + if (!applyIpAssociations(network, true)) { + // if fail to apply ip assciations again, unassign ip address without updating resource + // count and generating usage event as there is no need to keep it in the db + _ipAddressDao.unassignIpAddress(ip.getId()); } + } catch (Exception e) { + s_logger.warn("Unable to disassociate ip address for recovery", e); } } } @@ -1327,7 +1331,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage PublicIp publicIp = PublicIp.createFromAddrAndVlan(ipToAssoc, _vlanDao.findById(ipToAssoc.getVlanId())); ipList.add(publicIp); Map> ipToServices = _networkModel.getIpToServices(ipList, false, true); - if (ipToServices != null & !ipToServices.isEmpty()) { + if (ipToServices != null && !ipToServices.isEmpty()) { Set services = ipToServices.get(publicIp); if (services != null && !services.isEmpty()) { throw new InvalidParameterValueException("IP " + ipToAssoc + " has services and rules associated in the network " + networkId); @@ -1368,7 +1372,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage PublicIp publicIp = PublicIp.createFromAddrAndVlan(ip, _vlanDao.findById(ip.getVlanId())); ipList.add(publicIp); Map> ipToServices = _networkModel.getIpToServices(ipList, false, true); - if (ipToServices != null & !ipToServices.isEmpty()) { + if (ipToServices != null && !ipToServices.isEmpty()) { Set ipServices = ipToServices.get(publicIp); if (ipServices != null && !ipServices.isEmpty()) { return false; @@ -1671,14 +1675,14 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public boolean applyStaticNats(List staticNats, boolean continueOnError, boolean forRevoke) throws ResourceUnavailableException { - Network network = _networksDao.findById(staticNats.get(0).getNetworkId()); - boolean success = true; - if (staticNats == null || staticNats.size() == 0) { s_logger.debug("There are no static nat rules for the network elements"); return true; } + Network network = _networksDao.findById(staticNats.get(0).getNetworkId()); + boolean success = true; + // get the list of public ip's owned by the network List userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null); List publicIps = new ArrayList(); diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index 52a08e1480e..68807d38939 100755 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -1017,14 +1017,14 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { List map = _ntwkOfferingSrvcDao.listByNetworkOfferingId(networkOfferingId); for (NetworkOfferingServiceMapVO instance : map) { - String service = instance.getService(); + Service service = Network.Service.getService(instance.getService()); Set providers; providers = serviceProviderMap.get(service); if (providers == null) { providers = new HashSet(); } providers.add(Provider.getProvider(instance.getProvider())); - serviceProviderMap.put(Service.getService(service), providers); + serviceProviderMap.put(service, providers); } return serviceProviderMap; @@ -1533,6 +1533,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { @Override public void checkNetworkPermissions(Account owner, Network network) { + if (network == null) { + throw new CloudRuntimeException("no network to check permissions for."); + } // Perform account permission check if (network.getGuestType() != Network.GuestType.Shared || (network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Account)) { AccountVO networkOwner = _accountDao.findById(network.getAccountId()); diff --git a/server/src/com/cloud/network/guru/ControlNetworkGuru.java b/server/src/com/cloud/network/guru/ControlNetworkGuru.java index a6e21801586..13ff385da90 100755 --- a/server/src/com/cloud/network/guru/ControlNetworkGuru.java +++ b/server/src/com/cloud/network/guru/ControlNetworkGuru.java @@ -224,12 +224,12 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu Map dbParams = _configDao.getConfiguration(params); - _cidr = dbParams.get(Config.ControlCidr); + _cidr = dbParams.get(Config.ControlCidr.toString()); if (_cidr == null) { _cidr = "169.254.0.0/16"; } - _gateway = dbParams.get(Config.ControlGateway); + _gateway = dbParams.get(Config.ControlGateway.toString()); if (_gateway == null) { _gateway = NetUtils.getLinkLocalGateway(); } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 2face90a7a4..51e476f4ee6 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -424,14 +424,14 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis List map = _vpcOffSvcMapDao.listByVpcOffId(vpcOffId); for (VpcOfferingServiceMapVO instance : map) { - String service = instance.getService(); + Service service = Service.getService(instance.getService()); Set providers; providers = serviceProviderMap.get(service); if (providers == null) { providers = new HashSet(); } providers.add(Provider.getProvider(instance.getProvider())); - serviceProviderMap.put(Service.getService(service), providers); + serviceProviderMap.put(service, providers); } return serviceProviderMap; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index ac641a2010c..56232d27609 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -425,7 +425,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (isISO) { desc = Upload.Type.ISO.toString(); } - eventId = eventId == null ? 0 : eventId; + eventId = (eventId == null ? 0 : eventId); if (!_accountMgr.isRootAdmin(caller.getType()) && _disableExtraction) { throw new PermissionDeniedException("Extraction has been disabled by admin"); @@ -1785,7 +1785,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } // Don't allow to modify system template - if (id == Long.valueOf(1)) { + if (Long.valueOf(1).equals(id)) { InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id"); ex.addProxyObject(String.valueOf(id), "templateId"); throw ex; From 9edeb24f3fc64bc5dd42f466fd65025884cee63a Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 16:36:27 +0100 Subject: [PATCH 068/126] findbugs: assign result of string manipulations(cherry picked from commit 20127e09dc0e341a2f790a8a52cded4c5f1f0cc1) --- .../security/SecurityGroupManagerImpl.java | 7 +++-- server/src/com/cloud/test/IPRangeConfig.java | 29 ++----------------- 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java index cd684407c2e..d5f9405bf59 100755 --- a/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java +++ b/server/src/com/cloud/network/security/SecurityGroupManagerImpl.java @@ -40,6 +40,9 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.log4j.Logger; + import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupEgressCmd; import org.apache.cloudstack.api.command.user.securitygroup.AuthorizeSecurityGroupIngressCmd; import org.apache.cloudstack.api.command.user.securitygroup.CreateSecurityGroupCmd; @@ -51,8 +54,6 @@ import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationSe import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.utils.identity.ManagementServerNode; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.NetworkRulesSystemVmCommand; @@ -373,7 +374,7 @@ public class SecurityGroupManagerImpl extends ManagerBase implements SecurityGro protected String generateRulesetSignature(Map> ingress, Map> egress) { String ruleset = ingress.toString(); - ruleset.concat(egress.toString()); + ruleset = ruleset.concat(egress.toString()); return DigestUtils.md5Hex(ruleset); } diff --git a/server/src/com/cloud/test/IPRangeConfig.java b/server/src/com/cloud/test/IPRangeConfig.java index f4619955f4f..1d564714087 100755 --- a/server/src/com/cloud/test/IPRangeConfig.java +++ b/server/src/com/cloud/test/IPRangeConfig.java @@ -69,7 +69,7 @@ public class IPRangeConfig { long zoneId = PodZoneConfig.getZoneId(zone); result = changeRange(op, "public", -1, zoneId, startIP, endIP, null, -1); - result.replaceAll("
", "/n"); + result = result.replaceAll("
", "/n"); System.out.println(result); } else if (type.equals("private")) { if (args.length != 5 && args.length != 6) { @@ -92,7 +92,7 @@ public class IPRangeConfig { long podId = PodZoneConfig.getPodId(pod, zone); long zoneId = PodZoneConfig.getZoneId(zone); result = changeRange(op, "private", podId, zoneId, startIP, endIP, null, -1); - result.replaceAll("
", "/n"); + result = result.replaceAll("
", "/n"); System.out.println(result); } else { printError(usage()); @@ -569,31 +569,6 @@ public class IPRangeConfig { "Unable to start DB connection to read guest cidr network. Please contact Cloud Support."); } -// public static String getGuestIpNetwork() { -// return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`configuration` WHERE name = \"guest.ip.network\"", "value", -// "Unable to start DB connection to read guest IP network. Please contact Cloud Support."); -// } -// -// public static String getGuestNetmask() { -// return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`configuration` WHERE name = \"guest.netmask\"", "value", -// "Unable to start DB connection to read guest netmask. Please contact Cloud Support."); -// } - -// public static String getGuestSubnet() { -// String guestIpNetwork = getGuestIpNetwork(); -// String guestNetmask = getGuestNetmask(); -// -// if (guestIpNetwork == null || guestIpNetwork.isEmpty()) printError("Please enter a valid guest IP network address."); -// if (guestNetmask == null || guestNetmask.isEmpty()) printError("Please enter a valid guest IP network netmask"); -// -// return NetUtils.getSubNet(guestIpNetwork, guestNetmask); -// } - -// public static long getGuestCidrSize() { -// String guestNetmask = getGuestNetmask(); -// return NetUtils.getCidrSize(guestNetmask); -// } - public static boolean validCIDR(final String cidr) { if (cidr == null || cidr.isEmpty()) { return false; From 5d8e8fd3a2e8ffe9a2147129a9715a29cb4ce064 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 16:46:05 +0100 Subject: [PATCH 069/126] findbugs: nullpointer guards and wrappertype comparisons(cherry picked from commit 791b7f8f7fe8f7d342e46fbb61a3f421e87fca59) --- .../cloud/resourcelimit/ResourceLimitManagerImpl.java | 2 +- server/src/com/cloud/storage/VolumeApiServiceImpl.java | 4 ++-- server/src/com/cloud/vm/UserVmManagerImpl.java | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 3a7251b2095..13c3051d861 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -877,7 +877,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim } _resourceCountDao.setResourceCount(accountId, ResourceOwnerType.Account, type, (newCount == null) ? 0 : newCount.longValue()); - if (oldCount != newCount) { + if (!Long.valueOf(oldCount).equals(newCount)) { s_logger.info("Discrepency in the resource count " + "(original count=" + oldCount + " correct count = " + newCount + ") for type " + type + " for account ID " + accountId + " is fixed during resource count recalculation."); } diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index a79d8b4c217..55582c6421d 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -449,8 +449,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic volume.setPoolId(null); volume.setDataCenterId(zoneId); volume.setPodId(null); - volume.setAccountId(owner.getAccountId()); - volume.setDomainId(owner.getDomainId()); + volume.setAccountId((owner == null) ? null : owner.getAccountId()); + volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); volume.setDiskOfferingId(diskOfferingId); // volume.setSize(size); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 85f35275933..1dcaf798a5d 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -34,6 +34,9 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -79,8 +82,6 @@ import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.to.TemplateObjectTO; -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -458,7 +459,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir protected boolean _dailyOrHourly = false; private int capacityReleaseInterval; - protected String _name; protected String _instance; protected String _zone; protected boolean _instanceNameFlag; @@ -4004,13 +4004,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir //if hosts are dedicated to different account/domains, raise an alert if (srcExplDedicated && destExplDedicated) { - if ((accountOfDedicatedHost(srcHost) != null) && (accountOfDedicatedHost(srcHost) != accountOfDedicatedHost(destHost))) { + if (!((accountOfDedicatedHost(srcHost) == null) || (accountOfDedicatedHost(srcHost).equals(accountOfDedicatedHost(destHost))))) { String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(srcHost) + " to host " + destHost.getName() + " explicitly dedicated to account " + accountOfDedicatedHost(destHost); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); s_logger.warn(msg); } - if ((domainOfDedicatedHost(srcHost) != null) && (domainOfDedicatedHost(srcHost) != domainOfDedicatedHost(destHost))) { + if (!((domainOfDedicatedHost(srcHost) == null) || (domainOfDedicatedHost(srcHost).equals(domainOfDedicatedHost(destHost))))) { String msg = "VM is being migrated from host " + srcHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(srcHost) + " to host " + destHost.getName() + " explicitly dedicated to domain " + domainOfDedicatedHost(destHost); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_USERVM, vm.getDataCenterId(), vm.getPodIdToDeployIn(), msg, msg); From be21822cbaca8bf0597781018cfe844252e6ed73 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 17:39:02 +0100 Subject: [PATCH 070/126] findbugs: throw exceptions when found(cherry picked from commit 9772693dca9a91a438078de11b1be1e6044aa6f3) --- server/src/com/cloud/projects/ProjectManagerImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 5e7d9a96617..5a0ed1cf64c 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -624,6 +624,7 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager { domainUuid = domain.getUuid(); } ex.addProxyObject(domainUuid, "domainId"); + throw ex; } //verify permissions From 53777c9523aad0c4544811194f8fe44b7e9958d4 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 17:42:17 +0100 Subject: [PATCH 071/126] findbugs: removed obfuscating fields(cherry picked from commit 9495c68c1378e379880433d45ec43bfda75ec3f9) --- .../com/cloud/network/ExternalIpAddressAllocator.java | 9 ++++----- .../src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/server/src/com/cloud/network/ExternalIpAddressAllocator.java b/server/src/com/cloud/network/ExternalIpAddressAllocator.java index 2b84231c050..3cf358067ee 100644 --- a/server/src/com/cloud/network/ExternalIpAddressAllocator.java +++ b/server/src/com/cloud/network/ExternalIpAddressAllocator.java @@ -40,7 +40,6 @@ import com.cloud.utils.exception.CloudRuntimeException; @Local(value = IpAddrAllocator.class) public class ExternalIpAddressAllocator extends AdapterBase implements IpAddrAllocator { private static final Logger s_logger = Logger.getLogger(ExternalIpAddressAllocator.class); - String _name; @Inject ConfigurationDao _configDao = null; @Inject @@ -52,10 +51,10 @@ public class ExternalIpAddressAllocator extends AdapterBase implements IpAddrAll @Override public IpAddr getPrivateIpAddress(String macAddr, long dcId, long podId) { - if (_externalIpAllocatorUrl == null || this._externalIpAllocatorUrl.equalsIgnoreCase("")) { + if (_externalIpAllocatorUrl == null || _externalIpAllocatorUrl.equalsIgnoreCase("")) { return new IpAddr(); } - String urlString = this._externalIpAllocatorUrl + "?command=getIpAddr&mac=" + macAddr + "&dc=" + dcId + "&pod=" + podId; + String urlString = _externalIpAllocatorUrl + "?command=getIpAddr&mac=" + macAddr + "&dc=" + dcId + "&pod=" + podId; s_logger.debug("getIP:" + urlString); BufferedReader in = null; @@ -101,11 +100,11 @@ public class ExternalIpAddressAllocator extends AdapterBase implements IpAddrAll @Override public boolean releasePrivateIpAddress(String ip, long dcId, long podId) { /*TODO: call API to release the ip address from external DHCP server*/ - if (_externalIpAllocatorUrl == null || this._externalIpAllocatorUrl.equalsIgnoreCase("")) { + if (_externalIpAllocatorUrl == null || _externalIpAllocatorUrl.equalsIgnoreCase("")) { return false; } - String urlString = this._externalIpAllocatorUrl + "?command=releaseIpAddr&ip=" + ip + "&dc=" + dcId + "&pod=" + podId; + String urlString = _externalIpAllocatorUrl + "?command=releaseIpAddr&ip=" + ip + "&dc=" + dcId + "&pod=" + podId; s_logger.debug("releaseIP:" + urlString); BufferedReader in = null; diff --git a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java index 1e3926dfb39..78652a22aee 100644 --- a/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java +++ b/server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java @@ -105,7 +105,6 @@ public class VMSnapshotManagerImpl extends ManagerBase implements VMSnapshotMana public static final String VM_WORK_JOB_HANDLER = VMSnapshotManagerImpl.class.getSimpleName(); - String _name; @Inject VMInstanceDao _vmInstanceDao; @Inject VMSnapshotDao _vmSnapshotDao; From 29e22384b7e758d12f72dab9cb05d53ed297e147 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Tue, 28 Jan 2014 10:38:30 -0700 Subject: [PATCH 072/126] fix checkstyle in DedicatedResourceVO.java, trailing space --- server/src/com/cloud/dc/DedicatedResourceVO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/dc/DedicatedResourceVO.java b/server/src/com/cloud/dc/DedicatedResourceVO.java index 41bdfec2c05..e7d7b3b282c 100644 --- a/server/src/com/cloud/dc/DedicatedResourceVO.java +++ b/server/src/com/cloud/dc/DedicatedResourceVO.java @@ -30,7 +30,7 @@ import javax.persistence.Table; public class DedicatedResourceVO implements DedicatedResources { /** - * + * */ private static final long serialVersionUID = -6659510127145101917L; From 1530c162e58abd8e572a89d2a2706de00bd49e26 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Tue, 28 Jan 2014 10:44:44 -0700 Subject: [PATCH 073/126] CLOUDSTACK-5968 create vm.memballoon.disable agent parameter --- agent/conf/agent.properties | 4 ++++ .../hypervisor/kvm/resource/LibvirtComputingResource.java | 8 +++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/agent/conf/agent.properties b/agent/conf/agent.properties index 5f5f3682afd..a7376b68947 100644 --- a/agent/conf/agent.properties +++ b/agent/conf/agent.properties @@ -114,3 +114,7 @@ domr.scripts.dir=scripts/network/domr/kvm # for examples:"Conroe" "Penryn", "Nehalem", "Westmere", "pentiumpro" and so # on,run virsh capabilities for more details. # guest.cpu.model= +# +# vm.memballoon.disable=true +# Disable memory ballooning on vm guests for overcommit, by default overcommit +# feature enables balloon and sets currentMemory to a minimum value. 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 1ea0989ee71..fd0078c6970 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 @@ -424,6 +424,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private boolean _canBridgeFirewall; protected String _localStoragePath; protected String _localStorageUUID; + protected boolean _noMemBalloon = false; protected String _guestCpuMode; protected String _guestCpuModel; private final Map _pifs = new HashMap(); @@ -771,6 +772,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv value = (String)params.get("cmds.timeout"); _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000; + value = (String) params.get("vm.memballoon.disable"); + if (Boolean.parseBoolean(value)) { + _noMemBalloon = true; + } + value = (String)params.get("host.reserved.mem.mb"); _dom0MinMem = NumbersUtil.parseInt(value, 0) * 1024 * 1024; @@ -3426,7 +3432,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv GuestResourceDef grd = new GuestResourceDef(); - if (vmTO.getMinRam() != vmTO.getMaxRam()) { + if (vmTO.getMinRam() != vmTO.getMaxRam() && !_noMemBalloon) { grd.setMemBalloning(true); grd.setCurrentMem(vmTO.getMinRam() / 1024); grd.setMemorySize(vmTO.getMaxRam() / 1024); From 0c28b66362f335ae7323f327cb2e175ee47cbb94 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 28 Jan 2014 10:25:17 -0800 Subject: [PATCH 074/126] Update socket icon --- ui/images/infrastructure-icons.png | Bin 62257 -> 62059 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ui/images/infrastructure-icons.png b/ui/images/infrastructure-icons.png index 5d35a8ed493e5ac740ec8a1cb668b0f6b31985b8..a589fc42dc2f9828358b85d9d690b4eb87581c9a 100644 GIT binary patch delta 8834 zcma)gcT`hZ_qH=SI#vdeB1M!IA<}yn2x>x6dI?2(3B9*)$5EOzNhm@nLkWn~009CL zR60n9&_TKo2)&p5;=J#y^{(%)?~j{xZ`MBN?EUQLJm>6Od*(0y^NrrSs_?&`^4CW0i%CmKOUQ_*%g9JbiHfR=t3ag0R3x8Bib_a7 zQJ0bwMO|g8q+ZJuy_CQ%WsJ^N5c(CbSlO>|Hx76>q!UiO&Tl>^om@&2L~I++z)n66nZxT zD1>D|np4JOEu3KN*1704AuvqTB5u@YE@!artOZUNg~QTI-pOcDONm-rJ2e$Z z;)%1_LQ;oBq6gblYfMY@ipG4DKFO080crQSo<@@c?Z%Ad4YQ1O%6FgEocdBka{QS`{P4>$TL$reH%aS*Fq5m zeoAe2jjLBmF71z8=gr8Nkl$F`={5z&kt$Wb1Ivxn5zCW|tn8J6rJA$;5#qk2zndGyXmIF^aK5#tTc}Sg3cQ)o z+u!r4o|3dB=ievaI}@nM@4Gsudr&btwOp~-dq#T29elp>6tZyG=^!+1ot<6pjfFG^ zZhpB^X?Z-55`M5YRvGB!<<}Nc43w4a@2$5lZIh8R2XZz9`J$rqLhj8Vqg&4l@Ju$} z3a{q8e*JpCJ%PLP0Lg#nT7h4ZBJ$BOL9=INvD3kSd41PPAVb@Ly{*jIeK~gNgy?H- z#Kgp;PcT#3vqwm3olCyGkWY_ zlU|lIDoIJ{Hd;3wW4E?&OUHZUulIkqrjJ_P3o?Dg#BE~nL@>E#$<^m4_F+hXQ1J=u z4~6`dR356*Dmm0Dr3^1I>}6q3>&|B%+sT021y(PItv16=?xBX564XuZ*`xk2?ALJo z5ke7q^r(Guax&3Lhyakf^}CQr8m`TapXHwd(pGQ!JYJR76@M9-H1X@2^lank;P9X9 zzmt$#@4s=rzpP9>N+<(tMoPp78Q>FzlP?64YL19A%Rv_TCj#VDDLXkhsK`4ES1Ayy z3zLoG#+$AWneI3Qsb!KE(kr!s6ep+}D2Tm%z8d{v3JeSA6%G671|M98XLvRg_@8Q9 zW*1ZjX`^`fpmRLeav_P|_!FF-lF_dUo?p7_p5JI_{J~H_{34!6uvTi+7ffNQacc-V zPeW7-E$tjVM0fC9ym&FAM>l9ZE8qB0S`sxBoYnWieU*)Q|BSI~dw8GJDf`0wL!XGe z=z|Qa7X@&D(DcXKb|}4*+4o+wEpKst;)R|<^kL^@)~lZ1Fg*iP-yYnTC?+ucsVjgZ z<-=>-VngSpLv5Uvx#QVSzA_Wb&ySX~fFQ5!<_W%7q9mrv+~nb%2rokVgvoFD!E3}8Fv0Il4>s2)XqmE$|6V`xhDHZi%U7VuTaV$qKQ(HjW1$mojr&n@LsUoQ z50(rri!m|DdML&3>Y@uk-xz zR^gtFjW>BDUT}ZUV8Y1U*P!0Cq!kRxrd2)} z{ny8Rso836WwH{YM{!|C-zF*ulgX;t@Ar^YgC;@kVB&~RskUVhF4$|4EVzF7gaa?G zctA+!>5S)FI!1Sj4pVir_OYGcBG*{@AJ!pidfcYG_6ELxf1KE1iy{zY z;X*07WATt+5~+jo+F&XM~ogNr_DZnkONsLCDCGFl(et1p%9Z z^d`r<1Z(+A0uLtp3+!kdXe_36Tl_C6-5F;@wWh(J`U} zE>d(H69;R-VX`-wSH#-K0dW?3QPQ~2a!*EoPlh~m8$Y8uE2cD8(y-5>M zdpE!8DMzXN@GEYB0$5gX@G`_t8*KYZ#7@>z$?pzvGw6l4^ns)fvJ+&X6HJ zfjt+CIA&Gf3Kv{BeuByQtIwl)vro~7pK!K6f#LEB0IaNL6J}1kXC@EVDuvDb51TvS z+ES|{PQsP4S;99KcLK{Q`Oe5CSKVW96yEybHz|)qNk`sxn)|4%j-f$` z47#RrokvV4zuZu>37_i3u5WG@%08#dp~s+1^A&w8tZ>K_^Y+;(xN#dC0a{8sL;JMKL4yvw|)wbW_h{jr9X+ zv53p=>4B`!$Sl->|6@+3b6=Bp!oEJn>L!FJ zQ9lkF#)#_D?heq~;?mLu5#ix^Q*Ih})XVCDs3CF#WpE_KlA?h1ybXe~w-w^@?Q|>i z5+BLH_+H1zC-nX{7^XVA@YvGVE5s)t$kw*_TwHnY3mR`~=`cp@*$%pCG9A;BN!q6* zsR|tp8e+DHyP^E32_njeh>@H*){f(R{e6uK_gPHtXKFU-ut#l`3FGb0;`(^6VW zPFYN$NI#9Gvl;4+tVw2@ zNc}cQ<0dV{iKHA#5jrlimQLyL`X?P9)$PDVLR})qjS}|6< z;3W$$8!=GIQkH~PR?1U4J+5Q&3!~=8-Yby8&5s89ld2b_cFTW@M)E{Aj7rn_}3ys4=vBPy-zZp73Iq-1!O$)`>zZ}xD91GZ!V!c`zDU2d@awv{R{~E(h<~=$%li`P2Ynvlx00FYmkSFr zJEsGeGv-eYHX4@>w^rCv<`#mB_p9sg0s${Qo?)Fr}^=TGkCLNAH=vlTGdY4Q)z(h`Gts)iSr+{{3^uIdS#t_m=>&Dcn~>-fzt@CNA#D zb}O5zIcfG!?UB`w0PPy~+l4>-JkI4WXDqDubax*$?!g=JrBk;~M#^SbECUzwN!70K zRW@n282e$;WHeyWQ6YD7D7MXx{Urj7L69!WI#V2 zzg)Sw_3#(;{ZSS)Y%~ENarp~=YTpPxh}S56k*He81!a#CeUhlF$brd+0$8bCTjC1} z1AS^%>M8l53+EcA#Q_2aj>_%RZVXw-AgCVA7&xm@O(A*1#hh7+fpeCLC*kK+FFv}! zWhv2Cqd`tD1Ev5&Q;pkUV&Z|Prr5pK@xH?p_7O&OzL=!v0x;rzv|SHN8mBX+cY4%A zNy`X2is(eXwtQrCCDa&_H)d>RmX4`YK`h&rHD1If1z0>`T3*h>>8G^aJLVd`P7733 zP1+_V5o~Z5-UuCE&u6iLEUbO`lIHVaRQl6{cACEDDai-g+zw*{zb3!UfegqbI^*jU zjfyScA8y?N)FEG=AQ1pSm24URvG0xl< zl;pt3$U*6SOQMny1^hO$ipim-m+l6v(ETtx1WO7$w??{oJw_l&eJ|A^2tgGoP#YcR zJHm>S&X6F@(cf>D2Cj`SiiVQoI+jw z70?;a_M*|{v7=1M$)j=4mK`xKkKXInu?btT80?hWTSX0za#AF|n!K@Z04VR+>`TV) z`Ay!vSGn(-WvMN{kGFzGbJ{Nc_=5CuoN?Padt60++f1MIPhy(x22pd&jY1gPXOZ>l z5ZjP>`>PXLqI`^m;>+vC{p0k??LY@k?PP)G%iNV$j%|vFJ{nFJdTQ|aAQXO1rquRy z@w>-vpT*YeV#oFN?H|-Gei7PY*$rK4sME*nzh0zS3(@C%ePCMeIfuKPD;n%0cJs8EqYs4~Ay{*s-<>xwe=M3w?*?J~?PlI16s+U4qCX zJU^fq*Jb7$yuECx7P1vU{Gp0Ad)wlzpRWCWbH>%9Z#+TsT@v>dT6uUT49ypBvnuha zuAeBU^2&O>1bPdl{$Qb*mb2C(8n1$lR*e37jW?8X8RxPZWkT~6DT~OI9){kJIB2X= z_$FXXfUCZwS$`JD7LGO?HA;S{803+~u2e4eYSg@;DOir7?(9A|g6OP@`#>q_7+F?IwG2ETVu8l?6X#1c z7p6ff?~)cda<1N>t$JU=>;(+bVeehB+ybD?q~2ks&-be`WO61SL!uHZb%ZqF zA+I&+nE)}v|F!knC0-pEPlv;6;$NA2+mcTmD!90GJLR4X)Xp+FbLBMi;O>0#`QqE4 zUiN|k%Yoxdg5AFfLNl*3L--S{N!}j=1yyh}GNC$&x1rI2o)H53DJL_-YQLffq%;%@+ddO};vnFLN2kP7q9@5^O2thJO|6|t*1SD+tMYNV%kb+F zSqxZJ*I2!+sb#d!`9Tw543wBWM4!rk+>`k*{kWyps#P6gXTDdQyQhgbZ{L9xJ~JVY zEq(oK@6&QiRj5JY+h)_U_x(Ut>+EYC#IZA&D|1xM3i0JYYN@-&C^^_n8*=?`J58g8;iQ43}N{LHzeK|zgCVeobW>Xw2u(kbzu2^A` zYjh+_(Oc5n5#Mx4Lvz5YM2lVUseC;4i8Ble2Rjuj7?B<+Q$0)avN=E#W*?t-_h?S* zv@@5nv6@rM=Yw8}@=*$1<1p}#y^6pHCvwiPlbHrAb5mOFpvT@mW=7|s0S|Oe^*IM( z@mX54n23ZzW^4Z-cD()MbqI7oLTQAvp|ovdqOa-T#@k34AP%%{Z@wxHg2+zi!>FT? z^Fh`w?$WGgBWP^PQH@^RKTPsT#aJflC-Qi@XM|#_XsSmzYLUQr@^Cj+e9 z8TzzSoF)kz&lUU+>5A~@vC#BgK+41z!4bah=(gHiT2wl{J@m}gS90(`F*Vgido5@- z40HJjiCVqkfE=73&3?EFbd9^i&bz~PsvhR zLf4JDWHmt?pK7vpo$kKT<3F5}>G|j!KQD6|6s4KgnH}~s z?{C6|ln>Aw4Ir2u1bj7EUX`DoOqQ6W_RT0KyGp=y_bZF?6*Xe>cMl9IluxoVg1>ML}J^?-)b8+Pi~th+-AD*_+?pfIKq-c}@;yTwa&a9&%In z78hukYrkQP5JGL>}-In$8r~#-$rREdPYV$PNmJ)Gt7w+*?1Uy6S zH)<#+g9v_0T8L&h5Odm1_0u~<#7+w;&vR}s@l6#?n#WpFqqh7i&wc8rn3Ro-CD&=y zy>2^mj{nTotJuZyXX^FKQuK8?mY>3Z?&AyD*dk~&f09zzmwuIX zJ!Zw1tBNe#(@P0nJMaAz@sqNjTgv$;5^Es`Co}M$IuQh52LDdtc4F~a5>Dq_-&_X{6FbG%c3&uE`KRb>x=Rauxb zWaCMw{K7}w!g-xt(SDPeAXWKHkVbTL^1tv4j<{o_I@dP>OUnniNY4gVEk_#whcbxg zBa8B&aRznVLdC0~6D_zyF^1VDDRNhi&NNypNA_Qy8_`|4=xP0HiT=?1gH9ImqF3&^ z4M^KevOe)yC?g&e!>}T}B<(&UaTeyRkD= z?hXEA0i!&paoQ#T7OUYUe)UtQbAmPNYiwg4!=fhY4B0I_UUQq%TOi`m@JdMbE`y3x zig;^t1INatSZs^hb0sfo%KvavK6DdlDP(|9bf@IwxuNWxYaKR&rOTnRQ8u1u!-GRS zaV1nhT;wVuD4V;wyhv(sf~(s)%~wNLv_)Jr%~^#YU1#^TvA%R zT7xloFkSJJ&N>~`TQRPNTMXWsT%M?E z0woO(og?;I0wt>`unA?c@{i-_ZhO1c=C1v+jbnJ>{@$`!sFZ`&_+aOYanEfUjvevm zLqNPv11Wj`hyy}Wd>irRk@jRzzcmFEll zas9~wVb35f4I96&{|IR{|NFm^sq2*n*!eC+BvuS6`W7ekWiZk|D`JAc~_L^Hl#ft=>s)b=lWAv+z+%0s}2vJ6w3&hs;%go7h&J-~i@RPy3$ zwHb==e%Z(UODa$D?b-HDh}8#6v$)t9%+-p!Xg)=Jx373msGsu>8)b0gv!j2GkaFv@ z{2~NFRb@b?zagYi*E9y&po@EP6&@=Az3pk(pH>7-kK8y}8HSe?F&4ePTf%`O?G8x+ zw1ddFboXC4WJN_87p}QN(Rl?MMzClogGqXZPfPQF7}0k8$$yl41YK^Df+d)EPVt)4 zB{{aOBcD3Kyni0)BD{`rphYBm^GUq4&yCIa&=nY zjnXAT2d~lt;GD#HM~4Qy-H**IiI=lRS|XUUOC>cGtH;xZI3f1d@QDYckOg~Ea;GqOOD=d@ZLnS0f{~T zXRbVOABL;hSB~yPXdNAHAYmUD2VS)Hx|DPAT>~b1Q-`WvySPQ@cIG>cUz_Nr)y6l) zLd(r*#a$Gr$uHnrm+fWoyFddYScgT)eV~f*(ijH}G2tTB^vZOvg;wFY;c$vq_Arhv)VP^#KW4V?kzzC1$4R@vUkB`lz|XW>w_Yp)mDpV~Xax+-o$y%0Ci- z6z_S;>6+s9l`KN=6nc+wq9YPo&QOBAMot^Xh?aA>B)jkK%`4 z_0vU1N~AC?*@NPV^=52G7;9{`3dELng?X)0zc=vtN4Vv{ctZIUDlC-&lQ@6@pXJg8 z-?c>XBos14C}o0^XACH8pG=CAj=uumcJ{_P$lHtK7Z-`M8w|V^RWhJ@%K$eU0qsPP7 zMOBbj^@7hk zccfc*pt|jsw@-lc8tdXDe}LMp&rNf|kQYgi{PEL?=VvWbVhS&kT)sz(+8YqHZDJNG zh&Sl;7xe(o8imtt^Z(dmyH>TE)MgHW?Fb+ch`+IK#7lN)em|_(F~I^hnMwI_{xM{= z(mxt+IK6YR=0y^14Pyf#jQmZykTcJt1qVv zqEOcPDN;;KAAP^_ID)6a%|pcSS7mN)HOZs--YF32?I&u)v`QF_2j5ZfL4Q`tS!c~c zyt04R4Z5M`-r@%N8)a8-k=|x?v~Pa)@~Axk&*Z57Bgg@jl)yvW;%5ApwnHkBqawe=5@pIiYIV`Sg+tb~`& z$2B{d(v+DoA>qq7YQAE8~TZ7bHI8o4+^xDO6t<8Q^&N;7h?sMOpOXn(9&Lt}U@~@m)PuF)x^7rO(&RZBN2CR3*>W7+|>7Zo~t6XpH*a z;U0|CR82;Qbs{}pH(vR^#B)`I?PA86S875+BFe2oP~mGbU6(R@-;@dQ$Qa#%U-JHW zsjKU|4BL0dn{TZ>zWq}nF`=0%0olD>QthYT6lgi#L=Ia`CnotA?DO<*zEEfh5*~I;PGq#sbktyWm;l8G&K&`S6F?33n4c5GKIPt(N{%4KM4`J zQ0cOM_uErqEdhanVusH-V%xD^oXp3XxZd90K9}L}Juh6^sfYa!LW}jPUJHRxi|Y^I zR3bF5`S3*hV$0^|Uu|w~W~gl1mX8~6R3waAa7t1}ClVT7Z`^qo%vC7g5(vpg+VvD%FdO1z6-4mch1KXCQpyL<( zX>#K3ALjn)C)YYw0EbB?Thwy!I6A9#2nw$JQ074^2Np!ohZ?h#vD$^Cq$Ki6@X5`d zF;5c+goNQ99|-67Ola85yip!@p{a>_5ayx~=vxA{+3Lqtt{l^P(Z&2nJNwB8HF&5` zd}LJrLbs51Ej|Q%l={NUdjF?jg01)5w|V4~=Yh@+z$sw9tmm&)VP!BGhMmG7d5~;M zctl%dCUh5%V_~zaaMTW>tQVuK#7ixZeJIg}uTqqfOa00S*_^EQsqbE*gnUuM;o#1x z@H~2A*g7jZIy%aVi(QHB3i9&)L&v|u9|cTn!t9Ub3{wi-)p{^m!Yu7Z$Kd6KYnx+b z;f^nXTu7a*WMA2JD}{;x!bS|2=k$H7*UaQP%gr%ds$QX)>1#*F+oX*R&==)6n^NeW z%mYHkL0o%SSUU*aJtI*v!n7GXRQ~EE;lk80g%W>*r>MAi|F__jJ$l6r*Dkv7Hr+0H zBe`RA%O&}Wg^x^L9<^CTL7|8qR{;&R8__`B!1(ZNIUaA%!4f)uc4!8Ud)<_~^`xS{i$7J55QKDa+M5 zq5AG{%=@x~8yyE_axN~<*xg^geCdTgdfjx(*x$Q9=3-O!+H9rxaGq8hCYht5p#fNR zLAn&+da>cd>&q#23kiIN{ z=0{?)-ijqCRxiqOfI24+N z*zm))vZ%PW_G)JZoycLyKUh}t5iv14QC%HxaZkEqrYyxdSjRvqRImkP61Kc76~57) z=BeIzv=A$7S!RX5%g!|M^XJpG^>ueM(UhwFyxOmByUfhRW3&HbZ5n1}#TJ}Qg3AlT zG+3t;=g$;VfGaSsvTJX+u6{r3QNrbk^R5{w!Ma)acJcVBRo0y-2`x5t^q7 z&3NlncSlD}uB?`wrW|T?Lb%1yl8DAp7g2@O2nE^%6SnG42G*9^;rkTlY8%h0h6eEL zL*Vo!1VYZsMx$d`HplqXN!l60V`yu&iQ!?jso~+7Uv)mOVMTHM7$hOT1mnHSJ0B{C?XPgwc-`nm{NwT3G1XwYW;fTi-c!zKG}vI9ICkq zY4lmXW~^EPB24ZdQT8`o(DfVL6+Kcdp-*%IYk#UR6=TnC_-X#dNeZj*{~R{lyu-6$ zU$OHk@8N?=qwmrhp~hd0ejFaw3874&z2`8zucQm53eHdrV)G*gyz{q#feHV6uu-JF zyu^A*MMZ@QZ3{>97(O7dHXoL>zLio@lHYMmW0(A50Tx4!f`+o;v>@nr80oEzCCJES z^cP&B>H+RzZSi$5;JM$GEzZewEjT-&zrWwe-+#1{GV;ToYqxDC<@-FdLfQ23O;S+L zfyJ|w3~N5kpLYsL!8ibx{jo|%hck6UJa=Wkz388Ox(jcvAuW&_M51~V>)f^SYtPiU z)QfkfOU*mZvy6xSFK67N zqg-Xw)Bw~V)!0_joxF2VZnMxaL~MZdj4{Ui;b z(G(kr6rIsVQ_IzILpLQs2nBUkjE|dJbUJjeFDwuryxNha!ru}y`}3DM25XSVqVysD^OEc1UiYDKE)o!hkVc zSRWJf)4h&ON2^-T9XBbD3}|v&jB45(N8hk(0xd6S3ax=rD@;>;YI4x>Z)9|@-Vf%&|3P!@Z zs$%!(Q&9U>sX21;oP5GY^o(SFDkzZoJ-QuoS_PSu;xrU5`O?0r`O)2n3ph7vi2$)(1&F9KYK23{zG)sYj!Im(<hzkVUvi{Vj=A zm1MV+aHtsCRZZZIi%J$6+}iR;cV7R5+nfLC_tjQ(D@IV!T9QNOI0Sb2fV>~~QNJC5 z2KoEWq?-%U(Ow$`IlIi%`^%=;hq!;HGc?>ZewDlbiJO&)El`c?7fw(+u-bpkfBY+!h+U=+%_^Gu_YS70t z<}+vV=6ks=5|(%qK73%;IBaD_myf%qdH(u(Pwn(%&qWezwX_gJ4|HE@&vKbLk29}g z`L!}mm?UmVb8vr}UN(vZt~38|g}Mb@R-*UDj&zOc&l*qW{mlNlFwp$hAN4#T#1ZLg zLG5d9vuDoyGjN9f%w;YGF=1Ls>VLr>k}ksMehtILwqt>BduEO70lWFg^6CPUAgJx# zrhe=fCznWE3C^sS5TMyHI(q>d#fCZcP*6$Xi`v=QV0)u6aF4Mu15P2uFk? zJl5&`*3yBkNm$@y6|tVhg>AE413`YGBI;pwnttVZ9r`x;7*lb&CdFe)!MMKxI5<2t>TM~}yu zcTpEa?ZSFcCLXDK^SuYX(r^dafw0_`;s=1RZol>MqX-17gMqoVwq6GjJbNyy<%bG{$h^oTZuuy)wj?78a7d`N(7vXKf$RNahpI|P~f#m`7*Y|hx z&AMIEQO420X*Vj+{v`iq_7;&CVv%u^KWCr?SRRX+p!nUjfN>G9xqmRsc|0gCww2fQ zVUJ82toS~ALTzz#@;j-jm6v&dUQy^^@?pOq3ZrXhm zjE%B(13F%`s3zh+b?P16veqz$ z{T<-2D(Z4v=I?;$%W-Rqr`zrF)7a0V^1-MRtd{EgXFo}7wJ~}OAl?8p7KXn zu=){fs>=fJ>UW!?oT;+YIOoLZBKPvFQ>n){DCa&nVNRTQBV_{*Se=|8KU2+ImKG2c{~{VV?oYdtb`8v9>niJACM#P50I zPzx2lV8=l|Xs4j@T3gOxS*C8G5Z5I}_9Q})zCDzI3@`lCJ$o7CpwbL8KZb#XB zpH%)E7!QzBiTYvSY1wSUyl2QdM_T3}wIOgyi}Lf7n%PL!Td=ZDRcO;UQP1cTWkO>s zr*(huu4X1H$hCN1_;6?m2VS9~%wAulx9qTw5!D>o`X0;Rn zJpirH@^pSO<(x5vZ9(vrV>s2T=%ow3*LSrS#(%&MfTsk`kGkIMZqnGG%_W@vKF|Mg z73GJrj?+8`G!Ka^ipkBwO$*$?0b?m7C@L9N~64boihC9`vQw)6ks-bbR zA|juoul<{j&ZjKu?{X81<2D_3l3OOe1}vkJ{Y0|@@?8(-Z9+GUwek|bm^?MwAMdym z2j~=kUA#Gl4qc;IHag8gG^laLQD00FeG30j%XNI{IwP+p^f1D>lRxBe5H;Hb-c;UW zpb+g|><_dhc%>M3W`Mu@{M+PQ$FJUC^u!Cb_g4~F)stt#X3srPl__#)B)W1@lZuO6 z+8C>L|^mMy0Z?m{2uzX6O)YPDG%*ZK)p>dL=6 z);D{I9ugmY;XvNdhE3ZUtD^#^x4n3I)XP+R{Fax~*6dnnmvv3ki$VxMXkoIGPxg1* ztY1cR_%W+F(rl@>lC4s8ZOw<3uKG;gqm9frcb^I2^<)8(o!djpVvG`H^Ru$>HG+95PaN%OsVubS_w=!wuR6lE!B{o3C0F%*(i;% zV~uUg2TH1CF+hy2xv2AKX$tn$dEKkX+JTvAF4?eC9r7AXqfURHQijHE_}T^0Vn>E& z_R9_ynH7QO4#x*%bJWL-VNryWsn?_Isz07-w(Ud)fEbx{qRwWN*xXwO&o)1IDN<}Y zNGYz~so43Ox&fh~n}PAB4Z`{}cIEy3137-B^Sl7~3YIOR9wZ+*x4)`LLkSlb{l;ie zpV!k?0VBne$th#72925u`B&elo^@p~7spvy)W6l{Ez>1X<;7h2xX`~{;AzO7?!{=j zp)e9d;3hAWI85FopeU6Sc2g1Mdh) zF2DiH3Sra({x3F?vA~r-J^YrO_*L2G)uv;HvFzt^BiZHCeb zP!*}$(HbTdR*4f^wr+PhVqN`#hyt{YEc+!E-l3bbJCYpCF-(#90mM)%Sy_KOXdfWo zy_Y%0NS};W?~pYwu?U>!Rr>1S!*lQbZSACt2DP+f4(+7+29PLctZ%>BUG^%-Y;IAJ zaE?#!AEwjO^EUtPP@YzF6^uMA%Fcv4{s&&fqV{`03wIp$?|?CXLGWF!4qvd zYTV*u23Ed-H|H4GJEbM)TMa<(m)dIASN+xo1Xx&Er4U4Qm!gRYYr;%}B_4)A^!kmk z{F|W6zkGN$D?0hi(~I;$A08&N|Ne2ULGF1@lJfIJPJH8s^^||{1f@m>=C`&!;#Kl~ z=_T>5(B=4m@P5$>4~t}5nGv#x{4*fr%@@cuka}B`q1}~$fw2a)N|RCFSNOK<@O)de zyqw&RUw@?7xQ$vWEf@t3KlguEaSwI0g^`KYGUsv=C|XLz>m~OH_@)>A$~MAu(QL)k z>3f7+Z?n~K+2I<`sr1wEUUgM_rdD4PhccHYW6|6l_#Qs`Rxo@i6Cqb?R+SSgDkH*- zKW3W*&ZVpp>310T;}s58WrRU8g!GiL^-{%2 zNv^Gm|G~Q_e!eUI81ksl)H+4abN;N?v-@O*l?BTmNqk?}nMu6d+)U4S94zjRtIxfy z*NdT&gnS*kD{V1|)1F&_)m;$zb>Jz`eW$4>1C|lNFL`GW;)>Py=p0Mf8>Rxn!al2T|Kfy)usMB5$SXAZaS{2s-K+CPgQGS@B8khzCzvX@5ODgU53 zX*F}LsXUvag+Y|d`;t3C_@v4^;?|e#B5!IXUN)8w_q}asZ~bAn3!P7^AACyI?$6Rl zYA-j0y60}S*o)n%eQczlGzkP5wux|AE>xvIrkJP*zGE|!Oj}O4#(lQ!&z?r-_meyx zBa^$)xdkSsJh)S7S!Mng!sZ;yaCckA$cTj-{1IZMne75GvD^vF7vMsccez|X*XjGH zBkrVTK#kO`h$vBK*;{t5pK!2veX#Cnq*MH&K_#=buQw< z1^)cGJ6t-+yGlXjxxkzz<5;5&+rj`(V{WbqBT8xUZD3yT%(tWa8gf;E+3`>5>ANMD zd2w~?3w+z9@AlNxvqe5}D{$1^=N>D!#*_cb6rkJvLa9!Oe6Nnh4IFXmrNkzG$$F? zep^|@CuMNByla1#W@4np<-aR)vCFs15PSwMoCt&ri6h?WFK|EO=t=p2dUkxlOC8SW zKQ+$C0*Dx}2xNxtH-4>6F7dx3@T<{jaQbV!Q@lkkV>%h*BHV`>m=@pDV(dffsQ-*+ ztCli*C#aRG0?babj#hv<;~#X4`CR=ochR{5OK(c*?KK$N2p^H$knq*Z>|IGAp*V_F zr0lCCS(RLwP&o>4W!WzI7FKA&vW<_BTsdI&E?y$)2v&2RYlV*JoAT0hiA5iMR^BQV&Q=ki=E*AwZc&ip%O(5s61k=01vk3Jtpxx4g#8@I)=(kwN( zQznd$p7GqruZi2T&nv8kXsv1?ZpUHC>BuKAlHGP5?+0bttk8Z_qObP zeShf#q(6ztbk+yos=9aM2CsfcN9XUkc-}tRDKpcdkgnfL?*#UOSSeVHET(`e*smNH zcL_N*3>_hT!mZZRK0!gfM&L15QOkx^nMdsHUcOF`1w{3HhPt_0ZI^nrCEbJ}gdzmy zsbI9u$nbdiM10bvWz%QEQjzr$LaX_AalpnTHVoO(d09-o(ryNr4Fkz>Z>$p~?{4V1 zq3OtiB*hVL2KoffqE81!vQH5FkSPT+gs{V$RjU+V4S3fEsMTYLnR^1~@8~A85@%GJ zsLc)XGOE*V4j2BH|D|FXFTu^t*R5CR$f=o#IDsdSGAFQ$;f3ykva;>Z3J?GSQF2T? zN;*)lM)E0hu}A0?nl5&UUZBIYS6ah?<<5@`LN@7wWbnkJ%>LVtM1FH*U?tep|&8pBi|;fD97F{9eyoz7{X0mY(JD`;QHA_V=y5GP=QgiOZUddB}#qutM;} zvAC#EvcxXv50SqOdfe;n*y|zDVkN9?8y>uW-DhMB0{J~%-!e!nVEf*9kKUlF8I*tM zJ{oQ2Xf{Iw*a<|}eQ6mdb!v73@c$Nm3F}0+{XYDHh#eVi(Ja(6j9c%zuP)=% z>RNhm>C4bev3M5CV)SL3u}{xz@0K6~vB{>|!|>1P+`Op~X6x&g)eR2rub;pL+w@$E z%}WE2lMM#_+UeJMFYm{!y!K};GpjHg-s*k)>H3XIRRD~Zz7o0@)SGVkCfRYKw5i9u zY~-UWVjig>T+WZEzi6ST^$;wE*I!15BS$D4HZvc5Ny|(eo7UJo4p@Yyo6!}O zKpqzvsNS%F_2)dKBy2Fjt%e?VrHnsav1=U>s}3C|do@BvO`5QKlgui~hT8`d+E>uKGAy2feG#uEmIgZ+Bi|89Najr!*f`+X2z5?FEH- zO*mm@msEWw;S11}7o94#IWC-;m@jmyMhLI-?3vI-7kKKEERgH`%@j zXWi9=f8FNCu#qDEg5R2afq6(e|JMy1>nU)?bo28!kxwjt?uO3jY8yR9Yrc&5e|p#< AJpcdz From 05189361b79e9ebd33486cf8d564a5e85a6747d8 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Tue, 28 Jan 2014 11:50:40 -0700 Subject: [PATCH 075/126] CLOUDSTACK-5968 last patch fixes setting low currentMemory during overprovision, this one explicitly tells libvirt we dont want a balloon device (won't use it anyway, and will just suck up a percent of vm memory) --- .../kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java | 2 ++ 1 file changed, 2 insertions(+) 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 9fd058fa3eb..5aeacdafae0 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 @@ -162,6 +162,8 @@ public class LibvirtVMDef { } if (_memBalloning) { resBuidler.append("\n" + "\n" + "\n"); + } else { + resBuidler.append("\n" + "\n" + "\n"); } if (_vcpu != -1) { resBuidler.append("" + _vcpu + "\n"); From 08d124d6b664bedea28b75fab02c6fd217a67a47 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 28 Jan 2014 11:24:20 -0800 Subject: [PATCH 076/126] Add listView async tests --- ui/tests/test.widget.listView.js | 88 ++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/ui/tests/test.widget.listView.js b/ui/tests/test.widget.listView.js index 2209c42ddb9..3640a5a4cca 100644 --- a/ui/tests/test.widget.listView.js +++ b/ui/tests/test.widget.listView.js @@ -86,4 +86,92 @@ equal($field.html(), v.label, k + '-> Has correct label'); }); }); + + test('Data loading state', function() { + var $listView = listView(); + + equal($listView.find('table.body tr.loading').size(), 1, 'Row has loading state'); + equal($listView.find('table.body tr.loading td.loading.icon').size(), 1, 'Row cell has loading icon'); + }); + + asyncTest('Data provider: basic', function() { + expect(3); + var $listView = listView({ + listView: { + fields: { + fieldA: { label: 'TestFieldA' }, + fieldB: { label: 'TestFieldB' } + }, + dataProvider: function(args) { + args.response.success({ data: [] }); + + ok(true, 'Data provider called'); + start(); + } + } + }); + + equal($listView.find('.data-table table.body tbody tr.empty td').size(), 1, 'Body table has empty table row'); + equal($listView.find('.data-table table.body tbody tr.empty td').html(), 'label.no.data', 'Empty contents notice displayed'); + }); + + asyncTest('Data provider: load data', function() { + var $listView = listView({ + listView: { + fields: { + fieldA: { label: 'TestFieldA' }, + fieldB: { label: 'TestFieldB' } + }, + dataProvider: function(args) { + args.response.success({ + data: [ + { fieldA: 'FieldDataA', fieldB: 'FieldDataB' } + ] + }); + + start(); + } + } + }); + + equal($listView.find('table.body tbody tr').size(), 1, 'Body table has table row'); + equal($listView.find('table.body tbody tr td').size(), 2, 'Body table has table cells'); + equal($listView.find('table.body tbody tr td.fieldA > span').html(), 'FieldDataA', 'FieldDataA content present'); + equal($listView.find('table.body tbody tr td.fieldB > span').html(), 'FieldDataB', 'FieldDataB content present'); + }); + + asyncTest('Data provider: multiple rows of data', function() { + var testData = [ + { fieldA: 'FieldDataA1', fieldB: 'FieldDataB1' }, + { fieldA: 'FieldDataA2', fieldB: 'FieldDataB2' }, + { fieldA: 'FieldDataA3', fieldB: 'FieldDataB3' } + ]; + + var $listView = listView({ + listView: { + fields: { + fieldA: { label: 'TestFieldA' }, + fieldB: { label: 'TestFieldB' } + }, + dataProvider: function(args) { + args.response.success({ + data: testData + }); + + start(); + } + } + }); + + equal($listView.find('table.body tbody tr').size(), 3, 'Body table has correct # of table rows'); + + $(testData).map(function(index, data) { + var $tr = $listView.find('table.body tbody tr').filter(function() { + return $(this).index() === index; + }); + + equal($tr.find('td.fieldA > span').html(), 'FieldDataA' + (index + 1), 'FieldDataA' + (index + 1) + ' present'); + equal($tr.find('td.fieldB > span').html(), 'FieldDataB' + (index + 1), 'FieldDataB' + (index + 1) + ' present'); + }); + }); }()); From 18a3d3c3b85fd8dd44106bdfeffca231d87f2be1 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 28 Jan 2014 11:33:03 -0800 Subject: [PATCH 077/126] VM snapshots: If quiescevm is supported, make checkbox checked --- ui/scripts/instances.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/scripts/instances.js b/ui/scripts/instances.js index 989d9a81d1b..3b1931b862b 100644 --- a/ui/scripts/instances.js +++ b/ui/scripts/instances.js @@ -47,7 +47,13 @@ isBoolean: true, isChecked: false, isHidden: function(args) { - return args.context.instances[0].hypervisor !== 'VMware'; + if (args.context.instances[0].hypervisor !== 'VMware') { + return true; + } + + args.form.fields.quiescevm.isChecked = true; + + return false; } } } From 23f3047e7d4e0d53f830a9a316d9ec37cbfd0b3f Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 28 Jan 2014 11:42:55 -0800 Subject: [PATCH 078/126] CLOUDSTACK-5970: UI > network menu > guest network section > select non-VPC isolated network with SourceNAT enabled > IP Address section > select sourceNAT IP > show Configuration tab. --- ui/scripts/network.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index e4cd8b00db7..0aa5473117c 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -2226,7 +2226,7 @@ } } - if (ipAddress.issourcenat) { + if (ipAddress.vpcid != null && ipAddress.issourcenat) { //don't show Configuration(ipRules) tab on VPC sourceNAT IP disableIpRules = true; } From 25d8e3d7dbd2b08b521deaea9fa7ebfc7172b1a9 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 28 Jan 2014 11:53:39 -0800 Subject: [PATCH 079/126] Browser UI: Fix broken breadcrumb navigation Fix breadcrumb navigation becoming stuck when going back a couple levels, due to previous panels not being removed from the DOM --- ui/scripts/ui/widgets/cloudBrowser.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/ui/scripts/ui/widgets/cloudBrowser.js b/ui/scripts/ui/widgets/cloudBrowser.js index ffb5f157abe..31ac533dd11 100644 --- a/ui/scripts/ui/widgets/cloudBrowser.js +++ b/ui/scripts/ui/widgets/cloudBrowser.js @@ -205,16 +205,7 @@ .addClass('reduced') ).removeClass('active maximized'); - $toRemove.css( - _panel.initialState($container), { - duration: 500, - complete: function() { - $(this).remove(); - - if (complete) complete($toShow); - } - } - ); + $toRemove.remove(); $toShow.show(); $panel.css({ left: _panel.position($container, { From 547aa36707087beca72055dc5eceef195061a3ba Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 28 Jan 2014 11:55:43 -0800 Subject: [PATCH 080/126] multi-edit UI: Fix wrapping for multirange (start-end) fields --- ui/css/cloudstack3.css | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 18a88babc3e..993673bbd71 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -7624,7 +7624,6 @@ div.container div.panel div#details-tab-addloadBalancer.detail-group div.loadBal .multi-edit .range input { width: 35px; - margin-left: 6px; margin-right: 2px; position: relative; } From bd2acd1eff5d84630318cef0cde2c81204d07586 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Tue, 28 Jan 2014 23:20:45 +0100 Subject: [PATCH 081/126] findbugs: comparison of wrapper objects --- server/src/com/cloud/server/StatsCollector.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 95ae047cea8..601ab126992 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -839,11 +839,11 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc Double sum = avgCounter.get(counter_count); Double avg = sum / currentVM; Operator op = conditionVO.getRelationalOperator(); - boolean bConditionCheck = ((op == com.cloud.network.as.Condition.Operator.EQ) && (thresholdPercent == avg)) - || ((op == com.cloud.network.as.Condition.Operator.GE) && (avg >= thresholdPercent)) - || ((op == com.cloud.network.as.Condition.Operator.GT) && (avg > thresholdPercent)) - || ((op == com.cloud.network.as.Condition.Operator.LE) && (avg <= thresholdPercent)) - || ((op == com.cloud.network.as.Condition.Operator.LT) && (avg < thresholdPercent)); + boolean bConditionCheck = ((op == com.cloud.network.as.Condition.Operator.EQ) && (thresholdPercent.equals(avg))) + || ((op == com.cloud.network.as.Condition.Operator.GE) && (avg.doubleValue() >= thresholdPercent.doubleValue())) + || ((op == com.cloud.network.as.Condition.Operator.GT) && (avg.doubleValue() > thresholdPercent.doubleValue())) + || ((op == com.cloud.network.as.Condition.Operator.LE) && (avg.doubleValue() <= thresholdPercent.doubleValue())) + || ((op == com.cloud.network.as.Condition.Operator.LT) && (avg.doubleValue() < thresholdPercent.doubleValue())); if (!bConditionCheck) { bValid = false; From a26c81178b4db78ad4936fb90a41444fc71eea83 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 28 Jan 2014 13:09:57 -0800 Subject: [PATCH 082/126] CLOUDSTACK-5971:Templates created from a snapshots can't be copied to other zones. --- .../cloudstack/storage/image/TemplateServiceImpl.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 2c829141a1e..a8dec0988f1 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -75,6 +75,7 @@ import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.ResourceAllocationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateStorageResourceAssoc; @@ -721,6 +722,13 @@ public class TemplateServiceImpl implements TemplateService { @Override public AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, DataStore destStore) { + // for vmware template, we need to check if ova packing is needed, since template created from snapshot does not have .ova file + // we invoke createEntityExtractURL to trigger ova packing. Ideally, we can directly use extractURL to pass to following createTemplate. + // Need to understand what is the background to use two different urls for copy and extract. + if (srcTemplate.getFormat() == ImageFormat.OVA){ + ImageStoreEntity tmpltStore = (ImageStoreEntity)srcTemplate.getDataStore(); + tmpltStore.createEntityExtractUrl(srcTemplate.getInstallPath(), srcTemplate.getFormat(), srcTemplate); + } // generate a URL from source template ssvm to download to destination data store String url = generateCopyUrl(srcTemplate); if (url == null) { From 16a9171f55d729e22240c26d15b73a4295f0e960 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 28 Jan 2014 14:53:18 -0800 Subject: [PATCH 083/126] Fix trailing whitespace. --- .../apache/cloudstack/storage/image/TemplateServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index a8dec0988f1..166b523e387 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -723,7 +723,7 @@ public class TemplateServiceImpl implements TemplateService { @Override public AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, DataStore destStore) { // for vmware template, we need to check if ova packing is needed, since template created from snapshot does not have .ova file - // we invoke createEntityExtractURL to trigger ova packing. Ideally, we can directly use extractURL to pass to following createTemplate. + // we invoke createEntityExtractURL to trigger ova packing. Ideally, we can directly use extractURL to pass to following createTemplate. // Need to understand what is the background to use two different urls for copy and extract. if (srcTemplate.getFormat() == ImageFormat.OVA){ ImageStoreEntity tmpltStore = (ImageStoreEntity)srcTemplate.getDataStore(); From ebcf6a1da88c4d750f9342df45fc409be80c9759 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 28 Jan 2014 14:54:30 -0800 Subject: [PATCH 084/126] List view: tests for field pre-filter --- ui/tests/test.widget.listView.js | 38 +++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/ui/tests/test.widget.listView.js b/ui/tests/test.widget.listView.js index 3640a5a4cca..84f914b8f78 100644 --- a/ui/tests/test.widget.listView.js +++ b/ui/tests/test.widget.listView.js @@ -104,7 +104,7 @@ }, dataProvider: function(args) { args.response.success({ data: [] }); - + ok(true, 'Data provider called'); start(); } @@ -128,7 +128,7 @@ { fieldA: 'FieldDataA', fieldB: 'FieldDataB' } ] }); - + start(); } } @@ -146,7 +146,7 @@ { fieldA: 'FieldDataA2', fieldB: 'FieldDataB2' }, { fieldA: 'FieldDataA3', fieldB: 'FieldDataB3' } ]; - + var $listView = listView({ listView: { fields: { @@ -157,7 +157,7 @@ args.response.success({ data: testData }); - + start(); } } @@ -169,9 +169,37 @@ var $tr = $listView.find('table.body tbody tr').filter(function() { return $(this).index() === index; }); - + equal($tr.find('td.fieldA > span').html(), 'FieldDataA' + (index + 1), 'FieldDataA' + (index + 1) + ' present'); equal($tr.find('td.fieldB > span').html(), 'FieldDataB' + (index + 1), 'FieldDataB' + (index + 1) + ' present'); }); }); + + test('Field pre-filter', function() { + var $listView = listView({ + listView: { + fields: { + fieldA: { label: 'TestFieldA' }, + fieldB: { label: 'TestFieldB' }, + fieldHidden: { label: 'TestFieldHidden' } + }, + preFilter: function(args) { + return ['fieldHidden']; + }, + dataProvider: function(args) { + args.response.success({ + data: [ + { fieldA: 'FieldDataA', fieldB: 'FieldDataB', fieldHidden: 'FieldDataHidden' } + ] + }); + + start(); + } + } + }); + + equal($listView.find('table tr th').size(), 2, 'Correct number of header columns present'); + equal($listView.find('table.body tbody tr td').size(), 2, 'Correct number of data body columns present'); + ok(!$listView.find('table.body tbody td.fieldHidden').size(), 'Hidden field not present'); + }); }()); From 3ac181e396c2564df66947184048565d4b199716 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 28 Jan 2014 15:48:33 -0800 Subject: [PATCH 085/126] List view: tests for filter dropdown --- ui/tests/test.widget.listView.js | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/ui/tests/test.widget.listView.js b/ui/tests/test.widget.listView.js index 84f914b8f78..43c42f9d16a 100644 --- a/ui/tests/test.widget.listView.js +++ b/ui/tests/test.widget.listView.js @@ -202,4 +202,44 @@ equal($listView.find('table.body tbody tr td').size(), 2, 'Correct number of data body columns present'); ok(!$listView.find('table.body tbody td.fieldHidden').size(), 'Hidden field not present'); }); + + test('Filter dropdown', function() { + var $listView = listView({ + listView: { + fields: { + state: { label: 'State' } + }, + filters: { + on: { label: 'FilterOnLabel' }, + off: { label: 'FilterOffLabel' } + }, + dataProvider: function(args) { + var filterBy = args.filterBy.kind; + var data = filterBy === 'on' ? [{ state: 'on' }] : [{ state: 'off' }]; + + args.response.success({ + data: data + }); + + start(); + } + } + }); + + var $filters = $listView.find('.filters select'); + + var testFilterDropdownContent = function() { + equal($filters.find('option').size(), 2, 'Correct # of filters present'); + equal($filters.find('option:first').html(), 'FilterOnLabel', 'Filter on label present'); + equal($filters.find('option:last').html(), 'FilterOffLabel', 'Filter off label present'); + }; + + testFilterDropdownContent(); + equal($filters.find('option').val(), 'on', 'Correct default filter active'); + equal($listView.find('tbody td.state span').html(), 'on', '"on" data item visible'); + ok($filters.val('off').trigger('change'), 'Change filter to "off"'); + equal($listView.find('tbody td.state span').html(), 'off', '"off" data item visible'); + equal($filters.val(), 'off', 'Correct filter active'); + testFilterDropdownContent(); + }); }()); From 1c57dd7bcd4c21fa9c55b8a488474243c458347d Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Wed, 29 Jan 2014 09:16:23 +0100 Subject: [PATCH 086/126] Give findbugs some more memory or it will fail with an OOM on awsapi --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 01ddf111906..d8c8851a3bf 100644 --- a/pom.xml +++ b/pom.xml @@ -871,6 +871,7 @@ High true false + 1024 From 1c4bbecc4a50b059b8bb87a802023ee6f48ca1f2 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Wed, 29 Jan 2014 13:55:44 +0530 Subject: [PATCH 087/126] CLOUDSTACK-5900: Failed to delete template/ISO that failed to download. --- .../resource/NfsSecondaryStorageResource.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 4d11dd38e79..3d994438d98 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -1716,16 +1716,23 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S parent += File.separator; } String absoluteTemplatePath = parent + relativeTemplatePath; - File tmpltDir = new File(absoluteTemplatePath); + + File tmpltParent; + if(absoluteTemplatePath.endsWith(String.valueOf(obj.getId()))) { + tmpltParent = new File(absoluteTemplatePath); + } else { + tmpltParent = new File(absoluteTemplatePath).getParentFile(); + } + String details = null; - if (!tmpltDir.exists()) { - details = "template parent directory " + tmpltDir.getName() + " doesn't exist"; + if (!tmpltParent.exists()) { + details = "template parent directory " + tmpltParent.getName() + " doesn't exist"; s_logger.debug(details); return new Answer(cmd, true, details); } - File[] tmpltFiles = tmpltDir.listFiles(); + File[] tmpltFiles = tmpltParent.listFiles(); if (tmpltFiles == null || tmpltFiles.length == 0) { - details = "No files under template parent directory " + tmpltDir.getName(); + details = "No files under template parent directory " + tmpltParent.getName(); s_logger.debug(details); } else { boolean found = false; @@ -1751,12 +1758,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } if (!found) { - details = "Can not find template.properties under " + tmpltDir.getName(); + details = "Can not find template.properties under " + tmpltParent.getName(); s_logger.debug(details); } } - if (!tmpltDir.delete()) { - details = "Unable to delete directory " + tmpltDir.getName() + " under Template path " + relativeTemplatePath; + if (!tmpltParent.delete()) { + details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + relativeTemplatePath; s_logger.debug(details); return new Answer(cmd, false, details); } From fef2daf5d4aeef80e8780fc1605c7bee6ecf3849 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 29 Jan 2014 12:06:34 +0100 Subject: [PATCH 088/126] findbugs: compare strings with equals() --- server/src/com/cloud/server/StatsCollector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 601ab126992..548587cfa8e 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -737,7 +737,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } String counterName = getCounternamebyCondition(conditionId.longValue()); - if (counterName == Counter.Source.memory.toString()) { + if (Counter.Source.memory.toString().equals(counterName)) { // calculate memory in percent Long profileId = asGroup.getProfileId(); AutoScaleVmProfileVO profileVo = _asProfileDao.findById(profileId); From ee1e8a6c2a375a1a7232f2c7ca2f95f78b3c3d2f Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 29 Jan 2014 12:36:34 +0100 Subject: [PATCH 089/126] findbugs: use system account id instead of null (security considerations to be made here) --- server/src/com/cloud/storage/VolumeApiServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 55582c6421d..c856379b812 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -449,7 +449,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic volume.setPoolId(null); volume.setDataCenterId(zoneId); volume.setPodId(null); - volume.setAccountId((owner == null) ? null : owner.getAccountId()); + // to prevent a nullpointer deref I put the system account id here when no owner is given. + // TODO Decide if this is valid or whether throwing a CloudRuntimeException is more appropriate + volume.setAccountId((owner == null) ? Account.ACCOUNT_ID_SYSTEM : owner.getAccountId()); volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner.getDomainId()); long diskOfferingId = _diskOfferingDao.findByUniqueName("Cloud.com-Custom").getId(); volume.setDiskOfferingId(diskOfferingId); From 920163f24f4348309c223a973cf68d7f8352babf Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Wed, 29 Jan 2014 13:09:17 +0100 Subject: [PATCH 090/126] findbugs: possible nulpointer derefs --- server/src/com/cloud/storage/upload/UploadMonitorImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 991f35f7c69..6f1f5e90c4e 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -269,7 +269,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)store).getMountPoint(), path, uuid, null); Answer ans = ep.sendMessage(cmd); if (ans == null || !ans.getResult()) { - errorString = "Unable to create a link for " + type + " id:" + template.getId() + "," + ans.getDetails(); + errorString = "Unable to create a link for " + type + " id:" + template.getId() + "," + (ans == null ? "" : ans.getDetails()); s_logger.error(errorString); throw new CloudRuntimeException(errorString); } @@ -325,7 +325,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)secStore).getMountPoint(), path, uuid, null); Answer ans = ep.sendMessage(cmd); if (ans == null || !ans.getResult()) { - errorString = "Unable to create a link for " + type + " id:" + entityId + "," + ans.getDetails(); + errorString = "Unable to create a link for " + type + " id:" + entityId + "," + (ans == null ? "" : ans.getDetails()); s_logger.warn(errorString); throw new CloudRuntimeException(errorString); } From 12777e9e3a633dda51f14229ae7d0587d6a34577 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Wed, 29 Jan 2014 13:42:55 +0100 Subject: [PATCH 091/126] Allow even more memory for findbugs, awsapi is hungry --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d8c8851a3bf..1d2304ffcc6 100644 --- a/pom.xml +++ b/pom.xml @@ -871,7 +871,7 @@ High true false - 1024 + 2048 From 68937cd20770c1154544bfb239b8f72e9d781a9b Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 29 Jan 2014 11:33:24 -0800 Subject: [PATCH 092/126] CLOUDSTACK-5983: changed responseName param in assignCertToLoadBalancer and removeCertFromLoadBalancer API commands --- .../command/user/loadbalancer/AssignCertToLoadBalancerCmd.java | 3 ++- .../user/loadbalancer/RemoveCertFromLoadBalancerCmd.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java index 4ea4a588cea..4b0ea544c5e 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java @@ -1,3 +1,4 @@ + // 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 @@ -42,7 +43,7 @@ public class AssignCertToLoadBalancerCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(AssignCertToLoadBalancerCmd.class.getName()); - private static final String s_name = "assignCertToLoadBalancer"; + private static final String s_name = "assigncerttoloadbalancerresponse"; @Parameter(name = ApiConstants.LBID, type = CommandType.UUID, diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java index e92d20801c4..ea420f31bf5 100644 --- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java @@ -41,7 +41,7 @@ public class RemoveCertFromLoadBalancerCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(RemoveCertFromLoadBalancerCmd.class.getName()); - private static final String s_name = "removeCertFromLoadBalancer"; + private static final String s_name = "removecertfromloadbalancerresponse"; @Parameter(name = ApiConstants.LBID, type = CommandType.UUID, From 3b781d1a227e59e8a7a1602737ed2cd04d393177 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 29 Jan 2014 10:25:54 -0800 Subject: [PATCH 093/126] ResizeVolume API - volumeId should be a required parameter --- .../cloudstack/api/command/user/volume/ResizeVolumeCmd.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java index 0cc8039200d..e69194438bf 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ResizeVolumeCmd.java @@ -16,8 +16,6 @@ // under the License. package org.apache.cloudstack.api.command.user.volume; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiCommandJobType; import org.apache.cloudstack.api.ApiConstants; @@ -28,6 +26,7 @@ import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.context.CallContext; +import org.apache.log4j.Logger; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; @@ -47,7 +46,7 @@ public class ResizeVolumeCmd extends BaseAsyncCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name = ApiConstants.ID, entityType = VolumeResponse.class, type = CommandType.UUID, description = "the ID of the disk volume") + @Parameter(name = ApiConstants.ID, entityType = VolumeResponse.class, required = true, type = CommandType.UUID, description = "the ID of the disk volume") private Long id; @Parameter(name = ApiConstants.SIZE, type = CommandType.LONG, required = false, description = "New volume size in G") From fdb25d6f5bbd36051b54ce866d8710456a93c1a1 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 29 Jan 2014 13:11:29 -0800 Subject: [PATCH 094/126] Resource metadata support for autoscaleVmProfile CS object --- api/src/com/cloud/server/ResourceTag.java | 3 +- .../autoscale/ListAutoScaleVmProfilesCmd.java | 11 ++- ...spring-engine-schema-core-daos-context.xml | 29 +++---- .../AutoScaleVmProfileDetailVO.java | 81 +++++++++++++++++++ .../dao/AutoScaleVmProfileDetailsDao.java | 26 ++++++ .../dao/AutoScaleVmProfileDetailsDaoImpl.java | 33 ++++++++ .../network/as/AutoScaleManagerImpl.java | 7 ++ .../cloud/tags/TaggedResourceManagerImpl.java | 5 +- setup/db/db/schema-430to440.sql | 10 +++ 9 files changed, 186 insertions(+), 19 deletions(-) create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index 41931f0949b..a08c3e4fede 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -51,7 +51,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit CustomerGateway(false, true), VpnConnection(false, true), User(true, true), - DiskOffering(false, true); + DiskOffering(false, true), + AutoScaleVmProfile(false, true); ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { this.resourceTagsSupport = resourceTagsSupport; diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java index 651f98703e8..34c2543b9c6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java @@ -19,15 +19,15 @@ package org.apache.cloudstack.api.command.user.autoscale; import java.util.ArrayList; import java.util.List; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.TemplateResponse; +import org.apache.log4j.Logger; import com.cloud.network.as.AutoScaleVmProfile; @@ -47,6 +47,9 @@ public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourc @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class, description = "the templateid of the autoscale vm profile") private Long templateId; + @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID, entityType = ServiceOfferingResponse.class, description = "list profiles by service offering id") + private Long serviceOffId; + @Parameter(name = ApiConstants.OTHER_DEPLOY_PARAMS, type = CommandType.STRING, description = "the otherdeployparameters of the autoscale vm profile") private String otherDeployParams; @@ -66,6 +69,10 @@ public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourc return otherDeployParams; } + public Long getServiceOfferingId() { + return serviceOffId; + } + // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// // /////////////////////////////////////////////////// diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 1a400e049e0..d1a68ede322 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -36,7 +36,7 @@ - + @@ -45,7 +45,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -63,7 +63,7 @@ - + @@ -72,7 +72,7 @@ - + @@ -81,7 +81,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -99,7 +99,7 @@ - + @@ -109,7 +109,7 @@ - + @@ -172,12 +172,12 @@ - - - - + + + + - + @@ -331,6 +331,7 @@ + diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java new file mode 100644 index 00000000000..06d7296fe13 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmProfileDetailVO.java @@ -0,0 +1,81 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.resourcedetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "autoscale_vmprofile_details") +public class AutoScaleVmProfileDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "autoscale_vmprofile_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display; + + public AutoScaleVmProfileDetailVO() { + } + + public AutoScaleVmProfileDetailVO(long id, String name, String value) { + this.resourceId = id; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java new file mode 100644 index 00000000000..9da313a85a7 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDao.java @@ -0,0 +1,26 @@ +// 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 org.apache.cloudstack.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.AutoScaleVmProfileDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.utils.db.GenericDao; + +public interface AutoScaleVmProfileDetailsDao extends GenericDao, ResourceDetailsDao { + +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.java new file mode 100644 index 00000000000..17e0316bc98 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmProfileDetailsDaoImpl.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 org.apache.cloudstack.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.AutoScaleVmProfileDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +@Local(value = {AutoScaleVmProfileDetailsDao.class}) +public class AutoScaleVmProfileDetailsDaoImpl extends ResourceDetailsDaoBase implements AutoScaleVmProfileDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value) { + super.addDetail(new AutoScaleVmProfileDetailVO(resourceId, key, value)); + } +} \ No newline at end of file diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 0751b69343d..321c29f09c6 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -437,12 +437,14 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale Long id = cmd.getId(); Long templateId = cmd.getTemplateId(); String otherDeployParams = cmd.getOtherDeployParams(); + Long serviceOffId = cmd.getServiceOfferingId(); SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId()); SearchBuilder sb = searchWrapper.getSearchBuilder(); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ); + sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ); sb.and("otherDeployParams", sb.entity().getOtherDeployParams(), SearchCriteria.Op.LIKE); SearchCriteria sc = searchWrapper.buildSearchCriteria(); @@ -455,6 +457,11 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale if (otherDeployParams != null) { sc.addAnd("otherDeployParams", SearchCriteria.Op.LIKE, "%" + otherDeployParams + "%"); } + + if (serviceOffId != null) { + sc.setParameters("serviceOfferingId", serviceOffId); + } + return searchWrapper.search(); } diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index be896f063bd..555a8452786 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -25,12 +25,11 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.log4j.Logger; import com.cloud.api.query.dao.ResourceTagJoinDao; import com.cloud.dc.DataCenterVO; @@ -40,6 +39,7 @@ import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.network.as.AutoScaleVmProfileVO; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.LoadBalancerVO; import com.cloud.network.dao.NetworkVO; @@ -116,6 +116,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso s_typeMap.put(ResourceObjectType.VpnConnection, Site2SiteVpnConnectionVO.class); s_typeMap.put(ResourceObjectType.User, UserVO.class); s_typeMap.put(ResourceObjectType.DiskOffering, DiskOfferingVO.class); + s_typeMap.put(ResourceObjectType.AutoScaleVmProfile, AutoScaleVmProfileVO.class); } @Inject diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index 3fa34029fb7..8c45295de02 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -447,3 +447,13 @@ CREATE VIEW `cloud`.`user_vm_view` AS `cloud`.`user_vm_details` `custom_ram_size` ON (((`custom_ram_size`.`vm_id` = `cloud`.`vm_instance`.`id`) and (`custom_ram_size`.`name` = 'memory'))); INSERT INTO `cloud`.`configuration`(category, instance, component, name, value, description, default_value) VALUES ('NetworkManager', 'DEFAULT', 'management-server', 'vm.network.nic.max.secondary.ipaddresses', NULL, 'Specify the number of secondary ip addresses per nic per vm', '256') ON DUPLICATE KEY UPDATE category='NetworkManager'; + +CREATE TABLE `cloud`.`autoscale_vmprofile_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `autoscale_vmprofile_id` bigint unsigned NOT NULL COMMENT 'VPC gateway id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end autoscale_vmprofile', + PRIMARY KEY (`id`), + CONSTRAINT `fk_autoscale_vmprofile_details__autoscale_vmprofile_id` FOREIGN KEY `fk_autoscale_vmprofile_details__autoscale_vmprofile_id`(`autoscale_vmprofile_id`) REFERENCES `autoscale_vmprofiles`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; From 65c5de1cb604a6547a9bd01bc9c28d55aa30e904 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 29 Jan 2014 13:32:29 -0800 Subject: [PATCH 095/126] Removed recently introduced api.servlet.endpoint global config as CS already has config serving the same purpose - 'endpointe.url' --- .../cloudstack/config/ApiServiceConfiguration.java | 2 +- server/src/com/cloud/configuration/Config.java | 1 - .../com/cloud/network/as/AutoScaleManagerImpl.java | 4 ++-- .../network/lb/LoadBalancingRulesManagerImpl.java | 12 +++++------- setup/db/db/schema-421to430.sql | 2 -- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java b/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java index edf5a21b673..94c0a55de6a 100644 --- a/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java +++ b/api/src/org/apache/cloudstack/config/ApiServiceConfiguration.java @@ -24,7 +24,7 @@ import org.apache.cloudstack.framework.config.Configurable; @Local(value = {ApiServiceConfiguration.class}) public class ApiServiceConfiguration implements Configurable { public static final ConfigKey ManagementHostIPAdr = new ConfigKey("Advanced", String.class, "host", "localhost", "The ip address of management server", true); - public static final ConfigKey ApiServletPath = new ConfigKey("Advanced", String.class, "api.servlet.endpoint", "http://localhost:8080/client/api?", + public static final ConfigKey ApiServletPath = new ConfigKey("Advanced", String.class, "endpointe.url", "http://localhost:8080/client/api", "API end point. Can be used by CS components/services deployed remotely, for sending CS API requests", true); @Override diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 6ba67749aef..975eecdc117 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -985,7 +985,6 @@ public enum Config { "FirstFitPlanner", "'FirstFitPlanner', 'UserDispersingPlanner', 'UserConcentratedPodPlanner': DeploymentPlanner heuristic that will be used for VM deployment.", null), - EndpointeUrl("Advanced", ManagementServer.class, String.class, "endpointe.url", "http://localhost:8080/client/api", "Endpointe Url", null), ElasticLoadBalancerEnabled( "Advanced", ManagementServer.class, diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 321c29f09c6..7492c9ace6b 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -50,13 +50,13 @@ import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScalePolicyCmd import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmGroupCmd; import org.apache.cloudstack.api.command.user.autoscale.UpdateAutoScaleVmProfileCmd; import org.apache.cloudstack.api.command.user.vm.DeployVMCmd; +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.log4j.Logger; import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiDispatcher; -import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; @@ -312,7 +312,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale String apiKey = user.getApiKey(); String secretKey = user.getSecretKey(); - String csUrl = _configDao.getValue(Config.EndpointeUrl.key()); + String csUrl = ApiServiceConfiguration.ApiServletPath.value(); if (apiKey == null) { throw new InvalidParameterValueException("apiKey for user: " + user.getUsername() + " is empty. Please generate it"); diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index 821427425c3..67346e14b3b 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -30,11 +30,6 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; -import org.apache.log4j.Logger; - -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBHealthCheckPolicyCmd; import org.apache.cloudstack.api.command.user.loadbalancer.CreateLBStickinessPolicyCmd; @@ -44,14 +39,15 @@ import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRuleI import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerRulesCmd; import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerRuleCmd; import org.apache.cloudstack.api.response.ServiceResponse; +import org.apache.cloudstack.config.ApiServiceConfiguration; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.lb.ApplicationLoadBalancerRuleVO; import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; +import org.apache.log4j.Logger; import com.cloud.agent.api.to.LoadBalancerTO; -import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; @@ -168,6 +164,8 @@ import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; @Local(value = {LoadBalancingRulesManager.class, LoadBalancingRulesService.class}) public class LoadBalancingRulesManagerImpl extends ManagerBase implements LoadBalancingRulesManager, LoadBalancingRulesService { @@ -305,7 +303,7 @@ public class LoadBalancingRulesManagerImpl extends ManagerBase implements User user = _userDao.findByIdIncludingRemoved(autoscaleUserId); String apiKey = user.getApiKey(); String secretKey = user.getSecretKey(); - String csUrl = _configDao.getValue(Config.EndpointeUrl.key()); + String csUrl = ApiServiceConfiguration.ApiServletPath.value(); String zoneId = _dcDao.findById(autoScaleVmProfile.getZoneId()).getUuid(); String domainId = _domainDao.findById(autoScaleVmProfile.getDomainId()).getUuid(); String serviceOfferingId = _offeringsDao.findById(autoScaleVmProfile.getServiceOfferingId()).getUuid(); diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index fcf9b9fcc6e..afad06c128f 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -898,8 +898,6 @@ INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(uuid, hypervisor_type, hype ALTER TABLE `cloud`.`network_acl_item` modify `cidr` varchar(2048); -INSERT IGNORE INTO `cloud`.`configuration` VALUES ("Advanced", 'DEFAULT', 'management-server', "api.servlet.endpoint", "http://localhost:8080/client/api?", "API end point. Can be used by CS components/services deployed remotely, for sending CS API requests", "http://localhost:8080/client/api?", NULL,NULL,0); - DROP VIEW IF EXISTS `cloud`.`user_vm_view`; CREATE VIEW `cloud`.`user_vm_view` AS select From 37fa8012f869b24a937034537ee378cdcf8053ff Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 29 Jan 2014 14:31:40 -0800 Subject: [PATCH 096/126] Resource metadata for autoscaleVmProfile - forgot to add dao mapping to the ResourceMetaDataManagerImpl --- .../src/com/cloud/metadata/ResourceMetaDataManagerImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java index c7906f52d16..5393a6a6b3f 100644 --- a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java +++ b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java @@ -26,6 +26,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.ResourceDetail; import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.AutoScaleVmProfileDetailsDao; import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao; import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao; import org.apache.cloudstack.resourcedetail.dao.NetworkACLItemDetailsDao; @@ -107,6 +108,8 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource DiskOfferingDetailsDao _diskOfferingDetailsDao; @Inject UserDetailsDao _userDetailsDao; + @Inject + AutoScaleVmProfileDetailsDao _autoScaleVmProfileDetailsDao; private static Map> s_daoMap = new HashMap>(); @@ -134,6 +137,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource s_daoMap.put(ResourceObjectType.VpnConnection, _vpnConnectionDetailsDao); s_daoMap.put(ResourceObjectType.DiskOffering, _diskOfferingDetailsDao); s_daoMap.put(ResourceObjectType.User, _userDetailsDao); + s_daoMap.put(ResourceObjectType.AutoScaleVmProfile, _autoScaleVmProfileDetailsDao); return true; } From b38c033d5c84af6a79150bc099b88ceba54a2c63 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 29 Jan 2014 17:12:46 -0800 Subject: [PATCH 097/126] LOUDSTACK-5987: when listTemplates with filter=community/featured, get public templates from all domains in the system, not just parent/child subdomains of the caller --- .../com/cloud/api/query/QueryManagerImpl.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index bdd413270db..27a05290807 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -26,9 +26,6 @@ import java.util.Set; import javax.ejb.Local; import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO; import org.apache.cloudstack.affinity.AffinityGroupResponse; @@ -90,6 +87,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.query.QueryService; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.api.query.dao.AccountJoinDao; import com.cloud.api.query.dao.AffinityGroupJoinDao; @@ -175,8 +174,8 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDetailsDao; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; -import com.cloud.template.VirtualMachineTemplate.TemplateFilter; import com.cloud.template.VirtualMachineTemplate.State; +import com.cloud.template.VirtualMachineTemplate.TemplateFilter; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; @@ -2828,10 +2827,17 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if (!permittedAccounts.isEmpty()) { for (Account account : permittedAccounts) { permittedAccountIds.add(account.getId()); - DomainVO accountDomain = _domainDao.findById(account.getDomainId()); + boolean publicTemplates = (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community); // get all parent domain ID's all the way till root domain - DomainVO domainTreeNode = accountDomain; + DomainVO domainTreeNode = null; + //if template filter is featured, or community, all child domains should be included in search + if (publicTemplates) { + domainTreeNode = _domainDao.findById(Domain.ROOT_DOMAIN); + + } else { + domainTreeNode = _domainDao.findById(account.getDomainId()); + } relatedDomainIds.add(domainTreeNode.getId()); while (domainTreeNode.getParent() != null) { domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); @@ -2839,8 +2845,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } // get all child domain ID's - if (_accountMgr.isAdmin(account.getType()) || (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community)) { - List allChildDomains = _domainDao.findAllChildren(accountDomain.getPath(), accountDomain.getId()); + if (_accountMgr.isAdmin(account.getType()) || publicTemplates) { + List allChildDomains = _domainDao.findAllChildren(domainTreeNode.getPath(), domainTreeNode.getId()); for (DomainVO childDomain : allChildDomains) { relatedDomainIds.add(childDomain.getId()); } From 121d88743a764e009717cc84440b1c7d5b1e42a4 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Wed, 29 Jan 2014 16:15:24 -0800 Subject: [PATCH 098/126] CLOUDSTACK-5986: Make dnsmasq handle dnsmasq.leases when dhcp_release is available The original issue has been exposed due to CloudStack VR would modify the dnsmasq.leases, thus make it unsync with dnsmasq's memory lease. Make the modification to let dnsmasq handle the lease file if dhcp_release is available. --- .../config/etc/init.d/cloud-early-config | 10 ++++ .../debian/config/opt/cloud/bin/edithosts.sh | 53 +++++++++---------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config index df80a289c2d..fa95fdadb16 100755 --- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config +++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config @@ -750,6 +750,16 @@ setup_dnsmasq() { sed -i -e "/^dhcp-client-update/d" /etc/dnsmasq.conf echo 'dhcp-client-update' >> /etc/dnsmasq.conf fi + + command -v dhcp_release > /dev/null 2>&1 + no_dhcp_release=$? + if [ $no_dhcp_release -eq 0 -a -z "$ETH0_IP6" ] + then + echo 1 > /var/cache/cloud/dnsmasq_managed_lease + sed -i -e "/^leasefile-ro/d" /etc/dnsmasq.conf + else + echo 0 > /var/cache/cloud/dnsmasq_managed_lease + fi } setup_sshd(){ diff --git a/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh b/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh index b82fb8e79be..8e7ddac8fd8 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh +++ b/systemvm/patches/debian/config/opt/cloud/bin/edithosts.sh @@ -80,8 +80,7 @@ fi grep "redundant_router=1" /var/cache/cloud/cmdline > /dev/null no_redundant=$? -command -v dhcp_release > /dev/null 2>&1 -no_dhcp_release=$? +dnsmasq_managed_lease=`cat /var/cache/cloud/dnsmasq_managed_lease` wait_for_dnsmasq () { local _pid=$(pidof dnsmasq) @@ -96,12 +95,7 @@ wait_for_dnsmasq () { return 1 } -if [ $ipv6 ] -then - no_dhcp_release=1 -fi - -if [ $no_dhcp_release -eq 0 ] +if [ $dnsmasq_managed_lease ] then #release previous dhcp lease if present logger -t cloud "edithosts: releasing $ipv4" @@ -145,27 +139,30 @@ then fi fi -#delete leases to supplied mac and ip addresses -if [ $ipv4 ] +if [ $dnsmasq_managed_lease -eq 0 ] then - sed -i /$mac/d $DHCP_LEASES - sed -i /"$ipv4 "/d $DHCP_LEASES -fi -if [ $ipv6 ] -then - sed -i /$duid/d $DHCP_LEASES - sed -i /"$ipv6 "/d $DHCP_LEASES -fi -sed -i /"$host "/d $DHCP_LEASES + #delete leases to supplied mac and ip addresses + if [ $ipv4 ] + then + sed -i /$mac/d $DHCP_LEASES + sed -i /"$ipv4 "/d $DHCP_LEASES + fi + if [ $ipv6 ] + then + sed -i /$duid/d $DHCP_LEASES + sed -i /"$ipv6 "/d $DHCP_LEASES + fi + sed -i /"$host "/d $DHCP_LEASES -#put in the new entry -if [ $ipv4 ] -then - echo "0 $mac $ipv4 $host *" >> $DHCP_LEASES -fi -if [ $ipv6 ] -then - echo "0 $duid $ipv6 $host *" >> $DHCP_LEASES + #put in the new entry + if [ $ipv4 ] + then + echo "0 $mac $ipv4 $host *" >> $DHCP_LEASES + fi + if [ $ipv6 ] + then + echo "0 $duid $ipv6 $host *" >> $DHCP_LEASES + fi fi #edit hosts file as well @@ -215,7 +212,7 @@ pid=$(pidof dnsmasq) if [ "$pid" != "" ] then # use SIGHUP to avoid service outage if dhcp_release is available. - if [ $no_dhcp_release -eq 0 ] + if [ $dnsmasq_managed_lease ] then kill -HUP $pid else From dfe744c4a9209369204be6d51bffe87064cc1e9c Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Thu, 30 Jan 2014 13:25:30 +0530 Subject: [PATCH 099/126] CLOUDSTACK-5900: Failed to delete template/ISO that failed to download. --- .../storage/resource/NfsSecondaryStorageResource.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 3d994438d98..7c4b8ca03d3 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -1716,12 +1716,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S parent += File.separator; } String absoluteTemplatePath = parent + relativeTemplatePath; - - File tmpltParent; - if(absoluteTemplatePath.endsWith(String.valueOf(obj.getId()))) { - tmpltParent = new File(absoluteTemplatePath); + File tmpltPath = new File(absoluteTemplatePath); + File tmpltParent = null; + if(tmpltPath.exists() && tmpltPath.isDirectory()) { + tmpltParent = tmpltPath; } else { - tmpltParent = new File(absoluteTemplatePath).getParentFile(); + tmpltParent = tmpltPath.getParentFile(); } String details = null; From 20fd2769a91435e1d33af87bb047c831f4f06951 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Thu, 30 Jan 2014 16:26:52 +0530 Subject: [PATCH 100/126] CLOUDSTACK-5660: Migrate vm live migration succeeds but throws error as ""Failed to migrate the system vm"". --- server/src/com/cloud/vm/UserVmManagerImpl.java | 7 ++++++- ui/scripts/system.js | 14 +++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 1dcaf798a5d..7efea6952c4 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3933,7 +3933,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir collectVmDiskStatistics(uservm); } _itMgr.migrate(vm.getUuid(), srcHostId, dest); - return _vmDao.findById(vmId); + VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); + if (vmInstance.getType().equals(VirtualMachine.Type.User)) { + return _vmDao.findById(vmId); + } else { + return vmInstance; + } } private boolean checkIfHostIsDedicated(HostVO host) { diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 870b4338bdd..4c0543ed8a0 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -2547,7 +2547,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -3073,7 +3073,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listInternalLoadBalancerVMs&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listInternalLoadBalancerVMs&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -3671,7 +3671,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -6264,7 +6264,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -7720,7 +7720,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listSystemVms&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listSystemVms&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -8892,7 +8892,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listRouters&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { @@ -10117,7 +10117,7 @@ getUpdatedItem: function (json) { //return json.queryasyncjobresultresponse.jobresult.systemvminstance; //not all properties returned in systemvminstance $.ajax({ - url: createURL("listSystemVms&id=" + json.queryasyncjobresultresponse.jobresult.systemvminstance.id), + url: createURL("listSystemVms&id=" + json.queryasyncjobresultresponse.jobresult.systemvm.id), dataType: "json", async: false, success: function (json) { From 85d0f8f93aaf118e0597fcbba0f4cf06efa9df1f Mon Sep 17 00:00:00 2001 From: Saksham Srivastava Date: Tue, 21 Jan 2014 13:36:05 +0530 Subject: [PATCH 101/126] CLOUDSTACK-5916: associateIpAddress leaves an IP in allocating state --- server/src/com/cloud/network/NetworkServiceImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index d02f1760e1d..40c5b645c62 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -3865,10 +3865,16 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { Network network = _networksDao.findById(networkId); if (network == null) { + // release the acquired IP addrress before throwing the exception + // else it will always be in allocating state + releaseIpAddress(ipId); throw new InvalidParameterValueException("Invalid network id is given"); } if (network.getVpcId() != null) { + // release the acquired IP addrress before throwing the exception + // else it will always be in allocating state + releaseIpAddress(ipId); throw new InvalidParameterValueException("Can't assign ip to the network directly when network belongs" + " to VPC.Specify vpcId to associate ip address to VPC"); } return _ipAddrMgr.associateIPToGuestNetwork(ipId, networkId, true); From 5de9ae0bceddd751ae7f59fa4b7aec1d13f8bf59 Mon Sep 17 00:00:00 2001 From: David Grizzanti Date: Thu, 30 Jan 2014 17:30:42 +0530 Subject: [PATCH 102/126] CLOUDSTACK-5496 : Account included in ActionEvents is Project Account ID When Action Events are generated and placed on the Event Bus, an "account" parameter is included with the event. When these events are generated for resources within projects, this "account" parameter is not useful as it's the UUID of the project account, instead of the project. To solve this, I updated ActionEventsUtil class to include a "project" parameter in the generated events when the resource is being changed/add/deleted in a project. --- server/src/com/cloud/event/ActionEventUtils.java | 9 +++++++++ .../apache/cloudstack/affinity/AffinityApiUnitTest.java | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/server/src/com/cloud/event/ActionEventUtils.java b/server/src/com/cloud/event/ActionEventUtils.java index d435381b69b..c332a8e32e4 100755 --- a/server/src/com/cloud/event/ActionEventUtils.java +++ b/server/src/com/cloud/event/ActionEventUtils.java @@ -41,6 +41,8 @@ import com.cloud.user.AccountVO; import com.cloud.user.User; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; +import com.cloud.projects.dao.ProjectDao; +import com.cloud.projects.Project; import com.cloud.utils.component.ComponentContext; public class ActionEventUtils { @@ -48,6 +50,7 @@ public class ActionEventUtils { private static EventDao s_eventDao; private static AccountDao s_accountDao; + private static ProjectDao s_projectDao; protected static UserDao s_userDao; protected static EventBus s_eventBus = null; @@ -63,6 +66,8 @@ public class ActionEventUtils { AccountDao accountDao; @Inject UserDao userDao; + @Inject + ProjectDao projectDao; public ActionEventUtils() { } @@ -72,6 +77,7 @@ public class ActionEventUtils { s_eventDao = eventDao; s_accountDao = accountDao; s_userDao = userDao; + s_projectDao = projectDao; } public static Long onActionEvent(Long userId, Long accountId, Long domainId, String type, String description) { @@ -185,6 +191,7 @@ public class ActionEventUtils { new org.apache.cloudstack.framework.events.Event(ManagementService.Name, eventCategory, eventType, EventTypes.getEntityForEvent(eventType), entityUuid); Map eventDescription = new HashMap(); + Project project = s_projectDao.findByProjectAccountId(accountId); Account account = s_accountDao.findById(accountId); User user = s_userDao.findById(userId); // if account has been deleted, this might be called during cleanup of resources and results in null pointer @@ -192,6 +199,8 @@ public class ActionEventUtils { return; if (user == null) return; + if (project != null) + eventDescription.put("project", project.getUuid()); eventDescription.put("user", user.getUuid()); eventDescription.put("account", account.getUuid()); eventDescription.put("event", eventType); diff --git a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java index 061fd42ac6b..f891e70196d 100644 --- a/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java +++ b/server/test/org/apache/cloudstack/affinity/AffinityApiUnitTest.java @@ -78,6 +78,7 @@ import com.cloud.utils.component.ComponentContext; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.UserVmDao; +import com.cloud.projects.dao.ProjectDao; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(loader = AnnotationConfigContextLoader.class) @@ -110,6 +111,9 @@ public class AffinityApiUnitTest { @Inject AccountDao _accountDao; + @Inject + ProjectDao _projectDao; + @Inject EventDao _eventDao; @@ -217,6 +221,11 @@ public class AffinityApiUnitTest { return Mockito.mock(AccountDao.class); } + @Bean + public ProjectDao projectDao() { + return Mockito.mock(ProjectDao.class); + } + @Bean public AccountService accountService() { return Mockito.mock(AccountService.class); From b32b49e853b2742ec8b32e64eecc083a621fd835 Mon Sep 17 00:00:00 2001 From: Hiroaki KAWAI Date: Thu, 30 Jan 2014 20:14:55 +0900 Subject: [PATCH 103/126] Fix mock socket client/server test. Normally a server will bind to 0.0.0.0, which is not an address that a client can specify to connect to. 127.0.0.1 or ::1 will do. --- .../rdpconsole/src/test/java/rdpclient/MockServerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java index a40cdb8ed79..17bc4bde0c4 100755 --- a/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java +++ b/services/console-proxy-rdp/rdpconsole/src/test/java/rdpclient/MockServerTest.java @@ -58,7 +58,7 @@ public class MockServerTest extends TestCase { Socket socket = SocketFactory.getDefault().createSocket(); try { - socket.connect(server.getAddress()); + socket.connect(new InetSocketAddress("127.0.0.1", server.getAddress().getPort())); InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); @@ -127,7 +127,7 @@ public class MockServerTest extends TestCase { Socket socket = SocketFactory.getDefault().createSocket(); try { - InetSocketAddress address = server.getAddress(); + InetSocketAddress address = new InetSocketAddress("127.0.0.1", server.getAddress().getPort()); socket.connect(address); // Send hello data over plain connection From cb048f4108b53dd811803abaa0b613e86b33d607 Mon Sep 17 00:00:00 2001 From: Hiroaki KAWAI Date: Thu, 30 Jan 2014 21:28:43 +0900 Subject: [PATCH 104/126] Some rework stratosphere ssp plugin * add missing command entry in commands.properties * migrate httpclient 3.x to 4.x * fix the broken SspClient * add webapp session checking in mock ssp server --- client/tomcatconf/commands.properties.in | 5 + .../cloudstack/network/element/SspClient.java | 272 ++++++++---------- .../network/element/SspElement.java | 21 +- .../stratosphere-ssp/sspmock/sspmock.py | 58 ++-- .../network/element/SspClientTest.java | 63 ++-- 5 files changed, 201 insertions(+), 218 deletions(-) diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 4f38c317bdd..aecc912b500 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -593,6 +593,11 @@ addBigSwitchVnsDevice=1 deleteBigSwitchVnsDevice=1 listBigSwitchVnsDevices=1 +#### stratosphere ssp commands + +addStratosphereSsp=1 +deleteStratoshereSsp=1 + #### host simulator commands configureSimulator=1 diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java index 3ab5204be0e..c0db92ccab0 100644 --- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java +++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java @@ -17,26 +17,33 @@ package org.apache.cloudstack.network.element; import java.io.IOException; +import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Arrays; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.HttpConnectionManager; -import org.apache.commons.httpclient.HttpException; -import org.apache.commons.httpclient.HttpMethod; -import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; -import org.apache.commons.httpclient.URIException; -import org.apache.commons.httpclient.cookie.CookiePolicy; -import org.apache.commons.httpclient.methods.DeleteMethod; -import org.apache.commons.httpclient.methods.EntityEnclosingMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.PutMethod; -import org.apache.commons.httpclient.methods.RequestEntity; -import org.apache.commons.httpclient.methods.StringRequestEntity; -import org.apache.commons.httpclient.params.HttpClientParams; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; +import org.apache.http.client.HttpClient; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.params.ClientPNames; +import org.apache.http.client.params.CookiePolicy; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.params.CoreConnectionPNames; import org.apache.log4j.Logger; import com.google.gson.Gson; +import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; /** @@ -44,117 +51,75 @@ import com.google.gson.annotations.SerializedName; */ public class SspClient { private static final Logger s_logger = Logger.getLogger(SspClient.class); - private static final HttpConnectionManager s_httpclient_manager = new MultiThreadedHttpConnectionManager(); - private static final HttpClientParams s_httpclient_params = new HttpClientParams(); + private static final HttpClient s_client = new DefaultHttpClient( + new PoolingClientConnectionManager()); static { - s_httpclient_params.setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY); + s_client.getParams() + .setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY) + .setParameter(CoreConnectionPNames.SO_TIMEOUT, 10000); } private final String apiUrl; private final String username; private final String password; - protected HttpClient client; - protected PostMethod postMethod; - protected DeleteMethod deleteMethod; - protected PutMethod putMethod; - public SspClient(String apiUrl, String username, String password) { super(); this.apiUrl = apiUrl; this.username = username; this.password = password; - client = new HttpClient(s_httpclient_params, s_httpclient_manager); - postMethod = new PostMethod(apiUrl); - deleteMethod = new DeleteMethod(apiUrl); - putMethod = new PutMethod(apiUrl); + } + + protected HttpClient getHttpClient() { // for mock test + return s_client; + } + + private HttpResponse innerExecuteMethod(HttpRequestBase req, String path) { + try { + URI base = new URI(apiUrl); + req.setURI(new URI(base.getScheme(), base.getUserInfo(), base.getHost(), + base.getPort(), path, null, null)); + } catch (URISyntaxException e) { + s_logger.error("invalid API URL " + apiUrl + " path " + path, e); + return null; + } + HttpResponse res = null; + try { + res = getHttpClient().execute(req); + s_logger.info("ssp api call:" + req + " status=" + res.getStatusLine()); + } catch (IOException e) { + s_logger.error("ssp api call failed: " + req, e); + } + return res; + } + + private HttpResponse executeMethod(HttpRequestBase req, String path) { + HttpResponse res = innerExecuteMethod(req, path); + if (res.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED && login()) { + req.reset(); + res = innerExecuteMethod(req, path); + } + return res; } public boolean login() { - PostMethod method = postMethod; - method.setPath("/ws.v1/login"); // NOTE: /ws.v1/login is correct - method.addParameter("username", username); - method.addParameter("password", password); + HttpPost method = new HttpPost(); + try { + method.setEntity(new UrlEncodedFormEntity(Arrays.asList( + new BasicNameValuePair("username", username), + new BasicNameValuePair("password", password)))); + } catch (UnsupportedEncodingException e) { + s_logger.error("invalid username or password", e); + return false; + } - try { - client.executeMethod(method); - } catch (HttpException e) { - s_logger.info("Login " + username + " to " + apiUrl + " failed", e); - return false; - } catch (IOException e) { - s_logger.info("Login " + username + " to " + apiUrl + " failed", e); - return false; - } finally { - method.releaseConnection(); - } - String apiCallPath = null; - try { - apiCallPath = method.getName() + " " + method.getURI().toString(); - } catch (URIException e) { - s_logger.error("method getURI failed", e); - } - s_logger.info("ssp api call:" + apiCallPath + " user=" + username + " status=" + method.getStatusLine()); - if (method.getStatusCode() == HttpStatus.SC_OK) { + HttpResponse res = this.innerExecuteMethod(method, "/ws.v1/login"); + if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { return true; } return false; } - private String executeMethod(HttpMethod method) { - String apiCallPath = null; - try { - apiCallPath = method.getName() + " " + method.getURI().toString(); - } catch (URIException e) { - s_logger.error("method getURI failed", e); - } - - String response = null; - try { - client.executeMethod(method); - response = method.getResponseBodyAsString(); - } catch (HttpException e) { - s_logger.error("ssp api call failed " + apiCallPath, e); - return null; - } catch (IOException e) { - s_logger.error("ssp api call failed " + apiCallPath, e); - return null; - } finally { - method.releaseConnection(); - } - - if (method.getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { - if (!login()) { - return null; - } - - try { - client.executeMethod(method); - response = method.getResponseBodyAsString(); - } catch (HttpException e) { - s_logger.error("ssp api call failed " + apiCallPath, e); - return null; - } catch (IOException e) { - s_logger.error("ssp api call failed " + apiCallPath, e); - return null; - } finally { - method.releaseConnection(); - } - } - s_logger.info("ssp api call:" + apiCallPath + " user=" + username + " status=" + method.getStatusLine()); - if (method instanceof EntityEnclosingMethod) { - EntityEnclosingMethod emethod = (EntityEnclosingMethod)method; - RequestEntity reqEntity = emethod.getRequestEntity(); - if (reqEntity instanceof StringRequestEntity) { - StringRequestEntity strReqEntity = (StringRequestEntity)reqEntity; - s_logger.debug("ssp api request body:" + strReqEntity.getContent()); - } else { - s_logger.debug("ssp api request body:" + emethod.getRequestEntity()); - } - } - s_logger.debug("ssp api response body:" + response); - return response; - } - public class TenantNetwork { public String uuid; public String name; @@ -167,30 +132,31 @@ public class SspClient { req.name = networkName; req.tenantUuid = tenantUuid; - PostMethod method = postMethod; - method.setPath("/ssp.v1/tenant-networks"); - StringRequestEntity entity = null; - try { - entity = new StringRequestEntity(new Gson().toJson(req), "application/json", "UTF-8"); - } catch (UnsupportedEncodingException e) { - s_logger.error("failed creating http request body", e); + HttpPost method = new HttpPost(); + method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON)); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-networks"); + if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { return null; } - method.setRequestEntity(entity); - - String response = executeMethod(method); - if (response != null && method.getStatusCode() == HttpStatus.SC_CREATED) { - return new Gson().fromJson(response, TenantNetwork.class); + try { + return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent()), + TenantNetwork.class); + } catch (JsonSyntaxException e) { + s_logger.error("reading response body failed", e); + } catch (JsonIOException e) { + s_logger.error("reading response body failed", e); + } catch (IllegalStateException e) { + s_logger.error("reading response body failed", e); + } catch (IOException e) { + s_logger.error("reading response body failed", e); } return null; } public boolean deleteTenantNetwork(String tenantNetworkUuid) { - DeleteMethod method = deleteMethod; - method.setPath("/ssp.v1/tenant-networks/" + tenantNetworkUuid); - - executeMethod(method); - if (method.getStatusCode() == HttpStatus.SC_NO_CONTENT) { + HttpDelete method = new HttpDelete(); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-networks/" + tenantNetworkUuid); + if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) { return true; } return false; @@ -214,30 +180,33 @@ public class SspClient { req.networkUuid = tenantNetworkUuid; req.attachmentType = "NoAttachment"; - PostMethod method = postMethod; - method.setPath("/ssp.v1/tenant-ports"); - StringRequestEntity entity = null; - try { - entity = new StringRequestEntity(new Gson().toJson(req), "application/json", "UTF-8"); - } catch (UnsupportedEncodingException e) { - s_logger.error("failed creating http request body", e); + HttpPost method = new HttpPost(); + method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON)); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports"); + + if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_CREATED) { return null; } - method.setRequestEntity(entity); - - String response = executeMethod(method); - if (response != null && method.getStatusCode() == HttpStatus.SC_CREATED) { - return new Gson().fromJson(response, TenantPort.class); + try { + return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent()), + TenantPort.class); + } catch (JsonSyntaxException e) { + s_logger.error("reading response body failed", e); + } catch (JsonIOException e) { + s_logger.error("reading response body failed", e); + } catch (IllegalStateException e) { + s_logger.error("reading response body failed", e); + } catch (IOException e) { + s_logger.error("reading response body failed", e); } return null; } public boolean deleteTenantPort(String tenantPortUuid) { - DeleteMethod method = deleteMethod; - method.setPath("/ssp.v1/tenant-ports/" + tenantPortUuid); + HttpDelete method = new HttpDelete(); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports/" + tenantPortUuid); - executeMethod(method); - if (method.getStatusCode() == HttpStatus.SC_NO_CONTENT) { + if (res != null && res.getStatusLine().getStatusCode() == HttpStatus.SC_NO_CONTENT) { return true; } return false; @@ -252,20 +221,23 @@ public class SspClient { req.attachmentType = "NoAttachment"; } - PutMethod method = putMethod; - method.setPath("/ssp.v1/tenant-ports/" + portUuid); - StringRequestEntity entity = null; - try { - entity = new StringRequestEntity(new Gson().toJson(req), "application/json", "UTF-8"); - } catch (UnsupportedEncodingException e) { - s_logger.error("failed creating http request body", e); + HttpPut method = new HttpPut(); + method.setEntity(new StringEntity(new Gson().toJson(req), ContentType.APPLICATION_JSON)); + HttpResponse res = executeMethod(method, "/ssp.v1/tenant-ports/" + portUuid); + if (res == null || res.getStatusLine().getStatusCode() != HttpStatus.SC_OK) { return null; } - method.setRequestEntity(entity); - - String response = executeMethod(method); - if (response != null && method.getStatusCode() == HttpStatus.SC_OK) { - return new Gson().fromJson(response, TenantPort.class); + try { + return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent()), + TenantPort.class); + } catch (JsonSyntaxException e) { + s_logger.error("reading response body failed", e); + } catch (JsonIOException e) { + s_logger.error("reading response body failed", e); + } catch (IllegalStateException e) { + s_logger.error("reading response body failed", e); + } catch (IOException e) { + s_logger.error("reading response body failed", e); } return null; } diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java index 173d6f0de9e..b41be40b4e9 100644 --- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java +++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspElement.java @@ -92,6 +92,7 @@ import com.cloud.vm.dao.NicDao; public class SspElement extends AdapterBase implements ConnectivityProvider, SspManager, SspService, NetworkMigrationResponder { private static final Logger s_logger = Logger.getLogger(SspElement.class); public static final String s_SSP_NAME = "StratosphereSsp"; + private static final Provider s_ssp_provider = new Provider(s_SSP_NAME, false); @Inject NetworkServiceMapDao _ntwkSrvcDao; @@ -134,15 +135,7 @@ public class SspElement extends AdapterBase implements ConnectivityProvider, Ssp @Override public Provider getProvider() { - Provider provider = null; - synchronized (s_SSP_NAME) { - provider = Provider.getProvider(s_SSP_NAME); - if (provider == null) { - provider = new Provider(s_SSP_NAME, true); - s_logger.debug("registering Network.Provider " + s_SSP_NAME); - } - } - return provider; + return s_ssp_provider; } private List fetchSspClients(Long physicalNetworkId, Long dataCenterId, boolean enabledOnly) { @@ -187,14 +180,10 @@ public class SspElement extends AdapterBase implements ConnectivityProvider, Ssp public boolean isReady(PhysicalNetworkServiceProvider provider) { PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(provider.getPhysicalNetworkId()); assert (physicalNetwork != null); - if (physicalNetwork != null) { - if (fetchSspClients(physicalNetwork.getId(), physicalNetwork.getDataCenterId(), false).size() > 0) { - return true; - } - s_logger.warn("Ssp api endpoint not found. " + physicalNetwork.toString()); - } else { - s_logger.warn("PhysicalNetwork is NULL."); + if (fetchSspClients(physicalNetwork.getId(), physicalNetwork.getDataCenterId(), false).size() > 0) { + return true; } + s_logger.warn("Ssp api endpoint not found. " + physicalNetwork.toString()); return false; } diff --git a/plugins/network-elements/stratosphere-ssp/sspmock/sspmock.py b/plugins/network-elements/stratosphere-ssp/sspmock/sspmock.py index 5e7e61067c6..9ac646e244e 100644 --- a/plugins/network-elements/stratosphere-ssp/sspmock/sspmock.py +++ b/plugins/network-elements/stratosphere-ssp/sspmock/sspmock.py @@ -17,7 +17,8 @@ import json import uuid -from flask import Flask +from flask import Flask,request,make_response +from beaker.middleware import SessionMiddleware app = Flask(__name__) tenant_networks = [] @@ -25,50 +26,59 @@ tenant_ports = [] @app.route("/ws.v1/login", methods=["POST",]) def login(): - response.content_type = "application/json" - return "" + assert "username" in request.form + assert "password" in request.form + request.environ["beaker.session"]["login"] = True + res = make_response("", 200) + res.headers["Content-type"] = "application/json" + return res @app.route("/ssp.v1/tenant-networks", methods=["POST",]) def create_tenant_network(): - response.content_type = "application/json" - response.status = 201 + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) obj = request.json obj["uuid"] = str(uuid.uuid1()) tenant_networks.append(obj) - return json.dumps(obj) + res = make_response(json.dumps(obj), 201) + res.headers["Content-type"] = "application/json" + return res @app.route("/ssp.v1/tenant-networks/", methods=["DELETE",]) def delete_tenant_network(tenant_net_uuid): + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) for net in tenant_networks: if net["uuid"] == tenant_net_uuid: tenant_networks.remove(net) - response.status = 204 - return "" - response.status = 404 - return "" + return make_response("", 204) + return make_response("", 404) @app.route("/ssp.v1/tenant-ports", methods=["POST",]) def create_tenant_port(): - response.content_type = "application/json" - response.status = 201 + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) obj = request.json obj["uuid"] = str(uuid.uuid1()) tenant_ports.append(obj) - return json.dumps(obj) + res = make_response(json.dumps(obj), 201) + res.headers["Content-type"] = "application/json" + return res @app.route("/ssp.v1/tenant-ports/", methods=["DELETE",]) def delete_tenant_port(tenant_port_uuid): + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) for port in tenant_ports: if port["uuid"] == tenant_port_uuid: tenant_ports.remove(port) - response.status = 204 - return "" - response.status = 404 - return "" + return make_response("", 204) + return make_response("", 404) @app.route("/ssp.v1/tenant-ports/", methods=["PUT",]) def update_tenant_port(tenant_port_uuid): - response.content_type = "application/json" + if "login" not in request.environ["beaker.session"]: + return make_response("", 401) for port in tenant_ports: if port["uuid"] == tenant_port_uuid: obj = request.json @@ -76,10 +86,14 @@ def update_tenant_port(tenant_port_uuid): obj["vlan_id"] = 100 tenant_ports.remove(port) tenant_ports.append(obj) - response.status = 200 - return json.dumps(obj) - response.status = 404 - return "" + res = make_response(json.dumps(obj), 200) + res.headers["Content-type"] = "application/json" + return res + return make_response("", 404) if __name__=="__main__": + app.wsgi_app = SessionMiddleware(app.wsgi_app, { + "session.auto":True, + "session.type":"cookie", + "session.validate_key":"hoge"}) app.run(host="0.0.0.0", port=9080, debug=True) diff --git a/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java b/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java index 2cff927e287..627cc878f59 100644 --- a/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java +++ b/plugins/network-elements/stratosphere-ssp/test/org/apache/cloudstack/network/element/SspClientTest.java @@ -20,46 +20,37 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; +import java.io.ByteArrayInputStream; import java.util.UUID; -import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpStatus; -import org.apache.commons.httpclient.URI; -import org.apache.commons.httpclient.methods.DeleteMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpUriRequest; import org.junit.Test; public class SspClientTest { - HttpClient _client = mock(HttpClient.class); - PostMethod _postMethod = mock(PostMethod.class); - PutMethod _putMethod = mock(PutMethod.class); - DeleteMethod _deleteMethod = mock(DeleteMethod.class); - String uuid = UUID.randomUUID().toString(); String apiUrl = "http://a.example.jp/"; String username = "foo"; String password = "bar"; - SspClient sspClient = new SspClient(apiUrl, username, password) { - { - client = _client; - postMethod = _postMethod; - putMethod = _putMethod; - deleteMethod = _deleteMethod; - } - }; - - @SuppressWarnings("deprecation") - private URI getUri() throws Exception { - return new URI(apiUrl); - } @Test public void loginTest() throws Exception { - when(_postMethod.getURI()).thenReturn(getUri()); - when(_postMethod.getStatusCode()).thenReturn(HttpStatus.SC_OK); + SspClient sspClient = spy(new SspClient(apiUrl, username, password)); + + HttpClient client = mock(HttpClient.class); + HttpResponse res = mock(HttpResponse.class, RETURNS_DEEP_STUBS); + doReturn(client).when(sspClient).getHttpClient(); + when(client.execute(any(HttpUriRequest.class))).thenReturn(res); + when(res.getStatusLine().getStatusCode()).thenReturn(HttpStatus.SC_OK); + assertTrue(sspClient.login()); assertTrue(sspClient.login()); assertTrue(sspClient.login()); @@ -69,10 +60,18 @@ public class SspClientTest { public void createNetworkTest() throws Exception { String networkName = "example network 1"; String tenant_net_uuid = UUID.randomUUID().toString(); + SspClient sspClient = spy(new SspClient(apiUrl, username, password)); + + HttpClient client = mock(HttpClient.class); + HttpResponse res = mock(HttpResponse.class, RETURNS_DEEP_STUBS); + doReturn(client).when(sspClient).getHttpClient(); + when(client.execute(any(HttpUriRequest.class))).thenReturn(res); + when(res.getStatusLine().getStatusCode()).thenReturn(HttpStatus.SC_CREATED); + String body = "{\"uuid\":\"" + tenant_net_uuid + "\",\"name\":\"" + networkName + + "\",\"tenant_uuid\":\"" + uuid + "\"}"; + when(res.getEntity().getContent()).thenReturn( + new ByteArrayInputStream(body.getBytes("UTF-8"))); - when(_postMethod.getURI()).thenReturn(getUri()); - when(_postMethod.getStatusCode()).thenReturn(HttpStatus.SC_CREATED); - when(_postMethod.getResponseBodyAsString()).thenReturn("{\"uuid\":\"" + tenant_net_uuid + "\",\"name\":\"" + networkName + "\",\"tenant_uuid\":\"" + uuid + "\"}"); SspClient.TenantNetwork tnet = sspClient.createTenantNetwork(uuid, networkName); assertEquals(tnet.name, networkName); assertEquals(tnet.uuid, tenant_net_uuid); @@ -82,9 +81,13 @@ public class SspClientTest { @Test public void deleteNetworkTest() throws Exception { String tenant_net_uuid = UUID.randomUUID().toString(); + SspClient sspClient = spy(new SspClient(apiUrl, username, password)); - when(_deleteMethod.getURI()).thenReturn(getUri()); - when(_deleteMethod.getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); + HttpClient client = mock(HttpClient.class); + HttpResponse res = mock(HttpResponse.class, RETURNS_DEEP_STUBS); + doReturn(client).when(sspClient).getHttpClient(); + when(client.execute(any(HttpUriRequest.class))).thenReturn(res); + when(res.getStatusLine().getStatusCode()).thenReturn(HttpStatus.SC_NO_CONTENT); sspClient.deleteTenantNetwork(tenant_net_uuid); } From 06f79a881cce6e502a58aefa16a9068bced23b1f Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Thu, 30 Jan 2014 18:01:28 +0530 Subject: [PATCH 105/126] CLOUDSTACK-5994. Hitting IndexOutOfBoundsException in GetVmStatsCommand after upgrade. To obtain network read/write statistics, multiply sample duration with the average of the particular performance metric obtained over the sample period. --- .../cloud/hypervisor/vmware/resource/VmwareResource.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 407327592bc..c609686efa1 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -5290,11 +5290,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vals.get(vi) instanceof PerfMetricIntSeries) { PerfMetricIntSeries val = (PerfMetricIntSeries)vals.get(vi); List perfValues = val.getValue(); + Long sumRate = 0L; + for (int j = 0; j < infos.size(); j++) { // Size of the array matches the size as the PerfSampleInfo + sumRate += perfValues.get(j); + } + Long averageRate = sumRate / infos.size(); if (vals.get(vi).getId().getCounterId() == rxPerfCounterInfo.getKey()) { - networkReadKBs = sampleDuration * perfValues.get(3); //get the average RX rate multiplied by sampled duration + networkReadKBs = sampleDuration * averageRate; //get the average RX rate multiplied by sampled duration } if (vals.get(vi).getId().getCounterId() == txPerfCounterInfo.getKey()) { - networkWriteKBs = sampleDuration * perfValues.get(3);//get the average TX rate multiplied by sampled duration + networkWriteKBs = sampleDuration * averageRate;//get the average TX rate multiplied by sampled duration } } } From 13e6c2fe72f591fbfb224e660b1e98421d9ae084 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 30 Jan 2014 10:42:52 -0800 Subject: [PATCH 106/126] Fixed API doc that got broken by adding new commands for stratosphere ssp plugin Conflicts: tools/apidoc/gen_toc.py --- tools/apidoc/gen_toc.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index 01261518aff..29ff3bf441b 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -6,9 +6,9 @@ # 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 @@ -126,7 +126,7 @@ known_categories = { 'Project': 'Project', 'Lun': 'Storage', 'Pool': 'Pool', - 'VPC': 'VPC', + 'VPC': 'VPC', 'PrivateGateway': 'VPC', 'Simulator': 'simulator', 'StaticRoute': 'VPC', @@ -160,7 +160,8 @@ known_categories = { 'Ucs' : 'UCS', 'CacheStores' : 'Cache Stores', 'CacheStore' : 'Cache Store', - 'OvsElement' : 'Ovs Element' + 'OvsElement' : 'Ovs Element', + 'StratosphereSsp' : ' Stratosphere SSP' } @@ -205,7 +206,7 @@ for f in sys.argv: pass except IndexError, e: print fn - + def xml_for(command): name = command['name'] @@ -220,7 +221,7 @@ def xml_for(command): def write_xml(out, user): with file(out, 'w') as f: cat_strings = [] - + for category in categories.keys(): strings = [] for command in categories[category]: @@ -242,7 +243,7 @@ def write_xml(out, user): %(all_strings)s - +
''' % locals() @@ -268,7 +269,7 @@ def java_for_user(user): for command in categories[category]: if command['user'] == user: strings.append(java_for(command, user)) - func = user_to_func[user] + func = user_to_func[user] all_strings = ''.join(strings) return ''' public void %(func)s() { From cb073e063450097f348fd2afd4006487ca99919a Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 30 Jan 2014 11:57:12 -0800 Subject: [PATCH 107/126] listAutoscaleVmProfiles: added zoneId to the list of optional api parameters --- .../user/autoscale/ListAutoScaleVmProfilesCmd.java | 8 ++++++++ server/src/com/cloud/network/as/AutoScaleManagerImpl.java | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java index 34c2543b9c6..5b4a46eef59 100644 --- a/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/autoscale/ListAutoScaleVmProfilesCmd.java @@ -27,6 +27,7 @@ import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.TemplateResponse; +import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.log4j.Logger; import com.cloud.network.as.AutoScaleVmProfile; @@ -53,6 +54,9 @@ public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourc @Parameter(name = ApiConstants.OTHER_DEPLOY_PARAMS, type = CommandType.STRING, description = "the otherdeployparameters of the autoscale vm profile") private String otherDeployParams; + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, since = "4.4", description = "availability zone for the auto deployed virtual machine") + private Long zoneId; + // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// @@ -73,10 +77,14 @@ public class ListAutoScaleVmProfilesCmd extends BaseListProjectAndAccountResourc return serviceOffId; } + public Long getZoneId() { + return zoneId; + } // /////////////////////////////////////////////////// // ///////////// API Implementation/////////////////// // /////////////////////////////////////////////////// + @Override public String getCommandName() { return s_name; diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 7492c9ace6b..7eeec9c4e75 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -438,6 +438,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale Long templateId = cmd.getTemplateId(); String otherDeployParams = cmd.getOtherDeployParams(); Long serviceOffId = cmd.getServiceOfferingId(); + Long zoneId = cmd.getZoneId(); SearchWrapper searchWrapper = new SearchWrapper(_autoScaleVmProfileDao, AutoScaleVmProfileVO.class, cmd, cmd.getId()); SearchBuilder sb = searchWrapper.getSearchBuilder(); @@ -446,6 +447,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ); sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ); sb.and("otherDeployParams", sb.entity().getOtherDeployParams(), SearchCriteria.Op.LIKE); + sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.LIKE); SearchCriteria sc = searchWrapper.buildSearchCriteria(); if (id != null) { @@ -462,6 +464,10 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale sc.setParameters("serviceOfferingId", serviceOffId); } + if (zoneId != null) { + sc.setParameters("zoneId", zoneId); + } + return searchWrapper.search(); } From 02bdb28d767931c7dd1115902a9a83d2f015085d Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 30 Jan 2014 13:00:00 -0800 Subject: [PATCH 108/126] Resource metadata support for autoscale vm group object --- api/src/com/cloud/server/ResourceTag.java | 3 +- ...spring-engine-schema-core-daos-context.xml | 1 + .../AutoScaleVmGroupDetailVO.java | 81 +++++++++++++++++++ .../dao/AutoScaleVmGroupDetailsDao.java | 26 ++++++ .../dao/AutoScaleVmGroupDetailsDaoImpl.java | 33 ++++++++ .../metadata/ResourceMetaDataManagerImpl.java | 4 + .../network/as/AutoScaleManagerImpl.java | 2 +- .../cloud/tags/TaggedResourceManagerImpl.java | 2 + setup/db/db/schema-430to440.sql | 10 +++ 9 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java create mode 100644 engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index a08c3e4fede..275510e1a1a 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -52,7 +52,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit VpnConnection(false, true), User(true, true), DiskOffering(false, true), - AutoScaleVmProfile(false, true); + AutoScaleVmProfile(false, true), + AutoScaleVmGroup(false, true); ResourceObjectType(boolean resourceTagsSupport, boolean resourceMetadataSupport) { this.resourceTagsSupport = resourceTagsSupport; diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index d1a68ede322..08efb8345f5 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -332,6 +332,7 @@ + diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java new file mode 100644 index 00000000000..a657caa7d98 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/AutoScaleVmGroupDetailVO.java @@ -0,0 +1,81 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.resourcedetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "autoscale_vmgroup_details") +public class AutoScaleVmGroupDetailVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "autoscale_vmgroup_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display; + + public AutoScaleVmGroupDetailVO() { + } + + public AutoScaleVmGroupDetailVO(long id, String name, String value) { + this.resourceId = id; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } +} \ No newline at end of file diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java new file mode 100644 index 00000000000..6e20e5ae2ca --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDao.java @@ -0,0 +1,26 @@ +// 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 org.apache.cloudstack.resourcedetail.dao; + +import org.apache.cloudstack.resourcedetail.AutoScaleVmGroupDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import com.cloud.utils.db.GenericDao; + +public interface AutoScaleVmGroupDetailsDao extends GenericDao, ResourceDetailsDao { + +} diff --git a/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.java new file mode 100644 index 00000000000..b4c82bc06a1 --- /dev/null +++ b/engine/schema/src/org/apache/cloudstack/resourcedetail/dao/AutoScaleVmGroupDetailsDaoImpl.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 org.apache.cloudstack.resourcedetail.dao; + +import javax.ejb.Local; + +import org.apache.cloudstack.resourcedetail.AutoScaleVmGroupDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +@Local(value = {AutoScaleVmGroupDetailsDao.class}) +public class AutoScaleVmGroupDetailsDaoImpl extends ResourceDetailsDaoBase implements AutoScaleVmGroupDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value) { + super.addDetail(new AutoScaleVmGroupDetailVO(resourceId, key, value)); + } +} \ No newline at end of file diff --git a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java index 5393a6a6b3f..17b489510aa 100644 --- a/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java +++ b/server/src/com/cloud/metadata/ResourceMetaDataManagerImpl.java @@ -26,6 +26,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.ResourceDetail; import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; +import org.apache.cloudstack.resourcedetail.dao.AutoScaleVmGroupDetailsDao; import org.apache.cloudstack.resourcedetail.dao.AutoScaleVmProfileDetailsDao; import org.apache.cloudstack.resourcedetail.dao.DiskOfferingDetailsDao; import org.apache.cloudstack.resourcedetail.dao.FirewallRuleDetailsDao; @@ -110,6 +111,8 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource UserDetailsDao _userDetailsDao; @Inject AutoScaleVmProfileDetailsDao _autoScaleVmProfileDetailsDao; + @Inject + AutoScaleVmGroupDetailsDao _autoScaleVmGroupDetailsDao; private static Map> s_daoMap = new HashMap>(); @@ -138,6 +141,7 @@ public class ResourceMetaDataManagerImpl extends ManagerBase implements Resource s_daoMap.put(ResourceObjectType.DiskOffering, _diskOfferingDetailsDao); s_daoMap.put(ResourceObjectType.User, _userDetailsDao); s_daoMap.put(ResourceObjectType.AutoScaleVmProfile, _autoScaleVmProfileDetailsDao); + s_daoMap.put(ResourceObjectType.AutoScaleVmGroup, _autoScaleVmGroupDetailsDao); return true; } diff --git a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java index 7eeec9c4e75..a2cc32ef219 100644 --- a/server/src/com/cloud/network/as/AutoScaleManagerImpl.java +++ b/server/src/com/cloud/network/as/AutoScaleManagerImpl.java @@ -447,7 +447,7 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScale sb.and("templateId", sb.entity().getTemplateId(), SearchCriteria.Op.EQ); sb.and("serviceOfferingId", sb.entity().getServiceOfferingId(), SearchCriteria.Op.EQ); sb.and("otherDeployParams", sb.entity().getOtherDeployParams(), SearchCriteria.Op.LIKE); - sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.LIKE); + sb.and("zoneId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); SearchCriteria sc = searchWrapper.buildSearchCriteria(); if (id != null) { diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 555a8452786..06746833800 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -39,6 +39,7 @@ import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.network.as.AutoScaleVmGroupVO; import com.cloud.network.as.AutoScaleVmProfileVO; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.LoadBalancerVO; @@ -117,6 +118,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso s_typeMap.put(ResourceObjectType.User, UserVO.class); s_typeMap.put(ResourceObjectType.DiskOffering, DiskOfferingVO.class); s_typeMap.put(ResourceObjectType.AutoScaleVmProfile, AutoScaleVmProfileVO.class); + s_typeMap.put(ResourceObjectType.AutoScaleVmGroup, AutoScaleVmGroupVO.class); } @Inject diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql index 8c45295de02..70f7352f896 100644 --- a/setup/db/db/schema-430to440.sql +++ b/setup/db/db/schema-430to440.sql @@ -457,3 +457,13 @@ CREATE TABLE `cloud`.`autoscale_vmprofile_details` ( PRIMARY KEY (`id`), CONSTRAINT `fk_autoscale_vmprofile_details__autoscale_vmprofile_id` FOREIGN KEY `fk_autoscale_vmprofile_details__autoscale_vmprofile_id`(`autoscale_vmprofile_id`) REFERENCES `autoscale_vmprofiles`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`autoscale_vmgroup_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `autoscale_vmgroup_id` bigint unsigned NOT NULL COMMENT 'VPC gateway id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `display` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'True if the detail can be displayed to the end autoscale_vmgroup', + PRIMARY KEY (`id`), + CONSTRAINT `fk_autoscale_vmgroup_details__autoscale_vmgroup_id` FOREIGN KEY `fk_autoscale_vmgroup_details__autoscale_vmgroup_id`(`autoscale_vmgroup_id`) REFERENCES `autoscale_vmgroups`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; From 41fd0a2ab7450005da574002d04d58971f32f47e Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 30 Jan 2014 22:58:52 +0100 Subject: [PATCH 109/126] findbugs equals on same type of objects --- awsapi/src/com/cloud/bridge/model/SObjectItemVO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awsapi/src/com/cloud/bridge/model/SObjectItemVO.java b/awsapi/src/com/cloud/bridge/model/SObjectItemVO.java index 5eada3c136d..77077c6a2b6 100644 --- a/awsapi/src/com/cloud/bridge/model/SObjectItemVO.java +++ b/awsapi/src/com/cloud/bridge/model/SObjectItemVO.java @@ -168,7 +168,7 @@ public class SObjectItemVO { } if (theObject.getId() != null) { - if (!theObject.getId().equals(((SObjectItemVO)other).getTheObject())) + if (!theObject.getId().equals(((SObjectItemVO)other).getTheObject().getId())) return false; } else { if (((SObjectItemVO)other).getTheObject() != null) From c6118ad92ea628423cebe5457d99bd24ed369f84 Mon Sep 17 00:00:00 2001 From: Daan Hoogland Date: Thu, 30 Jan 2014 23:16:24 +0100 Subject: [PATCH 110/126] findbugs bitwise or guaranteed positively bitfields --- .../cloud/bridge/io/DimeDelimitedInputStream.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java b/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java index 0f40c934de2..d901c53aebe 100644 --- a/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java +++ b/awsapi/src/com/cloud/bridge/io/DimeDelimitedInputStream.java @@ -354,13 +354,19 @@ public class DimeDelimitedInputStream extends FilterInputStream { } //OPTIONS_LENGTH - int optionsLength = ((((int)header[2]) << 8) & 0xff00) | ((int)header[3]); + int oneButLastByte = (((int)header[2]) << 8) & 0xff00; + int lastByte = (int)header[3] & 0xff; + int optionsLength = oneButLastByte | lastByte; //ID_LENGTH - int idLength = ((((int)header[4]) << 8) & 0xff00) | ((int)header[5]); + oneButLastByte = ((((int)header[4]) << 8) & 0xff00); + lastByte = ((int)header[5]) & 0xff; + int idLength = oneButLastByte | lastByte; //TYPE_LENGTH - int typeLength = ((((int)header[6]) << 8) & 0xff00) | ((int)header[7]); + oneButLastByte = ((((int)header[6]) << 8) & 0xff00); + lastByte = ((int)header[7]) & 0xff; + int typeLength = oneButLastByte | lastByte; //DATA_LENGTH recordLength = From d84a6937d7211db0d4b8d195b07854db2223da7e Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 30 Jan 2014 14:44:49 -0800 Subject: [PATCH 111/126] CLOUDSTACK-5996: UI - In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), because in project view, all API calls are appended with projectid=[projectID]. Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. --- ui/scripts/system.js | 95 +++++++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 27 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 4c0543ed8a0..955d391060a 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -325,7 +325,6 @@ virtualRouterCount: function (data) { var data2 = { - projectid: -1, page: 1, pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property. }; @@ -334,24 +333,35 @@ data: data2, success: function (json) { var total1 = json.listroutersresponse.count ? json.listroutersresponse.count: 0; + var total2 = 0; //reset + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view var data3 = { listAll: true, + projectid: -1, page: 1, pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property. }; $.ajax({ url: createURL('listRouters'), data: data3, + async: false, success: function (json) { - var total2 = json.listroutersresponse.count ? json.listroutersresponse.count: 0; + total2 = json.listroutersresponse.count ? json.listroutersresponse.count : 0; + } + }); + } + dataFns.capacity($.extend(data, { virtualRouterCount: (total1 + total2) })); } }); - } - }); }, capacity: function (data) { @@ -2356,10 +2366,16 @@ routers.push(item); }); - // Get project routers + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view $.ajax({ url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"), data: data2, + async: false, success: function (json) { var items = json.listroutersresponse.router ? json.listroutersresponse.router:[]; @@ -2367,14 +2383,16 @@ $(items).map(function (index, item) { routers.push(item); }); + } + }); + } + args.response.success({ actionFilter: routerActionfilter, data: $(routers).map(mapRouterType) }); } }); - } - }); }, detailView: { name: 'Virtual applicance details', @@ -3444,25 +3462,32 @@ routers.push(item); }); - // Get project routers + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view $.ajax({ url: createURL("listRouters&zoneid=" + selectedZoneObj.id + "&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"), dataType: 'json', data: data2, - async: true, + async: false, success: function (json) { var items = json.listroutersresponse.router; $(items).map(function (index, item) { routers.push(item); }); + } + }); + } + args.response.success({ actionFilter: routerActionfilter, data: $(routers).map(mapRouterType) }); } }); - } - }); }, detailView: { name: 'Virtual applicance details', @@ -8336,24 +8361,24 @@ routers.push(item); }); - //get project-owned routers - var toSearchByProjectid = true; + //if account is specified in advanced search, don't search project-owned routers + var accountIsNotSpecifiedInAdvSearch = true; if (args.filterBy != null) { - if (args.filterBy.advSearch != null && typeof (args.filterBy.advSearch) == "object") { - //advanced search - if ('account' in args.filterBy.advSearch && args.filterBy.advSearch.account.length > 0) { - //if account is specified in advanced search, don't search project-owned routers - toSearchByProjectid = false; //since account and projectid can't be specified together + if (args.filterBy.advSearch != null && typeof(args.filterBy.advSearch) == "object") { //advanced search + if ('account' in args.filterBy.advSearch && args.filterBy.advSearch.account.length > 0) { + accountIsNotSpecifiedInAdvSearch = false; //since account and projectid can't be specified together } } } - if (toSearchByProjectid) { + if (accountIsNotSpecifiedInAdvSearch) { + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view $.ajax({ - url: createURL('listRouters'), - data: $.extend(data, { - listAll: true, - projectid: -1 - }), + url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + "&projectid=-1"), async: false, success: function (json) { var items = json.listroutersresponse.router ? json.listroutersresponse.router:[]; @@ -8362,7 +8387,14 @@ }); } }); + } + } + + args.response.success({ + actionFilter: routerActionfilter, + data: $(routers).map(mapRouterType) + }); } }); @@ -8632,10 +8664,17 @@ $(items).map(function (index, item) { routers.push(item); }); - // Get project routers + + /* + * In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1), + * because in project view, all API calls are appended with projectid=[projectID]. + * Therefore, we only call the second listRouters API(with projectid=-1) in non-project view. + */ + if (cloudStack.context && cloudStack.context.projects == null) { //non-project view $.ajax({ url: createURL("listRouters&listAll=true&page=" + args.page + "&pagesize=" + pageSize + array1.join("") + "&projectid=-1"), data: data2, + async: false, success: function (json) { var items = json.listroutersresponse.router ? json.listroutersresponse.router:[]; @@ -8643,14 +8682,16 @@ $(items).map(function (index, item) { routers.push(item); }); + } + }); + } + args.response.success({ actionFilter: routerActionfilter, data: $(routers).map(mapRouterType) }); } }); - } - }); }, detailView: { name: 'Virtual applicance details', From 0e2e6995b7ae92c253c1fcea0d7e3fb93689f827 Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Thu, 30 Jan 2014 17:59:55 -0800 Subject: [PATCH 112/126] CLOUDSTACK-5997: Template state changes side affects --- .../cloud/storage/dao/VMTemplateDaoImpl.java | 31 ++++++++++++------- .../template/HypervisorTemplateAdapter.java | 18 ++++++----- .../cloud/template/TemplateManagerImpl.java | 6 ---- setup/db/db/schema-421to430.sql | 2 +- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 9a22466c99e..aab32560717 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -28,6 +28,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.template.VirtualMachineTemplate; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -147,7 +148,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sb.and("format", sb.entity().getFormat(), SearchCriteria.Op.EQ); sb.and("type", sb.entity().getTemplateType(), SearchCriteria.Op.EQ); sb.and("bootable", sb.entity().isBootable(), SearchCriteria.Op.EQ); - sb.and("removed", sb.entity().getRemoved(), SearchCriteria.Op.EQ); + sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); SearchBuilder tagSearch = _tagsDao.createSearchBuilder(); for (int count = 0; count < tags.size(); count++) { @@ -170,7 +171,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } if (!listRemoved) { - sc.setParameters("removed", (Object)null); + sc.setParameters("state", VirtualMachineTemplate.State.Active); } if (tags != null && !tags.isEmpty()) { @@ -197,7 +198,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sc.setParameters("type", TemplateType.USER.toString()); if (!listRemoved) { - sc.setParameters("removed", (Object)null); + sc.setParameters("state", VirtualMachineTemplate.State.Active); } return listBy(sc); @@ -217,7 +218,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem String sql = "select * from template_host_ref as thr INNER JOIN vm_template as t ON t.id=thr.template_id " - + "where thr.host_id=? and t.public=0 and t.featured=0 and t.type='USER' and t.removed is NULL"; + + "where thr.host_id=? and t.public=0 and t.featured=0 and t.type='USER' and t.state='Active'"; List l = new ArrayList(); @@ -265,6 +266,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public List listByAccountId(long accountId) { SearchCriteria sc = AccountIdSearch.create(); sc.setParameters("accountId", accountId); + sc.setParameters("state", VirtualMachineTemplate.State.Active); return listBy(sc); } @@ -312,12 +314,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem PublicIsoSearch.and("format", PublicIsoSearch.entity().getFormat(), SearchCriteria.Op.EQ); PublicIsoSearch.and("type", PublicIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); PublicIsoSearch.and("bootable", PublicIsoSearch.entity().isBootable(), SearchCriteria.Op.EQ); - PublicIsoSearch.and("removed", PublicIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ); + PublicIsoSearch.and("state", PublicIsoSearch.entity().getState(), SearchCriteria.Op.EQ); UserIsoSearch = createSearchBuilder(); UserIsoSearch.and("format", UserIsoSearch.entity().getFormat(), SearchCriteria.Op.EQ); UserIsoSearch.and("type", UserIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); - UserIsoSearch.and("removed", UserIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ); + UserIsoSearch.and("state", UserIsoSearch.entity().getState(), SearchCriteria.Op.EQ); tmpltTypeHyperSearch = createSearchBuilder(); tmpltTypeHyperSearch.and("templateType", tmpltTypeHyperSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); @@ -332,7 +334,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem tmpltTypeHyperSearch.done(); readySystemTemplateSearch = createSearchBuilder(); - readySystemTemplateSearch.and("removed", readySystemTemplateSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + readySystemTemplateSearch.and("state", readySystemTemplateSearch.entity().getState(), SearchCriteria.Op.EQ); readySystemTemplateSearch.and("templateType", readySystemTemplateSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); SearchBuilder templateDownloadSearch = _templateDataStoreDao.createSearchBuilder(); templateDownloadSearch.and("downloadState", templateDownloadSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); @@ -355,13 +357,13 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem tmpltTypeHyperSearch2.and("templateName", tmpltTypeHyperSearch2.entity().getName(), SearchCriteria.Op.EQ); tmpltTypeSearch = createSearchBuilder(); - tmpltTypeSearch.and("removed", tmpltTypeSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + tmpltTypeSearch.and("state", tmpltTypeSearch.entity().getState(), SearchCriteria.Op.EQ); tmpltTypeSearch.and("templateType", tmpltTypeSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); AccountIdSearch = createSearchBuilder(); AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountIdSearch.and("publicTemplate", AccountIdSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ); - AccountIdSearch.and("removed", AccountIdSearch.entity().getRemoved(), SearchCriteria.Op.NULL); // only list not removed templates for this account + AccountIdSearch.and("state", AccountIdSearch.entity().getState(), SearchCriteria.Op.EQ); // only list not removed templates for this account AccountIdSearch.done(); SearchBuilder tmpltZoneSearch = _templateZoneDao.createSearchBuilder(); @@ -369,7 +371,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem tmpltZoneSearch.and("zoneId", tmpltZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ); TmpltsInZoneSearch = createSearchBuilder(); - TmpltsInZoneSearch.and("removed", TmpltsInZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + TmpltsInZoneSearch.and("state", TmpltsInZoneSearch.entity().getState(), SearchCriteria.Op.EQ); TmpltsInZoneSearch.and().op("avoidtype", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NEQ); TmpltsInZoneSearch.or("templateType", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NULL); TmpltsInZoneSearch.cp(); @@ -378,12 +380,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem TmpltsInZoneSearch.done(); ActiveTmpltSearch = createSearchBuilder(); - ActiveTmpltSearch.and("removed", ActiveTmpltSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + ActiveTmpltSearch.and("state", ActiveTmpltSearch.entity().getState(), SearchCriteria.Op.EQ); CountTemplatesByAccount = createSearchBuilder(Long.class); CountTemplatesByAccount.select(null, Func.COUNT, null); CountTemplatesByAccount.and("account", CountTemplatesByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); - CountTemplatesByAccount.and("removed", CountTemplatesByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); + CountTemplatesByAccount.and("state", CountTemplatesByAccount.entity().getState(), SearchCriteria.Op.EQ); CountTemplatesByAccount.done(); // updateStateSearch = this.createSearchBuilder(); @@ -774,6 +776,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public List listAllInZone(long dataCenterId) { SearchCriteria sc = TmpltsInZoneSearch.create(); sc.setParameters("avoidtype", TemplateType.PERHOST.toString()); + sc.setParameters("state", VirtualMachineTemplate.State.Active); sc.setJoinParameters("tmpltzone", "zoneId", dataCenterId); return listBy(sc); } @@ -781,6 +784,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override public List listAllActive() { SearchCriteria sc = ActiveTmpltSearch.create(); + sc.setParameters("state", VirtualMachineTemplate.State.Active.toString()); return listBy(sc); } @@ -788,6 +792,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public List listDefaultBuiltinTemplates() { SearchCriteria sc = tmpltTypeSearch.create(); sc.setParameters("templateType", Storage.TemplateType.BUILTIN); + sc.setParameters("state", VirtualMachineTemplate.State.Active); return listBy(sc); } @@ -813,6 +818,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public VMTemplateVO findSystemVMReadyTemplate(long zoneId, HypervisorType hypervisorType) { SearchCriteria sc = readySystemTemplateSearch.create(); sc.setParameters("templateType", Storage.TemplateType.SYSTEM); + sc.setParameters("state", VirtualMachineTemplate.State.Active); sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing); sc.setJoinParameters("tmplHyper", "zoneId", zoneId); sc.setJoinParameters("vmTemplateJoinTemplateStoreRef", "downloadState", VMTemplateStorageResourceAssoc.Status.DOWNLOADED); @@ -873,6 +879,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem public Long countTemplatesForAccount(long accountId) { SearchCriteria sc = CountTemplatesByAccount.create(); sc.setParameters("account", accountId); + sc.setParameters("state", VirtualMachineTemplate.State.Active.toString()); return customSearch(sc, null).get(0); } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 25e79db2bbe..96bf9a34703 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -382,14 +382,16 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { // find all eligible image stores for this template List iStores = templateMgr.getImageStoreByTemplate(template.getId(), null); if (iStores == null || iStores.size() == 0) { - // remove template from vm_templates table - if (_tmpltDao.remove(template.getId())) { - // Decrement the number of templates and total secondary storage - // space used by the account - Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); - _resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template); - _resourceLimitMgr.recalculateResourceCount(template.getAccountId(), account.getDomainId(), ResourceType.secondary_storage.getOrdinal()); - } + // Mark template as Inactive. + template.setState(VirtualMachineTemplate.State.Inactive); + _tmpltDao.update(template.getId(), template); + + // Decrement the number of templates and total secondary storage + // space used by the account + Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); + _resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template); + _resourceLimitMgr.recalculateResourceCount(template.getAccountId(), account.getDomainId(), ResourceType.secondary_storage.getOrdinal()); + } } return success; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 56232d27609..c2ce344f78c 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1084,9 +1084,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Please specify a valid template."); } - template.setState(VirtualMachineTemplate.State.Inactive); - _tmpltDao.update(template.getId(), template); - TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateProfile profile = adapter.prepareDelete(cmd); return adapter.delete(profile); @@ -1119,9 +1116,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone."); } - template.setState(VirtualMachineTemplate.State.Inactive); - _tmpltDao.update(template.getId(), template); - TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateProfile profile = adapter.prepareDelete(cmd); boolean result = adapter.delete(profile); diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql index afad06c128f..a0c45062736 100644 --- a/setup/db/db/schema-421to430.sql +++ b/setup/db/db/schema-421to430.sql @@ -299,7 +299,7 @@ CREATE VIEW `cloud`.`template_view` AS left join `cloud`.`vm_template` source_template ON source_template.id = vm_template.source_template_id left join - `cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id and template_store_ref.store_role = 'Image' + `cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id and template_store_ref.store_role = 'Image' and template_store_ref.destroyed=0 left join `cloud`.`image_store` ON image_store.removed is NULL AND template_store_ref.store_id is not NULL AND image_store.id = template_store_ref.store_id left join From ed3e1b95b01ed5f84619c2bb1fed816b71528551 Mon Sep 17 00:00:00 2001 From: sbalineni Date: Wed, 8 Jan 2014 03:16:55 +0000 Subject: [PATCH 113/126] VPC Support for contrail networking Signed-off-by: Sheng Yang --- api/src/com/cloud/network/Network.java | 1 + .../contrail/spring-contrail-context.xml | 4 + .../contrail/management/ContrailGuru.java | 24 ++- .../contrail/management/ContrailManager.java | 11 + .../management/ContrailManagerImpl.java | 121 ++++++++++- .../management/ContrailVpcElementImpl.java | 199 ++++++++++++++++++ .../contrail/management/ServerDBSyncImpl.java | 18 +- .../contrail/model/NetworkPolicyModel.java | 2 +- .../ConfigurationManagerImpl.java | 4 +- .../com/cloud/network/vpc/VpcManagerImpl.java | 4 +- 10 files changed, 374 insertions(+), 14 deletions(-) create mode 100644 plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 62151a4f0c0..6dc67521663 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -113,6 +113,7 @@ public interface Network extends ControlledEntity, StateObject, I public static final Provider VirtualRouter = new Provider("VirtualRouter", false); public static final Provider JuniperContrailRouter = new Provider("JuniperContrailRouter", false); + public static final Provider JuniperContrailVpcRouter = new Provider("JuniperContrailVpcRouter", false); public static final Provider JuniperSRX = new Provider("JuniperSRX", true); public static final Provider PaloAlto = new Provider("PaloAlto", true); public static final Provider F5BigIp = new Provider("F5BigIp", true); diff --git a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml index 4614af79a4b..99ab02ea84b 100644 --- a/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml +++ b/plugins/network-elements/juniper-contrail/resources/META-INF/cloudstack/contrail/spring-contrail-context.xml @@ -32,6 +32,10 @@ class="org.apache.cloudstack.network.contrail.management.ContrailElementImpl"> + + + diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java index 704dedd4a3c..0bb95dd81cb 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.network.contrail.management; import java.io.IOException; import java.net.URI; +import java.util.List; import javax.inject.Inject; import javax.ejb.Local; @@ -54,6 +55,8 @@ import com.cloud.network.guru.NetworkGuru; import com.cloud.network.PhysicalNetwork; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.addr.PublicIp; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; @@ -94,7 +97,7 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { private boolean canHandle(NetworkOffering offering, NetworkType networkType, PhysicalNetwork physicalNetwork) { if (networkType == NetworkType.Advanced - && offering.getId() == _manager.getRouterOffering().getId() + && (offering.getId() == _manager.getRouterOffering().getId() || offering.getId() == _manager.getVpcRouterOffering().getId()) && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == Network.GuestType.Isolated && physicalNetwork.getIsolationMethods().contains("L3VPN")) @@ -148,6 +151,25 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { return network; } _manager.getDatabase().getVirtualNetworks().add(vnModel); + + if (network.getVpcId() != null) { + List ips = _ipAddressDao.listByAssociatedVpc(network.getVpcId(), true); + if (ips.isEmpty()) { + s_logger.debug("Creating a source nat ip for network " + network); + Account owner = _accountMgr.getAccount(network.getAccountId()); + try { + PublicIp publicIp = _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, network); + IPAddressVO ip = publicIp.ip(); + ip.setVpcId(network.getVpcId()); + _ipAddressDao.acquireInLockTable(ip.getId()); + _ipAddressDao.update(ip.getId(), ip); + _ipAddressDao.releaseFromLockTable(ip.getId()); + } catch (Exception e) { + s_logger.error("Unable to allocate source nat ip: " + e); + } + } + } + return network; } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java index 6853d1efd55..1fe13035fb1 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java @@ -38,12 +38,19 @@ import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.offering.NetworkOffering; import com.cloud.projects.ProjectVO; import com.cloud.network.vpc.NetworkACLVO; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.network.vpc.VpcVO; public interface ContrailManager { public static final String routerOfferingName = "Juniper Contrail Network Offering"; public static final String routerOfferingDisplayText = "Juniper Contrail Network Offering"; public static final String routerPublicOfferingName = "Juniper Contrail Public Network Offering"; public static final String routerPublicOfferingDisplayText = "Juniper Contrail Public Network Offering"; + public static final String vpcRouterOfferingName = "Juniper Contrail VPC Network Offering"; + public static final String vpcRouterOfferingDisplayText = "Juniper Contrail VPC Network Offering"; + public static final String juniperVPCOfferingName = "Juniper Contrail VPC Offering"; + public static final String juniperVPCOfferingDisplayText = "Juniper Contrail VPC Offering"; + public static final int DB_SYNC_INTERVAL_DEFAULT = 600000; public static final String VNC_ROOT_DOMAIN = "default-domain"; public static final String VNC_DEFAULT_PROJECT = "default-project"; @@ -51,6 +58,8 @@ public interface ContrailManager { public NetworkOffering getRouterOffering(); public NetworkOffering getPublicRouterOffering(); + public NetworkOffering getVpcRouterOffering(); + public VpcOffering getVpcOffering(); public void syncNetworkDB(short syncMode) throws IOException; @@ -116,6 +125,8 @@ public interface ContrailManager { public List findManagedPublicIps(); + public List findManagedVpcs(); + public List findManagedACLs(); public VirtualNetwork findDefaultVirtualNetwork(TrafficType trafficType) throws IOException; diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java index ef76e4cee49..616a8c5c85a 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java @@ -81,6 +81,12 @@ import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.projects.ProjectVO; import com.cloud.network.vpc.dao.NetworkACLDao; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcOfferingDao; +import com.cloud.network.vpc.VpcOffering; +import com.cloud.network.vpc.VpcOfferingVO; +import com.cloud.network.vpc.VpcProvisioningService; +import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.NetworkACLVO; import com.cloud.projects.dao.ProjectDao; import com.cloud.user.Account; @@ -132,6 +138,12 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager @Inject UserVmDao _vmDao; @Inject + VpcOfferingDao _vpcOffDao; + @Inject + VpcProvisioningService _vpcProvSvc; + @Inject + VpcDao _vpcDao; + @Inject NetworkACLDao _networkAclDao; private static final Logger s_logger = Logger.getLogger(ContrailManager.class); @@ -141,6 +153,9 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager private NetworkOffering _offering; private NetworkOffering _routerOffering; private NetworkOffering _routerPublicOffering; + private NetworkOffering _vpcRouterOffering; + private VpcOffering _vpcOffering; + private Timer _dbSyncTimer; private int _dbSyncInterval = DB_SYNC_INTERVAL_DEFAULT; private final String configuration = "contrail.properties"; @@ -175,7 +190,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _database; } - private NetworkOffering LocatePublicNetworkOffering(String offeringName, + private NetworkOffering locatePublicNetworkOffering(String offeringName, String offeringDisplayText, Provider provider) { List offerList = _configService.listNetworkOfferings(TrafficType.Public, false); for (NetworkOffering offer: offerList) { @@ -210,7 +225,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _networkOfferingDao.findById(id); } - private NetworkOffering LocateNetworkOffering(String offeringName, + private NetworkOffering locateNetworkOffering(String offeringName, String offeringDisplayText, Provider provider) { List offerList = _configService.listNetworkOfferings(TrafficType.Guest, false); for (NetworkOffering offer : offerList) { @@ -239,6 +254,38 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _networkOfferingDao.findById(id); } + private VpcOffering locateVpcOffering() { + VpcOffering vpcOffer = _vpcOffDao.findByUniqueName(juniperVPCOfferingName); + if (vpcOffer != null) { + if (((VpcOfferingVO)vpcOffer).getState() == VpcOffering.State.Enabled) { + return vpcOffer; + } + ((VpcOfferingVO)vpcOffer).setState(VpcOffering.State.Enabled); + long id = vpcOffer.getId(); + _vpcOffDao.update(id, (VpcOfferingVO)vpcOffer); + return vpcOffer; + } + Map> serviceProviderMap = new HashMap>(); + List providerSet = new ArrayList(); + providerSet.add(Provider.JuniperContrailVpcRouter.getName()); + final List services = new ArrayList(); + services.add(Service.Connectivity.getName()); + services.add(Service.Dhcp.getName()); + services.add(Service.NetworkACL.getName()); + services.add(Service.StaticNat.getName()); + services.add(Service.SourceNat.getName()); + services.add(Service.Gateway.getName()); + + for (String svc: services) { + serviceProviderMap.put(svc, providerSet); + } + vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null); + ((VpcOfferingVO)vpcOffer).setState(VpcOffering.State.Enabled); + long id = vpcOffer.getId(); + _vpcOffDao.update(id, (VpcOfferingVO)vpcOffer); + return _vpcOffDao.findById(id); + } + private NetworkOffering EnableNetworkOffering(long id) { NetworkOfferingVO offering = _networkOfferingDao.createForUpdate(id); offering.setState(NetworkOffering.State.Enabled); @@ -281,10 +328,13 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager _controller = new ModelController(this, _api, _vmDao, _networksDao, _nicDao, _vlanDao, _ipAddressDao); - _routerOffering = LocateNetworkOffering(routerOfferingName, routerOfferingDisplayText, + _routerOffering = locateNetworkOffering(routerOfferingName, routerOfferingDisplayText, Provider.JuniperContrailRouter); - _routerPublicOffering = LocatePublicNetworkOffering(routerPublicOfferingName, routerPublicOfferingDisplayText, + _routerPublicOffering = locatePublicNetworkOffering(routerPublicOfferingName, routerPublicOfferingDisplayText, Provider.JuniperContrailRouter); + _vpcRouterOffering = locateNetworkOffering(vpcRouterOfferingName, vpcRouterOfferingDisplayText, + Provider.JuniperContrailVpcRouter); + _vpcOffering = locateVpcOffering(); _eventHandler.subscribe(); @@ -303,6 +353,16 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return _routerOffering; } + @Override + public NetworkOffering getVpcRouterOffering() { + return _vpcRouterOffering; + } + + @Override + public VpcOffering getVpcOffering() { + return _vpcOffering; + } + @Override public String getPhysicalNetworkName(PhysicalNetworkVO physNet) { String physname = physNet.getName(); @@ -465,7 +525,8 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager public boolean isManagedPhysicalNetwork(Network network) { List net_list = _physicalNetworkDao.listByZone(network.getDataCenterId()); for (PhysicalNetworkVO phys : net_list) { - if (_physProviderDao.findByServiceProvider(phys.getId(), Network.Provider.JuniperContrailRouter.getName()) != null) { + if(_physProviderDao.findByServiceProvider(phys.getId(), Provider.JuniperContrailRouter.getName()) != null || + _physProviderDao.findByServiceProvider(phys.getId(), Provider.JuniperContrailVpcRouter.getName()) != null) { return true; } } @@ -564,6 +625,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager SearchCriteria sc = searchBuilder.create(); List offerings = new ArrayList(); offerings.add(getRouterOffering().getId()); + offerings.add(getVpcRouterOffering().getId()); offerings.add(getPublicRouterOffering().getId()); sc.setParameters("networkOfferingId", offerings.toArray()); @@ -585,9 +647,11 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager List phys_list = _physicalNetworkDao.listAll(); final String provider = Network.Provider.JuniperContrailRouter.getName(); + final String vpcProvider = Provider.JuniperContrailVpcRouter.getName(); for (Iterator iter = phys_list.iterator(); iter.hasNext();) { PhysicalNetworkVO phys = iter.next(); - if (_physProviderDao.findByServiceProvider(phys.getId(), provider) != null) { + if (_physProviderDao.findByServiceProvider(phys.getId(), provider) != null || + _physProviderDao.findByServiceProvider(phys.getId(), vpcProvider) != null) { List infraNets = new ArrayList(); findInfrastructureNetworks(phys, infraNets); for (NetworkVO net : infraNets) { @@ -611,10 +675,51 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager return dbNets; } + @Override + public List findManagedVpcs() { + SearchBuilder searchBuilder = _vpcDao.createSearchBuilder(); + searchBuilder.and("vpcOffering", searchBuilder.entity().getVpcOfferingId(), Op.EQ); + SearchCriteria sc = searchBuilder.create(); + sc.setParameters("vpcOffering", getVpcOffering().getId()); + List vpcs = _vpcDao.search(sc, null); + if (vpcs == null || vpcs.size() == 0) { + s_logger.debug("no vpcs found"); + return null; + } + return vpcs; + } + @Override public List findManagedACLs() { - /* contrail vpc is not yet implemented */ - return null; + List vpcs = findManagedVpcs(); + if (vpcs == null || vpcs.isEmpty()) { + return null; + } + List vpcIds = new ArrayList(); + /* default-allow, default-deny ACLs will be under vpcId '0', so include it*/ + vpcIds.add((long)0); + for (VpcVO vpc:vpcs) { + vpcIds.add(vpc.getId()); + } + SearchBuilder searchBuilder = _networkAclDao.createSearchBuilder(); + searchBuilder.and("vpcId", searchBuilder.entity().getVpcId(), Op.IN); + SearchCriteria sc = searchBuilder.create(); + sc.setParameters("vpcId", vpcIds.toArray()); + List acls = _networkAclDao.search(sc, null); + if (acls == null || acls.size() == 0) { + s_logger.debug("no acls found"); + return null; + } + /* only return if acl is associated to any network */ + List jnprAcls = new ArrayList(); + for (NetworkACLVO acl:acls) { + List nets = _networksDao.listByAclId(acl.getId()); + if (nets == null || nets.isEmpty()) { + continue; + } + jnprAcls.add(acl); + } + return jnprAcls; } /* diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java new file mode 100644 index 00000000000..4a72fcb6697 --- /dev/null +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailVpcElementImpl.java @@ -0,0 +1,199 @@ +// 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 org.apache.cloudstack.network.contrail.management; + +import java.io.IOException; +import java.util.List; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.network.contrail.model.VirtualNetworkModel; +import org.apache.cloudstack.network.contrail.model.NetworkPolicyModel; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.Network; +import com.cloud.network.Network.Provider; +import com.cloud.network.element.NetworkACLServiceProvider; +import com.cloud.network.element.VpcProvider; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.NetworkACLVO; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRouteProfile; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.dao.NetworkACLDao; +import com.cloud.vm.ReservationContext; + +@Component +@Local(value = {NetworkACLServiceProvider.class, VpcProvider.class, ContrailElementImpl.class}) +public class ContrailVpcElementImpl extends ContrailElementImpl implements NetworkACLServiceProvider, VpcProvider { + private static final Logger s_logger = + Logger.getLogger(ContrailElement.class); + + @Inject + NetworkACLDao _networkACLDao; + + // NetworkElement API + @Override + public Provider getProvider() { + return Provider.JuniperContrailVpcRouter; + } + + @Override + public boolean implementVpc(Vpc vpc, DeployDestination dest, + ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement implementVpc"); + return true; + } + + @Override + public boolean shutdownVpc(Vpc vpc, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement shutdownVpc"); + return true; + } + + @Override + public boolean createPrivateGateway(PrivateGateway gateway) + throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement createPrivateGateway"); + return false; + } + + @Override + public boolean deletePrivateGateway(PrivateGateway privateGateway) + throws ConcurrentOperationException, ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement deletePrivateGateway"); + return false; + } + + @Override + public boolean applyStaticRoutes(Vpc vpc, List routes) + throws ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement applyStaticRoutes"); + return true; + } + + @Override + public boolean applyNetworkACLs(Network net, + List rules) + throws ResourceUnavailableException { + s_logger.debug("NetworkElement applyNetworkACLs"); + if (rules == null || rules.isEmpty()) { + s_logger.debug("no rules to apply"); + return true; + } + + Long aclId = rules.get(0).getAclId(); + NetworkACLVO acl = _networkACLDao.findById(aclId); + NetworkPolicyModel policyModel = _manager.getDatabase().lookupNetworkPolicy(acl.getUuid()); + if (policyModel == null) { + /* + * For the first time, when a CS ACL applied to a network, create a network-policy in VNC + * and when there are no networks associated to CS ACL, delete it from VNC. + */ + policyModel = new NetworkPolicyModel(acl.getUuid(), acl.getName()); + net.juniper.contrail.api.types.Project project; + try { + project = _manager.getVncProject(net.getDomainId(), net.getAccountId()); + if (project == null) { + project = _manager.getDefaultVncProject(); + } + } catch (IOException ex) { + s_logger.warn("read project", ex); + return false; + } + policyModel.setProject(project); + } + + VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(net.getUuid(), + _manager.getCanonicalName(net), net.getTrafficType()); + NetworkPolicyModel oldPolicyModel = null; + /* this method is called when network is destroyed too, hence vn model might have been deleted already */ + if (vnModel != null) { + oldPolicyModel = vnModel.getNetworkPolicyModel(); + vnModel.addToNetworkPolicy(policyModel); + } + + try { + policyModel.build(_manager.getModelController(), rules); + } catch (Exception e) { + s_logger.error(e); + e.printStackTrace(); + return false; + } + + try { + if (!policyModel.verify(_manager.getModelController())) { + policyModel.update(_manager.getModelController()); + } + _manager.getDatabase().getNetworkPolicys().add(policyModel); + } catch (Exception ex) { + s_logger.error("network-policy update: ", ex); + ex.printStackTrace(); + return false; + } + + if (!policyModel.hasPolicyRules()) { + try { + policyModel.delete(_manager.getModelController()); + _manager.getDatabase().getNetworkPolicys().remove(policyModel); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + /* + * if no other VNs are associated with the old policy, + * we could delete it from the Contrail VNC + */ + if (policyModel != oldPolicyModel && oldPolicyModel != null && !oldPolicyModel.hasDescendents()) { + try { + oldPolicyModel.delete(_manager.getModelController()); + _manager.getDatabase().getNetworkPolicys().remove(oldPolicyModel); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + return true; + } + + @Override + public boolean applyACLItemsToPrivateGw(PrivateGateway privateGateway, + List rules) + throws ResourceUnavailableException { + // TODO Auto-generated method stub + s_logger.debug("NetworkElement applyACLItemsToPrivateGw"); + return true; + } + +} diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java index b1f47187ed8..b9a3ed3b034 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java @@ -68,6 +68,8 @@ import com.cloud.network.vpc.NetworkACLItemDao; import com.cloud.network.vpc.NetworkACLItemVO; import com.cloud.network.vpc.NetworkACLVO; import com.cloud.network.vpc.dao.NetworkACLDao; +import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.dao.VpcDao; import com.cloud.projects.ProjectVO; import com.cloud.projects.dao.ProjectDao; import com.cloud.vm.NicVO; @@ -97,6 +99,8 @@ public class ServerDBSyncImpl implements ServerDBSync { @Inject ContrailManager _manager; @Inject + VpcDao _vpcDao; + @Inject NetworkACLItemDao _networkACLItemDao; @Inject NetworkACLDao _networkACLDao; @@ -990,7 +994,12 @@ public class ServerDBSyncImpl implements ServerDBSync { NetworkPolicyModel policyModel = new NetworkPolicyModel(db.getUuid(), db.getName()); net.juniper.contrail.api.types.Project project = null; try { - project = _manager.getDefaultVncProject(); + VpcVO vpc = _vpcDao.findById(db.getVpcId()); + if (vpc != null) { + project = _manager.getVncProject(vpc.getDomainId(), vpc.getAccountId()); + } else { + project = _manager.getDefaultVncProject(); + } } catch (IOException ex) { s_logger.warn("read project", ex); throw ex; @@ -1055,7 +1064,12 @@ public class ServerDBSyncImpl implements ServerDBSync { NetworkPolicyModel policyModel = new NetworkPolicyModel(db.getUuid(), db.getName()); net.juniper.contrail.api.types.Project project = null; try { - project = _manager.getDefaultVncProject(); + VpcVO vpc = _vpcDao.findById(db.getVpcId()); + if (vpc != null) { + project = _manager.getVncProject(vpc.getDomainId(), vpc.getAccountId()); + } else { + project = _manager.getDefaultVncProject(); + } } catch (IOException ex) { s_logger.warn("read project", ex); } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java index 8ec2ff7187a..3092cad4ff6 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java @@ -73,7 +73,7 @@ public class NetworkPolicyModel extends ModelObjectBase { SearchCriteria sc = searchBuilder.create(); - sc.setParameters("networkOfferingId", controller.getManager().getRouterOffering().getId()); + sc.setParameters("networkOfferingId", controller.getManager().getVpcRouterOffering().getId()); sc.setParameters("cidr", cidr); sc.setParameters("trafficType", Networks.TrafficType.Guest); diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 20037167487..0109b4b7b6d 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -4294,7 +4294,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override public boolean isOfferingForVpc(NetworkOffering offering) { - boolean vpcProvider = _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.VPCVirtualRouter); + boolean vpcProvider = _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.VPCVirtualRouter) || + _ntwkOffServiceMapDao.isProviderForNetworkOffering(offering.getId(), Provider.JuniperContrailVpcRouter); + return vpcProvider; } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 51e476f4ee6..a2521d01588 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -203,7 +203,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker")); private List vpcElements = null; private final List nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall); - private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler); + private final List supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter); int _cleanupInterval; int _maxNetworks; @@ -308,6 +308,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis // Just here for 4.1, replaced by commit 836ce6c1 in newer versions Set sdnProviders = new HashSet(); sdnProviders.add(Provider.NiciraNvp); + sdnProviders.add(Provider.JuniperContrailVpcRouter); boolean sourceNatSvc = false; boolean firewallSvs = false; @@ -1191,6 +1192,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (vpcElements == null) { vpcElements = new ArrayList(); vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.VPCVirtualRouter.getName())); + vpcElements.add((VpcProvider)_ntwkModel.getElementImplementingProvider(Provider.JuniperContrailVpcRouter.getName())); } if (vpcElements == null) { From 836a9caa72cbd2a5d1571a8aea6e569ba870ffde Mon Sep 17 00:00:00 2001 From: Hiroaki KAWAI Date: Fri, 31 Jan 2014 12:57:13 +0900 Subject: [PATCH 114/126] add charset arg to InputStreamReader constructor thanks to findbugs. --- .../org/apache/cloudstack/network/element/SspClient.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java index c0db92ccab0..4d0be2d207b 100644 --- a/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java +++ b/plugins/network-elements/stratosphere-ssp/src/org/apache/cloudstack/network/element/SspClient.java @@ -139,7 +139,7 @@ public class SspClient { return null; } try { - return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent()), + return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent(), "UTF-8"), TenantNetwork.class); } catch (JsonSyntaxException e) { s_logger.error("reading response body failed", e); @@ -188,7 +188,7 @@ public class SspClient { return null; } try { - return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent()), + return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent(), "UTF-8"), TenantPort.class); } catch (JsonSyntaxException e) { s_logger.error("reading response body failed", e); @@ -228,7 +228,7 @@ public class SspClient { return null; } try { - return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent()), + return new Gson().fromJson(new InputStreamReader(res.getEntity().getContent(), "UTF-8"), TenantPort.class); } catch (JsonSyntaxException e) { s_logger.error("reading response body failed", e); From f2f605dfda5b731246ab932936e164b0fa94089c Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Fri, 31 Jan 2014 10:35:19 +0530 Subject: [PATCH 115/126] CLOUDSTACK-5993: Cloud agent fails to start on 32-bit system vms (cpvm and ssvm) created with 4GB RAM offering Capped the max heap size of the JVM at 2600M for 32-bit system VMs. For 64-bit, existing logic works fine. --- systemvm/scripts/_run.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/systemvm/scripts/_run.sh b/systemvm/scripts/_run.sh index bd063468cfb..1a37c7d372c 100755 --- a/systemvm/scripts/_run.sh +++ b/systemvm/scripts/_run.sh @@ -61,4 +61,11 @@ then maxmem=$eightypcnt fi +if [ "$(uname -m | grep '64')" == "" ]; then + let "maxmem32bit=2600" + if [ $maxmem -gt $maxmem32bit ]; then + maxmem=$maxmem32bit + fi +fi + java -Djavax.net.ssl.trustStore=./certs/realhostip.keystore -Dlog.home=$LOGHOME -mx${maxmem}m -cp $CP com.cloud.agent.AgentShell $keyvalues $@ From 580ebb0010cbebcb13fefd8bd96137b7033ef872 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Thu, 30 Jan 2014 18:07:24 +0530 Subject: [PATCH 116/126] CLOUDSTACK-5989: Trying to start a vm while 'vm snapshot' is in progress results in inconsistency The fix is to fail the start operation if a vm snapshot is in progress --- .../src/com/cloud/vm/VirtualMachineManagerImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index b71252879fc..f3e3c36c57c 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1525,6 +1525,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } protected boolean stateTransitTo(VMInstanceVO vm, VirtualMachine.Event e, Long hostId, String reservationId) throws NoTransitionException { + // if there are active vm snapshots task, state change is not allowed + if (_vmSnapshotMgr.hasActiveVMSnapshotTasks(vm.getId())) { + s_logger.error("State transit with event: " + e + " failed due to: " + vm.getInstanceName() + " has active VM snapshots tasks"); + return false; + } vm.setReservationId(reservationId); return _stateMachine.transitTo(vm, e, new Pair(vm.getHostId(), hostId), _vmDao); } From 7f6b3c08db5fb3809ffab1a181df2392333f4e24 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Fri, 31 Jan 2014 10:52:02 +0530 Subject: [PATCH 117/126] CLOUDSTACK-5998. [AWSAPI] describe addresses call returns a fault with "domain cannot be null!!". --- awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java index dac18e42d20..d44f1d1101e 100644 --- a/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java +++ b/awsapi/src/com/cloud/bridge/service/EC2SoapServiceImpl.java @@ -1977,6 +1977,7 @@ public class EC2SoapServiceImpl implements AmazonEC2SkeletonInterface { DescribeAddressesResponseItemType item = new DescribeAddressesResponseItemType(); item.setPublicIp(addr.getIpAddress()); item.setInstanceId(addr.getAssociatedInstanceId()); + item.setDomain("standard"); // Since VPC is not supported by AWSAPI default to 'standard' items.add(item); } DescribeAddressesResponseInfoType descAddrRespInfoType = new DescribeAddressesResponseInfoType(); From d409d709e3837a24bc5d2ff88b17ad324cb21e45 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Thu, 30 Jan 2014 23:33:27 -0700 Subject: [PATCH 118/126] CLOUDSTACK-6000: When expunging fails, move volume state back to Destroy, so that the cleanup thread will try again on next run. --- api/src/com/cloud/storage/Volume.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 84f0872f909..36648840448 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -82,7 +82,7 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba s_fsm.addTransition(Destroy, Event.ExpungingRequested, Expunging); s_fsm.addTransition(Expunging, Event.ExpungingRequested, Expunging); s_fsm.addTransition(Expunging, Event.OperationSucceeded, Expunged); - s_fsm.addTransition(Expunging, Event.OperationFailed, Expunging); + s_fsm.addTransition(Expunging, Event.OperationFailed, Destroy); s_fsm.addTransition(Ready, Event.SnapshotRequested, Snapshotting); s_fsm.addTransition(Snapshotting, Event.OperationSucceeded, Ready); s_fsm.addTransition(Snapshotting, Event.OperationFailed, Ready); From d56c5dfc1363c4acee4375108f5c4c868f547d14 Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Thu, 30 Jan 2014 14:44:50 +0100 Subject: [PATCH 119/126] Fix for a potential NPE --- .../storage/volume/VolumeServiceImpl.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 3e5a5466fd0..3e315da4b48 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -420,12 +420,12 @@ public class VolumeServiceImpl implements VolumeService { } else { if (s_logger.isDebugEnabled()) { s_logger.debug("Found template " + template.getUniqueName() + " in storage pool " + dataStore.getId() + " with VMTemplateStoragePool id: " + - templatePoolRef.getId()); + templatePoolRef.getId()); } } long templatePoolRefId = templatePoolRef.getId(); CreateBaseImageContext context = - new CreateBaseImageContext(null, volume, dataStore, template, future, templateOnPrimaryStoreObj, templatePoolRefId); + new CreateBaseImageContext(null, volume, dataStore, template, future, templateOnPrimaryStoreObj, templatePoolRefId); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)).setContext(context); @@ -440,9 +440,9 @@ public class VolumeServiceImpl implements VolumeService { s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId); } templatePoolRef = _tmpltPoolDao.findByPoolTemplate(dataStore.getId(), template.getId()); - if (templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) { + if (templatePoolRef != null && templatePoolRef.getState() == ObjectInDataStoreStateMachine.State.Ready) { s_logger.info("Unable to acquire lock on VMTemplateStoragePool " + templatePoolRefId + ", But Template " + template.getUniqueName() + - " is already copied to primary storage, skip copying"); + " is already copied to primary storage, skip copying"); createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future); return; } @@ -523,7 +523,7 @@ public class VolumeServiceImpl implements VolumeService { volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested); CreateVolumeFromBaseImageContext context = - new CreateVolumeFromBaseImageContext(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null); + new CreateVolumeFromBaseImageContext(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null)); caller.setContext(context); @@ -534,7 +534,7 @@ public class VolumeServiceImpl implements VolumeService { @DB protected Void createVolumeFromBaseImageCallBack(AsyncCallbackDispatcher callback, - CreateVolumeFromBaseImageContext context) { + CreateVolumeFromBaseImageContext context) { DataObject vo = context.vo; DataObject tmplOnPrimary = context.templateOnStore; CopyCommandResult result = callback.getResult(); @@ -615,7 +615,7 @@ public class VolumeServiceImpl implements VolumeService { volumeOnStore.processEvent(Event.CreateOnlyRequested); snapshot.processEvent(Event.CopyingRequested); CreateVolumeFromBaseImageContext context = - new CreateVolumeFromBaseImageContext(null, volume, store, volumeOnStore, future, snapshot); + new CreateVolumeFromBaseImageContext(null, volume, store, volumeOnStore, future, snapshot); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)).setContext(context); motionSrv.copyAsync(snapshot, volumeOnStore, caller); @@ -630,7 +630,7 @@ public class VolumeServiceImpl implements VolumeService { } protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher callback, - CreateVolumeFromBaseImageContext context) { + CreateVolumeFromBaseImageContext context) { CopyCommandResult result = callback.getResult(); VolumeInfo volume = (VolumeInfo)context.templateOnStore; SnapshotInfo snapshot = context.snapshot; @@ -716,7 +716,7 @@ public class VolumeServiceImpl implements VolumeService { } protected Void - copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { + copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { VolumeInfo srcVolume = context.srcVolume; VolumeInfo destVolume = context.destVolume; CopyCommandResult result = callback.getResult(); @@ -770,7 +770,7 @@ public class VolumeServiceImpl implements VolumeService { } protected Void - copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { + copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { VolumeInfo srcVolume = context.srcVolume; VolumeInfo destVolume = context.destVolume; CopyCommandResult result = callback.getResult(); @@ -988,7 +988,7 @@ public class VolumeServiceImpl implements VolumeService { } protected Void - migrateVmWithVolumesCallBack(AsyncCallbackDispatcher callback, MigrateVmWithVolumesContext context) { + migrateVmWithVolumesCallBack(AsyncCallbackDispatcher callback, MigrateVmWithVolumesContext context) { Map volumeToPool = context.volumeToPool; CopyCommandResult result = callback.getResult(); AsyncCallFuture future = context.future; @@ -1065,20 +1065,20 @@ public class VolumeServiceImpl implements VolumeService { physicalSize = volStore.getPhysicalSize(); } else { s_logger.warn("No entry found in volume_store_ref for volume id: " + vo.getId() + " and image store id: " + ds.getId() + - " at the end of uploading volume!"); + " at the end of uploading volume!"); } Scope dsScope = ds.getScope(); if (dsScope.getScopeType() == ScopeType.ZONE) { if (dsScope.getScopeId() != null) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), dsScope.getScopeId(), vo.getId(), vo.getName(), null, - null, physicalSize, vo.getSize(), Volume.class.getName(), vo.getUuid()); + null, physicalSize, vo.getSize(), Volume.class.getName(), vo.getUuid()); } else { s_logger.warn("Zone scope image store " + ds.getId() + " has a null scope id"); } } else if (dsScope.getScopeType() == ScopeType.REGION) { // publish usage event for region-wide image store using a -1 zoneId for 4.2, need to revisit post-4.2 UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_UPLOAD, vo.getAccountId(), -1, vo.getId(), vo.getName(), null, null, physicalSize, - vo.getSize(), Volume.class.getName(), vo.getUuid()); + vo.getSize(), Volume.class.getName(), vo.getUuid()); _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, vo.getSize()); } @@ -1173,7 +1173,7 @@ public class VolumeServiceImpl implements VolumeService { VolumeVO volume = _volumeDao.findById(volumeStore.getVolumeId()); if (volume == null) { s_logger.warn("Volume_store_ref shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId + - ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed"); + ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark it as destroyed"); volumeStore.setDestroyed(true); _volumeStoreDao.update(volumeStore.getId(), volumeStore); continue; @@ -1193,7 +1193,7 @@ public class VolumeServiceImpl implements VolumeService { s_logger.info("msg"); if (volumeStore.getDownloadUrl() == null) { msg = - "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + + "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + "is corrupted, please check in image store: " + volumeStore.getDataStoreId(); s_logger.warn(msg); } else { @@ -1221,15 +1221,15 @@ public class VolumeServiceImpl implements VolumeService { if (volInfo.getSize() > 0) { try { _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), - com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize()); + com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize()); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), - e.getMessage(), - e.getMessage()); + e.getMessage(), + e.getMessage()); } finally { _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); + com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); } } } @@ -1238,7 +1238,7 @@ public class VolumeServiceImpl implements VolumeService { // Volume is not on secondary but we should download. if (volumeStore.getDownloadState() != Status.DOWNLOADED) { s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + - ", will request download to start/resume shortly"); + ", will request download to start/resume shortly"); toBeDownloaded.add(volumeStore); } } From 8f10dedce90e7768aca491a93f5f32f282669ece Mon Sep 17 00:00:00 2001 From: Hugo Trippaers Date: Fri, 31 Jan 2014 09:36:33 +0100 Subject: [PATCH 120/126] Fix findbugs findings and remove dead code --- .../resource/NfsSecondaryStorageResource.java | 207 +++------- .../resource/SecondaryStorageDiscoverer.java | 7 - .../storage/template/DownloadManagerImpl.java | 353 +++++++----------- .../storage/template/UploadManagerImpl.java | 246 ++++-------- 4 files changed, 259 insertions(+), 554 deletions(-) diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 7c4b8ca03d3..9782c2ec7c4 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -19,7 +19,6 @@ package org.apache.cloudstack.storage.resource; import static com.cloud.utils.S3Utils.mputFile; import static com.cloud.utils.S3Utils.putFile; import static com.cloud.utils.StringUtils.join; -import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock; import static java.lang.String.format; import static java.util.Arrays.asList; import static org.apache.commons.lang.StringUtils.substringAfterLast; @@ -44,7 +43,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.concurrent.Callable; import javax.naming.ConfigurationException; @@ -142,7 +140,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class); private static final String TEMPLATE_ROOT_DIR = "template/tmpl"; - private static final String SNAPSHOT_ROOT_DIR = "snapshots"; private static final String VOLUME_ROOT_DIR = "volumes"; int _timeout; @@ -180,7 +177,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private String _storageGateway; private final List nfsIps = new ArrayList(); protected String _parent = "/mnt/SecStorage"; - final private String _tmpltDir = "/var/cloudstack/template"; final private String _tmpltpp = "template.properties"; protected String createTemplateFromSnapshotXenScript; @@ -264,7 +260,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr; int installTimeoutPerGig = 180 * 60 * 1000; - int imgSizeGigs = (int)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024)); + long imgSizeGigs = (long)Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024)); imgSizeGigs++; // add one just in case long timeout = imgSizeGigs * installTimeoutPerGig; @@ -279,7 +275,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String templateName = UUID.randomUUID().toString(); String templateFilename = templateName + "." + extension; Script scr = new Script(script, timeout, s_logger); - scr.add("-s", Integer.toString(imgSizeGigs)); // not used for now + scr.add("-s", Long.toString(imgSizeGigs)); // not used for now scr.add("-n", templateFilename); scr.add("-t", downloadPath); @@ -324,7 +320,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S try { String downloadPath = determineStorageTemplatePath(storagePath, destPath); final File downloadDirectory = _storage.getFile(downloadPath); - downloadDirectory.mkdirs(); + if (!downloadDirectory.mkdirs()) { + return new CopyCmdAnswer("Failed to create download directory " + downloadPath); + } File destFile = SwiftUtil.getObject(swiftTO, downloadDirectory, srcData.getPath()); return postProcessing(destFile, downloadPath, destPath, srcData, destData); } catch (Exception e) { @@ -341,9 +339,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String downloadPath = determineStorageTemplatePath(storagePath, destPath); final File downloadDirectory = _storage.getFile(downloadPath); - downloadDirectory.mkdirs(); - if (!downloadDirectory.exists()) { + if (!downloadDirectory.mkdirs()) { final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache."; s_logger.error(errMsg); return new CopyCmdAnswer(errMsg); @@ -372,7 +369,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, - NfsTO destDataStore) { + NfsTO destDataStore) { String srcMountPoint = getRootDir(srcDataStore.getUrl()); String snapshotPath = srcData.getPath(); int index = snapshotPath.lastIndexOf("/"); @@ -488,6 +485,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S processor = new QCOW2Processor(); } else if (srcFormat == ImageFormat.RAW) { processor = new RawImageProcessor(); + } else { + throw new ConfigurationException("Unknown image format " + srcFormat.toString()); } Map params = new HashMap(); @@ -550,8 +549,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } else if (destDataStore instanceof SwiftTO) { //create template on the same data store CopyCmdAnswer answer = - (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, - (NfsTO)srcDataStore); + (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, + (NfsTO)srcDataStore); if (!answer.getResult()) { return answer; } @@ -585,8 +584,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } else if (destDataStore instanceof S3TO) { //create template on the same data store CopyCmdAnswer answer = - (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, - (NfsTO)srcDataStore); + (CopyCmdAnswer)copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, + (NfsTO)srcDataStore); if (!answer.getResult()) { return answer; } @@ -651,7 +650,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR); } - @SuppressWarnings("unchecked") private String determineS3TemplateNameFromKey(String key) { return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR); } @@ -661,12 +659,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR); } - @SuppressWarnings("unchecked") protected Long determineS3VolumeIdFromKey(String key) { return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR)); } - @SuppressWarnings("unchecked") private String determineStorageTemplatePath(final String storagePath, String dataPath) { return join(asList(getRootDir(storagePath), dataPath), File.separator); } @@ -690,8 +686,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S _storage.mkdirs(filePath); } File destFile = new File(filePath + File.separator + name); - if (!destFile.exists()) { - destFile.createNewFile(); + if (!destFile.createNewFile()) { + s_logger.warn("Reusing existing file " + destFile.getPath()); } FileOutputStream outputStream = new FileOutputStream(destFile); entity.writeTo(outputStream); @@ -744,9 +740,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } DownloadAnswer answer = - new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, file.length(), file.length(), md5sum); + new DownloadAnswer(null, 100, null, VMTemplateStorageResourceAssoc.Status.DOWNLOADED, swiftPath, swiftPath, file.length(), file.length(), md5sum); return answer; - } catch (Exception e) { + } catch (IOException e) { s_logger.debug("Failed to register template into swift", e); return new DownloadAnswer(e.toString(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } finally { @@ -904,7 +900,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + - swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath); + swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -916,7 +912,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String[] lines = parser.getLines().split("\\n"); for (String line : lines) { if (line.contains("Errno") || line.contains("failed")) { - String errMsg = "swiftDownload failed , err=" + lines.toString(); + String errMsg = "swiftDownload failed , err=" + parser.getLines(); s_logger.warn(errMsg); return errMsg; } @@ -930,7 +926,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + - swift.getUserName() + " -K " + swift.getKey() + " download " + container); + swift.getUserName() + " -K " + swift.getKey() + " download " + container); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -942,7 +938,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String[] lines = parser.getLines().split("\\n"); for (String line : lines) { if (line.contains("Errno") || line.contains("failed")) { - String errMsg = "swiftDownloadContainer failed , err=" + lines.toString(); + String errMsg = "swiftDownloadContainer failed , err=" + parser.getLines(); s_logger.warn(errMsg); return errMsg; } @@ -974,10 +970,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S command.add("-c"); if (size <= SWIFT_MAX_SIZE) { command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + - swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file); + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file); } else { command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + - swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file); + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file); } OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); @@ -990,7 +986,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String[] lines = parser.getLines().split("\\n"); for (String line : lines) { if (line.contains("Errno") || line.contains("failed")) { - String errMsg = "swiftUpload failed , err=" + lines.toString(); + String errMsg = "swiftUpload failed , err=" + parser.getLines(); s_logger.warn(errMsg); return errMsg; } @@ -1005,7 +1001,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + - swift.getUserName() + " -K " + swift.getKey() + " list " + container + " " + rFilename); + swift.getUserName() + " -K " + swift.getKey() + " list " + container + " " + rFilename); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result == null && parser.getLines() != null) { @@ -1027,7 +1023,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + - swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object); + swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -1039,7 +1035,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String[] lines = parser.getLines().split("\\n"); for (String line : lines) { if (line.contains("Errno") || line.contains("failed")) { - String errMsg = "swiftDelete failed , err=" + lines.toString(); + String errMsg = "swiftDelete failed , err=" + parser.getLines(); s_logger.warn(errMsg); return errMsg; } @@ -1094,7 +1090,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { final String errorMessage = - String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); + String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } @@ -1123,21 +1119,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - private String determineSnapshotS3Directory(final Long accountId, final Long volumeId) { - return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId); - } - - private String determineSnapshotS3Key(final Long accountId, final Long volumeId, final String snapshotFileName) { - - final String directoryName = determineSnapshotS3Directory(accountId, volumeId); - return join(S3Utils.SEPARATOR, directoryName, snapshotFileName); - - } - - private String determineSnapshotLocalDirectory(final String secondaryStorageUrl, final Long accountId, final Long volumeId) { - return join(File.pathSeparator, getRootDir(secondaryStorageUrl), SNAPSHOT_ROOT_DIR, accountId, volumeId); - } - private Answer execute(ComputeChecksumCommand cmd) { String relativeTemplatePath = cmd.getTemplatePath(); @@ -1207,7 +1188,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } else { String prvKey = certs.getPrivKey(); String pubCert = certs.getPrivCert(); - String certChain = certs.getCertChain(); try { File prvKeyFile = File.createTempFile("prvkey", null); @@ -1265,69 +1245,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId, final String name, - final Boolean deleteAllFlag) { - String lPath = null; - int index = name.lastIndexOf(File.separator); - String snapshotPath = name.substring(0, index); - if (deleteAllFlag) { - lPath = getRootDir(secondaryStorageUrl) + File.separator + snapshotPath + File.separator + "*"; - } else { - lPath = getRootDir(secondaryStorageUrl) + File.separator + name + "*"; - } - - final String result = deleteLocalFile(lPath); - - if (result != null) { - return "failed to delete snapshot " + lPath + " , err=" + result; - } - - return null; - - } - - private String deleteSnapshotBackupfromS3(final S3TO s3, final Long accountId, final Long volumeId, final String name, final Boolean deleteAllFlag) { - - try { - - final String bucket = s3.getBucketName(); - - final String result = executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), new Callable() { - - @Override - public String call() throws Exception { - - if (deleteAllFlag) { - S3Utils.deleteDirectory(s3, bucket, determineSnapshotS3Directory(accountId, volumeId)); - } else { - S3Utils.deleteObject(s3, bucket, determineSnapshotS3Key(accountId, volumeId, determineSnapshotBackupFilename(name))); - } - - return null; - - } - - }); - - return result; - - } catch (Exception e) { - - s_logger.error(String.format("Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.", accountId, volumeId), e); - return e.getMessage(); - - } - - } - - private String determineSnapshotBackupFilename(final String snapshotUuid) { - return snapshotUuid + ".vhd"; - } - - private String determineSnapshotLockId(final Long accountId, final Long volumeId) { - return join("_", "SNAPSHOT", accountId, volumeId); - } - protected Answer deleteSnapshot(final DeleteCommand cmd) { DataTO obj = cmd.getData(); DataStoreTO dstore = obj.getDataStore(); @@ -1381,7 +1298,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { final String errorMessage = - String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); + String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } @@ -1523,7 +1440,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } DataStoreTO store = cmd.getDataStore(); if (store instanceof NfsTO) { - NfsTO nfs = (NfsTO)store; String root = getRootDir(cmd.getSecUrl()); Map templateInfos = _dlMgr.gatherVolumeInfo(root); return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos); @@ -1571,45 +1487,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } - private String setVhdParent(String lFullPath, String pFullPath) { - Script command = new Script("/bin/bash", s_logger); - command.add("-c"); - command.add("/bin/vhd-util modify -n " + lFullPath + " -p " + pFullPath); - String result = command.execute(); - if (result != null) { - String errMsg = "failed to set vhd parent, child " + lFullPath + " parent " + pFullPath + ", err=" + result; - s_logger.warn(errMsg); - return errMsg; - } - return null; - } - - private String createLocalDir(String folder) { - Script command = new Script("/bin/bash", s_logger); - command.add("-c"); - command.add("mkdir -p " + folder); - String result = command.execute(); - if (result != null) { - String errMsg = "Create local path " + folder + " failed , err=" + result; - s_logger.warn(errMsg); - return errMsg; - } - return null; - } - - private String deleteLocalDir(String folder) { - Script command = new Script("/bin/bash", s_logger); - command.add("-c"); - command.add("rmdir " + folder); - String result = command.execute(); - if (result != null) { - String errMsg = "Delete local path " + folder + " failed , err=" + result; - s_logger.warn(errMsg); - return errMsg; - } - return null; - } - private String deleteLocalFile(String fullPath) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); @@ -1690,12 +1567,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, "Object with null install path does not exist on image store , no need to delete"); } switch (objType) { - case TEMPLATE: - return deleteTemplate(cmd); - case VOLUME: - return deleteVolume(cmd); - case SNAPSHOT: - return deleteSnapshot(cmd); + case TEMPLATE: + return deleteTemplate(cmd); + case VOLUME: + return deleteVolume(cmd); + case SNAPSHOT: + return deleteSnapshot(cmd); } return Answer.createUnsupportedCommandAnswer(cmd); } @@ -1777,7 +1654,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket)); } catch (Exception e) { final String errorMessage = - String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); + String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } @@ -2361,7 +2238,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S List args = URLEncodedUtils.parse(uri, "UTF-8"); boolean foundUser = false; boolean foundPswd = false; - String extraOpts = ""; + StringBuilder extraOpts = new StringBuilder(); for (NameValuePair nvp : args) { String name = nvp.getName(); if (name.equals("user")) { @@ -2369,10 +2246,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S s_logger.debug("foundUser is" + foundUser); } else if (name.equals("password")) { foundPswd = true; - s_logger.debug("foundPswd is" + foundPswd); + s_logger.debug("password is present in uri"); } - extraOpts = extraOpts + name + "=" + nvp.getValue() + ","; + extraOpts.append(name + "=" + nvp.getValue() + ","); } if (s_logger.isDebugEnabled()) { @@ -2381,12 +2258,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if (!foundUser || !foundPswd) { String errMsg = - "Missing user and password from URI. Make sure they" + "are in the query string and separated by '&'. E.g. " - + "cifs://example.com/some_share?user=foo&password=bar"; + "Missing user and password from URI. Make sure they" + "are in the query string and separated by '&'. E.g. " + + "cifs://example.com/some_share?user=foo&password=bar"; s_logger.error(errMsg); throw new CloudRuntimeException(errMsg); } - return extraOpts; + return extraOpts.toString(); } protected boolean mountExists(String localRootPath, URI uri) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java index fef034dbdbd..ee5064751be 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageDiscoverer.java @@ -32,12 +32,9 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; - import com.cloud.agent.AgentManager; import com.cloud.host.HostVO; import com.cloud.host.Status.Event; -import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.resource.Discoverer; import com.cloud.resource.DiscovererBase; @@ -66,16 +63,12 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov Random _random = new Random(System.currentTimeMillis()); @Inject - protected HostDao _hostDao = null; - @Inject protected VMTemplateDao _tmpltDao = null; @Inject protected VMTemplateZoneDao _vmTemplateZoneDao = null; @Inject protected VMTemplateDao _vmTemplateDao = null; @Inject - protected ConfigurationDao _configDao = null; - @Inject protected AgentManager _agentMgr = null; protected SecondaryStorageDiscoverer() { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java index 84daf27de7c..d45a6bbe607 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java @@ -62,6 +62,7 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.template.HttpTemplateDownloader; import com.cloud.storage.template.IsoProcessor; import com.cloud.storage.template.LocalTemplateDownloader; +import com.cloud.storage.template.OVAProcessor; import com.cloud.storage.template.Processor; import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; @@ -75,7 +76,6 @@ import com.cloud.storage.template.TemplateDownloader.Status; import com.cloud.storage.template.TemplateLocation; import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.VhdProcessor; -import com.cloud.storage.template.OVAProcessor; import com.cloud.storage.template.VmdkProcessor; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ManagerBase; @@ -104,14 +104,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private static class DownloadJob { private final TemplateDownloader td; - private final String jobId; private final String tmpltName; private final boolean hvm; private final ImageFormat format; private String tmpltPath; private final String description; private String checksum; - private final Long accountId; private final String installPathPrefix; private long templatesize; private long templatePhysicalSize; @@ -122,11 +120,9 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String installPathPrefix, ResourceType resourceType) { super(); this.td = td; - this.jobId = jobId; this.tmpltName = tmpltName; this.format = format; this.hvm = hvm; - this.accountId = accountId; description = descr; checksum = cksum; this.installPathPrefix = installPathPrefix; @@ -135,10 +131,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager this.resourceType = resourceType; } - public TemplateDownloader getTd() { - return td; - } - public String getDescription() { return description; } @@ -151,10 +143,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return td; } - public String getJobId() { - return jobId; - } - public String getTmpltName() { return tmpltName; } @@ -167,10 +155,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return hvm; } - public Long getAccountId() { - return accountId; - } - public long getId() { return id; } @@ -232,7 +216,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private String _volumeDir; private String createTmpltScr; private String createVolScr; - private List processors; private ExecutorService threadPool; @@ -240,7 +223,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private String listTmpltScr; private String listVolScr; private int installTimeoutPerGig = 180 * 60 * 1000; - private boolean _sslCopy; public void setThreadPool(ExecutorService threadPool) { this.threadPool = threadPool; @@ -268,55 +250,55 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager TemplateDownloader td = dj.getTemplateDownloader(); s_logger.info("Download Completion for jobId: " + jobId + ", status=" + status); s_logger.info("local: " + td.getDownloadLocalPath() + ", bytes=" + td.getDownloadedBytes() + ", error=" + td.getDownloadError() + ", pct=" + - td.getDownloadPercent()); + td.getDownloadPercent()); switch (status) { - case ABORTED: - case NOT_STARTED: - case UNRECOVERABLE_ERROR: - // TODO - dj.cleanup(); - break; - case UNKNOWN: - return; - case IN_PROGRESS: - s_logger.info("Resuming jobId: " + jobId + ", status=" + status); - td.setResume(true); - threadPool.execute(td); - break; - case RECOVERABLE_ERROR: - threadPool.execute(td); - break; - case DOWNLOAD_FINISHED: - if (!(td instanceof S3TemplateDownloader)) { - // we currently only create template.properties for NFS by - // running some post download script - td.setDownloadError("Download success, starting install "); - String result = postDownload(jobId); - if (result != null) { - s_logger.error("Failed post download script: " + result); - td.setStatus(Status.UNRECOVERABLE_ERROR); - td.setDownloadError("Failed post download script: " + result); - } else { - td.setStatus(Status.POST_DOWNLOAD_FINISHED); - td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date())); - } + case ABORTED: + case NOT_STARTED: + case UNRECOVERABLE_ERROR: + // TODO + dj.cleanup(); + break; + case UNKNOWN: + return; + case IN_PROGRESS: + s_logger.info("Resuming jobId: " + jobId + ", status=" + status); + td.setResume(true); + threadPool.execute(td); + break; + case RECOVERABLE_ERROR: + threadPool.execute(td); + break; + case DOWNLOAD_FINISHED: + if (!(td instanceof S3TemplateDownloader)) { + // we currently only create template.properties for NFS by + // running some post download script + td.setDownloadError("Download success, starting install "); + String result = postDownload(jobId); + if (result != null) { + s_logger.error("Failed post download script: " + result); + td.setStatus(Status.UNRECOVERABLE_ERROR); + td.setDownloadError("Failed post download script: " + result); } else { - // for s3 and swift, we skip post download step and just set - // status to trigger callback. td.setStatus(Status.POST_DOWNLOAD_FINISHED); - // set template size for S3 - S3TemplateDownloader std = (S3TemplateDownloader)td; - long size = std.totalBytes; - DownloadJob dnld = jobs.get(jobId); - dnld.setTemplatesize(size); - dnld.setTemplatePhysicalSize(size); - dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name. + td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date())); } - dj.cleanup(); - break; - default: - break; + } else { + // for s3 and swift, we skip post download step and just set + // status to trigger callback. + td.setStatus(Status.POST_DOWNLOAD_FINISHED); + // set template size for S3 + S3TemplateDownloader std = (S3TemplateDownloader)td; + long size = std.totalBytes; + DownloadJob dnld = jobs.get(jobId); + dnld.setTemplatesize(size); + dnld.setTemplatePhysicalSize(size); + dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name. + } + dj.cleanup(); + break; + default: + break; } } @@ -360,28 +342,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager DownloadJob dnld = jobs.get(jobId); TemplateDownloader td = dnld.getTemplateDownloader(); String resourcePath = dnld.getInstallPathPrefix(); // path with mount - // directory + // directory String finalResourcePath = dnld.getTmpltPath(); // template download - // path on secondary - // storage + // path on secondary + // storage ResourceType resourceType = dnld.getResourceType(); - /* - // once template path is set, remove the parent dir so that the template - // is installed with a relative path - String finalResourcePath = ""; - if (resourceType == ResourceType.TEMPLATE) { - finalResourcePath += _templateDir + File.separator + dnld.getAccountId() + File.separator + dnld.getId() + File.separator; - resourcePath = dnld.getInstallPathPrefix() + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;// dnld.getTmpltName(); - } else { - finalResourcePath += _volumeDir + File.separator + dnld.getId() + File.separator; - resourcePath = dnld.getInstallPathPrefix() + dnld.getId() + File.separator;// dnld.getTmpltName(); - } - - _storage.mkdirs(resourcePath); - dnld.setTmpltPath(finalResourcePath); - */ - File originalTemplate = new File(td.getDownloadLocalPath()); String checkSum = computeCheckSum(originalTemplate); if (checkSum == null) { @@ -421,7 +387,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager scr.add("-t", resourcePath); scr.add("-f", td.getDownloadLocalPath()); // this is the temporary - // template file downloaded + // template file downloaded if (dnld.getChecksum() != null && dnld.getChecksum().length() > 1) { scr.add("-c", dnld.getChecksum()); } @@ -497,7 +463,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager @Override public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, - String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { + String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); @@ -527,7 +493,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager @Override public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, - String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { + String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); String tmpDir = installPathPrefix; @@ -540,52 +506,52 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } // TO DO - define constant for volume properties. File file = - ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : _storage.getFile(tmpDir + File.separator + - "volume.properties"); - if (file.exists()) { - file.delete(); - } + ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : _storage.getFile(tmpDir + File.separator + + "volume.properties"); + if (file.exists()) { + file.delete(); + } - if (!file.createNewFile()) { - s_logger.warn("Unable to create new file: " + file.getAbsolutePath()); - return "Unable to create new file: " + file.getAbsolutePath(); - } + if (!file.createNewFile()) { + s_logger.warn("Unable to create new file: " + file.getAbsolutePath()); + return "Unable to create new file: " + file.getAbsolutePath(); + } - URI uri; - try { - uri = new URI(url); - } catch (URISyntaxException e) { - throw new CloudRuntimeException("URI is incorrect: " + url); - } - TemplateDownloader td; - if ((uri != null) && (uri.getScheme() != null)) { - if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) { - td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType); - } else if (uri.getScheme().equalsIgnoreCase("file")) { - td = new LocalTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId)); - } else if (uri.getScheme().equalsIgnoreCase("scp")) { - td = new ScpTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId)); - } else if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("cifs")) { - td = null; - // TODO: implement this. - throw new CloudRuntimeException("Scheme is not supported " + url); - } else { - throw new CloudRuntimeException("Scheme is not supported " + url); - } - } else { - throw new CloudRuntimeException("Unable to download from URL: " + url); - } - // NOTE the difference between installPathPrefix and templatePath - // here. instalPathPrefix is the absolute path for template - // including mount directory - // on ssvm, while templatePath is the final relative path on - // secondary storage. - DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType); - dj.setTmpltPath(templatePath); - jobs.put(jobId, dj); - threadPool.execute(td); + URI uri; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + throw new CloudRuntimeException("URI is incorrect: " + url); + } + TemplateDownloader td; + if ((uri != null) && (uri.getScheme() != null)) { + if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) { + td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType); + } else if (uri.getScheme().equalsIgnoreCase("file")) { + td = new LocalTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId)); + } else if (uri.getScheme().equalsIgnoreCase("scp")) { + td = new ScpTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId)); + } else if (uri.getScheme().equalsIgnoreCase("nfs") || uri.getScheme().equalsIgnoreCase("cifs")) { + td = null; + // TODO: implement this. + throw new CloudRuntimeException("Scheme is not supported " + url); + } else { + throw new CloudRuntimeException("Scheme is not supported " + url); + } + } else { + throw new CloudRuntimeException("Unable to download from URL: " + url); + } + // NOTE the difference between installPathPrefix and templatePath + // here. instalPathPrefix is the absolute path for template + // including mount directory + // on ssvm, while templatePath is the final relative path on + // secondary storage. + DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType); + dj.setTmpltPath(templatePath); + jobs.put(jobId, dj); + threadPool.execute(td); - return jobId; + return jobId; } catch (IOException e) { s_logger.warn("Unable to download to " + tmpDir, e); return null; @@ -645,24 +611,24 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager public static VMTemplateHostVO.Status convertStatus(Status tds) { switch (tds) { - case ABORTED: - return VMTemplateHostVO.Status.NOT_DOWNLOADED; - case DOWNLOAD_FINISHED: - return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS; - case IN_PROGRESS: - return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS; - case NOT_STARTED: - return VMTemplateHostVO.Status.NOT_DOWNLOADED; - case RECOVERABLE_ERROR: - return VMTemplateHostVO.Status.NOT_DOWNLOADED; - case UNKNOWN: - return VMTemplateHostVO.Status.UNKNOWN; - case UNRECOVERABLE_ERROR: - return VMTemplateHostVO.Status.DOWNLOAD_ERROR; - case POST_DOWNLOAD_FINISHED: - return VMTemplateHostVO.Status.DOWNLOADED; - default: - return VMTemplateHostVO.Status.UNKNOWN; + case ABORTED: + return VMTemplateHostVO.Status.NOT_DOWNLOADED; + case DOWNLOAD_FINISHED: + return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS; + case IN_PROGRESS: + return VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS; + case NOT_STARTED: + return VMTemplateHostVO.Status.NOT_DOWNLOADED; + case RECOVERABLE_ERROR: + return VMTemplateHostVO.Status.NOT_DOWNLOADED; + case UNKNOWN: + return VMTemplateHostVO.Status.UNKNOWN; + case UNRECOVERABLE_ERROR: + return VMTemplateHostVO.Status.DOWNLOAD_ERROR; + case POST_DOWNLOAD_FINISHED: + return VMTemplateHostVO.Status.DOWNLOADED; + default: + return VMTemplateHostVO.Status.UNKNOWN; } } @@ -680,7 +646,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager if (cmd.getUrl() == null) { return new DownloadAnswer(resourceType.toString() + " is corrupted on storage due to an invalid url , cannot download", - VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); + VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } if (cmd.getName() == null) { @@ -697,27 +663,27 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String password = null; if (cmd.getAuth() != null) { user = cmd.getAuth().getUserName(); - password = new String(cmd.getAuth().getPassword()); + password = cmd.getAuth().getPassword(); } // TO DO - Define Volume max size as well long maxDownloadSizeInBytes = - (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes()); + (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes()); String jobId = null; if (dstore instanceof S3TO) { jobId = - downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), - cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), + cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); } else { jobId = - downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), - cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), + cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); } sleep(); if (jobId == null) { return new DownloadAnswer("Internal Error", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId), - getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId)); + getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId)); } private void sleep() { @@ -745,29 +711,29 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } TemplateDownloader td = dj.getTemplateDownloader(); switch (cmd.getRequest()) { - case GET_STATUS: - break; - case ABORT: - td.stopDownload(); - sleep(); - break; - case RESTART: - td.stopDownload(); - sleep(); - threadPool.execute(td); - break; - case PURGE: - td.stopDownload(); - answer = + case GET_STATUS: + break; + case ABORT: + td.stopDownload(); + sleep(); + break; + case RESTART: + td.stopDownload(); + sleep(); + threadPool.execute(td); + break; + case PURGE: + td.stopDownload(); + answer = new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), - getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId)); - jobs.remove(jobId); - return answer; - default: - break; // TODO + getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId)); + jobs.remove(jobId); + return answer; + default: + break; // TODO } return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId), - getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId)); + getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId)); } private String getInstallPath(String jobId) { @@ -778,16 +744,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return null; } - private String createTempDir(File rootDir, String name) throws IOException { - - File f = File.createTempFile(name, "", rootDir); - f.delete(); - f.mkdir(); - _storage.setWorldReadableAndWriteable(f); - return f.getAbsolutePath(); - - } - private List listVolumes(String rootdir) { List result = new ArrayList(); @@ -915,27 +871,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return result; } - private int deleteDownloadDirectories(File downloadPath, int deleted) { - try { - if (downloadPath.exists()) { - File[] files = downloadPath.listFiles(); - for (int i = 0; i < files.length; i++) { - if (files[i].isDirectory()) { - deleteDownloadDirectories(files[i], deleted); - files[i].delete(); - deleted++; - } else { - files[i].delete(); - deleted++; - } - } - } - } catch (Exception ex) { - s_logger.info("Failed to clean up template downloads directory " + ex.toString()); - } - return deleted; - } - public static class ZfsPathParser extends OutputInterpreter { String _parent; List paths = new ArrayList(); @@ -992,11 +927,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager throw new ConfigurationException("Unable to instantiate " + value); } } - String useSsl = (String)params.get("sslcopy"); - if (useSsl != null) { - _sslCopy = Boolean.parseBoolean(useSsl); - } String inSystemVM = (String)params.get("secondary.storage.vm"); if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) { s_logger.info("DownloadManager: starting additional services since we are inside system vm"); @@ -1081,7 +1012,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String intf = "eth1"; command.add("-c"); command.add("iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "80" + " -j REJECT;" + "iptables -A OUTPUT -o " + intf + - " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;"); + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;"); String result = command.execute(); if (result != null) { @@ -1120,7 +1051,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j ACCEPT;" + "iptables -I INPUT -i " + intf + - " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;"); + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;"); result = command.execute(); if (result != null) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java index dc0ef06b8ac..cdbc52dec5a 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/UploadManagerImpl.java @@ -21,7 +21,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -46,7 +45,6 @@ import com.cloud.storage.StorageLayer; import com.cloud.storage.Upload; import com.cloud.storage.UploadVO; import com.cloud.storage.template.FtpTemplateUploader; -import com.cloud.storage.template.Processor; import com.cloud.storage.template.TemplateUploader; import com.cloud.storage.template.TemplateUploader.Status; import com.cloud.storage.template.TemplateUploader.UploadCompleteCallback; @@ -72,87 +70,17 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { private static class UploadJob { private final TemplateUploader tu; - private final String jobId; - private final String name; - private final ImageFormat format; - private String tmpltPath; - private String description; - private String checksum; - private Long accountId; - private String installPathPrefix; - private long templatesize; - private long id; public UploadJob(TemplateUploader tu, String jobId, long id, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix) { super(); this.tu = tu; - this.jobId = jobId; - this.name = name; - this.format = format; - this.accountId = accountId; - this.description = descr; - this.checksum = cksum; - this.installPathPrefix = installPathPrefix; - this.templatesize = 0; - this.id = id; - } - - public TemplateUploader getTd() { - return tu; - } - - public String getDescription() { - return description; - } - - public String getChecksum() { - return checksum; - } - - public UploadJob(TemplateUploader td, String jobId, UploadCommand cmd) { - this.tu = td; - this.jobId = jobId; - this.name = cmd.getName(); - this.format = cmd.getFormat(); } public TemplateUploader getTemplateUploader() { return tu; } - public String getJobId() { - return jobId; - } - - public String getTmpltName() { - return name; - } - - public ImageFormat getFormat() { - return format; - } - - public Long getAccountId() { - return accountId; - } - - public long getId() { - return id; - } - - public void setTmpltPath(String tmpltPath) { - this.tmpltPath = tmpltPath; - } - - public String getTmpltPath() { - return tmpltPath; - } - - public String getInstallPathPrefix() { - return installPathPrefix; - } - public void cleanup() { if (tu != null) { String upldPath = tu.getUploadLocalPath(); @@ -163,30 +91,19 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { } } - public void setTemplatesize(long templatesize) { - this.templatesize = templatesize; - } - - public long getTemplatesize() { - return templatesize; - } } public static final Logger s_logger = Logger.getLogger(UploadManagerImpl.class); private ExecutorService threadPool; private final Map jobs = new ConcurrentHashMap(); private String parentDir; - private List _processors; - private String publicTemplateRepo; private final String extractMountPoint = "/mnt/SecStorage/extractmnt"; private StorageLayer _storage; - private int installTimeoutPerGig; - private boolean _sslCopy; private boolean hvm; @Override public String uploadPublicTemplate(long id, String url, String name, ImageFormat format, Long accountId, String descr, String cksum, String installPathPrefix, - String userName, String passwd, long templateSizeInBytes) { + String userName, String passwd, long templateSizeInBytes) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); @@ -253,24 +170,24 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { public static UploadVO.Status convertStatus(Status tds) { switch (tds) { - case ABORTED: - return UploadVO.Status.NOT_UPLOADED; - case UPLOAD_FINISHED: - return UploadVO.Status.UPLOAD_IN_PROGRESS; - case IN_PROGRESS: - return UploadVO.Status.UPLOAD_IN_PROGRESS; - case NOT_STARTED: - return UploadVO.Status.NOT_UPLOADED; - case RECOVERABLE_ERROR: - return UploadVO.Status.NOT_UPLOADED; - case UNKNOWN: - return UploadVO.Status.UNKNOWN; - case UNRECOVERABLE_ERROR: - return UploadVO.Status.UPLOAD_ERROR; - case POST_UPLOAD_FINISHED: - return UploadVO.Status.UPLOADED; - default: - return UploadVO.Status.UNKNOWN; + case ABORTED: + return UploadVO.Status.NOT_UPLOADED; + case UPLOAD_FINISHED: + return UploadVO.Status.UPLOAD_IN_PROGRESS; + case IN_PROGRESS: + return UploadVO.Status.UPLOAD_IN_PROGRESS; + case NOT_STARTED: + return UploadVO.Status.NOT_UPLOADED; + case RECOVERABLE_ERROR: + return UploadVO.Status.NOT_UPLOADED; + case UNKNOWN: + return UploadVO.Status.UNKNOWN; + case UNRECOVERABLE_ERROR: + return UploadVO.Status.UPLOAD_ERROR; + case POST_UPLOAD_FINISHED: + return UploadVO.Status.UPLOADED; + default: + return UploadVO.Status.UNKNOWN; } } @@ -296,29 +213,29 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { } TemplateUploader td = uj.getTemplateUploader(); switch (cmd.getRequest()) { - case GET_STATUS: - break; - case ABORT: - td.stopUpload(); - sleep(); - break; + case GET_STATUS: + break; + case ABORT: + td.stopUpload(); + sleep(); + break; /*case RESTART: td.stopUpload(); sleep(); threadPool.execute(td); break;*/ - case PURGE: - td.stopUpload(); - answer = + case PURGE: + td.stopUpload(); + answer = new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId), - getUploadTemplateSize(jobId)); - jobs.remove(jobId); - return answer; - default: - break; // TODO + getUploadTemplateSize(jobId)); + jobs.remove(jobId); + return answer; + default: + break; // TODO } return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId), - getUploadTemplateSize(jobId)); + getUploadTemplateSize(jobId)); } @Override @@ -331,14 +248,11 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { String user = null; String password = null; String jobId = - uploadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), - cmd.getInstallPath(), user, password, cmd.getTemplateSizeInBytes()); + uploadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), + cmd.getInstallPath(), user, password, cmd.getTemplateSizeInBytes()); sleep(); - if (jobId == null) { - return new UploadAnswer(null, 0, "Internal Error", com.cloud.storage.UploadVO.Status.UPLOAD_ERROR, "", "", 0); - } return new UploadAnswer(jobId, getUploadPct(jobId), getUploadError(jobId), getUploadStatus2(jobId), getUploadLocalPath(jobId), getInstallPath(jobId), - getUploadTemplateSize(jobId)); + getUploadTemplateSize(jobId)); } @Override @@ -435,13 +349,10 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { } private long getUploadTemplateSize(String jobId) { - UploadJob uj = jobs.get(jobId); - if (uj != null) { - return uj.getTemplatesize(); - } return 0; } + @SuppressWarnings("unchecked") @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -466,11 +377,7 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { throw new ConfigurationException("Unable to instantiate " + value); } } - String useSsl = (String)params.get("sslcopy"); - if (useSsl != null) { - _sslCopy = Boolean.parseBoolean(useSsl); - } String inSystemVM = (String)params.get("secondary.storage.vm"); if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) { s_logger.info("UploadManager: starting additional services since we are inside system vm"); @@ -478,9 +385,6 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { //blockOutgoingOnPrivate(); } - value = (String)params.get("install.timeout.pergig"); - this.installTimeoutPerGig = NumbersUtil.parseInt(value, 15 * 60) * 1000; - value = (String)params.get("install.numthreads"); final int numInstallThreads = NumbersUtil.parseInt(value, 10); @@ -544,43 +448,43 @@ public class UploadManagerImpl extends ManagerBase implements UploadManager { s_logger.warn("UploadedBytes=" + tu.getUploadedBytes() + ", error=" + tu.getUploadError() + ", pct=" + tu.getUploadPercent()); switch (status) { - case ABORTED: - case NOT_STARTED: - case UNRECOVERABLE_ERROR: - // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume. - if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) { - uj.cleanup(); - } - break; - case UNKNOWN: - return; - case IN_PROGRESS: - s_logger.info("Resuming jobId: " + jobId + ", status=" + status); - tu.setResume(true); - threadPool.execute(tu); - break; - case RECOVERABLE_ERROR: - threadPool.execute(tu); - break; - case UPLOAD_FINISHED: - tu.setUploadError("Upload success, starting install "); - String result = postUpload(jobId); - if (result != null) { - s_logger.error("Failed post upload script: " + result); - tu.setStatus(Status.UNRECOVERABLE_ERROR); - tu.setUploadError("Failed post upload script: " + result); - } else { - s_logger.warn("Upload completed successfully at " + new SimpleDateFormat().format(new Date())); - tu.setStatus(Status.POST_UPLOAD_FINISHED); - tu.setUploadError("Upload completed successfully at " + new SimpleDateFormat().format(new Date())); - } - // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume. - if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) { - uj.cleanup(); - } - break; - default: - break; + case ABORTED: + case NOT_STARTED: + case UNRECOVERABLE_ERROR: + // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume. + if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) { + uj.cleanup(); + } + break; + case UNKNOWN: + return; + case IN_PROGRESS: + s_logger.info("Resuming jobId: " + jobId + ", status=" + status); + tu.setResume(true); + threadPool.execute(tu); + break; + case RECOVERABLE_ERROR: + threadPool.execute(tu); + break; + case UPLOAD_FINISHED: + tu.setUploadError("Upload success, starting install "); + String result = postUpload(jobId); + if (result != null) { + s_logger.error("Failed post upload script: " + result); + tu.setStatus(Status.UNRECOVERABLE_ERROR); + tu.setUploadError("Failed post upload script: " + result); + } else { + s_logger.warn("Upload completed successfully at " + new SimpleDateFormat().format(new Date())); + tu.setStatus(Status.POST_UPLOAD_FINISHED); + tu.setUploadError("Upload completed successfully at " + new SimpleDateFormat().format(new Date())); + } + // Delete the entity only if its a volume. TO DO - find a better way of finding it a volume. + if (uj.getTemplateUploader().getUploadLocalPath().indexOf("volume") > -1) { + uj.cleanup(); + } + break; + default: + break; } } From 0685371179a22035351be1fa6151a39f16865ae6 Mon Sep 17 00:00:00 2001 From: Abhinandan Prateek Date: Fri, 17 Jan 2014 16:11:28 +0530 Subject: [PATCH 121/126] updating the jre to version 7 on system vms (cherry picked from commit fc2e7ec70a1cc48a10a168ec3df607b49a7bcdf6) Signed-off-by: Hugo Trippaers --- tools/appliance/definitions/systemvm64template/postinstall.sh | 2 +- tools/appliance/definitions/systemvmtemplate/postinstall.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/appliance/definitions/systemvm64template/postinstall.sh b/tools/appliance/definitions/systemvm64template/postinstall.sh index a9a057d4e55..144187d18e7 100644 --- a/tools/appliance/definitions/systemvm64template/postinstall.sh +++ b/tools/appliance/definitions/systemvm64template/postinstall.sh @@ -69,7 +69,7 @@ install_packages() { # ipcalc apt-get --no-install-recommends -q -y --force-yes install ipcalc # java - apt-get --no-install-recommends -q -y --force-yes install default-jre-headless + apt-get --no-install-recommends -q -y --force-yes install openjdk-7-jre-headless echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections diff --git a/tools/appliance/definitions/systemvmtemplate/postinstall.sh b/tools/appliance/definitions/systemvmtemplate/postinstall.sh index 48ba04b5280..a4ff11f2fbc 100644 --- a/tools/appliance/definitions/systemvmtemplate/postinstall.sh +++ b/tools/appliance/definitions/systemvmtemplate/postinstall.sh @@ -65,7 +65,7 @@ install_packages() { # ipcalc apt-get --no-install-recommends -q -y --force-yes install ipcalc # java - apt-get --no-install-recommends -q -y --force-yes install default-jre-headless + apt-get --no-install-recommends -q -y --force-yes install openjdk-7-jre-headless echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | debconf-set-selections echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | debconf-set-selections From d578d7ef85a7304aec18a207a35535f62eed0e0b Mon Sep 17 00:00:00 2001 From: Abhinandan Prateek Date: Fri, 17 Jan 2014 21:15:51 +0530 Subject: [PATCH 122/126] update packages list before getting jre 7 (cherry picked from commit 5121f8cd4e4adcdf23b6ec25cb1c28bec8f417a7) Signed-off-by: Hugo Trippaers --- tools/appliance/definitions/systemvm64template/postinstall.sh | 1 + tools/appliance/definitions/systemvmtemplate/postinstall.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/appliance/definitions/systemvm64template/postinstall.sh b/tools/appliance/definitions/systemvm64template/postinstall.sh index 144187d18e7..1eddbdb371c 100644 --- a/tools/appliance/definitions/systemvm64template/postinstall.sh +++ b/tools/appliance/definitions/systemvm64template/postinstall.sh @@ -68,6 +68,7 @@ install_packages() { apt-get --no-install-recommends -q -y --force-yes install keepalived conntrackd ipvsadm libnetfilter-conntrack3 libnl1 # ipcalc apt-get --no-install-recommends -q -y --force-yes install ipcalc + apt-get update # java apt-get --no-install-recommends -q -y --force-yes install openjdk-7-jre-headless diff --git a/tools/appliance/definitions/systemvmtemplate/postinstall.sh b/tools/appliance/definitions/systemvmtemplate/postinstall.sh index a4ff11f2fbc..175fc1f745b 100644 --- a/tools/appliance/definitions/systemvmtemplate/postinstall.sh +++ b/tools/appliance/definitions/systemvmtemplate/postinstall.sh @@ -64,6 +64,7 @@ install_packages() { apt-get --no-install-recommends -q -y --force-yes install keepalived conntrackd ipvsadm libnetfilter-conntrack3 libnl1 # ipcalc apt-get --no-install-recommends -q -y --force-yes install ipcalc + apt-get update # java apt-get --no-install-recommends -q -y --force-yes install openjdk-7-jre-headless From e8438f1b6df6dc0a3697148662a0dc5d7bd7996e Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Fri, 31 Jan 2014 17:08:34 +0530 Subject: [PATCH 123/126] CLOUDSTACK-5566: "Entity com.cloud.event.EventVO$$EnhancerByCGLIB$$9e317420@aeb3d75 and entity com.cloud.event.EventVO$$EnhancerByCGLIB$$9e317420@5a0fd1ec belong to different accounts" message while deleting multiple events . --- server/src/com/cloud/server/ManagementServerImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 4bffa3f60dd..449e879aa76 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -904,7 +904,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), permittedAccountIds); ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); - _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEvents); + _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, sameOwnerEvents); if (ids != null && events.size() < ids.size()) { result = false; @@ -931,7 +931,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getStartDate(), cmd.getEndDate(), permittedAccountIds); ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); - _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true, sameOwnerEvents); + _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, false, sameOwnerEvents); if (ids != null && events.size() < ids.size()) { result = false; From 48361d8a8bbfc5490f1afa01326ea477e1207e8e Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 30 Jan 2014 15:40:32 -0800 Subject: [PATCH 124/126] Fixed listAutoScaleVmGroups: used to return incorrect value in lbruleid field (wrong parameter was used when search in firewall_rules table - profileId instead of lbRuleId) --- server/src/com/cloud/api/ApiResponseHelper.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index a50b3eeffb2..4d9c2ddfb9e 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -30,8 +30,6 @@ import java.util.TimeZone; import javax.inject.Inject; -import org.apache.log4j.Logger; - import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.affinity.AffinityGroup; @@ -147,6 +145,7 @@ import org.apache.cloudstack.region.Region; import org.apache.cloudstack.usage.Usage; import org.apache.cloudstack.usage.UsageService; import org.apache.cloudstack.usage.UsageTypes; +import org.apache.log4j.Logger; import com.cloud.api.query.ViewResponseHelper; import com.cloud.api.query.vo.AccountJoinVO; @@ -2968,7 +2967,7 @@ public class ApiResponseHelper implements ResponseGenerator { if (profile != null) { response.setProfileId(profile.getUuid()); } - FirewallRuleVO fw = ApiDBUtils.findFirewallRuleById(vmGroup.getProfileId()); + FirewallRuleVO fw = ApiDBUtils.findFirewallRuleById(vmGroup.getLoadBalancerId()); if (fw != null) { response.setLoadBalancerId(fw.getUuid()); } From 158280181d61f463be32e2376159c868deafb511 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Thu, 30 Jan 2014 16:40:52 -0800 Subject: [PATCH 125/126] generateAlert API: set max value of "description" parameter to match correspondig field's length in VO object --- .../cloudstack/api/command/admin/alert/GenerateAlertCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java b/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java index 620c5ed8faa..3eaa0530646 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/alert/GenerateAlertCmd.java @@ -48,7 +48,7 @@ public class GenerateAlertCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "Name of the alert", required = true) private String name; - @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "Alert description", required = true) + @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "Alert description", required = true, length = 999) private String description; @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, description = "Zone id for which alert is generated") From 7d0472bdaa2d25f7a3658c44a11bebcfd258bc42 Mon Sep 17 00:00:00 2001 From: Prachi Damle Date: Thu, 30 Jan 2014 11:24:46 -0800 Subject: [PATCH 126/126] CLOUDSTACK-5995 ; change service offering is not honouring host tags - Check host tag when the lastHostId is set. --- .../deploy/DeploymentPlanningManagerImpl.java | 95 +++++++++++-------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java index 35a0b39acb2..3c87b249990 100644 --- a/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java +++ b/server/src/com/cloud/deploy/DeploymentPlanningManagerImpl.java @@ -362,49 +362,68 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy " already has max Running VMs(count includes system VMs), skipping this and trying other available hosts"); } else { if (host.getStatus() == Status.Up && host.getResourceState() == ResourceState.Enabled) { - long cluster_id = host.getClusterId(); - ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id, "cpuOvercommitRatio"); - ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id, "memoryOvercommitRatio"); - Float cpuOvercommitRatio = Float.parseFloat(cluster_detail_cpu.getValue()); - Float memoryOvercommitRatio = Float.parseFloat(cluster_detail_ram.getValue()); - if (_capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true, cpuOvercommitRatio, memoryOvercommitRatio, true) - && _capacityMgr.checkIfHostHasCpuCapability(host.getId(), offering.getCpu(), offering.getSpeed())) { - s_logger.debug("The last host of this VM is UP and has enough capacity"); - s_logger.debug("Now checking for suitable pools under zone: " + host.getDataCenterId() + ", pod: " + host.getPodId() + ", cluster: " + - host.getClusterId()); - // search for storage under the zone, pod, cluster of - // the last host. - DataCenterDeployment lastPlan = - new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null); - Pair>, List> result = - findSuitablePoolsForVolumes(vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL); - Map> suitableVolumeStoragePools = result.first(); - List readyAndReusedVolumes = result.second(); + boolean hostTagsMatch = true; + if(offering.getHostTag() != null){ + _hostDao.loadHostTags(host); + if (!(host.getHostTags() != null && host.getHostTags().contains(offering.getHostTag()))) { + hostTagsMatch = false; + } + } + if (hostTagsMatch) { + long cluster_id = host.getClusterId(); + ClusterDetailsVO cluster_detail_cpu = _clusterDetailsDao.findDetail(cluster_id, + "cpuOvercommitRatio"); + ClusterDetailsVO cluster_detail_ram = _clusterDetailsDao.findDetail(cluster_id, + "memoryOvercommitRatio"); + Float cpuOvercommitRatio = Float.parseFloat(cluster_detail_cpu.getValue()); + Float memoryOvercommitRatio = Float.parseFloat(cluster_detail_ram.getValue()); + if (_capacityMgr.checkIfHostHasCapacity(host.getId(), cpu_requested, ram_requested, true, + cpuOvercommitRatio, memoryOvercommitRatio, true) + && _capacityMgr.checkIfHostHasCpuCapability(host.getId(), offering.getCpu(), + offering.getSpeed())) { + s_logger.debug("The last host of this VM is UP and has enough capacity"); + s_logger.debug("Now checking for suitable pools under zone: " + host.getDataCenterId() + + ", pod: " + host.getPodId() + ", cluster: " + host.getClusterId()); + // search for storage under the zone, pod, cluster + // of + // the last host. + DataCenterDeployment lastPlan = new DataCenterDeployment(host.getDataCenterId(), + host.getPodId(), host.getClusterId(), host.getId(), plan.getPoolId(), null); + Pair>, List> result = findSuitablePoolsForVolumes( + vmProfile, lastPlan, avoids, HostAllocator.RETURN_UPTO_ALL); + Map> suitableVolumeStoragePools = result.first(); + List readyAndReusedVolumes = result.second(); - // choose the potential pool for this VM for this host - if (!suitableVolumeStoragePools.isEmpty()) { - List suitableHosts = new ArrayList(); - suitableHosts.add(host); - Pair> potentialResources = findPotentialDeploymentResources( - suitableHosts, suitableVolumeStoragePools, avoids, - getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes); - if (potentialResources != null) { - Pod pod = _podDao.findById(host.getPodId()); - Cluster cluster = _clusterDao.findById(host.getClusterId()); - Map storageVolMap = potentialResources.second(); - // remove the reused vol<->pool from - // destination, since we don't have to prepare - // this volume. - for (Volume vol : readyAndReusedVolumes) { - storageVolMap.remove(vol); + // choose the potential pool for this VM for this + // host + if (!suitableVolumeStoragePools.isEmpty()) { + List suitableHosts = new ArrayList(); + suitableHosts.add(host); + Pair> potentialResources = findPotentialDeploymentResources( + suitableHosts, suitableVolumeStoragePools, avoids, + getPlannerUsage(planner, vmProfile, plan, avoids), readyAndReusedVolumes); + if (potentialResources != null) { + Pod pod = _podDao.findById(host.getPodId()); + Cluster cluster = _clusterDao.findById(host.getClusterId()); + Map storageVolMap = potentialResources.second(); + // remove the reused vol<->pool from + // destination, since we don't have to + // prepare + // this volume. + for (Volume vol : readyAndReusedVolumes) { + storageVolMap.remove(vol); + } + DeployDestination dest = new DeployDestination(dc, pod, cluster, host, + storageVolMap); + s_logger.debug("Returning Deployment Destination: " + dest); + return dest; } - DeployDestination dest = new DeployDestination(dc, pod, cluster, host, storageVolMap); - s_logger.debug("Returning Deployment Destination: " + dest); - return dest; } + } else { + s_logger.debug("The last host of this VM does not have enough capacity"); } } else { - s_logger.debug("The last host of this VM does not have enough capacity"); + s_logger.debug("Service Offering host tag does not match the last host of this VM"); } } else { s_logger.debug("The last host of this VM is not UP or is not enabled, host status is: " + host.getStatus().name() + ", host resource state is: " +