Description of problem:
Deploying a symbolic link to a spacewalk-managed system fails if the symlink location is not on the root (/) filesystem
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. Add a locally managed symbolic link to a spacewalk managed system, set the symbolic link location to a filesystem other than / (I am using /opt), the target of the symlink does not matter
2. deploy the symlink to the system
Deployment fails with:
Client execution returned "Failed deployment, rolled back: [Errno 18] Invalid cross-device link" (code 49)
Symlink to be properly deployed
- Deploying a symbolic link to a directory on the root (/) file system works
- I've traced the problem back to an os.rename in /usr/share/rhn/config_common/transactions.py and attached a prof of concept fix. Calling `mv` is a hack and probably fragile but hopefully it will help someone with better python skills than me write a better solution
--- /usr/share/rhn/config_common/transactions.py.orig 2010-08-11 17:04:33.000000000 -0600
+++ /usr/share/rhn/config_common/transactions.py 2010-08-12 10:51:13.000000000 -0600
@@ -350,7 +351,21 @@
log_debug(6, "deploying %s ..." % path)
- os.rename(self.newtemp_by_path[path], path)
+ # os.renames will fail if the path and the new_path are on different partitions
+ # need to make sure to handle it if we catch a 'OSError: [Errno 18] Invalid cross-device link'
+ log_debug(9, "trying to use os.rename to move the temp file into place")
+ os.rename(self.newtemp_by_path[path], path)
+ except OSError, e:
+ if e.errno == 18:
+ #log_debug(9, "os.rename failed, using shutil functions")
+ #shutil.copy(self.newtemp_by_path[path], path)
+ # This is kind of hacky but i don't know a better way that properly handles dangling symlinks
+ log_debug(9, "os.rename failed, using the system `mv` command to copy %s to %s" % (self.newtemp_by_path[path], path))
+ os.system("mv %s %s" % (self.newtemp_by_path[path], path))
log_debug(9, "new version of %s deployed" % path)
- In my testing this fix works regardless of where the symbolic link points to (directory, file, or dangling symlink).
- With this fix symlink deployments will fail if the destination directory doesn't exist (i.e. deploying /nonresistant/directory/symlink will fail). And deploying the same symlink twice will fail if the symlink target is a directory
/usr/share/rhn/config_common/transactions.py needs to be patched on the client systems, not the spacewalk server
(In reply to comment #0)
> + os.system("mv %s %s" % (self.newtemp_by_path[path],
I don't like forking the mv, not mentioning the fact that the comemnt will fail if the path is strange (starts with a dash or has a space in it or something).
Why can't we create the temporary entries in the same directory as the final location, with some dot at start and some random suffix?
Mass-moving to space13.
We did not have time for this one during Spacewalk 1.4 time frame. Mass moving to Spacewalk 1.5.
Aligning under space16.
I was not able to reproduce this issue with the latest rhncfg-client.
# rhncfg-client get
# ll /mnt/dir/
-rw-r--r-- 1 root root 6 Aug 24 13:53 file
lrwxrwxrwx 1 root root 9 Aug 24 13:53 link -> /bin/bash
# df /bin /mnt
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/xvda1 40629568 1870084 36662856 5% /
/root/filesys.img 39663 4610 33005 13% /mnt
# rpm -q rhncfg-client
So I'm closing it as WORKSFORME.
If you disagree please reopen and specify exact version of rhncfg-client.