123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- package dockerfile // import "github.com/docker/docker/builder/dockerfile"
- import (
- "fmt"
- "io"
- "sort"
- "github.com/docker/docker/runconfig/opts"
- )
- // 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,
- "ALL_PROXY": true,
- "all_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
- }
- // NewBuildArgs creates a new BuildArgs type
- 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,
- }
- }
- // Clone returns a copy of the BuildArgs type
- func (b *BuildArgs) Clone() *BuildArgs {
- result := NewBuildArgs(b.argsFromOptions)
- for k, v := range b.allowedBuildArgs {
- result.allowedBuildArgs[k] = v
- }
- for k, v := range b.allowedMetaArgs {
- result.allowedMetaArgs[k] = v
- }
- for k := range b.referencedArgs {
- result.referencedArgs[k] = struct{}{}
- }
- return result
- }
- // MergeReferencedArgs merges referenced args from another BuildArgs
- // object into the current one
- func (b *BuildArgs) MergeReferencedArgs(other *BuildArgs) {
- for k := range other.referencedArgs {
- b.referencedArgs[k] = struct{}{}
- }
- }
- // WarnOnUnusedBuildArgs checks if there are any leftover build-args that were
- // passed but not consumed during build. Print a warning, if there are any.
- func (b *BuildArgs) WarnOnUnusedBuildArgs(out io.Writer) {
- var leftoverArgs []string
- for arg := range b.argsFromOptions {
- _, isReferenced := b.referencedArgs[arg]
- _, isBuiltin := builtinAllowedBuildArgs[arg]
- if !isBuiltin && !isReferenced {
- leftoverArgs = append(leftoverArgs, arg)
- }
- }
- if len(leftoverArgs) > 0 {
- sort.Strings(leftoverArgs)
- fmt.Fprintf(out, "[Warning] One or more build-args %v were not consumed\n", 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{}{}
- }
- // IsReferencedOrNotBuiltin checks if the key is a built-in arg, or if it has been
- // referenced by the Dockerfile. Returns true if the arg is not a builtin or
- // if the builtin has been referenced in the Dockerfile.
- func (b *BuildArgs) IsReferencedOrNotBuiltin(key string) bool {
- _, isBuiltin := builtinAllowedBuildArgs[key]
- _, isAllowed := b.allowedBuildArgs[key]
- return isAllowed || !isBuiltin
- }
- // 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 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
- }
- // FilterAllowed returns all allowed args without the filtered args
- func (b *BuildArgs) FilterAllowed(filter []string) []string {
- envs := []string{}
- configEnv := opts.ConvertKVStringsToMap(filter)
- for key, val := range b.GetAllAllowed() {
- if _, ok := configEnv[key]; !ok {
- envs = append(envs, fmt.Sprintf("%s=%s", key, val))
- }
- }
- return envs
- }
- 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
- }
|