package_providers.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. =================
  2. Package Providers
  3. =================
  4. This page contains guidelines for writing package providers.
  5. Package Functions
  6. -----------------
  7. One of the most important features of Salt is package management. There is no
  8. shortage of package managers, so in the interest of providing a consistent
  9. experience in :mod:`pkg <salt.states.pkg>` states, there are certain functions
  10. that should be present in a package provider. Note that these are subject to
  11. change as new features are added or existing features are enhanced.
  12. list_pkgs
  13. ^^^^^^^^^
  14. This function should declare an empty dict, and then add packages to it by
  15. calling :mod:`pkg_resource.add_pkg <salt.modules.pkg_resource.add_pkg>`, like
  16. so:
  17. .. code-block:: python
  18. __salt__["pkg_resource.add_pkg"](ret, name, version)
  19. The last thing that should be done before returning is to execute
  20. :mod:`pkg_resource.sort_pkglist <salt.modules.pkg_resource.sort_pkglist>`. This
  21. function does not presently do anything to the return dict, but will be used in
  22. future versions of Salt.
  23. .. code-block:: python
  24. __salt__["pkg_resource.sort_pkglist"](ret)
  25. ``list_pkgs`` returns a dictionary of installed packages, with the keys being
  26. the package names and the values being the version installed. Example return
  27. data:
  28. .. code-block:: python
  29. {"foo": "1.2.3-4", "bar": "5.6.7-8"}
  30. latest_version
  31. ^^^^^^^^^^^^^^
  32. Accepts an arbitrary number of arguments. Each argument is a package name. The
  33. return value for a package will be an empty string if the package is not found
  34. or if the package is up-to-date. The only case in which a non-empty string is
  35. returned is if the package is available for new installation (i.e. not already
  36. installed) or if there is an upgrade available.
  37. If only one argument was passed, this function return a string, otherwise a
  38. dict of name/version pairs is returned.
  39. This function must also accept ``**kwargs``, in order to receive the
  40. ``fromrepo`` and ``repo`` keyword arguments from pkg states. Where supported,
  41. these arguments should be used to find the install/upgrade candidate in the
  42. specified repository. The ``fromrepo`` kwarg takes precedence over ``repo``, so
  43. if both of those kwargs are present, the repository specified in ``fromrepo``
  44. should be used. However, if ``repo`` is used instead of ``fromrepo``, it should
  45. still work, to preserve backwards compatibility with older versions of Salt.
  46. version
  47. ^^^^^^^
  48. Like ``latest_version``, accepts an arbitrary number of arguments and
  49. returns a string if a single package name was passed, or a dict of name/value
  50. pairs if more than one was passed. The only difference is that the return
  51. values are the currently-installed versions of whatever packages are passed. If
  52. the package is not installed, an empty string is returned for that package.
  53. upgrade_available
  54. ^^^^^^^^^^^^^^^^^
  55. Deprecated and destined to be removed. For now, should just do the following:
  56. .. code-block:: python
  57. def myfunc():
  58. return __salt__["pkg.latest_version"](name) != ""
  59. install
  60. ^^^^^^^
  61. The following arguments are required and should default to ``None``:
  62. #. name (for single-package pkg states)
  63. #. pkgs (for multiple-package pkg states)
  64. #. sources (for binary package file installation)
  65. The first thing that this function should do is call
  66. :mod:`pkg_resource.parse_targets <salt.modules.pkg_resource.parse_targets>`
  67. (see below). This function will convert the SLS input into a more easily parsed
  68. data structure.
  69. :mod:`pkg_resource.parse_targets <salt.modules.pkg_resource.parse_targets>` may
  70. need to be modified to support your new package provider, as it does things
  71. like parsing package metadata which cannot be done for every package management
  72. system.
  73. .. code-block:: python
  74. pkg_params, pkg_type = __salt__["pkg_resource.parse_targets"](name, pkgs, sources)
  75. Two values will be returned to the :strong:`install` function. The first of
  76. them will be a dictionary. The keys of this dictionary will be package names,
  77. though the values will differ depending on what kind of installation is being
  78. done:
  79. * If :strong:`name` was provided (and :strong:`pkgs` was not), then there will
  80. be a single key in the dictionary, and its value will be ``None``. Once the
  81. data has been returned, if the :strong:`version` keyword argument was
  82. provided, then it should replace the ``None`` value in the dictionary.
  83. * If :strong:`pkgs` was provided, then :strong:`name` is ignored, and the
  84. dictionary will contain one entry for each package in the :strong:`pkgs`
  85. list. The values in the dictionary will be ``None`` if a version was not
  86. specified for the package, and the desired version if specified. See the
  87. :strong:`Multiple Package Installation Options` section of the
  88. :mod:`pkg.installed <salt.states.pkg.installed>` state for more info.
  89. * If :strong:`sources` was provided, then :strong:`name` is ignored, and the
  90. dictionary values will be the path/URI for the package.
  91. The second return value will be a string with two possible values:
  92. ``repository`` or ``file``. The :strong:`install` function can use this value
  93. (if necessary) to build the proper command to install the targeted package(s).
  94. Both before and after the installing the target(s), you should run
  95. :strong:`list_pkgs` to obtain a list of the installed packages. You should then
  96. return the output of ``salt.utils.data.compare_dicts()``:
  97. .. code-block:: python
  98. def myfunc():
  99. return salt.utils.data.compare_dicts(old, new)
  100. remove
  101. ^^^^^^
  102. Removes the passed package and return a list of the packages removed.
  103. Package Repo Functions
  104. ----------------------
  105. There are some functions provided by ``pkg`` which are specific to package
  106. repositories, and not to packages themselves. When writing modules for new
  107. package managers, these functions should be made available as stated below, in
  108. order to provide compatibility with the ``pkgrepo`` state.
  109. All repo functions should accept a basedir option, which defines which
  110. directory repository configuration should be found in. The default for this
  111. is dictated by the repo manager that is being used, and rarely needs to be
  112. changed.
  113. .. code-block:: python
  114. basedir = "/etc/yum.repos.d"
  115. __salt__["pkg.list_repos"](basedir)
  116. list_repos
  117. ^^^^^^^^^^
  118. Lists the repositories that are currently configured on this system.
  119. .. code-block:: python
  120. __salt__["pkg.list_repos"]()
  121. Returns a dictionary, in the following format:
  122. .. code-block:: pycon
  123. {'reponame': 'config_key_1': 'config value 1',
  124. 'config_key_2': 'config value 2',
  125. 'config_key_3': ['list item 1 (when appropriate)',
  126. 'list item 2 (when appropriate)]}
  127. get_repo
  128. ^^^^^^^^
  129. Displays all local configuration for a specific repository.
  130. .. code-block:: python
  131. __salt__["pkg.get_repo"](repo="myrepo")
  132. The information is formatted in much the same way as list_repos, but is
  133. specific to only one repo.
  134. .. code-block:: pycon
  135. {'config_key_1': 'config value 1',
  136. 'config_key_2': 'config value 2',
  137. 'config_key_3': ['list item 1 (when appropriate)',
  138. 'list item 2 (when appropriate)]}
  139. del_repo
  140. ^^^^^^^^
  141. Removes the local configuration for a specific repository. Requires a `repo`
  142. argument, which must match the locally configured name. This function returns
  143. a string, which informs the user as to whether or not the operation was a
  144. success.
  145. .. code-block:: python
  146. __salt__["pkg.del_repo"](repo="myrepo")
  147. mod_repo
  148. ^^^^^^^^
  149. Modify the local configuration for one or more option for a configured repo.
  150. This is also the way to create new repository configuration on the local
  151. system; if a repo is specified which does not yet exist, it will be created.
  152. The options specified for this function are specific to the system; please
  153. refer to the documentation for your specific repo manager for specifics.
  154. .. code-block:: python
  155. __salt__["pkg.mod_repo"](repo="myrepo", url="http://myurl.com/repo")
  156. Low-Package Functions
  157. ---------------------
  158. In general, the standard package functions as describes above will meet your
  159. needs. These functions use the system's native repo manager (for instance,
  160. yum or the apt tools). In most cases, the repo manager is actually separate
  161. from the package manager. For instance, yum is usually a front-end for rpm, and
  162. apt is usually a front-end for dpkg. When possible, the package functions that
  163. use those package managers directly should do so through the low package
  164. functions.
  165. It is normal and sane for ``pkg`` to make calls to ``lowpkgs``, but ``lowpkg``
  166. must never make calls to ``pkg``. This is affects functions which are required
  167. by both ``pkg`` and ``lowpkg``, but the technique in ``pkg`` is more performant
  168. than what is available to ``lowpkg``. When this is the case, the ``lowpkg``
  169. function that requires that technique must still use the ``lowpkg`` version.
  170. list_pkgs
  171. ^^^^^^^^^
  172. Returns a dict of packages installed, including the package name and version.
  173. Can accept a list of packages; if none are specified, then all installed
  174. packages will be listed.
  175. .. code-block:: python
  176. installed = __salt__["lowpkg.list_pkgs"]("foo", "bar")
  177. Example output:
  178. .. code-block:: python
  179. {"foo": "1.2.3-4", "bar": "5.6.7-8"}
  180. verify
  181. ^^^^^^
  182. Many (but not all) package management systems provide a way to verify that the
  183. files installed by the package manager have or have not changed. This function
  184. accepts a list of packages; if none are specified, all packages will be
  185. included.
  186. .. code-block:: python
  187. installed = __salt__["lowpkg.verify"]("httpd")
  188. Example output:
  189. .. code-block:: python
  190. {
  191. "/etc/httpd/conf/httpd.conf": {
  192. "mismatch": ["size", "md5sum", "mtime"],
  193. "type": "config",
  194. }
  195. }
  196. file_list
  197. ^^^^^^^^^
  198. Lists all of the files installed by all packages specified. If not packages are
  199. specified, then all files for all known packages are returned.
  200. .. code-block:: python
  201. installed = __salt__["lowpkg.file_list"]("httpd", "apache")
  202. This function does not return which files belong to which packages; all files
  203. are returned as one giant list (hence the `file_list` function name. However,
  204. This information is still returned inside of a dict, so that it can provide
  205. any errors to the user in a sane manner.
  206. .. code-block:: python
  207. {
  208. "errors": ["package apache is not installed"],
  209. "files": ["/etc/httpd", "/etc/httpd/conf", "/etc/httpd/conf.d", "...SNIP..."],
  210. }
  211. file_dict
  212. ^^^^^^^^^
  213. Lists all of the files installed by all packages specified. If not packages are
  214. specified, then all files for all known packages are returned.
  215. .. code-block:: python
  216. installed = __salt__["lowpkg.file_dict"]("httpd", "apache", "kernel")
  217. Unlike `file_list`, this function will break down which files belong to which
  218. packages. It will also return errors in the same manner as `file_list`.
  219. .. code-block:: python
  220. {
  221. "errors": ["package apache is not installed"],
  222. "packages": {
  223. "httpd": ["/etc/httpd", "/etc/httpd/conf", "...SNIP..."],
  224. "kernel": [
  225. "/boot/.vmlinuz-2.6.32-279.el6.x86_64.hmac",
  226. "/boot/System.map-2.6.32-279.el6.x86_64",
  227. "...SNIP...",
  228. ],
  229. },
  230. }