Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ttar cannot remove existing directory #3

Closed
knweiss opened this issue Apr 10, 2018 · 5 comments
Closed

ttar cannot remove existing directory #3

knweiss opened this issue Apr 10, 2018 · 5 comments

Comments

@knweiss
Copy link
Contributor

knweiss commented Apr 10, 2018

I've created a small ttar testcase for a problem I ran into while working on this PR: prometheus/node_exporter#871:

#!/bin/sh
echo "*** Create 1st archive"
mkdir -p ttar_testcase/sys/bus/cpu/devices/cpu0
ttar -C ttar_testcase/ -c -f ttar_testcase/sys1.ttar sys
echo

echo "*** Create 2nd archive"
rmdir ttar_testcase/sys/bus/cpu/devices/cpu0
mkdir -p ttar_testcase/sys/devices/system/cpu/cpu0
pushd ttar_testcase/sys/bus/cpu/devices/
ln -s ../../../devices/system/cpu/cpu0 .
popd
ttar -C ttar_testcase/ -c -f ttar_testcase/sys2.ttar sys
echo

echo "*** Remove directory"
rm -rf ttar_testcase/sys/*

echo "*** Extract 1st archive"
ttar -C ttar_testcase/ -x -f ttar_testcase/sys1.ttar
echo

echo "*** Extract 2nd archive over first archive"
ttar -C ttar_testcase/ -x -f ttar_testcase/sys2.ttar
echo

echo "*** Extract 2nd archive over first archive - now with sh -x"
sh -x ttar -C ttar_testcase/ -x -f ttar_testcase/sys2.ttar 2>&1 | tail -n 5

Let's run it:

$ sh ttar_testcase.sh
*** Create 1st archive
/home/knweiss/ttar_testcase

*** Create 2nd archive
/home/knweiss/ttar_testcase/sys/bus/cpu/devices
~/ttar_testcase/sys/bus/cpu/devices ~
~
/home/knweiss/ttar_testcase

*** Remove directory
*** Extract 1st archive
/home/knweiss/ttar_testcase

*** Extract 2nd archive over first archive
/home/knweiss/ttar_testcase
rm: cannot remove 'sys/bus/cpu/devices/cpu0': Is a directory

*** Extract 2nd archive over first archive - now with sh -x
+ [[ Path: sys/bus/cpu/devices/cpu0 =~ ^Path: (.*)$ ]]
+ path=sys/bus/cpu/devices/cpu0
+ '[' -e sys/bus/cpu/devices/cpu0 ']'
+ rm sys/bus/cpu/devices/cpu0
rm: cannot remove 'sys/bus/cpu/devices/cpu0': Is a directory

I.e. ttar is unable to remove an existing directory. The rm fails here:

   246          if [[ $line =~ ^Path:\ (.*)$ ]]; then
   247              path=${BASH_REMATCH[1]}
   248              if [ -e "$path" ] || [ -L "$path" ]; then
>  249                  rm "$path"
   250              fi
knweiss added a commit to knweiss/ttar that referenced this issue Apr 10, 2018
knweiss added a commit to knweiss/ttar that referenced this issue Apr 10, 2018
@ideaship
Copy link
Owner

@knweiss I refactored the code. It still passes the testcase you helpfully supplied. But it may no longer suit your needs, because it will fail if the directory is not empty. We may have to change the "rmdir" back to "rm -r" after all. I need to think about this.

@knweiss
Copy link
Contributor Author

knweiss commented Apr 11, 2018

@ideaship I had the same worries regarding security implications yesterday after sending the pull request.

Unfortunately, it now really no longer suits my needs in node-exporter as the directory is not empty in this case.

@ideaship
Copy link
Owner

@knweiss GNU tar does the same thing as ttar. It removes empty directories, but aborts with "Cannot open: File exists" if a directory is not empty. I do not want ttar to deviate from user expectations in a potentially dangerous way.

While not the default, GNU tar does have an option "--recursive-unlink" which does what you are looking for. Would such an option work for you?

@knweiss
Copy link
Contributor Author

knweiss commented Apr 11, 2018

@ideaship I think we can leave it as-is (rmdir) because clearing the directory tree before extraction is the better solution anyway.

@ideaship
Copy link
Owner

Okay. I am closing the issue then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants