123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- package genericresource
- import (
- "encoding/csv"
- "fmt"
- "strconv"
- "strings"
- "github.com/docker/swarmkit/api"
- )
- func newParseError(format string, args ...interface{}) error {
- return fmt.Errorf("could not parse GenericResource: "+format, args...)
- }
- // discreteResourceVal returns an int64 if the string is a discreteResource
- // and an error if it isn't
- func discreteResourceVal(res string) (int64, error) {
- return strconv.ParseInt(res, 10, 64)
- }
- // allNamedResources returns true if the array of resources are all namedResources
- // e.g: res = [red, orange, green]
- func allNamedResources(res []string) bool {
- for _, v := range res {
- if _, err := discreteResourceVal(v); err == nil {
- return false
- }
- }
- return true
- }
- // ParseCmd parses the Generic Resource command line argument
- // and returns a list of *api.GenericResource
- func ParseCmd(cmd string) ([]*api.GenericResource, error) {
- if strings.Contains(cmd, "\n") {
- return nil, newParseError("unexpected '\\n' character")
- }
- r := csv.NewReader(strings.NewReader(cmd))
- records, err := r.ReadAll()
- if err != nil {
- return nil, newParseError("%v", err)
- }
- if len(records) != 1 {
- return nil, newParseError("found multiple records while parsing cmd %v", records)
- }
- return Parse(records[0])
- }
- // Parse parses a table of GenericResource resources
- func Parse(cmds []string) ([]*api.GenericResource, error) {
- tokens := make(map[string][]string)
- for _, term := range cmds {
- kva := strings.Split(term, "=")
- if len(kva) != 2 {
- return nil, newParseError("incorrect term %s, missing"+
- " '=' or malformed expression", term)
- }
- key := strings.TrimSpace(kva[0])
- val := strings.TrimSpace(kva[1])
- tokens[key] = append(tokens[key], val)
- }
- var rs []*api.GenericResource
- for k, v := range tokens {
- if u, ok := isDiscreteResource(v); ok {
- if u < 0 {
- return nil, newParseError("cannot ask for"+
- " negative resource %s", k)
- }
- rs = append(rs, NewDiscrete(k, u))
- continue
- }
- if allNamedResources(v) {
- rs = append(rs, NewSet(k, v...)...)
- continue
- }
- return nil, newParseError("mixed discrete and named resources"+
- " in expression '%s=%s'", k, v)
- }
- return rs, nil
- }
- // isDiscreteResource returns true if the array of resources is a
- // Discrete Resource.
- // e.g: res = [1]
- func isDiscreteResource(values []string) (int64, bool) {
- if len(values) != 1 {
- return int64(0), false
- }
- u, err := discreteResourceVal(values[0])
- if err != nil {
- return int64(0), false
- }
- return u, true
- }
|