From 28744d5936445992f49de8e15c0c9a93083129a1 Mon Sep 17 00:00:00 2001 From: wuqixuan Date: Mon, 6 Jul 2015 16:52:12 +0800 Subject: [PATCH 1/2] fleetd: support operators in metadata If define metadata in fleet conf, such as "ram=1024", we can define the operator in [X-Fleet] unit as below: [X-Fleet] MachineMetadata=ram>=2048 The operators have been supported: "<=", ">=", "!=", "<", ">", "=" If the operatior are "<=", ">=", "!=", "<", ">", the value should be integer, otherwise, the unit will never be launched. Fixes #1143 --- job/job.go | 12 ++++++- machine/machine.go | 80 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/job/job.go b/job/job.go index b0a04009d..10f0387ae 100644 --- a/job/job.go +++ b/job/job.go @@ -260,7 +260,17 @@ func (j *Job) RequiredTargetMetadata() map[string]pkg.Set { fleetMachineMetadata, } { for _, valuePair := range j.requirements()[key] { - s := strings.Split(valuePair, "=") + var s []string + for _, sep := range []string{"<=", ">=", "!=", "<", ">"} { + index := strings.Index(valuePair, sep) + if index != -1 { + s = []string{valuePair[0:index], valuePair[index:]} + break + } + } + if s == nil { + s = strings.Split(valuePair, "=") + } if len(s) != 2 { continue diff --git a/machine/machine.go b/machine/machine.go index 8be43d5a1..fc67c9a95 100644 --- a/machine/machine.go +++ b/machine/machine.go @@ -15,6 +15,9 @@ package machine import ( + "strconv" + "strings" + "github.com/coreos/fleet/log" "github.com/coreos/fleet/pkg" ) @@ -38,8 +41,81 @@ func HasMetadata(state *MachineState, metadata map[string]pkg.Set) bool { if values.Contains(local) { log.Debugf("Local Metadata(%s) meets requirement", key) } else { - log.Debugf("Local Metadata(%s) does not match requirement", key) - return false + vs := values.Values() + for _, v := range vs { + if index := strings.Index(v, "<="); strings.Contains(v, "<=") && (index == 0) { + need, err1 := strconv.Atoi(v[2:]) + have, err2 := strconv.Atoi(local) + if err1 == nil && err2 == nil { + if have <= need { + log.Debugf("Local Metadata(%s) meets requirement", key) + continue + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } else if index := strings.Index(v, ">="); strings.Contains(v, ">=") && (index == 0) { + need, err1 := strconv.Atoi(v[2:]) + have, err2 := strconv.Atoi(local) + if err1 == nil && err2 == nil { + if have >= need { + log.Debugf("Local Metadata(%s) meets requirement", key) + continue + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } else if index := strings.Index(v, ">"); strings.Contains(v, ">") && (index == 0) { + need, err1 := strconv.Atoi(v[1:]) + have, err2 := strconv.Atoi(local) + if err1 == nil && err2 == nil { + if have > need { + log.Debugf("Local Metadata(%s) meets requirement", key) + continue + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } else if index := strings.Index(v, "<"); strings.Contains(v, "<") && (index == 0) { + need, err1 := strconv.Atoi(v[1:]) + have, err2 := strconv.Atoi(local) + if err1 == nil && err2 == nil { + if have < need { + log.Debugf("Local Metadata(%s) meets requirement", key) + continue + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } else if index := strings.Index(v, "!="); strings.Contains(v, "!=") && (index == 0) { + if v[2:] != local { + log.Debugf("Local Metadata(%s) meets requirement", key) + continue + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } else { + log.Debugf("Local Metadata(%s) does not match requirement", key) + return false + } + } } } From 6f47df3e64555775644bc2803677b0e24dd7f61f Mon Sep 17 00:00:00 2001 From: wuqixuan Date: Tue, 7 Jul 2015 16:44:39 +0800 Subject: [PATCH 2/2] fleetd: support operators in metadata Update documentation. Fixes #1143 --- Documentation/unit-files-and-scheduling.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/unit-files-and-scheduling.md b/Documentation/unit-files-and-scheduling.md index c181643e2..9b2c7437b 100644 --- a/Documentation/unit-files-and-scheduling.md +++ b/Documentation/unit-files-and-scheduling.md @@ -125,6 +125,14 @@ MachineMetadata=region=us-west-1 This would allow a machine to match just one of the provided values to be considered eligible to run. +`MachineMetadata` also support relational operators, including `<=`, `>=`, `<`, `>` and `!=`: + +``` +[X-Fleet] +MachineMetadata=ram<1024 +``` +This requires an eligible machine to have the `ram` less than 1024. The value must be numeral when using `<=`, `>=`, `<` or `>`. + A machine is not automatically configured with metadata. A deployer may define machine metadata using the `metadata` [config option](https://github.com/coreos/fleet/blob/master/Documentation/deployment-and-configuration.md#metadata).