#!/usr/bin/python # sim-util -- various utility commands for Cactus/simfactory # # Michael Thomas # Center for Computation & Technology # Louisiana State University # import sys, os, shutil ############################################ ## APP SPECIFIC DEFINES ## # # Usage when (-h, --help) is used, this is the first line showing how to call the app # optionGroups which option groups from etc/options to import. common is always imported. App = "sim-util" Usage = "usage: %prog ..." optionGroups = ['sim-build'] Purpose = "Simfactory utility commands" ############################################ ############################################ ## INIT ## if os.path.basename(sys.argv[0]) == App: rp = os.path.abspath(__file__) paths = rp.split(os.sep) paths.pop() paths.pop() global BASE_PATH BASE_PATH = os.sep.join(paths) sys.path.append(BASE_PATH) LIB_PATH = "%s%slib" % (BASE_PATH, os.sep) sys.path.append(LIB_PATH) from lib import * import libutil import simdt import simarchive from libutil import dprint ## FUNCTIONS ## known_commands = ['checkout', 'login', 'get-archived-simulation', 'setup', 'setup-silent', 'execute'] usage_strings = { 'login': 'launch an interactive shell on a remote machine', 'checkout': 'checkout thorns using GetComponents', 'get-archived-simulation': 'retrieve an archived simulation by simulationid', 'setup': 'interactively configure simfactory', 'setup-silent': 'silently create a set of reasonable defaults', 'execute': 'execute a command'} def buildUsageString(): global Usage cmdString = "%s\n\n\nAvailable Commands:\n" % Usage iString = [] for kk in known_commands: ss = " %s%s" % (libutil.BuildWithSpace(kk, 35), usage_strings[kk]) iString.append(ss) cmdString = "%s%s" % (cmdString, "\n".join(iString)) return cmdString def CommandDispatch(): global SimEnvironment global OptionsManager global known_commands if SimEnvironment.COMMAND == None: command = OptionsManager.args.pop(0) else: command = SimEnvironment.COMMAND if len(OptionsManager.args) > 0: if command == OptionsManager.args[0]: OptionsManager.args.pop() if command not in known_commands: dprint("Error: unknown command %s" % command) sys.exit(1) dprint("Executing command: %s" % command) command = command.replace("-", "_") exec("command_%s()" % command) def command_execute(): global SimLib global SimEnvironment global ConfigurationDatabase global OptionsManager global DefineDatabase SimEnvironment.RequireMachine() cmd = OptionsManager.args.pop(0) output = SimLib.ExecuteCommand(cmd, True) dprint(output) def command_setup(): global SimLib global SimEnvironment global ConfigurationDatabase global OptionsManager global DefineDatabase # suppress warnings. SimEnvironment.VERBOSE = False try: dt = simdt.DecisionTree(SimEnvironment, "defaults") dt.setupTree() dt.begin() except KeyboardInterrupt: dprint("\nSetup terminated.", True) sys.exit(1) def command_setup_silent(): global SimLib global SimEnvironment global ConfigurationDatabase global OptionsManager global DefineDatabase # suppress warnings. SimEnvironment.VERBOSE = False try: dt = simdt.DecisionTree(SimEnvironment, "defaults-silent") dt.setupTree() dt.begin() except KeyboardInterrupt: dprint("\nSetup terminated.", True) sys.exit(1) def command_login(): global SimLib global SimEnvironment global ConfigurationDatabase global OptionsManager global DefineDatabase SimEnvironment.RequireMachine() if len(OptionsManager.args) == 0: dprint("Error: missing machine name", True) dprint("Usage: %s login ", True) sys.exit(1) machineName = OptionsManager.args.pop() dprint("Logging into remote machine %s" % machineName, True) machineEntry = ConfigurationDatabase.GetMachine(machineName) localMachineEntry = SimEnvironment.LocalMachineEntry SimLib.VerifyKeys(localMachineEntry, ['user', 'sourcebasedir']) SimLib.VerifyKeys(machineEntry, ['user', 'sourcebasedir', 'basedir']) DefineDatabase.Set('USER', localMachineEntry.GetKey('user')) sourcebasedir = DefineDatabase.SubAll(localMachineEntry.GetKey('sourcebasedir')) source_name = SimLib.GetDirSuffix(sourcebasedir) local_sourcedir = SimLib.BuildPath([sourcebasedir, source_name]) DefineDatabase.Set('SOURCEDIR', local_sourcedir) DefineDatabase.Set('USER', machineEntry.GetKey('user')) path = str() simulation = OptionsManager.GetOption('simulation') if simulation == None: msourcebasedir = DefineDatabase.SubAll(machineEntry.GetKey('sourcebasedir')) path = SimLib.BuildPath([msourcebasedir, source_name]) else: basedir = OptionsManager.GetOption('basedir') if basedir == None: basedir = DefineDatabase.SubAll(machineEntry.GetKey('basedir')) path = SimLib.BuildPath([basedir, simulation]) cmd = "cd %s && $SHELL -l" % path cmd = SimLib.GetSSHCommand(machineName, cmd, "-t") if machineEntry.HasKey("localsshsetup"): cmd = "{ %s; } && %s" % (DefineDatabase.SubAll(machineEntry.localsshsetup), cmd) output = SimLib.ExecuteCommand(cmd) def command_get_archived_simulation(): global SimLib global SimEnvironment SimEnvironment.RequireMachine() machineEntry = SimEnvironment.LocalMachineEntry SimLib.VerifyKeys(machineEntry, ['archivetype']) archiveType = machineEntry.archivetype ArchiveEngine = simarchive.SimArchive(SimEnvironment, archiveType) ArchiveEngine.authenticate() if len(OptionsManager.args) < 1: dprint("Error: wrong number of arguments", True) dprint("Usage: %s get-archived-simulation [--restart-id=] []" % sys.argv[0], True) sys.exit(1) simulationid = OptionsManager.args[0] if len(OptionsManager.args) == 1: dstPath = "." else: dstPath = OptionsManager.args[1] dprint("Retrieving simulation: %s" % simulationid, True) dprint("Destination path: %s" % dstPath, True) if OptionsManager.HasOption('restart-id'): restart_id = OptionsManager.GetOption('restart-id') else: restart_id = None ArchiveEngine.get(simulationid, dstPath, restart_id) def command_checkout(): global OptionsManager global ConfigurationDatabase global SimLib global DefineDatabase global SimEnvironment SimEnvironment.RequireMachine() thornList = OptionsManager.args if len(thornList) == 0: dprint("Error: no thornlist(s) specified", True) dprint("Usage: %s checkout ", True) sys.exit(1) thfile = "ThornList" getComponents = SimLib.BuildPath([SimEnvironment.APP_PATH, 'GetComponents']) dprint("Using GetComponents: %s" % getComponents) if not(os.path.exists(getComponents)): dprint("Error: could not find GetComponents at %s" % getComponents, True) sys.exit(1) for th in thornList: if th.count("://") > 0: local_name = th.split("/").pop() if os.path.exists(local_name): dprint("Error: thornlist file %s already exists; refusing to overwrite" % local_name, True) sys.exit(1) ret = SimLib.ExecuteCommand("curl -O %s" % th) if ret != 0: ret = SimLib.ExecuteCommand("wget --no-check-certificate -O %s %s" % (local_name, th)) if ret != 0: dprint("Error: could not download thorn list <%s>" % th, True) sys.exit(1) th = local_name contents = SimLib.GetFileContents(th) DefineDatabase.AddReplacement('!DEFINE ROOT', '.') contents = DefineDatabase.SubAll(contents) SimLib.WriteContents(thfile, contents) cmd = "%s -a %s" % (getComponents, thfile) SimLib.ExecuteCommand(cmd) os.unlink(thfile) def RemoteExecute(machineName): global SimEnvironment SimEnvironment.RequireMachine() RemoteEnvironment = simremote.RemoteEnvironment(SimEnvironment) RemoteEnvironment.init(machineName) RemoteEnvironment.ExecuteSameCommand(parrotArguments=True, stripArguments=['remotemachine']) def main(env): global OptionsManager global ConfigurationDatabase global SimLib global DefineDatabase global SimEnvironment SimEnvironment = env OptionsManager = SimEnvironment.OptionsManager ConfigurationDatabase = SimEnvironment.ConfigurationDatabase SimLib = SimEnvironment.SimLib DefineDatabase = SimEnvironment.DefineDatabase ############################################ if os.path.basename(SimEnvironment.EXECUTABLE) == App: dprint("sim-util: %s" % Purpose, True) dprint("defs: %s" % SimEnvironment.cdb) if SimEnvironment.udb != None: dprint("defs.local: %s" % SimEnvironment.udb) print # make sure our configs directory is created try: os.mkdir(SimEnvironment.CONFIGS_PATH) except OSError: pass if OptionsManager.HasOption("remotemachine"): remoteMachine = OptionsManager.GetOption("remotemachine") dprint("Executing utility for remote machine: %s" % remoteMachine, True) RemoteExecute(remoteMachine) return CommandDispatch() # only run if you are App if os.path.basename(sys.argv[0]) == App: global SimEnvironment SimEnvironment = simenv.SimEnvironment(BASE_PATH, os.path.abspath(sys.argv[0])) SimEnvironment.initApp(usageString=buildUsageString(), optionGroups=optionGroups) main(SimEnvironment)