diff --git a/api/src/com/cloud/event/ActionEvent.java b/api/src/com/cloud/event/ActionEvent.java new file mode 100644 index 00000000000..658d2b014ad --- /dev/null +++ b/api/src/com/cloud/event/ActionEvent.java @@ -0,0 +1,22 @@ +/** + * 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/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index d8dd1982248..19cea4603bd 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,7 @@ public interface NetworkManager extends NetworkService { List listPodVlans(long podId); + Network getBasicZoneDefaultPublicNetwork(long zoneId); + + 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..7d27a7f06b4 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; @@ -75,12 +69,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,12 +84,14 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; +<<<<<<< HEAD import com.cloud.network.dao.RemoteAccessVpnDao; +======= +>>>>>>> changes for injectors 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; @@ -111,6 +105,10 @@ import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.resource.Resource; import com.cloud.resource.Resource.ReservationStrategy; +<<<<<<< HEAD +======= +import com.cloud.service.ServiceOfferingVO; +>>>>>>> changes for injectors import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; @@ -165,7 +163,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 +172,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 +352,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 +992,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); 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..81034be3feb 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -17,6 +17,7 @@ */ package com.cloud.vm; +import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -61,6 +62,10 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuru; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkVO; +import com.cloud.network.element.NetworkElement; +import com.cloud.network.guru.NetworkGuru; +import com.cloud.resource.Resource; +import com.cloud.resource.Resource.ReservationStrategy; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; @@ -90,6 +95,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 +121,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 +207,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, DeployDestionation dest, ReservationContext context) { + + } + + @Override public T allocate(T vm, VMTemplateVO template, @@ -337,11 +396,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; diff --git a/utils/src/com/cloud/utils/component/ComponentLocator.java b/utils/src/com/cloud/utils/component/ComponentLocator.java index ce326a15752..453f3ae6085 100755 --- a/utils/src/com/cloud/utils/component/ComponentLocator.java +++ b/utils/src/com/cloud/utils/component/ComponentLocator.java @@ -90,6 +90,7 @@ public class ComponentLocator implements ComponentLocatorMBean { protected String _serverName; protected Object _component; protected HashMap, Class> _factories; + protected List _injectors; static { Runtime.getRuntime().addShutdownHook(new CleanupThread());