| 41 | } |
| 42 | |
| 43 | int FeatureUtility::EnableFeatures(const std::vector<std::string>& features) |
| 44 | { |
| 45 | String features_available_dir = GetFeaturesAvailablePath(); |
| 46 | String features_enabled_dir = GetFeaturesEnabledPath(); |
| 47 | |
| 48 | if (!Utility::PathExists(features_available_dir) ) { |
| 49 | Log(LogCritical, "cli") |
| 50 | << "Cannot parse available features. Path '" << features_available_dir << "' does not exist."; |
| 51 | return 1; |
| 52 | } |
| 53 | |
| 54 | if (!Utility::PathExists(features_enabled_dir) ) { |
| 55 | Log(LogCritical, "cli") |
| 56 | << "Cannot enable features. Path '" << features_enabled_dir << "' does not exist."; |
| 57 | return 1; |
| 58 | } |
| 59 | |
| 60 | std::vector<std::string> errors; |
| 61 | |
| 62 | for (auto& feature : features) { |
| 63 | String source = features_available_dir + "/" + feature + ".conf"; |
| 64 | |
| 65 | if (!Utility::PathExists(source) ) { |
| 66 | Log(LogCritical, "cli") |
| 67 | << "Cannot enable feature '" << feature << "'. Source file '" << source + "' does not exist."; |
| 68 | errors.push_back(feature); |
| 69 | continue; |
| 70 | } |
| 71 | |
| 72 | String target = features_enabled_dir + "/" + feature + ".conf"; |
| 73 | |
| 74 | if (Utility::PathExists(target) ) { |
| 75 | Log(LogWarning, "cli") |
| 76 | << "Feature '" << feature << "' already enabled."; |
| 77 | continue; |
| 78 | } |
| 79 | |
| 80 | std::cout << "Enabling feature " << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << feature |
| 81 | << ConsoleColorTag(Console_Normal) << ". Make sure to restart Icinga 2 for these changes to take effect.\n"; |
| 82 | |
| 83 | #ifndef _WIN32 |
| 84 | String relativeSource = "../features-available/" + feature + ".conf"; |
| 85 | |
| 86 | if (symlink(relativeSource.CStr(), target.CStr()) < 0) { |
| 87 | Log(LogCritical, "cli") |
| 88 | << "Cannot enable feature '" << feature << "'. Linking source '" << relativeSource << "' to target file '" << target |
| 89 | << "' failed with error code " << errno << ", \"" << Utility::FormatErrorNumber(errno) << "\"."; |
| 90 | errors.push_back(feature); |
| 91 | continue; |
| 92 | } |
| 93 | #else /* _WIN32 */ |
| 94 | std::ofstream fp; |
| 95 | fp.open(target.CStr()); |
| 96 | fp << "include \"../features-available/" << feature << ".conf\"" << std::endl; |
| 97 | fp.close(); |
| 98 | |
| 99 | if (fp.fail()) { |
| 100 | Log(LogCritical, "cli") |
nothing calls this directly
no test coverage detected