Esempio n. 1
0
    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''
Esempio n. 2
0
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
Esempio n. 3
0
File: url.py Progetto: yy721746/salt
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
Esempio n. 4
0
    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
Esempio n. 5
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,
        '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
Esempio n. 6
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.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