diff --git a/anvil/actions/uninstall.py b/anvil/actions/uninstall.py index 9cbd877a..af4b498d 100644 --- a/anvil/actions/uninstall.py +++ b/anvil/actions/uninstall.py @@ -57,19 +57,23 @@ class UninstallAction(action.Action): 'pre-uninstall', *removals ) - removals += ['install'] + + general_package = "general" + dependency_handler = self.distro.dependency_handler_class( + self.distro, self.root_dir, instances.values()) self._run_phase( action.PhaseFunctors( - start=lambda i: LOG.info('Uninstalling %s.', colorizer.quote(i.name)), - run=lambda i: i.uninstall(), + start=lambda i: LOG.info("Uninstalling packages"), + run=lambda i: dependency_handler.uninstall(), end=None, ), - component_order, - instances, - 'uninstall', + [general_package], + {general_package: instances[general_package]}, + "uninstall", *removals ) - removals += ['download', 'configure', "download-patch", 'pre-install', 'post-install'] + + removals += ['install', 'download', 'configure', "download-patch", 'pre-install', 'post-install'] self._run_phase( action.PhaseFunctors( start=lambda i: LOG.info('Post-uninstalling %s.', colorizer.quote(i.name)), diff --git a/anvil/components/base_install.py b/anvil/components/base_install.py index 8ced0fa5..05334d86 100644 --- a/anvil/components/base_install.py +++ b/anvil/components/base_install.py @@ -210,34 +210,13 @@ class PkgUninstallComponent(base.Component): for fn in sym_files: sh.unlink(fn, run_as_root=True) - def uninstall(self): - self._uninstall_pkgs() - self._uninstall_files() - def post_uninstall(self): + self._uninstall_files() self._uninstall_dirs() def pre_uninstall(self): pass - def _uninstall_pkgs(self): - pkgs = self.tracereader.packages_installed() - if pkgs: - pkg_names = set([p['name'] for p in pkgs]) - utils.log_iterable(pkg_names, logger=LOG, - header="Potentially removing %s distribution packages" % (len(pkg_names))) - which_removed = [] - with utils.progress_bar('Uninstalling', len(pkgs), reverse=True) as p_bar: - for (i, p) in enumerate(pkgs): - uninstaller = make_packager(p, self.distro.package_manager_class, - distro=self.distro, - remove_default=self.purge_packages) - if uninstaller.remove(p): - which_removed.append(p['name']) - p_bar.update(i + 1) - utils.log_iterable(which_removed, logger=LOG, - header="Actually removed %s distribution packages" % (len(which_removed))) - def _uninstall_files(self): files_touched = self.tracereader.files_touched() if files_touched: @@ -254,25 +233,3 @@ class PkgUninstallComponent(base.Component): header="Removing %s created directories" % (len(dirs_alive))) for dir_name in dirs_alive: sh.deldir(dir_name, run_as_root=True) - - -class PythonUninstallComponent(PkgUninstallComponent): - - def uninstall(self): - self._uninstall_python() - PkgUninstallComponent.uninstall(self) - - def _uninstall_python(self): - py_listing = self.tracereader.py_listing() - if py_listing: - py_listing_dirs = set() - for (_name, where) in py_listing: - py_listing_dirs.add(where) - utils.log_iterable(py_listing_dirs, logger=LOG, - header="Uninstalling %s python setups" % (len(py_listing_dirs))) - unsetup_cmd = self.distro.get_command('python', 'unsetup') - for where in py_listing_dirs: - if sh.isdir(where): - sh.execute(*unsetup_cmd, cwd=where, run_as_root=True) - else: - LOG.warn("No python directory found at %s - skipping", colorizer.quote(where, quote_color='red')) diff --git a/anvil/components/horizon.py b/anvil/components/horizon.py index c8cf00b4..a57e1cb9 100644 --- a/anvil/components/horizon.py +++ b/anvil/components/horizon.py @@ -38,9 +38,9 @@ SECRET_KEY_LEN = 10 BAD_APACHE_USERS = ['root'] -class HorizonUninstaller(binstall.PythonUninstallComponent): +class HorizonUninstaller(binstall.PkgUninstallComponent): def __init__(self, *args, **kargs): - binstall.PythonUninstallComponent.__init__(self, *args, **kargs) + binstall.PkgUninstallComponent.__init__(self, *args, **kargs) class HorizonInstaller(binstall.PythonInstallComponent): diff --git a/anvil/components/nova.py b/anvil/components/nova.py index b6aac688..382e8f91 100644 --- a/anvil/components/nova.py +++ b/anvil/components/nova.py @@ -61,9 +61,9 @@ FLOATING_NET_CMDS = [ ] -class NovaUninstaller(binstall.PythonUninstallComponent): +class NovaUninstaller(binstall.PkgUninstallComponent): def __init__(self, *args, **kargs): - binstall.PythonUninstallComponent.__init__(self, *args, **kargs) + binstall.PkgUninstallComponent.__init__(self, *args, **kargs) self.virsh = lv.Virsh(self.get_int_option('service_wait_seconds'), self.distro) def pre_uninstall(self): diff --git a/anvil/components/pkglist.py b/anvil/components/pkglist.py index c5a024ea..a3b76214 100644 --- a/anvil/components/pkglist.py +++ b/anvil/components/pkglist.py @@ -26,5 +26,5 @@ class Installer(binstall.PythonInstallComponent): return None -class Uninstaller(binstall.PythonUninstallComponent): +class Uninstaller(binstall.PkgUninstallComponent): pass diff --git a/anvil/packaging/base.py b/anvil/packaging/base.py index bcdb78e6..7aa6778e 100644 --- a/anvil/packaging/base.py +++ b/anvil/packaging/base.py @@ -159,6 +159,9 @@ class DependencyHandler(object): for pkg in inst.get_option("nopackages") or []: self.nopackages.append(pkg["name"]) + def uninstall(self): + pass + def clean_pip_requires(self, requires_files): # Fixup incompatible dependencies if not (requires_files and self.forced_packages): diff --git a/anvil/packaging/yum.py b/anvil/packaging/yum.py index a88f6a76..9d8d91b2 100644 --- a/anvil/packaging/yum.py +++ b/anvil/packaging/yum.py @@ -271,6 +271,18 @@ BuildArch: noarch sh.write_file( self.anvil_repo_filename, utils.expand_template(content, params)) + def _create_openstack_packages_list(self): + cmdline = [self.py2rpm_executable, "--convert"] + self.python_names + rpm_names = [] + # run as root since /tmp/pip-build-root must be owned by root + for name in sh.execute(*cmdline, run_as_root=True)[0].splitlines(): + # name is "Requires: rpm-name" + try: + rpm_names.append(name.split(":")[1].strip()) + except IndexError: + pass + return rpm_names + def install(self): super(YumDependencyHandler, self).install() with sh.Rooted(True): @@ -286,15 +298,15 @@ BuildArch: noarch sh.execute(*cmdline, run_as_root=True, stdout_fh=sys.stdout, stderr_fh=sys.stderr) - cmdline = [self.py2rpm_executable, "--convert"] + self.python_names - rpm_names = [] - # run as root since /tmp/pip-build-root must be owned by root - for name in sh.execute(*cmdline, run_as_root=True)[0].splitlines(): - # name is "Requires: rpm-name" - try: - rpm_names.append(name.split(":")[1].strip()) - except IndexError: - pass + rpm_names = self._create_openstack_packages_list() cmdline = ["yum", "install", "-y"] + rpm_names sh.execute(*cmdline, run_as_root=True, stdout_fh=sys.stdout, stderr_fh=sys.stderr) + + def uninstall(self): + super(YumDependencyHandler, self).uninstall() + rpm_names = self._create_openstack_packages_list() + cmdline = ["yum", "remove", "--remove-leaves", "-y"] + rpm_names + sh.execute(*cmdline, run_as_root=True, + stdout_fh=sys.stdout, stderr_fh=sys.stderr) + diff --git a/anvil/trace.py b/anvil/trace.py index d0aa6c3a..70b0cfd8 100644 --- a/anvil/trace.py +++ b/anvil/trace.py @@ -27,7 +27,6 @@ DOWNLOADED = "DOWNLOADED" FILE_TOUCHED = "FILE_TOUCHED" PIP_INSTALL = 'PIP_INSTALL' PKG_INSTALL = "PKG_INSTALL" -PYTHON_INSTALL = "PYTHON_INSTALL" SYMLINK_MAKE = "SYMLINK_MAKE" @@ -60,13 +59,6 @@ class TraceWriter(object): self.started = True self.dirs_made(*trace_dirs) - def py_installed(self, name, where): - self._start() - what = dict() - what['name'] = name - what['where'] = where - self.trace(PYTHON_INSTALL, json.dumps(what)) - def symlink_made(self, link): self._start() self.trace(SYMLINK_MAKE, link) @@ -147,16 +139,6 @@ class TraceReader(object): apps.append((entry.get('name'), entry.get('trace_fn'), entry.get('how'))) return apps - def py_listing(self): - lines = self.read() - py_entries = list() - for (cmd, action) in lines: - if cmd == PYTHON_INSTALL and len(action): - entry = json.loads(action) - if type(entry) is dict: - py_entries.append((entry.get("name"), entry.get("where"))) - return py_entries - def download_locations(self): lines = self.read() locations = list() @@ -210,16 +192,3 @@ class TraceReader(object): if type(pip_info_full) is dict: pips_installed.append(pip_info_full) return pips_installed - - def packages_installed(self): - lines = self.read() - pkgs_installed = list() - pkg_list = list() - for (cmd, action) in lines: - if cmd == PKG_INSTALL and len(action): - pkg_list.append(action) - for pkg_data in pkg_list: - pkg_info = json.loads(pkg_data) - if type(pkg_info) is dict: - pkgs_installed.append(pkg_info) - return pkgs_installed diff --git a/conf/distros/rhel.yaml b/conf/distros/rhel.yaml index 9845d6e1..062f22c6 100644 --- a/conf/distros/rhel.yaml +++ b/conf/distros/rhel.yaml @@ -49,7 +49,7 @@ components: running: anvil.components.cinder:CinderRuntime test: anvil.components.base_testing:PythonTestingComponent coverage: anvil.components.base_testing:PythonTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent pips: - name: hp3parclient cinder-client: @@ -58,7 +58,7 @@ components: running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.base_testing:PythonTestingComponent coverage: anvil.components.base_testing:PythonTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent db: action_classes: install: anvil.distros.rhel:DBInstaller @@ -142,7 +142,7 @@ components: running: anvil.components.glance:GlanceRuntime coverage: anvil.components:PythonTestingComponent test: anvil.components.glance:GlanceTester - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent packages: - name: MySQL-python pips: @@ -157,7 +157,7 @@ components: running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.glance_client:GlanceClientTester coverage: anvil.components.glance_client:GlanceClientTester - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent horizon: action_classes: install: anvil.distros.rhel:HorizonInstaller @@ -174,14 +174,14 @@ components: install: anvil.components.base_install:PythonInstallComponent running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.base_testing:EmptyTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent keystone: action_classes: install: anvil.components.keystone:KeystoneInstaller running: anvil.components.keystone:KeystoneRuntime test: anvil.components.keystone:KeystoneTester coverage: anvil.components.keystone:KeystoneTester - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent packages: - name: MySQL-python keystone-client: @@ -190,7 +190,7 @@ components: running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.base_testing:PythonTestingComponent coverage: anvil.components.base_testing:PythonTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent nova: action_classes: install: anvil.distros.rhel:NovaInstaller @@ -268,7 +268,7 @@ components: running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.base_testing:PythonTestingComponent coverage: anvil.components.base_testing:PythonTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent no-vnc: action_classes: install: anvil.components.base_install:PythonInstallComponent @@ -276,7 +276,7 @@ components: running: anvil.components.novnc:NoVNCRuntime test: anvil.components.base_testing:EmptyTestingComponent coverage: anvil.components.base_testing:EmptyTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent packages: - name: python-websockify - name: numpy @@ -286,35 +286,35 @@ components: running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.openstack_client:OpenStackClientTester coverage: anvil.components.openstack_client:OpenStackClientTester - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent oslo-config: action_classes: install: anvil.components.base_install:PythonInstallComponent running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.base_testing:PythonTestingComponent coverage: anvil.components.base_testing:PythonTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent oslo-incubator: action_classes: install: anvil.components.base_install:PythonInstallComponent running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.base_testing:PythonTestingComponent coverage: anvil.components.base_testing:PythonTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent quantum: action_classes: install: anvil.components.quantum:QuantumInstaller running: anvil.components.quantum:QuantumRuntime test: anvil.components.base_testing:PythonTestingComponent coverage: anvil.components.base_testing:PythonTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent quantum-client: action_classes: install: anvil.components.base_install:PythonInstallComponent running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.base_testing:PythonTestingComponent coverage: anvil.components.base_testing:PythonTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent rabbit-mq: action_classes: install: anvil.components.rabbit:RabbitInstaller @@ -346,5 +346,5 @@ components: running: anvil.components.base_runtime:EmptyRuntime test: anvil.components.base_testing:PythonTestingComponent coverage: anvil.components.base_testing:PythonTestingComponent - uninstall: anvil.components.base_install:PythonUninstallComponent + uninstall: anvil.components.base_install:PkgUninstallComponent ... diff --git a/tools/bootstrap/CommonRedHat b/tools/bootstrap/CommonRedHat index e2ae5a14..07adeec9 100644 --- a/tools/bootstrap/CommonRedHat +++ b/tools/bootstrap/CommonRedHat @@ -25,6 +25,7 @@ require python-psutil require python-iniparse require pylint require createrepo +require yum-plugin-remove-with-leaves # multipip dependencies require rpm-build