Bug 11522 - New agent manager

able to compile besides mycloud stuff
This commit is contained in:
frank 2011-09-26 16:55:20 -07:00
parent caa8aaf6fe
commit e8c13e10c7
14 changed files with 101 additions and 130 deletions

View File

@ -14,16 +14,13 @@ public enum ResourceState {
Maintenance;
public enum Event {
InternalCreating("Resource is creating"),
AdminEnable("Admin enables"),
AdminDisable("Admin disables"),
ClusterUnmanage("Cluster is unmanaged"),
ClusterManage("Cluster is managed"),
InternalCreated("Resource is created"),
Enable("Admin enables"),
Disable("Admin disables"),
AdminAskMaintenace("Admin asks to enter maintenance"),
AdminCancelMaintenance("Admin asks to cancel maintenance"),
InternalEnterMaintenance("Resource enters maintenance"),
Unmanaged("Admin turns a host into umanaged state"),
AdminAskReconnect("Admin triggers a reconnect"),
UpdatePassword("Admin updates password of host"),
UnableToMigrate("Management server migrates VM failed"),
DeleteHost("Admin delete a host");
@ -61,18 +58,24 @@ public enum ResourceState {
protected static final StateMachine<ResourceState, Event> s_fsm = new StateMachine<ResourceState, Event>();
static {
s_fsm.addTransition(null, Event.InternalCreating, ResourceState.Enabled);
s_fsm.addTransition(ResourceState.Enabled, Event.AdminEnable, ResourceState.Enabled);
s_fsm.addTransition(ResourceState.Enabled, Event.AdminDisable, ResourceState.Disabled);
s_fsm.addTransition(ResourceState.Enabled, Event.ClusterUnmanage, ResourceState.Unmanaged);
s_fsm.addTransition(ResourceState.Enabled, Event.AdminAskMaintenace, ResourceState.PrepareForMaintenace);
s_fsm.addTransition(ResourceState.Disabled, Event.AdminEnable, ResourceState.Enabled);
s_fsm.addTransition(ResourceState.Disabled, Event.AdminDisable, ResourceState.Disabled);
s_fsm.addTransition(ResourceState.Disabled, Event.ClusterUnmanage, ResourceState.Unmanaged);
s_fsm.addTransition(ResourceState.Unmanaged, Event.ClusterUnmanage, ResourceState.Unmanaged);
s_fsm.addTransition(ResourceState.Unmanaged, Event.ClusterManage, ResourceState.Disabled);
s_fsm.addTransition(ResourceState.PrepareForMaintenace, Event.InternalEnterMaintenance, ResourceState.Maintenance);
s_fsm.addTransition(ResourceState.PrepareForMaintenace, Event.AdminCancelMaintenance, ResourceState.Enabled);
s_fsm.addTransition(null, Event.InternalCreated, ResourceState.Enabled);
s_fsm.addTransition(ResourceState.Enabled, Event.Enable, ResourceState.Enabled);
s_fsm.addTransition(ResourceState.Enabled, Event.Disable, ResourceState.Disabled);
s_fsm.addTransition(ResourceState.Enabled, Event.Unmanaged, ResourceState.Unmanaged);
s_fsm.addTransition(ResourceState.Enabled, Event.AdminAskMaintenace, ResourceState.PrepareForMaintenance);
s_fsm.addTransition(ResourceState.Disabled, Event.Enable, ResourceState.Enabled);
s_fsm.addTransition(ResourceState.Disabled, Event.Disable, ResourceState.Disabled);
s_fsm.addTransition(ResourceState.Disabled, Event.Unmanaged, ResourceState.Unmanaged);
s_fsm.addTransition(ResourceState.Unmanaged, Event.Unmanaged, ResourceState.Unmanaged);
s_fsm.addTransition(ResourceState.PrepareForMaintenance, Event.InternalEnterMaintenance, ResourceState.Maintenance);
s_fsm.addTransition(ResourceState.PrepareForMaintenance, Event.AdminCancelMaintenance, ResourceState.Enabled);
s_fsm.addTransition(ResourceState.PrepareForMaintenance, Event.Unmanaged, ResourceState.Unmanaged);
s_fsm.addTransition(ResourceState.Maintenance, Event.AdminCancelMaintenance, ResourceState.Enabled);
s_fsm.addTransition(ResourceState.Maintenance, Event.DeleteHost, ResourceState.Disabled);
s_fsm.addTransition(ResourceState.Maintenance, Event.Unmanaged, ResourceState.Unmanaged);
s_fsm.addTransition(ResourceState.ErrorInMaintenance, Event.Unmanaged, ResourceState.Unmanaged);
s_fsm.addTransition(ResourceState.ErrorInMaintenance, Event.Disable, ResourceState.Disabled);
s_fsm.addTransition(ResourceState.ErrorInMaintenance, Event.DeleteHost, ResourceState.Disabled);
s_fsm.addTransition(ResourceState.ErrorInMaintenance, Event.InternalEnterMaintenance, ResourceState.Maintenance);
}
}

View File

@ -715,6 +715,6 @@ public class HostVO implements Host {
@Override
public boolean isInMaintenanceStates() {
return (getResourceState() == ResourceState.Maintenance || getResourceState() == ResourceState.ErrorInMaintenance
|| getResourceState() == ResourceState.PrepareForMaintenace);
|| getResourceState() == ResourceState.PrepareForMaintenance);
}
}

View File

@ -198,8 +198,6 @@ public interface AgentManager extends Manager {
Answer sendToSecStorage(HostVO ssHost, Command cmd);
HostVO getSSAgent(HostVO ssHost);
void updateStatus(HostVO host, Event event);
/* working as a lock while agent is being loaded */
public boolean tapLoadingAgents(Long hostId, TapAgentsAction action);

View File

@ -1250,99 +1250,6 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
return false;
}
public boolean checkCIDR(Host.Type type, HostPodVO pod, String serverPrivateIP, String serverPrivateNetmask) {
if (serverPrivateIP == null) {
return true;
}
// Get the CIDR address and CIDR size
String cidrAddress = pod.getCidrAddress();
long cidrSize = pod.getCidrSize();
// If the server's private IP address is not in the same subnet as the
// pod's CIDR, return false
String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
if (!cidrSubnet.equals(serverSubnet)) {
return false;
}
// If the server's private netmask is less inclusive than the pod's CIDR
// netmask, return false
String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask);
if (serverNetmaskNumeric > cidrNetmaskNumeric) {
return false;
}
return true;
}
protected void checkCIDR(Host.Type type, HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask) throws IllegalArgumentException {
// Skip this check for Storage Agents and Console Proxies
if (type == Host.Type.Storage || type == Host.Type.ConsoleProxy) {
return;
}
if (serverPrivateIP == null) {
return;
}
// Get the CIDR address and CIDR size
String cidrAddress = pod.getCidrAddress();
long cidrSize = pod.getCidrSize();
// If the server's private IP address is not in the same subnet as the
// pod's CIDR, return false
String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize);
String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask);
if (!cidrSubnet.equals(serverSubnet)) {
s_logger.warn("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() + " and zone: " + dc.getName());
throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() + " and zone: " + dc.getName());
}
// If the server's private netmask is less inclusive than the pod's CIDR
// netmask, return false
String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize);
long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask);
long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask);
if (serverNetmaskNumeric > cidrNetmaskNumeric) {
throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() + " and zone: " + dc.getName());
}
}
public void checkIPConflicts(Host.Type type, HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask, String serverPublicIP, String serverPublicNetmask) {
// If the server's private IP is the same as is public IP, this host has
// a host-only private network. Don't check for conflicts with the
// private IP address table.
if (serverPrivateIP != serverPublicIP) {
if (!_privateIPAddressDao.mark(dc.getId(), pod.getId(), serverPrivateIP)) {
// If the server's private IP address is already in the
// database, return false
List<DataCenterIpAddressVO> existingPrivateIPs = _privateIPAddressDao.listByPodIdDcIdIpAddress(pod.getId(), dc.getId(), serverPrivateIP);
assert existingPrivateIPs.size() <= 1 : " How can we get more than one ip address with " + serverPrivateIP;
if (existingPrivateIPs.size() > 1) {
throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName());
}
if (existingPrivateIPs.size() == 1) {
DataCenterIpAddressVO vo = existingPrivateIPs.get(0);
if (vo.getInstanceId() != null) {
throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName());
}
}
}
}
if (serverPublicIP != null && !_publicIPAddressDao.mark(dc.getId(), new Ip(serverPublicIP))) {
// If the server's public IP address is already in the database,
// return false
List<IPAddressVO> existingPublicIPs = _publicIPAddressDao.listByDcIdIpAddress(dc.getId(), serverPublicIP);
if (existingPublicIPs.size() > 0) {
throw new IllegalArgumentException("The public ip address of the server (" + serverPublicIP + ") is already in use in zone: " + dc.getName());
}
}
}
protected AgentAttache createAttacheForConnect(HostVO host, Link link) throws ConnectionException {
s_logger.debug("create ConnectedAgentAttache for " + host.getId());
AgentAttache attache = new ConnectedAgentAttache(this, host.getId(), link, host.isInMaintenanceStates());
@ -1692,7 +1599,7 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
if (event == Status.Event.AgentConnected) {
allow = false;
}
} else if (state == ResourceState.PrepareForMaintenace) {
} else if (state == ResourceState.PrepareForMaintenance) {
} else if (state == ResourceState.Maintenance) {

View File

@ -141,7 +141,7 @@ public class AgentMonitor extends Thread implements Listener {
_agentMgr.disconnectWithInvestigation(agentId, Event.PingTimeout);
}
List<HostVO> hosts = _hostDao.listByResourceState(ResourceState.PrepareForMaintenace, ResourceState.ErrorInMaintenance);
List<HostVO> hosts = _hostDao.listByResourceState(ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance);
for (HostVO host : hosts) {
long hostId = host.getId();
DataCenterVO dcVO = _dcDao.findById(host.getDataCenterId());

View File

@ -174,5 +174,17 @@ public class DummyClusterManagerImpl implements ClusterManager {
@Override
public boolean isAgentRebalanceEnabled() {
return false;
}
@Override
public Boolean propagateResourceEvent(long agentId, com.cloud.resource.ResourceState.Event event) throws AgentUnavailableException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean executeResourceUserRequest(long hostId, com.cloud.resource.ResourceState.Event event) throws AgentUnavailableException {
// TODO Auto-generated method stub
return false;
}
}

View File

@ -134,6 +134,7 @@ public class CloudZonesStartupProcessor implements StartupCommandProcessor {
}
protected boolean processHostStartup(StartupRoutingCommand startup) throws ConnectionException{
/*
boolean found = false;
Type type = Host.Type.Routing;
final Map<String, String> hostDetails = startup.getHostDetails();
@ -170,6 +171,7 @@ public class CloudZonesStartupProcessor implements StartupCommandProcessor {
s_logger.info("Old " + server.getType().toString()
+ " host reconnected w/ id =" + server.getId());
}
*/
return true;
@ -396,6 +398,7 @@ public class CloudZonesStartupProcessor implements StartupCommandProcessor {
protected boolean processStorageStartup(StartupStorageCommand startup) throws ConnectionException{
/*
if (startup.getResourceType() != Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE) {
return false;
}
@ -435,6 +438,7 @@ public class CloudZonesStartupProcessor implements StartupCommandProcessor {
s_logger.info("Old " + server.getType().toString()
+ " host reconnected w/ id =" + server.getId());
}
*/
return true;

View File

@ -316,7 +316,7 @@ public class ExternalNetworkManagerImpl implements ExternalNetworkManager, Resou
}
try {
if (_agentMgr.maintain(hostId) && _agentMgr.deleteHost(hostId, false, false, caller)) {
if (_resourceMgr.maintain(hostId) && _resourceMgr.deleteHost(hostId, false, false)) {
DataCenterVO zone = _dcDao.findById(externalLoadBalancer.getDataCenterId());
if (zone.getNetworkType().equals(NetworkType.Advanced)) {
@ -676,7 +676,7 @@ public class ExternalNetworkManagerImpl implements ExternalNetworkManager, Resou
}
try {
if (_agentMgr.maintain(hostId) && _agentMgr.deleteHost(hostId, false, false, caller)) {
if (_resourceMgr.maintain(hostId) && _resourceMgr.deleteHost(hostId, false, false)) {
DataCenterVO zone = _dcDao.findById(externalFirewall.getDataCenterId());
zone.setFirewallProvider(Network.Provider.VirtualRouter.getName());
zone.setUserDataProvider(Network.Provider.VirtualRouter.getName());

View File

@ -161,7 +161,7 @@ public class F5BigIpManagerImpl extends ExternalNetworkManagerImpl implements Ex
}
try {
if (_agentMgr.maintain(hostId) && _agentMgr.deleteHost(hostId, false, false, caller)) {
if (_resourceMgr.maintain(hostId) && _resourceMgr.deleteHost(hostId, false, false)) {
DataCenterVO zone = _dcDao.findById(externalLoadBalancer.getDataCenterId());
if (zone.getNetworkType().equals(NetworkType.Advanced)) {

View File

@ -225,8 +225,8 @@ public class JuniperSrxManagerImpl extends ExternalNetworkManagerImpl implements
throw new InvalidParameterValueException("Could not find an external firewall with ID: " + hostId);
}
try {
if (_agentMgr.maintain(hostId) && _agentMgr.deleteHost(hostId, false, false, caller)) {
try {
if (_resourceMgr.maintain(hostId) && _resourceMgr.deleteHost(hostId, false, false)) {
DataCenterVO zone = _dcDao.findById(externalFirewall.getDataCenterId());
zone.setFirewallProvider(Network.Provider.VirtualRouter.getName());
zone.setUserDataProvider(Network.Provider.VirtualRouter.getName());

View File

@ -183,9 +183,9 @@ public class NetworkUsageManagerImpl implements NetworkUsageManager, ResourceSta
throw new InvalidParameterValueException("Could not find an traffic monitor with ID: " + hostId);
}
try {
if (_agentMgr.maintain(hostId) && _agentMgr.deleteHost(hostId, false, false, caller)) {
return true;
try {
if (_resourceMgr.maintain(hostId) && _resourceMgr.deleteHost(hostId, false, false)) {
return true;
} else {
return false;
}

View File

@ -79,4 +79,8 @@ public interface ResourceManager {
boolean umanageHost(long hostId);
boolean maintenanceFailed(long hostId);
public boolean maintain(final long hostId) throws AgentUnavailableException;
public boolean deleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage);
}

View File

@ -88,6 +88,7 @@ import com.cloud.network.dao.IPAddressDao;
import com.cloud.org.Cluster;
import com.cloud.org.Grouping;
import com.cloud.org.Managed;
import com.cloud.resource.ResourceState.Event;
import com.cloud.storage.GuestOSCategoryVO;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
@ -716,6 +717,12 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
}
}
try {
updateResourceState(host, ResourceState.Event.DeleteHost, _nodeId);
} catch (NoTransitionException e) {
s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
}
// Delete the associated entries in host ref table
_storagePoolHostDao.deletePrimaryRecordsForHost(hostId);
@ -1019,7 +1026,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
return true;
}
private boolean maintain(final long hostId) throws AgentUnavailableException {
public boolean maintain(final long hostId) throws AgentUnavailableException {
Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.AdminAskMaintenace);
if (result != null) {
return result;
@ -1373,6 +1380,12 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
_hostDao.update(host.getId(), host);
/* Agent goes to Connecting status */
_agentMgr.agentStatusTransitTo(host, Status.Event.AgentConnected, _nodeId);
try {
updateResourceState(host, ResourceState.Event.InternalCreated, _nodeId);
} catch (NoTransitionException e) {
s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
}
return host;
}
@ -1422,6 +1435,17 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
if (host != null) {
/* Change agent status to Alert */
_agentMgr.agentStatusTransitTo(host, Status.Event.AgentDisconnected, _nodeId);
try {
updateResourceState(host, ResourceState.Event.Disable, _nodeId);
} catch (NoTransitionException e) {
s_logger.debug("Cannot transmit host " + host.getId() + "to Disabled state", e);
}
}
} else {
try {
updateResourceState(host, ResourceState.Event.InternalCreated, _nodeId);
} catch (NoTransitionException e) {
s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
}
}
}
@ -1617,7 +1641,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
}
/*TODO: think twice about returning true or throwing out exception, I really prefer to exception that always exposes bugs */
if (host.getResourceState() != ResourceState.PrepareForMaintenace && host.getResourceState() != ResourceState.Maintenance && host.getResourceState() != ResourceState.ErrorInMaintenance) {
if (host.getResourceState() != ResourceState.PrepareForMaintenance && host.getResourceState() != ResourceState.Maintenance && host.getResourceState() != ResourceState.ErrorInMaintenance) {
throw new CloudRuntimeException("Cannot perform cancelMaintenance when resource state is " + host.getResourceState() + ", hostId = " + hostId);
}
@ -1631,8 +1655,14 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
}
}
_agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.ResetRequested);
return true;
try {
updateResourceState(host, ResourceState.Event.AdminCancelMaintenance, _nodeId);
_agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.ResetRequested);
return true;
} catch (NoTransitionException e) {
s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e);
return false;
}
}
private boolean cancelMaintenance(long hostId) {
@ -1668,8 +1698,20 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
}
private boolean doUmanageHost(long hostId) {
_agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.AgentDisconnected);
return true;
try {
HostVO host = _hostDao.findById(hostId);
if (host == null) {
s_logger.debug("Cannot find host " + hostId + ", assuming it has been deleted, skip umanage");
return true;
}
updateResourceState(host, ResourceState.Event.AdminCancelMaintenance, _nodeId);
_agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.AgentDisconnected);
return true;
} catch (NoTransitionException e) {
s_logger.debug("Cannot transmit host " + hostId + "to Enabled state", e);
return false;
}
}

View File

@ -66,4 +66,5 @@ public interface SerialVersionUID {
public static final long NoTransitionException = Base | 0x26;
public static final long CloudExecutionException = Base | 0x27;
public static final long CallFailedException = Base | 0x28;
public static final long UnableDeleteHostException = Base | 0x29;
}