github.com/pwn-term/docker@v0.0.0-20210616085119-6e977cce2565/cli/opts/parse.go (about)

     1  package opts
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/docker/docker/api/types/container"
    10  )
    11  
    12  // ReadKVStrings reads a file of line terminated key=value pairs, and overrides any keys
    13  // present in the file with additional pairs specified in the override parameter
    14  func ReadKVStrings(files []string, override []string) ([]string, error) {
    15  	return readKVStrings(files, override, nil)
    16  }
    17  
    18  // ReadKVEnvStrings reads a file of line terminated key=value pairs, and overrides any keys
    19  // present in the file with additional pairs specified in the override parameter.
    20  // If a key has no value, it will get the value from the environment.
    21  func ReadKVEnvStrings(files []string, override []string) ([]string, error) {
    22  	return readKVStrings(files, override, os.LookupEnv)
    23  }
    24  
    25  func readKVStrings(files []string, override []string, emptyFn func(string) (string, bool)) ([]string, error) {
    26  	var variables []string
    27  	for _, ef := range files {
    28  		parsedVars, err := parseKeyValueFile(ef, emptyFn)
    29  		if err != nil {
    30  			return nil, err
    31  		}
    32  		variables = append(variables, parsedVars...)
    33  	}
    34  	// parse the '-e' and '--env' after, to allow override
    35  	variables = append(variables, override...)
    36  
    37  	return variables, nil
    38  }
    39  
    40  // ConvertKVStringsToMap converts ["key=value"] to {"key":"value"}
    41  func ConvertKVStringsToMap(values []string) map[string]string {
    42  	result := make(map[string]string, len(values))
    43  	for _, value := range values {
    44  		kv := strings.SplitN(value, "=", 2)
    45  		if len(kv) == 1 {
    46  			result[kv[0]] = ""
    47  		} else {
    48  			result[kv[0]] = kv[1]
    49  		}
    50  	}
    51  
    52  	return result
    53  }
    54  
    55  // ConvertKVStringsToMapWithNil converts ["key=value"] to {"key":"value"}
    56  // but set unset keys to nil - meaning the ones with no "=" in them.
    57  // We use this in cases where we need to distinguish between
    58  //   FOO=  and FOO
    59  // where the latter case just means FOO was mentioned but not given a value
    60  func ConvertKVStringsToMapWithNil(values []string) map[string]*string {
    61  	result := make(map[string]*string, len(values))
    62  	for _, value := range values {
    63  		kv := strings.SplitN(value, "=", 2)
    64  		if len(kv) == 1 {
    65  			result[kv[0]] = nil
    66  		} else {
    67  			result[kv[0]] = &kv[1]
    68  		}
    69  	}
    70  
    71  	return result
    72  }
    73  
    74  // ParseRestartPolicy returns the parsed policy or an error indicating what is incorrect
    75  func ParseRestartPolicy(policy string) (container.RestartPolicy, error) {
    76  	p := container.RestartPolicy{}
    77  
    78  	if policy == "" {
    79  		return p, nil
    80  	}
    81  
    82  	parts := strings.Split(policy, ":")
    83  
    84  	if len(parts) > 2 {
    85  		return p, fmt.Errorf("invalid restart policy format")
    86  	}
    87  	if len(parts) == 2 {
    88  		count, err := strconv.Atoi(parts[1])
    89  		if err != nil {
    90  			return p, fmt.Errorf("maximum retry count must be an integer")
    91  		}
    92  
    93  		p.MaximumRetryCount = count
    94  	}
    95  
    96  	p.Name = parts[0]
    97  
    98  	return p, nil
    99  }