def container_file_put(name, src, dst, recursive=False, overwrite=False,
                       mode=None, uid=None, gid=None, saltenv='base',
                       remote_addr=None,
                       cert=None, key=None, verify_cert=True):
    '''
    Put a file into a container

    name :
        Name of the container

    src :
        The source file or directory

    dst :
        The destination file or directory

    recursive :
        Decent into src directory

    overwrite :
        Replace destination if it exists

    mode :
        Set file mode to octal number

    uid :
        Set file uid (owner)

    gid :
        Set file gid (group)

    remote_addr :
        An URL to a remote Server, you also have to give cert and key if
        you provide remote_addr and its a TCP Address!

        Examples:
            https://myserver.lan:8443
            /var/lib/mysocket.sock

    cert :
        PEM Formatted SSL Certificate.

        Examples:
            ~/.config/lxc/client.crt

    key :
        PEM Formatted SSL Key.

        Examples:
            ~/.config/lxc/client.key

    verify_cert : True
        Wherever to verify the cert, this is by default True
        but in the most cases you want to set it off as LXD
        normaly uses self-signed certificates.

    CLI Example:

    .. code-block:: bash

        salt '*' lxd.container_file_put <container name> /var/tmp/foo /var/tmp/

    '''
    # Possibilities:
    #  (src, dst, dir, dir1, and dir2 are directories)
    #  cp /src/file1 /dst/file1
    #  cp /src/file1 /dst/file2
    #  cp /src/file1 /dst
    #  cp /src/file1 /dst/
    #  cp -r /src/dir /dst/
    #  cp -r /src/dir/ /dst/
    #  cp -r /src/dir1 /dst/dir2 (which is not /src/dir1 /dst/dir2/)
    #  cp -r /src/dir1 /dst/dir2/

    # Fix mode. Salt commandline doesn't use octals, so 0600 will be
    # the decimal integer 600 (and not the octal 0600). So, it it's
    # and integer, handle it as if it where a octal representation.
    mode = six.text_type(mode)
    if not mode.startswith('0'):
        mode = '0{0}'.format(mode)

    container = container_get(
        name, remote_addr, cert, key, verify_cert, _raw=True
    )

    src = os.path.expanduser(src)

    if not os.path.isabs(src):
        if src.find('://') >= 0:
            cached_file = __salt__['cp.cache_file'](src, saltenv=saltenv)
            if not cached_file:
                raise SaltInvocationError("File '{0}' not found".format(src))
            if not os.path.isabs(cached_file):
                raise SaltInvocationError('File path must be absolute.')
            src = cached_file

    # Make sure that src doesn't end with '/', unless it's '/'
    src = src.rstrip(os.path.sep)
    if not src:
        src = os.path.sep

    if not os.path.exists(src):
        raise CommandExecutionError(
            'No such file or directory \'{0}\''.format(src)
        )

    if os.path.isdir(src) and not recursive:
        raise SaltInvocationError(
            ("Cannot copy overwriting a directory "
             "without recursive flag set to true!")
        )

    try:
        dst_is_directory = False
        container.files.get(os.path.join(dst, '.'))
    except pylxd.exceptions.NotFound:
        pass
    except pylxd.exceptions.LXDAPIException as why:
        if six.text_type(why).find('Is a directory') >= 0:
            dst_is_directory = True

    if os.path.isfile(src):
        # Source is a file
        if dst_is_directory:
            dst = os.path.join(dst, os.path.basename(src))
            if not overwrite:
                found = True
                try:
                    container.files.get(os.path.join(dst))
                except pylxd.exceptions.NotFound:
                    found = False
                except pylxd.exceptions.LXDAPIException as why:
                    if six.text_type(why).find('not found') >= 0:
                        # Old version of pylxd
                        found = False
                    else:
                        raise
                if found:
                    raise SaltInvocationError(
                        "Destination exists and overwrite is false"
                    )
        if mode is not None or uid is not None or gid is not None:
            # Need to get file stats
            stat = os.stat(src)
            if mode is None:
                mode = oct(stat.st_mode)
            if uid is None:
                uid = stat.st_uid
            if gid is None:
                gid = stat.st_gid

        with salt.utils.files.fopen(src, 'rb') as src_fp:
            container.files.put(
                dst, src_fp.read(),
                mode=mode, uid=uid, gid=gid
            )
        return True
    elif not os.path.isdir(src):
        raise SaltInvocationError(
            "Source is neither file nor directory"
        )

    # Source is a directory
    # idx for dstdir = dst + src[idx:]
    if dst.endswith(os.sep):
        idx = len(os.path.dirname(src))
    elif dst_is_directory:
        idx = len(src)
    else:
        # Destination is not a directory and doesn't end with '/'
        # Check that the parent directory of dst exists
        # and is a directory
        try:
            container.files.get(os.path.join(os.path.dirname(dst), '.'))
        except pylxd.exceptions.NotFound:
            pass
        except pylxd.exceptions.LXDAPIException as why:
            if six.text_type(why).find('Is a directory') >= 0:
                dst_is_directory = True
                # destination is non-existent
                # cp -r /src/dir1 /scr/dir1
                # cp -r /src/dir1 /scr/dir2
                idx = len(src)
                overwrite = True

    # Copy src directory recursive
    if not overwrite:
        raise SaltInvocationError(
            "Destination exists and overwrite is false"
        )

    # Collect all directories first, to create them in one call
    # (for performance reasons)
    dstdirs = []
    for path, _, files in os.walk(src):
        dstdir = os.path.join(dst, path[idx:].lstrip(os.path.sep))
        dstdirs.append(dstdir)
    container.execute(['mkdir', '-p'] + dstdirs)

    set_mode = mode
    set_uid = uid
    set_gid = gid
    # Now transfer the files
    for path, _, files in os.walk(src):
        dstdir = os.path.join(dst, path[idx:].lstrip(os.path.sep))
        for name in files:
            src_name = os.path.join(path, name)
            dst_name = os.path.join(dstdir, name)

            if mode is not None or uid is not None or gid is not None:
                # Need to get file stats
                stat = os.stat(src_name)
                if mode is None:
                    set_mode = oct(stat.st_mode)
                if uid is None:
                    set_uid = stat.st_uid
                if gid is None:
                    set_gid = stat.st_gid

            with salt.utils.files.fopen(src_name, 'rb') as src_fp:
                container.files.put(
                    dst_name, src_fp.read(),
                    mode=set_mode, uid=set_uid, gid=set_gid
                )

    return True
def container_file_put ( name , src , dst , recursive = False , overwrite = False , mode = None , uid = None , gid = None , saltenv = 'base' , remote_addr = None , cert = None , key = None , verify_cert = True ) : mode = six . text_type ( mode ) if not mode . startswith ( '0' ) : mode = '0{0}' . format ( mode ) container = container_get ( name , remote_addr , cert , key , verify_cert , _raw = True ) src = os . path . expanduser ( src ) if not os . path . isabs ( src ) : if src . find ( '://' ) >= 0 : cached_file = __salt__ [ 'cp.cache_file' ] ( src , saltenv = saltenv ) if not cached_file : raise SaltInvocationError ( "File '{0}' not found" . format ( src ) ) if not os . path . isabs ( cached_file ) : raise SaltInvocationError ( 'File path must be absolute.' ) src = cached_file src = src . rstrip ( os . path . sep ) if not src : src = os . path . sep if not os . path . exists ( src ) : raise CommandExecutionError ( 'No such file or directory \'{0}\'' . format ( src ) ) if os . path . isdir ( src ) and not recursive : raise SaltInvocationError ( ( "Cannot copy overwriting a directory " "without recursive flag set to true!" ) ) try : dst_is_directory = False container . files . get ( os . path . join ( dst , '.' ) ) except pylxd . exceptions . NotFound : pass except pylxd . exceptions . LXDAPIException as why : if six . text_type ( why ) . find ( 'Is a directory' ) >= 0 : dst_is_directory = True if os . path . isfile ( src ) : if dst_is_directory : dst = os . path . join ( dst , os . path . basename ( src ) ) if not overwrite : found = True try : container . files . get ( os . path . join ( dst ) ) except pylxd . exceptions . NotFound : found = False except pylxd . exceptions . LXDAPIException as why : if six . text_type ( why ) . find ( 'not found' ) >= 0 : found = False else : raise if found : raise SaltInvocationError ( "Destination exists and overwrite is false" ) if mode is not None or uid is not None or gid is not None : stat = os . stat ( src ) if mode is None : mode = oct ( stat . st_mode ) if uid is None : uid = stat . st_uid if gid is None : gid = stat . st_gid with salt . utils . files . fopen ( src , 'rb' ) as src_fp : container . files . put ( dst , src_fp . read ( ) , mode = mode , uid = uid , gid = gid ) return True elif not os . path . isdir ( src ) : raise SaltInvocationError ( "Source is neither file nor directory" ) if dst . endswith ( os . sep ) : idx = len ( os . path . dirname ( src ) ) elif dst_is_directory : idx = len ( src ) else : try : container . files . get ( os . path . join ( os . path . dirname ( dst ) , '.' ) ) except pylxd . exceptions . NotFound : pass except pylxd . exceptions . LXDAPIException as why : if six . text_type ( why ) . find ( 'Is a directory' ) >= 0 : dst_is_directory = True idx = len ( src ) overwrite = True if not overwrite : raise SaltInvocationError ( "Destination exists and overwrite is false" ) dstdirs = [ ] for path , _ , files in os . walk ( src ) : dstdir = os . path . join ( dst , path [ idx : ] . lstrip ( os . path . sep ) ) dstdirs . append ( dstdir ) container . execute ( [ 'mkdir' , '-p' ] + dstdirs ) set_mode = mode set_uid = uid set_gid = gid for path , _ , files in os . walk ( src ) : dstdir = os . path . join ( dst , path [ idx : ] . lstrip ( os . path . sep ) ) for name in files : src_name = os . path . join ( path , name ) dst_name = os . path . join ( dstdir , name ) if mode is not None or uid is not None or gid is not None : stat = os . stat ( src_name ) if mode is None : set_mode = oct ( stat . st_mode ) if uid is None : set_uid = stat . st_uid if gid is None : set_gid = stat . st_gid with salt . utils . files . fopen ( src_name , 'rb' ) as src_fp : container . files . put ( dst_name , src_fp . read ( ) , mode = set_mode , uid = set_uid , gid = set_gid ) return True
Put a file into a container

    name :
        Name of the container

    src :
        The source file or directory

    dst :
        The destination file or directory

    recursive :
        Decent into src directory

    overwrite :
        Replace destination if it exists

    mode :
        Set file mode to octal number

    uid :
        Set file uid (owner)

    gid :
        Set file gid (group)

    remote_addr :
        An URL to a remote Server, you also have to give cert and key if
        you provide remote_addr and its a TCP Address!

        Examples:
            https://myserver.lan:8443
            /var/lib/mysocket.sock

    cert :
        PEM Formatted SSL Certificate.

        Examples:
            ~/.config/lxc/client.crt

    key :
        PEM Formatted SSL Key.

        Examples:
            ~/.config/lxc/client.key

    verify_cert : True
        Wherever to verify the cert, this is by default True
        but in the most cases you want to set it off as LXD
        normaly uses self-signed certificates.

    CLI Example:

    .. code-block:: bash

        salt '*' lxd.container_file_put <container name> /var/tmp/foo /var/tmp/