fileserver-and-client.rst 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. .. _internals-fileserver-client:
  2. The Salt Fileserver and Client
  3. ==============================
  4. Introduction
  5. ------------
  6. Salt has a modular fileserver, and multiple client classes which are used to
  7. interact with it. This page serves as a developer's reference, to help explain
  8. how the fileserver and clients both work.
  9. Fileserver
  10. ----------
  11. The fileserver is not a daemon, so the fileserver and client are not a true
  12. server and client in the traditional sense. Instead, the fileserver is simply a
  13. class (``salt.fileserver.Fileserver``), located in
  14. `salt/fileserver/__init__.py`_. This class has access to the configured
  15. fileserver backends via a loader instance, referenced as ``self.servers``. When
  16. a request comes in from the fileclient, it will ultimately result in a
  17. ``Fileserver`` class function being run.
  18. The functions in this class will run corresponding functions in the configured
  19. fileserver backends to perform the requested action. So, in summary:
  20. 1. A fileclient class makes a request...
  21. 2. which triggers the fileserver to run a function...
  22. 3. which runs a named function in each of the configured backends.
  23. Not all of the functions will always execute on every configured backend. For
  24. instance, the ``find_file`` function in the fileserver will stop when it finds
  25. a match, so if it finds a match for the desired path in the first configured
  26. backend, it won't proceed and try to find the file in the next backend in the
  27. list.
  28. Additionally, not all backends implement all functions in the
  29. ``salt.fileserver.Fileserver`` class. For instance, there is a function called
  30. ``update``, which exists to update remote fileservers such as the ``git``,
  31. ``hg``, and ``svn`` backends. This action has no use however in the ``roots``
  32. backend, so it is simply not implemented there, and thus the ``roots`` backend
  33. will be skipped if the ``update`` function is run on the fileserver.
  34. Backends for the fileserver are located in `salt/fileserver/`_ (the files not
  35. named ``__init__.py``).
  36. .. _`salt/fileserver/__init__.py`: https://github.com/saltstack/salt/tree/|repo_primary_branch|/salt/fileserver/__init__.py
  37. .. _`salt/fileserver/`: https://github.com/saltstack/salt/tree/|repo_primary_branch|/salt/fileserver
  38. Fileclient
  39. ----------
  40. There are three fileclient classes:
  41. salt.fileclient.RemoteClient
  42. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  43. This client is used when :conf_minion:`file_client` is set to ``remote``. This
  44. is how minions request files from the master.
  45. Functions in this client will craft a payload and send it to the master via the
  46. transport channel. This is the same way that the minion asks the minion to do
  47. other things, such as updating and requesting data from the mine. The payload
  48. will be a dictionary with a key called ``cmd``, and other values as needed.
  49. Payloads sent via the transport channel are processed my an MWorker instance on
  50. the master, and the MWorker's ``_handle_aes()`` function will execute the
  51. command. The command will be a function attribute of the
  52. ``salt.master.AESFuncs`` class. The AESFuncs class' ``__setup_fileserver()``
  53. function instantiates a ``salt.fileserver.Fileserver`` instance and maps its
  54. member functions to AESFuncs attributes. This is what makes the fileserver
  55. functions available remotely. The result of the function is returned back
  56. through the transport channel to the minion.
  57. Transporting files is done in chunks, the size of which is decided by the
  58. ``file_buffer_size`` config option. If you look at the ``serve_file()``
  59. function in any of the fileserver backends, you can see how the ``loc`` value
  60. in the payload determines the offset so that an intermediate chunk of the file
  61. can be served. The RemoteClient's ``get_file()`` function will loop until the
  62. end of the file is reached, retrieving one chunk at a time.
  63. salt.fileclient.FSClient
  64. ~~~~~~~~~~~~~~~~~~~~~~~~
  65. This client is used when :conf_minion:`file_client` is set to ``local``. This
  66. is how masterless minions request files.
  67. This class inherits from the RemoteClient, but instead of using a transport
  68. channel (zmq, tcp, etc.), it uses a "fake" transport channel
  69. (``salt.fileserver.FSChan``), which implements its own ``send()`` function.
  70. Thus, when a function that the FSClient inherits from the RemoteClient runs
  71. ``self.channel.send()``, it's actually calling
  72. ``salt.fileserver.FSChan.send()``, which calls corresponding functions in the
  73. ``salt.fileserver.Fileserver()`` class. The result is that local file requests
  74. use the same code as remote file requests, they just bypass sending them
  75. through an actual transport channel and instead call them on the FSChan's
  76. Fileserver instance.
  77. salt.fileclient.LocalClient
  78. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  79. This client is now used exclusively by Pillar. This used to be used when
  80. :conf_minion:`file_client` was set to ``local``, but the ``FSChan`` class was
  81. written to allow minions with ``file_client: local`` to access the full set of
  82. backends. This class will probably be renamed at some point as it is often
  83. confused with ``salt.client.LocalClient``.
  84. The :mod:`cp <salt.modules.cp>` Module
  85. --------------------------------------
  86. Most of the user-facing interaction with the fileclient happens via the
  87. :mod:`cp <salt.modules.cp>` module. The functions in this module instantiate a
  88. fileclient instance (if one is not already saved to the ``__context__``
  89. dunder) and run fileclient functions.
  90. Updating the Fileserver
  91. -----------------------
  92. The master daemon spawns a process dedicated to routine maintenance tasks upon
  93. startup. This process runs an instance of ``salt.master.Maintenance``, which
  94. loops forever, running a series of functions and then sleeping for a length of
  95. time determined by the :conf_master:`loop_interval` config option. One of the
  96. maintenance tasks is to update the fileserver, and it essentially runs
  97. ``salt.fileserver.Fileserver.update()``, which as we know from above will run
  98. all configured backends' ``update()`` functions, if present. This is now remote
  99. fileservers like ``git``, ``hg``, and ``svn`` stay up-to-date.
  100. For the local file_client (FSClient), since it does not interact with the
  101. master, upon spawning of its FSChan it will update the fileserver.