def is_cached(self, path, saltenv=u'base', cachedir=None): ''' Returns the full path to a file if it is cached locally on the minion otherwise returns a blank string ''' if path.startswith(u'salt://'): path, senv = salt.utils.url.parse(path) if senv: saltenv = senv escaped = True if salt.utils.url.is_escaped(path) else False # also strip escape character '|' localsfilesdest = os.path.join( self.opts[u'cachedir'], u'localfiles', path.lstrip(u'|/')) filesdest = os.path.join( self.opts[u'cachedir'], u'files', saltenv, path.lstrip(u'|/')) extrndest = self._extrn_path(path, saltenv, cachedir=cachedir) if os.path.exists(filesdest): return salt.utils.url.escape(filesdest) if escaped else filesdest elif os.path.exists(localsfilesdest): return salt.utils.url.escape(localsfilesdest) \ if escaped \ else localsfilesdest elif os.path.exists(extrndest): return extrndest return u''
def unescape(url): """ remove escape character `|` from `url` """ scheme = urlparse(url).scheme if not scheme: return url.lstrip("|") elif scheme == "salt": path, saltenv = parse(url) if salt.utils.platform.is_windows() and "|" in url: return create(path.lstrip("_"), saltenv) else: return create(path.lstrip("|"), saltenv) else: return url
def unescape(url): ''' remove escape character `|` from `url` ''' scheme = urlparse(url).scheme if not scheme: return url.lstrip('|') elif scheme == 'salt': path, saltenv = parse(url) if salt.utils.platform.is_windows() and '|' in url: return create(path.lstrip('_'), saltenv) else: return create(path.lstrip('|'), saltenv) else: return url
def cache_local_file(self, path, **kwargs): ''' Cache a local file on the minion in the localfiles cache ''' dest = os.path.join(self.opts[u'cachedir'], u'localfiles', path.lstrip(u'/')) destdir = os.path.dirname(dest) if not os.path.isdir(destdir): os.makedirs(destdir) shutil.copyfile(path, dest) return dest
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, 'tok': auth.gen_token(b'salt') } channel = salt.transport.Channel.factory(__opts__) 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 IOError: 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(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.transport.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