package io.cattle.platform.allocator.constraint;
import io.cattle.platform.allocator.constraint.AffinityConstraintDefinition.AffinityOps;
import io.cattle.platform.allocator.dao.AllocatorDao;
import io.cattle.platform.allocator.service.AllocationCandidate;
public class ContainerLabelAffinityConstraint implements Constraint {
public static final String ENV_HEADER_AFFINITY_CONTAINER_LABEL = "affinity:";
public static final String LABEL_HEADER_AFFINITY_CONTAINER_LABEL = "io.rancher.scheduler.affinity:container_label";
AllocatorDao allocatorDao;
AffinityOps op;
String labelKey;
String labelValue;
public ContainerLabelAffinityConstraint(AffinityConstraintDefinition def, AllocatorDao allocatorDao) {
this.op = def.op;
this.labelKey = def.key;
this.labelValue = def.value;
this.allocatorDao = allocatorDao;
}
// If necessary we can do additional optimizations to allow multiple container label or host label
// affinity constraints to share results from DB queries
@Override
public boolean matches(AllocationCandidate candidate) {
if (candidate.getHost() == null) {
return false;
}
if (op == AffinityOps.SOFT_EQ || op == AffinityOps.EQ) {
return allocatorDao.hostHasContainerLabel(candidate.getHost(), labelKey, labelValue);
} else {
// Anti-affinity
return !allocatorDao.hostHasContainerLabel(candidate.getHost(), labelKey, labelValue);
}
}
@Override
public boolean isHardConstraint() {
return (op == AffinityOps.EQ || op == AffinityOps.NE);
}
@Override
public String toString() {
String hard = AffinityOps.EQ.equals(op) || AffinityOps.NE.equals(op) ? "must" : "should";
String with = AffinityOps.EQ.equals(op) || AffinityOps.SOFT_EQ.equals(op) ? "have" : "not have";
return String.format("host %s %s a container with label %s=%s", hard, with, labelKey, labelValue);
}
}