Code

oops, forgot upgrade note
[roundup.git] / doc / upgrading.txt
1 ======================================
2 Upgrading to newer versions of Roundup
3 ======================================
5 Please read each section carefully and edit your tracker home files
6 accordingly.
8 .. contents::
10 Migrating from 0.5 to 0.6
11 =========================
13 - Introduced EMAIL_FROM_TAG config variable.
17 Migrating from 0.4.x to 0.5.0
18 =============================
20 This has been a fairly major revision of Roundup:
22 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
23    Unfortunately, this means all your current templates are useless. Hopefully
24    the new documentation and examples will be enough to help you make the
25    transition. Please don't hesitate to ask on roundup-users for help (or
26    complete conversions if you're completely stuck)!
27 2. The database backed got a lot more flexible, allowing Metakit and SQL
28    databases! The only decent SQL database implemented at present is sqlite,
29    but others shouldn't be a whole lot more work.
30 3. A brand new, highly flexible and much more robust security system including
31    a system of Permissions, Roles and Role assignments to users. You may now
32    define your own Permissions that may be checked in CGI transactions.
33 4. Journalling has been made less storage-hungry, so has been turned on
34    by default *except* for author, recipient and nosy link/unlink events. You
35    are advised to turn it off in your trackers too.
36 5. We've changed the terminology from "instance" to "tracker", to ease the
37    learning curve/impact for new users.
38 6. Because of the above changes, the tracker configuration has seen some
39    major changes. See below for the details.
41 Please, **back up your database** before you start the migration process. This
42 is as simple as copying the "db" directory and all its contents from your
43 tracker to somewhere safe.
46 0.5.0 Configuration
47 -------------------
49 First up, rename your ``instance_config.py`` file to just ``config.py``.
51 Then edit your tracker's ``__init__.py`` module. It'll currently look
52 like this::
54  from instance_config import *
55  try:
56      from dbinit import *
57  except ImportError:
58      pass # in installdir (probably :)
59  from interfaces import *
61 and it needs to be::
63  import config
64  from dbinit import open, init
65  from interfaces import Client, MailGW
67 Due to the new templating having a top-level ``page`` that defines links for
68 searching, indexes, adding items etc, the following variables are no longer
69 used:
71 - HEADER_INDEX_LINKS
72 - HEADER_ADD_LINKS
73 - HEADER_SEARCH_LINKS
74 - SEARCH_FILTERS
75 - DEFAULT_INDEX
76 - UNASSIGNED_INDEX
77 - USER_INDEX
78 - ISSUE_FILTER
80 The new security implementation will require additions to the dbinit module,
81 but also removes the need for the following tracker config variables:
83 - ANONYMOUS_ACCESS
84 - ANONYMOUS_REGISTER
86 but requires two new variables which define the Roles assigned to users who
87 register through the web and e-mail interfaces:
89 - NEW_WEB_USER_ROLES
90 - NEW_EMAIL_USER_ROLES
92 in both cases, 'User' is a good initial setting. To emulate
93 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
94 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
95 Registration" and/or the "Email Registration" Permission from the "Anonymous"
96 Role. See the section on customising security in the `customisation
97 documentation`_ for more information.
99 Finally, the following config variables have been renamed to make more sense:
101 - INSTANCE_HOME -> TRACKER_HOME
102 - INSTANCE_NAME -> TRACKER_NAME
103 - ISSUE_TRACKER_WEB -> TRACKER_WEB
104 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
107 0.5.0 Schema Specification
108 --------------------------
110 0.5.0 Database backend changes
111 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
113 Your select_db module in your tracker has changed a fair bit. Where it used
114 to contain::
116  # WARNING: DO NOT EDIT THIS FILE!!!
117  from roundup.backends.back_anydbm import Database
119 it must now contain::
121  # WARNING: DO NOT EDIT THIS FILE!!!
122  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
124 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
125 Note the addition of the Class, FileClass, IssueClass imports. These are very
126 important, as they're going to make the next change work too. You now need to
127 modify the top of the dbinit module in your tracker from::
129  import instance_config
130  from roundup import roundupdb
131  from select_db import Database
133  from roundup.roundupdb import Class, FileClass
135  class Database(roundupdb.Database, select_db.Database):
136      ''' Creates a hybrid database from:
137           . the selected database back-end from select_db
138           . the roundup extensions from roundupdb
139      '''
140      pass
142  class IssueClass(roundupdb.IssueClass):
143      ''' issues need the email information
144      '''
145      pass
147 to::
149  import config
150  from select_db import Database, Class, FileClass, IssueClass
152 Yes, remove the Database and IssueClass definitions and those other imports.
153 They're not needed any more!
155 Look for places in dbinit.py where ``instance_config`` is used too, and
156 rename them ``config``.
159 0.5.0 Journalling changes
160 ~~~~~~~~~~~~~~~~~~~~~~~~~
162 Journalling has been optimised for storage. Journalling of links has been
163 turned back on by default. If your tracker has a large user base, you may wish
164 to turn off journalling of nosy list, message author and message recipient
165 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
166 initialisation in your dbinit. For example, your *msg* class initialisation
167 probably looks like this::
169     msg = FileClass(db, "msg",
170                     author=Link("user"), recipients=Multilink("user"),
171                     date=Date(),         summary=String(),
172                     files=Multilink("file"),
173                     messageid=String(),  inreplyto=String())
175 to turn off journalling of author and recipient link events, add
176 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
177 like so::
179     msg = FileClass(db, "msg",
180                     author=Link("user", do_journal='no'),
181                     recipients=Multilink("user", do_journal='no'),
182                     date=Date(),         summary=String(),
183                     files=Multilink("file"),
184                     messageid=String(),  inreplyto=String())
186 Nosy list link event journalling is actually turned off by default now. If you
187 want to turn it on, change to your issue class' nosy list, change its
188 definition from::
190     issue = IssueClass(db, "issue",
191                     assignedto=Link("user"), topic=Multilink("keyword"),
192                     priority=Link("priority"), status=Link("status"))
194 to::
196     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
197                     assignedto=Link("user"), topic=Multilink("keyword"),
198                     priority=Link("priority"), status=Link("status"))
200 noting that your definition of the nosy Multilink will override the normal one.
203 0.5.0 User schema changes
204 ~~~~~~~~~~~~~~~~~~~~~~~~~
206 Users have two more properties, "queries" and "roles". You'll have something
207 like this in your dbinit module now::
209     user = Class(db, "user",
210                     username=String(),   password=Password(),
211                     address=String(),    realname=String(),
212                     phone=String(),      organisation=String(),
213                     alternate_addresses=String())
214     user.setkey("username")
216 and you'll need to add the new properties and the new "query" class to it
217 like so::
219     query = Class(db, "query",
220                     klass=String(),     name=String(),
221                     url=String())
222     query.setkey("name")
224     # Note: roles is a comma-separated string of Role names
225     user = Class(db, "user",
226                     username=String(),   password=Password(),
227                     address=String(),    realname=String(),
228                     phone=String(),      organisation=String(),
229                     alternate_addresses=String(),
230                     queries=Multilink('query'), roles=String())
231     user.setkey("username")
233 The "queries" property is used to store off the user's favourite database
234 queries. The "roles" property is explained below in `0.5.0 Security
235 Settings`_.
238 0.5.0 Security Settings
239 ~~~~~~~~~~~~~~~~~~~~~~~
241 See the `security documentation`_ for an explanation of how the new security
242 system works. In a nutshell though, the security is handled as a four step
243 process:
245 1. Permissions are defined as having a name and optionally a hyperdb class
246    they're specific to,
247 2. Roles are defined that have one or more Permissions,
248 3. Users are assigned Roles in their "roles" property, and finally
249 4. Roundup checks that users have appropriate Permissions at appropriate times
250    (like editing issues).
252 Your tracker dbinit module's *open* function now has to define any
253 Permissions that are specific to your tracker, and also the assignment
254 of Permissions to Roles. At the moment, your open function
255 ends with::
257     import detectors
258     detectors.init(db)
260     return db
262 and what we need to do is insert some commands that will set up the security
263 parameters. Right above the ``import detectors`` line, you'll want to insert
264 these lines::
266     #
267     # SECURITY SETTINGS
268     #
269     # new permissions for this schema
270     for cl in 'issue', 'file', 'msg', 'user':
271         db.security.addPermission(name="Edit", klass=cl,
272             description="User is allowed to edit "+cl)
273         db.security.addPermission(name="View", klass=cl,
274             description="User is allowed to access "+cl)
276     # Assign the access and edit permissions for issue, file and message
277     # to regular users now
278     for cl in 'issue', 'file', 'msg':
279         p = db.security.getPermission('View', cl)
280         db.security.addPermissionToRole('User', p)
281         p = db.security.getPermission('Edit', cl)
282         db.security.addPermissionToRole('User', p)
283     # and give the regular users access to the web and email interface
284     p = db.security.getPermission('Web Access')
285     db.security.addPermissionToRole('User', p)
286     p = db.security.getPermission('Email Access')
287     db.security.addPermissionToRole('User', p)
289     # May users view other user information? Comment these lines out
290     # if you don't want them to
291     p = db.security.getPermission('View', 'user')
292     db.security.addPermissionToRole('User', p)
294     # Assign the appropriate permissions to the anonymous user's Anonymous
295     # Role. Choices here are:
296     # - Allow anonymous users to register through the web
297     p = db.security.getPermission('Web Registration')
298     db.security.addPermissionToRole('Anonymous', p)
299     # - Allow anonymous (new) users to register through the email gateway
300     p = db.security.getPermission('Email Registration')
301     db.security.addPermissionToRole('Anonymous', p)
302     # - Allow anonymous users access to the "issue" class of data
303     #   Note: this also grants access to related information like files,
304     #         messages, statuses etc that are linked to issues
305     #p = db.security.getPermission('View', 'issue')
306     #db.security.addPermissionToRole('Anonymous', p)
307     # - Allow anonymous users access to edit the "issue" class of data
308     #   Note: this also grants access to create related information like
309     #         files and messages etc that are linked to issues
310     #p = db.security.getPermission('Edit', 'issue')
311     #db.security.addPermissionToRole('Anonymous', p)
313     # oh, g'wan, let anonymous access the web interface too
314     p = db.security.getPermission('Web Access')
315     db.security.addPermissionToRole('Anonymous', p)
317 Note in the comments there the places where you might change the permissions
318 to restrict users or grant users more access. If you've created additional
319 classes that users should be able to edit and view, then you should add them
320 to the "new permissions for this schema" section at the start of the security
321 block. Then add them to the "Assign the access and edit permissions" section
322 too, so people actually have the new Permission you've created.
324 One final change is needed that finishes off the security system's
325 initialisation. We need to add a call to ``db.post_init()`` at the end of the
326 dbinit open() function. Add it like this::
328     import detectors
329     detectors.init(db)
331     # schema is set up - run any post-initialisation
332     db.post_init()
333     return db
335 You may verify the setup of Permissions and Roles using the new
336 "``roundup-admin security``" command.
339 0.5.0 User changes
340 ~~~~~~~~~~~~~~~~~~
342 To support all those schema changes, you'll need to massage your user database
343 a little too, to:
345 1. make sure there's an "anonymous" user - this user is mandatory now and is
346    the one that unknown users are logged in as.
347 2. make sure all users have at least one Role.
349 If you don't have the "anonymous" user, create it now with the command::
351   roundup-admin create user username=anonymous roles=Anonymous
353 making sure the capitalisation is the same as above. Once you've done that,
354 you'll need to set the roles property on all users to a reasonable default.
355 The admin user should get "Admin", the anonymous user "Anonymous"
356 and all other users "User". The ``fixroles.py`` script in the tools directory
357 will do this. Run it like so (where python is your python 2+ binary)::
359   python tools/fixroles.py -i <tracker home> fixroles
363 0.5.0 CGI interface changes
364 ---------------------------
366 The CGI interface code was completely reorganised and largely rewritten. The
367 end result is that this section of your tracker interfaces module will need
368 changing from::
370  from roundup import cgi_client, mailgw
371  from roundup.i18n import _
372  
373  class Client(cgi_client.Client):
374      ''' derives basic CGI implementation from the standard module,
375          with any specific extensions
376      '''
377      pass
379 to::
381  from roundup import mailgw
382  from roundup.cgi import client
383  
384  class Client(client.Client): 
385      ''' derives basic CGI implementation from the standard module,
386          with any specific extensions
387      '''
388      pass
390 You will also need to install the new version of roundup.cgi from the source
391 cgi-bin directory if you're using it.
394 0.5.0 HTML templating
395 ---------------------
397 You'll want to make a backup of your current tracker html directory. You
398 should then copy the html directory from the Roundup source "classic" template
399 and modify it according to your local schema changes.
401 If you need help with the new templating system, please ask questions on the
402 roundup-users mailing list (available through the roundup project page on
403 sourceforge, http://roundup.sf.net/)
406 0.5.0 Detectors
407 ---------------
409 The nosy reactor has been updated to handle the tracker not having an
410 "assignedto" property on issues. You may want to copy it into your tracker's
411 detectors directory. Chances are you've already fixed it though :)
414 Migrating from 0.4.1 to 0.4.2
415 =============================
417 0.4.2 Configuration
418 -------------------
419 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
420 allowing replacement of 'assignedto' with the user's userid. Users must change
421 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
422 the replacement behaviour to occur now.
424 The new configuration variables are:
426 - EMAIL_KEEP_QUOTED_TEXT 
427 - EMAIL_LEAVE_BODY_UNCHANGED
428 - ADD_RECIPIENTS_TO_NOSY
430 See the sample configuration files in::
432  <roundup source>/roundup/templates/classic/instance_config.py
434 and::
436  <roundup source>/roundup/templates/extended/instance_config.py
438 and the `customisation documentation`_ for information on how they're used.
441 0.4.2 Changes to detectors
442 --------------------------
443 You will need to copy the detectors from the distribution into your instance
444 home "detectors" directory. If you used the classic schema, the detectors
445 are in::
447  <roundup source>/roundup/templates/classic/detectors/
449 If you used the extended schema, the detectors are in::
451  <roundup source>/roundup/templates/extended/detectors/
453 The change means that schema-specific code has been removed from the
454 mail gateway and cgi interface and made into auditors:
456 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
457   list with author, recipient and assignedto information.
458 - statusauditor.py makes the unread or resolved -> chatting changes and
459   presets the status of an issue to unread.
461 There's also a bug or two fixed in the nosyreactor code.
463 0.4.2 HTML templating changes
464 -----------------------------
465 The link() htmltemplate function now has a "showid" option for links and
466 multilinks. When true, it only displays the linked item id as the anchor
467 text. The link value is displayed as a tooltip using the title anchor
468 attribute. To use in eg. the superseder field, have something like this::
470    <td>
471     <display call="field('superseder', showid=1)">
472     <display call="classhelp('issue', 'id,title', label='list', width=500)">
473     <property name="superseder">
474      <br>View: <display call="link('superseder', showid=1)">
475     </property>
476    </td>
478 The stylesheets have been cleaned up too. You may want to use the newer
479 versions in::
481  <roundup source>/roundup/templates/<template>/html/default.css
485 Migrating from 0.4.0 to 0.4.1
486 =============================
488 0.4.1 Files storage
489 -------------------
491 Messages and files from newly created issues will be put into subdierectories
492 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
493 will go into files/file/2/file2003. Previous messages are still found, but
494 could be put into this structure.
496 0.4.1 Configuration
497 -------------------
499 To allow more fine-grained access control, the variable used to check
500 permission to auto-register users in the mail gateway is now called
501 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
502 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
504 Configuring the links in the web header is now easier too. The following
505 variables have been added to the classic instance_config.py::
507   HEADER_INDEX_LINKS   - defines the "index" links to be made available
508   HEADER_ADD_LINKS     - defines the "add" links
509   DEFAULT_INDEX        - specifies the index view for DEFAULT
510   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
511   USER_INDEX           - specifies the index view for USER
513 See the <roundup source>/roundup/templates/classic/instance_config.py for more
514 information - including how the variables are to be set up. Most users will
515 just be able to copy the variables from the source to their instance home. If
516 you've modified the header by changing the source of the interfaces.py file in
517 the instance home, you'll need to remove that customisation and move it into
518 the appropriate variables in instance_config.py.
520 The extended schema has similar variables added too - see the source for more
521 info.
523 0.4.1 Alternate E-Mail Addresses
524 --------------------------------
526 If you add the property "alternate_addresses" to your user class, your users
527 will be able to register alternate email addresses that they may use to
528 communicate with roundup as. All email from roundup will continue to be sent
529 to their primary address.
531 If you have not edited the dbinit.py file in your instance home directory,
532 you may simply copy the new dbinit.py file from the core code. If you used
533 the classic schema, the interfaces file is in::
535  <roundup source>/roundup/templates/classic/dbinit.py
537 If you used the extended schema, the file is in::
539  <roundup source>/roundup/templates/extended/dbinit.py 
541 If you have modified your dbinit.py file, you need to edit the dbinit.py
542 file in your instance home directory. Find the lines which define the user
543 class::
545     user = Class(db, "msg",
546                     username=String(),   password=Password(),
547                     address=String(),    realname=String(), 
548                     phone=String(),      organisation=String(),
549                     alternate_addresses=String())
551 You will also want to add the property to the user's details page. The
552 template for this is the "user.item" file in your instance home "html"
553 directory. Similar to above, you may copy the file from the roundup source if
554 you haven't modified it. Otherwise, add the following to the template::
556    <display call="multiline('alternate_addresses')">
558 with appropriate labelling etc. See the standard template for an idea.
562 Migrating from 0.3.x to 0.4.0
563 =============================
565 0.4.0 Message-ID and In-Reply-To addition
566 -----------------------------------------
567 0.4.0 adds the tracking of messages by message-id and allows threading
568 using in-reply-to. Most e-mail clients support threading using this
569 feature, and we hope to add support for it to the web gateway. If you
570 have not edited the dbinit.py file in your instance home directory, you may
571 simply copy the new dbinit.py file from the core code. If you used the
572 classic schema, the interfaces file is in::
574  <roundup source>/roundup/templates/classic/dbinit.py
576 If you used the extended schema, the file is in::
578  <roundup source>/roundup/templates/extended/dbinit.py 
580 If you have modified your dbinit.py file, you need to edit the dbinit.py
581 file in your instance home directory. Find the lines which define the msg
582 class::
584     msg = FileClass(db, "msg",
585                     author=Link("user"), recipients=Multilink("user"),
586                     date=Date(),         summary=String(),
587                     files=Multilink("file"))
589 and add the messageid and inreplyto properties like so::
591     msg = FileClass(db, "msg",
592                     author=Link("user"), recipients=Multilink("user"),
593                     date=Date(),         summary=String(),
594                     files=Multilink("file"),
595                     messageid=String(),  inreplyto=String())
597 Also, configuration is being cleaned up. This means that your dbinit.py will
598 also need to be changed in the open function. If you haven't changed your
599 dbinit.py, the above copy will be enough. If you have, you'll need to change
600 the line (round line 50)::
602     db = Database(instance_config.DATABASE, name)
604 to::
606     db = Database(instance_config, name)
609 0.4.0 Configuration
610 --------------------
611 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
612 instance_config.py. The simplest solution is to copy the default values
613 from template in the core source.
615 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
616 are to be automatically registered with the tracker. If it is set to "deny"
617 then unknown users will not have access. If it is set to "allow" they will be
618 automatically registered with the tracker.
621 0.4.0 CGI script roundup.cgi
622 ----------------------------
623 The CGI script has been updated with some features and a bugfix, so you should
624 copy it from the roundup cgi-bin source directory again. Make sure you update
625 the ROUNDUP_INSTANCE_HOMES after the copy.
628 0.4.0 Nosy reactor
629 ------------------
630 The nosy reactor has also changed - copy the nosyreactor.py file from the core
631 source::
633    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
635 to your instance home "detectors" directory.
638 0.4.0 HTML templating
639 ---------------------
640 The field() function was incorrectly implemented - links and multilinks now
641 display as text fields when rendered using field(). To display a menu (drop-
642 down or select box) you need to use the menu() function.
646 Migrating from 0.2.x to 0.3.x
647 =============================
649 0.3.x Cookie Authentication changes
650 -----------------------------------
651 0.3.0 introduces cookie authentication - you will need to copy the
652 interfaces.py file from the roundup source to your instance home to enable
653 authentication. If you used the classic schema, the interfaces file is in::
655  <roundup source>/roundup/templates/classic/interfaces.py
657 If you used the extended schema, the file is in::
659  <roundup source>/roundup/templates/extended/interfaces.py
661 If you have modified your interfaces.Client class, you will need to take
662 note of the login/logout functionality provided in roundup.cgi_client.Client
663 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
664 modify your instance code apropriately.
667 0.3.x Password encoding
668 -----------------------
669 This release also introduces encoding of passwords in the database. If you
670 have not edited the dbinit.py file in your instance home directory, you may
671 simply copy the new dbinit.py file from the core code. If you used the
672 classic schema, the interfaces file is in::
674  <roundup source>/roundup/templates/classic/dbinit.py
676 If you used the extended schema, the file is in::
678  <roundup source>/roundup/templates/extended/dbinit.py
681 If you have modified your dbinit.py file, you may use encoded passwords:
683 1. Edit the dbinit.py file in your instance home directory
684    a. At the first code line of the open() function::
686        from roundup.hyperdb import String, Date, Link, Multilink
688       alter to include Password, as so::
690        from roundup.hyperdb import String, Password, Date, Link, Multilink
692    b. Where the password property is defined (around line 66)::
694        user = Class(db, "user", 
695                        username=String(),   password=String(),
696                        address=String(),    realname=String(), 
697                        phone=String(),      organisation=String())
698        user.setkey("username")
700       alter the "password=String()" to "password=Password()"::
702        user = Class(db, "user", 
703                        username=String(),   password=Password(),
704                        address=String(),    realname=String(), 
705                        phone=String(),      organisation=String())
706        user.setkey("username")
708 2. Any existing passwords in the database will remain cleartext until they
709    are edited. It is recommended that at a minimum the admin password be
710    changed immediately::
712       roundup-admin -i <instance home> set user1 password=<new password>
715 0.3.x Configuration
716 -------------------
717 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
718 the instance_config.py. Simplest solution is to copy the default values from
719 template in the core source.
721 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
722 to send nosy messages to the author. Default behaviour is to not send nosy
723 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
724 dbinit.py in your instance home.
727 0.3.x CGI script roundup.cgi
728 ----------------------------
729 There have been some structural changes to the roundup.cgi script - you will
730 need to install it again from the cgi-bin directory of the source
731 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
732 copy.
735 .. _`customisation documentation`: customizing.html
736 .. _`security documentation`: security.html