docker_cli_build_test.go 133 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253
  1. package main
  2. import (
  3. "archive/tar"
  4. "bufio"
  5. "bytes"
  6. "encoding/json"
  7. "fmt"
  8. "io/ioutil"
  9. "os"
  10. "os/exec"
  11. "path/filepath"
  12. "reflect"
  13. "regexp"
  14. "runtime"
  15. "strconv"
  16. "strings"
  17. "sync"
  18. "text/template"
  19. "time"
  20. "github.com/docker/docker/builder/command"
  21. "github.com/docker/docker/pkg/archive"
  22. "github.com/docker/docker/pkg/stringutils"
  23. "github.com/go-check/check"
  24. )
  25. func (s *DockerSuite) TestBuildJSONEmptyRun(c *check.C) {
  26. name := "testbuildjsonemptyrun"
  27. _, err := buildImage(
  28. name,
  29. `
  30. FROM busybox
  31. RUN []
  32. `,
  33. true)
  34. if err != nil {
  35. c.Fatal("error when dealing with a RUN statement with empty JSON array")
  36. }
  37. }
  38. func (s *DockerSuite) TestBuildEmptyWhitespace(c *check.C) {
  39. name := "testbuildemptywhitespace"
  40. _, err := buildImage(
  41. name,
  42. `
  43. FROM busybox
  44. COPY
  45. quux \
  46. bar
  47. `,
  48. true)
  49. if err == nil {
  50. c.Fatal("no error when dealing with a COPY statement with no content on the same line")
  51. }
  52. }
  53. func (s *DockerSuite) TestBuildShCmdJSONEntrypoint(c *check.C) {
  54. name := "testbuildshcmdjsonentrypoint"
  55. _, err := buildImage(
  56. name,
  57. `
  58. FROM busybox
  59. ENTRYPOINT ["/bin/echo"]
  60. CMD echo test
  61. `,
  62. true)
  63. if err != nil {
  64. c.Fatal(err)
  65. }
  66. out, _, err := runCommandWithOutput(
  67. exec.Command(
  68. dockerBinary,
  69. "run",
  70. "--rm",
  71. name))
  72. if err != nil {
  73. c.Fatal(err)
  74. }
  75. if strings.TrimSpace(out) != "/bin/sh -c echo test" {
  76. c.Fatal("CMD did not contain /bin/sh -c")
  77. }
  78. }
  79. func (s *DockerSuite) TestBuildEnvironmentReplacementUser(c *check.C) {
  80. name := "testbuildenvironmentreplacement"
  81. _, err := buildImage(name, `
  82. FROM scratch
  83. ENV user foo
  84. USER ${user}
  85. `, true)
  86. if err != nil {
  87. c.Fatal(err)
  88. }
  89. res, err := inspectFieldJSON(name, "Config.User")
  90. if err != nil {
  91. c.Fatal(err)
  92. }
  93. if res != `"foo"` {
  94. c.Fatal("User foo from environment not in Config.User on image")
  95. }
  96. }
  97. func (s *DockerSuite) TestBuildEnvironmentReplacementVolume(c *check.C) {
  98. name := "testbuildenvironmentreplacement"
  99. _, err := buildImage(name, `
  100. FROM scratch
  101. ENV volume /quux
  102. VOLUME ${volume}
  103. `, true)
  104. if err != nil {
  105. c.Fatal(err)
  106. }
  107. res, err := inspectFieldJSON(name, "Config.Volumes")
  108. if err != nil {
  109. c.Fatal(err)
  110. }
  111. var volumes map[string]interface{}
  112. if err := json.Unmarshal([]byte(res), &volumes); err != nil {
  113. c.Fatal(err)
  114. }
  115. if _, ok := volumes["/quux"]; !ok {
  116. c.Fatal("Volume /quux from environment not in Config.Volumes on image")
  117. }
  118. }
  119. func (s *DockerSuite) TestBuildEnvironmentReplacementExpose(c *check.C) {
  120. name := "testbuildenvironmentreplacement"
  121. _, err := buildImage(name, `
  122. FROM scratch
  123. ENV port 80
  124. EXPOSE ${port}
  125. `, true)
  126. if err != nil {
  127. c.Fatal(err)
  128. }
  129. res, err := inspectFieldJSON(name, "Config.ExposedPorts")
  130. if err != nil {
  131. c.Fatal(err)
  132. }
  133. var exposedPorts map[string]interface{}
  134. if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
  135. c.Fatal(err)
  136. }
  137. if _, ok := exposedPorts["80/tcp"]; !ok {
  138. c.Fatal("Exposed port 80 from environment not in Config.ExposedPorts on image")
  139. }
  140. }
  141. func (s *DockerSuite) TestBuildEnvironmentReplacementWorkdir(c *check.C) {
  142. name := "testbuildenvironmentreplacement"
  143. _, err := buildImage(name, `
  144. FROM busybox
  145. ENV MYWORKDIR /work
  146. RUN mkdir ${MYWORKDIR}
  147. WORKDIR ${MYWORKDIR}
  148. `, true)
  149. if err != nil {
  150. c.Fatal(err)
  151. }
  152. }
  153. func (s *DockerSuite) TestBuildEnvironmentReplacementAddCopy(c *check.C) {
  154. name := "testbuildenvironmentreplacement"
  155. ctx, err := fakeContext(`
  156. FROM scratch
  157. ENV baz foo
  158. ENV quux bar
  159. ENV dot .
  160. ENV fee fff
  161. ENV gee ggg
  162. ADD ${baz} ${dot}
  163. COPY ${quux} ${dot}
  164. ADD ${zzz:-${fee}} ${dot}
  165. COPY ${zzz:-${gee}} ${dot}
  166. `,
  167. map[string]string{
  168. "foo": "test1",
  169. "bar": "test2",
  170. "fff": "test3",
  171. "ggg": "test4",
  172. })
  173. if err != nil {
  174. c.Fatal(err)
  175. }
  176. defer ctx.Close()
  177. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  178. c.Fatal(err)
  179. }
  180. }
  181. func (s *DockerSuite) TestBuildEnvironmentReplacementEnv(c *check.C) {
  182. name := "testbuildenvironmentreplacement"
  183. _, err := buildImage(name,
  184. `
  185. FROM busybox
  186. ENV foo zzz
  187. ENV bar ${foo}
  188. ENV abc1='$foo'
  189. ENV env1=$foo env2=${foo} env3="$foo" env4="${foo}"
  190. RUN [ "$abc1" = '$foo' ] && (echo "$abc1" | grep -q foo)
  191. ENV abc2="\$foo"
  192. RUN [ "$abc2" = '$foo' ] && (echo "$abc2" | grep -q foo)
  193. ENV abc3 '$foo'
  194. RUN [ "$abc3" = '$foo' ] && (echo "$abc3" | grep -q foo)
  195. ENV abc4 "\$foo"
  196. RUN [ "$abc4" = '$foo' ] && (echo "$abc4" | grep -q foo)
  197. `, true)
  198. if err != nil {
  199. c.Fatal(err)
  200. }
  201. res, err := inspectFieldJSON(name, "Config.Env")
  202. if err != nil {
  203. c.Fatal(err)
  204. }
  205. envResult := []string{}
  206. if err = unmarshalJSON([]byte(res), &envResult); err != nil {
  207. c.Fatal(err)
  208. }
  209. found := false
  210. envCount := 0
  211. for _, env := range envResult {
  212. parts := strings.SplitN(env, "=", 2)
  213. if parts[0] == "bar" {
  214. found = true
  215. if parts[1] != "zzz" {
  216. c.Fatalf("Could not find replaced var for env `bar`: got %q instead of `zzz`", parts[1])
  217. }
  218. } else if strings.HasPrefix(parts[0], "env") {
  219. envCount++
  220. if parts[1] != "zzz" {
  221. c.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
  222. }
  223. } else if strings.HasPrefix(parts[0], "env") {
  224. envCount++
  225. if parts[1] != "foo" {
  226. c.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
  227. }
  228. }
  229. }
  230. if !found {
  231. c.Fatal("Never found the `bar` env variable")
  232. }
  233. if envCount != 4 {
  234. c.Fatalf("Didn't find all env vars - only saw %d\n%s", envCount, envResult)
  235. }
  236. }
  237. func (s *DockerSuite) TestBuildHandleEscapes(c *check.C) {
  238. name := "testbuildhandleescapes"
  239. _, err := buildImage(name,
  240. `
  241. FROM scratch
  242. ENV FOO bar
  243. VOLUME ${FOO}
  244. `, true)
  245. if err != nil {
  246. c.Fatal(err)
  247. }
  248. var result map[string]map[string]struct{}
  249. res, err := inspectFieldJSON(name, "Config.Volumes")
  250. if err != nil {
  251. c.Fatal(err)
  252. }
  253. if err = unmarshalJSON([]byte(res), &result); err != nil {
  254. c.Fatal(err)
  255. }
  256. if _, ok := result["bar"]; !ok {
  257. c.Fatal("Could not find volume bar set from env foo in volumes table")
  258. }
  259. deleteImages(name)
  260. _, err = buildImage(name,
  261. `
  262. FROM scratch
  263. ENV FOO bar
  264. VOLUME \${FOO}
  265. `, true)
  266. if err != nil {
  267. c.Fatal(err)
  268. }
  269. res, err = inspectFieldJSON(name, "Config.Volumes")
  270. if err != nil {
  271. c.Fatal(err)
  272. }
  273. if err = unmarshalJSON([]byte(res), &result); err != nil {
  274. c.Fatal(err)
  275. }
  276. if _, ok := result["${FOO}"]; !ok {
  277. c.Fatal("Could not find volume ${FOO} set from env foo in volumes table")
  278. }
  279. deleteImages(name)
  280. // this test in particular provides *7* backslashes and expects 6 to come back.
  281. // Like above, the first escape is swallowed and the rest are treated as
  282. // literals, this one is just less obvious because of all the character noise.
  283. _, err = buildImage(name,
  284. `
  285. FROM scratch
  286. ENV FOO bar
  287. VOLUME \\\\\\\${FOO}
  288. `, true)
  289. if err != nil {
  290. c.Fatal(err)
  291. }
  292. res, err = inspectFieldJSON(name, "Config.Volumes")
  293. if err != nil {
  294. c.Fatal(err)
  295. }
  296. if err = unmarshalJSON([]byte(res), &result); err != nil {
  297. c.Fatal(err)
  298. }
  299. if _, ok := result[`\\\${FOO}`]; !ok {
  300. c.Fatal(`Could not find volume \\\${FOO} set from env foo in volumes table`, result)
  301. }
  302. }
  303. func (s *DockerSuite) TestBuildOnBuildLowercase(c *check.C) {
  304. name := "testbuildonbuildlowercase"
  305. name2 := "testbuildonbuildlowercase2"
  306. _, err := buildImage(name,
  307. `
  308. FROM busybox
  309. onbuild run echo quux
  310. `, true)
  311. if err != nil {
  312. c.Fatal(err)
  313. }
  314. _, out, err := buildImageWithOut(name2, fmt.Sprintf(`
  315. FROM %s
  316. `, name), true)
  317. if err != nil {
  318. c.Fatal(err)
  319. }
  320. if !strings.Contains(out, "quux") {
  321. c.Fatalf("Did not receive the expected echo text, got %s", out)
  322. }
  323. if strings.Contains(out, "ONBUILD ONBUILD") {
  324. c.Fatalf("Got an ONBUILD ONBUILD error with no error: got %s", out)
  325. }
  326. }
  327. func (s *DockerSuite) TestBuildEnvEscapes(c *check.C) {
  328. name := "testbuildenvescapes"
  329. _, err := buildImage(name,
  330. `
  331. FROM busybox
  332. ENV TEST foo
  333. CMD echo \$
  334. `,
  335. true)
  336. out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name))
  337. if err != nil {
  338. c.Fatal(err)
  339. }
  340. if strings.TrimSpace(out) != "$" {
  341. c.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
  342. }
  343. }
  344. func (s *DockerSuite) TestBuildEnvOverwrite(c *check.C) {
  345. name := "testbuildenvoverwrite"
  346. _, err := buildImage(name,
  347. `
  348. FROM busybox
  349. ENV TEST foo
  350. CMD echo ${TEST}
  351. `,
  352. true)
  353. if err != nil {
  354. c.Fatal(err)
  355. }
  356. out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-e", "TEST=bar", "-t", name))
  357. if err != nil {
  358. c.Fatal(err)
  359. }
  360. if strings.TrimSpace(out) != "bar" {
  361. c.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
  362. }
  363. }
  364. func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainerInSourceImage(c *check.C) {
  365. name := "testbuildonbuildforbiddenmaintainerinsourceimage"
  366. createCmd := exec.Command(dockerBinary, "create", "busybox", "true")
  367. out, _, _, err := runCommandWithStdoutStderr(createCmd)
  368. if err != nil {
  369. c.Fatal(out, err)
  370. }
  371. cleanedContainerID := strings.TrimSpace(out)
  372. commitCmd := exec.Command(dockerBinary, "commit", "--run", "{\"OnBuild\":[\"MAINTAINER docker.io\"]}", cleanedContainerID, "onbuild")
  373. if _, err := runCommand(commitCmd); err != nil {
  374. c.Fatal(err)
  375. }
  376. _, err = buildImage(name,
  377. `FROM onbuild`,
  378. true)
  379. if err != nil {
  380. if !strings.Contains(err.Error(), "maintainer isn't allowed as an ONBUILD trigger") {
  381. c.Fatalf("Wrong error %v, must be about MAINTAINER and ONBUILD in source image", err)
  382. }
  383. } else {
  384. c.Fatal("Error must not be nil")
  385. }
  386. }
  387. func (s *DockerSuite) TestBuildOnBuildForbiddenFromInSourceImage(c *check.C) {
  388. name := "testbuildonbuildforbiddenfrominsourceimage"
  389. createCmd := exec.Command(dockerBinary, "create", "busybox", "true")
  390. out, _, _, err := runCommandWithStdoutStderr(createCmd)
  391. if err != nil {
  392. c.Fatal(out, err)
  393. }
  394. cleanedContainerID := strings.TrimSpace(out)
  395. commitCmd := exec.Command(dockerBinary, "commit", "--run", "{\"OnBuild\":[\"FROM busybox\"]}", cleanedContainerID, "onbuild")
  396. if _, err := runCommand(commitCmd); err != nil {
  397. c.Fatal(err)
  398. }
  399. _, err = buildImage(name,
  400. `FROM onbuild`,
  401. true)
  402. if err != nil {
  403. if !strings.Contains(err.Error(), "from isn't allowed as an ONBUILD trigger") {
  404. c.Fatalf("Wrong error %v, must be about FROM and ONBUILD in source image", err)
  405. }
  406. } else {
  407. c.Fatal("Error must not be nil")
  408. }
  409. }
  410. func (s *DockerSuite) TestBuildOnBuildForbiddenChainedInSourceImage(c *check.C) {
  411. name := "testbuildonbuildforbiddenchainedinsourceimage"
  412. createCmd := exec.Command(dockerBinary, "create", "busybox", "true")
  413. out, _, _, err := runCommandWithStdoutStderr(createCmd)
  414. if err != nil {
  415. c.Fatal(out, err)
  416. }
  417. cleanedContainerID := strings.TrimSpace(out)
  418. commitCmd := exec.Command(dockerBinary, "commit", "--run", "{\"OnBuild\":[\"ONBUILD RUN ls\"]}", cleanedContainerID, "onbuild")
  419. if _, err := runCommand(commitCmd); err != nil {
  420. c.Fatal(err)
  421. }
  422. _, err = buildImage(name,
  423. `FROM onbuild`,
  424. true)
  425. if err != nil {
  426. if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  427. c.Fatalf("Wrong error %v, must be about chaining ONBUILD in source image", err)
  428. }
  429. } else {
  430. c.Fatal("Error must not be nil")
  431. }
  432. }
  433. func (s *DockerSuite) TestBuildOnBuildCmdEntrypointJSON(c *check.C) {
  434. name1 := "onbuildcmd"
  435. name2 := "onbuildgenerated"
  436. _, err := buildImage(name1, `
  437. FROM busybox
  438. ONBUILD CMD ["hello world"]
  439. ONBUILD ENTRYPOINT ["echo"]
  440. ONBUILD RUN ["true"]`,
  441. false)
  442. if err != nil {
  443. c.Fatal(err)
  444. }
  445. _, err = buildImage(name2, fmt.Sprintf(`FROM %s`, name1), false)
  446. if err != nil {
  447. c.Fatal(err)
  448. }
  449. out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
  450. if err != nil {
  451. c.Fatal(err)
  452. }
  453. if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
  454. c.Fatal("did not get echo output from onbuild", out)
  455. }
  456. }
  457. func (s *DockerSuite) TestBuildOnBuildEntrypointJSON(c *check.C) {
  458. name1 := "onbuildcmd"
  459. name2 := "onbuildgenerated"
  460. _, err := buildImage(name1, `
  461. FROM busybox
  462. ONBUILD ENTRYPOINT ["echo"]`,
  463. false)
  464. if err != nil {
  465. c.Fatal(err)
  466. }
  467. _, err = buildImage(name2, fmt.Sprintf("FROM %s\nCMD [\"hello world\"]\n", name1), false)
  468. if err != nil {
  469. c.Fatal(err)
  470. }
  471. out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
  472. if err != nil {
  473. c.Fatal(err)
  474. }
  475. if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
  476. c.Fatal("got malformed output from onbuild", out)
  477. }
  478. }
  479. func (s *DockerSuite) TestBuildCacheADD(c *check.C) {
  480. name := "testbuildtwoimageswithadd"
  481. server, err := fakeStorage(map[string]string{
  482. "robots.txt": "hello",
  483. "index.html": "world",
  484. })
  485. if err != nil {
  486. c.Fatal(err)
  487. }
  488. defer server.Close()
  489. if _, err := buildImage(name,
  490. fmt.Sprintf(`FROM scratch
  491. ADD %s/robots.txt /`, server.URL()),
  492. true); err != nil {
  493. c.Fatal(err)
  494. }
  495. if err != nil {
  496. c.Fatal(err)
  497. }
  498. deleteImages(name)
  499. _, out, err := buildImageWithOut(name,
  500. fmt.Sprintf(`FROM scratch
  501. ADD %s/index.html /`, server.URL()),
  502. true)
  503. if err != nil {
  504. c.Fatal(err)
  505. }
  506. if strings.Contains(out, "Using cache") {
  507. c.Fatal("2nd build used cache on ADD, it shouldn't")
  508. }
  509. }
  510. func (s *DockerSuite) TestBuildLastModified(c *check.C) {
  511. name := "testbuildlastmodified"
  512. server, err := fakeStorage(map[string]string{
  513. "file": "hello",
  514. })
  515. if err != nil {
  516. c.Fatal(err)
  517. }
  518. defer server.Close()
  519. var out, out2 string
  520. dFmt := `FROM busybox
  521. ADD %s/file /
  522. RUN ls -le /file`
  523. dockerfile := fmt.Sprintf(dFmt, server.URL())
  524. if _, out, err = buildImageWithOut(name, dockerfile, false); err != nil {
  525. c.Fatal(err)
  526. }
  527. originMTime := regexp.MustCompile(`root.*/file.*\n`).FindString(out)
  528. // Make sure our regexp is correct
  529. if strings.Index(originMTime, "/file") < 0 {
  530. c.Fatalf("Missing ls info on 'file':\n%s", out)
  531. }
  532. // Build it again and make sure the mtime of the file didn't change.
  533. // Wait a few seconds to make sure the time changed enough to notice
  534. time.Sleep(2 * time.Second)
  535. if _, out2, err = buildImageWithOut(name, dockerfile, false); err != nil {
  536. c.Fatal(err)
  537. }
  538. newMTime := regexp.MustCompile(`root.*/file.*\n`).FindString(out2)
  539. if newMTime != originMTime {
  540. c.Fatalf("MTime changed:\nOrigin:%s\nNew:%s", originMTime, newMTime)
  541. }
  542. // Now 'touch' the file and make sure the timestamp DID change this time
  543. // Create a new fakeStorage instead of just using Add() to help windows
  544. server, err = fakeStorage(map[string]string{
  545. "file": "hello",
  546. })
  547. if err != nil {
  548. c.Fatal(err)
  549. }
  550. defer server.Close()
  551. dockerfile = fmt.Sprintf(dFmt, server.URL())
  552. if _, out2, err = buildImageWithOut(name, dockerfile, false); err != nil {
  553. c.Fatal(err)
  554. }
  555. newMTime = regexp.MustCompile(`root.*/file.*\n`).FindString(out2)
  556. if newMTime == originMTime {
  557. c.Fatalf("MTime didn't change:\nOrigin:%s\nNew:%s", originMTime, newMTime)
  558. }
  559. }
  560. func (s *DockerSuite) TestBuildSixtySteps(c *check.C) {
  561. name := "foobuildsixtysteps"
  562. ctx, err := fakeContext("FROM scratch\n"+strings.Repeat("ADD foo /\n", 60),
  563. map[string]string{
  564. "foo": "test1",
  565. })
  566. if err != nil {
  567. c.Fatal(err)
  568. }
  569. defer ctx.Close()
  570. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  571. c.Fatal(err)
  572. }
  573. }
  574. func (s *DockerSuite) TestBuildAddSingleFileToRoot(c *check.C) {
  575. name := "testaddimg"
  576. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  577. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  578. RUN echo 'dockerio:x:1001:' >> /etc/group
  579. RUN touch /exists
  580. RUN chown dockerio.dockerio /exists
  581. ADD test_file /
  582. RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  583. RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ]
  584. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  585. map[string]string{
  586. "test_file": "test1",
  587. })
  588. if err != nil {
  589. c.Fatal(err)
  590. }
  591. defer ctx.Close()
  592. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  593. c.Fatal(err)
  594. }
  595. }
  596. // Issue #3960: "ADD src ." hangs
  597. func (s *DockerSuite) TestBuildAddSingleFileToWorkdir(c *check.C) {
  598. name := "testaddsinglefiletoworkdir"
  599. ctx, err := fakeContext(`FROM busybox
  600. ADD test_file .`,
  601. map[string]string{
  602. "test_file": "test1",
  603. })
  604. if err != nil {
  605. c.Fatal(err)
  606. }
  607. defer ctx.Close()
  608. done := make(chan struct{})
  609. go func() {
  610. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  611. c.Fatal(err)
  612. }
  613. close(done)
  614. }()
  615. select {
  616. case <-time.After(5 * time.Second):
  617. c.Fatal("Build with adding to workdir timed out")
  618. case <-done:
  619. }
  620. }
  621. func (s *DockerSuite) TestBuildAddSingleFileToExistDir(c *check.C) {
  622. name := "testaddsinglefiletoexistdir"
  623. ctx, err := fakeContext(`FROM busybox
  624. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  625. RUN echo 'dockerio:x:1001:' >> /etc/group
  626. RUN mkdir /exists
  627. RUN touch /exists/exists_file
  628. RUN chown -R dockerio.dockerio /exists
  629. ADD test_file /exists/
  630. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  631. RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
  632. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  633. map[string]string{
  634. "test_file": "test1",
  635. })
  636. if err != nil {
  637. c.Fatal(err)
  638. }
  639. defer ctx.Close()
  640. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  641. c.Fatal(err)
  642. }
  643. }
  644. func (s *DockerSuite) TestBuildCopyAddMultipleFiles(c *check.C) {
  645. server, err := fakeStorage(map[string]string{
  646. "robots.txt": "hello",
  647. })
  648. if err != nil {
  649. c.Fatal(err)
  650. }
  651. defer server.Close()
  652. name := "testcopymultiplefilestofile"
  653. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  654. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  655. RUN echo 'dockerio:x:1001:' >> /etc/group
  656. RUN mkdir /exists
  657. RUN touch /exists/exists_file
  658. RUN chown -R dockerio.dockerio /exists
  659. COPY test_file1 test_file2 /exists/
  660. ADD test_file3 test_file4 %s/robots.txt /exists/
  661. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  662. RUN [ $(ls -l /exists/test_file1 | awk '{print $3":"$4}') = 'root:root' ]
  663. RUN [ $(ls -l /exists/test_file2 | awk '{print $3":"$4}') = 'root:root' ]
  664. RUN [ $(ls -l /exists/test_file3 | awk '{print $3":"$4}') = 'root:root' ]
  665. RUN [ $(ls -l /exists/test_file4 | awk '{print $3":"$4}') = 'root:root' ]
  666. RUN [ $(ls -l /exists/robots.txt | awk '{print $3":"$4}') = 'root:root' ]
  667. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  668. `, server.URL()),
  669. map[string]string{
  670. "test_file1": "test1",
  671. "test_file2": "test2",
  672. "test_file3": "test3",
  673. "test_file4": "test4",
  674. })
  675. defer ctx.Close()
  676. if err != nil {
  677. c.Fatal(err)
  678. }
  679. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  680. c.Fatal(err)
  681. }
  682. }
  683. func (s *DockerSuite) TestBuildAddMultipleFilesToFile(c *check.C) {
  684. name := "testaddmultiplefilestofile"
  685. ctx, err := fakeContext(`FROM scratch
  686. ADD file1.txt file2.txt test
  687. `,
  688. map[string]string{
  689. "file1.txt": "test1",
  690. "file2.txt": "test1",
  691. })
  692. defer ctx.Close()
  693. if err != nil {
  694. c.Fatal(err)
  695. }
  696. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  697. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  698. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  699. }
  700. }
  701. func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFile(c *check.C) {
  702. name := "testjsonaddmultiplefilestofile"
  703. ctx, err := fakeContext(`FROM scratch
  704. ADD ["file1.txt", "file2.txt", "test"]
  705. `,
  706. map[string]string{
  707. "file1.txt": "test1",
  708. "file2.txt": "test1",
  709. })
  710. defer ctx.Close()
  711. if err != nil {
  712. c.Fatal(err)
  713. }
  714. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  715. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  716. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  717. }
  718. }
  719. func (s *DockerSuite) TestBuildAddMultipleFilesToFileWild(c *check.C) {
  720. name := "testaddmultiplefilestofilewild"
  721. ctx, err := fakeContext(`FROM scratch
  722. ADD file*.txt test
  723. `,
  724. map[string]string{
  725. "file1.txt": "test1",
  726. "file2.txt": "test1",
  727. })
  728. defer ctx.Close()
  729. if err != nil {
  730. c.Fatal(err)
  731. }
  732. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  733. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  734. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  735. }
  736. }
  737. func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFileWild(c *check.C) {
  738. name := "testjsonaddmultiplefilestofilewild"
  739. ctx, err := fakeContext(`FROM scratch
  740. ADD ["file*.txt", "test"]
  741. `,
  742. map[string]string{
  743. "file1.txt": "test1",
  744. "file2.txt": "test1",
  745. })
  746. defer ctx.Close()
  747. if err != nil {
  748. c.Fatal(err)
  749. }
  750. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  751. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  752. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  753. }
  754. }
  755. func (s *DockerSuite) TestBuildCopyMultipleFilesToFile(c *check.C) {
  756. name := "testcopymultiplefilestofile"
  757. ctx, err := fakeContext(`FROM scratch
  758. COPY file1.txt file2.txt test
  759. `,
  760. map[string]string{
  761. "file1.txt": "test1",
  762. "file2.txt": "test1",
  763. })
  764. defer ctx.Close()
  765. if err != nil {
  766. c.Fatal(err)
  767. }
  768. expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
  769. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  770. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  771. }
  772. }
  773. func (s *DockerSuite) TestBuildJSONCopyMultipleFilesToFile(c *check.C) {
  774. name := "testjsoncopymultiplefilestofile"
  775. ctx, err := fakeContext(`FROM scratch
  776. COPY ["file1.txt", "file2.txt", "test"]
  777. `,
  778. map[string]string{
  779. "file1.txt": "test1",
  780. "file2.txt": "test1",
  781. })
  782. defer ctx.Close()
  783. if err != nil {
  784. c.Fatal(err)
  785. }
  786. expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
  787. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  788. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  789. }
  790. }
  791. func (s *DockerSuite) TestBuildAddFileWithWhitespace(c *check.C) {
  792. name := "testaddfilewithwhitespace"
  793. ctx, err := fakeContext(`FROM busybox
  794. RUN mkdir "/test dir"
  795. RUN mkdir "/test_dir"
  796. ADD [ "test file1", "/test_file1" ]
  797. ADD [ "test_file2", "/test file2" ]
  798. ADD [ "test file3", "/test file3" ]
  799. ADD [ "test dir/test_file4", "/test_dir/test_file4" ]
  800. ADD [ "test_dir/test_file5", "/test dir/test_file5" ]
  801. ADD [ "test dir/test_file6", "/test dir/test_file6" ]
  802. RUN [ $(cat "/test_file1") = 'test1' ]
  803. RUN [ $(cat "/test file2") = 'test2' ]
  804. RUN [ $(cat "/test file3") = 'test3' ]
  805. RUN [ $(cat "/test_dir/test_file4") = 'test4' ]
  806. RUN [ $(cat "/test dir/test_file5") = 'test5' ]
  807. RUN [ $(cat "/test dir/test_file6") = 'test6' ]`,
  808. map[string]string{
  809. "test file1": "test1",
  810. "test_file2": "test2",
  811. "test file3": "test3",
  812. "test dir/test_file4": "test4",
  813. "test_dir/test_file5": "test5",
  814. "test dir/test_file6": "test6",
  815. })
  816. defer ctx.Close()
  817. if err != nil {
  818. c.Fatal(err)
  819. }
  820. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  821. c.Fatal(err)
  822. }
  823. }
  824. func (s *DockerSuite) TestBuildCopyFileWithWhitespace(c *check.C) {
  825. name := "testcopyfilewithwhitespace"
  826. ctx, err := fakeContext(`FROM busybox
  827. RUN mkdir "/test dir"
  828. RUN mkdir "/test_dir"
  829. COPY [ "test file1", "/test_file1" ]
  830. COPY [ "test_file2", "/test file2" ]
  831. COPY [ "test file3", "/test file3" ]
  832. COPY [ "test dir/test_file4", "/test_dir/test_file4" ]
  833. COPY [ "test_dir/test_file5", "/test dir/test_file5" ]
  834. COPY [ "test dir/test_file6", "/test dir/test_file6" ]
  835. RUN [ $(cat "/test_file1") = 'test1' ]
  836. RUN [ $(cat "/test file2") = 'test2' ]
  837. RUN [ $(cat "/test file3") = 'test3' ]
  838. RUN [ $(cat "/test_dir/test_file4") = 'test4' ]
  839. RUN [ $(cat "/test dir/test_file5") = 'test5' ]
  840. RUN [ $(cat "/test dir/test_file6") = 'test6' ]`,
  841. map[string]string{
  842. "test file1": "test1",
  843. "test_file2": "test2",
  844. "test file3": "test3",
  845. "test dir/test_file4": "test4",
  846. "test_dir/test_file5": "test5",
  847. "test dir/test_file6": "test6",
  848. })
  849. defer ctx.Close()
  850. if err != nil {
  851. c.Fatal(err)
  852. }
  853. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  854. c.Fatal(err)
  855. }
  856. }
  857. func (s *DockerSuite) TestBuildAddMultipleFilesToFileWithWhitespace(c *check.C) {
  858. name := "testaddmultiplefilestofilewithwhitespace"
  859. ctx, err := fakeContext(`FROM busybox
  860. ADD [ "test file1", "test file2", "test" ]
  861. `,
  862. map[string]string{
  863. "test file1": "test1",
  864. "test file2": "test2",
  865. })
  866. defer ctx.Close()
  867. if err != nil {
  868. c.Fatal(err)
  869. }
  870. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  871. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  872. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  873. }
  874. }
  875. func (s *DockerSuite) TestBuildCopyMultipleFilesToFileWithWhitespace(c *check.C) {
  876. name := "testcopymultiplefilestofilewithwhitespace"
  877. ctx, err := fakeContext(`FROM busybox
  878. COPY [ "test file1", "test file2", "test" ]
  879. `,
  880. map[string]string{
  881. "test file1": "test1",
  882. "test file2": "test2",
  883. })
  884. defer ctx.Close()
  885. if err != nil {
  886. c.Fatal(err)
  887. }
  888. expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
  889. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  890. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  891. }
  892. }
  893. func (s *DockerSuite) TestBuildCopyWildcard(c *check.C) {
  894. name := "testcopywildcard"
  895. server, err := fakeStorage(map[string]string{
  896. "robots.txt": "hello",
  897. "index.html": "world",
  898. })
  899. if err != nil {
  900. c.Fatal(err)
  901. }
  902. defer server.Close()
  903. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  904. COPY file*.txt /tmp/
  905. RUN ls /tmp/file1.txt /tmp/file2.txt
  906. RUN mkdir /tmp1
  907. COPY dir* /tmp1/
  908. RUN ls /tmp1/dirt /tmp1/nested_file /tmp1/nested_dir/nest_nest_file
  909. RUN mkdir /tmp2
  910. ADD dir/*dir %s/robots.txt /tmp2/
  911. RUN ls /tmp2/nest_nest_file /tmp2/robots.txt
  912. `, server.URL()),
  913. map[string]string{
  914. "file1.txt": "test1",
  915. "file2.txt": "test2",
  916. "dir/nested_file": "nested file",
  917. "dir/nested_dir/nest_nest_file": "2 times nested",
  918. "dirt": "dirty",
  919. })
  920. defer ctx.Close()
  921. if err != nil {
  922. c.Fatal(err)
  923. }
  924. id1, err := buildImageFromContext(name, ctx, true)
  925. if err != nil {
  926. c.Fatal(err)
  927. }
  928. // Now make sure we use a cache the 2nd time
  929. id2, err := buildImageFromContext(name, ctx, true)
  930. if err != nil {
  931. c.Fatal(err)
  932. }
  933. if id1 != id2 {
  934. c.Fatal("didn't use the cache")
  935. }
  936. }
  937. func (s *DockerSuite) TestBuildCopyWildcardNoFind(c *check.C) {
  938. name := "testcopywildcardnofind"
  939. ctx, err := fakeContext(`FROM busybox
  940. COPY file*.txt /tmp/
  941. `, nil)
  942. defer ctx.Close()
  943. if err != nil {
  944. c.Fatal(err)
  945. }
  946. _, err = buildImageFromContext(name, ctx, true)
  947. if err == nil {
  948. c.Fatal("should have failed to find a file")
  949. }
  950. if !strings.Contains(err.Error(), "No source files were specified") {
  951. c.Fatalf("Wrong error %v, must be about no source files", err)
  952. }
  953. }
  954. func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) {
  955. name := "testcopywildcardcache"
  956. ctx, err := fakeContext(`FROM busybox
  957. COPY file1.txt /tmp/`,
  958. map[string]string{
  959. "file1.txt": "test1",
  960. })
  961. defer ctx.Close()
  962. if err != nil {
  963. c.Fatal(err)
  964. }
  965. id1, err := buildImageFromContext(name, ctx, true)
  966. if err != nil {
  967. c.Fatal(err)
  968. }
  969. // Now make sure we use a cache the 2nd time even with wild cards.
  970. // Use the same context so the file is the same and the checksum will match
  971. ctx.Add("Dockerfile", `FROM busybox
  972. COPY file*.txt /tmp/`)
  973. id2, err := buildImageFromContext(name, ctx, true)
  974. if err != nil {
  975. c.Fatal(err)
  976. }
  977. if id1 != id2 {
  978. c.Fatal("didn't use the cache")
  979. }
  980. }
  981. func (s *DockerSuite) TestBuildAddSingleFileToNonExistingDir(c *check.C) {
  982. name := "testaddsinglefiletononexistingdir"
  983. ctx, err := fakeContext(`FROM busybox
  984. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  985. RUN echo 'dockerio:x:1001:' >> /etc/group
  986. RUN touch /exists
  987. RUN chown dockerio.dockerio /exists
  988. ADD test_file /test_dir/
  989. RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  990. RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  991. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  992. map[string]string{
  993. "test_file": "test1",
  994. })
  995. if err != nil {
  996. c.Fatal(err)
  997. }
  998. defer ctx.Close()
  999. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1000. c.Fatal(err)
  1001. }
  1002. }
  1003. func (s *DockerSuite) TestBuildAddDirContentToRoot(c *check.C) {
  1004. name := "testadddircontenttoroot"
  1005. ctx, err := fakeContext(`FROM busybox
  1006. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1007. RUN echo 'dockerio:x:1001:' >> /etc/group
  1008. RUN touch /exists
  1009. RUN chown dockerio.dockerio exists
  1010. ADD test_dir /
  1011. RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1012. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1013. map[string]string{
  1014. "test_dir/test_file": "test1",
  1015. })
  1016. if err != nil {
  1017. c.Fatal(err)
  1018. }
  1019. defer ctx.Close()
  1020. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1021. c.Fatal(err)
  1022. }
  1023. }
  1024. func (s *DockerSuite) TestBuildAddDirContentToExistingDir(c *check.C) {
  1025. name := "testadddircontenttoexistingdir"
  1026. ctx, err := fakeContext(`FROM busybox
  1027. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1028. RUN echo 'dockerio:x:1001:' >> /etc/group
  1029. RUN mkdir /exists
  1030. RUN touch /exists/exists_file
  1031. RUN chown -R dockerio.dockerio /exists
  1032. ADD test_dir/ /exists/
  1033. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1034. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1035. RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1036. map[string]string{
  1037. "test_dir/test_file": "test1",
  1038. })
  1039. if err != nil {
  1040. c.Fatal(err)
  1041. }
  1042. defer ctx.Close()
  1043. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1044. c.Fatal(err)
  1045. }
  1046. }
  1047. func (s *DockerSuite) TestBuildAddWholeDirToRoot(c *check.C) {
  1048. name := "testaddwholedirtoroot"
  1049. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1050. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1051. RUN echo 'dockerio:x:1001:' >> /etc/group
  1052. RUN touch /exists
  1053. RUN chown dockerio.dockerio exists
  1054. ADD test_dir /test_dir
  1055. RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1056. RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1057. RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1058. RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ]
  1059. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1060. map[string]string{
  1061. "test_dir/test_file": "test1",
  1062. })
  1063. if err != nil {
  1064. c.Fatal(err)
  1065. }
  1066. defer ctx.Close()
  1067. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1068. c.Fatal(err)
  1069. }
  1070. }
  1071. // Testing #5941
  1072. func (s *DockerSuite) TestBuildAddEtcToRoot(c *check.C) {
  1073. name := "testaddetctoroot"
  1074. ctx, err := fakeContext(`FROM scratch
  1075. ADD . /`,
  1076. map[string]string{
  1077. "etc/test_file": "test1",
  1078. })
  1079. if err != nil {
  1080. c.Fatal(err)
  1081. }
  1082. defer ctx.Close()
  1083. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1084. c.Fatal(err)
  1085. }
  1086. }
  1087. // Testing #9401
  1088. func (s *DockerSuite) TestBuildAddPreservesFilesSpecialBits(c *check.C) {
  1089. name := "testaddpreservesfilesspecialbits"
  1090. ctx, err := fakeContext(`FROM busybox
  1091. ADD suidbin /usr/bin/suidbin
  1092. RUN chmod 4755 /usr/bin/suidbin
  1093. RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]
  1094. ADD ./data/ /
  1095. RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]`,
  1096. map[string]string{
  1097. "suidbin": "suidbin",
  1098. "/data/usr/test_file": "test1",
  1099. })
  1100. if err != nil {
  1101. c.Fatal(err)
  1102. }
  1103. defer ctx.Close()
  1104. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1105. c.Fatal(err)
  1106. }
  1107. }
  1108. func (s *DockerSuite) TestBuildCopySingleFileToRoot(c *check.C) {
  1109. name := "testcopysinglefiletoroot"
  1110. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1111. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1112. RUN echo 'dockerio:x:1001:' >> /etc/group
  1113. RUN touch /exists
  1114. RUN chown dockerio.dockerio /exists
  1115. COPY test_file /
  1116. RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1117. RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ]
  1118. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1119. map[string]string{
  1120. "test_file": "test1",
  1121. })
  1122. if err != nil {
  1123. c.Fatal(err)
  1124. }
  1125. defer ctx.Close()
  1126. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1127. c.Fatal(err)
  1128. }
  1129. }
  1130. // Issue #3960: "ADD src ." hangs - adapted for COPY
  1131. func (s *DockerSuite) TestBuildCopySingleFileToWorkdir(c *check.C) {
  1132. name := "testcopysinglefiletoworkdir"
  1133. ctx, err := fakeContext(`FROM busybox
  1134. COPY test_file .`,
  1135. map[string]string{
  1136. "test_file": "test1",
  1137. })
  1138. if err != nil {
  1139. c.Fatal(err)
  1140. }
  1141. defer ctx.Close()
  1142. done := make(chan struct{})
  1143. go func() {
  1144. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1145. c.Fatal(err)
  1146. }
  1147. close(done)
  1148. }()
  1149. select {
  1150. case <-time.After(5 * time.Second):
  1151. c.Fatal("Build with adding to workdir timed out")
  1152. case <-done:
  1153. }
  1154. }
  1155. func (s *DockerSuite) TestBuildCopySingleFileToExistDir(c *check.C) {
  1156. name := "testcopysinglefiletoexistdir"
  1157. ctx, err := fakeContext(`FROM busybox
  1158. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1159. RUN echo 'dockerio:x:1001:' >> /etc/group
  1160. RUN mkdir /exists
  1161. RUN touch /exists/exists_file
  1162. RUN chown -R dockerio.dockerio /exists
  1163. COPY test_file /exists/
  1164. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1165. RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1166. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1167. map[string]string{
  1168. "test_file": "test1",
  1169. })
  1170. if err != nil {
  1171. c.Fatal(err)
  1172. }
  1173. defer ctx.Close()
  1174. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1175. c.Fatal(err)
  1176. }
  1177. }
  1178. func (s *DockerSuite) TestBuildCopySingleFileToNonExistDir(c *check.C) {
  1179. name := "testcopysinglefiletononexistdir"
  1180. ctx, err := fakeContext(`FROM busybox
  1181. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1182. RUN echo 'dockerio:x:1001:' >> /etc/group
  1183. RUN touch /exists
  1184. RUN chown dockerio.dockerio /exists
  1185. COPY test_file /test_dir/
  1186. RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1187. RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1188. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1189. map[string]string{
  1190. "test_file": "test1",
  1191. })
  1192. if err != nil {
  1193. c.Fatal(err)
  1194. }
  1195. defer ctx.Close()
  1196. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1197. c.Fatal(err)
  1198. }
  1199. }
  1200. func (s *DockerSuite) TestBuildCopyDirContentToRoot(c *check.C) {
  1201. name := "testcopydircontenttoroot"
  1202. ctx, err := fakeContext(`FROM busybox
  1203. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1204. RUN echo 'dockerio:x:1001:' >> /etc/group
  1205. RUN touch /exists
  1206. RUN chown dockerio.dockerio exists
  1207. COPY test_dir /
  1208. RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1209. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1210. map[string]string{
  1211. "test_dir/test_file": "test1",
  1212. })
  1213. if err != nil {
  1214. c.Fatal(err)
  1215. }
  1216. defer ctx.Close()
  1217. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1218. c.Fatal(err)
  1219. }
  1220. }
  1221. func (s *DockerSuite) TestBuildCopyDirContentToExistDir(c *check.C) {
  1222. name := "testcopydircontenttoexistdir"
  1223. ctx, err := fakeContext(`FROM busybox
  1224. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1225. RUN echo 'dockerio:x:1001:' >> /etc/group
  1226. RUN mkdir /exists
  1227. RUN touch /exists/exists_file
  1228. RUN chown -R dockerio.dockerio /exists
  1229. COPY test_dir/ /exists/
  1230. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1231. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1232. RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1233. map[string]string{
  1234. "test_dir/test_file": "test1",
  1235. })
  1236. if err != nil {
  1237. c.Fatal(err)
  1238. }
  1239. defer ctx.Close()
  1240. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1241. c.Fatal(err)
  1242. }
  1243. }
  1244. func (s *DockerSuite) TestBuildCopyWholeDirToRoot(c *check.C) {
  1245. name := "testcopywholedirtoroot"
  1246. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1247. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1248. RUN echo 'dockerio:x:1001:' >> /etc/group
  1249. RUN touch /exists
  1250. RUN chown dockerio.dockerio exists
  1251. COPY test_dir /test_dir
  1252. RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1253. RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1254. RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1255. RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ]
  1256. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1257. map[string]string{
  1258. "test_dir/test_file": "test1",
  1259. })
  1260. if err != nil {
  1261. c.Fatal(err)
  1262. }
  1263. defer ctx.Close()
  1264. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1265. c.Fatal(err)
  1266. }
  1267. }
  1268. func (s *DockerSuite) TestBuildCopyEtcToRoot(c *check.C) {
  1269. name := "testcopyetctoroot"
  1270. ctx, err := fakeContext(`FROM scratch
  1271. COPY . /`,
  1272. map[string]string{
  1273. "etc/test_file": "test1",
  1274. })
  1275. if err != nil {
  1276. c.Fatal(err)
  1277. }
  1278. defer ctx.Close()
  1279. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1280. c.Fatal(err)
  1281. }
  1282. }
  1283. func (s *DockerSuite) TestBuildCopyDisallowRemote(c *check.C) {
  1284. name := "testcopydisallowremote"
  1285. _, out, err := buildImageWithOut(name, `FROM scratch
  1286. COPY https://index.docker.io/robots.txt /`,
  1287. true)
  1288. if err == nil || !strings.Contains(out, "Source can't be a URL for COPY") {
  1289. c.Fatalf("Error should be about disallowed remote source, got err: %s, out: %q", err, out)
  1290. }
  1291. }
  1292. func (s *DockerSuite) TestBuildAddBadLinks(c *check.C) {
  1293. const (
  1294. dockerfile = `
  1295. FROM scratch
  1296. ADD links.tar /
  1297. ADD foo.txt /symlink/
  1298. `
  1299. targetFile = "foo.txt"
  1300. )
  1301. var (
  1302. name = "test-link-absolute"
  1303. )
  1304. ctx, err := fakeContext(dockerfile, nil)
  1305. if err != nil {
  1306. c.Fatal(err)
  1307. }
  1308. defer ctx.Close()
  1309. tempDir, err := ioutil.TempDir("", "test-link-absolute-temp-")
  1310. if err != nil {
  1311. c.Fatalf("failed to create temporary directory: %s", tempDir)
  1312. }
  1313. defer os.RemoveAll(tempDir)
  1314. var symlinkTarget string
  1315. if runtime.GOOS == "windows" {
  1316. var driveLetter string
  1317. if abs, err := filepath.Abs(tempDir); err != nil {
  1318. c.Fatal(err)
  1319. } else {
  1320. driveLetter = abs[:1]
  1321. }
  1322. tempDirWithoutDrive := tempDir[2:]
  1323. symlinkTarget = fmt.Sprintf(`%s:\..\..\..\..\..\..\..\..\..\..\..\..%s`, driveLetter, tempDirWithoutDrive)
  1324. } else {
  1325. symlinkTarget = fmt.Sprintf("/../../../../../../../../../../../..%s", tempDir)
  1326. }
  1327. tarPath := filepath.Join(ctx.Dir, "links.tar")
  1328. nonExistingFile := filepath.Join(tempDir, targetFile)
  1329. fooPath := filepath.Join(ctx.Dir, targetFile)
  1330. tarOut, err := os.Create(tarPath)
  1331. if err != nil {
  1332. c.Fatal(err)
  1333. }
  1334. tarWriter := tar.NewWriter(tarOut)
  1335. header := &tar.Header{
  1336. Name: "symlink",
  1337. Typeflag: tar.TypeSymlink,
  1338. Linkname: symlinkTarget,
  1339. Mode: 0755,
  1340. Uid: 0,
  1341. Gid: 0,
  1342. }
  1343. err = tarWriter.WriteHeader(header)
  1344. if err != nil {
  1345. c.Fatal(err)
  1346. }
  1347. tarWriter.Close()
  1348. tarOut.Close()
  1349. foo, err := os.Create(fooPath)
  1350. if err != nil {
  1351. c.Fatal(err)
  1352. }
  1353. defer foo.Close()
  1354. if _, err := foo.WriteString("test"); err != nil {
  1355. c.Fatal(err)
  1356. }
  1357. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1358. c.Fatal(err)
  1359. }
  1360. if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1361. c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1362. }
  1363. }
  1364. func (s *DockerSuite) TestBuildAddBadLinksVolume(c *check.C) {
  1365. const (
  1366. dockerfileTemplate = `
  1367. FROM busybox
  1368. RUN ln -s /../../../../../../../../%s /x
  1369. VOLUME /x
  1370. ADD foo.txt /x/`
  1371. targetFile = "foo.txt"
  1372. )
  1373. var (
  1374. name = "test-link-absolute-volume"
  1375. dockerfile = ""
  1376. )
  1377. tempDir, err := ioutil.TempDir("", "test-link-absolute-volume-temp-")
  1378. if err != nil {
  1379. c.Fatalf("failed to create temporary directory: %s", tempDir)
  1380. }
  1381. defer os.RemoveAll(tempDir)
  1382. dockerfile = fmt.Sprintf(dockerfileTemplate, tempDir)
  1383. nonExistingFile := filepath.Join(tempDir, targetFile)
  1384. ctx, err := fakeContext(dockerfile, nil)
  1385. if err != nil {
  1386. c.Fatal(err)
  1387. }
  1388. defer ctx.Close()
  1389. fooPath := filepath.Join(ctx.Dir, targetFile)
  1390. foo, err := os.Create(fooPath)
  1391. if err != nil {
  1392. c.Fatal(err)
  1393. }
  1394. defer foo.Close()
  1395. if _, err := foo.WriteString("test"); err != nil {
  1396. c.Fatal(err)
  1397. }
  1398. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1399. c.Fatal(err)
  1400. }
  1401. if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1402. c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1403. }
  1404. }
  1405. // Issue #5270 - ensure we throw a better error than "unexpected EOF"
  1406. // when we can't access files in the context.
  1407. func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) {
  1408. testRequires(c, UnixCli) // test uses chown/chmod: not available on windows
  1409. {
  1410. name := "testbuildinaccessiblefiles"
  1411. ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"fileWithoutReadAccess": "foo"})
  1412. if err != nil {
  1413. c.Fatal(err)
  1414. }
  1415. defer ctx.Close()
  1416. // This is used to ensure we detect inaccessible files early during build in the cli client
  1417. pathToFileWithoutReadAccess := filepath.Join(ctx.Dir, "fileWithoutReadAccess")
  1418. if err = os.Chown(pathToFileWithoutReadAccess, 0, 0); err != nil {
  1419. c.Fatalf("failed to chown file to root: %s", err)
  1420. }
  1421. if err = os.Chmod(pathToFileWithoutReadAccess, 0700); err != nil {
  1422. c.Fatalf("failed to chmod file to 700: %s", err)
  1423. }
  1424. buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1425. buildCmd.Dir = ctx.Dir
  1426. out, _, err := runCommandWithOutput(buildCmd)
  1427. if err == nil {
  1428. c.Fatalf("build should have failed: %s %s", err, out)
  1429. }
  1430. // check if we've detected the failure before we started building
  1431. if !strings.Contains(out, "no permission to read from ") {
  1432. c.Fatalf("output should've contained the string: no permission to read from but contained: %s", out)
  1433. }
  1434. if !strings.Contains(out, "Error checking context is accessible") {
  1435. c.Fatalf("output should've contained the string: Error checking context is accessible")
  1436. }
  1437. }
  1438. {
  1439. name := "testbuildinaccessibledirectory"
  1440. ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"directoryWeCantStat/bar": "foo"})
  1441. if err != nil {
  1442. c.Fatal(err)
  1443. }
  1444. defer ctx.Close()
  1445. // This is used to ensure we detect inaccessible directories early during build in the cli client
  1446. pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1447. pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1448. if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1449. c.Fatalf("failed to chown directory to root: %s", err)
  1450. }
  1451. if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1452. c.Fatalf("failed to chmod directory to 444: %s", err)
  1453. }
  1454. if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1455. c.Fatalf("failed to chmod file to 700: %s", err)
  1456. }
  1457. buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1458. buildCmd.Dir = ctx.Dir
  1459. out, _, err := runCommandWithOutput(buildCmd)
  1460. if err == nil {
  1461. c.Fatalf("build should have failed: %s %s", err, out)
  1462. }
  1463. // check if we've detected the failure before we started building
  1464. if !strings.Contains(out, "can't stat") {
  1465. c.Fatalf("output should've contained the string: can't access %s", out)
  1466. }
  1467. if !strings.Contains(out, "Error checking context is accessible") {
  1468. c.Fatalf("output should've contained the string: Error checking context is accessible")
  1469. }
  1470. }
  1471. {
  1472. name := "testlinksok"
  1473. ctx, err := fakeContext("FROM scratch\nADD . /foo/", nil)
  1474. if err != nil {
  1475. c.Fatal(err)
  1476. }
  1477. defer ctx.Close()
  1478. target := "../../../../../../../../../../../../../../../../../../../azA"
  1479. if err := os.Symlink(filepath.Join(ctx.Dir, "g"), target); err != nil {
  1480. c.Fatal(err)
  1481. }
  1482. defer os.Remove(target)
  1483. // This is used to ensure we don't follow links when checking if everything in the context is accessible
  1484. // This test doesn't require that we run commands as an unprivileged user
  1485. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1486. c.Fatal(err)
  1487. }
  1488. }
  1489. {
  1490. name := "testbuildignoredinaccessible"
  1491. ctx, err := fakeContext("FROM scratch\nADD . /foo/",
  1492. map[string]string{
  1493. "directoryWeCantStat/bar": "foo",
  1494. ".dockerignore": "directoryWeCantStat",
  1495. })
  1496. if err != nil {
  1497. c.Fatal(err)
  1498. }
  1499. defer ctx.Close()
  1500. // This is used to ensure we don't try to add inaccessible files when they are ignored by a .dockerignore pattern
  1501. pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1502. pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1503. if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1504. c.Fatalf("failed to chown directory to root: %s", err)
  1505. }
  1506. if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1507. c.Fatalf("failed to chmod directory to 755: %s", err)
  1508. }
  1509. if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1510. c.Fatalf("failed to chmod file to 444: %s", err)
  1511. }
  1512. buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1513. buildCmd.Dir = ctx.Dir
  1514. if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  1515. c.Fatalf("build should have worked: %s %s", err, out)
  1516. }
  1517. }
  1518. }
  1519. func (s *DockerSuite) TestBuildForceRm(c *check.C) {
  1520. containerCountBefore, err := getContainerCount()
  1521. if err != nil {
  1522. c.Fatalf("failed to get the container count: %s", err)
  1523. }
  1524. name := "testbuildforcerm"
  1525. ctx, err := fakeContext("FROM scratch\nRUN true\nRUN thiswillfail", nil)
  1526. if err != nil {
  1527. c.Fatal(err)
  1528. }
  1529. defer ctx.Close()
  1530. buildCmd := exec.Command(dockerBinary, "build", "-t", name, "--force-rm", ".")
  1531. buildCmd.Dir = ctx.Dir
  1532. if out, _, err := runCommandWithOutput(buildCmd); err == nil {
  1533. c.Fatalf("failed to build the image: %s, %v", out, err)
  1534. }
  1535. containerCountAfter, err := getContainerCount()
  1536. if err != nil {
  1537. c.Fatalf("failed to get the container count: %s", err)
  1538. }
  1539. if containerCountBefore != containerCountAfter {
  1540. c.Fatalf("--force-rm shouldn't have left containers behind")
  1541. }
  1542. }
  1543. // Test that an infinite sleep during a build is killed if the client disconnects.
  1544. // This test is fairly hairy because there are lots of ways to race.
  1545. // Strategy:
  1546. // * Monitor the output of docker events starting from before
  1547. // * Run a 1-year-long sleep from a docker build.
  1548. // * When docker events sees container start, close the "docker build" command
  1549. // * Wait for docker events to emit a dying event.
  1550. func (s *DockerSuite) TestBuildCancelationKillsSleep(c *check.C) {
  1551. var wg sync.WaitGroup
  1552. defer wg.Wait()
  1553. name := "testbuildcancelation"
  1554. // (Note: one year, will never finish)
  1555. ctx, err := fakeContext("FROM busybox\nRUN sleep 31536000", nil)
  1556. if err != nil {
  1557. c.Fatal(err)
  1558. }
  1559. defer ctx.Close()
  1560. finish := make(chan struct{})
  1561. defer close(finish)
  1562. eventStart := make(chan struct{})
  1563. eventDie := make(chan struct{})
  1564. containerID := make(chan string)
  1565. startEpoch := daemonTime(c).Unix()
  1566. wg.Add(1)
  1567. // Goroutine responsible for watching start/die events from `docker events`
  1568. go func() {
  1569. defer wg.Done()
  1570. // Watch for events since epoch.
  1571. eventsCmd := exec.Command(
  1572. dockerBinary, "events",
  1573. "--since", strconv.FormatInt(startEpoch, 10))
  1574. stdout, err := eventsCmd.StdoutPipe()
  1575. err = eventsCmd.Start()
  1576. if err != nil {
  1577. c.Fatalf("failed to start 'docker events': %s", err)
  1578. }
  1579. go func() {
  1580. <-finish
  1581. eventsCmd.Process.Kill()
  1582. }()
  1583. cid := <-containerID
  1584. matchStart := regexp.MustCompile(cid + `(.*) start$`)
  1585. matchDie := regexp.MustCompile(cid + `(.*) die$`)
  1586. //
  1587. // Read lines of `docker events` looking for container start and stop.
  1588. //
  1589. scanner := bufio.NewScanner(stdout)
  1590. for scanner.Scan() {
  1591. switch {
  1592. case matchStart.MatchString(scanner.Text()):
  1593. close(eventStart)
  1594. case matchDie.MatchString(scanner.Text()):
  1595. close(eventDie)
  1596. }
  1597. }
  1598. err = eventsCmd.Wait()
  1599. if err != nil && !IsKilled(err) {
  1600. c.Fatalf("docker events had bad exit status: %s", err)
  1601. }
  1602. }()
  1603. buildCmd := exec.Command(dockerBinary, "build", "-t", name, ".")
  1604. buildCmd.Dir = ctx.Dir
  1605. stdoutBuild, err := buildCmd.StdoutPipe()
  1606. err = buildCmd.Start()
  1607. if err != nil {
  1608. c.Fatalf("failed to run build: %s", err)
  1609. }
  1610. matchCID := regexp.MustCompile("Running in ")
  1611. scanner := bufio.NewScanner(stdoutBuild)
  1612. for scanner.Scan() {
  1613. line := scanner.Text()
  1614. if ok := matchCID.MatchString(line); ok {
  1615. containerID <- line[len(line)-12:]
  1616. break
  1617. }
  1618. }
  1619. select {
  1620. case <-time.After(5 * time.Second):
  1621. c.Fatal("failed to observe build container start in timely fashion")
  1622. case <-eventStart:
  1623. // Proceeds from here when we see the container fly past in the
  1624. // output of "docker events".
  1625. // Now we know the container is running.
  1626. }
  1627. // Send a kill to the `docker build` command.
  1628. // Causes the underlying build to be cancelled due to socket close.
  1629. err = buildCmd.Process.Kill()
  1630. if err != nil {
  1631. c.Fatalf("error killing build command: %s", err)
  1632. }
  1633. // Get the exit status of `docker build`, check it exited because killed.
  1634. err = buildCmd.Wait()
  1635. if err != nil && !IsKilled(err) {
  1636. c.Fatalf("wait failed during build run: %T %s", err, err)
  1637. }
  1638. select {
  1639. case <-time.After(5 * time.Second):
  1640. // If we don't get here in a timely fashion, it wasn't killed.
  1641. c.Fatal("container cancel did not succeed")
  1642. case <-eventDie:
  1643. // We saw the container shut down in the `docker events` stream,
  1644. // as expected.
  1645. }
  1646. }
  1647. func (s *DockerSuite) TestBuildRm(c *check.C) {
  1648. name := "testbuildrm"
  1649. ctx, err := fakeContext("FROM scratch\nADD foo /\nADD foo /", map[string]string{"foo": "bar"})
  1650. if err != nil {
  1651. c.Fatal(err)
  1652. }
  1653. defer ctx.Close()
  1654. {
  1655. containerCountBefore, err := getContainerCount()
  1656. if err != nil {
  1657. c.Fatalf("failed to get the container count: %s", err)
  1658. }
  1659. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--rm", "-t", name, ".")
  1660. if err != nil {
  1661. c.Fatal("failed to build the image", out)
  1662. }
  1663. containerCountAfter, err := getContainerCount()
  1664. if err != nil {
  1665. c.Fatalf("failed to get the container count: %s", err)
  1666. }
  1667. if containerCountBefore != containerCountAfter {
  1668. c.Fatalf("-rm shouldn't have left containers behind")
  1669. }
  1670. deleteImages(name)
  1671. }
  1672. {
  1673. containerCountBefore, err := getContainerCount()
  1674. if err != nil {
  1675. c.Fatalf("failed to get the container count: %s", err)
  1676. }
  1677. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name, ".")
  1678. if err != nil {
  1679. c.Fatal("failed to build the image", out)
  1680. }
  1681. containerCountAfter, err := getContainerCount()
  1682. if err != nil {
  1683. c.Fatalf("failed to get the container count: %s", err)
  1684. }
  1685. if containerCountBefore != containerCountAfter {
  1686. c.Fatalf("--rm shouldn't have left containers behind")
  1687. }
  1688. deleteImages(name)
  1689. }
  1690. {
  1691. containerCountBefore, err := getContainerCount()
  1692. if err != nil {
  1693. c.Fatalf("failed to get the container count: %s", err)
  1694. }
  1695. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--rm=false", "-t", name, ".")
  1696. if err != nil {
  1697. c.Fatal("failed to build the image", out)
  1698. }
  1699. containerCountAfter, err := getContainerCount()
  1700. if err != nil {
  1701. c.Fatalf("failed to get the container count: %s", err)
  1702. }
  1703. if containerCountBefore == containerCountAfter {
  1704. c.Fatalf("--rm=false should have left containers behind")
  1705. }
  1706. deleteImages(name)
  1707. }
  1708. }
  1709. func (s *DockerSuite) TestBuildWithVolumes(c *check.C) {
  1710. var (
  1711. result map[string]map[string]struct{}
  1712. name = "testbuildvolumes"
  1713. emptyMap = make(map[string]struct{})
  1714. expected = map[string]map[string]struct{}{
  1715. "/test1": emptyMap,
  1716. "/test2": emptyMap,
  1717. "/test3": emptyMap,
  1718. "/test4": emptyMap,
  1719. "/test5": emptyMap,
  1720. "/test6": emptyMap,
  1721. "[/test7": emptyMap,
  1722. "/test8]": emptyMap,
  1723. }
  1724. )
  1725. _, err := buildImage(name,
  1726. `FROM scratch
  1727. VOLUME /test1
  1728. VOLUME /test2
  1729. VOLUME /test3 /test4
  1730. VOLUME ["/test5", "/test6"]
  1731. VOLUME [/test7 /test8]
  1732. `,
  1733. true)
  1734. if err != nil {
  1735. c.Fatal(err)
  1736. }
  1737. res, err := inspectFieldJSON(name, "Config.Volumes")
  1738. if err != nil {
  1739. c.Fatal(err)
  1740. }
  1741. err = unmarshalJSON([]byte(res), &result)
  1742. if err != nil {
  1743. c.Fatal(err)
  1744. }
  1745. equal := reflect.DeepEqual(&result, &expected)
  1746. if !equal {
  1747. c.Fatalf("Volumes %s, expected %s", result, expected)
  1748. }
  1749. }
  1750. func (s *DockerSuite) TestBuildMaintainer(c *check.C) {
  1751. name := "testbuildmaintainer"
  1752. expected := "dockerio"
  1753. _, err := buildImage(name,
  1754. `FROM scratch
  1755. MAINTAINER dockerio`,
  1756. true)
  1757. if err != nil {
  1758. c.Fatal(err)
  1759. }
  1760. res, err := inspectField(name, "Author")
  1761. if err != nil {
  1762. c.Fatal(err)
  1763. }
  1764. if res != expected {
  1765. c.Fatalf("Maintainer %s, expected %s", res, expected)
  1766. }
  1767. }
  1768. func (s *DockerSuite) TestBuildUser(c *check.C) {
  1769. name := "testbuilduser"
  1770. expected := "dockerio"
  1771. _, err := buildImage(name,
  1772. `FROM busybox
  1773. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1774. USER dockerio
  1775. RUN [ $(whoami) = 'dockerio' ]`,
  1776. true)
  1777. if err != nil {
  1778. c.Fatal(err)
  1779. }
  1780. res, err := inspectField(name, "Config.User")
  1781. if err != nil {
  1782. c.Fatal(err)
  1783. }
  1784. if res != expected {
  1785. c.Fatalf("User %s, expected %s", res, expected)
  1786. }
  1787. }
  1788. func (s *DockerSuite) TestBuildRelativeWorkdir(c *check.C) {
  1789. name := "testbuildrelativeworkdir"
  1790. expected := "/test2/test3"
  1791. _, err := buildImage(name,
  1792. `FROM busybox
  1793. RUN [ "$PWD" = '/' ]
  1794. WORKDIR test1
  1795. RUN [ "$PWD" = '/test1' ]
  1796. WORKDIR /test2
  1797. RUN [ "$PWD" = '/test2' ]
  1798. WORKDIR test3
  1799. RUN [ "$PWD" = '/test2/test3' ]`,
  1800. true)
  1801. if err != nil {
  1802. c.Fatal(err)
  1803. }
  1804. res, err := inspectField(name, "Config.WorkingDir")
  1805. if err != nil {
  1806. c.Fatal(err)
  1807. }
  1808. if res != expected {
  1809. c.Fatalf("Workdir %s, expected %s", res, expected)
  1810. }
  1811. }
  1812. func (s *DockerSuite) TestBuildWorkdirWithEnvVariables(c *check.C) {
  1813. name := "testbuildworkdirwithenvvariables"
  1814. expected := "/test1/test2"
  1815. _, err := buildImage(name,
  1816. `FROM busybox
  1817. ENV DIRPATH /test1
  1818. ENV SUBDIRNAME test2
  1819. WORKDIR $DIRPATH
  1820. WORKDIR $SUBDIRNAME/$MISSING_VAR`,
  1821. true)
  1822. if err != nil {
  1823. c.Fatal(err)
  1824. }
  1825. res, err := inspectField(name, "Config.WorkingDir")
  1826. if err != nil {
  1827. c.Fatal(err)
  1828. }
  1829. if res != expected {
  1830. c.Fatalf("Workdir %s, expected %s", res, expected)
  1831. }
  1832. }
  1833. func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) {
  1834. name := "testbuildrelativecopy"
  1835. dockerfile := `
  1836. FROM busybox
  1837. WORKDIR /test1
  1838. WORKDIR test2
  1839. RUN [ "$PWD" = '/test1/test2' ]
  1840. COPY foo ./
  1841. RUN [ "$(cat /test1/test2/foo)" = 'hello' ]
  1842. ADD foo ./bar/baz
  1843. RUN [ "$(cat /test1/test2/bar/baz)" = 'hello' ]
  1844. COPY foo ./bar/baz2
  1845. RUN [ "$(cat /test1/test2/bar/baz2)" = 'hello' ]
  1846. WORKDIR ..
  1847. COPY foo ./
  1848. RUN [ "$(cat /test1/foo)" = 'hello' ]
  1849. COPY foo /test3/
  1850. RUN [ "$(cat /test3/foo)" = 'hello' ]
  1851. WORKDIR /test4
  1852. COPY . .
  1853. RUN [ "$(cat /test4/foo)" = 'hello' ]
  1854. WORKDIR /test5/test6
  1855. COPY foo ../
  1856. RUN [ "$(cat /test5/foo)" = 'hello' ]
  1857. `
  1858. ctx, err := fakeContext(dockerfile, map[string]string{
  1859. "foo": "hello",
  1860. })
  1861. defer ctx.Close()
  1862. if err != nil {
  1863. c.Fatal(err)
  1864. }
  1865. _, err = buildImageFromContext(name, ctx, false)
  1866. if err != nil {
  1867. c.Fatal(err)
  1868. }
  1869. }
  1870. func (s *DockerSuite) TestBuildEnv(c *check.C) {
  1871. name := "testbuildenv"
  1872. expected := "[PATH=/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]"
  1873. _, err := buildImage(name,
  1874. `FROM busybox
  1875. ENV PATH /test:$PATH
  1876. ENV PORT 2375
  1877. RUN [ $(env | grep PORT) = 'PORT=2375' ]`,
  1878. true)
  1879. if err != nil {
  1880. c.Fatal(err)
  1881. }
  1882. res, err := inspectField(name, "Config.Env")
  1883. if err != nil {
  1884. c.Fatal(err)
  1885. }
  1886. if res != expected {
  1887. c.Fatalf("Env %s, expected %s", res, expected)
  1888. }
  1889. }
  1890. func (s *DockerSuite) TestBuildContextCleanup(c *check.C) {
  1891. testRequires(c, SameHostDaemon)
  1892. name := "testbuildcontextcleanup"
  1893. entries, err := ioutil.ReadDir("/var/lib/docker/tmp")
  1894. if err != nil {
  1895. c.Fatalf("failed to list contents of tmp dir: %s", err)
  1896. }
  1897. _, err = buildImage(name,
  1898. `FROM scratch
  1899. ENTRYPOINT ["/bin/echo"]`,
  1900. true)
  1901. if err != nil {
  1902. c.Fatal(err)
  1903. }
  1904. entriesFinal, err := ioutil.ReadDir("/var/lib/docker/tmp")
  1905. if err != nil {
  1906. c.Fatalf("failed to list contents of tmp dir: %s", err)
  1907. }
  1908. if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  1909. c.Fatalf("context should have been deleted, but wasn't")
  1910. }
  1911. }
  1912. func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) {
  1913. testRequires(c, SameHostDaemon)
  1914. name := "testbuildcontextcleanup"
  1915. entries, err := ioutil.ReadDir("/var/lib/docker/tmp")
  1916. if err != nil {
  1917. c.Fatalf("failed to list contents of tmp dir: %s", err)
  1918. }
  1919. _, err = buildImage(name,
  1920. `FROM scratch
  1921. RUN /non/existing/command`,
  1922. true)
  1923. if err == nil {
  1924. c.Fatalf("expected build to fail, but it didn't")
  1925. }
  1926. entriesFinal, err := ioutil.ReadDir("/var/lib/docker/tmp")
  1927. if err != nil {
  1928. c.Fatalf("failed to list contents of tmp dir: %s", err)
  1929. }
  1930. if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  1931. c.Fatalf("context should have been deleted, but wasn't")
  1932. }
  1933. }
  1934. func (s *DockerSuite) TestBuildCmd(c *check.C) {
  1935. name := "testbuildcmd"
  1936. expected := "{[/bin/echo Hello World]}"
  1937. _, err := buildImage(name,
  1938. `FROM scratch
  1939. CMD ["/bin/echo", "Hello World"]`,
  1940. true)
  1941. if err != nil {
  1942. c.Fatal(err)
  1943. }
  1944. res, err := inspectField(name, "Config.Cmd")
  1945. if err != nil {
  1946. c.Fatal(err)
  1947. }
  1948. if res != expected {
  1949. c.Fatalf("Cmd %s, expected %s", res, expected)
  1950. }
  1951. }
  1952. func (s *DockerSuite) TestBuildExpose(c *check.C) {
  1953. name := "testbuildexpose"
  1954. expected := "map[2375/tcp:{}]"
  1955. _, err := buildImage(name,
  1956. `FROM scratch
  1957. EXPOSE 2375`,
  1958. true)
  1959. if err != nil {
  1960. c.Fatal(err)
  1961. }
  1962. res, err := inspectField(name, "Config.ExposedPorts")
  1963. if err != nil {
  1964. c.Fatal(err)
  1965. }
  1966. if res != expected {
  1967. c.Fatalf("Exposed ports %s, expected %s", res, expected)
  1968. }
  1969. }
  1970. func (s *DockerSuite) TestBuildExposeMorePorts(c *check.C) {
  1971. // start building docker file with a large number of ports
  1972. portList := make([]string, 50)
  1973. line := make([]string, 100)
  1974. expectedPorts := make([]int, len(portList)*len(line))
  1975. for i := 0; i < len(portList); i++ {
  1976. for j := 0; j < len(line); j++ {
  1977. p := i*len(line) + j + 1
  1978. line[j] = strconv.Itoa(p)
  1979. expectedPorts[p-1] = p
  1980. }
  1981. if i == len(portList)-1 {
  1982. portList[i] = strings.Join(line, " ")
  1983. } else {
  1984. portList[i] = strings.Join(line, " ") + ` \`
  1985. }
  1986. }
  1987. dockerfile := `FROM scratch
  1988. EXPOSE {{range .}} {{.}}
  1989. {{end}}`
  1990. tmpl := template.Must(template.New("dockerfile").Parse(dockerfile))
  1991. buf := bytes.NewBuffer(nil)
  1992. tmpl.Execute(buf, portList)
  1993. name := "testbuildexpose"
  1994. _, err := buildImage(name, buf.String(), true)
  1995. if err != nil {
  1996. c.Fatal(err)
  1997. }
  1998. // check if all the ports are saved inside Config.ExposedPorts
  1999. res, err := inspectFieldJSON(name, "Config.ExposedPorts")
  2000. if err != nil {
  2001. c.Fatal(err)
  2002. }
  2003. var exposedPorts map[string]interface{}
  2004. if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
  2005. c.Fatal(err)
  2006. }
  2007. for _, p := range expectedPorts {
  2008. ep := fmt.Sprintf("%d/tcp", p)
  2009. if _, ok := exposedPorts[ep]; !ok {
  2010. c.Errorf("Port(%s) is not exposed", ep)
  2011. } else {
  2012. delete(exposedPorts, ep)
  2013. }
  2014. }
  2015. if len(exposedPorts) != 0 {
  2016. c.Errorf("Unexpected extra exposed ports %v", exposedPorts)
  2017. }
  2018. }
  2019. func (s *DockerSuite) TestBuildExposeOrder(c *check.C) {
  2020. buildID := func(name, exposed string) string {
  2021. _, err := buildImage(name, fmt.Sprintf(`FROM scratch
  2022. EXPOSE %s`, exposed), true)
  2023. if err != nil {
  2024. c.Fatal(err)
  2025. }
  2026. id, err := inspectField(name, "Id")
  2027. if err != nil {
  2028. c.Fatal(err)
  2029. }
  2030. return id
  2031. }
  2032. id1 := buildID("testbuildexpose1", "80 2375")
  2033. id2 := buildID("testbuildexpose2", "2375 80")
  2034. if id1 != id2 {
  2035. c.Errorf("EXPOSE should invalidate the cache only when ports actually changed")
  2036. }
  2037. }
  2038. func (s *DockerSuite) TestBuildExposeUpperCaseProto(c *check.C) {
  2039. name := "testbuildexposeuppercaseproto"
  2040. expected := "map[5678/udp:{}]"
  2041. _, err := buildImage(name,
  2042. `FROM scratch
  2043. EXPOSE 5678/UDP`,
  2044. true)
  2045. if err != nil {
  2046. c.Fatal(err)
  2047. }
  2048. res, err := inspectField(name, "Config.ExposedPorts")
  2049. if err != nil {
  2050. c.Fatal(err)
  2051. }
  2052. if res != expected {
  2053. c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2054. }
  2055. }
  2056. func (s *DockerSuite) TestBuildExposeHostPort(c *check.C) {
  2057. // start building docker file with ip:hostPort:containerPort
  2058. name := "testbuildexpose"
  2059. expected := "map[5678/tcp:{}]"
  2060. _, out, err := buildImageWithOut(name,
  2061. `FROM scratch
  2062. EXPOSE 192.168.1.2:2375:5678`,
  2063. true)
  2064. if err != nil {
  2065. c.Fatal(err)
  2066. }
  2067. if !strings.Contains(out, "to map host ports to container ports (ip:hostPort:containerPort) is deprecated.") {
  2068. c.Fatal("Missing warning message")
  2069. }
  2070. res, err := inspectField(name, "Config.ExposedPorts")
  2071. if err != nil {
  2072. c.Fatal(err)
  2073. }
  2074. if res != expected {
  2075. c.Fatalf("Exposed ports %s, expected %s", res, expected)
  2076. }
  2077. }
  2078. func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
  2079. name := "testbuildentrypointinheritance"
  2080. name2 := "testbuildentrypointinheritance2"
  2081. _, err := buildImage(name,
  2082. `FROM busybox
  2083. ENTRYPOINT ["/bin/echo"]`,
  2084. true)
  2085. if err != nil {
  2086. c.Fatal(err)
  2087. }
  2088. res, err := inspectField(name, "Config.Entrypoint")
  2089. if err != nil {
  2090. c.Fatal(err)
  2091. }
  2092. expected := "{[/bin/echo]}"
  2093. if res != expected {
  2094. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2095. }
  2096. _, err = buildImage(name2,
  2097. fmt.Sprintf(`FROM %s
  2098. ENTRYPOINT []`, name),
  2099. true)
  2100. if err != nil {
  2101. c.Fatal(err)
  2102. }
  2103. res, err = inspectField(name2, "Config.Entrypoint")
  2104. if err != nil {
  2105. c.Fatal(err)
  2106. }
  2107. expected = "{[]}"
  2108. if res != expected {
  2109. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2110. }
  2111. }
  2112. func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) {
  2113. name := "testbuildentrypoint"
  2114. expected := "{[]}"
  2115. _, err := buildImage(name,
  2116. `FROM busybox
  2117. ENTRYPOINT []`,
  2118. true)
  2119. if err != nil {
  2120. c.Fatal(err)
  2121. }
  2122. res, err := inspectField(name, "Config.Entrypoint")
  2123. if err != nil {
  2124. c.Fatal(err)
  2125. }
  2126. if res != expected {
  2127. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2128. }
  2129. }
  2130. func (s *DockerSuite) TestBuildEntrypoint(c *check.C) {
  2131. name := "testbuildentrypoint"
  2132. expected := "{[/bin/echo]}"
  2133. _, err := buildImage(name,
  2134. `FROM scratch
  2135. ENTRYPOINT ["/bin/echo"]`,
  2136. true)
  2137. if err != nil {
  2138. c.Fatal(err)
  2139. }
  2140. res, err := inspectField(name, "Config.Entrypoint")
  2141. if err != nil {
  2142. c.Fatal(err)
  2143. }
  2144. if res != expected {
  2145. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2146. }
  2147. }
  2148. // #6445 ensure ONBUILD triggers aren't committed to grandchildren
  2149. func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) {
  2150. var (
  2151. out2, out3 string
  2152. )
  2153. {
  2154. name1 := "testonbuildtrigger1"
  2155. dockerfile1 := `
  2156. FROM busybox
  2157. RUN echo "GRANDPARENT"
  2158. ONBUILD RUN echo "ONBUILD PARENT"
  2159. `
  2160. ctx, err := fakeContext(dockerfile1, nil)
  2161. if err != nil {
  2162. c.Fatal(err)
  2163. }
  2164. defer ctx.Close()
  2165. out1, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name1, ".")
  2166. if err != nil {
  2167. c.Fatalf("build failed to complete: %s, %v", out1, err)
  2168. }
  2169. }
  2170. {
  2171. name2 := "testonbuildtrigger2"
  2172. dockerfile2 := `
  2173. FROM testonbuildtrigger1
  2174. `
  2175. ctx, err := fakeContext(dockerfile2, nil)
  2176. if err != nil {
  2177. c.Fatal(err)
  2178. }
  2179. defer ctx.Close()
  2180. out2, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name2, ".")
  2181. if err != nil {
  2182. c.Fatalf("build failed to complete: %s, %v", out2, err)
  2183. }
  2184. }
  2185. {
  2186. name3 := "testonbuildtrigger3"
  2187. dockerfile3 := `
  2188. FROM testonbuildtrigger2
  2189. `
  2190. ctx, err := fakeContext(dockerfile3, nil)
  2191. if err != nil {
  2192. c.Fatal(err)
  2193. }
  2194. defer ctx.Close()
  2195. out3, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name3, ".")
  2196. if err != nil {
  2197. c.Fatalf("build failed to complete: %s, %v", out3, err)
  2198. }
  2199. }
  2200. // ONBUILD should be run in second build.
  2201. if !strings.Contains(out2, "ONBUILD PARENT") {
  2202. c.Fatalf("ONBUILD instruction did not run in child of ONBUILD parent")
  2203. }
  2204. // ONBUILD should *not* be run in third build.
  2205. if strings.Contains(out3, "ONBUILD PARENT") {
  2206. c.Fatalf("ONBUILD instruction ran in grandchild of ONBUILD parent")
  2207. }
  2208. }
  2209. func (s *DockerSuite) TestBuildWithCache(c *check.C) {
  2210. name := "testbuildwithcache"
  2211. id1, err := buildImage(name,
  2212. `FROM scratch
  2213. MAINTAINER dockerio
  2214. EXPOSE 5432
  2215. ENTRYPOINT ["/bin/echo"]`,
  2216. true)
  2217. if err != nil {
  2218. c.Fatal(err)
  2219. }
  2220. id2, err := buildImage(name,
  2221. `FROM scratch
  2222. MAINTAINER dockerio
  2223. EXPOSE 5432
  2224. ENTRYPOINT ["/bin/echo"]`,
  2225. true)
  2226. if err != nil {
  2227. c.Fatal(err)
  2228. }
  2229. if id1 != id2 {
  2230. c.Fatal("The cache should have been used but hasn't.")
  2231. }
  2232. }
  2233. func (s *DockerSuite) TestBuildWithoutCache(c *check.C) {
  2234. name := "testbuildwithoutcache"
  2235. name2 := "testbuildwithoutcache2"
  2236. id1, err := buildImage(name,
  2237. `FROM scratch
  2238. MAINTAINER dockerio
  2239. EXPOSE 5432
  2240. ENTRYPOINT ["/bin/echo"]`,
  2241. true)
  2242. if err != nil {
  2243. c.Fatal(err)
  2244. }
  2245. id2, err := buildImage(name2,
  2246. `FROM scratch
  2247. MAINTAINER dockerio
  2248. EXPOSE 5432
  2249. ENTRYPOINT ["/bin/echo"]`,
  2250. false)
  2251. if err != nil {
  2252. c.Fatal(err)
  2253. }
  2254. if id1 == id2 {
  2255. c.Fatal("The cache should have been invalided but hasn't.")
  2256. }
  2257. }
  2258. func (s *DockerSuite) TestBuildConditionalCache(c *check.C) {
  2259. name := "testbuildconditionalcache"
  2260. dockerfile := `
  2261. FROM busybox
  2262. ADD foo /tmp/`
  2263. ctx, err := fakeContext(dockerfile, map[string]string{
  2264. "foo": "hello",
  2265. })
  2266. if err != nil {
  2267. c.Fatal(err)
  2268. }
  2269. defer ctx.Close()
  2270. id1, err := buildImageFromContext(name, ctx, true)
  2271. if err != nil {
  2272. c.Fatalf("Error building #1: %s", err)
  2273. }
  2274. if err := ctx.Add("foo", "bye"); err != nil {
  2275. c.Fatalf("Error modifying foo: %s", err)
  2276. }
  2277. id2, err := buildImageFromContext(name, ctx, false)
  2278. if err != nil {
  2279. c.Fatalf("Error building #2: %s", err)
  2280. }
  2281. if id2 == id1 {
  2282. c.Fatal("Should not have used the cache")
  2283. }
  2284. id3, err := buildImageFromContext(name, ctx, true)
  2285. if err != nil {
  2286. c.Fatalf("Error building #3: %s", err)
  2287. }
  2288. if id3 != id2 {
  2289. c.Fatal("Should have used the cache")
  2290. }
  2291. }
  2292. func (s *DockerSuite) TestBuildADDLocalFileWithCache(c *check.C) {
  2293. name := "testbuildaddlocalfilewithcache"
  2294. name2 := "testbuildaddlocalfilewithcache2"
  2295. dockerfile := `
  2296. FROM busybox
  2297. MAINTAINER dockerio
  2298. ADD foo /usr/lib/bla/bar
  2299. RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2300. ctx, err := fakeContext(dockerfile, map[string]string{
  2301. "foo": "hello",
  2302. })
  2303. defer ctx.Close()
  2304. if err != nil {
  2305. c.Fatal(err)
  2306. }
  2307. id1, err := buildImageFromContext(name, ctx, true)
  2308. if err != nil {
  2309. c.Fatal(err)
  2310. }
  2311. id2, err := buildImageFromContext(name2, ctx, true)
  2312. if err != nil {
  2313. c.Fatal(err)
  2314. }
  2315. if id1 != id2 {
  2316. c.Fatal("The cache should have been used but hasn't.")
  2317. }
  2318. }
  2319. func (s *DockerSuite) TestBuildADDMultipleLocalFileWithCache(c *check.C) {
  2320. name := "testbuildaddmultiplelocalfilewithcache"
  2321. name2 := "testbuildaddmultiplelocalfilewithcache2"
  2322. dockerfile := `
  2323. FROM busybox
  2324. MAINTAINER dockerio
  2325. ADD foo Dockerfile /usr/lib/bla/
  2326. RUN [ "$(cat /usr/lib/bla/foo)" = "hello" ]`
  2327. ctx, err := fakeContext(dockerfile, map[string]string{
  2328. "foo": "hello",
  2329. })
  2330. defer ctx.Close()
  2331. if err != nil {
  2332. c.Fatal(err)
  2333. }
  2334. id1, err := buildImageFromContext(name, ctx, true)
  2335. if err != nil {
  2336. c.Fatal(err)
  2337. }
  2338. id2, err := buildImageFromContext(name2, ctx, true)
  2339. if err != nil {
  2340. c.Fatal(err)
  2341. }
  2342. if id1 != id2 {
  2343. c.Fatal("The cache should have been used but hasn't.")
  2344. }
  2345. }
  2346. func (s *DockerSuite) TestBuildADDLocalFileWithoutCache(c *check.C) {
  2347. name := "testbuildaddlocalfilewithoutcache"
  2348. name2 := "testbuildaddlocalfilewithoutcache2"
  2349. dockerfile := `
  2350. FROM busybox
  2351. MAINTAINER dockerio
  2352. ADD foo /usr/lib/bla/bar
  2353. RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2354. ctx, err := fakeContext(dockerfile, map[string]string{
  2355. "foo": "hello",
  2356. })
  2357. defer ctx.Close()
  2358. if err != nil {
  2359. c.Fatal(err)
  2360. }
  2361. id1, err := buildImageFromContext(name, ctx, true)
  2362. if err != nil {
  2363. c.Fatal(err)
  2364. }
  2365. id2, err := buildImageFromContext(name2, ctx, false)
  2366. if err != nil {
  2367. c.Fatal(err)
  2368. }
  2369. if id1 == id2 {
  2370. c.Fatal("The cache should have been invalided but hasn't.")
  2371. }
  2372. }
  2373. func (s *DockerSuite) TestBuildCopyDirButNotFile(c *check.C) {
  2374. name := "testbuildcopydirbutnotfile"
  2375. name2 := "testbuildcopydirbutnotfile2"
  2376. dockerfile := `
  2377. FROM scratch
  2378. COPY dir /tmp/`
  2379. ctx, err := fakeContext(dockerfile, map[string]string{
  2380. "dir/foo": "hello",
  2381. })
  2382. defer ctx.Close()
  2383. if err != nil {
  2384. c.Fatal(err)
  2385. }
  2386. id1, err := buildImageFromContext(name, ctx, true)
  2387. if err != nil {
  2388. c.Fatal(err)
  2389. }
  2390. // Check that adding file with similar name doesn't mess with cache
  2391. if err := ctx.Add("dir_file", "hello2"); err != nil {
  2392. c.Fatal(err)
  2393. }
  2394. id2, err := buildImageFromContext(name2, ctx, true)
  2395. if err != nil {
  2396. c.Fatal(err)
  2397. }
  2398. if id1 != id2 {
  2399. c.Fatal("The cache should have been used but wasn't")
  2400. }
  2401. }
  2402. func (s *DockerSuite) TestBuildADDCurrentDirWithCache(c *check.C) {
  2403. name := "testbuildaddcurrentdirwithcache"
  2404. name2 := name + "2"
  2405. name3 := name + "3"
  2406. name4 := name + "4"
  2407. name5 := name + "5"
  2408. dockerfile := `
  2409. FROM scratch
  2410. MAINTAINER dockerio
  2411. ADD . /usr/lib/bla`
  2412. ctx, err := fakeContext(dockerfile, map[string]string{
  2413. "foo": "hello",
  2414. })
  2415. defer ctx.Close()
  2416. if err != nil {
  2417. c.Fatal(err)
  2418. }
  2419. id1, err := buildImageFromContext(name, ctx, true)
  2420. if err != nil {
  2421. c.Fatal(err)
  2422. }
  2423. // Check that adding file invalidate cache of "ADD ."
  2424. if err := ctx.Add("bar", "hello2"); err != nil {
  2425. c.Fatal(err)
  2426. }
  2427. id2, err := buildImageFromContext(name2, ctx, true)
  2428. if err != nil {
  2429. c.Fatal(err)
  2430. }
  2431. if id1 == id2 {
  2432. c.Fatal("The cache should have been invalided but hasn't.")
  2433. }
  2434. // Check that changing file invalidate cache of "ADD ."
  2435. if err := ctx.Add("foo", "hello1"); err != nil {
  2436. c.Fatal(err)
  2437. }
  2438. id3, err := buildImageFromContext(name3, ctx, true)
  2439. if err != nil {
  2440. c.Fatal(err)
  2441. }
  2442. if id2 == id3 {
  2443. c.Fatal("The cache should have been invalided but hasn't.")
  2444. }
  2445. // Check that changing file to same content invalidate cache of "ADD ."
  2446. time.Sleep(1 * time.Second) // wait second because of mtime precision
  2447. if err := ctx.Add("foo", "hello1"); err != nil {
  2448. c.Fatal(err)
  2449. }
  2450. id4, err := buildImageFromContext(name4, ctx, true)
  2451. if err != nil {
  2452. c.Fatal(err)
  2453. }
  2454. if id3 == id4 {
  2455. c.Fatal("The cache should have been invalided but hasn't.")
  2456. }
  2457. id5, err := buildImageFromContext(name5, ctx, true)
  2458. if err != nil {
  2459. c.Fatal(err)
  2460. }
  2461. if id4 != id5 {
  2462. c.Fatal("The cache should have been used but hasn't.")
  2463. }
  2464. }
  2465. func (s *DockerSuite) TestBuildADDCurrentDirWithoutCache(c *check.C) {
  2466. name := "testbuildaddcurrentdirwithoutcache"
  2467. name2 := "testbuildaddcurrentdirwithoutcache2"
  2468. dockerfile := `
  2469. FROM scratch
  2470. MAINTAINER dockerio
  2471. ADD . /usr/lib/bla`
  2472. ctx, err := fakeContext(dockerfile, map[string]string{
  2473. "foo": "hello",
  2474. })
  2475. defer ctx.Close()
  2476. if err != nil {
  2477. c.Fatal(err)
  2478. }
  2479. id1, err := buildImageFromContext(name, ctx, true)
  2480. if err != nil {
  2481. c.Fatal(err)
  2482. }
  2483. id2, err := buildImageFromContext(name2, ctx, false)
  2484. if err != nil {
  2485. c.Fatal(err)
  2486. }
  2487. if id1 == id2 {
  2488. c.Fatal("The cache should have been invalided but hasn't.")
  2489. }
  2490. }
  2491. func (s *DockerSuite) TestBuildADDRemoteFileWithCache(c *check.C) {
  2492. name := "testbuildaddremotefilewithcache"
  2493. server, err := fakeStorage(map[string]string{
  2494. "baz": "hello",
  2495. })
  2496. if err != nil {
  2497. c.Fatal(err)
  2498. }
  2499. defer server.Close()
  2500. id1, err := buildImage(name,
  2501. fmt.Sprintf(`FROM scratch
  2502. MAINTAINER dockerio
  2503. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2504. true)
  2505. if err != nil {
  2506. c.Fatal(err)
  2507. }
  2508. id2, err := buildImage(name,
  2509. fmt.Sprintf(`FROM scratch
  2510. MAINTAINER dockerio
  2511. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2512. true)
  2513. if err != nil {
  2514. c.Fatal(err)
  2515. }
  2516. if id1 != id2 {
  2517. c.Fatal("The cache should have been used but hasn't.")
  2518. }
  2519. }
  2520. func (s *DockerSuite) TestBuildADDRemoteFileWithoutCache(c *check.C) {
  2521. name := "testbuildaddremotefilewithoutcache"
  2522. name2 := "testbuildaddremotefilewithoutcache2"
  2523. server, err := fakeStorage(map[string]string{
  2524. "baz": "hello",
  2525. })
  2526. if err != nil {
  2527. c.Fatal(err)
  2528. }
  2529. defer server.Close()
  2530. id1, err := buildImage(name,
  2531. fmt.Sprintf(`FROM scratch
  2532. MAINTAINER dockerio
  2533. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2534. true)
  2535. if err != nil {
  2536. c.Fatal(err)
  2537. }
  2538. id2, err := buildImage(name2,
  2539. fmt.Sprintf(`FROM scratch
  2540. MAINTAINER dockerio
  2541. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2542. false)
  2543. if err != nil {
  2544. c.Fatal(err)
  2545. }
  2546. if id1 == id2 {
  2547. c.Fatal("The cache should have been invalided but hasn't.")
  2548. }
  2549. }
  2550. func (s *DockerSuite) TestBuildADDRemoteFileMTime(c *check.C) {
  2551. name := "testbuildaddremotefilemtime"
  2552. name2 := name + "2"
  2553. name3 := name + "3"
  2554. name4 := name + "4"
  2555. files := map[string]string{"baz": "hello"}
  2556. server, err := fakeStorage(files)
  2557. if err != nil {
  2558. c.Fatal(err)
  2559. }
  2560. defer server.Close()
  2561. ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2562. MAINTAINER dockerio
  2563. ADD %s/baz /usr/lib/baz/quux`, server.URL()), nil)
  2564. if err != nil {
  2565. c.Fatal(err)
  2566. }
  2567. defer ctx.Close()
  2568. id1, err := buildImageFromContext(name, ctx, true)
  2569. if err != nil {
  2570. c.Fatal(err)
  2571. }
  2572. id2, err := buildImageFromContext(name2, ctx, true)
  2573. if err != nil {
  2574. c.Fatal(err)
  2575. }
  2576. if id1 != id2 {
  2577. c.Fatal("The cache should have been used but wasn't - #1")
  2578. }
  2579. // Now create a different server withsame contents (causes different mtim)
  2580. // This time the cache should not be used
  2581. // allow some time for clock to pass as mtime precision is only 1s
  2582. time.Sleep(2 * time.Second)
  2583. server2, err := fakeStorage(files)
  2584. if err != nil {
  2585. c.Fatal(err)
  2586. }
  2587. defer server2.Close()
  2588. ctx2, err := fakeContext(fmt.Sprintf(`FROM scratch
  2589. MAINTAINER dockerio
  2590. ADD %s/baz /usr/lib/baz/quux`, server2.URL()), nil)
  2591. if err != nil {
  2592. c.Fatal(err)
  2593. }
  2594. defer ctx2.Close()
  2595. id3, err := buildImageFromContext(name3, ctx2, true)
  2596. if err != nil {
  2597. c.Fatal(err)
  2598. }
  2599. if id1 == id3 {
  2600. c.Fatal("The cache should not have been used but was")
  2601. }
  2602. // And for good measure do it again and make sure cache is used this time
  2603. id4, err := buildImageFromContext(name4, ctx2, true)
  2604. if err != nil {
  2605. c.Fatal(err)
  2606. }
  2607. if id3 != id4 {
  2608. c.Fatal("The cache should have been used but wasn't - #2")
  2609. }
  2610. }
  2611. func (s *DockerSuite) TestBuildADDLocalAndRemoteFilesWithCache(c *check.C) {
  2612. name := "testbuildaddlocalandremotefilewithcache"
  2613. server, err := fakeStorage(map[string]string{
  2614. "baz": "hello",
  2615. })
  2616. if err != nil {
  2617. c.Fatal(err)
  2618. }
  2619. defer server.Close()
  2620. ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2621. MAINTAINER dockerio
  2622. ADD foo /usr/lib/bla/bar
  2623. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2624. map[string]string{
  2625. "foo": "hello world",
  2626. })
  2627. if err != nil {
  2628. c.Fatal(err)
  2629. }
  2630. defer ctx.Close()
  2631. id1, err := buildImageFromContext(name, ctx, true)
  2632. if err != nil {
  2633. c.Fatal(err)
  2634. }
  2635. id2, err := buildImageFromContext(name, ctx, true)
  2636. if err != nil {
  2637. c.Fatal(err)
  2638. }
  2639. if id1 != id2 {
  2640. c.Fatal("The cache should have been used but hasn't.")
  2641. }
  2642. }
  2643. func testContextTar(c *check.C, compression archive.Compression) {
  2644. ctx, err := fakeContext(
  2645. `FROM busybox
  2646. ADD foo /foo
  2647. CMD ["cat", "/foo"]`,
  2648. map[string]string{
  2649. "foo": "bar",
  2650. },
  2651. )
  2652. defer ctx.Close()
  2653. if err != nil {
  2654. c.Fatal(err)
  2655. }
  2656. context, err := archive.Tar(ctx.Dir, compression)
  2657. if err != nil {
  2658. c.Fatalf("failed to build context tar: %v", err)
  2659. }
  2660. name := "contexttar"
  2661. buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-")
  2662. buildCmd.Stdin = context
  2663. if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  2664. c.Fatalf("build failed to complete: %v %v", out, err)
  2665. }
  2666. }
  2667. func (s *DockerSuite) TestBuildContextTarGzip(c *check.C) {
  2668. testContextTar(c, archive.Gzip)
  2669. }
  2670. func (s *DockerSuite) TestBuildContextTarNoCompression(c *check.C) {
  2671. testContextTar(c, archive.Uncompressed)
  2672. }
  2673. func (s *DockerSuite) TestBuildNoContext(c *check.C) {
  2674. buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
  2675. buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
  2676. if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  2677. c.Fatalf("build failed to complete: %v %v", out, err)
  2678. }
  2679. if out, _ := dockerCmd(c, "run", "--rm", "nocontext"); out != "ok\n" {
  2680. c.Fatalf("run produced invalid output: %q, expected %q", out, "ok")
  2681. }
  2682. }
  2683. // TODO: TestCaching
  2684. func (s *DockerSuite) TestBuildADDLocalAndRemoteFilesWithoutCache(c *check.C) {
  2685. name := "testbuildaddlocalandremotefilewithoutcache"
  2686. name2 := "testbuildaddlocalandremotefilewithoutcache2"
  2687. server, err := fakeStorage(map[string]string{
  2688. "baz": "hello",
  2689. })
  2690. if err != nil {
  2691. c.Fatal(err)
  2692. }
  2693. defer server.Close()
  2694. ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2695. MAINTAINER dockerio
  2696. ADD foo /usr/lib/bla/bar
  2697. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2698. map[string]string{
  2699. "foo": "hello world",
  2700. })
  2701. if err != nil {
  2702. c.Fatal(err)
  2703. }
  2704. defer ctx.Close()
  2705. id1, err := buildImageFromContext(name, ctx, true)
  2706. if err != nil {
  2707. c.Fatal(err)
  2708. }
  2709. id2, err := buildImageFromContext(name2, ctx, false)
  2710. if err != nil {
  2711. c.Fatal(err)
  2712. }
  2713. if id1 == id2 {
  2714. c.Fatal("The cache should have been invalided but hasn't.")
  2715. }
  2716. }
  2717. func (s *DockerSuite) TestBuildWithVolumeOwnership(c *check.C) {
  2718. name := "testbuildimg"
  2719. _, err := buildImage(name,
  2720. `FROM busybox:latest
  2721. RUN mkdir /test && chown daemon:daemon /test && chmod 0600 /test
  2722. VOLUME /test`,
  2723. true)
  2724. if err != nil {
  2725. c.Fatal(err)
  2726. }
  2727. cmd := exec.Command(dockerBinary, "run", "--rm", "testbuildimg", "ls", "-la", "/test")
  2728. out, _, err := runCommandWithOutput(cmd)
  2729. if err != nil {
  2730. c.Fatal(out, err)
  2731. }
  2732. if expected := "drw-------"; !strings.Contains(out, expected) {
  2733. c.Fatalf("expected %s received %s", expected, out)
  2734. }
  2735. if expected := "daemon daemon"; !strings.Contains(out, expected) {
  2736. c.Fatalf("expected %s received %s", expected, out)
  2737. }
  2738. }
  2739. // testing #1405 - config.Cmd does not get cleaned up if
  2740. // utilizing cache
  2741. func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) {
  2742. name := "testbuildcmdcleanup"
  2743. if _, err := buildImage(name,
  2744. `FROM busybox
  2745. RUN echo "hello"`,
  2746. true); err != nil {
  2747. c.Fatal(err)
  2748. }
  2749. ctx, err := fakeContext(`FROM busybox
  2750. RUN echo "hello"
  2751. ADD foo /foo
  2752. ENTRYPOINT ["/bin/echo"]`,
  2753. map[string]string{
  2754. "foo": "hello",
  2755. })
  2756. defer ctx.Close()
  2757. if err != nil {
  2758. c.Fatal(err)
  2759. }
  2760. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2761. c.Fatal(err)
  2762. }
  2763. res, err := inspectField(name, "Config.Cmd")
  2764. if err != nil {
  2765. c.Fatal(err)
  2766. }
  2767. // Cmd must be cleaned up
  2768. if res != "<nil>" {
  2769. c.Fatalf("Cmd %s, expected nil", res)
  2770. }
  2771. }
  2772. func (s *DockerSuite) TestBuildForbiddenContextPath(c *check.C) {
  2773. name := "testbuildforbidpath"
  2774. ctx, err := fakeContext(`FROM scratch
  2775. ADD ../../ test/
  2776. `,
  2777. map[string]string{
  2778. "test.txt": "test1",
  2779. "other.txt": "other",
  2780. })
  2781. defer ctx.Close()
  2782. if err != nil {
  2783. c.Fatal(err)
  2784. }
  2785. expected := "Forbidden path outside the build context: ../../ "
  2786. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  2787. c.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
  2788. }
  2789. }
  2790. func (s *DockerSuite) TestBuildADDFileNotFound(c *check.C) {
  2791. name := "testbuildaddnotfound"
  2792. ctx, err := fakeContext(`FROM scratch
  2793. ADD foo /usr/local/bar`,
  2794. map[string]string{"bar": "hello"})
  2795. defer ctx.Close()
  2796. if err != nil {
  2797. c.Fatal(err)
  2798. }
  2799. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2800. if !strings.Contains(err.Error(), "foo: no such file or directory") {
  2801. c.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
  2802. }
  2803. } else {
  2804. c.Fatal("Error must not be nil")
  2805. }
  2806. }
  2807. func (s *DockerSuite) TestBuildInheritance(c *check.C) {
  2808. name := "testbuildinheritance"
  2809. _, err := buildImage(name,
  2810. `FROM scratch
  2811. EXPOSE 2375`,
  2812. true)
  2813. if err != nil {
  2814. c.Fatal(err)
  2815. }
  2816. ports1, err := inspectField(name, "Config.ExposedPorts")
  2817. if err != nil {
  2818. c.Fatal(err)
  2819. }
  2820. _, err = buildImage(name,
  2821. fmt.Sprintf(`FROM %s
  2822. ENTRYPOINT ["/bin/echo"]`, name),
  2823. true)
  2824. if err != nil {
  2825. c.Fatal(err)
  2826. }
  2827. res, err := inspectField(name, "Config.Entrypoint")
  2828. if err != nil {
  2829. c.Fatal(err)
  2830. }
  2831. if expected := "{[/bin/echo]}"; res != expected {
  2832. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2833. }
  2834. ports2, err := inspectField(name, "Config.ExposedPorts")
  2835. if err != nil {
  2836. c.Fatal(err)
  2837. }
  2838. if ports1 != ports2 {
  2839. c.Fatalf("Ports must be same: %s != %s", ports1, ports2)
  2840. }
  2841. }
  2842. func (s *DockerSuite) TestBuildFails(c *check.C) {
  2843. name := "testbuildfails"
  2844. _, err := buildImage(name,
  2845. `FROM busybox
  2846. RUN sh -c "exit 23"`,
  2847. true)
  2848. if err != nil {
  2849. if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
  2850. c.Fatalf("Wrong error %v, must be about non-zero code 23", err)
  2851. }
  2852. } else {
  2853. c.Fatal("Error must not be nil")
  2854. }
  2855. }
  2856. func (s *DockerSuite) TestBuildFailsDockerfileEmpty(c *check.C) {
  2857. name := "testbuildfails"
  2858. _, err := buildImage(name, ``, true)
  2859. if err != nil {
  2860. if !strings.Contains(err.Error(), "The Dockerfile (Dockerfile) cannot be empty") {
  2861. c.Fatalf("Wrong error %v, must be about empty Dockerfile", err)
  2862. }
  2863. } else {
  2864. c.Fatal("Error must not be nil")
  2865. }
  2866. }
  2867. func (s *DockerSuite) TestBuildOnBuild(c *check.C) {
  2868. name := "testbuildonbuild"
  2869. _, err := buildImage(name,
  2870. `FROM busybox
  2871. ONBUILD RUN touch foobar`,
  2872. true)
  2873. if err != nil {
  2874. c.Fatal(err)
  2875. }
  2876. _, err = buildImage(name,
  2877. fmt.Sprintf(`FROM %s
  2878. RUN [ -f foobar ]`, name),
  2879. true)
  2880. if err != nil {
  2881. c.Fatal(err)
  2882. }
  2883. }
  2884. func (s *DockerSuite) TestBuildOnBuildForbiddenChained(c *check.C) {
  2885. name := "testbuildonbuildforbiddenchained"
  2886. _, err := buildImage(name,
  2887. `FROM busybox
  2888. ONBUILD ONBUILD RUN touch foobar`,
  2889. true)
  2890. if err != nil {
  2891. if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  2892. c.Fatalf("Wrong error %v, must be about chaining ONBUILD", err)
  2893. }
  2894. } else {
  2895. c.Fatal("Error must not be nil")
  2896. }
  2897. }
  2898. func (s *DockerSuite) TestBuildOnBuildForbiddenFrom(c *check.C) {
  2899. name := "testbuildonbuildforbiddenfrom"
  2900. _, err := buildImage(name,
  2901. `FROM busybox
  2902. ONBUILD FROM scratch`,
  2903. true)
  2904. if err != nil {
  2905. if !strings.Contains(err.Error(), "FROM isn't allowed as an ONBUILD trigger") {
  2906. c.Fatalf("Wrong error %v, must be about FROM forbidden", err)
  2907. }
  2908. } else {
  2909. c.Fatal("Error must not be nil")
  2910. }
  2911. }
  2912. func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainer(c *check.C) {
  2913. name := "testbuildonbuildforbiddenmaintainer"
  2914. _, err := buildImage(name,
  2915. `FROM busybox
  2916. ONBUILD MAINTAINER docker.io`,
  2917. true)
  2918. if err != nil {
  2919. if !strings.Contains(err.Error(), "MAINTAINER isn't allowed as an ONBUILD trigger") {
  2920. c.Fatalf("Wrong error %v, must be about MAINTAINER forbidden", err)
  2921. }
  2922. } else {
  2923. c.Fatal("Error must not be nil")
  2924. }
  2925. }
  2926. // gh #2446
  2927. func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) {
  2928. name := "testbuildaddtosymlinkdest"
  2929. ctx, err := fakeContext(`FROM busybox
  2930. RUN mkdir /foo
  2931. RUN ln -s /foo /bar
  2932. ADD foo /bar/
  2933. RUN [ -f /bar/foo ]
  2934. RUN [ -f /foo/foo ]`,
  2935. map[string]string{
  2936. "foo": "hello",
  2937. })
  2938. if err != nil {
  2939. c.Fatal(err)
  2940. }
  2941. defer ctx.Close()
  2942. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2943. c.Fatal(err)
  2944. }
  2945. }
  2946. func (s *DockerSuite) TestBuildEscapeWhitespace(c *check.C) {
  2947. name := "testbuildescaping"
  2948. _, err := buildImage(name, `
  2949. FROM busybox
  2950. MAINTAINER "Docker \
  2951. IO <io@\
  2952. docker.com>"
  2953. `, true)
  2954. res, err := inspectField(name, "Author")
  2955. if err != nil {
  2956. c.Fatal(err)
  2957. }
  2958. if res != "\"Docker IO <io@docker.com>\"" {
  2959. c.Fatalf("Parsed string did not match the escaped string. Got: %q", res)
  2960. }
  2961. }
  2962. func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) {
  2963. // Verify that strings that look like ints are still passed as strings
  2964. name := "testbuildstringing"
  2965. _, err := buildImage(name, `
  2966. FROM busybox
  2967. MAINTAINER 123
  2968. `, true)
  2969. out, rc, err := runCommandWithOutput(exec.Command(dockerBinary, "inspect", name))
  2970. if rc != 0 || err != nil {
  2971. c.Fatalf("Unexpected error from inspect: rc: %v err: %v", rc, err)
  2972. }
  2973. if !strings.Contains(out, "\"123\"") {
  2974. c.Fatalf("Output does not contain the int as a string:\n%s", out)
  2975. }
  2976. }
  2977. func (s *DockerSuite) TestBuildDockerignore(c *check.C) {
  2978. name := "testbuilddockerignore"
  2979. dockerfile := `
  2980. FROM busybox
  2981. ADD . /bla
  2982. RUN [[ -f /bla/src/x.go ]]
  2983. RUN [[ -f /bla/Makefile ]]
  2984. RUN [[ ! -e /bla/src/_vendor ]]
  2985. RUN [[ ! -e /bla/.gitignore ]]
  2986. RUN [[ ! -e /bla/README.md ]]
  2987. RUN [[ ! -e /bla/.git ]]`
  2988. ctx, err := fakeContext(dockerfile, map[string]string{
  2989. "Makefile": "all:",
  2990. ".git/HEAD": "ref: foo",
  2991. "src/x.go": "package main",
  2992. "src/_vendor/v.go": "package main",
  2993. ".gitignore": "",
  2994. "README.md": "readme",
  2995. ".dockerignore": ".git\npkg\n.gitignore\nsrc/_vendor\n*.md",
  2996. })
  2997. defer ctx.Close()
  2998. if err != nil {
  2999. c.Fatal(err)
  3000. }
  3001. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3002. c.Fatal(err)
  3003. }
  3004. }
  3005. func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) {
  3006. name := "testbuilddockerignorecleanpaths"
  3007. dockerfile := `
  3008. FROM busybox
  3009. ADD . /tmp/
  3010. RUN (! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)`
  3011. ctx, err := fakeContext(dockerfile, map[string]string{
  3012. "foo": "foo",
  3013. "foo2": "foo2",
  3014. "dir1/foo": "foo in dir1",
  3015. ".dockerignore": "./foo\ndir1//foo\n./dir1/../foo2",
  3016. })
  3017. if err != nil {
  3018. c.Fatal(err)
  3019. }
  3020. defer ctx.Close()
  3021. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3022. c.Fatal(err)
  3023. }
  3024. }
  3025. func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) {
  3026. name := "testbuilddockerignoredockerfile"
  3027. dockerfile := `
  3028. FROM busybox
  3029. ADD . /tmp/
  3030. RUN ! ls /tmp/Dockerfile
  3031. RUN ls /tmp/.dockerignore`
  3032. ctx, err := fakeContext(dockerfile, map[string]string{
  3033. "Dockerfile": dockerfile,
  3034. ".dockerignore": "Dockerfile\n",
  3035. })
  3036. if err != nil {
  3037. c.Fatal(err)
  3038. }
  3039. defer ctx.Close()
  3040. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3041. c.Fatalf("Didn't ignore Dockerfile correctly:%s", err)
  3042. }
  3043. // now try it with ./Dockerfile
  3044. ctx.Add(".dockerignore", "./Dockerfile\n")
  3045. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3046. c.Fatalf("Didn't ignore ./Dockerfile correctly:%s", err)
  3047. }
  3048. }
  3049. func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) {
  3050. name := "testbuilddockerignoredockerfile"
  3051. dockerfile := `
  3052. FROM busybox
  3053. ADD . /tmp/
  3054. RUN ls /tmp/Dockerfile
  3055. RUN ! ls /tmp/MyDockerfile
  3056. RUN ls /tmp/.dockerignore`
  3057. ctx, err := fakeContext(dockerfile, map[string]string{
  3058. "Dockerfile": "Should not use me",
  3059. "MyDockerfile": dockerfile,
  3060. ".dockerignore": "MyDockerfile\n",
  3061. })
  3062. if err != nil {
  3063. c.Fatal(err)
  3064. }
  3065. defer ctx.Close()
  3066. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3067. c.Fatalf("Didn't ignore MyDockerfile correctly:%s", err)
  3068. }
  3069. // now try it with ./MyDockerfile
  3070. ctx.Add(".dockerignore", "./MyDockerfile\n")
  3071. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3072. c.Fatalf("Didn't ignore ./MyDockerfile correctly:%s", err)
  3073. }
  3074. }
  3075. func (s *DockerSuite) TestBuildDockerignoringDockerignore(c *check.C) {
  3076. name := "testbuilddockerignoredockerignore"
  3077. dockerfile := `
  3078. FROM busybox
  3079. ADD . /tmp/
  3080. RUN ! ls /tmp/.dockerignore
  3081. RUN ls /tmp/Dockerfile`
  3082. ctx, err := fakeContext(dockerfile, map[string]string{
  3083. "Dockerfile": dockerfile,
  3084. ".dockerignore": ".dockerignore\n",
  3085. })
  3086. defer ctx.Close()
  3087. if err != nil {
  3088. c.Fatal(err)
  3089. }
  3090. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3091. c.Fatalf("Didn't ignore .dockerignore correctly:%s", err)
  3092. }
  3093. }
  3094. func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) {
  3095. var id1 string
  3096. var id2 string
  3097. name := "testbuilddockerignoretouchdockerfile"
  3098. dockerfile := `
  3099. FROM busybox
  3100. ADD . /tmp/`
  3101. ctx, err := fakeContext(dockerfile, map[string]string{
  3102. "Dockerfile": dockerfile,
  3103. ".dockerignore": "Dockerfile\n",
  3104. })
  3105. defer ctx.Close()
  3106. if err != nil {
  3107. c.Fatal(err)
  3108. }
  3109. if id1, err = buildImageFromContext(name, ctx, true); err != nil {
  3110. c.Fatalf("Didn't build it correctly:%s", err)
  3111. }
  3112. if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3113. c.Fatalf("Didn't build it correctly:%s", err)
  3114. }
  3115. if id1 != id2 {
  3116. c.Fatalf("Didn't use the cache - 1")
  3117. }
  3118. // Now make sure touching Dockerfile doesn't invalidate the cache
  3119. if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3120. c.Fatalf("Didn't add Dockerfile: %s", err)
  3121. }
  3122. if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3123. c.Fatalf("Didn't build it correctly:%s", err)
  3124. }
  3125. if id1 != id2 {
  3126. c.Fatalf("Didn't use the cache - 2")
  3127. }
  3128. // One more time but just 'touch' it instead of changing the content
  3129. if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3130. c.Fatalf("Didn't add Dockerfile: %s", err)
  3131. }
  3132. if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3133. c.Fatalf("Didn't build it correctly:%s", err)
  3134. }
  3135. if id1 != id2 {
  3136. c.Fatalf("Didn't use the cache - 3")
  3137. }
  3138. }
  3139. func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) {
  3140. name := "testbuilddockerignorewholedir"
  3141. dockerfile := `
  3142. FROM busybox
  3143. COPY . /
  3144. RUN [[ ! -e /.gitignore ]]
  3145. RUN [[ -f /Makefile ]]`
  3146. ctx, err := fakeContext(dockerfile, map[string]string{
  3147. "Dockerfile": "FROM scratch",
  3148. "Makefile": "all:",
  3149. ".dockerignore": ".*\n",
  3150. })
  3151. defer ctx.Close()
  3152. if err != nil {
  3153. c.Fatal(err)
  3154. }
  3155. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3156. c.Fatal(err)
  3157. }
  3158. }
  3159. func (s *DockerSuite) TestBuildLineBreak(c *check.C) {
  3160. name := "testbuildlinebreak"
  3161. _, err := buildImage(name,
  3162. `FROM busybox
  3163. RUN sh -c 'echo root:testpass \
  3164. > /tmp/passwd'
  3165. RUN mkdir -p /var/run/sshd
  3166. RUN [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3167. RUN [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3168. true)
  3169. if err != nil {
  3170. c.Fatal(err)
  3171. }
  3172. }
  3173. func (s *DockerSuite) TestBuildEOLInLine(c *check.C) {
  3174. name := "testbuildeolinline"
  3175. _, err := buildImage(name,
  3176. `FROM busybox
  3177. RUN sh -c 'echo root:testpass > /tmp/passwd'
  3178. RUN echo "foo \n bar"; echo "baz"
  3179. RUN mkdir -p /var/run/sshd
  3180. RUN [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3181. RUN [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3182. true)
  3183. if err != nil {
  3184. c.Fatal(err)
  3185. }
  3186. }
  3187. func (s *DockerSuite) TestBuildCommentsShebangs(c *check.C) {
  3188. name := "testbuildcomments"
  3189. _, err := buildImage(name,
  3190. `FROM busybox
  3191. # This is an ordinary comment.
  3192. RUN { echo '#!/bin/sh'; echo 'echo hello world'; } > /hello.sh
  3193. RUN [ ! -x /hello.sh ]
  3194. # comment with line break \
  3195. RUN chmod +x /hello.sh
  3196. RUN [ -x /hello.sh ]
  3197. RUN [ "$(cat /hello.sh)" = $'#!/bin/sh\necho hello world' ]
  3198. RUN [ "$(/hello.sh)" = "hello world" ]`,
  3199. true)
  3200. if err != nil {
  3201. c.Fatal(err)
  3202. }
  3203. }
  3204. func (s *DockerSuite) TestBuildUsersAndGroups(c *check.C) {
  3205. name := "testbuildusers"
  3206. _, err := buildImage(name,
  3207. `FROM busybox
  3208. # Make sure our defaults work
  3209. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)" = '0:0/root:root' ]
  3210. # TODO decide if "args.user = strconv.Itoa(syscall.Getuid())" is acceptable behavior for changeUser in sysvinit instead of "return nil" when "USER" isn't specified (so that we get the proper group list even if that is the empty list, even in the default case of not supplying an explicit USER to run as, which implies USER 0)
  3211. USER root
  3212. RUN [ "$(id -G):$(id -Gn)" = '0 10:root wheel' ]
  3213. # Setup dockerio user and group
  3214. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  3215. RUN echo 'dockerio:x:1001:' >> /etc/group
  3216. # Make sure we can switch to our user and all the information is exactly as we expect it to be
  3217. USER dockerio
  3218. RUN id -G
  3219. RUN id -Gn
  3220. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3221. # Switch back to root and double check that worked exactly as we might expect it to
  3222. USER root
  3223. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '0:0/root:root/0 10:root wheel' ]
  3224. # Add a "supplementary" group for our dockerio user
  3225. RUN echo 'supplementary:x:1002:dockerio' >> /etc/group
  3226. # ... and then go verify that we get it like we expect
  3227. USER dockerio
  3228. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3229. USER 1001
  3230. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3231. # super test the new "user:group" syntax
  3232. USER dockerio:dockerio
  3233. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3234. USER 1001:dockerio
  3235. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3236. USER dockerio:1001
  3237. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3238. USER 1001:1001
  3239. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3240. USER dockerio:supplementary
  3241. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3242. USER dockerio:1002
  3243. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3244. USER 1001:supplementary
  3245. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3246. USER 1001:1002
  3247. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3248. # make sure unknown uid/gid still works properly
  3249. USER 1042:1043
  3250. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/1042:1043/1043:1043' ]`,
  3251. true)
  3252. if err != nil {
  3253. c.Fatal(err)
  3254. }
  3255. }
  3256. func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
  3257. name := "testbuildenvusage"
  3258. dockerfile := `FROM busybox
  3259. ENV HOME /root
  3260. ENV PATH $HOME/bin:$PATH
  3261. ENV PATH /tmp:$PATH
  3262. RUN [ "$PATH" = "/tmp:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]
  3263. ENV FOO /foo/baz
  3264. ENV BAR /bar
  3265. ENV BAZ $BAR
  3266. ENV FOOPATH $PATH:$FOO
  3267. RUN [ "$BAR" = "$BAZ" ]
  3268. RUN [ "$FOOPATH" = "$PATH:/foo/baz" ]
  3269. ENV FROM hello/docker/world
  3270. ENV TO /docker/world/hello
  3271. ADD $FROM $TO
  3272. RUN [ "$(cat $TO)" = "hello" ]
  3273. ENV abc=def
  3274. ENV ghi=$abc
  3275. RUN [ "$ghi" = "def" ]
  3276. `
  3277. ctx, err := fakeContext(dockerfile, map[string]string{
  3278. "hello/docker/world": "hello",
  3279. })
  3280. if err != nil {
  3281. c.Fatal(err)
  3282. }
  3283. defer ctx.Close()
  3284. _, err = buildImageFromContext(name, ctx, true)
  3285. if err != nil {
  3286. c.Fatal(err)
  3287. }
  3288. }
  3289. func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
  3290. name := "testbuildenvusage2"
  3291. dockerfile := `FROM busybox
  3292. ENV abc=def
  3293. RUN [ "$abc" = "def" ]
  3294. ENV def="hello world"
  3295. RUN [ "$def" = "hello world" ]
  3296. ENV def=hello\ world
  3297. RUN [ "$def" = "hello world" ]
  3298. ENV v1=abc v2="hi there"
  3299. RUN [ "$v1" = "abc" ]
  3300. RUN [ "$v2" = "hi there" ]
  3301. ENV v3='boogie nights' v4="with'quotes too"
  3302. RUN [ "$v3" = "boogie nights" ]
  3303. RUN [ "$v4" = "with'quotes too" ]
  3304. ENV abc=zzz FROM=hello/docker/world
  3305. ENV abc=zzz TO=/docker/world/hello
  3306. ADD $FROM $TO
  3307. RUN [ "$(cat $TO)" = "hello" ]
  3308. ENV abc "zzz"
  3309. RUN [ $abc = "zzz" ]
  3310. ENV abc 'yyy'
  3311. RUN [ $abc = 'yyy' ]
  3312. ENV abc=
  3313. RUN [ "$abc" = "" ]
  3314. # use grep to make sure if the builder substitutes \$foo by mistake
  3315. # we don't get a false positive
  3316. ENV abc=\$foo
  3317. RUN [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3318. ENV abc \$foo
  3319. RUN [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3320. ENV abc=\'foo\'
  3321. RUN [ "$abc" = "'foo'" ]
  3322. ENV abc=\"foo\"
  3323. RUN [ "$abc" = "\"foo\"" ]
  3324. ENV abc "foo"
  3325. RUN [ "$abc" = "foo" ]
  3326. ENV abc 'foo'
  3327. RUN [ "$abc" = 'foo' ]
  3328. ENV abc \'foo\'
  3329. RUN [ "$abc" = "'foo'" ]
  3330. ENV abc \"foo\"
  3331. RUN [ "$abc" = '"foo"' ]
  3332. ENV abc=ABC
  3333. RUN [ "$abc" = "ABC" ]
  3334. ENV def=${abc:-DEF}
  3335. RUN [ "$def" = "ABC" ]
  3336. ENV def=${ccc:-DEF}
  3337. RUN [ "$def" = "DEF" ]
  3338. ENV def=${ccc:-${def}xx}
  3339. RUN [ "$def" = "DEFxx" ]
  3340. ENV def=${def:+ALT}
  3341. RUN [ "$def" = "ALT" ]
  3342. ENV def=${def:+${abc}:}
  3343. RUN [ "$def" = "ABC:" ]
  3344. ENV def=${ccc:-\$abc:}
  3345. RUN [ "$def" = '$abc:' ]
  3346. ENV def=${ccc:-\${abc}:}
  3347. RUN [ "$def" = '${abc:}' ]
  3348. ENV mypath=${mypath:+$mypath:}/home
  3349. RUN [ "$mypath" = '/home' ]
  3350. ENV mypath=${mypath:+$mypath:}/away
  3351. RUN [ "$mypath" = '/home:/away' ]
  3352. ENV e1=bar
  3353. ENV e2=$e1
  3354. ENV e3=$e11
  3355. ENV e4=\$e1
  3356. ENV e5=\$e11
  3357. RUN [ "$e0,$e1,$e2,$e3,$e4,$e5" = ',bar,bar,,$e1,$e11' ]
  3358. ENV ee1 bar
  3359. ENV ee2 $ee1
  3360. ENV ee3 $ee11
  3361. ENV ee4 \$ee1
  3362. ENV ee5 \$ee11
  3363. RUN [ "$ee1,$ee2,$ee3,$ee4,$ee5" = 'bar,bar,,$ee1,$ee11' ]
  3364. ENV eee1="foo"
  3365. ENV eee2='foo'
  3366. ENV eee3 "foo"
  3367. ENV eee4 'foo'
  3368. RUN [ "$eee1,$eee2,$eee3,$eee4" = 'foo,foo,foo,foo' ]
  3369. `
  3370. ctx, err := fakeContext(dockerfile, map[string]string{
  3371. "hello/docker/world": "hello",
  3372. })
  3373. if err != nil {
  3374. c.Fatal(err)
  3375. }
  3376. defer ctx.Close()
  3377. _, err = buildImageFromContext(name, ctx, true)
  3378. if err != nil {
  3379. c.Fatal(err)
  3380. }
  3381. }
  3382. func (s *DockerSuite) TestBuildAddScript(c *check.C) {
  3383. name := "testbuildaddscript"
  3384. dockerfile := `
  3385. FROM busybox
  3386. ADD test /test
  3387. RUN ["chmod","+x","/test"]
  3388. RUN ["/test"]
  3389. RUN [ "$(cat /testfile)" = 'test!' ]`
  3390. ctx, err := fakeContext(dockerfile, map[string]string{
  3391. "test": "#!/bin/sh\necho 'test!' > /testfile",
  3392. })
  3393. if err != nil {
  3394. c.Fatal(err)
  3395. }
  3396. defer ctx.Close()
  3397. _, err = buildImageFromContext(name, ctx, true)
  3398. if err != nil {
  3399. c.Fatal(err)
  3400. }
  3401. }
  3402. func (s *DockerSuite) TestBuildAddTar(c *check.C) {
  3403. name := "testbuildaddtar"
  3404. ctx := func() *FakeContext {
  3405. dockerfile := `
  3406. FROM busybox
  3407. ADD test.tar /
  3408. RUN cat /test/foo | grep Hi
  3409. ADD test.tar /test.tar
  3410. RUN cat /test.tar/test/foo | grep Hi
  3411. ADD test.tar /unlikely-to-exist
  3412. RUN cat /unlikely-to-exist/test/foo | grep Hi
  3413. ADD test.tar /unlikely-to-exist-trailing-slash/
  3414. RUN cat /unlikely-to-exist-trailing-slash/test/foo | grep Hi
  3415. RUN mkdir /existing-directory
  3416. ADD test.tar /existing-directory
  3417. RUN cat /existing-directory/test/foo | grep Hi
  3418. ADD test.tar /existing-directory-trailing-slash/
  3419. RUN cat /existing-directory-trailing-slash/test/foo | grep Hi`
  3420. tmpDir, err := ioutil.TempDir("", "fake-context")
  3421. testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3422. if err != nil {
  3423. c.Fatalf("failed to create test.tar archive: %v", err)
  3424. }
  3425. defer testTar.Close()
  3426. tw := tar.NewWriter(testTar)
  3427. if err := tw.WriteHeader(&tar.Header{
  3428. Name: "test/foo",
  3429. Size: 2,
  3430. }); err != nil {
  3431. c.Fatalf("failed to write tar file header: %v", err)
  3432. }
  3433. if _, err := tw.Write([]byte("Hi")); err != nil {
  3434. c.Fatalf("failed to write tar file content: %v", err)
  3435. }
  3436. if err := tw.Close(); err != nil {
  3437. c.Fatalf("failed to close tar archive: %v", err)
  3438. }
  3439. if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3440. c.Fatalf("failed to open destination dockerfile: %v", err)
  3441. }
  3442. return fakeContextFromDir(tmpDir)
  3443. }()
  3444. defer ctx.Close()
  3445. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3446. c.Fatalf("build failed to complete for TestBuildAddTar: %v", err)
  3447. }
  3448. }
  3449. func (s *DockerSuite) TestBuildAddTarXz(c *check.C) {
  3450. name := "testbuildaddtarxz"
  3451. ctx := func() *FakeContext {
  3452. dockerfile := `
  3453. FROM busybox
  3454. ADD test.tar.xz /
  3455. RUN cat /test/foo | grep Hi`
  3456. tmpDir, err := ioutil.TempDir("", "fake-context")
  3457. testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3458. if err != nil {
  3459. c.Fatalf("failed to create test.tar archive: %v", err)
  3460. }
  3461. defer testTar.Close()
  3462. tw := tar.NewWriter(testTar)
  3463. if err := tw.WriteHeader(&tar.Header{
  3464. Name: "test/foo",
  3465. Size: 2,
  3466. }); err != nil {
  3467. c.Fatalf("failed to write tar file header: %v", err)
  3468. }
  3469. if _, err := tw.Write([]byte("Hi")); err != nil {
  3470. c.Fatalf("failed to write tar file content: %v", err)
  3471. }
  3472. if err := tw.Close(); err != nil {
  3473. c.Fatalf("failed to close tar archive: %v", err)
  3474. }
  3475. xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  3476. xzCompressCmd.Dir = tmpDir
  3477. out, _, err := runCommandWithOutput(xzCompressCmd)
  3478. if err != nil {
  3479. c.Fatal(err, out)
  3480. }
  3481. if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3482. c.Fatalf("failed to open destination dockerfile: %v", err)
  3483. }
  3484. return fakeContextFromDir(tmpDir)
  3485. }()
  3486. defer ctx.Close()
  3487. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3488. c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  3489. }
  3490. }
  3491. func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) {
  3492. name := "testbuildaddtarxzgz"
  3493. ctx := func() *FakeContext {
  3494. dockerfile := `
  3495. FROM busybox
  3496. ADD test.tar.xz.gz /
  3497. RUN ls /test.tar.xz.gz`
  3498. tmpDir, err := ioutil.TempDir("", "fake-context")
  3499. testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3500. if err != nil {
  3501. c.Fatalf("failed to create test.tar archive: %v", err)
  3502. }
  3503. defer testTar.Close()
  3504. tw := tar.NewWriter(testTar)
  3505. if err := tw.WriteHeader(&tar.Header{
  3506. Name: "test/foo",
  3507. Size: 2,
  3508. }); err != nil {
  3509. c.Fatalf("failed to write tar file header: %v", err)
  3510. }
  3511. if _, err := tw.Write([]byte("Hi")); err != nil {
  3512. c.Fatalf("failed to write tar file content: %v", err)
  3513. }
  3514. if err := tw.Close(); err != nil {
  3515. c.Fatalf("failed to close tar archive: %v", err)
  3516. }
  3517. xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  3518. xzCompressCmd.Dir = tmpDir
  3519. out, _, err := runCommandWithOutput(xzCompressCmd)
  3520. if err != nil {
  3521. c.Fatal(err, out)
  3522. }
  3523. gzipCompressCmd := exec.Command("gzip", "test.tar.xz")
  3524. gzipCompressCmd.Dir = tmpDir
  3525. out, _, err = runCommandWithOutput(gzipCompressCmd)
  3526. if err != nil {
  3527. c.Fatal(err, out)
  3528. }
  3529. if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3530. c.Fatalf("failed to open destination dockerfile: %v", err)
  3531. }
  3532. return fakeContextFromDir(tmpDir)
  3533. }()
  3534. defer ctx.Close()
  3535. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3536. c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  3537. }
  3538. }
  3539. func (s *DockerSuite) TestBuildFromGIT(c *check.C) {
  3540. name := "testbuildfromgit"
  3541. git, err := fakeGIT("repo", map[string]string{
  3542. "Dockerfile": `FROM busybox
  3543. ADD first /first
  3544. RUN [ -f /first ]
  3545. MAINTAINER docker`,
  3546. "first": "test git data",
  3547. }, true)
  3548. if err != nil {
  3549. c.Fatal(err)
  3550. }
  3551. defer git.Close()
  3552. _, err = buildImageFromPath(name, git.RepoURL, true)
  3553. if err != nil {
  3554. c.Fatal(err)
  3555. }
  3556. res, err := inspectField(name, "Author")
  3557. if err != nil {
  3558. c.Fatal(err)
  3559. }
  3560. if res != "docker" {
  3561. c.Fatalf("Maintainer should be docker, got %s", res)
  3562. }
  3563. }
  3564. func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) {
  3565. name := "testbuildcmdcleanuponentrypoint"
  3566. if _, err := buildImage(name,
  3567. `FROM scratch
  3568. CMD ["test"]
  3569. ENTRYPOINT ["echo"]`,
  3570. true); err != nil {
  3571. c.Fatal(err)
  3572. }
  3573. if _, err := buildImage(name,
  3574. fmt.Sprintf(`FROM %s
  3575. ENTRYPOINT ["cat"]`, name),
  3576. true); err != nil {
  3577. c.Fatal(err)
  3578. }
  3579. res, err := inspectField(name, "Config.Cmd")
  3580. if err != nil {
  3581. c.Fatal(err)
  3582. }
  3583. if res != "<nil>" {
  3584. c.Fatalf("Cmd %s, expected nil", res)
  3585. }
  3586. res, err = inspectField(name, "Config.Entrypoint")
  3587. if err != nil {
  3588. c.Fatal(err)
  3589. }
  3590. if expected := "{[cat]}"; res != expected {
  3591. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  3592. }
  3593. }
  3594. func (s *DockerSuite) TestBuildClearCmd(c *check.C) {
  3595. name := "testbuildclearcmd"
  3596. _, err := buildImage(name,
  3597. `From scratch
  3598. ENTRYPOINT ["/bin/bash"]
  3599. CMD []`,
  3600. true)
  3601. if err != nil {
  3602. c.Fatal(err)
  3603. }
  3604. res, err := inspectFieldJSON(name, "Config.Cmd")
  3605. if err != nil {
  3606. c.Fatal(err)
  3607. }
  3608. if res != "[]" {
  3609. c.Fatalf("Cmd %s, expected %s", res, "[]")
  3610. }
  3611. }
  3612. func (s *DockerSuite) TestBuildEmptyCmd(c *check.C) {
  3613. name := "testbuildemptycmd"
  3614. if _, err := buildImage(name, "FROM scratch\nMAINTAINER quux\n", true); err != nil {
  3615. c.Fatal(err)
  3616. }
  3617. res, err := inspectFieldJSON(name, "Config.Cmd")
  3618. if err != nil {
  3619. c.Fatal(err)
  3620. }
  3621. if res != "null" {
  3622. c.Fatalf("Cmd %s, expected %s", res, "null")
  3623. }
  3624. }
  3625. func (s *DockerSuite) TestBuildOnBuildOutput(c *check.C) {
  3626. name := "testbuildonbuildparent"
  3627. if _, err := buildImage(name, "FROM busybox\nONBUILD RUN echo foo\n", true); err != nil {
  3628. c.Fatal(err)
  3629. }
  3630. _, out, err := buildImageWithOut(name, "FROM "+name+"\nMAINTAINER quux\n", true)
  3631. if err != nil {
  3632. c.Fatal(err)
  3633. }
  3634. if !strings.Contains(out, "Trigger 0, RUN echo foo") {
  3635. c.Fatal("failed to find the ONBUILD output", out)
  3636. }
  3637. }
  3638. func (s *DockerSuite) TestBuildInvalidTag(c *check.C) {
  3639. name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200)
  3640. _, out, err := buildImageWithOut(name, "FROM scratch\nMAINTAINER quux\n", true)
  3641. // if the error doesnt check for illegal tag name, or the image is built
  3642. // then this should fail
  3643. if !strings.Contains(out, "Illegal tag name") || strings.Contains(out, "Sending build context to Docker daemon") {
  3644. c.Fatalf("failed to stop before building. Error: %s, Output: %s", err, out)
  3645. }
  3646. }
  3647. func (s *DockerSuite) TestBuildCmdShDashC(c *check.C) {
  3648. name := "testbuildcmdshc"
  3649. if _, err := buildImage(name, "FROM busybox\nCMD echo cmd\n", true); err != nil {
  3650. c.Fatal(err)
  3651. }
  3652. res, err := inspectFieldJSON(name, "Config.Cmd")
  3653. if err != nil {
  3654. c.Fatal(err, res)
  3655. }
  3656. expected := `["/bin/sh","-c","echo cmd"]`
  3657. if res != expected {
  3658. c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  3659. }
  3660. }
  3661. func (s *DockerSuite) TestBuildCmdSpaces(c *check.C) {
  3662. // Test to make sure that when we strcat arrays we take into account
  3663. // the arg separator to make sure ["echo","hi"] and ["echo hi"] don't
  3664. // look the same
  3665. name := "testbuildcmdspaces"
  3666. var id1 string
  3667. var id2 string
  3668. var err error
  3669. if id1, err = buildImage(name, "FROM busybox\nCMD [\"echo hi\"]\n", true); err != nil {
  3670. c.Fatal(err)
  3671. }
  3672. if id2, err = buildImage(name, "FROM busybox\nCMD [\"echo\", \"hi\"]\n", true); err != nil {
  3673. c.Fatal(err)
  3674. }
  3675. if id1 == id2 {
  3676. c.Fatal("Should not have resulted in the same CMD")
  3677. }
  3678. // Now do the same with ENTRYPOINT
  3679. if id1, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo hi\"]\n", true); err != nil {
  3680. c.Fatal(err)
  3681. }
  3682. if id2, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo\", \"hi\"]\n", true); err != nil {
  3683. c.Fatal(err)
  3684. }
  3685. if id1 == id2 {
  3686. c.Fatal("Should not have resulted in the same ENTRYPOINT")
  3687. }
  3688. }
  3689. func (s *DockerSuite) TestBuildCmdJSONNoShDashC(c *check.C) {
  3690. name := "testbuildcmdjson"
  3691. if _, err := buildImage(name, "FROM busybox\nCMD [\"echo\", \"cmd\"]", true); err != nil {
  3692. c.Fatal(err)
  3693. }
  3694. res, err := inspectFieldJSON(name, "Config.Cmd")
  3695. if err != nil {
  3696. c.Fatal(err, res)
  3697. }
  3698. expected := `["echo","cmd"]`
  3699. if res != expected {
  3700. c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  3701. }
  3702. }
  3703. func (s *DockerSuite) TestBuildErrorInvalidInstruction(c *check.C) {
  3704. name := "testbuildignoreinvalidinstruction"
  3705. out, _, err := buildImageWithOut(name, "FROM busybox\nfoo bar", true)
  3706. if err == nil {
  3707. c.Fatalf("Should have failed: %s", out)
  3708. }
  3709. }
  3710. func (s *DockerSuite) TestBuildEntrypointInheritance(c *check.C) {
  3711. if _, err := buildImage("parent", `
  3712. FROM busybox
  3713. ENTRYPOINT exit 130
  3714. `, true); err != nil {
  3715. c.Fatal(err)
  3716. }
  3717. status, _ := runCommand(exec.Command(dockerBinary, "run", "parent"))
  3718. if status != 130 {
  3719. c.Fatalf("expected exit code 130 but received %d", status)
  3720. }
  3721. if _, err := buildImage("child", `
  3722. FROM parent
  3723. ENTRYPOINT exit 5
  3724. `, true); err != nil {
  3725. c.Fatal(err)
  3726. }
  3727. status, _ = runCommand(exec.Command(dockerBinary, "run", "child"))
  3728. if status != 5 {
  3729. c.Fatalf("expected exit code 5 but received %d", status)
  3730. }
  3731. }
  3732. func (s *DockerSuite) TestBuildEntrypointInheritanceInspect(c *check.C) {
  3733. var (
  3734. name = "testbuildepinherit"
  3735. name2 = "testbuildepinherit2"
  3736. expected = `["/bin/sh","-c","echo quux"]`
  3737. )
  3738. if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil {
  3739. c.Fatal(err)
  3740. }
  3741. if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil {
  3742. c.Fatal(err)
  3743. }
  3744. res, err := inspectFieldJSON(name2, "Config.Entrypoint")
  3745. if err != nil {
  3746. c.Fatal(err, res)
  3747. }
  3748. if res != expected {
  3749. c.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res)
  3750. }
  3751. out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "-t", name2))
  3752. if err != nil {
  3753. c.Fatal(err, out)
  3754. }
  3755. expected = "quux"
  3756. if strings.TrimSpace(out) != expected {
  3757. c.Fatalf("Expected output is %s, got %s", expected, out)
  3758. }
  3759. }
  3760. func (s *DockerSuite) TestBuildRunShEntrypoint(c *check.C) {
  3761. name := "testbuildentrypoint"
  3762. _, err := buildImage(name,
  3763. `FROM busybox
  3764. ENTRYPOINT /bin/echo`,
  3765. true)
  3766. if err != nil {
  3767. c.Fatal(err)
  3768. }
  3769. out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  3770. if err != nil {
  3771. c.Fatal(err, out)
  3772. }
  3773. }
  3774. func (s *DockerSuite) TestBuildExoticShellInterpolation(c *check.C) {
  3775. name := "testbuildexoticshellinterpolation"
  3776. _, err := buildImage(name, `
  3777. FROM busybox
  3778. ENV SOME_VAR a.b.c
  3779. RUN [ "$SOME_VAR" = 'a.b.c' ]
  3780. RUN [ "${SOME_VAR}" = 'a.b.c' ]
  3781. RUN [ "${SOME_VAR%.*}" = 'a.b' ]
  3782. RUN [ "${SOME_VAR%%.*}" = 'a' ]
  3783. RUN [ "${SOME_VAR#*.}" = 'b.c' ]
  3784. RUN [ "${SOME_VAR##*.}" = 'c' ]
  3785. RUN [ "${SOME_VAR/c/d}" = 'a.b.d' ]
  3786. RUN [ "${#SOME_VAR}" = '5' ]
  3787. RUN [ "${SOME_UNSET_VAR:-$SOME_VAR}" = 'a.b.c' ]
  3788. RUN [ "${SOME_VAR:+Version: ${SOME_VAR}}" = 'Version: a.b.c' ]
  3789. RUN [ "${SOME_UNSET_VAR:+${SOME_VAR}}" = '' ]
  3790. RUN [ "${SOME_UNSET_VAR:-${SOME_VAR:-d.e.f}}" = 'a.b.c' ]
  3791. `, false)
  3792. if err != nil {
  3793. c.Fatal(err)
  3794. }
  3795. }
  3796. func (s *DockerSuite) TestBuildVerifySingleQuoteFails(c *check.C) {
  3797. // This testcase is supposed to generate an error because the
  3798. // JSON array we're passing in on the CMD uses single quotes instead
  3799. // of double quotes (per the JSON spec). This means we interpret it
  3800. // as a "string" insead of "JSON array" and pass it on to "sh -c" and
  3801. // it should barf on it.
  3802. name := "testbuildsinglequotefails"
  3803. _, err := buildImage(name,
  3804. `FROM busybox
  3805. CMD [ '/bin/sh', '-c', 'echo hi' ]`,
  3806. true)
  3807. _, _, err = runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  3808. if err == nil {
  3809. c.Fatal("The image was not supposed to be able to run")
  3810. }
  3811. }
  3812. func (s *DockerSuite) TestBuildVerboseOut(c *check.C) {
  3813. name := "testbuildverboseout"
  3814. _, out, err := buildImageWithOut(name,
  3815. `FROM busybox
  3816. RUN echo 123`,
  3817. false)
  3818. if err != nil {
  3819. c.Fatal(err)
  3820. }
  3821. if !strings.Contains(out, "\n123\n") {
  3822. c.Fatalf("Output should contain %q: %q", "123", out)
  3823. }
  3824. }
  3825. func (s *DockerSuite) TestBuildWithTabs(c *check.C) {
  3826. name := "testbuildwithtabs"
  3827. _, err := buildImage(name,
  3828. "FROM busybox\nRUN echo\tone\t\ttwo", true)
  3829. if err != nil {
  3830. c.Fatal(err)
  3831. }
  3832. res, err := inspectFieldJSON(name, "ContainerConfig.Cmd")
  3833. if err != nil {
  3834. c.Fatal(err)
  3835. }
  3836. expected1 := `["/bin/sh","-c","echo\tone\t\ttwo"]`
  3837. expected2 := `["/bin/sh","-c","echo\u0009one\u0009\u0009two"]` // syntactically equivalent, and what Go 1.3 generates
  3838. if res != expected1 && res != expected2 {
  3839. c.Fatalf("Missing tabs.\nGot: %s\nExp: %s or %s", res, expected1, expected2)
  3840. }
  3841. }
  3842. func (s *DockerSuite) TestBuildLabels(c *check.C) {
  3843. name := "testbuildlabel"
  3844. expected := `{"License":"GPL","Vendor":"Acme"}`
  3845. _, err := buildImage(name,
  3846. `FROM busybox
  3847. LABEL Vendor=Acme
  3848. LABEL License GPL`,
  3849. true)
  3850. if err != nil {
  3851. c.Fatal(err)
  3852. }
  3853. res, err := inspectFieldJSON(name, "Config.Labels")
  3854. if err != nil {
  3855. c.Fatal(err)
  3856. }
  3857. if res != expected {
  3858. c.Fatalf("Labels %s, expected %s", res, expected)
  3859. }
  3860. }
  3861. func (s *DockerSuite) TestBuildLabelsCache(c *check.C) {
  3862. name := "testbuildlabelcache"
  3863. id1, err := buildImage(name,
  3864. `FROM busybox
  3865. LABEL Vendor=Acme`, false)
  3866. if err != nil {
  3867. c.Fatalf("Build 1 should have worked: %v", err)
  3868. }
  3869. id2, err := buildImage(name,
  3870. `FROM busybox
  3871. LABEL Vendor=Acme`, true)
  3872. if err != nil || id1 != id2 {
  3873. c.Fatalf("Build 2 should have worked & used cache(%s,%s): %v", id1, id2, err)
  3874. }
  3875. id2, err = buildImage(name,
  3876. `FROM busybox
  3877. LABEL Vendor=Acme1`, true)
  3878. if err != nil || id1 == id2 {
  3879. c.Fatalf("Build 3 should have worked & NOT used cache(%s,%s): %v", id1, id2, err)
  3880. }
  3881. id2, err = buildImage(name,
  3882. `FROM busybox
  3883. LABEL Vendor Acme`, true) // Note: " " and "=" should be same
  3884. if err != nil || id1 != id2 {
  3885. c.Fatalf("Build 4 should have worked & used cache(%s,%s): %v", id1, id2, err)
  3886. }
  3887. // Now make sure the cache isn't used by mistake
  3888. id1, err = buildImage(name,
  3889. `FROM busybox
  3890. LABEL f1=b1 f2=b2`, false)
  3891. if err != nil {
  3892. c.Fatalf("Build 5 should have worked: %q", err)
  3893. }
  3894. id2, err = buildImage(name,
  3895. `FROM busybox
  3896. LABEL f1="b1 f2=b2"`, true)
  3897. if err != nil || id1 == id2 {
  3898. c.Fatalf("Build 6 should have worked & NOT used the cache(%s,%s): %q", id1, id2, err)
  3899. }
  3900. }
  3901. func (s *DockerSuite) TestBuildStderr(c *check.C) {
  3902. // This test just makes sure that no non-error output goes
  3903. // to stderr
  3904. name := "testbuildstderr"
  3905. _, _, stderr, err := buildImageWithStdoutStderr(name,
  3906. "FROM busybox\nRUN echo one", true)
  3907. if err != nil {
  3908. c.Fatal(err)
  3909. }
  3910. if runtime.GOOS == "windows" {
  3911. // stderr might contain a security warning on windows
  3912. lines := strings.Split(stderr, "\n")
  3913. for _, v := range lines {
  3914. if v != "" && !strings.Contains(v, "SECURITY WARNING:") {
  3915. c.Fatalf("Stderr contains unexpected output line: %q", v)
  3916. }
  3917. }
  3918. } else {
  3919. if stderr != "" {
  3920. c.Fatalf("Stderr should have been empty, instead its: %q", stderr)
  3921. }
  3922. }
  3923. }
  3924. func (s *DockerSuite) TestBuildChownSingleFile(c *check.C) {
  3925. testRequires(c, UnixCli) // test uses chown: not available on windows
  3926. name := "testbuildchownsinglefile"
  3927. ctx, err := fakeContext(`
  3928. FROM busybox
  3929. COPY test /
  3930. RUN ls -l /test
  3931. RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ]
  3932. `, map[string]string{
  3933. "test": "test",
  3934. })
  3935. if err != nil {
  3936. c.Fatal(err)
  3937. }
  3938. defer ctx.Close()
  3939. if err := os.Chown(filepath.Join(ctx.Dir, "test"), 4242, 4242); err != nil {
  3940. c.Fatal(err)
  3941. }
  3942. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3943. c.Fatal(err)
  3944. }
  3945. }
  3946. func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) {
  3947. name := "testbuildsymlinkbreakout"
  3948. tmpdir, err := ioutil.TempDir("", name)
  3949. if err != nil {
  3950. c.Fatal(err)
  3951. }
  3952. defer os.RemoveAll(tmpdir)
  3953. ctx := filepath.Join(tmpdir, "context")
  3954. if err := os.MkdirAll(ctx, 0755); err != nil {
  3955. c.Fatal(err)
  3956. }
  3957. if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(`
  3958. from busybox
  3959. add symlink.tar /
  3960. add inject /symlink/
  3961. `), 0644); err != nil {
  3962. c.Fatal(err)
  3963. }
  3964. inject := filepath.Join(ctx, "inject")
  3965. if err := ioutil.WriteFile(inject, nil, 0644); err != nil {
  3966. c.Fatal(err)
  3967. }
  3968. f, err := os.Create(filepath.Join(ctx, "symlink.tar"))
  3969. if err != nil {
  3970. c.Fatal(err)
  3971. }
  3972. w := tar.NewWriter(f)
  3973. w.WriteHeader(&tar.Header{
  3974. Name: "symlink2",
  3975. Typeflag: tar.TypeSymlink,
  3976. Linkname: "/../../../../../../../../../../../../../../",
  3977. Uid: os.Getuid(),
  3978. Gid: os.Getgid(),
  3979. })
  3980. w.WriteHeader(&tar.Header{
  3981. Name: "symlink",
  3982. Typeflag: tar.TypeSymlink,
  3983. Linkname: filepath.Join("symlink2", tmpdir),
  3984. Uid: os.Getuid(),
  3985. Gid: os.Getgid(),
  3986. })
  3987. w.Close()
  3988. f.Close()
  3989. if _, err := buildImageFromContext(name, fakeContextFromDir(ctx), false); err != nil {
  3990. c.Fatal(err)
  3991. }
  3992. if _, err := os.Lstat(filepath.Join(tmpdir, "inject")); err == nil {
  3993. c.Fatal("symlink breakout - inject")
  3994. } else if !os.IsNotExist(err) {
  3995. c.Fatalf("unexpected error: %v", err)
  3996. }
  3997. }
  3998. func (s *DockerSuite) TestBuildXZHost(c *check.C) {
  3999. name := "testbuildxzhost"
  4000. ctx, err := fakeContext(`
  4001. FROM busybox
  4002. ADD xz /usr/local/sbin/
  4003. RUN chmod 755 /usr/local/sbin/xz
  4004. ADD test.xz /
  4005. RUN [ ! -e /injected ]`,
  4006. map[string]string{
  4007. "test.xz": "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00" +
  4008. "\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd" +
  4009. "\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21",
  4010. "xz": "#!/bin/sh\ntouch /injected",
  4011. })
  4012. if err != nil {
  4013. c.Fatal(err)
  4014. }
  4015. defer ctx.Close()
  4016. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4017. c.Fatal(err)
  4018. }
  4019. }
  4020. func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) {
  4021. var (
  4022. name = "testbuildvolumescontent"
  4023. expected = "some text"
  4024. )
  4025. ctx, err := fakeContext(`
  4026. FROM busybox
  4027. COPY content /foo/file
  4028. VOLUME /foo
  4029. CMD cat /foo/file`,
  4030. map[string]string{
  4031. "content": expected,
  4032. })
  4033. if err != nil {
  4034. c.Fatal(err)
  4035. }
  4036. defer ctx.Close()
  4037. if _, err := buildImageFromContext(name, ctx, false); err != nil {
  4038. c.Fatal(err)
  4039. }
  4040. out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "run", "--rm", name))
  4041. if err != nil {
  4042. c.Fatal(err)
  4043. }
  4044. if out != expected {
  4045. c.Fatalf("expected file contents for /foo/file to be %q but received %q", expected, out)
  4046. }
  4047. }
  4048. func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
  4049. ctx, err := fakeContext(`FROM busybox
  4050. RUN echo from Dockerfile`,
  4051. map[string]string{
  4052. "Dockerfile": "FROM busybox\nRUN echo from Dockerfile",
  4053. "files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile",
  4054. "files/dFile": "FROM busybox\nRUN echo from files/dFile",
  4055. "dFile": "FROM busybox\nRUN echo from dFile",
  4056. "files/dFile2": "FROM busybox\nRUN echo from files/dFile2",
  4057. })
  4058. defer ctx.Close()
  4059. if err != nil {
  4060. c.Fatal(err)
  4061. }
  4062. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4063. if err != nil {
  4064. c.Fatalf("Failed to build: %s\n%s", out, err)
  4065. }
  4066. if !strings.Contains(out, "from Dockerfile") {
  4067. c.Fatalf("test1 should have used Dockerfile, output:%s", out)
  4068. }
  4069. out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-f", filepath.Join("files", "Dockerfile"), "-t", "test2", ".")
  4070. if err != nil {
  4071. c.Fatal(err)
  4072. }
  4073. if !strings.Contains(out, "from files/Dockerfile") {
  4074. c.Fatalf("test2 should have used files/Dockerfile, output:%s", out)
  4075. }
  4076. out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", filepath.Join("files", "dFile")), "-t", "test3", ".")
  4077. if err != nil {
  4078. c.Fatal(err)
  4079. }
  4080. if !strings.Contains(out, "from files/dFile") {
  4081. c.Fatalf("test3 should have used files/dFile, output:%s", out)
  4082. }
  4083. out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--file=dFile", "-t", "test4", ".")
  4084. if err != nil {
  4085. c.Fatal(err)
  4086. }
  4087. if !strings.Contains(out, "from dFile") {
  4088. c.Fatalf("test4 should have used dFile, output:%s", out)
  4089. }
  4090. dirWithNoDockerfile, _ := ioutil.TempDir(os.TempDir(), "test5")
  4091. nonDockerfileFile := filepath.Join(dirWithNoDockerfile, "notDockerfile")
  4092. if _, err = os.Create(nonDockerfileFile); err != nil {
  4093. c.Fatal(err)
  4094. }
  4095. out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", nonDockerfileFile), "-t", "test5", ".")
  4096. if err == nil {
  4097. c.Fatalf("test5 was supposed to fail to find passwd")
  4098. }
  4099. if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", strings.Replace(nonDockerfileFile, `\`, `\\`, -1)); !strings.Contains(out, expected) {
  4100. c.Fatalf("wrong error messsage:%v\nexpected to contain=%v", out, expected)
  4101. }
  4102. out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test6", "..")
  4103. if err != nil {
  4104. c.Fatalf("test6 failed: %s", err)
  4105. }
  4106. if !strings.Contains(out, "from Dockerfile") {
  4107. c.Fatalf("test6 should have used root Dockerfile, output:%s", out)
  4108. }
  4109. out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join(ctx.Dir, "files", "Dockerfile"), "-t", "test7", "..")
  4110. if err != nil {
  4111. c.Fatalf("test7 failed: %s", err)
  4112. }
  4113. if !strings.Contains(out, "from files/Dockerfile") {
  4114. c.Fatalf("test7 should have used files Dockerfile, output:%s", out)
  4115. }
  4116. out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test8", ".")
  4117. if err == nil || !strings.Contains(out, "must be within the build context") {
  4118. c.Fatalf("test8 should have failed with Dockerfile out of context: %s", err)
  4119. }
  4120. tmpDir := os.TempDir()
  4121. out, _, err = dockerCmdInDir(c, tmpDir, "build", "-t", "test9", ctx.Dir)
  4122. if err != nil {
  4123. c.Fatalf("test9 - failed: %s", err)
  4124. }
  4125. if !strings.Contains(out, "from Dockerfile") {
  4126. c.Fatalf("test9 should have used root Dockerfile, output:%s", out)
  4127. }
  4128. out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", "dFile2", "-t", "test10", ".")
  4129. if err != nil {
  4130. c.Fatalf("test10 should have worked: %s", err)
  4131. }
  4132. if !strings.Contains(out, "from files/dFile2") {
  4133. c.Fatalf("test10 should have used files/dFile2, output:%s", out)
  4134. }
  4135. }
  4136. func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) {
  4137. testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4138. ctx, err := fakeContext(`FROM busybox
  4139. RUN echo from dockerfile`,
  4140. map[string]string{
  4141. "dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4142. })
  4143. defer ctx.Close()
  4144. if err != nil {
  4145. c.Fatal(err)
  4146. }
  4147. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4148. if err != nil {
  4149. c.Fatalf("Failed to build: %s\n%s", out, err)
  4150. }
  4151. if !strings.Contains(out, "from dockerfile") {
  4152. c.Fatalf("Missing proper output: %s", out)
  4153. }
  4154. }
  4155. func (s *DockerSuite) TestBuildWithTwoDockerfiles(c *check.C) {
  4156. testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4157. ctx, err := fakeContext(`FROM busybox
  4158. RUN echo from Dockerfile`,
  4159. map[string]string{
  4160. "dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4161. })
  4162. defer ctx.Close()
  4163. if err != nil {
  4164. c.Fatal(err)
  4165. }
  4166. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4167. if err != nil {
  4168. c.Fatalf("Failed to build: %s\n%s", out, err)
  4169. }
  4170. if !strings.Contains(out, "from Dockerfile") {
  4171. c.Fatalf("Missing proper output: %s", out)
  4172. }
  4173. }
  4174. func (s *DockerSuite) TestBuildFromURLWithF(c *check.C) {
  4175. server, err := fakeStorage(map[string]string{"baz": `FROM busybox
  4176. RUN echo from baz
  4177. COPY * /tmp/
  4178. RUN find /tmp/`})
  4179. if err != nil {
  4180. c.Fatal(err)
  4181. }
  4182. defer server.Close()
  4183. ctx, err := fakeContext(`FROM busybox
  4184. RUN echo from Dockerfile`,
  4185. map[string]string{})
  4186. defer ctx.Close()
  4187. if err != nil {
  4188. c.Fatal(err)
  4189. }
  4190. // Make sure that -f is ignored and that we don't use the Dockerfile
  4191. // that's in the current dir
  4192. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-f", "baz", "-t", "test1", server.URL()+"/baz")
  4193. if err != nil {
  4194. c.Fatalf("Failed to build: %s\n%s", out, err)
  4195. }
  4196. if !strings.Contains(out, "from baz") ||
  4197. strings.Contains(out, "/tmp/baz") ||
  4198. !strings.Contains(out, "/tmp/Dockerfile") {
  4199. c.Fatalf("Missing proper output: %s", out)
  4200. }
  4201. }
  4202. func (s *DockerSuite) TestBuildFromStdinWithF(c *check.C) {
  4203. ctx, err := fakeContext(`FROM busybox
  4204. RUN echo from Dockerfile`,
  4205. map[string]string{})
  4206. defer ctx.Close()
  4207. if err != nil {
  4208. c.Fatal(err)
  4209. }
  4210. // Make sure that -f is ignored and that we don't use the Dockerfile
  4211. // that's in the current dir
  4212. dockerCommand := exec.Command(dockerBinary, "build", "-f", "baz", "-t", "test1", "-")
  4213. dockerCommand.Dir = ctx.Dir
  4214. dockerCommand.Stdin = strings.NewReader(`FROM busybox
  4215. RUN echo from baz
  4216. COPY * /tmp/
  4217. RUN find /tmp/`)
  4218. out, status, err := runCommandWithOutput(dockerCommand)
  4219. if err != nil || status != 0 {
  4220. c.Fatalf("Error building: %s", err)
  4221. }
  4222. if !strings.Contains(out, "from baz") ||
  4223. strings.Contains(out, "/tmp/baz") ||
  4224. !strings.Contains(out, "/tmp/Dockerfile") {
  4225. c.Fatalf("Missing proper output: %s", out)
  4226. }
  4227. }
  4228. func (s *DockerSuite) TestBuildFromOfficialNames(c *check.C) {
  4229. name := "testbuildfromofficial"
  4230. fromNames := []string{
  4231. "busybox",
  4232. "docker.io/busybox",
  4233. "index.docker.io/busybox",
  4234. "library/busybox",
  4235. "docker.io/library/busybox",
  4236. "index.docker.io/library/busybox",
  4237. }
  4238. for idx, fromName := range fromNames {
  4239. imgName := fmt.Sprintf("%s%d", name, idx)
  4240. _, err := buildImage(imgName, "FROM "+fromName, true)
  4241. if err != nil {
  4242. c.Errorf("Build failed using FROM %s: %s", fromName, err)
  4243. }
  4244. deleteImages(imgName)
  4245. }
  4246. }
  4247. func (s *DockerSuite) TestBuildDockerfileOutsideContext(c *check.C) {
  4248. testRequires(c, UnixCli) // uses os.Symlink: not implemented in windows at the time of writing (go-1.4.2)
  4249. name := "testbuilddockerfileoutsidecontext"
  4250. tmpdir, err := ioutil.TempDir("", name)
  4251. if err != nil {
  4252. c.Fatal(err)
  4253. }
  4254. defer os.RemoveAll(tmpdir)
  4255. ctx := filepath.Join(tmpdir, "context")
  4256. if err := os.MkdirAll(ctx, 0755); err != nil {
  4257. c.Fatal(err)
  4258. }
  4259. if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte("FROM scratch\nENV X Y"), 0644); err != nil {
  4260. c.Fatal(err)
  4261. }
  4262. wd, err := os.Getwd()
  4263. if err != nil {
  4264. c.Fatal(err)
  4265. }
  4266. defer os.Chdir(wd)
  4267. if err := os.Chdir(ctx); err != nil {
  4268. c.Fatal(err)
  4269. }
  4270. if err := ioutil.WriteFile(filepath.Join(tmpdir, "outsideDockerfile"), []byte("FROM scratch\nENV x y"), 0644); err != nil {
  4271. c.Fatal(err)
  4272. }
  4273. if err := os.Symlink(filepath.Join("..", "outsideDockerfile"), filepath.Join(ctx, "dockerfile1")); err != nil {
  4274. c.Fatal(err)
  4275. }
  4276. if err := os.Symlink(filepath.Join(tmpdir, "outsideDockerfile"), filepath.Join(ctx, "dockerfile2")); err != nil {
  4277. c.Fatal(err)
  4278. }
  4279. for _, dockerfilePath := range []string{
  4280. filepath.Join("..", "outsideDockerfile"),
  4281. filepath.Join(ctx, "dockerfile1"),
  4282. filepath.Join(ctx, "dockerfile2"),
  4283. } {
  4284. out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "build", "-t", name, "--no-cache", "-f", dockerfilePath, "."))
  4285. if err == nil {
  4286. c.Fatalf("Expected error with %s. Out: %s", dockerfilePath, out)
  4287. }
  4288. if !strings.Contains(out, "must be within the build context") && !strings.Contains(out, "Cannot locate Dockerfile") {
  4289. c.Fatalf("Unexpected error with %s. Out: %s", dockerfilePath, out)
  4290. }
  4291. deleteImages(name)
  4292. }
  4293. os.Chdir(tmpdir)
  4294. // Path to Dockerfile should be resolved relative to working directory, not relative to context.
  4295. // There is a Dockerfile in the context, but since there is no Dockerfile in the current directory, the following should fail
  4296. out, _, err := runCommandWithOutput(exec.Command(dockerBinary, "build", "-t", name, "--no-cache", "-f", "Dockerfile", ctx))
  4297. if err == nil {
  4298. c.Fatalf("Expected error. Out: %s", out)
  4299. }
  4300. }
  4301. func (s *DockerSuite) TestBuildSpaces(c *check.C) {
  4302. // Test to make sure that leading/trailing spaces on a command
  4303. // doesn't change the error msg we get
  4304. var (
  4305. err1 error
  4306. err2 error
  4307. )
  4308. name := "testspaces"
  4309. ctx, err := fakeContext("FROM busybox\nCOPY\n",
  4310. map[string]string{
  4311. "Dockerfile": "FROM busybox\nCOPY\n",
  4312. })
  4313. if err != nil {
  4314. c.Fatal(err)
  4315. }
  4316. defer ctx.Close()
  4317. if _, err1 = buildImageFromContext(name, ctx, false); err1 == nil {
  4318. c.Fatal("Build 1 was supposed to fail, but didn't")
  4319. }
  4320. ctx.Add("Dockerfile", "FROM busybox\nCOPY ")
  4321. if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  4322. c.Fatal("Build 2 was supposed to fail, but didn't")
  4323. }
  4324. removeLogTimestamps := func(s string) string {
  4325. return regexp.MustCompile(`time="(.*?)"`).ReplaceAllString(s, `time=[TIMESTAMP]`)
  4326. }
  4327. // Skip over the times
  4328. e1 := removeLogTimestamps(err1.Error())
  4329. e2 := removeLogTimestamps(err2.Error())
  4330. // Ignore whitespace since that's what were verifying doesn't change stuff
  4331. if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  4332. c.Fatalf("Build 2's error wasn't the same as build 1's\n1:%s\n2:%s", err1, err2)
  4333. }
  4334. ctx.Add("Dockerfile", "FROM busybox\n COPY")
  4335. if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  4336. c.Fatal("Build 3 was supposed to fail, but didn't")
  4337. }
  4338. // Skip over the times
  4339. e1 = removeLogTimestamps(err1.Error())
  4340. e2 = removeLogTimestamps(err2.Error())
  4341. // Ignore whitespace since that's what were verifying doesn't change stuff
  4342. if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  4343. c.Fatalf("Build 3's error wasn't the same as build 1's\n1:%s\n3:%s", err1, err2)
  4344. }
  4345. ctx.Add("Dockerfile", "FROM busybox\n COPY ")
  4346. if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  4347. c.Fatal("Build 4 was supposed to fail, but didn't")
  4348. }
  4349. // Skip over the times
  4350. e1 = removeLogTimestamps(err1.Error())
  4351. e2 = removeLogTimestamps(err2.Error())
  4352. // Ignore whitespace since that's what were verifying doesn't change stuff
  4353. if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  4354. c.Fatalf("Build 4's error wasn't the same as build 1's\n1:%s\n4:%s", err1, err2)
  4355. }
  4356. }
  4357. func (s *DockerSuite) TestBuildSpacesWithQuotes(c *check.C) {
  4358. // Test to make sure that spaces in quotes aren't lost
  4359. name := "testspacesquotes"
  4360. dockerfile := `FROM busybox
  4361. RUN echo " \
  4362. foo "`
  4363. _, out, err := buildImageWithOut(name, dockerfile, false)
  4364. if err != nil {
  4365. c.Fatal("Build failed:", err)
  4366. }
  4367. expecting := "\n foo \n"
  4368. if !strings.Contains(out, expecting) {
  4369. c.Fatalf("Bad output: %q expecting to contain %q", out, expecting)
  4370. }
  4371. }
  4372. // #4393
  4373. func (s *DockerSuite) TestBuildVolumeFileExistsinContainer(c *check.C) {
  4374. buildCmd := exec.Command(dockerBinary, "build", "-t", "docker-test-errcreatevolumewithfile", "-")
  4375. buildCmd.Stdin = strings.NewReader(`
  4376. FROM busybox
  4377. RUN touch /foo
  4378. VOLUME /foo
  4379. `)
  4380. out, _, err := runCommandWithOutput(buildCmd)
  4381. if err == nil || !strings.Contains(out, "file exists") {
  4382. c.Fatalf("expected build to fail when file exists in container at requested volume path")
  4383. }
  4384. }
  4385. func (s *DockerSuite) TestBuildMissingArgs(c *check.C) {
  4386. // Test to make sure that all Dockerfile commands (except the ones listed
  4387. // in skipCmds) will generate an error if no args are provided.
  4388. // Note: INSERT is deprecated so we exclude it because of that.
  4389. skipCmds := map[string]struct{}{
  4390. "CMD": {},
  4391. "RUN": {},
  4392. "ENTRYPOINT": {},
  4393. "INSERT": {},
  4394. }
  4395. for cmd := range command.Commands {
  4396. cmd = strings.ToUpper(cmd)
  4397. if _, ok := skipCmds[cmd]; ok {
  4398. continue
  4399. }
  4400. var dockerfile string
  4401. if cmd == "FROM" {
  4402. dockerfile = cmd
  4403. } else {
  4404. // Add FROM to make sure we don't complain about it missing
  4405. dockerfile = "FROM busybox\n" + cmd
  4406. }
  4407. ctx, err := fakeContext(dockerfile, map[string]string{})
  4408. if err != nil {
  4409. c.Fatal(err)
  4410. }
  4411. defer ctx.Close()
  4412. var out string
  4413. if out, err = buildImageFromContext("args", ctx, true); err == nil {
  4414. c.Fatalf("%s was supposed to fail. Out:%s", cmd, out)
  4415. }
  4416. if !strings.Contains(err.Error(), cmd+" requires") {
  4417. c.Fatalf("%s returned the wrong type of error:%s", cmd, err)
  4418. }
  4419. }
  4420. }
  4421. func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) {
  4422. _, out, err := buildImageWithOut("sc", "FROM scratch", true)
  4423. if err == nil {
  4424. c.Fatalf("Build was supposed to fail")
  4425. }
  4426. if !strings.Contains(out, "No image was generated") {
  4427. c.Fatalf("Wrong error message: %v", out)
  4428. }
  4429. }
  4430. func (s *DockerSuite) TestBuildDotDotFile(c *check.C) {
  4431. ctx, err := fakeContext("FROM busybox\n",
  4432. map[string]string{
  4433. "..gitme": "",
  4434. })
  4435. if err != nil {
  4436. c.Fatal(err)
  4437. }
  4438. defer ctx.Close()
  4439. if _, err = buildImageFromContext("sc", ctx, false); err != nil {
  4440. c.Fatalf("Build was supposed to work: %s", err)
  4441. }
  4442. }
  4443. func (s *DockerSuite) TestBuildNotVerbose(c *check.C) {
  4444. ctx, err := fakeContext("FROM busybox\nENV abc=hi\nRUN echo $abc there", map[string]string{})
  4445. if err != nil {
  4446. c.Fatal(err)
  4447. }
  4448. defer ctx.Close()
  4449. // First do it w/verbose - baseline
  4450. buildCmd := exec.Command(dockerBinary, "build", "--no-cache", "-t", "verbose", ".")
  4451. buildCmd.Dir = ctx.Dir
  4452. out, _, err := runCommandWithOutput(buildCmd)
  4453. if err != nil {
  4454. c.Fatalf("failed to build the image w/o -q: %s, %v", out, err)
  4455. }
  4456. if !strings.Contains(out, "hi there") {
  4457. c.Fatalf("missing output:%s\n", out)
  4458. }
  4459. // Now do it w/o verbose
  4460. buildCmd = exec.Command(dockerBinary, "build", "--no-cache", "-q", "-t", "verbose", ".")
  4461. buildCmd.Dir = ctx.Dir
  4462. out, _, err = runCommandWithOutput(buildCmd)
  4463. if err != nil {
  4464. c.Fatalf("failed to build the image w/ -q: %s, %v", out, err)
  4465. }
  4466. if strings.Contains(out, "hi there") {
  4467. c.Fatalf("Bad output, should not contain 'hi there':%s", out)
  4468. }
  4469. }
  4470. func (s *DockerSuite) TestBuildRUNoneJSON(c *check.C) {
  4471. name := "testbuildrunonejson"
  4472. ctx, err := fakeContext(`FROM hello-world:frozen
  4473. RUN [ "/hello" ]`, map[string]string{})
  4474. if err != nil {
  4475. c.Fatal(err)
  4476. }
  4477. defer ctx.Close()
  4478. buildCmd := exec.Command(dockerBinary, "build", "--no-cache", "-t", name, ".")
  4479. buildCmd.Dir = ctx.Dir
  4480. out, _, err := runCommandWithOutput(buildCmd)
  4481. if err != nil {
  4482. c.Fatalf("failed to build the image: %s, %v", out, err)
  4483. }
  4484. if !strings.Contains(out, "Hello from Docker") {
  4485. c.Fatalf("bad output: %s", out)
  4486. }
  4487. }
  4488. func (s *DockerSuite) TestBuildResourceConstraintsAreUsed(c *check.C) {
  4489. name := "testbuildresourceconstraints"
  4490. ctx, err := fakeContext(`
  4491. FROM hello-world:frozen
  4492. RUN ["/hello"]
  4493. `, map[string]string{})
  4494. if err != nil {
  4495. c.Fatal(err)
  4496. }
  4497. cmd := exec.Command(dockerBinary, "build", "--no-cache", "--rm=false", "--memory=64m", "--memory-swap=-1", "--cpuset-cpus=0", "--cpuset-mems=0", "--cpu-shares=100", "--cpu-quota=8000", "-t", name, ".")
  4498. cmd.Dir = ctx.Dir
  4499. out, _, err := runCommandWithOutput(cmd)
  4500. if err != nil {
  4501. c.Fatal(err, out)
  4502. }
  4503. out, _ = dockerCmd(c, "ps", "-lq")
  4504. cID := strings.TrimSpace(out)
  4505. type hostConfig struct {
  4506. Memory int64
  4507. MemorySwap int64
  4508. CpusetCpus string
  4509. CpusetMems string
  4510. CpuShares int64
  4511. CpuQuota int64
  4512. }
  4513. cfg, err := inspectFieldJSON(cID, "HostConfig")
  4514. if err != nil {
  4515. c.Fatal(err)
  4516. }
  4517. var c1 hostConfig
  4518. if err := json.Unmarshal([]byte(cfg), &c1); err != nil {
  4519. c.Fatal(err, cfg)
  4520. }
  4521. if c1.Memory != 67108864 || c1.MemorySwap != -1 || c1.CpusetCpus != "0" || c1.CpusetMems != "0" || c1.CpuShares != 100 || c1.CpuQuota != 8000 {
  4522. c.Fatalf("resource constraints not set properly:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CpuShares: %d, CpuQuota: %d",
  4523. c1.Memory, c1.MemorySwap, c1.CpusetCpus, c1.CpusetMems, c1.CpuShares, c1.CpuQuota)
  4524. }
  4525. // Make sure constraints aren't saved to image
  4526. _, _ = dockerCmd(c, "run", "--name=test", name)
  4527. cfg, err = inspectFieldJSON("test", "HostConfig")
  4528. if err != nil {
  4529. c.Fatal(err)
  4530. }
  4531. var c2 hostConfig
  4532. if err := json.Unmarshal([]byte(cfg), &c2); err != nil {
  4533. c.Fatal(err, cfg)
  4534. }
  4535. if c2.Memory == 67108864 || c2.MemorySwap == -1 || c2.CpusetCpus == "0" || c2.CpusetMems == "0" || c2.CpuShares == 100 || c2.CpuQuota == 8000 {
  4536. c.Fatalf("resource constraints leaked from build:\nMemory: %d, MemSwap: %d, CpusetCpus: %s, CpusetMems: %s, CpuShares: %d, CpuQuota: %d",
  4537. c2.Memory, c2.MemorySwap, c2.CpusetCpus, c2.CpusetMems, c2.CpuShares, c2.CpuQuota)
  4538. }
  4539. }
  4540. func (s *DockerSuite) TestBuildEmptyStringVolume(c *check.C) {
  4541. name := "testbuildemptystringvolume"
  4542. _, err := buildImage(name, `
  4543. FROM busybox
  4544. ENV foo=""
  4545. VOLUME $foo
  4546. `, false)
  4547. if err == nil {
  4548. c.Fatal("Should have failed to build")
  4549. }
  4550. }