in src/extensions/step_handlers/swupdate_handler_v2/src/swupdate_handler_v2.cpp [137:306]
ADUC_Result SWUpdateHandler_PerformAction(
const std::string& action,
const tagADUC_WorkflowData* workflowData,
bool prepareArgsOnly,
std::string& scriptFilePath,
std::vector<std::string>& args,
std::vector<std::string>& commandLineArgs,
std::string& scriptOutput)
{
Log_Info("Action (%s) begin", action.c_str());
ADUC_Result result = { ADUC_GeneralResult_Failure };
const ADUC_ConfigInfo* config = nullptr;
int exitCode = 0;
commandLineArgs.clear();
if (workflowData == nullptr || workflowData->WorkflowHandle == nullptr)
{
result.ExtendedResultCode = ADUC_ERC_SWUPDATE_HANDLER_INSTALL_ERROR_NULL_WORKFLOW;
return result;
}
const char* apiVer = workflow_peek_update_manifest_handler_properties_string(
workflowData->WorkflowHandle, HANDLER_PROPERTIES_API_VERSION);
char* workFolder = ADUC_WorkflowData_GetWorkFolder(workflowData);
std::string scriptWorkfolder = workFolder;
std::string scriptResultFile = scriptWorkfolder + "/" + "aduc_result.json";
JSON_Value* actionResultValue = nullptr;
std::vector<std::string> aduShellArgs;
config = ADUC_ConfigInfo_GetInstance();
if (config == nullptr)
{
result.ExtendedResultCode = ADUC_ERC_SWUPDATE_HANDLER_PERFORM_ACTION_FAILED_TO_GET_CONFIG_INSTANCE;
goto done;
}
aduShellArgs.emplace_back(adushconst::config_folder_opt);
aduShellArgs.emplace_back(config->configFolder);
aduShellArgs.emplace_back(adushconst::update_type_opt);
aduShellArgs.emplace_back(adushconst::update_type_microsoft_script);
aduShellArgs.emplace_back(adushconst::update_action_opt);
aduShellArgs.emplace_back(adushconst::update_action_execute);
result = SWUpdateHandlerImpl::PrepareCommandArguments(
workflowData->WorkflowHandle, scriptResultFile, scriptWorkfolder, scriptFilePath, args);
if (IsAducResultCodeFailure(result.ResultCode))
{
goto done;
}
// If any install-item reported that the update is already installed on the
// selected component, we will skip the 'apply' phase, and then skip the
// remaining install-item(s).
// Also, don't continue if WorkflowHandle is NULL in the ADUInterface_Connected->HandleStartupWorkflowData flow.
if (result.ResultCode == ADUC_Result_Install_Skipped_UpdateAlreadyInstalled
|| workflowData->WorkflowHandle == nullptr)
{
goto done;
}
aduShellArgs.emplace_back(adushconst::target_data_opt);
aduShellArgs.emplace_back(scriptFilePath);
commandLineArgs.emplace_back(scriptFilePath);
// Prepare arguments based on specified api version.
if (apiVer == nullptr || strcmp(apiVer, "1.0") == 0)
{
std::string backcompatAction = "--action-" + action;
aduShellArgs.emplace_back(adushconst::target_options_opt);
aduShellArgs.emplace_back(backcompatAction.c_str());
commandLineArgs.emplace_back(backcompatAction.c_str());
}
else if (strcmp(apiVer, "1.1") == 0)
{
aduShellArgs.emplace_back(adushconst::target_options_opt);
aduShellArgs.emplace_back(HANDLER_ARG_ACTION);
commandLineArgs.emplace_back(HANDLER_ARG_ACTION);
aduShellArgs.emplace_back(adushconst::target_options_opt);
aduShellArgs.emplace_back(action.c_str());
commandLineArgs.emplace_back(action.c_str());
}
for (const auto& a : args)
{
aduShellArgs.emplace_back(adushconst::target_options_opt);
aduShellArgs.emplace_back(a);
commandLineArgs.emplace_back(a);
}
if (prepareArgsOnly)
{
std::stringstream ss;
for (const auto& a : aduShellArgs)
{
if (a[0] != '-')
{
ss << " \"" << a << "\"";
}
else
{
ss << " " << a;
}
}
scriptOutput = ss.str();
Log_Debug("Prepare Only! adu-shell Command:\n\n %s", scriptOutput.c_str());
result.ResultCode = ADUC_Result_Success;
result.ExtendedResultCode = 0;
goto done;
}
exitCode = ADUC_LaunchChildProcess(config->aduShellFilePath, aduShellArgs, scriptOutput);
if (exitCode != 0)
{
int extendedCode = ADUC_ERC_SWUPDATE_HANDLER_CHILD_FAILURE_PROCESS_EXITCODE(exitCode);
Log_Error("Install failed, extendedResultCode:0x%X (exitCode:%d)", extendedCode, exitCode);
result.ResultCode = ADUC_Result_Failure;
result.ExtendedResultCode = extendedCode;
}
if (!scriptOutput.empty())
{
Log_Info("%s\n", scriptOutput.c_str());
}
// Parse result file.
actionResultValue = json_parse_file(scriptResultFile.c_str());
if (actionResultValue == nullptr)
{
result.ResultCode = ADUC_Result_Failure;
result.ExtendedResultCode = ADUC_ERC_SWUPDATE_HANDLER_INSTALL_FAILURE_PARSE_RESULT_FILE;
workflow_set_result_details(
workflowData->WorkflowHandle,
"The install script doesn't create a result file '%s'.",
scriptResultFile.c_str());
goto done;
}
else
{
JSON_Object* actionResultObject = json_object(actionResultValue);
result.ResultCode = (ADUC_Result_t)json_object_get_number(actionResultObject, "resultCode");
result.ExtendedResultCode = (ADUC_Result_t)json_object_get_number(actionResultObject, "extendedResultCode");
const char* details = json_object_get_string(actionResultObject, "resultDetails");
workflow_set_result_details(workflowData->WorkflowHandle, details);
}
Log_Info(
"Action (%s) done - returning rc:%d, erc:0x%X, rd:%s",
action.c_str(),
result.ResultCode,
result.ExtendedResultCode,
workflow_peek_result_details(workflowData->WorkflowHandle));
done:
ADUC_ConfigInfo_ReleaseInstance(config);
if (IsAducResultCodeFailure(result.ResultCode))
{
workflow_set_result(workflowData->WorkflowHandle, result);
workflow_set_state(workflowData->WorkflowHandle, ADUCITF_State_Failed);
}
json_value_free(actionResultValue);
workflow_free_string(workFolder);
return result;
}