|
@ -1,13 +1,16 @@ |
|
|
"""EasyEngine package installation using apt-get module.""" |
|
|
"""EasyEngine package installation using apt-get module.""" |
|
|
import apt |
|
|
import apt |
|
|
|
|
|
import apt_pkg |
|
|
import sys |
|
|
import sys |
|
|
|
|
|
from ee.core.logging import Log |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EEAptGet(): |
|
|
class EEAptGet(): |
|
|
"""Generic apt-get intialisation""" |
|
|
"""Generic apt-get intialisation""" |
|
|
|
|
|
|
|
|
def update(): |
|
|
def update(self): |
|
|
"""Similar to apt-get update""" |
|
|
"""Similar to apt-get update""" |
|
|
|
|
|
|
|
|
# app.log.debug("Update cache") |
|
|
# app.log.debug("Update cache") |
|
|
cache = apt.Cache() |
|
|
cache = apt.Cache() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
@ -15,7 +18,7 @@ class EEAptGet(): |
|
|
cache.update(fprogress) |
|
|
cache.update(fprogress) |
|
|
cache.close() |
|
|
cache.close() |
|
|
|
|
|
|
|
|
def upgrade(packages): |
|
|
def upgrade(self, packages): |
|
|
"""Similar to apt-get update""" |
|
|
"""Similar to apt-get update""" |
|
|
cache = apt.Cache() |
|
|
cache = apt.Cache() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
@ -63,7 +66,7 @@ class EEAptGet(): |
|
|
return(False) |
|
|
return(False) |
|
|
return(True) |
|
|
return(True) |
|
|
|
|
|
|
|
|
def install(packages): |
|
|
def install(self, packages): |
|
|
"""Installation of packages""" |
|
|
"""Installation of packages""" |
|
|
cache = apt.Cache() |
|
|
cache = apt.Cache() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
@ -97,6 +100,7 @@ class EEAptGet(): |
|
|
with cache.actiongroup(): |
|
|
with cache.actiongroup(): |
|
|
# Mark Package for Installation |
|
|
# Mark Package for Installation |
|
|
pkg.mark_install() |
|
|
pkg.mark_install() |
|
|
|
|
|
pkg.mark_auto(auto=False) |
|
|
my_selected_packages.append(pkg.name) |
|
|
my_selected_packages.append(pkg.name) |
|
|
|
|
|
|
|
|
# Check if packages available for install. |
|
|
# Check if packages available for install. |
|
@ -110,7 +114,7 @@ class EEAptGet(): |
|
|
.format(req_download=cache.required_download)) |
|
|
.format(req_download=cache.required_download)) |
|
|
print("After this operation, {space} bytes of" |
|
|
print("After this operation, {space} bytes of" |
|
|
"additional disk space will be used." |
|
|
"additional disk space will be used." |
|
|
.format(space=cache.required_space)) |
|
|
.format(space=cache.required_space/1e6)) |
|
|
try: |
|
|
try: |
|
|
# Commit changes in cache (actually install) |
|
|
# Commit changes in cache (actually install) |
|
|
cache.commit(fprogress, iprogress) |
|
|
cache.commit(fprogress, iprogress) |
|
@ -122,7 +126,7 @@ class EEAptGet(): |
|
|
cache.close() |
|
|
cache.close() |
|
|
return(True) |
|
|
return(True) |
|
|
|
|
|
|
|
|
def remove(packages, auto=True, purge=False): |
|
|
def remove(self, packages, auto=False, purge=False): |
|
|
def __dependencies_loop(cache, deplist, pkg, onelevel=True): |
|
|
def __dependencies_loop(cache, deplist, pkg, onelevel=True): |
|
|
""" Loops through pkg's dependencies. |
|
|
""" Loops through pkg's dependencies. |
|
|
Returns a list with every package found. """ |
|
|
Returns a list with every package found. """ |
|
@ -132,15 +136,18 @@ class EEAptGet(): |
|
|
return |
|
|
return |
|
|
for depf in pkg.installed.dependencies: |
|
|
for depf in pkg.installed.dependencies: |
|
|
for dep in depf: |
|
|
for dep in depf: |
|
|
if (dep.name in cache and not cache[dep.name] |
|
|
# if (dep.name in cache and not cache[dep.name] |
|
|
in deplist): |
|
|
# in deplist): |
|
|
deplist.append(cache[dep.name]) |
|
|
# deplist.append(cache[dep.name]) |
|
|
__dependencies_loop(cache, deplist, cache[dep.name]) |
|
|
# __dependencies_loop(cache, deplist, cache[dep.name]) |
|
|
if onelevel: |
|
|
# if onelevel: |
|
|
if dep.name in cache: |
|
|
if dep.name in cache: |
|
|
|
|
|
if (cache[dep.name].is_installed and |
|
|
|
|
|
not cache[dep.name].is_auto_installed and |
|
|
|
|
|
not cache[dep.name].marked_delete): |
|
|
onelevellist.append(cache[dep.name]) |
|
|
onelevellist.append(cache[dep.name]) |
|
|
if onelevel: |
|
|
# if onelevel: |
|
|
return onelevellist |
|
|
return onelevellist |
|
|
|
|
|
|
|
|
cache = apt.Cache() |
|
|
cache = apt.Cache() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
@ -154,68 +161,37 @@ class EEAptGet(): |
|
|
cache.open() |
|
|
cache.open() |
|
|
for package in packages: |
|
|
for package in packages: |
|
|
print("processing", package) |
|
|
print("processing", package) |
|
|
package = cache[package] |
|
|
try: |
|
|
if not package.is_installed: |
|
|
pkg = cache[package] |
|
|
print("Package '{package_name}' is not installed," |
|
|
except KeyError as e: |
|
|
" so not removed." |
|
|
Log.debug(self, "{0}".format(e)) |
|
|
.format(package_name=package.name)) |
|
|
|
|
|
continue |
|
|
continue |
|
|
if package.marked_delete: |
|
|
if not pkg.is_installed: |
|
|
my_selected_packages.append(package.name) |
|
|
Log.info(self, "Package '{package_name}' is not installed," |
|
|
# Mark for deletion the first package, to fire up |
|
|
" so not removed." |
|
|
# auto_removable Purge? |
|
|
.format(package_name=pkg.name)) |
|
|
if purge: |
|
|
|
|
|
package.mark_delete(purge=True) |
|
|
|
|
|
else: |
|
|
|
|
|
package.mark_delete(purge=False) |
|
|
|
|
|
continue |
|
|
continue |
|
|
else: |
|
|
my_selected_packages.append(pkg.name) |
|
|
my_selected_packages.append(package.name) |
|
|
print(my_selected_packages) |
|
|
print(my_selected_packages) |
|
|
# How logic works: |
|
|
# How logic works: |
|
|
# 1) We loop trough dependencies's dependencies and add them to |
|
|
# 1) We loop trough dependencies's dependencies and add them to |
|
|
# the list. |
|
|
# the list. |
|
|
# 2) We sequentially remove every package in list |
|
|
# 2) We sequentially remove every package in list |
|
|
# - via is_auto_installed we check if we can safely remove it |
|
|
# - via is_auto_installed we check if we can safely remove it |
|
|
deplist = [] |
|
|
deplist = [] |
|
|
onelevel = __dependencies_loop(cache, deplist, pkg, |
|
|
onelevel = __dependencies_loop(cache, deplist, package, |
|
|
onelevel=True) |
|
|
onelevel=True) |
|
|
# Mark for deletion the first package, to fire up |
|
|
# Mark for deletion the first package, to fire up |
|
|
# auto_removable Purge? |
|
|
# auto_removable Purge? |
|
|
packages = packages + onelevel |
|
|
|
|
|
try: |
|
|
if purge: |
|
|
if purge: |
|
|
package.mark_delete(purge=True) |
|
|
pkg.mark_delete(purge=True) |
|
|
else: |
|
|
|
|
|
package.mark_delete(purge=False) |
|
|
|
|
|
|
|
|
|
|
|
# Also ensure we remove AT LEAST the first level of |
|
|
|
|
|
# dependencies (that is, the actual package's dependencies). |
|
|
|
|
|
if auto: |
|
|
|
|
|
markedauto = [] |
|
|
|
|
|
for pkg in onelevel: |
|
|
|
|
|
if (not pkg.marked_install and pkg.is_installed |
|
|
|
|
|
and not pkg.is_auto_installed): |
|
|
|
|
|
pkg.mark_auto() |
|
|
|
|
|
markedauto.append(pkg) |
|
|
|
|
|
|
|
|
|
|
|
for pkg in deplist: |
|
|
|
|
|
if (not pkg.marked_install and pkg.is_installed and |
|
|
|
|
|
pkg.is_auto_removable): |
|
|
|
|
|
# Purge? |
|
|
|
|
|
if purge: |
|
|
|
|
|
pkg.mark_delete(purge=True) |
|
|
|
|
|
else: |
|
|
|
|
|
pkg.mark_delete(purge=False) |
|
|
|
|
|
# Restore auted items |
|
|
|
|
|
for pkg in markedauto: |
|
|
|
|
|
if not pkg.marked_delete: |
|
|
|
|
|
pkg.mark_auto(False) |
|
|
|
|
|
else: |
|
|
else: |
|
|
# We need to ensure that the onelevel packages are not |
|
|
pkg.mark_delete(purge=False) |
|
|
# marked as automatically installed, otherwise the user may |
|
|
except SystemError as e: |
|
|
# drop them via autoremove or aptitude. |
|
|
Log.debug(self, "{0}".format(e)) |
|
|
for pkg in onelevel: |
|
|
Log.error(self, "Unable to purge packages.") |
|
|
if pkg.is_installed and pkg.is_auto_installed: |
|
|
|
|
|
pkg.mark_auto(auto=False) |
|
|
|
|
|
|
|
|
|
|
|
# Check if packages available for remove/update. |
|
|
# Check if packages available for remove/update. |
|
|
if cache.delete_count > 0: |
|
|
if cache.delete_count > 0: |
|
@ -239,7 +215,7 @@ class EEAptGet(): |
|
|
cache.close() |
|
|
cache.close() |
|
|
return(True) |
|
|
return(True) |
|
|
|
|
|
|
|
|
def is_installed(package): |
|
|
def is_installed(self, package): |
|
|
cache = apt.Cache() |
|
|
cache = apt.Cache() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
|
fprogress = apt.progress.text.AcquireProgress() |
|
|
iprogress = apt.progress.base.InstallProgress() |
|
|
iprogress = apt.progress.base.InstallProgress() |
|
@ -258,6 +234,8 @@ class EEAptGet(): |
|
|
else: |
|
|
else: |
|
|
cache.close() |
|
|
cache.close() |
|
|
return False |
|
|
return False |
|
|
|
|
|
except KeyError as e: |
|
|
|
|
|
Log.debug(self, "{0}".format(e)) |
|
|
except Exception as e: |
|
|
except Exception as e: |
|
|
cache.close() |
|
|
cache.close() |
|
|
return False |
|
|
return False |
|
|