1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import sys
21 from optparse import OptionParser, Option
22
23 from spacewalk.server import rhnSQL
24 from spacewalk.common import rhn_rpm
25 from spacewalk.common.rhn_pkg import InvalidPackageError
26
27 SERVER_RETURN = 0
32
36
40
44
45 status = None
46 table = None
47 config_tree = None
48 server_root = None
49 mpm_query = None
50 exists_config_define = None
51
52 OK = 1
53
54
55
56 sys.modules["_apache"] = sys.modules["__main__"]
57
58 options_table = [
59 Option("-v", "--verbose", action="count",
60 help="Increase verbosity"),
61 Option("--commit", action="store_true",
62 help="Commit work"),
63 Option("--backup-file", action="store",
64 help="Backup packages into this file"),
65 Option("--prefix", action="store", default='/pub',
66 help="Prefix to find files in"),
67 ]
71
73 self.options = None
74 self._channels_hash = None
75 self._channel_packages = {}
76
78 parser = OptionParser(option_list=options_table)
79
80 (self.options, _args) = parser.parse_args()
81
82 rhnSQL.initDB()
83
84 self._channels_hash = self._get_channels()
85
86 package_ids = self._get_packages()
87 if package_ids is None:
88 return 1
89
90 if self.options.backup_file:
91 self._backup_packages(package_ids, self.options.backup_file)
92
93 try:
94 self._add_package_header_values(package_ids)
95 except:
96 rhnSQL.rollback()
97 raise
98
99 if self.options.commit:
100 print("Commiting work")
101 rhnSQL.commit()
102 else:
103 print("Rolling back")
104 rhnSQL.rollback()
105 return 0
106
108 package_ids = {}
109
110 h = rhnSQL.prepare(self._query_get_packages)
111 for channel_id in self._channels_hash.values():
112 h.execute(channel_id=channel_id)
113 while 1:
114 row = h.fetchone_dict()
115 if not row:
116 break
117 package_id = row['package_id']
118 package_ids[package_id] = (row['path'], row['header_start'], row['header_end'])
119
120 self._channel_packages = {}
121 orphaned_packages = {}
122
123 h = rhnSQL.prepare(self._query_get_channel_packages)
124 for package_id in package_ids:
125 h.execute(package_id=package_id)
126 while 1:
127 row = h.fetchone_dict()
128 if not row:
129 break
130 channel_label = row['label']
131 if package_id in self._channel_packages:
132 l = self._channel_packages[package_id]
133 else:
134 l = self._channel_packages[package_id] = []
135 l.append(channel_label)
136
137 if channel_label not in self._channels_hash:
138 orphaned_packages[package_id] = None
139
140 if orphaned_packages:
141 print("Bailing out because of packages shared with other channels")
142 for package_id in orphaned_packages:
143 channels = self._channel_packages[package_id]
144 print(package_id, channels)
145 return None
146
147 return package_ids
148
149 _query_get_channel_packages = rhnSQL.Statement("""
150 select c.id, c.label
151 from rhnChannel c,
152 rhnChannelPackage cp
153 where cp.package_id = :package_id
154 and cp.channel_id = c.id
155 """)
156
157 _query_get_channels = rhnSQL.Statement("""
158 select id, label from rhnChannel
159 """)
160
172
173 _query_get_packages = rhnSQL.Statement("""
174 select cp.package_id, p.path, p.header_start, p.header_end
175 from rhnChannelPackage cp,
176 rhnPackage p
177 where cp.channel_id = :channel_id
178 and cp.package_id = p.id
179 and p.path is not null
180 and p.header_start = -1
181 """)
182
183 _query_add_package_header_values = rhnSQL.Statement("""
184 update rhnPackage
185 set header_start = :header_start,
186 header_end = :header_end
187 where id = :package_id
188 """)
189
191 if not package_ids:
192 return
193 h = rhnSQL.prepare(self._query_add_package_header_values)
194 for package_id, (path, header_start, header_end) in package_ids.items():
195 try:
196 p_file = file(self.options.prefix + "/" + path, 'r')
197 except IOError:
198 print("Error opening file %s" % path)
199 continue
200
201 try:
202 (header_start, header_end) = rhn_rpm.get_header_byte_range(p_file)
203 except InvalidPackageError:
204 e = sys.exc_info()[1]
205 print("Error reading header size from file %s: %s" % (path, e))
206
207 try:
208 h.execute(package_id=package_id, header_start=header_start, header_end=header_end)
209 except rhnSQL.SQLError:
210 pass
211
212 @staticmethod
214 f = open(backup_file, "w+")
215
216 if not package_ids:
217 return
218
219 template = "update rhnPackage set header_start=%s and header_end=%s where id = %s;\n"
220 for package_id, (_path, header_start, header_end) in package_ids.items():
221 s = template % (header_start, header_end, package_id)
222 f.write(s)
223 f.write("commit;\n")
224 f.close()
225
226 if __name__ == '__main__':
227 sys.exit(Runner().main() or 0)
228