forked from LaconicNetwork/kompose
Add support for placement preferences docker-compose v3.3+ (#1425)
This commit is contained in:
@@ -595,6 +595,11 @@ func TestCheckPlacementCustomLabels(t *testing.T) {
|
||||
"node.labels.something == anything",
|
||||
"node.labels.monitor != xxx",
|
||||
},
|
||||
Preferences: []types.PlacementPreferences{
|
||||
{Spread: "node.labels.zone"},
|
||||
{Spread: "foo"},
|
||||
{Spread: "node.labels.ssd"},
|
||||
},
|
||||
}
|
||||
output := loadV3Placement(placement)
|
||||
|
||||
@@ -605,10 +610,22 @@ func TestCheckPlacementCustomLabels(t *testing.T) {
|
||||
NegativeConstraints: map[string]string{
|
||||
"monitor": "xxx",
|
||||
},
|
||||
Preferences: []string{
|
||||
"zone", "ssd",
|
||||
},
|
||||
}
|
||||
|
||||
checkConstraints(t, "positive", output.PositiveConstraints, expected.PositiveConstraints)
|
||||
checkConstraints(t, "negative", output.NegativeConstraints, expected.NegativeConstraints)
|
||||
|
||||
if len(output.Preferences) != len(expected.Preferences) {
|
||||
t.Errorf("preferences len is not equal, expected %d, got %d", len(expected.Preferences), len(output.Preferences))
|
||||
}
|
||||
for i := range output.Preferences {
|
||||
if output.Preferences[i] != expected.Preferences[i] {
|
||||
t.Errorf("preference is not equal, expected %s, got %s", expected.Preferences[i], output.Preferences[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkConstraints(t *testing.T, caseName string, output, expected map[string]string) {
|
||||
|
||||
+34
-11
@@ -137,9 +137,11 @@ func loadV3Placement(placement types.Placement) kobject.Placement {
|
||||
komposePlacement := kobject.Placement{
|
||||
PositiveConstraints: make(map[string]string),
|
||||
NegativeConstraints: make(map[string]string),
|
||||
Preferences: make([]string, 0, len(placement.Preferences)),
|
||||
}
|
||||
|
||||
// Convert constraints
|
||||
equal, notEqual := " == ", " != "
|
||||
errMsg := " constraints in placement is not supported, only 'node.hostname', 'engine.labels.operatingsystem' and 'node.labels.xxx' (ex: node.labels.something == anything) is supported as a constraint "
|
||||
for _, j := range placement.Constraints {
|
||||
operator := equal
|
||||
if strings.Contains(j, notEqual) {
|
||||
@@ -147,19 +149,13 @@ func loadV3Placement(placement types.Placement) kobject.Placement {
|
||||
}
|
||||
p := strings.Split(j, operator)
|
||||
if len(p) < 2 {
|
||||
log.Warn(p[0], errMsg)
|
||||
log.Warnf("Failed to parse placement constraints %s, the correct format is 'label == xxx'", j)
|
||||
continue
|
||||
}
|
||||
|
||||
var key string
|
||||
if p[0] == "node.hostname" {
|
||||
key = "kubernetes.io/hostname"
|
||||
} else if p[0] == "engine.labels.operatingsystem" {
|
||||
key = "beta.kubernetes.io/os"
|
||||
} else if strings.HasPrefix(p[0], "node.labels.") {
|
||||
key = strings.TrimPrefix(p[0], "node.labels.")
|
||||
} else {
|
||||
log.Warn(p[0], errMsg)
|
||||
key, err := convertDockerLabel(p[0])
|
||||
if err != nil {
|
||||
log.Warn("Ignore placement constraints: ", err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -169,9 +165,36 @@ func loadV3Placement(placement types.Placement) kobject.Placement {
|
||||
komposePlacement.NegativeConstraints[key] = p[1]
|
||||
}
|
||||
}
|
||||
|
||||
// Convert preferences
|
||||
for _, p := range placement.Preferences {
|
||||
// Spread is the only supported strategy currently
|
||||
label, err := convertDockerLabel(p.Spread)
|
||||
if err != nil {
|
||||
log.Warn("Ignore placement preferences: ", err.Error())
|
||||
continue
|
||||
}
|
||||
komposePlacement.Preferences = append(komposePlacement.Preferences, label)
|
||||
}
|
||||
return komposePlacement
|
||||
}
|
||||
|
||||
// Convert docker label to k8s label
|
||||
func convertDockerLabel(dockerLabel string) (string, error) {
|
||||
switch dockerLabel {
|
||||
case "node.hostname":
|
||||
return "kubernetes.io/hostname", nil
|
||||
case "engine.labels.operatingsystem":
|
||||
return "kubernetes.io/os", nil
|
||||
default:
|
||||
if strings.HasPrefix(dockerLabel, "node.labels.") {
|
||||
return strings.TrimPrefix(dockerLabel, "node.labels."), nil
|
||||
}
|
||||
}
|
||||
errMsg := fmt.Sprint(dockerLabel, " is not supported, only 'node.hostname', 'engine.labels.operatingsystem' and 'node.labels.xxx' (ex: node.labels.something == anything) is supported")
|
||||
return "", errors.New(errMsg)
|
||||
}
|
||||
|
||||
// Convert the Docker Compose v3 volumes to []string (the old way)
|
||||
// TODO: Check to see if it's a "bind" or "volume". Ignore for now.
|
||||
// TODO: Refactor it similar to loadV3Ports
|
||||
|
||||
Reference in New Issue
Block a user