@@ -80,40 +80,57 @@ def get_labels(config, container_config):
8080 return dict (sorted (labels .items ()))
8181
8282
83- def extract_tar (location , target_dir ):
83+ def extract_tar (location , target_dir , skip_symlinks = True ):
8484 """
8585 Extract a tar archive at `location` in the `target_dir` directory.
86- Ignore special device files and symlinks and hardlinks.
87- Do not preserve the permissions and owners.
88- Raise an Exception on error.
89- """
90- raise NotImplementedError ('This function has been removed, use extract_tar_keeping_symlinks instead' )
91-
92-
93- def extract_tar_keeping_symlinks (location , target_dir ):
94- """
95- Extract a tar archive at `location` in the `target_dir` directory.
96- Ignore special device files. Keep symlinks and hardlinks
86+ Ignore special device files. Skip symlinks and hardlinks if skip_symlinks is True.
9787 Do not preserve the permissions and owners.
9888 Raise exceptions on possible problematic relative paths.
89+ Issue a warning if skip_symlinks is True and links target are missing.
9990 """
10091 import tarfile
101- if TRACE : logger .debug (f'extract_tar_keeping_symlinks: { location } to { target_dir } ' )
92+ tarfile .TarInfo
93+ if TRACE : logger .debug (f'_extract_tar: { location } to { target_dir } skip_symlinks: { skip_symlinks } ' )
10294
10395 fileutils .create_dir (target_dir )
10496
10597 with tarfile .open (location ) as tarball :
10698 # never extract character device, block and fifo files:
10799 # we extract dirs, files and links only
108- for tinfo in tarball :
109- if tinfo .isdev ():
100+ to_extract = []
101+ for tarinfo in tarball :
102+ if TRACE : logger .debug (f'_extract_tar: { tarinfo } ' )
103+
104+ if tarinfo .isdev () or tarinfo .ischr () or tarinfo .isblk () or tarinfo .isfifo () or tarinfo .sparse :
105+ if TRACE :
106+ logger .debug (f'_extract_tar: skipping unsupported { tarinfo } file type: block, chr, dev or sparse file' )
110107 continue
111- if TRACE : logger .debug (f'extract_tar_keeping_symlinks: { tinfo } ' )
112- tarball .extract (
113- member = tinfo ,
114- path = target_dir ,
115- set_attrs = False ,
116- )
108+
109+ if '..' in tarinfo .name :
110+ if TRACE : logger .debug (f'_extract_tar: skipping unsupported { tarinfo } with relative path' )
111+ continue
112+
113+ if tarinfo .islnk () or tarinfo .issym ():
114+ try :
115+ target = tarball ._find_link_target (tarinfo )
116+ if not target :
117+ if TRACE :
118+ logger .debug (f'_extract_tar: skipping link with missing target: { tarinfo } ' )
119+ continue
120+
121+ except Exception :
122+ import traceback
123+ if TRACE :
124+ logger .debug (f'_extract_tar: skipping link with missing target: { tarinfo } : { traceback .format_exc ()} ' )
125+ continue
126+
127+ tarinfo .mode = 0o755
128+ tarinfo .name = tarinfo .name .lstrip ('/' )
129+ tarball .extract (member = tarinfo , path = target_dir , set_attrs = False ,)
130+
131+
132+ def extract_tar_with_symlinks (location , target_dir ):
133+ return extract_tar (location , target_dir , skip_symlinks = False )
117134
118135
119136def lower_keys (mapping ):
0 commit comments