summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Woods <wwoods@redhat.com>2009-02-23 16:29:28 -0500
committerWill Woods <wwoods@redhat.com>2009-02-23 16:29:28 -0500
commitd477e79342d015291871a69779bb089d58388c43 (patch)
tree2e15a6b057ce0d6de4d0f8cc52880767da19343d
parentfc485a268ded2a6ce60ba0a7817f007a0a4c06ce (diff)
downloaddebuginfofs-d477e79342d015291871a69779bb089d58388c43.zip
debuginfofs-d477e79342d015291871a69779bb089d58388c43.tar.gz
debuginfofs-d477e79342d015291871a69779bb089d58388c43.tar.xz
Add warn_on_collision to mkdebuginfolinks and make unpack_rpm atomically create the target dir
-rwxr-xr-xdebuginfofs-mirror54
1 files changed, 30 insertions, 24 deletions
diff --git a/debuginfofs-mirror b/debuginfofs-mirror
index f9ed607..b6ff618 100755
--- a/debuginfofs-mirror
+++ b/debuginfofs-mirror
@@ -135,33 +135,36 @@ def fix_perms(targetdir):
mode = os.stat(i)[0]
os.chmod(i, mode | 0444)
-def unpack_rpm(rpm, targetdir):
- created_dir = False
+def _unpack_rpm(rpm, targetdir):
+ '''Unpack the given rpm into the given directory'''
if not os.path.isdir(targetdir):
- os.makedirs(targetdir)
- created_dir = True
+ os.makedirs(targetdir,mode=0755)
+ os.chdir(targetdir)
+ # rpm2cpio $rpm | cpio --quiet -iumd
+ p1 = Popen(['rpm2cpio',rpm], stdout=PIPE)
+ p2 = Popen(['cpio','--quiet','-iumd'], stdin=p1.stdout, stdout=PIPE)
+ output = p2.communicate()[0] # should be empty
+ if p2.returncode != 0:
+ raise OSError, "cpio failed: %s output:\n%s" % (str(p2.returncode),output)
+ # Fix perms so all files are readable
+ fix_perms(targetdir)
+def unpack_rpm(rpm, targetdir):
+ '''Unpack the given rpm into a temporary directory alongside the targetdir,
+ then rename the temp dir once finished.'''
+ tmpdir = tempfile.mkdtemp(dir=os.path.dirname(targetdir))
try:
- # FIXME: unpack into a tmpdir and then move into place after finishing
- # or else interrupted unpacks will leave us with incomplete output
- os.chdir(targetdir)
- # rpm2cpio $rpm | cpio --quiet -iumd
- p1 = Popen(['rpm2cpio',rpm], stdout=PIPE)
- p2 = Popen(['cpio','--quiet','-iumd'], stdin=p1.stdout, stdout=PIPE)
- output = p2.communicate()[0] # should be empty
- if p2.returncode != 0:
- raise OSError, "cpio failed: %s output:\n%s" % (str(p2.returncode),output)
- # Fix perms so all files are readable
- fix_perms(targetdir)
- except (IOError, OSError), e:
- print str(e)
- if created_dir:
- print "removing %s" % targetdir
+ _unpack_rpm(rpm, tmpdir)
+ if os.path.isdir(targetdir):
shutil.rmtree(targetdir)
+ os.rename(tmpdir,targetdir)
+ return True
+ except (OSError, IOError), e:
+ print "unpack_rpm failed: %s" % str(e)
+ shutil.rmtree(tmpdir)
return False
- return True
-def mkdebuginfolinks(sourcedir, targetdir):
+def mkdebuginfolinks(sourcedir, targetdir, warn_on_collision=False):
'''hardlink debuginfo from sourcedir into targetdir'''
count = 0
for top, dirs, files in os.walk(sourcedir, topdown=True):
@@ -172,13 +175,15 @@ def mkdebuginfolinks(sourcedir, targetdir):
linkname = u.split('/usr/lib/debug/.build-id/')[1]
newlink = os.path.join(targetdir,linkname)
try:
- os.makedirs(os.path.dirname(newlink))
+ os.makedirs(os.path.dirname(newlink),mode=0755)
except OSError, e:
if e.errno != 17:
raise e
if os.path.exists(newlink):
- # TODO: check to see if the contents of target == newlink
- # If not, we have a collision. That's bad.
+ if warn_on_collision and (os.stat(newlink) != os.stat(target)):
+ # TODO: better logging here
+ print "WARNING: collision or damaged debuginfo detected"
+ print "%s exists - removing" % (newlink,)
os.unlink(newlink)
os.link(target,newlink)
count += 1
@@ -238,6 +243,7 @@ def main():
repo.cachedir = repo.id
y.repos.add(repo)
y.repos.doSetup(thisrepo=repo.id)
+ # FIXME: locking - don't setup a repo that's in use by another process
repolist = y.repos.listEnabled()
if repolist: