def package(self, package, fileChecksumType, fileChecksum): self.warn(1, "Uploading package %s" % package) if not os.access(package, os.R_OK): self.die(-1, "Could not read file %s" % package) try: h = uploadLib.get_header(package, source=self.options.source) except uploadLib.UploadError: e = sys.exc_info()[1] # GS: MALFORMED PACKAGE print("Unable to load package", package, ":", e) return None if hasattr(h, 'packaging'): packaging = h.packaging else: packaging = 'rpm' if packaging == 'rpm' and self.options.nosig is None and not h.is_signed( ): # pkilambi:bug#173886:force exit to check for sig if --nosig raise uploadLib.UploadError( "ERROR: %s: unsigned rpm (use --nosig to force)" % package) try: ret = self._push_package_v2(package, fileChecksumType, fileChecksum) except uploadLib.UploadError: e = sys.exc_info()[1] ret, diff_level, pdict = e.args[:3] severities = { 1: 'path changed', 2: 'package resigned', 3: 'differing build times or hosts', 4: 'package recompiled', } if diff_level in severities: strmsg = \ "Error: Package with same name already exists on " + \ "server but contents differ (" + \ severities[diff_level] + \ "). Use --force or remove old package before " + \ "uploading the newer version." else: strmsg = "Error: severity %s" % diff_level self.warn( -1, "Uploading failed for %s\n%s\n\tDiff: %s" % (package, strmsg, pdict['diff']['diff'])) if diff_level != 1: # This will prevent us from annoyingly retrying when there is # no reason to. raise uploadLib.UploadError() return ret return ret
def _push_package_v2(self, package, fileChecksumType, fileChecksum): self.warn(1, "Using POST request") pu = rhnpush_v2.PackageUpload(self.url_v2, self.options.proxy) pu.set_session(self.session.getSessionString()) pu.set_force(self.options.force) pu.set_null_org(self.options.nullorg) pu.set_timeout(self.options.timeout) status, msgstr = pu.upload(package, fileChecksumType, fileChecksum) ret = {} for tag in ('name', 'version', 'release', 'epoch', 'arch'): val = getattr(pu, "package_%s" % tag) if val is None: val = '' ret[tag] = val ret['checksum_type'] = fileChecksumType ret['checksum'] = fileChecksum if status == 400: # Bad request - something bad happened try: data = rpclib.xmlrpclib.loads(msgstr) except: # Raise the exception instead of silently dying raise_with_tb( uploadLib.UploadError("Error pushing %s: %s (%s)" % (package, msgstr, status)), sys.exc_info()[2]) (diff_dict, ), methodname = data del methodname diff_level = diff_dict['level'] pdict = diff_dict['diff'] raise uploadLib.UploadError(ret, diff_level, pdict) if status == 403: # auth expired raise an exception to grab one raise AuthenticationRequired() if status != 200: self.die(1, "Error pushing %s: %s (%s)" % (package, msgstr, status)) return ret
def packages(self): self.setForce() # set the org self.setOrg() # set the URL self.setURL() # set the channels self.setChannels() # set the server self.setServer() # 12/22/05 wregglej 173287 authenticate the session. self.authenticate() # Do we have the new-style handler available? # ping the server for status self.warn(2, "url is", self.url_v2) ping = rhnpush_v2.PingPackageUpload(self.url_v2, self.options.proxy) ping_status, errmsg, headerinfo = ping.ping() self.warn(2, "Result codes:", ping_status, errmsg) # move patch clusters to the end because all the patches in the cluster # have to be pushed before the cluster itself files1 = [] files2 = [] for filename in self.files: if filename.startswith('patch-cluster-'): files2.append(filename) else: files1.append(filename) self.files = files1 + files2 channel_packages = [] # a little fault tolarence is in order random.seed() tries = 3 # satellites < 4.1.0 are no more supported if sys.version_info[0] == 3: pack_exist_check = headerinfo.get('X-RHN-Check-Package-Exists') else: pack_exist_check = headerinfo.getheader( 'X-RHN-Check-Package-Exists') if not pack_exist_check: self.die(-1, "Pushing to Satellite < 4.1.0 is not supported.") (server_digest_hash, pkgs_info, digest_hash) = self.check_package_exists() for pkg in self.files: ret = None # pkilambi:errors off as not initialized.this fixes it. # temporary fix for picking pkgs instead of full paths pkg_key = (pkg.strip()).split('/')[-1] if pkg_key not in server_digest_hash: continue checksum_type, checksum = digest = digest_hash[pkg_key] server_digest = tuple(server_digest_hash[pkg_key]) # compare checksums for existance check if server_digest == digest and not self.options.force: channel_packages.append(pkgs_info[pkg_key]) self.warn( 1, "Package %s already exists on the SUSE Manager Server-- Skipping Upload...." % pkg) continue elif server_digest == (): self.warn( 1, "Package %s Not Found on SUSE Manager Server -- Uploading" % pkg) elif server_digest == "on-disk" and not self.options.force: channel_packages.append(pkgs_info[pkg_key]) self.warn( 0, "Package on disk but not on db -- Skipping Upload " % pkg) continue elif server_digest != digest: if self.options.force: self.warn( 1, "Package checksum %s mismatch -- Forcing Upload" % pkg) else: msg = "Error: Package %s already exists on the server with" \ " a different checksum. Skipping upload to prevent" \ " overwriting existing package. (You may use rhnpush with" \ " the --force option to force this upload if the" \ " force_upload option is enabled on your server.)\n" % pkg if not self.options.tolerant: self.die(-1, msg) self.warn(0, msg) continue for _t in range(0, tries): try: ret = self.package(pkg, checksum_type, checksum) if ret is None: raise uploadLib.UploadError() # TODO: Revisit this. We throw this error all over the place, # but doing so will cause us to skip the --tolerant logic # below. I don't think we really want this behavior. # There are some cases where we don't want to retry 3 # times, but not at the expense of disabling the tolerant # flag, IMHO. This loop needs some lovin'. -- pav # FIX: it checks for tolerant flag and aborts only if the flag is #not specified except uploadLib.UploadError: ue = sys.exc_info()[1] if not self.options.tolerant: self.die(1, ue) self.warn(2, ue) except AuthenticationRequired: # session expired so we re-authenticate for the process to complete # this uses the username and password from memory if available # else it prompts for one. self.authenticate() except: self.warn(2, sys.exc_info()[1]) wait = random.randint(1, 5) self.warn(0, "Waiting %d seconds and trying again..." % wait) time.sleep(wait) # The else clause gets executed in the stuff in the try-except block *succeeds*. else: break # if the preceeding for-loop exits without a call to break, then this else clause gets called. # What's kind of weird is that if the preceeding for-loop doesn't call break then an error occurred # and all of retry attempts failed. If the for-loop *does* call break then everything is hunky-dory. # In short, this else clause only get's called if something is F.U.B.A.R and the retry attempts don't # fix anything. else: if not self.options.tolerant: # pkilambi:bug#176358:this exits with a error code of 1 self.die(1, "Giving up after %d attempts" % tries) else: print("Giving up after %d attempts and continuing on..." % (tries, )) # 5/13/05 wregglej - 154248 ?? we still want to add the packages if they're source. if ret and self.channels: # and ret['arch'] != 'src': # Don't bother to add the package if # no channel was specified or a source rpm was passed channel_packages.append(ret) # self.channels is never None, it always has at least one entry with an empty string. if len(self.channels) == 1 and self.channels[0] == '': return info = {'packages': channel_packages, 'channels': self.channels} if self.orgId == '' or self.orgId > 0: info['orgId'] = self.orgId # 2/3/06 wregglej 173287 Added check to see if we can use session tokens. if channel_packages: self.authenticate() uploadLib.call( self.server.packages.channelPackageSubscriptionBySession, self.session.getSessionString(), info) return 0