From a63a49caa13f863ebe54647a3987a274d2a718e7 Mon Sep 17 00:00:00 2001 From: jakedt Date: Thu, 20 Feb 2014 22:26:10 -0500 Subject: [PATCH] Fix up the shared base images stuff. --- data/model.py | 36 ++++++++++++++++++++++++++++-------- endpoints/index.py | 10 +++++++--- initdb.py | 2 +- test/data/test.db | Bin 157696 -> 157696 bytes test/test_image_sharing.py | 2 +- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/data/model.py b/data/model.py index d00ebbdb0..30f8f174a 100644 --- a/data/model.py +++ b/data/model.py @@ -884,12 +884,19 @@ def create_repository(namespace, name, creating_user, visibility='private'): return repo -def create_or_link_image(docker_image_id, repository, username): +def __translate_ancestry(old_ancestry, translations): + old_ids = [int(id_str) for id_str in old_ancestry.split('/')[1:-1]] + new_ids = [str(translations[old_id]) for old_id in old_ids] + return '/%s/' % '/'.join(new_ids) + + +def create_or_link_image(docker_image_id, repository, username, translations): with transaction_factory(db): - query = (ImageStorage - .select() + query = (Image + .select(Image, ImageStorage) .distinct() - .join(Image) + .join(ImageStorage) + .switch(Image) .join(Repository) .join(Visibility) .switch(Repository) @@ -898,16 +905,29 @@ def create_or_link_image(docker_image_id, repository, username): query = (_filter_to_repos_for_user(query, username) .where(Image.docker_image_id == docker_image_id)) + new_image_ancestry = '/' + origin_image_id = None try: - storage = query.get() + to_copy = query.get() msg = 'Linking image to existing storage with docker id: %s and uuid: %s' - logger.debug(msg, docker_image_id, storage.uuid) - except ImageStorage.DoesNotExist: + logger.debug(msg, docker_image_id, to_copy.storage.uuid) + + new_image_ancestry = __translate_ancestry(to_copy.ancestors, + translations) + + storage = to_copy.storage + origin_image_id = to_copy.id + except Image.DoesNotExist: logger.debug('Creating new storage for docker id: %s', docker_image_id) storage = ImageStorage.create() new_image = Image.create(docker_image_id=docker_image_id, - repository=repository, storage=storage) + repository=repository, storage=storage, + ancestors=new_image_ancestry) + + if origin_image_id: + translations[origin_image_id] = new_image.id + return new_image diff --git a/endpoints/index.py b/endpoints/index.py index 73ced37db..10105a587 100644 --- a/endpoints/index.py +++ b/endpoints/index.py @@ -4,6 +4,7 @@ import urlparse from flask import request, make_response, jsonify, session, Blueprint from functools import wraps +from collections import OrderedDict from data import model, userevent from data.queue import webhook_queue @@ -183,15 +184,18 @@ def create_repository(namespace, repository): repo = model.create_repository(namespace, repository, get_authenticated_user()) - new_repo_images = {desc['id']: desc for desc in image_descriptions} - added_images = dict(new_repo_images) + added_images = OrderedDict([(desc['id'], desc) + for desc in image_descriptions]) + new_repo_images = dict(added_images) for existing in model.get_repository_images(namespace, repository): if existing.docker_image_id in new_repo_images: added_images.pop(existing.docker_image_id) username = get_authenticated_user() and get_authenticated_user().username + translations = {} for image_description in added_images.values(): - model.create_or_link_image(image_description['id'], repo, username) + model.create_or_link_image(image_description['id'], repo, username, + translations) response = make_response('Created', 201) diff --git a/initdb.py b/initdb.py index 87d7fa769..113d96a3e 100644 --- a/initdb.py +++ b/initdb.py @@ -67,7 +67,7 @@ def __create_subtree(repo, structure, creator_username, parent): logger.debug('new docker id: %s' % docker_image_id) checksum = __gen_checksum(docker_image_id) - new_image = model.create_or_link_image(docker_image_id, repo, None) + new_image = model.create_or_link_image(docker_image_id, repo, None, {}) new_image.storage.uuid = IMAGE_UUIDS[image_num % len(IMAGE_UUIDS)] new_image.storage.save() diff --git a/test/data/test.db b/test/data/test.db index 0a6b7aa200f15335c3d3ec3ceaa243b916a35a33..37967b6df0bca9cf5f7883591360123b46b2ab66 100644 GIT binary patch delta 3671 zcmbtUdvH@#9_~50y-6QTX(^?aCWZ2-ZB2XcO>S;d1WD2)%{%EMO)g#fNRzabzT42k z2;B9tI4rVmM~_vi$g+ygT9jg7mo5xDP? zeCKz*-|zdr-`P5uv~@D+wX@}`D>Y74xvfgC)O(FOwOVOZS~!nUSEbN1T7}x_vuiwt z3Px$Ct0|T@dksdu+M_p@Tgq*e!e!&!Lum#N+wULHg?f9t0)180>skU`8ei*xC1A2R zHMGm$-_%zcG&`#4UQ=LD(bq{SD|>p>9_P?AhI`qP-fq2v=E}=WHO{v69*)&H)@hwp zeud6$w-`#B2L~LbCDq-bP`S-w4jEn6R;ng2bj@%d+iU9UrF#ZU-nNzsH5c&rZnO{T z`^_Pr+hXX@baj+;yEgP|x_TP*3Z~N5?N#zrsA|Y-EM_;*C3e2l5Ngx6+Sm1|O4tEi zYpqjj9W$syX=OGJIL(7Yhm8fSSy36Z7%JRdgFQ|~ySJS+ zH3d5ZPE)wQf3VY{Z?gvV9;V%DX|u8$)|XR*Ucb89Ih1K)SF4Pc8cOdldt5%Jnzivp z5ASdps@xo}u^C;pUc1j!<*c?^RQjq4u7Yt{E3IlhW92=r3ZCXol|zr2a1ICxlP{#%}J@EKa0A@(lY}hw0j>Q zx4^q?4;mA3b4kCfIVSm*`3L$29@xSJDOGcT4ahZ(jcU2l?`Py1PT`kRN{&)1{7fL& zq!z(aC`kY{Nmv$%G7xB{n>kkAOlwqfC8Y|;8O$=sGYBcg@wV&a{YCol-7-1P%5{9Ccatc#Xix{Si zVat?s2}{u`jyn`h1INXy@0KBw4L(W9`04X3tDp~kw*>g+-UcX2D5Zi`GpJDsjCVS} zz=C@b#R39dQi6gz-N2PONX-K6oj_b(hz_zK`~QI2bk&Rmx3`jmEGkf#&d$Paw(}bIB;6F<(7Oit)<9BS}@zZ894dp;iR93 zCI16&`7s(ZuZwTT=~=RoKY?c{m-zEA@e}x_h?ZC`XUIjf@!Mf26={=ZgrR475b=WO zYBKHn?myT`Bs~Eb#0`T5;*3eJRLDw1?I(Z&Z5sylMCrrNdeG%z&?i>aX73YZBDDD= z#)h8(A@TiVCzl9Pi1H@zN!ha?NUnm{>v({UPT&XMe--TIawo7JOQVy+XnX>ANkz2rLAwlrB0P}o z6t)w-`Sc|rON!h@P=Q8HVLQ{#ZPrKr4oD(nUxH|_h=6`@8B_vM!oGx!LvBd`H5>%R z$-ZLAO-&0#==HaNBT-y;(q4obM`CT9!S5zLdi-4>s}Q|D5{tffT1t>-c5pD2W?=|7-ahEWZu6;y;>MvpE@*n%+0vf%9by0r1XHU2!?%bwNu`XpVT;EbAXVS)6wb*M&dCDi?eBOl?$moz*eNpO$aWN+im_D} zIFRECX3Ot5{zO2ETQ#@y%@I^TjoFfWCry#BaTdkdS2x@v$R3Dqhvo;+LasdG z5~Qo*%W?h(JayTsFP;3#_;L)~z@te%Y|BHtZ(y={-~1+krf*=f#7k$t374TA2eH=U zQ9PPP$~PQ@A%g5WoG)aV;+pR!U_Dv7{X#<67~2*l(j>xFME1^|*=SQD93dWf@Wd-9 zmxQ|rB6a=-G)_VS8EXxGJ;-6n<$#3`O_l#r#3FZ+lX))Ps|bEYE_7?qGP_v`s~ z2Lhup%hU1Y1>fxL7qaZgJsPt-9bbm+s;%g9I_wkY3>>*8$gF6y0sHxM25b>0{`KR} z1*rw)8S#l`9t@FX50#mCbA12L&4bGb*#G5ZBs0dvrEuH%nz#unDTY=opJ+h!QfMWX zp0ce(qf&@1Z%CJfE8`|?ltC>qPe1NN$7Fce#nX$%Q9~Xcc8Tk~%aKL+O|iInC{vKu z#nsmo!XPQz)l$H(iK~CE5H2P1wk6RhT8LQ|pN9l;6k(PO-I*Ijj`>x-pV(|6F#8AY}w0d zA4I!Vm@VgnY6Y5BVK(uawW09Z_SHjLRKIa9|r9*!3H92&&wAh6_Au5@-46jz3hUuBz!${sl5k*E4Ykv<|F5BkDWyz1{e2l(w!@jv?7e_}0S?A2xNT9At_(WR5S7UPoX~(T)I|Yi6rV2+O z)f^h&+heOuqjOc*XX5nnZINmiCCC+_m52Gkm^pYjABGCn9{mrh_r>Ir|2hMW`ruQE x8=aNmaLgMTZRBwRGPj#Ip<_H&;QriCzC{gdumVLd?5~T|!Rsjm^|zM%{{ka&TbV6;G@RZ#&$?nmy;js1{>e1||n2!z-*B!oafR1_|Vop|fo zwcTmEjpPBsKkC2l z^S;05_j{h__ilbCZSy;6&z~?>n0N!{s`t4)E?X^E%dy%@r^DD_tE4>6O2%Y%GWu$# zQNuRYI(;6t#=%f_y57}bA*=0Po7TZN2eVD}>{{B}5+R-1W(RGuwwKp;_SNhBJs}}z zYZdCcy2+l7>VCgk8+DOUhBfg~JG0Kl4L)XC%B~hx)9b3%bk=KyzDjH7dJoxA-_>I3 z*idWZ*SA^Clu*NHyit9PFSw>xu(|6z?G4evuT9I?-gZYM8gBDy{ZX66t~0bY&~Blp zr`ffk+uqWt4_QK;A<|vL^{wp;8k>2cqsQ1D9Q2vXSbi5LFHn%o!uy&H&CbdEE zlt-Ftx*3*lH-$XrntpYMoAN}XEtaUJx1062Y6f32FJWu#wNb$sb~qZ=2UqKYtxTm& zW36fSwhEllYt)AN`e>8dYxVi+`;1*ojce7qPItp#zJ;x*a*%GuqTx+uqsLlb&skWD zrNQoMa+-7R2?%@nwwGFkQRh^W&n)A^Ot(}!ZeV?ml?2M&6AICnB?jFm$ z^E7tjhA#~K;)cf=`!w)~bl^s_X9a`=05J>0ev-TySLwSioR%r=k{%e#&2N#y;SoR# zU^m(xW==uPrTw(#OzBt5-`Cx@VjvXed9s;lR)v})L6xQ@OsjY@qET@Xx|sl!Vk|mXj+Aypxoji|!3u9?y>Eexw^!K7+%=>d>{RFaBl zNR39L(&|D9h9ITV=`=c3OC(G&GObP<(M7ni>9HqQuB>7k%~r-?^?41fp0hPFbxbW) zX*aT5qgz8!u13Z{nOFyJqkUeR&Sm$yj0P>^Hn|&_D!tKaNTo?iqatY)#m}d7%PDp_ zNtd%)R!8&W@oexXS;dVq#O8vJGiF^=o+mk;AOC70Xw10^V9Ir9YEB1(8eqQO`3Edm z3P~2=@SFxLx!w)*vH!Wpgvb~S%RxuDS&nkl;koquuJVc%Ym}% zVCOkdmrKuhg8G{cLt3D|4z^nhmd`vMpVWf4lml1fyWCoaQmO|t&ASYz|2UlX<8bQ# zzym)-<8pP`HTVqKh-=^(%BB1`j9&v^649Q>5|{W!;ga@d|CRm zA2#g*JMp}(oYB}Yh-YS(kCaV|iu^Q*SHj#Pmcd&lfC}Ea7la8dcUjUs&43W!dVoH$1NjJLl$8n&?7au8~j=cmTnfR=t;b&m`5p*fHz4$F* z0i4{P@aHwuVXE)wD{$j$s6*8o?8C6=DAHs8f(Ps1p`*Y@6h3m#H%=u4rD&k431sKu zoV+JRxdOUNF$NAzAUnzTPnO1B2Luj@9Bell<&q(1-v-6RvbyuPIZI)1C_#1%y)N$k z%qz-E;0r^EFdRd#3`?W35mB)i&Lhyt@)Jk~ z{`H2KzZkwupmyFrflSEyLK=^~1LFCFRCQ{DpGx|pJ%^y8kJ^f0;2iQN)lg6YN6(?@ zZ+`tGEtDty+4u>Xp84))7I^p*G(9!seG@i)il)D1DLx)MpKvPkSjJgV!C&nMO2Z^d zgXI2+U4CuSk5iM#5AJ||8;nmPwqpOG-LU#|#CFpwBWgjDG^F4nGGxKoF*^)gL~JD= z-SuJY3zRrn?!jN(Eh<+ecR)7<+6YPi2~lxJas|#zp{YweZDao1lPl0SjYcbb_Sav+ z;b}ysBqR61i_?efaE| ziJj0uT?%#wuFTlvgd0<^Av|YlBmj#DY$v|7c63UYn6@3$pGbvh3##uvTd zTo}twa20*!`q1x9n!qU#M2v#_VL*X7a79=ghNB8>D^Ye}?*XAUX+pme)8iQ{zdjES zE77p>`cLnJP4m#OS>j)cWAjl>ndH=M4Wi=Cr24uNEJBoP*$4b9lj@%?!4~0pv-g`| zyach7RS&!Yt4k3}QPD(!;7h7sScX;L^k}pO2FehNI=JDp*s?@z75PG;sBBIqT*qRq zvfHg&z7!RqWWvv|h;7Nie~f{~Nr>A-1gF8qNrJC71Y+ z7O^c{2l`?>7Ri)l_Wt|lqP!y^Hw||gu_j`c{Tsc|p2$4VHuxUT~1@^d5wZiZ2IqX~q!RM$N=SI~OfqlFv?}F~n zQMF&XQ8lji=)>@W8|%(tTGj7~iZz%2MJZfUi~Z)N1@Ud7V)d03oB*Xz=Rv_J|F&S0 zzcaD$6g=%g?n|H9vpH6W#c^WsUzsldhJ_9I;i4?Z*mn^q=rvGd*W*qzw-8Myo-P1}C}u^U@s diff --git a/test/test_image_sharing.py b/test/test_image_sharing.py index 6f7245feb..e9b381555 100644 --- a/test/test_image_sharing.py +++ b/test/test_image_sharing.py @@ -43,7 +43,7 @@ class TestImageSharing(unittest.TestCase): def createStorage(self, docker_image_id, repository=REPO, username=ADMIN_ACCESS_USER): repository_obj = model.get_repository(repository.split('/')[0], repository.split('/')[1]) - image = model.create_or_link_image(docker_image_id, repository_obj, username) + image = model.create_or_link_image(docker_image_id, repository_obj, username, {}) return image.storage.id def assertSameStorage(self, docker_image_id, storage_id, repository=REPO, username=ADMIN_ACCESS_USER):