buildargs.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package dockerfile
  2. import (
  3. "fmt"
  4. "github.com/docker/docker/runconfig/opts"
  5. )
  6. // builtinAllowedBuildArgs is list of built-in allowed build args
  7. // these args are considered transparent and are excluded from the image history.
  8. // Filtering from history is implemented in dispatchers.go
  9. var builtinAllowedBuildArgs = map[string]bool{
  10. "HTTP_PROXY": true,
  11. "http_proxy": true,
  12. "HTTPS_PROXY": true,
  13. "https_proxy": true,
  14. "FTP_PROXY": true,
  15. "ftp_proxy": true,
  16. "NO_PROXY": true,
  17. "no_proxy": true,
  18. }
  19. // buildArgs manages arguments used by the builder
  20. type buildArgs struct {
  21. // args that are allowed for expansion/substitution and passing to commands in 'run'.
  22. allowedBuildArgs map[string]*string
  23. // args defined before the first `FROM` in a Dockerfile
  24. allowedMetaArgs map[string]*string
  25. // args referenced by the Dockerfile
  26. referencedArgs map[string]struct{}
  27. // args provided by the user on the command line
  28. argsFromOptions map[string]*string
  29. }
  30. func newBuildArgs(argsFromOptions map[string]*string) *buildArgs {
  31. return &buildArgs{
  32. allowedBuildArgs: make(map[string]*string),
  33. allowedMetaArgs: make(map[string]*string),
  34. referencedArgs: make(map[string]struct{}),
  35. argsFromOptions: argsFromOptions,
  36. }
  37. }
  38. // UnreferencedOptionArgs returns the list of args that were set from options but
  39. // were never referenced from the Dockerfile
  40. func (b *buildArgs) UnreferencedOptionArgs() []string {
  41. leftoverArgs := []string{}
  42. for arg := range b.argsFromOptions {
  43. if _, ok := b.referencedArgs[arg]; !ok {
  44. leftoverArgs = append(leftoverArgs, arg)
  45. }
  46. }
  47. return leftoverArgs
  48. }
  49. // ResetAllowed clears the list of args that are allowed to be used by a
  50. // directive
  51. func (b *buildArgs) ResetAllowed() {
  52. b.allowedBuildArgs = make(map[string]*string)
  53. }
  54. // AddMetaArg adds a new meta arg that can be used by FROM directives
  55. func (b *buildArgs) AddMetaArg(key string, value *string) {
  56. b.allowedMetaArgs[key] = value
  57. }
  58. // AddArg adds a new arg that can be used by directives
  59. func (b *buildArgs) AddArg(key string, value *string) {
  60. b.allowedBuildArgs[key] = value
  61. b.referencedArgs[key] = struct{}{}
  62. }
  63. // IsUnreferencedBuiltin checks if the key is a built-in arg, or if it has been
  64. // referenced by the Dockerfile. Returns true if the arg is a builtin that has
  65. // not been referenced in the Dockerfile.
  66. func (b *buildArgs) IsUnreferencedBuiltin(key string) bool {
  67. _, isBuiltin := builtinAllowedBuildArgs[key]
  68. _, isAllowed := b.allowedBuildArgs[key]
  69. return isBuiltin && !isAllowed
  70. }
  71. // GetAllAllowed returns a mapping with all the allowed args
  72. func (b *buildArgs) GetAllAllowed() map[string]string {
  73. return b.getAllFromMapping(b.allowedBuildArgs)
  74. }
  75. // GetAllMeta returns a mapping with all the meta meta args
  76. func (b *buildArgs) GetAllMeta() map[string]string {
  77. return b.getAllFromMapping(b.allowedMetaArgs)
  78. }
  79. func (b *buildArgs) getAllFromMapping(source map[string]*string) map[string]string {
  80. m := make(map[string]string)
  81. keys := keysFromMaps(source, builtinAllowedBuildArgs)
  82. for _, key := range keys {
  83. v, ok := b.getBuildArg(key, source)
  84. if ok {
  85. m[key] = v
  86. }
  87. }
  88. return m
  89. }
  90. // FilterAllowed returns all allowed args without the filtered args
  91. func (b *buildArgs) FilterAllowed(filter []string) []string {
  92. envs := []string{}
  93. configEnv := opts.ConvertKVStringsToMap(filter)
  94. for key, val := range b.GetAllAllowed() {
  95. if _, ok := configEnv[key]; !ok {
  96. envs = append(envs, fmt.Sprintf("%s=%s", key, val))
  97. }
  98. }
  99. return envs
  100. }
  101. func (b *buildArgs) getBuildArg(key string, mapping map[string]*string) (string, bool) {
  102. defaultValue, exists := mapping[key]
  103. // Return override from options if one is defined
  104. if v, ok := b.argsFromOptions[key]; ok && v != nil {
  105. return *v, ok
  106. }
  107. if defaultValue == nil {
  108. if v, ok := b.allowedMetaArgs[key]; ok && v != nil {
  109. return *v, ok
  110. }
  111. return "", false
  112. }
  113. return *defaultValue, exists
  114. }
  115. func keysFromMaps(source map[string]*string, builtin map[string]bool) []string {
  116. keys := []string{}
  117. for key := range source {
  118. keys = append(keys, key)
  119. }
  120. for key := range builtin {
  121. keys = append(keys, key)
  122. }
  123. return keys
  124. }