#!/usr/bin/env python """ Upgrade a kforge system from one version to another. Currently only upgrades from 0.9 to 0.10 Notes: * Some kforge imports are inline since they automatically create a connection to the db and we can't do this until the sql has been rewritten To run tests: (a) run UpgradeTest (b) run bin/kforge-test (note that if you aren't running in development mode you will need to run createDevelopmentData first) """ import os import kforge.system sysdict = kforge.system.SystemDictionary() dbuser = sysdict['db.user'] dbname = sysdict['db.name'] dbhost = sysdict['db.host'] def pgsqlCommand(dbcmd, extra='', dbhost=dbhost, dbuser=dbuser, dbname=dbname): print "Command %s requires '%s' user authentication:" % (dbcmd, dbuser) cmd = "%s -h %s -U %s %s %s" % (dbcmd, dbhost, dbuser, dbname, extra) if os.system(cmd): raise "ERROR (Kforge): Could not execute command: %s" % cmd class Upgrade(object): def execute(self): self.alterRawSql() import kforge.dom self.registry = kforge.dom.DomainRegistry() self.createAccessControlData() self.createPersonalGrants() self.createPlugins() def alterRawSql(self): sql = """DROP TABLE role_permission; DROP TABLE permission; DROP TABLE protection_object; DROP TABLE permission_type; ALTER TABLE person ADD COLUMN role_id integer; ALTER TABLE person ADD CONSTRAINT role_id_exists FOREIGN KEY (role_id) REFERENCES role (id); UPDATE role SET name = 'Visitor' where name = 'Guest'; DELETE FROM member where role_id = 5 or role_id = 6; DELETE FROM role where name = 'SystemAdministrator' OR name = 'SystemGuest'; -- # get rid of sysadmin role and system guest role UPDATE person SET name = 'visitor' where name = 'guest'; -- make all people have general role visitor UPDATE person SET role_id = 4; -- make UPDATE person SET role_id = 1 where name = 'admin';""" pgsqlCommand('psql', '-c "%s"' % sql) def createAccessControlData(self): import kforge.command.initialise roles = self.registry.roles initialiseCmd = kforge.command.initialise.InitialiseDomainModel() initialiseCmd.adminRole = roles['Administrator'] initialiseCmd.developerRole = roles['Developer'] initialiseCmd.friendRole = roles['Friend'] initialiseCmd.visitorRole = roles['Visitor'] initialiseCmd.createSystem() initialiseCmd.createActions() initialiseCmd.createProtectionObjects() initialiseCmd.createGrants() initialiseCmd.createRefusals() initialiseCmd.createPersonalBars() def createPersonalGrants(self): protectionClass = self.registry.getDomainClass('ProtectionObject') for person in self.registry.persons: protectedName = protectionClass.makeProtectedName(person) protectionObject = self.registry.protectionObjects.create(protectedName) for permission in protectionObject.permissions: if not permission in person.grants: person.grants.create(permission) def createPluginPermissions(self): for plugin in self.registry.plugins: plugin.getSystem().onCreate() def createPlugins(self): self.registry.plugins.create('accesscontrol') import unittest class UpgradeTest(unittest.TestCase): """ For test to work you need to provide a db dump of a 0.9 db and provide link to it below and also edit the other values to reflect your setup. """ oldSql = os.path.normpath('~/tmp/kforge_0.9.sql') # edit these values to reflect the state of your original install numberOfUsers = 31 numberOfProjects = 10 personName = 'rgrp' # put a project on which personName is an administrator projectName = 'kforge' def setUp(self): pgsqlCommand('dropdb') pgsqlCommand('createdb') pgsqlCommand('psql', '-q --file %s' % self.oldSql) upgradeCmd = Upgrade() upgradeCmd.execute() import kforge.dom self.registry = kforge.dom.DomainRegistry() def testUpgrade(self): "All in one test because setup takes so long." persons = self.registry.persons self.failUnless('admin' in persons) self.failUnless('visitor' in persons) self.failIf('guest' in persons) self.failUnless(len(persons) == self.numberOfUsers) self.failUnless(self.personName in persons) projects = self.registry.projects self.failUnless('administration' in projects) self.failUnless(self.projectName in projects) self.failUnless(len(projects) == self.numberOfProjects) roles = self.registry.roles testPerson = persons[self.personName] testProject = projects[self.projectName] self.failUnless(testPerson in testProject.members) self.failUnless(testProject.members[testPerson].role == roles['Administrator']) def createDevelopmentData(): "Create the data used for testing in development mode" import kforge.command.initialise initialiseCmd = kforge.command.initialise.InitialiseDomainModel() initialiseCmd.createTestPlugins() initialiseCmd.setUpTestFixtures() def upgrade(): print 'Upgrading from 0.9 to 0.10:' try: cmd = Upgrade() cmd.execute() print 'Upgrade: OK' except: print 'Uprade: FAIL' raise if __name__ == '__main__': upgrade()