bityard Blog

// Installing Anitya Upstream Release Monitoring on RHEL 7

Anitya is a release monitoring project developed and provided by the Fedora (Fedora) project. It is used to monitor upstream software projects for new releases in a automated fashion. It is thus similar to the uscan command from the Debian (Debian) devscripts package. Unlike the uscan command, Anitya is written in Python (Python) and comes with an integrated WebUI. Also unlike uscan, Anitya uses the FedMsg (Federated Message Bus) in order to publish messages indicating a detected upstream release event. These messages can in turn be consumed by other systems in order to trigger various actions upon a new upstream release. Anitya can be used “as a service” through https://release-monitoring.org/ or be installed as a dedicated instance. This article describes the necessary steps to set up an own, dedicated Anitya instance on a RHEL 7 system.


According to the official Anitya installation and configuration documentation there are only two steps – pip install anitya and editing /etc/anitya/anitya.toml – needed to set up Anitya. I have found this a bit too optimistic in case of a RHEL 7 system which was the installation target in my case. Here is a more detailed description of the necessary steps to get Anitya up and running on RHEL 7:

  1. Install some basic Anitya dependencies like Python, the Python installer, the Apache webserver, the Apache WSGI module and some development files:

    root@host:# yum install python httpd mod_wsgi python2-pip python-devel zeromq-devel
  2. Install Anitya and its dependencies:

    root@host:# pip2 install anitya

    Unfortunately, the Python 2 environment is necessary since the Apache WSGI module in RHEL 7 is compiled against Python 2.

  3. Adjust the import of the Anitya classes in the WGSI application. Open the file /usr/lib/python2.7/site-packages/anitya/wsgi.py in an editor of your choice:

    root@host:# vi /usr/lib/python2.7/site-packages/anitya/wsgi.py

    Alter its contents like shown in the following patch:

    wsgi.py
    --- /usr/lib/python2.7/site-packages/anitya/wsgi.py.orig        2018-12-05 16:59:26.000000000 +0100
    +++ /usr/lib/python2.7/site-packages/anitya/wsgi.py     2018-12-05 16:40:40.000000000 +0100
    @@ -14,7 +14,7 @@
     # You should have received a copy of the GNU General Public License
     # along with this program; if not, write to the Free Software
     # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
    -from .app import create
    +from anitya.app import create
     
     
     application = create()
  4. Create and adjust the basic Anitya configuration.

    Create the Anitya configuration directory:

    root@host:# mkdir /etc/anitya

    and download the sample configuration file from the Anitya GitHub repository:

    root@host:# wget -O /etc/anitya/anitya.toml https://raw.githubusercontent.com/release-monitoring/anitya/master/files/anitya.toml.sample

    Generate a secret key with e.g. the pwgen command:

    root@host:# pwgen -sncB 32 1

    Adjust the several settings in the Anitya configuration file. Open the file /etc/anitya/anitya.toml in an editor of your choice:

    root@host:# vi /etc/anitya/anitya.toml

    Alter the four configuration entries admin_email, secret_key, db_url and default_regex like shown in the following example:

    /etc/anitya/anitya.toml
    admin_email = "<YOUR-EMAIL-ADDRESS>"
    secret_key = "<SECRET-KEY>"
    db_url = "sqlite:////var/www/html/anitya.sqlite"
    default_regex = '''(?i)%(name)s(?:[-_]?(?:minsrc|src|source))?[-_]([^-/_\s]+?)(?:[-_]
                       (?:minsrc|src|source|asc|release))?\.(?:tar|t[bglx]z|tbz2|zip)'''

    Substitute the placeholder <YOUR-EMAIL-ADDRESS> with the email address at which you want to receive emails about errors of the Anitya application. This address will also be used as part of the request headers which identify the Anitya HTTP user agent. Substitute the placeholder <SECRET-KEY> with the secret key generated above.

    In case a SQLite database is used, make sure the value of the db_url entry points to a location within the filesystem that is reachable from the context of the webserver the Anitya application is running in. If e.g. the Apache webserver is used, the SQLite database should be located somewhere within the DocumentRoot of the Apache VirtualHost.

    Be careful with the syntax of the configuration file and the configuration entries in there. It seems that the configuration parsing part of Anitya is not very robust. A single invalid or syntactically incorrect entry will cause Anitya to skip all other entries as well and fall back to its default values. It took me a while to figure out that the Anitya database was generated and searched in the default location sqlite:////var/tmp/anitya-dev.sqlite no matter which value was given for the db_url configuration entry, just because another configuration entry – specifically the default_regex – had a syntactically incorrect value.

  5. Download the Anitya cron job from the Anitya GitHub repository:

    root@host:# cd /usr/lib/python2.7/site-packages/anitya
    root@host:# wget https://raw.githubusercontent.com/release-monitoring/anitya/<RELEASE>/files/anitya_cron.py

    The Anitya cron job should match the installed Anitya release. To ensure this, substitute the placeholder <RELEASE> in the above URL with the installed Anitya version. E.g. for the Anitya version 0.13.2:

    root@host:# wget https://raw.githubusercontent.com/release-monitoring/anitya/0.13.2/files/anitya_cron.py

    Make the Anitya cron job executeable:

    root@host:# chmod 755 /usr/lib/python2.7/site-packages/anitya/anitya_cron.py

    and adjust the Python interpreter to the RHEL 7 standard by opening the file /usr/lib/python2.7/site-packages/anitya/anitya_cron.py in an editor of your choice:

    root@host:# vi /usr/lib/python2.7/site-packages/anitya/anitya_cron.py

    Alter its contents like shown in the following patch:

    anitya_cron.py.patch
    # diff -uwi anitya_cron.py.orig anitya_cron.py
    --- anitya_cron.py.orig 2018-12-23 19:52:31.000000000 +0100
    +++ anitya_cron.py      2018-12-23 19:52:37.000000000 +0100
    @@ -1,4 +1,4 @@
    -#!/usr/bin/env python3
    +#!/usr/bin/env python2
     # -*- coding: utf-8 -*-
     
     import sys
  6. Download the Anitya database creation and initialization script from the Anitya GitHub repository:

    root@host:# cd /usr/lib/python2.7/site-packages/anitya
    root@host:# wget https://raw.githubusercontent.com/release-monitoring/anitya/master/createdb.py

    Run the downloaded script in order to create and initialize the Anitya database:

    root@host:# python createdb.py

    To grant access to the webserver the Anitya application is running in, adjust the ownership and the permissions of the Anitya database file:

    root@host:# chown apache:apache /var/www/html/anitya.sqlite
    root@host:# chmod 644 /var/www/html/anitya.sqlite
  7. Reapply changes to the database from a missing database version.

    Configure Alembic by opening the file /usr/lib/python2.7/site-packages/anitya/alembic.ini in an editor of your choice:

    root@host:# cd /usr/lib/python2.7/site-packages/anitya
    root@host:# vi alembic.ini

    Insert the contents like shown in the following configuration example:

    alembic.ini
    # A generic, single database configuration.
     
    [alembic]
    # path to migration scripts
    script_location = /usr/lib/python2.7/site-packages/anitya/db/migrations
     
    # template used to generate migration files
    # file_template = %%(rev)s_%%(slug)s
     
    # max length of characters to apply to the
    # "slug" field
    #truncate_slug_length = 40
     
    # set to 'true' to run the environment during
    # the 'revision' command, regardless of autogenerate
    # revision_environment = false
     
    # set to 'true' to allow .pyc and .pyo files without
    # a source .py file to be detected as revisions in the
    # versions/ directory
    # sourceless = false
    sqlalchemy.url = sqlite:////var/www/html/anitya.sqlite
     
    # Logging configuration
    [loggers]
    keys = root,sqlalchemy,alembic
     
    [handlers]
    keys = console
     
    [formatters]
    keys = generic
     
    [logger_root]
    level = WARN
    handlers = console
    qualname =
     
    [logger_sqlalchemy]
    level = WARN
    handlers =
    qualname = sqlalchemy.engine
    [logger_alembic]
    level = INFO
    handlers =
    qualname = alembic
     
    [handler_console]
    class = StreamHandler
    args = (sys.stderr,)
    level = NOTSET
    formatter = generic
     
    [formatter_generic]
    format = %(levelname)-5.5s [%(name)s] %(message)s
    datefmt = %H:%M:%S

    Initialize the Alembic table in the Anitya database and show the current database version:

    root@host:# alembic current
    7a8c4aa92678 (head)

    Manually change the database version known to Alembic in order to trick it into again applying the missing change to the database:

    root@host:# sqlite3 /var/www/html/anitya.sqlite
    
    sqlite> INSERT INTO alembic_version (version_num) VALUES ('a52d2fe99d4f');
    sqlite> .quit

    Reapply the change to the database from the missing database version feeaa70ead67:

    root@host:# alembic upgrade feeaa70ead67

    Determine the current “head” database version and manually change the database version known to Alembic:

    root@host:# alembic history
    540bdcf7edbc -> 7a8c4aa92678 (head), Add missing GitHub owner/project pairs
    27342bce1d0f -> 540bdcf7edbc, Convert GitHub URL to owner/project
    [...]
    
    root@host:# sqlite3 /var/www/html/anitya.sqlite
    
    sqlite> UPDATE alembic_version SET version_num = '7a8c4aa92678';
    sqlite> .quit
  8. Setup the Anitya cron job with the previously downloaded script by opening the file /etc/cron.d/anitya in an editor of your choice:

    root@host:# vi /etc/cron.d/anitya

    Insert the contents like shown in the following example:

    /etc/cron.d/anitya
    */5 * * * * root /usr/lib/python2.7/site-packages/anitya/anitya_cron.py 1>>/var/log/anitya.log 2>&1

    Adjust the execution interval according to your environment and needs.

  9. Create a VirtualHost configuration for e.g. the Apache webserver in whose context the Anitya application will be running in and start the Apache webserver.

    Create the VirtualHost configuration by opening the file /etc/httpd/conf.d/anitya.conf in an editor of your choice:

    root@host:# vi /etc/httpd/conf.d/anitya.conf

    Insert the contents like shown in the following configuration example:

    /etc/httpd/conf.d/anitya.conf
    <VirtualHost <IP>:<PORT>>
      DocumentRoot "/var/www/html/"
      ServerName <FQDN>
      <Directory />
        Options FollowSymLinks
        AllowOverride None
      </Directory>
     
      WSGIDaemonProcess anitya user=apache group=apache processes=2 threads=25 python-path=/usr/lib/python2.7/site-packages
      WSGIProcessGroup anitya
      WSGIScriptAlias /anitya /usr/lib/python2.7/site-packages/anitya/wsgi.py process-group=anitya
     
      <Directory "/usr/lib/python2.7/site-packages/anitya">
        <Files wsgi.py>
          Order deny,allow
          Allow from all
          Require all granted
        </Files>
     
        Order allow,deny
        Options Indexes FollowSymLinks
        Allow from all
      </Directory>
     
      Alias "/anitya/static" "/usr/lib/python2.7/site-packages/anitya/static"
      <Directory "/usr/lib/python2.7/site-packages/anitya/static">
        Order allow,deny
        Options Indexes FollowSymLinks
        Allow from all
        Require all granted
      </Directory>
    </VirtualHost>

    Substitute the placeholders <IP> and <PORT> with the IP address and TCP port on which the virtual host should be listening. Substitute the placeholder <FQDN> with the fully qualified domain name under which you want to reach the Anitya application with your browser.

    Enable and start the Apache webserver:

    root@host:# systemctl enable httpd
    root@host:# systemctl start httpd

After performing the steps outlined above, your own, dedicated Anitya instance on a RHEL 7 system should be ready. The WebUI of the Anitya instance will be reachable with a browser under the following URL http://<FQDN>/anitya, where the placeholder <FQDN> has to be substituted with the fully qualified domain name given in the above Apache VirtualHost configuration.

After logging into Anitya and adding an upstream software project, the next run of the Anitya cron job should discover the initial and current versions of the upstream software project. This should be visible in two places, firstly in the logfile of the Anitya cron job /var/log/anitya.log and secondly on the projects page of the Anitya WebUI. If this is not the case after the next execution interval of the Anitya cron job, review the logfile /var/log/anitya.log for possible errors.

I hope you find the provided Anitya installation and configuration guide for a RHEL 7 target system useful and enjoyed reading this blog post. Please don't hesitate to drop me a note if you have any suggestions or run into any issues with this guide. In future articles i will – hopefully soon – write about the neccessary steps to set up the FedMsg (Federated Message Bus) and connect Anitya to it, as well as an enhancement to Anitya itself.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website. More information about cookies