@Override public HandlerResult handle(ProcessState state, ProcessInstance process) { final Instance instance = (Instance) state.getResource(); List<Volume> volumes = InstanceHelpers.extractVolumesFromMounts(instance, objectManager); for (final Volume v : volumes) { String driver = DataAccessor.fieldString(v, VolumeConstants.FIELD_VOLUME_DRIVER); if (StringUtils.isNotEmpty(driver) && !VolumeConstants.LOCAL_DRIVER.equals(driver)) { StoragePool sp = storagePoolDao.findStoragePoolByDriverName(v.getAccountId(), driver); if (sp == null) { continue; } final String accessMode = sp.getVolumeAccessMode(); if (StringUtils.isNotEmpty(accessMode) && StringUtils.isEmpty(v.getAccessMode()) && !accessMode.equals(v.getAccessMode())) { lockManager.lock( new InstanceVolumeAccessModeLock(v.getId()), new LockCallbackNoReturn() { @Override public void doWithLockNoResult() { objectManager.setFields(v, VOLUME.ACCESS_MODE, accessMode); } }); } } } return null; }
@Override public boolean recordCandidate(AllocationAttempt attempt, AllocationCandidate candidate) { Long newHost = candidate.getHost(); if (newHost != null) { for (Instance instance : attempt.getInstances()) { log.info("Associating instance [{}] to host [{}]", instance.getId(), newHost); objectManager.create( InstanceHostMap.class, INSTANCE_HOST_MAP.HOST_ID, newHost, INSTANCE_HOST_MAP.INSTANCE_ID, instance.getId()); modifyDisk(newHost, instance, true); List<Volume> vols = InstanceHelpers.extractVolumesFromMounts(instance, objectManager); for (Volume v : vols) { if (VolumeConstants.ACCESS_MODE_SINGLE_HOST_RW.equals(v.getAccessMode())) { objectManager.setFields(v, VOLUME.HOST_ID, newHost); } } } } Map<Long, Set<Long>> existingPools = attempt.getPoolIds(); Map<Long, Set<Long>> newPools = candidate.getPools(); if (!existingPools.keySet().equals(newPools.keySet())) { throw new IllegalStateException( String.format( "Volumes don't match. currently %s, new %s", existingPools.keySet(), newPools.keySet())); } for (Map.Entry<Long, Set<Long>> entry : newPools.entrySet()) { long volumeId = entry.getKey(); Set<Long> existingPoolsForVol = existingPools.get(entry.getKey()); Set<Long> newPoolsForVol = entry.getValue(); if (existingPoolsForVol == null || existingPoolsForVol.size() == 0) { for (long poolId : newPoolsForVol) { log.info("Associating volume [{}] to storage pool [{}]", volumeId, poolId); objectManager.create( VolumeStoragePoolMap.class, VOLUME_STORAGE_POOL_MAP.VOLUME_ID, volumeId, VOLUME_STORAGE_POOL_MAP.STORAGE_POOL_ID, poolId); } } else if (!existingPoolsForVol.equals(newPoolsForVol)) { throw new IllegalStateException( String.format( "Can not move volume %s, currently: %s, new: %s", volumeId, existingPools, newPools)); } } for (Nic nic : attempt.getNics()) { Long subnetId = candidate.getSubnetIds().get(nic.getId()); if (subnetId == null || (nic.getSubnetId() != null && subnetId.longValue() == nic.getSubnetId())) { continue; } log.info("Associating nic [{}] to subnet [{}]", nic.getId(), subnetId); int i = create().update(NIC).set(NIC.SUBNET_ID, subnetId).where(NIC.ID.eq(nic.getId())).execute(); if (i != 1) { throw new IllegalStateException( "Expected to update nic id [" + nic.getId() + "] with subnet [" + subnetId + "] but update [" + i + "] rows"); } } return true; }