@DB public void work() { if (s_logger.isTraceEnabled()) { s_logger.trace("Checking the database"); } final SecurityGroupWorkVO work = _workDao.take(_serverId); if (work == null) { if (s_logger.isTraceEnabled()) { s_logger.trace("Security Group work: no work found"); } return; } Long userVmId = work.getInstanceId(); if (work.getStep() == Step.Done) { if (s_logger.isDebugEnabled()) { s_logger.debug( "Security Group work: found a job in done state, rescheduling for vm: " + userVmId); } ArrayList<Long> affectedVms = new ArrayList<Long>(); affectedVms.add(userVmId); scheduleRulesetUpdateToHosts(affectedVms, false, _timeBetweenCleanups * 1000l); return; } UserVm vm = null; Long seqnum = null; s_logger.debug("Working on " + work); final Transaction txn = Transaction.currentTxn(); txn.start(); boolean locked = false; try { vm = _userVMDao.acquireInLockTable(work.getInstanceId()); if (vm == null) { vm = _userVMDao.findById(work.getInstanceId()); if (vm == null) { s_logger.info("VM " + work.getInstanceId() + " is removed"); locked = true; return; } s_logger.warn("Unable to acquire lock on vm id=" + userVmId); return; } locked = true; Long agentId = null; VmRulesetLogVO log = _rulesetLogDao.findByVmId(userVmId); if (log == null) { s_logger.warn("Cannot find log record for vm id=" + userVmId); return; } seqnum = log.getLogsequence(); if (vm != null && vm.getState() == State.Running) { Map<PortAndProto, Set<String>> rules = generateRulesForVM(userVmId); agentId = vm.getHostId(); if (agentId != null) { SecurityIngressRulesCmd cmd = generateRulesetCmd( vm.getInstanceName(), vm.getPrivateIpAddress(), vm.getPrivateMacAddress(), vm.getId(), generateRulesetSignature(rules), seqnum, rules); Commands cmds = new Commands(cmd); try { _agentMgr.send(agentId, cmds, _answerListener); } catch (AgentUnavailableException e) { s_logger.debug( "Unable to send updates for vm: " + userVmId + "(agentid=" + agentId + ")"); _workDao.updateStep(work.getInstanceId(), seqnum, Step.Done); } } } } finally { if (locked) { _userVMDao.releaseFromLockTable(userVmId); _workDao.updateStep(work.getId(), Step.Done); } txn.commit(); } }
@Override @DB @ActionEvent( eventType = EventTypes.EVENT_ASSIGN_TO_LOAD_BALANCER_RULE, eventDescription = "assigning to load balancer", async = true) public boolean assignToLoadBalancer(long loadBalancerId, List<Long> instanceIds) { UserContext ctx = UserContext.current(); Account caller = ctx.getCaller(); LoadBalancerVO loadBalancer = _lbDao.findById(loadBalancerId); if (loadBalancer == null) { throw new InvalidParameterValueException( "Failed to assign to load balancer " + loadBalancerId + ", the load balancer was not found."); } List<LoadBalancerVMMapVO> mappedInstances = _lb2VmMapDao.listByLoadBalancerId(loadBalancerId, false); Set<Long> mappedInstanceIds = new HashSet<Long>(); for (LoadBalancerVMMapVO mappedInstance : mappedInstances) { mappedInstanceIds.add(Long.valueOf(mappedInstance.getInstanceId())); } List<UserVm> vmsToAdd = new ArrayList<UserVm>(); for (Long instanceId : instanceIds) { if (mappedInstanceIds.contains(instanceId)) { throw new InvalidParameterValueException( "VM " + instanceId + " is already mapped to load balancer."); } UserVm vm = _vmDao.findById(instanceId); if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging) { throw new InvalidParameterValueException("Invalid instance id: " + instanceId); } _rulesMgr.checkRuleAndUserVm(loadBalancer, vm, caller); if (vm.getAccountId() != loadBalancer.getAccountId()) { throw new PermissionDeniedException( "Cannot add virtual machines that do not belong to the same owner."); } // Let's check to make sure the vm has a nic in the same network as the load balancing rule. List<? extends Nic> nics = _networkMgr.getNics(vm.getId()); Nic nicInSameNetwork = null; for (Nic nic : nics) { if (nic.getNetworkId() == loadBalancer.getNetworkId()) { nicInSameNetwork = nic; break; } } if (nicInSameNetwork == null) { throw new InvalidParameterValueException( "VM " + instanceId + " cannot be added because it doesn't belong in the same network."); } if (s_logger.isDebugEnabled()) { s_logger.debug("Adding " + vm + " to the load balancer pool"); } vmsToAdd.add(vm); } Transaction txn = Transaction.currentTxn(); txn.start(); for (UserVm vm : vmsToAdd) { LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vm.getId(), false); map = _lb2VmMapDao.persist(map); } txn.commit(); try { loadBalancer.setState(FirewallRule.State.Add); _lbDao.persist(loadBalancer); applyLoadBalancerConfig(loadBalancerId); } catch (ResourceUnavailableException e) { s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); return false; } return true; }