Skip to content

Salt Text Handling of different Line Endings #36502

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
damon-atkins opened this issue Sep 22, 2016 · 17 comments
Closed

Salt Text Handling of different Line Endings #36502

damon-atkins opened this issue Sep 22, 2016 · 17 comments
Labels
Bug broken, incorrect, or confusing behavior severity-low 4th level, cosemtic problems, work around exists
Milestone

Comments

@damon-atkins
Copy link
Contributor

Description of Issue/Question

I will raise this as a separate issue as its bigger than this PR.
There are multiple competing Line Ending Formats:

  • LF+CR
  • LF
  • CR
  • CR+LF

It's a bad assumptions on Python part that only one type will be on the platform.
Application A on windows may use LF+CR and application B may use LF. Or on Unix you may use salt to generate a file on Unix, which is provide to windows clients using Samba.
Text handling needs to hand all cases on a platform.

Here is an example
C:\salt>salt-call --version
salt-call 2016.3.3 (Boron)

image

I think this will take a brain trust to decide on a way forward.

@Ch3LL
Copy link
Contributor

Ch3LL commented Sep 22, 2016

I want to get a couple more people on this issue to determine how we could move forward these issues because obviously as @lorengordon points out there are multiple issues were this has caused issues.

ping @twangboy @terminalmage @cachedout just wanted to get any of your inputs on whether you think there is an easy way for us to handle these situations within salt which we could track here. thanks

@Ch3LL Ch3LL added the Pending-Discussion The issue or pull request needs more discussion before it can be closed or merged label Sep 22, 2016
@Ch3LL Ch3LL added this to the Blocked milestone Sep 22, 2016
@damon-atkins
Copy link
Contributor Author

damon-atkins commented Sep 22, 2016

I see the option as

  • Editing in place, read the first line (or 1MB or use mmap??) of a text file to determine the line feed before performing any action. eg. regex (.[\r\n].) If file does not exist use **kargs newline='\r\n' or if newline=None use the platforms default newline
  • Use the same line feed as the original file which may come from http:// salt:// etc.

@damon-atkins
Copy link
Contributor Author

damon-atkins commented Sep 22, 2016

From def prepend(path, _args, *_kwargs):

    try:
        with salt.utils.fopen(path) as fhr:
            contents = fhr.readlines()
    except IOError:
        contents = []
    preface = []
    for line in args:
        preface.append('{0}\n'.format(line))
    with salt.utils.fopen(path, "w") as ofile:
        contents = preface + contents
        ofile.write(''.join(contents))
    return 'Prepended {0} lines to "{1}"'.format(len(args), path)

I am adding this here as I suspect this is a general comment as well on handling text files.
prepend() assumes file is small by reading it into memory. It also does not have a back out for disk full e.g. rename original, read original 1MB (or use mmap??) at a time, write out new file. And if back-out needed, rename backup file to original file. Other checks are free disk space to perform the operation. I have also seen Configuration Management Tools backup a file every-time its changes to a backup location.

@lorengordon
Copy link

Couple notes:

  • io.open() also has some of this platform-specific newline logic built-in.
  • I like the idea of reading the first line to determine the line ending, if the file already exists. This can be a utility function.

@stale
Copy link

stale bot commented Jul 4, 2018

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

If this issue is closed prematurely, please leave a comment and we will gladly reopen the issue.

@stale stale bot added the stale label Jul 4, 2018
@damon-atkins
Copy link
Contributor Author

This is still outstanding

@stale
Copy link

stale bot commented Jul 4, 2018

Thank you for updating this issue. It is no longer marked as stale.

@stale
Copy link

stale bot commented Jan 10, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

If this issue is closed prematurely, please leave a comment and we will gladly reopen the issue.

@stale stale bot added the stale label Jan 10, 2020
@stale
Copy link

stale bot commented Jan 13, 2020

Thank you for updating this issue. It is no longer marked as stale.

@stale stale bot removed the stale label Jan 13, 2020
@waynew
Copy link
Contributor

waynew commented Feb 11, 2020

I think there's an even higher (lower?) level perspective here that we need to address, and my answer to

just wanted to get any of your inputs on whether you think there is an easy way for us to handle these situations within salt which we could track here.

is... no.


Historically, (python2), bytes and text was conflated. That meant that you could read fnord.jpg and fnord.txt into the same str in Python. For Salt, this was pretty great, because it meant that we could treat text and binary files the same, and usually get the expected behavior.

With Python3, however, text is unicode and bytes are bytes. If you want to treat something as text, you have to explicitly tell Python that it's text. Or that bytes should be bytes.

Right now Salt mostly assumes that everything is text/UTF-8, rather than requiring that we're told what kind of thing it is. And in many cases, we don't even allow being told that something isn't text. We just treat it all as text.

This fundamental shift in Python2/3 text/bytes separation is great for ensuring that we really have the representation that we expect. But it's also caused a few issues within Salt - and this is one of them. Python, if a file is opened in text mode, will translate '\n' to the appropriate OS line endings. If it's opened in binary mode then whatever bytes we feed the file will be written there - such as LF+CR, CR+LF, LF, CR, or any other weird combination.

The unfortunate part of this problem is that this probably requires a pretty fundamental shift in how Salt thinks about data, and will have an impact throughout the Salt codebase.

@stale
Copy link

stale bot commented Mar 12, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

If this issue is closed prematurely, please leave a comment and we will gladly reopen the issue.

@stale stale bot added the stale label Mar 12, 2020
@lorengordon
Copy link

wow, 30 days? that's a really tight activity window for issues! c'mon @stalebot

@stale
Copy link

stale bot commented Mar 13, 2020

Thank you for updating this issue. It is no longer marked as stale.

@stale stale bot removed the stale label Mar 13, 2020
@Ch3LL Ch3LL added Bug broken, incorrect, or confusing behavior severity-low 4th level, cosemtic problems, work around exists P3 Priority 3 and removed Pending-Discussion The issue or pull request needs more discussion before it can be closed or merged labels Mar 18, 2020
@Ch3LL Ch3LL modified the milestones: Blocked, Approved Mar 18, 2020
@sagetherage sagetherage removed the P3 Priority 3 label Jun 3, 2020
@twangboy
Copy link
Contributor

@damon-atkins Is this still an issue on 3006.2?

@twangboy
Copy link
Contributor

Closing this issue due to age and lack of activity. Please test this on version 3006.2 and create a new issue if the problem persists. The new issue template has more information and will allow us to track and reproduce the issue more effectively. Thanks!

@damon-atkins
Copy link
Contributor Author

@twangboy I do not believe any code changes have happen to resolve this. Salt does not read a file to find out the line ending it users, or allow the user to indicate which line ending to force use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug broken, incorrect, or confusing behavior severity-low 4th level, cosemtic problems, work around exists
Projects
None yet
Development

No branches or pull requests

6 participants