Пример #1
0
void V8ShellFeature::loadModules(ShellFeature::RunMode runMode) {
  auto context = _isolate->GetCurrentContext();

  JSLoader loader;
  loader.setDirectory(_startupDirectory);

  // load all init files
  std::vector<std::string> files;

  files.push_back("common/bootstrap/scaffolding.js");
  files.push_back("common/bootstrap/modules/internal.js");  // deps: -
  files.push_back("common/bootstrap/errors.js");            // deps: internal
  files.push_back("client/bootstrap/modules/internal.js");  // deps: internal
  files.push_back("common/bootstrap/modules/vm.js");        // deps: internal
  files.push_back("common/bootstrap/modules/console.js");   // deps: internal
  files.push_back("common/bootstrap/modules/assert.js");    // deps: -
  files.push_back("common/bootstrap/modules/buffer.js");    // deps: internal
  files.push_back(
      "common/bootstrap/modules/fs.js");  // deps: internal, buffer (hidden)
  files.push_back("common/bootstrap/modules/path.js");     // deps: internal, fs
  files.push_back("common/bootstrap/modules/events.js");   // deps: -
  files.push_back("common/bootstrap/modules/process.js");  // deps: internal,
                                                           // fs, events,
                                                           // console
  files.push_back(
      "common/bootstrap/modules.js");  // must come last before patches

  files.push_back("client/client.js");  // needs internal

  for (size_t i = 0; i < files.size(); ++i) {
    switch (loader.loadScript(_isolate, context, files[i])) {
      case JSLoader::eSuccess:
        LOG(TRACE) << "loaded JavaScript file '" << files[i] << "'";
        break;
      case JSLoader::eFailLoad:
        LOG(FATAL) << "cannot load JavaScript file '" << files[i] << "'";
        FATAL_ERROR_EXIT();
        break;
      case JSLoader::eFailExecute:
        LOG(FATAL) << "error during execution of JavaScript file '" << files[i]
                   << "'";
        FATAL_ERROR_EXIT();
        break;
    }
  }
}
Пример #2
0
void AvocadoServer::executeShell () {
    v8::Isolate* isolate;
    v8::Persistent<v8::Context> context;
    bool ok;
    char const* files[] = { "bootstrap/modules.js",
                            "bootstrap/print.js",
                            "server/modules.js",
                            "server/json.js",
                            "server/aql.js",
                            "server/shell.js"
                          };
    size_t i;

    // only simple logging
    TRI_ShutdownLogging();
    TRI_InitialiseLogging(false);
    TRI_CreateLogAppenderFile("+");

    // open the database
    openDatabase();

    // enter a new isolate
    isolate = v8::Isolate::New();
    isolate->Enter();

    // global scope
    v8::HandleScope globalScope;

    // create the context
    context = v8::Context::New(0);

    if (context.IsEmpty()) {
        LOGGER_FATAL << "cannot initialize V8 engine";
        cerr << "cannot initialize V8 engine\n";
        exit(EXIT_FAILURE);
    }

    context->Enter();

    LOGGER_INFO << "using JavaScript modules path '" << _startupModules << "'";

    TRI_InitV8VocBridge(context, _vocbase);
    TRI_InitV8Conversions(context);
    TRI_InitV8Utils(context, _startupModules);
    TRI_InitV8Shell(context);

    // load all init files
    for (i = 0;  i < sizeof(files) / sizeof(files[0]);  ++i) {
        ok = StartupLoader.loadScript(context, files[i]);

        if (ok) {
            LOGGER_TRACE << "loaded json file '" << files[i] << "'";
        }
        else {
            LOGGER_FATAL << "cannot load json file '" << files[i] << "'";
            cerr << "cannot load json file '" << files[i] << "'\n";
            exit(EXIT_FAILURE);
        }
    }

    // run the shell
    printf("AvocadoDB shell [V8 version %s, DB version %s]\n", v8::V8::GetVersion(), TRIAGENS_VERSION);

    v8::Context::Scope contextScope(context);
    v8::Local<v8::String> name(v8::String::New("(avocado)"));

    V8LineEditor* console = new V8LineEditor(context, ".avocado");

    console->open();

    while (true) {
        while(! v8::V8::IdleNotification()) {
        }

        char* input = console->prompt("avocado> ");

        if (input == 0) {
            printf("bye...\n");
            TRI_FreeString(input);
            break;
        }

        if (*input == '\0') {
            TRI_FreeString(input);
            continue;
        }

        console->addHistory(input);

        v8::HandleScope scope;

        TRI_ExecuteStringVocBase(context, v8::String::New(input), name, true, true);

        TRI_FreeString(input);
    }
    console->close();

    delete console;

    // and return from the context and isolate
    context->Exit();
    isolate->Exit();

    // close the database
    closeDatabase();
}
Пример #3
0
void AvocadoServer::buildApplicationServer () {
    _applicationServer = ApplicationServerDispatcher::create("[<options>] <database-directory>", TRIAGENS_VERSION);

#ifdef TRI_ENABLE_RELATIVE
    _applicationServer->setSystemConfigFile("avocado.conf", _binaryPath + "/../etc/");
#else
    _applicationServer->setSystemConfigFile("avocado.conf");
#endif

    _applicationServer->setUserConfigFile(".avocado/avocado.conf");

    // .............................................................................
    // allow multi-threading scheduler
    // .............................................................................

    _applicationServer->allowMultiScheduler(true);

    // .............................................................................
    // and start a simple admin server
    // .............................................................................

    _applicationAdminServer = ApplicationAdminServer::create(_applicationServer);
    _applicationServer->addFeature(_applicationAdminServer);

#ifdef TRI_ENABLE_RELATIVE
    _applicationAdminServer->allowAdminDirectory(_binaryPath + "/../share/avocado/html/admin");
#else
    _applicationAdminServer->allowAdminDirectory();
#endif

    _applicationAdminServer->allowLogViewer();
    _applicationAdminServer->allowVersion("avocado", TRIAGENS_VERSION);

    // .............................................................................
    // a http server
    // .............................................................................

    _applicationHttpServer = ApplicationHttpServer::create(_applicationServer);
    _applicationServer->addFeature(_applicationHttpServer);

    // .............................................................................
    // daemon and supervisor mode
    // .............................................................................

    map<string, ProgramOptionsDescription> additional;

    additional[ApplicationServer::OPTIONS_CMDLINE]
    ("shell", "do not start as server, start in shell mode instead")
    ;

    additional[ApplicationServer::OPTIONS_CMDLINE + ":help-extended"]
    ("daemon", "run as daemon")
    ("supervisor", "starts a supervisor and runs as daemon")
    ("pid-file", &_pidFile, "pid-file in daemon mode")
    ("working directory", &_workingDirectory, "working directory in daemon mode")
    ;

    // .............................................................................
    // for this server we display our own options such as port to use
    // .............................................................................

    _applicationHttpServer->showPortOptions(false);

    additional["PORT Options"]
    ("server.http-port", &_httpPort, "port for client access")
    ;

    additional[ApplicationServer::OPTIONS_HIDDEN]
    ("port", &_httpPort, "port for client access")
    ;

    // .............................................................................
    // database options
    // .............................................................................

    additional["DATABASE Options:help-admin"]
    ("database.directory", &_databasePath, "path to the database directory (use this option in configuration files instead of passing it via the command line)")
    ;

    // .............................................................................
    // JavaScript options
    // .............................................................................

    additional["JAVASCRIPT Options:help-admin"]
    ("startup.directory", &_startupPath, "path to the directory containing alternate startup scripts")
    ("startup.modules-path", &_startupModules, "one or more directories separated by semicolon")
    ("action.directory", &_actionPath, "path to the action directory, defaults to <database.directory>/_ACTIONS")
    ;

    additional["JAVASCRIPT Options:help-admin"]
    ("action.system-directory", &_systemActionPath, "path to the system action directory")
    ("action.threads", &_actionThreads, "threads for actions")
    ;

    // .............................................................................
    // database options
    // .............................................................................

    additional["Server Options:help-admin"]
    ("server.admin-port", &_adminPort, "http server:port for ADMIN requests")
    ("dispatcher.threads", &_dispatcherThreads, "number of dispatcher threads")
    ;

    // .............................................................................
    // parse the command line options - exit if there is a parse error
    // .............................................................................

    if (! _applicationServer->parse(_argc, _argv, additional)) {
        exit(EXIT_FAILURE);
    }

    // .............................................................................
    // set directories and scripts
    // .............................................................................

    vector<string> arguments = _applicationServer->programArguments();

    if (1 < arguments.size()) {
        LOGGER_FATAL << "expected at most one database directory, got " << arguments.size();
        exit(EXIT_FAILURE);
    }
    else if (1 == arguments.size()) {
        _databasePath = arguments[0];
    }

    if (_startupPath.empty()) {
        LOGGER_INFO << "using built-in JavaScript startup files";
        StartupLoader.defineScript("bootstrap/modules.js", JS_bootstrap_modules);
        StartupLoader.defineScript("bootstrap/print.js", JS_bootstrap_print);
        StartupLoader.defineScript("server/modules.js", JS_server_modules);
        StartupLoader.defineScript("server/actions.js", JS_server_actions);
        StartupLoader.defineScript("server/aql.js", JS_server_aql);
        StartupLoader.defineScript("server/json.js", JS_server_json);
        StartupLoader.defineScript("server/shell.js", JS_server_shell);
    }
    else {
        LOGGER_INFO << "using JavaScript startup files at '" << _startupPath << "'";
        StartupLoader.setDirectory(_startupPath);
    }

    if (_actionPath.empty()) {
        char* path = TRI_Concatenate2File(_databasePath.c_str(), "_ACTIONS");
        string pathString(path);
        if (path) {
            // memleak otherwise
            TRI_Free(path);
        }

        if (! TRI_IsDirectory(pathString.c_str())) {
            bool ok = TRI_ExistsFile(pathString.c_str());

            if (ok) {
                LOGGER_FATAL << "action directory '" << pathString << "' must be a directory";
                cerr << "action directory '" << pathString << "' must be a directory\n";
                LOGGER_INFO << "please use the '--database.directory' option";
                exit(EXIT_FAILURE);
            }

            ok = TRI_CreateDirectory(pathString.c_str());

            if (! ok) {
                LOGGER_FATAL << "cannot create action directory '" << pathString << "': " << TRI_last_error();
                LOGGER_INFO << "please use the '--database.directory' option";
                exit(EXIT_FAILURE);
            }
        }

        ActionLoader.setDirectory(pathString);

        LOGGER_INFO << "using database action files at '" << pathString << "'";
    }
    else {
        ActionLoader.setDirectory(_actionPath);
        LOGGER_INFO << "using alternate action files at '" << _actionPath << "'";
    }

    if (! _systemActionPath.empty()) {
        SystemActionLoader.setDirectory(_systemActionPath);
        LOGGER_INFO << "using system action files at '" << _systemActionPath << "'";
    }
    else {
        LOGGER_INFO << "system actions are disabled, empty system action path";
    }

    // .............................................................................
    // in shell mode ignore the rest
    // .............................................................................

    if (_applicationServer->programOptions().has("shell")) {
        executeShell();
        exit(EXIT_SUCCESS);
    }

    // .............................................................................
    // sanity checks
    // .............................................................................

    if (_applicationServer->programOptions().has("daemon")) {
        _daemonMode = true;
    }

    if (_applicationServer->programOptions().has("supervisor")) {
        _supervisorMode = true;
    }

    if (_daemonMode) {
        if (_pidFile.empty()) {
            LOGGER_FATAL << "no pid-file defined, but daemon mode requested";
            cerr << "no pid-file defined, but daemon mode requested\n";
            LOGGER_INFO << "please use the '--pid-file' option";
            exit(EXIT_FAILURE);
        }
    }

    if (_databasePath.empty()) {
        LOGGER_FATAL << "no database path has been supplied, giving up";
        cerr << "no database path has been supplied, giving up\n";
        LOGGER_INFO << "please use the '--database.directory' option";
        exit(EXIT_FAILURE);
    }
}