11 #include "CompatibilityUtils.hpp"
50 char* COMMIT_HASH =
fo_sysconfig(AGENT_NAME,
"COMMIT_HASH");
54 if (!asprintf(&agentRevision,
"%s.%s", VERSION, COMMIT_HASH))
58 agentRevision, AGENT_DESC);
79 PGconn* connection =
dbManager.getConnection();
82 return fo_WriteARS(connection, arsId, uploadId, agentId, AGENT_ARS, NULL,
107 vector<unsigned long> fileIds =
115 #pragma omp parallel default(none) \
116 shared(databaseHandler, fileIds, agentIds, state, errors, stdout, \
120 databaseHandler.
spawn());
122 size_t pFileCount = fileIds.size();
125 for (
size_t it = 0; it < pFileCount; ++it)
130 unsigned long pFileId = fileIds[it];
135 vector<unsigned long> licId =
137 if (!mainLicenses.empty())
139 set<unsigned long> licSet;
140 licSet.insert(licId.begin(), licId.end());
141 licSet.insert(mainLicenses.begin(), mainLicenses.end());
144 licId.insert(licId.end(), licSet.begin(), licSet.end());
147 if (licId.size() < 2)
157 threadLocalDatabaseHandler);
160 catch (std::runtime_error& e)
162 LOG_FATAL(
"Unable to read %s.", e.what());
169 LOG_FATAL(
"Unable to store results in database for pfile %ld.",
192 std::string& types, std::string& rules,
string& jFile,
195 boost::program_options::options_description desc(AGENT_NAME
196 ": recognized options");
198 (
"help,h",
"shows help")
199 (
"verbose,v",
"increase verbosity")
200 (
"file,f", boost::program_options::value<string>(),
201 "json file, containing fileNames and licenses within that fileNames")
202 (
"json,J",
"output as JSON")
203 (
"main_license", boost::program_options::value<string>(),
204 "name of main license to check licenses in files against")
205 (
"config,c", boost::program_options::value<string>(),
206 "path to the sysconfigdir")
208 "specifies, that the agent was called by the scheduler")
209 (
"userID", boost::program_options::value<int>(),
210 "the id of the user that created the job (only in combination with "
211 "--scheduler_start)")
212 (
"groupID", boost::program_options::value<int>(),
213 "the id of the group of the user that created the job (only in "
214 "combination with --scheduler_start)")
215 (
"jobId", boost::program_options::value<int>(),
216 "the id of the job (only in combination with --scheduler_start)")
217 (
"types,t", boost::program_options::value<string>(),
218 "license types for compatibility rules")
219 (
"rules,r", boost::program_options::value<string>(),
220 "license compatibility rules");
222 boost::program_options::positional_options_description p;
223 boost::program_options::variables_map vm;
227 boost::program_options::store(
228 boost::program_options::command_line_parser(argc, argv)
234 if (vm.count(
"help") > 0)
236 cout << desc <<
'\n';
240 if (vm.count(
"rules"))
242 rules = vm[
"rules"].as<std::string>();
245 if (vm.count(
"types"))
247 types = vm[
"types"].as<std::string>();
250 if (vm.count(
"file"))
252 jFile = vm[
"file"].as<std::string>();
255 if (vm.count(
"main_license"))
257 mainLicense = vm[
"main_license"].as<std::string>();
260 int verbosity = (int) vm.count(
"verbose");
261 bool json = vm.count(
"json") > 0;
267 catch (boost::bad_any_cast&)
269 cout <<
"wrong parameter type\n";
270 cout << desc <<
'\n';
273 catch (boost::program_options::error&)
275 cout <<
"wrong command line arguments\n";
276 cout << desc <<
'\n';
289 void appendToJson(
const std::vector<tuple<string, string, bool>>& resultPair,
290 const std::string& fileName,
bool& printComma)
293 #if JSONCPP_VERSION_HEXA < ((1 << 24) | (4 << 16))
295 Json::FastWriter jsonBuilder;
299 Json::StreamWriterBuilder jsonBuilder;
300 jsonBuilder[
"commentStyle"] =
"None";
301 jsonBuilder[
"indentation"] =
"";
304 Json::Value licenses;
305 Json::Value res(Json::arrayValue);
306 for (
const auto& i : resultPair)
308 Json::Value
license(Json::arrayValue);
315 final[
"compatibility"] = comp;
319 if (fileName !=
"null")
321 result[
"file"] = fileName;
322 result[
"results"] = res;
326 result[
"package-level-result"] = res;
330 #pragma omp critical(jsonPrinter)
341 #if JSONCPP_VERSION_HEXA < ((1 << 24) | (4 << 16))
344 jsonString = jsonBuilder.write(result);
345 jsonString.replace(jsonString.find(
"\n"),
string(
"\n").length(),
"");
348 jsonString = Json::writeString(jsonBuilder, result);
350 cout <<
" " << jsonString;
361 const std::vector<tuple<string, string, bool>>& resultPair,
362 const std::string& fileName)
365 if (fileName !=
"null")
367 cout <<
"----" << fileName <<
"----\n";
368 for (
const auto& i : resultPair)
370 string result = get<2>(i) ?
"true" :
"false";
371 cout << get<0>(i) <<
"," << get<1>(i) <<
"::" << result <<
'\n';
376 cout <<
"----all licenses with their compatibility----\n";
377 for (
const auto& i : resultPair)
379 string result = get<2>(i) ?
"true" :
"false";
380 cout << get<0>(i) <<
"," << get<1>(i) <<
"::" << result <<
'\n';
392 std::set<std::string> licenses;
393 std::string delimiter =
" AND ";
394 std::string
s = mainLicense;
397 while ((pos =
s.find(delimiter)) != std::string::npos) {
398 licenses.insert(
s.substr(0, pos));
399 s.erase(0, pos + delimiter.length());
401 if (licenses.empty() && !
s.empty()) {
402 licenses.insert(mainLicense);
404 else if (!
s.empty())
407 licenses.insert(
s.substr(0,
s.length()));
422 const string& first_type,
const string& second_name,
423 const string& second_type,
424 const map<tuple<string, string, string, string>,
bool>& rule_list)
427 rule_list.find(make_tuple(first_name,
"", second_name,
""));
428 if (result_check == rule_list.end())
430 result_check = rule_list.find(make_tuple(second_name,
"", first_name,
""));
432 if (result_check != rule_list.end())
434 return result_check->second;
436 result_check = rule_list.find(make_tuple(
"", first_type,
"", second_type));
437 if (result_check == rule_list.end())
439 result_check = rule_list.find(make_tuple(
"", second_type,
"", first_type));
441 if (result_check != rule_list.end())
443 return result_check->second;
445 result_check = rule_list.find(make_tuple(first_name,
"",
"", second_type));
446 if (result_check == rule_list.end())
448 result_check = rule_list.find(make_tuple(second_name,
"",
"", first_type));
450 if (result_check == rule_list.end())
452 result_check = rule_list.find(make_tuple(
"", first_type, second_name,
""));
454 if (result_check == rule_list.end())
456 result_check = rule_list.find(make_tuple(
"", second_type, first_name,
""));
458 if (result_check != rule_list.end())
460 return result_check->second;
462 auto default_value = rule_list.find(make_tuple(
"~",
"~",
"~",
"~"));
463 if (default_value == rule_list.end())
469 return default_value->second;
484 stringstream lineStream(header);
487 while(getline(lineStream, cell,
','))
489 string::size_type
start = cell.find_first_not_of(
' ');
490 string::size_type end = cell.find_last_not_of(
' ');
494 if (cell ==
"shortname")
498 else if (cell ==
"licensetype")
508 else if (type_col == -1)
522 const string& file_location)
524 std::ifstream ip(file_location);
525 string line, name, type;
526 unordered_map<string, string> license_type_map;
527 int name_column = -1, type_column = -1;
532 throw invalid_argument(
"missing header `shortname` and/or `licensetype` "
535 while (getline(ip, line))
537 stringstream ss(line);
540 while (getline(ss, cell,
','))
542 if (i == name_column)
546 if (i == type_column)
552 license_type_map[name] = type;
554 return license_type_map;
568 const string& file_location)
570 YAML::Node root = YAML::LoadFile(file_location);
571 map<tuple<string, string, string, string>,
bool> rule_map;
573 for (
const auto& yml_rule : root[
"rules"])
575 string first_type, second_type, first_name, second_name;
577 for (
const auto&
tag : yml_rule)
579 string first =
tag.first.as<
string>();
580 if (first ==
"comment")
585 if (
tag.second.IsNull())
591 second =
tag.second.as<
string>();
593 if (first ==
"compatibility")
595 ans = second ==
"true";
597 else if (first ==
"firsttype" && (second !=
"~"))
601 else if (first ==
"secondtype" && (second !=
"~"))
603 second_type = second;
605 else if (first ==
"firstname" && (second !=
"~"))
609 else if (first ==
"secondname" && (second !=
"~"))
611 second_name = second;
614 rule_map[make_tuple(first_name, first_type, second_name, second_type)] = ans;
616 rule_map[make_tuple(
"~",
"~",
"~",
"~")] =
617 root[
"default"].as<
string>() ==
"true";
map< tuple< string, string, string, string >, bool > initialize_rule_list(const string &file_location)
Read YAML file of rules and parse it as map.
int get_column_ids(const string &header, int &name_col, int &type_col)
Get the column index for shortname and licensetype columns from CSV header.
unordered_map< string, string > initialize_license_map(const string &file_location)
Parse license type CSV and create a map.
bool processUploadId(const CompatibilityState &state, int uploadId, CompatibilityDatabaseHandler &databaseHandler, int groupId)
bool parseCliOptions(int argc, char **argv, CompatibilityCliOptions &dest, std::string &types, std::string &rules, string &jFile, string &mainLicense)
Parse the options sent by CLI to CliOptions object.
void printResultToStdout(const std::vector< tuple< string, string, bool >> &resultPair, const std::string &fileName)
CompatibilityState getState(DbManager &dbManager, CompatibilityCliOptions &&cliOptions)
Create a new state for the current agent based on CliOptions.
int writeARS(const CompatibilityState &state, int arsId, int uploadId, int success, DbManager &dbManager)
int queryAgentId(DbManager &dbManager)
std::set< std::string > mainLicenseToSet(const string &mainLicense)
void appendToJson(const std::vector< tuple< string, string, bool >> &resultPair, const std::string &fileName, bool &printComma)
bool are_licenses_compatible(const string &first_name, const string &first_type, const string &second_name, const string &second_type, const map< tuple< string, string, string, string >, bool > &rule_list)
Check the licenses against rules and get the compatibility result.
bool checkCompatibilityForPfile(vector< unsigned long > &licId, unsigned long &pFileId, CompatibilityDatabaseHandler &databaseHandler) const
find the compatibility between the licenses using scheduler mode
Store the options sent through the CLI.
std::vector< unsigned long > queryScannerIdsForUpload(int uploadId)
Get the agent id of latest scanners run on the upload.
std::vector< unsigned long > queryMainLicenseForUpload(int uploadId, int groupId)
Get the main licenses for the upload.
std::vector< unsigned long > queryLicIdsFromPfile(unsigned long pFileId, vector< unsigned long > agentIds)
to get the license id from the file id
std::vector< unsigned long > queryFileIdsForScan(int uploadId, int agentId)
CompatibilityDatabaseHandler spawn() const
Store the state of the agent.
const CompatibilityAgent & getCompatibilityAgent() const
int s
The socket that the CLI will use to communicate.
FUNCTION int fo_WriteARS(PGconn *pgConn, int ars_pk, int upload_pk, int agent_pk, const char *tableName, const char *ars_status, int ars_success)
Write ars record.
FUNCTION int fo_GetAgentKey(PGconn *pgConn, const char *agent_name, long Upload_pk, const char *rev, const char *agent_desc)
Get the latest enabled agent key (agent_pk) from the database.
void fo_scheduler_disconnect(int retcode)
Disconnect the scheduler connection.
void fo_scheduler_heart(int i)
This function must be called by agents to let the scheduler know they are alive and how many items th...
char * fo_sysconfig(const char *sectionname, const char *variablename)
gets a system configuration variable from the configuration data.
fo_dbManager * dbManager
fo_dbManager object
fo namespace holds the FOSSology library functions.
start($application)
start the application Assumes application is restartable via /etc/init.d/<script>....