Can't pull a file from a Container with "/*.gz" as filename


(Gunnar) #1

I want to pull a file of which I only know the suffix (.gz) from inside a container to my host.
The filename itself changes periodically

lxc file pull [container]/path/to/*.gz .

gives me an “Error: not found

Am I doing something wrong or do ‘*’ simply not work with lxc file pull operations?


#2

I don’t think it’s possible, my guess on the current state of lxc/lxd is that only ONE target is allowed and of course if you allow wildcard in file name you could pull several files, so it’s only possible to get the content of a directory, with the flag ‘recurse’, if it can work for you (ideally the file you want is all by itself in a directory)
If not there is always the possibility to start a sshd service in the container and with sftp you have all its possibilities.


(Stéphane Graber) #3

Those type of patterns are normally expanded by your local shell, this isn’t something that the LXD client can really expand itself as patterns will vary based on your shell and OS.

*.gz is also a valid filename which is what LXD tried to download for you.

Your best bet is to either transfer recursively or possibly use lxc exec to run your shell pattern in the container, getting the full filename that way and then download it with lxc file pull.


(Brian Mullan) #4

You could use scp on the host to copy *.gz from the container to host


#5

Here is an example in using lxc exec to get the list of files from the shell pattern.

lxc exec mycontainer -- bash -c 'ls /home/ubuntu/myfile*'

Suppose the output is

/home/ubuntu/myfile.1 /home/ubuntu/myfile.2

Then, you would need to append mycontainer to each result and pass it to lxc file pull.

lxc file pull mycontainer/home/ubuntu/myfile.1 mycontainer/home/ubuntu/myfile.2 /tmp/

Here a bash function that does just that.

lxcmpull() {
	# Use as 
	#
	# $ lxcmpull mycontainer "/home/ubuntu/myfile*" destination_dir
	#
        # lxc multi pull Bash function.
	# Use quotes to avoid expanding on the host. 
	#
	if [ "$#" -ne 3 ]; then
		echo "Usage: lxcmpull mycontainer "/home/ubuntu/myfile*" destination_dir"
		return
	fi

	files=`lxc exec $1 -- bash -c "ls $2 2>/dev/null"`
	if [ ! -z "$files" ]
	then 
		ARRAY=($files)
		LXCFILES=(`printf "$1%s " "${ARRAY[@]}"`)
	fi
	lxc file pull "${LXCFILES[@]}" $3
}

You put this in a file (let’s say myfile.sh), then you source myfile.sh. Finally, you run as follows.

lxcmpull mycontainer "/home/ubuntu/myfile*" /tmp

#6

The trouble with starting to give a bash example is that someone will always give another version

lxc exec mycontainer – bash -c “find /home/ubuntu/myfile* -maxdepth 1 -not -type d”

referring to sftp (or scp) don’t have this problem :slight_smile:


#7

lxc file pull has a --recursive parameter, therefore it is an option to let lxc to recurse instead.

Having said that, it is useful to evaluate the available options and have an idea what is possible.

With SSH, you would need to figure out a usable way to deliver public SSH keys into the containers.
Either to lxc file push them, or add them into the container through the LXD profile.
With a full example, it would be easier to conclude as to which to choose from, and suggest to users.