private boolean sendCommandsToRouter(final DomainRouterVO elbVm, Commands cmds) throws AgentUnavailableException { Answer[] answers = null; try { answers = _agentMgr.send(elbVm.getHostId(), cmds); } catch (OperationTimedoutException e) { s_logger.warn("ELB: Timed Out", e); throw new AgentUnavailableException( "Unable to send commands to virtual elbVm ", elbVm.getHostId(), e); } if (answers == null) { return false; } if (answers.length != cmds.size()) { return false; } // FIXME: Have to return state for individual command in the future if (answers.length > 0) { Answer ans = answers[0]; return ans.getResult(); } return true; }
@Override public List<DomainRouterVO> startRouters( final RouterDeploymentDefinition routerDeploymentDefinition) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { final List<DomainRouterVO> runningRouters = new ArrayList<DomainRouterVO>(); for (DomainRouterVO router : routerDeploymentDefinition.getRouters()) { boolean skip = false; final State state = router.getState(); if (router.getHostId() != null && state != State.Running) { final HostVO host = _hostDao.findById(router.getHostId()); if (host == null || host.getState() != Status.Up) { skip = true; } } if (!skip) { if (state != State.Running) { router = startVirtualRouter( router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), routerDeploymentDefinition.getParams()); } if (router != null) { runningRouters.add(router); } } } return runningRouters; }
@Override public void CheckAndDestroyTunnel(VirtualMachine vm) { if (!_isEnabled) { return; } List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getAccountId(), vm.getHostId()); if (vm.getType() == VirtualMachine.Type.User) { if (userVms.size() > 1) { return; } List<DomainRouterVO> routers = _routerDao.findBy(vm.getAccountId(), vm.getDataCenterIdToDeployIn()); for (DomainRouterVO router : routers) { if (router.getHostId() == vm.getHostId()) { return; } } } else if (vm.getType() == VirtualMachine.Type.DomainRouter && userVms.size() != 0) { return; } try { /* Now we are last one on host, destroy all tunnels of my account */ Command cmd = new OvsDestroyTunnelCommand(vm.getAccountId(), "[]"); Answer ans = _agentMgr.send(vm.getHostId(), cmd); handleDestroyTunnelAnswer(ans, vm.getHostId(), 0, vm.getAccountId()); /* Then ask hosts have peer tunnel with me to destroy them */ List<OvsTunnelAccountVO> peers = _tunnelAccountDao.listByToAccount(vm.getHostId(), vm.getAccountId()); for (OvsTunnelAccountVO p : peers) { cmd = new OvsDestroyTunnelCommand(p.getAccount(), p.getPortName()); ans = _agentMgr.send(p.getFrom(), cmd); handleDestroyTunnelAnswer(ans, p.getFrom(), p.getTo(), p.getAccount()); } } catch (Exception e) { s_logger.warn( String.format( "Destroy tunnel(account:%1$s, hostId:%2$s) failed", vm.getAccountId(), vm.getHostId()), e); } }
@Override public DomainRouterVO startVirtualRouter( final DomainRouterVO router, final User user, final Account caller, final Map<Param, Object> params) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) { return start(router, user, caller, params, null); } if (router.getState() == State.Running) { s_logger.debug("Redundant router " + router.getInstanceName() + " is already running!"); return router; } // // If another thread has already requested a VR start, there is a // transition period for VR to transit from // Starting to Running, there exist a race conditioning window here // We will wait until VR is up or fail if (router.getState() == State.Starting) { return waitRouter(router); } final DataCenterDeployment plan = new DataCenterDeployment(0, null, null, null, null, null); DomainRouterVO result = null; assert router.getIsRedundantRouter(); final List<Long> networkIds = _routerDao.getRouterNetworks(router.getId()); DomainRouterVO routerToBeAvoid = null; if (networkIds.size() != 0) { final List<DomainRouterVO> routerList = _routerDao.findByNetwork(networkIds.get(0)); for (final DomainRouterVO rrouter : routerList) { if (rrouter.getHostId() != null && rrouter.getIsRedundantRouter() && rrouter.getState() == State.Running) { if (routerToBeAvoid != null) { throw new ResourceUnavailableException( "Try to start router " + router.getInstanceName() + "(" + router.getId() + ")" + ", but there are already two redundant routers with IP " + router.getPublicIpAddress() + ", they are " + rrouter.getInstanceName() + "(" + rrouter.getId() + ") and " + routerToBeAvoid.getInstanceName() + "(" + routerToBeAvoid.getId() + ")", DataCenter.class, rrouter.getDataCenterId()); } routerToBeAvoid = rrouter; } } } if (routerToBeAvoid == null) { return start(router, user, caller, params, null); } // We would try best to deploy the router to another place final int retryIndex = 5; final ExcludeList[] avoids = new ExcludeList[5]; avoids[0] = new ExcludeList(); avoids[0].addPod(routerToBeAvoid.getPodIdToDeployIn()); avoids[1] = new ExcludeList(); avoids[1].addCluster(_hostDao.findById(routerToBeAvoid.getHostId()).getClusterId()); avoids[2] = new ExcludeList(); final List<VolumeVO> volumes = _volumeDao.findByInstanceAndType(routerToBeAvoid.getId(), Volume.Type.ROOT); if (volumes != null && volumes.size() != 0) { avoids[2].addPool(volumes.get(0).getPoolId()); } avoids[2].addHost(routerToBeAvoid.getHostId()); avoids[3] = new ExcludeList(); avoids[3].addHost(routerToBeAvoid.getHostId()); avoids[4] = new ExcludeList(); for (int i = 0; i < retryIndex; i++) { if (s_logger.isTraceEnabled()) { s_logger.trace( "Try to deploy redundant virtual router:" + router.getHostName() + ", for " + i + " time"); } plan.setAvoids(avoids[i]); try { result = start(router, user, caller, params, plan); } catch (final InsufficientServerCapacityException ex) { result = null; } if (result != null) { break; } } return result; }