github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/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  //
    59  //	FOO=  and FOO
    60  //
    61  // where the latter case just means FOO was mentioned but not given a value
    62  func ConvertKVStringsToMapWithNil(values []string) map[string]*string {
    63  	result := make(map[string]*string, len(values))
    64  	for _, value := range values {
    65  		kv := strings.SplitN(value, "=", 2)
    66  		if len(kv) == 1 {
    67  			result[kv[0]] = nil
    68  		} else {
    69  			result[kv[0]] = &kv[1]
    70  		}
    71  	}
    72  
    73  	return result
    74  }
    75  
    76  // ParseRestartPolicy returns the parsed policy or an error indicating what is incorrect
    77  func ParseRestartPolicy(policy string) (container.RestartPolicy, error) {
    78  	p := container.RestartPolicy{}
    79  
    80  	if policy == "" {
    81  		return p, nil
    82  	}
    83  
    84  	parts := strings.Split(policy, ":")
    85  
    86  	if len(parts) > 2 {
    87  		return p, fmt.Errorf("invalid restart policy format")
    88  	}
    89  	if len(parts) == 2 {
    90  		count, err := strconv.Atoi(parts[1])
    91  		if err != nil {
    92  			return p, fmt.Errorf("maximum retry count must be an integer")
    93  		}
    94  
    95  		p.MaximumRetryCount = count
    96  	}
    97  
    98  	p.Name = parts[0]
    99  
   100  	return p, nil
   101  }