anvil/devstack/components/swift.py

219 lines
8.8 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (C) 2012 Yahoo! Inc. All Rights Reserved.
#
# 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.
import re
from devstack import component as comp
from devstack import log as logging
from devstack import shell as sh
from devstack import utils
LOG = logging.getLogger("devstack.components.swift")
# Swift has alot of config files!
SWIFT_CONF = 'swift.conf'
PROXY_SERVER_CONF = 'proxy-server.conf'
ACCOUNT_SERVER_CONF = 'account-server.conf'
CONTAINER_SERVER_CONF = 'container-server.conf'
OBJECT_SERVER_CONF = 'object-server.conf'
RSYNC_CONF = 'rsyncd.conf'
SYSLOG_CONF = 'rsyslog.conf'
SWIFT_MAKERINGS = 'swift-remakerings'
SWIFT_STARTMAIN = 'swift-startmain'
SWIFT_INIT = 'swift-init'
SWIFT_IMG = 'drives/images/swift.img'
DEVICE_PATH = 'drives/sdb1'
CONFIGS = [SWIFT_CONF, PROXY_SERVER_CONF, ACCOUNT_SERVER_CONF,
CONTAINER_SERVER_CONF, OBJECT_SERVER_CONF, RSYNC_CONF,
SYSLOG_CONF, SWIFT_MAKERINGS, SWIFT_STARTMAIN]
SWIFT_RSYNC_LOC = '/etc/rsyslog.d/10-swift.conf'
DEF_LOOP_SIZE = 1000000
# Adjustments to rsync/rsyslog
RSYNC_CONF_LOC = '/etc/default/rsync'
RSYNCD_CONF_LOC = '/etc/rsyncd.conf'
RSYNC_SERVICE_RESTART = ['service', 'rsync', 'restart']
RSYSLOG_SERVICE_RESTART = ['service', 'rsyslog', 'restart']
RSYNC_ON_OFF_RE = re.compile(r'^\s*RSYNC_ENABLE\s*=\s*(.*)$', re.I)
# FIXME: This should come from the persona, if we really expect
# people to change it.
# Defines our auth service type
AUTH_SERVICE = 'keystone'
# Defines what type of loopback filesystem we will make
# xfs is preferred due to its extended attributes
FS_TYPE = "xfs"
# Subdirs of the git checkout
BIN_DIR = 'bin'
LOG_DIR = 'logs'
# Config keys we warm up so u won't be prompted later
WARMUP_PWS = [('service_token', 'the service admin token'),
('swift_hash', 'the random unique string for your swift cluster')]
class SwiftUninstaller(comp.PythonUninstallComponent):
def __init__(self, *args, **kargs):
comp.PythonUninstallComponent.__init__(self, *args, **kargs)
self.datadir = sh.joinpths(self.app_dir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.logdir = sh.joinpths(self.datadir, LOG_DIR)
def pre_uninstall(self):
sh.umount(sh.joinpths(self.datadir, DEVICE_PATH))
sh.replace_in(RSYNC_CONF_LOC, RSYNC_ON_OFF_RE, 'RSYNC_ENABLE=false', True)
def post_uninstall(self):
sh.execute(*RSYSLOG_SERVICE_RESTART, run_as_root=True)
sh.execute(*RSYNC_SERVICE_RESTART, run_as_root=True)
class SwiftInstaller(comp.PythonInstallComponent):
def __init__(self, *args, **kargs):
comp.PythonInstallComponent.__init__(self, *args, **kargs)
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.datadir = sh.joinpths(self.app_dir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
self.logdir = sh.joinpths(self.datadir, LOG_DIR)
self.startmain_file = sh.joinpths(self.bin_dir, SWIFT_STARTMAIN)
self.makerings_file = sh.joinpths(self.bin_dir, SWIFT_MAKERINGS)
self.fs_dev = sh.joinpths(self.datadir, DEVICE_PATH)
self.fs_image = sh.joinpths(self.datadir, SWIFT_IMG)
self.auth_server = AUTH_SERVICE
def _get_download_locations(self):
places = list()
places.append({
'uri': ('git', 'swift_repo'),
'branch': ('git', 'swift_branch')
})
return places
def _get_config_files(self):
return list(CONFIGS)
def warm_configs(self):
for (pw_key, prompt) in WARMUP_PWS:
self.pw_gen.get_password(pw_key, prompt)
def _get_param_map(self, config_fn):
return {
'USER': self.cfg.getdefaulted('swift', 'swift_user', sh.getuser()),
'GROUP': self.cfg.getdefaulted('swift', 'swift_group', sh.getgroupname()),
'SWIFT_DATA_LOCATION': self.datadir,
'SWIFT_CONFIG_LOCATION': self.cfg_dir,
'SERVICE_TOKEN': self.cfg.get('passwords', 'service_token'),
'AUTH_SERVER': self.auth_server,
'SWIFT_HASH': self.cfg.get('passwords', 'swift_hash'),
'SWIFT_LOGDIR': self.logdir,
'SWIFT_PARTITION_POWER_SIZE': self.cfg.getdefaulted('swift', 'partition_power_size', '9'),
# Note: leave these alone, will be adjusted later
'NODE_PATH': '%NODE_PATH%',
'BIND_PORT': '%BIND_PORT%',
'LOG_FACILITY': '%LOG_FACILITY%',
}
def _create_data_location(self):
loop_size = self.cfg.get('swift', 'loopback_disk_size')
if not loop_size:
loop_size = DEF_LOOP_SIZE
else:
loop_size = utils.to_bytes(loop_size)
sh.create_loopback_file(fname=self.fs_image,
size=loop_size,
fs_type=FS_TYPE)
self.tracewriter.file_touched(self.fs_image)
sh.mount_loopback_file(self.fs_image, self.fs_dev, FS_TYPE)
sh.chown_r(self.fs_dev, sh.geteuid(), sh.getegid())
def _create_node_config(self, node_number, port):
for t in ['object', 'container', 'account']:
src_fn = sh.joinpths(self.cfg_dir, '%s-server.conf' % t)
tgt_fn = sh.joinpths(self.cfg_dir, '%s-server/%d.conf' % (t, node_number))
adjustments = {
'%NODE_PATH%': sh.joinpths(self.datadir, str(node_number)),
'%BIND_PORT%': str(port),
'%LOG_FACILITY%': str(2 + node_number),
}
sh.copy_replace_file(src_fn, tgt_fn, adjustments)
port += 1
def _delete_templates(self):
for t in ['object', 'container', 'account']:
sh.unlink(sh.joinpths(self.cfg_dir, '%s-server.conf' % t))
def _create_nodes(self):
for i in range(1, 5):
self.tracewriter.dirs_made(sh.mkdirslist(sh.joinpths(self.fs_dev, '%d/node' % i)))
link_tgt = sh.joinpths(self.datadir, str(i))
sh.symlink(sh.joinpths(self.fs_dev, str(i)), link_tgt)
self.tracewriter.symlink_made(link_tgt)
start_port = (6010 + (i - 1) * 5)
self._create_node_config(i, start_port)
self._delete_templates()
def _turn_on_rsync(self):
sh.symlink(sh.joinpths(self.cfg_dir, RSYNC_CONF), RSYNCD_CONF_LOC)
self.tracewriter.symlink_made(RSYNCD_CONF_LOC)
sh.replace_in(RSYNC_CONF_LOC, RSYNC_ON_OFF_RE, 'RSYNC_ENABLE=true', True)
def _create_log_dirs(self):
self.tracewriter.dirs_made(*sh.mkdirslist(sh.joinpths(self.logdir, 'hourly')))
sh.symlink(sh.joinpths(self.cfg_dir, SYSLOG_CONF), SWIFT_RSYNC_LOC)
self.tracewriter.symlink_made(SWIFT_RSYNC_LOC)
def _setup_binaries(self):
sh.move(sh.joinpths(self.cfg_dir, SWIFT_MAKERINGS), self.makerings_file)
sh.chmod(self.makerings_file, 0777)
self.tracewriter.file_touched(self.makerings_file)
sh.move(sh.joinpths(self.cfg_dir, SWIFT_STARTMAIN), self.startmain_file)
sh.chmod(self.startmain_file, 0777)
self.tracewriter.file_touched(self.startmain_file)
def _make_rings(self):
sh.execute(self.makerings_file, run_as_root=True)
def post_install(self):
self._create_data_location()
self._create_nodes()
self._turn_on_rsync()
self._create_log_dirs()
self._setup_binaries()
self._make_rings()
class SwiftRuntime(comp.PythonRuntime):
def __init__(self, *args, **kargs):
comp.PythonRuntime.__init__(self, *args, **kargs)
self.datadir = sh.joinpths(self.app_dir, self.cfg.getdefaulted('swift', 'data_location', 'data'))
self.bin_dir = sh.joinpths(self.app_dir, BIN_DIR)
self.logdir = sh.joinpths(self.datadir, LOG_DIR)
def start(self):
sh.execute(*RSYSLOG_SERVICE_RESTART, run_as_root=True)
sh.execute(*RSYNC_SERVICE_RESTART, run_as_root=True)
swift_start_cmd = [sh.joinpths(self.bin_dir, SWIFT_INIT)] + ['all', 'start']
sh.execute(*swift_start_cmd, run_as_root=True)
def stop(self):
swift_stop_cmd = [sh.joinpths(self.bin_dir, SWIFT_INIT)] + ['all', 'stop']
sh.execute(*swift_stop_cmd, run_as_root=True)
def restart(self):
swift_restart_cmd = [sh.joinpths(self.bin_dir, SWIFT_INIT)] + ['all', 'restart']
sh.execute(*swift_restart_cmd, run_as_root=True)