Skip to content

Instantly share code, notes, and snippets.

@jorgenschaefer
Created November 2, 2013 12:33
Show Gist options
  • Save jorgenschaefer/7278462 to your computer and use it in GitHub Desktop.
Save jorgenschaefer/7278462 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# Simple server cleanup script for Debian.
# Author: Jorgen Schaefer <[email protected]>
# License: GPL
# Takes a list of wanted packages (comments with # allowed), marks
# everything else as automatically installed, uses apt-get autoremove
# to clean up the packages, and then checks whether any installed
# package versions are not even available from any currently
# configured sources.
import os
import subprocess
import sys
def main():
if len(sys.argv) != 2:
exit("usage: checksystem <packagelist.txt>")
print("Marking unwanted packages as automatically installed")
mark_auto(pkg for (pkg, ver) in get_installed_packages())
mark_manual(get_wanted_packages(sys.argv[1]))
print("Uninstalling superfluous packages")
subprocess.check_call(["apt-get", "autoremove"])
print("Checking available packages")
available = get_available_packages()
for pkg, ver in get_installed_packages():
if pkg not in available:
print("{0} version {1} installed, but not available"
.format(pkg, ver))
elif ver not in available[pkg]:
print("{0} version {1} installed, but only {2} available"
.format(pkg, ver, ", ".join(available[pkg])))
print("All done")
def get_wanted_packages(pkgfile):
with open(pkgfile) as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
yield line
def get_available_packages():
available = {}
for filename in os.listdir("/var/lib/apt/lists/"):
if filename.endswith("_Packages"):
pkg = None
ver = None
with open(os.path.join("/var/lib/apt/lists/", filename)) as f:
for line in f:
if line.startswith("Package:"):
_, pkg = line.strip().split(": ")
elif line.startswith("Version:"):
_, ver = line.strip().split(": ")
elif line.strip() == '':
if pkg is not None and ver is not None:
available.setdefault(pkg, set())
available[pkg].add(ver)
return available
def get_installed_packages():
p = subprocess.Popen(["dpkg", "-l"], stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
for line in stdout.split("\n"):
if line.startswith("ii"):
cols = line.split()
pkg = cols[1]
ver = cols[2]
yield pkg, ver
def mark_auto(packages):
with open("/dev/null", "w") as devnull:
subprocess.check_call(["apt-get", "markauto"] + list(packages),
stdout=devnull)
def mark_manual(packages):
with open("/dev/null", "w") as devnull:
subprocess.check_call(["apt-get", "unmarkauto"] + list(packages),
stdout=devnull)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment