* fix 571:

- refactor remove operation for a builder pattern
  - smart remove
    - first write, then remove leftover files
    - don't remove entries from db until necessary
  - tested, but needs more testing to see if it has
    not broken anything
* unremoved stuff:
  - give a warning
  - something's fishy there. what's the deal with all
    the directories that are remnant of removed packages?
This commit is contained in:
Eray Özkural
2005-10-03 10:12:53 +00:00
parent c83fac8f89
commit d1e4858091
2 changed files with 67 additions and 36 deletions
+23 -6
View File
@@ -49,7 +49,7 @@ class Installer:
self.ask_reinstall = ask_reinstall
self.check_requirements()
self.check_relations()
self.reinstall()
self.check_reinstall()
self.extract_install()
self.store_pisi_files()
if ctx.comard:
@@ -81,11 +81,12 @@ class Installer:
' not satisfied')
raise InstallError("Package not installable")
def reinstall(self):
"check reinstall, confirm action, and remove package if reinstall"
def check_reinstall(self):
"check reinstall, confirm action, and schedule reinstall"
pkg = self.pkginfo
self.reinstall = False
if ctx.installdb.is_installed(pkg.name): # is this a reinstallation?
(iversion, irelease, ibuild) = ctx.installdb.get_version(pkg.name)
@@ -130,15 +131,28 @@ class Installer:
if not ctx.ui.confirm(x):
raise InstallError('Package downgrade declined')
# remove old package then
operations.remove_single(pkg.name)
# schedule for reinstall
self.old_files = ctx.installdb.files(pkg.name)
self.reinstall = True
operations.run_preremove(pkg.name)
def extract_install(self):
"unzip package in place"
ctx.ui.info('Extracting files,')
self.package.extract_dir_flat('install', ctx.config.destdir)
if self.reinstall:
# remove left over files
new = set(map(lambda x: str(x.path), self.files.list))
old = set(map(lambda x: str(x.path), self.old_files.list))
leftover = old - new
old_fileinfo = {}
for fileinfo in self.old_files.list:
old_fileinfo[str(fileinfo.path)] = fileinfo
for path in leftover:
operations.remove_file( old_fileinfo[path] )
def store_pisi_files(self):
"""put files.xml, metadata.xml, actions.py and COMAR scripts
somewhere in the file system. We'll need these in future..."""
@@ -179,6 +193,9 @@ class Installer:
def update_databases(self):
"update databases"
if self.reinstall:
operations.remove_db(self.metadata.package.name)
# installdb
ctx.installdb.install(self.metadata.package.name,
self.metadata.package.version,
+44 -30
View File
@@ -21,6 +21,45 @@ from pisi.uri import URI
# single package operations
# remove stuff
def remove_file(fileinfo):
fpath = os.path.join(ctx.config.destdir, fileinfo.path)
# TODO: We have to store configuration files for futher
# usage. Currently we'are doing it like rpm does, saving
# with a prefix and leaving the user to edit it. In the future
# we'll have a plan for these configuration files.
if fileinfo.type == ctx.const.conf:
if os.path.isfile(fpath):
os.rename(fpath, fpath + ".pisi")
else:
# check if file is removed manually.
# And we don't remove directories!
# TODO: remove directory if there is nothing under it?
if os.path.isfile(fpath) or os.path.islink(fpath):
os.unlink(fpath)
else:
ctx.ui.warning('Not removing non-file, non-link %d' % fpath)
def run_preremove(package_name):
if ctx.comard:
com = ctx.comard
# TODO: run preremove scripts...
# com.call("System.Package", "preremove")
com.remove(package_name)
while 1:
reply = com.read_cmd()
if reply[0] == com.RESULT:
break
elif reply[1] == com.ERROR:
raise Error, "COMAR.remove failed!"
def remove_db(package_name):
ctx.installdb.remove(package_name)
packagedb.remove_package(package_name) #FIXME: this looks like a mistake!
def remove_single(package_name):
"""Remove a single package"""
inst_packagedb = packagedb.inst_packagedb
@@ -31,38 +70,13 @@ def remove_single(package_name):
if not ctx.installdb.is_installed(package_name):
raise Exception('Trying to remove nonexistent package '
+ package_name)
if ctx.comard:
com = ctx.comard
# TODO: run preremove scripts...
# com.call("System.Package", "preremove")
com.remove(package_name)
while 1:
reply = com.read_cmd()
if reply[0] == com.RESULT:
break
elif reply[1] == com.ERROR:
raise Error, "COMAR.remove failed!"
run_preremove(package_name)
for fileinfo in ctx.installdb.files(package_name).list:
fpath = os.path.join(ctx.config.destdir, fileinfo.path)
# TODO: We have to store configuration files for futher
# usage. Currently we'are doing it like rpm does, saving
# with a prefix and leaving the user to edit it. In the future
# we'll have a plan for these configuration files.
if fileinfo.type == ctx.const.conf:
if os.path.isfile(fpath):
os.rename(fpath, fpath + ".pisi")
else:
# check if file is removed manually.
# And we don't remove directories!
# FIXME: should give a warning if it is...
if os.path.isfile(fpath) or os.path.islink(fpath):
os.unlink(fpath)
remove_file(fileinfo)
ctx.installdb.remove(package_name)
packagedb.remove_package(package_name)
remove_db(package_name)
def install_single(pkg, upgrade = False):
"""install a single package from URI or ID"""