mirror of
https://github.com/ceph/ceph
synced 2025-01-30 23:13:44 +00:00
78166c01a4
... for locating downburst executable Signed-off-by: Zack Cerza <zack.cerza@inktank.com>
124 lines
4.2 KiB
Python
124 lines
4.2 KiB
Python
import logging
|
|
import os
|
|
import subprocess
|
|
import tempfile
|
|
import yaml
|
|
|
|
from .config import config
|
|
from .misc import decanonicalize_hostname
|
|
from .lockstatus import get_status
|
|
from .misc import get_distro
|
|
from .misc import get_distro_version
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
def _get_downburst_exec():
|
|
"""
|
|
First check for downburst in the user's path.
|
|
Then check in ~/src, ~ubuntu/src, and ~teuthology/src.
|
|
Return '' if no executable downburst is found.
|
|
"""
|
|
if config.downburst:
|
|
return config.downburst
|
|
path = os.environ.get('PATH', None)
|
|
if path:
|
|
for p in os.environ.get('PATH', '').split(os.pathsep):
|
|
pth = os.path.join(p, 'downburst')
|
|
if os.access(pth, os.X_OK):
|
|
return pth
|
|
import pwd
|
|
little_old_me = pwd.getpwuid(os.getuid()).pw_name
|
|
for user in [little_old_me, 'ubuntu', 'teuthology']:
|
|
pth = os.path.expanduser("~%s/src/downburst/virtualenv/bin/downburst"
|
|
% user)
|
|
if os.access(pth, os.X_OK):
|
|
return pth
|
|
return ''
|
|
|
|
|
|
def create_if_vm(ctx, machine_name):
|
|
"""
|
|
Use downburst to create a virtual machine
|
|
"""
|
|
status_info = get_status(machine_name)
|
|
if not status_info.get('is_vm', False):
|
|
return False
|
|
phys_host = decanonicalize_hostname(status_info['vm_host']['name'])
|
|
os_type = get_distro(ctx)
|
|
os_version = get_distro_version(ctx)
|
|
|
|
createMe = decanonicalize_hostname(machine_name)
|
|
with tempfile.NamedTemporaryFile() as tmp:
|
|
if hasattr(ctx, 'config') and ctx.config is not None:
|
|
lcnfg = ctx.config.get('downburst', dict())
|
|
else:
|
|
lcnfg = {}
|
|
distro = lcnfg.get('distro', os_type.lower())
|
|
distroversion = lcnfg.get('distroversion', os_version)
|
|
|
|
file_info = {}
|
|
file_info['disk-size'] = lcnfg.get('disk-size', '100G')
|
|
file_info['ram'] = lcnfg.get('ram', '1.9G')
|
|
file_info['cpus'] = lcnfg.get('cpus', 1)
|
|
file_info['networks'] = lcnfg.get(
|
|
'networks',
|
|
[{'source': 'front', 'mac': status_info['mac_address']}])
|
|
file_info['distro'] = distro
|
|
file_info['distroversion'] = distroversion
|
|
file_info['additional-disks'] = lcnfg.get(
|
|
'additional-disks', 3)
|
|
file_info['additional-disks-size'] = lcnfg.get(
|
|
'additional-disks-size', '200G')
|
|
file_info['arch'] = lcnfg.get('arch', 'x86_64')
|
|
file_out = {'downburst': file_info}
|
|
yaml.safe_dump(file_out, tmp)
|
|
metadata = "--meta-data=%s" % tmp.name
|
|
dbrst = _get_downburst_exec()
|
|
if not dbrst:
|
|
log.error("No downburst executable found.")
|
|
return False
|
|
p = subprocess.Popen([dbrst, '-c', phys_host,
|
|
'create', metadata, createMe],
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,)
|
|
owt, err = p.communicate()
|
|
if err:
|
|
log.info("Downburst completed on %s: %s" %
|
|
(machine_name, err))
|
|
else:
|
|
log.info("%s created: %s" % (machine_name, owt))
|
|
# If the guest already exists first destroy then re-create:
|
|
if 'exists' in err:
|
|
log.info("Guest files exist. Re-creating guest: %s" %
|
|
(machine_name))
|
|
destroy_if_vm(ctx, machine_name)
|
|
create_if_vm(ctx, machine_name)
|
|
return True
|
|
|
|
|
|
def destroy_if_vm(ctx, machine_name):
|
|
"""
|
|
Use downburst to destroy a virtual machine
|
|
|
|
Return False only on vm downburst failures.
|
|
"""
|
|
status_info = get_status(machine_name)
|
|
if not status_info or not status_info.get('is_vm', False):
|
|
return True
|
|
phys_host = decanonicalize_hostname(status_info['vm_host']['name'])
|
|
destroyMe = decanonicalize_hostname(machine_name)
|
|
dbrst = _get_downburst_exec()
|
|
if not dbrst:
|
|
log.error("No downburst executable found.")
|
|
return False
|
|
p = subprocess.Popen([dbrst, '-c', phys_host,
|
|
'destroy', destroyMe],
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,)
|
|
owt, err = p.communicate()
|
|
if err:
|
|
log.error(err)
|
|
return False
|
|
else:
|
|
log.info("%s destroyed: %s" % (machine_name, owt))
|
|
return True
|