github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/builder/dockerfile/buildargs.go (about) 1 package dockerfile 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/docker/docker/runconfig/opts" 8 ) 9 10 // builtinAllowedBuildArgs is list of built-in allowed build args 11 // these args are considered transparent and are excluded from the image history. 12 // Filtering from history is implemented in dispatchers.go 13 var builtinAllowedBuildArgs = map[string]bool{ 14 "HTTP_PROXY": true, 15 "http_proxy": true, 16 "HTTPS_PROXY": true, 17 "https_proxy": true, 18 "FTP_PROXY": true, 19 "ftp_proxy": true, 20 "NO_PROXY": true, 21 "no_proxy": true, 22 } 23 24 // buildArgs manages arguments used by the builder 25 type buildArgs struct { 26 // args that are allowed for expansion/substitution and passing to commands in 'run'. 27 allowedBuildArgs map[string]*string 28 // args defined before the first `FROM` in a Dockerfile 29 allowedMetaArgs map[string]*string 30 // args referenced by the Dockerfile 31 referencedArgs map[string]struct{} 32 // args provided by the user on the command line 33 argsFromOptions map[string]*string 34 } 35 36 func newBuildArgs(argsFromOptions map[string]*string) *buildArgs { 37 return &buildArgs{ 38 allowedBuildArgs: make(map[string]*string), 39 allowedMetaArgs: make(map[string]*string), 40 referencedArgs: make(map[string]struct{}), 41 argsFromOptions: argsFromOptions, 42 } 43 } 44 45 // WarnOnUnusedBuildArgs checks if there are any leftover build-args that were 46 // passed but not consumed during build. Print a warning, if there are any. 47 func (b *buildArgs) WarnOnUnusedBuildArgs(out io.Writer) { 48 leftoverArgs := []string{} 49 for arg := range b.argsFromOptions { 50 _, isReferenced := b.referencedArgs[arg] 51 _, isBuiltin := builtinAllowedBuildArgs[arg] 52 if !isBuiltin && !isReferenced { 53 leftoverArgs = append(leftoverArgs, arg) 54 } 55 } 56 if len(leftoverArgs) > 0 { 57 fmt.Fprintf(out, "[Warning] One or more build-args %v were not consumed\n", leftoverArgs) 58 } 59 } 60 61 // ResetAllowed clears the list of args that are allowed to be used by a 62 // directive 63 func (b *buildArgs) ResetAllowed() { 64 b.allowedBuildArgs = make(map[string]*string) 65 } 66 67 // AddMetaArg adds a new meta arg that can be used by FROM directives 68 func (b *buildArgs) AddMetaArg(key string, value *string) { 69 b.allowedMetaArgs[key] = value 70 } 71 72 // AddArg adds a new arg that can be used by directives 73 func (b *buildArgs) AddArg(key string, value *string) { 74 b.allowedBuildArgs[key] = value 75 b.referencedArgs[key] = struct{}{} 76 } 77 78 // IsReferencedOrNotBuiltin checks if the key is a built-in arg, or if it has been 79 // referenced by the Dockerfile. Returns true if the arg is not a builtin or 80 // if the builtin has been referenced in the Dockerfile. 81 func (b *buildArgs) IsReferencedOrNotBuiltin(key string) bool { 82 _, isBuiltin := builtinAllowedBuildArgs[key] 83 _, isAllowed := b.allowedBuildArgs[key] 84 return isAllowed || !isBuiltin 85 } 86 87 // GetAllAllowed returns a mapping with all the allowed args 88 func (b *buildArgs) GetAllAllowed() map[string]string { 89 return b.getAllFromMapping(b.allowedBuildArgs) 90 } 91 92 // GetAllMeta returns a mapping with all the meta meta args 93 func (b *buildArgs) GetAllMeta() map[string]string { 94 return b.getAllFromMapping(b.allowedMetaArgs) 95 } 96 97 func (b *buildArgs) getAllFromMapping(source map[string]*string) map[string]string { 98 m := make(map[string]string) 99 100 keys := keysFromMaps(source, builtinAllowedBuildArgs) 101 for _, key := range keys { 102 v, ok := b.getBuildArg(key, source) 103 if ok { 104 m[key] = v 105 } 106 } 107 return m 108 } 109 110 // FilterAllowed returns all allowed args without the filtered args 111 func (b *buildArgs) FilterAllowed(filter []string) []string { 112 envs := []string{} 113 configEnv := opts.ConvertKVStringsToMap(filter) 114 115 for key, val := range b.GetAllAllowed() { 116 if _, ok := configEnv[key]; !ok { 117 envs = append(envs, fmt.Sprintf("%s=%s", key, val)) 118 } 119 } 120 return envs 121 } 122 123 func (b *buildArgs) getBuildArg(key string, mapping map[string]*string) (string, bool) { 124 defaultValue, exists := mapping[key] 125 // Return override from options if one is defined 126 if v, ok := b.argsFromOptions[key]; ok && v != nil { 127 return *v, ok 128 } 129 130 if defaultValue == nil { 131 if v, ok := b.allowedMetaArgs[key]; ok && v != nil { 132 return *v, ok 133 } 134 return "", false 135 } 136 return *defaultValue, exists 137 } 138 139 func keysFromMaps(source map[string]*string, builtin map[string]bool) []string { 140 keys := []string{} 141 for key := range source { 142 keys = append(keys, key) 143 } 144 for key := range builtin { 145 keys = append(keys, key) 146 } 147 return keys 148 }