import repository from arizona
[raven.git] / apps / mprepo / repometafileupdate.py
1 #! /usr/bin/env python
2
3 """
4 <Program Name>
5    repometafileupdate.py
6
7 <Started>
8    June 7, 2006
9
10 <Author>
11    Programmed by Jeffry Johnston
12
13 <Purpose>
14    Updates the metafile with hashes for metafile tarballs.
15 """
16
17 import os
18 import sys
19 import time
20 import arizonaconfig
21 import arizonacrypt
22 import arizonageneral
23 import arizonareport
24 import ravenlib.package.storkpackage
25
26 def metafileUpdate(files, metafiledir, metafilename, privatekey_fn, discard_existing=False):
27    arizonageneral.makedirs_existok(metafiledir)
28
29    metafilepathname = os.path.join(metafiledir, metafilename)
30    signed_metafilepathname = metafilepathname + ".signed"
31
32    if discard_existing:
33        oldmetafile = []
34    else:
35        # read the existing metafile
36        try:
37           f = open(metafilepathname)
38           oldmetafile = f.readlines()
39           f.close()
40        except IOError:
41           oldmetafile = []
42
43    # add existing entries that won't be updated
44    newmetafile = []
45    items = [] # list of tuples in format (filepath, hash)
46    for item in oldmetafile:
47       itemparts = item.split()
48       try:
49          filename = itemparts[0]
50       except IndexError:
51          continue
52       if not filename in files:
53          # make sure the tarball exists before adding it back to the metafile
54          if os.path.isfile(os.path.join(metafiledir, filename)):
55             items.append((filename, itemparts[1]))
56             newmetafile.append(item)
57
58    # build the new metafile entries
59    for filename in files:
60       pathname = os.path.join(metafiledir, filename)
61       arizonareport.send_out(2, "metafileUpdate: processing " + pathname)
62
63       # get tarball metadata
64       try:
65          hash = ravenlib.package.storkpackage.get_package_metadata_hash(pathname)
66       except TypeError, e:
67          arizonareport.send_error(1, "Skipping " + pathname + " (" + str(e) + ")")
68          continue
69
70       # add the new entry
71       items.append((filename, hash))
72       newmetafile.append(filename + " " + hash + "\n")
73
74    temp_name = metafilepathname + "." + str(time.time()) + ".tmp"
75
76    arizonareport.send_out(1, "writing unsigned metafile to " + temp_name)
77
78    # write the un-signed metafile
79    f = open(temp_name, "w")
80    f.write("".join(newmetafile))
81    f.close()
82
83    # for atomicity, replace the old file with the new one
84    os.rename(temp_name, metafilepathname)
85
86    arizonareport.send_out(1, "unsigned metafile renamed to " + metafilepathname)
87
88    # write and sign the signed metafile
89    # ideally both the metafile and signed metafile would be created and then moved
90    # into place at the same time
91    if not privatekey_fn:
92       arizonareport.send_out(1, "No repository private key specified. Cannot create signed metafile.")
93    else:
94       temp_name = signed_metafilepathname + "." + str(time.time()) + ".tmp"
95
96       arizonareport.send_out(1, "writing signed metafile to " + temp_name)
97
98       f = open(temp_name, "w")
99       for (fn, hash) in items:
100           size = str(os.path.getsize(os.path.join(metafiledir, fn)))
101           f.write(fn + " " + hash + " " + size + "\n")
102       f.close()
103
104       arizonacrypt.XML_sign_file_using_privatekey_fn(temp_name, privatekey_fn, certify_filename = False)
105
106       os.chmod(temp_name, 0644)
107
108       # for atomicity, replace the old file with the new one
109       os.rename(temp_name, signed_metafilepathname)
110
111       arizonareport.send_out(1, "signed metafile renamed to " + signed_metafilepathname)
112
113    return metafilepathname
114