1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
# Copyright 2008 The Tor Project, Inc. See LICENSE for licensing information.
import atexit
import shelve
import logging
import thandy.util
import thandy.formats
import thandy.packagesys.PackageSystem as PS
class SimplePackageDB:
"""Trivial wrapper around Python's shelve module to provide storage for
installation information for package items that don't automatically
record their presence.
"""
def __init__(self, filename):
thandy.util.ensureParentDir(filename)
self._db = shelve.open(filename, 'c')
atexit.register(self.close)
def close(self):
self._db.close()
def setVersion(self, package, version, filelist):
self._db['pv_%s'%str(package)] = (version, filelist)
def setInstallParameters(self, package, params):
self._db['ip_%s'%str(package)] = params
def setManifest(self, package, fnameToDigest):
self._db['mf_%s'%str(package)] = fnameToDigest
def getCurVersion(self, package):
v = self._db.get('pv_%s'%str(package))
if v != None:
return v[0]
else:
return None
def getInstallParameters(self, package):
return self._db.get('pi_%s'%str(package))
def getManifest(self, package):
return self._db.get('mf_%s'%str(package), {})
def removeAll(self, package):
for template in ["pv_%s", "ip_%s", "mf_%s"]:
try:
del self._db[template % str(package)]
except KeyError:
pass
_DB_INSTANCE = None
def getPackageDBInstance():
global _DB_INSTANCE
if _DB_INSTANCE == None:
fname = thandy.util.userFilename("db/packages")
logging.info("Opening package database in %s", fname)
_DB_INSTANCE = SimplePackageDB(fname)
return _DB_INSTANCE
class _DBMixin:
def setDB(self, db):
self._db = db
def getDB(self):
if self._db is None:
self._db = getPackageDBInstance()
return self._db
class DBChecker(PS.Checker, _DBMixin):
def __init__(self, name, version):
PS.Checker.__init__(self)
self._name = name
self._version = version
self._db = None
def __repr__(self):
return "DBChecker(%r, %r)"%(self._name, self._version)
# def checkInstall(self):
# if not self.isInstalled():
# return False
# else:
# return self._checkManifest()
#
# def _getInstallRoot(self):
# return "/"
#
# def _checkManifest(self):
# manifest = self.getDB().getManifest(self._name)
# root = self._getInstallRoot()
# all_ok = True
# for fname, digest_want in manifest:
# real_fname = os.path.join(self._getInstallRoot(), fname)
# logging.info("Checking digest on %s", fname)
# try:
# digest = thandy.formats.getFileDigest(real_fname):
# if digest != digest_want:
# logging.warn("Digest on %s not as expected", real_fname)
# all_ok = False
# except OSError:
# logging.warn("File %s not found.", real_fname)
# all_ok = False
# return all_ok
#
def getInstalledVersions(self):
return [ self.getDB().getCurVersion(self._name) ]
def isInstalled(self):
return self._version in self.getInstalledVersions()
class DBInstaller(PS.Installer, _DBMixin):
def __init__(self, name, version, relPath, installer):
PS.Installer.__init__(self, relPath)
self._name = name
self._version = version
self._installer = installer
def __repr__(self):
return "DBInstaller(%r, %r, %r, %r)"%(self._name,
self._version,
self._relPath,
self._installer)
def setTransaction(self, transaction):
self._installer.setTransaction(transaction)
def setCacheRoot(self, cacheRoot):
self._installer.setCacheRoot(cacheRoot)
def install(self):
self._installer.install()
params, manifest = self._installer.getInstallResult()
self.getDB().setCurVersion(self._name, self._version)
if params != None:
self.getDB().getInstallParameters(self._name, params)
if manifest != None:
self.getDB().setManifest(self._name, manifest)
def remove(self):
self._installer.remove()
self.getDB().removeAll(self._name)
|