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
This commit is contained in:
parent
7708794221
commit
3fc724a675
@ -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-OS: trusty
|
||||||
node /^afsdb.*\.openstack\.org$/ {
|
node /^afsdb.*\.openstack\.org$/ {
|
||||||
$group = "afsdb"
|
$group = "afsdb"
|
||||||
|
78
modules/openstack_project/files/openafs/release-volumes.py
Normal file
78
modules/openstack_project/files/openafs/release-volumes.py
Normal file
@ -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()
|
44
modules/openstack_project/manifests/afsrelease.pp
Normal file
44
modules/openstack_project/manifests/afsrelease.pp
Normal file
@ -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'],
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user