Exemple #1
0
def main(parser, options, suite, *task_globs):
    if not options.state and not options.outputs:
        parser.error("Neither --state=STATE nor --output=OUTPUT is set")

    if options.state == "spawn":
        # Back compat.
        sys.stderr.write(
            "'cylc reset -s spawn' is deprecated; calling 'cylc spawn'\n")
        cmd = sys.argv[0].replace('reset', 'spawn')
        try:
            os.execvp(cmd, [cmd] + task_globs)
        except OSError as exc:
            if exc.filename is None:
                exc.filename = cmd
            raise SystemExit(exc)

    if not options.state:
        options.state = ''

    prompt('Reset task(s) %s in %s' % (task_globs, suite), options.force)
    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port, options.comms_timeout)
    pclient(
        'reset_task_states', {
            'task_globs': task_globs,
            'state': options.state,
            'outputs': options.outputs
        })
Exemple #2
0
def main(parser, options, suite, *task_globs):
    prompt('remove task(s) %s in %s' % (task_globs, suite), options.force)
    pclient = SuiteRuntimeClient(
        suite, options.owner, options.host, options.port,
        options.comms_timeout)
    pclient(
        'remove_tasks',
        {'tasks': task_globs, 'spawn': (not options.no_spawn)}
    )
Exemple #3
0
def main(parser, options, suite, *task_globs):
    """CLI of "cylc kill"."""
    if task_globs:
        prompt('Kill task %s in %s' % (task_globs, suite), options.force)
    else:
        prompt('Kill ALL tasks in %s' % (suite), options.force)
    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port)
    pclient('kill_tasks', {'tasks': task_globs}, timeout=options.comms_timeout)
Exemple #4
0
def main(parser, options, suite, *task_globs):
    if task_globs:
        prompt('Poll task %s in %s' % (task_globs, suite), options.force)
    else:
        prompt('Poll ALL tasks in %s' % (suite), options.force)
    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port, options.comms_timeout)
    pclient('poll_tasks', {
        'tasks': task_globs,
        'poll_succeeded': options.poll_succ
    })
def main(parser, options, suite, severity_str):
    try:
        severity = LOGGING_LVL_OF[severity_str]
    except KeyError:
        parser.error("Illegal logging level, %s" % severity_str)

    prompt("Set logging level to %s in %s" % (severity_str, suite),
           options.force)
    pclient = SuiteRuntimeClient(
        suite, options.owner, options.host, options.port,
        options.comms_timeout)

    pclient('set_verbosity', {'level': severity})
Exemple #6
0
def main(parser, options, suite, *items):
    for i, item in enumerate(items):
        if not TaskID.is_valid_id_2(item):
            raise UserInputError(
                '"%s": invalid task ID (argument %d)' % (item, i + 1))
    prompt('Insert %s in %s' % (items, suite), options.force)

    pclient = SuiteRuntimeClient(
        suite, options.owner, options.host, options.port)

    pclient(
        'insert_tasks',
        {'items': items, 'no_check': options.no_check,
         'stop_point_string': options.stop_point_string},
        timeout=options.comms_timeout
    )
Exemple #7
0
def main(parser, options, suite, *task_globs):
    if task_globs:
        prompt('Hold task(s) %s in %s' % (task_globs, suite), options.force)
    elif options.hold_point_string:
        prompt('Hold suite after %s' % options.hold_point_string,
               options.force)
    else:
        prompt('Hold suite %s' % suite, options.force)

    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port)

    if task_globs:
        pclient('hold_tasks', {'task_globs': task_globs},
                timeout=options.comms_timeout)
    elif options.hold_point_string:
        pclient('hold_after_point_string',
                {'point_string': options.hold_point_string},
                timeout=options.comms_timeout)
    else:
        pclient('hold_suite', timeout=options.comms_timeout)
Exemple #8
0
def main(parser, options, suite, shutdown_arg=None):
    if shutdown_arg is not None and options.kill:
        parser.error("ERROR: --kill is not compatible with [STOP]")

    if options.kill and options.now:
        parser.error("ERROR: --kill is not compatible with --now")

    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port, options.comms_timeout)

    if int(options.max_polls) > 0:
        # (test to avoid the "nothing to do" warning for # --max-polls=0)
        spoller = StopPoller(pclient, "suite stopped", options.interval,
                             options.max_polls)

    if options.wall_clock:
        prompt(
            'Set shutdown at wall clock %s for %s' %
            (options.wall_clock, suite), options.force)
        pclient('set_stop_after_clock_time',
                {'datetime_string': options.wall_clock})
    elif shutdown_arg is not None and TaskID.is_valid_id(shutdown_arg):
        # STOP argument detected
        prompt('Set shutdown after task %s for %s' % (shutdown_arg, suite),
               options.force)
        pclient('set_stop_after_task', {'task_id': shutdown_arg})
    elif shutdown_arg is not None:
        # not a task ID, may be a cycle point
        prompt('Set shutdown at cycle point %s for %s' % (shutdown_arg, suite),
               options.force)
        pclient('set_stop_after_point', {'point_string': shutdown_arg})
    elif options.now > 1:
        prompt('Shut down and terminate %s now' % suite, options.force)
        pclient('stop_now', {'terminate': True})
    elif options.now:
        prompt('Shut down %s now' % suite, options.force)
        pclient('stop_now')
    else:
        prompt('Shut down %s' % suite, options.force)
        pclient('set_stop_cleanly', {'kill_active_tasks': options.kill})

    if int(options.max_polls) > 0:
        # (test to avoid the "nothing to do" warning for # --max-polls=0)
        if not spoller.poll():
            sys.exit(1)
Exemple #9
0
def main(parser, options, suite, *task_globs):
    prompt('Spawn task(s) %s in %s' % (task_globs, suite), options.force)
    pclient = SuiteRuntimeClient(suite, options.owner, options.host,
                                 options.port, options.comms_timeout)

    pclient('spawn_tasks', {'task_globs': task_globs})
Exemple #10
0
def main(parser, options, suite, *task_globs):
    """CLI for "cylc trigger"."""
    msg = 'Trigger task(s) %s in %s' % (task_globs, suite)
    prompt(msg, options.force)

    pclient = SuiteRuntimeClient(
        suite, options.owner, options.host, options.port,
        options.comms_timeout)

    aborted = False
    if options.edit_run:
        task_id = task_globs[0]
        # Check that TASK is a unique task.
        success, msg = pclient(
            'ping_task',
            {'task_id': task_id, 'exists_only': True}
        )

        # Get the job filename from the suite server program - the task cycle
        # point may need standardising to the suite cycle point format.
        jobfile_path = pclient(
            'get_task_jobfile_path', {'task_id': task_id})
        if not jobfile_path:
            raise UserInputError('task not found')

        # Note: localhost time and file system time may be out of sync,
        #       so the safe way to detect whether a new file is modified
        #       or is to detect whether time stamp has changed or not.
        #       Comparing the localhost time with the file timestamp is unsafe
        #       and may cause the "while True" loop that follows to sys.exit
        #       with an error message after MAX_TRIES.
        try:
            old_mtime = os.stat(jobfile_path).st_mtime
        except OSError:
            old_mtime = None

        # Tell the suite server program to generate the job file.
        pclient(
            'dry_run_tasks',
            {'tasks': [task_id], 'check_syntax': False}
        )

        # Wait for the new job file to be written. Use mtime because the same
        # file could potentially exist already, left from a previous run.
        count = 0
        MAX_TRIES = 10
        while True:
            count += 1
            try:
                mtime = os.stat(jobfile_path).st_mtime
            except OSError:
                pass
            else:
                if old_mtime is None or mtime > old_mtime:
                    break
            if count > MAX_TRIES:
                raise CylcError(
                    'no job file after %s seconds' % MAX_TRIES)
            time.sleep(1)

        # Make a pre-edit copy to allow a post-edit diff.
        jobfile_copy_path = "%s.ORIG" % jobfile_path
        shutil.copy(jobfile_path, jobfile_copy_path)

        # Edit the new job file.
        if options.geditor:
            editor = glbl_cfg().get(['editors', 'gui'])
        else:
            editor = glbl_cfg().get(['editors', 'terminal'])
        # The editor command may have options, e.g. 'emacs -nw'.
        command_list = re.split(' ', editor)
        command_list.append(jobfile_path)
        command = ' '.join(command_list)
        try:
            # Block until the editor exits.
            retcode = call(command_list)
            if retcode != 0:
                raise CylcError(
                    'command failed with %d:\n %s' % (retcode, command))
        except OSError:
            raise CylcError('unable to execute:\n %s' % command)

        # Get confirmation after editing is done.
        # Don't allow force-no-prompt in this case.
        if options.geditor:
            # Alert stdout of the dialog window, in case it's missed.
            print("Editing done. I'm popping up a confirmation dialog now.")

        # Save a diff to record the changes made.
        difflog = os.path.join(os.path.dirname(jobfile_path), JOB_LOG_DIFF)
        with open(difflog, 'wb') as diff_file:
            for line in difflib.unified_diff(
                    open(jobfile_copy_path).readlines(),
                    open(jobfile_path).readlines(),
                    fromfile="original",
                    tofile="edited"):
                diff_file.write(line.encode())
        os.unlink(jobfile_copy_path)

        msg = "Trigger edited task %s?" % task_id
        if not prompt(msg, gui=options.geditor, no_force=True, no_abort=True):
            log_dir_symlink = os.path.dirname(jobfile_path)
            real_log_dir = os.path.realpath(log_dir_symlink)
            prev_nn = "%02d" % (int(os.path.basename(real_log_dir)) - 1)
            os.unlink(log_dir_symlink)
            if int(prev_nn) == 0:
                # No previous submit: delete the whole parent directory.
                shutil.rmtree(os.path.dirname(real_log_dir))
            else:
                # Reset to previous NN symlink and delete the log directory.
                dirname = os.path.dirname(real_log_dir)
                os.symlink(prev_nn, os.path.join(dirname, "NN"))
                shutil.rmtree(real_log_dir)
            aborted = True

    # Trigger the task proxy(s).
    pclient(
        'trigger_tasks',
        {'tasks': task_globs, 'back_out': aborted}
    )
Exemple #11
0
def main(parser, options, suite):
    prompt('Reload %s' % suite, options.force)
    pclient = SuiteRuntimeClient(
        suite, options.owner, options.host, options.port,
        options.comms_timeout)
    pclient('reload_suite')