====================================== Upgrading to newer versions of Roundup ====================================== Please read each section carefully and edit your tracker home files accordingly. Note that there is information about upgrade procedures in the `administration guide`_. .. contents:: Migrating from 0.6 to 0.7 ========================= 0.7.0 Saving and sharing of user queries ---------------------------------------- Due to popular demand, the user query saving mechanisms have been overhauled. This means that queries remember the user that created them and they may be marked as being private for a particular user. You *are not required* to make these changes. You only need to make them if you wish to use the new query editing features. It's highly recommended, as the effort is minimal. 1. You will need to edit your tracker's ``dbinit.py`` to change the way queries are stored. Change the lines:: query = Class(db, "query", klass=String(), name=String(), url=String()) query.setkey("name") to:: query = Class(db, "query", klass=String(), name=String(), url=String(), private_for=Link('user')) That is, add the "private_for" property, and remove the line that says ``query.setkey("name")``. The latter is the most important edit here. 2. You will also need to copy the ``query.edit.html`` template page from the ``templates/classic/html/`` directory of the source to your tracker's ``html`` directory. 3. Once you've done that, edit the tracker's ``page.html`` template to change::
Your Queries
Your Queries (edit)
After that all users should be able to provide their timezone information.
Timezone should be a positive or negative integer - offset from GMT.
After providing timezone, roundup will show all dates values, found in web
and mail interfaces in local time. It will also accept any Date info in
local time, convert and store it in GMT.
0.6.0 Search page structure
---------------------------
In order to accomodate query editing the search page has been restructured. If
you want to provide your users with query editing, you should update your
search page using the macros detailed in the customisation doc section
`Searching on categories`__.
__ customizing.html#searching-on-categories
Also, the url field in the query class no longer starts with a '?'. You'll need
to remove this question mark from the url field to support queries. There's
a script in the "tools" directory called ``migrate-queries.py`` that should
automatically change any existing queries for you. As always, make a backup
of your database before running such a script.
0.6.0 Notes for metakit backend users
-------------------------------------
Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
support it, some modifications to interval storing routine were made. So if
your tracker uses metakit backend and your db schema contains intervals
property, searches on that property will not be accurate for db items that
was stored before roundup' upgrade. However all new records should be
searchable on intervals.
It is possible to convert your database to new format: you can export and
import back all your data (consult "Migrating backends" in "Maintenance"
documentation). After this operation all your interval properties should
become searchable.
Users of backends others than metakit should not worry about this issue.
Migrating from 0.4.x to 0.5.0
=============================
This has been a fairly major revision of Roundup:
1. Brand new, much more powerful, flexible, tasty and nutritious templating.
Unfortunately, this means all your current templates are useless. Hopefully
the new documentation and examples will be enough to help you make the
transition. Please don't hesitate to ask on roundup-users for help (or
complete conversions if you're completely stuck)!
2. The database backed got a lot more flexible, allowing Metakit and SQL
databases! The only decent SQL database implemented at present is sqlite,
but others shouldn't be a whole lot more work.
3. A brand new, highly flexible and much more robust security system including
a system of Permissions, Roles and Role assignments to users. You may now
define your own Permissions that may be checked in CGI transactions.
4. Journalling has been made less storage-hungry, so has been turned on
by default *except* for author, recipient and nosy link/unlink events. You
are advised to turn it off in your trackers too.
5. We've changed the terminology from "instance" to "tracker", to ease the
learning curve/impact for new users.
6. Because of the above changes, the tracker configuration has seen some
major changes. See below for the details.
Please, **back up your database** before you start the migration process. This
is as simple as copying the "db" directory and all its contents from your
tracker to somewhere safe.
0.5.0 Configuration
-------------------
First up, rename your ``instance_config.py`` file to just ``config.py``.
Then edit your tracker's ``__init__.py`` module. It'll currently look
like this::
from instance_config import *
try:
from dbinit import *
except ImportError:
pass # in installdir (probably :)
from interfaces import *
and it needs to be::
import config
from dbinit import open, init
from interfaces import Client, MailGW
Due to the new templating having a top-level ``page`` that defines links for
searching, indexes, adding items etc, the following variables are no longer
used:
- HEADER_INDEX_LINKS
- HEADER_ADD_LINKS
- HEADER_SEARCH_LINKS
- SEARCH_FILTERS
- DEFAULT_INDEX
- UNASSIGNED_INDEX
- USER_INDEX
- ISSUE_FILTER
The new security implementation will require additions to the dbinit module,
but also removes the need for the following tracker config variables:
- ANONYMOUS_ACCESS
- ANONYMOUS_REGISTER
but requires two new variables which define the Roles assigned to users who
register through the web and e-mail interfaces:
- NEW_WEB_USER_ROLES
- NEW_EMAIL_USER_ROLES
in both cases, 'User' is a good initial setting. To emulate
``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
"Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
Registration" and/or the "Email Registration" Permission from the "Anonymous"
Role. See the section on customising security in the `customisation
documentation`_ for more information.
Finally, the following config variables have been renamed to make more sense:
- INSTANCE_HOME -> TRACKER_HOME
- INSTANCE_NAME -> TRACKER_NAME
- ISSUE_TRACKER_WEB -> TRACKER_WEB
- ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
0.5.0 Schema Specification
--------------------------
0.5.0 Database backend changes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Your select_db module in your tracker has changed a fair bit. Where it used
to contain::
# WARNING: DO NOT EDIT THIS FILE!!!
from roundup.backends.back_anydbm import Database
it must now contain::
# WARNING: DO NOT EDIT THIS FILE!!!
from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
Note the addition of the Class, FileClass, IssueClass imports. These are very
important, as they're going to make the next change work too. You now need to
modify the top of the dbinit module in your tracker from::
import instance_config
from roundup import roundupdb
from select_db import Database
from roundup.roundupdb import Class, FileClass
class Database(roundupdb.Database, select_db.Database):
''' Creates a hybrid database from:
. the selected database back-end from select_db
. the roundup extensions from roundupdb
'''
pass
class IssueClass(roundupdb.IssueClass):
''' issues need the email information
'''
pass
to::
import config
from select_db import Database, Class, FileClass, IssueClass
Yes, remove the Database and IssueClass definitions and those other imports.
They're not needed any more!
Look for places in dbinit.py where ``instance_config`` is used too, and
rename them ``config``.
0.5.0 Journalling changes
~~~~~~~~~~~~~~~~~~~~~~~~~
Journalling has been optimised for storage. Journalling of links has been
turned back on by default. If your tracker has a large user base, you may wish
to turn off journalling of nosy list, message author and message recipient
link and unlink events. You do this by adding ``do_journal='no'`` to the Class
initialisation in your dbinit. For example, your *msg* class initialisation
probably looks like this::
msg = FileClass(db, "msg",
author=Link("user"), recipients=Multilink("user"),
date=Date(), summary=String(),
files=Multilink("file"),
messageid=String(), inreplyto=String())
to turn off journalling of author and recipient link events, add
``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
like so::
msg = FileClass(db, "msg",
author=Link("user", do_journal='no'),
recipients=Multilink("user", do_journal='no'),
date=Date(), summary=String(),
files=Multilink("file"),
messageid=String(), inreplyto=String())
Nosy list link event journalling is actually turned off by default now. If you
want to turn it on, change to your issue class' nosy list, change its
definition from::
issue = IssueClass(db, "issue",
assignedto=Link("user"), topic=Multilink("keyword"),
priority=Link("priority"), status=Link("status"))
to::
issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
assignedto=Link("user"), topic=Multilink("keyword"),
priority=Link("priority"), status=Link("status"))
noting that your definition of the nosy Multilink will override the normal one.
0.5.0 User schema changes
~~~~~~~~~~~~~~~~~~~~~~~~~
Users have two more properties, "queries" and "roles". You'll have something
like this in your dbinit module now::
user = Class(db, "user",
username=String(), password=Password(),
address=String(), realname=String(),
phone=String(), organisation=String(),
alternate_addresses=String())
user.setkey("username")
and you'll need to add the new properties and the new "query" class to it
like so::
query = Class(db, "query",
klass=String(), name=String(),
url=String())
query.setkey("name")
# Note: roles is a comma-separated string of Role names
user = Class(db, "user",
username=String(), password=Password(),
address=String(), realname=String(),
phone=String(), organisation=String(),
alternate_addresses=String(),
queries=Multilink('query'), roles=String())
user.setkey("username")
The "queries" property is used to store off the user's favourite database
queries. The "roles" property is explained below in `0.5.0 Security
Settings`_.
0.5.0 Security Settings
~~~~~~~~~~~~~~~~~~~~~~~
See the `security documentation`_ for an explanation of how the new security
system works. In a nutshell though, the security is handled as a four step
process:
1. Permissions are defined as having a name and optionally a hyperdb class
they're specific to,
2. Roles are defined that have one or more Permissions,
3. Users are assigned Roles in their "roles" property, and finally
4. Roundup checks that users have appropriate Permissions at appropriate times
(like editing issues).
Your tracker dbinit module's *open* function now has to define any
Permissions that are specific to your tracker, and also the assignment
of Permissions to Roles. At the moment, your open function
ends with::
import detectors
detectors.init(db)
return db
and what we need to do is insert some commands that will set up the security
parameters. Right above the ``import detectors`` line, you'll want to insert
these lines::
#
# SECURITY SETTINGS
#
# new permissions for this schema
for cl in 'issue', 'file', 'msg', 'user':
db.security.addPermission(name="Edit", klass=cl,
description="User is allowed to edit "+cl)
db.security.addPermission(name="View", klass=cl,
description="User is allowed to access "+cl)
# Assign the access and edit permissions for issue, file and message
# to regular users now
for cl in 'issue', 'file', 'msg':
p = db.security.getPermission('View', cl)
db.security.addPermissionToRole('User', p)
p = db.security.getPermission('Edit', cl)
db.security.addPermissionToRole('User', p)
# and give the regular users access to the web and email interface
p = db.security.getPermission('Web Access')
db.security.addPermissionToRole('User', p)
p = db.security.getPermission('Email Access')
db.security.addPermissionToRole('User', p)
# May users view other user information? Comment these lines out
# if you don't want them to
p = db.security.getPermission('View', 'user')
db.security.addPermissionToRole('User', p)
# Assign the appropriate permissions to the anonymous user's Anonymous
# Role. Choices here are:
# - Allow anonymous users to register through the web
p = db.security.getPermission('Web Registration')
db.security.addPermissionToRole('Anonymous', p)
# - Allow anonymous (new) users to register through the email gateway
p = db.security.getPermission('Email Registration')
db.security.addPermissionToRole('Anonymous', p)
# - Allow anonymous users access to the "issue" class of data
# Note: this also grants access to related information like files,
# messages, statuses etc that are linked to issues
#p = db.security.getPermission('View', 'issue')
#db.security.addPermissionToRole('Anonymous', p)
# - Allow anonymous users access to edit the "issue" class of data
# Note: this also grants access to create related information like
# files and messages etc that are linked to issues
#p = db.security.getPermission('Edit', 'issue')
#db.security.addPermissionToRole('Anonymous', p)
# oh, g'wan, let anonymous access the web interface too
p = db.security.getPermission('Web Access')
db.security.addPermissionToRole('Anonymous', p)
Note in the comments there the places where you might change the permissions
to restrict users or grant users more access. If you've created additional
classes that users should be able to edit and view, then you should add them
to the "new permissions for this schema" section at the start of the security
block. Then add them to the "Assign the access and edit permissions" section
too, so people actually have the new Permission you've created.
One final change is needed that finishes off the security system's
initialisation. We need to add a call to ``db.post_init()`` at the end of the
dbinit open() function. Add it like this::
import detectors
detectors.init(db)
# schema is set up - run any post-initialisation
db.post_init()
return db
You may verify the setup of Permissions and Roles using the new
"``roundup-admin security``" command.
0.5.0 User changes
~~~~~~~~~~~~~~~~~~
To support all those schema changes, you'll need to massage your user database
a little too, to:
1. make sure there's an "anonymous" user - this user is mandatory now and is
the one that unknown users are logged in as.
2. make sure all users have at least one Role.
If you don't have the "anonymous" user, create it now with the command::
roundup-admin create user username=anonymous roles=Anonymous
making sure the capitalisation is the same as above. Once you've done that,
you'll need to set the roles property on all users to a reasonable default.
The admin user should get "Admin", the anonymous user "Anonymous"
and all other users "User". The ``fixroles.py`` script in the tools directory
will do this. Run it like so (where python is your python 2+ binary)::
python tools/fixroles.py -i Timezone
timezone
The stylesheets have been cleaned up too. You may want to use the newer
versions in::
View: