1 /* 2 * Copyright (C) 2018 Red Hat, Inc. 3 * 4 * Licensed under the GNU Lesser General Public License Version 2.1 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef LIBDNF_MODULEPACKAGECONTAINER_HPP 22 #define LIBDNF_MODULEPACKAGECONTAINER_HPP 23 24 #include "libdnf/dnf-utils.h" 25 #include "ModulePackage.hpp" 26 #include "libdnf/nsvcap.hpp" 27 28 #include <map> 29 #include <memory> 30 #include <string> 31 #include <vector> 32 #include <set> 33 #include <stdexcept> 34 35 namespace libdnf { 36 37 struct ModulePackageContainer 38 { 39 public: 40 enum class ModuleState { 41 UNKNOWN, 42 ENABLED, 43 DISABLED, 44 DEFAULT, 45 INSTALLED 46 }; 47 48 enum class ModuleErrorType { 49 NO_ERROR = 0, 50 INFO, 51 /// Error in module defaults detected during resolvement of module dependencies 52 ERROR_IN_DEFAULTS, 53 /// Error detected during resolvement of module dependencies 54 ERROR, 55 /// Error detected during resolvement of module dependencies - Unexpected error!!! 56 CANNOT_RESOLVE_MODULES, 57 CANNOT_RESOLVE_MODULE_SPEC, 58 CANNOT_ENABLE_MULTIPLE_STREAMS, 59 CANNOT_MODIFY_MULTIPLE_TIMES_MODULE_STATE, 60 /// Problem with latest modules during resolvement of module dependencies 61 ERROR_IN_LATEST 62 }; 63 64 struct Exception : public std::runtime_error 65 { Exceptionlibdnf::ModulePackageContainer::Exception66 explicit Exception(const std::string &what) : runtime_error(what) {} 67 }; 68 69 struct NoModuleException : public Exception 70 { NoModuleExceptionlibdnf::ModulePackageContainer::NoModuleException71 explicit NoModuleException(const std::string &moduleName) : Exception("No such module: " + moduleName) {} 72 }; 73 74 struct NoStreamException : public Exception 75 { NoStreamExceptionlibdnf::ModulePackageContainer::NoStreamException76 explicit NoStreamException(const std::string &moduleStream) : Exception("No such stream: " + moduleStream) {} 77 }; 78 79 struct EnabledStreamException : public Exception 80 { EnabledStreamExceptionlibdnf::ModulePackageContainer::EnabledStreamException81 explicit EnabledStreamException(const std::string &moduleName) : Exception("No enabled stream for module: " + moduleName) {} 82 }; 83 84 struct EnableMultipleStreamsException : public Exception 85 { 86 explicit EnableMultipleStreamsException(const std::string & moduleName); 87 }; 88 89 struct ConflictException : public Exception 90 { ConflictExceptionlibdnf::ModulePackageContainer::ConflictException91 explicit ConflictException(const std::string &what) : Exception(what) {} 92 }; 93 94 struct ResolveException : public Exception 95 { ResolveExceptionlibdnf::ModulePackageContainer::ResolveException96 explicit ResolveException(const std::string &what) : Exception(what) {} 97 }; 98 99 explicit ModulePackageContainer(bool allArch, std::string installRoot, const char * arch, 100 const char * persistDir = nullptr); 101 ~ModulePackageContainer(); 102 103 void add(const std::string & fileContent, const std::string & repoID); 104 105 /** 106 * @brief Can raise ModulePackageContainer::ConflictException 107 * 108 */ 109 void add(DnfSack * sack); 110 111 /** 112 * @brief Can raise ModulePackageContainer::ConflictException 113 * 114 */ 115 void addDefaultsFromDisk(); 116 void moduleDefaultsResolve(); 117 Id addPlatformPackage(const std::string &osReleasePath, const char * platformModule); 118 Id addPlatformPackage(DnfSack * sack, 119 const std::vector<std::string> & osReleasePath, const char * platformModule); 120 /// DEPRECATED 121 void createConflictsBetweenStreams(); 122 123 /** 124 * @brief Return true if no module package in container 125 * 126 * @return bool 127 */ 128 bool empty() const noexcept; 129 130 /** 131 * @brief Can throw std::out_of_range exception 132 */ 133 ModulePackage * getModulePackage(Id id); 134 std::vector<ModulePackage *> getModulePackages(); 135 std::vector<std::vector<std::vector<ModulePackage *>>> getLatestModulesPerRepo( 136 ModuleState moduleFilter, std::vector<ModulePackage *> modulePackages); 137 138 /** 139 * @brief Return all latest ModulePackages for each module Name, stream, context and architecture. In case of 140 * multiple latest packages, all will be returned. When activeOnly is true, it returns only the latest active 141 * packages. 142 * 143 * @return std::vector<ModulePackage *> 144 */ 145 std::vector<ModulePackage *> getLatestModules(const std::vector<ModulePackage *> modulePackages, bool activeOnly); 146 147 ModulePackage * getLatestModule(std::vector<ModulePackage *> modulePackages, bool activeOnly); 148 149 std::vector<ModulePackage *> requiresModuleEnablement(const libdnf::PackageSet & packages); 150 151 /** 152 * @brief Enable module stream. Return true if requested change realy triggers a change in 153 * the persistor. 154 * When the count parameter is set to false the change will not count towards the limit of 155 * module state modifications. 156 * It can throw ModulePackageContainer::EnableMultipleStreamsException or 157 * ModulePackageContainer::NoModuleException exceprion if module do not exist 158 * 159 * @return bool 160 */ 161 bool enable(const std::string &name, const std::string &stream, const bool count = true); 162 163 /** 164 * @brief Enable module stream. Return true if requested changes realy triggers a change in 165 * the persistor. 166 * When the count parameter is set to false the change will not count towards the limit of 167 * module state modifications. 168 * It can throw ModulePackageContainer::EnableMultipleStreamsException or 169 * ModulePackageContainer::NoModuleException exceprion if module do not exist 170 * 171 * @return bool 172 */ 173 bool enable(const ModulePackage * module, const bool count = true); 174 /** 175 * @brief unmark module 'name' from any streams 176 * When the count parameter is set to false the change will not count towards the limit of 177 * module state modifications. 178 */ 179 void disable(const std::string & name, const bool count = true); 180 void disable(const ModulePackage * module, const bool count = true); 181 /** 182 * @brief Reset module state so it's no longer enabled or disabled. 183 * When the count parameter is set to false the change will not count towards the limit of 184 * module state modifications. 185 */ 186 void reset(const std::string &name, const bool count = true); 187 void reset(const ModulePackage * module, const bool count = true); 188 /** 189 * @brief add profile to name:stream 190 */ 191 void install(const std::string &name, const std::string &stream, const std::string &profile); 192 void install(const ModulePackage * module, const std::string &profile); 193 /** 194 * @brief remove profile from name:stream 195 */ 196 void uninstall(const std::string &name, const std::string &stream, const std::string &profile); 197 void uninstall(const ModulePackage * module, const std::string &profile); 198 /** 199 * @brief commit module changes to storage 200 */ 201 void save(); 202 /** 203 * @brief discard all module changes and revert to storage state 204 */ 205 void rollback(); 206 /** 207 * @brief Are there any changes to be saved? 208 */ 209 bool isChanged(); 210 211 bool isEnabled(const std::string &name, const std::string &stream); 212 bool isEnabled(const ModulePackage * module); 213 214 bool isDisabled(const std::string &name); 215 bool isDisabled(const ModulePackage * module); 216 ModuleState getModuleState(const std::string & name); 217 std::set<std::string> getInstalledPkgNames(); 218 219 std::string getReport(); 220 221 /** 222 * @brief Get configured default profiles for module stream 223 */ 224 std::vector<std::string> getDefaultProfiles(std::string moduleName, std::string moduleStream); 225 226 /** 227 * @brief Get configured default stream for a module 228 */ 229 const std::string & getDefaultStream(const std::string &name) const; 230 231 /** 232 * @brief get enabled stream for a module 233 */ 234 const std::string & getEnabledStream(const std::string &name); 235 236 /** 237 * @brief list of name:stream for module streams that are to be enable 238 */ 239 std::map<std::string, std::string> getEnabledStreams(); 240 241 /** 242 * @brief list of names of modules that are to be disabled 243 */ 244 std::vector<std::string> getDisabledModules(); 245 246 /** 247 * @brief list of name:stream for module streams that are to be disabled 248 * "Will be removed after 2019-12-31. Use getDisabledModules() instead." 249 */ 250 DEPRECATED("Will be removed after 2019-12-31. Use getDisabledModules() instead.") 251 std::map<std::string, std::string> getDisabledStreams(); 252 253 /** 254 * @brief list of names of modules that are to be reset 255 */ 256 std::vector<std::string> getResetModules(); 257 258 /** 259 * @brief list of name:stream for module streams that are to be reset 260 * "Will be removed after 2019-12-31. Use getResetModules() instead." 261 */ 262 DEPRECATED("Will be removed after 2019-12-31. Use getResetModules() instead.") 263 std::map<std::string, std::string> getResetStreams(); 264 /** 265 * @brief list of name:<old_stream:new_stream> for modules whose stream has changed 266 */ 267 std::map<std::string, std::pair<std::string, std::string>> getSwitchedStreams(); 268 /** 269 * @brief list of name:[profiles] for module profiles being added 270 */ 271 std::map<std::string, std::vector<std::string>> getInstalledProfiles(); 272 273 /** 274 * @brief list of installed profiles for module name 275 */ 276 std::vector<std::string> getInstalledProfiles(std::string moduleName); 277 /** 278 * @brief list of name:[profiles] for module profiles being removed 279 */ 280 std::map<std::string, std::vector<std::string>> getRemovedProfiles(); 281 /** 282 * @brief Query modules according libdnf::Nsvcap. But the search ignores profiles 283 * 284 */ 285 std::vector<ModulePackage *> query(libdnf::Nsvcap & moduleNevra); 286 /** 287 * @brief Requiers subject in format <name>, <name>:<stream>, or <name>:<stream>:<contex> 288 * 289 * @param subject p_subject:... 290 * @return std::vector<ModulePackage *> 291 */ 292 std::vector<ModulePackage *> query(std::string subject); 293 std::vector<ModulePackage *> query(std::string name, std::string stream, 294 std::string version, std::string context, std::string arch); 295 void enableDependencyTree(std::vector<ModulePackage *> & modulePackages); 296 std::pair<std::vector<std::vector<std::string>>, ModulePackageContainer::ModuleErrorType> resolveActiveModulePackages(bool debugSolver); 297 bool isModuleActive(Id id); 298 bool isModuleActive(const ModulePackage * modulePackage); 299 void loadFailSafeData(); 300 void updateFailSafeData(); 301 void applyObsoletes(); 302 303 private: 304 class Impl; 305 std::unique_ptr<Impl> pImpl; 306 }; 307 308 } 309 310 #endif //LIBDNF_MODULEPACKAGECONTAINER_HPP 311