6

hello stackoverflowers,

I want to preserve the original file permissions when using Python's tarfile module. I have quite a few executable files that lose their permissions once the tarball is extracted.

I'm doing something like this:

import tarfile
tar = tarfile.open("mytarball.tar.gz", 'w:gz')
tar.add('my_folder') #tar the entire folder 
tar.close()

Then I copy it from windows to a linux machine (mapped with samba) using shutil:

shutil.copy("mytarball.tar.gz",unix_dir)

Then, to extract the tarball in linux I do

unix>tar -xvf mytarball.tar.gz  

After the tarball is extracted I lose all the 'x' permissions on my files

Any clues how to solve this issue?

Regards

user3352256
  • 109
  • 2
  • 5
  • I did a small test using your code and it kept the 'x' permissions. Is there something more complicated going on? Are you certain the permissions are correct before they're added to the tarball? – Dan Getz Apr 30 '14 at 15:18
  • I'm copying the tarbal from windows to unix over samba. I'm using shutil : shutil.copy("mytarball.tar.gz",unix_dir) It might be something going on there. I'd have to double check. But copying individual files seems to work. The permissions are kept. – user3352256 Apr 30 '14 at 19:11
  • Ah, ok, my test was only on Linux where I know how execute file permissions work. Not sure how Python treats execute file permissions on Windows. – Dan Getz Apr 30 '14 at 19:51
  • Because "executable" can have different meanings on Linux and Windows, how do you think it should be determined which files have executable permissions? – Dan Getz Apr 30 '14 at 20:12
  • shutil is doing its job. In other words, copying files from windows to unix over samba does not change permissions. The problem seems to be the tarfile module which ignores the permissions if run under windows. I extracted the tarball in windows and I observed that the permissions are gone. – user3352256 Apr 30 '14 at 20:32
  • I thought when extracting a tarfile, regardless of whether it has the original permissions saved in it, that you have to use the `p` flag if you want the extracted files to have the saved permissions. E.g. `tar -xvpf mytarball.tar.gz` – Brōtsyorfuzthrāx Mar 25 '16 at 05:52

2 Answers2

6

If you know which of your files should have execute permissions or not, you can set the permissions manually with a filter function:

def set_permissions(tarinfo):
    tarinfo.mode = 0777 # for example
    return tarinfo

tar.add('my_folder', filter=set_permissions)
Dan Getz
  • 8,774
  • 6
  • 30
  • 64
  • couldn't find the right filter for my windows files. The tarball is always empty. :( – user3352256 May 01 '14 at 10:38
  • My fault, I think! Forgot to return the tarinfo object from my example filter. Returning None would filter it out of the resulting tarball, yes. – Dan Getz May 01 '14 at 10:43
1

Based on @DanGetz solution, I made this work for python3.8:

I'm using stream response to create the my tar file but here you're with the full code.

tar_stream = io.BytesIO()
tar = tarfile.TarFile(fileobj=tar_stream, mode='w')
file_data = content.encode('utf8')
tarinfo = tarfile.TarInfo(name=file_name)
tarinfo.size = len(file_data)
tarinfo.mtime = time.time()
tarinfo.mode = 0o740 # <--------
tar.addfile(tarinfo, io.BytesIO(file_data))
tar.close()

In python 2.6 and 3+ you must use this format for perissions: 0o777 instead of 0777.

from: https://stackoverflow.com/a/1627222/6809926

Zenocode
  • 656
  • 7
  • 19