pongasoft / glu

Deployment Automation Platform
Apache License 2.0
518 stars 99 forks source link

When uninstalling, the glu agent tries to remove the target of a symlink #304

Open reversefold opened 9 years ago

reversefold commented 9 years ago

Removal of the symlink is sufficient and more correct as it follows the conventions of e.g. rm -r.

ypujante commented 9 years ago

Can you provide more descriptions of the problem. I am not sure I understand.

reversefold commented 9 years ago

For instance, I have a package that uses a python virtualenv. Part of the setup for the virtualenv is to create symlinks to system files inside of the virtualenv directory. It is definitely not intended for glu to remove the system files linked to by these symlinks when it uninstalls the package which includes the virtualenv.

In general, I think that following symlinks when deleting files is a bug and a violation of the principal of least surprise. On unix, symlinks are generally treated as files unless you explicitly treat them like a directory. For instance, if you do this:

{/tmp} $ mkdir test
{/tmp} $ touch test_file
{/tmp} $ cd test
{test} $ ln -s ../test_file .
{test} $ ls -al
total 8
drwxr-xr-x   3 jpatrin  wheel  102 Jul 14 14:42 .
drwxrwxrwt  11 root     wheel  374 Jul 14 14:41 ..
lrwxr-xr-x   1 jpatrin  wheel   12 Jul 14 14:42 test_file -> ../test_file
{test} $ cd ..
{/tmp} $ rm -r test
{/tmp} $ ls -al test_file
-rw-r--r--  1 jpatrin  wheel  0 Jul 14 14:41 test_file

The symlink is removed, as if it is a file in the directory, but the target file is left unchanged. I would argue that this should always be the default when recursively deleting a directory as removing the target of a symlink could affect files outside of the directory. In the case we are running into, if we were (inadvisably) running glu as an inherently privileged user (such as root, or one with a group who had write to system files) then it would have removed system files which were not installed by glu.

sodul commented 9 years ago

This is a similar case to this: http://glu.977617.n3.nabble.com/Glu-uninstall-follows-symlinks-and-delete-files-outside-of-mountPoint-td4024877.html

What is happening is that justin is installing a package that has a lot of symlinks pointing to root owned files (Python's VirtualEnv is doing it). When uninstalling our groovy script is calling shell.exec('rm -rf $mountPoint') when calling the uninstall step which works fine.

There is a case however where if the install step failed, after unpacking the archive with the symlinks, where the console consider (correctly) that the uninstall step should not be called and then the code in RootScript.groovy is calling shell.rmdirs(args.mountPoint) which fails since that code follows symlinks and fails on the first root owned file.

We can't change the behavior of the package since it is using Python's VirtualEnv which symlinks to OS owned files a lot. This case should be rare yet we would need to have a way to handle it.

I propose 2 ways to handle this:

Personally I think symlinks should not be followed on deletes by default since it indeeds differs from the standard *nix behavior but I respect the fact that you might want to preserve existing behavior by default.

ypujante commented 9 years ago

I understand now. It was not obvious what the problem was from the original bug. I do agree that glu should not be deleting the target of symlinks. I am not sure who would be relying on this behavior but I can imagine it would be a non backward compatible change so there should definitely be an option to turn it on/off.