diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java index 9fda4e46446..0e2be2bc31d 100644 --- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java @@ -38,7 +38,6 @@ public class VirtualMachineTO { String bootArgs; String[] bootupScripts; boolean rebootOnCrash; - Monitor monitor; VolumeTO[] disks; NicTO[] nics; @@ -70,14 +69,6 @@ public class VirtualMachineTO { return name; } - public Monitor getMonitor() { - return monitor; - } - - public void setMonitor(Monitor monitor) { - this.monitor = monitor; - } - public void setName(String name) { this.name = name; } @@ -187,26 +178,4 @@ public class VirtualMachineTO { public void setNics(NicTO[] nics) { this.nics = nics; } - - public static interface Monitor { - - } - - public static class SshMonitor implements Monitor { - String ip; - int port; - - public String getIp() { - return ip; - } - - public int getPort() { - return port; - } - - public SshMonitor(String ip, int port) { - this.ip = ip; - this.port = port; - } - } } diff --git a/api/src/com/cloud/api/commands/AddHostCmd.java b/api/src/com/cloud/api/commands/AddHostCmd.java index a1f7b02754d..e73eb037864 100644 --- a/api/src/com/cloud/api/commands/AddHostCmd.java +++ b/api/src/com/cloud/api/commands/AddHostCmd.java @@ -63,7 +63,7 @@ public class AddHostCmd extends BaseCmd { @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the Zone ID for the host") private Long zoneId; - @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, required=false, description="hypervisor type of the host") + @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, required=true, description="hypervisor type of the host") private String hypervisor; diff --git a/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java b/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java index 008f4fe8a0d..e1da8de662c 100644 --- a/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java +++ b/api/src/com/cloud/api/commands/AuthorizeSecurityGroupIngressCmd.java @@ -40,7 +40,6 @@ import com.cloud.user.Account; import com.cloud.user.UserContext; import com.cloud.utils.StringUtils; -//FIXME - add description @Implementation(responseObject=IngressRuleResponse.class) @SuppressWarnings("rawtypes") public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(AuthorizeSecurityGroupIngressCmd.class.getName()); @@ -54,40 +53,31 @@ public class AuthorizeSecurityGroupIngressCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, description="TCP is default. UDP is the other supported protocol") private String protocol; - //FIXME - add description - @Parameter(name=ApiConstants.START_PORT, type=CommandType.INTEGER) + @Parameter(name=ApiConstants.START_PORT, type=CommandType.INTEGER, description="start port for this ingress rule") private Integer startPort; - //FIXME - add description - @Parameter(name=ApiConstants.END_PORT, type=CommandType.INTEGER) + @Parameter(name=ApiConstants.END_PORT, type=CommandType.INTEGER, description="end port for this ingress rule") private Integer endPort; - //FIXME - add description - @Parameter(name=ApiConstants.ICMP_TYPE, type=CommandType.INTEGER) + @Parameter(name=ApiConstants.ICMP_TYPE, type=CommandType.INTEGER, description="type of the icmp message being sent") private Integer icmpType; - //FIXME - add description - @Parameter(name=ApiConstants.ICMP_CODE, type=CommandType.INTEGER) + @Parameter(name=ApiConstants.ICMP_CODE, type=CommandType.INTEGER, description="error code for this icmp message") private Integer icmpCode; - //FIXME - add description - @Parameter(name=ApiConstants.SECURITY_GROUP_NAME, type=CommandType.STRING, required=true) + @Parameter(name=ApiConstants.SECURITY_GROUP_NAME, type=CommandType.STRING, required=true, description="the security group name") private String securityGroupName; - //FIXME - add description - @Parameter(name=ApiConstants.CIDR_LIST, type=CommandType.LIST, collectionType=CommandType.STRING) + @Parameter(name=ApiConstants.CIDR_LIST, type=CommandType.LIST, collectionType=CommandType.STRING, description="the cidr list associated") private List cidrList; - //FIXME - add description - @Parameter(name=ApiConstants.USER_SECURITY_GROUP_LIST, type=CommandType.MAP) + @Parameter(name=ApiConstants.USER_SECURITY_GROUP_LIST, type=CommandType.MAP, description="user to security group mapping") private Map userSecurityGroupList; - //FIXME - add description - @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING) + @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, description="an optional account for the security group. Must be used with domainId.") private String accountName; - //FIXME - add description - @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG) + @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="an optional domainId for the security group. If the account parameter is used, domainId must also be used.") private Long domainId; diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index 17bc361f43c..2686617a9fb 100644 --- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -74,11 +74,11 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements @Override public String getProtocol() { - return protocol; + return protocol.trim(); } public String getPublicPort() { - return publicPort; + return publicPort.trim(); } @Override @@ -133,17 +133,17 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements @Override public Ip getSourceIpAddress() { - return new Ip(ipAddress); + return new Ip(ipAddress.trim()); } @Override public int getSourcePortStart() { - return Integer.parseInt(publicPort); + return Integer.parseInt(publicPort.trim()); } @Override public int getSourcePortEnd() { - return Integer.parseInt(publicPort); + return Integer.parseInt(publicPort.trim()); } @Override diff --git a/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java b/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java index 1864b4e06b9..64c726bd64f 100644 --- a/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java +++ b/api/src/com/cloud/api/commands/ListNetworkOfferingsCmd.java @@ -49,9 +49,6 @@ public class ListNetworkOfferingsCmd extends BaseListCmd { @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, description="list network offerings by display text") private String displayText; - @Parameter(name=ApiConstants.TYPE, type=CommandType.STRING, description="list by type of the network") - private String type; - @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.STRING, description="list by traffic type") private String trafficType; @@ -78,11 +75,7 @@ public class ListNetworkOfferingsCmd extends BaseListCmd { public String getDisplayText() { return displayText; } - - public String getType() { - return type; - } - + public String getTrafficType() { return trafficType; } diff --git a/api/src/com/cloud/event/ActionEvent.java b/api/src/com/cloud/event/ActionEvent.java new file mode 100644 index 00000000000..b890172ec77 --- /dev/null +++ b/api/src/com/cloud/event/ActionEvent.java @@ -0,0 +1,21 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.event; + +public @interface ActionEvent { +} diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index 6a36b071370..9f4b70ba245 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -85,6 +85,7 @@ public interface NetworkOffering { Availability getAvailability(); + boolean isDnsService(); boolean isGatewayService(); diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index f152f103fcd..5f1d7fd299e 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -23,6 +23,7 @@ documented, please contact the author. --> + diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 011d5e8a605..d7aa0500dd9 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -148,8 +148,6 @@ import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; -import com.cloud.agent.api.to.VirtualMachineTO.Monitor; -import com.cloud.agent.api.to.VirtualMachineTO.SshMonitor; import com.cloud.agent.api.to.VolumeTO; import com.cloud.dc.Vlan; import com.cloud.exception.InternalErrorException; @@ -829,25 +827,6 @@ public abstract class CitrixResourceBase implements ServerResource { } } } - - Monitor monitor = vmSpec.getMonitor(); - if (monitor != null && monitor instanceof SshMonitor) { - SshMonitor sshMon = (SshMonitor)monitor; - String privateIp = sshMon.getIp(); - int cmdPort = sshMon.getPort(); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Ping command port, " + privateIp + ":" + cmdPort); - } - - String result = connect(conn, vmName, privateIp, cmdPort); - if (result != null) { - throw new CloudRuntimeException("Can not ping System vm " + vmName + "due to:" + result); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Ping command port succeeded for vm " + vmName); - } - } state = State.Running; return new StartAnswer(cmd); @@ -2604,7 +2583,7 @@ public abstract class CitrixResourceBase implements ServerResource { } } - void startVM(Connection conn, Host host, VM vm, String vmName) { + void startVM(Connection conn, Host host, VM vm, String vmName) throws XmlRpcException { try { vm.startOn(conn, host, false, true); } catch (Exception e) { diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index b908ae4d341..f0a50327f00 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -1531,7 +1531,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Long dcId = host.getDataCenterId(); ReadyCommand ready = new ReadyCommand(dcId); Answer answer = easySend(hostId, ready); - if (answer == null) { + if (answer == null || !answer.getResult()) { // this is tricky part for secondary storage // make it as disconnected, wait for secondary storage VM to be up // return the attache instead of null, even it is disconnectede diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 57cfce0d2a8..e7f2becfbc7 100644 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -154,7 +154,7 @@ public enum Config { MaxTemplateAndIsoSize("Advanced", ManagementServer.class, Long.class, "max.template.iso.size", "50", "The maximum size for a downloaded template or ISO (in GB).", null), SecStorageAllowedInternalDownloadSites("Advanced", ManagementServer.class, String.class, "secstorage.allowed.internal.sites", null, "Comma separated list of cidrs internal to the datacenter that can host template download servers", null), SecStorageEncryptCopy("Advanced", ManagementServer.class, Boolean.class, "secstorage.encrypt.copy", "false", "Use SSL method used to encrypt copy traffic between zones", "true,false"), - SecStorageSecureCopyCert("Advanced", ManagementServer.class, Boolean.class, "secstorage.ssl.cert.domain", "realhostip.com", "SSL certificate used to encrypt copy traffic between zones", "realhostip.com"), + SecStorageSecureCopyCert("Advanced", ManagementServer.class, String.class, "secstorage.ssl.cert.domain", "realhostip.com", "SSL certificate used to encrypt copy traffic between zones", null), DirectAttachSecurityGroupsEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.security.groups.enabled", "false", "Ec2-style distributed firewall for direct-attach VMs", "true,false"), DirectAttachNetworkEnabled("Advanced", ManagementServer.class, Boolean.class, "direct.attach.network.externalIpAllocator.enabled", "false", "Direct-attach VMs using external DHCP server", "true,false"), DirectAttachNetworkExternalAPIURL("Advanced", ManagementServer.class, String.class, "direct.attach.network.externalIpAllocator.url", null, "Direct-attach VMs using external DHCP server (API url)", null), diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 968f025a330..8edd2c78c9e 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -285,7 +285,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (type.equals(Boolean.class)) { if (!(value.equals("true") || value.equals("false"))) { s_logger.error("Configuration variable " + name + " is expecting true or false in stead of " + value); - return "Please enter either \"true\" or \"false\"."; + return "Please enter either 'true' or 'false'."; } return null; } @@ -2739,7 +2739,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura Object id = cmd.getId(); Object name = cmd.getNetworkOfferingName(); Object displayText = cmd.getDisplayText(); - Object type = cmd.getType(); Object trafficType = cmd.getTrafficType(); Object isDefault = cmd.getIsDefault(); Object specifyVlan = cmd.getSpecifyVlan(); @@ -2765,9 +2764,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura if (displayText != null) { sc.addAnd("displayText", SearchCriteria.Op.LIKE, "%" + displayText + "%"); } - if (type != null) { - sc.addAnd("guestIpType", SearchCriteria.Op.EQ, type); - } if (trafficType != null) { sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType); diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 04a13bfb1ee..d0c1b05bdd3 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -334,4 +334,5 @@ public class DefaultComponentLibrary implements ComponentLibrary { factories.put(EntityManager.class, EntityManagerImpl.class); return factories; } + } diff --git a/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java b/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java new file mode 100644 index 00000000000..846f8d0533b --- /dev/null +++ b/server/src/com/cloud/configuration/DefaultInterceptorLibrary.java @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.configuration; + +import java.util.List; + +import com.cloud.utils.component.AnnotationInterceptor; +import com.cloud.utils.component.InterceptorLibrary; +import com.cloud.utils.db.DatabaseCallback; + +public class DefaultInterceptorLibrary implements InterceptorLibrary { + + @Override + public void addInterceptors(List> interceptors) { + interceptors.add(new DatabaseCallback()); + } +} diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index c953144543c..e77fec8d2e4 100644 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -91,7 +91,7 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu return -1; } GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getName())); - return answer == null ? -1 : answer.getPort(); + return (answer == null || !answer.getResult()) ? -1 : answer.getPort(); } @Override diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 0b4819018b8..129cd3f90a2 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -1531,7 +1531,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx final RebootCommand cmd = new RebootCommand(proxy.getInstanceName()); final Answer answer = _agentMgr.easySend(proxy.getHostId(), cmd); - if (answer != null) { + if (answer != null && answer.getResult()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully reboot console proxy " + proxy.getName()); } @@ -1708,7 +1708,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx MigrateCommand cmd = new MigrateCommand(proxy.getInstanceName(), host.getPrivateIpAddress(), false); Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); - if (answer == null) { + if (answer == null || !answer.getResult()) { return false; } diff --git a/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java b/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java index 38728608fb6..4dd5ce8582d 100644 --- a/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java +++ b/server/src/com/cloud/dc/dao/DataCenterDaoImpl.java @@ -58,10 +58,10 @@ public class DataCenterDaoImpl extends GenericDaoBase implem protected SearchBuilder PublicZonesSearch; protected SearchBuilder ChildZonesSearch; - protected static final DataCenterIpAddressDaoImpl _ipAllocDao = ComponentLocator.inject(DataCenterIpAddressDaoImpl.class); - protected static final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class); - protected static final DataCenterVnetDaoImpl _vnetAllocDao = ComponentLocator.inject(DataCenterVnetDaoImpl.class); - protected static final PodVlanDaoImpl _podVlanAllocDao = ComponentLocator.inject(PodVlanDaoImpl.class); + protected final DataCenterIpAddressDaoImpl _ipAllocDao = ComponentLocator.inject(DataCenterIpAddressDaoImpl.class); + protected final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class); + protected final DataCenterVnetDaoImpl _vnetAllocDao = ComponentLocator.inject(DataCenterVnetDaoImpl.class); + protected final PodVlanDaoImpl _podVlanAllocDao = ComponentLocator.inject(PodVlanDaoImpl.class); protected long _prefix; protected Random _rand = new Random(System.currentTimeMillis()); protected TableGenerator _tgMacAddress; diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index d8dd1982248..6d3896751de 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -32,6 +32,7 @@ import com.cloud.network.Network.Capability; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; +import com.cloud.network.guru.NetworkGuru; import com.cloud.network.rules.FirewallRule; import com.cloud.network.vpn.RemoteAccessVpnElement; import com.cloud.offerings.NetworkOfferingVO; @@ -140,4 +141,5 @@ public interface NetworkManager extends NetworkService { List listPodVlans(long podId); + Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 3addb3b067e..6020d0efc0a 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -20,8 +20,6 @@ package com.cloud.network; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -36,11 +34,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; -import com.cloud.agent.AgentManager; -import com.cloud.agent.AgentManager.OnError; -import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.NicTO; -import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.BaseCmd; import com.cloud.api.commands.AssociateIPAddrCmd; @@ -48,10 +42,12 @@ import com.cloud.api.commands.CreateNetworkCmd; import com.cloud.api.commands.DisassociateIPAddrCmd; import com.cloud.api.commands.ListNetworksCmd; import com.cloud.api.commands.RestartNetworkCmd; +import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.ResourceCount.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; @@ -75,12 +71,10 @@ import com.cloud.event.UsageEventVO; import com.cloud.event.dao.EventDao; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AccountLimitException; -import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; @@ -92,17 +86,13 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.RemoteAccessVpnDao; import com.cloud.network.element.NetworkElement; import com.cloud.network.guru.NetworkGuru; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRulesManager; -import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.PortForwardingRule; -import com.cloud.network.rules.PortForwardingRuleVO; import com.cloud.network.rules.RulesManager; -import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.vpn.RemoteAccessVpnElement; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; @@ -165,7 +155,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject EventDao _eventDao = null; @Inject ConfigurationDao _configDao; @Inject UserVmDao _vmDao = null; - @Inject AgentManager _agentMgr; + @Inject ResourceLimitDao _limitDao = null; + @Inject CapacityDao _capacityDao = null; @Inject AlertManager _alertMgr; @Inject AccountManager _accountMgr; @Inject ConfigurationManager _configMgr; @@ -173,8 +164,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Inject NetworkOfferingDao _networkOfferingDao = null; @Inject NetworkDao _networksDao = null; @Inject NicDao _nicDao = null; - @Inject RemoteAccessVpnDao _remoteAccessVpnDao = null; - @Inject VirtualNetworkApplianceManager _routerMgr; @Inject RulesManager _rulesMgr; @Inject LoadBalancingRulesManager _lbMgr; @Inject UsageEventDao _usageEventDao; @@ -355,77 +344,77 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag @Override public boolean associateIP(final DomainRouterVO router, final List ipAddrList, final boolean add, long vmId) { - Commands cmds = new Commands(OnError.Continue); - boolean sourceNat = false; - Map> vlanIpMap = new HashMap>(); - for (final String ipAddress: ipAddrList) { - IPAddressVO ip = _ipAddressDao.findById(new Ip(ipAddress)); - - VlanVO vlan = _vlanDao.findById(ip.getVlanId()); - ArrayList ipList = vlanIpMap.get(vlan.getId()); - if (ipList == null) { - ipList = new ArrayList(); - } - ipList.add(ip); - vlanIpMap.put(vlan, ipList); - } - for (Map.Entry> vlanAndIp: vlanIpMap.entrySet()) { - boolean firstIP = true; - ArrayList ipList = vlanAndIp.getValue(); - Collections.sort(ipList, new Comparator() { - @Override - public int compare(IPAddressVO o1, IPAddressVO o2) { - return o1.getAddress().compareTo(o2.getAddress()); - } }); - - for (final IPAddressVO ip: ipList) { - sourceNat = ip.isSourceNat(); - VlanVO vlan = vlanAndIp.getKey(); - String vlanId = vlan.getVlanTag(); - String vlanGateway = vlan.getVlanGateway(); - String vlanNetmask = vlan.getVlanNetmask(); - - String vifMacAddress = null; - if (firstIP && add) { - String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId()); - vifMacAddress = macAddresses[1]; - } - String vmGuestAddress = null; - if(vmId!=0){ - vmGuestAddress = _vmDao.findById(vmId).getGuestIpAddress(); - } - - //cmds.addCommand(new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress)); - - firstIP = false; - } - } - - Answer[] answers = null; - try { - answers = _agentMgr.send(router.getHostId(), cmds); - } catch (final AgentUnavailableException e) { - s_logger.warn("Agent unavailable", e); - return false; - } catch (final OperationTimedoutException e) { - s_logger.warn("Timed Out", e); - return false; - } - - if (answers == null) { - return false; - } - - if (answers.length != ipAddrList.size()) { - return false; - } - - // FIXME: this used to be a loop for all answers, but then we always returned the - // first one in the array, so what should really be done here? - if (answers.length > 0) { - Answer ans = answers[0]; - return ans.getResult(); - } +// Commands cmds = new Commands(OnError.Continue); +// boolean sourceNat = false; +// Map> vlanIpMap = new HashMap>(); +// for (final String ipAddress: ipAddrList) { +// IPAddressVO ip = _ipAddressDao.findById(new Ip(ipAddress)); +// +// VlanVO vlan = _vlanDao.findById(ip.getVlanId()); +// ArrayList ipList = vlanIpMap.get(vlan.getId()); +// if (ipList == null) { +// ipList = new ArrayList(); +// } +// ipList.add(ip); +// vlanIpMap.put(vlan, ipList); +// } +// for (Map.Entry> vlanAndIp: vlanIpMap.entrySet()) { +// boolean firstIP = true; +// ArrayList ipList = vlanAndIp.getValue(); +// Collections.sort(ipList, new Comparator() { +// @Override +// public int compare(IPAddressVO o1, IPAddressVO o2) { +// return o1.getAddress().compareTo(o2.getAddress()); +// } }); +// +// for (final IPAddressVO ip: ipList) { +// sourceNat = ip.isSourceNat(); +// VlanVO vlan = vlanAndIp.getKey(); +// String vlanId = vlan.getVlanTag(); +// String vlanGateway = vlan.getVlanGateway(); +// String vlanNetmask = vlan.getVlanNetmask(); +// +// String vifMacAddress = null; +// if (firstIP && add) { +// String[] macAddresses = _dcDao.getNextAvailableMacAddressPair(ip.getDataCenterId()); +// vifMacAddress = macAddresses[1]; +// } +// String vmGuestAddress = null; +// if(vmId!=0){ +// vmGuestAddress = _vmDao.findById(vmId).getGuestIpAddress(); +// } +// +// //cmds.addCommand(new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ip.getAddress(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress)); +// +// firstIP = false; +// } +// } +// +// Answer[] answers = null; +// try { +// answers = _agentMgr.send(router.getHostId(), cmds); +// } catch (final AgentUnavailableException e) { +// s_logger.warn("Agent unavailable", e); +// return false; +// } catch (final OperationTimedoutException e) { +// s_logger.warn("Timed Out", e); +// return false; +// } +// +// if (answers == null) { +// return false; +// } +// +// if (answers.length != ipAddrList.size()) { +// return false; +// } +// +// // FIXME: this used to be a loop for all answers, but then we always returned the +// // first one in the array, so what should really be done here? +// if (answers.length > 0) { +// Answer ans = answers[0]; +// return ans.getResult(); +// } return true; } @@ -995,8 +984,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return to; } + @Override @DB - protected Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public Pair implementNetwork(long networkId, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { Transaction.currentTxn(); Pair implemented = new Pair(null, null); @@ -1440,6 +1430,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag isSystem = false; } + //Account/domainId parameters and isSystem are mutually exclusive + if (isSystem && (accountName != null || domainId != null)) { + throw new InvalidParameterValueException("System network belongs to system, account and domainId parameters can't be specified"); + } + if (_accountMgr.isAdmin(account.getType())) { if (domainId != null) { if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { @@ -1502,7 +1497,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (type != null) { sc.addAnd("guestType", SearchCriteria.Op.EQ, type); } - if (account.getType() != Account.ACCOUNT_TYPE_ADMIN || (accountName != null && domainId != null)) { + + if (!isSystem && (account.getType() != Account.ACCOUNT_TYPE_ADMIN || (accountName != null && domainId != null))) { sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); } diff --git a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java b/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java index 20e6880f14b..f4df776966e 100644 --- a/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java +++ b/server/src/com/cloud/network/security/dao/SecurityGroupDaoImpl.java @@ -40,7 +40,7 @@ public class SecurityGroupDaoImpl extends GenericDaoBase AccountIdNameSearch = createSearchBuilder(); AccountIdNameSearch.and("accountId", AccountIdNameSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - AccountIdNameSearch.and("groupName", AccountIdNameSearch.entity().getName(), SearchCriteria.Op.EQ); + AccountIdNameSearch.and("name", AccountIdNameSearch.entity().getName(), SearchCriteria.Op.EQ); AccountIdNamesSearch = createSearchBuilder(); AccountIdNamesSearch.and("accountId", AccountIdNamesSearch.entity().getAccountId(), SearchCriteria.Op.EQ); @@ -74,7 +74,7 @@ public class SecurityGroupDaoImpl extends GenericDaoBase public SecurityGroupVO findByAccountAndName(Long accountId, String name) { SearchCriteria sc = AccountIdNameSearch.create(); sc.setParameters("accountId", accountId); - sc.setParameters("groupName", name); + sc.setParameters("name", name); return findOneIncludingRemovedBy(sc); } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 20944dcd134..8c042489443 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -2729,7 +2729,7 @@ public class ManagementServerImpl implements ManagementServer { } GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getInstanceName())); - if(answer != null) { + if(answer != null && answer.getResult()) { return new Pair(answer.getAddress(), answer.getPort()); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 0ba0d3f998b..74c5198cb4f 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1477,11 +1477,9 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag DeleteStoragePoolCommand cmd = new DeleteStoragePoolCommand(sPool); final Answer answer = _agentMgr.easySend(host.getHostId(), cmd); - if (answer != null) { - if (answer.getResult() == true) { - deleteFlag = true; - break; - } + if (answer != null && answer.getResult()) { + deleteFlag = true; + break; } } @@ -2006,18 +2004,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag try { s_logger.info("Storage Garbage Collection Thread is running."); - GlobalLock scanLock = GlobalLock.getInternLock(this.getClass().getName()); - try { - if (scanLock.lock(3)) { - try { - cleanupStorage(true); - } finally { - scanLock.unlock(); - } - } - } finally { - scanLock.releaseRef(); - } + cleanupStorage(true); } catch (Exception e) { s_logger.error("Caught the following Exception", e); @@ -2027,89 +2014,99 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag @Override public void cleanupStorage(boolean recurring) { + GlobalLock scanLock = GlobalLock.getInternLock(this.getClass().getName()); + + try { + if (scanLock.lock(3)) { + try { + // Cleanup primary storage pools + List storagePools = _storagePoolDao.listAll(); + for (StoragePoolVO pool : storagePools) { + try { + if (recurring && pool.isLocal()) { + continue; + } - // Cleanup primary storage pools - List storagePools = _storagePoolDao.listAll(); - for (StoragePoolVO pool : storagePools) { - try { - if (recurring && pool.isLocal()) { - continue; - } - - List unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool); - s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName()); - for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) { - if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - s_logger.debug("Storage pool garbage collector is skipping templatePoolVO with ID: " + templatePoolVO.getId() + " because it is not completely downloaded."); - continue; - } - - if (!templatePoolVO.getMarkedForGC()) { - templatePoolVO.setMarkedForGC(true); - _vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO); - s_logger.debug("Storage pool garbage collector has marked templatePoolVO with ID: " + templatePoolVO.getId() + " for garbage collection."); - continue; - } - - _tmpltMgr.evictTemplateFromStoragePool(templatePoolVO); - } - } catch (Exception e) { - s_logger.warn("Problem cleaning up primary storage pool " + pool, e); - } - } + List unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool); + s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName()); + for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) { + if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + s_logger.debug("Storage pool garbage collector is skipping templatePoolVO with ID: " + templatePoolVO.getId() + " because it is not completely downloaded."); + continue; + } - // Cleanup secondary storage hosts - List secondaryStorageHosts = _hostDao.listSecondaryStorageHosts(); - for (HostVO secondaryStorageHost : secondaryStorageHosts) { - try { - long hostId = secondaryStorageHost.getId(); - List destroyedTemplateHostVOs = _vmTemplateHostDao.listDestroyed(hostId); - s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateHostVOs.size() + " templates to cleanup on secondary storage host: " - + secondaryStorageHost.getName()); - for (VMTemplateHostVO destroyedTemplateHostVO : destroyedTemplateHostVOs) { - if (!_tmpltMgr.templateIsDeleteable(destroyedTemplateHostVO)) { - s_logger.debug("Not deleting template at: " + destroyedTemplateHostVO.getInstallPath()); - continue; - } - - String installPath = destroyedTemplateHostVO.getInstallPath(); - - if (installPath != null) { - Answer answer = _agentMgr.easySend(hostId, new DeleteTemplateCommand(destroyedTemplateHostVO.getInstallPath())); - - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete template at: " + destroyedTemplateHostVO.getInstallPath()); - } else { - _vmTemplateHostDao.remove(destroyedTemplateHostVO.getId()); - s_logger.debug("Deleted template at: " + destroyedTemplateHostVO.getInstallPath()); - } - } else { - _vmTemplateHostDao.remove(destroyedTemplateHostVO.getId()); - } - } - } catch (Exception e) { - s_logger.warn("problem cleaning up secondary storage " + secondaryStorageHost, e); - } - } - - List vols = _volsDao.listRemovedButNotDestroyed(); - for (VolumeVO vol : vols) { - try { - Long poolId = vol.getPoolId(); - Answer answer = null; - StoragePoolVO pool = _storagePoolDao.findById(poolId); - final DestroyCommand cmd = new DestroyCommand(pool, vol, null); - answer = sendToPool(pool, cmd); - if (answer != null && answer.getResult()) { - s_logger.debug("Destroyed " + vol); - vol.setDestroyed(true); - _volsDao.update(vol.getId(), vol); - } - } catch (Exception e) { - s_logger.warn("Unable to destroy " + vol.getId(), e); - } - } + if (!templatePoolVO.getMarkedForGC()) { + templatePoolVO.setMarkedForGC(true); + _vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO); + s_logger.debug("Storage pool garbage collector has marked templatePoolVO with ID: " + templatePoolVO.getId() + " for garbage collection."); + continue; + } + _tmpltMgr.evictTemplateFromStoragePool(templatePoolVO); + } + } catch (Exception e) { + s_logger.warn("Problem cleaning up primary storage pool " + pool, e); + } + } + + // Cleanup secondary storage hosts + List secondaryStorageHosts = _hostDao.listSecondaryStorageHosts(); + for (HostVO secondaryStorageHost : secondaryStorageHosts) { + try { + long hostId = secondaryStorageHost.getId(); + List destroyedTemplateHostVOs = _vmTemplateHostDao.listDestroyed(hostId); + s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateHostVOs.size() + " templates to cleanup on secondary storage host: " + + secondaryStorageHost.getName()); + for (VMTemplateHostVO destroyedTemplateHostVO : destroyedTemplateHostVOs) { + if (!_tmpltMgr.templateIsDeleteable(destroyedTemplateHostVO)) { + s_logger.debug("Not deleting template at: " + destroyedTemplateHostVO.getInstallPath()); + continue; + } + + String installPath = destroyedTemplateHostVO.getInstallPath(); + + if (installPath != null) { + Answer answer = _agentMgr.easySend(hostId, new DeleteTemplateCommand(destroyedTemplateHostVO.getInstallPath())); + + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to delete template at: " + destroyedTemplateHostVO.getInstallPath()); + } else { + _vmTemplateHostDao.remove(destroyedTemplateHostVO.getId()); + s_logger.debug("Deleted template at: " + destroyedTemplateHostVO.getInstallPath()); + } + } else { + _vmTemplateHostDao.remove(destroyedTemplateHostVO.getId()); + } + } + } catch (Exception e) { + s_logger.warn("problem cleaning up secondary storage " + secondaryStorageHost, e); + } + } + + List vols = _volsDao.listRemovedButNotDestroyed(); + for (VolumeVO vol : vols) { + try { + Long poolId = vol.getPoolId(); + Answer answer = null; + StoragePoolVO pool = _storagePoolDao.findById(poolId); + final DestroyCommand cmd = new DestroyCommand(pool, vol, null); + answer = sendToPool(pool, cmd); + if (answer != null && answer.getResult()) { + s_logger.debug("Destroyed " + vol); + vol.setDestroyed(true); + _volsDao.update(vol.getId(), vol); + } + } catch (Exception e) { + s_logger.warn("Unable to destroy " + vol.getId(), e); + } + } + } finally { + scanLock.unlock(); + } + } + } finally { + scanLock.releaseRef(); + } } @Override diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 4b47bb2df79..ace1022cd41 100644 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -315,7 +315,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V setupCmd.setCopyPassword(copyPasswd); setupCmd.setCopyUserName(TemplateConstants.DEFAULT_HTTP_AUTH_USER); Answer answer = _agentMgr.easySend(storageHost.getId(), setupCmd); - if (answer != null) { + if (answer != null && answer.getResult()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully programmed http auth into " + secStorageVm.getName()); } @@ -359,7 +359,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V } } Answer answer = _agentMgr.easySend(storageHost.getId(), cpc); - if (answer != null) { + if (answer != null && answer.getResult()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully programmed firewall rules into " + secStorageVm.getName()); } @@ -1083,7 +1083,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V final RebootCommand cmd = new RebootCommand(secStorageVm.getInstanceName()); final Answer answer = _agentMgr.easySend(secStorageVm.getHostId(), cmd); - if (answer != null) { + if (answer != null && answer.getResult()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Successfully reboot secondary storage vm " + secStorageVm.getName()); } @@ -1274,7 +1274,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V MigrateCommand cmd = new MigrateCommand(secStorageVm.getInstanceName(), host.getPrivateIpAddress(), false); Answer answer = _agentMgr.easySend(fromHost.getId(), cmd); - if (answer == null) { + if (answer == null || !answer.getResult()) { return false; } diff --git a/server/src/com/cloud/vm/ItWorkVO.java b/server/src/com/cloud/vm/ItWorkVO.java index a823c7be11b..c150a125851 100644 --- a/server/src/com/cloud/vm/ItWorkVO.java +++ b/server/src/com/cloud/vm/ItWorkVO.java @@ -36,9 +36,15 @@ public class ItWorkVO { Cleanup; } - enum State { - Working, - Cancelling, + enum ResourceType { + Volume, + Nic + } + + enum Step { + Prepare, + Start, + Started, } @Id @@ -58,21 +64,53 @@ public class ItWorkVO { String threadName; @Column(name="state") - State state; + Step step; @Column(name="cancel_taken") @Temporal(value=TemporalType.TIMESTAMP) Date taken; + @Column(name="instance_id") + long instanceId; + + public long getInstanceId() { + return instanceId; + } + + @Column(name="resource_id") + long resourceId; + + @Column(name="resource_type") + ResourceType resourceType; + + + public long getResourceId() { + return resourceId; + } + + public void setResourceId(long resourceId) { + this.resourceId = resourceId; + } + + public ResourceType getResourceType() { + return resourceType; + } + + public void setResourceType(ResourceType resourceType) { + this.resourceType = resourceType; + } + protected ItWorkVO() { } - protected ItWorkVO(String id, long managementServerId, Type type) { + protected ItWorkVO(String id, long managementServerId, Type type, long instanceId) { this.id = id; this.managementServerId = managementServerId; this.type = type; this.threadName = Thread.currentThread().getName(); - this.state = State.Working; + this.step = Step.Prepare; + this.instanceId = instanceId; + this.resourceType = null; } public String getId() { @@ -99,12 +137,12 @@ public class ItWorkVO { return threadName; } - public State getState() { - return state; + public Step getStep() { + return step; } - public void setState(State state) { - this.state = state; + public void setStep(Step state) { + this.step = state; } public Date getTaken() { diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 7f58a0c3bf6..cda2c647325 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -90,6 +90,7 @@ import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.ConsoleProxyDao; import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @@ -115,6 +116,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster @Inject private ConsoleProxyDao _consoleDao; @Inject private SecondaryStorageVmDao _secondaryDao; @Inject private UsageEventDao _usageEventDao; + @Inject private NicDao _nicsDao; @Inject(adapter=DeploymentPlanner.class) private Adapters _planners; @@ -200,6 +202,58 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster return vm; } + protected void reserveNics(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { +// List nics = _nicsDao.listBy(vmProfile.getId()); +// for (NicVO nic : nics) { +// Pair implemented = _networkMgr.implementNetwork(nic.getNetworkId(), dest, context); +// NetworkGuru concierge = implemented.first(); +// NetworkVO network = implemented.second(); +// NicProfile profile = null; +// if (nic.getReservationStrategy() == ReservationStrategy.Start) { +// nic.setState(Resource.State.Reserving); +// nic.setReservationId(context.getReservationId()); +// _nicsDao.update(nic.getId(), nic); +// URI broadcastUri = nic.getBroadcastUri(); +// if (broadcastUri == null) { +// network.getBroadcastUri(); +// } +// +// URI isolationUri = nic.getIsolationUri(); +// +// profile = new NicProfile(nic, network, broadcastUri, isolationUri); +// concierge.reserve(profile, network, vmProfile, dest, context); +// nic.setIp4Address(profile.getIp4Address()); +// nic.setIp6Address(profile.getIp6Address()); +// nic.setMacAddress(profile.getMacAddress()); +// nic.setIsolationUri(profile.getIsolationUri()); +// nic.setBroadcastUri(profile.getBroadCastUri()); +// nic.setReserver(concierge.getName()); +// nic.setState(Resource.State.Reserved); +// nic.setNetmask(profile.getNetmask()); +// nic.setGateway(profile.getGateway()); +// nic.setAddressFormat(profile.getFormat()); +// _nicsDao.update(nic.getId(), nic); +// } else { +// profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri()); +// } +// +// for (NetworkElement element : _networkElements) { +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Asking " + element.getName() + " to prepare for " + nic); +// } +// element.prepare(network, profile, vmProfile, dest, context); +// } +// +// vmProfile.addNic(profile); +// _networksDao.changeActiveNicsBy(network.getId(), 1); +// } + } + + protected void prepareNics(VirtualMachineProfile vmProfile, DeployDestination dest, ReservationContext context) { + + } + + @Override public T allocate(T vm, VMTemplateVO template, @@ -337,11 +391,15 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster @Override public T advanceStart(T vm, Map params, User caller, Account account, HypervisorType hyperType) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { State state = vm.getState(); - if (state == State.Starting || state == State.Running) { + if (state == State.Running) { s_logger.debug("VM is already started: " + vm); return vm; } + if (state == State.Starting) { + + } + if (state != State.Stopped) { s_logger.debug("VM " + vm + " is not in a state to be started: " + state); return null; @@ -353,7 +411,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster Journal journal = new Journal.LogJournal("Creating " + vm, s_logger); - ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, ItWorkVO.Type.Start); + ItWorkVO work = new ItWorkVO(UUID.randomUUID().toString(), _nodeId, ItWorkVO.Type.Start, vm.getId()); work = _workDao.persist(work); ReservationContextImpl context = new ReservationContextImpl(work.getId(), journal, caller, account); @@ -563,7 +621,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster stateTransitTo(vm, Event.OperationSucceeded, null); if (cleanup) { - ItWorkVO work = new ItWorkVO(reservationId, _nodeId, Type.Cleanup); + ItWorkVO work = new ItWorkVO(reservationId, _nodeId, Type.Cleanup, vm.getId()); _workDao.persist(work); } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 253dee46224..eb22d1fd532 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -103,6 +103,9 @@ CREATE TABLE `cloud`.`op_it_work` ( `type` char(32) NOT NULL COMMENT 'type of work', `state` char(32) NOT NULL COMMENT 'state', `cancel_taken` timestamp COMMENT 'time it was taken over', + `instance_id` bigint unsigned NOT NULL COMMENT 'vm instance', + `resource_type` char(32) COMMENT 'type of resource being worked on', + `resource_id` bigint unsigned COMMENT 'resource id being worked on', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/ui/css/main.css b/ui/css/main.css index 36c97b229bf..25225cc553c 100644 --- a/ui/css/main.css +++ b/ui/css/main.css @@ -299,7 +299,7 @@ a:hover { .vmpopup_container_closebutton { width:13px; height:13px; - float:left; + float:right; background:url(../images/vm_closebutton.gif) no-repeat top left; margin:8px 0 0 0; padding:0; diff --git a/ui/custom/custom1/css/custom1.css b/ui/custom/custom1/css/custom1.css new file mode 100644 index 00000000000..82215920360 --- /dev/null +++ b/ui/custom/custom1/css/custom1.css @@ -0,0 +1,367 @@ +@charset "UTF-8"; +/* CSS Document */ + +#main_header { + min-width:980px; + width:100%; + height:44px; + float:left; + background:#b84634 url(../../custom1/images/custom1_header_bg.jpg) repeat-x top left; + margin:0; + padding:0; +} + +.header_left { + width:309px; + height:44px; + float:left; + background:url(../../custom1/images/custom1_headerleft.jpg) no-repeat top left; + margin:0; + padding:0; +} + +.logo { + width:80px; + height:37px; + float:left; + background:url(../../custom1/images/custom1_logo.jpg) no-repeat top left; + margin:0 0 0 8px; + display:inline; + padding:0; +} + +.mgmtconsole_logo { + width:157px; + height:21px; + float:left; + background:url(../../custom1/images/custom1_mgmtconsole_logo.jpg) no-repeat top left; + margin:15px 0 0 9px; + display:inline; + padding:0; +} + + +.language_dropdownpanel { + width:103px; + height:19px; + float:left; + position:relative; + background:url(../../custom1/images/custom1_language_bg.gif) no-repeat top left; + margin:-3px 0 0 8px; + display:inline; + padding:0; + cursor:pointer; + cursor:hand; +} + +.language_dropdownpanel:hover { + background:url(../../custom1/images/custom1_language_bg_hover.gif) no-repeat top left; +} + +.language_icon { + width: 13px; + height:12px; + float:left; + background:url(../../custom1/images/custom1_language_icon.gif) no-repeat top left; + margin:3px 0 0 5px; + display:inline; + padding:0; +} + +.language_dropdownbox { + width:101px; + height:auto; + position:absolute; + background:#a44031 repeat top left; + border:1px solid #d87d58; + margin:0; + padding:0 0 15px 0; + top:17px; + z-index:1010; +} + +.leftmenu_panel { + width:221px; + height:100%; + min-height:1025px; + float:left; + background:#f3f3f3 repeat top left; + border-right:1px dotted #262626; + border-top:1px solid #FFF; + margin:0 0 0 -100%; + padding:0; +} + +.leftmenu_list{ + width:100%; + height:auto; + float:left; + margin:0; + padding:0; + background:url(../../custom1/images/custom1_leftmenubg.gif) repeat-x bottom left; + border-bottom:1px dotted #333; +} + +.leftmenu_expandedbox{ + width:100%; + height:auto; + float:left; + position:relative; + background:#9fa983 url(../../custom1/images/custom1_leftmenu_expanded.gif) repeat-x top left; + border-bottom:1px solid #FFF; + margin:0; + padding:0; + overflow-x:scoll; + overflow-x:auto; + overflow-y:hidden; +} + +.leftmenu_content_flevel.selected{ + background:#8a8a8a url(../../custom1/images/custom1_leftmenu_highlighted.gif) repeat-x top left; + border-bottom:1px dotted #333; + font-weight:bold; + color:#FFF; +} + +.leftmenu_content_flevel:hover{ + background:#f7f7f7 url(../../custom1/images/custom1_leftmenu_hover.gif) repeat-x top left; +} + +.leftmenu_content:hover{ + color:#7c8559; + background:#919b6c repeat top left; +} + +.leftmenu_content.selected{ + color:#FFF; + background:#b6b6b6 url(../../custom1/images/custom1_leftmenu_contentselected.gif) repeat-x top left; + border-bottom:1px solid #666666; +} + +.leftmenu_secondindent{ + min-width:180px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 30px; + display:inline; + padding:0; +} + +.leftmenu_thirdindent{ + min-width:160px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 50px; + display:inline; + padding:0; +} + +.leftmenu_fourthindent{ + min-width:200px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 70px; + display:inline; + padding:0; +} + +.leftmenu_fifthindent{ + min-width:200px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 100px; + display:inline; + padding:0; +} + +.leftmenu_sixthindent{ + min-width:200px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 120px; + display:inline; + padding:0; +} + +.leftmenu_domainindent{ + min-width:180px; + max-width:auto; + height:auto; + float:left; + color:#333; + margin:7px 0 0 30px; + display:inline; + padding:0; +} + + +.actionpanel { + width:100%; + height:27px; + float:left; + background: url(../../custom1/images/custom1_actionpanel_bg.gif) repeat-x top left; + margin:0; + padding:0; +} + +.searchpanel { + width:223px; + height:27px; + float:left; + margin:0; + padding:0; + background:url(../../custom1/images/custom1_actionpanel_border.gif) no-repeat top right; + list-style:none +} + +.searchpanel_filterbutton { + width:16px; + height:16px; + float:left; + margin:5px 0 0 4px; + display:inline; + background:url(../../custom1/images/custom1_filter_downarrow.gif) no-repeat top left; + cursor:pointer; + cursor:hand; +} + +.searchpanel_filterbutton.up { + background:url(../../custom1/images/custom1_filter_uparrow.gif) no-repeat top left; +} + +.search_textbg { + width:186px; + height:16px; + float:left; + background:url(../../custom1/images/custom1_search_textbg.gif) no-repeat top left; + margin:0; + padding:0; +} + +.actionpanel_button_wrapper{ + width:auto; + height:27px; + float:left; + margin:0; + padding:0; + background:url(../../custom1/images/custom1_actionpanel_border.gif) no-repeat top right; +} + +.actionpanel_button_links{ + width:auto; + height:auto; + color:#333; + font-size:10px; + font-weight:normal; + text-decoration:none; + float:left; + margin:7px 11px 0 5px; + padding:0; +} + + +.actionpanel_button:hover{ + background:url(../../custom1/images/custom1_actionpanel_hover.gif) repeat-x top right; + color:#FFF; +} + +.midmenu_panel { + width:221px; + min-height:1000px; + height:auto; + float:left; + position:relative; + background:#fdfaf0 repeat top left; + border-right:1px solid #aeb9c5; + margin:27px 0 0 -100%; + display:inline; + padding:0; +} + +.midmenu_list{ + width:220px; + height:auto; + float:left; + background:#fef8e5 url(../../custom1/images/custom1_midmenubg.gif) repeat-x bottom left; + border-bottom:1px dotted #333; + margin:0; + padding:0; +} + +.midmenu_content:hover{ + background:#f6efce url(../../custom1/images/custom1_midmenu_hover.gif) repeat-x top left; + color:#333; +} + +.midmenu_content.selected { + background:#b6b6b6 url(../../custom1/images/custom1_midmenu_selected.gif) repeat-x top left; + color:#333; + +} + + +.tabbox { + width:100%; + height:auto; + float:left; + margin:0; + padding:0; + border:none; +} + +.content_tabs { + width:101px; + height:27px; + float:left; + font-size:11px; + margin:0 0 0 0; + text-align:center; + padding:6px 0 0 0; + display:inline; + +} + +.content_tabs.on { + background:url(../../custom1/images/custom1_contenttab_ON.gif) no-repeat bottom left; + color:#FFF; + border-right:1px dotted #333; + + +} + +.content_tabs.off { + background:none; + color:#333; + cursor:pointer; + cursor:hand; + border-right:1px dotted #333; + + +} + +.content_tabs.off:hover { + background:url(../../custom1/images/custom1_contenttab_hover.gif) no-repeat bottom left; + color:#333; + cursor:pointer; + cursor:hand; +} + +.adv_searchpopup_bg { + width:100%; + height:auto; + float:left; + background:#777777 url(../../custom1/images/custom1_adv_searchbg.gif) repeat-x top left; + border-bottom:1px solid #2d2d2d; + margin:0; + padding:0 0 9px 0; +} diff --git a/ui/custom/custom1/images/custom1_actionpanel_bg.gif b/ui/custom/custom1/images/custom1_actionpanel_bg.gif new file mode 100644 index 00000000000..897a2219a80 Binary files /dev/null and b/ui/custom/custom1/images/custom1_actionpanel_bg.gif differ diff --git a/ui/custom/custom1/images/custom1_actionpanel_border.gif b/ui/custom/custom1/images/custom1_actionpanel_border.gif new file mode 100644 index 00000000000..dc5048559ee Binary files /dev/null and b/ui/custom/custom1/images/custom1_actionpanel_border.gif differ diff --git a/ui/custom/custom1/images/custom1_actionpanel_hover.gif b/ui/custom/custom1/images/custom1_actionpanel_hover.gif new file mode 100644 index 00000000000..77378ff5c94 Binary files /dev/null and b/ui/custom/custom1/images/custom1_actionpanel_hover.gif differ diff --git a/ui/custom/custom1/images/custom1_adv_searchbg.gif b/ui/custom/custom1/images/custom1_adv_searchbg.gif new file mode 100644 index 00000000000..9afafc9ce12 Binary files /dev/null and b/ui/custom/custom1/images/custom1_adv_searchbg.gif differ diff --git a/ui/custom/custom1/images/custom1_contenttab_ON.gif b/ui/custom/custom1/images/custom1_contenttab_ON.gif new file mode 100644 index 00000000000..cbecfc38662 Binary files /dev/null and b/ui/custom/custom1/images/custom1_contenttab_ON.gif differ diff --git a/ui/custom/custom1/images/custom1_contenttab_hover.gif b/ui/custom/custom1/images/custom1_contenttab_hover.gif new file mode 100644 index 00000000000..f8bf1abbdf0 Binary files /dev/null and b/ui/custom/custom1/images/custom1_contenttab_hover.gif differ diff --git a/ui/custom/custom1/images/custom1_filter_downarrow.gif b/ui/custom/custom1/images/custom1_filter_downarrow.gif new file mode 100644 index 00000000000..35bc3330338 Binary files /dev/null and b/ui/custom/custom1/images/custom1_filter_downarrow.gif differ diff --git a/ui/custom/custom1/images/custom1_filter_uparrow.gif b/ui/custom/custom1/images/custom1_filter_uparrow.gif new file mode 100644 index 00000000000..264da97f494 Binary files /dev/null and b/ui/custom/custom1/images/custom1_filter_uparrow.gif differ diff --git a/ui/custom/custom1/images/custom1_header_bg.jpg b/ui/custom/custom1/images/custom1_header_bg.jpg new file mode 100644 index 00000000000..2902bf6e53c Binary files /dev/null and b/ui/custom/custom1/images/custom1_header_bg.jpg differ diff --git a/ui/custom/custom1/images/custom1_headerleft.jpg b/ui/custom/custom1/images/custom1_headerleft.jpg new file mode 100644 index 00000000000..570bff9fd4b Binary files /dev/null and b/ui/custom/custom1/images/custom1_headerleft.jpg differ diff --git a/ui/custom/custom1/images/custom1_language_bg.gif b/ui/custom/custom1/images/custom1_language_bg.gif new file mode 100644 index 00000000000..5c668e733e3 Binary files /dev/null and b/ui/custom/custom1/images/custom1_language_bg.gif differ diff --git a/ui/custom/custom1/images/custom1_language_bg_hover.gif b/ui/custom/custom1/images/custom1_language_bg_hover.gif new file mode 100644 index 00000000000..ec770413b97 Binary files /dev/null and b/ui/custom/custom1/images/custom1_language_bg_hover.gif differ diff --git a/ui/custom/custom1/images/custom1_language_icon.gif b/ui/custom/custom1/images/custom1_language_icon.gif new file mode 100644 index 00000000000..d4ac50fc4f9 Binary files /dev/null and b/ui/custom/custom1/images/custom1_language_icon.gif differ diff --git a/ui/custom/custom1/images/custom1_leftmenu_contentselected.gif b/ui/custom/custom1/images/custom1_leftmenu_contentselected.gif new file mode 100644 index 00000000000..5a631e83b8a Binary files /dev/null and b/ui/custom/custom1/images/custom1_leftmenu_contentselected.gif differ diff --git a/ui/custom/custom1/images/custom1_leftmenu_expanded.gif b/ui/custom/custom1/images/custom1_leftmenu_expanded.gif new file mode 100644 index 00000000000..be340094672 Binary files /dev/null and b/ui/custom/custom1/images/custom1_leftmenu_expanded.gif differ diff --git a/ui/custom/custom1/images/custom1_leftmenu_highlighted.gif b/ui/custom/custom1/images/custom1_leftmenu_highlighted.gif new file mode 100644 index 00000000000..e7242259367 Binary files /dev/null and b/ui/custom/custom1/images/custom1_leftmenu_highlighted.gif differ diff --git a/ui/custom/custom1/images/custom1_leftmenu_hover.gif b/ui/custom/custom1/images/custom1_leftmenu_hover.gif new file mode 100644 index 00000000000..74bb0bb96ad Binary files /dev/null and b/ui/custom/custom1/images/custom1_leftmenu_hover.gif differ diff --git a/ui/custom/custom1/images/custom1_leftmenubg.gif b/ui/custom/custom1/images/custom1_leftmenubg.gif new file mode 100644 index 00000000000..3fb02f4c5cb Binary files /dev/null and b/ui/custom/custom1/images/custom1_leftmenubg.gif differ diff --git a/ui/custom/custom1/images/custom1_logo.jpg b/ui/custom/custom1/images/custom1_logo.jpg new file mode 100644 index 00000000000..ab98b2bf42b Binary files /dev/null and b/ui/custom/custom1/images/custom1_logo.jpg differ diff --git a/ui/custom/custom1/images/custom1_mgmtconsole_logo.jpg b/ui/custom/custom1/images/custom1_mgmtconsole_logo.jpg new file mode 100644 index 00000000000..6598db09dbe Binary files /dev/null and b/ui/custom/custom1/images/custom1_mgmtconsole_logo.jpg differ diff --git a/ui/custom/custom1/images/custom1_midmenu_hover.gif b/ui/custom/custom1/images/custom1_midmenu_hover.gif new file mode 100644 index 00000000000..8f249926d1b Binary files /dev/null and b/ui/custom/custom1/images/custom1_midmenu_hover.gif differ diff --git a/ui/custom/custom1/images/custom1_midmenu_selected.gif b/ui/custom/custom1/images/custom1_midmenu_selected.gif new file mode 100644 index 00000000000..b9a3bfc2323 Binary files /dev/null and b/ui/custom/custom1/images/custom1_midmenu_selected.gif differ diff --git a/ui/custom/custom1/images/custom1_midmenubg.gif b/ui/custom/custom1/images/custom1_midmenubg.gif new file mode 100644 index 00000000000..61c908f2493 Binary files /dev/null and b/ui/custom/custom1/images/custom1_midmenubg.gif differ diff --git a/ui/custom/custom1/images/custom1_search_textbg.gif b/ui/custom/custom1/images/custom1_search_textbg.gif new file mode 100644 index 00000000000..9fdf616093e Binary files /dev/null and b/ui/custom/custom1/images/custom1_search_textbg.gif differ diff --git a/ui/index.jsp b/ui/index.jsp index fd6677c2b85..9326576a920 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -12,6 +12,7 @@ + diff --git a/ui/scripts/cloud.core.init.js b/ui/scripts/cloud.core.init.js index 2710f480f3a..6380a64a7ef 100644 --- a/ui/scripts/cloud.core.init.js +++ b/ui/scripts/cloud.core.init.js @@ -163,7 +163,7 @@ var md5Hashed = true; //configuration bindAndListMidMenuItems($("#leftmenu_service_offering"), "listServiceOfferings", serviceOfferingGetSearchParams, "listserviceofferingsresponse", "serviceoffering", "jsp/serviceoffering.jsp", afterLoadServiceOfferingJSP, serviceOfferingToMidmenu, serviceOfferingToRightPanel, getMidmenuId, false); bindAndListMidMenuItems($("#leftmenu_disk_offering"), "listDiskOfferings", diskOfferingGetSearchParams, "listdiskofferingsresponse", "diskoffering", "jsp/diskoffering.jsp", afterLoadDiskOfferingJSP, diskOfferingToMidmenu, diskOfferingToRightPanel, getMidmenuId, false); - bindAndListMidMenuItems($("#leftmenu_network_offering"), "listNetworkOfferings&type=Virtual", networkOfferingGetSearchParams, "listnetworkofferingsresponse", "networkoffering", "jsp/networkoffering.jsp", afterLoadNetworkOfferingJSP, networkOfferingToMidmenu, networkOfferingToRightPanel, getMidmenuId, false); + bindAndListMidMenuItems($("#leftmenu_network_offering"), "listNetworkOfferings&traffictype=Guest", networkOfferingGetSearchParams, "listnetworkofferingsresponse", "networkoffering", "jsp/networkoffering.jsp", afterLoadNetworkOfferingJSP, networkOfferingToMidmenu, networkOfferingToRightPanel, getMidmenuId, false); } $("#leftmenu_global_setting").bind("click", function(event) { diff --git a/ui/scripts/cloud.core.ipaddress.js b/ui/scripts/cloud.core.ipaddress.js index c9b098e24c5..990e9e72644 100644 --- a/ui/scripts/cloud.core.ipaddress.js +++ b/ui/scripts/cloud.core.ipaddress.js @@ -333,19 +333,39 @@ function ipToRightPanel($midmenuItem1) { if(ipObj.forvirtualnetwork == true) { //(public network) if(isIpManageable(ipObj.domainid, ipObj.account) == true) { //Port Forwarding tab - var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); - var portForwardingCapabilityObj = ipFindCapabilityByName("PortForwarding", firewallServiceObj); - if(firewallServiceObj != null && portForwardingCapabilityObj != null && portForwardingCapabilityObj.value == "true") - $("#tab_port_forwarding").show(); - else - $("#tab_port_forwarding").hide(); + if(networkObj != null) { + var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); + if(firewallServiceObj != null) { + var portForwardingCapabilityObj = ipFindCapabilityByName("PortForwarding", firewallServiceObj); + if(portForwardingCapabilityObj != null) { + if(portForwardingCapabilityObj.value == "true") + $("#tab_port_forwarding").show(); + else + $("#tab_port_forwarding").hide(); + } + else { + $("#tab_port_forwarding").hide(); + } + } + else { + $("#tab_port_forwarding").hide(); + } + } + else { + $("#tab_port_forwarding").hide(); + } //Load Balancer tab - var lbServiceObj = ipFindNetworkServiceByName("Lb", networkObj); - if(lbServiceObj != null) - $("#tab_load_balancer").show(); - else - $("#tab_load_balancer").hide(); + if(networkObj != null) { + var lbServiceObj = ipFindNetworkServiceByName("Lb", networkObj); + if(lbServiceObj != null) + $("#tab_load_balancer").show(); + else + $("#tab_load_balancer").hide(); + } + else { + $("#tab_load_balancer").hide(); + } //VPN tab var vpnServiceObj = ipFindNetworkServiceByName("Vpn", networkObj); @@ -388,15 +408,20 @@ function ipJsonToPortForwardingTab() { $thisTab.find("#tab_container").hide(); $thisTab.find("#tab_spinning_wheel").show(); - var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); - var supportedProtocolsCapabilityObj = ipFindCapabilityByName("SupportedProtocols", firewallServiceObj); - if(supportedProtocolsCapabilityObj != null) { - var protocols = supportedProtocolsCapabilityObj.value.toUpperCase(); //e.g. "tcp,udp" => "TCP,UDP" - var array1 = protocols.split(","); - var $protocolField = $("#create_port_forwarding_row").find("#protocol").empty(); - for(var i=0; i"+array1[i]+"") + if(networkObj != null) { + var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); + if(firewallServiceObj != null) { + var supportedProtocolsCapabilityObj = ipFindCapabilityByName("SupportedProtocols", firewallServiceObj); + if(supportedProtocolsCapabilityObj != null) { + var protocols = supportedProtocolsCapabilityObj.value.toUpperCase(); //e.g. "tcp,udp" => "TCP,UDP" + var array1 = protocols.split(","); + var $protocolField = $("#create_port_forwarding_row").find("#protocol").empty(); + for(var i=0; i"+array1[i]+"") + } + } } + refreshCreatePortForwardingRow(); $.ajax({ @@ -438,18 +463,23 @@ function ipJsonToLoadBalancerTab() { $thisTab.find("#tab_container").hide(); $thisTab.find("#tab_spinning_wheel").show(); - var lbServiceObj = ipFindNetworkServiceByName("Lb", networkObj); - var supportedLbAlgorithmsCapabilityObj = ipFindCapabilityByName("SupportedLbAlgorithms", lbServiceObj); - if(lbServiceObj != null && supportedLbAlgorithmsCapabilityObj != null) { - var algorithms = supportedLbAlgorithmsCapabilityObj.value; //e.g. "roundrobin,leastconn,sourceip" - var array1 = algorithms.split(","); - var $algorithmField1 = $("#create_load_balancer_row").find("#algorithm_select").empty(); - var $algorithmField2 = $("#load_balancer_template").find("#row_container_edit").find("#algorithm_select").empty(); - for(var i=0; i"+array1[i]+""); - $algorithmField2.append(""); - } - } + if(networkObj != null) { + var lbServiceObj = ipFindNetworkServiceByName("Lb", networkObj); + if(lbServiceObj != null) { + var supportedLbAlgorithmsCapabilityObj = ipFindCapabilityByName("SupportedLbAlgorithms", lbServiceObj); + if(supportedLbAlgorithmsCapabilityObj != null) { + var algorithms = supportedLbAlgorithmsCapabilityObj.value; //e.g. "roundrobin,leastconn,sourceip" + var array1 = algorithms.split(","); + var $algorithmField1 = $("#create_load_balancer_row").find("#algorithm_select").empty(); + var $algorithmField2 = $("#load_balancer_template").find("#row_container_edit").find("#algorithm_select").empty(); + for(var i=0; i"+array1[i]+""); + $algorithmField2.append(""); + } + } + } + } + refreshCreateLoadBalancerRow(); $.ajax({ @@ -943,12 +973,18 @@ function ipJsonToDetailsTab() { buildActionLinkForTab("Disable Static NAT", ipActionMap, $actionMenu, $midmenuItem1, $thisTab); noAvailableActions = false; } else { - if(ipObj.issourcenat != true) { - var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); - var staticNatCapabilityObj = ipFindCapabilityByName("StaticNat", firewallServiceObj); - if(firewallServiceObj != null && staticNatCapabilityObj != null && staticNatCapabilityObj.value == "true") - buildActionLinkForTab("Enable Static NAT", ipActionMap, $actionMenu, $midmenuItem1, $thisTab); - + if(ipObj.issourcenat != true) { + if(networkObj != null) { + var firewallServiceObj = ipFindNetworkServiceByName("Firewall", networkObj); + if(firewallServiceObj != null) { + var staticNatCapabilityObj = ipFindCapabilityByName("StaticNat", firewallServiceObj); + if(staticNatCapabilityObj != null) { + if(staticNatCapabilityObj.value == "true") + buildActionLinkForTab("Enable Static NAT", ipActionMap, $actionMenu, $midmenuItem1, $thisTab); + } + } + } + buildActionLinkForTab("Release IP", ipActionMap, $actionMenu, $midmenuItem1, $thisTab); noAvailableActions = false; } @@ -965,6 +1001,8 @@ function ipJsonToDetailsTab() { } function ipFindNetworkServiceByName(pName, networkObj) { + if(networkObj == null) + return null; for(var i=0; i 0) - $("#"+selected_midmenu_id).find("#content").removeClass("selected"); - selected_midmenu_id = getMidmenuIdFn($midmenuItem1.data("jsonObj")); - $midmenuItem1.find("#content").addClass("selected"); - clearRightPanel(); - toRightPanelFn($midmenuItem1); - //$midmenuItem1.click(); - - $midmenuItem1.addClass("ui-selected"); //because instance page is using JQuery selectable widget to do multiple-selection - selectedItemsInMidMenu[items[i].id] = $midmenuItem1; //because instance page is using JQuery selectable widget to do multiple-selection + else { + clickItemInMultipleSelectionMidmenu($midmenuItem1); } } } @@ -1007,6 +1003,19 @@ function listMidMenuItems2(commandString, getSearchParamsFn, jsonResponse1, json return count; } +function clickItemInMultipleSelectionMidmenu($midmenuItem1) { + $midmenuItem1.find("#content").addClass("selected"); //css of vmops + $midmenuItem1.addClass("ui-selected"); //css of JQuery selectable widget + + var toRightPanelFn = $midmenuItem1.data("toRightPanelFn"); + toRightPanelFn($midmenuItem1); + + var jsonObj = $midmenuItem1.data("jsonObj"); + selectedItemsInMidMenu[jsonObj.id] = $midmenuItem1; + + selected_midmenu_id = $midmenuItem1.attr("id"); +} + var currentLeftMenuId; var currentRightPanelJSP = null; function listMidMenuItems(commandString, getSearchParamsFn, jsonResponse1, jsonResponse2, rightPanelJSP, afterLoadRightPanelJSPFn, toMidmenuFn, toRightPanelFn, getMidmenuIdFn, isMultipleSelectionInMidMenu, leftmenuId, refreshDataBindingFn) { diff --git a/ui/scripts/cloud.core.network.js b/ui/scripts/cloud.core.network.js index 79bbf7c649b..9bf4d9a937a 100644 --- a/ui/scripts/cloud.core.network.js +++ b/ui/scripts/cloud.core.network.js @@ -1122,7 +1122,7 @@ function bindAddNetworkButton($button) { var networkOfferings = json.listnetworkofferingsresponse.networkoffering; if (networkOfferings != null && networkOfferings.length > 0) { for (var i = 0; i < networkOfferings.length; i++) { - if (networkOfferings[i].type == "Direct" && networkOfferings[i].isdefault) { + if (networkOfferings[i].isdefault) { // Create a network from this. $.ajax({ data: createURL("command=createNetwork&name="+name+"&displayText="+desc+"&networkOfferingId="+networkOfferings[i].id+"&zoneId="+zoneObj.id+vlan+scopeParams+"&gateway="+todb(gateway)+"&netmask="+todb(netmask)+"&startip="+todb(startip)+"&endip="+todb(endip)), diff --git a/ui/scripts/cloud.core.securitygroup.js b/ui/scripts/cloud.core.securitygroup.js index b1c8aa3d74b..a96682e480a 100644 --- a/ui/scripts/cloud.core.securitygroup.js +++ b/ui/scripts/cloud.core.securitygroup.js @@ -221,7 +221,7 @@ function securityGroupJsonToDetailsTab() { dataType: "json", async: false, success: function(json) { - var items = json.listsecurityGroupsresponse.securitygroup; + var items = json.listsecuritygroupsresponse.securitygroup; if(items != null && items.length > 0) { jsonObj = items[0]; $midmenuItem1.data("jsonObj", jsonObj); @@ -264,7 +264,7 @@ function securityGroupJsonToIngressRuleTab() { data: createURL("command=listSecurityGroups"+"&domainid="+securityGroupObj.domainid+"&account="+securityGroupObj.account+"&securitygroupname="+securityGroupObj.name), dataType: "json", success: function(json) { - var securityGroupObj = json.listsecurityGroupsresponse.securitygroup[0]; + var securityGroupObj = json.listsecuritygroupsresponse.securitygroup[0]; var items = securityGroupObj.ingressrule; var $container = $thisTab.find("#tab_container").empty(); if (items != null && items.length > 0) { diff --git a/utils/src/com/cloud/utils/component/AnnotationInterceptor.java b/utils/src/com/cloud/utils/component/AnnotationInterceptor.java new file mode 100644 index 00000000000..e614fcc6751 --- /dev/null +++ b/utils/src/com/cloud/utils/component/AnnotationInterceptor.java @@ -0,0 +1,23 @@ +/** + * + */ +package com.cloud.utils.component; + +import java.lang.reflect.AnnotatedElement; + +import net.sf.cglib.proxy.Callback; + +/** + * AnnotationIntercepter says it can intercept an annotation. + */ +public interface AnnotationInterceptor { + boolean needToIntercept(AnnotatedElement element); + + T interceptStart(AnnotatedElement element); + + void interceptComplete(AnnotatedElement element, T attach); + + void interceptException(AnnotatedElement element, T attach); + + Callback getCallback(); +} diff --git a/utils/src/com/cloud/utils/component/ComponentLibrary.java b/utils/src/com/cloud/utils/component/ComponentLibrary.java index f1b67e073c1..5ed4c9512e7 100644 --- a/utils/src/com/cloud/utils/component/ComponentLibrary.java +++ b/utils/src/com/cloud/utils/component/ComponentLibrary.java @@ -50,4 +50,5 @@ public interface ComponentLibrary { Map>> getAdapters(); Map, Class> getFactories(); + } diff --git a/utils/src/com/cloud/utils/component/ComponentLocator.java b/utils/src/com/cloud/utils/component/ComponentLocator.java index ce326a15752..3bdaf05986a 100755 --- a/utils/src/com/cloud/utils/component/ComponentLocator.java +++ b/utils/src/com/cloud/utils/component/ComponentLocator.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; @@ -48,6 +49,8 @@ import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.Factory; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.NoOp; import org.apache.log4j.Logger; @@ -79,11 +82,12 @@ public class ComponentLocator implements ComponentLocatorMBean { protected static final ThreadLocal s_tl = new ThreadLocal(); protected static final ConcurrentHashMap, Singleton> s_singletons = new ConcurrentHashMap, Singleton>(111); protected static final HashMap s_locators = new HashMap(); - protected static final Callback[] s_callbacks = new Callback[] { NoOp.INSTANCE, new DatabaseCallback() }; - protected static final CallbackFilter s_callbackFilter = new DatabaseCallbackFilter(); protected static final HashMap, InjectInfo> s_factories = new HashMap, InjectInfo>(); protected static Boolean s_once = false; - + protected static Callback[] s_callbacks = new Callback[] { NoOp.INSTANCE, new DatabaseCallback()}; + protected static CallbackFilter s_callbackFilter = new DatabaseCallbackFilter(); + protected static final List> s_interceptors = new ArrayList>(); + protected HashMap> _adapterMap; protected HashMap> _managerMap; protected LinkedHashMap>> _daoMap; @@ -182,7 +186,7 @@ public class ComponentLocator implements ComponentLocatorMBean { s_logger.info("Skipping configuration using " + filename); return; } - + XmlHandler handler = result.first(); HashMap>> adapters = result.second(); try { @@ -829,7 +833,7 @@ public class ComponentLocator implements ComponentLocatorMBean { if (info.name == null) { throw new CloudRuntimeException("Missing name attribute for " + interphace.getName()); } - info.name = info.name + "-" + clazzName; + info.name = info.name; s_logger.debug("Looking for class " + clazzName); try { info.clazz = Class.forName(clazzName); @@ -849,6 +853,34 @@ public class ComponentLocator implements ComponentLocatorMBean { @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { + if (qName.equals("interceptors") && s_interceptors.size() == 0) { + synchronized(s_interceptors){ + if (s_interceptors.size() == 0) { + String libraryName = getAttribute(atts, "library"); + try { + Class libraryClazz = Class.forName(libraryName); + InterceptorLibrary library = (InterceptorLibrary)libraryClazz.newInstance(); + library.addInterceptors(s_interceptors); + if (s_interceptors.size() > 0) { + s_callbacks = new Callback[s_interceptors.size() + 2]; + int i = 0; + s_callbacks[i++] = NoOp.INSTANCE; + s_callbacks[i++] = new InterceptorDispatcher(); + for (AnnotationInterceptor interceptor : s_interceptors) { + s_callbacks[i++] = interceptor.getCallback(); + } + s_callbackFilter = new InterceptorFilter(); + } + } catch (ClassNotFoundException e) { + throw new CloudRuntimeException("Unable to find " + libraryName, e); + } catch (InstantiationException e) { + throw new CloudRuntimeException("Unable to instantiate " + libraryName, e); + } catch (IllegalAccessException e) { + throw new CloudRuntimeException("Illegal access " + libraryName, e); + } + } + } + } if (!parse) { if (qName.equals(_serverName)) { parse = true; @@ -1012,4 +1044,51 @@ public class ComponentLocator implements ComponentLocatorMBean { this.state = State.Instantiated; } } + + protected class InterceptorDispatcher implements MethodInterceptor { + + @Override + public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { + ArrayList, Object>> interceptors = new ArrayList, Object>>(); + for (AnnotationInterceptor interceptor : s_interceptors) { + if (interceptor.needToIntercept(method)) { + Object obj = interceptor.interceptStart(method); + interceptors.add(new Pair, Object>((AnnotationInterceptor)interceptor, obj)); + } + } + boolean success = false; + try { + Object obj = methodProxy.invokeSuper(object, args); + success = true; + return obj; + } finally { + for (Pair, Object> interceptor : interceptors) { + if (success) { + interceptor.first().interceptComplete(method, interceptor.second()); + } else { + interceptor.first().interceptException(method, interceptor.second()); + } + } + } + } + } + + protected static class InterceptorFilter implements CallbackFilter { + @Override + public int accept(Method method) { + int index = 0; + for (int i = 2; i < s_callbacks.length; i++) { + AnnotationInterceptor interceptor = (AnnotationInterceptor)s_callbacks[i]; + if (interceptor.needToIntercept(method)) { + if (index == 0) { + index = i; + } else { + return 1; + } + } + } + + return index; + } + } } diff --git a/utils/src/com/cloud/utils/component/Injector.java b/utils/src/com/cloud/utils/component/Injector.java deleted file mode 100644 index e278ab5ba08..00000000000 --- a/utils/src/com/cloud/utils/component/Injector.java +++ /dev/null @@ -1,19 +0,0 @@ -/** - * - */ -package com.cloud.utils.component; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; - -/** - * Injector implements customized Injectors for ComponentLocator. - * - */ -public interface Injector { - /** - * Can this injector handle injecting into this type of class? - */ - boolean canInject(AnnotatedElement element, Annotation ann); - -} diff --git a/utils/src/com/cloud/utils/component/InterceptorLibrary.java b/utils/src/com/cloud/utils/component/InterceptorLibrary.java new file mode 100644 index 00000000000..1da4ffd746b --- /dev/null +++ b/utils/src/com/cloud/utils/component/InterceptorLibrary.java @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.utils.component; + +import java.util.List; + +public interface InterceptorLibrary { + + void addInterceptors(List> interceptors); + +} diff --git a/utils/src/com/cloud/utils/db/DatabaseCallback.java b/utils/src/com/cloud/utils/db/DatabaseCallback.java index 5587084c80d..ba25e32b242 100644 --- a/utils/src/com/cloud/utils/db/DatabaseCallback.java +++ b/utils/src/com/cloud/utils/db/DatabaseCallback.java @@ -17,20 +17,69 @@ */ package com.cloud.utils.db; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; +import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; -public class DatabaseCallback implements MethodInterceptor { +import com.cloud.utils.component.AnnotationInterceptor; + +public class DatabaseCallback implements MethodInterceptor, AnnotationInterceptor { @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { - Transaction txn = Transaction.open(method.getName()); + Transaction txn = interceptStart(method); try { return methodProxy.invokeSuper(object, args); } finally { - txn.close(); + interceptComplete(method, txn); } } + + @Override + public boolean needToIntercept(AnnotatedElement element) { + if (!(element instanceof Method)) { + return false; + + } + Method method = (Method)element; + DB db = method.getAnnotation(DB.class); + if (db != null) { + return db.txn(); + } + + Class clazz = method.getDeclaringClass(); + do { + db = clazz.getAnnotation(DB.class); + if (db != null) { + return db.txn(); + } + clazz = clazz.getSuperclass(); + } while (clazz != Object.class && clazz != null); + + return false; + } + + @Override + public Transaction interceptStart(AnnotatedElement element) { + return Transaction.open(((Method)element).getName()); + } + + @Override + public void interceptComplete(AnnotatedElement element, Transaction txn) { + txn.close(); + } + + @Override + public void interceptException(AnnotatedElement element, Transaction txn) { + txn.close(); + } + + @Override + public Callback getCallback() { + return this; + } + }