On Wed, Dec 26, 2007 at 11:53:25PM +0100, Adeodato Sim?? wrote: > *Personally*, I like the idea of Javier Fern??ndez-Sanguino expressed in > the mail linked above of keeping debian_version as is, and introducing > /etc/lsb-release with detailed information like: > DISTRIB_ID=Debian > DISTRIB_RELEASE=4.0 > DISTRIB_CODENAME=etch > DISTRIB_DESCRIPTION="Debian GNU/Linux 4.0 'etch'"
The problem with base-files providing /etc/debian_version is that it means /etc/debian_version can really only tell you what version of base-files is installed. So if you upgrade every other package but base-files from 4.0r1 to 4.0r2, you have all the functionality of 4.0r2 but get reported as 4.0r1, and if you just upgrade base-files, you get reported as 4.0r2 while still having the bugs from 4.0r1 that were meant to have been fixed. Maybe it would be better to have aptitude or similar actually analyse what's installed compared to the available Packages/Release files, and generate a /etc/debian_version or /etc/lsb-release file based on that. It wouldn't require any additional downloads -- it'd just be a matter of: - looking at /var/lib/apt/lists/*_Release to see what the latest available revision is - looking at /var/lib/dpkg/status and /var/lib/apt/lists/*_Packages to see if the packages on this system are actually updated to that revision - based on the above updating /etc/debian_version to reflect the version of Debian actually installed And that way the only things needed for getting the right version would be (the equivalent of): # update Release file apt-get update apt-get dist-upgrade aptitude debian-version-update with no need to worry about multiple branches of base-files or whatever, or worrying what apt pinning says the admin's intending to install or similar. I'm at a bit of a loss as to how you'd do it properly (using python-apt or something, say), but a proof of concept is attached. Example output: $ ./debian_version.py Packages seem to be from Debian release lenny 91.7% HIT RATE (1325 of 1445) 95.5% of installed packages available 2.2% of matching packages could be upgraded 1.8% of matching packages are more recent $ ./debian_version.py Packages seem to be from Debian release 4.0r1 87.3% HIT RATE (517 of 592) 97.3% of installed packages available 0.0% of matching packages could be upgraded 10.2% of matching packages are more recent $ ./debian_version.py iterate Packages seem to be from Debian release 4.0r1 87.3% HIT RATE (517 of 592) 97.3% of installed packages available 0.0% of matching packages could be upgraded 10.2% of matching packages are more recent Remaining packages seem to be from Debian release 4.0-updates 61.3% HIT RATE (46 of 75) 68.0% of installed packages available 9.8% of matching packages could be upgraded 0.0% of matching packages are more recent Remaining packages seem to be from Debian-Security release etch 10.3% HIT RATE (3 of 29) 24.1% of installed packages available 14.3% of matching packages could be upgraded 42.9% of matching packages are more recent Remaining packages: bzr: 0.15-1 ... Cheers, aj
#!/usr/bin/env python # Copyright 2007 Anthony Towns # GPL v2 or later. import apt_pkg, sys, os apt_pkg.init() def get_installed(): vs = {} i = open("/var/lib/dpkg/status", "r") p,v,x = None,None,None for l in i.xreadlines(): l = l.rstrip() if l.startswith("Package: "): p = l[l.find(" ")+1:] if l.startswith("Version: "): v = l[l.find(" ")+1:] if l.startswith("Status: "): x = l.split(" ")[1:] if l == "": if x and x[0] != "hold" and x[1] == "ok" and x[2] == "installed": vs[p] = v p,v,x = None,None,None i.close() return vs vlal = "/var/lib/apt/lists" arch = "".join(os.popen("dpkg --print-architecture", "r").readlines()).rstrip() def releases(): urs = {} for path in os.listdir(vlal): if not path.endswith("_Release.gpg"): continue path = path[:-4] o,l,s,v,c = [None] * 5 for l in open(os.path.join(vlal,path)).xreadlines(): l = l.rstrip() if l.startswith("Origin: "): o = l[l.find(" ")+1:] if l.startswith("Label: "): L = l[l.find(" ")+1:] if l.startswith("Suite: "): s = l[l.find(" ")+1:] if l.startswith("Version: "): v = l[l.find(" ")+1:] if l.startswith("Codename: "): c = l[l.find(" ")+1:] vendor = filter(None, [L,o,"unknown"])[0] version = filter(None, [v,c,s,"unknown"])[0] pkgs = [x for x in os.listdir(vlal) if x.startswith(path[:-7]) and x.endswith("_binary-%s_Packages" % arch) ] k = (vendor,version) if k not in urs: urs[k] = ([],[]) urs[k][0].append( path ) urs[k][1].extend( pkgs ) res = [] for k,v in urs.iteritems(): (vendor, version) = k (paths, pkgs) = v res.append( (vendor, version, paths, readlist(pkgs)) ) return res def readlist(files): vs = {} for file in files: i = open(os.path.join(vlal, file), "r") p,v = None,None for l in i.xreadlines(): l = l.rstrip() if l.startswith("Package: "): p = l[l.find(" ")+1:] if l.startswith("Version: "): v = l[l.find(" ")+1:] if l == "": vs[p] = v p,v = None,None i.close() return vs.items() def compare(installed, list): same, new, old = 0,0,0 tryagain = dict(installed) for (p, tv) in list: if p in installed: if tv == installed[p]: same += 1 del tryagain[p] else: x = apt_pkg.VersionCompare(installed[p], tv) if x > 0: old += 1 elif x < 0: new += 1 else: same += 1 del tryagain[p] return same,new,old,tryagain installed = get_installed() release_pkgs = releases() iterate = 0 if len(sys.argv) > 1 and sys.argv[1] == "iterate": iterate = 1 intro = "Packages" while installed: best = 0,len(installed),0,"-","-","-",[] for vendor, version, path, packages in release_pkgs: same,new,old,tryagain = compare(installed, packages) if same > best[0]: best = same,new,old,vendor,version,path,tryagain same,new,old,vendor,version,path,tryagain = best if same == 0: break total = same+new+old inst = len(installed) print "%s seem to be from %s release %s" % (intro, vendor, version) print " %5.1f%% HIT RATE (%d of %d)" % (100.0*same/inst, same, inst) print " %5.1f%% of installed packages available" % (100.0*total/inst) print " %5.1f%% of matching packages could be upgraded" % (100.0*new/total) print " %5.1f%% of matching packages are more recent" % (100.0*old/total) if iterate: installed = tryagain intro = "\nRemaining packages" else: installed = [] if installed and iterate: print "\nRemaining packages:" for p,v in installed.iteritems(): print " %s: %s" % (p,v)
signature.asc
Description: Digital signature