示例#1
0
svc_action_t *
resources_action_create(const char *name, const char *standard,
                        const char *provider, const char *agent,
                        const char *action, guint interval_ms, int timeout,
                        GHashTable *params, enum svc_action_flags flags)
{
    svc_action_t *op = NULL;
    uint32_t ra_caps = 0;

    /*
     * Do some up front sanity checks before we go off and
     * build the svc_action_t instance.
     */

    if (crm_strlen_zero(name)) {
        crm_err("Cannot create operation without resource name");
        goto return_error;
    }

    if (crm_strlen_zero(standard)) {
        crm_err("Cannot create operation for %s without resource class", name);
        goto return_error;
    }
    ra_caps = pcmk_get_ra_caps(standard);

    if (is_set(ra_caps, pcmk_ra_cap_provider) && crm_strlen_zero(provider)) {
        crm_err("Cannot create operation for %s without provider", name);
        goto return_error;
    }

    if (crm_strlen_zero(agent)) {
        crm_err("Cannot create operation for %s without agent name", name);
        goto return_error;
    }

    if (crm_strlen_zero(action)) {
        crm_err("Cannot create operation for %s without operation name", name);
        goto return_error;
    }

    /*
     * Sanity checks passed, proceed!
     */

    op = calloc(1, sizeof(svc_action_t));
    op->opaque = calloc(1, sizeof(svc_action_private_t));
    op->rsc = strdup(name);
    op->interval_ms = interval_ms;
    op->timeout = timeout;
    op->standard = expand_resource_class(name, standard, agent);
    op->agent = strdup(agent);
    op->sequence = ++operations;
    op->flags = flags;
    op->id = generate_op_key(name, action, interval_ms);

    if (is_set(ra_caps, pcmk_ra_cap_status) && safe_str_eq(action, "monitor")) {
        op->action = strdup("status");
    } else {
        op->action = strdup(action);
    }

    if (is_set(ra_caps, pcmk_ra_cap_provider)) {
        op->provider = strdup(provider);
    }

    if (is_set(ra_caps, pcmk_ra_cap_params)) {
        op->params = params;
        params = NULL; // so we don't free them in this function
    }

    if (strcasecmp(op->standard, PCMK_RESOURCE_CLASS_OCF) == 0) {
        op->opaque->exec = crm_strdup_printf("%s/resource.d/%s/%s",
                                             OCF_ROOT_DIR, provider, agent);
        op->opaque->args[0] = strdup(op->opaque->exec);
        op->opaque->args[1] = strdup(op->action);

    } else if (strcasecmp(op->standard, PCMK_RESOURCE_CLASS_LSB) == 0) {
        op->opaque->exec = services__lsb_agent_path(op->agent);
        op->opaque->args[0] = strdup(op->opaque->exec);
        op->opaque->args[1] = strdup(op->action);

#if SUPPORT_SYSTEMD
    } else if (strcasecmp(op->standard, PCMK_RESOURCE_CLASS_SYSTEMD) == 0) {
        op->opaque->exec = strdup("systemd-dbus");
#endif
#if SUPPORT_UPSTART
    } else if (strcasecmp(op->standard, PCMK_RESOURCE_CLASS_UPSTART) == 0) {
        op->opaque->exec = strdup("upstart-dbus");
#endif
#if SUPPORT_NAGIOS
    } else if (strcasecmp(op->standard, PCMK_RESOURCE_CLASS_NAGIOS) == 0) {
        op->opaque->exec = dup_file_path(op->agent, NAGIOS_PLUGIN_DIR);
        op->opaque->args[0] = strdup(op->opaque->exec);

        if (safe_str_eq(op->action, "monitor") && (op->interval_ms == 0)) {
            /* Invoke --version for a nagios probe */
            op->opaque->args[1] = strdup("--version");

        } else if (op->params) {
            GHashTableIter iter;
            char *key = NULL;
            char *value = NULL;
            int index = 1;
            static int args_size = sizeof(op->opaque->args) / sizeof(char *);

            g_hash_table_iter_init(&iter, op->params);

            while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value) &&
                   index <= args_size - 3) {

                if (safe_str_eq(key, XML_ATTR_CRM_VERSION) || strstr(key, CRM_META "_")) {
                    continue;
                }
                op->opaque->args[index++] = crm_strdup_printf("--%s", key);
                op->opaque->args[index++] = strdup(value);
            }
        }

        // Nagios actions don't need to keep the parameters
        if (op->params != NULL) {
            g_hash_table_destroy(op->params);
            op->params = NULL;
        }
#endif
    } else {
        crm_err("Unknown resource standard: %s", op->standard);
        goto return_error;
    }

    if(params) {
        g_hash_table_destroy(params);
    }
    return op;

  return_error:
    if(params) {
        g_hash_table_destroy(params);
    }
    services_action_free(op);

    return NULL;
}
示例#2
0
svc_action_t *
resources_action_create(const char *name, const char *standard, const char *provider,
                        const char *agent, const char *action, int interval, int timeout,
                        GHashTable * params)
{
    svc_action_t *op = NULL;

    /*
     * Do some up front sanity checks before we go off and
     * build the svc_action_t instance.
     */

    if (crm_strlen_zero(name)) {
        crm_err("A service or resource action must have a name.");
        goto return_error;
    }

    if (crm_strlen_zero(standard)) {
        crm_err("A service action must have a valid standard.");
        goto return_error;
    }

    if (!strcasecmp(standard, "ocf") && crm_strlen_zero(provider)) {
        crm_err("An OCF resource action must have a provider.");
        goto return_error;
    }

    if (crm_strlen_zero(agent)) {
        crm_err("A service or resource action must have an agent.");
        goto return_error;
    }

    if (crm_strlen_zero(action)) {
        crm_err("A service or resource action must specify an action.");
        goto return_error;
    }

    if (safe_str_eq(action, "monitor")
        && (safe_str_eq(standard, "lsb") || safe_str_eq(standard, "service"))) {
        action = "status";
    }

    /*
     * Sanity checks passed, proceed!
     */

    op = calloc(1, sizeof(svc_action_t));
    op->opaque = calloc(1, sizeof(svc_action_private_t));
    op->rsc = strdup(name);
    op->action = strdup(action);
    op->interval = interval;
    op->timeout = timeout;
    op->standard = strdup(standard);
    op->agent = strdup(agent);
    op->sequence = ++operations;
    if (asprintf(&op->id, "%s_%s_%d", name, action, interval) == -1) {
        goto return_error;
    }

    if (strcasecmp(op->standard, "service") == 0) {
        const char *expanded = resources_find_service_class(op->agent);

        if(expanded) {
            crm_debug("Found a %s agent for %s/%s", expanded, op->rsc, op->agent);
            free(op->standard);
            op->standard = strdup(expanded);

        } else {
            crm_info("Cannot determine the standard for %s (%s)", op->rsc, op->agent);
            free(op->standard);
            op->standard = strdup("lsb");
        }
    }

    if (strcasecmp(op->standard, "ocf") == 0) {
        op->provider = strdup(provider);
        op->params = params;
        params = NULL;

        if (asprintf(&op->opaque->exec, "%s/resource.d/%s/%s", OCF_ROOT_DIR, provider, agent) == -1) {
            crm_err("Internal error: cannot create agent path");
            goto return_error;
        }
        op->opaque->args[0] = strdup(op->opaque->exec);
        op->opaque->args[1] = strdup(action);

    } else if (strcasecmp(op->standard, "lsb") == 0) {
        if (op->agent[0] == '/') {
            /* if given an absolute path, use that instead
             * of tacking on the LSB_ROOT_DIR path to the front */
            op->opaque->exec = strdup(op->agent);
        } else if (asprintf(&op->opaque->exec, "%s/%s", LSB_ROOT_DIR, op->agent) == -1) {
            crm_err("Internal error: cannot create agent path");
            goto return_error;
        }
        op->opaque->args[0] = strdup(op->opaque->exec);
        op->opaque->args[1] = strdup(op->action);
        op->opaque->args[2] = NULL;

#if SUPPORT_SYSTEMD
    } else if (strcasecmp(op->standard, "systemd") == 0) {
        op->opaque->exec = strdup("systemd-dbus");
#endif
#if SUPPORT_UPSTART
    } else if (strcasecmp(op->standard, "upstart") == 0) {
        op->opaque->exec = strdup("upstart-dbus");
#endif
    } else if (strcasecmp(op->standard, "service") == 0) {
        op->opaque->exec = strdup(SERVICE_SCRIPT);
        op->opaque->args[0] = strdup(SERVICE_SCRIPT);
        op->opaque->args[1] = strdup(agent);
        op->opaque->args[2] = strdup(action);

#if SUPPORT_NAGIOS
    } else if (strcasecmp(op->standard, "nagios") == 0) {
        int index = 0;

        if (op->agent[0] == '/') {
            /* if given an absolute path, use that instead
             * of tacking on the NAGIOS_PLUGIN_DIR path to the front */
            op->opaque->exec = strdup(op->agent);

        } else if (asprintf(&op->opaque->exec, "%s/%s", NAGIOS_PLUGIN_DIR, op->agent) == -1) {
            crm_err("Internal error: cannot create agent path");
            goto return_error;
        }

        op->opaque->args[0] = strdup(op->opaque->exec);
        index = 1;

        if (safe_str_eq(op->action, "monitor") && op->interval == 0) {
            /* Invoke --version for a nagios probe */
            op->opaque->args[index] = strdup("--version");
            index++;

        } else if (params) {
            GHashTableIter iter;
            char *key = NULL;
            char *value = NULL;
            static int args_size = sizeof(op->opaque->args) / sizeof(char *);

            g_hash_table_iter_init(&iter, params);

            while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value) &&
                   index <= args_size - 3) {
                int len = 3;
                char *long_opt = NULL;

                if (safe_str_eq(key, XML_ATTR_CRM_VERSION) || strstr(key, CRM_META "_")) {
                    continue;
                }

                len += strlen(key);
                long_opt = calloc(1, len);
                sprintf(long_opt, "--%s", key);
                long_opt[len - 1] = 0;

                op->opaque->args[index] = long_opt;
                op->opaque->args[index + 1] = strdup(value);
                index += 2;
            }
        }
        op->opaque->args[index] = NULL;
#endif

    } else {
        crm_err("Unknown resource standard: %s", op->standard);
        services_action_free(op);
        op = NULL;
    }

    if(params) {
        g_hash_table_destroy(params);
    }
    return op;

  return_error:
    if(params) {
        g_hash_table_destroy(params);
    }
    services_action_free(op);

    return NULL;
}
示例#3
0
svc_action_t *resources_action_create(
    const char *name, const char *standard, const char *provider, const char *agent,
    const char *action, int interval, int timeout, GHashTable *params)
{
    svc_action_t *op;

    /*
     * Do some up front sanity checks before we go off and
     * build the svc_action_t instance.
     */

    if (crm_strlen_zero(name)) {
        crm_err("A service or resource action must have a name.");
        return NULL;
    }

    if (crm_strlen_zero(standard)) {
        crm_err("A service action must have a valid standard.");
        return NULL;
    }

    if (!strcasecmp(standard, "ocf") && crm_strlen_zero(provider)) {
        crm_err("An OCF resource action must have a provider.");
        return NULL;
    }

    if (crm_strlen_zero(agent)) {
        crm_err("A service or resource action must have an agent.");
        return NULL;
    }

    if (crm_strlen_zero(action)) {
        crm_err("A service or resource action must specify an action.");
        return NULL;
    }

    if (safe_str_eq(action, "monitor") && (safe_str_eq(standard, "lsb") || safe_str_eq(standard, "service"))) {
        action = "status";
    }

    /*
     * Sanity checks passed, proceed!
     */

    op = calloc(1, sizeof(svc_action_t));
    op->opaque = calloc(1, sizeof(svc_action_private_t));
    op->rsc = strdup(name);
    op->action = strdup(action);
    op->interval = interval;
    op->timeout = timeout;
    op->standard = strdup(standard);
    op->agent = strdup(agent);
    op->sequence = ++operations;
    if (asprintf(&op->id, "%s_%s_%d", name, action, interval) == -1) {
        goto return_error;
    }

    if(strcasecmp(op->standard, "service") == 0) {
        /* Work it out and then fall into the if-else block below.
         * Priority is:
         * - lsb
         * - systemd
         * - upstart
         */
        int rc = 0;
        struct stat st;
        char *path = NULL;

#ifdef LSB_ROOT_DIR
        rc = asprintf(&path, "%s/%s", LSB_ROOT_DIR, op->agent);
        if(rc > 0 && stat(path, &st) == 0) {
            crm_debug("Found an lsb agent for %s/% the", op->rsc, op->agent);
            free(path);
            free(op->standard);
            op->standard = strdup("lsb");
            goto expanded;
        }
        free(path);
#endif

#if SUPPORT_SYSTEMD
        if(systemd_unit_exists(op->agent)) {
            crm_debug("Found a systemd agent for %s/%s", op->rsc, op->agent);
            free(op->standard);
            op->standard = strdup("systemd");
            goto expanded;
        }
#endif

#if SUPPORT_UPSTART
        if(upstart_job_exists(op->agent)) {
            crm_debug("Found an upstart agent for %s/%s", op->rsc, op->agent);
            free(op->standard);
            op->standard = strdup("upstart");
            goto expanded;
        }
#endif

        crm_info("Cannot determine the standard for %s (%s)", op->rsc, op->agent);
    }

expanded:
    if(strcasecmp(op->standard, "ocf") == 0) {
        op->provider = strdup(provider);
        op->params = params;

        if (asprintf(&op->opaque->exec, "%s/resource.d/%s/%s",
                     OCF_ROOT_DIR, provider, agent) == -1) {
            goto return_error;
        }
        op->opaque->args[0] = strdup(op->opaque->exec);
        op->opaque->args[1] = strdup(action);

    } else if(strcasecmp(op->standard, "lsb") == 0) {
        if (op->agent[0] == '/') {
            /* if given an absolute path, use that instead
            * of tacking on the LSB_ROOT_DIR path to the front */
            op->opaque->exec = strdup(op->agent);
        } else if (asprintf(&op->opaque->exec, "%s/%s", LSB_ROOT_DIR, op->agent) == -1) {
            goto return_error;
        }
        op->opaque->args[0] = strdup(op->opaque->exec);
        op->opaque->args[1] = strdup(op->action);
        op->opaque->args[2] = NULL;

#if SUPPORT_SYSTEMD
    } else if(strcasecmp(op->standard, "systemd") == 0) {
        op->opaque->exec = strdup("systemd-dbus");
#endif
#if SUPPORT_UPSTART
    } else if(strcasecmp(op->standard, "upstart") == 0) {
        op->opaque->exec = strdup("upstart-dbus");
#endif
    } else if(strcasecmp(op->standard, "service") == 0) {
        op->opaque->exec = strdup(SERVICE_SCRIPT);
        op->opaque->args[0] = strdup(SERVICE_SCRIPT);
        op->opaque->args[1] = strdup(agent);
        op->opaque->args[2] = strdup(action);

    } else {
        crm_err("Unknown resource standard: %s", op->standard);
        services_action_free(op);
        op = NULL;
    }

    return op;

return_error:
    services_action_free(op);

    return NULL;
}