diff --git a/TODO b/TODO index 6e8a543..cac8f49 100644 --- a/TODO +++ b/TODO @@ -45,6 +45,10 @@ default, say via the $TSSHBATCH environment variable, but override it when you need to. + - A new directive, .notify, tells tsshbatch to print an informative + message from within a command file. This is a runtime activity + and is helpful, for example when tracking progress of a long + command file. [CHANGES] @@ -67,8 +71,6 @@ TODO ---- - - Add ability to send informative messages back during execution - - Protect path walk from files/dirs that cannot be opened. diff --git a/tsshbatch.py b/tsshbatch.py index d538223..3c2b63a 100755 --- a/tsshbatch.py +++ b/tsshbatch.py @@ -69,45 +69,46 @@ ##### -ABORTING = 'Aborting ...' -BANNERTIME = 'Elapsed Time: %s Seconds' -BANNERMSG = '%s %s %s On %s At %s' % (PROGNAME, VERSION, '%s', '%s', '%s') -BANNEREND = 'Ended' -BANNERSTART = 'Started' -COMMENT = '#' -COMMANDS = 'Commands' -CFGKEYID = 'identityfile' -CFGREALHOST = 'hostname' -CONSUCCESS = 'SUCCESS: Connection Established' -EXECUTE = '!' -FILEGET = '.getfile' -FILEPUT = '.putfile' -GETFILES = 'Files To GET' -HOSTSEP = '-' -HOSTNOISE = '[%s]' -HOSTLIST = 'Hosts' -INDENTWIDTH = 8 -NOMATCH = "No string matches!" -OPTIONSLIST = 'BC:EF:G:H:KLNP:ST:V:Wabef:hi:kl:n:p:qrstvxy' -PADWIDTH = 12 -PATHDELIM = ':' -PATHSEP = os.sep -PUTFILES = 'Files To PUT' -SEPARATOR = ' ---> ' -STDIN = '-' -SUDO = 'sudo' -SUDOPROMPT = 'READINGSUDOPW' -SUDOARGS = '-S -p %s' % SUDOPROMPT -SUDOPWHINT = '(Default: login password): ' -SYMTABLE = 'Symbol Table' -TESTRUN = 'Test Run For' -TRAILER = ': ' -USERVAR = 'USER' +ABORTING = 'Aborting ...' +BANNERTIME = 'Elapsed Time: %s Seconds' +BANNERMSG = '%s %s %s On %s At %s' % (PROGNAME, VERSION, '%s', '%s', '%s') +BANNEREND = 'Ended' +BANNERSTART = 'Started' +COMMENT = '#' +COMMANDS = 'Commands' +CFGKEYID = 'identityfile' +CFGREALHOST = 'hostname' +CONSUCCESS = 'SUCCESS: Connection Established' +EXECUTE = '!' +FILEGET = '.getfile' +FILEPUT = '.putfile' +GETFILES = 'Files To GET' +HOSTSEP = '-' +HOSTNOISE = '[%s]' +HOSTLIST = 'Hosts' +INDENTWIDTH = 8 +NOMATCH = "No string matches!" +NOTIFICATION = 'NOTIFICATION' +OPTIONSLIST = 'BC:EF:G:H:KLNP:ST:V:Wabef:hi:kl:n:p:qrstvxy' +PADWIDTH = 12 +PATHDELIM = ':' +PATHSEP = os.sep +PUTFILES = 'Files To PUT' +SEPARATOR = ' ---> ' +STDIN = '-' +SUDO = 'sudo' +SUDOPROMPT = 'READINGSUDOPW' +SUDOARGS = '-S -p %s' % SUDOPROMPT +SUDOPWHINT = '(Default: login password): ' +SYMTABLE = 'Symbol Table' +TESTRUN = 'Test Run For' +TRAILER = ': ' +USERVAR = 'USER' -USAGE = \ +USAGE = \ PROGVER + "\n" +\ HOMEPAGE + "\n\n" +\ - "Usage: tsshbatch.py [-BEF:KLNSTVWaehkqrstvy -C configfile -G 'file dest' -P 'file dest' -f cmdfile -l logfile -n name -p pw ] -H 'host ..' -i 'hostfile ...' [command arg ... ]\n" +\ + "Usage: tsshbatch.py [-BEF:KLNSTVWaehkqrstvy -C configfile -G 'file dest' -P 'file dest' -f cmdfile -l logfile -n name -p pw ] -H 'host ...' -i 'hostfile ...' [command arg ... ]\n" +\ " where,\n" +\ "\n" +\ " -B Print start and stop statistics (Off)\n" +\ @@ -150,6 +151,7 @@ ASSIGN = '=' DEFINE = '.define' INCLUDE = '.include' +NOTIFY = '.notify' ##### @@ -489,6 +491,12 @@ if not command: continue + # Process notifications + + if command.startswith(NOTIFY): + PrintReport([NOTIFICATION, " ".join(command.split(NOTIFY)).strip() + '\n'], HANDLER=PrintStdout) + continue + # If this is a sudo run, force password to be read # from stdin thereby avoiding fiddling around with ptys. diff --git a/tsshbatch.rst b/tsshbatch.rst index 94c47c8..da2f9d1 100644 --- a/tsshbatch.rst +++ b/tsshbatch.rst @@ -262,19 +262,57 @@ your local shell will interfere with them being properly conveyed to the remote machine. +``tsshbatch`` does all the ``GETs``, then all the ``PUTs`` before +attempting to do any command processing. If no ``GETs``, ``PUTs``, or +commands have been specified, ``tsshbatch`` will exit silently, since +"nothing to do" really isn't an error. + + +COMMAND FILES +------------- + +Command files are nothing more than files with a list of commands to +execute. Notice that this is not the same thing as a shell script. +There are no conditionals or other programming features. It's more-or-less +a "to do" list for each host. Command files may include other command +files, make use of variables, and even specify sudo commands. Their +basic form is: + + .include master_commands # optional, can be repeated + command1 # a command to run on each host + sudo foo # run foo with sudo promotion + If you've specified a ``cmdfile`` containing the commands you want run via the ``-f`` option, these commands will run *before* the command you've defined on the command line. It is always the last command run on each host. -You can put as many ``-f`` arguments as you wish on the command -line and the contents of these files will be run in the order -they appeared from left-to-right on the command line. +Command files may freely make use of comments and variable +definitions as described below. They also have a special +directive available, ``.notify`` which causes ``tsshbatch`` to +print descriptive messages to ``stdout`` as the commands in the file +are executed on a remote host. This is helpful when running long, +complex jobs:: -``tsshbatch`` does all the ``GETs``, then all the ``PUTs`` before -attempting to do any command processing. If no ``GETs``, ``PUTs``, or -commands have been specified, ``tsshbatch`` will exit silently, since -"nothing to do" really isn't an error. + # Example cmdfile + + .include /my/fine/options + .define __JOB_NAME__ + .notify starting JOB_NAME processing + /usr/local/__JOB_NAME__ + .notify starting phase 2 of __JOB_NAME__ + do_another_command + +Notifications are entirely optional *and do not run on the remote +host*. Think of them as runtime comments to help you see what's going +on. + +You can also specify file transfers within a command file. See the +section below on file transfers for all the details. + +You can put as many ``-f`` arguments as you wish on the command line +and the contents of these files will be run in the order they appeared +from left-to-right on the command line. ENVIRONMENT