Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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