Package entropy :: Package services :: Package repository :: Module interfaces

Source Code for Module entropy.services.repository.interfaces

  1  # -*- coding: utf-8 -*- 
  2  ''' 
  3      # DESCRIPTION: 
  4      # Entropy Object Oriented Interface 
  5   
  6      Copyright (C) 2007-2009 Fabio Erculiani 
  7   
  8      This program is free software; you can redistribute it and/or modify 
  9      it under the terms of the GNU General Public License as published by 
 10      the Free Software Foundation; either version 2 of the License, or 
 11      (at your option) any later version. 
 12   
 13      This program is distributed in the hope that it will be useful, 
 14      but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16      GNU General Public License for more details. 
 17   
 18      You should have received a copy of the GNU General Public License 
 19      along with this program; if not, write to the Free Software 
 20      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21  ''' 
 22   
 23  from __future__ import with_statement 
 24  import os 
 25  from entropy.services.interfaces import SocketHost 
 26  from entropy.output import TextInterface, blue, brown 
 27  from entropy.const import etpConst, etpCache 
 28  from entropy.misc import TimeScheduled 
 29  from entropy.i18n import _ 
 30   
31 -class Server(SocketHost):
32
33 - class ServiceInterface(TextInterface):
34 - def __init__(self, *args, **kwargs):
35 pass
36 37 import entropy.tools as entropyTools 38 import entropy.dump as dumpTools
39 - def __init__(self, repositories, do_ssl = False, stdout_logging = True, **kwargs):
40 41 # instantiate critical constants 42 etpConst['socket_service']['max_connections'] = 5000 43 44 from entropy.services.repository.commands import Repository 45 self.RepositoryCommands = Repository 46 from entropy.db import dbapi2 47 self.dbapi2 = dbapi2 48 from entropy.client.interfaces import Client 49 self.Entropy = Client(noclientdb = 2) 50 self.do_ssl = do_ssl 51 self.LockScanner = None 52 self.syscache = { 53 'db': {}, 54 'db_trashed': set(), 55 'dbs_not_available': set(), 56 } 57 58 # setup System Settings 59 from entropy.core import SystemSettings 60 self.SystemSettings = SystemSettings() 61 self.SystemSettings['socket_service']['max_connections'] = 5000 62 63 etpConst['socketloglevel'] = 1 64 if not kwargs.has_key('external_cmd_classes'): 65 kwargs['external_cmd_classes'] = [] 66 kwargs['external_cmd_classes'].insert(0,self.RepositoryCommands) 67 SocketHost.__init__( 68 self, 69 self.ServiceInterface, 70 noclientdb = 2, 71 sock_output = self.Entropy, 72 ssl = do_ssl, 73 **kwargs 74 ) 75 self.stdout_logging = stdout_logging 76 self.repositories = repositories 77 self.expand_repositories() 78 # start timed lock file scanning 79 self.start_repository_lock_scanner()
80
81 - def killall(self):
82 SocketHost.killall(self) 83 if self.LockScanner != None: 84 self.LockScanner.kill()
85
87 self.LockScanner = TimeScheduled(0.5, self.lock_scan) 88 self.LockScanner.start()
89
90 - def set_repository_db_availability(self, repo_tuple):
91 self.repositories[repo_tuple]['enabled'] = False 92 mydbpath = os.path.join(self.repositories[repo_tuple]['dbpath'],etpConst['etpdatabasefile']) 93 if os.path.isfile(mydbpath) and os.access(mydbpath, os.W_OK): 94 self.syscache['dbs_not_available'].discard(repo_tuple) 95 self.repositories[repo_tuple]['enabled'] = True
96
97 - def is_repository_available(self, repo_tuple):
98 99 if repo_tuple not in self.repositories: 100 return None 101 # is repository being updated 102 if self.repositories[repo_tuple]['locked']: 103 return False 104 # repository database does not exist 105 if not self.repositories[repo_tuple]['enabled']: 106 return False 107 108 return True
109
110 - def lock_scan(self):
111 do_clear = set() 112 for repository,arch,product,branch in self.repositories: 113 x = (repository,arch,product,branch,) 114 self.set_repository_db_availability(x) 115 if not self.repositories[x]['enabled']: 116 if x in self.syscache['dbs_not_available']: 117 continue 118 self.syscache['dbs_not_available'].add(x) 119 mytxt = blue("%s.") % (_("database does not exist. Locking services for it"),) 120 self.updateProgress( 121 "[%s] %s" % ( 122 brown(str(x)), 123 mytxt, 124 ), 125 importance = 1, 126 type = "info" 127 ) 128 do_clear.add(repository) 129 continue 130 if os.path.isfile(self.repositories[x]['download_lock']) and \ 131 not self.repositories[x]['locked']: 132 self.repositories[x]['locked'] = True 133 mydbpath = os.path.join(self.repositories[x]['dbpath'],etpConst['etpdatabasefile']) 134 self.close_db(mydbpath) 135 self.eapi3_lock_repo(*x) 136 do_clear.add(repository) 137 mytxt = blue("%s.") % (_("database got locked. Locking services for it"),) 138 self.updateProgress( 139 "[%s] %s" % ( 140 brown(str(x)), 141 mytxt, 142 ), 143 importance = 1, 144 type = "info" 145 ) 146 elif not os.path.isfile(self.repositories[x]['download_lock']) and \ 147 self.repositories[x]['locked']: 148 mydbpath = os.path.join(self.repositories[x]['dbpath'],etpConst['etpdatabasefile']) 149 self.close_db(mydbpath) 150 mytxt = blue("%s. %s:") % ( 151 _("unlocking and indexing database"), 152 _("hash"), 153 ) 154 self.updateProgress( 155 "[%s] %s" % ( 156 brown(str(x)), 157 mytxt, 158 ), 159 importance = 1, 160 type = "info" 161 ) 162 # woohoo, got unlocked eventually 163 mydb = self.open_db(mydbpath, docache = False) 164 mydb.createAllIndexes() 165 self.updateProgress( 166 str(mydb.database_checksum(do_order = True, strict = False, strings = True)), 167 importance = 1, 168 type = "info" 169 ) 170 mydb.closeDB() 171 self.Entropy.clear_dump_cache(etpCache['repository_server']+"/"+repository+"/") 172 self.repositories[x]['locked'] = False 173 self.eapi3_unlock_repo(*x) 174 175 for repo in do_clear: 176 self.Entropy.clear_dump_cache(etpCache['repository_server']+"/"+repo+"/")
177
178 - def eapi3_lock_repo(self, repository, arch, product, branch):
179 lock_file = os.path.join(self.repositories[(repository, arch, product, branch,)]['dbpath'],etpConst['etpdatabaseeapi3lockfile']) 180 if not os.path.lexists(lock_file): 181 f = open(lock_file,"w") 182 f.write("this repository is EAPI3 locked") 183 f.flush() 184 f.close()
185
186 - def eapi3_unlock_repo(self, repository, arch, product, branch):
187 lock_file = os.path.join(self.repositories[(repository, arch, product, branch,)]['dbpath'],etpConst['etpdatabaseeapi3lockfile']) 188 if os.path.isfile(lock_file): 189 os.remove(lock_file)
190
191 - def get_dcache(self, item, repo = '_norepo_'):
192 return self.dumpTools.loadobj(etpCache['repository_server']+"/"+repo+"/"+str(hash(item)))
193
194 - def set_dcache(self, item, data, repo = '_norepo_'):
195 self.dumpTools.dumpobj(etpCache['repository_server']+"/"+repo+"/"+str(hash(item)),data)
196
197 - def close_db(self, dbpath):
198 try: 199 dbc = self.syscache['db'].pop(dbpath) 200 dbc.closeDB() 201 except KeyError: 202 pass 203 except self.dbapi2.ProgrammingError: 204 # they've been opened by the Commands Processor 205 self.syscache['db_trashed'].add(dbc)
206
207 - def open_db(self, dbpath, docache = True):
208 if docache: 209 cached = self.syscache['db'].get(dbpath) 210 if cached != None: 211 return cached 212 dbc = self.Entropy.open_generic_database( 213 dbpath, 214 xcache = False, 215 readOnly = True, 216 skipChecks = True 217 ) 218 if docache: 219 self.syscache['db'][dbpath] = dbc 220 return dbc
221
222 - def expand_repositories(self):
223 224 for repository,arch,product, branch in self.repositories: 225 x = (repository,arch,product,branch,) 226 self.repositories[x]['locked'] = True # loading locked 227 self.set_repository_db_availability(x) 228 mydbpath = self.repositories[x]['dbpath'] 229 myrevfile = os.path.join(mydbpath,etpConst['etpdatabaserevisionfile']) 230 myrev = '0' 231 if os.path.isfile(myrevfile): 232 while 1: 233 try: 234 f = open(myrevfile) 235 myrev = f.readline().strip() 236 f.close() 237 except IOError: # should never happen but who knows 238 continue 239 break 240 self.repositories[x]['dbrevision'] = myrev 241 self.repositories[x]['download_lock'] = os.path.join( 242 mydbpath, 243 etpConst['etpdatabasedownloadlockfile'] 244 )
245