docker_cli_build_test.go 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566
  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "os/exec"
  6. "path/filepath"
  7. "strings"
  8. "testing"
  9. "time"
  10. "github.com/dotcloud/docker/archive"
  11. )
  12. func TestBuildCacheADD(t *testing.T) {
  13. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildCacheADD", "1")
  14. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcacheadd1", ".")
  15. buildCmd.Dir = buildDirectory
  16. exitCode, err := runCommand(buildCmd)
  17. errorOut(err, t, fmt.Sprintf("build failed to complete: %v", err))
  18. if err != nil || exitCode != 0 {
  19. t.Fatal("failed to build the image")
  20. }
  21. buildDirectory = filepath.Join(workingDirectory, "build_tests", "TestBuildCacheADD", "2")
  22. buildCmd = exec.Command(dockerBinary, "build", "-t", "testcacheadd2", ".")
  23. buildCmd.Dir = buildDirectory
  24. out, exitCode, err := runCommandWithOutput(buildCmd)
  25. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  26. if err != nil || exitCode != 0 {
  27. t.Fatal("failed to build the image")
  28. }
  29. if strings.Contains(out, "Using cache") {
  30. t.Fatal("2nd build used cache on ADD, it shouldn't")
  31. }
  32. deleteImages("testcacheadd1")
  33. deleteImages("testcacheadd2")
  34. logDone("build - build two images with ADD")
  35. }
  36. func TestBuildSixtySteps(t *testing.T) {
  37. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildSixtySteps")
  38. buildCmd := exec.Command(dockerBinary, "build", "-t", "foobuildsixtysteps", ".")
  39. buildCmd.Dir = buildDirectory
  40. out, exitCode, err := runCommandWithOutput(buildCmd)
  41. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  42. if err != nil || exitCode != 0 {
  43. t.Fatal("failed to build the image")
  44. }
  45. deleteImages("foobuildsixtysteps")
  46. logDone("build - build an image with sixty build steps")
  47. }
  48. func TestAddSingleFileToRoot(t *testing.T) {
  49. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd", "SingleFileToRoot")
  50. f, err := os.OpenFile(filepath.Join(buildDirectory, "test_file"), os.O_CREATE, 0644)
  51. if err != nil {
  52. t.Fatal(err)
  53. }
  54. f.Close()
  55. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", ".")
  56. buildCmd.Dir = buildDirectory
  57. out, exitCode, err := runCommandWithOutput(buildCmd)
  58. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  59. if err != nil || exitCode != 0 {
  60. t.Fatal("failed to build the image")
  61. }
  62. deleteImages("testaddimg")
  63. logDone("build - add single file to root")
  64. }
  65. // Issue #3960: "ADD src ." hangs
  66. func TestAddSingleFileToWorkdir(t *testing.T) {
  67. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd", "SingleFileToWorkdir")
  68. f, err := os.OpenFile(filepath.Join(buildDirectory, "test_file"), os.O_CREATE, 0644)
  69. if err != nil {
  70. t.Fatal(err)
  71. }
  72. f.Close()
  73. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", ".")
  74. buildCmd.Dir = buildDirectory
  75. done := make(chan error)
  76. go func() {
  77. out, exitCode, err := runCommandWithOutput(buildCmd)
  78. if err != nil || exitCode != 0 {
  79. done <- fmt.Errorf("build failed to complete: %s %v", out, err)
  80. return
  81. }
  82. done <- nil
  83. }()
  84. select {
  85. case <-time.After(5 * time.Second):
  86. if err := buildCmd.Process.Kill(); err != nil {
  87. fmt.Printf("could not kill build (pid=%d): %v\n", buildCmd.Process.Pid, err)
  88. }
  89. t.Fatal("build timed out")
  90. case err := <-done:
  91. if err != nil {
  92. t.Fatal(err)
  93. }
  94. }
  95. deleteImages("testaddimg")
  96. logDone("build - add single file to workdir")
  97. }
  98. func TestAddSingleFileToExistDir(t *testing.T) {
  99. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  100. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "SingleFileToExistDir")
  101. buildCmd.Dir = buildDirectory
  102. out, exitCode, err := runCommandWithOutput(buildCmd)
  103. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  104. if err != nil || exitCode != 0 {
  105. t.Fatal("failed to build the image")
  106. }
  107. deleteImages("testaddimg")
  108. logDone("build - add single file to existing dir")
  109. }
  110. func TestAddSingleFileToNonExistDir(t *testing.T) {
  111. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  112. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "SingleFileToNonExistDir")
  113. buildCmd.Dir = buildDirectory
  114. out, exitCode, err := runCommandWithOutput(buildCmd)
  115. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  116. if err != nil || exitCode != 0 {
  117. t.Fatal("failed to build the image")
  118. }
  119. deleteImages("testaddimg")
  120. logDone("build - add single file to non-existing dir")
  121. }
  122. func TestAddDirContentToRoot(t *testing.T) {
  123. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  124. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "DirContentToRoot")
  125. buildCmd.Dir = buildDirectory
  126. out, exitCode, err := runCommandWithOutput(buildCmd)
  127. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  128. if err != nil || exitCode != 0 {
  129. t.Fatal("failed to build the image")
  130. }
  131. deleteImages("testaddimg")
  132. logDone("build - add directory contents to root")
  133. }
  134. func TestAddDirContentToExistDir(t *testing.T) {
  135. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  136. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "DirContentToExistDir")
  137. buildCmd.Dir = buildDirectory
  138. out, exitCode, err := runCommandWithOutput(buildCmd)
  139. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  140. if err != nil || exitCode != 0 {
  141. t.Fatal("failed to build the image")
  142. }
  143. deleteImages("testaddimg")
  144. logDone("build - add directory contents to existing dir")
  145. }
  146. func TestAddWholeDirToRoot(t *testing.T) {
  147. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd", "WholeDirToRoot")
  148. test_dir := filepath.Join(buildDirectory, "test_dir")
  149. if err := os.MkdirAll(test_dir, 0755); err != nil {
  150. t.Fatal(err)
  151. }
  152. f, err := os.OpenFile(filepath.Join(test_dir, "test_file"), os.O_CREATE, 0644)
  153. if err != nil {
  154. t.Fatal(err)
  155. }
  156. f.Close()
  157. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", ".")
  158. buildCmd.Dir = buildDirectory
  159. out, exitCode, err := runCommandWithOutput(buildCmd)
  160. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  161. if err != nil || exitCode != 0 {
  162. t.Fatal("failed to build the image")
  163. }
  164. deleteImages("testaddimg")
  165. logDone("build - add whole directory to root")
  166. }
  167. func TestAddEtcToRoot(t *testing.T) {
  168. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestAdd")
  169. buildCmd := exec.Command(dockerBinary, "build", "-t", "testaddimg", "EtcToRoot")
  170. buildCmd.Dir = buildDirectory
  171. out, exitCode, err := runCommandWithOutput(buildCmd)
  172. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  173. if err != nil || exitCode != 0 {
  174. t.Fatal("failed to build the image")
  175. }
  176. deleteImages("testaddimg")
  177. logDone("build - add etc directory to root")
  178. }
  179. func TestCopySingleFileToRoot(t *testing.T) {
  180. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestCopy", "SingleFileToRoot")
  181. f, err := os.OpenFile(filepath.Join(buildDirectory, "test_file"), os.O_CREATE, 0644)
  182. if err != nil {
  183. t.Fatal(err)
  184. }
  185. f.Close()
  186. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", ".")
  187. buildCmd.Dir = buildDirectory
  188. out, exitCode, err := runCommandWithOutput(buildCmd)
  189. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  190. if err != nil || exitCode != 0 {
  191. t.Fatal("failed to build the image")
  192. }
  193. deleteImages("testcopyimg")
  194. logDone("build - copy single file to root")
  195. }
  196. // Issue #3960: "ADD src ." hangs - adapted for COPY
  197. func TestCopySingleFileToWorkdir(t *testing.T) {
  198. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestCopy", "SingleFileToWorkdir")
  199. f, err := os.OpenFile(filepath.Join(buildDirectory, "test_file"), os.O_CREATE, 0644)
  200. if err != nil {
  201. t.Fatal(err)
  202. }
  203. f.Close()
  204. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", ".")
  205. buildCmd.Dir = buildDirectory
  206. done := make(chan error)
  207. go func() {
  208. out, exitCode, err := runCommandWithOutput(buildCmd)
  209. if err != nil || exitCode != 0 {
  210. done <- fmt.Errorf("build failed to complete: %s %v", out, err)
  211. return
  212. }
  213. done <- nil
  214. }()
  215. select {
  216. case <-time.After(5 * time.Second):
  217. if err := buildCmd.Process.Kill(); err != nil {
  218. fmt.Printf("could not kill build (pid=%d): %v\n", buildCmd.Process.Pid, err)
  219. }
  220. t.Fatal("build timed out")
  221. case err := <-done:
  222. if err != nil {
  223. t.Fatal(err)
  224. }
  225. }
  226. deleteImages("testcopyimg")
  227. logDone("build - copy single file to workdir")
  228. }
  229. func TestCopySingleFileToExistDir(t *testing.T) {
  230. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestCopy")
  231. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", "SingleFileToExistDir")
  232. buildCmd.Dir = buildDirectory
  233. out, exitCode, err := runCommandWithOutput(buildCmd)
  234. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  235. if err != nil || exitCode != 0 {
  236. t.Fatal("failed to build the image")
  237. }
  238. deleteImages("testcopyimg")
  239. logDone("build - add single file to existing dir")
  240. }
  241. func TestCopySingleFileToNonExistDir(t *testing.T) {
  242. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestCopy")
  243. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", "SingleFileToNonExistDir")
  244. buildCmd.Dir = buildDirectory
  245. out, exitCode, err := runCommandWithOutput(buildCmd)
  246. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  247. if err != nil || exitCode != 0 {
  248. t.Fatal("failed to build the image")
  249. }
  250. deleteImages("testcopyimg")
  251. logDone("build - copy single file to non-existing dir")
  252. }
  253. func TestCopyDirContentToRoot(t *testing.T) {
  254. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestCopy")
  255. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", "DirContentToRoot")
  256. buildCmd.Dir = buildDirectory
  257. out, exitCode, err := runCommandWithOutput(buildCmd)
  258. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  259. if err != nil || exitCode != 0 {
  260. t.Fatal("failed to build the image")
  261. }
  262. deleteImages("testcopyimg")
  263. logDone("build - copy directory contents to root")
  264. }
  265. func TestCopyDirContentToExistDir(t *testing.T) {
  266. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestCopy")
  267. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", "DirContentToExistDir")
  268. buildCmd.Dir = buildDirectory
  269. out, exitCode, err := runCommandWithOutput(buildCmd)
  270. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  271. if err != nil || exitCode != 0 {
  272. t.Fatal("failed to build the image")
  273. }
  274. deleteImages("testcopyimg")
  275. logDone("build - copy directory contents to existing dir")
  276. }
  277. func TestCopyWholeDirToRoot(t *testing.T) {
  278. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestCopy", "WholeDirToRoot")
  279. test_dir := filepath.Join(buildDirectory, "test_dir")
  280. if err := os.MkdirAll(test_dir, 0755); err != nil {
  281. t.Fatal(err)
  282. }
  283. f, err := os.OpenFile(filepath.Join(test_dir, "test_file"), os.O_CREATE, 0644)
  284. if err != nil {
  285. t.Fatal(err)
  286. }
  287. f.Close()
  288. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", ".")
  289. buildCmd.Dir = buildDirectory
  290. out, exitCode, err := runCommandWithOutput(buildCmd)
  291. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  292. if err != nil || exitCode != 0 {
  293. t.Fatal("failed to build the image")
  294. }
  295. deleteImages("testcopyimg")
  296. logDone("build - copy whole directory to root")
  297. }
  298. func TestCopyEtcToRoot(t *testing.T) {
  299. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestCopy")
  300. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", "EtcToRoot")
  301. buildCmd.Dir = buildDirectory
  302. out, exitCode, err := runCommandWithOutput(buildCmd)
  303. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out, err))
  304. if err != nil || exitCode != 0 {
  305. t.Fatal("failed to build the image")
  306. }
  307. deleteImages("testcopyimg")
  308. logDone("build - copy etc directory to root")
  309. }
  310. func TestCopyDisallowRemote(t *testing.T) {
  311. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestCopy")
  312. buildCmd := exec.Command(dockerBinary, "build", "-t", "testcopyimg", "DisallowRemote")
  313. buildCmd.Dir = buildDirectory
  314. out, exitCode, err := runCommandWithOutput(buildCmd)
  315. if err == nil || exitCode == 0 {
  316. t.Fatalf("building the image should've failed; output: %s", out)
  317. }
  318. deleteImages("testcopyimg")
  319. logDone("build - copy - disallow copy from remote")
  320. }
  321. // Issue #5270 - ensure we throw a better error than "unexpected EOF"
  322. // when we can't access files in the context.
  323. func TestBuildWithInaccessibleFilesInContext(t *testing.T) {
  324. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildWithInaccessibleFilesInContext")
  325. {
  326. // This is used to ensure we detect inaccessible files early during build in the cli client
  327. pathToInaccessibleFileBuildDirectory := filepath.Join(buildDirectory, "inaccessiblefile")
  328. pathToFileWithoutReadAccess := filepath.Join(pathToInaccessibleFileBuildDirectory, "fileWithoutReadAccess")
  329. err := os.Chown(pathToFileWithoutReadAccess, 0, 0)
  330. errorOut(err, t, fmt.Sprintf("failed to chown file to root: %s", err))
  331. err = os.Chmod(pathToFileWithoutReadAccess, 0700)
  332. errorOut(err, t, fmt.Sprintf("failed to chmod file to 700: %s", err))
  333. buildCommandStatement := fmt.Sprintf("%s build -t inaccessiblefiles .", dockerBinary)
  334. buildCmd := exec.Command("su", "unprivilegeduser", "-c", buildCommandStatement)
  335. buildCmd.Dir = pathToInaccessibleFileBuildDirectory
  336. out, exitCode, err := runCommandWithOutput(buildCmd)
  337. if err == nil || exitCode == 0 {
  338. t.Fatalf("build should have failed: %s %s", err, out)
  339. }
  340. // check if we've detected the failure before we started building
  341. if !strings.Contains(out, "no permission to read from ") {
  342. t.Fatalf("output should've contained the string: no permission to read from but contained: %s", out)
  343. }
  344. if !strings.Contains(out, "Error checking context is accessible") {
  345. t.Fatalf("output should've contained the string: Error checking context is accessible")
  346. }
  347. }
  348. {
  349. // This is used to ensure we detect inaccessible directories early during build in the cli client
  350. pathToInaccessibleDirectoryBuildDirectory := filepath.Join(buildDirectory, "inaccessibledirectory")
  351. pathToDirectoryWithoutReadAccess := filepath.Join(pathToInaccessibleDirectoryBuildDirectory, "directoryWeCantStat")
  352. pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  353. err := os.Chown(pathToDirectoryWithoutReadAccess, 0, 0)
  354. errorOut(err, t, fmt.Sprintf("failed to chown directory to root: %s", err))
  355. err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444)
  356. errorOut(err, t, fmt.Sprintf("failed to chmod directory to 755: %s", err))
  357. err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700)
  358. errorOut(err, t, fmt.Sprintf("failed to chmod file to 444: %s", err))
  359. buildCommandStatement := fmt.Sprintf("%s build -t inaccessiblefiles .", dockerBinary)
  360. buildCmd := exec.Command("su", "unprivilegeduser", "-c", buildCommandStatement)
  361. buildCmd.Dir = pathToInaccessibleDirectoryBuildDirectory
  362. out, exitCode, err := runCommandWithOutput(buildCmd)
  363. if err == nil || exitCode == 0 {
  364. t.Fatalf("build should have failed: %s %s", err, out)
  365. }
  366. // check if we've detected the failure before we started building
  367. if !strings.Contains(out, "can't stat") {
  368. t.Fatalf("output should've contained the string: can't access %s", out)
  369. }
  370. if !strings.Contains(out, "Error checking context is accessible") {
  371. t.Fatalf("output should've contained the string: Error checking context is accessible")
  372. }
  373. }
  374. {
  375. // This is used to ensure we don't follow links when checking if everything in the context is accessible
  376. // This test doesn't require that we run commands as an unprivileged user
  377. pathToDirectoryWhichContainsLinks := filepath.Join(buildDirectory, "linksdirectory")
  378. buildCmd := exec.Command(dockerBinary, "build", "-t", "testlinksok", ".")
  379. buildCmd.Dir = pathToDirectoryWhichContainsLinks
  380. out, exitCode, err := runCommandWithOutput(buildCmd)
  381. if err != nil || exitCode != 0 {
  382. t.Fatalf("build should have worked: %s %s", err, out)
  383. }
  384. deleteImages("testlinksok")
  385. }
  386. deleteImages("inaccessiblefiles")
  387. logDone("build - ADD from context with inaccessible files must fail")
  388. logDone("build - ADD from context with accessible links must work")
  389. }
  390. func TestBuildForceRm(t *testing.T) {
  391. containerCountBefore, err := getContainerCount()
  392. if err != nil {
  393. t.Fatalf("failed to get the container count: %s", err)
  394. }
  395. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildForceRm")
  396. buildCmd := exec.Command(dockerBinary, "build", "--force-rm", ".")
  397. buildCmd.Dir = buildDirectory
  398. _, exitCode, err := runCommandWithOutput(buildCmd)
  399. if err == nil || exitCode == 0 {
  400. t.Fatal("failed to build the image")
  401. }
  402. containerCountAfter, err := getContainerCount()
  403. if err != nil {
  404. t.Fatalf("failed to get the container count: %s", err)
  405. }
  406. if containerCountBefore != containerCountAfter {
  407. t.Fatalf("--force-rm shouldn't have left containers behind")
  408. }
  409. logDone("build - ensure --force-rm doesn't leave containers behind")
  410. }
  411. func TestBuildRm(t *testing.T) {
  412. {
  413. containerCountBefore, err := getContainerCount()
  414. if err != nil {
  415. t.Fatalf("failed to get the container count: %s", err)
  416. }
  417. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildRm")
  418. buildCmd := exec.Command(dockerBinary, "build", "--rm", "-t", "testbuildrm", ".")
  419. buildCmd.Dir = buildDirectory
  420. _, exitCode, err := runCommandWithOutput(buildCmd)
  421. if err != nil || exitCode != 0 {
  422. t.Fatal("failed to build the image")
  423. }
  424. containerCountAfter, err := getContainerCount()
  425. if err != nil {
  426. t.Fatalf("failed to get the container count: %s", err)
  427. }
  428. if containerCountBefore != containerCountAfter {
  429. t.Fatalf("-rm shouldn't have left containers behind")
  430. }
  431. deleteImages("testbuildrm")
  432. }
  433. {
  434. containerCountBefore, err := getContainerCount()
  435. if err != nil {
  436. t.Fatalf("failed to get the container count: %s", err)
  437. }
  438. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildRm")
  439. buildCmd := exec.Command(dockerBinary, "build", "-t", "testbuildrm", ".")
  440. buildCmd.Dir = buildDirectory
  441. _, exitCode, err := runCommandWithOutput(buildCmd)
  442. if err != nil || exitCode != 0 {
  443. t.Fatal("failed to build the image")
  444. }
  445. containerCountAfter, err := getContainerCount()
  446. if err != nil {
  447. t.Fatalf("failed to get the container count: %s", err)
  448. }
  449. if containerCountBefore != containerCountAfter {
  450. t.Fatalf("--rm shouldn't have left containers behind")
  451. }
  452. deleteImages("testbuildrm")
  453. }
  454. {
  455. containerCountBefore, err := getContainerCount()
  456. if err != nil {
  457. t.Fatalf("failed to get the container count: %s", err)
  458. }
  459. buildDirectory := filepath.Join(workingDirectory, "build_tests", "TestBuildRm")
  460. buildCmd := exec.Command(dockerBinary, "build", "--rm=false", "-t", "testbuildrm", ".")
  461. buildCmd.Dir = buildDirectory
  462. _, exitCode, err := runCommandWithOutput(buildCmd)
  463. if err != nil || exitCode != 0 {
  464. t.Fatal("failed to build the image")
  465. }
  466. containerCountAfter, err := getContainerCount()
  467. if err != nil {
  468. t.Fatalf("failed to get the container count: %s", err)
  469. }
  470. if containerCountBefore == containerCountAfter {
  471. t.Fatalf("--rm=false should have left containers behind")
  472. }
  473. deleteAllContainers()
  474. deleteImages("testbuildrm")
  475. }
  476. logDone("build - ensure --rm doesn't leave containers behind and that --rm=true is the default")
  477. logDone("build - ensure --rm=false overrides the default")
  478. }
  479. func TestBuildWithVolumes(t *testing.T) {
  480. name := "testbuildvolumes"
  481. expected := "map[/test1:map[] /test2:map[]]"
  482. defer deleteImages(name)
  483. _, err := buildImage(name,
  484. `FROM scratch
  485. VOLUME /test1
  486. VOLUME /test2`,
  487. true)
  488. if err != nil {
  489. t.Fatal(err)
  490. }
  491. res, err := inspectField(name, "Config.Volumes")
  492. if err != nil {
  493. t.Fatal(err)
  494. }
  495. if res != expected {
  496. t.Fatalf("Volumes %s, expected %s", res, expected)
  497. }
  498. logDone("build - with volumes")
  499. }
  500. func TestBuildMaintainer(t *testing.T) {
  501. name := "testbuildmaintainer"
  502. expected := "dockerio"
  503. defer deleteImages(name)
  504. _, err := buildImage(name,
  505. `FROM scratch
  506. MAINTAINER dockerio`,
  507. true)
  508. if err != nil {
  509. t.Fatal(err)
  510. }
  511. res, err := inspectField(name, "Author")
  512. if err != nil {
  513. t.Fatal(err)
  514. }
  515. if res != expected {
  516. t.Fatalf("Maintainer %s, expected %s", res, expected)
  517. }
  518. logDone("build - maintainer")
  519. }
  520. func TestBuildUser(t *testing.T) {
  521. name := "testbuilduser"
  522. expected := "dockerio"
  523. defer deleteImages(name)
  524. _, err := buildImage(name,
  525. `FROM busybox
  526. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  527. USER dockerio
  528. RUN [ $(whoami) = 'dockerio' ]`,
  529. true)
  530. if err != nil {
  531. t.Fatal(err)
  532. }
  533. res, err := inspectField(name, "Config.User")
  534. if err != nil {
  535. t.Fatal(err)
  536. }
  537. if res != expected {
  538. t.Fatalf("User %s, expected %s", res, expected)
  539. }
  540. logDone("build - user")
  541. }
  542. func TestBuildRelativeWorkdir(t *testing.T) {
  543. name := "testbuildrelativeworkdir"
  544. expected := "/test2/test3"
  545. defer deleteImages(name)
  546. _, err := buildImage(name,
  547. `FROM busybox
  548. RUN [ "$PWD" = '/' ]
  549. WORKDIR test1
  550. RUN [ "$PWD" = '/test1' ]
  551. WORKDIR /test2
  552. RUN [ "$PWD" = '/test2' ]
  553. WORKDIR test3
  554. RUN [ "$PWD" = '/test2/test3' ]`,
  555. true)
  556. if err != nil {
  557. t.Fatal(err)
  558. }
  559. res, err := inspectField(name, "Config.WorkingDir")
  560. if err != nil {
  561. t.Fatal(err)
  562. }
  563. if res != expected {
  564. t.Fatalf("Workdir %s, expected %s", res, expected)
  565. }
  566. logDone("build - relative workdir")
  567. }
  568. func TestBuildEnv(t *testing.T) {
  569. name := "testbuildenv"
  570. expected := "[HOME=/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]"
  571. defer deleteImages(name)
  572. _, err := buildImage(name,
  573. `FROM busybox
  574. ENV PORT 2375
  575. RUN [ $(env | grep PORT) = 'PORT=2375' ]`,
  576. true)
  577. if err != nil {
  578. t.Fatal(err)
  579. }
  580. res, err := inspectField(name, "Config.Env")
  581. if err != nil {
  582. t.Fatal(err)
  583. }
  584. if res != expected {
  585. t.Fatalf("Env %s, expected %s", res, expected)
  586. }
  587. logDone("build - env")
  588. }
  589. func TestBuildCmd(t *testing.T) {
  590. name := "testbuildcmd"
  591. expected := "[/bin/echo Hello World]"
  592. defer deleteImages(name)
  593. _, err := buildImage(name,
  594. `FROM scratch
  595. CMD ["/bin/echo", "Hello World"]`,
  596. true)
  597. if err != nil {
  598. t.Fatal(err)
  599. }
  600. res, err := inspectField(name, "Config.Cmd")
  601. if err != nil {
  602. t.Fatal(err)
  603. }
  604. if res != expected {
  605. t.Fatalf("Cmd %s, expected %s", res, expected)
  606. }
  607. logDone("build - cmd")
  608. }
  609. func TestBuildExpose(t *testing.T) {
  610. name := "testbuildexpose"
  611. expected := "map[2375/tcp:map[]]"
  612. defer deleteImages(name)
  613. _, err := buildImage(name,
  614. `FROM scratch
  615. EXPOSE 2375`,
  616. true)
  617. if err != nil {
  618. t.Fatal(err)
  619. }
  620. res, err := inspectField(name, "Config.ExposedPorts")
  621. if err != nil {
  622. t.Fatal(err)
  623. }
  624. if res != expected {
  625. t.Fatalf("Exposed ports %s, expected %s", res, expected)
  626. }
  627. logDone("build - expose")
  628. }
  629. func TestBuildEntrypoint(t *testing.T) {
  630. name := "testbuildentrypoint"
  631. expected := "[/bin/echo]"
  632. defer deleteImages(name)
  633. _, err := buildImage(name,
  634. `FROM scratch
  635. ENTRYPOINT ["/bin/echo"]`,
  636. true)
  637. if err != nil {
  638. t.Fatal(err)
  639. }
  640. res, err := inspectField(name, "Config.Entrypoint")
  641. if err != nil {
  642. t.Fatal(err)
  643. }
  644. if res != expected {
  645. t.Fatalf("Entrypoint %s, expected %s", res, expected)
  646. }
  647. logDone("build - entrypoint")
  648. }
  649. // #6445 ensure ONBUILD triggers aren't committed to grandchildren
  650. func TestBuildOnBuildLimitedInheritence(t *testing.T) {
  651. name1 := "testonbuildtrigger1"
  652. dockerfile1 := `
  653. FROM busybox
  654. RUN echo "GRANDPARENT"
  655. ONBUILD RUN echo "ONBUILD PARENT"
  656. `
  657. ctx1, err := fakeContext(dockerfile1, nil)
  658. if err != nil {
  659. t.Fatal(err)
  660. }
  661. buildCmd := exec.Command(dockerBinary, "build", "-t", name1, ".")
  662. buildCmd.Dir = ctx1.Dir
  663. out1, _, err := runCommandWithOutput(buildCmd)
  664. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out1, err))
  665. defer deleteImages(name1)
  666. name2 := "testonbuildtrigger2"
  667. dockerfile2 := `
  668. FROM testonbuildtrigger1
  669. `
  670. ctx2, err := fakeContext(dockerfile2, nil)
  671. if err != nil {
  672. t.Fatal(err)
  673. }
  674. buildCmd = exec.Command(dockerBinary, "build", "-t", name2, ".")
  675. buildCmd.Dir = ctx2.Dir
  676. out2, _, err := runCommandWithOutput(buildCmd)
  677. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out2, err))
  678. defer deleteImages(name2)
  679. name3 := "testonbuildtrigger3"
  680. dockerfile3 := `
  681. FROM testonbuildtrigger2
  682. `
  683. ctx3, err := fakeContext(dockerfile3, nil)
  684. if err != nil {
  685. t.Fatal(err)
  686. }
  687. buildCmd = exec.Command(dockerBinary, "build", "-t", name3, ".")
  688. buildCmd.Dir = ctx3.Dir
  689. out3, _, err := runCommandWithOutput(buildCmd)
  690. errorOut(err, t, fmt.Sprintf("build failed to complete: %v %v", out3, err))
  691. defer deleteImages(name3)
  692. // ONBUILD should be run in second build.
  693. if !strings.Contains(out2, "ONBUILD PARENT") {
  694. t.Fatalf("ONBUILD instruction did not run in child of ONBUILD parent")
  695. }
  696. // ONBUILD should *not* be run in third build.
  697. if strings.Contains(out3, "ONBUILD PARENT") {
  698. t.Fatalf("ONBUILD instruction ran in grandchild of ONBUILD parent")
  699. }
  700. logDone("build - onbuild")
  701. }
  702. func TestBuildWithCache(t *testing.T) {
  703. name := "testbuildwithcache"
  704. defer deleteImages(name)
  705. id1, err := buildImage(name,
  706. `FROM scratch
  707. MAINTAINER dockerio
  708. EXPOSE 5432
  709. ENTRYPOINT ["/bin/echo"]`,
  710. true)
  711. if err != nil {
  712. t.Fatal(err)
  713. }
  714. id2, err := buildImage(name,
  715. `FROM scratch
  716. MAINTAINER dockerio
  717. EXPOSE 5432
  718. ENTRYPOINT ["/bin/echo"]`,
  719. true)
  720. if err != nil {
  721. t.Fatal(err)
  722. }
  723. if id1 != id2 {
  724. t.Fatal("The cache should have been used but hasn't.")
  725. }
  726. logDone("build - with cache")
  727. }
  728. func TestBuildWithoutCache(t *testing.T) {
  729. name := "testbuildwithoutcache"
  730. defer deleteImages(name)
  731. id1, err := buildImage(name,
  732. `FROM scratch
  733. MAINTAINER dockerio
  734. EXPOSE 5432
  735. ENTRYPOINT ["/bin/echo"]`,
  736. true)
  737. if err != nil {
  738. t.Fatal(err)
  739. }
  740. id2, err := buildImage(name,
  741. `FROM scratch
  742. MAINTAINER dockerio
  743. EXPOSE 5432
  744. ENTRYPOINT ["/bin/echo"]`,
  745. false)
  746. if err != nil {
  747. t.Fatal(err)
  748. }
  749. if id1 == id2 {
  750. t.Fatal("The cache should have been invalided but hasn't.")
  751. }
  752. logDone("build - without cache")
  753. }
  754. func TestBuildADDLocalFileWithCache(t *testing.T) {
  755. name := "testbuildaddlocalfilewithcache"
  756. defer deleteImages(name)
  757. dockerfile := `
  758. FROM busybox
  759. MAINTAINER dockerio
  760. ADD foo /usr/lib/bla/bar
  761. RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  762. ctx, err := fakeContext(dockerfile, map[string]string{
  763. "foo": "hello",
  764. })
  765. defer ctx.Close()
  766. if err != nil {
  767. t.Fatal(err)
  768. }
  769. id1, err := buildImageFromContext(name, ctx, true)
  770. if err != nil {
  771. t.Fatal(err)
  772. }
  773. id2, err := buildImageFromContext(name, ctx, true)
  774. if err != nil {
  775. t.Fatal(err)
  776. }
  777. if id1 != id2 {
  778. t.Fatal("The cache should have been used but hasn't.")
  779. }
  780. logDone("build - add local file with cache")
  781. }
  782. func TestBuildADDLocalFileWithoutCache(t *testing.T) {
  783. name := "testbuildaddlocalfilewithoutcache"
  784. defer deleteImages(name)
  785. dockerfile := `
  786. FROM busybox
  787. MAINTAINER dockerio
  788. ADD foo /usr/lib/bla/bar
  789. RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  790. ctx, err := fakeContext(dockerfile, map[string]string{
  791. "foo": "hello",
  792. })
  793. defer ctx.Close()
  794. if err != nil {
  795. t.Fatal(err)
  796. }
  797. id1, err := buildImageFromContext(name, ctx, true)
  798. if err != nil {
  799. t.Fatal(err)
  800. }
  801. id2, err := buildImageFromContext(name, ctx, false)
  802. if err != nil {
  803. t.Fatal(err)
  804. }
  805. if id1 == id2 {
  806. t.Fatal("The cache should have been invalided but hasn't.")
  807. }
  808. logDone("build - add local file without cache")
  809. }
  810. func TestBuildADDCurrentDirWithCache(t *testing.T) {
  811. name := "testbuildaddcurrentdirwithcache"
  812. defer deleteImages(name)
  813. dockerfile := `
  814. FROM scratch
  815. MAINTAINER dockerio
  816. ADD . /usr/lib/bla`
  817. ctx, err := fakeContext(dockerfile, map[string]string{
  818. "foo": "hello",
  819. })
  820. defer ctx.Close()
  821. if err != nil {
  822. t.Fatal(err)
  823. }
  824. id1, err := buildImageFromContext(name, ctx, true)
  825. if err != nil {
  826. t.Fatal(err)
  827. }
  828. // Check that adding file invalidate cache of "ADD ."
  829. if err := ctx.Add("bar", "hello2"); err != nil {
  830. t.Fatal(err)
  831. }
  832. id2, err := buildImageFromContext(name, ctx, true)
  833. if err != nil {
  834. t.Fatal(err)
  835. }
  836. if id1 == id2 {
  837. t.Fatal("The cache should have been invalided but hasn't.")
  838. }
  839. // Check that changing file invalidate cache of "ADD ."
  840. if err := ctx.Add("foo", "hello1"); err != nil {
  841. t.Fatal(err)
  842. }
  843. id3, err := buildImageFromContext(name, ctx, true)
  844. if err != nil {
  845. t.Fatal(err)
  846. }
  847. if id2 == id3 {
  848. t.Fatal("The cache should have been invalided but hasn't.")
  849. }
  850. // Check that changing file to same content invalidate cache of "ADD ."
  851. time.Sleep(1 * time.Second) // wait second because of mtime precision
  852. if err := ctx.Add("foo", "hello1"); err != nil {
  853. t.Fatal(err)
  854. }
  855. id4, err := buildImageFromContext(name, ctx, true)
  856. if err != nil {
  857. t.Fatal(err)
  858. }
  859. if id3 == id4 {
  860. t.Fatal("The cache should have been invalided but hasn't.")
  861. }
  862. id5, err := buildImageFromContext(name, ctx, true)
  863. if err != nil {
  864. t.Fatal(err)
  865. }
  866. if id4 != id5 {
  867. t.Fatal("The cache should have been used but hasn't.")
  868. }
  869. logDone("build - add current directory with cache")
  870. }
  871. func TestBuildADDCurrentDirWithoutCache(t *testing.T) {
  872. name := "testbuildaddcurrentdirwithoutcache"
  873. defer deleteImages(name)
  874. dockerfile := `
  875. FROM scratch
  876. MAINTAINER dockerio
  877. ADD . /usr/lib/bla`
  878. ctx, err := fakeContext(dockerfile, map[string]string{
  879. "foo": "hello",
  880. })
  881. defer ctx.Close()
  882. if err != nil {
  883. t.Fatal(err)
  884. }
  885. id1, err := buildImageFromContext(name, ctx, true)
  886. if err != nil {
  887. t.Fatal(err)
  888. }
  889. id2, err := buildImageFromContext(name, ctx, false)
  890. if err != nil {
  891. t.Fatal(err)
  892. }
  893. if id1 == id2 {
  894. t.Fatal("The cache should have been invalided but hasn't.")
  895. }
  896. logDone("build - add current directory without cache")
  897. }
  898. func TestBuildADDRemoteFileWithCache(t *testing.T) {
  899. name := "testbuildaddremotefilewithcache"
  900. defer deleteImages(name)
  901. server, err := fakeStorage(map[string]string{
  902. "baz": "hello",
  903. })
  904. if err != nil {
  905. t.Fatal(err)
  906. }
  907. defer server.Close()
  908. id1, err := buildImage(name,
  909. fmt.Sprintf(`FROM scratch
  910. MAINTAINER dockerio
  911. ADD %s/baz /usr/lib/baz/quux`, server.URL),
  912. true)
  913. if err != nil {
  914. t.Fatal(err)
  915. }
  916. id2, err := buildImage(name,
  917. fmt.Sprintf(`FROM scratch
  918. MAINTAINER dockerio
  919. ADD %s/baz /usr/lib/baz/quux`, server.URL),
  920. true)
  921. if err != nil {
  922. t.Fatal(err)
  923. }
  924. if id1 != id2 {
  925. t.Fatal("The cache should have been used but hasn't.")
  926. }
  927. logDone("build - add remote file with cache")
  928. }
  929. func TestBuildADDRemoteFileWithoutCache(t *testing.T) {
  930. name := "testbuildaddremotefilewithoutcache"
  931. defer deleteImages(name)
  932. server, err := fakeStorage(map[string]string{
  933. "baz": "hello",
  934. })
  935. if err != nil {
  936. t.Fatal(err)
  937. }
  938. defer server.Close()
  939. id1, err := buildImage(name,
  940. fmt.Sprintf(`FROM scratch
  941. MAINTAINER dockerio
  942. ADD %s/baz /usr/lib/baz/quux`, server.URL),
  943. true)
  944. if err != nil {
  945. t.Fatal(err)
  946. }
  947. id2, err := buildImage(name,
  948. fmt.Sprintf(`FROM scratch
  949. MAINTAINER dockerio
  950. ADD %s/baz /usr/lib/baz/quux`, server.URL),
  951. false)
  952. if err != nil {
  953. t.Fatal(err)
  954. }
  955. if id1 == id2 {
  956. t.Fatal("The cache should have been invalided but hasn't.")
  957. }
  958. logDone("build - add remote file without cache")
  959. }
  960. func TestBuildADDLocalAndRemoteFilesWithCache(t *testing.T) {
  961. name := "testbuildaddlocalandremotefilewithcache"
  962. defer deleteImages(name)
  963. server, err := fakeStorage(map[string]string{
  964. "baz": "hello",
  965. })
  966. if err != nil {
  967. t.Fatal(err)
  968. }
  969. defer server.Close()
  970. ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  971. MAINTAINER dockerio
  972. ADD foo /usr/lib/bla/bar
  973. ADD %s/baz /usr/lib/baz/quux`, server.URL),
  974. map[string]string{
  975. "foo": "hello world",
  976. })
  977. if err != nil {
  978. t.Fatal(err)
  979. }
  980. defer ctx.Close()
  981. id1, err := buildImageFromContext(name, ctx, true)
  982. if err != nil {
  983. t.Fatal(err)
  984. }
  985. id2, err := buildImageFromContext(name, ctx, true)
  986. if err != nil {
  987. t.Fatal(err)
  988. }
  989. if id1 != id2 {
  990. t.Fatal("The cache should have been used but hasn't.")
  991. }
  992. logDone("build - add local and remote file with cache")
  993. }
  994. func testContextTar(t *testing.T, compression archive.Compression) {
  995. contextDirectory := filepath.Join(workingDirectory, "build_tests", "TestContextTar")
  996. context, err := archive.Tar(contextDirectory, compression)
  997. if err != nil {
  998. t.Fatalf("failed to build context tar: %v", err)
  999. }
  1000. buildCmd := exec.Command(dockerBinary, "build", "-t", "contexttar", "-")
  1001. buildCmd.Stdin = context
  1002. out, exitCode, err := runCommandWithOutput(buildCmd)
  1003. if err != nil || exitCode != 0 {
  1004. t.Fatalf("build failed to complete: %v %v", out, err)
  1005. }
  1006. deleteImages("contexttar")
  1007. logDone(fmt.Sprintf("build - build an image with a context tar, compression: %v", compression))
  1008. }
  1009. func TestContextTarGzip(t *testing.T) {
  1010. testContextTar(t, archive.Gzip)
  1011. }
  1012. func TestContextTarNoCompression(t *testing.T) {
  1013. testContextTar(t, archive.Uncompressed)
  1014. }
  1015. func TestNoContext(t *testing.T) {
  1016. buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
  1017. buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
  1018. out, exitCode, err := runCommandWithOutput(buildCmd)
  1019. if err != nil || exitCode != 0 {
  1020. t.Fatalf("build failed to complete: %v %v", out, err)
  1021. }
  1022. out, exitCode, err = cmd(t, "run", "nocontext")
  1023. if out != "ok\n" {
  1024. t.Fatalf("run produced invalid output: %q, expected %q", out, "ok")
  1025. }
  1026. deleteImages("nocontext")
  1027. logDone("build - build an image with no context")
  1028. }
  1029. // TODO: TestCaching
  1030. func TestBuildADDLocalAndRemoteFilesWithoutCache(t *testing.T) {
  1031. name := "testbuildaddlocalandremotefilewithoutcache"
  1032. defer deleteImages(name)
  1033. server, err := fakeStorage(map[string]string{
  1034. "baz": "hello",
  1035. })
  1036. if err != nil {
  1037. t.Fatal(err)
  1038. }
  1039. defer server.Close()
  1040. ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  1041. MAINTAINER dockerio
  1042. ADD foo /usr/lib/bla/bar
  1043. ADD %s/baz /usr/lib/baz/quux`, server.URL),
  1044. map[string]string{
  1045. "foo": "hello world",
  1046. })
  1047. if err != nil {
  1048. t.Fatal(err)
  1049. }
  1050. defer ctx.Close()
  1051. id1, err := buildImageFromContext(name, ctx, true)
  1052. if err != nil {
  1053. t.Fatal(err)
  1054. }
  1055. id2, err := buildImageFromContext(name, ctx, false)
  1056. if err != nil {
  1057. t.Fatal(err)
  1058. }
  1059. if id1 == id2 {
  1060. t.Fatal("The cache should have been invalided but hasn't.")
  1061. }
  1062. logDone("build - add local and remote file without cache")
  1063. }
  1064. func TestBuildWithVolumeOwnership(t *testing.T) {
  1065. name := "testbuildimg"
  1066. defer deleteImages(name)
  1067. _, err := buildImage(name,
  1068. `FROM busybox:latest
  1069. RUN mkdir /test && chown daemon:daemon /test && chmod 0600 /test
  1070. VOLUME /test`,
  1071. true)
  1072. if err != nil {
  1073. t.Fatal(err)
  1074. }
  1075. cmd := exec.Command(dockerBinary, "run", "--rm", "testbuildimg", "ls", "-la", "/test")
  1076. out, _, err := runCommandWithOutput(cmd)
  1077. if err != nil {
  1078. t.Fatal(err)
  1079. }
  1080. if expected := "drw-------"; !strings.Contains(out, expected) {
  1081. t.Fatalf("expected %s received %s", expected, out)
  1082. }
  1083. if expected := "daemon daemon"; !strings.Contains(out, expected) {
  1084. t.Fatalf("expected %s received %s", expected, out)
  1085. }
  1086. logDone("build - volume ownership")
  1087. }
  1088. // testing #1405 - config.Cmd does not get cleaned up if
  1089. // utilizing cache
  1090. func TestBuildEntrypointRunCleanup(t *testing.T) {
  1091. name := "testbuildcmdcleanup"
  1092. defer deleteImages(name)
  1093. if _, err := buildImage(name,
  1094. `FROM busybox
  1095. RUN echo "hello"`,
  1096. true); err != nil {
  1097. t.Fatal(err)
  1098. }
  1099. ctx, err := fakeContext(`FROM busybox
  1100. RUN echo "hello"
  1101. ADD foo /foo
  1102. ENTRYPOINT ["/bin/echo"]`,
  1103. map[string]string{
  1104. "foo": "hello",
  1105. })
  1106. defer ctx.Close()
  1107. if err != nil {
  1108. t.Fatal(err)
  1109. }
  1110. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1111. t.Fatal(err)
  1112. }
  1113. res, err := inspectField(name, "Config.Cmd")
  1114. if err != nil {
  1115. t.Fatal(err)
  1116. }
  1117. // Cmd inherited from busybox, maybe will be fixed in #5147
  1118. if expected := "[/bin/sh]"; res != expected {
  1119. t.Fatalf("Cmd %s, expected %s", res, expected)
  1120. }
  1121. logDone("build - cleanup cmd after RUN")
  1122. }
  1123. func TestBuldForbiddenContextPath(t *testing.T) {
  1124. name := "testbuildforbidpath"
  1125. defer deleteImages(name)
  1126. ctx, err := fakeContext(`FROM scratch
  1127. ADD ../../ test/
  1128. `,
  1129. map[string]string{
  1130. "test.txt": "test1",
  1131. "other.txt": "other",
  1132. })
  1133. defer ctx.Close()
  1134. if err != nil {
  1135. t.Fatal(err)
  1136. }
  1137. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1138. if !strings.Contains(err.Error(), "Forbidden path outside the build context: ../../ (/)") {
  1139. t.Fatal("Wrong error, must be about forbidden ../../ path")
  1140. }
  1141. } else {
  1142. t.Fatal("Error must not be nil")
  1143. }
  1144. logDone("build - forbidden context path")
  1145. }
  1146. func TestBuildADDFileNotFound(t *testing.T) {
  1147. name := "testbuildaddnotfound"
  1148. defer deleteImages(name)
  1149. ctx, err := fakeContext(`FROM scratch
  1150. ADD foo /usr/local/bar`,
  1151. map[string]string{"bar": "hello"})
  1152. defer ctx.Close()
  1153. if err != nil {
  1154. t.Fatal(err)
  1155. }
  1156. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1157. if !strings.Contains(err.Error(), "foo: no such file or directory") {
  1158. t.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
  1159. }
  1160. } else {
  1161. t.Fatal("Error must not be nil")
  1162. }
  1163. logDone("build - add file not found")
  1164. }
  1165. func TestBuildInheritance(t *testing.T) {
  1166. name := "testbuildinheritance"
  1167. defer deleteImages(name)
  1168. _, err := buildImage(name,
  1169. `FROM scratch
  1170. EXPOSE 2375`,
  1171. true)
  1172. if err != nil {
  1173. t.Fatal(err)
  1174. }
  1175. ports1, err := inspectField(name, "Config.ExposedPorts")
  1176. if err != nil {
  1177. t.Fatal(err)
  1178. }
  1179. _, err = buildImage(name,
  1180. fmt.Sprintf(`FROM %s
  1181. ENTRYPOINT ["/bin/echo"]`, name),
  1182. true)
  1183. if err != nil {
  1184. t.Fatal(err)
  1185. }
  1186. res, err := inspectField(name, "Config.Entrypoint")
  1187. if err != nil {
  1188. t.Fatal(err)
  1189. }
  1190. if expected := "[/bin/echo]"; res != expected {
  1191. t.Fatalf("Entrypoint %s, expected %s", res, expected)
  1192. }
  1193. ports2, err := inspectField(name, "Config.ExposedPorts")
  1194. if err != nil {
  1195. t.Fatal(err)
  1196. }
  1197. if ports1 != ports2 {
  1198. t.Fatalf("Ports must be same: %s != %s", ports1, ports2)
  1199. }
  1200. logDone("build - inheritance")
  1201. }
  1202. func TestBuildFails(t *testing.T) {
  1203. name := "testbuildfails"
  1204. defer deleteImages(name)
  1205. _, err := buildImage(name,
  1206. `FROM busybox
  1207. RUN sh -c "exit 23"`,
  1208. true)
  1209. if err != nil {
  1210. if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
  1211. t.Fatalf("Wrong error %v, must be about non-zero code 23", err)
  1212. }
  1213. } else {
  1214. t.Fatal("Error must not be nil")
  1215. }
  1216. logDone("build - fails")
  1217. }
  1218. func TestBuildFailsDockerfileEmpty(t *testing.T) {
  1219. name := "testbuildfails"
  1220. defer deleteImages(name)
  1221. _, err := buildImage(name, ``, true)
  1222. if err != nil {
  1223. if !strings.Contains(err.Error(), "Dockerfile cannot be empty") {
  1224. t.Fatalf("Wrong error %v, must be about empty Dockerfile", err)
  1225. }
  1226. } else {
  1227. t.Fatal("Error must not be nil")
  1228. }
  1229. logDone("build - fails with empty dockerfile")
  1230. }
  1231. func TestBuildOnBuild(t *testing.T) {
  1232. name := "testbuildonbuild"
  1233. defer deleteImages(name)
  1234. _, err := buildImage(name,
  1235. `FROM busybox
  1236. ONBUILD RUN touch foobar`,
  1237. true)
  1238. if err != nil {
  1239. t.Fatal(err)
  1240. }
  1241. _, err = buildImage(name,
  1242. fmt.Sprintf(`FROM %s
  1243. RUN [ -f foobar ]`, name),
  1244. true)
  1245. if err != nil {
  1246. t.Fatal(err)
  1247. }
  1248. logDone("build - onbuild")
  1249. }
  1250. func TestBuildOnBuildForbiddenChained(t *testing.T) {
  1251. name := "testbuildonbuildforbiddenchained"
  1252. defer deleteImages(name)
  1253. _, err := buildImage(name,
  1254. `FROM busybox
  1255. ONBUILD ONBUILD RUN touch foobar`,
  1256. true)
  1257. if err != nil {
  1258. if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  1259. t.Fatalf("Wrong error %v, must be about chaining ONBUILD", err)
  1260. }
  1261. } else {
  1262. t.Fatal("Error must not be nil")
  1263. }
  1264. logDone("build - onbuild forbidden chained")
  1265. }
  1266. func TestBuildOnBuildForbiddenFrom(t *testing.T) {
  1267. name := "testbuildonbuildforbiddenfrom"
  1268. defer deleteImages(name)
  1269. _, err := buildImage(name,
  1270. `FROM busybox
  1271. ONBUILD FROM scratch`,
  1272. true)
  1273. if err != nil {
  1274. if !strings.Contains(err.Error(), "FROM isn't allowed as an ONBUILD trigger") {
  1275. t.Fatalf("Wrong error %v, must be about FROM forbidden", err)
  1276. }
  1277. } else {
  1278. t.Fatal("Error must not be nil")
  1279. }
  1280. logDone("build - onbuild forbidden from")
  1281. }
  1282. func TestBuildOnBuildForbiddenMaintainer(t *testing.T) {
  1283. name := "testbuildonbuildforbiddenmaintainer"
  1284. defer deleteImages(name)
  1285. _, err := buildImage(name,
  1286. `FROM busybox
  1287. ONBUILD MAINTAINER docker.io`,
  1288. true)
  1289. if err != nil {
  1290. if !strings.Contains(err.Error(), "MAINTAINER isn't allowed as an ONBUILD trigger") {
  1291. t.Fatalf("Wrong error %v, must be about MAINTAINER forbidden", err)
  1292. }
  1293. } else {
  1294. t.Fatal("Error must not be nil")
  1295. }
  1296. logDone("build - onbuild forbidden maintainer")
  1297. }
  1298. // gh #2446
  1299. func TestBuildAddToSymlinkDest(t *testing.T) {
  1300. name := "testbuildaddtosymlinkdest"
  1301. defer deleteImages(name)
  1302. ctx, err := fakeContext(`FROM busybox
  1303. RUN mkdir /foo
  1304. RUN ln -s /foo /bar
  1305. ADD foo /bar/
  1306. RUN [ -f /bar/foo ]
  1307. RUN [ -f /foo/foo ]`,
  1308. map[string]string{
  1309. "foo": "hello",
  1310. })
  1311. if err != nil {
  1312. t.Fatal(err)
  1313. }
  1314. defer ctx.Close()
  1315. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1316. t.Fatal(err)
  1317. }
  1318. logDone("build - add to symlink destination")
  1319. }
  1320. func TestBuildEscapeWhitespace(t *testing.T) {
  1321. name := "testbuildescaping"
  1322. defer deleteImages(name)
  1323. _, err := buildImage(name, `
  1324. FROM busybox
  1325. MAINTAINER "Docker \
  1326. IO <io@\
  1327. docker.com>"
  1328. `, true)
  1329. res, err := inspectField(name, "Author")
  1330. if err != nil {
  1331. t.Fatal(err)
  1332. }
  1333. if res != "Docker IO <io@docker.com>" {
  1334. t.Fatal("Parsed string did not match the escaped string")
  1335. }
  1336. logDone("build - validate escaping whitespace")
  1337. }
  1338. func TestDockerignore(t *testing.T) {
  1339. name := "testbuilddockerignore"
  1340. defer deleteImages(name)
  1341. dockerfile := `
  1342. FROM busybox
  1343. ADD . /bla
  1344. RUN [[ -f /bla/src/x.go ]]
  1345. RUN [[ -f /bla/Makefile ]]
  1346. RUN [[ ! -e /bla/src/_vendor ]]
  1347. RUN [[ ! -e /bla/.gitignore ]]
  1348. RUN [[ ! -e /bla/README.md ]]
  1349. RUN [[ ! -e /bla/.git ]]`
  1350. ctx, err := fakeContext(dockerfile, map[string]string{
  1351. "Makefile": "all:",
  1352. ".git/HEAD": "ref: foo",
  1353. "src/x.go": "package main",
  1354. "src/_vendor/v.go": "package main",
  1355. ".gitignore": "",
  1356. "README.md": "readme",
  1357. ".dockerignore": ".git\npkg\n.gitignore\nsrc/_vendor\n*.md",
  1358. })
  1359. defer ctx.Close()
  1360. if err != nil {
  1361. t.Fatal(err)
  1362. }
  1363. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1364. t.Fatal(err)
  1365. }
  1366. logDone("build - test .dockerignore")
  1367. }
  1368. func TestDockerignoringDockerfile(t *testing.T) {
  1369. name := "testbuilddockerignoredockerfile"
  1370. defer deleteImages(name)
  1371. dockerfile := `
  1372. FROM scratch`
  1373. ctx, err := fakeContext(dockerfile, map[string]string{
  1374. "Dockerfile": "FROM scratch",
  1375. ".dockerignore": "Dockerfile\n",
  1376. })
  1377. defer ctx.Close()
  1378. if err != nil {
  1379. t.Fatal(err)
  1380. }
  1381. if _, err = buildImageFromContext(name, ctx, true); err == nil {
  1382. t.Fatalf("Didn't get expected error from ignoring Dockerfile")
  1383. }
  1384. logDone("build - test .dockerignore of Dockerfile")
  1385. }