PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/cp.py |
""" Minion side functions for salt-cp """ import base64 import errno import fnmatch import logging import os import urllib.parse import salt.channel.client import salt.crypt import salt.fileclient import salt.minion import salt.utils.data import salt.utils.files import salt.utils.functools import salt.utils.gzip_util import salt.utils.path import salt.utils.templates import salt.utils.url from salt.exceptions import CommandExecutionError from salt.loader.dunder import __file_client__ log = logging.getLogger(__name__) __proxyenabled__ = ["*"] def _auth(): """ Return the auth object """ if "auth" not in __context__: __context__["auth"] = salt.crypt.SAuth(__opts__) return __context__["auth"] def _gather_pillar(pillarenv, pillar_override): """ Whenever a state run starts, gather the pillar data fresh """ pillar = salt.pillar.get_pillar( __opts__, __grains__.value(), __opts__["id"], __opts__["saltenv"], pillar_override=pillar_override, pillarenv=pillarenv, ) ret = pillar.compile_pillar() if pillar_override and isinstance(pillar_override, dict): ret.update(pillar_override) return ret def recv(files, dest): """ Used with salt-cp, pass the files dict, and the destination. This function receives small fast copy files from the master via salt-cp. It does not work via the CLI. CLI Example: .. code-block:: bash salt '*' cp.recv """ ret = {} for path, data in files.items(): if os.path.basename(path) == os.path.basename(dest) and not os.path.isdir(dest): final = dest elif os.path.isdir(dest): final = os.path.join(dest, os.path.basename(path)) elif os.path.isdir(os.path.dirname(dest)): final = dest else: return "Destination unavailable" try: with salt.utils.files.fopen(final, "w+") as fp_: fp_.write(data) ret[final] = True except OSError: ret[final] = False return ret def recv_chunked(dest, chunk, append=False, compressed=True, mode=None): """ This function receives files copied to the minion using ``salt-cp`` and is not intended to be used directly on the CLI. CLI Example: .. code-block:: bash salt '*' cp.recv_chunked """ if "retcode" not in __context__: __context__["retcode"] = 0 def _error(msg): __context__["retcode"] = 1 return msg if chunk is None: # dest is an empty dir and needs to be created try: os.makedirs(dest) except OSError as exc: if exc.errno == errno.EEXIST: if os.path.isfile(dest): return "Path exists and is a file" else: return _error(str(exc)) return True chunk = base64.b64decode(chunk) open_mode = "ab" if append else "wb" try: fh_ = salt.utils.files.fopen(dest, open_mode) # pylint: disable=W8470 except OSError as exc: if exc.errno != errno.ENOENT: # Parent dir does not exist, we need to create it return _error(str(exc)) try: os.makedirs(os.path.dirname(dest)) except OSError as makedirs_exc: # Failed to make directory return _error(str(makedirs_exc)) fh_ = salt.utils.files.fopen(dest, open_mode) # pylint: disable=W8470 try: # Write the chunk to disk fh_.write(salt.utils.gzip_util.uncompress(chunk) if compressed else chunk) except OSError as exc: # Write failed return _error(str(exc)) else: # Write successful if not append and mode is not None: # If this is the first chunk we're writing, set the mode # log.debug('Setting mode for %s to %s', dest, oct(mode)) log.debug("Setting mode for %s to %s", dest, mode) try: os.chmod(dest, mode) except OSError as exc: return _error(str(exc)) return True finally: try: fh_.close() except AttributeError: pass def _client(): """ Return a file client If the __file_client__ context is set return it, otherwize create a new file client using __opts__. """ if __file_client__: return __file_client__.value() return salt.fileclient.get_file_client(__opts__) def _render_filenames(path, dest, saltenv, template, **kw): """ Process markup in the :param:`path` and :param:`dest` variables (NOT the files under the paths they ultimately point to) according to the markup format provided by :param:`template`. """ if not template: return (path, dest) # render the path as a template using path_template_engine as the engine if template not in salt.utils.templates.TEMPLATE_REGISTRY: raise CommandExecutionError( f"Attempted to render file paths with unavailable engine {template}" ) kwargs = {} kwargs["salt"] = __salt__ if "pillarenv" in kw or "pillar" in kw: pillarenv = kw.get("pillarenv", __opts__.get("pillarenv")) kwargs["pillar"] = _gather_pillar(pillarenv, kw.get("pillar")) else: kwargs["pillar"] = __pillar__ kwargs["grains"] = __grains__ kwargs["opts"] = __opts__ kwargs["saltenv"] = saltenv def _render(contents): """ Render :param:`contents` into a literal pathname by writing it to a temp file, rendering that file, and returning the result. """ # write out path to temp file tmp_path_fn = salt.utils.files.mkstemp() with salt.utils.files.fopen(tmp_path_fn, "w+") as fp_: fp_.write(salt.utils.stringutils.to_str(contents)) data = salt.utils.templates.TEMPLATE_REGISTRY[template]( tmp_path_fn, to_str=True, **kwargs ) salt.utils.files.safe_rm(tmp_path_fn) if not data["result"]: # Failed to render the template raise CommandExecutionError( "Failed to render file path with error: {}".format(data["data"]) ) else: return data["data"] path = _render(path) dest = _render(dest) return (path, dest) def get_file( path, dest, saltenv=None, makedirs=False, template=None, gzip=None, **kwargs ): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set .. versionchanged:: 2018.3.0 ``dest`` can now be a directory Used to get a single file from the salt master CLI Example: .. code-block:: bash salt '*' cp.get_file salt://path/to/file /minion/dest Template rendering can be enabled on both the source and destination file names like so: .. code-block:: bash salt '*' cp.get_file "salt://{{grains.os}}/vimrc" /etc/vimrc template=jinja This example would instruct all Salt minions to download the vimrc from a directory with the same name as their os grain and copy it to /etc/vimrc For larger files, the cp.get_file module also supports gzip compression. Because gzip is CPU-intensive, this should only be used in scenarios where the compression ratio is very high (e.g. pretty-printed JSON or YAML files). Use the *gzip* named argument to enable it. Valid values are 1..9, where 1 is the lightest compression and 9 the heaviest. 1 uses the least CPU on the master (and minion), 9 uses the most. There are two ways of defining the fileserver environment (a.k.a. ``saltenv``) from which to retrieve the file. One is to use the ``saltenv`` parameter, and the other is to use a querystring syntax in the ``salt://`` URL. The below two examples are equivalent: .. code-block:: bash salt '*' cp.get_file salt://foo/bar.conf /etc/foo/bar.conf saltenv=config salt '*' cp.get_file salt://foo/bar.conf?saltenv=config /etc/foo/bar.conf .. note:: It may be necessary to quote the URL when using the querystring method, depending on the shell being used to run the command. """ if not saltenv: saltenv = __opts__["saltenv"] or "base" (path, dest) = _render_filenames(path, dest, saltenv, template, **kwargs) path, senv = salt.utils.url.split_env(path) if senv: saltenv = senv if not hash_file(path, saltenv): return "" else: with _client() as client: return client.get_file(path, dest, makedirs, saltenv, gzip) def envs(): """ List available environments for fileserver CLI Example: .. code-block:: bash salt '*' cp.envs """ with _client() as client: return client.envs() def get_template(path, dest, template="jinja", saltenv=None, makedirs=False, **kwargs): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Render a file as a template before setting it down. Warning, order is not the same as in fileclient.cp for non breaking old API. CLI Example: .. code-block:: bash salt '*' cp.get_template salt://path/to/template /minion/dest """ if not saltenv: saltenv = __opts__["saltenv"] or "base" if "salt" not in kwargs: kwargs["salt"] = __salt__ if "pillar" not in kwargs: kwargs["pillar"] = __pillar__ if "grains" not in kwargs: kwargs["grains"] = __grains__ if "opts" not in kwargs: kwargs["opts"] = __opts__ with _client() as client: return client.get_template(path, dest, template, makedirs, saltenv, **kwargs) def get_dir(path, dest, saltenv=None, template=None, gzip=None, **kwargs): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Used to recursively copy a directory from the salt master CLI Example: .. code-block:: bash salt '*' cp.get_dir salt://path/to/dir/ /minion/dest get_dir supports the same template and gzip arguments as get_file. """ if not saltenv: saltenv = __opts__["saltenv"] or "base" (path, dest) = _render_filenames(path, dest, saltenv, template, **kwargs) with _client() as client: return client.get_dir(path, dest, saltenv, gzip) def get_url(path, dest="", saltenv=None, makedirs=False, source_hash=None): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set .. versionchanged:: 2018.3.0 ``dest`` can now be a directory Used to get a single file from a URL. path A URL to download a file from. Supported URL schemes are: ``salt://``, ``http://``, ``https://``, ``ftp://``, ``s3://``, ``swift://`` and ``file://`` (local filesystem). If no scheme was specified, this is equivalent of using ``file://``. If a ``file://`` URL is given, the function just returns absolute path to that file on a local filesystem. The function returns ``False`` if Salt was unable to fetch a file from a ``salt://`` URL. dest The default behaviour is to write the fetched file to the given destination path. If this parameter is omitted or set as empty string (``''``), the function places the remote file on the local filesystem inside the Minion cache directory and returns the path to that file. .. note:: To simply return the file contents instead, set destination to ``None``. This works with ``salt://``, ``http://``, ``https://`` and ``file://`` URLs. The files fetched by ``http://`` and ``https://`` will not be cached. saltenv Salt fileserver environment from which to retrieve the file. Ignored if ``path`` is not a ``salt://`` URL. source_hash If ``path`` is an http(s) or ftp URL and the file exists in the minion's file cache, this option can be passed to keep the minion from re-downloading the file if the cached copy matches the specified hash. .. versionadded:: 2018.3.0 CLI Example: .. code-block:: bash salt '*' cp.get_url salt://my/file /tmp/this_file_is_mine salt '*' cp.get_url http://www.slashdot.org /tmp/index.html """ if not saltenv: saltenv = __opts__["saltenv"] or "base" if isinstance(dest, str): with _client() as client: result = client.get_url( path, dest, makedirs, saltenv, source_hash=source_hash ) else: with _client() as client: result = client.get_url( path, None, makedirs, saltenv, no_cache=True, source_hash=source_hash ) if not result: log.error( "Unable to fetch file %s from saltenv %s.", salt.utils.url.redact_http_basic_auth(path), saltenv, ) if result: return salt.utils.stringutils.to_unicode(result) return result def get_file_str(path, saltenv=None): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Download a file from a URL to the Minion cache directory and return the contents of that file Returns ``False`` if Salt was unable to cache a file from a URL. CLI Example: .. code-block:: bash salt '*' cp.get_file_str salt://my/file """ if not saltenv: saltenv = __opts__["saltenv"] or "base" fn_ = cache_file(path, saltenv) if isinstance(fn_, str): try: with salt.utils.files.fopen(fn_, "r") as fp_: return salt.utils.stringutils.to_unicode(fp_.read()) except OSError: return False return fn_ def cache_file(path, saltenv=None, source_hash=None, verify_ssl=True, use_etag=False): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Used to cache a single file on the Minion Returns the location of the new cached file on the Minion source_hash If ``name`` is an http(s) or ftp URL and the file exists in the minion's file cache, this option can be passed to keep the minion from re-downloading the file if the cached copy matches the specified hash. .. versionadded:: 2018.3.0 verify_ssl If ``False``, remote https file sources (``https://``) and source_hash will not attempt to validate the servers certificate. Default is True. .. versionadded:: 3002 use_etag If ``True``, remote http/https file sources will attempt to use the ETag header to determine if the remote file needs to be downloaded. This provides a lightweight mechanism for promptly refreshing files changed on a web server without requiring a full hash comparison via the ``source_hash`` parameter. .. versionadded:: 3005 CLI Example: .. code-block:: bash salt '*' cp.cache_file salt://path/to/file There are two ways of defining the fileserver environment (a.k.a. ``saltenv``) from which to cache the file. One is to use the ``saltenv`` parameter, and the other is to use a querystring syntax in the ``salt://`` URL. The below two examples are equivalent: .. code-block:: bash salt '*' cp.cache_file salt://foo/bar.conf saltenv=config salt '*' cp.cache_file salt://foo/bar.conf?saltenv=config If the path being cached is a ``salt://`` URI, and the path does not exist, then ``False`` will be returned. .. note:: It may be necessary to quote the URL when using the querystring method, depending on the shell being used to run the command. """ if not saltenv: saltenv = __opts__["saltenv"] or "base" path = salt.utils.data.decode(path) saltenv = salt.utils.data.decode(saltenv) contextkey = "{}_|-{}_|-{}".format("cp.cache_file", path, saltenv) path_is_remote = ( urllib.parse.urlparse(path).scheme in salt.utils.files.REMOTE_PROTOS ) try: if path_is_remote and contextkey in __context__: # Prevent multiple caches in the same salt run. Affects remote URLs # since the master won't know their hash, so the fileclient # wouldn't be able to prevent multiple caches if we try to cache # the remote URL more than once. if os.path.isfile(__context__[contextkey]): return __context__[contextkey] else: # File is in __context__ but no longer exists in the minion # cache, get rid of the context key and re-cache below. # Accounts for corner case where file is removed from minion # cache between cp.cache_file calls in the same salt-run. __context__.pop(contextkey) except AttributeError: pass path, senv = salt.utils.url.split_env(path) if senv: saltenv = senv with _client() as client: result = client.cache_file( path, saltenv, source_hash=source_hash, verify_ssl=verify_ssl, use_etag=use_etag, ) if not result and not use_etag: log.error("Unable to cache file '%s' from saltenv '%s'.", path, saltenv) if path_is_remote: # Cache was successful, store the result in __context__ to prevent # multiple caches (see above). __context__[contextkey] = result return result cache_file_ssh = salt.utils.functools.alias_function(cache_file, "cache_file_ssh") def cache_dest(url, saltenv=None): """ .. versionadded:: 3000 .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Returns the expected cache path for the file, if cached using :py:func:`cp.cache_file <salt.modules.cp.cache_file>`. .. note:: This only returns the _expected_ path, it does not tell you if the URL is really cached. To check if the URL is cached, use :py:func:`cp.is_cached <salt.modules.cp.is_cached>` instead. CLI Examples: .. code-block:: bash salt '*' cp.cache_dest https://foo.com/bar.rpm salt '*' cp.cache_dest salt://my/file salt '*' cp.cache_dest salt://my/file saltenv=dev """ if not saltenv: saltenv = __opts__["saltenv"] or "base" with _client() as client: return client.cache_dest(url, saltenv) def cache_files(paths, saltenv=None): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Used to gather many files from the Master, the gathered files will be saved in the minion cachedir reflective to the paths retrieved from the Master CLI Example: .. code-block:: bash salt '*' cp.cache_files salt://pathto/file1,salt://pathto/file1 There are two ways of defining the fileserver environment (a.k.a. ``saltenv``) from which to cache the files. One is to use the ``saltenv`` parameter, and the other is to use a querystring syntax in the ``salt://`` URL. The below two examples are equivalent: .. code-block:: bash salt '*' cp.cache_files salt://foo/bar.conf,salt://foo/baz.conf saltenv=config salt '*' cp.cache_files salt://foo/bar.conf?saltenv=config,salt://foo/baz.conf?saltenv=config The querystring method is less useful when all files are being cached from the same environment, but is a good way of caching files from multiple different environments in the same command. For example, the below command will cache the first file from the ``config1`` environment, and the second one from the ``config2`` environment. .. code-block:: bash salt '*' cp.cache_files salt://foo/bar.conf?saltenv=config1,salt://foo/bar.conf?saltenv=config2 .. note:: It may be necessary to quote the URL when using the querystring method, depending on the shell being used to run the command. """ if not saltenv: saltenv = __opts__["saltenv"] or "base" with _client() as client: return client.cache_files(paths, saltenv) def cache_dir( path, saltenv=None, include_empty=False, include_pat=None, exclude_pat=None ): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Download and cache everything under a directory from the master include_pat : None Glob or regex to narrow down the files cached from the given path. If matching with a regex, the regex must be prefixed with ``E@``, otherwise the expression will be interpreted as a glob. .. versionadded:: 2014.7.0 exclude_pat : None Glob or regex to exclude certain files from being cached from the given path. If matching with a regex, the regex must be prefixed with ``E@``, otherwise the expression will be interpreted as a glob. .. note:: If used with ``include_pat``, files matching this pattern will be excluded from the subset of files defined by ``include_pat``. .. versionadded:: 2014.7.0 CLI Examples: .. code-block:: bash salt '*' cp.cache_dir salt://path/to/dir salt '*' cp.cache_dir salt://path/to/dir include_pat='E@*.py$' """ if not saltenv: saltenv = __opts__["saltenv"] or "base" with _client() as client: return client.cache_dir(path, saltenv, include_empty, include_pat, exclude_pat) def cache_master(saltenv=None): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Retrieve all of the files on the master and cache them locally CLI Example: .. code-block:: bash salt '*' cp.cache_master """ if not saltenv: saltenv = __opts__["saltenv"] or "base" with _client() as client: return client.cache_master(saltenv) def cache_local_file(path): """ Cache a local file on the minion in the localfiles cache CLI Example: .. code-block:: bash salt '*' cp.cache_local_file /etc/hosts """ if not os.path.exists(path): return "" path_cached = is_cached(path) # If the file has already been cached, return the path if path_cached: path_hash = hash_file(path) path_cached_hash = hash_file(path_cached) if path_hash["hsum"] == path_cached_hash["hsum"]: return path_cached # The file hasn't been cached or has changed; cache it with _client() as client: return client.cache_local_file(path) def list_states(saltenv=None): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set List all of the available state files in an environment CLI Example: .. code-block:: bash salt '*' cp.list_states """ if not saltenv: saltenv = __opts__["saltenv"] or "base" with _client() as client: return client.list_states(saltenv) def list_master(saltenv=None, prefix=""): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set List all of the files stored on the master CLI Example: .. code-block:: bash salt '*' cp.list_master """ if not saltenv: saltenv = __opts__["saltenv"] or "base" with _client() as client: return client.file_list(saltenv, prefix) def list_master_dirs(saltenv=None, prefix=""): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set List all of the directories stored on the master CLI Example: .. code-block:: bash salt '*' cp.list_master_dirs """ if not saltenv: saltenv = __opts__["saltenv"] or "base" with _client() as client: return client.dir_list(saltenv, prefix) def list_master_symlinks(saltenv=None, prefix=""): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set List all of the symlinks stored on the master CLI Example: .. code-block:: bash salt '*' cp.list_master_symlinks """ if not saltenv: saltenv = __opts__["saltenv"] or "base" with _client() as client: return client.symlink_list(saltenv, prefix) def list_minion(saltenv=None): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set List all of the files cached on the minion CLI Example: .. code-block:: bash salt '*' cp.list_minion """ if not saltenv: saltenv = __opts__["saltenv"] or "base" with _client() as client: return client.file_local_list(saltenv) def is_cached(path, saltenv=None): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Returns the full path to a file if it is cached locally on the minion otherwise returns a blank string CLI Example: .. code-block:: bash salt '*' cp.is_cached salt://path/to/file """ if not saltenv: saltenv = __opts__["saltenv"] or "base" path, senv = salt.utils.url.split_env(path) if senv: saltenv = senv with _client() as client: return client.is_cached(path, saltenv) def hash_file(path, saltenv=None): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Return the hash of a file, to get the hash of a file on the salt master file server prepend the path with salt://<file on server> otherwise, prepend the file with / for a local file. CLI Example: .. code-block:: bash salt '*' cp.hash_file salt://path/to/file """ if not saltenv: saltenv = __opts__["saltenv"] or "base" path, senv = salt.utils.url.split_env(path) if senv: saltenv = senv with _client() as client: return client.hash_file(path, saltenv) hash_file_ssh = salt.utils.functools.alias_function(hash_file, "hash_file_ssh") def stat_file(path, saltenv=None, octal=True): """ .. versionchanged:: 3005 ``saltenv`` will use value from config if not explicitly set Return the permissions of a file, to get the permissions of a file on the salt master file server prepend the path with salt://<file on server> otherwise, prepend the file with / for a local file. CLI Example: .. code-block:: bash salt '*' cp.stat_file salt://path/to/file """ if not saltenv: saltenv = __opts__["saltenv"] or "base" path, senv = salt.utils.url.split_env(path) if senv: saltenv = senv with _client() as client: stat = client.hash_and_stat_file(path, saltenv)[1] if stat is None: return stat return salt.utils.files.st_mode_to_octal(stat[0]) if octal is True else stat[0] def push(path, keep_symlinks=False, upload_path=None, remove_source=False): """ WARNING Files pushed to the master will have global read permissions.. Push a file from the minion up to the master, the file will be saved to the salt master in the master's minion files cachedir (defaults to ``/var/cache/salt/master/minions/minion-id/files``) Since this feature allows a minion to push a file up to the master server it is disabled by default for security purposes. To enable, set ``file_recv`` to ``True`` in the master configuration file, and restart the master. keep_symlinks Keep the path value without resolving its canonical form upload_path Provide a different path inside the master's minion files cachedir remove_source Remove the source file on the minion .. versionadded:: 2016.3.0 CLI Example: .. code-block:: bash salt '*' cp.push /etc/fstab salt '*' cp.push /etc/system-release keep_symlinks=True salt '*' cp.push /etc/fstab upload_path='/new/path/fstab' salt '*' cp.push /tmp/filename remove_source=True """ log.debug("Trying to copy '%s' to master", path) if "../" in path or not os.path.isabs(path): log.debug("Path must be absolute, returning False") return False if not keep_symlinks: path = os.path.realpath(path) if not os.path.isfile(path): log.debug("Path failed os.path.isfile check, returning False") return False auth = _auth() if upload_path: if "../" in upload_path: log.debug("Path must be absolute, returning False") log.debug("Bad path: %s", upload_path) return False load_path = upload_path.lstrip(os.sep) else: load_path = path.lstrip(os.sep) # Normalize the path. This does not eliminate # the possibility that relative entries will still be present load_path_normal = os.path.normpath(load_path) # If this is Windows and a drive letter is present, remove it load_path_split_drive = os.path.splitdrive(load_path_normal)[1] # Finally, split the remaining path into a list for delivery to the master load_path_list = [_f for _f in load_path_split_drive.split(os.sep) if _f] load = { "cmd": "_file_recv", "id": __opts__["id"], "path": load_path_list, "size": os.path.getsize(path), "tok": auth.gen_token(b"salt"), } with salt.channel.client.ReqChannel.factory(__opts__) as channel: with salt.utils.files.fopen(path, "rb") as fp_: init_send = False while True: load["loc"] = fp_.tell() load["data"] = fp_.read(__opts__["file_buffer_size"]) if not load["data"] and init_send: if remove_source: try: salt.utils.files.rm_rf(path) log.debug("Removing source file '%s'", path) except OSError: log.error("cp.push failed to remove file '%s'", path) return False return True ret = channel.send(load) if not ret: log.error( "cp.push Failed transfer failed. Ensure master has " "'file_recv' set to 'True' and that the file " "is not larger than the 'file_recv_size_max' " "setting on the master." ) return ret init_send = True def push_dir(path, glob=None, upload_path=None): """ Push a directory from the minion up to the master, the files will be saved to the salt master in the master's minion files cachedir (defaults to ``/var/cache/salt/master/minions/minion-id/files``). It also has a glob for matching specific files using globbing. .. versionadded:: 2014.7.0 Since this feature allows a minion to push files up to the master server it is disabled by default for security purposes. To enable, set ``file_recv`` to ``True`` in the master configuration file, and restart the master. upload_path Provide a different path and directory name inside the master's minion files cachedir CLI Example: .. code-block:: bash salt '*' cp.push /usr/lib/mysql salt '*' cp.push /usr/lib/mysql upload_path='/newmysql/path' salt '*' cp.push_dir /etc/modprobe.d/ glob='*.conf' """ if "../" in path or not os.path.isabs(path): return False tmpupload_path = upload_path path = os.path.realpath(path) if os.path.isfile(path): return push(path, upload_path=upload_path) else: filelist = [] for root, _, files in salt.utils.path.os_walk(path): filelist += [os.path.join(root, tmpfile) for tmpfile in files] if glob is not None: filelist = [ fi for fi in filelist if fnmatch.fnmatch(os.path.basename(fi), glob) ] if not filelist: return False for tmpfile in filelist: if upload_path and tmpfile.startswith(path): tmpupload_path = os.path.join( os.path.sep, upload_path.strip(os.path.sep), tmpfile.replace(path, "").strip(os.path.sep), ) ret = push(tmpfile, upload_path=tmpupload_path) if not ret: return ret return True