1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
# Identify a test's scripts.
#
# Copyright (C) 2016 Andrew Cagney <cagney@gnu.org>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
import os
import re
from glob import glob
from os import path
from fab import argutil
from fab import hosts
# In Command GUEST can be None because it is a blank line or comment.
class Command:
def __init__(self, guest, line, script):
self.guest = guest
self.line = line
self.script = script
def __str__(self):
if self.guest:
if self.script:
return self.script+" "+self.guest.name + "# " + self.line
return self.guest.name + "# " + self.line
return self.line
class Commands(list):
def __str__(self):
# string is used by --print test-scripts (it has no spaces)
return "\n".join(str(script) for script in self)
def _scripts(directory):
"""Returns a set of *.sh scripts found in DIRECTORY"""
scripts = set()
for script in glob(path.join(directory, "*.sh")):
if not path.isfile(script):
continue
# Add more filter-outs
scripts.add(path.basename(script))
return scripts
def _add_commands(script, commands, directory, guests):
for guest in guests:
for line in open(os.path.join(directory, script), "r"):
# toss blank lines and trailing '\n'
line = line.strip()
if line:
commands.append(Command(guest, line, script))
def _add_script(script, commands, scripts, directory, guests):
if script in scripts:
scripts.remove(script)
_add_commands(script, commands, directory, guests)
def _script_guests(script, guests):
matched = list()
for guest in guests:
if re.search(guest.name, script):
matched.append(guest)
return matched
def _guest_scripts(directory, logger):
"""Return a list of {guest_name:, path:} to run"""
scripts = _scripts(directory)
logger.debug("scripts: %s", scripts);
# Form a subset of GUESTS based on the names found in the
# scripts.
guests = set()
for script in scripts:
guests.update(_script_guests(script, hosts.GUESTS))
guests = sorted(guests)
logger.debug("guests: %s", guests)
# Compatibility hack: form a list of scripts matching <host>init.sh
# and within that force "nic" then "east" to be on the front of
# the list. These will be run first.
init_commands = Commands()
_add_script("nicinit.sh", init_commands,
scripts, directory, [hosts.NIC])
_add_script("eastinit.sh", init_commands,
scripts, directory, [hosts.EAST])
for guest in guests:
_add_script(guest.name+"init.sh", init_commands,
scripts, directory, [guest])
logger.debug("init commands: %s", init_commands)
# Compatibility hack: form a list of scripts matching <host>run.sh.
# These will be run second.
run_commands = Commands()
for guest in guests:
_add_script(guest.name+"run.sh", run_commands,
scripts, directory, [guest])
logger.debug("run commands: %s", run_commands)
# Part compatibility hack, part new behaviour: form a list of
# scripts matching <host>final.sh. These will be run last.
final_commands = Commands()
_add_script("final.sh", final_commands,
scripts, directory, guests)
logger.debug("final commands: %s", run_commands)
# What's left are ordered scripts. Preserve the order that the
# host names appear in the file name. For instance, the script
# 99-west-east.sh would be run on west then east.
ordered_commands = Commands()
for script in sorted(scripts):
_add_commands(script, ordered_commands, directory,
_script_guests(script, guests))
logger.debug("ordered commands: %s", ordered_commands)
# Form the list of scripts to run. Per above: init, run, ordered,
# final.
all_commands = Commands()
all_commands.extend(init_commands)
all_commands.extend(run_commands)
all_commands.extend(ordered_commands)
all_commands.extend(final_commands)
return all_commands
# for line in open("r").line includes; when <guest> is blank, a
# comment is assumed.
_GUEST_COMMAND_PATTERN = r'^(?P<guest>[a-z]*)# ?(?P<line>.*)[\n]$'
_GUEST_COMMAND_REGEX = re.compile(_GUEST_COMMAND_PATTERN)
def commands(directory, logger):
for script in ("all.sh", "all.console.txt"):
all = path.join(directory, script)
if os.path.exists(all):
commands = Commands()
# read includes '\n';
for line in open(all, "r"):
# regex matches both:
# <host># command
# and
# # comment
command = _GUEST_COMMAND_REGEX.match(line)
if command:
guest = command.group("guest")
line = command.group("line")
if guest:
commands.append(Command(hosts.lookup(guest), line, script))
elif line:
commands.append(Command(None, "# "+line, script))
else:
commands.append(Command(None, "#", script))
return commands
return _guest_scripts(directory, logger)
|