[Spacewalk-list] Ubuntu 18.04 package management in Spacewalk 2.8

Paul-Andre Panon paul-andre.panon at avigilon.com
Tue Dec 18 22:58:55 UTC 2018


On Tuesday, December 11, 2018 4:34 PM, I wrote:
that I had tracked down the false positive "newer" Ubuntu packages to the
rhnServerNeededCache and that it was getting repopulated by the rhn_check.

>After clearing the unwanted entries in the rhnServerNeededCache table, I
verified that the incorrect packages had been >cleared from the package
list for the servers. I then ran rhn_check on one of the clients that had
been cleared and after >some delay (due to queuing a taskomatic task to
update the server's package list?) the incorrect packages came back.
>Hopefully that can help someone else figure out the last few steps of
which task is incorrectly updating >rhnServerNeededCache, why it's doing
it, and fix the bug.

I tracked that down through the taskomatic task triggered by the rhn_check
to the ErrataCacheManager.java reference I had found earlier. Robert P.
helped me find the source for the rhn_server.update_needed_cache stored
proc that gets called in  ErrataCacheManager.java.

Anyways, digging through a few more layers into the definition of the
evr_t type and its comparison overload functions, you eventually get to
Function rpmstrcmp in
spacewalk/schema/spacewalk/postgres/packages/rpm.pkb, which breaks apart
the alphanumeric components of the package version and revision. That
function treats the non-alphanum separators as non-significant, so when
comparing versions in (,8.2.0,1ubuntu2~18.04)  and (,8-20180414,1ubuntu2)
8 = 8, but 20180414 > 2, so the latter evr is considered bigger.

So the latest question is, if we change that function to actually care
about separators, so that '.' (from 8.2.0) > '-' (from 8-20180414), will
that break the comparison for rpm versioning rules? The new function would
be something like (I haven't tested it)

    create or replace FUNCTION rpmstrcmp (string1 IN VARCHAR, string2 IN
VARCHAR)
    RETURNS INTEGER as $$
    declare
        str1 VARCHAR := string1;
        str2 VARCHAR := string2;
        digits VARCHAR(10) := '0123456789';
        lc_alpha VARCHAR(27) := 'abcdefghijklmnopqrstuvwxyz';
        uc_alpha VARCHAR(27) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        alpha VARCHAR(54) := lc_alpha || uc_alpha;
        one VARCHAR;
        two VARCHAR;
        sep1 VARCHAR;
        sep2 VARCHAR;
        isnum BOOLEAN;
    BEGIN
        if str1 is NULL or str2 is NULL
        then
            RAISE EXCEPTION 'VALUE_ERROR.';
        end if;

        if str1 = str2
        then
            return 0;
        end if;
        one := str1;
        two := str2;

        <<segment_loop>>
        while one <> '' and two <> ''
        loop
            declare
                segm1 VARCHAR;
                segm2 VARCHAR;
            begin
                sep1 := ''
                sep2 := ''
                --DBMS_OUTPUT.PUT_LINE('Params: ' || one || ',' || two);
                -- Pull out all separating non-alphanum characters
                while one <> '' and not rpm.isalphanum(one)
                loop
                    sep1 := sep1 || substr(one, 1, 1);
                    one := substr(one, 2);
                end loop;
                while two <> '' and not rpm.isalphanum(two)
                loop
                    sep2 := sep2 || substr(two, 1, 1);
                    two := substr(two, 2);
                end loop;

                str1 := one;
                str2 := two;
                if str1 <> '' and rpm.isdigit(str1)
                then
                    str1 := ltrim(str1, digits);
                    str2 := ltrim(str2, digits);
                    isnum := true;
                else
                    str1 := ltrim(str1, alpha);
                    str2 := ltrim(str2, alpha);
                    isnum := false;
                end if;
                if str1 <> ''
                then segm1 := substr(one, 1, length(one) - length(str1));
                else segm1 := one;
                end if;

                if str2 <> ''
                then segm2 := substr(two, 1, length(two) - length(str2));
                else segm2 := two;
                end if;

                -- if one of the separators is for a point subversion
indicator and the other isn't, then the point subversion is considered
more recent.
                if isnum and sep1 <> '' and sep2 <> ''
                then
                    if sep1 = '.' and sep2 <> '.'
                    then
                        return 1;
	      end if;
                    if sep2 = '.' and sep1 <> '.'
                    then
                        return -1;
	      end if;
                endif

                if segm1 = '' then return -1; end if; /* arbitrary */
                if segm2 = '' then
                                        if isnum then
                                                return 1;
                                        else
                                                return -1;
                                        end if;
                                end if;
                if isnum
                then

                    segm1 := ltrim(segm1, '0');
                    segm2 := ltrim(segm2, '0');

                    if segm1 = '' and segm2 <> ''
                    then
                        return -1;
                    end if;
                    if segm1 <> '' and segm2 = ''
                    then
                        return 1;
                    end if;
                    if length(segm1) > length(segm2) then return 1; end
if;
                    if length(segm2) > length(segm1) then return -1; end
if;
                end if;
                  if segm1 < segm2 then return -1; end if;
                if segm1 > segm2 then return 1; end if;
               one := str1;
                two := str2;
            end;
        end loop segment_loop;

        if one = '' and two = '' then return 0; end if;
        if one = '' then return -1; end if;
        return 1;
    END ;
$$ language 'plpgsql';



-----Original Message-----
From: Paul-Andre Panon <paul-andre.panon at avigilon.com>
Sent: Monday, December 10, 2018 4:51 PM
To: 'spacewalk-list at redhat.com' <spacewalk-list at redhat.com>;
'spacewalk-list at redhat.com' <spacewalk-list at redhat.com>
Subject: RE: Ubuntu 18.04 package management in Spacewalk 2.8

Earlier today I wrote about the changes in PR500. That parsing actually
seems to be OK after all because the EVR entries in the database are OK.

That said, it looks like the spurious package entries are due to spurious
entries in the rhnServerNeededCache table. So the question is what is
populating the rhnServerNeededCache table incorrectly, and why?




More information about the Spacewalk-list mailing list