Ejemplo n.º 1
0
bud_error_t bud_config_reload(bud_config_t* config) {
  bud_error_t err;
  bud_config_t* loaded;
  bud_config_t restore;

  loaded = bud_config_load(config->path, config->inlined, &err);
  if (!bud_is_ok(err))
    return err;

  memset(&restore, 0, sizeof(restore));
  bud_config_copy(&restore, config);
  bud_config_copy(config, loaded);

  /* Initialize config with new params */
  err = bud_config_init(config);

  /* Restore everything on failure */
  if (!bud_is_ok(err)) {
    bud_config_copy(config, &restore);
    bud_config_free(loaded);
    return err;
  }

  free(loaded);
  bud_config_destroy(&restore);
  return bud_ok();
}
Ejemplo n.º 2
0
Archivo: config.c Proyecto: indutny/bud
bud_error_t bud_config_load(bud_config_t* config) {
  int i;
  bud_error_t err;
  JSON_Value* json;
  JSON_Value* val;
  JSON_Object* frontend;
  JSON_Object* obj;
  JSON_Object* log;
  JSON_Object* avail;
  JSON_Array* contexts;

  if (config->piped) {
    char* content;

    ASSERT(config->loop != NULL, "Loop should be present");
    err = bud_read_file_by_fd(config->loop, 0, &content);
    if (!bud_is_ok(err))
      goto end;

    err = bud_hashmap_insert(&config->files.hashmap,
                             kPipedConfigPath,
                             strlen(kPipedConfigPath),
                             content);
    if (!bud_is_ok(err)) {
      free(content);
      goto end;
    }

    json = json_parse_string(content);
  } else if (config->inlined) {
    json = json_parse_string(config->path);
  } else {
    const char* contents;

    err = bud_config_load_file(config, config->path, &contents);
    if (!bud_is_ok(err))
      goto end;
    json = json_parse_string(contents);
  }

  if (json == NULL) {
    err = bud_error_dstr(kBudErrJSONParse, config->path);
    goto end;
  }

  obj = json_value_get_object(json);
  if (obj == NULL) {
    err = bud_error(kBudErrJSONNonObjectRoot);
    goto failed_alloc_path;
  }

  err = bud_config_load_tracing(&config->trace,
                                json_object_get_object(obj, "tracing"));
  if (!bud_is_ok(err))
    goto failed_alloc_path;

  /* Allocate contexts and backends */
  contexts = json_object_get_array(obj, "contexts");
  config->context_count = contexts == NULL ? 0 : json_array_get_count(contexts);
  config->contexts = calloc(config->context_count + 1,
                            sizeof(*config->contexts));
  if (config->contexts == NULL) {
    err = bud_error_str(kBudErrNoMem, "bud_context_t");
    goto failed_alloc_contexts;
  }

  config->json = json;

  /* Workers configuration */
  config->worker_count = -1;
  config->restart_timeout = -1;
  config->master_ipc = -1;
  val = json_object_get_value(obj, "workers");
  if (val != NULL)
    config->worker_count = json_value_get_number(val);
  val = json_object_get_value(obj, "restart_timeout");
  if (val != NULL)
    config->restart_timeout = json_value_get_number(val);
  val = json_object_get_value(obj, "master_ipc");
  if (val != NULL)
    config->master_ipc = json_value_get_boolean(val);

  /* Logger configuration */
  log = json_object_get_object(obj, "log");
  config->log.stdio = -1;
  config->log.syslog = -1;
  if (log != NULL) {
    config->log.level = json_object_get_string(log, "level");
    config->log.facility = json_object_get_string(log, "facility");

    val = json_object_get_value(log, "stdio");
    if (val != NULL)
      config->log.stdio = json_value_get_boolean(val);
    val = json_object_get_value(log, "syslog");
    if (val != NULL)
      config->log.syslog = json_value_get_boolean(val);
  }

  /* Availability configuration */
  avail = json_object_get_object(obj, "availability");
  config->availability.death_timeout = -1;
  config->availability.revive_interval = -1;
  config->availability.retry_interval = -1;
  config->availability.max_retries = -1;
  if (avail != NULL) {
    val = json_object_get_value(avail, "death_timeout");
    if (val != NULL)
      config->availability.death_timeout = json_value_get_number(val);
    val = json_object_get_value(avail, "revive_interval");
    if (val != NULL)
      config->availability.revive_interval = json_value_get_number(val);
    val = json_object_get_value(avail, "retry_interval");
    if (val != NULL)
      config->availability.retry_interval = json_value_get_number(val);
    val = json_object_get_value(avail, "max_retries");
    if (val != NULL)
      config->availability.max_retries = json_value_get_number(val);
  }

  /* Frontend configuration */
  frontend = json_object_get_object(obj, "frontend");
  err = bud_config_load_frontend(frontend, &config->frontend);
  if (!bud_is_ok(err))
    goto failed_alloc_contexts;

  /* Load frontend's context */
  err = bud_context_load(frontend, &config->contexts[0]);
  if (!bud_is_ok(err))
    goto failed_alloc_contexts;

  /* Backend configuration */
  config->balance = json_object_get_string(obj, "balance");
  err = bud_config_load_backend_list(config,
                                      obj,
                                      &config->contexts[0].backend);
  if (!bud_is_ok(err))
    goto failed_alloc_contexts;

  /* User and group configuration */
  config->user = json_object_get_string(obj, "user");
  config->group = json_object_get_string(obj, "group");

  /* SNI configuration */
  bud_config_read_pool_conf(obj, "sni", &config->sni);

  /* OCSP Stapling configuration */
  bud_config_read_pool_conf(obj, "stapling", &config->stapling);

  /* SSL Contexts */

  /* TODO(indutny): sort them and do binary search */
  for (i = 0; i < config->context_count; i++) {
    bud_context_t* ctx;

    /* NOTE: contexts[0] - is a default context */
    ctx = &config->contexts[i + 1];
    obj = json_array_get_object(contexts, i);
    if (obj == NULL) {
      err = bud_error(kBudErrJSONNonObjectCtx);
      goto failed_load_context;
    }

    err = bud_context_load(obj, ctx);
    if (!bud_is_ok(err))
      goto failed_load_context;

    err = bud_config_load_backend_list(config, obj, &ctx->backend);
    if (!bud_is_ok(err))
      goto failed_load_context;
  }

  bud_config_set_defaults(config);

  return bud_config_init(config);

failed_load_context:
  /* Deinitalize contexts */
  for (i++; i >= 0; i--) {
    bud_context_t* ctx;

    ctx = &config->contexts[i];
    free(ctx->backend.list);
    ctx->backend.list = NULL;
  }

failed_alloc_contexts:
  free(config->contexts);
  config->contexts = NULL;
  free(config->trace.dso);
  config->trace.dso = NULL;

failed_alloc_path:
  json_value_free(json);
  config->json = NULL;

end:
  return err;
}
Ejemplo n.º 3
0
bud_config_t* bud_config_cli_load(uv_loop_t* loop,
                                  int argc,
                                  char** argv,
                                  bud_error_t* err) {
  int c;
  int r;
  int index;
  int is_daemon;
  int is_worker;
  size_t path_len;
  bud_config_t* config;

  struct option long_options[] = {
    { "version", 0, NULL, 'v' },
    { "config", 1, NULL, 'c' },
#ifndef _WIN32
    { "daemonize", 0, NULL, 'd' },
#endif  /* !_WIN32 */
    { "worker", 0, NULL, 1000 },
    { "default-config", 0, NULL, 1001 },
    { NULL, 0, NULL, 0 }
  };

  *err = bud_ok();
  config = NULL;
  is_daemon = 0;
  is_worker = 0;
  do {
    index = 0;
    c = getopt_long(argc, argv, "vc:d", long_options, &index);
    switch (c) {
      case 'v':
        bud_print_version();
        break;
      case 'c':
        config = bud_config_load(loop,optarg, err);
        if (config == NULL) {
          ASSERT(!bud_is_ok(*err), "Config load failed without error");
          c = -1;
          break;
        }
        if (is_daemon)
          config->is_daemon = 1;
        if (is_worker)
          config->is_worker = 1;
        break;
#ifndef _WIN32
      case 'd':
        is_daemon = 1;
        if (config != NULL)
          config->is_daemon = 1;
#endif  /* !_WIN32 */
        break;
      case 1000:
        is_worker = 1;
        if (config != NULL)
          config->is_worker = 1;
        break;
      case 1001:
        bud_config_print_default();
        c = -1;
        break;
      default:
        if (config == NULL)
          bud_print_help(argc, argv);
        c = -1;
        break;
    }
  } while (c != -1);

  if (config != NULL) {
    /* CLI options */
    config->argc = argc;
    config->argv = argv;

    /* Get executable path */
    path_len = sizeof(config->exepath);
    r = uv_exepath(config->exepath, &path_len);
    ASSERT(path_len < sizeof(config->exepath), "Exepath OOB");

    config->exepath[path_len] = 0;
    if (r != 0) {
      bud_config_free(config);
      config = NULL;
      *err = bud_error_num(kBudErrExePath, r);
    }

    /* Initialize config */
    *err = bud_config_init(config);
    if (!bud_is_ok(*err)) {
      bud_config_free(config);
      return NULL;
    }
  }

  return config;
}