ADUC_Result SWUpdateHandlerImpl::PrepareCommandArguments()

in src/extensions/step_handlers/swupdate_handler_v2/src/swupdate_handler_v2.cpp [605:871]


ADUC_Result SWUpdateHandlerImpl::PrepareCommandArguments(
    ADUC_WorkflowHandle workflowHandle,
    std::string resultFilePath,
    std::string workFolder,
    std::string& commandFilePath,
    std::vector<std::string>& args)
{
    ADUC_Result result = { ADUC_GeneralResult_Failure };
    bool isComponentsAware = false;
    ADUC_FileEntity* scriptFileEntity = nullptr;

    const char* selectedComponentsJson = nullptr;
    JSON_Value* selectedComponentsValue = nullptr;
    JSON_Object* selectedComponentsObject = nullptr;
    JSON_Array* componentsArray = nullptr;
    size_t componentCount = 0;
    JSON_Object* component = nullptr;

    std::string fileArgs;
    std::vector<std::string> argumentList;
    std::unordered_map<std::string, std::string> swupdateConfigs;

    std::stringstream filePath;
    std::stringstream swuFilePath;
    const char* scriptFileName = nullptr;
    const char* swuFileName = nullptr;

    char* installedCriteria = nullptr;
    const char* arguments = nullptr;

    bool success = false;
    if (workflowHandle == nullptr)
    {
        result.ExtendedResultCode = ADUC_ERC_UPDATE_CONTENT_HANDLER_INSTALL_FAILURE_NULL_WORKFLOW;
        goto done;
    }

    installedCriteria = workflow_get_installed_criteria(workflowHandle);

    // Parse components list. If the list is empty, nothing to download.
    selectedComponentsJson = workflow_peek_selected_components(workflowHandle);

    if (!IsNullOrEmpty(selectedComponentsJson))
    {
        isComponentsAware = true;
        selectedComponentsValue = json_parse_string(selectedComponentsJson);
        if (selectedComponentsValue == nullptr)
        {
            result.ExtendedResultCode = ADUC_ERC_UPDATE_CONTENT_HANDLER_INSTALL_FAILURE_MISSING_PRIMARY_COMPONENT;
            goto done;
        }

        selectedComponentsObject = json_value_get_object(selectedComponentsValue);
        componentsArray = json_object_get_array(selectedComponentsObject, "components");
        if (componentsArray == nullptr)
        {
            result.ExtendedResultCode = ADUC_ERC_UPDATE_CONTENT_HANDLER_INSTALL_FAILURE_MISSING_PRIMARY_COMPONENT;
            goto done;
        }

        // Prepare target component info.
        componentCount = json_array_get_count(componentsArray);

        if (componentCount <= 0)
        {
            result.ResultCode = ADUC_Result_Download_Skipped_NoMatchingComponents;
            goto done;
        }

        if (componentCount > 1)
        {
            Log_Error("Expecting only 1 component, but got %d.", componentCount);
            result.ExtendedResultCode = ADUC_ERC_SWUPDATE_HANDLER_TOO_MANY_COMPONENTS;
        }

        component = json_array_get_object(componentsArray, 0);
        if (component == nullptr)
        {
            result.ExtendedResultCode = ADUC_ERC_SWUPDATE_HANDLER_INVALID_COMPONENTS_DATA;
            goto done;
        }
    }

    // Prepare main script file info.
    scriptFileName =
        workflow_peek_update_manifest_handler_properties_string(workflowHandle, HANDLER_PROPERTIES_SCRIPT_FILENAME);
    if (IsNullOrEmpty(scriptFileName))
    {
        result.ExtendedResultCode = ADUC_ERC_SWUPDATE_HANDLER_MISSING_SCRIPT_FILE_NAME;
        workflow_set_result_details(workflowHandle, "Missing 'handlerProperties.scriptFileName' property");
        goto done;
    }

    filePath << workFolder.c_str() << "/" << scriptFileName;
    commandFilePath = filePath.str();

    // swu file.
    swuFileName =
        workflow_peek_update_manifest_handler_properties_string(workflowHandle, HANDLER_PROPERTIES_SWU_FILENAME);
    if (IsNullOrEmpty(swuFileName))
    {
        result.ExtendedResultCode = ADUC_ERC_SWUPDATE_HANDLER_MISSING_SWU_FILE_NAME;
        workflow_set_result_details(workflowHandle, "Missing 'handlerProperties.swuFileName' property");
        goto done;
    }

    swuFilePath << workFolder.c_str() << "/" << swuFileName;

    args.emplace_back("--swu-file");
    args.emplace_back(swuFilePath.str());

    //
    // Prepare command-line arguments.
    //

    // Read arguments from swupdate_handler_config.json
    result = ReadConfig(ADUC_SWUPDATE_HANDLER_CONF_FILE_PATH, swupdateConfigs);
    if (IsAducResultCodeSuccess(result.ResultCode))
    {
        for (const auto& a : swupdateConfigs)
        {
            args.emplace_back(a.first);
            args.emplace_back(a.second);
        }
    }

    // Add customer specified arguments first.
    arguments = workflow_peek_update_manifest_handler_properties_string(workflowHandle, "arguments");
    if (arguments == nullptr)
    {
        arguments = "";
    }
    fileArgs = arguments;

    Log_Info("Parsing handlerProperties.arguments: %s", arguments);
    argumentList = ADUC::StringUtils::Split(fileArgs, ' ');
    for (size_t i = 0; i < argumentList.size(); i++)
    {
        const std::string argument = argumentList[i];
        if (!argument.empty())
        {
            if (argument == "--component-id-val" || argument == "${du_component_id}")
            {
                const char* val = json_object_get_string(component, "id");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back("n/a");
                }
            }
            else if (argument == "--component-name-val" || argument == "${du_component_name}")
            {
                const char* val = json_object_get_string(component, "name");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back("n/a");
                }
            }
            else if (argument == "--component-manufacturer-val" || argument == "${du_component_manufacturer}")
            {
                const char* val = json_object_get_string(component, "manufacturer");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back("n/a");
                }
            }
            else if (argument == "--component-model-val" || argument == "${du_component_model}")
            {
                const char* val = json_object_get_string(component, "model");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back("n/a");
                }
            }
            else if (argument == "--component-version-val" || argument == "${du_component_version}")
            {
                const char* val = json_object_get_string(component, "version");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back("n/a");
                }
            }
            else if (argument == "--component-group-val" || argument == "${du_component_group}")
            {
                const char* val = json_object_get_string(component, "group");
                if (val != nullptr)
                {
                    args.emplace_back(val);
                }
                else
                {
                    args.emplace_back("n/a");
                }
            }
            else if (argument == "--component-prop-val" || argument == "${du_component_prop}")
            {
                if (i < argumentList.size() - 1)
                {
                    std::string propertyPath = "properties.";
                    propertyPath += argumentList[i + 1];
                    const char* val = json_object_dotget_string(component, propertyPath.c_str());
                    if (val != nullptr)
                    {
                        args.emplace_back(val);
                    }
                    i++;
                }
                else
                {
                    args.emplace_back("n/a");
                }
            }
            else
            {
                args.emplace_back(argument);
            }
        }
    }

    // Default options.

    args.emplace_back("--work-folder");
    args.emplace_back(workFolder);

    args.emplace_back("--result-file");
    args.emplace_back(resultFilePath);

    if (IsNullOrEmpty(installedCriteria))
    {
        Log_Info("--installed-criteria is not specified");
    }
    else
    {
        args.emplace_back("--installed-criteria");
        args.emplace_back(installedCriteria);
    }

    result = { ADUC_Result_Success };

done:
    if (selectedComponentsValue != nullptr)
    {
        json_value_free(selectedComponentsValue);
    }

    workflow_free_string(installedCriteria);
    return result;
}