package io.cattle.platform.allocator.constraint; import io.cattle.platform.allocator.dao.AllocatorDao; import io.cattle.platform.allocator.exception.FailedToAllocate; import io.cattle.platform.allocator.service.AllocationAttempt; import io.cattle.platform.allocator.service.AllocationLog; import io.cattle.platform.core.constants.CommonStatesConstants; import io.cattle.platform.core.constants.VolumeConstants; import io.cattle.platform.core.model.Instance; import io.cattle.platform.core.model.Volume; import io.cattle.platform.core.util.InstanceHelpers; import io.cattle.platform.object.ObjectManager; import io.cattle.platform.object.util.DataAccessor; import java.util.Arrays; import java.util.List; import java.util.Set; import javax.inject.Inject; public class VolumeAccessModeConstraintProvider implements AllocationConstraintsProvider { static final List<Object> IHM_STATES = Arrays.asList(new Object[] { CommonStatesConstants.INACTIVE, CommonStatesConstants.DEACTIVATING, CommonStatesConstants.REMOVED, CommonStatesConstants.REMOVING }); @Inject AllocatorDao allocatorDao; @Inject ObjectManager objectManager; @Override public void appendConstraints(AllocationAttempt attempt, AllocationLog log, List<Constraint> constraints) { for (Instance instance : attempt.getInstances()) { List<Volume> volumes = InstanceHelpers.extractVolumesFromMounts(instance, objectManager); for (Volume v : volumes) { if (VolumeConstants.ACCESS_MODE_SINGLE_HOST_RW.equals(v.getAccessMode())) { Long hostID = null; Object hostIdObject = DataAccessor.fromDataFieldOf(v).withKey(VolumeConstants.FIELD_LAST_ALLOCATED_HOST_ID).get(); if ( hostIdObject != null) { hostID = Long.parseLong(hostIdObject.toString()); } Set<Long> hostIds = allocatorDao.findHostsWithVolumeInUse(v.getId()); boolean hardConstraint = false; if (hostIds.size() == 0) { hardConstraint = false; } else if (hostIds.size() == 1) { hardConstraint = true; for(Long id: hostIds) { hostID = id; } } else { throw new FailedToAllocate("SingleHostRW volume is used by mutiple hosts"); } if (hostID != null) { constraints.add(new VolumeAccessModeSingleHostConstraint(hostID, v.getId(), hardConstraint)); } } else if (VolumeConstants.ACCESS_MODE_SINGLE_INSTANCE_RW.equals(v.getAccessMode())) { List<Long> currentlyUsedBy = allocatorDao.getInstancesWithVolumeMounted(v.getId(), instance.getId()); if (currentlyUsedBy.size() > 0) { constraints.add(new VolumeAccessModeSingleInstanceConstraint(v.getId(), v.getAccessMode(), currentlyUsedBy)); } } } } } @Override public boolean isCritical() { return true; } }