Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.

Bug 1423017

Summary: configchannel.createOrUpdatePath() strips the return line '\n' character from the end of the file
Product: Red Hat Satellite 5 Reporter: Marcelo Moreira de Mello <mmello>
Component: APIAssignee: Grant Gainey <ggainey>
Status: CLOSED NOTABUG QA Contact: Red Hat Satellite QA List <satqe-list>
Severity: medium Docs Contact:
Priority: medium    
Version: 570CC: ggainey, lhellebr, mmello
Target Milestone: ---   
Target Release: ---   
Hardware: x86_64   
OS: All   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-05-09 14:34:32 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: 1358815    

Description Marcelo Moreira de Mello 2017-02-16 21:14:52 UTC
Description of problem:

configchannel.createOrUpdatePath() strips the return line '\n' character from the end of the file. 


Version-Release number of selected component (if applicable):
Red Hat Satellite 5.7


How reproducible:
100%


Steps to Reproduce:

--- API script
↪ cat upload_configfile.py 
#!/usr/bin/python
import xmlrpclib
import os
import base64

SATELLITE_URL = "http://orbital.usersys.redhat.com/rpc/api"
SATELLITE_LOGIN = "admin"
SATELLITE_PASSWORD = "redhat"

client = xmlrpclib.Server(SATELLITE_URL, verbose=0)
token = client.auth.login(SATELLITE_LOGIN, SATELLITE_PASSWORD)

cf_channel = raw_input("Config Channel: ")
cfg_path = raw_input("Config File: ")

try:

    if os.path.isfile(cfg_path):
        with open(cfg_path, 'r') as fd:
            isDir = False
            #enc_cfg = base64.b64decode(fd.read())
            enc_cfg = fd.read()

    ct = {}
    ct['contents'] = enc_cfg
    #ct['contents_enc64'] = True
    ct['contents_enc64'] = False
    ct['owner'] = 'root'
    ct['group'] = 'root'
    ct['permissions'] = '644'
    ct['macro-start-delimiter'] = '{|'
    ct['macro-end-delimiter'] = '|}'
    ct['binary'] = False

    ret = client.configchannel.createOrUpdatePath(token, cf_channel, cfg_path, isDir, ct)

except:
    raise
client.auth.logout(token)

   So to test it, the file we want to has this content (with the return line)

# cat /etc/test-file-API 
this is a file
#


   Then uploading it via the and deploying to the client we got the issue reproduced:

↪ ./upload_configfile.py
Config Channel: test-configs
Config File: /etc/test-file-API

 --- on the client

[root@localhost ~]# rm -f /etc/test-file-API ; rhncfg-client get /etc/test-file-API ; cat /etc/test-file-API
Using server name orbital.usersys.redhat.com
Deploying /etc/test-file-API
this is a file[root@localhost ~]

  Note: if we edit the file via webUI and add manually the return line, the file is deployed as expected.


Actual results:

 \n is being stripped on Serializer when file is upload

Expected results:

 respect what the contents of the file


Additional info:

Comment 3 Grant Gainey 2017-02-20 16:35:17 UTC
Attaching a debugger to ConfigChannelHandler.createOrUpdatePath(), and re-running the reproducer, shows me that data['contents'] has already had its trailing newlines stripped. Backing up the stack a ways,  XmlRpcServlet.service() request.request.coyoteRequest.inputBuffer.bodyBuff, shows the newlines are *still there*.

So - the newlines get to the backend correctly, and whatever is removing them happens well before the specific handler gets called. 

Investigation continues.

Comment 5 Grant Gainey 2017-02-20 16:49:18 UTC
See the XMLRPC spec :

https://www.w3.org/2008/xmlsec/Drafts/xml-norm/Overview.html

Search on "TrimTextNodes" :

===
TrimTextNodes of type boolean, defaulting to true
Whether to trim (i.e. remove leading and trailing whitespace) all text nodes while normalizing. Adjacent text nodes must be coalesced prior to trimming. If an element has an xml:space="preserve" attribute, then text node descendants of that element are not trimmed regardless the value of this parameter.
===

I expect we're seeing the default behavior of XMLRPC here.

Comment 6 Grant Gainey 2017-05-03 12:38:12 UTC
*** Bug 1441590 has been marked as a duplicate of this bug. ***

Comment 7 Grant Gainey 2017-05-09 14:34:32 UTC
As noted in #c5 this is redstone-xmlrpc doing its job. If whitespace is *really important*, you need to deal with the file as binary instead of text, to keep redstone's grubby paws off of it.