github.com/lazyboychen7/engine@v17.12.1-ce-rc2+incompatible/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 func (b *buildArgs) Clone() *buildArgs { 46 result := newBuildArgs(b.argsFromOptions) 47 for k, v := range b.allowedBuildArgs { 48 result.allowedBuildArgs[k] = v 49 } 50 for k, v := range b.allowedMetaArgs { 51 result.allowedMetaArgs[k] = v 52 } 53 for k := range b.referencedArgs { 54 result.referencedArgs[k] = struct{}{} 55 } 56 return result 57 } 58 59 func (b *buildArgs) MergeReferencedArgs(other *buildArgs) { 60 for k := range other.referencedArgs { 61 b.referencedArgs[k] = struct{}{} 62 } 63 } 64 65 // WarnOnUnusedBuildArgs checks if there are any leftover build-args that were 66 // passed but not consumed during build. Print a warning, if there are any. 67 func (b *buildArgs) WarnOnUnusedBuildArgs(out io.Writer) { 68 leftoverArgs := []string{} 69 for arg := range b.argsFromOptions { 70 _, isReferenced := b.referencedArgs[arg] 71 _, isBuiltin := builtinAllowedBuildArgs[arg] 72 if !isBuiltin && !isReferenced { 73 leftoverArgs = append(leftoverArgs, arg) 74 } 75 } 76 if len(leftoverArgs) > 0 { 77 fmt.Fprintf(out, "[Warning] One or more build-args %v were not consumed\n", leftoverArgs) 78 } 79 } 80 81 // ResetAllowed clears the list of args that are allowed to be used by a 82 // directive 83 func (b *buildArgs) ResetAllowed() { 84 b.allowedBuildArgs = make(map[string]*string) 85 } 86 87 // AddMetaArg adds a new meta arg that can be used by FROM directives 88 func (b *buildArgs) AddMetaArg(key string, value *string) { 89 b.allowedMetaArgs[key] = value 90 } 91 92 // AddArg adds a new arg that can be used by directives 93 func (b *buildArgs) AddArg(key string, value *string) { 94 b.allowedBuildArgs[key] = value 95 b.referencedArgs[key] = struct{}{} 96 } 97 98 // IsReferencedOrNotBuiltin checks if the key is a built-in arg, or if it has been 99 // referenced by the Dockerfile. Returns true if the arg is not a builtin or 100 // if the builtin has been referenced in the Dockerfile. 101 func (b *buildArgs) IsReferencedOrNotBuiltin(key string) bool { 102 _, isBuiltin := builtinAllowedBuildArgs[key] 103 _, isAllowed := b.allowedBuildArgs[key] 104 return isAllowed || !isBuiltin 105 } 106 107 // GetAllAllowed returns a mapping with all the allowed args 108 func (b *buildArgs) GetAllAllowed() map[string]string { 109 return b.getAllFromMapping(b.allowedBuildArgs) 110 } 111 112 // GetAllMeta returns a mapping with all the meta meta args 113 func (b *buildArgs) GetAllMeta() map[string]string { 114 return b.getAllFromMapping(b.allowedMetaArgs) 115 } 116 117 func (b *buildArgs) getAllFromMapping(source map[string]*string) map[string]string { 118 m := make(map[string]string) 119 120 keys := keysFromMaps(source, builtinAllowedBuildArgs) 121 for _, key := range keys { 122 v, ok := b.getBuildArg(key, source) 123 if ok { 124 m[key] = v 125 } 126 } 127 return m 128 } 129 130 // FilterAllowed returns all allowed args without the filtered args 131 func (b *buildArgs) FilterAllowed(filter []string) []string { 132 envs := []string{} 133 configEnv := opts.ConvertKVStringsToMap(filter) 134 135 for key, val := range b.GetAllAllowed() { 136 if _, ok := configEnv[key]; !ok { 137 envs = append(envs, fmt.Sprintf("%s=%s", key, val)) 138 } 139 } 140 return envs 141 } 142 143 func (b *buildArgs) getBuildArg(key string, mapping map[string]*string) (string, bool) { 144 defaultValue, exists := mapping[key] 145 // Return override from options if one is defined 146 if v, ok := b.argsFromOptions[key]; ok && v != nil { 147 return *v, ok 148 } 149 150 if defaultValue == nil { 151 if v, ok := b.allowedMetaArgs[key]; ok && v != nil { 152 return *v, ok 153 } 154 return "", false 155 } 156 return *defaultValue, exists 157 } 158 159 func keysFromMaps(source map[string]*string, builtin map[string]bool) []string { 160 keys := []string{} 161 for key := range source { 162 keys = append(keys, key) 163 } 164 for key := range builtin { 165 keys = append(keys, key) 166 } 167 return keys 168 }