.. versionadded:: 2014.1.0

    Create a hard link to a file

    CLI Example:

    .. code-block:: bash

        salt '*' file.link /path/to/file /path/to/link
548982
def link(src, path):
    '''
    
    '''
    src = os.path.expanduser(src)

    if not os.path.isabs(src):
        raise SaltInvocationError('File path must be absolute.')

    try:
        os.link(src, path)
        return True
    except (OSError, IOError):
        raise CommandExecutionError('Could not create \'{0}\''.format(path))
    return False
144729
def symlink(target, linkname):
    
    target = os.path.abspath(target)
    linkname = os.path.abspath(linkname)
    if not os.path.exists(target):
        raise ValueError("target {} not found".format(target))

    link_dir = os.path.dirname(linkname)
    if not os.path.exists(link_dir):
        os.makedirs(link_dir)

    run(['ln', '-s', '-f', target, linkname])
    return linkname
1078738
def tail(path, lines):
    '''
    
    '''
    path = os.path.expanduser(path)
    lines_found = []
    buffer_size = 4098

    if not os.path.isfile(path):
        raise SaltInvocationError('File not found: {0}'.format(path))

    if not __utils__['files.is_text'](path):
        raise SaltInvocationError(
            'Cannot tail a binary file: {0}'.format(path))

    try:
        lines = int(lines)
    except ValueError:
        raise SaltInvocationError('file.tail: \'lines\' value must be an integer')

    try:
        with salt.utils.fopen(path) as tail_fh:
            blk_cnt = 1
            size = os.stat(path).st_size

            if size > buffer_size:
                tail_fh.seek(-buffer_size * blk_cnt, os.SEEK_END)
            data = string.split(tail_fh.read(buffer_size), os.linesep)

            for i in range(lines):
                while len(data) == 1 and ((blk_cnt * buffer_size) < size):
                    blk_cnt += 1
                    line = data[0]
                    try:
                        tail_fh.seek(-buffer_size * blk_cnt, os.SEEK_END)
                        data = string.split(tail_fh.read(buffer_size) + line, os.linesep)
                    except IOError:
                        tail_fh.seek(0)
                        data = string.split(tail_fh.read(size - (buffer_size * (blk_cnt - 1))) + line, os.linesep)

                line = data[-1]
                data.pop()
                lines_found.append(line)

        return lines_found[-lines:]
    except (OSError, IOError):
        raise CommandExecutionError('Could not tail \'{0}\''.format(path))
275937
def make_links(current_cn):
    '''
        
    '''
    if not os.path.isfile(CURRENT_CERTIFICATE_PATH):
        target = '{}/{}.crt'.format(CERTIFICATES_PATH, current_cn)
        print 'Create symlink {} -> {}'.format(CURRENT_CERTIFICATE_PATH,
                                               target)
        os.symlink(target, CURRENT_CERTIFICATE_PATH)

    if not os.path.isfile(CURRENT_PRIVATE_KEY_PATH):
        target = '{}/{}.key'.format(CERTIFICATES_PATH, current_cn)
        print 'Create symlink {} -> {}'.format(CURRENT_PRIVATE_KEY_PATH,
                                               target)
        os.symlink(target, CURRENT_PRIVATE_KEY_PATH)
326910
def _link_bam_file(in_file, new_dir, data):
    
    new_dir = utils.safe_makedir(new_dir)
    out_file = os.path.join(new_dir, os.path.basename(in_file))
    if not utils.file_exists(out_file):
        out_file = os.path.join(new_dir, "%s-prealign.bam" % dd.get_sample_name(data))
    if data.get("cwl_keys"):
        # Has indexes, we're okay to go with the original file
        if utils.file_exists(in_file + ".bai"):
            out_file = in_file
        else:
            utils.copy_plus(in_file, out_file)
    else:
        utils.symlink_plus(in_file, out_file)
    return out_file
978882
def persist(name, value, config='/etc/sysctl.conf'):
    '''
    
    '''
    nlines = []
    edited = False
    value = six.text_type(value)

    # create /etc/sysctl.conf if not present
    if not os.path.isfile(config):
        try:
            with salt.utils.files.fopen(config, 'w+'):
                pass
        except (IOError, OSError):
            msg = 'Could not create {0}'
            raise CommandExecutionError(msg.format(config))

    with salt.utils.files.fopen(config, 'r') as ifile:
        for line in ifile:
            line = salt.utils.stringutils.to_unicode(line)
            m = re.match(r'{0}(\??=)'.format(name), line)
            if not m:
                nlines.append(line)
                continue
            else:
                key, rest = line.split('=', 1)
                if rest.startswith('"'):
                    _, rest_v, rest = rest.split('"', 2)
                elif rest.startswith('\''):
                    _, rest_v, rest = rest.split('\'', 2)
                else:
                    rest_v = rest.split()[0]
                    rest = rest[len(rest_v):]
                if rest_v == value:
                    return 'Already set'
                new_line = '{0}{1}{2}{3}'.format(name, m.group(1), value, rest)
                nlines.append(new_line)
                edited = True

    if not edited:
        newline = '{0}={1}'.format(name, value)
        nlines.append("{0}\n".format(newline))

    with salt.utils.files.fopen(config, 'wb') as ofile:
        ofile.writelines(
            salt.utils.data.encode(nlines)
        )

    assign(name, value)

    return 'Updated'
994423
def create_hardlink(self, dest_path: str):
        '''  '''

        # self
        dirinfo = DirectoryInfo(dest_path)
        dirinfo.ensure_created()

        # child
        for item in self.list_items():
            item.create_hardlink(os.path.join(dest_path, item.path.name))
1344901
def link(source_path):
    """"""
    if not os.path.isfile(source_path):
        raise SourceNotFound(source_path)
    with open(source_path, 'r') as f:
        content = f.read()
    block_map = BlockMap()  # The map will be populated with the following function call.
    all_block = convert_lines_to_block(
            content.splitlines(), block_map, LinkStack(source_path), source_path)
    return all_block, block_map.get_variables()
273881
def _rm_dr_link(self, rec):
        # type: (dr.DirectoryRecord) -> int
        '''
        
        '''
        if not rec.is_file():
            raise pycdlibexception.PyCdlibInvalidInput('Cannot remove a directory with rm_hard_link (try rm_directory instead)')

        num_bytes_to_remove = 0

        logical_block_size = rec.vd.logical_block_size()

        done = False
        while not done:
            num_bytes_to_remove += self._remove_child_from_dr(rec,
                                                              rec.index_in_parent,
                                                              logical_block_size)

            if rec.inode is not None:
                found_index = None
                for index, link in enumerate(rec.inode.linked_records):
                    if id(link) == id(rec):
                        found_index = index
                        break
                else:
                    # This should never happen
                    raise pycdlibexception.PyCdlibInternalError('Could not find inode corresponding to record')

                del rec.inode.linked_records[found_index]

                # We only remove the size of the child from the ISO if there are no
                # other references to this file on the ISO.
                if not rec.inode.linked_records:
                    found_index = None
                    for index, ino in enumerate(self.inodes):
                        if id(ino) == id(rec.inode):
                            found_index = index
                            break
                    else:
                        # This should never happen
                        raise pycdlibexception.PyCdlibInternalError('Could not find inode corresponding to record')
                    del self.inodes[found_index]

                    num_bytes_to_remove += rec.get_data_length()

            if rec.data_continuation is not None:
                rec = rec.data_continuation
            else:
                done = True

        return num_bytes_to_remove
1088749
function resolveLinks(currentFile, resolveFile, $) {
    var currentDirectory = path.dirname(currentFile);

    return editHTMLElement($, 'a', function($a) {
        var href = $a.attr('href');

        // Don't change a tag without href
        if (!href) {
            return;
        }

        if (LocationUtils.isExternal(href)) {
            $a.attr('target', '_blank');
            return;
        }

        // Split anchor
        var parsed = url.parse(href);
        href = parsed.pathname || '';

        if (href) {
            // Calcul absolute path for this
            href = LocationUtils.toAbsolute(href, currentDirectory, '.');

            // Resolve file
            href = resolveFile(href);

            // Convert back to relative
            href = LocationUtils.relative(currentDirectory, href);
        }

        // Add back anchor
        href = href + (parsed.hash || '');

        $a.attr('href', href);
    });
}
898781
def link(**kwargs):
  '''  '''
  
  if kwargs['yes']:
    output, err = cli_syncthing_adapter.link(**kwargs)
    click.echo("%s" % output, err=err)
  else:
    if click.confirm("Are you sure you want to link %s?" % kwargs['path']):
      output, err = cli_syncthing_adapter.link(**kwargs)
      click.echo("%s" % output, err=err)
348101
def file_hash(load, fnd):
    '''
    
    '''
    if 'env' in load:
        # "env" is not supported; Use "saltenv".
        load.pop('env')

    if not all(x in load for x in ('path', 'saltenv')):
        return ''
    saltenv = load['saltenv']
    if saltenv == 'base':
        saltenv = 'trunk'
    ret = {}
    relpath = fnd['rel']
    path = fnd['path']

    # If the file doesn't exist, we can't get a hash
    if not path or not os.path.isfile(path):
        return ret

    # Set the hash_type as it is determined by config
    ret['hash_type'] = __opts__['hash_type']

    # Check if the hash is cached
    # Cache file's contents should be "hash:mtime"
    cache_path = os.path.join(__opts__['cachedir'],
                              'svnfs',
                              'hash',
                              saltenv,
                              '{0}.hash.{1}'.format(relpath,
                                                    __opts__['hash_type']))
    # If we have a cache, serve that if the mtime hasn't changed
    if os.path.exists(cache_path):
        with salt.utils.files.fopen(cache_path, 'rb') as fp_:
            hsum, mtime = fp_.read().split(':')
            if os.path.getmtime(path) == mtime:
                # check if mtime changed
                ret['hsum'] = hsum
                return ret

    # if we don't have a cache entry-- lets make one
    ret['hsum'] = salt.utils.hashutils.get_hash(path, __opts__['hash_type'])
    cache_dir = os.path.dirname(cache_path)
    # make cache directory if it doesn't exist
    if not os.path.exists(cache_dir):
        os.makedirs(cache_dir)
    # save the cache object "hash:mtime"
    with salt.utils.files.fopen(cache_path, 'w') as fp_:
        fp_.write('{0}:{1}'.format(ret['hsum'], os.path.getmtime(path)))

    return ret
900834
def create(path, saltenv=None):
    '''
    
    '''
    if salt.utils.platform.is_windows():
        path = salt.utils.path.sanitize_win_path(path)
    path = salt.utils.data.decode(path)

    query = 'saltenv={0}'.format(saltenv) if saltenv else ''
    url = salt.utils.data.decode(urlunparse(('file', '', path, '', query, '')))
    return 'salt://{0}'.format(url[len('file:///'):])
1064550
def _construct_pillar(top_dir,
                      follow_dir_links,
                      keep_newline=False,
                      render_default=None,
                      renderer_blacklist=None,
                      renderer_whitelist=None,
                      template=False):
    '''
    
    '''
    pillar = {}
    renderers = salt.loader.render(__opts__, __salt__)

    norm_top_dir = os.path.normpath(top_dir)
    for dir_path, dir_names, file_names in salt.utils.path.os_walk(
            top_dir, topdown=True, onerror=_on_walk_error,
            followlinks=follow_dir_links):
        # Find current path in pillar tree
        pillar_node = pillar
        norm_dir_path = os.path.normpath(dir_path)
        prefix = os.path.relpath(norm_dir_path, norm_top_dir)
        if norm_dir_path != norm_top_dir:
            path_parts = []
            head = prefix
            while head:
                head, tail = os.path.split(head)
                path_parts.insert(0, tail)
            while path_parts:
                pillar_node = pillar_node[path_parts.pop(0)]

        # Create dicts for subdirectories
        for dir_name in dir_names:
            pillar_node[dir_name] = {}

        # Add files
        for file_name in file_names:
            file_path = os.path.join(dir_path, file_name)
            if not os.path.isfile(file_path):
                log.error('file_tree: %s: not a regular file', file_path)
                continue

            contents = b''
            try:
                with salt.utils.files.fopen(file_path, 'rb') as fhr:
                    buf = fhr.read(__opts__['file_buffer_size'])
                    while buf:
                        contents += buf
                        buf = fhr.read(__opts__['file_buffer_size'])
                    if contents.endswith(b'\n') \
                            and _check_newline(prefix,
                                               file_name,
                                               keep_newline):
                        contents = contents[:-1]
            except (IOError, OSError) as exc:
                log.error('file_tree: Error reading %s: %s',
                          file_path,
                          exc.strerror)
            else:
                data = contents
                if template is True:
                    data = salt.template.compile_template_str(template=salt.utils.stringutils.to_unicode(contents),
                                                              renderers=renderers,
                                                              default=render_default,
                                                              blacklist=renderer_blacklist,
                                                              whitelist=renderer_whitelist)
                if salt.utils.stringio.is_readable(data):
                    pillar_node[file_name] = data.getvalue()
                else:
                    pillar_node[file_name] = data

    return pillar
993239
def add_env(url, saltenv):
    '''
    
    '''
    if not url.startswith('salt://'):
        return url

    path, senv = parse(url)
    return create(path, saltenv)
849179
def do_mkdir(self, line):
        
        args = self.line_to_args(line)
        for filename in args:
            filename = resolve_path(filename)
            if not mkdir(filename):
                print_err('Unable to create %s' % filename)
686048
def file_hash(load, fnd):
    '''
    
    '''
    if 'env' in load:
        # "env" is not supported; Use "saltenv".
        load.pop('env')

    if not all(x in load for x in ('path', 'saltenv')):
        return ''
    ret = {'hash_type': __opts__['hash_type']}
    relpath = fnd['rel']
    path = fnd['path']
    hashdest = os.path.join(__opts__['cachedir'],
                            'hgfs/hash',
                            load['saltenv'],
                            '{0}.hash.{1}'.format(relpath,
                                                  __opts__['hash_type']))
    if not os.path.isfile(hashdest):
        ret['hsum'] = salt.utils.hashutils.get_hash(path, __opts__['hash_type'])
        with salt.utils.files.fopen(hashdest, 'w+') as fp_:
            fp_.write(ret['hsum'])
        return ret
    else:
        with salt.utils.files.fopen(hashdest, 'rb') as fp_:
            ret['hsum'] = salt.utils.stringutils.to_unicode(fp_.read())
        return ret