github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/builder/dockerfile/buildargs.go (about) 1 package dockerfile // import "github.com/docker/docker/builder/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 "ALL_PROXY": true, 23 "all_proxy": true, 24 } 25 26 // BuildArgs manages arguments used by the builder 27 type BuildArgs struct { 28 // args that are allowed for expansion/substitution and passing to commands in 'run'. 29 allowedBuildArgs map[string]*string 30 // args defined before the first `FROM` in a Dockerfile 31 allowedMetaArgs map[string]*string 32 // args referenced by the Dockerfile 33 referencedArgs map[string]struct{} 34 // args provided by the user on the command line 35 argsFromOptions map[string]*string 36 } 37 38 // NewBuildArgs creates a new BuildArgs type 39 func NewBuildArgs(argsFromOptions map[string]*string) *BuildArgs { 40 return &BuildArgs{ 41 allowedBuildArgs: make(map[string]*string), 42 allowedMetaArgs: make(map[string]*string), 43 referencedArgs: make(map[string]struct{}), 44 argsFromOptions: argsFromOptions, 45 } 46 } 47 48 // Clone returns a copy of the BuildArgs type 49 func (b *BuildArgs) Clone() *BuildArgs { 50 result := NewBuildArgs(b.argsFromOptions) 51 for k, v := range b.allowedBuildArgs { 52 result.allowedBuildArgs[k] = v 53 } 54 for k, v := range b.allowedMetaArgs { 55 result.allowedMetaArgs[k] = v 56 } 57 for k := range b.referencedArgs { 58 result.referencedArgs[k] = struct{}{} 59 } 60 return result 61 } 62 63 // MergeReferencedArgs merges referenced args from another BuildArgs 64 // object into the current one 65 func (b *BuildArgs) MergeReferencedArgs(other *BuildArgs) { 66 for k := range other.referencedArgs { 67 b.referencedArgs[k] = struct{}{} 68 } 69 } 70 71 // WarnOnUnusedBuildArgs checks if there are any leftover build-args that were 72 // passed but not consumed during build. Print a warning, if there are any. 73 func (b *BuildArgs) WarnOnUnusedBuildArgs(out io.Writer) { 74 var leftoverArgs []string 75 for arg := range b.argsFromOptions { 76 _, isReferenced := b.referencedArgs[arg] 77 _, isBuiltin := builtinAllowedBuildArgs[arg] 78 if !isBuiltin && !isReferenced { 79 leftoverArgs = append(leftoverArgs, arg) 80 } 81 } 82 if len(leftoverArgs) > 0 { 83 fmt.Fprintf(out, "[Warning] One or more build-args %v were not consumed\n", leftoverArgs) 84 } 85 } 86 87 // ResetAllowed clears the list of args that are allowed to be used by a 88 // directive 89 func (b *BuildArgs) ResetAllowed() { 90 b.allowedBuildArgs = make(map[string]*string) 91 } 92 93 // AddMetaArg adds a new meta arg that can be used by FROM directives 94 func (b *BuildArgs) AddMetaArg(key string, value *string) { 95 b.allowedMetaArgs[key] = value 96 } 97 98 // AddArg adds a new arg that can be used by directives 99 func (b *BuildArgs) AddArg(key string, value *string) { 100 b.allowedBuildArgs[key] = value 101 b.referencedArgs[key] = struct{}{} 102 } 103 104 // IsReferencedOrNotBuiltin checks if the key is a built-in arg, or if it has been 105 // referenced by the Dockerfile. Returns true if the arg is not a builtin or 106 // if the builtin has been referenced in the Dockerfile. 107 func (b *BuildArgs) IsReferencedOrNotBuiltin(key string) bool { 108 _, isBuiltin := builtinAllowedBuildArgs[key] 109 _, isAllowed := b.allowedBuildArgs[key] 110 return isAllowed || !isBuiltin 111 } 112 113 // GetAllAllowed returns a mapping with all the allowed args 114 func (b *BuildArgs) GetAllAllowed() map[string]string { 115 return b.getAllFromMapping(b.allowedBuildArgs) 116 } 117 118 // GetAllMeta returns a mapping with all the meta args 119 func (b *BuildArgs) GetAllMeta() map[string]string { 120 return b.getAllFromMapping(b.allowedMetaArgs) 121 } 122 123 func (b *BuildArgs) getAllFromMapping(source map[string]*string) map[string]string { 124 m := make(map[string]string) 125 126 keys := keysFromMaps(source, builtinAllowedBuildArgs) 127 for _, key := range keys { 128 v, ok := b.getBuildArg(key, source) 129 if ok { 130 m[key] = v 131 } 132 } 133 return m 134 } 135 136 // FilterAllowed returns all allowed args without the filtered args 137 func (b *BuildArgs) FilterAllowed(filter []string) []string { 138 envs := []string{} 139 configEnv := opts.ConvertKVStringsToMap(filter) 140 141 for key, val := range b.GetAllAllowed() { 142 if _, ok := configEnv[key]; !ok { 143 envs = append(envs, fmt.Sprintf("%s=%s", key, val)) 144 } 145 } 146 return envs 147 } 148 149 func (b *BuildArgs) getBuildArg(key string, mapping map[string]*string) (string, bool) { 150 defaultValue, exists := mapping[key] 151 // Return override from options if one is defined 152 if v, ok := b.argsFromOptions[key]; ok && v != nil { 153 return *v, ok 154 } 155 156 if defaultValue == nil { 157 if v, ok := b.allowedMetaArgs[key]; ok && v != nil { 158 return *v, ok 159 } 160 return "", false 161 } 162 return *defaultValue, exists 163 } 164 165 func keysFromMaps(source map[string]*string, builtin map[string]bool) []string { 166 keys := []string{} 167 for key := range source { 168 keys = append(keys, key) 169 } 170 for key := range builtin { 171 keys = append(keys, key) 172 } 173 return keys 174 }