Skip to content
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

ini.options_present adds unnecessary whitespaces #33669

Open
giannello opened this issue Jun 1, 2016 · 35 comments
Open

ini.options_present adds unnecessary whitespaces #33669

giannello opened this issue Jun 1, 2016 · 35 comments
Assignees
Labels
Confirmed Salt engineer has confirmed bug/feature - often including a MCVE Feature new functionality including changes to functionality and code refactors, etc. Platform Relates to OS, containers, platform-based utilities like FS, system based apps severity-medium 3rd level, incorrect or bad functionality, confusing and lacks a work around State-Module

Comments

@giannello
Copy link
Contributor

giannello commented Jun 1, 2016

Description of Issue/Question

With the 2016.3.0 release, ini.options_present adds unnecessary (sometimes breaking) whitespaces around the key/value separator

Setup

On 2015.8

test:
  ini.options_present:
    - name: /tmp/test
    - sections:
        DEFAULT_IMPLICIT:
          LANG: 'en_US.UTF-8'
          LC_ALL: 'en_US.UTF-8'

results in

LANG=en_US.UTF-8a
LC_ALL=en_US.UTF-8a

In 2016.3 the following

test:
  ini.options_present:
    - name: /tmp/test
    - sections:
        LANG: 'en_US.UTF-8'
        LC_ALL: 'en_US.UTF-8'

results in

LANG = en_US.UTF-8a
LC_ALL = en_US.UTF-8a

In our specific case, we use ini_manage to handle some files that are sourced by the shell (/etc/default/locales). Adding whitespaces around the "=" breaks the environment.

Also, even if the file already contains the right values and there's no whitespaces around the separator, whitespaces are added and the return message reports that no changes have been applied to the file.

@Ch3LL
Copy link
Contributor

Ch3LL commented Jun 1, 2016

@giannello I am able to replicate this. Looks like this is related to #21592 and #26359

ping @Akilesh1597 looks like this was done on purpose, due ot another user wanting the space in their configuration file. Do you see a solution to this issue? Possibly adding a switch to either add/remove whitespace?

@Ch3LL Ch3LL added Bug broken, incorrect, or confusing behavior P4 Priority 4 severity-medium 3rd level, incorrect or bad functionality, confusing and lacks a work around Platform Relates to OS, containers, platform-based utilities like FS, system based apps labels Jun 1, 2016
@Ch3LL Ch3LL added this to the Approved milestone Jun 1, 2016
@Ch3LL Ch3LL added State-Module Confirmed Salt engineer has confirmed bug/feature - often including a MCVE labels Jun 1, 2016
@Akilesh1597
Copy link
Contributor

The space was added for the purpose of readability of ini file. It would definitely break a file with some evn variable. I'll see if I can add a flag somewhere.

@lorengordon
Copy link
Contributor

How about a separator or assignment param? It can default to '=' and if you want spaces, just set it to ' = '.

@dstensnes
Copy link

This is annoying. It partially breaks usage of this module for me...
Can we please have a fix for this soon?

@lorengordon
Copy link
Contributor

lorengordon commented Nov 16, 2017

Can probably be closed, as #31210 was merged. @Ch3LL?

@boltronics
Copy link
Contributor

@lorengordon #31210 doesn't actually address this issue. The key piece of code in that PR related to this issue is the following line:

' {0} '.format(self.sep) if self.sep != ' ' else self.sep

So if someone adds separator: ' ' to their state file, they can get an ini file looking like this:

[example_1]
some_option on
another_option off

This is as opposed to the default which is:

[example_2]
some_option = on
another_option = off

If someone adds something other than space, they will still also get extra whitespace. eg. if the separator is set to '->' they will get:

[example_3]
some_option -> on
another_option -> off

Now we could instead just change that one line to look like this:

'{0}'.format(self.sep) if self.sep != ' ' else self.sep

This would result in the first example looking the same and the second example doing what @giannello is trying to achieve, but then the third example would look like this:

[example_3]
some_option->on
another_option->off

If an application parser required -> to be surrounded by whitespace, the code change would break that application.

The only clean option I see is to add another argument the user must specify to avoid the whitespace. eg. having a default of trim_whitespace=False which can be changed if the user desires. I can easily implement that... but I question if that's a good thing for the project to have? Are there any use cases for an ini-like file format that cannot have whitespace between the separator character? I do think using this module to generate shell scripts just isn't what it's meant for, and most probably file.replace is a better fit for that sort of task.

Having said that, it's certainly not my call. I'll wait to hear what one of the Salt devs such as @Ch3LL think should be done.

Also, even if the file already contains the right values and there's no whitespaces around the separator, whitespaces are added and the return message reports that no changes have been applied to the file.

I am working to address that here: #50613

@Poil
Copy link

Poil commented Nov 26, 2018

I personally don't like file.replace because if a new version of a package add new options you will not be advertised, (yes I prefer to have something broken)

@boltronics
Copy link
Contributor

@Poil We have ignore_if_missing to control what to do if the file is missing. Perhaps it would make more sense to add something similar - an option there named something like ignore_if_no_matches that does nothing unless set to False, whereby it errors out?

Such an option would be incompatible with append_if_not_found/prepend_if_not_found, but I think would otherwise be relatively straightforward. Would that meet your requirements?

@rjc
Copy link
Contributor

rjc commented May 3, 2019

I've been hit by this issues today, myself.

The easiest way out that I can see is, adjusting the documentation and mentioning the extra (superfluous) spaces around the separator but, at the same time, provide an option to have the separator as '=', without spaces.

Given that there is not actual INI standard, most programs refer to this as INI-style file format, and some are sensitive to spaces around the separator.

If anything, a principle of least surprise should be followed -> '=' used, foo=bar expected; ' = ' used, bar = baz expected; '= ' used, opt= val expected, etc.

BTW, Puppet has done this the right way for years :^)

@rjc
Copy link
Contributor

rjc commented May 8, 2019

As it stands, ini currently only works with a specific type of INI files, i.e.: ones with sections in square brackets ([]), etc.

I just tried to managing /etc/default/exim4 on Debian/Ubuntu and, after the '=' -> ' = ' change, the exim4 service would not start.

Could we take the P4 label off, please? These aren't corner cases any more.

While we're at it, is there any way to make section-less INI-style files easier to manage? Currently, I have to do this:

/etc/default/exim4:
  ini.options_present:
    - sections:
          QUEUERUNNER: "'queueonly'"

I.e. the empty -sections: and spacing before the option: value found by trial and error.

@drel4o
Copy link

drel4o commented May 20, 2019

Hello,

+1 for no spaces around the separator.

Our case is altering apache2 envvars on ubuntu. There is just no other salt module more convenient than this one.
D

@boltronics
Copy link
Contributor

boltronics commented May 21, 2019

Files under /etc/default/ are all expected to be shell scripts that are sourced. Some of those files even have shell functions in them (eg. the one provided by the aufs package)! As for apache vhosts, there is an entire module dedicated to that use-case built in, and I don't see them as even being close to the traditional ini format, which has no concept of things like closing tags.

My take is that both of these fall well outside the scope of ini file management. I've personally never seen an actual ini file that has an issue with whitespace padded around the delimiter, although I'm happy to be corrected if examples can be provided. As such, while I don't have anything against supporting the requested changes discussed here, I would view them both as feature requests, and not bugs per se. I'm a bit surprised the High Severity and Bug tags still remain attached.

One thing that I find very surprising about Salt's ini_manage module is that it wasn't written to use Python's built-in ConfigParser. Going through the commit history, it started out as using a bunch of regular expressions! I think we can do better, and probably wouldn't have seen the subtle change in whitespace behaviour were we letting the built-in library handle the bulk of the work.

I can only theorise that perhaps the ConfigParser included in Python 2.7 wasn't considered flexible enough, although with less than a year now before 2.7 goes EOL, that shouldn't be much of a worry at this point!

@galet
Copy link

galet commented Apr 3, 2020

There is a number of cases where the spaces are problematic and there is no other elegant alternative in Salt. It is very frustrating. Wouldn't a simple change of the default delimiter from '=' to ' = ' and corresponding formatting line solve the problem without significantly breaking backward compatibility?

@rjc
Copy link
Contributor

rjc commented Apr 3, 2020

@galet If I understand correctly, what you are proposing is:

- separator: ' = '

as in three characters - = and a space on either side? With additional spaces removed from formattig that would work. And indeed, no backward compatibility issues! :^)

As long as with:

- separator: '=>'

I don't get spaces around it, then I'm all for it! Great idea! :^)

Thanks!

@boltronics
Copy link
Contributor

Wouldn't a simple change of the default delimiter from '=' to ' = ' and corresponding formatting line solve the problem without significantly breaking backward compatibility?

Unfortunately not. See my comment from Nov 2018 above, where I mention the problem with this and also proposed a possible solution that doesn't break backwards compatibility.

@galet
Copy link

galet commented Apr 6, 2020

@boltronics I agree with you, that's why I used "significantly" in that sentence:) Your proposed solution by adding additional parameter to trim the whitespace is perfectly fine with me.

One could argue example3 is far less common so those usages would be broken and would require changes by users (changing their settings from "->" to " -> "). The question is whether simplicity (avoiding additional parameters) is more valuable than braking the backward compatibility for some users. I'm not in a position to express a preference here.

Unfortunately, shell style variable assignments (no spaces around "=" allowed) are very common for a number of tools or applications. file.maged or file.replace simply cannot be used (e.g. file not completely managed by salt and updated by the application too) or are very cumbersome (file.replace). Therefore, any solution to this issue would be very welcomed.

@boltronics
Copy link
Contributor

Hmm... if using this for shell scripts, I would have thought a good regex with file.replace would be more reliable honestly, but I'd be interested to read about any problematic examples to get a better understanding.

I've looked around my system, and the majority of ini files I have have use " = ". Only one doesn't, but looks like it permits whitespace all the same.

On Windows it's the opposite, where there are some examples of " = " but the majority use "=".

In my personal opinion, we should scan the existing ini file and see what is being used for the first option found (or the option being edited if it already exists) and default to using that, with an option to turn off any auto-detection with a trim_whitespace argument which can either be set to True or False as preferred. If we are working on a brand new ini file with no pre-existing options, we would default to " = " on all hosts except Windows, where we default to "=", and we would document this behaviour.

But maybe this would be too "automatic" for some people's taste? It's also more work to implement.

@rjc
Copy link
Contributor

rjc commented Apr 6, 2020

A real life my.cnf example:

[ndbd]
connect-string=ndb_mgmd.mysql.com

[ndb_mgm]
connect-string=ndb_mgmd.mysql.com

Now, I'd like to manage the former and the latter. Can file.replace do that easily?

@rjc
Copy link
Contributor

rjc commented Apr 6, 2020

IMVHO, the separator should always be verbatim, without spaces around it, i.e.:

' ='
'= '
' = '
'='
'=>'
[...]

By all means, make the default to be backward compatible, but do break backward compatibility if it is the only way to move forward.

@boltronics
Copy link
Contributor

A real life my.cnf example:

But my.cnf does accept whitespace around the = separator. 😃

$ grep -v -e '^#.*$' -e '^$' /etc/mysql/my.cnf
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
$ grep -v -e '^#.*$' -e '^$' /etc/mysql/mysql.conf.d/mysqld.cnf 
[mysqld_safe]
socket		= /var/run/mysqld/mysqld.sock
nice		= 0
[mysqld]
user		= mysql
pid-file	= /var/run/mysqld/mysqld.pid
socket		= /var/run/mysqld/mysqld.sock
port		= 3306
basedir		= /usr
datadir		= /var/lib/mysql
tmpdir		= /tmp
lc-messages-dir	= /usr/share/mysql
skip-external-locking
bind-address		= 127.0.0.1
key_buffer_size		= 16M
max_allowed_packet	= 16M
thread_stack		= 192K
thread_cache_size       = 8
myisam-recover         = BACKUP
query_cache_limit	= 1M
query_cache_size        = 16M
log_error = /var/log/mysql/error.log
expire_logs_days	= 10
max_binlog_size   = 100M
$ 

It's actually the default on Debian. It has been for as long as I can remember.

@sagetherage sagetherage added status-to-do and removed Aluminium Release Post Mg and Pre Si status-in-prog labels Feb 5, 2021
@MurzNN
Copy link

MurzNN commented Apr 25, 2021

So, still no ways to remove unnecessary spaces from ini separators?
To not break old behavior, maybe add separate option to manage spacing rules like:

no_spaces: True

And add spaces to separator variable manually, if this option is false, something like this: #60081

@sagetherage
Copy link
Contributor

@MurzNN

So, still no ways to remove unnecessary spaces from ini separators?
To not break old behavior, maybe add separate option to manage spacing rules like:

no_spaces: True

And add spaces to separator variable manually, if this option is false, something like this: #60081

Good question - I have posted this to our Community Slack workspace https://saltstackcommunity.slack.com/archives/C8832QN4U/p1619474427216100
I will do my best to follow up and I hope this helps.

@MurzNN
Copy link

MurzNN commented Apr 29, 2021

Before this issue is solved, as workaround we can reuse https://docs.saltproject.io/en/latest/ref/states/all/salt.states.augeas.html for manage ini file settings.

@vincent-olivert-riera
Copy link

Any progress on this?

@apokryphal
Copy link

Any updates here? Was the PR ever reviewed?

@boltronics
Copy link
Contributor

I'm not a project member, but the PR looks good to me (although I haven't tried it). I'm guessing it should have a test case associated with it though, which might be why it was not given a closer look.

I'd also prefer it used no_extra_spaces instead of no_spaces for consistency and clarity, but that's a nitpick.

@twangboy twangboy added Feature new functionality including changes to functionality and code refactors, etc. and removed Feature new functionality including changes to functionality and code refactors, etc. labels Aug 21, 2023
@twangboy
Copy link
Contributor

Looks like the fix is here: #60081
Just need to write some simple tests and generate a changelog

@MKLeb MKLeb self-assigned this Aug 29, 2023
@MKLeb MKLeb added Feature new functionality including changes to functionality and code refactors, etc. and removed Bug broken, incorrect, or confusing behavior labels Aug 29, 2023
@sscotter
Copy link

Apologies if this is a newbie error (I've only been using Salt a matter of weeks) but I think the white space around seperator "bug" is still present.

I'm running the following version across a pair of Debian and Ubuntu test hosts.

salt-minion --version
salt-minion 3007.1 (Chlorine)

The following state file...

file_etc_systemd_timesyncd.conf:
  ini.options_present:
    - name: /etc/systemd/timesyncd.conf.d/local.conf
    - separator: '='
    - sections:
        Time:
          NTP: ntp1.domain.local

... produces the following content in /etc/systemd/timesyncd.conf.d/local.conf ...

[Time]
NTP = ntp1.example.local

While the output doesn't break functionality in this case, I personally think it doesn't read well and more importantly seems to be at odds to the fix apparently remediated by #60081 as suggested by twangboy on Aug 21, 2023

@twangboy
Copy link
Contributor

The above PR should address this issue. Thanks, @MurzNN for the idea on how to fix it. It was a little more involved than that, but I think I got it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Confirmed Salt engineer has confirmed bug/feature - often including a MCVE Feature new functionality including changes to functionality and code refactors, etc. Platform Relates to OS, containers, platform-based utilities like FS, system based apps severity-medium 3rd level, incorrect or bad functionality, confusing and lacks a work around State-Module
Projects
None yet
Development

Successfully merging a pull request may close this issue.