diff --git a/api/src/com/cloud/network/NetworkConfiguration.java b/api/src/com/cloud/network/NetworkConfiguration.java index 82a1ac62da8..207997d49dd 100644 --- a/api/src/com/cloud/network/NetworkConfiguration.java +++ b/api/src/com/cloud/network/NetworkConfiguration.java @@ -12,6 +12,11 @@ import com.cloud.network.Network.TrafficType; * owned by an account. */ public interface NetworkConfiguration { + enum State { + Allocated, // Indicates the network configuration is in allocated but not setup. + Setup, // Indicates the network configuration is setup. + InUse; // Indicates the network configuration is in use. + } /** * @return id of the network profile. Null means the network profile is not from the database. @@ -28,7 +33,9 @@ public interface NetworkConfiguration { String getCidr(); - public long getDataCenterId(); + long getDataCenterId(); long getNetworkOfferingId(); + + State getState(); } diff --git a/api/src/com/cloud/network/NetworkProfiler.java b/api/src/com/cloud/network/NetworkProfiler.java deleted file mode 100644 index 226d5fd9af0..00000000000 --- a/api/src/com/cloud/network/NetworkProfiler.java +++ /dev/null @@ -1,21 +0,0 @@ -/** - * - */ -package com.cloud.network; - -import java.util.Map; - -import com.cloud.deploy.DeploymentPlan; -import com.cloud.offering.NetworkOffering; -import com.cloud.user.Account; -import com.cloud.utils.component.Adapter; - -/** - * NetworkProfiler takes the list of network offerings requested and figures - * out what are the additional network profiles that are needed to add - * to the account in order to support this network. - * - */ -public interface NetworkProfiler extends Adapter { - NetworkConfiguration convert(NetworkOffering offering, DeploymentPlan plan, Map params, Account owner); -} diff --git a/api/src/com/cloud/network/configuration/NetworkGuru.java b/api/src/com/cloud/network/configuration/NetworkGuru.java new file mode 100644 index 00000000000..2f7bb5cded2 --- /dev/null +++ b/api/src/com/cloud/network/configuration/NetworkGuru.java @@ -0,0 +1,24 @@ +/** + * + */ +package com.cloud.network.configuration; + +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.network.NetworkConfiguration; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.utils.component.Adapter; + +/** + * NetworkProfiler takes the list of network offerings requested and figures + * out what are the additional network profiles that are needed to add + * to the account in order to support this network. + * + */ +public interface NetworkGuru extends Adapter { + NetworkConfiguration design(NetworkOffering offering, DeploymentPlan plan, NetworkConfiguration config, Account owner); + NetworkConfiguration implement(NetworkConfiguration config, NetworkOffering offering, DeployDestination destination); + + +} diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/com/cloud/network/element/NetworkElement.java new file mode 100644 index 00000000000..e89123d7e98 --- /dev/null +++ b/api/src/com/cloud/network/element/NetworkElement.java @@ -0,0 +1,32 @@ +/** + * + */ +package com.cloud.network.element; + +import com.cloud.network.NetworkConfiguration; +import com.cloud.offering.NetworkOffering; +import com.cloud.utils.component.Adapter; +import com.cloud.vm.NicProfile; +import com.cloud.vm.VirtualMachineProfile; + +/** + * Represents one network element that exists in a network. + */ +public interface NetworkElement extends Adapter { + /** + * Implement the network configuration as specified. + * @param config fully specified network configuration. + * @param offering network offering that originated the network configuration. + * @return true if network configuration is now usable; false if not. + */ + boolean implement(NetworkConfiguration config, NetworkOffering offering); + + /** + * Prepare the nic profile to be used within the network. + * @param config + * @param nic + * @param offering + * @return + */ + boolean prepare(NetworkConfiguration config, NicProfile nic, VirtualMachineProfile vm, NetworkOffering offering); +} diff --git a/api/src/com/cloud/resource/Resource.java b/api/src/com/cloud/resource/Resource.java index 3269fcd2382..0ab66082ee4 100644 --- a/api/src/com/cloud/resource/Resource.java +++ b/api/src/com/cloud/resource/Resource.java @@ -19,6 +19,12 @@ public interface Resource { Releasing, } + enum ReservationStrategy { + UserSpecified, + Create, + Start + } + /** * @return id in the CloudStack database */ @@ -56,4 +62,6 @@ public interface Resource { * @return the reservation state of the resource. */ State getState(); + + ReservationStrategy getReservationStrategy(); } diff --git a/api/src/com/cloud/vm/NetworkConcierge.java b/api/src/com/cloud/vm/NetworkConcierge.java index b5979950391..6611466e0f6 100644 --- a/api/src/com/cloud/vm/NetworkConcierge.java +++ b/api/src/com/cloud/vm/NetworkConcierge.java @@ -7,7 +7,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.network.NetworkConfiguration; -import com.cloud.utils.component.Adapter; +import com.cloud.resource.Concierge; /** * NetworkConcierge reserves network settings for a VM based @@ -16,7 +16,7 @@ import com.cloud.utils.component.Adapter; * the reservation. * */ -public interface NetworkConcierge extends Adapter { +public interface NetworkConcierge extends Concierge { String getUniqueName(); NicProfile allocate(VirtualMachine vm, NetworkConfiguration config, NicProfile nic) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException; diff --git a/api/src/com/cloud/vm/State.java b/api/src/com/cloud/vm/State.java index 81692497d9f..53bd798818f 100644 --- a/api/src/com/cloud/vm/State.java +++ b/api/src/com/cloud/vm/State.java @@ -19,10 +19,13 @@ package com.cloud.vm; import java.util.List; +import java.util.Set; +import com.cloud.utils.fsm.FiniteState; import com.cloud.utils.fsm.StateMachine; +import com.cloud.vm.VirtualMachine.Event; -public enum State { +public enum State implements FiniteState { Creating(true), Starting(true), Running(false), @@ -44,22 +47,24 @@ public enum State { return _transitional; } - public static String[] toStrings(State... states) { - String[] strs = new String[states.length]; - for (int i = 0; i < states.length; i++) { - strs[i] = states[i].toString(); - } - - return strs; - } - + @Override public State getNextState(VirtualMachine.Event e) { return s_fsm.getNextState(this, e); } - public State[] getFromStates(VirtualMachine.Event e) { - List from = s_fsm.getFromStates(this, e); - return from.toArray(new State[from.size()]); + @Override + public List getFromStates(VirtualMachine.Event e) { + return s_fsm.getFromStates(this, e); + } + + @Override + public Set getPossibleEvents() { + return s_fsm.getPossibleEvents(this); + } + + @Override + public StateMachine getStateMachine() { + return s_fsm; } protected static final StateMachine s_fsm = new StateMachine(); diff --git a/api/src/com/cloud/vm/VirtualMachineProfile.java b/api/src/com/cloud/vm/VirtualMachineProfile.java index c0c4cea4fd2..6d97f5d21c1 100644 --- a/api/src/com/cloud/vm/VirtualMachineProfile.java +++ b/api/src/com/cloud/vm/VirtualMachineProfile.java @@ -67,10 +67,18 @@ public class VirtualMachineProfile { this._nics = profiles; } + public List getNics() { + return _nics; + } + public void setDisks(List profiles) { this._disks = profiles; } + public List getDisks() { + return _disks; + } + public Hypervisor.Type getHypervisorType() { return _hypervisorType; } diff --git a/core/src/com/cloud/vm/VMInstanceVO.java b/core/src/com/cloud/vm/VMInstanceVO.java index 3ca1894206d..6b109c1ad95 100644 --- a/core/src/com/cloud/vm/VMInstanceVO.java +++ b/core/src/com/cloud/vm/VMInstanceVO.java @@ -36,12 +36,14 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import com.cloud.utils.db.GenericDao; +import com.cloud.utils.db.StateMachine; +import com.cloud.utils.fsm.FiniteStateObject; @Entity @Table(name="vm_instance") @Inheritance(strategy=InheritanceType.JOINED) @DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.STRING, length=32) -public class VMInstanceVO implements VirtualMachine { +public class VMInstanceVO implements VirtualMachine, FiniteStateObject { @Id @TableGenerator(name="vm_instance_sq", table="sequence", pkColumnName="name", valueColumnName="value", pkColumnValue="vm_instance_seq", allocationSize=1) @Column(name="id", updatable=false, nullable = false) @@ -65,7 +67,8 @@ public class VMInstanceVO implements VirtualMachine { * the state machine needs to go through the DAO object because someone * else could be updating it as well. */ - @Enumerated(value=EnumType.STRING) + @Enumerated(value=EnumType.STRING) + @StateMachine(state=State.class, event=Event.class) @Column(name="state", updatable=true, nullable=false, length=32) private State state = null; @@ -249,7 +252,8 @@ public class VMInstanceVO implements VirtualMachine { } // don't use this directly, use VM state machine instead, this method is added for migration tool only - public void setState(State state) { + @Override + public void setState(State state) { this.state = state; } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 7dce64b35c3..7717f52cf81 100644 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -1020,7 +1020,7 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemVmControlNetwork, NetworkOfferingVO.SystemVmManagementNetwork, NetworkOfferingVO.SystemVmPublicNetwork); List profiles = new ArrayList(offerings.size()); for (NetworkOfferingVO offering : offerings) { - profiles.add(_networkMgr.setupNetworkProfile(_accountMgr.getSystemAccount(), offering, plan)); + profiles.add(_networkMgr.setupNetworkConfiguration(_accountMgr.getSystemAccount(), offering, plan)); } ConsoleProxyVO proxy = new ConsoleProxyVO(id, name, _template.getId(), _template.getGuestOSId(), dataCenterId, 0); proxy = _consoleProxyDao.persist(proxy); diff --git a/server/src/com/cloud/network/NetworkConfigurationVO.java b/server/src/com/cloud/network/NetworkConfigurationVO.java index 863c303269b..0605aeb4516 100644 --- a/server/src/com/cloud/network/NetworkConfigurationVO.java +++ b/server/src/com/cloud/network/NetworkConfigurationVO.java @@ -70,11 +70,20 @@ public class NetworkConfigurationVO implements NetworkConfiguration { @Column(name="data_center_id") long dataCenterId; + @Column(name="handler_name") + String handlerName; + + @Column(name="state") + @Enumerated(value=EnumType.STRING) + State state; + public NetworkConfigurationVO() { } - public NetworkConfigurationVO(NetworkConfiguration that, long offeringId, long dataCenterId) { + public NetworkConfigurationVO(NetworkConfiguration that, long offeringId, long dataCenterId, String handlerName) { this(that.getTrafficType(), that.getMode(), that.getBroadcastDomainType(), offeringId, dataCenterId); + this.handlerName = handlerName; + this.state = that.getState(); } public NetworkConfigurationVO(TrafficType trafficType, Mode mode, BroadcastDomainType broadcastDomainType, long networkOfferingId, long dataCenterId) { @@ -83,6 +92,16 @@ public class NetworkConfigurationVO implements NetworkConfiguration { this.broadcastDomainType = broadcastDomainType; this.networkOfferingId = networkOfferingId; this.dataCenterId = dataCenterId; + this.state = State.Allocated; + } + + @Override + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; } @Override @@ -108,6 +127,14 @@ public class NetworkConfigurationVO implements NetworkConfiguration { public BroadcastDomainType getBroadcastDomainType() { return broadcastDomainType; } + + public String getHandlerName() { + return handlerName; + } + + public void setHandlerName(String handlerName) { + this.handlerName = handlerName; + } public void setBroadcastDomainType(BroadcastDomainType broadcastDomainType) { this.broadcastDomainType = broadcastDomainType; diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 3ec4ee4486d..1b1dcedcd6e 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -26,9 +26,12 @@ import com.cloud.async.executor.LoadBalancerParam; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.VlanVO; +import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.exception.ResourceAllocationException; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.service.ServiceOfferingVO; @@ -41,6 +44,7 @@ import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachineProfile; /** * NetworkManager manages the network for the different end users. @@ -215,15 +219,15 @@ public interface NetworkManager extends Manager { */ List listPublicIpAddressesInVirtualNetwork(long accountId, long dcId, Boolean sourceNat); - NetworkConfigurationVO setupNetworkProfile(AccountVO account, NetworkOfferingVO offering, DeploymentPlan plan); - NetworkConfigurationVO setupNetworkProfile(AccountVO account, NetworkOfferingVO offering, Map params, DeploymentPlan plan); - List setupNetworkProfiles(AccountVO account, List offerings, DeploymentPlan plan); + NetworkConfigurationVO setupNetworkConfiguration(AccountVO owner, NetworkOfferingVO offering, DeploymentPlan plan); + NetworkConfigurationVO setupNetworkConfiguration(AccountVO owner, NetworkOfferingVO offering, NetworkConfiguration predefined, DeploymentPlan plan); + List setupNetworkConfigurations(AccountVO owner, List offerings, DeploymentPlan plan); List getSystemAccountNetworkOfferings(String... offeringNames); List allocate(K vm, List> networks) throws InsufficientCapacityException; - List prepare(K vm); + List prepare(VirtualMachineProfile profile, DeployDestination dest) throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapcityException; void create(K vm); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index deb0e461b3c..a7dcca27e58 100644 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -79,6 +79,7 @@ import com.cloud.dc.VlanVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; @@ -88,7 +89,9 @@ import com.cloud.event.EventVO; import com.cloud.event.dao.EventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.exception.InternalErrorException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; @@ -102,6 +105,7 @@ import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.network.Network.TrafficType; +import com.cloud.network.configuration.NetworkGuru; import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; @@ -111,6 +115,8 @@ import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; +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.StorageManager; @@ -157,6 +163,7 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.VirtualMachineName; +import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; @@ -205,8 +212,8 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager @Inject NetworkConfigurationDao _networkProfileDao = null; @Inject NicDao _nicDao; - @Inject(adapter=NetworkProfiler.class) - Adapters _networkProfilers; + @Inject(adapter=NetworkGuru.class) + Adapters _networkGurus; @Inject(adapter=NetworkConcierge.class) Adapters _networkConcierges; @@ -1794,7 +1801,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("RouterMonitor")); final ComponentLocator locator = ComponentLocator.getCurrentLocator(); - _networkProfilers = locator.getAdapters(NetworkProfiler.class); + _networkGurus = locator.getAdapters(NetworkGuru.class); _networkConcierges = locator.getAdapters(NetworkConcierge.class); final Map configs = _configDao.getConfiguration("AgentManager", params); @@ -2344,12 +2351,12 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager } @Override - public NetworkConfigurationVO setupNetworkProfile(AccountVO owner, NetworkOfferingVO offering, DeploymentPlan plan) { - return setupNetworkProfile(owner, offering, new HashMap(), plan); + public NetworkConfigurationVO setupNetworkConfiguration(AccountVO owner, NetworkOfferingVO offering, DeploymentPlan plan) { + return setupNetworkConfiguration(owner, offering, null, plan); } @Override - public NetworkConfigurationVO setupNetworkProfile(AccountVO owner, NetworkOfferingVO offering, Map params, DeploymentPlan plan) { + public NetworkConfigurationVO setupNetworkConfiguration(AccountVO owner, NetworkOfferingVO offering, NetworkConfiguration predefined, DeploymentPlan plan) { List configs = _networkProfileDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId()); if (configs.size() > 0) { if (s_logger.isDebugEnabled()) { @@ -2358,8 +2365,8 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager return configs.get(0); } - for (NetworkProfiler profiler : _networkProfilers) { - NetworkConfiguration profile = profiler.convert(offering, plan, params, owner); + for (NetworkGuru guru : _networkGurus) { + NetworkConfiguration profile = guru.design(offering, plan, predefined, owner); if (profile == null) { continue; } @@ -2372,7 +2379,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager } } - NetworkConfigurationVO vo = new NetworkConfigurationVO(profile, offering.getId(), plan.getDataCenterId()); + NetworkConfigurationVO vo = new NetworkConfigurationVO(profile, offering.getId(), plan.getDataCenterId(), guru.getName()); return _networkProfileDao.persist(vo, owner.getId()); } @@ -2380,10 +2387,10 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager } @Override - public List setupNetworkProfiles(AccountVO owner, List offerings, DeploymentPlan plan) { + public List setupNetworkConfigurations(AccountVO owner, List offerings, DeploymentPlan plan) { List profiles = new ArrayList(offerings.size()); for (NetworkOfferingVO offering : offerings) { - profiles.add(setupNetworkProfile(owner, offering, plan)); + profiles.add(setupNetworkConfiguration(owner, offering, plan)); } return profiles; } @@ -2447,10 +2454,29 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager } @Override - public List prepare(K vm) { + public List prepare(VirtualMachineProfile vmProfile, DeployDestination dest) throws InsufficientAddressCapacityException, InsufficientVirtualNetworkCapcityException { + List nics = _nicDao.listBy(vmProfile.getId()); + for (NicVO nic : nics) { + NetworkConfigurationVO config = _networkProfileDao.findById(nic.getNetworkConfigurationId()); + + if (nic.getReservationStrategy() == ReservationStrategy.Start) { + NetworkConcierge concierge = _networkConcierges.get(nic.getReserver()); + nic.setState(Resource.State.Reserving); + _nicDao.update(nic.getId(), nic); + concierge.reserve(vmProfile.getId(), toNicProfile(nic), dest); + } else { + + } + } return null; } + NicProfile toNicProfile(NicVO nic) { + NetworkConfiguration config = _networkProfileDao.findById(nic.getNetworkConfigurationId()); + NicProfile profile = new NicProfile(nic, config); + return profile; + } + @Override public void create(K vm) { for (NetworkConcierge concierge : _networkConcierges) { diff --git a/server/src/com/cloud/network/profiler/ControlNetworkProfiler.java b/server/src/com/cloud/network/configuration/ControlNetworkGuru.java similarity index 87% rename from server/src/com/cloud/network/profiler/ControlNetworkProfiler.java rename to server/src/com/cloud/network/configuration/ControlNetworkGuru.java index 2c23180d62b..6daa2b8d035 100644 --- a/server/src/com/cloud/network/profiler/ControlNetworkProfiler.java +++ b/server/src/com/cloud/network/configuration/ControlNetworkGuru.java @@ -1,7 +1,7 @@ /** * */ -package com.cloud.network.profiler; +package com.cloud.network.configuration; import java.util.Map; @@ -22,7 +22,6 @@ import com.cloud.network.Network.Mode; import com.cloud.network.Network.TrafficType; import com.cloud.network.NetworkConfiguration; import com.cloud.network.NetworkConfigurationVO; -import com.cloud.network.NetworkProfiler; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; @@ -34,15 +33,15 @@ import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachine; -@Local(value={NetworkProfiler.class, NetworkConcierge.class}) -public class ControlNetworkProfiler extends AdapterBase implements NetworkProfiler, NetworkConcierge { - private static final Logger s_logger = Logger.getLogger(ControlNetworkProfiler.class); +@Local(value={NetworkGuru.class, NetworkConcierge.class}) +public class ControlNetworkGuru extends AdapterBase implements NetworkGuru, NetworkConcierge { + private static final Logger s_logger = Logger.getLogger(ControlNetworkGuru.class); @Inject DataCenterDao _dcDao; String _cidr; String _gateway; @Override - public NetworkConfiguration convert(NetworkOffering offering, DeploymentPlan plan, Map params, Account owner) { + public NetworkConfiguration design(NetworkOffering offering, DeploymentPlan plan, NetworkConfiguration specifiedConfig, Account owner) { if (offering.getTrafficType() != TrafficType.Control) { return null; } @@ -54,7 +53,7 @@ public class ControlNetworkProfiler extends AdapterBase implements NetworkProfil return config; } - protected ControlNetworkProfiler() { + protected ControlNetworkGuru() { super(); } @@ -120,4 +119,9 @@ public class ControlNetworkProfiler extends AdapterBase implements NetworkProfil _dcDao.releaseLinkLocalPrivateIpAddress(Long.parseLong(uniqueId)); return true; } + + @Override + public NetworkConfiguration implement(NetworkConfiguration config, NetworkOffering offering, DeployDestination destination) { + return config; + } } diff --git a/server/src/com/cloud/network/profiler/GuestNetworkProfiler.java b/server/src/com/cloud/network/configuration/GuestNetworkGuru.java similarity index 73% rename from server/src/com/cloud/network/profiler/GuestNetworkProfiler.java rename to server/src/com/cloud/network/configuration/GuestNetworkGuru.java index 2542161eb95..1f76612cadd 100644 --- a/server/src/com/cloud/network/profiler/GuestNetworkProfiler.java +++ b/server/src/com/cloud/network/configuration/GuestNetworkGuru.java @@ -1,22 +1,20 @@ /** * */ -package com.cloud.network.profiler; - -import java.util.Map; +package com.cloud.network.configuration; import javax.ejb.Local; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.network.Network.BroadcastDomainType; import com.cloud.network.Network.Mode; import com.cloud.network.Network.TrafficType; import com.cloud.network.NetworkConfiguration; import com.cloud.network.NetworkConfigurationVO; -import com.cloud.network.NetworkProfiler; import com.cloud.network.dao.NetworkConfigurationDao; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.GuestIpType; @@ -24,18 +22,18 @@ import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.Inject; -@Local(value=NetworkProfiler.class) -public class GuestNetworkProfiler extends AdapterBase implements NetworkProfiler { +@Local(value=NetworkGuru.class) +public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { @Inject protected NetworkConfigurationDao _profileDao; @Inject protected DataCenterDao _dcDao; @Inject protected VlanDao _vlanDao; - protected GuestNetworkProfiler() { + protected GuestNetworkGuru() { super(); } @Override - public NetworkConfiguration convert(NetworkOffering offering, DeploymentPlan plan, Map params, Account owner) { + public NetworkConfiguration design(NetworkOffering offering, DeploymentPlan plan, NetworkConfiguration userSpecified, Account owner) { if (offering.getTrafficType() != TrafficType.Guest) { return null; } @@ -57,4 +55,10 @@ public class GuestNetworkProfiler extends AdapterBase implements NetworkProfiler return profile; } + @Override + public NetworkConfiguration implement(NetworkConfiguration config, NetworkOffering offering, DeployDestination destination) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/server/src/com/cloud/network/configuration/GuruUtils.java b/server/src/com/cloud/network/configuration/GuruUtils.java new file mode 100644 index 00000000000..1b6c9c04bff --- /dev/null +++ b/server/src/com/cloud/network/configuration/GuruUtils.java @@ -0,0 +1,9 @@ +/** + * + */ +package com.cloud.network.configuration; + +public final class GuruUtils { + + +} diff --git a/server/src/com/cloud/network/profiler/PodBasedNetworkProfiler.java b/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java similarity index 83% rename from server/src/com/cloud/network/profiler/PodBasedNetworkProfiler.java rename to server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java index 1b7c73055e3..3b446ccbb9a 100644 --- a/server/src/com/cloud/network/profiler/PodBasedNetworkProfiler.java +++ b/server/src/com/cloud/network/configuration/PodBasedNetworkGuru.java @@ -1,9 +1,7 @@ /** * */ -package com.cloud.network.profiler; - -import java.util.Map; +package com.cloud.network.configuration; import javax.ejb.Local; @@ -20,7 +18,6 @@ import com.cloud.network.Network.Mode; import com.cloud.network.Network.TrafficType; import com.cloud.network.NetworkConfiguration; import com.cloud.network.NetworkConfigurationVO; -import com.cloud.network.NetworkProfiler; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; @@ -31,13 +28,13 @@ import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachine; -@Local(value={NetworkProfiler.class, NetworkConcierge.class}) -public class PodBasedNetworkProfiler extends AdapterBase implements NetworkProfiler, NetworkConcierge { - private static final Logger s_logger = Logger.getLogger(PodBasedNetworkProfiler.class); +@Local(value={NetworkGuru.class, NetworkConcierge.class}) +public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru, NetworkConcierge { + private static final Logger s_logger = Logger.getLogger(PodBasedNetworkGuru.class); @Inject DataCenterDao _dcDao; @Override - public NetworkConfiguration convert(NetworkOffering offering, DeploymentPlan plan, Map params, Account owner) { + public NetworkConfiguration design(NetworkOffering offering, DeploymentPlan plan, NetworkConfiguration userSpecified, Account owner) { TrafficType type = offering.getTrafficType(); if (type != TrafficType.Management && type != TrafficType.Storage) { @@ -49,7 +46,7 @@ public class PodBasedNetworkProfiler extends AdapterBase implements NetworkProfi return config; } - protected PodBasedNetworkProfiler() { + protected PodBasedNetworkGuru() { super(); } @@ -96,4 +93,10 @@ public class PodBasedNetworkProfiler extends AdapterBase implements NetworkProfi return true; } + @Override + public NetworkConfiguration implement(NetworkConfiguration config, NetworkOffering offering, DeployDestination destination) { + // TODO Auto-generated method stub + return null; + } + } diff --git a/server/src/com/cloud/network/profiler/PublicNetworkProfiler.java b/server/src/com/cloud/network/configuration/PublicNetworkProfiler.java similarity index 79% rename from server/src/com/cloud/network/profiler/PublicNetworkProfiler.java rename to server/src/com/cloud/network/configuration/PublicNetworkProfiler.java index 58d2e755c49..f3e0da7ded4 100644 --- a/server/src/com/cloud/network/profiler/PublicNetworkProfiler.java +++ b/server/src/com/cloud/network/configuration/PublicNetworkProfiler.java @@ -1,12 +1,11 @@ /** * */ -package com.cloud.network.profiler; - -import java.util.Map; +package com.cloud.network.configuration; import javax.ejb.Local; +import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.exception.InsufficientAddressCapacityException; @@ -16,21 +15,22 @@ import com.cloud.network.Network.Mode; import com.cloud.network.Network.TrafficType; import com.cloud.network.NetworkConfiguration; import com.cloud.network.NetworkConfigurationVO; -import com.cloud.network.NetworkProfiler; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; import com.cloud.utils.component.AdapterBase; +import com.cloud.utils.component.Inject; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NetworkConcierge; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachine; -@Local(value={NetworkProfiler.class, NetworkConcierge.class}) -public class PublicNetworkProfiler extends AdapterBase implements NetworkProfiler, NetworkConcierge { +@Local(value={NetworkGuru.class, NetworkConcierge.class}) +public class PublicNetworkProfiler extends AdapterBase implements NetworkGuru, NetworkConcierge { + @Inject DataCenterDao _dcDao; @Override - public NetworkConfiguration convert(NetworkOffering offering, DeploymentPlan plan, Map params, Account owner) { + public NetworkConfiguration design(NetworkOffering offering, DeploymentPlan plan, NetworkConfiguration config, Account owner) { if (offering.getTrafficType() != TrafficType.Public) { return null; } @@ -77,4 +77,11 @@ public class PublicNetworkProfiler extends AdapterBase implements NetworkProfile public boolean release(String uniqueName, String uniqueId) { return false; } + + @Override + public NetworkConfiguration implement(NetworkConfiguration config, NetworkOffering offering, DeployDestination destination) { + + // TODO Auto-generated method stub + return null; + } } diff --git a/server/src/com/cloud/network/profiler/ProfilerUtils.java b/server/src/com/cloud/network/profiler/ProfilerUtils.java deleted file mode 100644 index 905d1208424..00000000000 --- a/server/src/com/cloud/network/profiler/ProfilerUtils.java +++ /dev/null @@ -1,9 +0,0 @@ -/** - * - */ -package com.cloud.network.profiler; - -public final class ProfilerUtils { - - -} diff --git a/server/src/com/cloud/vm/MauriceMoss.java b/server/src/com/cloud/vm/MauriceMoss.java index 25858fe7510..3e9fb6b0c53 100644 --- a/server/src/com/cloud/vm/MauriceMoss.java +++ b/server/src/com/cloud/vm/MauriceMoss.java @@ -29,6 +29,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; +import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.deploy.DeployDestination; @@ -55,6 +56,7 @@ import com.cloud.utils.component.Inject; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.VirtualMachine.Event; import com.cloud.vm.dao.VMInstanceDao; @Local(value=VmManager.class) @@ -85,14 +87,15 @@ public class MauriceMoss implements VmManager { if (s_logger.isDebugEnabled()) { s_logger.debug("Allocating entries for VM: " + vm); } - VMInstanceVO instance = _vmDao.findById(vm.getId()); - VirtualMachineProfile vmProfile = new VirtualMachineProfile(instance, serviceOffering); + //VMInstanceVO vm = _vmDao.findById(vm.getId()); + VirtualMachineProfile vmProfile = new VirtualMachineProfile(vm, serviceOffering); Transaction txn = Transaction.currentTxn(); txn.start(); - instance.setDataCenterId(plan.getDataCenterId()); - _vmDao.update(instance.getId(), instance); - List nics = _networkMgr.allocate(instance, networks); + vm.setDataCenterId(plan.getDataCenterId()); + _vmDao.update(vm.getId(), vm); + + List nics = _networkMgr.allocate(vm, networks); vmProfile.setNics(nics); if (dataDiskOfferings == null) { @@ -101,32 +104,21 @@ public class MauriceMoss implements VmManager { List disks = new ArrayList(dataDiskOfferings.size() + 1); if (template.getFormat() == ImageFormat.ISO) { - disks.add(_storageMgr.allocateRawVolume(VolumeType.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), rootDiskOffering.second(), instance, owner)); + disks.add(_storageMgr.allocateRawVolume(VolumeType.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), rootDiskOffering.second(), vm, owner)); } else { - disks.add(_storageMgr.allocateTemplatedVolume(VolumeType.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), template, instance, owner)); + disks.add(_storageMgr.allocateTemplatedVolume(VolumeType.ROOT, "ROOT-" + vm.getId(), rootDiskOffering.first(), template, vm, owner)); } for (Pair offering : dataDiskOfferings) { - disks.add(_storageMgr.allocateRawVolume(VolumeType.DATADISK, "DATA-" + vm.getId(), offering.first(), offering.second(), instance, owner)); + disks.add(_storageMgr.allocateRawVolume(VolumeType.DATADISK, "DATA-" + vm.getId(), offering.first(), offering.second(), vm, owner)); } vmProfile.setDisks(disks); - + + _vmDao.updateIf(vm, Event.OperationSucceeded, null); txn.commit(); if (s_logger.isDebugEnabled()) { s_logger.debug("Allocation completed for VM: " + vm); } - boolean created = false; - try { - vmProfile = create(vmProfile, plan); - created = vmProfile != null; - } catch (InsufficientCapacityException e) { - throw e; - } finally { - if (!created) { - // TODO: Error handling - } - } - return vmProfile; } @@ -240,8 +232,45 @@ public class MauriceMoss implements VmManager { } @Override - public T start(T vm) { - // TODO Auto-generated method stub + public T start(VirtualMachineProfile vmProfile, DeploymentPlan plan) throws InsufficientCapacityException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating actual resources for VM " + vmProfile); + } + + Journal journal = new Journal.LogJournal("Creating " + vmProfile, s_logger); + + Set avoids = new HashSet(); + int retry = _retry; + while (_retry-- > 0) { + DeployDestination context = null; + for (DeploymentDispatcher dispatcher : _dispatchers) { + context = dispatcher.plan(vmProfile, plan, avoids); + if (context != null) { + avoids.add(context); + journal.record("Deployment found ", vmProfile, context); + break; + } + } + + if (context == null) { + throw new CloudRuntimeException("Unable to create a deployment for " + vmProfile); + } + + VMInstanceVO vm = _vmDao.findById(vmProfile.getId()); + + vm.setDataCenterId(context.getDataCenter().getId()); + vm.setPodId(context.getPod().getId()); + _vmDao.updateIf(vm, Event.StartRequested, context.getHost().getId()); + + VirtualMachineTO vmTO = new VirtualMachineTO(); +// _networkMgr.prepare(vmProfile); +// _storageMgr.prepare(vm); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creation complete for VM " + vmProfile); + } + return null; } diff --git a/server/src/com/cloud/vm/NicVO.java b/server/src/com/cloud/vm/NicVO.java index 6025ad9c342..3ce09fd7313 100644 --- a/server/src/com/cloud/vm/NicVO.java +++ b/server/src/com/cloud/vm/NicVO.java @@ -157,6 +157,11 @@ public class NicVO implements Nic { public void setReserver(String reserver) { this.reserver = reserver; } + + @Override + public ReservationStrategy getReservationStrategy() { + return ReservationStrategy.Start; + } @Override public int getExpectedReservationInterval() { diff --git a/server/src/com/cloud/vm/VmManager.java b/server/src/com/cloud/vm/VmManager.java index 45fc167783b..fabf4b65ffd 100644 --- a/server/src/com/cloud/vm/VmManager.java +++ b/server/src/com/cloud/vm/VmManager.java @@ -62,7 +62,7 @@ public interface VmManager extends Manager { DeploymentPlan plan, AccountVO owner) throws InsufficientCapacityException, StorageUnavailableException; - T start(T vm) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException; + T start(VirtualMachineProfile p, DeploymentPlan plan) throws InsufficientCapacityException, StorageUnavailableException, ConcurrentOperationException; T stop(T vm) throws AgentUnavailableException, ConcurrentOperationException; diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index b4b9b995d6e..9878ac4cd11 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -100,7 +100,9 @@ CREATE TABLE `cloud`.`network_configurations` ( `mode` varchar(32) COMMENT 'How to retrieve ip address in this network', `vlan_id` bigint unsigned NULL COMMENT 'vlan id if the broadcast_domain_type is the vlan', `network_offering_id` bigint unsigned NOT NULL COMMENT 'network offering id that this configuration is created from', - `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id that this configuration is used in', + `data_center_id` bigint unsigned NOT NULL COMMENT 'data center id that this configuration is used in', + `handler_name` varchar(255) NOT NULL COMMENT 'who is responsible for this type of network configuration', + `state` varchar(32) NOT NULL COMMENT 'what state is this configuration in', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/utils/src/com/cloud/utils/component/Adapters.java b/utils/src/com/cloud/utils/component/Adapters.java index 0fc5afad683..26417f17251 100755 --- a/utils/src/com/cloud/utils/component/Adapters.java +++ b/utils/src/com/cloud/utils/component/Adapters.java @@ -74,7 +74,7 @@ public class Adapters implements Iterable { this._adapters = adapters; } - protected T get(String name) { + public T get(String name) { return _map.get(name); } diff --git a/utils/src/com/cloud/utils/db/GenericDao.java b/utils/src/com/cloud/utils/db/GenericDao.java index 4a28068d342..da785808dd6 100755 --- a/utils/src/com/cloud/utils/db/GenericDao.java +++ b/utils/src/com/cloud/utils/db/GenericDao.java @@ -101,7 +101,7 @@ public interface GenericDao { * @return object if acquired; null if not. If null, you need to call findById to see if it is actually not found. */ T acquire(ID id); - + /** * Acquires a database wide lock on the id of the entity. This ensures * that only one is being used. The timeout is the configured default. @@ -184,7 +184,15 @@ public interface GenericDao { boolean remove(ID id); /** - * remove the entity bean. + * Remove based on the search criteria. This will delete if the VO object + * does not have a REMOVED column. + * @param sc search criteria to match + * @return rows removed. + */ + int remove(SearchCriteria sc); + + /** + * Expunge actually delete the row even if it's REMOVED. * @param id * @return true if removed. */ @@ -212,5 +220,4 @@ public interface GenericDao { */ boolean configure(String name, Map params) throws ConfigurationException; - int remove(SearchCriteria sc); } \ No newline at end of file diff --git a/utils/src/com/cloud/utils/db/GenericDaoBase.java b/utils/src/com/cloud/utils/db/GenericDaoBase.java index 3cce85f230d..653485ceb64 100755 --- a/utils/src/com/cloud/utils/db/GenericDaoBase.java +++ b/utils/src/com/cloud/utils/db/GenericDaoBase.java @@ -1370,4 +1370,5 @@ public abstract class GenericDaoBase implements Gene SearchBuilder builder = createSearchBuilder(); return builder.create(); } + } diff --git a/utils/src/com/cloud/utils/db/GenericSearchBuilder.java b/utils/src/com/cloud/utils/db/GenericSearchBuilder.java index f7931fb8cb8..4b7fef121ba 100644 --- a/utils/src/com/cloud/utils/db/GenericSearchBuilder.java +++ b/utils/src/com/cloud/utils/db/GenericSearchBuilder.java @@ -43,7 +43,7 @@ import com.cloud.utils.exception.CloudRuntimeException; * @param VO object this Search is build for. * @param Result object that should contain the results. */ -public class GenericSearchBuilder implements DaoSearch, MethodInterceptor { +public class GenericSearchBuilder implements MethodInterceptor { final protected Map _attrs; protected ArrayList _conditions; diff --git a/utils/src/com/cloud/utils/db/StateMachine.java b/utils/src/com/cloud/utils/db/StateMachine.java new file mode 100644 index 00000000000..d8b16e3ff4e --- /dev/null +++ b/utils/src/com/cloud/utils/db/StateMachine.java @@ -0,0 +1,31 @@ +/** + * 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.db; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Target(FIELD) +@Retention(RUNTIME) +public @interface StateMachine { + public Class state(); + public Class event(); +} diff --git a/utils/src/com/cloud/utils/fsm/FiniteState.java b/utils/src/com/cloud/utils/fsm/FiniteState.java new file mode 100644 index 00000000000..7ce9b2a6ed9 --- /dev/null +++ b/utils/src/com/cloud/utils/fsm/FiniteState.java @@ -0,0 +1,55 @@ +/** + * 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.fsm; + +import java.util.List; +import java.util.Set; + +/** + * Interface for a state in the finite state machine. + * + * @param State + * @param Event + */ +public interface FiniteState { + /** + * @return the state machine being used. + */ + StateMachine getStateMachine(); + + /** + * get next state based on the event. + * @param event + * @return next State + */ + S getNextState(E event); + + /** + * Get the states that could have traveled to the current state + * via this event. + * @param event + * @return array of states + */ + List getFromStates(E event); + + /** + * Get the possible events that can happen from the current state. + * @return array of events. + */ + Set getPossibleEvents(); +} diff --git a/utils/src/com/cloud/utils/db/DaoSearch.java b/utils/src/com/cloud/utils/fsm/FiniteStateObject.java similarity index 79% rename from utils/src/com/cloud/utils/db/DaoSearch.java rename to utils/src/com/cloud/utils/fsm/FiniteStateObject.java index bfe1536cdf3..277af6fb597 100644 --- a/utils/src/com/cloud/utils/db/DaoSearch.java +++ b/utils/src/com/cloud/utils/fsm/FiniteStateObject.java @@ -1,7 +1,7 @@ /** * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. * - * This software is licensed under the GNU General Public License v3 or later. + * 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 @@ -15,7 +15,13 @@ * along with this program. If not, see . * */ -package com.cloud.utils.db; +package com.cloud.utils.fsm; -public interface DaoSearch { +public interface FiniteStateObject { + /** + * @return finite state. + */ + FiniteState getState(); + + void setState(S state); }