static
int
globus_l_staging_replace_stream(
    globus_gram_jobmanager_request_t *  request,
    char *                              parameter,
    char *                              cached_destination)
{
    globus_list_t *                     list;
    globus_rsl_value_t                  *to;
    globus_rsl_value_t                  from_cached;
    globus_bool_t                       single;
    int                                 rc = GLOBUS_SUCCESS;

    list = globus_rsl_param_get_values(
            request->rsl,
            parameter);

    if (list == NULL)
    {
        /* Attempting to replace something that was never in the job
         * RSL---too bad
         */
        return GLOBUS_SUCCESS;
    }
    from_cached.type = GLOBUS_RSL_VALUE_LITERAL;
    from_cached.value.literal.string = cached_destination;

    /* The stdout and stderr attributes can occur in two forms:
     * - stdout = destination [tag]
     * - stdout = (destination [tag])+
     * That is, either as a sequence of 1 or 2 values, or as a sequence of
     * sequences.
     *
     * In either form, if there is only one destination, and it's a local file
     * or x-gass-cache URL, we can safely write directly to that file and don't
     * need it to be staged after the job completes. Otherwise, we'll have to
     * write to the stdout (stderr) file in the job directory and copy it
     * during the STAGE_OUT state.
     */
    if (! globus_rsl_value_is_sequence(globus_list_first(list)))
    {
        rc = globus_l_staging_replace_one_stream(
                request,
                parameter,
                cached_destination,
                list,
                GLOBUS_TRUE);
    }
    else
    {
        single = (globus_list_size(list) == 1);

        while (!globus_list_empty(list))
        {
            globus_list_t                   *sequence_list;

            to = globus_list_first(list);
            list = globus_list_rest(list);

            if (!globus_rsl_value_is_sequence(to))
            {
                /* Bare value instead of a sequence */
                rc = GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDOUT;
                goto bad_value;
            }

            sequence_list = globus_rsl_value_sequence_get_value_list(to);

            rc = globus_l_staging_replace_one_stream(
                    request,
                    parameter,
                    cached_destination,
                    sequence_list,
                    single);

            if (rc != GLOBUS_SUCCESS)
            {
                goto bad_value;
            }

        }
    }

    if (rc != GLOBUS_SUCCESS)
    {
bad_value:
        /* Normalize error types to match the RSL attribute that we are
         * processing
         */
        if (strcmp(parameter, GLOBUS_GRAM_PROTOCOL_STDERR_PARAM) == 0)
        {
            switch (rc)
            {
                case GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDOUT:
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_RSL_STDERR;
                    break;
                case GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDOUT:
                    rc = GLOBUS_GRAM_PROTOCOL_ERROR_OPENING_STDERR;
                    break;
                default:
                    break;
            }
        }
    }
    return rc;
}
int
globus_gram_job_manager_staging_create_list(
    globus_gram_jobmanager_request_t *  request)
{
    int                                 i;
    int                                 rc;
    globus_rsl_value_t *                from;
    globus_rsl_value_t *                to;
    globus_list_t *                     list;
    globus_list_t *                     pairs;
    char *                              can_stage_list[] =
    {
        GLOBUS_GRAM_PROTOCOL_FILE_STAGE_IN_PARAM,
        GLOBUS_GRAM_PROTOCOL_FILE_STAGE_IN_SHARED_PARAM,
        GLOBUS_GRAM_PROTOCOL_FILE_STAGE_OUT_PARAM,
        NULL
    };
    int                                 errors_list[] =
    {
        GLOBUS_GRAM_PROTOCOL_ERROR_RSL_FILE_STAGE_IN,
        GLOBUS_GRAM_PROTOCOL_ERROR_RSL_FILE_STAGE_IN_SHARED,
        GLOBUS_GRAM_PROTOCOL_ERROR_RSL_FILE_STAGE_OUT,
        0
    };

    if(request->jm_restart)
    {
        return GLOBUS_SUCCESS;
    }

    for(i = 0; can_stage_list[i] != NULL; i++)
    {
        list = globus_rsl_param_get_values(request->rsl, can_stage_list[i]);

        if(!list)
        {
            continue;
        }

        while(!globus_list_empty(list))
        {
            pairs = globus_rsl_value_sequence_get_value_list(
                    globus_list_first(list));
            list = globus_list_rest(list);

            if(globus_list_size(pairs) != 2)
            {
                rc = errors_list[i];
                goto failed_adding_exit;
            }

            from = globus_list_first(pairs);
            to = globus_list_first(globus_list_rest(pairs));

            rc = globus_l_gram_job_manager_staging_add_pair(
                    request,
                    from,
                    to,
                    can_stage_list[i]);

            if(rc != GLOBUS_SUCCESS)
            {
                goto failed_adding_exit;
                
            }
        }
    }

    rc = globus_gram_job_manager_streaming_list_replace(request);

failed_adding_exit:
    if (rc != GLOBUS_SUCCESS)
    {
        globus_gram_job_manager_staging_free_all(request);
    }
    return rc;
}
Пример #3
0
static bool
value_to_expr(globus_rsl_value_t * value, classad::ExprTree*& expr)
{
    if (globus_rsl_value_is_literal(value))
    {
        char * literal = globus_rsl_value_literal_get_string(value);
        if (!literal) { return false; }
        classad::Value val;
        try
        {
            val.SetIntegerValue(boost::lexical_cast<long long>(literal));
        }
        catch (const boost::bad_lexical_cast &)
        {
            try
            {
                val.SetRealValue(boost::lexical_cast<double>(literal));
            }
            catch (const boost::bad_lexical_cast &)
            {
                std::string lower = literal;
                boost::algorithm::to_lower(lower);
                if (lower == "true") { val.SetBooleanValue(true); }
                else if (lower == "false") { val.SetBooleanValue(false); }
                else { val.SetStringValue(literal); }
            }
        }
        expr = classad::Literal::MakeLiteral(val);
        if (!expr) { return false; }
        return true;
    }
    else if (globus_rsl_value_is_sequence(value))
    {
        globus_list_t * value_list = globus_rsl_value_sequence_get_value_list(value);
        if (!value_list) { return false; }

        classad::ExprList expr_list;
        while (!globus_list_empty(value_list))
        {
            globus_rsl_value_t *list_item = static_cast<globus_rsl_value_t*>(globus_list_first(value_list));
            value_list = globus_list_rest(value_list);
            if (!list_item) { continue; }

            classad::ExprTree *expr_item = NULL;
            if (!value_to_expr(list_item, expr_item) || !expr_item) { continue; }

            expr_list.push_back(expr_item);
        }
        expr = expr_list.Copy();
        return expr ? true : false;
    }
    else if (globus_rsl_value_is_concatenation(value))
    {
        globus_rsl_value_t *left_value = globus_rsl_value_concatenation_get_left(value);
        globus_rsl_value_t *right_value = globus_rsl_value_concatenation_get_right(value);
        if (!left_value || !right_value) { return false; }

        classad::ExprTree *left_expr = NULL, *right_expr = NULL;
        if (!value_to_expr(left_value, left_expr) || !left_expr || !value_to_expr(right_value, right_expr) || !right_expr) { return false; }
        std::vector<classad::ExprTree*> argList; argList.push_back(left_expr); argList.push_back(right_expr);

        expr = classad::FunctionCall::MakeFunctionCall("strcat", argList);
        return expr ? true : false;
    }
    else if (globus_rsl_value_is_variable(value))
    {
        char * char_variable_name = globus_rsl_value_variable_get_name(value);
        char * default_value = globus_rsl_value_variable_get_default(value);
        if (!char_variable_name) { return false; }

        // Canonical forms of Globus RSL strip out all underscores and makes the string
        // lowercase.  As ClassAds are case-preserving (and underscores are significant),
        // we just do the former transform.
        std::string variable_name(char_variable_name);
        boost::algorithm::replace_all(variable_name, "_", "");

        if (default_value)
        {
            // ifThenElse(isUndefined(variable_name), default_value, variable_name)
            std::vector<classad::ExprTree*> ifArgList;

            classad::ExprTree *attr1 = classad::AttributeReference::MakeAttributeReference(NULL, variable_name);
            if (!attr1) { return false; }
            std::vector<classad::ExprTree*> argList; argList.push_back(attr1);
            classad::ExprTree *isUndefined = classad::FunctionCall::MakeFunctionCall("isUndefined", argList);
            ifArgList.push_back(isUndefined);

            classad::Value val; val.SetStringValue(default_value);
            classad::ExprTree *lit = classad::Literal::MakeLiteral(val);
            if (!lit) { return false; }
            ifArgList.push_back(lit);

            classad::ExprTree *attr2 = classad::AttributeReference::MakeAttributeReference(NULL, variable_name);
            if (!attr2) { return false; }
            ifArgList.push_back(attr2);

            expr = classad::FunctionCall::MakeFunctionCall("ifThenElse", ifArgList);
        }
        else
        {
            expr = classad::AttributeReference::MakeAttributeReference(NULL, variable_name);
        }
        return expr ? true : false;
    }
    return false;
}