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