diff --git a/README.mkd b/README.mkd index a6b0084..46dfe9f 100644 --- a/README.mkd +++ b/README.mkd @@ -13,6 +13,5 @@ DEPENDENCIES TODO ==== -* [mediate] read package info * [low] support symlinking packages here * [low] verify packages diff --git a/repomon.py b/repomon.py index f2fe109..18340de 100755 --- a/repomon.py +++ b/repomon.py @@ -12,6 +12,7 @@ import sqlite3 import socket import time import hashlib +import pickle import pyinotify Event = pyinotify.Event @@ -19,6 +20,7 @@ from tornado.ioloop import IOLoop import tornado.process import archpkg +import pkgreader logger = logging.getLogger(__name__) @@ -197,7 +199,8 @@ class EventHandler(pyinotify.ProcessEvent): forarch text, owner text, mtime int, - state int)''') + state int, + info text)''') dirs = [os.path.join(base, x) for x in ('any', 'i686', 'x86_64')] self.files = files = set() @@ -305,11 +308,18 @@ class EventHandler(pyinotify.ProcessEvent): except KeyError: owner = 'uid_%d' % stat.st_uid + try: + info = pkgreader.readpkg(act.path) + except: + logger.error('failed to read info for package %s', act.path) + info = None + info = pickle.dumps(info) + self._db.execute( '''insert or replace into pkginfo - (filename, pkgname, pkgarch, pkgver, forarch, state, owner, mtime) values - (?, ?, ?, ?, ?, ?, ?, ?)''', - (act.path, act.name, act.arch, act.fullversion, arch, 1, owner, mtime)) + (filename, pkgname, pkgarch, pkgver, forarch, state, owner, mtime, info) values + (?, ?, ?, ?, ?, ?, ?, ?, ?)''', + (act.path, act.name, act.arch, act.fullversion, arch, 1, owner, mtime, info)) else: res = self._db.execute('select state from pkginfo where filename = ? and state = 1 limit 1', (act.path,)) diff --git a/scripts/common.py b/scripts/common.py new file mode 100644 index 0000000..aea9d89 --- /dev/null +++ b/scripts/common.py @@ -0,0 +1,18 @@ +import sqlite3 + +def getver(db): + try: + ver = tuple(db.execute('select ver from version_info limit 1'))[0][0] + except sqlite3.OperationalError: + ver = '0.1' # This version has no version info + return ver + +def setver(db, ver): + db.execute('''create table if not exists version_info + (ver text)''') + c = tuple(db.execute('select count(*) from version_info'))[0][0] + if c == 1: + db.execute('update version_info set ver=?', (ver,)) + else: + db.execute('insert into version_info (ver) values (?)', (ver,)) + db.commit() diff --git a/scripts/upgrade_from_0.1.py b/scripts/upgrade_from_0.1.py new file mode 100755 index 0000000..c3f3304 --- /dev/null +++ b/scripts/upgrade_from_0.1.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# vim:fileencoding=utf-8 + +import os, sys +import sqlite3 +import configparser +import pickle + +top_dir = os.path.normpath(os.path.join(__file__, '../..')) +sys.path.append(top_dir) + +import pkgreader +from common import * + +def main(conffile): + config = configparser.ConfigParser() + config.read(conffile) + config = config['repository'] + + base = config.get('path') + dbname = config.get('info-db', os.path.join(base, 'pkginfo.db')) + db = sqlite3.connect(dbname, isolation_level=None) + assert getver(db) == '0.1', 'wrong database version' + input('Please stop the service and then press Enter.') + try: + db.execute('alter table pkginfo add info text') + except sqlite3.OperationalError: + # the column is already there + pass + pkgs = [x[0] for x in db.execute('select filename from pkginfo')] + for p in pkgs: + try: + info = pkgreader.readpkg(p) + except: + logger.error('failed to read info for package %s', act.path) + info = None + info = pickle.dumps(info) + db.execute('update pkginfo set info=?', (info,)) + setver(db, '0.2') + db.close() + + input('Please re-start the service with new code and then press Enter.') + +if __name__ == '__main__': + main(sys.argv[1])