dotcloud/docker

View on GitHub
plugin/v2/settable.go

Summary

Maintainability
A
0 mins
Test Coverage
package v2 // import "github.com/docker/docker/plugin/v2"

import (
    "errors"
    "fmt"
    "strings"
)

type settable struct {
    name  string
    field string
    value string
}

var (
    allowedSettableFieldsEnv     = []string{"value"}
    allowedSettableFieldsArgs    = []string{"value"}
    allowedSettableFieldsDevices = []string{"path"}
    allowedSettableFieldsMounts  = []string{"source"}

    errMultipleFields = errors.New("multiple fields are settable, one must be specified")
    errInvalidFormat  = errors.New("invalid format, must be <name>[.<field>][=<value>]")
)

func newSettables(args []string) ([]settable, error) {
    sets := make([]settable, 0, len(args))
    for _, arg := range args {
        set, err := newSettable(arg)
        if err != nil {
            return nil, err
        }
        sets = append(sets, set)
    }
    return sets, nil
}

func newSettable(arg string) (settable, error) {
    var set settable
    if i := strings.Index(arg, "="); i == 0 {
        return set, errInvalidFormat
    } else if i < 0 {
        set.name = arg
    } else {
        set.name = arg[:i]
        set.value = arg[i+1:]
    }

    if i := strings.LastIndex(set.name, "."); i > 0 {
        set.field = set.name[i+1:]
        set.name = arg[:i]
    }

    return set, nil
}

// prettyName return name.field if there is a field, otherwise name.
func (set *settable) prettyName() string {
    if set.field != "" {
        return fmt.Sprintf("%s.%s", set.name, set.field)
    }
    return set.name
}

func (set *settable) isSettable(allowedSettableFields []string, settable []string) (bool, error) {
    if set.field == "" {
        if len(settable) == 1 {
            // if field is not specified and there only one settable, default to it.
            set.field = settable[0]
        } else if len(settable) > 1 {
            return false, errMultipleFields
        }
    }

    isAllowed := false
    for _, allowedSettableField := range allowedSettableFields {
        if set.field == allowedSettableField {
            isAllowed = true
            break
        }
    }

    if isAllowed {
        for _, settableField := range settable {
            if set.field == settableField {
                return true, nil
            }
        }
    }

    return false, nil
}

func updateSettingsEnv(env *[]string, set *settable) {
    for i, e := range *env {
        if name, _, _ := strings.Cut(e, "="); name == set.name {
            (*env)[i] = set.name + "=" + set.value
            return
        }
    }

    *env = append(*env, set.name+"="+set.value)
}