Bug 1089678

Summary: rhnServerPath table gets updated every time client checks in
Product: [Community] Spacewalk Reporter: Tasos Papaioannou <tpapaioa>
Component: ServerAssignee: Stephen Herr <sherr>
Status: CLOSED CURRENTRELEASE QA Contact: Red Hat Satellite QA List <satqe-list>
Severity: medium Docs Contact:
Priority: medium    
Version: 2.2CC: cperry, jpazdziora, mhuth, tpapaioa
Target Milestone: ---Keywords: Patch
Target Release: ---   
Hardware: All   
OS: All   
Whiteboard:
Fixed In Version: spacewalk-backend-2.2.22-1 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 1089680 (view as bug list) Environment:
Last Closed: 2014-07-17 08:41:04 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1119298, 1207293    

Description Tasos Papaioannou 2014-04-21 14:21:19 UTC
Description of problem:

store_client_route in ./backend/server/rhnServer/server_route.py updates the client's Proxy server information in rhnServerPath every time the client checks in, even though it should only update the information if it actually changed.

gets called every time a client checks in with the Spacewalk server. It's supposed to check whether the client's Proxy server information in rhnServerPath needs to be updated. It pulls the information 

Version-Release number of selected component (if applicable):

spacewalk-backend-server-2.2.20-1

How reproducible:

100%

Steps to Reproduce:

1.) Register a system through a Spacewalk Proxy server.

2.) Verify that the client system appears in rhnServerPath:

rhnschema=# select * from rhnServerPath;

server_id  | proxy_server_id | position | hostname          | created | modified
------------------------------------------------------------------------
1000032541 |      1000027585 |        0 | proxy.example.com | 2014-04-04 08:49:56.143408-05 | 2014-04-04 08:49:56.143408-05

3.) Make the client check in or refresh its profile:

# rhn-profile-sync

4.) Verify that the created and modified times have been updated:

rhnschema=# select * from rhnServerPath;

server_id  | proxy_server_id | position | hostname          | created | modified
------------------------------------------------------------------------
1000032541 |      1000027585 |        0 | proxy.example.com | 2014-04-04 08:54:22.00102-05 | 2014-04-04 08:54:22.00102-05

Actual results:

rhnServerPath updated every time, even though server_route.py contains code to update the table only when the information has changed.

Expected results:

rhnServerPath gets updated only when the client's Proxy path information has changed.

Additional info:

./backend/server/rhnServer/server_route.py expects oldRoute, which contains the client's proxy information pulled from rhnServerPath, to be a list of tuples (see the comment in the code below):

****
def store_client_route(server_id):
    """ Stores the route the client took to get to hosted or the Satellite """

    log_debug(5, server_id)

    # get the old routing information for this server_id
    # oldRoute in this format: [(id0, hostname0),  (id1, hostname1),  ...]
    #                           closest to client, ..., closest to server
    h = rhnSQL.prepare("""
        select position,
               proxy_server_id,
               hostname
          from rhnServerPath
         where server_id = :server_id
        order by position
        """)
    h.execute(server_id=server_id)
    oldRoute = h.fetchall_dict() or []
    newRoute = []
****

The list returned by h.fetchall_dict() is actually a list of dicts:

oldRoute = <type 'list'> [{'position': 0, 'hostname': 'proxy.example.com', 'proxy_server_id': 1000027585}]

whereas newRoute, constructed from the 'X-RHN-Proxy-Auth' http headers sent by the Proxy, is in the expected format:

newRoute = <type 'list'> [('1000027585', 'proxy.example.com')]

So, when oldRoute is compared to newRoute, the comparison always fails, and the server decides to update (with a delete from then an insert into) the table.

****
    if oldRoute == newRoute:
        # Nothing to do here
        # This also catches the case of no routes at all
        return
[...]
    if oldRoute:
        # blow away table rhnServerPath entries for server_id
        log_debug(8, 'blow away route-info for %s' % server_id)
        h = rhnSQL.prepare("""
            delete from rhnServerPath where server_id = :server_id
        """)
        h.execute(server_id=server_id)
[...]
    h = rhnSQL.prepare("""
        insert into rhnServerPath
               (server_id, proxy_server_id, position, hostname)
        values (:server_id, :proxy_server_id, :position, :hostname)
    """)
****

Comment 1 Tasos Papaioannou 2014-04-21 14:35:37 UTC
Proposed patch submitted on GitHub:

https://github.com/spacewalkproject/spacewalk/pull/44

Comment 2 Jan Pazdziora (Red Hat) 2014-04-22 07:04:21 UTC
Could this Spacewalk bugzilla be made public?

Comment 3 Tasos Papaioannou 2014-04-22 13:10:02 UTC
(In reply to Jan Pazdziora from comment #2)
> Could this Spacewalk bugzilla be made public?

Ok, done.

Comment 4 Stephen Herr 2014-04-24 18:30:56 UTC
Thanks for the patch and the great investigative work.

Committing to Spacewalk master:
234558a29db5cbe0f7643421ffab9860e7e6730a

Comment 5 Stephen Herr 2014-04-24 18:45:40 UTC
Correct commit hash for comment 4 is:
4c5c2f21ebb5f7787c85e6785b8859bee16af734

Ignore the hash in comment 4.

Comment 8 Milan Zázrivec 2014-07-17 08:41:04 UTC
Spacewalk 2.2 has been released:

    https://fedorahosted.org/spacewalk/wiki/ReleaseNotes22