docker_cli_build_test.go 171 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488
  1. package main
  2. import (
  3. "archive/tar"
  4. "bytes"
  5. "encoding/json"
  6. "fmt"
  7. "io/ioutil"
  8. "os"
  9. "os/exec"
  10. "path/filepath"
  11. "reflect"
  12. "regexp"
  13. "runtime"
  14. "strconv"
  15. "strings"
  16. "text/template"
  17. "time"
  18. "github.com/docker/docker/builder/dockerfile/command"
  19. "github.com/docker/docker/pkg/archive"
  20. "github.com/docker/docker/pkg/integration/checker"
  21. "github.com/docker/docker/pkg/stringutils"
  22. "github.com/go-check/check"
  23. )
  24. func (s *DockerSuite) TestBuildJSONEmptyRun(c *check.C) {
  25. testRequires(c, DaemonIsLinux)
  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. testRequires(c, DaemonIsLinux)
  40. name := "testbuildemptywhitespace"
  41. _, err := buildImage(
  42. name,
  43. `
  44. FROM busybox
  45. COPY
  46. quux \
  47. bar
  48. `,
  49. true)
  50. if err == nil {
  51. c.Fatal("no error when dealing with a COPY statement with no content on the same line")
  52. }
  53. }
  54. func (s *DockerSuite) TestBuildShCmdJSONEntrypoint(c *check.C) {
  55. testRequires(c, DaemonIsLinux)
  56. name := "testbuildshcmdjsonentrypoint"
  57. _, err := buildImage(
  58. name,
  59. `
  60. FROM busybox
  61. ENTRYPOINT ["/bin/echo"]
  62. CMD echo test
  63. `,
  64. true)
  65. if err != nil {
  66. c.Fatal(err)
  67. }
  68. out, _ := dockerCmd(c, "run", "--rm", name)
  69. if strings.TrimSpace(out) != "/bin/sh -c echo test" {
  70. c.Fatalf("CMD did not contain /bin/sh -c : %s", out)
  71. }
  72. }
  73. func (s *DockerSuite) TestBuildEnvironmentReplacementUser(c *check.C) {
  74. testRequires(c, DaemonIsLinux)
  75. name := "testbuildenvironmentreplacement"
  76. _, err := buildImage(name, `
  77. FROM scratch
  78. ENV user foo
  79. USER ${user}
  80. `, true)
  81. if err != nil {
  82. c.Fatal(err)
  83. }
  84. res := inspectFieldJSON(c, name, "Config.User")
  85. if res != `"foo"` {
  86. c.Fatal("User foo from environment not in Config.User on image")
  87. }
  88. }
  89. func (s *DockerSuite) TestBuildEnvironmentReplacementVolume(c *check.C) {
  90. testRequires(c, DaemonIsLinux)
  91. name := "testbuildenvironmentreplacement"
  92. _, err := buildImage(name, `
  93. FROM scratch
  94. ENV volume /quux
  95. VOLUME ${volume}
  96. `, true)
  97. if err != nil {
  98. c.Fatal(err)
  99. }
  100. res := inspectFieldJSON(c, name, "Config.Volumes")
  101. var volumes map[string]interface{}
  102. if err := json.Unmarshal([]byte(res), &volumes); err != nil {
  103. c.Fatal(err)
  104. }
  105. if _, ok := volumes["/quux"]; !ok {
  106. c.Fatal("Volume /quux from environment not in Config.Volumes on image")
  107. }
  108. }
  109. func (s *DockerSuite) TestBuildEnvironmentReplacementExpose(c *check.C) {
  110. testRequires(c, DaemonIsLinux)
  111. name := "testbuildenvironmentreplacement"
  112. _, err := buildImage(name, `
  113. FROM scratch
  114. ENV port 80
  115. EXPOSE ${port}
  116. ENV ports " 99 100 "
  117. EXPOSE ${ports}
  118. `, true)
  119. if err != nil {
  120. c.Fatal(err)
  121. }
  122. res := inspectFieldJSON(c, name, "Config.ExposedPorts")
  123. var exposedPorts map[string]interface{}
  124. if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
  125. c.Fatal(err)
  126. }
  127. exp := []int{80, 99, 100}
  128. for _, p := range exp {
  129. tmp := fmt.Sprintf("%d/tcp", p)
  130. if _, ok := exposedPorts[tmp]; !ok {
  131. c.Fatalf("Exposed port %d from environment not in Config.ExposedPorts on image", p)
  132. }
  133. }
  134. }
  135. func (s *DockerSuite) TestBuildEnvironmentReplacementWorkdir(c *check.C) {
  136. testRequires(c, DaemonIsLinux)
  137. name := "testbuildenvironmentreplacement"
  138. _, err := buildImage(name, `
  139. FROM busybox
  140. ENV MYWORKDIR /work
  141. RUN mkdir ${MYWORKDIR}
  142. WORKDIR ${MYWORKDIR}
  143. `, true)
  144. if err != nil {
  145. c.Fatal(err)
  146. }
  147. }
  148. func (s *DockerSuite) TestBuildEnvironmentReplacementAddCopy(c *check.C) {
  149. testRequires(c, DaemonIsLinux)
  150. name := "testbuildenvironmentreplacement"
  151. ctx, err := fakeContext(`
  152. FROM scratch
  153. ENV baz foo
  154. ENV quux bar
  155. ENV dot .
  156. ENV fee fff
  157. ENV gee ggg
  158. ADD ${baz} ${dot}
  159. COPY ${quux} ${dot}
  160. ADD ${zzz:-${fee}} ${dot}
  161. COPY ${zzz:-${gee}} ${dot}
  162. `,
  163. map[string]string{
  164. "foo": "test1",
  165. "bar": "test2",
  166. "fff": "test3",
  167. "ggg": "test4",
  168. })
  169. if err != nil {
  170. c.Fatal(err)
  171. }
  172. defer ctx.Close()
  173. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  174. c.Fatal(err)
  175. }
  176. }
  177. func (s *DockerSuite) TestBuildEnvironmentReplacementEnv(c *check.C) {
  178. testRequires(c, DaemonIsLinux)
  179. name := "testbuildenvironmentreplacement"
  180. _, err := buildImage(name,
  181. `
  182. FROM busybox
  183. ENV foo zzz
  184. ENV bar ${foo}
  185. ENV abc1='$foo'
  186. ENV env1=$foo env2=${foo} env3="$foo" env4="${foo}"
  187. RUN [ "$abc1" = '$foo' ] && (echo "$abc1" | grep -q foo)
  188. ENV abc2="\$foo"
  189. RUN [ "$abc2" = '$foo' ] && (echo "$abc2" | grep -q foo)
  190. ENV abc3 '$foo'
  191. RUN [ "$abc3" = '$foo' ] && (echo "$abc3" | grep -q foo)
  192. ENV abc4 "\$foo"
  193. RUN [ "$abc4" = '$foo' ] && (echo "$abc4" | grep -q foo)
  194. `, true)
  195. if err != nil {
  196. c.Fatal(err)
  197. }
  198. res := inspectFieldJSON(c, name, "Config.Env")
  199. envResult := []string{}
  200. if err = unmarshalJSON([]byte(res), &envResult); err != nil {
  201. c.Fatal(err)
  202. }
  203. found := false
  204. envCount := 0
  205. for _, env := range envResult {
  206. parts := strings.SplitN(env, "=", 2)
  207. if parts[0] == "bar" {
  208. found = true
  209. if parts[1] != "zzz" {
  210. c.Fatalf("Could not find replaced var for env `bar`: got %q instead of `zzz`", parts[1])
  211. }
  212. } else if strings.HasPrefix(parts[0], "env") {
  213. envCount++
  214. if parts[1] != "zzz" {
  215. c.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
  216. }
  217. } else if strings.HasPrefix(parts[0], "env") {
  218. envCount++
  219. if parts[1] != "foo" {
  220. c.Fatalf("%s should be 'foo' but instead its %q", parts[0], parts[1])
  221. }
  222. }
  223. }
  224. if !found {
  225. c.Fatal("Never found the `bar` env variable")
  226. }
  227. if envCount != 4 {
  228. c.Fatalf("Didn't find all env vars - only saw %d\n%s", envCount, envResult)
  229. }
  230. }
  231. func (s *DockerSuite) TestBuildHandleEscapes(c *check.C) {
  232. testRequires(c, DaemonIsLinux)
  233. name := "testbuildhandleescapes"
  234. _, err := buildImage(name,
  235. `
  236. FROM scratch
  237. ENV FOO bar
  238. VOLUME ${FOO}
  239. `, true)
  240. if err != nil {
  241. c.Fatal(err)
  242. }
  243. var result map[string]map[string]struct{}
  244. res := inspectFieldJSON(c, name, "Config.Volumes")
  245. if err = unmarshalJSON([]byte(res), &result); err != nil {
  246. c.Fatal(err)
  247. }
  248. if _, ok := result["bar"]; !ok {
  249. c.Fatal("Could not find volume bar set from env foo in volumes table")
  250. }
  251. deleteImages(name)
  252. _, err = buildImage(name,
  253. `
  254. FROM scratch
  255. ENV FOO bar
  256. VOLUME \${FOO}
  257. `, true)
  258. if err != nil {
  259. c.Fatal(err)
  260. }
  261. res = inspectFieldJSON(c, name, "Config.Volumes")
  262. if err = unmarshalJSON([]byte(res), &result); err != nil {
  263. c.Fatal(err)
  264. }
  265. if _, ok := result["${FOO}"]; !ok {
  266. c.Fatal("Could not find volume ${FOO} set from env foo in volumes table")
  267. }
  268. deleteImages(name)
  269. // this test in particular provides *7* backslashes and expects 6 to come back.
  270. // Like above, the first escape is swallowed and the rest are treated as
  271. // literals, this one is just less obvious because of all the character noise.
  272. _, err = buildImage(name,
  273. `
  274. FROM scratch
  275. ENV FOO bar
  276. VOLUME \\\\\\\${FOO}
  277. `, true)
  278. if err != nil {
  279. c.Fatal(err)
  280. }
  281. res = inspectFieldJSON(c, name, "Config.Volumes")
  282. if err = unmarshalJSON([]byte(res), &result); err != nil {
  283. c.Fatal(err)
  284. }
  285. if _, ok := result[`\\\${FOO}`]; !ok {
  286. c.Fatal(`Could not find volume \\\${FOO} set from env foo in volumes table`, result)
  287. }
  288. }
  289. func (s *DockerSuite) TestBuildOnBuildLowercase(c *check.C) {
  290. testRequires(c, DaemonIsLinux)
  291. name := "testbuildonbuildlowercase"
  292. name2 := "testbuildonbuildlowercase2"
  293. _, err := buildImage(name,
  294. `
  295. FROM busybox
  296. onbuild run echo quux
  297. `, true)
  298. if err != nil {
  299. c.Fatal(err)
  300. }
  301. _, out, err := buildImageWithOut(name2, fmt.Sprintf(`
  302. FROM %s
  303. `, name), true)
  304. if err != nil {
  305. c.Fatal(err)
  306. }
  307. if !strings.Contains(out, "quux") {
  308. c.Fatalf("Did not receive the expected echo text, got %s", out)
  309. }
  310. if strings.Contains(out, "ONBUILD ONBUILD") {
  311. c.Fatalf("Got an ONBUILD ONBUILD error with no error: got %s", out)
  312. }
  313. }
  314. func (s *DockerSuite) TestBuildEnvEscapes(c *check.C) {
  315. testRequires(c, DaemonIsLinux)
  316. name := "testbuildenvescapes"
  317. _, err := buildImage(name,
  318. `
  319. FROM busybox
  320. ENV TEST foo
  321. CMD echo \$
  322. `,
  323. true)
  324. if err != nil {
  325. c.Fatal(err)
  326. }
  327. out, _ := dockerCmd(c, "run", "-t", name)
  328. if strings.TrimSpace(out) != "$" {
  329. c.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
  330. }
  331. }
  332. func (s *DockerSuite) TestBuildEnvOverwrite(c *check.C) {
  333. testRequires(c, DaemonIsLinux)
  334. name := "testbuildenvoverwrite"
  335. _, err := buildImage(name,
  336. `
  337. FROM busybox
  338. ENV TEST foo
  339. CMD echo ${TEST}
  340. `,
  341. true)
  342. if err != nil {
  343. c.Fatal(err)
  344. }
  345. out, _ := dockerCmd(c, "run", "-e", "TEST=bar", "-t", name)
  346. if strings.TrimSpace(out) != "bar" {
  347. c.Fatalf("Env TEST was not overwritten with bar when foo was supplied to dockerfile: was %q", strings.TrimSpace(out))
  348. }
  349. }
  350. func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainerInSourceImage(c *check.C) {
  351. testRequires(c, DaemonIsLinux)
  352. name := "testbuildonbuildforbiddenmaintainerinsourceimage"
  353. out, _ := dockerCmd(c, "create", "busybox", "true")
  354. cleanedContainerID := strings.TrimSpace(out)
  355. dockerCmd(c, "commit", "--run", "{\"OnBuild\":[\"MAINTAINER docker.io\"]}", cleanedContainerID, "onbuild")
  356. _, err := buildImage(name,
  357. `FROM onbuild`,
  358. true)
  359. if err != nil {
  360. if !strings.Contains(err.Error(), "maintainer isn't allowed as an ONBUILD trigger") {
  361. c.Fatalf("Wrong error %v, must be about MAINTAINER and ONBUILD in source image", err)
  362. }
  363. } else {
  364. c.Fatal("Error must not be nil")
  365. }
  366. }
  367. func (s *DockerSuite) TestBuildOnBuildForbiddenFromInSourceImage(c *check.C) {
  368. testRequires(c, DaemonIsLinux)
  369. name := "testbuildonbuildforbiddenfrominsourceimage"
  370. out, _ := dockerCmd(c, "create", "busybox", "true")
  371. cleanedContainerID := strings.TrimSpace(out)
  372. dockerCmd(c, "commit", "--run", "{\"OnBuild\":[\"FROM busybox\"]}", cleanedContainerID, "onbuild")
  373. _, err := buildImage(name,
  374. `FROM onbuild`,
  375. true)
  376. if err != nil {
  377. if !strings.Contains(err.Error(), "from isn't allowed as an ONBUILD trigger") {
  378. c.Fatalf("Wrong error %v, must be about FROM and ONBUILD in source image", err)
  379. }
  380. } else {
  381. c.Fatal("Error must not be nil")
  382. }
  383. }
  384. func (s *DockerSuite) TestBuildOnBuildForbiddenChainedInSourceImage(c *check.C) {
  385. testRequires(c, DaemonIsLinux)
  386. name := "testbuildonbuildforbiddenchainedinsourceimage"
  387. out, _ := dockerCmd(c, "create", "busybox", "true")
  388. cleanedContainerID := strings.TrimSpace(out)
  389. dockerCmd(c, "commit", "--run", "{\"OnBuild\":[\"ONBUILD RUN ls\"]}", cleanedContainerID, "onbuild")
  390. _, err := buildImage(name,
  391. `FROM onbuild`,
  392. true)
  393. if err != nil {
  394. if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  395. c.Fatalf("Wrong error %v, must be about chaining ONBUILD in source image", err)
  396. }
  397. } else {
  398. c.Fatal("Error must not be nil")
  399. }
  400. }
  401. func (s *DockerSuite) TestBuildOnBuildCmdEntrypointJSON(c *check.C) {
  402. testRequires(c, DaemonIsLinux)
  403. name1 := "onbuildcmd"
  404. name2 := "onbuildgenerated"
  405. _, err := buildImage(name1, `
  406. FROM busybox
  407. ONBUILD CMD ["hello world"]
  408. ONBUILD ENTRYPOINT ["echo"]
  409. ONBUILD RUN ["true"]`,
  410. false)
  411. if err != nil {
  412. c.Fatal(err)
  413. }
  414. _, err = buildImage(name2, fmt.Sprintf(`FROM %s`, name1), false)
  415. if err != nil {
  416. c.Fatal(err)
  417. }
  418. out, _ := dockerCmd(c, "run", "-t", name2)
  419. if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
  420. c.Fatal("did not get echo output from onbuild", out)
  421. }
  422. }
  423. func (s *DockerSuite) TestBuildOnBuildEntrypointJSON(c *check.C) {
  424. testRequires(c, DaemonIsLinux)
  425. name1 := "onbuildcmd"
  426. name2 := "onbuildgenerated"
  427. _, err := buildImage(name1, `
  428. FROM busybox
  429. ONBUILD ENTRYPOINT ["echo"]`,
  430. false)
  431. if err != nil {
  432. c.Fatal(err)
  433. }
  434. _, err = buildImage(name2, fmt.Sprintf("FROM %s\nCMD [\"hello world\"]\n", name1), false)
  435. if err != nil {
  436. c.Fatal(err)
  437. }
  438. out, _ := dockerCmd(c, "run", "-t", name2)
  439. if !regexp.MustCompile(`(?m)^hello world`).MatchString(out) {
  440. c.Fatal("got malformed output from onbuild", out)
  441. }
  442. }
  443. func (s *DockerSuite) TestBuildCacheAdd(c *check.C) {
  444. testRequires(c, DaemonIsLinux)
  445. name := "testbuildtwoimageswithadd"
  446. server, err := fakeStorage(map[string]string{
  447. "robots.txt": "hello",
  448. "index.html": "world",
  449. })
  450. if err != nil {
  451. c.Fatal(err)
  452. }
  453. defer server.Close()
  454. if _, err := buildImage(name,
  455. fmt.Sprintf(`FROM scratch
  456. ADD %s/robots.txt /`, server.URL()),
  457. true); err != nil {
  458. c.Fatal(err)
  459. }
  460. if err != nil {
  461. c.Fatal(err)
  462. }
  463. deleteImages(name)
  464. _, out, err := buildImageWithOut(name,
  465. fmt.Sprintf(`FROM scratch
  466. ADD %s/index.html /`, server.URL()),
  467. true)
  468. if err != nil {
  469. c.Fatal(err)
  470. }
  471. if strings.Contains(out, "Using cache") {
  472. c.Fatal("2nd build used cache on ADD, it shouldn't")
  473. }
  474. }
  475. func (s *DockerSuite) TestBuildLastModified(c *check.C) {
  476. testRequires(c, DaemonIsLinux)
  477. name := "testbuildlastmodified"
  478. server, err := fakeStorage(map[string]string{
  479. "file": "hello",
  480. })
  481. if err != nil {
  482. c.Fatal(err)
  483. }
  484. defer server.Close()
  485. var out, out2 string
  486. dFmt := `FROM busybox
  487. ADD %s/file /
  488. RUN ls -le /file`
  489. dockerfile := fmt.Sprintf(dFmt, server.URL())
  490. if _, out, err = buildImageWithOut(name, dockerfile, false); err != nil {
  491. c.Fatal(err)
  492. }
  493. originMTime := regexp.MustCompile(`root.*/file.*\n`).FindString(out)
  494. // Make sure our regexp is correct
  495. if strings.Index(originMTime, "/file") < 0 {
  496. c.Fatalf("Missing ls info on 'file':\n%s", out)
  497. }
  498. // Build it again and make sure the mtime of the file didn't change.
  499. // Wait a few seconds to make sure the time changed enough to notice
  500. time.Sleep(2 * time.Second)
  501. if _, out2, err = buildImageWithOut(name, dockerfile, false); err != nil {
  502. c.Fatal(err)
  503. }
  504. newMTime := regexp.MustCompile(`root.*/file.*\n`).FindString(out2)
  505. if newMTime != originMTime {
  506. c.Fatalf("MTime changed:\nOrigin:%s\nNew:%s", originMTime, newMTime)
  507. }
  508. // Now 'touch' the file and make sure the timestamp DID change this time
  509. // Create a new fakeStorage instead of just using Add() to help windows
  510. server, err = fakeStorage(map[string]string{
  511. "file": "hello",
  512. })
  513. if err != nil {
  514. c.Fatal(err)
  515. }
  516. defer server.Close()
  517. dockerfile = fmt.Sprintf(dFmt, server.URL())
  518. if _, out2, err = buildImageWithOut(name, dockerfile, false); err != nil {
  519. c.Fatal(err)
  520. }
  521. newMTime = regexp.MustCompile(`root.*/file.*\n`).FindString(out2)
  522. if newMTime == originMTime {
  523. c.Fatalf("MTime didn't change:\nOrigin:%s\nNew:%s", originMTime, newMTime)
  524. }
  525. }
  526. func (s *DockerSuite) TestBuildSixtySteps(c *check.C) {
  527. testRequires(c, DaemonIsLinux)
  528. name := "foobuildsixtysteps"
  529. ctx, err := fakeContext("FROM scratch\n"+strings.Repeat("ADD foo /\n", 60),
  530. map[string]string{
  531. "foo": "test1",
  532. })
  533. if err != nil {
  534. c.Fatal(err)
  535. }
  536. defer ctx.Close()
  537. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  538. c.Fatal(err)
  539. }
  540. }
  541. func (s *DockerSuite) TestBuildAddSingleFileToRoot(c *check.C) {
  542. testRequires(c, DaemonIsLinux)
  543. name := "testaddimg"
  544. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  545. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  546. RUN echo 'dockerio:x:1001:' >> /etc/group
  547. RUN touch /exists
  548. RUN chown dockerio.dockerio /exists
  549. ADD test_file /
  550. RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  551. RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ]
  552. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  553. map[string]string{
  554. "test_file": "test1",
  555. })
  556. if err != nil {
  557. c.Fatal(err)
  558. }
  559. defer ctx.Close()
  560. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  561. c.Fatal(err)
  562. }
  563. }
  564. // Issue #3960: "ADD src ." hangs
  565. func (s *DockerSuite) TestBuildAddSingleFileToWorkdir(c *check.C) {
  566. testRequires(c, DaemonIsLinux)
  567. name := "testaddsinglefiletoworkdir"
  568. ctx, err := fakeContext(`FROM busybox
  569. ADD test_file .`,
  570. map[string]string{
  571. "test_file": "test1",
  572. })
  573. if err != nil {
  574. c.Fatal(err)
  575. }
  576. defer ctx.Close()
  577. errChan := make(chan error)
  578. go func() {
  579. _, err := buildImageFromContext(name, ctx, true)
  580. errChan <- err
  581. close(errChan)
  582. }()
  583. select {
  584. case <-time.After(15 * time.Second):
  585. c.Fatal("Build with adding to workdir timed out")
  586. case err := <-errChan:
  587. c.Assert(err, check.IsNil)
  588. }
  589. }
  590. func (s *DockerSuite) TestBuildAddSingleFileToExistDir(c *check.C) {
  591. testRequires(c, DaemonIsLinux)
  592. name := "testaddsinglefiletoexistdir"
  593. ctx, err := fakeContext(`FROM busybox
  594. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  595. RUN echo 'dockerio:x:1001:' >> /etc/group
  596. RUN mkdir /exists
  597. RUN touch /exists/exists_file
  598. RUN chown -R dockerio.dockerio /exists
  599. ADD test_file /exists/
  600. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  601. RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
  602. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  603. map[string]string{
  604. "test_file": "test1",
  605. })
  606. if err != nil {
  607. c.Fatal(err)
  608. }
  609. defer ctx.Close()
  610. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  611. c.Fatal(err)
  612. }
  613. }
  614. func (s *DockerSuite) TestBuildCopyAddMultipleFiles(c *check.C) {
  615. testRequires(c, DaemonIsLinux)
  616. server, err := fakeStorage(map[string]string{
  617. "robots.txt": "hello",
  618. })
  619. if err != nil {
  620. c.Fatal(err)
  621. }
  622. defer server.Close()
  623. name := "testcopymultiplefilestofile"
  624. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  625. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  626. RUN echo 'dockerio:x:1001:' >> /etc/group
  627. RUN mkdir /exists
  628. RUN touch /exists/exists_file
  629. RUN chown -R dockerio.dockerio /exists
  630. COPY test_file1 test_file2 /exists/
  631. ADD test_file3 test_file4 %s/robots.txt /exists/
  632. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  633. RUN [ $(ls -l /exists/test_file1 | awk '{print $3":"$4}') = 'root:root' ]
  634. RUN [ $(ls -l /exists/test_file2 | awk '{print $3":"$4}') = 'root:root' ]
  635. RUN [ $(ls -l /exists/test_file3 | awk '{print $3":"$4}') = 'root:root' ]
  636. RUN [ $(ls -l /exists/test_file4 | awk '{print $3":"$4}') = 'root:root' ]
  637. RUN [ $(ls -l /exists/robots.txt | awk '{print $3":"$4}') = 'root:root' ]
  638. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  639. `, server.URL()),
  640. map[string]string{
  641. "test_file1": "test1",
  642. "test_file2": "test2",
  643. "test_file3": "test3",
  644. "test_file4": "test4",
  645. })
  646. if err != nil {
  647. c.Fatal(err)
  648. }
  649. defer ctx.Close()
  650. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  651. c.Fatal(err)
  652. }
  653. }
  654. func (s *DockerSuite) TestBuildAddMultipleFilesToFile(c *check.C) {
  655. testRequires(c, DaemonIsLinux)
  656. name := "testaddmultiplefilestofile"
  657. ctx, err := fakeContext(`FROM scratch
  658. ADD file1.txt file2.txt test
  659. `,
  660. map[string]string{
  661. "file1.txt": "test1",
  662. "file2.txt": "test1",
  663. })
  664. if err != nil {
  665. c.Fatal(err)
  666. }
  667. defer ctx.Close()
  668. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  669. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  670. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  671. }
  672. }
  673. func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFile(c *check.C) {
  674. testRequires(c, DaemonIsLinux)
  675. name := "testjsonaddmultiplefilestofile"
  676. ctx, err := fakeContext(`FROM scratch
  677. ADD ["file1.txt", "file2.txt", "test"]
  678. `,
  679. map[string]string{
  680. "file1.txt": "test1",
  681. "file2.txt": "test1",
  682. })
  683. if err != nil {
  684. c.Fatal(err)
  685. }
  686. defer ctx.Close()
  687. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  688. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  689. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  690. }
  691. }
  692. func (s *DockerSuite) TestBuildAddMultipleFilesToFileWild(c *check.C) {
  693. testRequires(c, DaemonIsLinux)
  694. name := "testaddmultiplefilestofilewild"
  695. ctx, err := fakeContext(`FROM scratch
  696. ADD file*.txt test
  697. `,
  698. map[string]string{
  699. "file1.txt": "test1",
  700. "file2.txt": "test1",
  701. })
  702. if err != nil {
  703. c.Fatal(err)
  704. }
  705. defer ctx.Close()
  706. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  707. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  708. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  709. }
  710. }
  711. func (s *DockerSuite) TestBuildJSONAddMultipleFilesToFileWild(c *check.C) {
  712. testRequires(c, DaemonIsLinux)
  713. name := "testjsonaddmultiplefilestofilewild"
  714. ctx, err := fakeContext(`FROM scratch
  715. ADD ["file*.txt", "test"]
  716. `,
  717. map[string]string{
  718. "file1.txt": "test1",
  719. "file2.txt": "test1",
  720. })
  721. if err != nil {
  722. c.Fatal(err)
  723. }
  724. defer ctx.Close()
  725. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  726. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  727. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  728. }
  729. }
  730. func (s *DockerSuite) TestBuildCopyMultipleFilesToFile(c *check.C) {
  731. testRequires(c, DaemonIsLinux)
  732. name := "testcopymultiplefilestofile"
  733. ctx, err := fakeContext(`FROM scratch
  734. COPY file1.txt file2.txt test
  735. `,
  736. map[string]string{
  737. "file1.txt": "test1",
  738. "file2.txt": "test1",
  739. })
  740. if err != nil {
  741. c.Fatal(err)
  742. }
  743. defer ctx.Close()
  744. expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
  745. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  746. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  747. }
  748. }
  749. func (s *DockerSuite) TestBuildJSONCopyMultipleFilesToFile(c *check.C) {
  750. testRequires(c, DaemonIsLinux)
  751. name := "testjsoncopymultiplefilestofile"
  752. ctx, err := fakeContext(`FROM scratch
  753. COPY ["file1.txt", "file2.txt", "test"]
  754. `,
  755. map[string]string{
  756. "file1.txt": "test1",
  757. "file2.txt": "test1",
  758. })
  759. if err != nil {
  760. c.Fatal(err)
  761. }
  762. defer ctx.Close()
  763. expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
  764. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  765. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  766. }
  767. }
  768. func (s *DockerSuite) TestBuildAddFileWithWhitespace(c *check.C) {
  769. testRequires(c, DaemonIsLinux)
  770. name := "testaddfilewithwhitespace"
  771. ctx, err := fakeContext(`FROM busybox
  772. RUN mkdir "/test dir"
  773. RUN mkdir "/test_dir"
  774. ADD [ "test file1", "/test_file1" ]
  775. ADD [ "test_file2", "/test file2" ]
  776. ADD [ "test file3", "/test file3" ]
  777. ADD [ "test dir/test_file4", "/test_dir/test_file4" ]
  778. ADD [ "test_dir/test_file5", "/test dir/test_file5" ]
  779. ADD [ "test dir/test_file6", "/test dir/test_file6" ]
  780. RUN [ $(cat "/test_file1") = 'test1' ]
  781. RUN [ $(cat "/test file2") = 'test2' ]
  782. RUN [ $(cat "/test file3") = 'test3' ]
  783. RUN [ $(cat "/test_dir/test_file4") = 'test4' ]
  784. RUN [ $(cat "/test dir/test_file5") = 'test5' ]
  785. RUN [ $(cat "/test dir/test_file6") = 'test6' ]`,
  786. map[string]string{
  787. "test file1": "test1",
  788. "test_file2": "test2",
  789. "test file3": "test3",
  790. "test dir/test_file4": "test4",
  791. "test_dir/test_file5": "test5",
  792. "test dir/test_file6": "test6",
  793. })
  794. if err != nil {
  795. c.Fatal(err)
  796. }
  797. defer ctx.Close()
  798. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  799. c.Fatal(err)
  800. }
  801. }
  802. func (s *DockerSuite) TestBuildCopyFileWithWhitespace(c *check.C) {
  803. testRequires(c, DaemonIsLinux)
  804. name := "testcopyfilewithwhitespace"
  805. ctx, err := fakeContext(`FROM busybox
  806. RUN mkdir "/test dir"
  807. RUN mkdir "/test_dir"
  808. COPY [ "test file1", "/test_file1" ]
  809. COPY [ "test_file2", "/test file2" ]
  810. COPY [ "test file3", "/test file3" ]
  811. COPY [ "test dir/test_file4", "/test_dir/test_file4" ]
  812. COPY [ "test_dir/test_file5", "/test dir/test_file5" ]
  813. COPY [ "test dir/test_file6", "/test dir/test_file6" ]
  814. RUN [ $(cat "/test_file1") = 'test1' ]
  815. RUN [ $(cat "/test file2") = 'test2' ]
  816. RUN [ $(cat "/test file3") = 'test3' ]
  817. RUN [ $(cat "/test_dir/test_file4") = 'test4' ]
  818. RUN [ $(cat "/test dir/test_file5") = 'test5' ]
  819. RUN [ $(cat "/test dir/test_file6") = 'test6' ]`,
  820. map[string]string{
  821. "test file1": "test1",
  822. "test_file2": "test2",
  823. "test file3": "test3",
  824. "test dir/test_file4": "test4",
  825. "test_dir/test_file5": "test5",
  826. "test dir/test_file6": "test6",
  827. })
  828. if err != nil {
  829. c.Fatal(err)
  830. }
  831. defer ctx.Close()
  832. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  833. c.Fatal(err)
  834. }
  835. }
  836. func (s *DockerSuite) TestBuildAddMultipleFilesToFileWithWhitespace(c *check.C) {
  837. testRequires(c, DaemonIsLinux)
  838. name := "testaddmultiplefilestofilewithwhitespace"
  839. ctx, err := fakeContext(`FROM busybox
  840. ADD [ "test file1", "test file2", "test" ]
  841. `,
  842. map[string]string{
  843. "test file1": "test1",
  844. "test file2": "test2",
  845. })
  846. if err != nil {
  847. c.Fatal(err)
  848. }
  849. defer ctx.Close()
  850. expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
  851. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  852. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  853. }
  854. }
  855. func (s *DockerSuite) TestBuildCopyMultipleFilesToFileWithWhitespace(c *check.C) {
  856. testRequires(c, DaemonIsLinux)
  857. name := "testcopymultiplefilestofilewithwhitespace"
  858. ctx, err := fakeContext(`FROM busybox
  859. COPY [ "test file1", "test file2", "test" ]
  860. `,
  861. map[string]string{
  862. "test file1": "test1",
  863. "test file2": "test2",
  864. })
  865. if err != nil {
  866. c.Fatal(err)
  867. }
  868. defer ctx.Close()
  869. expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
  870. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  871. c.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
  872. }
  873. }
  874. func (s *DockerSuite) TestBuildCopyWildcard(c *check.C) {
  875. testRequires(c, DaemonIsLinux)
  876. name := "testcopywildcard"
  877. server, err := fakeStorage(map[string]string{
  878. "robots.txt": "hello",
  879. "index.html": "world",
  880. })
  881. if err != nil {
  882. c.Fatal(err)
  883. }
  884. defer server.Close()
  885. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  886. COPY file*.txt /tmp/
  887. RUN ls /tmp/file1.txt /tmp/file2.txt
  888. RUN mkdir /tmp1
  889. COPY dir* /tmp1/
  890. RUN ls /tmp1/dirt /tmp1/nested_file /tmp1/nested_dir/nest_nest_file
  891. RUN mkdir /tmp2
  892. ADD dir/*dir %s/robots.txt /tmp2/
  893. RUN ls /tmp2/nest_nest_file /tmp2/robots.txt
  894. `, server.URL()),
  895. map[string]string{
  896. "file1.txt": "test1",
  897. "file2.txt": "test2",
  898. "dir/nested_file": "nested file",
  899. "dir/nested_dir/nest_nest_file": "2 times nested",
  900. "dirt": "dirty",
  901. })
  902. if err != nil {
  903. c.Fatal(err)
  904. }
  905. defer ctx.Close()
  906. id1, err := buildImageFromContext(name, ctx, true)
  907. if err != nil {
  908. c.Fatal(err)
  909. }
  910. // Now make sure we use a cache the 2nd time
  911. id2, err := buildImageFromContext(name, ctx, true)
  912. if err != nil {
  913. c.Fatal(err)
  914. }
  915. if id1 != id2 {
  916. c.Fatal("didn't use the cache")
  917. }
  918. }
  919. func (s *DockerSuite) TestBuildCopyWildcardNoFind(c *check.C) {
  920. testRequires(c, DaemonIsLinux)
  921. name := "testcopywildcardnofind"
  922. ctx, err := fakeContext(`FROM busybox
  923. COPY file*.txt /tmp/
  924. `, nil)
  925. if err != nil {
  926. c.Fatal(err)
  927. }
  928. defer ctx.Close()
  929. _, err = buildImageFromContext(name, ctx, true)
  930. if err == nil {
  931. c.Fatal("should have failed to find a file")
  932. }
  933. if !strings.Contains(err.Error(), "No source files were specified") {
  934. c.Fatalf("Wrong error %v, must be about no source files", err)
  935. }
  936. }
  937. func (s *DockerSuite) TestBuildCopyWildcardInName(c *check.C) {
  938. testRequires(c, DaemonIsLinux)
  939. name := "testcopywildcardinname"
  940. ctx, err := fakeContext(`FROM busybox
  941. COPY *.txt /tmp/
  942. RUN [ "$(cat /tmp/\*.txt)" = 'hi there' ]
  943. `, map[string]string{"*.txt": "hi there"})
  944. if err != nil {
  945. // Normally we would do c.Fatal(err) here but given that
  946. // the odds of this failing are so rare, it must be because
  947. // the OS we're running the client on doesn't support * in
  948. // filenames (like windows). So, instead of failing the test
  949. // just let it pass. Then we don't need to explicitly
  950. // say which OSs this works on or not.
  951. return
  952. }
  953. defer ctx.Close()
  954. _, err = buildImageFromContext(name, ctx, true)
  955. if err != nil {
  956. c.Fatalf("should have built: %q", err)
  957. }
  958. }
  959. func (s *DockerSuite) TestBuildCopyWildcardCache(c *check.C) {
  960. testRequires(c, DaemonIsLinux)
  961. name := "testcopywildcardcache"
  962. ctx, err := fakeContext(`FROM busybox
  963. COPY file1.txt /tmp/`,
  964. map[string]string{
  965. "file1.txt": "test1",
  966. })
  967. if err != nil {
  968. c.Fatal(err)
  969. }
  970. defer ctx.Close()
  971. id1, err := buildImageFromContext(name, ctx, true)
  972. if err != nil {
  973. c.Fatal(err)
  974. }
  975. // Now make sure we use a cache the 2nd time even with wild cards.
  976. // Use the same context so the file is the same and the checksum will match
  977. ctx.Add("Dockerfile", `FROM busybox
  978. COPY file*.txt /tmp/`)
  979. id2, err := buildImageFromContext(name, ctx, true)
  980. if err != nil {
  981. c.Fatal(err)
  982. }
  983. if id1 != id2 {
  984. c.Fatal("didn't use the cache")
  985. }
  986. }
  987. func (s *DockerSuite) TestBuildAddSingleFileToNonExistingDir(c *check.C) {
  988. testRequires(c, DaemonIsLinux)
  989. name := "testaddsinglefiletononexistingdir"
  990. ctx, err := fakeContext(`FROM busybox
  991. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  992. RUN echo 'dockerio:x:1001:' >> /etc/group
  993. RUN touch /exists
  994. RUN chown dockerio.dockerio /exists
  995. ADD test_file /test_dir/
  996. RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  997. RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  998. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  999. map[string]string{
  1000. "test_file": "test1",
  1001. })
  1002. if err != nil {
  1003. c.Fatal(err)
  1004. }
  1005. defer ctx.Close()
  1006. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1007. c.Fatal(err)
  1008. }
  1009. }
  1010. func (s *DockerSuite) TestBuildAddDirContentToRoot(c *check.C) {
  1011. testRequires(c, DaemonIsLinux)
  1012. name := "testadddircontenttoroot"
  1013. ctx, err := fakeContext(`FROM busybox
  1014. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1015. RUN echo 'dockerio:x:1001:' >> /etc/group
  1016. RUN touch /exists
  1017. RUN chown dockerio.dockerio exists
  1018. ADD test_dir /
  1019. RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1020. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1021. map[string]string{
  1022. "test_dir/test_file": "test1",
  1023. })
  1024. if err != nil {
  1025. c.Fatal(err)
  1026. }
  1027. defer ctx.Close()
  1028. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1029. c.Fatal(err)
  1030. }
  1031. }
  1032. func (s *DockerSuite) TestBuildAddDirContentToExistingDir(c *check.C) {
  1033. testRequires(c, DaemonIsLinux)
  1034. name := "testadddircontenttoexistingdir"
  1035. ctx, err := fakeContext(`FROM busybox
  1036. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1037. RUN echo 'dockerio:x:1001:' >> /etc/group
  1038. RUN mkdir /exists
  1039. RUN touch /exists/exists_file
  1040. RUN chown -R dockerio.dockerio /exists
  1041. ADD test_dir/ /exists/
  1042. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1043. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1044. RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1045. map[string]string{
  1046. "test_dir/test_file": "test1",
  1047. })
  1048. if err != nil {
  1049. c.Fatal(err)
  1050. }
  1051. defer ctx.Close()
  1052. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1053. c.Fatal(err)
  1054. }
  1055. }
  1056. func (s *DockerSuite) TestBuildAddWholeDirToRoot(c *check.C) {
  1057. testRequires(c, DaemonIsLinux)
  1058. name := "testaddwholedirtoroot"
  1059. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1060. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1061. RUN echo 'dockerio:x:1001:' >> /etc/group
  1062. RUN touch /exists
  1063. RUN chown dockerio.dockerio exists
  1064. ADD test_dir /test_dir
  1065. RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1066. RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1067. RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1068. RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ]
  1069. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1070. map[string]string{
  1071. "test_dir/test_file": "test1",
  1072. })
  1073. if err != nil {
  1074. c.Fatal(err)
  1075. }
  1076. defer ctx.Close()
  1077. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1078. c.Fatal(err)
  1079. }
  1080. }
  1081. // Testing #5941
  1082. func (s *DockerSuite) TestBuildAddEtcToRoot(c *check.C) {
  1083. testRequires(c, DaemonIsLinux)
  1084. name := "testaddetctoroot"
  1085. ctx, err := fakeContext(`FROM scratch
  1086. ADD . /`,
  1087. map[string]string{
  1088. "etc/test_file": "test1",
  1089. })
  1090. if err != nil {
  1091. c.Fatal(err)
  1092. }
  1093. defer ctx.Close()
  1094. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1095. c.Fatal(err)
  1096. }
  1097. }
  1098. // Testing #9401
  1099. func (s *DockerSuite) TestBuildAddPreservesFilesSpecialBits(c *check.C) {
  1100. testRequires(c, DaemonIsLinux)
  1101. name := "testaddpreservesfilesspecialbits"
  1102. ctx, err := fakeContext(`FROM busybox
  1103. ADD suidbin /usr/bin/suidbin
  1104. RUN chmod 4755 /usr/bin/suidbin
  1105. RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]
  1106. ADD ./data/ /
  1107. RUN [ $(ls -l /usr/bin/suidbin | awk '{print $1}') = '-rwsr-xr-x' ]`,
  1108. map[string]string{
  1109. "suidbin": "suidbin",
  1110. "/data/usr/test_file": "test1",
  1111. })
  1112. if err != nil {
  1113. c.Fatal(err)
  1114. }
  1115. defer ctx.Close()
  1116. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1117. c.Fatal(err)
  1118. }
  1119. }
  1120. func (s *DockerSuite) TestBuildCopySingleFileToRoot(c *check.C) {
  1121. testRequires(c, DaemonIsLinux)
  1122. name := "testcopysinglefiletoroot"
  1123. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1124. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1125. RUN echo 'dockerio:x:1001:' >> /etc/group
  1126. RUN touch /exists
  1127. RUN chown dockerio.dockerio /exists
  1128. COPY test_file /
  1129. RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1130. RUN [ $(ls -l /test_file | awk '{print $1}') = '%s' ]
  1131. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1132. map[string]string{
  1133. "test_file": "test1",
  1134. })
  1135. if err != nil {
  1136. c.Fatal(err)
  1137. }
  1138. defer ctx.Close()
  1139. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1140. c.Fatal(err)
  1141. }
  1142. }
  1143. // Issue #3960: "ADD src ." hangs - adapted for COPY
  1144. func (s *DockerSuite) TestBuildCopySingleFileToWorkdir(c *check.C) {
  1145. testRequires(c, DaemonIsLinux)
  1146. name := "testcopysinglefiletoworkdir"
  1147. ctx, err := fakeContext(`FROM busybox
  1148. COPY test_file .`,
  1149. map[string]string{
  1150. "test_file": "test1",
  1151. })
  1152. if err != nil {
  1153. c.Fatal(err)
  1154. }
  1155. defer ctx.Close()
  1156. errChan := make(chan error)
  1157. go func() {
  1158. _, err := buildImageFromContext(name, ctx, true)
  1159. errChan <- err
  1160. close(errChan)
  1161. }()
  1162. select {
  1163. case <-time.After(15 * time.Second):
  1164. c.Fatal("Build with adding to workdir timed out")
  1165. case err := <-errChan:
  1166. c.Assert(err, check.IsNil)
  1167. }
  1168. }
  1169. func (s *DockerSuite) TestBuildCopySingleFileToExistDir(c *check.C) {
  1170. testRequires(c, DaemonIsLinux)
  1171. name := "testcopysinglefiletoexistdir"
  1172. ctx, err := fakeContext(`FROM busybox
  1173. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1174. RUN echo 'dockerio:x:1001:' >> /etc/group
  1175. RUN mkdir /exists
  1176. RUN touch /exists/exists_file
  1177. RUN chown -R dockerio.dockerio /exists
  1178. COPY test_file /exists/
  1179. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1180. RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1181. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1182. map[string]string{
  1183. "test_file": "test1",
  1184. })
  1185. if err != nil {
  1186. c.Fatal(err)
  1187. }
  1188. defer ctx.Close()
  1189. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1190. c.Fatal(err)
  1191. }
  1192. }
  1193. func (s *DockerSuite) TestBuildCopySingleFileToNonExistDir(c *check.C) {
  1194. testRequires(c, DaemonIsLinux)
  1195. name := "testcopysinglefiletononexistdir"
  1196. ctx, err := fakeContext(`FROM busybox
  1197. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1198. RUN echo 'dockerio:x:1001:' >> /etc/group
  1199. RUN touch /exists
  1200. RUN chown dockerio.dockerio /exists
  1201. COPY test_file /test_dir/
  1202. RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1203. RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1204. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1205. map[string]string{
  1206. "test_file": "test1",
  1207. })
  1208. if err != nil {
  1209. c.Fatal(err)
  1210. }
  1211. defer ctx.Close()
  1212. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1213. c.Fatal(err)
  1214. }
  1215. }
  1216. func (s *DockerSuite) TestBuildCopyDirContentToRoot(c *check.C) {
  1217. testRequires(c, DaemonIsLinux)
  1218. name := "testcopydircontenttoroot"
  1219. ctx, err := fakeContext(`FROM busybox
  1220. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1221. RUN echo 'dockerio:x:1001:' >> /etc/group
  1222. RUN touch /exists
  1223. RUN chown dockerio.dockerio exists
  1224. COPY test_dir /
  1225. RUN [ $(ls -l /test_file | awk '{print $3":"$4}') = 'root:root' ]
  1226. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`,
  1227. map[string]string{
  1228. "test_dir/test_file": "test1",
  1229. })
  1230. if err != nil {
  1231. c.Fatal(err)
  1232. }
  1233. defer ctx.Close()
  1234. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1235. c.Fatal(err)
  1236. }
  1237. }
  1238. func (s *DockerSuite) TestBuildCopyDirContentToExistDir(c *check.C) {
  1239. testRequires(c, DaemonIsLinux)
  1240. name := "testcopydircontenttoexistdir"
  1241. ctx, err := fakeContext(`FROM busybox
  1242. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1243. RUN echo 'dockerio:x:1001:' >> /etc/group
  1244. RUN mkdir /exists
  1245. RUN touch /exists/exists_file
  1246. RUN chown -R dockerio.dockerio /exists
  1247. COPY test_dir/ /exists/
  1248. RUN [ $(ls -l / | grep exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1249. RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio' ]
  1250. RUN [ $(ls -l /exists/test_file | awk '{print $3":"$4}') = 'root:root' ]`,
  1251. map[string]string{
  1252. "test_dir/test_file": "test1",
  1253. })
  1254. if err != nil {
  1255. c.Fatal(err)
  1256. }
  1257. defer ctx.Close()
  1258. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1259. c.Fatal(err)
  1260. }
  1261. }
  1262. func (s *DockerSuite) TestBuildCopyWholeDirToRoot(c *check.C) {
  1263. testRequires(c, DaemonIsLinux)
  1264. name := "testcopywholedirtoroot"
  1265. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  1266. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1267. RUN echo 'dockerio:x:1001:' >> /etc/group
  1268. RUN touch /exists
  1269. RUN chown dockerio.dockerio exists
  1270. COPY test_dir /test_dir
  1271. RUN [ $(ls -l / | grep test_dir | awk '{print $3":"$4}') = 'root:root' ]
  1272. RUN [ $(ls -l / | grep test_dir | awk '{print $1}') = 'drwxr-xr-x' ]
  1273. RUN [ $(ls -l /test_dir/test_file | awk '{print $3":"$4}') = 'root:root' ]
  1274. RUN [ $(ls -l /test_dir/test_file | awk '{print $1}') = '%s' ]
  1275. RUN [ $(ls -l /exists | awk '{print $3":"$4}') = 'dockerio:dockerio' ]`, expectedFileChmod),
  1276. map[string]string{
  1277. "test_dir/test_file": "test1",
  1278. })
  1279. if err != nil {
  1280. c.Fatal(err)
  1281. }
  1282. defer ctx.Close()
  1283. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1284. c.Fatal(err)
  1285. }
  1286. }
  1287. func (s *DockerSuite) TestBuildCopyEtcToRoot(c *check.C) {
  1288. testRequires(c, DaemonIsLinux)
  1289. name := "testcopyetctoroot"
  1290. ctx, err := fakeContext(`FROM scratch
  1291. COPY . /`,
  1292. map[string]string{
  1293. "etc/test_file": "test1",
  1294. })
  1295. if err != nil {
  1296. c.Fatal(err)
  1297. }
  1298. defer ctx.Close()
  1299. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1300. c.Fatal(err)
  1301. }
  1302. }
  1303. func (s *DockerSuite) TestBuildCopyDisallowRemote(c *check.C) {
  1304. testRequires(c, DaemonIsLinux)
  1305. name := "testcopydisallowremote"
  1306. _, out, err := buildImageWithOut(name, `FROM scratch
  1307. COPY https://index.docker.io/robots.txt /`,
  1308. true)
  1309. if err == nil || !strings.Contains(out, "Source can't be a URL for COPY") {
  1310. c.Fatalf("Error should be about disallowed remote source, got err: %s, out: %q", err, out)
  1311. }
  1312. }
  1313. func (s *DockerSuite) TestBuildAddBadLinks(c *check.C) {
  1314. testRequires(c, DaemonIsLinux)
  1315. const (
  1316. dockerfile = `
  1317. FROM scratch
  1318. ADD links.tar /
  1319. ADD foo.txt /symlink/
  1320. `
  1321. targetFile = "foo.txt"
  1322. )
  1323. var (
  1324. name = "test-link-absolute"
  1325. )
  1326. ctx, err := fakeContext(dockerfile, nil)
  1327. if err != nil {
  1328. c.Fatal(err)
  1329. }
  1330. defer ctx.Close()
  1331. tempDir, err := ioutil.TempDir("", "test-link-absolute-temp-")
  1332. if err != nil {
  1333. c.Fatalf("failed to create temporary directory: %s", tempDir)
  1334. }
  1335. defer os.RemoveAll(tempDir)
  1336. var symlinkTarget string
  1337. if runtime.GOOS == "windows" {
  1338. var driveLetter string
  1339. if abs, err := filepath.Abs(tempDir); err != nil {
  1340. c.Fatal(err)
  1341. } else {
  1342. driveLetter = abs[:1]
  1343. }
  1344. tempDirWithoutDrive := tempDir[2:]
  1345. symlinkTarget = fmt.Sprintf(`%s:\..\..\..\..\..\..\..\..\..\..\..\..%s`, driveLetter, tempDirWithoutDrive)
  1346. } else {
  1347. symlinkTarget = fmt.Sprintf("/../../../../../../../../../../../..%s", tempDir)
  1348. }
  1349. tarPath := filepath.Join(ctx.Dir, "links.tar")
  1350. nonExistingFile := filepath.Join(tempDir, targetFile)
  1351. fooPath := filepath.Join(ctx.Dir, targetFile)
  1352. tarOut, err := os.Create(tarPath)
  1353. if err != nil {
  1354. c.Fatal(err)
  1355. }
  1356. tarWriter := tar.NewWriter(tarOut)
  1357. header := &tar.Header{
  1358. Name: "symlink",
  1359. Typeflag: tar.TypeSymlink,
  1360. Linkname: symlinkTarget,
  1361. Mode: 0755,
  1362. Uid: 0,
  1363. Gid: 0,
  1364. }
  1365. err = tarWriter.WriteHeader(header)
  1366. if err != nil {
  1367. c.Fatal(err)
  1368. }
  1369. tarWriter.Close()
  1370. tarOut.Close()
  1371. foo, err := os.Create(fooPath)
  1372. if err != nil {
  1373. c.Fatal(err)
  1374. }
  1375. defer foo.Close()
  1376. if _, err := foo.WriteString("test"); err != nil {
  1377. c.Fatal(err)
  1378. }
  1379. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1380. c.Fatal(err)
  1381. }
  1382. if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1383. c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1384. }
  1385. }
  1386. func (s *DockerSuite) TestBuildAddBadLinksVolume(c *check.C) {
  1387. testRequires(c, DaemonIsLinux)
  1388. const (
  1389. dockerfileTemplate = `
  1390. FROM busybox
  1391. RUN ln -s /../../../../../../../../%s /x
  1392. VOLUME /x
  1393. ADD foo.txt /x/`
  1394. targetFile = "foo.txt"
  1395. )
  1396. var (
  1397. name = "test-link-absolute-volume"
  1398. dockerfile = ""
  1399. )
  1400. tempDir, err := ioutil.TempDir("", "test-link-absolute-volume-temp-")
  1401. if err != nil {
  1402. c.Fatalf("failed to create temporary directory: %s", tempDir)
  1403. }
  1404. defer os.RemoveAll(tempDir)
  1405. dockerfile = fmt.Sprintf(dockerfileTemplate, tempDir)
  1406. nonExistingFile := filepath.Join(tempDir, targetFile)
  1407. ctx, err := fakeContext(dockerfile, nil)
  1408. if err != nil {
  1409. c.Fatal(err)
  1410. }
  1411. defer ctx.Close()
  1412. fooPath := filepath.Join(ctx.Dir, targetFile)
  1413. foo, err := os.Create(fooPath)
  1414. if err != nil {
  1415. c.Fatal(err)
  1416. }
  1417. defer foo.Close()
  1418. if _, err := foo.WriteString("test"); err != nil {
  1419. c.Fatal(err)
  1420. }
  1421. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1422. c.Fatal(err)
  1423. }
  1424. if _, err := os.Stat(nonExistingFile); err == nil || err != nil && !os.IsNotExist(err) {
  1425. c.Fatalf("%s shouldn't have been written and it shouldn't exist", nonExistingFile)
  1426. }
  1427. }
  1428. // Issue #5270 - ensure we throw a better error than "unexpected EOF"
  1429. // when we can't access files in the context.
  1430. func (s *DockerSuite) TestBuildWithInaccessibleFilesInContext(c *check.C) {
  1431. testRequires(c, DaemonIsLinux)
  1432. testRequires(c, UnixCli) // test uses chown/chmod: not available on windows
  1433. {
  1434. name := "testbuildinaccessiblefiles"
  1435. ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"fileWithoutReadAccess": "foo"})
  1436. if err != nil {
  1437. c.Fatal(err)
  1438. }
  1439. defer ctx.Close()
  1440. // This is used to ensure we detect inaccessible files early during build in the cli client
  1441. pathToFileWithoutReadAccess := filepath.Join(ctx.Dir, "fileWithoutReadAccess")
  1442. if err = os.Chown(pathToFileWithoutReadAccess, 0, 0); err != nil {
  1443. c.Fatalf("failed to chown file to root: %s", err)
  1444. }
  1445. if err = os.Chmod(pathToFileWithoutReadAccess, 0700); err != nil {
  1446. c.Fatalf("failed to chmod file to 700: %s", err)
  1447. }
  1448. buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1449. buildCmd.Dir = ctx.Dir
  1450. out, _, err := runCommandWithOutput(buildCmd)
  1451. if err == nil {
  1452. c.Fatalf("build should have failed: %s %s", err, out)
  1453. }
  1454. // check if we've detected the failure before we started building
  1455. if !strings.Contains(out, "no permission to read from ") {
  1456. c.Fatalf("output should've contained the string: no permission to read from but contained: %s", out)
  1457. }
  1458. if !strings.Contains(out, "Error checking context") {
  1459. c.Fatalf("output should've contained the string: Error checking context")
  1460. }
  1461. }
  1462. {
  1463. name := "testbuildinaccessibledirectory"
  1464. ctx, err := fakeContext("FROM scratch\nADD . /foo/", map[string]string{"directoryWeCantStat/bar": "foo"})
  1465. if err != nil {
  1466. c.Fatal(err)
  1467. }
  1468. defer ctx.Close()
  1469. // This is used to ensure we detect inaccessible directories early during build in the cli client
  1470. pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1471. pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1472. if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1473. c.Fatalf("failed to chown directory to root: %s", err)
  1474. }
  1475. if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1476. c.Fatalf("failed to chmod directory to 444: %s", err)
  1477. }
  1478. if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1479. c.Fatalf("failed to chmod file to 700: %s", err)
  1480. }
  1481. buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1482. buildCmd.Dir = ctx.Dir
  1483. out, _, err := runCommandWithOutput(buildCmd)
  1484. if err == nil {
  1485. c.Fatalf("build should have failed: %s %s", err, out)
  1486. }
  1487. // check if we've detected the failure before we started building
  1488. if !strings.Contains(out, "can't stat") {
  1489. c.Fatalf("output should've contained the string: can't access %s", out)
  1490. }
  1491. if !strings.Contains(out, "Error checking context") {
  1492. c.Fatalf("output should've contained the string: Error checking context\ngot:%s", out)
  1493. }
  1494. }
  1495. {
  1496. name := "testlinksok"
  1497. ctx, err := fakeContext("FROM scratch\nADD . /foo/", nil)
  1498. if err != nil {
  1499. c.Fatal(err)
  1500. }
  1501. defer ctx.Close()
  1502. target := "../../../../../../../../../../../../../../../../../../../azA"
  1503. if err := os.Symlink(filepath.Join(ctx.Dir, "g"), target); err != nil {
  1504. c.Fatal(err)
  1505. }
  1506. defer os.Remove(target)
  1507. // This is used to ensure we don't follow links when checking if everything in the context is accessible
  1508. // This test doesn't require that we run commands as an unprivileged user
  1509. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  1510. c.Fatal(err)
  1511. }
  1512. }
  1513. {
  1514. name := "testbuildignoredinaccessible"
  1515. ctx, err := fakeContext("FROM scratch\nADD . /foo/",
  1516. map[string]string{
  1517. "directoryWeCantStat/bar": "foo",
  1518. ".dockerignore": "directoryWeCantStat",
  1519. })
  1520. if err != nil {
  1521. c.Fatal(err)
  1522. }
  1523. defer ctx.Close()
  1524. // This is used to ensure we don't try to add inaccessible files when they are ignored by a .dockerignore pattern
  1525. pathToDirectoryWithoutReadAccess := filepath.Join(ctx.Dir, "directoryWeCantStat")
  1526. pathToFileInDirectoryWithoutReadAccess := filepath.Join(pathToDirectoryWithoutReadAccess, "bar")
  1527. if err = os.Chown(pathToDirectoryWithoutReadAccess, 0, 0); err != nil {
  1528. c.Fatalf("failed to chown directory to root: %s", err)
  1529. }
  1530. if err = os.Chmod(pathToDirectoryWithoutReadAccess, 0444); err != nil {
  1531. c.Fatalf("failed to chmod directory to 755: %s", err)
  1532. }
  1533. if err = os.Chmod(pathToFileInDirectoryWithoutReadAccess, 0700); err != nil {
  1534. c.Fatalf("failed to chmod file to 444: %s", err)
  1535. }
  1536. buildCmd := exec.Command("su", "unprivilegeduser", "-c", fmt.Sprintf("%s build -t %s .", dockerBinary, name))
  1537. buildCmd.Dir = ctx.Dir
  1538. if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  1539. c.Fatalf("build should have worked: %s %s", err, out)
  1540. }
  1541. }
  1542. }
  1543. func (s *DockerSuite) TestBuildForceRm(c *check.C) {
  1544. testRequires(c, DaemonIsLinux)
  1545. containerCountBefore, err := getContainerCount()
  1546. if err != nil {
  1547. c.Fatalf("failed to get the container count: %s", err)
  1548. }
  1549. name := "testbuildforcerm"
  1550. ctx, err := fakeContext("FROM scratch\nRUN true\nRUN thiswillfail", nil)
  1551. if err != nil {
  1552. c.Fatal(err)
  1553. }
  1554. defer ctx.Close()
  1555. dockerCmdInDir(c, ctx.Dir, "build", "-t", name, "--force-rm", ".")
  1556. containerCountAfter, err := getContainerCount()
  1557. if err != nil {
  1558. c.Fatalf("failed to get the container count: %s", err)
  1559. }
  1560. if containerCountBefore != containerCountAfter {
  1561. c.Fatalf("--force-rm shouldn't have left containers behind")
  1562. }
  1563. }
  1564. func (s *DockerSuite) TestBuildRm(c *check.C) {
  1565. testRequires(c, DaemonIsLinux)
  1566. name := "testbuildrm"
  1567. ctx, err := fakeContext("FROM scratch\nADD foo /\nADD foo /", map[string]string{"foo": "bar"})
  1568. if err != nil {
  1569. c.Fatal(err)
  1570. }
  1571. defer ctx.Close()
  1572. {
  1573. containerCountBefore, err := getContainerCount()
  1574. if err != nil {
  1575. c.Fatalf("failed to get the container count: %s", err)
  1576. }
  1577. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--rm", "-t", name, ".")
  1578. if err != nil {
  1579. c.Fatal("failed to build the image", out)
  1580. }
  1581. containerCountAfter, err := getContainerCount()
  1582. if err != nil {
  1583. c.Fatalf("failed to get the container count: %s", err)
  1584. }
  1585. if containerCountBefore != containerCountAfter {
  1586. c.Fatalf("-rm shouldn't have left containers behind")
  1587. }
  1588. deleteImages(name)
  1589. }
  1590. {
  1591. containerCountBefore, err := getContainerCount()
  1592. if err != nil {
  1593. c.Fatalf("failed to get the container count: %s", err)
  1594. }
  1595. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name, ".")
  1596. if err != nil {
  1597. c.Fatal("failed to build the image", out)
  1598. }
  1599. containerCountAfter, err := getContainerCount()
  1600. if err != nil {
  1601. c.Fatalf("failed to get the container count: %s", err)
  1602. }
  1603. if containerCountBefore != containerCountAfter {
  1604. c.Fatalf("--rm shouldn't have left containers behind")
  1605. }
  1606. deleteImages(name)
  1607. }
  1608. {
  1609. containerCountBefore, err := getContainerCount()
  1610. if err != nil {
  1611. c.Fatalf("failed to get the container count: %s", err)
  1612. }
  1613. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--rm=false", "-t", name, ".")
  1614. if err != nil {
  1615. c.Fatal("failed to build the image", out)
  1616. }
  1617. containerCountAfter, err := getContainerCount()
  1618. if err != nil {
  1619. c.Fatalf("failed to get the container count: %s", err)
  1620. }
  1621. if containerCountBefore == containerCountAfter {
  1622. c.Fatalf("--rm=false should have left containers behind")
  1623. }
  1624. deleteImages(name)
  1625. }
  1626. }
  1627. func (s *DockerSuite) TestBuildWithVolumes(c *check.C) {
  1628. testRequires(c, DaemonIsLinux)
  1629. var (
  1630. result map[string]map[string]struct{}
  1631. name = "testbuildvolumes"
  1632. emptyMap = make(map[string]struct{})
  1633. expected = map[string]map[string]struct{}{
  1634. "/test1": emptyMap,
  1635. "/test2": emptyMap,
  1636. "/test3": emptyMap,
  1637. "/test4": emptyMap,
  1638. "/test5": emptyMap,
  1639. "/test6": emptyMap,
  1640. "[/test7": emptyMap,
  1641. "/test8]": emptyMap,
  1642. }
  1643. )
  1644. _, err := buildImage(name,
  1645. `FROM scratch
  1646. VOLUME /test1
  1647. VOLUME /test2
  1648. VOLUME /test3 /test4
  1649. VOLUME ["/test5", "/test6"]
  1650. VOLUME [/test7 /test8]
  1651. `,
  1652. true)
  1653. if err != nil {
  1654. c.Fatal(err)
  1655. }
  1656. res := inspectFieldJSON(c, name, "Config.Volumes")
  1657. err = unmarshalJSON([]byte(res), &result)
  1658. if err != nil {
  1659. c.Fatal(err)
  1660. }
  1661. equal := reflect.DeepEqual(&result, &expected)
  1662. if !equal {
  1663. c.Fatalf("Volumes %s, expected %s", result, expected)
  1664. }
  1665. }
  1666. func (s *DockerSuite) TestBuildMaintainer(c *check.C) {
  1667. testRequires(c, DaemonIsLinux)
  1668. name := "testbuildmaintainer"
  1669. expected := "dockerio"
  1670. _, err := buildImage(name,
  1671. `FROM scratch
  1672. MAINTAINER dockerio`,
  1673. true)
  1674. if err != nil {
  1675. c.Fatal(err)
  1676. }
  1677. res := inspectField(c, name, "Author")
  1678. if res != expected {
  1679. c.Fatalf("Maintainer %s, expected %s", res, expected)
  1680. }
  1681. }
  1682. func (s *DockerSuite) TestBuildUser(c *check.C) {
  1683. testRequires(c, DaemonIsLinux)
  1684. name := "testbuilduser"
  1685. expected := "dockerio"
  1686. _, err := buildImage(name,
  1687. `FROM busybox
  1688. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  1689. USER dockerio
  1690. RUN [ $(whoami) = 'dockerio' ]`,
  1691. true)
  1692. if err != nil {
  1693. c.Fatal(err)
  1694. }
  1695. res := inspectField(c, name, "Config.User")
  1696. if res != expected {
  1697. c.Fatalf("User %s, expected %s", res, expected)
  1698. }
  1699. }
  1700. func (s *DockerSuite) TestBuildRelativeWorkdir(c *check.C) {
  1701. testRequires(c, DaemonIsLinux)
  1702. name := "testbuildrelativeworkdir"
  1703. expected := "/test2/test3"
  1704. _, err := buildImage(name,
  1705. `FROM busybox
  1706. RUN [ "$PWD" = '/' ]
  1707. WORKDIR test1
  1708. RUN [ "$PWD" = '/test1' ]
  1709. WORKDIR /test2
  1710. RUN [ "$PWD" = '/test2' ]
  1711. WORKDIR test3
  1712. RUN [ "$PWD" = '/test2/test3' ]`,
  1713. true)
  1714. if err != nil {
  1715. c.Fatal(err)
  1716. }
  1717. res := inspectField(c, name, "Config.WorkingDir")
  1718. if res != expected {
  1719. c.Fatalf("Workdir %s, expected %s", res, expected)
  1720. }
  1721. }
  1722. func (s *DockerSuite) TestBuildWorkdirWithEnvVariables(c *check.C) {
  1723. testRequires(c, DaemonIsLinux)
  1724. name := "testbuildworkdirwithenvvariables"
  1725. expected := "/test1/test2"
  1726. _, err := buildImage(name,
  1727. `FROM busybox
  1728. ENV DIRPATH /test1
  1729. ENV SUBDIRNAME test2
  1730. WORKDIR $DIRPATH
  1731. WORKDIR $SUBDIRNAME/$MISSING_VAR`,
  1732. true)
  1733. if err != nil {
  1734. c.Fatal(err)
  1735. }
  1736. res := inspectField(c, name, "Config.WorkingDir")
  1737. if res != expected {
  1738. c.Fatalf("Workdir %s, expected %s", res, expected)
  1739. }
  1740. }
  1741. func (s *DockerSuite) TestBuildRelativeCopy(c *check.C) {
  1742. // cat /test1/test2/foo gets permission denied for the user
  1743. testRequires(c, NotUserNamespace)
  1744. testRequires(c, DaemonIsLinux)
  1745. name := "testbuildrelativecopy"
  1746. dockerfile := `
  1747. FROM busybox
  1748. WORKDIR /test1
  1749. WORKDIR test2
  1750. RUN [ "$PWD" = '/test1/test2' ]
  1751. COPY foo ./
  1752. RUN [ "$(cat /test1/test2/foo)" = 'hello' ]
  1753. ADD foo ./bar/baz
  1754. RUN [ "$(cat /test1/test2/bar/baz)" = 'hello' ]
  1755. COPY foo ./bar/baz2
  1756. RUN [ "$(cat /test1/test2/bar/baz2)" = 'hello' ]
  1757. WORKDIR ..
  1758. COPY foo ./
  1759. RUN [ "$(cat /test1/foo)" = 'hello' ]
  1760. COPY foo /test3/
  1761. RUN [ "$(cat /test3/foo)" = 'hello' ]
  1762. WORKDIR /test4
  1763. COPY . .
  1764. RUN [ "$(cat /test4/foo)" = 'hello' ]
  1765. WORKDIR /test5/test6
  1766. COPY foo ../
  1767. RUN [ "$(cat /test5/foo)" = 'hello' ]
  1768. `
  1769. ctx, err := fakeContext(dockerfile, map[string]string{
  1770. "foo": "hello",
  1771. })
  1772. if err != nil {
  1773. c.Fatal(err)
  1774. }
  1775. defer ctx.Close()
  1776. _, err = buildImageFromContext(name, ctx, false)
  1777. if err != nil {
  1778. c.Fatal(err)
  1779. }
  1780. }
  1781. func (s *DockerSuite) TestBuildEnv(c *check.C) {
  1782. testRequires(c, DaemonIsLinux)
  1783. name := "testbuildenv"
  1784. expected := "[PATH=/test:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PORT=2375]"
  1785. _, err := buildImage(name,
  1786. `FROM busybox
  1787. ENV PATH /test:$PATH
  1788. ENV PORT 2375
  1789. RUN [ $(env | grep PORT) = 'PORT=2375' ]`,
  1790. true)
  1791. if err != nil {
  1792. c.Fatal(err)
  1793. }
  1794. res := inspectField(c, name, "Config.Env")
  1795. if res != expected {
  1796. c.Fatalf("Env %s, expected %s", res, expected)
  1797. }
  1798. }
  1799. func (s *DockerSuite) TestBuildPATH(c *check.C) {
  1800. testRequires(c, DaemonIsLinux)
  1801. defPath := "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  1802. fn := func(dockerfile string, exp string) {
  1803. _, err := buildImage("testbldpath", dockerfile, true)
  1804. c.Assert(err, check.IsNil)
  1805. res := inspectField(c, "testbldpath", "Config.Env")
  1806. if res != exp {
  1807. c.Fatalf("Env %q, expected %q for dockerfile:%q", res, exp, dockerfile)
  1808. }
  1809. }
  1810. tests := []struct{ dockerfile, exp string }{
  1811. {"FROM scratch\nMAINTAINER me", "[PATH=" + defPath + "]"},
  1812. {"FROM busybox\nMAINTAINER me", "[PATH=" + defPath + "]"},
  1813. {"FROM scratch\nENV FOO=bar", "[PATH=" + defPath + " FOO=bar]"},
  1814. {"FROM busybox\nENV FOO=bar", "[PATH=" + defPath + " FOO=bar]"},
  1815. {"FROM scratch\nENV PATH=/test", "[PATH=/test]"},
  1816. {"FROM busybox\nENV PATH=/test", "[PATH=/test]"},
  1817. {"FROM scratch\nENV PATH=''", "[PATH=]"},
  1818. {"FROM busybox\nENV PATH=''", "[PATH=]"},
  1819. }
  1820. for _, test := range tests {
  1821. fn(test.dockerfile, test.exp)
  1822. }
  1823. }
  1824. func (s *DockerSuite) TestBuildContextCleanup(c *check.C) {
  1825. testRequires(c, DaemonIsLinux)
  1826. testRequires(c, SameHostDaemon)
  1827. name := "testbuildcontextcleanup"
  1828. entries, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  1829. if err != nil {
  1830. c.Fatalf("failed to list contents of tmp dir: %s", err)
  1831. }
  1832. _, err = buildImage(name,
  1833. `FROM scratch
  1834. ENTRYPOINT ["/bin/echo"]`,
  1835. true)
  1836. if err != nil {
  1837. c.Fatal(err)
  1838. }
  1839. entriesFinal, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  1840. if err != nil {
  1841. c.Fatalf("failed to list contents of tmp dir: %s", err)
  1842. }
  1843. if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  1844. c.Fatalf("context should have been deleted, but wasn't")
  1845. }
  1846. }
  1847. func (s *DockerSuite) TestBuildContextCleanupFailedBuild(c *check.C) {
  1848. testRequires(c, DaemonIsLinux)
  1849. testRequires(c, SameHostDaemon)
  1850. name := "testbuildcontextcleanup"
  1851. entries, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  1852. if err != nil {
  1853. c.Fatalf("failed to list contents of tmp dir: %s", err)
  1854. }
  1855. _, err = buildImage(name,
  1856. `FROM scratch
  1857. RUN /non/existing/command`,
  1858. true)
  1859. if err == nil {
  1860. c.Fatalf("expected build to fail, but it didn't")
  1861. }
  1862. entriesFinal, err := ioutil.ReadDir(filepath.Join(dockerBasePath, "tmp"))
  1863. if err != nil {
  1864. c.Fatalf("failed to list contents of tmp dir: %s", err)
  1865. }
  1866. if err = compareDirectoryEntries(entries, entriesFinal); err != nil {
  1867. c.Fatalf("context should have been deleted, but wasn't")
  1868. }
  1869. }
  1870. func (s *DockerSuite) TestBuildCmd(c *check.C) {
  1871. testRequires(c, DaemonIsLinux)
  1872. name := "testbuildcmd"
  1873. expected := "{[/bin/echo Hello World]}"
  1874. _, err := buildImage(name,
  1875. `FROM scratch
  1876. CMD ["/bin/echo", "Hello World"]`,
  1877. true)
  1878. if err != nil {
  1879. c.Fatal(err)
  1880. }
  1881. res := inspectField(c, name, "Config.Cmd")
  1882. if res != expected {
  1883. c.Fatalf("Cmd %s, expected %s", res, expected)
  1884. }
  1885. }
  1886. func (s *DockerSuite) TestBuildExpose(c *check.C) {
  1887. testRequires(c, DaemonIsLinux)
  1888. name := "testbuildexpose"
  1889. expected := "map[2375/tcp:{}]"
  1890. _, err := buildImage(name,
  1891. `FROM scratch
  1892. EXPOSE 2375`,
  1893. true)
  1894. if err != nil {
  1895. c.Fatal(err)
  1896. }
  1897. res := inspectField(c, name, "Config.ExposedPorts")
  1898. if res != expected {
  1899. c.Fatalf("Exposed ports %s, expected %s", res, expected)
  1900. }
  1901. }
  1902. func (s *DockerSuite) TestBuildExposeMorePorts(c *check.C) {
  1903. testRequires(c, DaemonIsLinux)
  1904. // start building docker file with a large number of ports
  1905. portList := make([]string, 50)
  1906. line := make([]string, 100)
  1907. expectedPorts := make([]int, len(portList)*len(line))
  1908. for i := 0; i < len(portList); i++ {
  1909. for j := 0; j < len(line); j++ {
  1910. p := i*len(line) + j + 1
  1911. line[j] = strconv.Itoa(p)
  1912. expectedPorts[p-1] = p
  1913. }
  1914. if i == len(portList)-1 {
  1915. portList[i] = strings.Join(line, " ")
  1916. } else {
  1917. portList[i] = strings.Join(line, " ") + ` \`
  1918. }
  1919. }
  1920. dockerfile := `FROM scratch
  1921. EXPOSE {{range .}} {{.}}
  1922. {{end}}`
  1923. tmpl := template.Must(template.New("dockerfile").Parse(dockerfile))
  1924. buf := bytes.NewBuffer(nil)
  1925. tmpl.Execute(buf, portList)
  1926. name := "testbuildexpose"
  1927. _, err := buildImage(name, buf.String(), true)
  1928. if err != nil {
  1929. c.Fatal(err)
  1930. }
  1931. // check if all the ports are saved inside Config.ExposedPorts
  1932. res := inspectFieldJSON(c, name, "Config.ExposedPorts")
  1933. var exposedPorts map[string]interface{}
  1934. if err := json.Unmarshal([]byte(res), &exposedPorts); err != nil {
  1935. c.Fatal(err)
  1936. }
  1937. for _, p := range expectedPorts {
  1938. ep := fmt.Sprintf("%d/tcp", p)
  1939. if _, ok := exposedPorts[ep]; !ok {
  1940. c.Errorf("Port(%s) is not exposed", ep)
  1941. } else {
  1942. delete(exposedPorts, ep)
  1943. }
  1944. }
  1945. if len(exposedPorts) != 0 {
  1946. c.Errorf("Unexpected extra exposed ports %v", exposedPorts)
  1947. }
  1948. }
  1949. func (s *DockerSuite) TestBuildExposeOrder(c *check.C) {
  1950. testRequires(c, DaemonIsLinux)
  1951. buildID := func(name, exposed string) string {
  1952. _, err := buildImage(name, fmt.Sprintf(`FROM scratch
  1953. EXPOSE %s`, exposed), true)
  1954. if err != nil {
  1955. c.Fatal(err)
  1956. }
  1957. id := inspectField(c, name, "Id")
  1958. return id
  1959. }
  1960. id1 := buildID("testbuildexpose1", "80 2375")
  1961. id2 := buildID("testbuildexpose2", "2375 80")
  1962. if id1 != id2 {
  1963. c.Errorf("EXPOSE should invalidate the cache only when ports actually changed")
  1964. }
  1965. }
  1966. func (s *DockerSuite) TestBuildExposeUpperCaseProto(c *check.C) {
  1967. testRequires(c, DaemonIsLinux)
  1968. name := "testbuildexposeuppercaseproto"
  1969. expected := "map[5678/udp:{}]"
  1970. _, err := buildImage(name,
  1971. `FROM scratch
  1972. EXPOSE 5678/UDP`,
  1973. true)
  1974. if err != nil {
  1975. c.Fatal(err)
  1976. }
  1977. res := inspectField(c, name, "Config.ExposedPorts")
  1978. if res != expected {
  1979. c.Fatalf("Exposed ports %s, expected %s", res, expected)
  1980. }
  1981. }
  1982. func (s *DockerSuite) TestBuildEmptyEntrypointInheritance(c *check.C) {
  1983. testRequires(c, DaemonIsLinux)
  1984. name := "testbuildentrypointinheritance"
  1985. name2 := "testbuildentrypointinheritance2"
  1986. _, err := buildImage(name,
  1987. `FROM busybox
  1988. ENTRYPOINT ["/bin/echo"]`,
  1989. true)
  1990. if err != nil {
  1991. c.Fatal(err)
  1992. }
  1993. res := inspectField(c, name, "Config.Entrypoint")
  1994. expected := "{[/bin/echo]}"
  1995. if res != expected {
  1996. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  1997. }
  1998. _, err = buildImage(name2,
  1999. fmt.Sprintf(`FROM %s
  2000. ENTRYPOINT []`, name),
  2001. true)
  2002. if err != nil {
  2003. c.Fatal(err)
  2004. }
  2005. res = inspectField(c, name2, "Config.Entrypoint")
  2006. expected = "{[]}"
  2007. if res != expected {
  2008. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2009. }
  2010. }
  2011. func (s *DockerSuite) TestBuildEmptyEntrypoint(c *check.C) {
  2012. testRequires(c, DaemonIsLinux)
  2013. name := "testbuildentrypoint"
  2014. expected := "{[]}"
  2015. _, err := buildImage(name,
  2016. `FROM busybox
  2017. ENTRYPOINT []`,
  2018. true)
  2019. if err != nil {
  2020. c.Fatal(err)
  2021. }
  2022. res := inspectField(c, name, "Config.Entrypoint")
  2023. if res != expected {
  2024. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2025. }
  2026. }
  2027. func (s *DockerSuite) TestBuildEntrypoint(c *check.C) {
  2028. testRequires(c, DaemonIsLinux)
  2029. name := "testbuildentrypoint"
  2030. expected := "{[/bin/echo]}"
  2031. _, err := buildImage(name,
  2032. `FROM scratch
  2033. ENTRYPOINT ["/bin/echo"]`,
  2034. true)
  2035. if err != nil {
  2036. c.Fatal(err)
  2037. }
  2038. res := inspectField(c, name, "Config.Entrypoint")
  2039. if res != expected {
  2040. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2041. }
  2042. }
  2043. // #6445 ensure ONBUILD triggers aren't committed to grandchildren
  2044. func (s *DockerSuite) TestBuildOnBuildLimitedInheritence(c *check.C) {
  2045. testRequires(c, DaemonIsLinux)
  2046. var (
  2047. out2, out3 string
  2048. )
  2049. {
  2050. name1 := "testonbuildtrigger1"
  2051. dockerfile1 := `
  2052. FROM busybox
  2053. RUN echo "GRANDPARENT"
  2054. ONBUILD RUN echo "ONBUILD PARENT"
  2055. `
  2056. ctx, err := fakeContext(dockerfile1, nil)
  2057. if err != nil {
  2058. c.Fatal(err)
  2059. }
  2060. defer ctx.Close()
  2061. out1, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", name1, ".")
  2062. if err != nil {
  2063. c.Fatalf("build failed to complete: %s, %v", out1, err)
  2064. }
  2065. }
  2066. {
  2067. name2 := "testonbuildtrigger2"
  2068. dockerfile2 := `
  2069. FROM testonbuildtrigger1
  2070. `
  2071. ctx, err := fakeContext(dockerfile2, nil)
  2072. if err != nil {
  2073. c.Fatal(err)
  2074. }
  2075. defer ctx.Close()
  2076. out2, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name2, ".")
  2077. if err != nil {
  2078. c.Fatalf("build failed to complete: %s, %v", out2, err)
  2079. }
  2080. }
  2081. {
  2082. name3 := "testonbuildtrigger3"
  2083. dockerfile3 := `
  2084. FROM testonbuildtrigger2
  2085. `
  2086. ctx, err := fakeContext(dockerfile3, nil)
  2087. if err != nil {
  2088. c.Fatal(err)
  2089. }
  2090. defer ctx.Close()
  2091. out3, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-t", name3, ".")
  2092. if err != nil {
  2093. c.Fatalf("build failed to complete: %s, %v", out3, err)
  2094. }
  2095. }
  2096. // ONBUILD should be run in second build.
  2097. if !strings.Contains(out2, "ONBUILD PARENT") {
  2098. c.Fatalf("ONBUILD instruction did not run in child of ONBUILD parent")
  2099. }
  2100. // ONBUILD should *not* be run in third build.
  2101. if strings.Contains(out3, "ONBUILD PARENT") {
  2102. c.Fatalf("ONBUILD instruction ran in grandchild of ONBUILD parent")
  2103. }
  2104. }
  2105. func (s *DockerSuite) TestBuildWithCache(c *check.C) {
  2106. testRequires(c, DaemonIsLinux)
  2107. name := "testbuildwithcache"
  2108. id1, err := buildImage(name,
  2109. `FROM scratch
  2110. MAINTAINER dockerio
  2111. EXPOSE 5432
  2112. ENTRYPOINT ["/bin/echo"]`,
  2113. true)
  2114. if err != nil {
  2115. c.Fatal(err)
  2116. }
  2117. id2, err := buildImage(name,
  2118. `FROM scratch
  2119. MAINTAINER dockerio
  2120. EXPOSE 5432
  2121. ENTRYPOINT ["/bin/echo"]`,
  2122. true)
  2123. if err != nil {
  2124. c.Fatal(err)
  2125. }
  2126. if id1 != id2 {
  2127. c.Fatal("The cache should have been used but hasn't.")
  2128. }
  2129. }
  2130. func (s *DockerSuite) TestBuildWithoutCache(c *check.C) {
  2131. testRequires(c, DaemonIsLinux)
  2132. name := "testbuildwithoutcache"
  2133. name2 := "testbuildwithoutcache2"
  2134. id1, err := buildImage(name,
  2135. `FROM scratch
  2136. MAINTAINER dockerio
  2137. EXPOSE 5432
  2138. ENTRYPOINT ["/bin/echo"]`,
  2139. true)
  2140. if err != nil {
  2141. c.Fatal(err)
  2142. }
  2143. id2, err := buildImage(name2,
  2144. `FROM scratch
  2145. MAINTAINER dockerio
  2146. EXPOSE 5432
  2147. ENTRYPOINT ["/bin/echo"]`,
  2148. false)
  2149. if err != nil {
  2150. c.Fatal(err)
  2151. }
  2152. if id1 == id2 {
  2153. c.Fatal("The cache should have been invalided but hasn't.")
  2154. }
  2155. }
  2156. func (s *DockerSuite) TestBuildConditionalCache(c *check.C) {
  2157. testRequires(c, DaemonIsLinux)
  2158. name := "testbuildconditionalcache"
  2159. dockerfile := `
  2160. FROM busybox
  2161. ADD foo /tmp/`
  2162. ctx, err := fakeContext(dockerfile, map[string]string{
  2163. "foo": "hello",
  2164. })
  2165. if err != nil {
  2166. c.Fatal(err)
  2167. }
  2168. defer ctx.Close()
  2169. id1, err := buildImageFromContext(name, ctx, true)
  2170. if err != nil {
  2171. c.Fatalf("Error building #1: %s", err)
  2172. }
  2173. if err := ctx.Add("foo", "bye"); err != nil {
  2174. c.Fatalf("Error modifying foo: %s", err)
  2175. }
  2176. id2, err := buildImageFromContext(name, ctx, false)
  2177. if err != nil {
  2178. c.Fatalf("Error building #2: %s", err)
  2179. }
  2180. if id2 == id1 {
  2181. c.Fatal("Should not have used the cache")
  2182. }
  2183. id3, err := buildImageFromContext(name, ctx, true)
  2184. if err != nil {
  2185. c.Fatalf("Error building #3: %s", err)
  2186. }
  2187. if id3 != id2 {
  2188. c.Fatal("Should have used the cache")
  2189. }
  2190. }
  2191. func (s *DockerSuite) TestBuildAddLocalFileWithCache(c *check.C) {
  2192. // local files are not owned by the correct user
  2193. testRequires(c, NotUserNamespace)
  2194. testRequires(c, DaemonIsLinux)
  2195. name := "testbuildaddlocalfilewithcache"
  2196. name2 := "testbuildaddlocalfilewithcache2"
  2197. dockerfile := `
  2198. FROM busybox
  2199. MAINTAINER dockerio
  2200. ADD foo /usr/lib/bla/bar
  2201. RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2202. ctx, err := fakeContext(dockerfile, map[string]string{
  2203. "foo": "hello",
  2204. })
  2205. if err != nil {
  2206. c.Fatal(err)
  2207. }
  2208. defer ctx.Close()
  2209. id1, err := buildImageFromContext(name, ctx, true)
  2210. if err != nil {
  2211. c.Fatal(err)
  2212. }
  2213. id2, err := buildImageFromContext(name2, ctx, true)
  2214. if err != nil {
  2215. c.Fatal(err)
  2216. }
  2217. if id1 != id2 {
  2218. c.Fatal("The cache should have been used but hasn't.")
  2219. }
  2220. }
  2221. func (s *DockerSuite) TestBuildAddMultipleLocalFileWithCache(c *check.C) {
  2222. testRequires(c, DaemonIsLinux)
  2223. name := "testbuildaddmultiplelocalfilewithcache"
  2224. name2 := "testbuildaddmultiplelocalfilewithcache2"
  2225. dockerfile := `
  2226. FROM busybox
  2227. MAINTAINER dockerio
  2228. ADD foo Dockerfile /usr/lib/bla/
  2229. RUN [ "$(cat /usr/lib/bla/foo)" = "hello" ]`
  2230. ctx, err := fakeContext(dockerfile, map[string]string{
  2231. "foo": "hello",
  2232. })
  2233. if err != nil {
  2234. c.Fatal(err)
  2235. }
  2236. defer ctx.Close()
  2237. id1, err := buildImageFromContext(name, ctx, true)
  2238. if err != nil {
  2239. c.Fatal(err)
  2240. }
  2241. id2, err := buildImageFromContext(name2, ctx, true)
  2242. if err != nil {
  2243. c.Fatal(err)
  2244. }
  2245. if id1 != id2 {
  2246. c.Fatal("The cache should have been used but hasn't.")
  2247. }
  2248. }
  2249. func (s *DockerSuite) TestBuildAddLocalFileWithoutCache(c *check.C) {
  2250. // local files are not owned by the correct user
  2251. testRequires(c, NotUserNamespace)
  2252. testRequires(c, DaemonIsLinux)
  2253. name := "testbuildaddlocalfilewithoutcache"
  2254. name2 := "testbuildaddlocalfilewithoutcache2"
  2255. dockerfile := `
  2256. FROM busybox
  2257. MAINTAINER dockerio
  2258. ADD foo /usr/lib/bla/bar
  2259. RUN [ "$(cat /usr/lib/bla/bar)" = "hello" ]`
  2260. ctx, err := fakeContext(dockerfile, map[string]string{
  2261. "foo": "hello",
  2262. })
  2263. if err != nil {
  2264. c.Fatal(err)
  2265. }
  2266. defer ctx.Close()
  2267. id1, err := buildImageFromContext(name, ctx, true)
  2268. if err != nil {
  2269. c.Fatal(err)
  2270. }
  2271. id2, err := buildImageFromContext(name2, ctx, false)
  2272. if err != nil {
  2273. c.Fatal(err)
  2274. }
  2275. if id1 == id2 {
  2276. c.Fatal("The cache should have been invalided but hasn't.")
  2277. }
  2278. }
  2279. func (s *DockerSuite) TestBuildCopyDirButNotFile(c *check.C) {
  2280. testRequires(c, DaemonIsLinux)
  2281. name := "testbuildcopydirbutnotfile"
  2282. name2 := "testbuildcopydirbutnotfile2"
  2283. dockerfile := `
  2284. FROM scratch
  2285. COPY dir /tmp/`
  2286. ctx, err := fakeContext(dockerfile, map[string]string{
  2287. "dir/foo": "hello",
  2288. })
  2289. if err != nil {
  2290. c.Fatal(err)
  2291. }
  2292. defer ctx.Close()
  2293. id1, err := buildImageFromContext(name, ctx, true)
  2294. if err != nil {
  2295. c.Fatal(err)
  2296. }
  2297. // Check that adding file with similar name doesn't mess with cache
  2298. if err := ctx.Add("dir_file", "hello2"); err != nil {
  2299. c.Fatal(err)
  2300. }
  2301. id2, err := buildImageFromContext(name2, ctx, true)
  2302. if err != nil {
  2303. c.Fatal(err)
  2304. }
  2305. if id1 != id2 {
  2306. c.Fatal("The cache should have been used but wasn't")
  2307. }
  2308. }
  2309. func (s *DockerSuite) TestBuildAddCurrentDirWithCache(c *check.C) {
  2310. testRequires(c, DaemonIsLinux)
  2311. name := "testbuildaddcurrentdirwithcache"
  2312. name2 := name + "2"
  2313. name3 := name + "3"
  2314. name4 := name + "4"
  2315. dockerfile := `
  2316. FROM scratch
  2317. MAINTAINER dockerio
  2318. ADD . /usr/lib/bla`
  2319. ctx, err := fakeContext(dockerfile, map[string]string{
  2320. "foo": "hello",
  2321. })
  2322. if err != nil {
  2323. c.Fatal(err)
  2324. }
  2325. defer ctx.Close()
  2326. id1, err := buildImageFromContext(name, ctx, true)
  2327. if err != nil {
  2328. c.Fatal(err)
  2329. }
  2330. // Check that adding file invalidate cache of "ADD ."
  2331. if err := ctx.Add("bar", "hello2"); err != nil {
  2332. c.Fatal(err)
  2333. }
  2334. id2, err := buildImageFromContext(name2, ctx, true)
  2335. if err != nil {
  2336. c.Fatal(err)
  2337. }
  2338. if id1 == id2 {
  2339. c.Fatal("The cache should have been invalided but hasn't.")
  2340. }
  2341. // Check that changing file invalidate cache of "ADD ."
  2342. if err := ctx.Add("foo", "hello1"); err != nil {
  2343. c.Fatal(err)
  2344. }
  2345. id3, err := buildImageFromContext(name3, ctx, true)
  2346. if err != nil {
  2347. c.Fatal(err)
  2348. }
  2349. if id2 == id3 {
  2350. c.Fatal("The cache should have been invalided but hasn't.")
  2351. }
  2352. // Check that changing file to same content with different mtime does not
  2353. // invalidate cache of "ADD ."
  2354. time.Sleep(1 * time.Second) // wait second because of mtime precision
  2355. if err := ctx.Add("foo", "hello1"); err != nil {
  2356. c.Fatal(err)
  2357. }
  2358. id4, err := buildImageFromContext(name4, ctx, true)
  2359. if err != nil {
  2360. c.Fatal(err)
  2361. }
  2362. if id3 != id4 {
  2363. c.Fatal("The cache should have been used but hasn't.")
  2364. }
  2365. }
  2366. func (s *DockerSuite) TestBuildAddCurrentDirWithoutCache(c *check.C) {
  2367. testRequires(c, DaemonIsLinux)
  2368. name := "testbuildaddcurrentdirwithoutcache"
  2369. name2 := "testbuildaddcurrentdirwithoutcache2"
  2370. dockerfile := `
  2371. FROM scratch
  2372. MAINTAINER dockerio
  2373. ADD . /usr/lib/bla`
  2374. ctx, err := fakeContext(dockerfile, map[string]string{
  2375. "foo": "hello",
  2376. })
  2377. if err != nil {
  2378. c.Fatal(err)
  2379. }
  2380. defer ctx.Close()
  2381. id1, err := buildImageFromContext(name, ctx, true)
  2382. if err != nil {
  2383. c.Fatal(err)
  2384. }
  2385. id2, err := buildImageFromContext(name2, ctx, false)
  2386. if err != nil {
  2387. c.Fatal(err)
  2388. }
  2389. if id1 == id2 {
  2390. c.Fatal("The cache should have been invalided but hasn't.")
  2391. }
  2392. }
  2393. func (s *DockerSuite) TestBuildAddRemoteFileWithCache(c *check.C) {
  2394. testRequires(c, DaemonIsLinux)
  2395. name := "testbuildaddremotefilewithcache"
  2396. server, err := fakeStorage(map[string]string{
  2397. "baz": "hello",
  2398. })
  2399. if err != nil {
  2400. c.Fatal(err)
  2401. }
  2402. defer server.Close()
  2403. id1, err := buildImage(name,
  2404. fmt.Sprintf(`FROM scratch
  2405. MAINTAINER dockerio
  2406. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2407. true)
  2408. if err != nil {
  2409. c.Fatal(err)
  2410. }
  2411. id2, err := buildImage(name,
  2412. fmt.Sprintf(`FROM scratch
  2413. MAINTAINER dockerio
  2414. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2415. true)
  2416. if err != nil {
  2417. c.Fatal(err)
  2418. }
  2419. if id1 != id2 {
  2420. c.Fatal("The cache should have been used but hasn't.")
  2421. }
  2422. }
  2423. func (s *DockerSuite) TestBuildAddRemoteFileWithoutCache(c *check.C) {
  2424. testRequires(c, DaemonIsLinux)
  2425. name := "testbuildaddremotefilewithoutcache"
  2426. name2 := "testbuildaddremotefilewithoutcache2"
  2427. server, err := fakeStorage(map[string]string{
  2428. "baz": "hello",
  2429. })
  2430. if err != nil {
  2431. c.Fatal(err)
  2432. }
  2433. defer server.Close()
  2434. id1, err := buildImage(name,
  2435. fmt.Sprintf(`FROM scratch
  2436. MAINTAINER dockerio
  2437. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2438. true)
  2439. if err != nil {
  2440. c.Fatal(err)
  2441. }
  2442. id2, err := buildImage(name2,
  2443. fmt.Sprintf(`FROM scratch
  2444. MAINTAINER dockerio
  2445. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2446. false)
  2447. if err != nil {
  2448. c.Fatal(err)
  2449. }
  2450. if id1 == id2 {
  2451. c.Fatal("The cache should have been invalided but hasn't.")
  2452. }
  2453. }
  2454. func (s *DockerSuite) TestBuildAddRemoteFileMTime(c *check.C) {
  2455. testRequires(c, DaemonIsLinux)
  2456. name := "testbuildaddremotefilemtime"
  2457. name2 := name + "2"
  2458. name3 := name + "3"
  2459. files := map[string]string{"baz": "hello"}
  2460. server, err := fakeStorage(files)
  2461. if err != nil {
  2462. c.Fatal(err)
  2463. }
  2464. defer server.Close()
  2465. ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2466. MAINTAINER dockerio
  2467. ADD %s/baz /usr/lib/baz/quux`, server.URL()), nil)
  2468. if err != nil {
  2469. c.Fatal(err)
  2470. }
  2471. defer ctx.Close()
  2472. id1, err := buildImageFromContext(name, ctx, true)
  2473. if err != nil {
  2474. c.Fatal(err)
  2475. }
  2476. id2, err := buildImageFromContext(name2, ctx, true)
  2477. if err != nil {
  2478. c.Fatal(err)
  2479. }
  2480. if id1 != id2 {
  2481. c.Fatal("The cache should have been used but wasn't - #1")
  2482. }
  2483. // Now create a different server with same contents (causes different mtime)
  2484. // The cache should still be used
  2485. // allow some time for clock to pass as mtime precision is only 1s
  2486. time.Sleep(2 * time.Second)
  2487. server2, err := fakeStorage(files)
  2488. if err != nil {
  2489. c.Fatal(err)
  2490. }
  2491. defer server2.Close()
  2492. ctx2, err := fakeContext(fmt.Sprintf(`FROM scratch
  2493. MAINTAINER dockerio
  2494. ADD %s/baz /usr/lib/baz/quux`, server2.URL()), nil)
  2495. if err != nil {
  2496. c.Fatal(err)
  2497. }
  2498. defer ctx2.Close()
  2499. id3, err := buildImageFromContext(name3, ctx2, true)
  2500. if err != nil {
  2501. c.Fatal(err)
  2502. }
  2503. if id1 != id3 {
  2504. c.Fatal("The cache should have been used but wasn't")
  2505. }
  2506. }
  2507. func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithCache(c *check.C) {
  2508. testRequires(c, DaemonIsLinux)
  2509. name := "testbuildaddlocalandremotefilewithcache"
  2510. server, err := fakeStorage(map[string]string{
  2511. "baz": "hello",
  2512. })
  2513. if err != nil {
  2514. c.Fatal(err)
  2515. }
  2516. defer server.Close()
  2517. ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2518. MAINTAINER dockerio
  2519. ADD foo /usr/lib/bla/bar
  2520. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2521. map[string]string{
  2522. "foo": "hello world",
  2523. })
  2524. if err != nil {
  2525. c.Fatal(err)
  2526. }
  2527. defer ctx.Close()
  2528. id1, err := buildImageFromContext(name, ctx, true)
  2529. if err != nil {
  2530. c.Fatal(err)
  2531. }
  2532. id2, err := buildImageFromContext(name, ctx, true)
  2533. if err != nil {
  2534. c.Fatal(err)
  2535. }
  2536. if id1 != id2 {
  2537. c.Fatal("The cache should have been used but hasn't.")
  2538. }
  2539. }
  2540. func testContextTar(c *check.C, compression archive.Compression) {
  2541. testRequires(c, DaemonIsLinux)
  2542. ctx, err := fakeContext(
  2543. `FROM busybox
  2544. ADD foo /foo
  2545. CMD ["cat", "/foo"]`,
  2546. map[string]string{
  2547. "foo": "bar",
  2548. },
  2549. )
  2550. if err != nil {
  2551. c.Fatal(err)
  2552. }
  2553. defer ctx.Close()
  2554. context, err := archive.Tar(ctx.Dir, compression)
  2555. if err != nil {
  2556. c.Fatalf("failed to build context tar: %v", err)
  2557. }
  2558. name := "contexttar"
  2559. buildCmd := exec.Command(dockerBinary, "build", "-t", name, "-")
  2560. buildCmd.Stdin = context
  2561. if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  2562. c.Fatalf("build failed to complete: %v %v", out, err)
  2563. }
  2564. }
  2565. func (s *DockerSuite) TestBuildContextTarGzip(c *check.C) {
  2566. testContextTar(c, archive.Gzip)
  2567. }
  2568. func (s *DockerSuite) TestBuildContextTarNoCompression(c *check.C) {
  2569. testContextTar(c, archive.Uncompressed)
  2570. }
  2571. func (s *DockerSuite) TestBuildNoContext(c *check.C) {
  2572. testRequires(c, DaemonIsLinux)
  2573. buildCmd := exec.Command(dockerBinary, "build", "-t", "nocontext", "-")
  2574. buildCmd.Stdin = strings.NewReader("FROM busybox\nCMD echo ok\n")
  2575. if out, _, err := runCommandWithOutput(buildCmd); err != nil {
  2576. c.Fatalf("build failed to complete: %v %v", out, err)
  2577. }
  2578. if out, _ := dockerCmd(c, "run", "--rm", "nocontext"); out != "ok\n" {
  2579. c.Fatalf("run produced invalid output: %q, expected %q", out, "ok")
  2580. }
  2581. }
  2582. // TODO: TestCaching
  2583. func (s *DockerSuite) TestBuildAddLocalAndRemoteFilesWithoutCache(c *check.C) {
  2584. testRequires(c, DaemonIsLinux)
  2585. name := "testbuildaddlocalandremotefilewithoutcache"
  2586. name2 := "testbuildaddlocalandremotefilewithoutcache2"
  2587. server, err := fakeStorage(map[string]string{
  2588. "baz": "hello",
  2589. })
  2590. if err != nil {
  2591. c.Fatal(err)
  2592. }
  2593. defer server.Close()
  2594. ctx, err := fakeContext(fmt.Sprintf(`FROM scratch
  2595. MAINTAINER dockerio
  2596. ADD foo /usr/lib/bla/bar
  2597. ADD %s/baz /usr/lib/baz/quux`, server.URL()),
  2598. map[string]string{
  2599. "foo": "hello world",
  2600. })
  2601. if err != nil {
  2602. c.Fatal(err)
  2603. }
  2604. defer ctx.Close()
  2605. id1, err := buildImageFromContext(name, ctx, true)
  2606. if err != nil {
  2607. c.Fatal(err)
  2608. }
  2609. id2, err := buildImageFromContext(name2, ctx, false)
  2610. if err != nil {
  2611. c.Fatal(err)
  2612. }
  2613. if id1 == id2 {
  2614. c.Fatal("The cache should have been invalided but hasn't.")
  2615. }
  2616. }
  2617. func (s *DockerSuite) TestBuildWithVolumeOwnership(c *check.C) {
  2618. testRequires(c, DaemonIsLinux)
  2619. name := "testbuildimg"
  2620. _, err := buildImage(name,
  2621. `FROM busybox:latest
  2622. RUN mkdir /test && chown daemon:daemon /test && chmod 0600 /test
  2623. VOLUME /test`,
  2624. true)
  2625. if err != nil {
  2626. c.Fatal(err)
  2627. }
  2628. out, _ := dockerCmd(c, "run", "--rm", "testbuildimg", "ls", "-la", "/test")
  2629. if expected := "drw-------"; !strings.Contains(out, expected) {
  2630. c.Fatalf("expected %s received %s", expected, out)
  2631. }
  2632. if expected := "daemon daemon"; !strings.Contains(out, expected) {
  2633. c.Fatalf("expected %s received %s", expected, out)
  2634. }
  2635. }
  2636. // testing #1405 - config.Cmd does not get cleaned up if
  2637. // utilizing cache
  2638. func (s *DockerSuite) TestBuildEntrypointRunCleanup(c *check.C) {
  2639. testRequires(c, DaemonIsLinux)
  2640. name := "testbuildcmdcleanup"
  2641. if _, err := buildImage(name,
  2642. `FROM busybox
  2643. RUN echo "hello"`,
  2644. true); err != nil {
  2645. c.Fatal(err)
  2646. }
  2647. ctx, err := fakeContext(`FROM busybox
  2648. RUN echo "hello"
  2649. ADD foo /foo
  2650. ENTRYPOINT ["/bin/echo"]`,
  2651. map[string]string{
  2652. "foo": "hello",
  2653. })
  2654. if err != nil {
  2655. c.Fatal(err)
  2656. }
  2657. defer ctx.Close()
  2658. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2659. c.Fatal(err)
  2660. }
  2661. res := inspectField(c, name, "Config.Cmd")
  2662. // Cmd must be cleaned up
  2663. if res != "<nil>" {
  2664. c.Fatalf("Cmd %s, expected nil", res)
  2665. }
  2666. }
  2667. func (s *DockerSuite) TestBuildForbiddenContextPath(c *check.C) {
  2668. testRequires(c, DaemonIsLinux)
  2669. name := "testbuildforbidpath"
  2670. ctx, err := fakeContext(`FROM scratch
  2671. ADD ../../ test/
  2672. `,
  2673. map[string]string{
  2674. "test.txt": "test1",
  2675. "other.txt": "other",
  2676. })
  2677. if err != nil {
  2678. c.Fatal(err)
  2679. }
  2680. defer ctx.Close()
  2681. expected := "Forbidden path outside the build context: ../../ "
  2682. if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
  2683. c.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
  2684. }
  2685. }
  2686. func (s *DockerSuite) TestBuildAddFileNotFound(c *check.C) {
  2687. testRequires(c, DaemonIsLinux)
  2688. name := "testbuildaddnotfound"
  2689. ctx, err := fakeContext(`FROM scratch
  2690. ADD foo /usr/local/bar`,
  2691. map[string]string{"bar": "hello"})
  2692. if err != nil {
  2693. c.Fatal(err)
  2694. }
  2695. defer ctx.Close()
  2696. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2697. if !strings.Contains(err.Error(), "foo: no such file or directory") {
  2698. c.Fatalf("Wrong error %v, must be about missing foo file or directory", err)
  2699. }
  2700. } else {
  2701. c.Fatal("Error must not be nil")
  2702. }
  2703. }
  2704. func (s *DockerSuite) TestBuildInheritance(c *check.C) {
  2705. testRequires(c, DaemonIsLinux)
  2706. name := "testbuildinheritance"
  2707. _, err := buildImage(name,
  2708. `FROM scratch
  2709. EXPOSE 2375`,
  2710. true)
  2711. if err != nil {
  2712. c.Fatal(err)
  2713. }
  2714. ports1 := inspectField(c, name, "Config.ExposedPorts")
  2715. _, err = buildImage(name,
  2716. fmt.Sprintf(`FROM %s
  2717. ENTRYPOINT ["/bin/echo"]`, name),
  2718. true)
  2719. if err != nil {
  2720. c.Fatal(err)
  2721. }
  2722. res := inspectField(c, name, "Config.Entrypoint")
  2723. if expected := "{[/bin/echo]}"; res != expected {
  2724. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  2725. }
  2726. ports2 := inspectField(c, name, "Config.ExposedPorts")
  2727. if ports1 != ports2 {
  2728. c.Fatalf("Ports must be same: %s != %s", ports1, ports2)
  2729. }
  2730. }
  2731. func (s *DockerSuite) TestBuildFails(c *check.C) {
  2732. testRequires(c, DaemonIsLinux)
  2733. name := "testbuildfails"
  2734. _, err := buildImage(name,
  2735. `FROM busybox
  2736. RUN sh -c "exit 23"`,
  2737. true)
  2738. if err != nil {
  2739. if !strings.Contains(err.Error(), "returned a non-zero code: 23") {
  2740. c.Fatalf("Wrong error %v, must be about non-zero code 23", err)
  2741. }
  2742. } else {
  2743. c.Fatal("Error must not be nil")
  2744. }
  2745. }
  2746. func (s *DockerSuite) TestBuildFailsDockerfileEmpty(c *check.C) {
  2747. name := "testbuildfails"
  2748. _, err := buildImage(name, ``, true)
  2749. if err != nil {
  2750. if !strings.Contains(err.Error(), "The Dockerfile (Dockerfile) cannot be empty") {
  2751. c.Fatalf("Wrong error %v, must be about empty Dockerfile", err)
  2752. }
  2753. } else {
  2754. c.Fatal("Error must not be nil")
  2755. }
  2756. }
  2757. func (s *DockerSuite) TestBuildOnBuild(c *check.C) {
  2758. testRequires(c, DaemonIsLinux)
  2759. name := "testbuildonbuild"
  2760. _, err := buildImage(name,
  2761. `FROM busybox
  2762. ONBUILD RUN touch foobar`,
  2763. true)
  2764. if err != nil {
  2765. c.Fatal(err)
  2766. }
  2767. _, err = buildImage(name,
  2768. fmt.Sprintf(`FROM %s
  2769. RUN [ -f foobar ]`, name),
  2770. true)
  2771. if err != nil {
  2772. c.Fatal(err)
  2773. }
  2774. }
  2775. func (s *DockerSuite) TestBuildOnBuildForbiddenChained(c *check.C) {
  2776. testRequires(c, DaemonIsLinux)
  2777. name := "testbuildonbuildforbiddenchained"
  2778. _, err := buildImage(name,
  2779. `FROM busybox
  2780. ONBUILD ONBUILD RUN touch foobar`,
  2781. true)
  2782. if err != nil {
  2783. if !strings.Contains(err.Error(), "Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed") {
  2784. c.Fatalf("Wrong error %v, must be about chaining ONBUILD", err)
  2785. }
  2786. } else {
  2787. c.Fatal("Error must not be nil")
  2788. }
  2789. }
  2790. func (s *DockerSuite) TestBuildOnBuildForbiddenFrom(c *check.C) {
  2791. testRequires(c, DaemonIsLinux)
  2792. name := "testbuildonbuildforbiddenfrom"
  2793. _, err := buildImage(name,
  2794. `FROM busybox
  2795. ONBUILD FROM scratch`,
  2796. true)
  2797. if err != nil {
  2798. if !strings.Contains(err.Error(), "FROM isn't allowed as an ONBUILD trigger") {
  2799. c.Fatalf("Wrong error %v, must be about FROM forbidden", err)
  2800. }
  2801. } else {
  2802. c.Fatal("Error must not be nil")
  2803. }
  2804. }
  2805. func (s *DockerSuite) TestBuildOnBuildForbiddenMaintainer(c *check.C) {
  2806. testRequires(c, DaemonIsLinux)
  2807. name := "testbuildonbuildforbiddenmaintainer"
  2808. _, err := buildImage(name,
  2809. `FROM busybox
  2810. ONBUILD MAINTAINER docker.io`,
  2811. true)
  2812. if err != nil {
  2813. if !strings.Contains(err.Error(), "MAINTAINER isn't allowed as an ONBUILD trigger") {
  2814. c.Fatalf("Wrong error %v, must be about MAINTAINER forbidden", err)
  2815. }
  2816. } else {
  2817. c.Fatal("Error must not be nil")
  2818. }
  2819. }
  2820. // gh #2446
  2821. func (s *DockerSuite) TestBuildAddToSymlinkDest(c *check.C) {
  2822. testRequires(c, DaemonIsLinux)
  2823. name := "testbuildaddtosymlinkdest"
  2824. ctx, err := fakeContext(`FROM busybox
  2825. RUN mkdir /foo
  2826. RUN ln -s /foo /bar
  2827. ADD foo /bar/
  2828. RUN [ -f /bar/foo ]
  2829. RUN [ -f /foo/foo ]`,
  2830. map[string]string{
  2831. "foo": "hello",
  2832. })
  2833. if err != nil {
  2834. c.Fatal(err)
  2835. }
  2836. defer ctx.Close()
  2837. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2838. c.Fatal(err)
  2839. }
  2840. }
  2841. func (s *DockerSuite) TestBuildEscapeWhitespace(c *check.C) {
  2842. testRequires(c, DaemonIsLinux)
  2843. name := "testbuildescaping"
  2844. _, err := buildImage(name, `
  2845. FROM busybox
  2846. MAINTAINER "Docker \
  2847. IO <io@\
  2848. docker.com>"
  2849. `, true)
  2850. if err != nil {
  2851. c.Fatal(err)
  2852. }
  2853. res := inspectField(c, name, "Author")
  2854. if res != "\"Docker IO <io@docker.com>\"" {
  2855. c.Fatalf("Parsed string did not match the escaped string. Got: %q", res)
  2856. }
  2857. }
  2858. func (s *DockerSuite) TestBuildVerifyIntString(c *check.C) {
  2859. testRequires(c, DaemonIsLinux)
  2860. // Verify that strings that look like ints are still passed as strings
  2861. name := "testbuildstringing"
  2862. _, err := buildImage(name, `
  2863. FROM busybox
  2864. MAINTAINER 123
  2865. `, true)
  2866. if err != nil {
  2867. c.Fatal(err)
  2868. }
  2869. out, _ := dockerCmd(c, "inspect", name)
  2870. if !strings.Contains(out, "\"123\"") {
  2871. c.Fatalf("Output does not contain the int as a string:\n%s", out)
  2872. }
  2873. }
  2874. func (s *DockerSuite) TestBuildDockerignore(c *check.C) {
  2875. testRequires(c, DaemonIsLinux)
  2876. name := "testbuilddockerignore"
  2877. dockerfile := `
  2878. FROM busybox
  2879. ADD . /bla
  2880. RUN [[ -f /bla/src/x.go ]]
  2881. RUN [[ -f /bla/Makefile ]]
  2882. RUN [[ ! -e /bla/src/_vendor ]]
  2883. RUN [[ ! -e /bla/.gitignore ]]
  2884. RUN [[ ! -e /bla/README.md ]]
  2885. RUN [[ ! -e /bla/dir/foo ]]
  2886. RUN [[ ! -e /bla/foo ]]
  2887. RUN [[ ! -e /bla/.git ]]
  2888. RUN [[ ! -e v.cc ]]
  2889. RUN [[ ! -e src/v.cc ]]
  2890. RUN [[ ! -e src/_vendor/v.cc ]]`
  2891. ctx, err := fakeContext(dockerfile, map[string]string{
  2892. "Makefile": "all:",
  2893. ".git/HEAD": "ref: foo",
  2894. "src/x.go": "package main",
  2895. "src/_vendor/v.go": "package main",
  2896. "src/_vendor/v.cc": "package main",
  2897. "src/v.cc": "package main",
  2898. "v.cc": "package main",
  2899. "dir/foo": "",
  2900. ".gitignore": "",
  2901. "README.md": "readme",
  2902. ".dockerignore": `
  2903. .git
  2904. pkg
  2905. .gitignore
  2906. src/_vendor
  2907. *.md
  2908. **/*.cc
  2909. dir`,
  2910. })
  2911. if err != nil {
  2912. c.Fatal(err)
  2913. }
  2914. defer ctx.Close()
  2915. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2916. c.Fatal(err)
  2917. }
  2918. }
  2919. func (s *DockerSuite) TestBuildDockerignoreCleanPaths(c *check.C) {
  2920. testRequires(c, DaemonIsLinux)
  2921. name := "testbuilddockerignorecleanpaths"
  2922. dockerfile := `
  2923. FROM busybox
  2924. ADD . /tmp/
  2925. RUN (! ls /tmp/foo) && (! ls /tmp/foo2) && (! ls /tmp/dir1/foo)`
  2926. ctx, err := fakeContext(dockerfile, map[string]string{
  2927. "foo": "foo",
  2928. "foo2": "foo2",
  2929. "dir1/foo": "foo in dir1",
  2930. ".dockerignore": "./foo\ndir1//foo\n./dir1/../foo2",
  2931. })
  2932. if err != nil {
  2933. c.Fatal(err)
  2934. }
  2935. defer ctx.Close()
  2936. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2937. c.Fatal(err)
  2938. }
  2939. }
  2940. func (s *DockerSuite) TestBuildDockerignoreExceptions(c *check.C) {
  2941. testRequires(c, DaemonIsLinux)
  2942. name := "testbuilddockerignoreexceptions"
  2943. dockerfile := `
  2944. FROM busybox
  2945. ADD . /bla
  2946. RUN [[ -f /bla/src/x.go ]]
  2947. RUN [[ -f /bla/Makefile ]]
  2948. RUN [[ ! -e /bla/src/_vendor ]]
  2949. RUN [[ ! -e /bla/.gitignore ]]
  2950. RUN [[ ! -e /bla/README.md ]]
  2951. RUN [[ -e /bla/dir/dir/foo ]]
  2952. RUN [[ ! -e /bla/dir/foo1 ]]
  2953. RUN [[ -f /bla/dir/e ]]
  2954. RUN [[ -f /bla/dir/e-dir/foo ]]
  2955. RUN [[ ! -e /bla/foo ]]
  2956. RUN [[ ! -e /bla/.git ]]
  2957. RUN [[ -e /bla/dir/a.cc ]]`
  2958. ctx, err := fakeContext(dockerfile, map[string]string{
  2959. "Makefile": "all:",
  2960. ".git/HEAD": "ref: foo",
  2961. "src/x.go": "package main",
  2962. "src/_vendor/v.go": "package main",
  2963. "dir/foo": "",
  2964. "dir/foo1": "",
  2965. "dir/dir/f1": "",
  2966. "dir/dir/foo": "",
  2967. "dir/e": "",
  2968. "dir/e-dir/foo": "",
  2969. ".gitignore": "",
  2970. "README.md": "readme",
  2971. "dir/a.cc": "hello",
  2972. ".dockerignore": `
  2973. .git
  2974. pkg
  2975. .gitignore
  2976. src/_vendor
  2977. *.md
  2978. dir
  2979. !dir/e*
  2980. !dir/dir/foo
  2981. **/*.cc
  2982. !**/*.cc`,
  2983. })
  2984. if err != nil {
  2985. c.Fatal(err)
  2986. }
  2987. defer ctx.Close()
  2988. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  2989. c.Fatal(err)
  2990. }
  2991. }
  2992. func (s *DockerSuite) TestBuildDockerignoringDockerfile(c *check.C) {
  2993. testRequires(c, DaemonIsLinux)
  2994. name := "testbuilddockerignoredockerfile"
  2995. dockerfile := `
  2996. FROM busybox
  2997. ADD . /tmp/
  2998. RUN ! ls /tmp/Dockerfile
  2999. RUN ls /tmp/.dockerignore`
  3000. ctx, err := fakeContext(dockerfile, map[string]string{
  3001. "Dockerfile": dockerfile,
  3002. ".dockerignore": "Dockerfile\n",
  3003. })
  3004. if err != nil {
  3005. c.Fatal(err)
  3006. }
  3007. defer ctx.Close()
  3008. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3009. c.Fatalf("Didn't ignore Dockerfile correctly:%s", err)
  3010. }
  3011. // now try it with ./Dockerfile
  3012. ctx.Add(".dockerignore", "./Dockerfile\n")
  3013. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3014. c.Fatalf("Didn't ignore ./Dockerfile correctly:%s", err)
  3015. }
  3016. }
  3017. func (s *DockerSuite) TestBuildDockerignoringRenamedDockerfile(c *check.C) {
  3018. testRequires(c, DaemonIsLinux)
  3019. name := "testbuilddockerignoredockerfile"
  3020. dockerfile := `
  3021. FROM busybox
  3022. ADD . /tmp/
  3023. RUN ls /tmp/Dockerfile
  3024. RUN ! ls /tmp/MyDockerfile
  3025. RUN ls /tmp/.dockerignore`
  3026. ctx, err := fakeContext(dockerfile, map[string]string{
  3027. "Dockerfile": "Should not use me",
  3028. "MyDockerfile": dockerfile,
  3029. ".dockerignore": "MyDockerfile\n",
  3030. })
  3031. if err != nil {
  3032. c.Fatal(err)
  3033. }
  3034. defer ctx.Close()
  3035. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3036. c.Fatalf("Didn't ignore MyDockerfile correctly:%s", err)
  3037. }
  3038. // now try it with ./MyDockerfile
  3039. ctx.Add(".dockerignore", "./MyDockerfile\n")
  3040. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3041. c.Fatalf("Didn't ignore ./MyDockerfile correctly:%s", err)
  3042. }
  3043. }
  3044. func (s *DockerSuite) TestBuildDockerignoringDockerignore(c *check.C) {
  3045. testRequires(c, DaemonIsLinux)
  3046. name := "testbuilddockerignoredockerignore"
  3047. dockerfile := `
  3048. FROM busybox
  3049. ADD . /tmp/
  3050. RUN ! ls /tmp/.dockerignore
  3051. RUN ls /tmp/Dockerfile`
  3052. ctx, err := fakeContext(dockerfile, map[string]string{
  3053. "Dockerfile": dockerfile,
  3054. ".dockerignore": ".dockerignore\n",
  3055. })
  3056. if err != nil {
  3057. c.Fatal(err)
  3058. }
  3059. defer ctx.Close()
  3060. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3061. c.Fatalf("Didn't ignore .dockerignore correctly:%s", err)
  3062. }
  3063. }
  3064. func (s *DockerSuite) TestBuildDockerignoreTouchDockerfile(c *check.C) {
  3065. testRequires(c, DaemonIsLinux)
  3066. var id1 string
  3067. var id2 string
  3068. name := "testbuilddockerignoretouchdockerfile"
  3069. dockerfile := `
  3070. FROM busybox
  3071. ADD . /tmp/`
  3072. ctx, err := fakeContext(dockerfile, map[string]string{
  3073. "Dockerfile": dockerfile,
  3074. ".dockerignore": "Dockerfile\n",
  3075. })
  3076. if err != nil {
  3077. c.Fatal(err)
  3078. }
  3079. defer ctx.Close()
  3080. if id1, err = buildImageFromContext(name, ctx, true); err != nil {
  3081. c.Fatalf("Didn't build it correctly:%s", err)
  3082. }
  3083. if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3084. c.Fatalf("Didn't build it correctly:%s", err)
  3085. }
  3086. if id1 != id2 {
  3087. c.Fatalf("Didn't use the cache - 1")
  3088. }
  3089. // Now make sure touching Dockerfile doesn't invalidate the cache
  3090. if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3091. c.Fatalf("Didn't add Dockerfile: %s", err)
  3092. }
  3093. if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3094. c.Fatalf("Didn't build it correctly:%s", err)
  3095. }
  3096. if id1 != id2 {
  3097. c.Fatalf("Didn't use the cache - 2")
  3098. }
  3099. // One more time but just 'touch' it instead of changing the content
  3100. if err = ctx.Add("Dockerfile", dockerfile+"\n# hi"); err != nil {
  3101. c.Fatalf("Didn't add Dockerfile: %s", err)
  3102. }
  3103. if id2, err = buildImageFromContext(name, ctx, true); err != nil {
  3104. c.Fatalf("Didn't build it correctly:%s", err)
  3105. }
  3106. if id1 != id2 {
  3107. c.Fatalf("Didn't use the cache - 3")
  3108. }
  3109. }
  3110. func (s *DockerSuite) TestBuildDockerignoringWholeDir(c *check.C) {
  3111. testRequires(c, DaemonIsLinux)
  3112. name := "testbuilddockerignorewholedir"
  3113. dockerfile := `
  3114. FROM busybox
  3115. COPY . /
  3116. RUN [[ ! -e /.gitignore ]]
  3117. RUN [[ -f /Makefile ]]`
  3118. ctx, err := fakeContext(dockerfile, map[string]string{
  3119. "Dockerfile": "FROM scratch",
  3120. "Makefile": "all:",
  3121. ".gitignore": "",
  3122. ".dockerignore": ".*\n",
  3123. })
  3124. c.Assert(err, check.IsNil)
  3125. defer ctx.Close()
  3126. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3127. c.Fatal(err)
  3128. }
  3129. c.Assert(ctx.Add(".dockerfile", "*"), check.IsNil)
  3130. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3131. c.Fatal(err)
  3132. }
  3133. c.Assert(ctx.Add(".dockerfile", "."), check.IsNil)
  3134. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3135. c.Fatal(err)
  3136. }
  3137. c.Assert(ctx.Add(".dockerfile", "?"), check.IsNil)
  3138. if _, err = buildImageFromContext(name, ctx, true); err != nil {
  3139. c.Fatal(err)
  3140. }
  3141. }
  3142. func (s *DockerSuite) TestBuildDockerignoringBadExclusion(c *check.C) {
  3143. testRequires(c, DaemonIsLinux)
  3144. name := "testbuilddockerignorebadexclusion"
  3145. dockerfile := `
  3146. FROM busybox
  3147. COPY . /
  3148. RUN [[ ! -e /.gitignore ]]
  3149. RUN [[ -f /Makefile ]]`
  3150. ctx, err := fakeContext(dockerfile, map[string]string{
  3151. "Dockerfile": "FROM scratch",
  3152. "Makefile": "all:",
  3153. ".gitignore": "",
  3154. ".dockerignore": "!\n",
  3155. })
  3156. c.Assert(err, check.IsNil)
  3157. defer ctx.Close()
  3158. if _, err = buildImageFromContext(name, ctx, true); err == nil {
  3159. c.Fatalf("Build was supposed to fail but didn't")
  3160. }
  3161. if err.Error() != "failed to build the image: Error checking context: 'Illegal exclusion pattern: !'.\n" {
  3162. c.Fatalf("Incorrect output, got:%q", err.Error())
  3163. }
  3164. }
  3165. func (s *DockerSuite) TestBuildDockerignoringWildTopDir(c *check.C) {
  3166. testRequires(c, DaemonIsLinux)
  3167. dockerfile := `
  3168. FROM busybox
  3169. COPY . /
  3170. RUN [[ ! -e /.dockerignore ]]
  3171. RUN [[ ! -e /Dockerfile ]]
  3172. RUN [[ ! -e /file1 ]]
  3173. RUN [[ ! -e /dir ]]`
  3174. ctx, err := fakeContext(dockerfile, map[string]string{
  3175. "Dockerfile": "FROM scratch",
  3176. "file1": "",
  3177. "dir/dfile1": "",
  3178. })
  3179. c.Assert(err, check.IsNil)
  3180. defer ctx.Close()
  3181. // All of these should result in ignoring all files
  3182. for _, variant := range []string{"**", "**/", "**/**", "*"} {
  3183. ctx.Add(".dockerignore", variant)
  3184. _, err = buildImageFromContext("noname", ctx, true)
  3185. c.Assert(err, check.IsNil, check.Commentf("variant: %s", variant))
  3186. }
  3187. }
  3188. func (s *DockerSuite) TestBuildDockerignoringWildDirs(c *check.C) {
  3189. testRequires(c, DaemonIsLinux)
  3190. dockerfile := `
  3191. FROM busybox
  3192. COPY . /
  3193. RUN [[ -e /.dockerignore ]]
  3194. RUN [[ -e /Dockerfile ]]
  3195. RUN [[ ! -e /file0 ]]
  3196. RUN [[ ! -e /dir1/file0 ]]
  3197. RUN [[ ! -e /dir2/file0 ]]
  3198. RUN [[ ! -e /file1 ]]
  3199. RUN [[ ! -e /dir1/file1 ]]
  3200. RUN [[ ! -e /dir1/dir2/file1 ]]
  3201. RUN [[ ! -e /dir1/file2 ]]
  3202. RUN [[ -e /dir1/dir2/file2 ]]
  3203. RUN [[ ! -e /dir1/dir2/file4 ]]
  3204. RUN [[ ! -e /dir1/dir2/file5 ]]
  3205. RUN [[ ! -e /dir1/dir2/file6 ]]
  3206. RUN [[ ! -e /dir1/dir3/file7 ]]
  3207. RUN [[ ! -e /dir1/dir3/file8 ]]
  3208. RUN [[ -e /dir1/dir3 ]]
  3209. RUN [[ -e /dir1/dir4 ]]
  3210. RUN [[ ! -e 'dir1/dir5/fileAA' ]]
  3211. RUN [[ -e 'dir1/dir5/fileAB' ]]
  3212. RUN [[ -e 'dir1/dir5/fileB' ]] # "." in pattern means nothing
  3213. RUN echo all done!`
  3214. ctx, err := fakeContext(dockerfile, map[string]string{
  3215. "Dockerfile": "FROM scratch",
  3216. "file0": "",
  3217. "dir1/file0": "",
  3218. "dir1/dir2/file0": "",
  3219. "file1": "",
  3220. "dir1/file1": "",
  3221. "dir1/dir2/file1": "",
  3222. "dir1/file2": "",
  3223. "dir1/dir2/file2": "", // remains
  3224. "dir1/dir2/file4": "",
  3225. "dir1/dir2/file5": "",
  3226. "dir1/dir2/file6": "",
  3227. "dir1/dir3/file7": "",
  3228. "dir1/dir3/file8": "",
  3229. "dir1/dir4/file9": "",
  3230. "dir1/dir5/fileAA": "",
  3231. "dir1/dir5/fileAB": "",
  3232. "dir1/dir5/fileB": "",
  3233. ".dockerignore": `
  3234. **/file0
  3235. **/*file1
  3236. **/dir1/file2
  3237. dir1/**/file4
  3238. **/dir2/file5
  3239. **/dir1/dir2/file6
  3240. dir1/dir3/**
  3241. **/dir4/**
  3242. **/file?A
  3243. **/file\?B
  3244. **/dir5/file.
  3245. `,
  3246. })
  3247. c.Assert(err, check.IsNil)
  3248. defer ctx.Close()
  3249. _, err = buildImageFromContext("noname", ctx, true)
  3250. c.Assert(err, check.IsNil)
  3251. }
  3252. func (s *DockerSuite) TestBuildLineBreak(c *check.C) {
  3253. testRequires(c, DaemonIsLinux)
  3254. name := "testbuildlinebreak"
  3255. _, err := buildImage(name,
  3256. `FROM busybox
  3257. RUN sh -c 'echo root:testpass \
  3258. > /tmp/passwd'
  3259. RUN mkdir -p /var/run/sshd
  3260. RUN [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3261. RUN [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3262. true)
  3263. if err != nil {
  3264. c.Fatal(err)
  3265. }
  3266. }
  3267. func (s *DockerSuite) TestBuildEOLInLine(c *check.C) {
  3268. testRequires(c, DaemonIsLinux)
  3269. name := "testbuildeolinline"
  3270. _, err := buildImage(name,
  3271. `FROM busybox
  3272. RUN sh -c 'echo root:testpass > /tmp/passwd'
  3273. RUN echo "foo \n bar"; echo "baz"
  3274. RUN mkdir -p /var/run/sshd
  3275. RUN [ "$(cat /tmp/passwd)" = "root:testpass" ]
  3276. RUN [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ]`,
  3277. true)
  3278. if err != nil {
  3279. c.Fatal(err)
  3280. }
  3281. }
  3282. func (s *DockerSuite) TestBuildCommentsShebangs(c *check.C) {
  3283. testRequires(c, DaemonIsLinux)
  3284. name := "testbuildcomments"
  3285. _, err := buildImage(name,
  3286. `FROM busybox
  3287. # This is an ordinary comment.
  3288. RUN { echo '#!/bin/sh'; echo 'echo hello world'; } > /hello.sh
  3289. RUN [ ! -x /hello.sh ]
  3290. # comment with line break \
  3291. RUN chmod +x /hello.sh
  3292. RUN [ -x /hello.sh ]
  3293. RUN [ "$(cat /hello.sh)" = $'#!/bin/sh\necho hello world' ]
  3294. RUN [ "$(/hello.sh)" = "hello world" ]`,
  3295. true)
  3296. if err != nil {
  3297. c.Fatal(err)
  3298. }
  3299. }
  3300. func (s *DockerSuite) TestBuildUsersAndGroups(c *check.C) {
  3301. testRequires(c, DaemonIsLinux)
  3302. name := "testbuildusers"
  3303. _, err := buildImage(name,
  3304. `FROM busybox
  3305. # Make sure our defaults work
  3306. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)" = '0:0/root:root' ]
  3307. # 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)
  3308. USER root
  3309. RUN [ "$(id -G):$(id -Gn)" = '0 10:root wheel' ]
  3310. # Setup dockerio user and group
  3311. RUN echo 'dockerio:x:1001:1001::/bin:/bin/false' >> /etc/passwd
  3312. RUN echo 'dockerio:x:1001:' >> /etc/group
  3313. # Make sure we can switch to our user and all the information is exactly as we expect it to be
  3314. USER dockerio
  3315. RUN id -G
  3316. RUN id -Gn
  3317. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3318. # Switch back to root and double check that worked exactly as we might expect it to
  3319. USER root
  3320. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '0:0/root:root/0 10:root wheel' ]
  3321. # Add a "supplementary" group for our dockerio user
  3322. RUN echo 'supplementary:x:1002:dockerio' >> /etc/group
  3323. # ... and then go verify that we get it like we expect
  3324. USER dockerio
  3325. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3326. USER 1001
  3327. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001 1002:dockerio supplementary' ]
  3328. # super test the new "user:group" syntax
  3329. USER dockerio:dockerio
  3330. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3331. USER 1001:dockerio
  3332. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3333. USER dockerio:1001
  3334. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3335. USER 1001:1001
  3336. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1001/dockerio:dockerio/1001:dockerio' ]
  3337. USER dockerio:supplementary
  3338. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3339. USER dockerio:1002
  3340. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3341. USER 1001:supplementary
  3342. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3343. USER 1001:1002
  3344. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1001:1002/dockerio:supplementary/1002:supplementary' ]
  3345. # make sure unknown uid/gid still works properly
  3346. USER 1042:1043
  3347. RUN [ "$(id -u):$(id -g)/$(id -un):$(id -gn)/$(id -G):$(id -Gn)" = '1042:1043/1042:1043/1043:1043' ]`,
  3348. true)
  3349. if err != nil {
  3350. c.Fatal(err)
  3351. }
  3352. }
  3353. func (s *DockerSuite) TestBuildEnvUsage(c *check.C) {
  3354. // /docker/world/hello is not owned by the correct user
  3355. testRequires(c, NotUserNamespace)
  3356. testRequires(c, DaemonIsLinux)
  3357. name := "testbuildenvusage"
  3358. dockerfile := `FROM busybox
  3359. ENV HOME /root
  3360. ENV PATH $HOME/bin:$PATH
  3361. ENV PATH /tmp:$PATH
  3362. RUN [ "$PATH" = "/tmp:$HOME/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ]
  3363. ENV FOO /foo/baz
  3364. ENV BAR /bar
  3365. ENV BAZ $BAR
  3366. ENV FOOPATH $PATH:$FOO
  3367. RUN [ "$BAR" = "$BAZ" ]
  3368. RUN [ "$FOOPATH" = "$PATH:/foo/baz" ]
  3369. ENV FROM hello/docker/world
  3370. ENV TO /docker/world/hello
  3371. ADD $FROM $TO
  3372. RUN [ "$(cat $TO)" = "hello" ]
  3373. ENV abc=def
  3374. ENV ghi=$abc
  3375. RUN [ "$ghi" = "def" ]
  3376. `
  3377. ctx, err := fakeContext(dockerfile, map[string]string{
  3378. "hello/docker/world": "hello",
  3379. })
  3380. if err != nil {
  3381. c.Fatal(err)
  3382. }
  3383. defer ctx.Close()
  3384. _, err = buildImageFromContext(name, ctx, true)
  3385. if err != nil {
  3386. c.Fatal(err)
  3387. }
  3388. }
  3389. func (s *DockerSuite) TestBuildEnvUsage2(c *check.C) {
  3390. // /docker/world/hello is not owned by the correct user
  3391. testRequires(c, NotUserNamespace)
  3392. testRequires(c, DaemonIsLinux)
  3393. name := "testbuildenvusage2"
  3394. dockerfile := `FROM busybox
  3395. ENV abc=def def="hello world"
  3396. RUN [ "$abc,$def" = "def,hello world" ]
  3397. ENV def=hello\ world v1=abc v2="hi there" v3='boogie nights' v4="with'quotes too"
  3398. RUN [ "$def,$v1,$v2,$v3,$v4" = "hello world,abc,hi there,boogie nights,with'quotes too" ]
  3399. ENV abc=zzz FROM=hello/docker/world
  3400. ENV abc=zzz TO=/docker/world/hello
  3401. ADD $FROM $TO
  3402. RUN [ "$abc,$(cat $TO)" = "zzz,hello" ]
  3403. ENV abc 'yyy'
  3404. RUN [ $abc = 'yyy' ]
  3405. ENV abc=
  3406. RUN [ "$abc" = "" ]
  3407. # use grep to make sure if the builder substitutes \$foo by mistake
  3408. # we don't get a false positive
  3409. ENV abc=\$foo
  3410. RUN [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3411. ENV abc \$foo
  3412. RUN [ "$abc" = "\$foo" ] && (echo "$abc" | grep foo)
  3413. ENV abc=\'foo\' abc2=\"foo\"
  3414. RUN [ "$abc,$abc2" = "'foo',\"foo\"" ]
  3415. ENV abc "foo"
  3416. RUN [ "$abc" = "foo" ]
  3417. ENV abc 'foo'
  3418. RUN [ "$abc" = 'foo' ]
  3419. ENV abc \'foo\'
  3420. RUN [ "$abc" = "'foo'" ]
  3421. ENV abc \"foo\"
  3422. RUN [ "$abc" = '"foo"' ]
  3423. ENV abc=ABC
  3424. RUN [ "$abc" = "ABC" ]
  3425. ENV def1=${abc:-DEF} def2=${ccc:-DEF}
  3426. ENV def3=${ccc:-${def2}xx} def4=${abc:+ALT} def5=${def2:+${abc}:} def6=${ccc:-\$abc:} def7=${ccc:-\${abc}:}
  3427. RUN [ "$def1,$def2,$def3,$def4,$def5,$def6,$def7" = 'ABC,DEF,DEFxx,ALT,ABC:,$abc:,${abc:}' ]
  3428. ENV mypath=${mypath:+$mypath:}/home
  3429. ENV mypath=${mypath:+$mypath:}/away
  3430. RUN [ "$mypath" = '/home:/away' ]
  3431. ENV e1=bar
  3432. ENV e2=$e1 e3=$e11 e4=\$e1 e5=\$e11
  3433. RUN [ "$e0,$e1,$e2,$e3,$e4,$e5" = ',bar,bar,,$e1,$e11' ]
  3434. ENV ee1 bar
  3435. ENV ee2 $ee1
  3436. ENV ee3 $ee11
  3437. ENV ee4 \$ee1
  3438. ENV ee5 \$ee11
  3439. RUN [ "$ee1,$ee2,$ee3,$ee4,$ee5" = 'bar,bar,,$ee1,$ee11' ]
  3440. ENV eee1="foo" eee2='foo'
  3441. ENV eee3 "foo"
  3442. ENV eee4 'foo'
  3443. RUN [ "$eee1,$eee2,$eee3,$eee4" = 'foo,foo,foo,foo' ]
  3444. `
  3445. ctx, err := fakeContext(dockerfile, map[string]string{
  3446. "hello/docker/world": "hello",
  3447. })
  3448. if err != nil {
  3449. c.Fatal(err)
  3450. }
  3451. defer ctx.Close()
  3452. _, err = buildImageFromContext(name, ctx, true)
  3453. if err != nil {
  3454. c.Fatal(err)
  3455. }
  3456. }
  3457. func (s *DockerSuite) TestBuildAddScript(c *check.C) {
  3458. testRequires(c, DaemonIsLinux)
  3459. name := "testbuildaddscript"
  3460. dockerfile := `
  3461. FROM busybox
  3462. ADD test /test
  3463. RUN ["chmod","+x","/test"]
  3464. RUN ["/test"]
  3465. RUN [ "$(cat /testfile)" = 'test!' ]`
  3466. ctx, err := fakeContext(dockerfile, map[string]string{
  3467. "test": "#!/bin/sh\necho 'test!' > /testfile",
  3468. })
  3469. if err != nil {
  3470. c.Fatal(err)
  3471. }
  3472. defer ctx.Close()
  3473. _, err = buildImageFromContext(name, ctx, true)
  3474. if err != nil {
  3475. c.Fatal(err)
  3476. }
  3477. }
  3478. func (s *DockerSuite) TestBuildAddTar(c *check.C) {
  3479. // /test/foo is not owned by the correct user
  3480. testRequires(c, NotUserNamespace)
  3481. testRequires(c, DaemonIsLinux)
  3482. name := "testbuildaddtar"
  3483. ctx := func() *FakeContext {
  3484. dockerfile := `
  3485. FROM busybox
  3486. ADD test.tar /
  3487. RUN cat /test/foo | grep Hi
  3488. ADD test.tar /test.tar
  3489. RUN cat /test.tar/test/foo | grep Hi
  3490. ADD test.tar /unlikely-to-exist
  3491. RUN cat /unlikely-to-exist/test/foo | grep Hi
  3492. ADD test.tar /unlikely-to-exist-trailing-slash/
  3493. RUN cat /unlikely-to-exist-trailing-slash/test/foo | grep Hi
  3494. RUN mkdir /existing-directory
  3495. ADD test.tar /existing-directory
  3496. RUN cat /existing-directory/test/foo | grep Hi
  3497. ADD test.tar /existing-directory-trailing-slash/
  3498. RUN cat /existing-directory-trailing-slash/test/foo | grep Hi`
  3499. tmpDir, err := ioutil.TempDir("", "fake-context")
  3500. c.Assert(err, check.IsNil)
  3501. testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3502. if err != nil {
  3503. c.Fatalf("failed to create test.tar archive: %v", err)
  3504. }
  3505. defer testTar.Close()
  3506. tw := tar.NewWriter(testTar)
  3507. if err := tw.WriteHeader(&tar.Header{
  3508. Name: "test/foo",
  3509. Size: 2,
  3510. }); err != nil {
  3511. c.Fatalf("failed to write tar file header: %v", err)
  3512. }
  3513. if _, err := tw.Write([]byte("Hi")); err != nil {
  3514. c.Fatalf("failed to write tar file content: %v", err)
  3515. }
  3516. if err := tw.Close(); err != nil {
  3517. c.Fatalf("failed to close tar archive: %v", err)
  3518. }
  3519. if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3520. c.Fatalf("failed to open destination dockerfile: %v", err)
  3521. }
  3522. return fakeContextFromDir(tmpDir)
  3523. }()
  3524. defer ctx.Close()
  3525. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3526. c.Fatalf("build failed to complete for TestBuildAddTar: %v", err)
  3527. }
  3528. }
  3529. func (s *DockerSuite) TestBuildAddBrokenTar(c *check.C) {
  3530. testRequires(c, DaemonIsLinux)
  3531. name := "testbuildaddbrokentar"
  3532. ctx := func() *FakeContext {
  3533. dockerfile := `
  3534. FROM busybox
  3535. ADD test.tar /`
  3536. tmpDir, err := ioutil.TempDir("", "fake-context")
  3537. c.Assert(err, check.IsNil)
  3538. testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3539. if err != nil {
  3540. c.Fatalf("failed to create test.tar archive: %v", err)
  3541. }
  3542. defer testTar.Close()
  3543. tw := tar.NewWriter(testTar)
  3544. if err := tw.WriteHeader(&tar.Header{
  3545. Name: "test/foo",
  3546. Size: 2,
  3547. }); err != nil {
  3548. c.Fatalf("failed to write tar file header: %v", err)
  3549. }
  3550. if _, err := tw.Write([]byte("Hi")); err != nil {
  3551. c.Fatalf("failed to write tar file content: %v", err)
  3552. }
  3553. if err := tw.Close(); err != nil {
  3554. c.Fatalf("failed to close tar archive: %v", err)
  3555. }
  3556. // Corrupt the tar by removing one byte off the end
  3557. stat, err := testTar.Stat()
  3558. if err != nil {
  3559. c.Fatalf("failed to stat tar archive: %v", err)
  3560. }
  3561. if err := testTar.Truncate(stat.Size() - 1); err != nil {
  3562. c.Fatalf("failed to truncate tar archive: %v", err)
  3563. }
  3564. if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3565. c.Fatalf("failed to open destination dockerfile: %v", err)
  3566. }
  3567. return fakeContextFromDir(tmpDir)
  3568. }()
  3569. defer ctx.Close()
  3570. if _, err := buildImageFromContext(name, ctx, true); err == nil {
  3571. c.Fatalf("build should have failed for TestBuildAddBrokenTar")
  3572. }
  3573. }
  3574. func (s *DockerSuite) TestBuildAddNonTar(c *check.C) {
  3575. testRequires(c, DaemonIsLinux)
  3576. name := "testbuildaddnontar"
  3577. // Should not try to extract test.tar
  3578. ctx, err := fakeContext(`
  3579. FROM busybox
  3580. ADD test.tar /
  3581. RUN test -f /test.tar`,
  3582. map[string]string{"test.tar": "not_a_tar_file"})
  3583. if err != nil {
  3584. c.Fatal(err)
  3585. }
  3586. defer ctx.Close()
  3587. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3588. c.Fatalf("build failed for TestBuildAddNonTar")
  3589. }
  3590. }
  3591. func (s *DockerSuite) TestBuildAddTarXz(c *check.C) {
  3592. // /test/foo is not owned by the correct user
  3593. testRequires(c, NotUserNamespace)
  3594. testRequires(c, DaemonIsLinux)
  3595. name := "testbuildaddtarxz"
  3596. ctx := func() *FakeContext {
  3597. dockerfile := `
  3598. FROM busybox
  3599. ADD test.tar.xz /
  3600. RUN cat /test/foo | grep Hi`
  3601. tmpDir, err := ioutil.TempDir("", "fake-context")
  3602. c.Assert(err, check.IsNil)
  3603. testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3604. if err != nil {
  3605. c.Fatalf("failed to create test.tar archive: %v", err)
  3606. }
  3607. defer testTar.Close()
  3608. tw := tar.NewWriter(testTar)
  3609. if err := tw.WriteHeader(&tar.Header{
  3610. Name: "test/foo",
  3611. Size: 2,
  3612. }); err != nil {
  3613. c.Fatalf("failed to write tar file header: %v", err)
  3614. }
  3615. if _, err := tw.Write([]byte("Hi")); err != nil {
  3616. c.Fatalf("failed to write tar file content: %v", err)
  3617. }
  3618. if err := tw.Close(); err != nil {
  3619. c.Fatalf("failed to close tar archive: %v", err)
  3620. }
  3621. xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  3622. xzCompressCmd.Dir = tmpDir
  3623. out, _, err := runCommandWithOutput(xzCompressCmd)
  3624. if err != nil {
  3625. c.Fatal(err, out)
  3626. }
  3627. if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3628. c.Fatalf("failed to open destination dockerfile: %v", err)
  3629. }
  3630. return fakeContextFromDir(tmpDir)
  3631. }()
  3632. defer ctx.Close()
  3633. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3634. c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  3635. }
  3636. }
  3637. func (s *DockerSuite) TestBuildAddTarXzGz(c *check.C) {
  3638. testRequires(c, DaemonIsLinux)
  3639. name := "testbuildaddtarxzgz"
  3640. ctx := func() *FakeContext {
  3641. dockerfile := `
  3642. FROM busybox
  3643. ADD test.tar.xz.gz /
  3644. RUN ls /test.tar.xz.gz`
  3645. tmpDir, err := ioutil.TempDir("", "fake-context")
  3646. c.Assert(err, check.IsNil)
  3647. testTar, err := os.Create(filepath.Join(tmpDir, "test.tar"))
  3648. if err != nil {
  3649. c.Fatalf("failed to create test.tar archive: %v", err)
  3650. }
  3651. defer testTar.Close()
  3652. tw := tar.NewWriter(testTar)
  3653. if err := tw.WriteHeader(&tar.Header{
  3654. Name: "test/foo",
  3655. Size: 2,
  3656. }); err != nil {
  3657. c.Fatalf("failed to write tar file header: %v", err)
  3658. }
  3659. if _, err := tw.Write([]byte("Hi")); err != nil {
  3660. c.Fatalf("failed to write tar file content: %v", err)
  3661. }
  3662. if err := tw.Close(); err != nil {
  3663. c.Fatalf("failed to close tar archive: %v", err)
  3664. }
  3665. xzCompressCmd := exec.Command("xz", "-k", "test.tar")
  3666. xzCompressCmd.Dir = tmpDir
  3667. out, _, err := runCommandWithOutput(xzCompressCmd)
  3668. if err != nil {
  3669. c.Fatal(err, out)
  3670. }
  3671. gzipCompressCmd := exec.Command("gzip", "test.tar.xz")
  3672. gzipCompressCmd.Dir = tmpDir
  3673. out, _, err = runCommandWithOutput(gzipCompressCmd)
  3674. if err != nil {
  3675. c.Fatal(err, out)
  3676. }
  3677. if err := ioutil.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644); err != nil {
  3678. c.Fatalf("failed to open destination dockerfile: %v", err)
  3679. }
  3680. return fakeContextFromDir(tmpDir)
  3681. }()
  3682. defer ctx.Close()
  3683. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  3684. c.Fatalf("build failed to complete for TestBuildAddTarXz: %v", err)
  3685. }
  3686. }
  3687. func (s *DockerSuite) TestBuildFromGIT(c *check.C) {
  3688. testRequires(c, DaemonIsLinux)
  3689. name := "testbuildfromgit"
  3690. git, err := newFakeGit("repo", map[string]string{
  3691. "Dockerfile": `FROM busybox
  3692. ADD first /first
  3693. RUN [ -f /first ]
  3694. MAINTAINER docker`,
  3695. "first": "test git data",
  3696. }, true)
  3697. if err != nil {
  3698. c.Fatal(err)
  3699. }
  3700. defer git.Close()
  3701. _, err = buildImageFromPath(name, git.RepoURL, true)
  3702. if err != nil {
  3703. c.Fatal(err)
  3704. }
  3705. res := inspectField(c, name, "Author")
  3706. if res != "docker" {
  3707. c.Fatalf("Maintainer should be docker, got %s", res)
  3708. }
  3709. }
  3710. func (s *DockerSuite) TestBuildFromGITWithContext(c *check.C) {
  3711. testRequires(c, DaemonIsLinux)
  3712. name := "testbuildfromgit"
  3713. git, err := newFakeGit("repo", map[string]string{
  3714. "docker/Dockerfile": `FROM busybox
  3715. ADD first /first
  3716. RUN [ -f /first ]
  3717. MAINTAINER docker`,
  3718. "docker/first": "test git data",
  3719. }, true)
  3720. if err != nil {
  3721. c.Fatal(err)
  3722. }
  3723. defer git.Close()
  3724. u := fmt.Sprintf("%s#master:docker", git.RepoURL)
  3725. _, err = buildImageFromPath(name, u, true)
  3726. if err != nil {
  3727. c.Fatal(err)
  3728. }
  3729. res := inspectField(c, name, "Author")
  3730. if res != "docker" {
  3731. c.Fatalf("Maintainer should be docker, got %s", res)
  3732. }
  3733. }
  3734. func (s *DockerSuite) TestBuildFromGITwithF(c *check.C) {
  3735. testRequires(c, DaemonIsLinux)
  3736. name := "testbuildfromgitwithf"
  3737. git, err := newFakeGit("repo", map[string]string{
  3738. "myApp/myDockerfile": `FROM busybox
  3739. RUN echo hi from Dockerfile`,
  3740. }, true)
  3741. if err != nil {
  3742. c.Fatal(err)
  3743. }
  3744. defer git.Close()
  3745. out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", "myApp/myDockerfile", git.RepoURL)
  3746. if err != nil {
  3747. c.Fatalf("Error on build. Out: %s\nErr: %v", out, err)
  3748. }
  3749. if !strings.Contains(out, "hi from Dockerfile") {
  3750. c.Fatalf("Missing expected output, got:\n%s", out)
  3751. }
  3752. }
  3753. func (s *DockerSuite) TestBuildFromRemoteTarball(c *check.C) {
  3754. testRequires(c, DaemonIsLinux)
  3755. name := "testbuildfromremotetarball"
  3756. buffer := new(bytes.Buffer)
  3757. tw := tar.NewWriter(buffer)
  3758. defer tw.Close()
  3759. dockerfile := []byte(`FROM busybox
  3760. MAINTAINER docker`)
  3761. if err := tw.WriteHeader(&tar.Header{
  3762. Name: "Dockerfile",
  3763. Size: int64(len(dockerfile)),
  3764. }); err != nil {
  3765. c.Fatalf("failed to write tar file header: %v", err)
  3766. }
  3767. if _, err := tw.Write(dockerfile); err != nil {
  3768. c.Fatalf("failed to write tar file content: %v", err)
  3769. }
  3770. if err := tw.Close(); err != nil {
  3771. c.Fatalf("failed to close tar archive: %v", err)
  3772. }
  3773. server, err := fakeBinaryStorage(map[string]*bytes.Buffer{
  3774. "testT.tar": buffer,
  3775. })
  3776. c.Assert(err, check.IsNil)
  3777. defer server.Close()
  3778. _, err = buildImageFromPath(name, server.URL()+"/testT.tar", true)
  3779. c.Assert(err, check.IsNil)
  3780. res := inspectField(c, name, "Author")
  3781. if res != "docker" {
  3782. c.Fatalf("Maintainer should be docker, got %s", res)
  3783. }
  3784. }
  3785. func (s *DockerSuite) TestBuildCleanupCmdOnEntrypoint(c *check.C) {
  3786. testRequires(c, DaemonIsLinux)
  3787. name := "testbuildcmdcleanuponentrypoint"
  3788. if _, err := buildImage(name,
  3789. `FROM scratch
  3790. CMD ["test"]
  3791. ENTRYPOINT ["echo"]`,
  3792. true); err != nil {
  3793. c.Fatal(err)
  3794. }
  3795. if _, err := buildImage(name,
  3796. fmt.Sprintf(`FROM %s
  3797. ENTRYPOINT ["cat"]`, name),
  3798. true); err != nil {
  3799. c.Fatal(err)
  3800. }
  3801. res := inspectField(c, name, "Config.Cmd")
  3802. if res != "<nil>" {
  3803. c.Fatalf("Cmd %s, expected nil", res)
  3804. }
  3805. res = inspectField(c, name, "Config.Entrypoint")
  3806. if expected := "{[cat]}"; res != expected {
  3807. c.Fatalf("Entrypoint %s, expected %s", res, expected)
  3808. }
  3809. }
  3810. func (s *DockerSuite) TestBuildClearCmd(c *check.C) {
  3811. testRequires(c, DaemonIsLinux)
  3812. name := "testbuildclearcmd"
  3813. _, err := buildImage(name,
  3814. `From scratch
  3815. ENTRYPOINT ["/bin/bash"]
  3816. CMD []`,
  3817. true)
  3818. if err != nil {
  3819. c.Fatal(err)
  3820. }
  3821. res := inspectFieldJSON(c, name, "Config.Cmd")
  3822. if res != "[]" {
  3823. c.Fatalf("Cmd %s, expected %s", res, "[]")
  3824. }
  3825. }
  3826. func (s *DockerSuite) TestBuildEmptyCmd(c *check.C) {
  3827. testRequires(c, DaemonIsLinux)
  3828. name := "testbuildemptycmd"
  3829. if _, err := buildImage(name, "FROM scratch\nMAINTAINER quux\n", true); err != nil {
  3830. c.Fatal(err)
  3831. }
  3832. res := inspectFieldJSON(c, name, "Config.Cmd")
  3833. if res != "null" {
  3834. c.Fatalf("Cmd %s, expected %s", res, "null")
  3835. }
  3836. }
  3837. func (s *DockerSuite) TestBuildOnBuildOutput(c *check.C) {
  3838. testRequires(c, DaemonIsLinux)
  3839. name := "testbuildonbuildparent"
  3840. if _, err := buildImage(name, "FROM busybox\nONBUILD RUN echo foo\n", true); err != nil {
  3841. c.Fatal(err)
  3842. }
  3843. _, out, err := buildImageWithOut(name, "FROM "+name+"\nMAINTAINER quux\n", true)
  3844. if err != nil {
  3845. c.Fatal(err)
  3846. }
  3847. if !strings.Contains(out, "# Executing 1 build trigger") {
  3848. c.Fatal("failed to find the build trigger output", out)
  3849. }
  3850. }
  3851. func (s *DockerSuite) TestBuildInvalidTag(c *check.C) {
  3852. testRequires(c, DaemonIsLinux)
  3853. name := "abcd:" + stringutils.GenerateRandomAlphaOnlyString(200)
  3854. _, out, err := buildImageWithOut(name, "FROM scratch\nMAINTAINER quux\n", true)
  3855. // if the error doesn't check for illegal tag name, or the image is built
  3856. // then this should fail
  3857. if !strings.Contains(out, "Error parsing reference") || strings.Contains(out, "Sending build context to Docker daemon") {
  3858. c.Fatalf("failed to stop before building. Error: %s, Output: %s", err, out)
  3859. }
  3860. }
  3861. func (s *DockerSuite) TestBuildCmdShDashC(c *check.C) {
  3862. testRequires(c, DaemonIsLinux)
  3863. name := "testbuildcmdshc"
  3864. if _, err := buildImage(name, "FROM busybox\nCMD echo cmd\n", true); err != nil {
  3865. c.Fatal(err)
  3866. }
  3867. res := inspectFieldJSON(c, name, "Config.Cmd")
  3868. expected := `["/bin/sh","-c","echo cmd"]`
  3869. if res != expected {
  3870. c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  3871. }
  3872. }
  3873. func (s *DockerSuite) TestBuildCmdSpaces(c *check.C) {
  3874. testRequires(c, DaemonIsLinux)
  3875. // Test to make sure that when we strcat arrays we take into account
  3876. // the arg separator to make sure ["echo","hi"] and ["echo hi"] don't
  3877. // look the same
  3878. name := "testbuildcmdspaces"
  3879. var id1 string
  3880. var id2 string
  3881. var err error
  3882. if id1, err = buildImage(name, "FROM busybox\nCMD [\"echo hi\"]\n", true); err != nil {
  3883. c.Fatal(err)
  3884. }
  3885. if id2, err = buildImage(name, "FROM busybox\nCMD [\"echo\", \"hi\"]\n", true); err != nil {
  3886. c.Fatal(err)
  3887. }
  3888. if id1 == id2 {
  3889. c.Fatal("Should not have resulted in the same CMD")
  3890. }
  3891. // Now do the same with ENTRYPOINT
  3892. if id1, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo hi\"]\n", true); err != nil {
  3893. c.Fatal(err)
  3894. }
  3895. if id2, err = buildImage(name, "FROM busybox\nENTRYPOINT [\"echo\", \"hi\"]\n", true); err != nil {
  3896. c.Fatal(err)
  3897. }
  3898. if id1 == id2 {
  3899. c.Fatal("Should not have resulted in the same ENTRYPOINT")
  3900. }
  3901. }
  3902. func (s *DockerSuite) TestBuildCmdJSONNoShDashC(c *check.C) {
  3903. testRequires(c, DaemonIsLinux)
  3904. name := "testbuildcmdjson"
  3905. if _, err := buildImage(name, "FROM busybox\nCMD [\"echo\", \"cmd\"]", true); err != nil {
  3906. c.Fatal(err)
  3907. }
  3908. res := inspectFieldJSON(c, name, "Config.Cmd")
  3909. expected := `["echo","cmd"]`
  3910. if res != expected {
  3911. c.Fatalf("Expected value %s not in Config.Cmd: %s", expected, res)
  3912. }
  3913. }
  3914. func (s *DockerSuite) TestBuildErrorInvalidInstruction(c *check.C) {
  3915. testRequires(c, DaemonIsLinux)
  3916. name := "testbuildignoreinvalidinstruction"
  3917. out, _, err := buildImageWithOut(name, "FROM busybox\nfoo bar", true)
  3918. if err == nil {
  3919. c.Fatalf("Should have failed: %s", out)
  3920. }
  3921. }
  3922. func (s *DockerSuite) TestBuildEntrypointInheritance(c *check.C) {
  3923. testRequires(c, DaemonIsLinux)
  3924. if _, err := buildImage("parent", `
  3925. FROM busybox
  3926. ENTRYPOINT exit 130
  3927. `, true); err != nil {
  3928. c.Fatal(err)
  3929. }
  3930. if _, status, _ := dockerCmdWithError("run", "parent"); status != 130 {
  3931. c.Fatalf("expected exit code 130 but received %d", status)
  3932. }
  3933. if _, err := buildImage("child", `
  3934. FROM parent
  3935. ENTRYPOINT exit 5
  3936. `, true); err != nil {
  3937. c.Fatal(err)
  3938. }
  3939. if _, status, _ := dockerCmdWithError("run", "child"); status != 5 {
  3940. c.Fatalf("expected exit code 5 but received %d", status)
  3941. }
  3942. }
  3943. func (s *DockerSuite) TestBuildEntrypointInheritanceInspect(c *check.C) {
  3944. testRequires(c, DaemonIsLinux)
  3945. var (
  3946. name = "testbuildepinherit"
  3947. name2 = "testbuildepinherit2"
  3948. expected = `["/bin/sh","-c","echo quux"]`
  3949. )
  3950. if _, err := buildImage(name, "FROM busybox\nENTRYPOINT /foo/bar", true); err != nil {
  3951. c.Fatal(err)
  3952. }
  3953. if _, err := buildImage(name2, fmt.Sprintf("FROM %s\nENTRYPOINT echo quux", name), true); err != nil {
  3954. c.Fatal(err)
  3955. }
  3956. res := inspectFieldJSON(c, name2, "Config.Entrypoint")
  3957. if res != expected {
  3958. c.Fatalf("Expected value %s not in Config.Entrypoint: %s", expected, res)
  3959. }
  3960. out, _ := dockerCmd(c, "run", "-t", name2)
  3961. expected = "quux"
  3962. if strings.TrimSpace(out) != expected {
  3963. c.Fatalf("Expected output is %s, got %s", expected, out)
  3964. }
  3965. }
  3966. func (s *DockerSuite) TestBuildRunShEntrypoint(c *check.C) {
  3967. testRequires(c, DaemonIsLinux)
  3968. name := "testbuildentrypoint"
  3969. _, err := buildImage(name,
  3970. `FROM busybox
  3971. ENTRYPOINT /bin/echo`,
  3972. true)
  3973. if err != nil {
  3974. c.Fatal(err)
  3975. }
  3976. dockerCmd(c, "run", "--rm", name)
  3977. }
  3978. func (s *DockerSuite) TestBuildExoticShellInterpolation(c *check.C) {
  3979. testRequires(c, DaemonIsLinux)
  3980. name := "testbuildexoticshellinterpolation"
  3981. _, err := buildImage(name, `
  3982. FROM busybox
  3983. ENV SOME_VAR a.b.c
  3984. RUN [ "$SOME_VAR" = 'a.b.c' ]
  3985. RUN [ "${SOME_VAR}" = 'a.b.c' ]
  3986. RUN [ "${SOME_VAR%.*}" = 'a.b' ]
  3987. RUN [ "${SOME_VAR%%.*}" = 'a' ]
  3988. RUN [ "${SOME_VAR#*.}" = 'b.c' ]
  3989. RUN [ "${SOME_VAR##*.}" = 'c' ]
  3990. RUN [ "${SOME_VAR/c/d}" = 'a.b.d' ]
  3991. RUN [ "${#SOME_VAR}" = '5' ]
  3992. RUN [ "${SOME_UNSET_VAR:-$SOME_VAR}" = 'a.b.c' ]
  3993. RUN [ "${SOME_VAR:+Version: ${SOME_VAR}}" = 'Version: a.b.c' ]
  3994. RUN [ "${SOME_UNSET_VAR:+${SOME_VAR}}" = '' ]
  3995. RUN [ "${SOME_UNSET_VAR:-${SOME_VAR:-d.e.f}}" = 'a.b.c' ]
  3996. `, false)
  3997. if err != nil {
  3998. c.Fatal(err)
  3999. }
  4000. }
  4001. func (s *DockerSuite) TestBuildVerifySingleQuoteFails(c *check.C) {
  4002. testRequires(c, DaemonIsLinux)
  4003. // This testcase is supposed to generate an error because the
  4004. // JSON array we're passing in on the CMD uses single quotes instead
  4005. // of double quotes (per the JSON spec). This means we interpret it
  4006. // as a "string" instead of "JSON array" and pass it on to "sh -c" and
  4007. // it should barf on it.
  4008. name := "testbuildsinglequotefails"
  4009. if _, err := buildImage(name,
  4010. `FROM busybox
  4011. CMD [ '/bin/sh', '-c', 'echo hi' ]`,
  4012. true); err != nil {
  4013. c.Fatal(err)
  4014. }
  4015. if _, _, err := dockerCmdWithError("run", "--rm", name); err == nil {
  4016. c.Fatal("The image was not supposed to be able to run")
  4017. }
  4018. }
  4019. func (s *DockerSuite) TestBuildVerboseOut(c *check.C) {
  4020. testRequires(c, DaemonIsLinux)
  4021. name := "testbuildverboseout"
  4022. _, out, err := buildImageWithOut(name,
  4023. `FROM busybox
  4024. RUN echo 123`,
  4025. false)
  4026. if err != nil {
  4027. c.Fatal(err)
  4028. }
  4029. if !strings.Contains(out, "\n123\n") {
  4030. c.Fatalf("Output should contain %q: %q", "123", out)
  4031. }
  4032. }
  4033. func (s *DockerSuite) TestBuildWithTabs(c *check.C) {
  4034. testRequires(c, DaemonIsLinux)
  4035. name := "testbuildwithtabs"
  4036. _, err := buildImage(name,
  4037. "FROM busybox\nRUN echo\tone\t\ttwo", true)
  4038. if err != nil {
  4039. c.Fatal(err)
  4040. }
  4041. res := inspectFieldJSON(c, name, "ContainerConfig.Cmd")
  4042. expected1 := `["/bin/sh","-c","echo\tone\t\ttwo"]`
  4043. expected2 := `["/bin/sh","-c","echo\u0009one\u0009\u0009two"]` // syntactically equivalent, and what Go 1.3 generates
  4044. if res != expected1 && res != expected2 {
  4045. c.Fatalf("Missing tabs.\nGot: %s\nExp: %s or %s", res, expected1, expected2)
  4046. }
  4047. }
  4048. func (s *DockerSuite) TestBuildLabels(c *check.C) {
  4049. testRequires(c, DaemonIsLinux)
  4050. name := "testbuildlabel"
  4051. expected := `{"License":"GPL","Vendor":"Acme"}`
  4052. _, err := buildImage(name,
  4053. `FROM busybox
  4054. LABEL Vendor=Acme
  4055. LABEL License GPL`,
  4056. true)
  4057. if err != nil {
  4058. c.Fatal(err)
  4059. }
  4060. res := inspectFieldJSON(c, name, "Config.Labels")
  4061. if res != expected {
  4062. c.Fatalf("Labels %s, expected %s", res, expected)
  4063. }
  4064. }
  4065. func (s *DockerSuite) TestBuildLabelsCache(c *check.C) {
  4066. testRequires(c, DaemonIsLinux)
  4067. name := "testbuildlabelcache"
  4068. id1, err := buildImage(name,
  4069. `FROM busybox
  4070. LABEL Vendor=Acme`, false)
  4071. if err != nil {
  4072. c.Fatalf("Build 1 should have worked: %v", err)
  4073. }
  4074. id2, err := buildImage(name,
  4075. `FROM busybox
  4076. LABEL Vendor=Acme`, true)
  4077. if err != nil || id1 != id2 {
  4078. c.Fatalf("Build 2 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4079. }
  4080. id2, err = buildImage(name,
  4081. `FROM busybox
  4082. LABEL Vendor=Acme1`, true)
  4083. if err != nil || id1 == id2 {
  4084. c.Fatalf("Build 3 should have worked & NOT used cache(%s,%s): %v", id1, id2, err)
  4085. }
  4086. id2, err = buildImage(name,
  4087. `FROM busybox
  4088. LABEL Vendor Acme`, true) // Note: " " and "=" should be same
  4089. if err != nil || id1 != id2 {
  4090. c.Fatalf("Build 4 should have worked & used cache(%s,%s): %v", id1, id2, err)
  4091. }
  4092. // Now make sure the cache isn't used by mistake
  4093. id1, err = buildImage(name,
  4094. `FROM busybox
  4095. LABEL f1=b1 f2=b2`, false)
  4096. if err != nil {
  4097. c.Fatalf("Build 5 should have worked: %q", err)
  4098. }
  4099. id2, err = buildImage(name,
  4100. `FROM busybox
  4101. LABEL f1="b1 f2=b2"`, true)
  4102. if err != nil || id1 == id2 {
  4103. c.Fatalf("Build 6 should have worked & NOT used the cache(%s,%s): %q", id1, id2, err)
  4104. }
  4105. }
  4106. func (s *DockerSuite) TestBuildNotVerboseSuccess(c *check.C) {
  4107. testRequires(c, DaemonIsLinux)
  4108. // This test makes sure that -q works correctly when build is successful:
  4109. // stdout has only the image ID (long image ID) and stderr is empty.
  4110. var stdout, stderr string
  4111. var err error
  4112. outRegexp := regexp.MustCompile("^(sha256:|)[a-z0-9]{64}\\n$")
  4113. tt := []struct {
  4114. Name string
  4115. BuildFunc func(string)
  4116. }{
  4117. {
  4118. Name: "quiet_build_stdin_success",
  4119. BuildFunc: func(name string) {
  4120. _, stdout, stderr, err = buildImageWithStdoutStderr(name, "FROM busybox", true, "-q", "--force-rm", "--rm")
  4121. },
  4122. },
  4123. {
  4124. Name: "quiet_build_ctx_success",
  4125. BuildFunc: func(name string) {
  4126. ctx, err := fakeContext("FROM busybox", map[string]string{
  4127. "quiet_build_success_fctx": "test",
  4128. })
  4129. if err != nil {
  4130. c.Fatalf("Failed to create context: %s", err.Error())
  4131. }
  4132. defer ctx.Close()
  4133. _, stdout, stderr, err = buildImageFromContextWithStdoutStderr(name, ctx, true, "-q", "--force-rm", "--rm")
  4134. },
  4135. },
  4136. {
  4137. Name: "quiet_build_git_success",
  4138. BuildFunc: func(name string) {
  4139. git, err := newFakeGit("repo", map[string]string{
  4140. "Dockerfile": "FROM busybox",
  4141. }, true)
  4142. if err != nil {
  4143. c.Fatalf("Failed to create the git repo: %s", err.Error())
  4144. }
  4145. defer git.Close()
  4146. _, stdout, stderr, err = buildImageFromGitWithStdoutStderr(name, git, true, "-q", "--force-rm", "--rm")
  4147. },
  4148. },
  4149. }
  4150. for _, te := range tt {
  4151. te.BuildFunc(te.Name)
  4152. if err != nil {
  4153. c.Fatalf("Test %s shouldn't fail, but got the following error: %s", te.Name, err.Error())
  4154. }
  4155. if outRegexp.Find([]byte(stdout)) == nil {
  4156. c.Fatalf("Test %s expected stdout to match the [%v] regexp, but it is [%v]", te.Name, outRegexp, stdout)
  4157. }
  4158. if runtime.GOOS == "windows" {
  4159. // stderr contains a security warning on Windows if the daemon isn't Windows
  4160. lines := strings.Split(stderr, "\n")
  4161. warningCount := 0
  4162. for _, v := range lines {
  4163. warningText := "SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host."
  4164. if strings.Contains(v, warningText) {
  4165. warningCount++
  4166. }
  4167. if v != "" && !strings.Contains(v, warningText) {
  4168. c.Fatalf("Stderr contains unexpected output line: %q", v)
  4169. }
  4170. }
  4171. if warningCount != 1 && daemonPlatform != "windows" {
  4172. c.Fatalf("Test %s didn't get security warning running from Windows to non-Windows", te.Name)
  4173. }
  4174. } else {
  4175. if stderr != "" {
  4176. c.Fatalf("Test %s expected stderr to be empty, but it is [%#v]", te.Name, stderr)
  4177. }
  4178. }
  4179. }
  4180. }
  4181. func (s *DockerSuite) TestBuildNotVerboseFailure(c *check.C) {
  4182. testRequires(c, DaemonIsLinux)
  4183. // This test makes sure that -q works correctly when build fails by
  4184. // comparing between the stderr output in quiet mode and in stdout
  4185. // and stderr output in verbose mode
  4186. tt := []struct {
  4187. TestName string
  4188. BuildCmds string
  4189. }{
  4190. {"quiet_build_no_from_at_the_beginning", "RUN whoami"},
  4191. {"quiet_build_unknown_instr", "FROMD busybox"},
  4192. {"quiet_build_not_exists_image", "FROM busybox11"},
  4193. }
  4194. for _, te := range tt {
  4195. _, _, qstderr, qerr := buildImageWithStdoutStderr(te.TestName, te.BuildCmds, false, "-q", "--force-rm", "--rm")
  4196. _, vstdout, vstderr, verr := buildImageWithStdoutStderr(te.TestName, te.BuildCmds, false, "--force-rm", "--rm")
  4197. if verr == nil || qerr == nil {
  4198. c.Fatal(fmt.Errorf("Test [%s] expected to fail but didn't", te.TestName))
  4199. }
  4200. if qstderr != vstdout+vstderr {
  4201. c.Fatal(fmt.Errorf("Test[%s] expected that quiet stderr and verbose stdout are equal; quiet [%v], verbose [%v]", te.TestName, qstderr, vstdout))
  4202. }
  4203. }
  4204. }
  4205. func (s *DockerSuite) TestBuildNotVerboseFailureRemote(c *check.C) {
  4206. testRequires(c, DaemonIsLinux)
  4207. // This test ensures that when given a wrong URL, stderr in quiet mode and
  4208. // stdout and stderr in verbose mode are identical.
  4209. URL := "http://bla.bla.com"
  4210. Name := "quiet_build_wrong_remote"
  4211. _, _, qstderr, qerr := buildImageWithStdoutStderr(Name, "", false, "-q", "--force-rm", "--rm", URL)
  4212. _, vstdout, vstderr, verr := buildImageWithStdoutStderr(Name, "", false, "--force-rm", "--rm", URL)
  4213. if qerr == nil || verr == nil {
  4214. c.Fatal(fmt.Errorf("Test [%s] expected to fail but didn't", Name))
  4215. }
  4216. if qstderr != vstdout+vstderr {
  4217. c.Fatal(fmt.Errorf("Test[%s] expected that quiet stderr and verbose stdout are equal; quiet [%v], verbose [%v]", Name, qstderr, vstdout))
  4218. }
  4219. }
  4220. func (s *DockerSuite) TestBuildStderr(c *check.C) {
  4221. testRequires(c, DaemonIsLinux)
  4222. // This test just makes sure that no non-error output goes
  4223. // to stderr
  4224. name := "testbuildstderr"
  4225. _, _, stderr, err := buildImageWithStdoutStderr(name,
  4226. "FROM busybox\nRUN echo one", true)
  4227. if err != nil {
  4228. c.Fatal(err)
  4229. }
  4230. if runtime.GOOS == "windows" {
  4231. // stderr might contain a security warning on windows
  4232. lines := strings.Split(stderr, "\n")
  4233. for _, v := range lines {
  4234. if v != "" && !strings.Contains(v, "SECURITY WARNING:") {
  4235. c.Fatalf("Stderr contains unexpected output line: %q", v)
  4236. }
  4237. }
  4238. } else {
  4239. if stderr != "" {
  4240. c.Fatalf("Stderr should have been empty, instead its: %q", stderr)
  4241. }
  4242. }
  4243. }
  4244. func (s *DockerSuite) TestBuildChownSingleFile(c *check.C) {
  4245. testRequires(c, UnixCli) // test uses chown: not available on windows
  4246. testRequires(c, DaemonIsLinux)
  4247. name := "testbuildchownsinglefile"
  4248. ctx, err := fakeContext(`
  4249. FROM busybox
  4250. COPY test /
  4251. RUN ls -l /test
  4252. RUN [ $(ls -l /test | awk '{print $3":"$4}') = 'root:root' ]
  4253. `, map[string]string{
  4254. "test": "test",
  4255. })
  4256. if err != nil {
  4257. c.Fatal(err)
  4258. }
  4259. defer ctx.Close()
  4260. if err := os.Chown(filepath.Join(ctx.Dir, "test"), 4242, 4242); err != nil {
  4261. c.Fatal(err)
  4262. }
  4263. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4264. c.Fatal(err)
  4265. }
  4266. }
  4267. func (s *DockerSuite) TestBuildSymlinkBreakout(c *check.C) {
  4268. testRequires(c, DaemonIsLinux)
  4269. name := "testbuildsymlinkbreakout"
  4270. tmpdir, err := ioutil.TempDir("", name)
  4271. c.Assert(err, check.IsNil)
  4272. defer os.RemoveAll(tmpdir)
  4273. ctx := filepath.Join(tmpdir, "context")
  4274. if err := os.MkdirAll(ctx, 0755); err != nil {
  4275. c.Fatal(err)
  4276. }
  4277. if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte(`
  4278. from busybox
  4279. add symlink.tar /
  4280. add inject /symlink/
  4281. `), 0644); err != nil {
  4282. c.Fatal(err)
  4283. }
  4284. inject := filepath.Join(ctx, "inject")
  4285. if err := ioutil.WriteFile(inject, nil, 0644); err != nil {
  4286. c.Fatal(err)
  4287. }
  4288. f, err := os.Create(filepath.Join(ctx, "symlink.tar"))
  4289. if err != nil {
  4290. c.Fatal(err)
  4291. }
  4292. w := tar.NewWriter(f)
  4293. w.WriteHeader(&tar.Header{
  4294. Name: "symlink2",
  4295. Typeflag: tar.TypeSymlink,
  4296. Linkname: "/../../../../../../../../../../../../../../",
  4297. Uid: os.Getuid(),
  4298. Gid: os.Getgid(),
  4299. })
  4300. w.WriteHeader(&tar.Header{
  4301. Name: "symlink",
  4302. Typeflag: tar.TypeSymlink,
  4303. Linkname: filepath.Join("symlink2", tmpdir),
  4304. Uid: os.Getuid(),
  4305. Gid: os.Getgid(),
  4306. })
  4307. w.Close()
  4308. f.Close()
  4309. if _, err := buildImageFromContext(name, fakeContextFromDir(ctx), false); err != nil {
  4310. c.Fatal(err)
  4311. }
  4312. if _, err := os.Lstat(filepath.Join(tmpdir, "inject")); err == nil {
  4313. c.Fatal("symlink breakout - inject")
  4314. } else if !os.IsNotExist(err) {
  4315. c.Fatalf("unexpected error: %v", err)
  4316. }
  4317. }
  4318. func (s *DockerSuite) TestBuildXZHost(c *check.C) {
  4319. // /usr/local/sbin/xz gets permission denied for the user
  4320. testRequires(c, NotUserNamespace)
  4321. testRequires(c, DaemonIsLinux)
  4322. name := "testbuildxzhost"
  4323. ctx, err := fakeContext(`
  4324. FROM busybox
  4325. ADD xz /usr/local/sbin/
  4326. RUN chmod 755 /usr/local/sbin/xz
  4327. ADD test.xz /
  4328. RUN [ ! -e /injected ]`,
  4329. map[string]string{
  4330. "test.xz": "\xfd\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00" +
  4331. "\x21\x01\x16\x00\x00\x00\x74\x2f\xe5\xa3\x01\x00\x3f\xfd" +
  4332. "\x37\x7a\x58\x5a\x00\x00\x04\xe6\xd6\xb4\x46\x02\x00\x21",
  4333. "xz": "#!/bin/sh\ntouch /injected",
  4334. })
  4335. if err != nil {
  4336. c.Fatal(err)
  4337. }
  4338. defer ctx.Close()
  4339. if _, err := buildImageFromContext(name, ctx, true); err != nil {
  4340. c.Fatal(err)
  4341. }
  4342. }
  4343. func (s *DockerSuite) TestBuildVolumesRetainContents(c *check.C) {
  4344. // /foo/file gets permission denied for the user
  4345. testRequires(c, NotUserNamespace)
  4346. testRequires(c, DaemonIsLinux)
  4347. var (
  4348. name = "testbuildvolumescontent"
  4349. expected = "some text"
  4350. )
  4351. ctx, err := fakeContext(`
  4352. FROM busybox
  4353. COPY content /foo/file
  4354. VOLUME /foo
  4355. CMD cat /foo/file`,
  4356. map[string]string{
  4357. "content": expected,
  4358. })
  4359. if err != nil {
  4360. c.Fatal(err)
  4361. }
  4362. defer ctx.Close()
  4363. if _, err := buildImageFromContext(name, ctx, false); err != nil {
  4364. c.Fatal(err)
  4365. }
  4366. out, _ := dockerCmd(c, "run", "--rm", name)
  4367. if out != expected {
  4368. c.Fatalf("expected file contents for /foo/file to be %q but received %q", expected, out)
  4369. }
  4370. }
  4371. func (s *DockerSuite) TestBuildRenamedDockerfile(c *check.C) {
  4372. testRequires(c, DaemonIsLinux)
  4373. ctx, err := fakeContext(`FROM busybox
  4374. RUN echo from Dockerfile`,
  4375. map[string]string{
  4376. "Dockerfile": "FROM busybox\nRUN echo from Dockerfile",
  4377. "files/Dockerfile": "FROM busybox\nRUN echo from files/Dockerfile",
  4378. "files/dFile": "FROM busybox\nRUN echo from files/dFile",
  4379. "dFile": "FROM busybox\nRUN echo from dFile",
  4380. "files/dFile2": "FROM busybox\nRUN echo from files/dFile2",
  4381. })
  4382. if err != nil {
  4383. c.Fatal(err)
  4384. }
  4385. defer ctx.Close()
  4386. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4387. if err != nil {
  4388. c.Fatalf("Failed to build: %s\n%s", out, err)
  4389. }
  4390. if !strings.Contains(out, "from Dockerfile") {
  4391. c.Fatalf("test1 should have used Dockerfile, output:%s", out)
  4392. }
  4393. out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "-f", filepath.Join("files", "Dockerfile"), "-t", "test2", ".")
  4394. if err != nil {
  4395. c.Fatal(err)
  4396. }
  4397. if !strings.Contains(out, "from files/Dockerfile") {
  4398. c.Fatalf("test2 should have used files/Dockerfile, output:%s", out)
  4399. }
  4400. out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", filepath.Join("files", "dFile")), "-t", "test3", ".")
  4401. if err != nil {
  4402. c.Fatal(err)
  4403. }
  4404. if !strings.Contains(out, "from files/dFile") {
  4405. c.Fatalf("test3 should have used files/dFile, output:%s", out)
  4406. }
  4407. out, _, err = dockerCmdInDir(c, ctx.Dir, "build", "--file=dFile", "-t", "test4", ".")
  4408. if err != nil {
  4409. c.Fatal(err)
  4410. }
  4411. if !strings.Contains(out, "from dFile") {
  4412. c.Fatalf("test4 should have used dFile, output:%s", out)
  4413. }
  4414. dirWithNoDockerfile, err := ioutil.TempDir(os.TempDir(), "test5")
  4415. c.Assert(err, check.IsNil)
  4416. nonDockerfileFile := filepath.Join(dirWithNoDockerfile, "notDockerfile")
  4417. if _, err = os.Create(nonDockerfileFile); err != nil {
  4418. c.Fatal(err)
  4419. }
  4420. out, _, err = dockerCmdInDir(c, ctx.Dir, "build", fmt.Sprintf("--file=%s", nonDockerfileFile), "-t", "test5", ".")
  4421. if err == nil {
  4422. c.Fatalf("test5 was supposed to fail to find passwd")
  4423. }
  4424. if expected := fmt.Sprintf("The Dockerfile (%s) must be within the build context (.)", nonDockerfileFile); !strings.Contains(out, expected) {
  4425. c.Fatalf("wrong error messsage:%v\nexpected to contain=%v", out, expected)
  4426. }
  4427. out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test6", "..")
  4428. if err != nil {
  4429. c.Fatalf("test6 failed: %s", err)
  4430. }
  4431. if !strings.Contains(out, "from Dockerfile") {
  4432. c.Fatalf("test6 should have used root Dockerfile, output:%s", out)
  4433. }
  4434. out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join(ctx.Dir, "files", "Dockerfile"), "-t", "test7", "..")
  4435. if err != nil {
  4436. c.Fatalf("test7 failed: %s", err)
  4437. }
  4438. if !strings.Contains(out, "from files/Dockerfile") {
  4439. c.Fatalf("test7 should have used files Dockerfile, output:%s", out)
  4440. }
  4441. out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", filepath.Join("..", "Dockerfile"), "-t", "test8", ".")
  4442. if err == nil || !strings.Contains(out, "must be within the build context") {
  4443. c.Fatalf("test8 should have failed with Dockerfile out of context: %s", err)
  4444. }
  4445. tmpDir := os.TempDir()
  4446. out, _, err = dockerCmdInDir(c, tmpDir, "build", "-t", "test9", ctx.Dir)
  4447. if err != nil {
  4448. c.Fatalf("test9 - failed: %s", err)
  4449. }
  4450. if !strings.Contains(out, "from Dockerfile") {
  4451. c.Fatalf("test9 should have used root Dockerfile, output:%s", out)
  4452. }
  4453. out, _, err = dockerCmdInDir(c, filepath.Join(ctx.Dir, "files"), "build", "-f", "dFile2", "-t", "test10", ".")
  4454. if err != nil {
  4455. c.Fatalf("test10 should have worked: %s", err)
  4456. }
  4457. if !strings.Contains(out, "from files/dFile2") {
  4458. c.Fatalf("test10 should have used files/dFile2, output:%s", out)
  4459. }
  4460. }
  4461. func (s *DockerSuite) TestBuildFromMixedcaseDockerfile(c *check.C) {
  4462. testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4463. testRequires(c, DaemonIsLinux)
  4464. ctx, err := fakeContext(`FROM busybox
  4465. RUN echo from dockerfile`,
  4466. map[string]string{
  4467. "dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4468. })
  4469. if err != nil {
  4470. c.Fatal(err)
  4471. }
  4472. defer ctx.Close()
  4473. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4474. if err != nil {
  4475. c.Fatalf("Failed to build: %s\n%s", out, err)
  4476. }
  4477. if !strings.Contains(out, "from dockerfile") {
  4478. c.Fatalf("Missing proper output: %s", out)
  4479. }
  4480. }
  4481. func (s *DockerSuite) TestBuildWithTwoDockerfiles(c *check.C) {
  4482. testRequires(c, UnixCli) // Dockerfile overwrites dockerfile on windows
  4483. testRequires(c, DaemonIsLinux)
  4484. ctx, err := fakeContext(`FROM busybox
  4485. RUN echo from Dockerfile`,
  4486. map[string]string{
  4487. "dockerfile": "FROM busybox\nRUN echo from dockerfile",
  4488. })
  4489. if err != nil {
  4490. c.Fatal(err)
  4491. }
  4492. defer ctx.Close()
  4493. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-t", "test1", ".")
  4494. if err != nil {
  4495. c.Fatalf("Failed to build: %s\n%s", out, err)
  4496. }
  4497. if !strings.Contains(out, "from Dockerfile") {
  4498. c.Fatalf("Missing proper output: %s", out)
  4499. }
  4500. }
  4501. func (s *DockerSuite) TestBuildFromURLWithF(c *check.C) {
  4502. testRequires(c, DaemonIsLinux)
  4503. server, err := fakeStorage(map[string]string{"baz": `FROM busybox
  4504. RUN echo from baz
  4505. COPY * /tmp/
  4506. RUN find /tmp/`})
  4507. if err != nil {
  4508. c.Fatal(err)
  4509. }
  4510. defer server.Close()
  4511. ctx, err := fakeContext(`FROM busybox
  4512. RUN echo from Dockerfile`,
  4513. map[string]string{})
  4514. if err != nil {
  4515. c.Fatal(err)
  4516. }
  4517. defer ctx.Close()
  4518. // Make sure that -f is ignored and that we don't use the Dockerfile
  4519. // that's in the current dir
  4520. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "-f", "baz", "-t", "test1", server.URL()+"/baz")
  4521. if err != nil {
  4522. c.Fatalf("Failed to build: %s\n%s", out, err)
  4523. }
  4524. if !strings.Contains(out, "from baz") ||
  4525. strings.Contains(out, "/tmp/baz") ||
  4526. !strings.Contains(out, "/tmp/Dockerfile") {
  4527. c.Fatalf("Missing proper output: %s", out)
  4528. }
  4529. }
  4530. func (s *DockerSuite) TestBuildFromStdinWithF(c *check.C) {
  4531. testRequires(c, DaemonIsLinux)
  4532. ctx, err := fakeContext(`FROM busybox
  4533. RUN echo from Dockerfile`,
  4534. map[string]string{})
  4535. if err != nil {
  4536. c.Fatal(err)
  4537. }
  4538. defer ctx.Close()
  4539. // Make sure that -f is ignored and that we don't use the Dockerfile
  4540. // that's in the current dir
  4541. dockerCommand := exec.Command(dockerBinary, "build", "-f", "baz", "-t", "test1", "-")
  4542. dockerCommand.Dir = ctx.Dir
  4543. dockerCommand.Stdin = strings.NewReader(`FROM busybox
  4544. RUN echo from baz
  4545. COPY * /tmp/
  4546. RUN find /tmp/`)
  4547. out, status, err := runCommandWithOutput(dockerCommand)
  4548. if err != nil || status != 0 {
  4549. c.Fatalf("Error building: %s", err)
  4550. }
  4551. if !strings.Contains(out, "from baz") ||
  4552. strings.Contains(out, "/tmp/baz") ||
  4553. !strings.Contains(out, "/tmp/Dockerfile") {
  4554. c.Fatalf("Missing proper output: %s", out)
  4555. }
  4556. }
  4557. func (s *DockerSuite) TestBuildFromOfficialNames(c *check.C) {
  4558. testRequires(c, DaemonIsLinux)
  4559. name := "testbuildfromofficial"
  4560. fromNames := []string{
  4561. "busybox",
  4562. "docker.io/busybox",
  4563. "index.docker.io/busybox",
  4564. "library/busybox",
  4565. "docker.io/library/busybox",
  4566. "index.docker.io/library/busybox",
  4567. }
  4568. for idx, fromName := range fromNames {
  4569. imgName := fmt.Sprintf("%s%d", name, idx)
  4570. _, err := buildImage(imgName, "FROM "+fromName, true)
  4571. if err != nil {
  4572. c.Errorf("Build failed using FROM %s: %s", fromName, err)
  4573. }
  4574. deleteImages(imgName)
  4575. }
  4576. }
  4577. func (s *DockerSuite) TestBuildDockerfileOutsideContext(c *check.C) {
  4578. testRequires(c, UnixCli) // uses os.Symlink: not implemented in windows at the time of writing (go-1.4.2)
  4579. testRequires(c, DaemonIsLinux)
  4580. name := "testbuilddockerfileoutsidecontext"
  4581. tmpdir, err := ioutil.TempDir("", name)
  4582. c.Assert(err, check.IsNil)
  4583. defer os.RemoveAll(tmpdir)
  4584. ctx := filepath.Join(tmpdir, "context")
  4585. if err := os.MkdirAll(ctx, 0755); err != nil {
  4586. c.Fatal(err)
  4587. }
  4588. if err := ioutil.WriteFile(filepath.Join(ctx, "Dockerfile"), []byte("FROM scratch\nENV X Y"), 0644); err != nil {
  4589. c.Fatal(err)
  4590. }
  4591. wd, err := os.Getwd()
  4592. if err != nil {
  4593. c.Fatal(err)
  4594. }
  4595. defer os.Chdir(wd)
  4596. if err := os.Chdir(ctx); err != nil {
  4597. c.Fatal(err)
  4598. }
  4599. if err := ioutil.WriteFile(filepath.Join(tmpdir, "outsideDockerfile"), []byte("FROM scratch\nENV x y"), 0644); err != nil {
  4600. c.Fatal(err)
  4601. }
  4602. if err := os.Symlink(filepath.Join("..", "outsideDockerfile"), filepath.Join(ctx, "dockerfile1")); err != nil {
  4603. c.Fatal(err)
  4604. }
  4605. if err := os.Symlink(filepath.Join(tmpdir, "outsideDockerfile"), filepath.Join(ctx, "dockerfile2")); err != nil {
  4606. c.Fatal(err)
  4607. }
  4608. for _, dockerfilePath := range []string{
  4609. filepath.Join("..", "outsideDockerfile"),
  4610. filepath.Join(ctx, "dockerfile1"),
  4611. filepath.Join(ctx, "dockerfile2"),
  4612. } {
  4613. out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", dockerfilePath, ".")
  4614. if err == nil {
  4615. c.Fatalf("Expected error with %s. Out: %s", dockerfilePath, out)
  4616. }
  4617. if !strings.Contains(out, "must be within the build context") && !strings.Contains(out, "Cannot locate Dockerfile") {
  4618. c.Fatalf("Unexpected error with %s. Out: %s", dockerfilePath, out)
  4619. }
  4620. deleteImages(name)
  4621. }
  4622. os.Chdir(tmpdir)
  4623. // Path to Dockerfile should be resolved relative to working directory, not relative to context.
  4624. // There is a Dockerfile in the context, but since there is no Dockerfile in the current directory, the following should fail
  4625. out, _, err := dockerCmdWithError("build", "-t", name, "--no-cache", "-f", "Dockerfile", ctx)
  4626. if err == nil {
  4627. c.Fatalf("Expected error. Out: %s", out)
  4628. }
  4629. }
  4630. func (s *DockerSuite) TestBuildSpaces(c *check.C) {
  4631. testRequires(c, DaemonIsLinux)
  4632. // Test to make sure that leading/trailing spaces on a command
  4633. // doesn't change the error msg we get
  4634. var (
  4635. err1 error
  4636. err2 error
  4637. )
  4638. name := "testspaces"
  4639. ctx, err := fakeContext("FROM busybox\nCOPY\n",
  4640. map[string]string{
  4641. "Dockerfile": "FROM busybox\nCOPY\n",
  4642. })
  4643. if err != nil {
  4644. c.Fatal(err)
  4645. }
  4646. defer ctx.Close()
  4647. if _, err1 = buildImageFromContext(name, ctx, false); err1 == nil {
  4648. c.Fatal("Build 1 was supposed to fail, but didn't")
  4649. }
  4650. ctx.Add("Dockerfile", "FROM busybox\nCOPY ")
  4651. if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  4652. c.Fatal("Build 2 was supposed to fail, but didn't")
  4653. }
  4654. removeLogTimestamps := func(s string) string {
  4655. return regexp.MustCompile(`time="(.*?)"`).ReplaceAllString(s, `time=[TIMESTAMP]`)
  4656. }
  4657. // Skip over the times
  4658. e1 := removeLogTimestamps(err1.Error())
  4659. e2 := removeLogTimestamps(err2.Error())
  4660. // Ignore whitespace since that's what were verifying doesn't change stuff
  4661. if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  4662. c.Fatalf("Build 2's error wasn't the same as build 1's\n1:%s\n2:%s", err1, err2)
  4663. }
  4664. ctx.Add("Dockerfile", "FROM busybox\n COPY")
  4665. if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  4666. c.Fatal("Build 3 was supposed to fail, but didn't")
  4667. }
  4668. // Skip over the times
  4669. e1 = removeLogTimestamps(err1.Error())
  4670. e2 = removeLogTimestamps(err2.Error())
  4671. // Ignore whitespace since that's what were verifying doesn't change stuff
  4672. if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  4673. c.Fatalf("Build 3's error wasn't the same as build 1's\n1:%s\n3:%s", err1, err2)
  4674. }
  4675. ctx.Add("Dockerfile", "FROM busybox\n COPY ")
  4676. if _, err2 = buildImageFromContext(name, ctx, false); err2 == nil {
  4677. c.Fatal("Build 4 was supposed to fail, but didn't")
  4678. }
  4679. // Skip over the times
  4680. e1 = removeLogTimestamps(err1.Error())
  4681. e2 = removeLogTimestamps(err2.Error())
  4682. // Ignore whitespace since that's what were verifying doesn't change stuff
  4683. if strings.Replace(e1, " ", "", -1) != strings.Replace(e2, " ", "", -1) {
  4684. c.Fatalf("Build 4's error wasn't the same as build 1's\n1:%s\n4:%s", err1, err2)
  4685. }
  4686. }
  4687. func (s *DockerSuite) TestBuildSpacesWithQuotes(c *check.C) {
  4688. testRequires(c, DaemonIsLinux)
  4689. // Test to make sure that spaces in quotes aren't lost
  4690. name := "testspacesquotes"
  4691. dockerfile := `FROM busybox
  4692. RUN echo " \
  4693. foo "`
  4694. _, out, err := buildImageWithOut(name, dockerfile, false)
  4695. if err != nil {
  4696. c.Fatal("Build failed:", err)
  4697. }
  4698. expecting := "\n foo \n"
  4699. if !strings.Contains(out, expecting) {
  4700. c.Fatalf("Bad output: %q expecting to contain %q", out, expecting)
  4701. }
  4702. }
  4703. // #4393
  4704. func (s *DockerSuite) TestBuildVolumeFileExistsinContainer(c *check.C) {
  4705. testRequires(c, DaemonIsLinux)
  4706. buildCmd := exec.Command(dockerBinary, "build", "-t", "docker-test-errcreatevolumewithfile", "-")
  4707. buildCmd.Stdin = strings.NewReader(`
  4708. FROM busybox
  4709. RUN touch /foo
  4710. VOLUME /foo
  4711. `)
  4712. out, _, err := runCommandWithOutput(buildCmd)
  4713. if err == nil || !strings.Contains(out, "file exists") {
  4714. c.Fatalf("expected build to fail when file exists in container at requested volume path")
  4715. }
  4716. }
  4717. func (s *DockerSuite) TestBuildMissingArgs(c *check.C) {
  4718. testRequires(c, DaemonIsLinux)
  4719. // Test to make sure that all Dockerfile commands (except the ones listed
  4720. // in skipCmds) will generate an error if no args are provided.
  4721. // Note: INSERT is deprecated so we exclude it because of that.
  4722. skipCmds := map[string]struct{}{
  4723. "CMD": {},
  4724. "RUN": {},
  4725. "ENTRYPOINT": {},
  4726. "INSERT": {},
  4727. }
  4728. for cmd := range command.Commands {
  4729. cmd = strings.ToUpper(cmd)
  4730. if _, ok := skipCmds[cmd]; ok {
  4731. continue
  4732. }
  4733. var dockerfile string
  4734. if cmd == "FROM" {
  4735. dockerfile = cmd
  4736. } else {
  4737. // Add FROM to make sure we don't complain about it missing
  4738. dockerfile = "FROM busybox\n" + cmd
  4739. }
  4740. ctx, err := fakeContext(dockerfile, map[string]string{})
  4741. if err != nil {
  4742. c.Fatal(err)
  4743. }
  4744. defer ctx.Close()
  4745. var out string
  4746. if out, err = buildImageFromContext("args", ctx, true); err == nil {
  4747. c.Fatalf("%s was supposed to fail. Out:%s", cmd, out)
  4748. }
  4749. if !strings.Contains(err.Error(), cmd+" requires") {
  4750. c.Fatalf("%s returned the wrong type of error:%s", cmd, err)
  4751. }
  4752. }
  4753. }
  4754. func (s *DockerSuite) TestBuildEmptyScratch(c *check.C) {
  4755. testRequires(c, DaemonIsLinux)
  4756. _, out, err := buildImageWithOut("sc", "FROM scratch", true)
  4757. if err == nil {
  4758. c.Fatalf("Build was supposed to fail")
  4759. }
  4760. if !strings.Contains(out, "No image was generated") {
  4761. c.Fatalf("Wrong error message: %v", out)
  4762. }
  4763. }
  4764. func (s *DockerSuite) TestBuildDotDotFile(c *check.C) {
  4765. testRequires(c, DaemonIsLinux)
  4766. ctx, err := fakeContext("FROM busybox\n",
  4767. map[string]string{
  4768. "..gitme": "",
  4769. })
  4770. if err != nil {
  4771. c.Fatal(err)
  4772. }
  4773. defer ctx.Close()
  4774. if _, err = buildImageFromContext("sc", ctx, false); err != nil {
  4775. c.Fatalf("Build was supposed to work: %s", err)
  4776. }
  4777. }
  4778. func (s *DockerSuite) TestBuildRUNoneJSON(c *check.C) {
  4779. testRequires(c, DaemonIsLinux)
  4780. name := "testbuildrunonejson"
  4781. ctx, err := fakeContext(`FROM hello-world:frozen
  4782. RUN [ "/hello" ]`, map[string]string{})
  4783. if err != nil {
  4784. c.Fatal(err)
  4785. }
  4786. defer ctx.Close()
  4787. out, _, err := dockerCmdInDir(c, ctx.Dir, "build", "--no-cache", "-t", name, ".")
  4788. if err != nil {
  4789. c.Fatalf("failed to build the image: %s, %v", out, err)
  4790. }
  4791. if !strings.Contains(out, "Hello from Docker") {
  4792. c.Fatalf("bad output: %s", out)
  4793. }
  4794. }
  4795. func (s *DockerSuite) TestBuildEmptyStringVolume(c *check.C) {
  4796. testRequires(c, DaemonIsLinux)
  4797. name := "testbuildemptystringvolume"
  4798. _, err := buildImage(name, `
  4799. FROM busybox
  4800. ENV foo=""
  4801. VOLUME $foo
  4802. `, false)
  4803. if err == nil {
  4804. c.Fatal("Should have failed to build")
  4805. }
  4806. }
  4807. func (s *DockerSuite) TestBuildContainerWithCgroupParent(c *check.C) {
  4808. testRequires(c, SameHostDaemon)
  4809. testRequires(c, DaemonIsLinux)
  4810. cgroupParent := "test"
  4811. data, err := ioutil.ReadFile("/proc/self/cgroup")
  4812. if err != nil {
  4813. c.Fatalf("failed to read '/proc/self/cgroup - %v", err)
  4814. }
  4815. selfCgroupPaths := parseCgroupPaths(string(data))
  4816. _, found := selfCgroupPaths["memory"]
  4817. if !found {
  4818. c.Fatalf("unable to find self memory cgroup path. CgroupsPath: %v", selfCgroupPaths)
  4819. }
  4820. cmd := exec.Command(dockerBinary, "build", "--cgroup-parent", cgroupParent, "-")
  4821. cmd.Stdin = strings.NewReader(`
  4822. FROM busybox
  4823. RUN cat /proc/self/cgroup
  4824. `)
  4825. out, _, err := runCommandWithOutput(cmd)
  4826. if err != nil {
  4827. c.Fatalf("unexpected failure when running container with --cgroup-parent option - %s\n%v", string(out), err)
  4828. }
  4829. m, err := regexp.MatchString(fmt.Sprintf("memory:.*/%s/.*", cgroupParent), out)
  4830. c.Assert(err, check.IsNil)
  4831. if !m {
  4832. c.Fatalf("There is no expected memory cgroup with parent /%s/: %s", cgroupParent, out)
  4833. }
  4834. }
  4835. func (s *DockerSuite) TestBuildNoDupOutput(c *check.C) {
  4836. testRequires(c, DaemonIsLinux)
  4837. // Check to make sure our build output prints the Dockerfile cmd
  4838. // property - there was a bug that caused it to be duplicated on the
  4839. // Step X line
  4840. name := "testbuildnodupoutput"
  4841. _, out, err := buildImageWithOut(name, `
  4842. FROM busybox
  4843. RUN env`, false)
  4844. if err != nil {
  4845. c.Fatalf("Build should have worked: %q", err)
  4846. }
  4847. exp := "\nStep 2 : RUN env\n"
  4848. if !strings.Contains(out, exp) {
  4849. c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  4850. }
  4851. }
  4852. // GH15826
  4853. func (s *DockerSuite) TestBuildStartsFromOne(c *check.C) {
  4854. testRequires(c, DaemonIsLinux)
  4855. // Explicit check to ensure that build starts from step 1 rather than 0
  4856. name := "testbuildstartsfromone"
  4857. _, out, err := buildImageWithOut(name, `
  4858. FROM busybox`, false)
  4859. if err != nil {
  4860. c.Fatalf("Build should have worked: %q", err)
  4861. }
  4862. exp := "\nStep 1 : FROM busybox\n"
  4863. if !strings.Contains(out, exp) {
  4864. c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  4865. }
  4866. }
  4867. func (s *DockerSuite) TestBuildBadCmdFlag(c *check.C) {
  4868. testRequires(c, DaemonIsLinux)
  4869. name := "testbuildbadcmdflag"
  4870. _, out, err := buildImageWithOut(name, `
  4871. FROM busybox
  4872. MAINTAINER --boo joe@example.com`, false)
  4873. if err == nil {
  4874. c.Fatal("Build should have failed")
  4875. }
  4876. exp := "\nUnknown flag: boo\n"
  4877. if !strings.Contains(out, exp) {
  4878. c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
  4879. }
  4880. }
  4881. func (s *DockerSuite) TestBuildRUNErrMsg(c *check.C) {
  4882. testRequires(c, DaemonIsLinux)
  4883. // Test to make sure the bad command is quoted with just "s and
  4884. // not as a Go []string
  4885. name := "testbuildbadrunerrmsg"
  4886. _, out, err := buildImageWithOut(name, `
  4887. FROM busybox
  4888. RUN badEXE a1 \& a2 a3`, false) // tab between a2 and a3
  4889. if err == nil {
  4890. c.Fatal("Should have failed to build")
  4891. }
  4892. exp := `The command '/bin/sh -c badEXE a1 \& a2 a3' returned a non-zero code: 127`
  4893. if !strings.Contains(out, exp) {
  4894. c.Fatalf("RUN doesn't have the correct output:\nGot:%s\nExpected:%s", out, exp)
  4895. }
  4896. }
  4897. func (s *DockerTrustSuite) TestTrustedBuild(c *check.C) {
  4898. repoName := s.setupTrustedImage(c, "trusted-build")
  4899. dockerFile := fmt.Sprintf(`
  4900. FROM %s
  4901. RUN []
  4902. `, repoName)
  4903. name := "testtrustedbuild"
  4904. buildCmd := buildImageCmd(name, dockerFile, true)
  4905. s.trustedCmd(buildCmd)
  4906. out, _, err := runCommandWithOutput(buildCmd)
  4907. if err != nil {
  4908. c.Fatalf("Error running trusted build: %s\n%s", err, out)
  4909. }
  4910. if !strings.Contains(out, fmt.Sprintf("FROM %s@sha", repoName[:len(repoName)-7])) {
  4911. c.Fatalf("Unexpected output on trusted build:\n%s", out)
  4912. }
  4913. // We should also have a tag reference for the image.
  4914. if out, exitCode := dockerCmd(c, "inspect", repoName); exitCode != 0 {
  4915. c.Fatalf("unexpected exit code inspecting image %q: %d: %s", repoName, exitCode, out)
  4916. }
  4917. // We should now be able to remove the tag reference.
  4918. if out, exitCode := dockerCmd(c, "rmi", repoName); exitCode != 0 {
  4919. c.Fatalf("unexpected exit code inspecting image %q: %d: %s", repoName, exitCode, out)
  4920. }
  4921. }
  4922. func (s *DockerTrustSuite) TestTrustedBuildUntrustedTag(c *check.C) {
  4923. repoName := fmt.Sprintf("%v/dockercli/build-untrusted-tag:latest", privateRegistryURL)
  4924. dockerFile := fmt.Sprintf(`
  4925. FROM %s
  4926. RUN []
  4927. `, repoName)
  4928. name := "testtrustedbuilduntrustedtag"
  4929. buildCmd := buildImageCmd(name, dockerFile, true)
  4930. s.trustedCmd(buildCmd)
  4931. out, _, err := runCommandWithOutput(buildCmd)
  4932. if err == nil {
  4933. c.Fatalf("Expected error on trusted build with untrusted tag: %s\n%s", err, out)
  4934. }
  4935. if !strings.Contains(out, "does not have trust data for") {
  4936. c.Fatalf("Unexpected output on trusted build with untrusted tag:\n%s", out)
  4937. }
  4938. }
  4939. func (s *DockerTrustSuite) TestBuildContextDirIsSymlink(c *check.C) {
  4940. testRequires(c, DaemonIsLinux)
  4941. tempDir, err := ioutil.TempDir("", "test-build-dir-is-symlink-")
  4942. c.Assert(err, check.IsNil)
  4943. defer os.RemoveAll(tempDir)
  4944. // Make a real context directory in this temp directory with a simple
  4945. // Dockerfile.
  4946. realContextDirname := filepath.Join(tempDir, "context")
  4947. if err := os.Mkdir(realContextDirname, os.FileMode(0755)); err != nil {
  4948. c.Fatal(err)
  4949. }
  4950. if err = ioutil.WriteFile(
  4951. filepath.Join(realContextDirname, "Dockerfile"),
  4952. []byte(`
  4953. FROM busybox
  4954. RUN echo hello world
  4955. `),
  4956. os.FileMode(0644),
  4957. ); err != nil {
  4958. c.Fatal(err)
  4959. }
  4960. // Make a symlink to the real context directory.
  4961. contextSymlinkName := filepath.Join(tempDir, "context_link")
  4962. if err := os.Symlink(realContextDirname, contextSymlinkName); err != nil {
  4963. c.Fatal(err)
  4964. }
  4965. // Executing the build with the symlink as the specified context should
  4966. // *not* fail.
  4967. if out, exitStatus := dockerCmd(c, "build", contextSymlinkName); exitStatus != 0 {
  4968. c.Fatalf("build failed with exit status %d: %s", exitStatus, out)
  4969. }
  4970. }
  4971. // Issue #15634: COPY fails when path starts with "null"
  4972. func (s *DockerSuite) TestBuildNullStringInAddCopyVolume(c *check.C) {
  4973. testRequires(c, DaemonIsLinux)
  4974. name := "testbuildnullstringinaddcopyvolume"
  4975. ctx, err := fakeContext(`
  4976. FROM busybox
  4977. ADD null /
  4978. COPY nullfile /
  4979. VOLUME nullvolume
  4980. `,
  4981. map[string]string{
  4982. "null": "test1",
  4983. "nullfile": "test2",
  4984. },
  4985. )
  4986. c.Assert(err, check.IsNil)
  4987. defer ctx.Close()
  4988. _, err = buildImageFromContext(name, ctx, true)
  4989. c.Assert(err, check.IsNil)
  4990. }
  4991. func (s *DockerSuite) TestBuildStopSignal(c *check.C) {
  4992. testRequires(c, DaemonIsLinux)
  4993. name := "test_build_stop_signal"
  4994. _, err := buildImage(name,
  4995. `FROM busybox
  4996. STOPSIGNAL SIGKILL`,
  4997. true)
  4998. c.Assert(err, check.IsNil)
  4999. res := inspectFieldJSON(c, name, "Config.StopSignal")
  5000. if res != `"SIGKILL"` {
  5001. c.Fatalf("Signal %s, expected SIGKILL", res)
  5002. }
  5003. }
  5004. func (s *DockerSuite) TestBuildBuildTimeArg(c *check.C) {
  5005. testRequires(c, DaemonIsLinux)
  5006. imgName := "bldargtest"
  5007. envKey := "foo"
  5008. envVal := "bar"
  5009. args := []string{
  5010. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5011. }
  5012. dockerfile := fmt.Sprintf(`FROM busybox
  5013. ARG %s
  5014. RUN echo $%s
  5015. CMD echo $%s`, envKey, envKey, envKey)
  5016. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  5017. if err != nil {
  5018. c.Fatalf("build failed to complete: %q %q", out, err)
  5019. }
  5020. c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  5021. }
  5022. containerName := "bldargCont"
  5023. if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  5024. c.Fatalf("run produced invalid output: %q, expected empty string", out)
  5025. }
  5026. }
  5027. func (s *DockerSuite) TestBuildBuildTimeArgHistory(c *check.C) {
  5028. testRequires(c, DaemonIsLinux)
  5029. imgName := "bldargtest"
  5030. envKey := "foo"
  5031. envVal := "bar"
  5032. envDef := "bar1"
  5033. args := []string{
  5034. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5035. }
  5036. dockerfile := fmt.Sprintf(`FROM busybox
  5037. ARG %s=%s`, envKey, envDef)
  5038. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  5039. if err != nil {
  5040. c.Fatalf("build failed to complete: %q %q", out, err)
  5041. }
  5042. c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  5043. }
  5044. out, _ := dockerCmd(c, "history", "--no-trunc", imgName)
  5045. outputTabs := strings.Split(out, "\n")[1]
  5046. if !strings.Contains(outputTabs, envDef) {
  5047. c.Fatalf("failed to find arg default in image history output: %q expected: %q", outputTabs, envDef)
  5048. }
  5049. }
  5050. func (s *DockerSuite) TestBuildBuildTimeArgCacheHit(c *check.C) {
  5051. testRequires(c, DaemonIsLinux)
  5052. imgName := "bldargtest"
  5053. envKey := "foo"
  5054. envVal := "bar"
  5055. args := []string{
  5056. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5057. }
  5058. dockerfile := fmt.Sprintf(`FROM busybox
  5059. ARG %s
  5060. RUN echo $%s`, envKey, envKey)
  5061. origImgID := ""
  5062. var err error
  5063. if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5064. c.Fatal(err)
  5065. }
  5066. imgNameCache := "bldargtestcachehit"
  5067. if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID != origImgID {
  5068. if err != nil {
  5069. c.Fatal(err)
  5070. }
  5071. c.Fatalf("build didn't use cache! expected image id: %q built image id: %q", origImgID, newImgID)
  5072. }
  5073. }
  5074. func (s *DockerSuite) TestBuildBuildTimeArgCacheMissExtraArg(c *check.C) {
  5075. testRequires(c, DaemonIsLinux)
  5076. imgName := "bldargtest"
  5077. envKey := "foo"
  5078. envVal := "bar"
  5079. extraEnvKey := "foo1"
  5080. extraEnvVal := "bar1"
  5081. args := []string{
  5082. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5083. }
  5084. dockerfile := fmt.Sprintf(`FROM busybox
  5085. ARG %s
  5086. ARG %s
  5087. RUN echo $%s`, envKey, extraEnvKey, envKey)
  5088. origImgID := ""
  5089. var err error
  5090. if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5091. c.Fatal(err)
  5092. }
  5093. imgNameCache := "bldargtestcachemiss"
  5094. args = append(args, "--build-arg", fmt.Sprintf("%s=%s", extraEnvKey, extraEnvVal))
  5095. if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID == origImgID {
  5096. if err != nil {
  5097. c.Fatal(err)
  5098. }
  5099. c.Fatalf("build used cache, expected a miss!")
  5100. }
  5101. }
  5102. func (s *DockerSuite) TestBuildBuildTimeArgCacheMissSameArgDiffVal(c *check.C) {
  5103. testRequires(c, DaemonIsLinux)
  5104. imgName := "bldargtest"
  5105. envKey := "foo"
  5106. envVal := "bar"
  5107. newEnvVal := "bar1"
  5108. args := []string{
  5109. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5110. }
  5111. dockerfile := fmt.Sprintf(`FROM busybox
  5112. ARG %s
  5113. RUN echo $%s`, envKey, envKey)
  5114. origImgID := ""
  5115. var err error
  5116. if origImgID, err = buildImage(imgName, dockerfile, true, args...); err != nil {
  5117. c.Fatal(err)
  5118. }
  5119. imgNameCache := "bldargtestcachemiss"
  5120. args = []string{
  5121. "--build-arg", fmt.Sprintf("%s=%s", envKey, newEnvVal),
  5122. }
  5123. if newImgID, err := buildImage(imgNameCache, dockerfile, true, args...); err != nil || newImgID == origImgID {
  5124. if err != nil {
  5125. c.Fatal(err)
  5126. }
  5127. c.Fatalf("build used cache, expected a miss!")
  5128. }
  5129. }
  5130. func (s *DockerSuite) TestBuildBuildTimeArgOverrideArgDefinedBeforeEnv(c *check.C) {
  5131. testRequires(c, DaemonIsLinux)
  5132. imgName := "bldargtest"
  5133. envKey := "foo"
  5134. envVal := "bar"
  5135. envValOveride := "barOverride"
  5136. args := []string{
  5137. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5138. }
  5139. dockerfile := fmt.Sprintf(`FROM busybox
  5140. ARG %s
  5141. ENV %s %s
  5142. RUN echo $%s
  5143. CMD echo $%s
  5144. `, envKey, envKey, envValOveride, envKey, envKey)
  5145. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  5146. if err != nil {
  5147. c.Fatalf("build failed to complete: %q %q", out, err)
  5148. }
  5149. c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  5150. }
  5151. containerName := "bldargCont"
  5152. if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  5153. c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  5154. }
  5155. }
  5156. func (s *DockerSuite) TestBuildBuildTimeArgOverrideEnvDefinedBeforeArg(c *check.C) {
  5157. testRequires(c, DaemonIsLinux)
  5158. imgName := "bldargtest"
  5159. envKey := "foo"
  5160. envVal := "bar"
  5161. envValOveride := "barOverride"
  5162. args := []string{
  5163. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5164. }
  5165. dockerfile := fmt.Sprintf(`FROM busybox
  5166. ENV %s %s
  5167. ARG %s
  5168. RUN echo $%s
  5169. CMD echo $%s
  5170. `, envKey, envValOveride, envKey, envKey, envKey)
  5171. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  5172. if err != nil {
  5173. c.Fatalf("build failed to complete: %q %q", out, err)
  5174. }
  5175. c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  5176. }
  5177. containerName := "bldargCont"
  5178. if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  5179. c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  5180. }
  5181. }
  5182. func (s *DockerSuite) TestBuildBuildTimeArgExpansion(c *check.C) {
  5183. testRequires(c, DaemonIsLinux)
  5184. imgName := "bldvarstest"
  5185. wdVar := "WDIR"
  5186. wdVal := "/tmp/"
  5187. addVar := "AFILE"
  5188. addVal := "addFile"
  5189. copyVar := "CFILE"
  5190. copyVal := "copyFile"
  5191. envVar := "foo"
  5192. envVal := "bar"
  5193. exposeVar := "EPORT"
  5194. exposeVal := "9999"
  5195. userVar := "USER"
  5196. userVal := "testUser"
  5197. volVar := "VOL"
  5198. volVal := "/testVol/"
  5199. args := []string{
  5200. "--build-arg", fmt.Sprintf("%s=%s", wdVar, wdVal),
  5201. "--build-arg", fmt.Sprintf("%s=%s", addVar, addVal),
  5202. "--build-arg", fmt.Sprintf("%s=%s", copyVar, copyVal),
  5203. "--build-arg", fmt.Sprintf("%s=%s", envVar, envVal),
  5204. "--build-arg", fmt.Sprintf("%s=%s", exposeVar, exposeVal),
  5205. "--build-arg", fmt.Sprintf("%s=%s", userVar, userVal),
  5206. "--build-arg", fmt.Sprintf("%s=%s", volVar, volVal),
  5207. }
  5208. ctx, err := fakeContext(fmt.Sprintf(`FROM busybox
  5209. ARG %s
  5210. WORKDIR ${%s}
  5211. ARG %s
  5212. ADD ${%s} testDir/
  5213. ARG %s
  5214. COPY $%s testDir/
  5215. ARG %s
  5216. ENV %s=${%s}
  5217. ARG %s
  5218. EXPOSE $%s
  5219. ARG %s
  5220. USER $%s
  5221. ARG %s
  5222. VOLUME ${%s}`,
  5223. wdVar, wdVar, addVar, addVar, copyVar, copyVar, envVar, envVar,
  5224. envVar, exposeVar, exposeVar, userVar, userVar, volVar, volVar),
  5225. map[string]string{
  5226. addVal: "some stuff",
  5227. copyVal: "some stuff",
  5228. })
  5229. if err != nil {
  5230. c.Fatal(err)
  5231. }
  5232. defer ctx.Close()
  5233. if _, err := buildImageFromContext(imgName, ctx, true, args...); err != nil {
  5234. c.Fatal(err)
  5235. }
  5236. var resMap map[string]interface{}
  5237. var resArr []string
  5238. res := ""
  5239. res = inspectField(c, imgName, "Config.WorkingDir")
  5240. if res != filepath.ToSlash(filepath.Clean(wdVal)) {
  5241. c.Fatalf("Config.WorkingDir value mismatch. Expected: %s, got: %s", filepath.ToSlash(filepath.Clean(wdVal)), res)
  5242. }
  5243. inspectFieldAndMarshall(c, imgName, "Config.Env", &resArr)
  5244. found := false
  5245. for _, v := range resArr {
  5246. if fmt.Sprintf("%s=%s", envVar, envVal) == v {
  5247. found = true
  5248. break
  5249. }
  5250. }
  5251. if !found {
  5252. c.Fatalf("Config.Env value mismatch. Expected <key=value> to exist: %s=%s, got: %v",
  5253. envVar, envVal, resArr)
  5254. }
  5255. inspectFieldAndMarshall(c, imgName, "Config.ExposedPorts", &resMap)
  5256. if _, ok := resMap[fmt.Sprintf("%s/tcp", exposeVal)]; !ok {
  5257. c.Fatalf("Config.ExposedPorts value mismatch. Expected exposed port: %s/tcp, got: %v", exposeVal, resMap)
  5258. }
  5259. res = inspectField(c, imgName, "Config.User")
  5260. if res != userVal {
  5261. c.Fatalf("Config.User value mismatch. Expected: %s, got: %s", userVal, res)
  5262. }
  5263. inspectFieldAndMarshall(c, imgName, "Config.Volumes", &resMap)
  5264. if _, ok := resMap[volVal]; !ok {
  5265. c.Fatalf("Config.Volumes value mismatch. Expected volume: %s, got: %v", volVal, resMap)
  5266. }
  5267. }
  5268. func (s *DockerSuite) TestBuildBuildTimeArgExpansionOverride(c *check.C) {
  5269. testRequires(c, DaemonIsLinux)
  5270. imgName := "bldvarstest"
  5271. envKey := "foo"
  5272. envVal := "bar"
  5273. envKey1 := "foo1"
  5274. envValOveride := "barOverride"
  5275. args := []string{
  5276. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5277. }
  5278. dockerfile := fmt.Sprintf(`FROM busybox
  5279. ARG %s
  5280. ENV %s %s
  5281. ENV %s ${%s}
  5282. RUN echo $%s
  5283. CMD echo $%s`, envKey, envKey, envValOveride, envKey1, envKey, envKey1, envKey1)
  5284. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 2 {
  5285. if err != nil {
  5286. c.Fatalf("build failed to complete: %q %q", out, err)
  5287. }
  5288. c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  5289. }
  5290. containerName := "bldargCont"
  5291. if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  5292. c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  5293. }
  5294. }
  5295. func (s *DockerSuite) TestBuildBuildTimeArgUntrustedDefinedAfterUse(c *check.C) {
  5296. testRequires(c, DaemonIsLinux)
  5297. imgName := "bldargtest"
  5298. envKey := "foo"
  5299. envVal := "bar"
  5300. args := []string{
  5301. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5302. }
  5303. dockerfile := fmt.Sprintf(`FROM busybox
  5304. RUN echo $%s
  5305. ARG %s
  5306. CMD echo $%s`, envKey, envKey, envKey)
  5307. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Contains(out, envVal) {
  5308. if err != nil {
  5309. c.Fatalf("build failed to complete: %q %q", out, err)
  5310. }
  5311. c.Fatalf("able to access environment variable in output: %q expected to be missing", out)
  5312. }
  5313. containerName := "bldargCont"
  5314. if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  5315. c.Fatalf("run produced invalid output: %q, expected empty string", out)
  5316. }
  5317. }
  5318. func (s *DockerSuite) TestBuildBuildTimeArgBuiltinArg(c *check.C) {
  5319. testRequires(c, DaemonIsLinux)
  5320. imgName := "bldargtest"
  5321. envKey := "HTTP_PROXY"
  5322. envVal := "bar"
  5323. args := []string{
  5324. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5325. }
  5326. dockerfile := fmt.Sprintf(`FROM busybox
  5327. RUN echo $%s
  5328. CMD echo $%s`, envKey, envKey)
  5329. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || !strings.Contains(out, envVal) {
  5330. if err != nil {
  5331. c.Fatalf("build failed to complete: %q %q", out, err)
  5332. }
  5333. c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envVal)
  5334. }
  5335. containerName := "bldargCont"
  5336. if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); out != "\n" {
  5337. c.Fatalf("run produced invalid output: %q, expected empty string", out)
  5338. }
  5339. }
  5340. func (s *DockerSuite) TestBuildBuildTimeArgDefaultOverride(c *check.C) {
  5341. testRequires(c, DaemonIsLinux)
  5342. imgName := "bldargtest"
  5343. envKey := "foo"
  5344. envVal := "bar"
  5345. envValOveride := "barOverride"
  5346. args := []string{
  5347. "--build-arg", fmt.Sprintf("%s=%s", envKey, envValOveride),
  5348. }
  5349. dockerfile := fmt.Sprintf(`FROM busybox
  5350. ARG %s=%s
  5351. ENV %s $%s
  5352. RUN echo $%s
  5353. CMD echo $%s`, envKey, envVal, envKey, envKey, envKey, envKey)
  5354. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envValOveride) != 1 {
  5355. if err != nil {
  5356. c.Fatalf("build failed to complete: %q %q", out, err)
  5357. }
  5358. c.Fatalf("failed to access environment variable in output: %q expected: %q", out, envValOveride)
  5359. }
  5360. containerName := "bldargCont"
  5361. if out, _ := dockerCmd(c, "run", "--name", containerName, imgName); !strings.Contains(out, envValOveride) {
  5362. c.Fatalf("run produced invalid output: %q, expected %q", out, envValOveride)
  5363. }
  5364. }
  5365. func (s *DockerSuite) TestBuildBuildTimeArgMultiArgsSameLine(c *check.C) {
  5366. testRequires(c, DaemonIsLinux)
  5367. imgName := "bldargtest"
  5368. envKey := "foo"
  5369. envKey1 := "foo1"
  5370. args := []string{}
  5371. dockerfile := fmt.Sprintf(`FROM busybox
  5372. ARG %s %s`, envKey, envKey1)
  5373. errStr := "ARG requires exactly one argument definition"
  5374. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err == nil {
  5375. c.Fatalf("build succeeded, expected to fail. Output: %v", out)
  5376. } else if !strings.Contains(out, errStr) {
  5377. c.Fatalf("Unexpected error. output: %q, expected error: %q", out, errStr)
  5378. }
  5379. }
  5380. func (s *DockerSuite) TestBuildBuildTimeArgUnconsumedArg(c *check.C) {
  5381. testRequires(c, DaemonIsLinux)
  5382. imgName := "bldargtest"
  5383. envKey := "foo"
  5384. envVal := "bar"
  5385. args := []string{
  5386. "--build-arg", fmt.Sprintf("%s=%s", envKey, envVal),
  5387. }
  5388. dockerfile := fmt.Sprintf(`FROM busybox
  5389. RUN echo $%s
  5390. CMD echo $%s`, envKey, envKey)
  5391. errStr := "One or more build-args"
  5392. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err == nil {
  5393. c.Fatalf("build succeeded, expected to fail. Output: %v", out)
  5394. } else if !strings.Contains(out, errStr) {
  5395. c.Fatalf("Unexpected error. output: %q, expected error: %q", out, errStr)
  5396. }
  5397. }
  5398. func (s *DockerSuite) TestBuildBuildTimeArgQuotedValVariants(c *check.C) {
  5399. testRequires(c, DaemonIsLinux)
  5400. imgName := "bldargtest"
  5401. envKey := "foo"
  5402. envKey1 := "foo1"
  5403. envKey2 := "foo2"
  5404. envKey3 := "foo3"
  5405. args := []string{}
  5406. dockerfile := fmt.Sprintf(`FROM busybox
  5407. ARG %s=""
  5408. ARG %s=''
  5409. ARG %s="''"
  5410. ARG %s='""'
  5411. RUN [ "$%s" != "$%s" ]
  5412. RUN [ "$%s" != "$%s" ]
  5413. RUN [ "$%s" != "$%s" ]
  5414. RUN [ "$%s" != "$%s" ]
  5415. RUN [ "$%s" != "$%s" ]`, envKey, envKey1, envKey2, envKey3,
  5416. envKey, envKey2, envKey, envKey3, envKey1, envKey2, envKey1, envKey3,
  5417. envKey2, envKey3)
  5418. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil {
  5419. c.Fatalf("build failed to complete: %q %q", out, err)
  5420. }
  5421. }
  5422. func (s *DockerSuite) TestBuildBuildTimeArgEmptyValVariants(c *check.C) {
  5423. testRequires(c, DaemonIsLinux)
  5424. imgName := "bldargtest"
  5425. envKey := "foo"
  5426. envKey1 := "foo1"
  5427. envKey2 := "foo2"
  5428. args := []string{}
  5429. dockerfile := fmt.Sprintf(`FROM busybox
  5430. ARG %s=
  5431. ARG %s=""
  5432. ARG %s=''
  5433. RUN [ "$%s" == "$%s" ]
  5434. RUN [ "$%s" == "$%s" ]
  5435. RUN [ "$%s" == "$%s" ]`, envKey, envKey1, envKey2, envKey, envKey1, envKey1, envKey2, envKey, envKey2)
  5436. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil {
  5437. c.Fatalf("build failed to complete: %q %q", out, err)
  5438. }
  5439. }
  5440. func (s *DockerSuite) TestBuildBuildTimeArgDefintionWithNoEnvInjection(c *check.C) {
  5441. testRequires(c, DaemonIsLinux)
  5442. imgName := "bldargtest"
  5443. envKey := "foo"
  5444. args := []string{}
  5445. dockerfile := fmt.Sprintf(`FROM busybox
  5446. ARG %s
  5447. RUN env`, envKey)
  5448. if _, out, err := buildImageWithOut(imgName, dockerfile, true, args...); err != nil || strings.Count(out, envKey) != 1 {
  5449. if err != nil {
  5450. c.Fatalf("build failed to complete: %q %q", out, err)
  5451. }
  5452. c.Fatalf("unexpected number of occurrences of the arg in output: %q expected: 1", out)
  5453. }
  5454. }
  5455. func (s *DockerSuite) TestBuildNoNamedVolume(c *check.C) {
  5456. testRequires(c, DaemonIsLinux)
  5457. dockerCmd(c, "run", "-v", "testname:/foo", "busybox", "sh", "-c", "touch /foo/oops")
  5458. dockerFile := `FROM busybox
  5459. VOLUME testname:/foo
  5460. RUN ls /foo/oops
  5461. `
  5462. _, err := buildImage("test", dockerFile, false)
  5463. c.Assert(err, check.NotNil, check.Commentf("image build should have failed"))
  5464. }
  5465. func (s *DockerSuite) TestBuildTagEvent(c *check.C) {
  5466. testRequires(c, DaemonIsLinux)
  5467. since := daemonTime(c).Unix()
  5468. dockerFile := `FROM busybox
  5469. RUN echo events
  5470. `
  5471. _, err := buildImage("test", dockerFile, false)
  5472. c.Assert(err, check.IsNil)
  5473. out, _ := dockerCmd(c, "events", fmt.Sprintf("--since=%d", since), fmt.Sprintf("--until=%d", daemonTime(c).Unix()), "--filter", "type=image")
  5474. events := strings.Split(strings.TrimSpace(out), "\n")
  5475. actions := eventActionsByIDAndType(c, events, "test:latest", "image")
  5476. var foundTag bool
  5477. for _, a := range actions {
  5478. if a == "tag" {
  5479. foundTag = true
  5480. break
  5481. }
  5482. }
  5483. c.Assert(foundTag, checker.True, check.Commentf("No tag event found:\n%s", out))
  5484. }
  5485. // #15780
  5486. func (s *DockerSuite) TestBuildMultipleTags(c *check.C) {
  5487. dockerfile := `
  5488. FROM busybox
  5489. MAINTAINER test-15780
  5490. `
  5491. cmd := exec.Command(dockerBinary, "build", "-t", "tag1", "-t", "tag2:v2",
  5492. "-t", "tag1:latest", "-t", "tag1", "--no-cache", "-")
  5493. cmd.Stdin = strings.NewReader(dockerfile)
  5494. _, err := runCommand(cmd)
  5495. c.Assert(err, check.IsNil)
  5496. id1, err := getIDByName("tag1")
  5497. c.Assert(err, check.IsNil)
  5498. id2, err := getIDByName("tag2:v2")
  5499. c.Assert(err, check.IsNil)
  5500. c.Assert(id1, check.Equals, id2)
  5501. }
  5502. // #17290
  5503. func (s *DockerSuite) TestBuildCacheBrokenSymlink(c *check.C) {
  5504. testRequires(c, DaemonIsLinux)
  5505. name := "testbuildbrokensymlink"
  5506. ctx, err := fakeContext(`
  5507. FROM busybox
  5508. COPY . ./`,
  5509. map[string]string{
  5510. "foo": "bar",
  5511. })
  5512. c.Assert(err, checker.IsNil)
  5513. defer ctx.Close()
  5514. err = os.Symlink(filepath.Join(ctx.Dir, "nosuchfile"), filepath.Join(ctx.Dir, "asymlink"))
  5515. c.Assert(err, checker.IsNil)
  5516. // warm up cache
  5517. _, err = buildImageFromContext(name, ctx, true)
  5518. c.Assert(err, checker.IsNil)
  5519. // add new file to context, should invalidate cache
  5520. err = ioutil.WriteFile(filepath.Join(ctx.Dir, "newfile"), []byte("foo"), 0644)
  5521. c.Assert(err, checker.IsNil)
  5522. _, out, err := buildImageFromContextWithOut(name, ctx, true)
  5523. c.Assert(err, checker.IsNil)
  5524. c.Assert(out, checker.Not(checker.Contains), "Using cache")
  5525. }
  5526. func (s *DockerSuite) TestBuildFollowSymlinkToFile(c *check.C) {
  5527. testRequires(c, DaemonIsLinux)
  5528. name := "testbuildbrokensymlink"
  5529. ctx, err := fakeContext(`
  5530. FROM busybox
  5531. COPY asymlink target`,
  5532. map[string]string{
  5533. "foo": "bar",
  5534. })
  5535. c.Assert(err, checker.IsNil)
  5536. defer ctx.Close()
  5537. err = os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink"))
  5538. c.Assert(err, checker.IsNil)
  5539. id, err := buildImageFromContext(name, ctx, true)
  5540. c.Assert(err, checker.IsNil)
  5541. out, _ := dockerCmd(c, "run", "--rm", id, "cat", "target")
  5542. c.Assert(out, checker.Matches, "bar")
  5543. // change target file should invalidate cache
  5544. err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644)
  5545. c.Assert(err, checker.IsNil)
  5546. id, out, err = buildImageFromContextWithOut(name, ctx, true)
  5547. c.Assert(err, checker.IsNil)
  5548. c.Assert(out, checker.Not(checker.Contains), "Using cache")
  5549. out, _ = dockerCmd(c, "run", "--rm", id, "cat", "target")
  5550. c.Assert(out, checker.Matches, "baz")
  5551. }
  5552. func (s *DockerSuite) TestBuildFollowSymlinkToDir(c *check.C) {
  5553. testRequires(c, DaemonIsLinux)
  5554. name := "testbuildbrokensymlink"
  5555. ctx, err := fakeContext(`
  5556. FROM busybox
  5557. COPY asymlink /`,
  5558. map[string]string{
  5559. "foo/abc": "bar",
  5560. "foo/def": "baz",
  5561. })
  5562. c.Assert(err, checker.IsNil)
  5563. defer ctx.Close()
  5564. err = os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink"))
  5565. c.Assert(err, checker.IsNil)
  5566. id, err := buildImageFromContext(name, ctx, true)
  5567. c.Assert(err, checker.IsNil)
  5568. out, _ := dockerCmd(c, "run", "--rm", id, "cat", "abc", "def")
  5569. c.Assert(out, checker.Matches, "barbaz")
  5570. // change target file should invalidate cache
  5571. err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo/def"), []byte("bax"), 0644)
  5572. c.Assert(err, checker.IsNil)
  5573. id, out, err = buildImageFromContextWithOut(name, ctx, true)
  5574. c.Assert(err, checker.IsNil)
  5575. c.Assert(out, checker.Not(checker.Contains), "Using cache")
  5576. out, _ = dockerCmd(c, "run", "--rm", id, "cat", "abc", "def")
  5577. c.Assert(out, checker.Matches, "barbax")
  5578. }
  5579. // TestBuildSymlinkBasename tests that target file gets basename from symlink,
  5580. // not from the target file.
  5581. func (s *DockerSuite) TestBuildSymlinkBasename(c *check.C) {
  5582. testRequires(c, DaemonIsLinux)
  5583. name := "testbuildbrokensymlink"
  5584. ctx, err := fakeContext(`
  5585. FROM busybox
  5586. COPY asymlink /`,
  5587. map[string]string{
  5588. "foo": "bar",
  5589. })
  5590. c.Assert(err, checker.IsNil)
  5591. defer ctx.Close()
  5592. err = os.Symlink("foo", filepath.Join(ctx.Dir, "asymlink"))
  5593. c.Assert(err, checker.IsNil)
  5594. id, err := buildImageFromContext(name, ctx, true)
  5595. c.Assert(err, checker.IsNil)
  5596. out, _ := dockerCmd(c, "run", "--rm", id, "cat", "asymlink")
  5597. c.Assert(out, checker.Matches, "bar")
  5598. }
  5599. // #17827
  5600. func (s *DockerSuite) TestBuildCacheRootSource(c *check.C) {
  5601. testRequires(c, DaemonIsLinux)
  5602. name := "testbuildrootsource"
  5603. ctx, err := fakeContext(`
  5604. FROM busybox
  5605. COPY / /data`,
  5606. map[string]string{
  5607. "foo": "bar",
  5608. })
  5609. c.Assert(err, checker.IsNil)
  5610. defer ctx.Close()
  5611. // warm up cache
  5612. _, err = buildImageFromContext(name, ctx, true)
  5613. c.Assert(err, checker.IsNil)
  5614. // change file, should invalidate cache
  5615. err = ioutil.WriteFile(filepath.Join(ctx.Dir, "foo"), []byte("baz"), 0644)
  5616. c.Assert(err, checker.IsNil)
  5617. _, out, err := buildImageFromContextWithOut(name, ctx, true)
  5618. c.Assert(err, checker.IsNil)
  5619. c.Assert(out, checker.Not(checker.Contains), "Using cache")
  5620. }
  5621. // #19375
  5622. func (s *DockerSuite) TestBuildFailsGitNotCallable(c *check.C) {
  5623. cmd := exec.Command(dockerBinary, "build", "github.com/docker/v1.10-migrator.git")
  5624. cmd.Env = append(cmd.Env, "PATH=")
  5625. out, _, err := runCommandWithOutput(cmd)
  5626. c.Assert(err, checker.NotNil)
  5627. c.Assert(out, checker.Contains, "unable to prepare context: unable to find 'git': ")
  5628. cmd = exec.Command(dockerBinary, "build", "https://github.com/docker/v1.10-migrator.git")
  5629. cmd.Env = append(cmd.Env, "PATH=")
  5630. out, _, err = runCommandWithOutput(cmd)
  5631. c.Assert(err, checker.NotNil)
  5632. c.Assert(out, checker.Contains, "unable to prepare context: unable to find 'git': ")
  5633. }