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

View File

@ -15,7 +15,6 @@
# under the License. # under the License.
import io import io
import time
from devstack import cfg from devstack import cfg
from devstack import component as comp from devstack import component as comp
@ -224,5 +223,5 @@ class GlanceRuntime(comp.PythonRuntime):
#install any images that need activating... #install any images that need activating...
# TODO: make this less cheesy - need to wait till glance goes online # 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)) 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() creator.ImageCreationService(self.cfg).install()

View File

@ -15,7 +15,6 @@
# under the License. # under the License.
import io import io
import time
from urlparse import urlunparse from urlparse import urlunparse
@ -224,7 +223,7 @@ class KeystoneRuntime(comp.PythonRuntime):
#these environment additions are important #these environment additions are important
#in that they eventually affect how this script runs #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)) 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 = dict()
env['ENABLED_SERVICES'] = ",".join(self.instances.keys()) env['ENABLED_SERVICES'] = ",".join(self.instances.keys())
env['BIN_DIR'] = self.bindir env['BIN_DIR'] = self.bindir

View File

@ -15,7 +15,6 @@
# under the License. # under the License.
import io import io
import time
from devstack import cfg from devstack import cfg
from devstack import component as comp from devstack import component as comp
@ -169,7 +168,7 @@ class MelangeRuntime(comp.PythonRuntime):
comp.PythonRuntime.post_start(self) comp.PythonRuntime.post_start(self)
if CREATE_CIDR in self.component_opts or not self.component_opts: 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)) 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 = dict()
mp['CIDR_RANGE'] = self.cfg.getdefaulted('melange', 'm_mac_range', DEF_CIDR_RANGE) mp['CIDR_RANGE'] = self.cfg.getdefaulted('melange', 'm_mac_range', DEF_CIDR_RANGE)
utils.execute_template(*CIDR_CREATE_CMD, params=mp) utils.execute_template(*CIDR_CREATE_CMD, params=mp)

View File

@ -17,7 +17,6 @@
from urlparse import urlunparse from urlparse import urlunparse
import os import os
import time
from devstack import component as comp from devstack import component as comp
from devstack import date from devstack import date
@ -444,7 +443,7 @@ class NovaRuntime(comp.PythonRuntime):
#in that they eventually affect how this script runs #in that they eventually affect how this script runs
if utils.service_enabled(settings.QUANTUM, self.instances, False): 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)) 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 = dict()
env['ENABLED_SERVICES'] = ",".join(self.instances.keys()) env['ENABLED_SERVICES'] = ",".join(self.instances.keys())
setup_cmd = NET_INIT_CMD_ROOT + [tgt_fn] 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)) LOG.debug("Attempting to create instance directory: %s" % (instances_path))
self.tracewriter.dirs_made(*sh.mkdirslist(instances_path)) self.tracewriter.dirs_made(*sh.mkdirslist(instances_path))
LOG.debug("Adjusting permissions of instance directory: %s" % (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): def _configure_libvirt(self, virt_type, nova_conf):
if virt_type == 'lxc': if virt_type == 'lxc':

View File

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

View File

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

View File

@ -49,6 +49,12 @@ def parse():
dest="verbosity", dest="verbosity",
default=[1], default=[1],
help="increase the verbose level") 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 = OptionGroup(parser, "Install & uninstall & start & stop specific options")
base_group.add_option("-a", "--action", base_group.add_option("-a", "--action",
@ -104,6 +110,7 @@ def parse():
output = dict() output = dict()
output['components'] = options.component or list() output['components'] = options.component or list()
output['dir'] = options.dir or "" output['dir'] = options.dir or ""
output['dryrun'] = options.dryrun or False
output['ref_components'] = options.ref_components or list() output['ref_components'] = options.ref_components or list()
output['action'] = options.action or "" output['action'] = options.action or ""
output['force'] = not options.force output['force'] = not options.force

View File

@ -24,6 +24,7 @@ import subprocess
import sys import sys
import random import random
import re import re
import time
from devstack import env from devstack import env
from devstack import exceptions as excp from devstack import exceptions as excp
@ -44,6 +45,13 @@ SHELL_QUOTE_REPLACERS = {
SHELL_WRAPPER = "\"%s\"" SHELL_WRAPPER = "\"%s\""
ROOT_PATH = os.sep ROOT_PATH = os.sep
RANDOMIZER = random.SystemRandom() RANDOMIZER = random.SystemRandom()
DRYRUN = None
def set_dryrun(val):
global DRYRUN
LOG.info("Setting dryrun to:%s" % (val))
DRYRUN = val
#root context guard #root context guard
@ -65,7 +73,6 @@ class Rooted(object):
def execute(*cmd, **kwargs): def execute(*cmd, **kwargs):
process_input = kwargs.pop('process_input', None) process_input = kwargs.pop('process_input', None)
check_exit_code = kwargs.pop('check_exit_code', [0]) check_exit_code = kwargs.pop('check_exit_code', [0])
cwd = kwargs.pop('cwd', None) cwd = kwargs.pop('cwd', None)
@ -129,6 +136,11 @@ def execute(*cmd, **kwargs):
rc = None rc = None
result = None result = None
with Rooted(run_as_root): with Rooted(run_as_root):
if DRYRUN:
LOG.info("DRYRUN:%s" % (execute_cmd))
# Pretend it worked
rc = 0
else:
try: try:
obj = subprocess.Popen(execute_cmd, obj = subprocess.Popen(execute_cmd,
stdin=stdin_fh, stdin=stdin_fh,
@ -343,6 +355,10 @@ def mkdirslist(path):
def append_file(fn, text, flush=True, quiet=False): 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: if not quiet:
LOG.debug("Appending to file %s (%d bytes)", fn, len(text)) LOG.debug("Appending to file %s (%d bytes)", fn, len(text))
with open(fn, "a") as f: 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): 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: if not quiet:
LOG.debug("Writing to file %s (%d bytes)", fn, len(text)) LOG.debug("Writing to file %s (%d bytes)", fn, len(text))
with open(fn, "w") as f: 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): 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 isfile(fn):
if not quiet: if not quiet:
LOG.debug("Touching and truncating file %s (%s)", fn, file_size) 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): def load_file(fn, quiet=False):
LOG.info("load_file:%s" % (fn))
if not quiet: if not quiet:
LOG.debug("Loading data from file %s", fn) LOG.debug("Loading data from file %s", fn)
try:
with open(fn, "r") as f: with open(fn, "r") as f:
data = f.read() 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: if not quiet:
LOG.debug("Loaded (%d) bytes from file %s", len(data), fn) LOG.debug("Loaded (%d) bytes from file %s", len(data), fn)
return data return data
def mkdir(path, recurse=True): def mkdir(path, recurse=True):
if DRYRUN:
LOG.info("DRYRUN mkdir:%s" % (path))
return
if not isdir(path): if not isdir(path):
if recurse: if recurse:
LOG.debug("Recursively creating directory \"%s\"" % (path)) LOG.debug("Recursively creating directory \"%s\"" % (path))
@ -396,6 +433,9 @@ def mkdir(path, recurse=True):
def deldir(path, run_as_root=False): def deldir(path, run_as_root=False):
if DRYRUN:
LOG.info("DRYRUN deldir:%s" % (path))
return
with Rooted(run_as_root): with Rooted(run_as_root):
if isdir(path): if isdir(path):
LOG.debug("Recursively deleting directory tree starting at \"%s\"" % (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): def rmdir(path, quiet=True, run_as_root=False):
if DRYRUN:
LOG.info("DRYRUN rmdir:%s" % (path))
return
if not isdir(path): if not isdir(path):
return return
try: try:
@ -422,6 +465,9 @@ def symlink(source, link, force=True, run_as_root=True):
LOG.debug("Creating symlink from %s => %s" % (link, source)) LOG.debug("Creating symlink from %s => %s" % (link, source))
path = dirname(link) path = dirname(link)
needed_pths = mkdirslist(path) needed_pths = mkdirslist(path)
if DRYRUN:
LOG.info("DRYRUN symlink from %s => %s" % (source, link))
else:
if force and (exists(link) or islink(link)): if force and (exists(link) or islink(link)):
unlink(link, True) unlink(link, True)
os.symlink(source, link) os.symlink(source, link)
@ -534,6 +580,9 @@ def umount(dev_name, ignore_errors=True):
def unlink(path, ignore_errors=True, run_as_root=False): def unlink(path, ignore_errors=True, run_as_root=False):
if DRYRUN:
LOG.info("DRYRUN unlink:%s" % (path))
return
try: try:
LOG.debug("Unlinking (removing) %s" % (path)) LOG.debug("Unlinking (removing) %s" % (path))
with Rooted(run_as_root): with Rooted(run_as_root):
@ -546,10 +595,16 @@ def unlink(path, ignore_errors=True, run_as_root=False):
def move(src, dst): def move(src, dst):
if DRYRUN:
LOG.info("DRYRUN move:%s" % (src, dst))
return
shutil.move(src, dst) shutil.move(src, dst)
def chmod(fname, mode): def chmod(fname, mode):
if DRYRUN:
LOG.info("DRYRUN chmod:%s to %s" % (fname, mode))
return
os.chmod(fname, mode) 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): def copy_replace_file(fsrc, fdst, linemap):
files = mkdirslist(dirname(fdst)) files = mkdirslist(dirname(fdst))
if DRYRUN:
LOG.info("DRYRUN copy_replace:%s" % (fsrc, fdst))
return
with open(fdst, 'w') as fh: with open(fdst, 'w') as fh:
for line in fileinput.input(fsrc): for line in fileinput.input(fsrc):
for (k, v) in linemap.items(): for (k, v) in linemap.items():
@ -626,3 +684,10 @@ def geteuid():
def getegid(): def getegid():
return os.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) #here on out we should be using the logger (and not print)
start_time = time.time() start_time = time.time()
config = common.get_config() 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')) pkg_manager = common.get_packager(distro, args.get('keep_old'))
components = utils.parse_components(args.pop("components")) components = utils.parse_components(args.pop("components"))
runner = actions.ActionRunner(distro, action, rootdir, config, pkg_manager, components=components, **args) runner = actions.ActionRunner(distro, action, rootdir, config, pkg_manager, components=components, **args)