in src/extensions/step_handlers/apt_handler/src/apt_handler.cpp [139:295]
ADUC_Result AptHandlerImpl::Download(const ADUC_WorkflowData* workflowData)
{
ADUC_Result result = { .ResultCode = ADUC_Result_Failure, .ExtendedResultCode = 0 };
std::stringstream aptManifestFilename;
std::unique_ptr<AptContent> aptContent{ nullptr };
ADUC_WorkflowHandle handle = workflowData->WorkflowHandle;
const ADUC_ConfigInfo* config = nullptr;
size_t fileCount = 0;
char* installedCriteria = nullptr;
if (workflow_is_cancel_requested(handle))
{
return this->Cancel(workflowData);
}
// For 'microsoft/apt:1', we're expecting 1 payload file.
fileCount = workflow_get_update_files_count(handle);
if (fileCount != 1)
{
Log_Error("APT packages expecting one file. (%d)", fileCount);
return ADUC_Result{ .ResultCode = ADUC_Result_Failure,
.ExtendedResultCode = ADUC_ERC_APT_HANDLER_PACKAGE_PREPARE_FAILURE_WRONG_FILECOUNT };
}
char* workFolder = workflow_get_workfolder(handle);
ADUC_FileEntity fileEntity;
memset(&fileEntity, 0, sizeof(fileEntity));
if (!workflow_get_update_file(handle, 0, &fileEntity))
{
result = { .ResultCode = ADUC_Result_Failure,
.ExtendedResultCode = ADUC_ERC_APT_HANDLER_GET_FILEENTITY_FAILURE };
goto done;
}
installedCriteria = workflow_get_installed_criteria(handle);
if (IsNullOrEmpty(installedCriteria))
{
workflow_set_result_details(handle, "Property 'installedCriteria' in handlerProperties is missing or empty.");
result = { .ResultCode = ADUC_Result_Failure,
.ExtendedResultCode = ADUC_ERC_APT_HANDLER_MISSING_INSTALLED_CRITERIA };
goto done;
}
// Let's get the config instance before downloading the APT manifest file
// because this is less expensive.
config = ADUC_ConfigInfo_GetInstance();
if (config == NULL)
{
Log_Error("Failed to get config instance.");
result = { ADUC_Result_Failure, ADUC_ERC_APT_HANDLER_DOWNLOAD_FAILED_TO_GET_CONFIG_INSTANCE };
goto done;
}
aptManifestFilename << workFolder << "/" << fileEntity.TargetFilename;
// Download the APT manifest file.
result = ExtensionManager::Download(
&fileEntity, workflowData->WorkflowHandle, &Default_ExtensionManager_Download_Options, nullptr);
if (IsAducResultCodeFailure(result.ResultCode))
{
goto done;
}
result = ParseContent(aptManifestFilename.str(), aptContent);
if (IsAducResultCodeFailure(result.ResultCode))
{
goto done;
}
{
std::string aptOutput;
int aptExitCode = -1;
// Perform apt-get update to fetch latest packages catalog.
// We'll log warning if failed, but will try to download specified packages.
try
{
// Perform apt-get update.
const std::vector<std::string> args = {
adushconst::config_folder_opt, config->configFolder,
adushconst::update_type_opt, adushconst::update_type_microsoft_apt,
adushconst::update_action_opt, adushconst::update_action_initialize
};
aptExitCode = ADUC_LaunchChildProcess(config->aduShellFilePath, args, aptOutput);
if (!aptOutput.empty())
{
Log_Info(aptOutput.c_str());
}
}
catch (const std::exception& de)
{
Log_Error("Exception occurred while processing apt-get update.\n%s", de.what());
aptExitCode = -1;
}
if (aptExitCode != 0)
{
Log_Error("APT update failed. (Exit code: %d)", aptExitCode);
}
// Download packages.
result = { ADUC_Result_Download_Success };
try
{
std::vector<std::string> args = { adushconst::config_folder_opt, config->configFolder,
adushconst::update_type_opt, adushconst::update_type_microsoft_apt,
adushconst::update_action_opt, adushconst::update_action_download };
// For microsoft/apt, target-data is a list of packages.
std::stringstream data;
data << "'";
for (const std::string& package : aptContent->Packages)
{
data << package << " ";
}
data << "'";
args.emplace_back(adushconst::target_data_opt);
args.emplace_back(data.str());
aptExitCode = ADUC_LaunchChildProcess(config->aduShellFilePath, args, aptOutput);
if (!aptOutput.empty())
{
Log_Info("\n\nadu-shell logs\n================\n\n%s", aptOutput.c_str());
}
}
catch (const std::exception& de)
{
Log_Error("Exception occurred during download. %s", de.what());
aptExitCode = -1;
}
if (aptExitCode != 0)
{
result.ResultCode = ADUC_Result_Failure;
result.ExtendedResultCode = ADUC_ERC_APT_HANDLER_PACKAGE_DOWNLOAD_FAILURE;
Log_Error("APT packages download failed. (Exit code: %d)", aptExitCode);
goto done;
}
}
result = { .ResultCode = ADUC_Result_Download_Success, .ExtendedResultCode = 0 };
done:
ADUC_ConfigInfo_ReleaseInstance(config);
workflow_free_string(installedCriteria);
workflow_free_string(workFolder);
ADUC_FileEntity_Uninit(&fileEntity);
return result;
}