Code

svn repository setup
[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. Note that there is information about upgrade procedures in the
7 `administration guide`_.
9 If a specific version transition isn't mentioned here (eg. 0.6.7 to 0.6.8)
10 then you don't need to do anything. If you're upgrading from 0.5.6 to
11 0.6.8 though, you'll need to check the "0.5 to 0.6" and "0.6.x to 0.6.3"
12 steps.
14 .. contents::
16 Migrating from 1.4.2 to 1.4.3
17 =============================
19 If you are using the MySQL backend you will need to replace some indexes
20 that may have been created by version 1.4.2.
22 You should to access your MySQL database directly and remove any indexes
23 with a name ending in "_key_retired_idx". You should then re-add them with
24 the same spec except the key column name needs a size. So an index on
25 "_user (__retired, _name)" should become "_user (__retired, _name(255))".
28 Migrating from 1.4.x to 1.4.2
29 =============================
31 You should run the "roundup-admin migrate" command for your tracker once
32 you've installed the latest codebase. 
34 Do this before you use the web, command-line or mail interface and before
35 any users access the tracker.
37 This command will respond with either "Tracker updated" (if you've not
38 previously run it on an RDBMS backend) or "No migration action required"
39 (if you have run it, or have used another interface to the tracker,
40 or are using anydbm).
42 It's safe to run this even if it's not required, so just get into the
43 habit.
46 Migrating from 1.3.3 to 1.4.0
47 =============================
49 Value of the "refwd_re" tracker configuration option (section "mailgw")
50 is treated as UTF-8 string.  In previous versions, it was ISO8859-1.
52 If you have running trackers based on the classic template, please
53 update the messagesummary detector as follows::
55     --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000      1.1
56     +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000       1.2
57     @@ -8,7 +8,7 @@
58      if newvalues.has_key('summary') or not newvalues.has_key('content'):
59          return
61     -    summary, content = parseContent(newvalues['content'], 1, 1)
62     +    summary, content = parseContent(newvalues['content'], config=db.config)
63      newvalues['summary'] = summary
65 In the latest version we have added some database indexes to the
66 SQL-backends (mysql, postgresql, sqlite) for speeding up building the
67 roundup-index for full-text search. We recommend that you create the
68 following database indexes on the database by hand::
70  CREATE INDEX words_by_id ON __words (_textid)
71  CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop)
73 Migrating from 1.2.x to 1.3.0
74 =============================
76 1.3.0 Web interface changes
77 ---------------------------
79 Some of the HTML files in the "classic" and "minimal" tracker templates
80 were changed to fix some bugs and clean them up. You may wish to compare
81 them to the HTML files in your tracker and apply any changes.
84 Migrating from 1.1.2 to 1.2.0
85 =============================
87 1.2.0 Sorting and grouping by multiple properties
88 -------------------------------------------------
90 Starting with this version, sorting and grouping by multiple properties
91 is possible. This means that request.sort and request.group are now
92 lists. This is reflected in several places:
94  * ``renderWith`` now has list attributes for ``sort`` and ``group``,
95    where you previously wrote::
96    
97     renderWith(... sort=('-', 'activity'), group=('+', 'priority')
99    you write now::
101     renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
103  * In templates that permit to edit sorting/grouping, request.sort and
104    request.group are (possibly empty) lists. You can now sort and group
105    by multiple attributes. For an example, see the classic template. You
106    may want search for the variable ``n_sort`` which can be set to the
107    number of sort/group properties.
109  * Templates that diplay new headlines for each group of items with
110    equal group properties can now use the modified ``batch.propchanged``
111    method that can take several properties which are checked for
112    changes. See the example in the classic template which makes use of
113    ``batch.propchanged``.
115 Migrating from 1.1.0 to 1.1.1
116 =============================
118 1.1.1 "Clear this message"
119 --------------------------
121 In 1.1.1, the standard ``page.html`` template includes a "clear this message"
122 link in the green "ok" message bar that appears after a successful edit
123 (or other) action.
125 To include this in your tracker, change the following in your ``page.html``
126 template::
128  <p tal:condition="options/ok_message | nothing" class="ok-message"
129     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
131 to be::
133  <p tal:condition="options/ok_message | nothing" class="ok-message">
134    <span tal:repeat="m options/ok_message"
135       tal:content="structure string:$m <br/ > " />
136     <a class="form-small" tal:attributes="href request/current_url"
137        i18n:translate="">clear this message</a>
138  </p>
141 If you implemented the "clear this message" in your 1.1.0 tracker, then you
142 should change it to the above and it will work much better!
145 Migrating from 1.0.x to 1.1.0
146 =============================
148 1.1 Login "For Session Only"
149 ----------------------------
151 In 1.1, web logins are alive for the length of a session only, *unless* you
152 add the following to the login form in your tracker's ``page.html``::
154     <input type="checkbox" name="remember" id="remember">
155     <label for="remember" i18n:translate="">Remember me?</label><br>
157 See the classic tracker ``page.html`` if you're unsure where this should
158 go.
161 1.1 Query Display Name
162 ----------------------
164 The ``dispname`` web variable has been renamed ``@dispname`` to avoid
165 clashing with other variables of the same name. If you are using the
166 display name feature, you will need to edit your tracker's ``page.html``
167 and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
169 A side-effect of this change is that the renderWith method used in the
170 ``home.html`` page may now take a dispname argument.
173 1.1 "Clear this message"
174 ------------------------
176 In 1.1, the standard ``page.html`` template includes a "clear this message"
177 link in the green "ok" message bar that appears after a successful edit
178 (or other) action.
180 To include this in your tracker, change the following in your ``page.html``
181 template::
183  <p tal:condition="options/ok_message | nothing" class="ok-message"
184     tal:repeat="m options/ok_message" tal:content="structure m">error</p>
186 to be::
188  <p tal:condition="options/ok_message | nothing" class="ok-message">
189    <span tal:repeat="m options/ok_message"
190       tal:content="structure string:$m <br/ > " />
191     <a class="form-small" tal:attributes="href string:issue${context/id}"
192        i18n:translate="">clear this message</a>
193  </p>
196 Migrating from 0.8.x to 1.0
197 ===========================
199 1.0 New Query Permissions
200 -------------------------
202 New permissions are defined for query editing and viewing. To include these
203 in your tracker, you need to add these lines to your tracker's
204 ``schema.py``::
206  # Users should be able to edit and view their own queries. They should also
207  # be able to view any marked as not private. They should not be able to
208  # edit others' queries, even if they're not private
209  def view_query(db, userid, itemid):
210      private_for = db.query.get(itemid, 'private_for')
211      if not private_for: return True
212      return userid == private_for
213  def edit_query(db, userid, itemid):
214      return userid == db.query.get(itemid, 'creator')
215  p = db.security.addPermission(name='View', klass='query', check=view_query,
216      description="User is allowed to view their own and public queries")
217  db.security.addPermissionToRole('User', p)
218  p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
219      description="User is allowed to edit their queries")
220  db.security.addPermissionToRole('User', p)
221  p = db.security.addPermission(name='Create', klass='query',
222      description="User is allowed to create queries")
223  db.security.addPermissionToRole('User', p)
225 and then remove 'query' from the line::
227  # Assign the access and edit Permissions for issue, file and message
228  # to regular users now
229  for cl in 'issue', 'file', 'msg', 'query', 'keyword':
231 so it looks like::
233  for cl in 'issue', 'file', 'msg', 'keyword':
236 Migrating from 0.8.0 to 0.8.3
237 =============================
239 0.8.3 Nosy Handling Changes
240 ---------------------------
242 A change was made to fix a bug in the ``nosyreaction.py`` standard
243 detector. To incorporate this fix in your trackers, you will need to copy
244 the ``nosyreaction.py`` file from the ``templates/classic/detectors``
245 directory of the source to your tracker's ``templates`` directory.
247 If you have modified the ``nosyreaction.py`` file from the standard
248 version, you will need to roll your changes into the new file.
251 Migrating from 0.7.1 to 0.8.0
252 =============================
254 You *must* fully uninstall previous Roundup version before installing
255 Roundup 0.8.0.  If you don't do that, ``roundup-admin install``
256 command may fail to function properly.
258 0.8.0 Backend changes
259 ---------------------
261 Backends 'bsddb' and 'bsddb3' are removed.  If you are using one of these,
262 you *must* migrate to another backend before upgrading.
265 0.8.0 API changes
266 -----------------
268 Class.safeget() was removed from the API. Test your item ids before calling
269 Class.get() instead.
272 0.8.0 New tracker layout
273 ------------------------
275 The ``config.py`` file has been replaced by ``config.ini``. You may use the
276 roundup-admin command "genconfig" to generate a new config file::
278   roundup-admin genconfig <tracker home>/config.ini
280 and modify the values therein based on the contents of your old config.py.
281 In most cases, the names of the config variables are the same.
283 The ``select_db.py`` file has been replaced by a file in the ``db``
284 directory called ``backend_name``. As you might guess, this file contains
285 just the name of the backend. To figure what the contents of yours should
286 be, use the following table:
288   ================================ =========================
289   ``select_db.py`` contents        ``backend_name`` contents
290   ================================ =========================
291   from back_anydbm import ...      anydbm
292   from back_metakit import ...     metakit
293   from back_sqlite import ...      sqlite
294   from back_mysql import ...       mysql
295   from back_postgresql import ...  postgresql
296   ================================ =========================
298 The ``dbinit.py`` file has been split into two new files,
299 ``initial_data.py`` and ``schema.py``. The contents of this file are:
301 ``initial_data.py``
302   You don't need one of these as your tracker is already initialised.
304 ``schema.py``
305   Copy the body of the ``def open(name=None)`` function from your old
306   tracker's ``dbinit.py`` file to this file. As the lines you're copying
307   aren't part of a function definition anymore, one level of indentation
308   needs to be removed (remove only the leading four spaces on each
309   line). 
311   The first few lines -- those starting with ``from roundup.hyperdb
312   import ...`` and the ``db = Database(config, name)`` line -- don't
313   need to be copied. Neither do the last few lines -- those starting
314   with ``import detectors``, down to ``return db`` inclusive.
316 You may remove the ``__init__.py`` module from the "detectors" directory as
317 it is no longer used.
319 There's a new way to write extension code for Roundup. If you have code in
320 an ``interfaces.py`` file you should move it. See the `customisation
321 documentation`_ for information about how extensions are now written.
322 Note that some older trackers may use ``interfaces.py`` to customise the
323 mail gateway behaviour. You will need to keep your ``interfaces.py`` file
324 if this is the case.
327 0.8.0 Permissions Changes
328 -------------------------
330 The creation of a new item in the user interfaces is now controlled by the
331 "Create" Permission. You will need to add an assignment of this Permission
332 to your users who are allowed to create items. The most common form of this
333 is the following in your ``schema.py`` added just under the current
334 assignation of the Edit Permission::
336     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
337         p = db.security.getPermission('Create', cl)
338         db.security.addPermissionToRole('User', p)
340 You will need to explicitly let anonymous users access the web interface so
341 that regular users are able to see the login form. Note that almost all
342 trackers will need this Permission. The only situation where it's not
343 required is in a tracker that uses an HTTP Basic Authenticated front-end.
344 It's enabled by adding to your ``schema.py``::
346     p = db.security.getPermission('Web Access')
347     db.security.addPermissionToRole('Anonymous', p)
349 Finally, you will need to enable permission for your users to edit their
350 own details by adding the following to ``schema.py``::
352     # Users should be able to edit their own details. Note that this
353     # permission is limited to only the situation where the Viewed or
354     # Edited item is their own.
355     def own_record(db, userid, itemid):
356         '''Determine whether the userid matches the item being accessed.'''
357         return userid == itemid
358     p = db.security.addPermission(name='View', klass='user', check=own_record,
359         description="User is allowed to view their own user details")
360     p = db.security.addPermission(name='Edit', klass='user', check=own_record,
361         description="User is allowed to edit their own user details")
362     db.security.addPermissionToRole('User', p)
365 0.8.0 Use of TemplatingUtils
366 ----------------------------
368 If you used custom python functions in TemplatingUtils, they must
369 be moved from interfaces.py to a new file in the ``extensions`` directory. 
371 Each Function that should be available through TAL needs to be defined
372 as a toplevel function in the newly created file. Furthermore you
373 add an inititialization function, that registers the functions with the 
374 tracker.
376 If you find this too tedious, donfu wrote an automatic init function that
377 takes an existing TemplatingUtils class, and registers all class methods
378 that do not start with an underscore. The following hack should be placed
379 in the ``extensions`` directory alongside other extensions::
381     class TemplatingUtils:
382          # copy from interfaces.py
384     def init(tracker):
385          util = TemplatingUtils()
387          def setClient(tu):
388              util.client = tu.client
389              return util
391          def execUtil(name):
392              return lambda tu, *args, **kwargs: \
393                      getattr(setClient(tu), name)(*args, **kwargs)
395          for name in dir(util):
396              if callable(getattr(util, name)) and not name.startswith('_'):
397                   tracker.registerUtil(name, execUtil(name))
400 0.8.0 Logging Configuration
401 ---------------------------
403 See the `administration guide`_ for information about configuring the new
404 logging implemented in 0.8.0.
407 Migrating from 0.7.2 to 0.7.3
408 =============================
410 0.7.3 Configuration
411 -------------------
413 If you choose, you may specify the directory from which static files are
414 served (those which use the URL component ``@@file``). Currently the
415 directory defaults to the ``TEMPLATES`` configuration variable. You may
416 define a new variable, ``STATIC_FILES`` which overrides this value for
417 static files.
420 Migrating from 0.7.0 to 0.7.2
421 =============================
423 0.7.2 DEFAULT_TIMEZONE is now required
424 --------------------------------------
426 The DEFAULT_TIMEZONE configuration variable is now required. Add the
427 following to your tracker's ``config.py`` file::
429     # You may specify a different default timezone, for use when users do not
430     # choose their own in their settings.
431     DEFAULT_TIMEZONE = 0            # specify as numeric hour offest
434 Migrating from 0.7.0 to 0.7.1
435 =============================
437 0.7.1 Permission assignments
438 ----------------------------
440 If you allow anonymous access to your tracker, you might need to assign
441 some additional View (or Edit if your tracker is that open) permissions
442 to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
443 says::
445     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
446         p = db.security.getPermission('View', cl)
447         db.security.addPermissionToRole('User', p)
448         p = db.security.getPermission('Edit', cl)
449         db.security.addPermissionToRole('User', p)
450     for cl in 'priority', 'status':
451         p = db.security.getPermission('View', cl)
452         db.security.addPermissionToRole('User', p)
454 Add add a line::
456         db.security.addPermissionToRole('Anonymous', p)
458 next to the existing ``'User'`` lines for the Permissions you wish to
459 assign to the anonymous user.
462 Migrating from 0.6 to 0.7
463 =========================
465 0.7.0 Permission assignments
466 ----------------------------
468 Due to a change in the rendering of web widgets, permissions are now
469 checked on Classes where they previously weren't (this is a good thing).
471 You will need to add some additional Permission assignments for your
472 regular users, or some displays will break. After the following in your 
473 tracker's ``dbinit.py``::
475     # Assign the access and edit Permissions for issue, file and message
476     # to regular users now
477     for cl in 'issue', 'file', 'msg', 'query', 'keyword':
478         p = db.security.getPermission('View', cl)
479         db.security.addPermissionToRole('User', p)
480         p = db.security.getPermission('Edit', cl)
481         db.security.addPermissionToRole('User', p)
483 add::
485     for cl in 'priority', 'status':
486         p = db.security.getPermission('View', cl)
487         db.security.addPermissionToRole('User', p)
490 0.7.0 Getting the current user id
491 ---------------------------------
493 The Database.curuserid attribute has been removed.
495 Any code referencing this attribute should be replaced with a
496 call to Database.getuid().
499 0.7.0 ZRoundup changes
500 ----------------------
502 The templates in your tracker's html directory will need updating if you
503 wish to use ZRoundup. If you've not modified those files (or some of them),
504 you may just copy the new versions from the Roundup source in the
505 templates/classic/html directory.
507 If you have modified the html files, then you'll need to manually edit them
508 to change all occurances of special form variables from using the colon ":"
509 special character to the at "@" special character. That is, variables such
510 as::
512   :action :required :template :remove:messages ...
514 should become::
516   @action @required @template @remove@messages ...
518 Note that ``tal:`` statements are unaffected. So are TAL expression type
519 prefixes such as ``python:`` and ``string:``. Please ask on the
520 roundup-users mailing list for help if you're unsure.
523 0.7.0 Edit collision detection
524 ------------------------------
526 Roundup now detects collisions with editing in the web interface (that is,
527 two people editing the same item at the same time).
529 You must copy the ``_generic.collision.html`` file from Roundup source in
530 the ``templates/classic/html`` directory. to your tracker's ``html``
531 directory.
534 Migrating from 0.6.x to 0.6.3
535 =============================
537 0.6.3 Configuration
538 -------------------
540 You will need to copy the file::
542   templates/classic/detectors/__init__.py
544 to your tracker's ``detectors`` directory, replacing the one already there.
545 This fixes a couple of bugs in that file.
549 Migrating from 0.5 to 0.6
550 =========================
553 0.6.0 Configuration
554 -------------------
556 Introduced EMAIL_FROM_TAG config variable. This value is inserted into
557 the From: line of nosy email. If the sending user is "Foo Bar", the
558 From: line is usually::
560      "Foo Bar" <issue_tracker@tracker.example>
562 the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
564      "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
566 I've altered the mechanism in the detectors __init__.py module so that it
567 doesn't cross-import detectors from other trackers (if you run more than one
568 in a single roundup-server). This change means that you'll need to copy the
569 __init__.py from roundup/templates/classic/detectors/__init__.py to your
570 <tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
571 one-size-fits-all, so it'll work even if you've added/removed detectors.
573 0.6.0 Templating changes
574 ------------------------
576 The ``user.item`` template (in the tracker home "templates" directory)
577 needs to have the following hidden variable added to its form (between the
578 ``<form...>`` and ``</form>`` tags::
580   <input type="hidden" name=":template" value="item">
583 0.6.0 Form handling changes
584 ---------------------------
586 Roundup's form handling capabilities have been significantly expanded. This
587 should not affect users of 0.5 installations - but if you find you're
588 getting errors from form submissions, please ask for help on the Roundup
589 users mailing list:
591   http://lists.sourceforge.net/lists/listinfo/roundup-users
593 See the customisation doc section on `Form Values`__ for documentation of the
594 new form variables possible.
596 __ customizing.html#form-values
599 0.6.0 Multilingual character set support
600 ----------------------------------------
602 Added internationalization support. This is done via encoding all data
603 stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
604 web interface you should add the folowing line to your tracker's html/page
605 and html/_generic.help files inside <head> tag::
606   
607     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
609 Since latin characters in utf-8 have the same codes as in ASCII table, this
610 modification is optional for users who use only plain latin characters. 
612 After this modification, you will be able to see and enter any world
613 character via web interface. Data received via mail interface also converted
614 to utf-8, however only new messages will be converted. If your roundup
615 database contains some of non-ASCII characters in one of 8-bit encoding,
616 they will not be visible in new unicode environment. Some of such data (e.g.
617 user names, keywords, etc)  can be edited by administrator, the others
618 (e.g. messages' contents) is not editable via web interface. Currently there
619 is no tool for converting such data, the only solution is to close
620 appropriate old issues and create new ones with the same content.
623 0.6.0 User timezone support
624 ---------------------------
626 From version 0.6.0 roundup supports displaying of Date data in user' local
627 timezone if he/she has provided timezone information. To make it possible
628 some modification to tracker's schema and HTML templates are required.
629 First you must add string property 'timezone' to user class in dbinit.py
630 like this::
631   
632     user = Class(db, "user", 
633                     username=String(),   password=Password(),
634                     address=String(),    realname=String(), 
635                     phone=String(),      organisation=String(),
636                     alternate_addresses=String(),
637                     queries=Multilink('query'), roles=String(),
638                     timezone=String())
639   
640 And second - html interface. Add following lines to
641 $TRACKER_HOME/html/user.item template::
642   
643      <tr>
644       <th>Timezone</th>
645       <td tal:content="structure context/timezone/field">timezone</td>
646      </tr>
648 After that all users should be able to provide their timezone information.
649 Timezone should be a positive or negative integer - offset from GMT.
651 After providing timezone, roundup will show all dates values, found in web
652 and mail interfaces in local time. It will also accept any Date info in
653 local time, convert and store it in GMT.
656 0.6.0 Search page structure
657 ---------------------------
659 In order to accomodate query editing the search page has been restructured. If
660 you want to provide your users with query editing, you should update your
661 search page using the macros detailed in the customisation doc section
662 `Searching on categories`__.
664 __ customizing.html#searching-on-categories
666 Also, the url field in the query class no longer starts with a '?'. You'll need
667 to remove this question mark from the url field to support queries. There's
668 a script in the "tools" directory called ``migrate-queries.py`` that should
669 automatically change any existing queries for you. As always, make a backup
670 of your database before running such a script.
673 0.6.0 Notes for metakit backend users
674 -------------------------------------
676 Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
677 support it, some modifications to interval storing routine were made. So if
678 your tracker uses metakit backend and your db schema contains intervals
679 property, searches on that property will not be accurate for db items that
680 was stored before roundup' upgrade. However all new records should be
681 searchable on intervals.
683 It is possible to convert your database to new format: you can export and
684 import back all your data (consult "Migrating backends" in "Maintenance"
685 documentation). After this operation all your interval properties should
686 become searchable.
688 Users of backends others than metakit should not worry about this issue.
691 Migrating from 0.4.x to 0.5.0
692 =============================
694 This has been a fairly major revision of Roundup:
696 1. Brand new, much more powerful, flexible, tasty and nutritious templating.
697    Unfortunately, this means all your current templates are useless. Hopefully
698    the new documentation and examples will be enough to help you make the
699    transition. Please don't hesitate to ask on roundup-users for help (or
700    complete conversions if you're completely stuck)!
701 2. The database backed got a lot more flexible, allowing Metakit and SQL
702    databases! The only decent SQL database implemented at present is sqlite,
703    but others shouldn't be a whole lot more work.
704 3. A brand new, highly flexible and much more robust security system including
705    a system of Permissions, Roles and Role assignments to users. You may now
706    define your own Permissions that may be checked in CGI transactions.
707 4. Journalling has been made less storage-hungry, so has been turned on
708    by default *except* for author, recipient and nosy link/unlink events. You
709    are advised to turn it off in your trackers too.
710 5. We've changed the terminology from "instance" to "tracker", to ease the
711    learning curve/impact for new users.
712 6. Because of the above changes, the tracker configuration has seen some
713    major changes. See below for the details.
715 Please, **back up your database** before you start the migration process. This
716 is as simple as copying the "db" directory and all its contents from your
717 tracker to somewhere safe.
720 0.5.0 Configuration
721 -------------------
723 First up, rename your ``instance_config.py`` file to just ``config.py``.
725 Then edit your tracker's ``__init__.py`` module. It'll currently look
726 like this::
728  from instance_config import *
729  try:
730      from dbinit import *
731  except ImportError:
732      pass # in installdir (probably :)
733  from interfaces import *
735 and it needs to be::
737  import config
738  from dbinit import open, init
739  from interfaces import Client, MailGW
741 Due to the new templating having a top-level ``page`` that defines links for
742 searching, indexes, adding items etc, the following variables are no longer
743 used:
745 - HEADER_INDEX_LINKS
746 - HEADER_ADD_LINKS
747 - HEADER_SEARCH_LINKS
748 - SEARCH_FILTERS
749 - DEFAULT_INDEX
750 - UNASSIGNED_INDEX
751 - USER_INDEX
752 - ISSUE_FILTER
754 The new security implementation will require additions to the dbinit module,
755 but also removes the need for the following tracker config variables:
757 - ANONYMOUS_ACCESS
758 - ANONYMOUS_REGISTER
760 but requires two new variables which define the Roles assigned to users who
761 register through the web and e-mail interfaces:
763 - NEW_WEB_USER_ROLES
764 - NEW_EMAIL_USER_ROLES
766 in both cases, 'User' is a good initial setting. To emulate
767 ``ANONYMOUS_ACCESS='deny'``, remove all "View" Permissions from the
768 "Anonymous" Role. To emulate ``ANONYMOUS_REGISTER='deny'``, remove the "Web
769 Registration" and/or the "Email Registration" Permission from the "Anonymous"
770 Role. See the section on customising security in the `customisation
771 documentation`_ for more information.
773 Finally, the following config variables have been renamed to make more sense:
775 - INSTANCE_HOME -> TRACKER_HOME
776 - INSTANCE_NAME -> TRACKER_NAME
777 - ISSUE_TRACKER_WEB -> TRACKER_WEB
778 - ISSUE_TRACKER_EMAIL -> TRACKER_EMAIL
781 0.5.0 Schema Specification
782 --------------------------
784 0.5.0 Database backend changes
785 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
787 Your select_db module in your tracker has changed a fair bit. Where it used
788 to contain::
790  # WARNING: DO NOT EDIT THIS FILE!!!
791  from roundup.backends.back_anydbm import Database
793 it must now contain::
795  # WARNING: DO NOT EDIT THIS FILE!!!
796  from roundup.backends.back_anydbm import Database, Class, FileClass, IssueClass
798 Yes, I realise the irony of the "DO NOT EDIT THIS FILE" statement :)
799 Note the addition of the Class, FileClass, IssueClass imports. These are very
800 important, as they're going to make the next change work too. You now need to
801 modify the top of the dbinit module in your tracker from::
803  import instance_config
804  from roundup import roundupdb
805  from select_db import Database
807  from roundup.roundupdb import Class, FileClass
809  class Database(roundupdb.Database, select_db.Database):
810      ''' Creates a hybrid database from:
811           . the selected database back-end from select_db
812           . the roundup extensions from roundupdb
813      '''
814      pass
816  class IssueClass(roundupdb.IssueClass):
817      ''' issues need the email information
818      '''
819      pass
821 to::
823  import config
824  from select_db import Database, Class, FileClass, IssueClass
826 Yes, remove the Database and IssueClass definitions and those other imports.
827 They're not needed any more!
829 Look for places in dbinit.py where ``instance_config`` is used too, and
830 rename them ``config``.
833 0.5.0 Journalling changes
834 ~~~~~~~~~~~~~~~~~~~~~~~~~
836 Journalling has been optimised for storage. Journalling of links has been
837 turned back on by default. If your tracker has a large user base, you may wish
838 to turn off journalling of nosy list, message author and message recipient
839 link and unlink events. You do this by adding ``do_journal='no'`` to the Class
840 initialisation in your dbinit. For example, your *msg* class initialisation
841 probably looks like this::
843     msg = FileClass(db, "msg",
844                     author=Link("user"), recipients=Multilink("user"),
845                     date=Date(),         summary=String(),
846                     files=Multilink("file"),
847                     messageid=String(),  inreplyto=String())
849 to turn off journalling of author and recipient link events, add
850 ``do_journal='no'`` to the ``author=Link("user")`` part of the statement,
851 like so::
853     msg = FileClass(db, "msg",
854                     author=Link("user", do_journal='no'),
855                     recipients=Multilink("user", do_journal='no'),
856                     date=Date(),         summary=String(),
857                     files=Multilink("file"),
858                     messageid=String(),  inreplyto=String())
860 Nosy list link event journalling is actually turned off by default now. If you
861 want to turn it on, change to your issue class' nosy list, change its
862 definition from::
864     issue = IssueClass(db, "issue",
865                     assignedto=Link("user"), topic=Multilink("keyword"),
866                     priority=Link("priority"), status=Link("status"))
868 to::
870     issue = IssueClass(db, "issue", nosy=Multilink("user", do_journal='yes'),
871                     assignedto=Link("user"), topic=Multilink("keyword"),
872                     priority=Link("priority"), status=Link("status"))
874 noting that your definition of the nosy Multilink will override the normal one.
877 0.5.0 User schema changes
878 ~~~~~~~~~~~~~~~~~~~~~~~~~
880 Users have two more properties, "queries" and "roles". You'll have something
881 like this in your dbinit module now::
883     user = Class(db, "user",
884                     username=String(),   password=Password(),
885                     address=String(),    realname=String(),
886                     phone=String(),      organisation=String(),
887                     alternate_addresses=String())
888     user.setkey("username")
890 and you'll need to add the new properties and the new "query" class to it
891 like so::
893     query = Class(db, "query",
894                     klass=String(),     name=String(),
895                     url=String())
896     query.setkey("name")
898     # Note: roles is a comma-separated string of Role names
899     user = Class(db, "user",
900                     username=String(),   password=Password(),
901                     address=String(),    realname=String(),
902                     phone=String(),      organisation=String(),
903                     alternate_addresses=String(),
904                     queries=Multilink('query'), roles=String())
905     user.setkey("username")
907 The "queries" property is used to store off the user's favourite database
908 queries. The "roles" property is explained below in `0.5.0 Security
909 Settings`_.
912 0.5.0 Security Settings
913 ~~~~~~~~~~~~~~~~~~~~~~~
915 See the `security documentation`_ for an explanation of how the new security
916 system works. In a nutshell though, the security is handled as a four step
917 process:
919 1. Permissions are defined as having a name and optionally a hyperdb class
920    they're specific to,
921 2. Roles are defined that have one or more Permissions,
922 3. Users are assigned Roles in their "roles" property, and finally
923 4. Roundup checks that users have appropriate Permissions at appropriate times
924    (like editing issues).
926 Your tracker dbinit module's *open* function now has to define any
927 Permissions that are specific to your tracker, and also the assignment
928 of Permissions to Roles. At the moment, your open function
929 ends with::
931     import detectors
932     detectors.init(db)
934     return db
936 and what we need to do is insert some commands that will set up the security
937 parameters. Right above the ``import detectors`` line, you'll want to insert
938 these lines::
940     #
941     # SECURITY SETTINGS
942     #
943     # new permissions for this schema
944     for cl in 'issue', 'file', 'msg', 'user':
945         db.security.addPermission(name="Edit", klass=cl,
946             description="User is allowed to edit "+cl)
947         db.security.addPermission(name="View", klass=cl,
948             description="User is allowed to access "+cl)
950     # Assign the access and edit permissions for issue, file and message
951     # to regular users now
952     for cl in 'issue', 'file', 'msg':
953         p = db.security.getPermission('View', cl)
954         db.security.addPermissionToRole('User', p)
955         p = db.security.getPermission('Edit', cl)
956         db.security.addPermissionToRole('User', p)
957     # and give the regular users access to the web and email interface
958     p = db.security.getPermission('Web Access')
959     db.security.addPermissionToRole('User', p)
960     p = db.security.getPermission('Email Access')
961     db.security.addPermissionToRole('User', p)
963     # May users view other user information? Comment these lines out
964     # if you don't want them to
965     p = db.security.getPermission('View', 'user')
966     db.security.addPermissionToRole('User', p)
968     # Assign the appropriate permissions to the anonymous user's Anonymous
969     # Role. Choices here are:
970     # - Allow anonymous users to register through the web
971     p = db.security.getPermission('Web Registration')
972     db.security.addPermissionToRole('Anonymous', p)
973     # - Allow anonymous (new) users to register through the email gateway
974     p = db.security.getPermission('Email Registration')
975     db.security.addPermissionToRole('Anonymous', p)
976     # - Allow anonymous users access to the "issue" class of data
977     #   Note: this also grants access to related information like files,
978     #         messages, statuses etc that are linked to issues
979     #p = db.security.getPermission('View', 'issue')
980     #db.security.addPermissionToRole('Anonymous', p)
981     # - Allow anonymous users access to edit the "issue" class of data
982     #   Note: this also grants access to create related information like
983     #         files and messages etc that are linked to issues
984     #p = db.security.getPermission('Edit', 'issue')
985     #db.security.addPermissionToRole('Anonymous', p)
987     # oh, g'wan, let anonymous access the web interface too
988     p = db.security.getPermission('Web Access')
989     db.security.addPermissionToRole('Anonymous', p)
991 Note in the comments there the places where you might change the permissions
992 to restrict users or grant users more access. If you've created additional
993 classes that users should be able to edit and view, then you should add them
994 to the "new permissions for this schema" section at the start of the security
995 block. Then add them to the "Assign the access and edit permissions" section
996 too, so people actually have the new Permission you've created.
998 One final change is needed that finishes off the security system's
999 initialisation. We need to add a call to ``db.post_init()`` at the end of the
1000 dbinit open() function. Add it like this::
1002     import detectors
1003     detectors.init(db)
1005     # schema is set up - run any post-initialisation
1006     db.post_init()
1007     return db
1009 You may verify the setup of Permissions and Roles using the new
1010 "``roundup-admin security``" command.
1013 0.5.0 User changes
1014 ~~~~~~~~~~~~~~~~~~
1016 To support all those schema changes, you'll need to massage your user database
1017 a little too, to:
1019 1. make sure there's an "anonymous" user - this user is mandatory now and is
1020    the one that unknown users are logged in as.
1021 2. make sure all users have at least one Role.
1023 If you don't have the "anonymous" user, create it now with the command::
1025   roundup-admin create user username=anonymous roles=Anonymous
1027 making sure the capitalisation is the same as above. Once you've done that,
1028 you'll need to set the roles property on all users to a reasonable default.
1029 The admin user should get "Admin", the anonymous user "Anonymous"
1030 and all other users "User". The ``fixroles.py`` script in the tools directory
1031 will do this. Run it like so (where python is your python 2+ binary)::
1033   python tools/fixroles.py -i <tracker home> fixroles
1037 0.5.0 CGI interface changes
1038 ---------------------------
1040 The CGI interface code was completely reorganised and largely rewritten. The
1041 end result is that this section of your tracker interfaces module will need
1042 changing from::
1044  from roundup import cgi_client, mailgw
1045  from roundup.i18n import _
1046  
1047  class Client(cgi_client.Client):
1048      ''' derives basic CGI implementation from the standard module,
1049          with any specific extensions
1050      '''
1051      pass
1053 to::
1055  from roundup import mailgw
1056  from roundup.cgi import client
1057  
1058  class Client(client.Client): 
1059      ''' derives basic CGI implementation from the standard module,
1060          with any specific extensions
1061      '''
1062      pass
1064 You will also need to install the new version of roundup.cgi from the source
1065 cgi-bin directory if you're using it.
1068 0.5.0 HTML templating
1069 ---------------------
1071 You'll want to make a backup of your current tracker html directory. You
1072 should then copy the html directory from the Roundup source "classic" template
1073 and modify it according to your local schema changes.
1075 If you need help with the new templating system, please ask questions on the
1076 roundup-users mailing list (available through the roundup project page on
1077 sourceforge, http://roundup.sf.net/)
1080 0.5.0 Detectors
1081 ---------------
1083 The nosy reactor has been updated to handle the tracker not having an
1084 "assignedto" property on issues. You may want to copy it into your tracker's
1085 detectors directory. Chances are you've already fixed it though :)
1088 Migrating from 0.4.1 to 0.4.2
1089 =============================
1091 0.4.2 Configuration
1092 -------------------
1093 The USER_INDEX definition introduced in 0.4.1 was too restrictive in its
1094 allowing replacement of 'assignedto' with the user's userid. Users must change
1095 the None value of 'assignedto' to 'CURRENT USER' (the string, in quotes) for
1096 the replacement behaviour to occur now.
1098 The new configuration variables are:
1100 - EMAIL_KEEP_QUOTED_TEXT 
1101 - EMAIL_LEAVE_BODY_UNCHANGED
1102 - ADD_RECIPIENTS_TO_NOSY
1104 See the sample configuration files in::
1106  <roundup source>/roundup/templates/classic/instance_config.py
1108 and::
1110  <roundup source>/roundup/templates/extended/instance_config.py
1112 and the `customisation documentation`_ for information on how they're used.
1115 0.4.2 Changes to detectors
1116 --------------------------
1117 You will need to copy the detectors from the distribution into your instance
1118 home "detectors" directory. If you used the classic schema, the detectors
1119 are in::
1121  <roundup source>/roundup/templates/classic/detectors/
1123 If you used the extended schema, the detectors are in::
1125  <roundup source>/roundup/templates/extended/detectors/
1127 The change means that schema-specific code has been removed from the
1128 mail gateway and cgi interface and made into auditors:
1130 - nosyreactor.py has now got an updatenosy auditor which updates the nosy
1131   list with author, recipient and assignedto information.
1132 - statusauditor.py makes the unread or resolved -> chatting changes and
1133   presets the status of an issue to unread.
1135 There's also a bug or two fixed in the nosyreactor code.
1137 0.4.2 HTML templating changes
1138 -----------------------------
1139 The link() htmltemplate function now has a "showid" option for links and
1140 multilinks. When true, it only displays the linked item id as the anchor
1141 text. The link value is displayed as a tooltip using the title anchor
1142 attribute. To use in eg. the superseder field, have something like this::
1144    <td>
1145     <display call="field('superseder', showid=1)">
1146     <display call="classhelp('issue', 'id,title', label='list', width=500)">
1147     <property name="superseder">
1148      <br>View: <display call="link('superseder', showid=1)">
1149     </property>
1150    </td>
1152 The stylesheets have been cleaned up too. You may want to use the newer
1153 versions in::
1155  <roundup source>/roundup/templates/<template>/html/default.css
1159 Migrating from 0.4.0 to 0.4.1
1160 =============================
1162 0.4.1 Files storage
1163 -------------------
1165 Messages and files from newly created issues will be put into subdierectories
1166 in thousands e.g. msg123 will be put into files/msg/0/msg123, file2003
1167 will go into files/file/2/file2003. Previous messages are still found, but
1168 could be put into this structure.
1170 0.4.1 Configuration
1171 -------------------
1173 To allow more fine-grained access control, the variable used to check
1174 permission to auto-register users in the mail gateway is now called
1175 ANONYMOUS_REGISTER_MAIL rather than overloading ANONYMOUS_REGISTER. If the
1176 variable doesn't exist, then ANONYMOUS_REGISTER is tested as before.
1178 Configuring the links in the web header is now easier too. The following
1179 variables have been added to the classic instance_config.py::
1181   HEADER_INDEX_LINKS   - defines the "index" links to be made available
1182   HEADER_ADD_LINKS     - defines the "add" links
1183   DEFAULT_INDEX        - specifies the index view for DEFAULT
1184   UNASSIGNED_INDEX     - specifies the index view for UNASSIGNED
1185   USER_INDEX           - specifies the index view for USER
1187 See the <roundup source>/roundup/templates/classic/instance_config.py for more
1188 information - including how the variables are to be set up. Most users will
1189 just be able to copy the variables from the source to their instance home. If
1190 you've modified the header by changing the source of the interfaces.py file in
1191 the instance home, you'll need to remove that customisation and move it into
1192 the appropriate variables in instance_config.py.
1194 The extended schema has similar variables added too - see the source for more
1195 info.
1197 0.4.1 Alternate E-Mail Addresses
1198 --------------------------------
1200 If you add the property "alternate_addresses" to your user class, your users
1201 will be able to register alternate email addresses that they may use to
1202 communicate with roundup as. All email from roundup will continue to be sent
1203 to their primary address.
1205 If you have not edited the dbinit.py file in your instance home directory,
1206 you may simply copy the new dbinit.py file from the core code. If you used
1207 the classic schema, the interfaces file is in::
1209  <roundup source>/roundup/templates/classic/dbinit.py
1211 If you used the extended schema, the file is in::
1213  <roundup source>/roundup/templates/extended/dbinit.py 
1215 If you have modified your dbinit.py file, you need to edit the dbinit.py
1216 file in your instance home directory. Find the lines which define the user
1217 class::
1219     user = Class(db, "msg",
1220                     username=String(),   password=Password(),
1221                     address=String(),    realname=String(), 
1222                     phone=String(),      organisation=String(),
1223                     alternate_addresses=String())
1225 You will also want to add the property to the user's details page. The
1226 template for this is the "user.item" file in your instance home "html"
1227 directory. Similar to above, you may copy the file from the roundup source if
1228 you haven't modified it. Otherwise, add the following to the template::
1230    <display call="multiline('alternate_addresses')">
1232 with appropriate labelling etc. See the standard template for an idea.
1236 Migrating from 0.3.x to 0.4.0
1237 =============================
1239 0.4.0 Message-ID and In-Reply-To addition
1240 -----------------------------------------
1241 0.4.0 adds the tracking of messages by message-id and allows threading
1242 using in-reply-to. Most e-mail clients support threading using this
1243 feature, and we hope to add support for it to the web gateway. If you
1244 have not edited the dbinit.py file in your instance home directory, you may
1245 simply copy the new dbinit.py file from the core code. If you used the
1246 classic schema, the interfaces file is in::
1248  <roundup source>/roundup/templates/classic/dbinit.py
1250 If you used the extended schema, the file is in::
1252  <roundup source>/roundup/templates/extended/dbinit.py 
1254 If you have modified your dbinit.py file, you need to edit the dbinit.py
1255 file in your instance home directory. Find the lines which define the msg
1256 class::
1258     msg = FileClass(db, "msg",
1259                     author=Link("user"), recipients=Multilink("user"),
1260                     date=Date(),         summary=String(),
1261                     files=Multilink("file"))
1263 and add the messageid and inreplyto properties like so::
1265     msg = FileClass(db, "msg",
1266                     author=Link("user"), recipients=Multilink("user"),
1267                     date=Date(),         summary=String(),
1268                     files=Multilink("file"),
1269                     messageid=String(),  inreplyto=String())
1271 Also, configuration is being cleaned up. This means that your dbinit.py will
1272 also need to be changed in the open function. If you haven't changed your
1273 dbinit.py, the above copy will be enough. If you have, you'll need to change
1274 the line (round line 50)::
1276     db = Database(instance_config.DATABASE, name)
1278 to::
1280     db = Database(instance_config, name)
1283 0.4.0 Configuration
1284 --------------------
1285 ``TRACKER_NAME`` and ``EMAIL_SIGNATURE_POSITION`` have been added to the
1286 instance_config.py. The simplest solution is to copy the default values
1287 from template in the core source.
1289 The mail gateway now checks ``ANONYMOUS_REGISTER`` to see if unknown users
1290 are to be automatically registered with the tracker. If it is set to "deny"
1291 then unknown users will not have access. If it is set to "allow" they will be
1292 automatically registered with the tracker.
1295 0.4.0 CGI script roundup.cgi
1296 ----------------------------
1297 The CGI script has been updated with some features and a bugfix, so you should
1298 copy it from the roundup cgi-bin source directory again. Make sure you update
1299 the ROUNDUP_INSTANCE_HOMES after the copy.
1302 0.4.0 Nosy reactor
1303 ------------------
1304 The nosy reactor has also changed - copy the nosyreactor.py file from the core
1305 source::
1307    <roundup source>/roundup/templates/<template>/detectors/nosyreactor.py
1309 to your instance home "detectors" directory.
1312 0.4.0 HTML templating
1313 ---------------------
1314 The field() function was incorrectly implemented - links and multilinks now
1315 display as text fields when rendered using field(). To display a menu (drop-
1316 down or select box) you need to use the menu() function.
1320 Migrating from 0.2.x to 0.3.x
1321 =============================
1323 0.3.x Cookie Authentication changes
1324 -----------------------------------
1325 0.3.0 introduces cookie authentication - you will need to copy the
1326 interfaces.py file from the roundup source to your instance home to enable
1327 authentication. If you used the classic schema, the interfaces file is in::
1329  <roundup source>/roundup/templates/classic/interfaces.py
1331 If you used the extended schema, the file is in::
1333  <roundup source>/roundup/templates/extended/interfaces.py
1335 If you have modified your interfaces.Client class, you will need to take
1336 note of the login/logout functionality provided in roundup.cgi_client.Client
1337 (classic schema) or roundup.cgi_client.ExtendedClient (extended schema) and
1338 modify your instance code apropriately.
1341 0.3.x Password encoding
1342 -----------------------
1343 This release also introduces encoding of passwords in the database. If you
1344 have not edited the dbinit.py file in your instance home directory, you may
1345 simply copy the new dbinit.py file from the core code. If you used the
1346 classic schema, the interfaces file is in::
1348  <roundup source>/roundup/templates/classic/dbinit.py
1350 If you used the extended schema, the file is in::
1352  <roundup source>/roundup/templates/extended/dbinit.py
1355 If you have modified your dbinit.py file, you may use encoded passwords:
1357 1. Edit the dbinit.py file in your instance home directory
1358    a. At the first code line of the open() function::
1360        from roundup.hyperdb import String, Date, Link, Multilink
1362       alter to include Password, as so::
1364        from roundup.hyperdb import String, Password, Date, Link, Multilink
1366    b. Where the password property is defined (around line 66)::
1368        user = Class(db, "user", 
1369                        username=String(),   password=String(),
1370                        address=String(),    realname=String(), 
1371                        phone=String(),      organisation=String())
1372        user.setkey("username")
1374       alter the "password=String()" to "password=Password()"::
1376        user = Class(db, "user", 
1377                        username=String(),   password=Password(),
1378                        address=String(),    realname=String(), 
1379                        phone=String(),      organisation=String())
1380        user.setkey("username")
1382 2. Any existing passwords in the database will remain cleartext until they
1383    are edited. It is recommended that at a minimum the admin password be
1384    changed immediately::
1386       roundup-admin -i <instance home> set user1 password=<new password>
1389 0.3.x Configuration
1390 -------------------
1391 FILTER_POSITION, ANONYMOUS_ACCESS, ANONYMOUS_REGISTER have been added to
1392 the instance_config.py. Simplest solution is to copy the default values from
1393 template in the core source.
1395 MESSAGES_TO_AUTHOR has been added to the IssueClass in dbinit.py. Set to 'yes'
1396 to send nosy messages to the author. Default behaviour is to not send nosy
1397 messages to the author. You will need to add MESSAGES_TO_AUTHOR to your
1398 dbinit.py in your instance home.
1401 0.3.x CGI script roundup.cgi
1402 ----------------------------
1403 There have been some structural changes to the roundup.cgi script - you will
1404 need to install it again from the cgi-bin directory of the source
1405 distribution. Make sure you update the ROUNDUP_INSTANCE_HOMES after the
1406 copy.
1409 .. _`customisation documentation`: customizing.html
1410 .. _`security documentation`: security.html
1411 .. _`administration guide`: admin_guide.html