MI_Result MI_CALL Pull_GetModules()

in LCM/dsc/engine/ca/CAInfrastructure/WebPullClient.c [2000:2157]


MI_Result MI_CALL Pull_GetModules(_Out_ MI_Uint32 * numModulesInstalled,
                                  const MI_Char *configurationID,
                                  const MI_Char *certificateID,
                                  MI_Char* directoryPath,
                                  MI_Char* fileName,
                                  MI_Char** result,
                                  MI_Uint32* getActionStatusCode,
                                  MI_Boolean bAllowedModuleOverride,
                                  _In_reads_z_(URL_SIZE) const MI_Char *url,
                                  _In_ MI_Uint32 port,
                                  _In_reads_z_(SUBURL_SIZE) const MI_Char *subUrl,
                                  MI_Boolean bIsHttps,
                                  MI_Instance **extendedError)
{
    ModuleTable moduleTable;
    ModuleTableEntry* current;
    MI_Result r;
    MI_Value value;
    int retval = 0;
    char zipPath[MAX_URL_LENGTH];
    char stringBuffer[MAX_URL_LENGTH];
    char * verifyFlag = "1";

    moduleTable.first = NULL;
    r = GetModuleNameVersionTable(fileName, &moduleTable, extendedError);
    if (r != MI_RESULT_OK)
    {
        CleanupModuleTable(moduleTable);
        return r;
    }

    r = MI_Instance_GetElement(g_metaConfig, MSFT_DSCMetaConfiguration_DisableModuleSignatureValidation, &value, NULL, NULL, NULL);

    if (r != MI_RESULT_OK)
    {
#if !defined(BUILD_OMS)
	// default is to not verify
	verifyFlag = "0";
#else
	// default is to verify for oms
	verifyFlag = "1";
#endif
    }
    else
    {
	if (value.boolean == MI_TRUE)
	{
	    verifyFlag = "0";
	}
    }

    // moduleTable now has the modules we need to pull
    current = moduleTable.first;
    while (current != NULL)
    {
        Snprintf(zipPath, MAX_URL_LENGTH, "%s/%s_%s.zip", directoryPath, current->moduleName, current->moduleVersionClassTuple->moduleVersion);
        r = IssueGetModuleRequest(configurationID,
                                  current->moduleName,
                                  current->moduleVersionClassTuple->moduleVersion,
                                  certificateID,
                                  zipPath,
                                  result,
                                  getActionStatusCode,
                                  url,
                                  port,
                                  subUrl,
                                  bIsHttps,
                                  extendedError);

        if (r != MI_RESULT_OK)
        {
            CleanupModuleTable(moduleTable);
            return r;
        }
        // Determine python version
        char data[BUFSIZ];
        int isPython2 = 1;
        DSC_LOG_INFO("Assuming python2 in WebPullClient\n");

	// Look for python2
        FILE * pipe = popen("python2 --version 2>&1", "r");
        fgets(data, BUFSIZ, pipe);
        if (!strstr(data, "not found"))
        {
            DSC_LOG_INFO("Found python2 in WebPullClient.\n");
                isPython2 = 1;
            }
        else
        {
            // If python2 does not exist, look for python3
            memset(&data[0], 0, sizeof(data));
                pipe = popen("python3 --version 2>&1", "r");
                fgets(data, BUFSIZ, pipe);
            if (!strstr(data, "not found")) {
                DSC_LOG_INFO("Found python3 in WebPullClient.\n");
                    isPython2 = 0;
                }
        }

      	if (isPython2 == 1)
      	{
        	DSC_LOG_INFO("Calling InstallModule with python2");
      		Snprintf(stringBuffer, MAX_URL_LENGTH, "%s %s %s", DSC_SCRIPT_PATH "/InstallModule.py", zipPath, verifyFlag);
      	}
      	else
      	{
		DSC_LOG_INFO("Calling InstallModule with python3");
		Snprintf(stringBuffer, MAX_URL_LENGTH, "%s %s %s %s", "/usr/bin/python3 " DSC_SCRIPT_PATH "/python3/InstallModule.py", zipPath, verifyFlag, " 2>&1");
      	}
        DSC_LOG_INFO("executing '%T'\n", stringBuffer);
        retval = system(stringBuffer);
        DSC_LOG_INFO("Executed '%T', returned %d\n", stringBuffer, retval);

        if (retval != 0)
        {
            if (retval == -1 && errno == ECHILD)
            {
                // This is an OK condition.  We weren't able to find the child process to reap after it completes.
            }
            else
            {
                // Attempt to remove the module as a last resort.  If it fails too, a reinstall may be necessary.
                if (isPython2 == 1)
                {
                    DSC_LOG_INFO("Calling RemoveModule with python2");
                    Snprintf(stringBuffer, MAX_URL_LENGTH, "%s %s", DSC_SCRIPT_PATH "/RemoveModule.py", current->moduleName);
                }
                else
                {
                    DSC_LOG_INFO("Calling RemoveModule with python3");
                    Snprintf(stringBuffer, MAX_URL_LENGTH, "%s %s %s", "/usr/bin/python3 " DSC_SCRIPT_PATH "/python3/RemoveModule.py", current->moduleName, " 2>&1");
                }

                retval = system(stringBuffer);
                DSC_LOG_INFO("Executed '%T', returned %d\n", stringBuffer, retval);
                if ( retval == 0 || (retval == -1 && errno == ECHILD) )
                {
                    r = GetCimMIError2Params(MI_RESULT_FAILED, extendedError, ID_PULL_INSTALLMODULEFAILED, current->moduleName, current->moduleVersionClassTuple->moduleVersion);
                }
                else
                {
                    r = GetCimMIError2Params(MI_RESULT_FAILED, extendedError, ID_PULL_INSTALLMODULEANDREMOVEMODULEFAILED, current->moduleName, current->moduleVersionClassTuple->moduleVersion);
                }

                CleanupModuleTable(moduleTable);
                return r;
            }
        }

        *numModulesInstalled = *numModulesInstalled + 1;
        current = current->next;
    }

    CleanupModuleTable(moduleTable);

    return MI_RESULT_OK;

}