Display a custom response during downtime

From EPrints Documentation
Revision as of 15:51, 14 March 2016 by Libjlrs (talk | contribs) (Created page with "We were recently migrating our database from an old server to a new one - which required a dump + load of data (rather than a replication). This meant we had a period of 3 hou...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

We were recently migrating our database from an old server to a new one - which required a dump + load of data (rather than a replication). This meant we had a period of 3 hours where EPrints wouldn't be accessible.

During this downtime, I wanted to to display a useful message, with a '503 Service unavailable' HTTP response. This is how to achieve this using EPrints triggers:

  1. Create a file ~/archives/ARCHIVEID/cfg/cfg.d/a_MAINTENANCE.pl. The name of the file isn't important - but it should be alphabetically before any other config file that defined a URL_REWRITE trigger.
  2. Add the following to the file, altering the maintenance_ip, maintenance_retry_after and maintenance_page_html appropriately. I'd keep the html page quite simple, but with enough info to help a human. Remember to escape any single-quotes in the HTML block with a backslash e.g. BAD: we've; GOOD: we\'ve.:
# Set maintenance to 1 to respond with a 503 for requests, except those from the maintenance_ip.
$c->{maintenance} = 0;
$c->{maintenance_allowed_ip} = '127.0.0.1'; #set this to your IP address

# set to a date/time after your maintenance will have finished, 
# or a period (in seconds) that the maintenance will last for
$c->{maintenance_retry_after} = 'Mon, 14 Mar 2016 12:00:00 GMT'; #set to a date/time after your maintenance will have finished

use EPrints::Const;
$c->add_trigger( EP_TRIGGER_URL_REWRITE, sub {
        my( %args ) = @_;

        # args passed to EP_TRIGGER_URL_REWRITE are:
        #     request, lang, args, urlpath, cgipath, uri, secure, return_code
        my( $repository, $request, $return_code, $uri, $urlpath ) = @args{ qw( repository request return_code uri urlpath ) };

        #check we're in maintenance mode
        if( $repository->config( "maintenance" ) && $repository->config( "maintenance" ) == 1 ){
                # is there an IP we should allow through?
                # NB You might need to do other checks - e.g. X-Forwarded-For if you are behind a load-balancer
                # or for different versions of Apache (like here: https://github.com/eprints/eprints/issues/214)
                # if you're not sure, ask on the EPrints Tech list first!
                if( $repository->config( "maintenance_allowed_ip" ) && 
                    $request->connection->remote_ip eq $repository->config( "maintenance_allowed_ip" ) ){
                        return EP_TRIGGER_OK;
                }
                elsif( $uri !~ /^$urlpath\/(style|images)\// ) # allow image/stylesheet requests 
                                                               # through - so you can display a branded 503 page
                {
                        $request->custom_response( Apache2::Const::HTTP_SERVICE_UNAVAILABLE, $c->{maintenance_page_html} );
                        if( $repository->config( "maintenance_retry_after" ) ){
                            $request->err_headers_out->{'Retry-After'} = $repository->config( "maintenance_retry_after" );
                        }
                        # set the 503 response
                        ${$return_code} = EPrints::Const::HTTP_SERVICE_UNAVAILABLE;
                        # and don't process any more EP_TRIGGER_URL_REWRITE triggers.
                        return EP_TRIGGER_DONE;
                }
        }
} );

# A simple maintenance page - not using the template (which will probably link to various other pages that aren't
# accessible during the maintenance window
$c->{maintenance_page_html} = '<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
body {
    font-family: sans-serif;
    margin: 3em;
}
footer {
    font-size: 80%;
    margin-top:2em;
}
</style>
<title>###REPO NAME### - Maintenance</title>
</head>
<body>
<header>
<img src="/images/sitelogo.png" />
<h1>###REPO NAME### - Maintenance</h1>
</header>
<section>
<p><strong>Date/Time</strong> We\'re currently doing things to the system.<br />
We\'ll be back soon!</p>
<p>If you have any questions, please contact someone@somewhere.blah</p>
</section>
<footer>
<p>###REPO NAME###</p>
</footer>
</body>
</html>';
  1. Do a ~/bin/epadmin test ARCHIVEID to make sure you haven't done anything silly in the config file.
  2. Do a ~/bin/epafmin reload ARCHIVEID and check that nothing's changed
  3. When you want to turn the maintenance response on, change set: $c->{maintenance} = 1; and reload the archive.
  4. Check that you can get in from the IP specified, and that you get the 503 response from other IPs.
  5. Do a graceful restart of Apache - to stop the noisy 'repository had been reloaded' error messages.
  6. Do the maintenance, test.
  7. Change $c->{maintenance} = 0;, graceful restart Apache, test.
  8. Done!

If you want to include the default CSS files in the 503 page, include <link rel="stylesheet" type="text/css" href="/style/auto-3.3.14.css"> in the maintenance_html_page -> head section (update it for your version of EPrints!).