| package dockerfile |
| |
| // builtinAllowedBuildArgs is list of built-in allowed build args |
| // these args are considered transparent and are excluded from the image history. |
| // Filtering from history is implemented in dispatchers.go |
| var builtinAllowedBuildArgs = map[string]bool{ |
| "HTTP_PROXY": true, |
| "http_proxy": true, |
| "HTTPS_PROXY": true, |
| "https_proxy": true, |
| "FTP_PROXY": true, |
| "ftp_proxy": true, |
| "NO_PROXY": true, |
| "no_proxy": true, |
| } |
| |
| // buildArgs manages arguments used by the builder |
| type buildArgs struct { |
| // args that are allowed for expansion/substitution and passing to commands in 'run'. |
| allowedBuildArgs map[string]*string |
| // args defined before the first `FROM` in a Dockerfile |
| allowedMetaArgs map[string]*string |
| // args referenced by the Dockerfile |
| referencedArgs map[string]struct{} |
| // args provided by the user on the command line |
| argsFromOptions map[string]*string |
| } |
| |
| func newBuildArgs(argsFromOptions map[string]*string) *buildArgs { |
| return &buildArgs{ |
| allowedBuildArgs: make(map[string]*string), |
| allowedMetaArgs: make(map[string]*string), |
| referencedArgs: make(map[string]struct{}), |
| argsFromOptions: argsFromOptions, |
| } |
| } |
| |
| // UnreferencedOptionArgs returns the list of args that were set from options but |
| // were never referenced from the Dockerfile |
| func (b *buildArgs) UnreferencedOptionArgs() []string { |
| leftoverArgs := []string{} |
| for arg := range b.argsFromOptions { |
| if _, ok := b.referencedArgs[arg]; !ok { |
| leftoverArgs = append(leftoverArgs, arg) |
| } |
| } |
| return leftoverArgs |
| } |
| |
| // ResetAllowed clears the list of args that are allowed to be used by a |
| // directive |
| func (b *buildArgs) ResetAllowed() { |
| b.allowedBuildArgs = make(map[string]*string) |
| } |
| |
| // AddMetaArg adds a new meta arg that can be used by FROM directives |
| func (b *buildArgs) AddMetaArg(key string, value *string) { |
| b.allowedMetaArgs[key] = value |
| } |
| |
| // AddArg adds a new arg that can be used by directives |
| func (b *buildArgs) AddArg(key string, value *string) { |
| b.allowedBuildArgs[key] = value |
| b.referencedArgs[key] = struct{}{} |
| } |
| |
| // IsUnreferencedBuiltin checks if the key is a built-in arg, or if it has been |
| // referenced by the Dockerfile. Returns true if the arg is a builtin that has |
| // not been referenced in the Dockerfile. |
| func (b *buildArgs) IsUnreferencedBuiltin(key string) bool { |
| _, isBuiltin := builtinAllowedBuildArgs[key] |
| _, isAllowed := b.allowedBuildArgs[key] |
| return isBuiltin && !isAllowed |
| } |
| |
| // GetAllAllowed returns a mapping with all the allowed args |
| func (b *buildArgs) GetAllAllowed() map[string]string { |
| return b.getAllFromMapping(b.allowedBuildArgs) |
| } |
| |
| // GetAllMeta returns a mapping with all the meta meta args |
| func (b *buildArgs) GetAllMeta() map[string]string { |
| return b.getAllFromMapping(b.allowedMetaArgs) |
| } |
| |
| func (b *buildArgs) getAllFromMapping(source map[string]*string) map[string]string { |
| m := make(map[string]string) |
| |
| keys := keysFromMaps(source, builtinAllowedBuildArgs) |
| for _, key := range keys { |
| v, ok := b.getBuildArg(key, source) |
| if ok { |
| m[key] = v |
| } |
| } |
| return m |
| } |
| |
| func (b *buildArgs) getBuildArg(key string, mapping map[string]*string) (string, bool) { |
| defaultValue, exists := mapping[key] |
| // Return override from options if one is defined |
| if v, ok := b.argsFromOptions[key]; ok && v != nil { |
| return *v, ok |
| } |
| |
| if defaultValue == nil { |
| if v, ok := b.allowedMetaArgs[key]; ok && v != nil { |
| return *v, ok |
| } |
| return "", false |
| } |
| return *defaultValue, exists |
| } |
| |
| func keysFromMaps(source map[string]*string, builtin map[string]bool) []string { |
| keys := []string{} |
| for key := range source { |
| keys = append(keys, key) |
| } |
| for key := range builtin { |
| keys = append(keys, key) |
| } |
| return keys |
| } |