docker_cli_build_test.go 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492
  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. }