Infrastructure - Web Applications > Index > Upgrading the Apache JIRAs
Added by Jeff Turner, last edited by Henri Yandell on Nov 23, 2008  (view change)
Untested

The process documented here should be complete and sufficient to allow someone to upgrade JIRA.
To iron out any bugs or unclear areas, please coordinate with the author (jefft@apache.org).

These are some notes on how to upgrade the Apache JIRA installations; currently:

TOC

Prerequisites

You will need:

  • Access to the 'jira' account on brutus.
  • An IRC client pointed to the #asfinfra channel on irc.freenode.net, to discuss anything with ASF admins should the need arise.
  • Knowledge of shell scripting, GNU diff and patch, command-line Subversion, and how to use a unix editor (vim, emacs, etc).
  • Subversion karma to commit to https://svn.apache.org/repos/asf/infrastructure/

You should also read the release notes and particularly the associated Upgrade Guide for the JIRA version you're upgrading to. It often contains important information.

Overview

This process uses the JIRA 'Standalone' edition, which comes with Tomcat prebundled. This has proven simpler than deploying new webapps into a permanently deployed Tomcat, and makes rolling back easier if if it all goes wrong, as there is always a fully working old Tomcat+JIRA+database configuration.

So we will start with JIRA Standalone, and progressively customize it to meet our needs.

§1 Applying ASF JIRA Customizations

In this step, we deploy a JIRA Standalone instance configured with all relevant plugins and patches, hooked up to Apache, pointing to an empty test database.

The process for deploying JIRA Standalone, compiling all added plugins, applying patches and connecting it to the database and Apache is all scripted (the 'jiradeploy' script). Inevitably the script will fail at first, as patches fail to apply cleanly or plugins don't compile against new JIRA. Your job is to fix broken patches and plugins and rerun the script, until it eventually succeeds. Eventually you'll have a working JIRA tricked out with all the required customizations, pointing at an
empty test database. It will be visible to you at https://issues.apache.org/jira_testing/.

Into this test JIRA we now import a copy of our real data. This tests the upgrade process itself, and that the new plugins and patches work with live data. There is a checklist below that you should go through, to ensure everything really is working.

The end result of this step is a customized JIRA Standalone instance that you're confident can be put into production. It is not yet customized for any particular JIRA instance. I've called this JIRA the template JIRA below and in the scripts.

§2 Making system-specific copies

We now copy the template, once for each new JIRA (/jira, /cayenne, //activemq and /struts), and making the copy instance-specific by:

  • editing database connection details, Tomcat ports, memory settings.
  • creating new, empty databases for the data to be imported into (eg. jira_activemq_3121 if we were upgrading to 3.12.1). This means the data from the previous JIRA version is still available should we need to roll back (eg. in jira_activemq_3101 if we upgraded from JIRA 3.10.1).

We now have 4 directories, each containing a customized copy of our JIRA, each pointing at a clean database, waiting to be started.

§3 Switching live JIRAs

Now everything is prepared, and we can make the actual changes. We basically follow the recommended upgrade procedure (which you should read), but with a twist that allows us to minimize downtime.

The recommended upgrade procedure involves exporting a database backup as XML, and importing it via JIRA into a clean database. This takes ~40 minutes. To avoid so much outright downtime, we:

  • make the live JIRA read-only at the database layer, and put up a banner saying so.
  • generate an XML export of the data.
  • start up the new JIRA (with an empty database).
  • import our XML export into the new JIRA.
  • do a quick sanity check on the new JIRA with its new live data.
  • shut down the new JIRA and change its listening ports and context path to that of the live JIRA, and enable email and mail-fetching.
  • shut down the old JIRA and bring up the new JIRA.

Net result: users experience 40 minutes of read-only'ness rather than 40 minutes' unavailability while JIRA imports the old data.

An even better alternative is to do an in-place database upgrade (just pointing the new JIRA at the old database). This involves less downtime, but isn't always possible. See the in-place upgrade section of these docs for details.

This process is repeated 4 times, once for each JIRA. It is best to start with the smaller JIRAs (eg. cayenne), so you can get some practice in before the main one.

The process in practice

Start by logging in, and using the sujira script to become the jira user.

jturner@teacup:~$ ssh jefft@brutus.apache.org
jefft@brutus:~$ 

  Become the 'jira' user:

jefft@brutus:~$ cat /usr/local/bin/sujira 
#!/bin/sh

sudo su - jira -s /bin/bash
jefft@brutus:~$ sujira
otp-md5 331 br9557 ext, Response:
Password: *********
jira@brutus:~$ 

Where is everything?

The JIRA installations are in /usr/local/tomcat:

jira@brutus:~$ ls -l /usr/local/tomcat
total 5824
drwxr-sr-x 11 jira jiraadmin    4096 2007-03-28 03:08 apache-tomcat-5.5.16
-rw-r--r--  1 jira jiraadmin 5878573 2006-04-08 08:10 apache-tomcat-5.5.16.tar.gz
drwxr-sr-x  8 jira jiraadmin    4096 2008-01-02 05:24 deleteme
-rw-r--r--  1 jira jiraadmin    1101 2007-08-06 17:08 LICENSES.txt
-rw-r--r--  1 jira jiraadmin     303 2006-12-27 21:14 PORTS.txt
drwxrwxr-x  3 jira jiraadmin    4096 2006-02-13 03:21 scarab
lrwxrwxrwx  1 jira jiraadmin      20 2006-04-13 08:59 tomcat -> apache-tomcat-5.5.16
drwxr-sr-x 11 root jiraadmin    4096 2006-10-27 15:05 tomcat-confluence
lrwxrwxrwx  1 jira jiraadmin      18 2008-01-01 15:25 tomcat-jira -> tomcat-jira-3.12.1
drwxr-sr-x 15 jira jiraadmin    4096 2007-09-20 12:48 tomcat-jira-3.10.1
drwxr-sr-x 14 jira jiraadmin    4096 2007-08-05 00:25 tomcat-jira-3.10.1-activemq
drwxr-sr-x 14 jira jiraadmin    4096 2007-11-13 07:43 tomcat-jira-3.10.1-cayenne
drwxr-sr-x 14 jira jiraadmin    4096 2007-08-05 00:25 tomcat-jira-3.10.1-struts
drwxr-sr-x 14 jira jiraadmin    4096 2007-08-28 18:54 tomcat-jira-3.10.1-template
drwxr-sr-x 16 jira jiraadmin    4096 2008-01-01 15:43 tomcat-jira-3.12.1
drwxr-sr-x 15 jira jiraadmin    4096 2008-01-01 06:02 tomcat-jira-3.12.1-activemq
drwxr-sr-x 15 jira jiraadmin    4096 2008-01-01 06:02 tomcat-jira-3.12.1-cayenne
drwxr-sr-x 15 jira jiraadmin    4096 2008-01-01 06:02 tomcat-jira-3.12.1-struts
drwxr-sr-x 15 jira jiraadmin    4096 2008-01-01 16:17 tomcat-jira-3.12.1-template
lrwxrwxrwx  1 jira jiraadmin      28 2008-01-01 06:49 tomcat-jira-activemq -> tomcat-jira-3.12.1-activemq/
lrwxrwxrwx  1 jira jiraadmin      27 2008-01-01 06:28 tomcat-jira-cayenne -> tomcat-jira-3.12.1-cayenne/
lrwxrwxrwx  1 jira jiraadmin      26 2008-01-01 07:21 tomcat-jira-struts -> tomcat-jira-3.12.1-struts/
drwxrwxr-x  9 jira jiraadmin    4096 2007-03-28 03:00 tomcat-scarab
jira@brutus:~$ 

There you can see tomcat-jira-*-template instances with generic changes:

drwxr-sr-x 15 jira jiraadmin    4096 2008-01-01 16:17 tomcat-jira-3.12.1-template

and copies of it made with system-specific changes:

drwxr-sr-x 16 jira jiraadmin    4096 2008-01-01 15:43 tomcat-jira-3.12.1
drwxr-sr-x 15 jira jiraadmin    4096 2008-01-01 06:02 tomcat-jira-3.12.1-activemq
drwxr-sr-x 15 jira jiraadmin    4096 2008-01-01 06:02 tomcat-jira-3.12.1-cayenne
drwxr-sr-x 15 jira jiraadmin    4096 2008-01-01 06:02 tomcat-jira-3.12.1-struts

Have a look at the conf/server.xml file in these to see which database they're using, their configured ports and context path.

We'll be creating another set of these during the upgrade.

The upgrade scripts are in ~/infrastructure/jira/upgrading:

jira@brutus:~$ cd infrastructure/jira/upgrading/
jira@brutus:~/infrastructure/jira/upgrading$ ls
activemq        bin               closedissues_editable.patch  jiraapplication.patch      jiradeploy_plugin_from_svn  log4j.patch  struts         webxml.patch
asfjiraplugin   bugzillaimporter  conf                         jiradeploy                 jiradeploy_rpcplugin        mainjira     svnplugin
atlassian-jira  cayenne           entityengine.patch           jiradeploy_chartingplugin  jiradeploy_svnplugin        rpcplugin    UPGRADING.txt
jira@brutus:~/infrastructure/jira/upgrading$

You should update these files from Subversion before beginning:

jira@brutus:~/infrastructure/jira/upgrading$ svn up
Authentication realm: <https://svn.apache.org:443> ASF Committers
Password for 'jira': 
Authentication realm: <https://svn.apache.org:443> ASF Committers
Username: jefft
Password for 'jefft': 
At revision 608106.
jira@brutus:~/infrastructure/jira/upgrading$ 

The ~/upgrade_$version directories contain artifacts from previous upgrades, notably backup files containing the data just before the upgrade.

The databases:

jira@brutus:~$ psql -l
            List of databases
        Name        |  Owner   | Encoding 
--------------------+----------+----------
 jira_3101          | jira     | UNICODE
 jira_3121          | jira     | UNICODE
 jira_activemq_3101 | jira     | UNICODE
 jira_activemq_3121 | jira     | UNICODE
 jira_cayenne_3101  | jira     | UNICODE
 jira_cayenne_3121  | jira     | UNICODE
 jira_struts_3101   | jira     | UNICODE
 jira_struts_3121   | jira     | UNICODE
 jira_testing       | jira     | UNICODE
 template0          | postgres | UNICODE
 template1          | postgres | UNICODE
(11 rows)

jira@brutus:~$ 

Here you can see the live databases (at time of writing) (jira*_3121 and previous version's database (jira*_3101). The jira_testing database is what we'll reuse below for our template JIRA.

The index and attachments directories are below /var/local/jira. You can query the databases to see where each JIRA says its index and attachments directories are:

jira@brutus:~$ psql jira_3121 -c "select pe.property_key, ps.propertyvalue from propertyentry pe, propertystring ps where pe.id=ps.id and pe.entity_name='jira.properties' and pe.property_key like 'jira.path.index'"
  property_key   |              propertyvalue              
-----------------+-----------------------------------------
 jira.path.index | /var/local/jira/indexes/mainjira/3.12.1
(1 row)

jira@brutus:~$ psql jira_3121 -c "select pe.property_key, ps.propertyvalue from propertyentry pe, propertystring ps where pe.id=ps.id and pe.entity_name='jira.properties' and pe.property_key like 'jira.path.attachments'"
     property_key      |          propertyvalue           
-----------------------+----------------------------------
 jira.path.attachments | /var/local/jira/attachments/jira
(1 row)

jira@brutus:~$ 

You don't need to deal with these directories much, but here they are:

jira@brutus:~$ ls /var/local/jira/
attachments  indexes
jira@brutus:~$ ls /var/local/jira/indexes/
activemq  cayenne  jira_testing  mainjira  struts
jira@brutus:~$ ls /var/local/jira/indexes/mainjira/
3.10.1  3.12.1
jira@brutus:~$ ls /var/local/jira/attachments/
activemq  cayenne  jira  struts
jira@brutus:~$ ls /var/local/jira/attachments/jira
ABDERA      CACTUS         DBUTILS  .....

The Apache configuration is /usr/local/apache2-install/issues.apache.org/conf/vhosts/issues.brutus.apache.org.part. It is also checked into svn here.

§1 Applying ASF JIRA Customizations

Updating variables in jiradeploy

We're now going to run the 'jiradeploy' script, which does everything: downloads JIRA, patches JIRA, downloads and installs plugins, hooks it up to a 'jira_testing' database, sets up the Apache connector, and finally starts JIRA. However first, we need to edit the jiradeploy script and friends to let it know which versions of plugins to use.

So:

Run and debug jiradeploy

Now run 'jiradeploy'. Here is a fairly typical first run:

jira@brutus:~/infrastructure/jira/upgrading$ jiradeploy 3.12.1
Downloading JIRA 3.12.1 ..
Clean copy of JIRA 3.12.1 unpacked to /home/jira/upgrade_3.12.1
Applying patches to JIRA ..
In /usr/local/tomcat/tomcat-jira-3.12.1-template
+ cat /home/jira/infrastructure/jira/upgrading/closedissues_editable.patch /home/jira/infrastructure/jira/upgrading/entityengine.patch /home/jira/infrastructure/jira/upgrading/jiraapplication.patch /home/jira/infrastructure/jira/upgrading/log4j.patch /home/jira/infrastructure/jira/upgrading/webxml.patch
+ patch -p0
patching file atlassian-jira/WEB-INF/classes/jira-workflow.xml
patching file atlassian-jira/WEB-INF/classes/entityengine.xml
patching file atlassian-jira/WEB-INF/classes/jira-application.properties
Hunk #1 succeeded at 108 with fuzz 2.
Hunk #2 succeeded at 135 (offset 5 lines).
Hunk #3 succeeded at 153 (offset 5 lines).
Hunk #4 FAILED at 305.
1 out of 4 hunks FAILED -- saving rejects to file atlassian-jira/WEB-INF/classes/jira-application.properties.rej
patching file atlassian-jira//WEB-INF/classes/log4j.properties
Hunk #1 FAILED at 85.
Hunk #2 succeeded at 126 with fuzz 2 (offset 7 lines).
1 out of 2 hunks FAILED -- saving rejects to file atlassian-jira//WEB-INF/classes/log4j.properties.rej
patching file atlassian-jira/WEB-INF/web.xml
Hunk #1 succeeded at 778 (offset 120 lines).
jira@brutus:~/infrastructure/jira/upgrading$ 

Dealing with patch failures

So let's take a look at that first failure:

Hunk #4 FAILED at 305.
1 out of 4 hunks FAILED -- saving rejects to file atlassian-jira/WEB-INF/classes/jira-application.properties.rej

Take a look at the .rej file to see what didn't cleanly apply:

jira@brutus:~/infrastructure/jira/upgrading$ cd /usr/local/tomcat/tomcat-jira-3.12.1-template
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-template$ cat atlassian-jira/WEB-INF/classes/jira-application.properties.rej
***************
*** 305,315 ****
  #
  # NOTE: this SHOULD BE EQUALS OR GREATER THAN than jira.search.views.default.max above, otherwise all issue navigator links will fail with a 403
  #
- #jira.search.views.max.limit =
  
  ##
  # Regardless of the above, users in this group will be able to request search requests that are unlimited.
--- 305,315 ----
  #
  # NOTE: this SHOULD BE EQUALS OR GREATER THAN than jira.search.views.default.max above, otherwise all issue navigator links will fail with a 403
  #
+ jira.search.views.max.limit = 10000
  
  ##
  # Regardless of the above, users in this group will be able to request search requests that are unlimited.
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-template$ 

In this example, for some reason patch was unable to replace the jira.search.views.max.limit line. Whatever the reason for the patch failure, the process for fixing it is the same: manually make the change to the file, regenerate the patch and rerun jiradeploy to try it.

So make the change by hand:

jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-template$ vim atlassian-jira/WEB-INF/classes/jira-application.properties

and now generate a new patch, replacing the broken one:

jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-template$ diff -u /home/jira/upgrade_3.12.1/atlassian-jira-enterprise-3.12.1-standalone/atlassian-jira/WEB-INF/classes/jira-application.properties atlassian-jira/WEB-INF/classes/jira-application.properties > /home/jira/infrastructure/jira/upgrading/jiraapplication.patch
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-template$ 

Now retry the deployment. You will notice that this time the script notices the half-patched files in {{/usr/local/tomcat/tomcat-jira-$version-template}, and offers to delete them.

jira@brutus:~$ jiradeploy 3.12.1
Deploy directory /usr/local/tomcat/tomcat-jira-3.12.1-template already exists; do you want to delete it? (delete/leave)
delete
Downloading JIRA 3.12.1 ..
Clean copy of JIRA 3.12.1 unpacked to /home/jira/upgrade_3.12.1
Applying patches to JIRA ..
In /usr/local/tomcat/tomcat-jira-3.12.1-template
+ cat /home/jira/infrastructure/jira/upgrading/closedissues_editable.patch /home/jira/infrastructure/jira/upgrading/entityengine.patch /home/jira/infrastructure/jira/upgrading/jiraapplication.patch /home/jira/infrastructure/jira/upgrading/log4j.patch /home/jira/infrastructure/jira/upgrading/webxml.patch
+ patch -p0
patching file atlassian-jira/WEB-INF/classes/jira-workflow.xml
patching file atlassian-jira/WEB-INF/classes/entityengine.xml
patching file atlassian-jira/WEB-INF/classes/jira-application.properties
patching file atlassian-jira//WEB-INF/classes/log4j.properties
Hunk #1 FAILED at 85.
Hunk #2 succeeded at 126 with fuzz 2 (offset 7 lines).
1 out of 2 hunks FAILED -- saving rejects to file atlassian-jira//WEB-INF/classes/log4j.properties.rej
patching file atlassian-jira/WEB-INF/web.xml
Hunk #1 succeeded at 778 (offset 120 lines).
jira@brutus:~$ 

So now jira-application.properties applies cleanly, and we move on to the next failure. Again, the fix process:

  1. examine the reject
  2. manually apply the change
  3. generate a new patch
  4. try again
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-template$ vim atlassian-jira//WEB-INF/classes/log4j.properties.rej
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-template$ vim atlassian-jira//WEB-INF/classes/log4j.properties +85
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-template$ diff -u /home/jira/upgrade_3.12.1/atlassian-jira-enterprise-3.12.1-standalone/atlassian-jira/WEB-INF/classes/log4j.properties atlassian-jira/WEB-INF/classes/log4j.properties > /home/jira/infrastructure/jira/upgrading/log4j.patch
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-template$ cd
jira@brutus:~$ jiradeploy 3.12.1
Deploy directory /usr/local/tomcat/tomcat-jira-3.12.1-template already exists; do you want to delete it? (delete/leave)
delete
Downloading JIRA 3.12.1 
.......

Plugin compilation failures

Once all patches apply, the script moves on to compiling each plugin against the new JIRA version.

jira@brutus:~$ jiradeploy 3.12.1
Deploy directory /usr/local/tomcat/tomcat-jira-3.12.1-template already exists; do you want to delete it? (delete/leave)
delete
Downloading JIRA 3.12.1 ..
Clean copy of JIRA 3.12.1 unpacked to /home/jira/upgrade_3.12.1
Applying patches to JIRA ..
In /usr/local/tomcat/tomcat-jira-3.12.1-template
+ cat /home/jira/infrastructure/jira/upgrading/closedissues_editable.patch /home/jira/infrastructure/jira/upgrading/entityengine.patch /home/jira/infrastructure/jira/upgrading/jiraapplication.patch /home/jira/infrastructure/jira/upgrading/log4j.patch /home/jira/infrastructure/jira/upgrading/webxml.patch
+ patch -p0
patching file atlassian-jira/WEB-INF/classes/jira-workflow.xml
patching file atlassian-jira/WEB-INF/classes/entityengine.xml
patching file atlassian-jira/WEB-INF/classes/jira-application.properties
patching file atlassian-jira/WEB-INF/classes/log4j.properties
patching file atlassian-jira/WEB-INF/web.xml
Hunk #1 succeeded at 778 (offset 120 lines).
+ set +vx
/usr/local/tomcat/tomcat-jira-3.12.1-template/external-source/src/java
patching file BugzillaImportBean.java
Hunk #1 succeeded at 1948 (offset 172 lines).
Buildfile: build.xml

prepare:
    [mkdir] Created dir: /usr/local/tomcat/tomcat-jira-3.12.1-template/external-source/etc
    [mkdir] Created dir: /usr/local/tomcat/tomcat-jira-3.12.1-template/external-source/lib

compile:
    [javac] Compiling 1 source file to /usr/local/tomcat/tomcat-jira-3.12.1-template/atlassian-jira/WEB-INF/classes
    [javac] Note: /usr/local/tomcat/tomcat-jira-3.12.1-template/external-source/src/java/BugzillaImportBean.java uses or overrides a deprecated API.
    [javac] Note: Recompile with -Xlint:deprecation for details.
    [javac] Note: /usr/local/tomcat/tomcat-jira-3.12.1-template/external-source/src/java/BugzillaImportBean.java uses unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.

BUILD SUCCESSFUL
Total time: 3 seconds
Installing jira-asf-plugin Plugin..
A    jira-asf-plugin/LICENSE.txt
A    jira-asf-plugin/project.properties
A    jira-asf-plugin/maven.xml
A    jira-asf-plugin/project.xml
A    jira-asf-plugin/src
A    jira-asf-plugin/src/java
A    jira-asf-plugin/src/java/com
A    jira-asf-plugin/src/java/com/atlassian
A    jira-asf-plugin/src/java/com/atlassian/jira
A    jira-asf-plugin/src/java/com/atlassian/jira/web
A    jira-asf-plugin/src/java/com/atlassian/jira/web/action
A    jira-asf-plugin/src/java/com/atlassian/jira/web/action/issue
A    jira-asf-plugin/src/java/com/atlassian/jira/web/action/issue/CopyrightAttachFile.java
A    jira-asf-plugin/src/java/com/atlassian/jira/web/action/ASFAdministrators.java
A    jira-asf-plugin/src/patches
A    jira-asf-plugin/src/patches/copyright-attachment.jsp.diff
A    jira-asf-plugin/src/patches/copyright-attachfile.jsp.diff
A    jira-asf-plugin/src/patches/copyright-manageattachments.jsp.diff
A    jira-asf-plugin/src/patches/webapp
A    jira-asf-plugin/src/patches/webapp/images
A    jira-asf-plugin/src/patches/webapp/images/icons
A    jira-asf-plugin/src/patches/webapp/images/icons/apachefeather.png
A    jira-asf-plugin/src/etc
A    jira-asf-plugin/src/etc/atlassian-plugin.xml
A    jira-asf-plugin/src/etc/com
A    jira-asf-plugin/src/etc/com/atlassian
A    jira-asf-plugin/src/etc/com/atlassian/jira
A    jira-asf-plugin/src/etc/com/atlassian/jira/web
A    jira-asf-plugin/src/etc/com/atlassian/jira/web/action
A    jira-asf-plugin/src/etc/com/atlassian/jira/web/action/ASFAdministrators.properties
A    jira-asf-plugin/src/etc/com/atlassian/jira/web/action/issue
A    jira-asf-plugin/src/etc/com/atlassian/jira/web/action/issue/CopyrightAttachFile.properties
A    jira-asf-plugin/src/etc/templates
A    jira-asf-plugin/src/etc/templates/asf_administrators.vm
A    jira-asf-plugin/atlassian-jira-3.10.1.pom
A    jira-asf-plugin/README.txt
Checked out revision 607809.
 __  __
|  \/  |__ _Apache__ ___
| |\/| / _` \ V / -_) ' \  ~ intelligent projects ~
|_|  |_\__,_|\_/\___|_||_|  v. 1.0.2

Attempting to download atlassian-jira-3.12.1.jar.
5243K downloaded
Attempting to download atlassian-configurableobjects-0.7.jar.
20K downloaded
Attempting to download atlassian-mail-1.5.jar.
47K downloaded
Attempting to download atlassian-seraph-0.30.jar.
92K downloaded
Attempting to download bcprov-jdk14-138.jar.
1515K downloaded
Attempting to download atlassian-extras-1.12.jar.
60K downloaded
Attempting to download atlassian-renderer-3.14.jar.
200K downloaded
Attempting to download atlassian-bonnie-2.3.jar.
115K downloaded
Attempting to download atlassian-gzipfilter-1.2.jar.
26K downloaded
Attempting to download oscore-2.2.6.jar.
87K downloaded
Attempting to download lucene-core-2.2.0.jar.
525K downloaded
Attempting to download lucene-analyzers-2.2.0.jar.
70K downloaded
Attempting to download easymock-1.2_Java1.3.jar.
35K downloaded
Attempting to download easymockclassextension-1.2.1.jar.
38K downloaded
Attempting to download commons-jelly-tags-regexp-1.0.jar.
8K downloaded
Attempting to download urlrewrite-2.5.2.jar.
130K downloaded
build:start:

java:prepare-filesystem:
    [mkdir] Created dir: /home/jira/upgrade_3.12.1/jira-asf-plugin/target/classes

java:compile:
    [echo] Compiling to /home/jira/upgrade_3.12.1/jira-asf-plugin/target/classes
    [echo] 
==========================================================

  NOTE: Targetting JVM 1.5, classes
  will not run on earlier JVMs

==========================================================
          
    [javac] Compiling 2 source files to /home/jira/upgrade_3.12.1/jira-asf-plugin/target/classes
Note: /home/jira/upgrade_3.12.1/jira-asf-plugin/src/java/com/atlassian/jira/web/action/issue/CopyrightAttachFile.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

java:jar-resources:
Copying 4 files to /home/jira/upgrade_3.12.1/jira-asf-plugin/target/classes

test:prepare-filesystem:
    [mkdir] Created dir: /home/jira/upgrade_3.12.1/jira-asf-plugin/target/test-classes
    [mkdir] Created dir: /home/jira/upgrade_3.12.1/jira-asf-plugin/target/test-reports

test:test-resources:

test:compile:
    [echo] No test source files to compile.

test:test:
    [echo] No tests to run.

jar:jar:
    [jar] Building jar: /home/jira/upgrade_3.12.1/jira-asf-plugin/target/jira-asf-plugin-3.12.1.jar
BUILD SUCCESSFUL
Total time: 28 seconds
Finished at: Mon Dec 31 22:40:15 PST 2007

D         atlassian-jira-3.10.1.pom
A         atlassian-jira-3.12.1.pom
Applying patches: src/patches/copyright-manageattachments.jsp.diff src/patches/copyright-attachfile.jsp.diff src/patches/copyright-attachment.jsp.diff
patching file secure/views/issue/manageattachments.jsp
In /home/jira/upgrade_3.12.1/jira-asf-plugin
patching file secure/views/issue/attachfile.jsp
Hunk #1 FAILED at 58.
1 out of 1 hunk FAILED -- saving rejects to file secure/views/issue/attachfile.jsp.rej
patching file includes/icons/attachment.jsp
jira@brutus:~$ 

Some plugins need associated modifications to be made to JIRA's JSPs. These modifications are stored as patch files. In this case, the plugin is compiling, but a patch file is not applying cleanly (probably the JIRA JSP changed).

To fix, examine the part that's failing, manually patch the file, and update the diff. You can generate a diff by comparing the unmodified copy of JIRA Standalone in /upgrade_3.12.1/atlassian-jira-enterprise-3.12.1-standalone with the modified one in /usr/local/tomcat/tomcat-jira-3.12.1-template/atlassian-jira, and updating the relevant patch in /upgrade_3.12.1/jira-asf-plugin/src/patches.

Once jiradeploy works

Assuming that 'jiradeploy' all works, check that:

– You see the JIRA setup wizard at https://issues.apache.org/jira_testing/
– There are no errors in logs/catalina.out, whose contents should look like:

java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode)

Jan 1, 2008 1:16:03 AM org.apache.coyote.http11.Http11BaseProtocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Jan 1, 2008 1:16:03 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1416 ms
Jan 1, 2008 1:16:03 AM org.apache.catalina.realm.JAASRealm setContainer
INFO: Set JAAS app name Catalina
Jan 1, 2008 1:16:03 AM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Jan 1, 2008 1:16:03 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/5.5.20
Jan 1, 2008 1:16:03 AM org.apache.catalina.core.StandardHost start
INFO: XML validation disabled
2008-01-01 01:16:06,915 main [core.entity.jdbc.DatabaseUtil] Entity "Action" has no table in the database
2008-01-01 01:16:07,298 main [core.entity.jdbc.DatabaseUtil] Entity "ChangeGroup" has no table in the database
2008-01-01 01:16:07,436 main [core.entity.jdbc.DatabaseUtil] Entity "ChangeItem" has no table in the database
2008-01-01 01:16:07,584 main [core.entity.jdbc.DatabaseUtil] Entity "ColumnLayout" has no table in the database
.....
008-01-01 01:16:16,081 main [core.entity.jdbc.DatabaseUtil] Entity "WorkflowScheme" has no table in the database
2008-01-01 01:16:16,171 main [core.entity.jdbc.DatabaseUtil] Entity "WorkflowSchemeEntity" has no table in the database
2008-01-01 01:16:16,224 main [core.entity.jdbc.DatabaseUtil] Entity "Worklog" has no table in the database
2008-01-01 01:16:24,045 main INFO [plugin.ext.subversion.MultipleSubversionRepositoryManagerImpl] Could not find any subversion repositories configured, trying to load from System Properties.
2008-01-01 01:16:24,051 main INFO [plugin.ext.subversion.SvnPropertiesLoader] No svn.root.1 specified in subversion-jira-plugin.properties
2008-01-01 01:16:24,786 main DEBUG [ext.subversion.revisions.RevisionIndexer] Repository list size = 1
2008-01-01 01:16:24,786 main DEBUG [ext.subversion.revisions.RevisionIndexer] RevisionIndexer.createIndexIfNeeded()
2008-01-01 01:16:24,790 main WARN [ext.subversion.revisions.RevisionIndexer] At the moment the root index path of jira is not set, so we can not form an index path for the subversion plugin.
2008-01-01 01:16:24,790 main WARN [ext.subversion.revisions.RevisionIndexer] At the moment the root index path of jira is not set, so we can not form an index path for the subversion plugin.
2008-01-01 01:16:26,088 main ERROR [jira.ext.fisheye.FishEyeConfigImpl] Invalid FishEye configuration: FishEye Url must be specified.
2008-01-01 01:16:26,119 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl] Starting JIRA Enterprise Edition, Version: 3.12.1-#299
2008-01-01 01:16:26,119 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl] Configured to use database: postgres72
2008-01-01 01:16:26,125 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl] Could not find Issue Cache Listener, adding.
2008-01-01 01:16:26,942 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl] Could not find Mail Listener, adding.
2008-01-01 01:16:26,977 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl] Could not find Mail Queue Service, adding.
2008-01-01 01:16:26,991 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl] Input Language has not been set.  Setting to 'English'
2008-01-01 01:16:27,164 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl]

******************************************************************************************************
JIRA 3.12.1 build: 299 (Enterprise Edition) started. You can now access JIRA through your web browser.
******************************************************************************************************

[Filter: profiling] Using parameter [jira_profile]
[Filter: profiling] defaulting to off [autostart=false]
[Filter: profiling] Turning filter off [jira_profile=off]
2008-01-01 01:16:27,875 main INFO [jira.web.filters.AccessLogFilter] AccessLogFilter initialized. Format is: <user> <url> <starting memory free (kb)> +- <difference in free mem (kb)> <query time (ms)>
2008-01-01 01:16:28,030 main [webwork.dispatcher.ServletDispatcher] Unable to find 'webwork.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir
Jan 1, 2008 1:16:28 AM org.apache.coyote.http11.Http11BaseProtocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Jan 1, 2008 1:16:28 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /127.0.0.1:20009
Jan 1, 2008 1:16:28 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/54  config=null
Jan 1, 2008 1:16:28 AM org.apache.catalina.storeconfig.StoreLoader load
INFO: Find registry server-registry.xml at classpath resource
Jan 1, 2008 1:16:28 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 25193 ms

Check for new plugins

Sometimes people install new plugins into the running JIRA, and don't integrate these into the upgrade script. Now that you've got all the existing plugins compiling and integrated, it's a good time to check if any more need to be added to jiradeploy.

You can check which jars were added by diffing the current (old) JIRA's WEB-INF/lib against a clean JIRA Standalone.

In this example, 3.10.1 is the current/old JIRA:

jira@brutus:/usr/local/tomcat/tomcat-jira/atlassian-jira/WEB-INF/lib$ diff /home/jira/upgrade_3.10.1/atlassian-jira-enterprise-3.10.1-standalone/atlassian-jira/WEB-INF/lib/ .
Only in .: atlassian-bulkmoverestorefields-plugin-1.0.jar
Only in /home/jira/upgrade_3.10.1/atlassian-jira-enterprise-3.10.1-standalone/atlassian-jira/WEB-INF/lib/: atlassian-jira-rpc-plugin-3.10.1-1.jar
Only in .: atlassian-jira-rpc-plugin-3.11-1-BAYARD.jar
Only in .: atlassian-jira-subversion-plugin-0.9.10.jar
Only in .: ganymed.jar
Only in .: javasvn-1.0.5.jar
Only in .: jira-asf-plugin-3.10.1.jar
Only in .: jira-charting-plugin-1.3.9.jar
Only in .: sourcelabs-jira-plugin-portlet-currentuser-1.0.3-SNAPSHOT.jar
Only in .: sourcelabs-jira-plugin-portlet-filterlist-1.0.3-SNAPSHOT.jar
Only in .: sourcelabs-jira-plugin-portlet-html-1.0.1-SNAPSHOT.jar
Only in .: sourcelabs-jira-plugin-portlet-projectlist-1.0.3-SNAPSHOT.jar
Only in .: sourcelabs-jira-plugin-portlet-releases-2.5-SNAPSHOT.jar
Only in .: sourcelabs-jira-plugin-portlet-search-1.0.2-SNAPSHOT.jar
Only in .: sourcelabs-jira-report-contribution-1.1-SNAPSHOT.jar
jira@brutus:/usr/local/tomcat/tomcat-jira/atlassian-jira/WEB-INF/lib$ 

Now check that each of these jars (or perhaps a later version) is present in the new JIRA. If not, you'll need to fix the jiradeploy script to include it.

Testing the plugins

We now have JIRA running with all our plugins. But do the plugins actually work? The patches applied, but do they make sense? We test these things in this section.

Now go to https://issues.apache.org/jira_testing and ensure you see the JIRA Setup wizard. You may have to reload repeatedly or just wait a while for Apache to notice Tomcat is running.

We now have a modified JIRA Standalone running, and want to test it with some real JIRA data to ensure the upgrade process goes smoothly. For test data, I use Cayenne data, which has a test user and project already set up.

Importing test data

  1. Go to https://issues.apache.org/cayenne
  2. Log in as an admin
  3. Create a plain XML backup at /home/jira/upgrade_3.12.1/testdata.xml
  4. Go to https://issues.apache.org/jira_testing, click "import your existing data" and import this testdata.xml, using index path:
    /usr/local/tomcat/jira-indexes/jira_testing

  5. Now log in as jira_testuser (pw: !jira_testuser!), and create a test issue in the TST project.

If everything has been done properly, JIRA should not be sending email notifications of any changes you make to the /jira_testing/ JIRA instance. If you run ps axw | grep jira.*template, you'll see the properties -Datlassian.mail.senddisabled=true -Datlassian.mail.popdisabled=true preventing JIRA from sending or processing email.

Test the Copyright Attachments patch

  1. Click "Attach file" and ensure that you see the "Attachment License" section at the bottom.
  2. Try to attach a file without selecting a license. Ensure that you get an error message:
  3. Attach the file, picking "Grant license for ASF inclusion". Ensure that on the subsequent page listing attachment, your attachment has an Apache feather icon, and has "ASF Granted License".
    Unable to render embedded object: File (attachfile_licensed.png) not found.

Test the Bulk Move patch

Check whether http://jira.atlassian.com/browse/JRA-8248 has been fixed yet. If not, we'll need to test if the "bulk move restore fields" plugin works. Check the plugin's home page to see if compatibility with the JIRA version you're upgrading to has been established. If not, we'll have to do it ourselves. To do this:

  • create a test issue in the CAY project, with a few components and versions selected:
  • Now search for the issue's summary, and on the search page click Bulk Change: current page.
  • Select just your test issue, and click through the screens to move it to the TST project. After the move, view the project, which (if the bug still exists) will have lost its components and versions:
  • Now log in as an administrator, go to Administration -> Bulk Move Restore Fields. Set "Original Project" to "CAY" and "Current project" to "TST":
  • After clicking "Restore lost fields", you should see a page saying that your issue has had its fields restored:
  • Now logging in as the test user again, verify that the issue has had its fields restored:
    Unable to render embedded object: File (testissue_afterrestore.png) not found.
  • Check the JIRA logs (/usr/local/tomcat/tomcat-jira-$version-template/logs/catalina.out) for errors to ensure nothing silently broke during this process.

Testing done!

You have now verified that the new JIRA plus all its plugins and patches works with live data. Now shut down the test JIRA:

jira@brutus:/usr/local/tomcat/tomcat-jira-3.7.2-template/bin$ ./shutdown.sh 

Commit modified plugins

Once we are satisfied that everything works, we need to commit all the modifications made above to
patches and plugins back to Subversion. All modified files can be found in ~/upgrade_3.12.1:

jira@brutus:~/upgrade_3.12.1$ ls -1
atlassian-jira-enterprise-3.12.1-standalone
atlassian-jira-enterprise-3.12.1-standalone.tar.gz
BugzillaImportBean.java
jira-asf-plugin
jira-bulkmoverestorefields-plugin
jira-charting-plugin-1.3.11.jar
jira-contribution-report
jira-currentuser-portlet
jira-filterlist-portlet
jira-html-portlet
jira-projectlist-portlet
jira-releases-portlet
jira-search
postgresql-8.0-318.jdbc3.jar
testdata.xml
jira@brutus:~/upgrade_3.12.1$ 
jira@brutus:~/upgrade_3.12.1$ svn stat jira-*/
?      jira-asf-plugin/target
M      src/patches/copyright-attachfile.jsp.diff
D      jira-asf-plugin/atlassian-jira-3.10.1.pom
A      jira-asf-plugin/atlassian-jira-3.12.1.pom
?      jira-bulkmoverestorefields-plugin/target
D      jira-bulkmoverestorefields-plugin/atlassian-jira-3.10.1.pom
A      jira-bulkmoverestorefields-plugin/atlassian-jira-3.12.1.pom
?      jira-contribution-report/target
D      jira-contribution-report/atlassian-jira-3.11.pom
A      jira-contribution-report/atlassian-jira-3.12.1.pom
?      jira-currentuser-portlet/target
D      jira-currentuser-portlet/atlassian-jira-3.11.pom
A      jira-currentuser-portlet/atlassian-jira-3.12.1.pom
?      jira-filterlist-portlet/target
D      jira-filterlist-portlet/atlassian-jira-3.11.pom
A      jira-filterlist-portlet/atlassian-jira-3.12.1.pom
?      jira-html-portlet/target
D      jira-html-portlet/atlassian-jira-3.11.pom
A      jira-html-portlet/atlassian-jira-3.12.1.pom
?      jira-projectlist-portlet/target
D      jira-projectlist-portlet/atlassian-jira-3.11.pom
A      jira-projectlist-portlet/atlassian-jira-3.12.1.pom
?      jira-releases-portlet/target
D      jira-releases-portlet/atlassian-jira-3.11.pom
A      jira-releases-portlet/atlassian-jira-3.12.1.pom
?      jira-search/target
D      jira-search/atlassian-jira-3.11.pom
A      jira-search/atlassian-jira-3.12.1.pom
jira@brutus:~/upgrade_3.12.1$ 

The only plugin we actively maintain is the jira-asf-plugin, which lives in the ASF Subversion tree. We should commit our changes as follows:

jira@brutus:~/upgrade_3.12.1/jira-asf-plugin$ svn stat
?      target
D      atlassian-jira-3.10.1.pom
M      project.xml
A      atlassian-jira-3.12.1.pom
M      src/patches/copyright-attachfile.jsp.diff

Besides the diff we updated, the jiradeploy script has update the Maven .pom to the new version. Commit all these changes:

jira@brutus:~/upgrade_3.12.1/jira-asf-plugin$ svn ci -m "Upgrade to JIRA 3.12.1"
Deleting       atlassian-jira-3.10.1.pom
Adding         atlassian-jira-3.12.1.pom
Sending        src/patches/copyright-attachfile.jsp.diff
Transmitting file data ..
Committed revision 607840.
jira@brutus:~/upgrade_3.12.1/jira-asf-plugin$ 

Also commit modified patches and upgrade scripts:

jira@brutus:~/infrastructure/jira/upgrading$ svn st
M      jiradeploy_plugin_from_svn
M      UPGRADING.txt
M      jiradeploy_chartingplugin
M      jiradeploy
M      jiraapplication.patch
M      jiradeploy_svnplugin
M      log4j.patch
jira@brutus:~/infrastructure/jira/upgrading$ 
jira@brutus:~/infrastructure/jira/upgrading$ svn ci -m "Changes for 3.12.1" log4j.patch
jiraapplication.patch 
Authentication realm: <https://svn.apache.org:443> ASF Committers
Password for 'jira': 
Authentication realm: <https://svn.apache.org:443> ASF Committers
Username: jefft
Password for 'jefft': 
Sending        jiraapplication.patch
Sending        log4j.patch
Transmitting file data ..
Committed revision 607844.
jira@brutus:~/infrastructure/jira/upgrading$ svn ci -m "Script now downloads JIRA too. Added bulkmoverestorefields plugin. Handle download failures gracefully. Minor cleanups" 
Sending        upgrading/jiradeploy
Sending        upgrading/jiradeploy_chartingplugin
Sending        upgrading/jiradeploy_plugin_from_svn
Sending        upgrading/jiradeploy_svnplugin
Transmitting file data ....
Committed revision 607845.
jira@brutus:~/infrastructure/jira/upgrading$ 

§2) Making system-specific copies

Jump to summary

We now have a modified JIRA Standalone on /jira_testing, running against a test database, that we know works. We now want to create copies of this with JIRA-instance-specific settings (for /cayenne,
/activemq, /struts and /jira).

Text in this section is intended to be cut & pasted into the terminal. Make sure you set NEWVER before you begin.

Create Tomcat for new JIRA installation

cd /usr/local/tomcat
NEWVER=3.12.1
cp -r tomcat-jira-$NEWVER-template/ tomcat-jira-$NEWVER-cayenne
cp -r tomcat-jira-$NEWVER-template/ tomcat-jira-$NEWVER-struts 
cp -r tomcat-jira-$NEWVER-template/ tomcat-jira-$NEWVER-activemq
cp -r tomcat-jira-$NEWVER-template/ tomcat-jira-$NEWVER

Change the database

cd /usr/local/tomcat
perl -i -pe "s:localhost/jira_testing:localhost/jira_cayenne_${NEWVER//./}:" tomcat-jira-$NEWVER-cayenne/conf/server.xml
perl -i -pe "s:localhost/jira_testing:localhost/jira_struts_${NEWVER//./}:" tomcat-jira-$NEWVER-struts/conf/server.xml
perl -i -pe "s:localhost/jira_testing:localhost/jira_activemq_${NEWVER//./}:" tomcat-jira-$NEWVER-activemq/conf/server.xml
perl -i -pe "s:localhost/jira_testing:localhost/jira_${NEWVER//./}:" tomcat-jira-$NEWVER/conf/server.xml

Then check that the change took effect:

jira@brutus:/usr/local/tomcat$ diff tomcat-jira-$NEWVER-template/conf/server.xml tomcat-jira-$NEWVER/conf/server.xml
17c17
<             url="jdbc:postgresql://localhost/jira_testing"
---
>             url="jdbc:postgresql://localhost/jira_3121"
jira@brutus:/usr/local/tomcat$ 

Create the databases

createdb jira_cayenne_${NEWVER//./}
createdb jira_struts_${NEWVER//./}
createdb jira_activemq_${NEWVER//./}
createdb jira_${NEWVER//./}

§3 Switching live JIRAs

This is the traumatic potentially catastrophic part Make sure you're clear on all these steps before you begin.

FOREACH LIVE JIRA

Do the following, starting with the smallest JIRA (cayenne).

Main JIRA only

For the main JIRA, the Subversion indexing makes things tricky. We don't want JIRA to re-index the whole of Subversion (in fact it would fail as the ASF SVN doesn't allow 'svn log' operations at the root). If we just import the main JIRA XML, right after importing the SVN service will kick, see no indexes, and start fetching it all. So for the main JIRA:

  1. Remove the SVN plugin jar
    jira@brutus:/usr/local/tomcat/tomcat-jira-3.10.1/bin$ mv ../atlassian-jira/WEB-INF/lib/atlassian-jira-subversion-plugin-0.9.10.jar /tmp
    
  2. Later after the data is imported, copy the Subversion indexes across:
    jira@brutus:/var/local/jira/indexes/mainjira/3.10.1$ cp -rp /usr/local/tomcat/jira-indexes/jira/plugins/ .
    

    and restore the plugin jar:

    jira@brutus:/usr/local/tomcat/tomcat-jira-3.10.1$ cp /tmp/atlassian-jira-subversion-plugin-0.9.10.jar atlassian-jira/WEB-INF/lib/
    

If all goes well you should see something like:

2007-08-05 08:22:17,244 JiraQuartzScheduler_Worker-3 DEBUG [ext.subversion.revisions.RevisionIndexer] Retrieving revisions to index (between 562877 and 562887) for repository=13f79535-47bb-0310-9956-ffa450edef68http://svn.apache.org/repos/asf

Start the new JIRA Tomcat at /jira_testing.

At this stage we have 4 copies of JIRA Standalone, each configured to mount at /jira_testing, each pointing to a separate empty database. For instance, /usr/local/tomcat/tomcat-jira-3.12.1-cayenne/conf/server.xml contains:

        <Context path="/jira_testing" docBase="${catalina.home}/atlassian-jira" reloadable="false">
          <Resource name="jdbc/JiraDS" auth="Container" type="javax.sql.DataSource"
            username="jira"
            password="....."
            driverClassName="org.postgresql.Driver"
            url="jdbc:postgresql://localhost/jira_cayenne_3121"
            maxActive="20" />

Now pick one of these copies of JIRA and start it. Here we've picked Cayenne (being the smallest it's a good first choice). You should see "XXX has no table in the database" messages in the logs as it starts, and finds an empty database:

jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ tail -f logs/catalina.out &
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ ./bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat/tomcat-jira-3.12.1-cayenne
Using CATALINA_HOME:   /usr/local/tomcat/tomcat-jira-3.12.1-cayenne
Using CATALINA_TMPDIR: /usr/local/tomcat/tomcat-jira-3.12.1-cayenne/temp
Using JRE_HOME:       /usr/local/jdk1.6.0
...
Jan 1, 2008 6:09:21 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/5.5.20
Jan 1, 2008 6:09:21 AM org.apache.catalina.core.StandardHost start
INFO: XML validation disabled
2008-01-01 06:09:25,332 main [core.entity.jdbc.DatabaseUtil] Entity "Action" has no table in the database
2008-01-01 06:09:25,563 main [core.entity.jdbc.DatabaseUtil] Entity "ChangeGroup" has no table in the database
2008-01-01 06:09:25,634 main [core.entity.jdbc.DatabaseUtil] Entity "ChangeItem" has no table in the database
2008-01-01 06:09:25,730 main [core.entity.jdbc.DatabaseUtil] Entity "ColumnLayout" has no table in the database
...
Jan 1, 2008 6:09:53 AM org.apache.catalina.storeconfig.StoreLoader load
INFO: Find registry server-registry.xml at classpath resource
Jan 1, 2008 6:09:53 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 32316 ms

Check that you see the JIRA setup wizard at https://issues.apache.org/jira_testing, where this new Cayenne JIRA has been temporarily mounted to avoid clashing with the live JIRA.

Set announcement banner

Set an Announcement Banner in the live JIRA (eg. https://issues.apache.org/cayenne), saying that JIRA is being upgraded, and updates are disabled. The banner text I use is:

JIRA is currently being upgraded, and will be read-only until the upgrade is complete and this message disappears. If you have any questions, please see me on irc.freenode.net #asfinfra - <a href="mailto:jefft@apache.org">Jeff</a>

Disable database updates

Disable updates in the live JIRA's database. First look at what databases are present:

jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ psql -l | grep jira_cayenne
 jira_cayenne_3101  | jira     | UNICODE
 jira_cayenne_3121  | jira     | UNICODE
 jira_cayenne_391   | jira     | UNICODE
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ 

In this example, jira_cayenne_3101 is the live JIRA 3.10.1 database, and jira_cayenne_3121 is the newly created (empty) database. So we disable the live 3.10.1 database:

jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ psql jira_cayenne_3101 -t -c "REVOKE INSERT, DELETE, UPDATE on project,jiraaction,jiraissue from jira"
REVOKE
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ 

At this point, any JIRA operation that modifies the database (eg. adding issues or comments) will fail with a stacktrace:

By this stage you're pretty much committed, but in an emergency you can re-enable database writes with GRANT INSERT, DELETE, UPDATE on project,jiraaction,jiraissue to jira.

Restore live data into new JIRA

  • In the live (currently read-only) JIRA at https://issues.apache.org/cayenne, create a backup to /home/jira/upgrade_3.12.1/cayenne.xml
  • In https://issues.apache.org/jira_testing, click "import your existing data"
    Import backup into new JIRA,
    Index path: /var/local/jira/indexes/cayenne/3.12.1 (the version here is the NEW version)
  • After the import completes, remove banner.
  • Do a final check that everything is okay
  • Shut down testing JIRA:
    jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ ./bin/shutdown.sh 
    
  • Change ports and context path:
NEWVER=3.12.1
PROJ=cayenne
cd /usr/local/tomcat/tomcat-jira-$NEWVER-$PROJ
patch -p0 < /home/jira/infrastructure/jira/upgrading/conf/disable8080.patch 
patch -p0 < /home/jira/infrastructure/jira/upgrading/$PROJ/changeports.patch 
For the main JIRA the patches are in /home/jira/infrastructure/jira/upgrading/mainjira/

Enable email

jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ vim bin/setenv.sh  # Change stuff, as shown below
jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ diff ../tomcat-jira-3.12.1-template/bin/setenv.sh bin/setenv.sh
7c7
< JAVA_OPTS="$JAVA_OPTS -Datlassian.mail.senddisabled=true -Datlassian.mail.popdisabled=true"
---
> #JAVA_OPTS="$JAVA_OPTS -Datlassian.mail.senddisabled=true -Datlassian.mail.popdisabled=true"
For the main JIRA, also increase -Xmx from 256m to 800m.

Shutdown live JIRA

jira@brutus:/usr/local/tomcat/tomcat-jira-3.12.1-cayenne$ cd ../tomcat-jira-cayenne
jira@brutus:/usr/local/tomcat/tomcat-jira-cayenne$ ./bin/shutdown.sh 

Move the symlink:

jira@brutus:/usr/local/tomcat/tomcat-jira-cayenne$ cd ..
jira@brutus:/usr/local/tomcat$ rm tomcat-jira-cayenne
jira@brutus:/usr/local/tomcat$ ln -s tomcat-jira-3.12.1-cayenne/ tomcat-jira-cayenne

Start new JIRA

jira@brutus:/usr/local/tomcat/tomcat-jira-cayenne$ ./bin/startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat/tomcat-jira-cayenne
Using CATALINA_HOME:   /usr/local/tomcat/tomcat-jira-cayenne
Using CATALINA_TMPDIR: /usr/local/tomcat/tomcat-jira-cayenne/temp
Using JRE_HOME:       /usr/local/jdk1.6.0

Jan 1, 2008 6:28:22 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/5.5.20
Jan 1, 2008 6:28:22 AM org.apache.catalina.core.StandardHost start
INFO: XML validation disabled
2008-01-01 06:29:47,453 main INFO [plugin.ext.subversion.MultipleSubversionRepositoryManagerImpl] Could not find any subversion repositories configured, trying to load from System Properties.
2008-01-01 06:29:47,549 main INFO [plugin.ext.subversion.SvnPropertiesLoader] No svn.root.1 specified in subversion-jira-plugin.properties
2008-01-01 06:29:56,574 main DEBUG [ext.subversion.revisions.RevisionIndexer] Repository list size = 1
2008-01-01 06:29:56,575 main DEBUG [ext.subversion.revisions.RevisionIndexer] RevisionIndexer.createIndexIfNeeded()
2008-01-01 06:30:08,732 main ERROR [jira.ext.fisheye.FishEyeConfigImpl] Invalid FishEye configuration: FishEye Url must be specified.
2008-01-01 06:30:08,809 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl] Starting JIRA Enterprise Edition, Version: 3.12.1-#299
2008-01-01 06:30:08,809 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl] Configured to use database: postgres72
2008-01-01 06:30:09,051 main INFO [atlassian.jira.upgrade.ConsistencyCheckImpl] 

******************************************************************************************************
JIRA 3.12.1 build: 299 (Enterprise Edition) started. You can now access JIRA through your web browser.
******************************************************************************************************

2008-01-01 06:30:09,322 JiraQuartzScheduler_Worker-3 DEBUG [ext.subversion.revisions.RevisionIndexer] RevisionIndexer.createIndexIfNeeded()
2008-01-01 06:30:09,327 JiraQuartzScheduler_Worker-3 DEBUG [ext.subversion.revisions.RevisionIndexer] repos size = 1
2008-01-01 06:30:09,327 JiraQuartzScheduler_Worker-3 DEBUG [ext.subversion.revisions.RevisionIndexer] Updating revision index for repository=2
2008-01-01 06:30:09,327 JiraQuartzScheduler_Worker-3 DEBUG [ext.subversion.revisions.RevisionIndexer] Updating last revision indexed.
.....
Jan 1, 2008 6:51:28 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /127.0.0.1:19009
Jan 1, 2008 6:51:28 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/130  config=null
Jan 1, 2008 6:51:28 AM org.apache.catalina.storeconfig.StoreLoader load
INFO: Find registry server-registry.xml at classpath resource
Jan 1, 2008 6:51:28 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 14365 ms

If you get this error:

Jan 1, 2008 6:50:09 AM org.apache.catalina.core.StandardServer await
SEVERE: StandardServer.await: create[19005]: 
java.net.BindException: Address already in use
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359)
        at java.net.ServerSocket.bind(ServerSocket.java:319)
        at java.net.ServerSocket.<init>(ServerSocket.java:185)
        at org.apache.catalina.core.StandardServer.await(StandardServer.java:372)
        at org.apache.catalina.startup.Catalina.await(Catalina.java:615)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:575)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:294)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:432)

Then you were too fast with the restart. You will need to wait for the port (19005) to get out of TIME_WAIT status:

jira@brutus:/usr/local/tomcat/tomcat-jira-activemq$ netstat -nap | grep 19005
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp6       0      0 ::ffff:127.0.0.1:54009  ::ffff:127.0.0.1:19005  TIME_WAIT  -

View live JIRA

Check the live JIRA - eg. https://issues.apache.org/cayenne/. Note that it is NORMAL for it to return "503 Service Temporarily Unavailable" a couple of times until Apache realises that the connection is live.

Create a test issue and attachment

Repeat above steps in 2) for each JIRA.

**Note: for the main JIRA, also change the -Xmx to 750Mb in bin/setenv.sh and read the warning about Subversion.

Alternative live upgrade procedure

The above process of doing an XML data export from the old system and import into the new system is the safest method, and the one recommended by the JIRA documentation. However as the upgrade page also notes, it is possible to just point the new JIRA at the old database, and JIRA will automatically modify any tables it needs. This is not always possible - be certain you read the upgrade guides for all releases between what you have and what you want to upgrade to.

If you know what you're doing, are certain the upgrade is possible this way (eg. going from 3.12 to 3.12.1) and want to save everyone some downtime, you can proceed with an in-place upgrade.

This section of the documentation is still being worked on

FOREACH PROJ in (cayenne activemq struts) do:

set -eu                  # Exit if any of these variables are used when unset
export OLDVER=3.12.1
export NEWVER=3.12.2 # Make very sure you update this!
export PROJ=cayenne
cd /usr/local/tomcat/tomcat-jira-${OLDVER}-${PROJ}
./bin/shutdown.sh
rsync -vvra /var/local/jira/indexes/$PROJ/$OLDVER/ /var/local/jira/indexes/$PROJ/$NEWVER
pg_dump jira_${PROJ}_${OLDVER//./} | psql jira_${PROJ}_${NEWVER//./}
psql jira_${PROJ}_${NEWVER//./} -c "update propertystring set propertyvalue=replace(propertyvalue, '${OLDVER}', '${NEWVER}') where propertyvalue like '/var/local/jira/indexes%' and id=(select id from propertyentry where entity_name='jira.properties' and property_key='jira.path.index');"
cd /usr/local/tomcat/tomcat-jira-${NEWVER}-${PROJ}
patch -p0 < /home/jira/infrastructure/jira/upgrading/conf/disable8080.patch
patch -p0 < /home/jira/infrastructure/jira/upgrading/$PROJ/changeports.patch
./bin/startup.sh