internals_linux_test.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package dockerfile // import "github.com/docker/docker/builder/dockerfile"
  2. import (
  3. "os"
  4. "path/filepath"
  5. "testing"
  6. "github.com/docker/docker/api/types"
  7. "github.com/docker/docker/pkg/idtools"
  8. "gotest.tools/v3/assert"
  9. is "gotest.tools/v3/assert/cmp"
  10. )
  11. func TestChownFlagParsing(t *testing.T) {
  12. testFiles := map[string]string{
  13. "passwd": `root:x:0:0::/bin:/bin/false
  14. bin:x:1:1::/bin:/bin/false
  15. wwwwww:x:21:33::/bin:/bin/false
  16. unicorn:x:1001:1002::/bin:/bin/false
  17. `,
  18. "group": `root:x:0:
  19. bin:x:1:
  20. wwwwww:x:33:
  21. unicorn:x:1002:
  22. somegrp:x:5555:
  23. othergrp:x:6666:
  24. `,
  25. }
  26. // test mappings for validating use of maps
  27. idMaps := []idtools.IDMap{
  28. {
  29. ContainerID: 0,
  30. HostID: 100000,
  31. Size: 65536,
  32. },
  33. }
  34. remapped := idtools.IdentityMapping{UIDMaps: idMaps, GIDMaps: idMaps}
  35. unmapped := idtools.IdentityMapping{}
  36. contextDir, cleanup := createTestTempDir(t, "", "builder-chown-parse-test")
  37. defer cleanup()
  38. if err := os.Mkdir(filepath.Join(contextDir, "etc"), 0755); err != nil {
  39. t.Fatalf("error creating test directory: %v", err)
  40. }
  41. for filename, content := range testFiles {
  42. createTestTempFile(t, filepath.Join(contextDir, "etc"), filename, content, 0644)
  43. }
  44. // positive tests
  45. for _, testcase := range []struct {
  46. builder *Builder
  47. name string
  48. chownStr string
  49. idMapping idtools.IdentityMapping
  50. state *dispatchState
  51. expected idtools.Identity
  52. }{
  53. {
  54. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  55. name: "UIDNoMap",
  56. chownStr: "1",
  57. idMapping: unmapped,
  58. state: &dispatchState{},
  59. expected: idtools.Identity{UID: 1, GID: 1},
  60. },
  61. {
  62. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  63. name: "UIDGIDNoMap",
  64. chownStr: "0:1",
  65. idMapping: unmapped,
  66. state: &dispatchState{},
  67. expected: idtools.Identity{UID: 0, GID: 1},
  68. },
  69. {
  70. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  71. name: "UIDWithMap",
  72. chownStr: "0",
  73. idMapping: remapped,
  74. state: &dispatchState{},
  75. expected: idtools.Identity{UID: 100000, GID: 100000},
  76. },
  77. {
  78. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  79. name: "UIDGIDWithMap",
  80. chownStr: "1:33",
  81. idMapping: remapped,
  82. state: &dispatchState{},
  83. expected: idtools.Identity{UID: 100001, GID: 100033},
  84. },
  85. {
  86. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  87. name: "UserNoMap",
  88. chownStr: "bin:5555",
  89. idMapping: unmapped,
  90. state: &dispatchState{},
  91. expected: idtools.Identity{UID: 1, GID: 5555},
  92. },
  93. {
  94. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  95. name: "GroupWithMap",
  96. chownStr: "0:unicorn",
  97. idMapping: remapped,
  98. state: &dispatchState{},
  99. expected: idtools.Identity{UID: 100000, GID: 101002},
  100. },
  101. {
  102. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  103. name: "UserOnlyWithMap",
  104. chownStr: "unicorn",
  105. idMapping: remapped,
  106. state: &dispatchState{},
  107. expected: idtools.Identity{UID: 101001, GID: 101002},
  108. },
  109. } {
  110. t.Run(testcase.name, func(t *testing.T) {
  111. idPair, err := parseChownFlag(testcase.builder, testcase.state, testcase.chownStr, contextDir, testcase.idMapping)
  112. assert.NilError(t, err, "Failed to parse chown flag: %q", testcase.chownStr)
  113. assert.Check(t, is.DeepEqual(testcase.expected, idPair), "chown flag mapping failure")
  114. })
  115. }
  116. // error tests
  117. for _, testcase := range []struct {
  118. builder *Builder
  119. name string
  120. chownStr string
  121. idMapping idtools.IdentityMapping
  122. state *dispatchState
  123. descr string
  124. }{
  125. {
  126. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  127. name: "BadChownFlagFormat",
  128. chownStr: "bob:1:555",
  129. idMapping: unmapped,
  130. state: &dispatchState{},
  131. descr: "invalid chown string format: bob:1:555",
  132. },
  133. {
  134. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  135. name: "UserNoExist",
  136. chownStr: "bob",
  137. idMapping: unmapped,
  138. state: &dispatchState{},
  139. descr: "can't find uid for user bob: no such user: bob",
  140. },
  141. {
  142. builder: &Builder{options: &types.ImageBuildOptions{Platform: "linux"}},
  143. name: "GroupNoExist",
  144. chownStr: "root:bob",
  145. idMapping: unmapped,
  146. state: &dispatchState{},
  147. descr: "can't find gid for group bob: no such group: bob",
  148. },
  149. } {
  150. t.Run(testcase.name, func(t *testing.T) {
  151. _, err := parseChownFlag(testcase.builder, testcase.state, testcase.chownStr, contextDir, testcase.idMapping)
  152. assert.Check(t, is.Error(err, testcase.descr), "Expected error string doesn't match")
  153. })
  154. }
  155. }