1
2 """
3
4 @author: Fabio Erculiani <lxnay@sabayonlinux.org>
5 @contact: lxnay@sabayonlinux.org
6 @copyright: Fabio Erculiani
7 @license: GPL-2
8
9 B{Entropy Services Repository Management Interface}.
10
11 """
12
13 from __future__ import with_statement
14 import os
15 import shutil
16 from entropy.services.interfaces import SocketHost
17 from entropy.output import TextInterface, blue, brown, darkred, darkgreen
18 from entropy.const import etpConst, etpCache
19 from entropy.misc import TimeScheduled
20 from entropy.i18n import _
21
23
27
28 import entropy.tools as entropyTools
29 import entropy.dump as dumpTools
30 - def __init__(self, repositories, do_ssl = False, stdout_logging = True, **kwargs):
71
76
80
82 self.repositories[repo_tuple]['enabled'] = False
83 mydbpath = os.path.join(self.repositories[repo_tuple]['dbpath'],etpConst['etpdatabasefile'])
84 if os.path.isfile(mydbpath) and os.access(mydbpath, os.W_OK):
85 self.syscache['dbs_not_available'].discard(repo_tuple)
86 self.repositories[repo_tuple]['enabled'] = True
87
89
90 if repo_tuple not in self.repositories:
91 return None
92
93 if self.repositories[repo_tuple]['locked']:
94 return False
95
96 if not self.repositories[repo_tuple]['enabled']:
97 return False
98
99 return True
100
102 do_clear = set()
103 for repository, arch, product, branch in self.repositories:
104 x = (repository,arch,product,branch,)
105 self.set_repository_db_availability(x)
106 if not self.repositories[x]['enabled']:
107 if x in self.syscache['dbs_not_available']:
108 continue
109 self.syscache['dbs_not_available'].add(x)
110 mytxt = blue("%s.") % (_("database does not exist. Locking services for it"),)
111 self.updateProgress(
112 "[%s] %s" % (
113 brown(str(x)),
114 mytxt,
115 ),
116 importance = 1,
117 type = "info"
118 )
119 do_clear.add(repository)
120 continue
121 if os.path.isfile(self.repositories[x]['download_lock']) and \
122 not self.repositories[x]['locked']:
123 self.repositories[x]['locked'] = True
124 mydbpath = os.path.join(self.repositories[x]['dbpath'],etpConst['etpdatabasefile'])
125 self.close_db(mydbpath)
126 self.eapi3_lock_repo(*x)
127 do_clear.add(repository)
128 mytxt = blue("%s.") % (_("database got locked. Locking services for it"),)
129 self.updateProgress(
130 "[%s] %s" % (
131 brown(str(x)),
132 mytxt,
133 ),
134 importance = 1,
135 type = "info"
136 )
137 elif not os.path.isfile(self.repositories[x]['download_lock']) and \
138 self.repositories[x]['locked']:
139
140
141 dbpath = self.repositories[x]['dbpath']
142 cmethod = self.repositories[x]['cmethod']
143 cmethod_data = etpConst['etpdatabasecompressclasses'].get(cmethod)
144 unpack_method = cmethod_data[1]
145 compressed_dbfile = etpConst[cmethod_data[2]]
146 compressed_dbpath = os.path.join(dbpath, compressed_dbfile)
147
148 if not os.access(compressed_dbpath, os.R_OK | os.F_OK | os.W_OK):
149 mytxt = darkred("%s: %s !!") % (
150 _("cannot unlock database, compressed file not found"),
151 compressed_dbpath,
152 )
153 self.updateProgress(
154 "[%s] %s" % (
155 brown(str(x)),
156 mytxt,
157 ),
158 importance = 1,
159 type = "warning"
160 )
161 self.syscache['dbs_not_available'].add(x)
162 do_clear.add(repository)
163 continue
164
165
166 mydbpath = os.path.join(dbpath, etpConst['etpdatabasefile'])
167 self.close_db(mydbpath)
168
169 mytxt = blue("%s: %s") % (
170 _("unpacking compressed database"),
171 compressed_dbpath,
172 )
173 self.updateProgress(
174 "[%s] %s" % (
175 brown(str(x)),
176 mytxt,
177 ),
178 importance = 1,
179 type = "info"
180 )
181
182
183 unpack_func = getattr(self.entropyTools, unpack_method)
184 generated_outpath = unpack_func(compressed_dbpath)
185 if mydbpath != generated_outpath:
186 try:
187 os.rename(generated_outpath, mydbpath)
188 except OSError:
189 shutil.move(generated_outpath, mydbpath)
190
191 mytxt = blue("%s. %s:") % (
192 _("unlocking and indexing database"),
193 _("hash"),
194 )
195 self.updateProgress(
196 "[%s] %s" % (
197 brown(str(x)),
198 mytxt,
199 ),
200 importance = 1,
201 type = "info"
202 )
203
204 mydb = self.open_db(mydbpath, docache = False)
205 mydb.createAllIndexes()
206 self.updateProgress(
207 darkgreen(str(mydb.checksum(do_order = True, strict = False, strings = True))),
208 importance = 1,
209 type = "info"
210 )
211 mydb.closeDB()
212 self.Entropy.clear_dump_cache(etpCache['repository_server']+"/"+repository+"/")
213 self.repositories[x]['locked'] = False
214 self.eapi3_unlock_repo(*x)
215
216 for repo in do_clear:
217 self.Entropy.clear_dump_cache(etpCache['repository_server']+"/"+repo+"/")
218
220 lock_file = os.path.join(self.repositories[(repository, arch, product, branch,)]['dbpath'],etpConst['etpdatabaseeapi3lockfile'])
221 if not os.path.lexists(lock_file):
222 f = open(lock_file,"w")
223 f.write("this repository is EAPI3 locked")
224 f.flush()
225 f.close()
226
228 lock_file = os.path.join(self.repositories[(repository, arch, product, branch,)]['dbpath'],etpConst['etpdatabaseeapi3lockfile'])
229 if os.path.isfile(lock_file):
230 os.remove(lock_file)
231
233 return self.dumpTools.loadobj(etpCache['repository_server']+"/"+repo+"/"+str(hash(item)))
234
235 - def set_dcache(self, item, data, repo = '_norepo_'):
236 self.dumpTools.dumpobj(etpCache['repository_server']+"/"+repo+"/"+str(hash(item)),data)
237
239 try:
240 dbc = self.syscache['db'].pop(dbpath)
241 dbc.closeDB()
242 except KeyError:
243 pass
244 except self.dbapi2.ProgrammingError:
245
246 self.syscache['db_trashed'].add(dbc)
247
248 - def open_db(self, dbpath, docache = True):
249 if docache:
250 cached = self.syscache['db'].get(dbpath)
251 if cached != None:
252 return cached
253 dbc = self.Entropy.open_generic_database(
254 dbpath,
255 xcache = False,
256 readOnly = True,
257 skipChecks = True
258 )
259 if docache:
260 self.syscache['db'][dbpath] = dbc
261 return dbc
262
264
265 for repository, arch, product, branch in self.repositories:
266 x = (repository,arch,product,branch,)
267 self.repositories[x]['locked'] = True
268 self.set_repository_db_availability(x)
269 mydbpath = self.repositories[x]['dbpath']
270 myrevfile = os.path.join(mydbpath,etpConst['etpdatabaserevisionfile'])
271 myrev = '0'
272 if os.path.isfile(myrevfile):
273 while 1:
274 try:
275 f = open(myrevfile)
276 myrev = f.readline().strip()
277 f.close()
278 except IOError:
279 continue
280 break
281 self.repositories[x]['dbrevision'] = myrev
282 self.repositories[x]['download_lock'] = os.path.join(
283 mydbpath,
284 etpConst['etpdatabasedownloadlockfile']
285 )
286 if not self.repositories[x].has_key('cmethod'):
287 raise AttributeError("cmethod not specified for: %s" % (x,))
288 if self.repositories[x]['cmethod'] not in etpConst['etpdatabasesupportedcformats']:
289 raise AttributeError("wrong cmethod for: %s" % (x,))
290