From 3fc724a6754fddd8df29d2709a741103e38ee806 Mon Sep 17 00:00:00 2001 From: "James E. Blair" Date: Tue, 22 Nov 2016 09:31:05 -0800 Subject: [PATCH] Add a cron job to release AFS volumes Every 5 minutes, check to see if the docs volumes have been updated, and if so, release them. This means we can serve the docs volumes from replicated read-only volumes with only a 5 minute delay. Since this does not coordinate with the docs publishing jobs, we may end up releasing partial updates, however, those jobs, since they use rsync, should tolerate this. Change-Id: I082ae6f37af9a6e12ad62b0cc4cb45e631a0935b --- manifests/site.pp | 15 ++++ .../files/openafs/release-volumes.py | 78 +++++++++++++++++++ .../openstack_project/manifests/afsrelease.pp | 44 +++++++++++ 3 files changed, 137 insertions(+) create mode 100644 modules/openstack_project/files/openafs/release-volumes.py create mode 100644 modules/openstack_project/manifests/afsrelease.pp diff --git a/manifests/site.pp b/manifests/site.pp index 0ac2be9480..ceb7243d9e 100644 --- a/manifests/site.pp +++ b/manifests/site.pp @@ -1196,6 +1196,21 @@ node 'kdc02.openstack.org' { } } +# Node-OS: trusty +node afsdb01.openstack.org/ { + $group = "afsdb" + + class { 'openstack_project::server': + iptables_public_udp_ports => [7000,7002,7003,7004,7005,7006,7007], + sysadmins => hiera('sysadmins', []), + afs => true, + manage_exim => true, + } + + include openstack_project::afsdb + include openstack_project::afsrelease +} + # Node-OS: trusty node /^afsdb.*\.openstack\.org$/ { $group = "afsdb" diff --git a/modules/openstack_project/files/openafs/release-volumes.py b/modules/openstack_project/files/openafs/release-volumes.py new file mode 100644 index 0000000000..605b6202d5 --- /dev/null +++ b/modules/openstack_project/files/openafs/release-volumes.py @@ -0,0 +1,78 @@ +# Copyright 2016 Red Hat, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from datetime import datetime +import re +import subprocess +import logging + +VOLUMES = ['docs', + 'docs.dev', + ] + +log = logging.getLogger("release") + +UPDATE_RE = re.compile("^\s+Last Update (.*)$") + + +def get_last_update(volume): + ret = [] + out = subprocess.check_output(['vos', 'examine', volume, '-localauth']) + state = 0 + for line in out.split('\n'): + if state == 0 and line.startswith(volume): + state = 1 + site = None + elif state == 1: + site = line.strip() + state = 0 + m = UPDATE_RE.match(line) + if m: + ret.append(dict(site=site, + volume=volume, + updated=datetime.strptime(m.group(1), + '%a %b %d %H:%M:%S %Y'))) + + return ret + + +def release(volume): + log.info("Releasing %s" % volume) + subprocess.check_output(['vos', 'release', volume, '-localauth']) + + +def check_release(volume): + log.info("Checking %s" % volume) + rw = get_last_update(volume)[0] + log.debug(" %s %s %s" % (rw['site'], rw['updated'], rw['volume'])) + ros = get_last_update(volume + '.readonly') + update = False + for ro in ros: + log.debug(" %s %s %s" % (ro['site'], ro['updated'], ro['volume'])) + if ro['updated'] < rw['updated']: + update = True + if update: + release(volume) + + +def main(): + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)s ' + '%(levelname)-8s %(message)s') + for volume in VOLUMES: + check_release(volume) + + +if __name__ == '__main__': + main() diff --git a/modules/openstack_project/manifests/afsrelease.pp b/modules/openstack_project/manifests/afsrelease.pp new file mode 100644 index 0000000000..39a403c482 --- /dev/null +++ b/modules/openstack_project/manifests/afsrelease.pp @@ -0,0 +1,44 @@ +# Release afs volumes +class openstack_project::afsrelease ( +) { + include logrotate + + file { '/usr/local/bin/release-volumes': + ensure => present, + owner => 'root', + group => 'root', + mode => '0755', + source => 'puppet:///modules/openstack_project/openafs/release-volumes.py', + } + + file { '/var/log/release': + ensure => directory, + owner => 'root', + group => 'root', + mode => '0755', + } + + cron { 'release': + user => 'root', + minute => '*/5', + command => '/usr/local/bin/release-volumes >>/var/log/release/release.log 2>&1', + environment => 'PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin', + require => [ + File['/usr/local/bin/release-volumes'], + ] + } + + logrotate::file { 'release': + ensure => present, + log => '/var/log/release/release.log', + options => ['compress', + 'copytruncate', + 'delaycompress', + 'missingok', + 'rotate 7', + 'daily', + 'notifempty', + ], + require => Cron['release'], + } +}