Installation | Maintenance | Beyond Lino

Upgrading a production site

This document gives generic instructions for upgrading a production site to a new version. This procedure is suitable for smaller sites with one contact person. See Installing a preview site for are more sophisticated approach on sites with many users.

  • Use go to cd to the project directory of the Lino site:

    $ go myproject
    
  • Activate the python environment using a:

    $ a
    
  • Stop any services that might want to write to the database (web server, supervisor):

    $ sudo service apache stop  # if used
    $ sudo service supervisor stop
    $ sudo service cron stop  # avoid a make_snapshot.sh while we are migrating
    

    NB: there is no need to stop nginx at the beginning of the upgrade. But we will restart it later after collectstatic to make sure that static files get out of the cache).

  • Run make_snapshot.sh to make a snapshot of your database:

    $ ./make_snapshot.sh
    

    See Making a snapshot of a Lino database for details.

  • Make sure that the snapshot is correctly done by looking at the timestamp of the snapshot.zip file:

    $ ls -l snapshot.zip
    
  • Run pull.sh to update the Python environment:

    $ pull.sh
    
  • Restore the snapshot:

    $ pm run snapshot/restore.py
    

    The restore.py script may produce lots of messages like “Deferred Foo : {‘bar’: [‘Bar instance with id 3762 does not exist.’]}”. These messages are caused by database rows that cross-refer to each other. No problem as long as it continues “Trying to save X deferred objects”.

  • Make sure that the restore.py script ends with something like:

    Done manage.py run snapshot/restore.py (PID 20651)
    

    But when it ends with saying “Abandoned with X unsaved objects”, see Troubleshooting

  • Run the install command to install any new Python dependencies if needed:

    $ python manage.py install
    

    You can skip this step when you know that there are no new Python dependencies.

  • If the site uses lino.modlib.elastic, run the buildindexes command:

    $ pm buildindexes
    

    This step can be skipped if there were no changes in the database schema.

  • Run the collectstatic command:

    $ pm collectstatic
    

    This step can be skipped if there were no changes in the static files.

  • Run the buildcache command:

    $ pm buildcache
    
  • Run the checkdata command with --fix and --prune options:

    $ pm checkdata -fp
    
  • Start the web server and supervisor:

    $ sudo service apache2 start  # apache
    $ sudo service nginx restart # nginx
    $ sudo service supervisor start
    $ sudo service cron start
    
  • Run the makehelp command:

    $ pm makehelp
    
  • Sign in to the site and look whether everything seems okay.

When to skip restore.py

You may skip the restore.py if you are sure that there is no change in the database structure. You can run restore.py also “just in case”, it doesn’t do any harm when there were no changes in the database structure.

Running restore.py just in case does no harm, but it can take much time for a bigger database. After all it drops all database tables, re-creates them, and then fills every single data row into it. So before running restore.py, you might prefer to check whether you actually need to run it:

$ pm dump2py -os t
$ diff snapshot/restore.py t/restore.py

That is, you call pm dump2py to make a temporary simulated snapshot with the new version (which takes much less time than restoring it) and then compare their restore.py files. If nothing has changed (i.e. diff gives no output), then you don’t need to run the restore.py.

Troubleshooting

When the restore.py ends with Abandoned with X unsaved objects, you should ask the application developer what to do. It’s their job to specify what happens during data migration by providing migrators. Of course you may also dive yourself into the code and the changelog.

The pull.sh updates only the Python packages maintained by the Lino team. In certain circumstances you might want to also update all other Python packages. You may do this manually or use a tool like pip-review.