@Override protected Long getId(Object obj) { if (obj instanceof Volume) { return ((Volume) obj).getId(); } return null; }
@Override public String toString() { return String.format("storage pool for volume %s must be one of kind %s", volume.getId(), AllocatorUtils.UNMANGED_STORAGE_POOLS); } }
@Override public String toString() { String matchText = exactMatch ? "must have exactly these pool(s): " : "must be one of pool(s)"; return String.format("volume [%d] %s %s", volume.getId(), matchText, storagePools); }
protected Set<Long> createVolumes(Instance instance, List<Volume> volumes, Map<String, Object> data) { Set<Long> volumeIds = new TreeSet<Long>(); Volume root = createRoot(instance, volumes, data); if (root != null) { volumeIds.add(root.getId()); } return volumeIds; }
@Override public void volumeDeallocate(Volume volume) { log.info("Deallocating volume [{}]", volume.getId()); if (!allocatorDao.isAllocationReleased(volume)) { allocatorDao.releaseAllocation(volume); callExternalSchedulerToRelease(volume); } log.info("Handled request for volume [{}]", volume.getId()); }
@Override public boolean matches(AllocationCandidate candidate) { Set<Long> poolIds = candidate.getPools().get(volume.getId()); if (storagePools.size() == 0 && poolIds.size() == 0) { return true; } if (exactMatch) { return storagePools.equals(poolIds); } for (Long poolId : poolIds) { if (!storagePools.contains(poolId)) { return false; } } return true; }
public AllocationAttempt(long accountId, List<Instance> instances, Long hostId, Long requestedHostId, Set<Volume> volumes, Map<Volume, Set<StoragePool>> pools) { super(); this.accountId = accountId; this.instances = instances; this.hostId = hostId; this.requestedHostId = requestedHostId; this.pools = pools; this.volumes = volumes == null ? new HashSet<Volume>(): volumes; this.poolIds = new HashMap<Long, Set<Long>>(); for (Volume v : volumes) { Set<StoragePool> storagePools = pools.get(v); if (storagePools != null) { Set<Long> poolIds = new HashSet<Long>(storagePools.size()); for (StoragePool pool : storagePools) { poolIds.add(pool.getId()); } this.poolIds.put(v.getId(), poolIds); } } }
@Override public boolean matches(AllocationCandidate candidate) { Set<Long> poolIds = candidate.getPools().get(volume.getId()); for (Long id : poolIds) { StoragePool pool = candidate.loadResource(StoragePool.class, id); if (!AllocatorUtils.UNMANGED_STORAGE_POOLS.contains(pool.getKind())) { return false; } } return true; }
@Override public Resource filter(ApiRequest request, Object original, Resource converted) { if (request != null && "v1".equals(request.getVersion())) { return converted; } if (original instanceof Volume) { Map<Long, Map<String, Object>> data = getCached(request); if (data != null) { Map<String, Object> fields = data.get(((Volume) original).getId()); if (fields != null) { converted.getFields().putAll(fields); } } } return converted; }
@Override public HandlerResult handle(ProcessState state, ProcessInstance process) { Map<String, Object> result = new HashMap<String, Object>(); Map<String, Set<Long>> allocationData = new HashMap<String, Set<Long>>(); result.put("_allocationData", allocationData); Volume volume = (Volume) state.getResource(); for (VolumeStoragePoolMap map : mapDao.findNonRemoved(VolumeStoragePoolMap.class, Volume.class, volume.getId())) { CollectionUtils.addToMap(allocationData, "volume:" + volume.getId(), map.getVolumeId(), HashSet.class); create(map, state.getData()); } return new HandlerResult(result); }
@Override public Mount doWithLock() { Map<Object, Object> criteria = new HashMap<Object, Object>(); criteria.put(MOUNT.VOLUME_ID, volume.getId()); criteria.put(MOUNT.INSTANCE_ID, instance.getId()); criteria.put(MOUNT.PATH, path); criteria.put(MOUNT.REMOVED, null); criteria.put(MOUNT.STATE, new Condition(ConditionType.NE, CommonStatesConstants.INACTIVE)); Mount mount = objectManager.findAny(Mount.class, criteria); if (mount != null) { if (!mount.getPath().equalsIgnoreCase(permissions)) objectManager.setFields(mount, MOUNT.PERMISSIONS, permissions); return mount; } return objectManager.create(Mount.class, MOUNT.ACCOUNT_ID, instance.getAccountId(), MOUNT.INSTANCE_ID, instance.getId(), MOUNT.VOLUME_ID, volume.getId(), MOUNT.PATH, path, MOUNT.PERMISSIONS, permissions); } });
protected Mount mountVolume(final Volume volume, final Instance instance, final String path, final String permissions) { return lockManager.lock(new MountVolumeLock(volume.getId()), new LockCallback<Mount>() { @Override public Mount doWithLock() { Map<Object, Object> criteria = new HashMap<Object, Object>(); criteria.put(MOUNT.VOLUME_ID, volume.getId()); criteria.put(MOUNT.INSTANCE_ID, instance.getId()); criteria.put(MOUNT.PATH, path); criteria.put(MOUNT.REMOVED, null); criteria.put(MOUNT.STATE, new Condition(ConditionType.NE, CommonStatesConstants.INACTIVE)); Mount mount = objectManager.findAny(Mount.class, criteria); if (mount != null) { if (!mount.getPath().equalsIgnoreCase(permissions)) objectManager.setFields(mount, MOUNT.PERMISSIONS, permissions); return mount; } return objectManager.create(Mount.class, MOUNT.ACCOUNT_ID, instance.getAccountId(), MOUNT.INSTANCE_ID, instance.getId(), MOUNT.VOLUME_ID, volume.getId(), MOUNT.PATH, path, MOUNT.PERMISSIONS, permissions); } }); }
@Override public Resource filter(ApiRequest request, Object original, Resource converted) { if (!(original instanceof Volume)) { return converted; } Volume volume = (Volume)original; List<String> caps = DataAccessor.fieldStringList(volume, ObjectMetaDataManager.CAPABILITIES_FIELD); Set<String> capabilities = new HashSet<>(caps); boolean snapshotCapable = capabilities.contains(VolumeConstants.CAPABILITY_SNAPSHOT); if (!snapshotCapable) { converted.getActions().remove(VolumeConstants.ACTION_SNAPSHOT); } if (!snapshotCapable || volumeDao.isVolumeInUseByRunningInstance(volume.getId())) { converted.getActions().remove(VolumeConstants.ACTION_REVERT); converted.getActions().remove(VolumeConstants.ACTION_RESTORE); } return converted; }
@Override public HandlerResult handle(ProcessState state, ProcessInstance process) { Volume volume = (Volume) state.getResource(); Set<Long> pools = new HashSet<Long>(); for (VolumeStoragePoolMap map : mapDao.findNonRemoved(VolumeStoragePoolMap.class, Volume.class, volume.getId())) { activatePool(volume, map, state.getData()); pools.add(map.getStoragePoolId()); } return new HandlerResult("_activatedPools", pools); }
@Override public HandlerResult handle(ProcessState state, ProcessInstance process) { Map<String, Object> result = new HashMap<String, Object>(); Volume volume = (Volume) state.getResource(); allocatorService.volumeDeallocate(volume); for (VolumeStoragePoolMap map : mapDao.findToRemove(VolumeStoragePoolMap.class, Volume.class, volume.getId())) { deactivateThenScheduleRemove(map, state.getData()); } return new HandlerResult(result); } }
@Override public HandlerResult handle(ProcessState state, ProcessInstance process) { Volume volume = (Volume)state.getResource(); List<Snapshot> snapshots = null; if (VolumeConstants.PROCESS_RESTORE_FROM_BACKUP.equalsIgnoreCase(process.getName())) { snapshots = objectManager.children(volume, Snapshot.class); } else if (VolumeConstants.PROCESS_REVERT.equalsIgnoreCase(process.getName())) { Snapshot snapshot = objectManager.loadResource(Snapshot.class, state.getData().get("snapshotId").toString()); Map<Object, Object> criteria = new HashMap<Object, Object>(); criteria.put(SNAPSHOT.VOLUME_ID, volume.getId()); criteria.put(SNAPSHOT.REMOVED, null); criteria.put(SNAPSHOT.ID, new Condition(ConditionType.GT, snapshot.getId())); snapshots = objectManager.find(Snapshot.class, criteria); } else { throw new IllegalStateException("Unknown process: " + process.getName()); } for (Snapshot s : snapshots) { if (s.getRemoved() == null) { objectProcessManager.scheduleStandardProcess(StandardProcess.REMOVE, s, null); } } return null; }
@Override public Object perform(String name, Object obj, ApiRequest request) { if (!(obj instanceof Volume)) { return null; } Volume volume = (Volume)obj; Snapshot snapshot = objectManager.newRecord(Snapshot.class); snapshot.setKind(SnapshotConstants.TYPE); snapshot.setAccountId(volume.getAccountId()); snapshot.setVolumeId(volume.getId()); String snapshotName = DataAccessor.fromMap(request.getRequestObject()).withKey("name").as(String.class); if (StringUtils.isNotBlank(snapshotName)) { snapshot.setName(snapshotName); } snapshot = objectManager.create(snapshot); processManager.scheduleStandardProcess(StandardProcess.CREATE, snapshot, null); return objectManager.reload(snapshot); } }
@Override public List<? extends StoragePool> getAssociatedPools(Volume volume) { return create() .select(STORAGE_POOL.fields()) .from(STORAGE_POOL) .join(VOLUME_STORAGE_POOL_MAP) .on(VOLUME_STORAGE_POOL_MAP.STORAGE_POOL_ID.eq(STORAGE_POOL.ID)) .where( VOLUME_STORAGE_POOL_MAP.REMOVED.isNull() .and(VOLUME_STORAGE_POOL_MAP.VOLUME_ID.eq(volume.getId()))) .fetchInto(StoragePoolRecord.class); }
@Override public void createVolumeInStoragePool(Map<String, Object> volumeData, String volumeName, StoragePool storagePool) { Record record = create() .select(VOLUME.fields()) .from(VOLUME) .join(VOLUME_STORAGE_POOL_MAP) .on(VOLUME_STORAGE_POOL_MAP.VOLUME_ID.eq(VOLUME.ID) .and(VOLUME_STORAGE_POOL_MAP.STORAGE_POOL_ID.eq(storagePool.getId()))) .join(STORAGE_POOL) .on(VOLUME_STORAGE_POOL_MAP.STORAGE_POOL_ID.eq(STORAGE_POOL.ID)) .and(STORAGE_POOL.REMOVED.isNull()) .where(VOLUME.NAME.eq(volumeName) .and((VOLUME.REMOVED.isNull().or(VOLUME.STATE.eq(CommonStatesConstants.REMOVING))))) .and(VOLUME.ACCOUNT_ID.eq(storagePool.getAccountId())) .fetchAny(); if (record != null) { return; } Volume volume = resourceDao.createAndSchedule(Volume.class, volumeData); Map<String, Object> vspm = new HashMap<String, Object>(); vspm.put("volumeId", volume.getId()); vspm.put("storagePoolId", storagePool.getId()); resourceDao.createAndSchedule(VolumeStoragePoolMap.class, vspm); }
@Override public boolean isOnSharedStorage(Volume volume) { Result<?> r = create().select(STORAGE_POOL.ID) .from(STORAGE_POOL) .join(VOLUME_STORAGE_POOL_MAP) .on(VOLUME_STORAGE_POOL_MAP.STORAGE_POOL_ID.eq(STORAGE_POOL.ID)) .where(STORAGE_POOL.REMOVED.isNull() .and(VOLUME_STORAGE_POOL_MAP.REMOVED.isNull()) .and(VOLUME_STORAGE_POOL_MAP.VOLUME_ID.eq(volume.getId())) .and(STORAGE_POOL.KIND.notIn(UNMANGED_STORAGE_POOLS))) .limit(1) .fetch(); return r.size() > 0; }