Placing Packages On Media: An Ugly Abuse of Smart
Darrin Thompson
darrint at progeny.com
Thu Feb 16 09:01:52 PST 2006
All,
I wrote a script to snarf a apt-deb repository of packages and calculate
an order of packages appropriate for placing on physical media. At this
point all it does is dump out an order and any errors it found.
The method I use runs a little too slow on really large repositories and
is probably bad for other reasons.
Basically I create an isolated sandbox for smart and put a channel in
it. Then I attempt to install each package in an individual transaction.
The bad hack is that I've hijacked the commitChangeSet method and just
intercept the "callbacks" of the commitTransactionStepped.
I'd appreciate feedback on this.
--
Darrin
from smart.transaction import Transaction, PolicyInstall,
ChangeSetSplitter
from smart import init, hooks, sysconf, iface
from smart.const import NEVER, INSTALL, REMOVE
from smart.control import ChangeSet
from smart.cache import Cache
from smart.transaction import Failed as TransactionFailed
from pprint import pprint as pp
from optparse import OptionParser
control = init(datadir = 'smart-data')
def get_opts():
usage = 'USAGE: testit.py [-a arch] url suite components...'
parser = OptionParser(usage = usage)
op = parser.add_option
op('-a', '--arch', dest = 'arch',
help = 'Debian architecture to scan', metavar = 'ARCH')
opts, args = parser.parse_args()
if len(args) < 3:
parser.error("Too few arguments given.")
sys.exit(1)
return opts, args
opts, args = get_opts()
url = args[0]
suite = args[1]
components = ' '.join(args[2:])
sysconf.set(('channels', 'pdk'),
{ 'baseurl': url,
'components': components,
'disabled': False,
'distribution': suite,
'fingerprint': '',
'manual': False,
'name': 'Command Line',
'priority': 0,
'removable': False,
'type': 'apt-deb'})
if opts.arch:
sysconf.set('deb-arch', opts.arch)
pp(sysconf.get(('channels')))
pp(sysconf.get(('deb-arch')))
control.rebuildSysConfChannels()
control.reloadChannels(caching = NEVER)
cache = control.getCache()
packages = cache.getPackages()
class CommitFaker(object):
def __init__(self):
self.clusters = []
self.already_installed = Cache()
def fakeCommitChangeSet(self, changeset, **dummy):
media_group = []
for package, op in changeset.iteritems():
if op is INSTALL:
media_group.append(package)
package.installed = True
elif op is REMOVE:
pass
self.clusters.append(media_group)
def attach(self, control):
control.commitChangeSet = self.fakeCommitChangeSet
faker = CommitFaker()
faker.attach(control)
total = len(packages)
prog = iface.getProgress(cache)
prog.setTopic("Solving...")
prog.set(0, total)
prog.show()
errors = []
for count, package in enumerate(packages):
prog.set(count, total)
prog.show()
trans = Transaction(cache, PolicyInstall)
trans.enqueue(package, INSTALL)
try:
trans.run()
except TransactionFailed, error:
errors.append(str(error))
control.commitTransactionStepped(trans, confirm=False)
prog.setDone()
prog.show()
prog.stop()
for cluster in faker.clusters:
cluster.sort()
print " ", cluster
pp(errors)
More information about the Smart
mailing list