internals_linux_test.go 4.7 KB

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