Merge branch 'master' of github.com:yahoo/Openstack-DevstackPy

This commit is contained in:
Joshua Harlow 2012-03-12 12:58:30 -07:00
commit 136b7b269d
10 changed files with 112 additions and 45 deletions

View File

@ -14,8 +14,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import time
from devstack import component as comp
from devstack import exceptions as excp
from devstack import log as logging
@ -248,7 +246,7 @@ class DBRuntime(comp.EmptyRuntime):
run_as_root=True,
check_exit_code=True)
LOG.info("Please wait %s seconds while it starts up." % START_WAIT_TIME)
time.sleep(START_WAIT_TIME)
sh.sleep(START_WAIT_TIME)
return 1
else:
return 0
@ -270,7 +268,7 @@ class DBRuntime(comp.EmptyRuntime):
run_as_root=True,
check_exit_code=True)
LOG.info("Please wait %s seconds while it restarts." % START_WAIT_TIME)
time.sleep(START_WAIT_TIME)
sh.sleep(START_WAIT_TIME)
return 1
def status(self):

View File

@ -15,7 +15,6 @@
# under the License.
import io
import time
from devstack import cfg
from devstack import component as comp
@ -224,5 +223,5 @@ class GlanceRuntime(comp.PythonRuntime):
#install any images that need activating...
# TODO: make this less cheesy - need to wait till glance goes online
LOG.info("Waiting %s seconds so that glance can start up before image install." % (WAIT_ONLINE_TO))
time.sleep(WAIT_ONLINE_TO)
sh.sleep(WAIT_ONLINE_TO)
creator.ImageCreationService(self.cfg).install()

View File

@ -15,7 +15,6 @@
# under the License.
import io
import time
from urlparse import urlunparse
@ -224,7 +223,7 @@ class KeystoneRuntime(comp.PythonRuntime):
#these environment additions are important
#in that they eventually affect how this script runs
LOG.info("Waiting %s seconds so that keystone can start up before running first time init." % (WAIT_ONLINE_TO))
time.sleep(WAIT_ONLINE_TO)
sh.sleep(WAIT_ONLINE_TO)
env = dict()
env['ENABLED_SERVICES'] = ",".join(self.instances.keys())
env['BIN_DIR'] = self.bindir

View File

@ -15,7 +15,6 @@
# under the License.
import io
import time
from devstack import cfg
from devstack import component as comp
@ -169,7 +168,7 @@ class MelangeRuntime(comp.PythonRuntime):
comp.PythonRuntime.post_start(self)
if CREATE_CIDR in self.component_opts or not self.component_opts:
LOG.info("Waiting %s seconds so that the melange server can start up before cidr range creation." % (WAIT_ONLINE_TO))
time.sleep(WAIT_ONLINE_TO)
sh.sleep(WAIT_ONLINE_TO)
mp = dict()
mp['CIDR_RANGE'] = self.cfg.getdefaulted('melange', 'm_mac_range', DEF_CIDR_RANGE)
utils.execute_template(*CIDR_CREATE_CMD, params=mp)

View File

@ -17,7 +17,6 @@
from urlparse import urlunparse
import os
import time
from devstack import component as comp
from devstack import date
@ -444,7 +443,7 @@ class NovaRuntime(comp.PythonRuntime):
#in that they eventually affect how this script runs
if utils.service_enabled(settings.QUANTUM, self.instances, False):
LOG.info("Waiting %s seconds so that quantum can start up before running first time init." % (WAIT_ONLINE_TO))
time.sleep(WAIT_ONLINE_TO)
sh.sleep(WAIT_ONLINE_TO)
env = dict()
env['ENABLED_SERVICES'] = ",".join(self.instances.keys())
setup_cmd = NET_INIT_CMD_ROOT + [tgt_fn]
@ -834,7 +833,7 @@ class NovaConfConfigurator(object):
LOG.debug("Attempting to create instance directory: %s" % (instances_path))
self.tracewriter.dirs_made(*sh.mkdirslist(instances_path))
LOG.debug("Adjusting permissions of instance directory: %s" % (instances_path))
os.chmod(instances_path, 0777)
sh.chmod(instances_path, 0777)
def _configure_libvirt(self, virt_type, nova_conf):
if virt_type == 'lxc':

View File

@ -15,7 +15,6 @@
# under the License.
from tempfile import TemporaryFile
import time
from devstack import component as comp
from devstack import log as logging
@ -133,7 +132,7 @@ class RabbitRuntime(comp.EmptyRuntime):
LOG.info("Restarting rabbit-mq.")
self._run_cmd(RESTART_CMD)
LOG.info("Please wait %s seconds while it starts up." % (WAIT_ON_TIME))
time.sleep(WAIT_ON_TIME)
sh.sleep(WAIT_ON_TIME)
return 1
def stop(self):

View File

@ -14,8 +14,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import time
from devstack import exceptions as excp
from devstack import log as logging
from devstack import settings
@ -109,7 +107,7 @@ def restart(distro):
mp['SERVICE'] = SV_NAME_MAP[distro]
utils.execute_template(*cmds, params=mp)
LOG.info("Restarting the libvirt service, please wait %s seconds until its started." % (WAIT_ALIVE_TIME))
time.sleep(WAIT_ALIVE_TIME)
sh.sleep(WAIT_ALIVE_TIME)
def virt_ok(virt_type, distro):

View File

@ -49,6 +49,12 @@ def parse():
dest="verbosity",
default=[1],
help="increase the verbose level")
parser.add_option("", "--dryrun",
action="store_const",
const=1,
dest="dryrun",
default=0,
help="log actions without actually doing any of them")
base_group = OptionGroup(parser, "Install & uninstall & start & stop specific options")
base_group.add_option("-a", "--action",
@ -104,6 +110,7 @@ def parse():
output = dict()
output['components'] = options.component or list()
output['dir'] = options.dir or ""
output['dryrun'] = options.dryrun or False
output['ref_components'] = options.ref_components or list()
output['action'] = options.action or ""
output['force'] = not options.force

View File

@ -24,6 +24,7 @@ import subprocess
import sys
import random
import re
import time
from devstack import env
from devstack import exceptions as excp
@ -44,6 +45,13 @@ SHELL_QUOTE_REPLACERS = {
SHELL_WRAPPER = "\"%s\""
ROOT_PATH = os.sep
RANDOMIZER = random.SystemRandom()
DRYRUN = None
def set_dryrun(val):
global DRYRUN
LOG.info("Setting dryrun to:%s" % (val))
DRYRUN = val
#root context guard
@ -65,7 +73,6 @@ class Rooted(object):
def execute(*cmd, **kwargs):
process_input = kwargs.pop('process_input', None)
check_exit_code = kwargs.pop('check_exit_code', [0])
cwd = kwargs.pop('cwd', None)
@ -129,27 +136,32 @@ def execute(*cmd, **kwargs):
rc = None
result = None
with Rooted(run_as_root):
try:
obj = subprocess.Popen(execute_cmd,
stdin=stdin_fh,
stdout=stdout_fh,
stderr=stderr_fh,
close_fds=close_file_descriptors,
cwd=cwd,
shell=shell,
env=process_env)
if process_input is not None:
result = obj.communicate(str(process_input))
else:
result = obj.communicate()
except OSError as e:
error_description = "%s: [%s, %s]" % (e.message, e.errno, e.strerror)
raise excp.ProcessExecutionError(description=error_description, cmd=str_cmd)
if (stdin_fh != subprocess.PIPE
and obj.stdin and close_stdin):
obj.stdin.close()
rc = obj.returncode
LOG.debug('Cmd result had exit code: %s' % rc)
if DRYRUN:
LOG.info("DRYRUN:%s" % (execute_cmd))
# Pretend it worked
rc = 0
else:
try:
obj = subprocess.Popen(execute_cmd,
stdin=stdin_fh,
stdout=stdout_fh,
stderr=stderr_fh,
close_fds=close_file_descriptors,
cwd=cwd,
shell=shell,
env=process_env)
if process_input is not None:
result = obj.communicate(str(process_input))
else:
result = obj.communicate()
except OSError as e:
error_description = "%s: [%s, %s]" % (e.message, e.errno, e.strerror)
raise excp.ProcessExecutionError(description=error_description, cmd=str_cmd)
if (stdin_fh != subprocess.PIPE
and obj.stdin and close_stdin):
obj.stdin.close()
rc = obj.returncode
LOG.debug('Cmd result had exit code: %s' % rc)
if not result:
result = ("", "")
@ -343,6 +355,10 @@ def mkdirslist(path):
def append_file(fn, text, flush=True, quiet=False):
if DRYRUN:
LOG.info("DRYRUN append_file:%s" % (fn))
LOG.info("%s" % (text))
return fn
if not quiet:
LOG.debug("Appending to file %s (%d bytes)", fn, len(text))
with open(fn, "a") as f:
@ -353,6 +369,10 @@ def append_file(fn, text, flush=True, quiet=False):
def write_file(fn, text, flush=True, quiet=False):
if DRYRUN:
LOG.info("DRYRUN write_file:%s" % (fn))
LOG.info("%s" % (text))
return fn
if not quiet:
LOG.debug("Writing to file %s (%d bytes)", fn, len(text))
with open(fn, "w") as f:
@ -363,6 +383,9 @@ def write_file(fn, text, flush=True, quiet=False):
def touch_file(fn, die_if_there=True, quiet=False, file_size=0):
if DRYRUN:
LOG.info("DRYRUN touch_file:%s" % (fn))
return fn
if not isfile(fn):
if not quiet:
LOG.debug("Touching and truncating file %s (%s)", fn, file_size)
@ -376,16 +399,30 @@ def touch_file(fn, die_if_there=True, quiet=False, file_size=0):
def load_file(fn, quiet=False):
LOG.info("load_file:%s" % (fn))
if not quiet:
LOG.debug("Loading data from file %s", fn)
with open(fn, "r") as f:
data = f.read()
try:
with open(fn, "r") as f:
data = f.read()
except IOError as e:
# If there was an error, then check if we're doing a dryrun. If
# yes, then return no data, otherwise the the error bubble on up
if DRYRUN:
LOG.info("DRYRUN: return no data for load_file:%s" % (fn))
data = ""
else:
raise e
if not quiet:
LOG.debug("Loaded (%d) bytes from file %s", len(data), fn)
return data
def mkdir(path, recurse=True):
if DRYRUN:
LOG.info("DRYRUN mkdir:%s" % (path))
return
if not isdir(path):
if recurse:
LOG.debug("Recursively creating directory \"%s\"" % (path))
@ -396,6 +433,9 @@ def mkdir(path, recurse=True):
def deldir(path, run_as_root=False):
if DRYRUN:
LOG.info("DRYRUN deldir:%s" % (path))
return
with Rooted(run_as_root):
if isdir(path):
LOG.debug("Recursively deleting directory tree starting at \"%s\"" % (path))
@ -403,6 +443,9 @@ def deldir(path, run_as_root=False):
def rmdir(path, quiet=True, run_as_root=False):
if DRYRUN:
LOG.info("DRYRUN rmdir:%s" % (path))
return
if not isdir(path):
return
try:
@ -422,9 +465,12 @@ def symlink(source, link, force=True, run_as_root=True):
LOG.debug("Creating symlink from %s => %s" % (link, source))
path = dirname(link)
needed_pths = mkdirslist(path)
if force and (exists(link) or islink(link)):
unlink(link, True)
os.symlink(source, link)
if DRYRUN:
LOG.info("DRYRUN symlink from %s => %s" % (source, link))
else:
if force and (exists(link) or islink(link)):
unlink(link, True)
os.symlink(source, link)
return needed_pths
@ -534,6 +580,9 @@ def umount(dev_name, ignore_errors=True):
def unlink(path, ignore_errors=True, run_as_root=False):
if DRYRUN:
LOG.info("DRYRUN unlink:%s" % (path))
return
try:
LOG.debug("Unlinking (removing) %s" % (path))
with Rooted(run_as_root):
@ -546,10 +595,16 @@ def unlink(path, ignore_errors=True, run_as_root=False):
def move(src, dst):
if DRYRUN:
LOG.info("DRYRUN move:%s" % (src, dst))
return
shutil.move(src, dst)
def chmod(fname, mode):
if DRYRUN:
LOG.info("DRYRUN chmod:%s to %s" % (fname, mode))
return
os.chmod(fname, mode)
@ -567,6 +622,9 @@ def replace_in(fn, search, replace, run_as_root=False):
def copy_replace_file(fsrc, fdst, linemap):
files = mkdirslist(dirname(fdst))
if DRYRUN:
LOG.info("DRYRUN copy_replace:%s" % (fsrc, fdst))
return
with open(fdst, 'w') as fh:
for line in fileinput.input(fsrc):
for (k, v) in linemap.items():
@ -626,3 +684,10 @@ def geteuid():
def getegid():
return os.getegid()
def sleep(winks):
if DRYRUN:
LOG.info("DRYRUN, sleep for:%s" % (winks))
else:
time.sleep(winks)

4
stack
View File

@ -93,6 +93,10 @@ def run(args):
#here on out we should be using the logger (and not print)
start_time = time.time()
config = common.get_config()
# Stash the dryrun value (if any) into the global configuration
dryrun = args.get('dryrun')
if dryrun:
sh.set_dryrun(dryrun)
pkg_manager = common.get_packager(distro, args.get('keep_old'))
components = utils.parse_components(args.pop("components"))
runner = actions.ActionRunner(distro, action, rootdir, config, pkg_manager, components=components, **args)