Bug 11522 - New agent manager

moves migration to ResourceManager
This commit is contained in:
frank 2011-09-23 15:22:39 -07:00
parent 81665757de
commit f63e412ac9
6 changed files with 117 additions and 2 deletions

View File

@ -257,4 +257,6 @@ public interface AgentManager extends Manager {
void disconnect(long hostId, Status.Event event);
public boolean disconnectAgent(HostVO host, Status.Event e, long msId);
public void pullAgentToMaintenance(long hostId);
}

View File

@ -2277,4 +2277,14 @@ public class AgentManagerImpl implements AgentManager, HandlerFactory, Manager {
return attache;
}
@Override
public void pullAgentToMaintenance(long hostId) {
AgentAttache attache = findAttache(hostId);
if (attache != null) {
attache.setMaintenanceMode(true);
// Now cancel all of the commands except for the active one.
attache.cancelAllCommands(Status.Disconnected, false);
}
}
}

View File

@ -27,6 +27,7 @@ import com.cloud.host.Status;
import com.cloud.host.Status.Event;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.info.RunningHostCountInfo;
import com.cloud.resource.ResourceState;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao;
@ -179,5 +180,7 @@ public interface HostDao extends GenericDao<HostVO, Long>, StateDao<Status, Stat
List<HostVO> listByInAllStatus(Type type, Long clusterId, Long podId, long dcId);
List<HostVO> listByClusterStatus(long clusterId, Status status);
List<HostVO> listByClusterStatus(long clusterId, Status status);
boolean updateResourceState(ResourceState oldState, ResourceState.Event event, ResourceState newState, Host vo);
}

View File

@ -45,6 +45,7 @@ import com.cloud.host.Status.Event;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.info.RunningHostCountInfo;
import com.cloud.org.Managed;
import com.cloud.resource.ResourceState;
import com.cloud.utils.DateUtil;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.db.Attribute;
@ -1082,5 +1083,34 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
return result > 0;
}
@Override
public boolean updateResourceState(ResourceState oldState, ResourceState.Event event, ResourceState newState, Host vo) {
HostVO host = (HostVO)vo;
SearchBuilder<HostVO> sb = createSearchBuilder();
sb.and("resource_state", sb.entity().getResourceState(), SearchCriteria.Op.EQ);
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.done();
SearchCriteria<HostVO> sc = sb.create();
sc.setParameters("status", oldState);
sc.setParameters("id", host.getId());
UpdateBuilder ub = getUpdateBuilder(host);
ub.set(host, _statusAttr, newState);
int result = update(ub, sc, null);
assert result <= 1 : "How can this update " + result + " rows? ";
if (s_logger.isDebugEnabled() && result == 0) {
HostVO ho = findById(host.getId());
assert ho != null : "How how how? : " + host.getId();
StringBuilder str = new StringBuilder("Unable to update resource state for event:").append(event.toString());
/*TODO: add defbug info*/
}
return result > 0;
}
}

View File

@ -29,6 +29,8 @@ import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.host.HostVO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.resource.ResourceState.Event;
import com.cloud.utils.fsm.NoTransitionException;
/**
* ResourceManager manages how physical resources are organized within the
@ -71,4 +73,6 @@ public interface ResourceManager {
public void deleteRoutingHost(HostVO host, boolean isForced, boolean forceDestroyStorage) throws UnableDeleteHostException;
public boolean executeUserRequest(long hostId, ResourceState.Event event) throws AgentUnavailableException;
boolean updateResourceState(Host host, Event event, long msId) throws NoTransitionException;
}

View File

@ -34,6 +34,8 @@ import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.AgentManager.TapAgentsAction;
import com.cloud.agent.api.MaintainAnswer;
import com.cloud.agent.api.MaintainCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.manager.AgentAttache;
@ -66,6 +68,7 @@ import com.cloud.exception.DiscoveryException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.ha.HighAvailabilityManager.WorkType;
import com.cloud.host.Host;
import com.cloud.host.Host.HostAllocationState;
import com.cloud.host.Host.Type;
@ -106,6 +109,7 @@ import com.cloud.utils.db.DB;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.utils.net.Ip;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.VMInstanceVO;
@ -966,6 +970,68 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
throw new CloudRuntimeException("Failed to reconnect host with id " + hostId.toString() + ", internal error.");
}
@Override
public boolean updateResourceState(Host host, ResourceState.Event event, long msId) throws NoTransitionException {
ResourceState currentState = host.getResourceState();
ResourceState nextState = currentState.getNextState(event);
if (nextState == null) {
throw new NoTransitionException("No next resource state found for current state =" + currentState + " event =" + event);
}
/*TODO: adding debug trace*/
return _hostDao.updateResourceState(currentState, event, nextState, host);
}
private boolean doMaintain(final long hostId) {
HostVO host = _hostDao.findById(hostId);
MaintainAnswer answer = (MaintainAnswer) _agentMgr.easySend(hostId, new MaintainCommand());
if (answer == null || !answer.getResult()) {
s_logger.warn("Unable to put host in maintainance mode: " + hostId);
return false;
}
try {
updateResourceState(host, ResourceState.Event.AdminAskMaintenace, _nodeId);
} catch (NoTransitionException e) {
String err = "Cannot transimit resource state of host " + host.getId() + " to " + ResourceState.Maintenance;
s_logger.debug(err, e);
throw new CloudRuntimeException(err + e.getMessage());
}
_agentMgr.pullAgentToMaintenance(hostId);
/*TODO: move below to listener */
if (host.getType() == Host.Type.Routing) {
final List<VMInstanceVO> vms = _vmDao.listByHostId(hostId);
if (vms.size() == 0) {
return true;
}
List<HostVO> hosts = _hostDao.listBy(host.getClusterId(), host.getPodId(), host.getDataCenterId());
for (final VMInstanceVO vm : vms) {
if (hosts == null || hosts.size() <= 1 || !answer.getMigrate()) {
// for the last host in this cluster, stop all the VMs
_haMgr.scheduleStop(vm, hostId, WorkType.ForceStop);
} else {
_haMgr.scheduleMigration(vm);
}
}
}
return true;
}
private boolean maintain(final long hostId) throws AgentUnavailableException {
Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.AdminAskMaintenace);
if (result != null) {
return result;
}
return doMaintain(hostId);
}
@Override
public Host maintain(PrepareForMaintenanceCmd cmd) {
Long hostId = cmd.getId();
@ -986,7 +1052,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
try {
processResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, hostId);
if (_agentMgr.maintain(hostId)) {
if (maintain(hostId)) {
processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, hostId);
return _hostDao.findById(hostId);
} else {