package io.cattle.platform.process.instance; import static io.cattle.platform.core.model.tables.VolumeTable.*; import io.cattle.platform.allocator.constraint.HostAffinityConstraint; import io.cattle.platform.core.constants.InstanceConstants; import io.cattle.platform.core.constants.VolumeConstants; import io.cattle.platform.core.dao.StoragePoolDao; import io.cattle.platform.core.model.Instance; import io.cattle.platform.core.model.StoragePool; import io.cattle.platform.core.model.Volume; import io.cattle.platform.core.util.InstanceHelpers; import io.cattle.platform.engine.handler.HandlerResult; import io.cattle.platform.engine.handler.ProcessPreListener; import io.cattle.platform.engine.process.ProcessInstance; import io.cattle.platform.engine.process.ProcessState; import io.cattle.platform.lock.LockCallbackNoReturn; import io.cattle.platform.lock.LockManager; import io.cattle.platform.object.util.DataAccessor; import io.cattle.platform.process.common.handler.AbstractObjectProcessLogic; import io.cattle.platform.process.lock.InstanceVolumeAccessModeLock; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.lang3.StringUtils; @Named public class InstancePreStart extends AbstractObjectProcessLogic implements ProcessPreListener { @Inject LockManager lockManager; @Inject StoragePoolDao storagePoolDao; @Override public HandlerResult handle(ProcessState state, ProcessInstance process) { final Instance instance = (Instance)state.getResource(); Map<String, Object> labels = DataAccessor.fieldMap(instance, InstanceConstants.FIELD_LABELS); 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)) { List<? extends StoragePool> pools = storagePoolDao.findStoragePoolByDriverName(v.getAccountId(), driver); if (pools.size() == 0) { continue; } StoragePool sp = pools.get(0); 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); } }); } } Map<String, Object> driver_opts = DataAccessor.fieldMap(v, VolumeConstants.FIELD_VOLUME_DRIVER_OPTS); if (driver_opts.containsKey(VolumeConstants.EC2_AZ)) { String zone = driver_opts.get(VolumeConstants.EC2_AZ).toString(); labels.put(HostAffinityConstraint.LABEL_HEADER_AFFINITY_HOST_LABEL, String.format("%s=%s", VolumeConstants.HOST_ZONE_LABEL_KEY, zone)); objectManager.setFields(instance, InstanceConstants.FIELD_LABELS, labels); } } return null; } @Override public String[] getProcessNames() { return new String[] { "instance.start" }; } }