On Fri, Dec 28, 2007 at 08:20:01AM +0100, Frans Pop wrote: > I agree with Anthony that it is very much preferable to have a solution > that's just able to automatically determine the correct version.
Okay, so here's a updated version that generates both debian_version and lsb-release as specced by dato, if it's given arguments of debian-version or dato-release, and has appropriate perms. In order for it to be useful, I guess it'd need to be in base, and hence written in perl or C (unless we decided to add python to base). ] $ ./debian_version.py debian-version ] /etc/debian_version should contain: ] lenny ] $ ./debian_version.py dato-release ] /etc/lsb-release should contain: ] DISTRIB_ID=Debian ] DISTRIB_RELEASE=lenny ] DISTRIB_CODENAME=lenny ] DISTRIB_DESCRIPTION="Debian x.y Testing distribution - Not Released" ] $ ./debian_version.py noisy ] Packages seem to be from Debian release lenny ] Debian x.y Testing distribution - Not Released ] ['mirror.internode.on.net_pub_debian_dists_lenny_Release', 'http.us.debian.org_debian_dists_lenny_Release'] ] 89.4% HIT RATE (1293 of 1447) ] 95.3% of installed packages available ] 4.4% of matching packages could be upgraded ] 1.8% of matching packages are more recent ] $ sudo rm /etc/debian_version /etc/lsb-release ] $ sudo ./debian_version.py debian-version dato-release ] $ cat /etc/debian_version; echo ----; cat /etc/lsb-release ] lenny ] ---- ] DISTRIB_ID=Debian ] DISTRIB_RELEASE=lenny ] DISTRIB_CODENAME=lenny ] DISTRIB_DESCRIPTION="Debian x.y Testing distribution - Not Released" Cheers, aj
#!/usr/bin/env python # Copyright 2007 Anthony Towns # GPL v2 or later. import apt_pkg, sys, os apt_pkg.init() def try_write(file): try: f = open(file, "w") except IOError: f = sys.stdout f.write("%s should contain:\n" % file) return f def uniq(l): return dict( [(x,1) for x in l] ).keys() 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] release_info = [] o,l,s,v,c = [None] * 5 for l in open(os.path.join(vlal,path)).xreadlines(): l = l.rstrip() if l[0] != " ": release_info.append( (l[:l.find(":")], l[l.find(":")+1:].lstrip()) ) else: x = release_info[-1] x = (x[0], x[1] + "\n" + l[1:]) release_info[-1] = x release_info_l = release_info release_info = dict(release_info) vendor = filter(None, [ release_info.get("Label", None), release_info.get("Origin", None), "unknown"] ) [0] version = filter(None, [ release_info.get("Version", None), release_info.get("Codename", None), release_info.get("Suite", None), "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].append( release_info ) urs[k][2].extend( pkgs ) res = [] for k,v in urs.iteritems(): (vendor, version) = k (paths, rels, pkgs) = v res.append( (vendor, version, paths, rels, 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() noisy = ("noisy" in sys.argv[1:]) iterate = ("iterate" in sys.argv[1:]) debian_version = ("debian-version" in sys.argv[1:]) dato_release = ("dato-release" in sys.argv[1:]) intro = "Packages" while installed: best = 0,len(installed),0,"-","-",[],"-",[] for vendor, version, path, rels, packages in release_pkgs: same,new,old,tryagain = compare(installed, packages) if same > best[0]: best = same,new,old,vendor,version,rels,path,tryagain same,new,old,vendor,version,rels,path,tryagain = best if same == 0: break total = same+new+old inst = len(installed) if noisy: print "%s seem to be from %s release %s" % (intro, vendor, version) print "%s" % (rels[0].get("Description","(no description)")) print "%s" % (path) 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 debian_version: debian_version = 0 f = try_write("/etc/debian_version") f.write("%s\n" % (version)) del f if dato_release: dato_release = 0 f = try_write("/etc/lsb-release") f.write("DISTRIB_ID=%s\n" % (vendor)) f.write("DISTRIB_RELEASE=%s\n" % (version)) for c in uniq([ x.get("Codename", None) for x in rels ]): if c == None: continue f.write("DISTRIB_CODENAME=%s\n" % (c)) break for d in uniq([ x.get("Description", None) for x in rels ]): if d == None: continue f.write("DISTRIB_DESCRIPTION=\"%s\"\n" % (d)) break if iterate and noisy: installed = tryagain intro = "\nRemaining packages" else: installed = [] if installed and iterate and noisy: print "\nRemaining packages:" for p,v in installed.iteritems(): print " %s: %s" % (p,v)
signature.asc
Description: Digital signature