Created
November 2, 2013 12:33
-
-
Save jorgenschaefer/7278462 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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