Source code orco/cli.py

  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
import argparse
import os
import sys

import json5

from .cfggen import build_config
from .runtime import Runtime
from .globals import has_global_runtime, get_global_runtime


def _command_serve(runtime, args):
    runtime.serve(port=args.port)


def _command_compute(runtime, args):
    tasks = _job_from_args(runtime, args)
    res = runtime.compute_many(tasks)
    for e in res:
        print("{:40s}   {!r}".format(e.key, e.value))


def _job_from_args(runtime, args):
    if not runtime.has_builder(args.builder):
        raise Exception("Unknown builder {!r}".format(args.builder))
    builder = runtime.get_builder(args.builder).make_proxy()
    cfg = json5.loads(args.config)
    cfg = build_config(cfg)
    print(cfg)
    if isinstance(cfg, list):
        tasks = [builder.job_from_config(c) for c in cfg]
    elif isinstance(cfg, dict):
        tasks = [builder.job_from_config(cfg)]
    else:
        raise Exception(
            "Expanded config has type {!r}, list (many tasks) or dict (one task) expected.".format(
                type(cfg)
            )
        )
    return tasks


def _command_drop(runtime, args):
    tasks = _job_from_args(runtime, args)
    runtime.drop_many(tasks)


def _command_archive(runtime, args):
    tasks = _job_from_args(runtime, args)
    runtime.archive_many(tasks)


def _command_free(runtime, args):
    tasks = _job_from_args(runtime, args)
    runtime.free_many(tasks)


def _command_drop_builder(runtime, args):
    runtime.drop_builder(args.builder)


def _parse_args():
    parser = argparse.ArgumentParser("orco", description="Organized Computing")
    parser.add_argument("-d", "--db", default=None, type=str)
    sp = parser.add_subparsers(title="command")
    parser.set_defaults(command=None)

    # SERVE
    p = sp.add_parser("serve")
    p.add_argument("--port", type=int, default=8550)
    p.set_defaults(command=_command_serve)

    # COMPUTE
    p = sp.add_parser("compute")
    p.add_argument("builder")
    p.add_argument("config")
    p.set_defaults(command=_command_compute)

    # DROP
    p = sp.add_parser("drop")
    p.add_argument("builder")
    p.add_argument("config")
    p.set_defaults(command=_command_drop)

    # ARCHIVE
    p = sp.add_parser("archive")
    p.add_argument("builder")
    p.add_argument("config")
    p.set_defaults(command=_command_archive)

    # FREE
    p = sp.add_parser("free")
    p.add_argument("builder")
    p.add_argument("config")
    p.set_defaults(command=_command_free)

    # DROP-BUILDER
    p = sp.add_parser("drop-builder")
    p.add_argument("builder")
    p.set_defaults(command=_command_drop_builder)

    return parser.parse_args()


def run_cli(runtime=None, db_path=None):
    """
    Start command-line interface over a runtime.

    The function always closes runtime on return, even in case of an exception.

    If not given, a Runtime is created with in-memory db or the db provided with '-d'.
    """
    try:
        args = _parse_args()
        if runtime is None:
            if args.db is not None:
                db_path = args.db
            else:
                db_path = os.environ.get("ORCO_DB")
            if db_path is None:
                if has_global_runtime():
                    runtime = get_global_runtime()
                else:
                    raise Exception(
                        "No database is defined, use parameter '--db' or env variable 'ORCO_DB'"
                    )
            else:
                runtime = Runtime(db_path)
        else:
            if args.db is not None:
                print(
                    "Warning: --db ignored (only used with the default runtime)",
                    file=sys.stderr,
                )

        if args.command is None:
            print("No command provided", file=sys.stderr)
        else:
            args.command(runtime, args)
    finally:
        if runtime is not None:
            runtime.stop()