Esempio n. 1
0
    def poll_packages(self, release, server_arch, timestamp=0, uuid=None):
        log_debug(1, release, server_arch, timestamp, uuid)

        # make sure we're dealing with strings here
        release = str(release)
        server_arch = rhnLib.normalize_server_arch(server_arch)
        timestamp = str(timestamp)
        uuid = str(uuid)

        # get a list of acceptable channels
        channel_list = []

        channel_list = rhnChannel.applet_channels_for_uuid(uuid)

        # it's possible the tie between uuid and rhnServer.id wasn't yet
        # made, default to normal behavior
        if not channel_list:
            channel_list = rhnChannel.get_channel_for_release_arch(
                release, server_arch)
            channel_list = [channel_list]
        # bork if no channels returned
        if not channel_list:
            log_debug(
                8, "No channels for release = '%s', arch = '%s', uuid = '%s'" %
                (release, server_arch, uuid))
            return {'last_modified': 0, 'contents': []}

        last_channel_changed_ts = max(
            [a["last_modified"] for a in channel_list])

        # make satellite content override a cache caused by hosted
        last_channel_changed_ts = str(LongType(last_channel_changed_ts) + 1)

        # gotta be careful about channel unsubscriptions...
        client_cache_invalidated = None

        # we return rhnServer.channels_changed for each row
        # in the satellite case, pluck it off the first...
        if "server_channels_changed" in channel_list[0]:
            sc_ts = channel_list[0]["server_channels_changed"]

            if sc_ts and (sc_ts >= last_channel_changed_ts):
                client_cache_invalidated = 1

        if (last_channel_changed_ts <=
                timestamp) and (not client_cache_invalidated):
            # XXX: I hate these freaking return codes that return
            # different members in the dictinary depending on what
            # sort of data you get
            log_debug(3, "Client has current data")
            return {'use_cached_copy': 1}

        # we'll have to return something big - compress
        rhnFlags.set("compress_response", 1)

        # Mark the response as being already XMLRPC-encoded
        rhnFlags.set("XMLRPC-Encoded-Response", 1)

        # next, check the cache if we have something with this timestamp
        label_list = [str(a["id"]) for a in channel_list]
        label_list.sort()
        log_debug(4, "label_list", label_list)
        cache_key = "applet-poll-%s" % string.join(label_list, "-")

        ret = rhnCache.get(cache_key, last_channel_changed_ts)
        if ret:  # we have a good entry with matching timestamp
            log_debug(3, "Cache HIT for", cache_key)
            return ret

        # damn, need to do some real work from chip's requirements:
        # The package list should be an array of hashes with the keys
        # nvre, name, version, release, epoch, errata_advisory,
        # errata_id, with the errata fields being empty strings if the
        # package isn't from an errata.
        ret = {'last_modified': last_channel_changed_ts, 'contents': []}

        # we search for packages only in the allowed channels - build
        # the SQL helper string and dictionary to make the foo IN (
        # list ) constructs use bind variables
        qlist = []
        qdict = {}
        for c in channel_list:
            v = c["id"]
            k = "channel_%s" % v
            qlist.append(":%s" % k)
            qdict[k] = v
        qlist = string.join(qlist, ", ")

        # This query is kind of big. One of these days I'm gonna start
        # pulling them out and transforming them into views. We can
        # also simulate this using several functions exposed out of
        # rhnChannel, but there is no difference in speed because we
        # need to do more than one query; besides, we cache the hell
        # out of it
        h = rhnSQL.prepare("""
        select distinct
            pn.name,
            pe.version,
            pe.release,
            pe.epoch,
            e_sq.errata_advisory,
            e_sq.errata_synopsis,
            e_sq.errata_id
        from
            rhnPackageName pn,
            rhnPackageEVR pe,
            rhnChannelNewestPackage cnp
        left join
            (   select  sq_e.id as errata_id,
                        sq_e.synopsis as errata_synopsis,
                        sq_e.advisory as errata_advisory,
                        sq_ep.package_id
                from
                        rhnErrata sq_e,
                        rhnErrataPackage sq_ep,
                        rhnChannelErrata sq_ce
                where   sq_ce.errata_id = sq_ep.errata_id
                        and sq_ce.errata_id = sq_e.id
                        and sq_ce.channel_id in ( %s )
            ) e_sq
          on cnp.package_id = e_sq.package_id
        where
            cnp.channel_id in ( %s )
        and cnp.name_id = pn.id
        and cnp.evr_id = pe.id
        """ % (qlist, qlist))
        h.execute(**qdict)

        plist = h.fetchall_dict()

        if not plist:
            # We've set XMLRPC-Encoded-Response above
            ret = xmlrpclib.dumps((ret, ), methodresponse=1)
            return ret

        contents = {}

        for p in plist:
            for k in list(p.keys()):
                if p[k] is None:
                    p[k] = ""
            p["nevr"] = "%s-%s-%s:%s" % (p["name"], p["version"], p["release"],
                                         p["epoch"])
            p["nvr"] = "%s-%s-%s" % (p["name"], p["version"], p["release"])

            pkg_name = p["name"]

            if pkg_name in contents:
                stored_pkg = contents[pkg_name]

                s = [
                    stored_pkg["name"], stored_pkg["version"],
                    stored_pkg["release"], stored_pkg["epoch"]
                ]

                n = [p["name"], p["version"], p["release"], p["epoch"]]

                log_debug(7, "comparing vres", s, n)
                if rhn_rpm.nvre_compare(s, n) < 0:
                    log_debug(7, "replacing %s with %s" % (pkg_name, p))
                    contents[pkg_name] = p
                else:
                    # already have a higher vre stored...
                    pass
            else:
                log_debug(7, "initial store for %s" % pkg_name)
                contents[pkg_name] = p

        ret["contents"] = list(contents.values())

        # save it in the cache
        # We've set XMLRPC-Encoded-Response above
        ret = xmlrpclib.dumps((ret, ), methodresponse=1)
        rhnCache.set(cache_key, ret, last_channel_changed_ts)

        return ret
Esempio n. 2
0
    def new_system_user_pass(self, profile_name, os_release_name,
                             version, arch, username,
                             password, other):
        """ Registers a new system to an org specified by a username, password, and
            optionally an org id.

            New for RHEL 5.

            All args are strings except other.
            other is a dict with:
            * org_id - optional. Must be a string that contains the number. If it's
            not given, the default org is used.
            * reg_num - optional. It should be an EN. It will not be activated. It's
            used for automatic subscription to child channels and for deciding which
            service level to entitle the machine to (managment, provisioning, etc).
            If not given, the machine will only be registered to a base channel and
            entitled to the highest level possible.

            If a profile is created it will return a dict with:
            * system_id - the same xml as was previously returned
            * channels - a list of the channels (as strings) the system was
              subscribed to
            * failed_channels - a list of channels (as strings) that
              the system should have been subscribed to but couldn't be because they
              don't have the necessary entitlements available. Can contain all the
              channels including the base channel.
            * system_slots - a list of the system slots used (as strings).
            * failed_system_slots - a list of system slots (as strings) that they
              should have used but couldn't because there weren't available
              entitlements
            * universal_activation_key - a list of universal default activation keys
              (as strings) that were used while registering.
            Allowable slots are 'enterprise_entitled' (management), 'sw_mgr_entitled'
            (updates), 'monitoring_entitled' (monitoring add on to management), and
            provisioning_entitled (provisioning add on to management).
            The call will try to use the highest system slot available. An entry will
            be added to failed_system_slots for each one that is tried and fails and
            system_slots will contain the one that succeeded if any.
            Eg: Calling this on hosted with no reg num and only update entitlements
            will result in system_slots containing 'sw_mgr_entitled' and
            failed_system_slots containing 'enterprise_entitled'.

            If an error occurs which prevents the creation of a profile, a fault will
            be raised:
            TODO
        """

        add_to_seclist(password)

        log_debug(4,'in new_system_user_pass')

        # release_name wasn't required in the old call, so I'm just going to
        # add it to other
        other['release_name'] = os_release_name

        # Authorize the username and password. Save the returned user object.
        user = self.validate_system_user(username, password)

        # This creates the rhnServer record and commits it to the db.
        # It also assigns the system a base channel.
        server_data = self.create_system(user, profile_name,
                                         version,
                                         arch,
                                         other)
        # Save the returned Server object
        newserv = server_data['server']

        # Get the server db id.
        server_id = newserv.getid()

        # Get the server certificate file
        system_certificate = newserv.system_id()

        log_debug(4, 'Server id created as %s' % server_id)

        failures = []
        unknowns = []

        # Build our return values.
        attempted_channels = []
        successful_channels = []
        failed_channels = []

        actual_channels = rhnChannel.channels_for_server(server_id)
        for channel in actual_channels:
            successful_channels.append(channel['label'])

        # If we don't have any successful channels, we know the base channel
        # failed.
        if len(successful_channels) == 0:
            log_debug(4, 'System %s not subscribed to any channels' % server_id)

            # Look up the base channel, and store it as a failure.
            try:
                base = rhnChannel.get_channel_for_release_arch(
                                                        version,
                                                        arch, newserv['org_id'])
                failed_channels.append(base['label'])
            # We want to swallow exceptions here as we are just generating data
            # for the review screen in rhn_register.
            except:
                pass

        # Store any of our child channel failures
        failed_channels = failed_channels + failures

        attempted_system_slots = ['enterprise_entitled', 'sw_mgr_entitled']
        successful_system_slots = server_lib.check_entitlement(server_id)
        successful_system_slots = successful_system_slots.keys()
        failed_system_slots = []

        # Check which entitlement level we got, starting with the highest.
        i = 0
        for slot in attempted_system_slots:
            if slot in successful_system_slots:
                break
            i = i + 1

        # Any entitlements we didn't have, we'll store as a failure.
        failed_system_slots = attempted_system_slots[0:i]

        universal_activation_key = []
        if rhnFlags.test("universal_registration_token"):
            token = rhnFlags.get("universal_registration_token")
            universal_activation_key = token.get_tokens()

        return { 'system_id' : system_certificate,
                 'channels' : successful_channels,
                 'failed_channels' : failed_channels,
                 'failed_options' : unknowns,
                 'system_slots' : successful_system_slots,
                 'failed_system_slots' : failed_system_slots,
                 'universal_activation_key' : universal_activation_key
                 }
Esempio n. 3
0
    def poll_packages(self, release, server_arch, timestamp = 0, uuid = None):
        log_debug(1, release, server_arch, timestamp, uuid)

        # make sure we're dealing with strings here
        release = str(release)
        server_arch = rhnLib.normalize_server_arch(server_arch)
        timestamp = str(timestamp)
        uuid = str(uuid)

        # get a list of acceptable channels
        channel_list = []

        channel_list = rhnChannel.applet_channels_for_uuid(uuid)

        # it's possible the tie between uuid and rhnServer.id wasn't yet
        # made, default to normal behavior
        if not channel_list:
            channel_list = rhnChannel.get_channel_for_release_arch(release,
                                                                   server_arch)
            channel_list = [channel_list]
        # bork if no channels returned
        if not channel_list:
            log_debug(8, "No channels for release = '%s', arch = '%s', uuid = '%s'" % (
                release, server_arch, uuid))
            return { 'last_modified' : 0, 'contents' : [] }

        last_channel_changed_ts = max(map(lambda a: a["last_modified"], channel_list))

        # make satellite content override a cache caused by hosted
        last_channel_changed_ts = str(long(last_channel_changed_ts) + 1)

        # gotta be careful about channel unsubscriptions...
        client_cache_invalidated = None

        # we return rhnServer.channels_changed for each row
        # in the satellite case, pluck it off the first...
        if channel_list[0].has_key("server_channels_changed"):
           sc_ts = channel_list[0]["server_channels_changed"]

           if sc_ts and (sc_ts >= last_channel_changed_ts):
               client_cache_invalidated = 1


        if (last_channel_changed_ts <= timestamp) and (not client_cache_invalidated):
            # XXX: I hate these freaking return codes that return
            # different members in the dictinary depending on what
            # sort of data you get
            log_debug(3, "Client has current data")
            return { 'use_cached_copy' : 1 }

        # we'll have to return something big - compress
        rhnFlags.set("compress_response", 1)

        # Mark the response as being already XMLRPC-encoded
        rhnFlags.set("XMLRPC-Encoded-Response", 1)

        # next, check the cache if we have something with this timestamp
        label_list = map(lambda a: str(a["id"]), channel_list)
        label_list.sort()
        log_debug(4, "label_list", label_list)
        cache_key = "applet-poll-%s" % string.join(label_list, "-")

        ret = rhnCache.get(cache_key, last_channel_changed_ts)
        if ret: # we have a good entry with matching timestamp
            log_debug(3, "Cache HIT for", cache_key)
            return ret

        # damn, need to do some real work from chip's requirements:
        # The package list should be an array of hashes with the keys
        # nvre, name, version, release, epoch, errata_advisory,
        # errata_id, with the errata fields being empty strings if the
        # package isn't from an errata.
        ret = { 'last_modified' : last_channel_changed_ts, 'contents' : [] }

        # we search for packages only in the allowed channels - build
        # the SQL helper string and dictionary to make the foo IN (
        # list ) constructs use bind variables
        qlist = []
        qdict = {}
        for c in channel_list:
            v = c["id"]
            k = "channel_%s" % v
            qlist.append(":%s" % k)
            qdict[k] = v
        qlist = string.join(qlist, ", ")

        # This query is kind of big. One of these days I'm gonna start
        # pulling them out and transforming them into views. We can
        # also simulate this using several functions exposed out of
        # rhnChannel, but there is no difference in speed because we
        # need to do more than one query; besides, we cache the hell
        # out of it
        h = rhnSQL.prepare("""
        select distinct
            pn.name,
            pe.version,
            pe.release,
            pe.epoch,
            e_sq.errata_advisory,
            e_sq.errata_synopsis,
            e_sq.errata_id
        from
            rhnPackageName pn,
            rhnPackageEVR pe,
            rhnChannelNewestPackage cnp
        left join
	    (	select	sq_e.id as errata_id,
			sq_e.synopsis as errata_synopsis,
			sq_e.advisory as errata_advisory,
			sq_ep.package_id
		from
			rhnErrata sq_e,
			rhnErrataPackage sq_ep,
			rhnChannelErrata sq_ce
		where	sq_ce.errata_id = sq_ep.errata_id
			and sq_ce.errata_id = sq_e.id
			and sq_ce.channel_id in ( %s )
	    ) e_sq
          on cnp.package_id = e_sq.package_id
        where
            cnp.channel_id in ( %s )
        and cnp.name_id = pn.id
        and cnp.evr_id = pe.id
        """ % (qlist, qlist))
        h.execute(**qdict)

        plist = h.fetchall_dict()

        if not plist:
            # We've set XMLRPC-Encoded-Response above
            ret = xmlrpclib.dumps((ret, ), methodresponse=1)
            return ret

        contents = {}

        for p in plist:
            for k in p.keys():
                if p[k] is None:
                    p[k] = ""
            p["nevr"] = "%s-%s-%s:%s" % (
                 p["name"], p["version"], p["release"], p["epoch"])
            p["nvr"] = "%s-%s-%s" % (p["name"], p["version"], p["release"])

            pkg_name = p["name"]

            if contents.has_key(pkg_name):
                stored_pkg = contents[pkg_name]

                s = [ stored_pkg["name"],
                      stored_pkg["version"],
                      stored_pkg["release"],
                      stored_pkg["epoch"] ]

                n = [ p["name"],
                      p["version"],
                      p["release"],
                      p["epoch"] ]

                log_debug(7, "comparing vres", s, n)
                if rhn_rpm.nvre_compare(s, n) < 0:
                    log_debug(7, "replacing %s with %s" % (pkg_name, p))
                    contents[pkg_name] = p
                else:
                    # already have a higher vre stored...
                    pass
            else:
                log_debug(7, "initial store for %s" % pkg_name)
                contents[pkg_name] = p

        ret["contents"] = contents.values()

        # save it in the cache
        # We've set XMLRPC-Encoded-Response above
        ret = xmlrpclib.dumps((ret, ), methodresponse=1)
        rhnCache.set(cache_key, ret, last_channel_changed_ts)

        return ret
Esempio n. 4
0
    def new_system_user_pass(self, profile_name, os_release_name,
                             version, arch, username,
                             password, other):
        """ Registers a new system to an org specified by a username, password, and
            optionally an org id.

            New for RHEL 5.

            All args are strings except other.
            other is a dict with:
            * org_id - optional. Must be a string that contains the number. If it's
            not given, the default org is used.
            * reg_num - optional. It should be an EN. It will not be activated. It's
            used for automatic subscription to child channels and for deciding which
            service level to entitle the machine to (managment, provisioning, etc).
            If not given, the machine will only be registered to a base channel and
            entitled to the highest level possible.

            If a profile is created it will return a dict with:
            * system_id - the same xml as was previously returned
            * channels - a list of the channels (as strings) the system was
              subscribed to
            * failed_channels - a list of channels (as strings) that
              the system should have been subscribed to but couldn't be because they
              don't have the necessary entitlements available. Can contain all the
              channels including the base channel.
            * system_slots - a list of the system slots used (as strings).
            * failed_system_slots - a list of system slots (as strings) that they
              should have used but couldn't because there weren't available
              entitlements
            * universal_activation_key - a list of universal default activation keys
              (as strings) that were used while registering.
            Allowable slots are 'enterprise_entitled' (management), 'sw_mgr_entitled'
            (updates), 'monitoring_entitled' (monitoring add on to management), and
            provisioning_entitled (provisioning add on to management).
            The call will try to use the highest system slot available. An entry will
            be added to failed_system_slots for each one that is tried and fails and
            system_slots will contain the one that succeeded if any.
            Eg: Calling this on hosted with no reg num and only update entitlements
            will result in system_slots containing 'sw_mgr_entitled' and
            failed_system_slots containing 'enterprise_entitled'.

            If an error occurs which prevents the creation of a profile, a fault will
            be raised:
            TODO
        """

        add_to_seclist(password)

        log_debug(4,'in new_system_user_pass')

        # release_name wasn't required in the old call, so I'm just going to
        # add it to other
        other['release_name'] = os_release_name

        # Authorize the username and password. Save the returned user object.
        user = self.validate_system_user(username, password)

        # This creates the rhnServer record and commits it to the db.
        # It also assigns the system a base channel.
        server_data = self.create_system(user, profile_name,
                                         version,
                                         arch,
                                         other)
        # Save the returned Server object
        newserv = server_data['server']

        # Get the server db id.
        server_id = newserv.getid()

        # Get the server certificate file
        system_certificate = newserv.system_id()

        log_debug(4, 'Server id created as %s' % server_id)

        failures = []
        unknowns = []

        # Build our return values.
        attempted_channels = []
        successful_channels = []
        failed_channels = []

        actual_channels = rhnChannel.channels_for_server(server_id)
        for channel in actual_channels:
            successful_channels.append(channel['label'])

        # If we don't have any successful channels, we know the base channel
        # failed.
        if len(successful_channels) == 0:
            log_debug(4, 'System %s not subscribed to any channels' % server_id)

            # Look up the base channel, and store it as a failure.
            try:
                base = rhnChannel.get_channel_for_release_arch(
                                                        version,
                                                        arch, newserv['org_id'])
                failed_channels.append(base['label'])
            # We want to swallow exceptions here as we are just generating data
            # for the review screen in rhn_register.
            except:
                pass

        # Store any of our child channel failures
        failed_channels = failed_channels + failures

        attempted_system_slots = ['enterprise_entitled', 'sw_mgr_entitled']
        successful_system_slots = server_lib.check_entitlement(server_id)
        successful_system_slots = successful_system_slots.keys()
        failed_system_slots = []

        # Check which entitlement level we got, starting with the highest.
        i = 0
        for slot in attempted_system_slots:
            if slot in successful_system_slots:
                break
            i = i + 1

        # Any entitlements we didn't have, we'll store as a failure.
        failed_system_slots = attempted_system_slots[0:i]

        universal_activation_key = []
        if rhnFlags.test("universal_registration_token"):
            token = rhnFlags.get("universal_registration_token")
            universal_activation_key = token.get_tokens()

        return { 'system_id' : system_certificate,
                 'channels' : successful_channels,
                 'failed_channels' : failed_channels,
                 'failed_options' : unknowns,
                 'system_slots' : successful_system_slots,
                 'failed_system_slots' : failed_system_slots,
                 'universal_activation_key' : universal_activation_key
                 }