Package backend :: Package server :: Package action :: Module utils
[hide private]
[frames] | no frames]

Source Code for Module backend.server.action.utils

  1  # 
  2  # Copyright (c) 2008--2016 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU General Public License, 
  5  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  6  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  8  # along with this software; if not, see 
  9  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 10  # 
 11  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 12  # granted to use or replicate Red Hat trademarks that are incorporated 
 13  # in this software or its documentation. 
 14  # 
 15  from spacewalk.server import rhnSQL, rhnAction 
 16  from spacewalk.server.rhnDependency import find_package_with_arch 
 17  from spacewalk.server.rhnChannel import channels_for_server 
 18   
 19   
20 -class PackageNotFound(Exception):
21 pass
22 23
24 -class NoActionInfo(Exception):
25 pass
26 27
28 -class SubscribedChannel:
29 30 """ 31 SubscribedChannel represents a channel to which the server is subscribed. 32 """ 33
34 - def __init__(self, server_id, channel_lookup_string):
35 """ 36 Constructor. 37 38 server_id is a string containing the unique number that the 39 database has assigned to the server. 40 41 channel_lookup_string is a string that the _get_channel_info function 42 uses to look up the correct channel by channel label. It does NOT have 43 to be the entire channel label, but it does have to occur at the beginning 44 of the channel label. For instance "rhn-tools" would match any of the 45 rhn-tools channels because they all begin with "rhn-tools". It can also be 46 the entire channel label, of course. 47 """ 48 self.server_id = server_id 49 self.found_channel = None 50 self.channel_id = None 51 self.channel_lookup_string = channel_lookup_string 52 self.channel_label = None
53
54 - def _get_channel_info(self):
55 """ 56 Looks up the correct channel based on channel_lookup_string. 57 Populates the id, label, and a boolean that tells whether the 58 channel is found. 59 """ 60 subscribed_channels = channels_for_server(self.server_id) 61 62 # Our tools channels all start with "rhn-tools", which seems 63 # to be the only way to reliably tell one channel from the other 64 # automagically. 65 self.found_tools_channel = False 66 for channel_info in subscribed_channels: 67 label_position = channel_info['label'].find(self.channel_lookup_string) 68 if label_position > -1 and label_position == 0: 69 self.found_channel = True 70 self.channel_id = channel_info['id'] 71 self.channel_label = channel_info['label']
72
73 - def is_subscribed_to_channel(self):
74 """ 75 Returns True if server_id is subscribed to the 76 channel, False otherwise 77 """ 78 if not self.found_channel: 79 self._get_channel_info() 80 return self.found_channel
81
82 - def get_channel_id(self):
83 """ 84 Returns the channel's unique id. 85 """ 86 if not self.channel_id: 87 self._get_channel_info() 88 return self.channel_id
89
90 - def get_channel_label(self):
91 """ 92 Returns the channel's label. 93 """ 94 if not self.channel_label: 95 self._get_channel_info() 96 return self.channel_label
97 98
99 -class ChannelPackage:
100 101 """ 102 Represents a package contained in a channel that the server is 103 subscribed to. 104 """ 105
106 - def __init__(self, server_id, package_name):
107 """ 108 Constructor. 109 110 server_id is the unique value assigned to the server by the db. 111 package_name is a string containing the name of the package 112 to be looked up. 113 """ 114 self.server_id = server_id 115 self.package_name = package_name 116 117 self.package_info = None 118 self.id = None 119 self.version = None 120 self.release = None 121 self.epoch = None 122 self.arch = None 123 124 self.name_id = None 125 self.evr_id = None 126 self.arch_id = None 127 128 self.id_index = 0 129 self.name_index = 1 130 self.version_index = 2 131 self.release_index = 3 132 self.epoch_index = 4 133 self.arch_index = 5
134
135 - def _get_package_info(self):
136 """ 137 "Private" function that retrieves info about the package. 138 Populates self.package_info, self.id, self.version, self.release, and self.epoch. 139 """ 140 # Get info on the package we want to install. 141 possible_packages = find_package_with_arch(self.server_id, [self.package_name]) 142 143 # There's a possibility, however slight, that more than one package 144 # may be returned by find_by_packages. If that's the case, we only 145 # want the info about package_name. 146 package_info = None 147 if self.package_name in possible_packages: 148 for package in possible_packages[self.package_name]: 149 if package[self.name_index] == self.package_name: 150 self.package_info = package 151 self.id = package[self.id_index] 152 self.version = package[self.version_index] 153 self.release = package[self.release_index] 154 self.epoch = package[self.epoch_index] 155 self.arch = package[self.arch_index]
156
157 - def _get_package_field_ids(self):
158 """ 159 "Private" function that retrieves the database id's for the name, EVR, and 160 package architecture and sets self.name_id, self.evr_id, and self.arch_id to 161 their values. 162 """ 163 package_id = self.get_id() 164 165 if not package_id: 166 raise PackageNotFound("ID for package %s was not found." % self.get_name()) 167 168 _package_info_query = rhnSQL.Statement(""" 169 select 170 p.name_id name_id, 171 p.evr_id evr_id, 172 p.package_arch_id arch_id 173 from 174 rhnPackage p 175 where 176 p.id = :package_id 177 """) 178 prepared_query = rhnSQL.prepare(_package_info_query) 179 prepared_query.execute(package_id=package_id) 180 package_info_results = prepared_query.fetchone_dict() 181 182 if not package_info_results: 183 raise PackageNotFound("Name, EVR, and Arch info not found for %s" % self.get_name()) 184 185 self.name_id = package_info_results['name_id'] 186 self.evr_id = package_info_results['evr_id'] 187 self.arch_id = package_info_results['arch_id']
188
189 - def exists(self):
190 """ 191 Returns True if the package is available for the server according to the db, 192 False otherwise. 193 """ 194 if not self.package_info: 195 self._get_package_info() 196 197 if not self.package_info: 198 return False 199 else: 200 return True
201
202 - def get_name_id(self):
203 """ 204 Returns the name_id of the package. 205 """ 206 if not self.name_id: 207 self._get_package_field_ids() 208 return self.name_id
209
210 - def get_evr_id(self):
211 """ 212 Returns the evr_id of the package. 213 """ 214 if not self.evr_id: 215 self._get_package_field_ids() 216 return self.evr_id
217
218 - def get_arch_id(self):
219 """ 220 Returns the arch_id of the package. 221 """ 222 if not self.arch_id: 223 self._get_package_field_ids() 224 return self.arch_id
225
226 - def get_id(self):
227 """ 228 Returns the id of the package. 229 """ 230 if not self.id: 231 self._get_package_field_ids() 232 return self.id
233
234 - def get_name(self):
235 """ 236 Returns the name of the package. 237 """ 238 return self.package_name
239
240 - def get_version(self):
241 """ 242 Returns the version of the package. 243 """ 244 if not self.version: 245 self._get_package_info() 246 return self.version
247
248 - def get_release(self):
249 """ 250 Returns the release of the package. 251 """ 252 if not self.release: 253 self._get_package_info() 254 return self.release
255
256 - def get_epoch(self):
257 """ 258 Returns the epoch of the package. 259 """ 260 if not self.epoch: 261 self._get_package_info() 262 return self.epoch
263
264 - def get_arch(self):
265 """ 266 Returns the arch of the package. 267 """ 268 if not self.arch: 269 self._get_package_info() 270 return self.arch
271 272
273 -class PackageInstallScheduler:
274 275 """ 276 Class responsible for scheduling package installs. Can 277 only be used inside actions during a kickstart. 278 """ 279
280 - def __init__(self, server_id, this_action_id, package):
281 """ 282 Constructor. 283 284 server_id is the unique number assigned to the server by the database. 285 this_action_id is the unique number assigned to the current action. 286 package is an instance of ChannelPackage. 287 """ 288 self.server_id = server_id 289 self.package = package 290 self.this_action_id = this_action_id 291 self.new_action_id = None
292
293 - def _get_action_info(self, action_id):
294 """ 295 Private function that returns the org_id and scheduler for action_id. 296 """ 297 h = rhnSQL.prepare(""" 298 select org_id, scheduler 299 from rhnAction 300 where id = :id 301 """) 302 h.execute(id=action_id) 303 row = h.fetchone_dict() 304 if not row: 305 raise NoActionInfo("Couldn't find org_id or scheduler for action %s." % str(action_id)) 306 return (row['org_id'], row['scheduler'])
307
308 - def schedule_package_install(self):
309 """ 310 Public function that schedules self.package for installation during the next rhn_check. 311 """ 312 org_id, scheduler = self._get_action_info(self.this_action_id) 313 314 self.new_action_id = rhnAction.schedule_server_action( 315 self.server_id, 316 action_type="packages.update", 317 action_name="Scheduling install of RHN's virtualization host packages.", 318 delta_time=0, 319 scheduler=scheduler, 320 org_id=org_id 321 ) 322 323 self._add_package_to_install_action(self.new_action_id)
324
325 - def _add_package_to_install_action(self, action_id):
326 """ 327 Private function that adds self.package to the rhnActionPackage table. 328 """ 329 name_id = self.package.get_name_id() 330 package_arch_id = self.package.get_arch_id() 331 evr_id = self.package.get_evr_id() 332 333 insert_package_query = rhnSQL.Statement(""" 334 insert into rhnActionPackage(id, 335 action_id, 336 parameter, 337 name_id, 338 evr_id, 339 package_arch_id) 340 values (sequence_nextval('rhn_act_p_id_seq'), 341 :action_id, 342 'install', 343 :name_id, 344 :evr_id, 345 :package_arch_id) 346 """) 347 prepared_query = rhnSQL.prepare(insert_package_query) 348 prepared_query.execute(action_id=str(action_id), 349 name_id=str(name_id), 350 evr_id=str(evr_id), 351 package_arch_id=str(package_arch_id))
352