[HN Gopher] Everything that uses configuration files should repo...
       ___________________________________________________________________
        
       Everything that uses configuration files should report where
       they're located
        
       Author : ingve
       Score  : 1306 points
       Date   : 2023-06-25 07:50 UTC (15 hours ago)
        
 (HTM) web link (utcc.utoronto.ca)
 (TXT) w3m dump (utcc.utoronto.ca)
        
       | jtode wrote:
       | Have my upvote. So many hours lost to "[software package] config
       | file location".
        
         | wspeirs wrote:
         | Agreed! Few things anger me more than when a program simply
         | reports, "File not found"... OK, which file? Where were you
         | looking for said file?
         | 
         | I know how we get here, people simply report the error from the
         | OS w/out adding context. This is why I love anyhow reporting in
         | Rust, you can attach context (like the file name and path) to
         | the error.
         | 
         | In log-store.com I report the default name of the config file
         | (you can specify it via cmdline if you want), and the 3
         | locations and order searched, if the config file isn't found. I
         | also have it report the file being used, so if you expected the
         | file in /etc, but you accidentally had one in your home
         | directory, you'll know on startup.
         | 
         | These things seem like table-stakes in 2023.
        
       | gillesjacobs wrote:
       | Anaconda being by far the worst offender I have encountered. It
       | places a ton of configuration spread out over your home,
       | .condarc, and your shell profile dotfiles, as well as further
       | configuration in the install folder and the of course the project
       | environment.yml file. Good luck finding out the channel
       | precedence.
        
       | Eduard wrote:
       | Programs should not only report where the configuration files are
       | located, but also report how configuration _options_ contained
       | therein are read in:
       | 
       | Some programs use a " _last_ occurrence wins " approach, while
       | other programs (e.g. sshd) use a " _first_ occurrence wins "
       | approach.
       | 
       | Buried in https://man.freebsd.org/cgi/man.cgi?sshd_config(5) and
       | awkwardly expressed:
       | 
       | "Unless noted otherwise, for each keyword, the first obtained
       | value will be used."
       | 
       | That's why e.g. Debian's _/ etc/ssh/sshd_config_ (
       | https://salsa.debian.org/ssh-team/openssh/-/blob/debian/1%25... )
       | starts with                 Include /etc/ssh/sshd_config.d/*.conf
       | 
       | , so that custom configurations in that directory win over the
       | distribution-provided defaults set up after this Include
       | directive inside _/ etc/ssh/sshd_config_.
        
         | bayindirh wrote:
         | If you pass -verbose switch to any of my programs you'll
         | definitely see a line similar to this:
         | verbose: Configuration file found at $PATH.
         | 
         | There are a couple of places I look for my config files: /etc,
         | ~/.config and "./conf", at that order. The last one accelerates
         | testing a great deal.
         | 
         | And every configuration that overrides the built-in defaults
         | are reported one by one.
         | 
         | Also, I started to detail how configuration file works in
         | README.md file, under its section now.
         | 
         | Lastly, I decided to fix all of my tools to work on same specs
         | from now on, regardless of the programming language they're
         | written in:
         | 
         | 1. Use TOML, and TOML only.
         | 
         | 2. Config file overrides the defaults, Command line flags
         | overrides the configuration file.
        
           | cperciva wrote:
           | _Config file overrides the defaults, Command line flags
           | overrides the configuration file._
           | 
           | Don't forget "user configuration file overrides system
           | configuration file (but is overridden by command line)".
           | 
           | In tarsnap the priority (lowest wins) is:
           | 
           | 0: Command line
           | 
           | 1: ~/.tarsnaprc
           | 
           | 2: /etc/tarsnap.conf (may be in a different system etc
           | depending on platform standards)
           | 
           | 3: tarsnap defaults.
        
             | spc476 wrote:
             | Where would configuration options via environment variables
             | fit in? I can see between 0 and 1, or 1 and 2, but can't
             | quite decide which is better.
        
               | cperciva wrote:
               | Not relevant to tarsnap (and in general something I would
               | be very careful about adding since people often don't
               | realize what's in their environment) but I would say that
               | command line options take priority over the environment
               | and the environment takes priority over all configuration
               | files.
        
         | bredren wrote:
         | It would also help if an active process said if it was running
         | using the current config.
         | 
         | For example, if a change has been introduced to a config file,
         | but the process has not been restarted to incorporate those
         | changes, this should be conveniently mentioned.
        
         | jonhohle wrote:
         | Amazon had a hierarchical configuration system for loading
         | config that could override other config (or add to it,
         | depending on the implementation). The Java framework would
         | provide an endpoint to show you the final resolved config along
         | with which file and line that value came from. Very helpful
         | when trying to figure out why config was different than
         | expected.
         | 
         | At least the inspector in Safari (and maybe other WebKit
         | browsers) does something similar for CSS.
         | 
         | I'm all for it. It's a pain when writing config systems (no
         | longer just key/value, but key+value+meta), but very helpful.
         | It can be a pain for things like JSON where libraries don't
         | give you that type of diagnostic information easily, however.
        
           | offbyone wrote:
           | I had the distinct pleasure (?) of owning the C++, Python,
           | and Java implementations of that config for a while and ...
           | yeah, it had some positives, but the fact that it had two
           | orthogonal hierarchies of configuration in addition to
           | implementation-specific feature gaps and nuances made it
           | something of a nightmare in practice.
        
         | cesaref wrote:
         | Agreed, logging in config retrieval code should log all this
         | stuff, requests, where they are filled from, that sort of
         | thing.
         | 
         | The problems with this approach when it's enabled is that log
         | aggregators (e.g splunk) can end up including stuff like
         | passwords which shouldn't be visible to the group able to view
         | those logs, so some care is needed.
        
           | TeMPOraL wrote:
           | Logging keys only should be sufficient for this.
        
           | usrusr wrote:
           | I'd rather have some config reserialization capability with
           | provenance (perhaps as an opt-in). A good config
           | reserialization can make itself useful in so many situations,
           | if it has the right features. Like pointing out key-value
           | pairs that don't have any effect, or simply writing out some
           | documentation.
           | 
           | Logging has its merits, like discoverability when you stare
           | at it without suspecting configuration to be the culprit, but
           | I believe that there can and should be more.
        
         | vishnugupta wrote:
         | While at it I've made it a practice to expose an internal
         | endpoint for every service to output its config. It has saved
         | me on numerous occasions to catch config related bugs.
        
           | simply_seal wrote:
           | Could you explain a little more? I am not sure what exactly
           | you mean by "exposing an internal endpoint" - do you mean
           | that as a secured API endpoint which you can call? Isn't that
           | hard to secure?
        
             | shrimpx wrote:
             | Presumably you can access it while on a secure VPN but not
             | publicly. You can do this by serving the config route on an
             | internal port.
        
               | vishnugupta wrote:
               | Indeed, that's exactly how my team did it.
        
             | delecti wrote:
             | Depending on your environment, endpoints might not default
             | to exposed. As an example where I work, we have to
             | explicitly enumerate endpoints to expose (potentially
             | including wildcards, like admin/*), and anything else is
             | only accessible with direct access to the pod.
        
         | doctorpangloss wrote:
         | It's crazy that a year from now, no one is ever going to be
         | thinking about this garbage ever again. By then, enough
         | programmers will have discovered how insanely good GPT4 is at
         | doing software configuration, and in the absence of the right
         | answer, reading these verbose docs to finally _just_ tell you
         | what to do.
        
         | Eduard wrote:
         | Also: processes / running programs should provide a
         | straightforward way to show their configuration.
         | 
         | While "sshd -T" shows the effective configuration from all
         | configuration file parsing, there is no straightforward way to
         | see the configuration of the/a currently running sshd process.
         | 
         | This has footgun potential, as someone could think their sshd
         | is secured and hardened by checking with "sshd -T", while the
         | actually running sshd process still uses old configurations.
         | 
         | Apache also makes it needlessly hard to find out its effective
         | (and active / currently running) configuration. I don't know of
         | any better way then awkwardly using mod_info (
         | https://httpd.apache.org/docs/2.4/mod/mod_info.html ) to get
         | such insights.
        
           | mike_hock wrote:
           | Not sure I get the reasoning here. That requires you to
           | actually go and proofread the configuration of each and every
           | running process, at which point it's easier to just verify
           | the effective configuration on disk and restart the service.
           | 
           | SSH is a special case because it leaves active sessions alive
           | when it restarts, but that doesn't generalize to other
           | daemons. Just restart if in doubt.
        
         | Shrezzing wrote:
         | It's a little bit away from the domain of config files, but I
         | think CSS is the most graceful example of handling this as a
         | generalised problem. Style configurations cascade, and the last
         | one read is the one that gets applied. There are overrides to
         | that flow, but you have to very overtly add a piece of syntax
         | to the overriding line like `!important`. Two overlapping
         | overrides revert back to the "last read" approach. The approach
         | is so fundamental to CSS that the entire language is named
         | after it, so there's no ambiguity or forwards compatibility
         | concerns in this regard whatsoever.
        
           | wildrhythms wrote:
           | Not true at all. There is a very much non-intuitive weighting
           | system applied to CSS selectors which is what ultimately
           | determines which gets applied:
           | https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
        
           | yard2010 wrote:
           | Fun trick to use if you use a css post processing (less,
           | sass, etc.) is "&&&", it will resolve to a very specific rule
           | which overwrites the other rules
        
           | cesarb wrote:
           | > Two overlapping overrides revert back to the "last read"
           | approach.
           | 
           | IIRC, there's an important (heh) exception to that: user
           | stylesheets. Without the "!important" override on the user
           | stylesheet, the site stylesheet wins; with the "!important"
           | override on the user stylesheet, the user stylesheet wins,
           | even if the site stylesheet also had an "!important" for that
           | rule.
        
           | masklinn wrote:
           | You might want to read on _specificity_ because it's a huge
           | spanner in your assumptions.
        
             | lioeters wrote:
             | > Specificity is the algorithm used by browsers to
             | determine the CSS declaration that is the most relevant to
             | an element, which in turn, determines the property value to
             | apply to the element. The specificity algorithm calculates
             | the weight of a CSS selector to determine which rule from
             | competing CSS declarations gets applied to an element.
             | 
             | https://developer.mozilla.org/en-
             | US/docs/Web/CSS/Specificity...
        
           | lavela wrote:
           | The rules of CSS specificity are a bit more involved than
           | '!important' or not, and I frequently see beginners trip
           | there, but apart from that I agree that the CSS rule set
           | might be worth incorporating.
        
           | fit2rule wrote:
           | [dead]
        
           | blowski wrote:
           | I'm sure you know this, but for readers who don't, it's much
           | more complex than "last defined wins with a few override
           | options". Based on "specificity", rules based on the selector
           | used.
           | 
           | Some examples:
           | 
           | 1. #mydiv overrides .mydiv - IDs are more specific than
           | classes
           | 
           | 2. .outerdiv .innerdiv overrides .innerdiv - nested selectors
           | are more specific
           | 
           | 3. .mydiv overrides div - classes are more specific than
           | elements
           | 
           | And a lot of other rules.
           | 
           | I can't imagine I'd want this level of complexity in config
           | files.
        
             | tobr wrote:
             | > I can't imagine I'd want this level of complexity in
             | config files.
             | 
             | Lots of people don't want it in their CSS either. It's
             | generally considered good practice to make everything the
             | same specificity and avoid !important.
        
               | lavela wrote:
               | > avoid !important
               | 
               | Sure, haven't seen that in a while in well structured
               | code bases.
               | 
               | > make everything the same specificity
               | 
               | How would you achieve same specificity on everything?
               | Only use either ids or classes? No type selectors /
               | pseudo-classes / pseudo-elements / multiple selectors? I
               | can't imagine how that would be feasible and am not aware
               | of anyone recommending this.
        
               | afiori wrote:
               | With :is and :where it is trivial to trick selectors
               | 
               |  _:is(selector_1,_ :where(selector_2))
               | 
               | Has always the specificity of selector_2, and if you
               | choose an impossible selector for selector_1 (the easiest
               | approach is to give multiple ids or use non existent
               | classes/elements) it only select by selector_2
        
               | Supermancho wrote:
               | There are a large number of companies that require ids as
               | the basis for every selector, by policy. This may not be
               | interesting to you, but I think this is what they meant.
               | The fact they may or may not be familiar to you is
               | incidental.
        
               | lavela wrote:
               | I'm familiar with policies that generally strive for
               | specificity of (0, 1, 0) like BEM or (1, 0, 0), but I'd
               | be very interested in any policy that rules out pseudo-
               | classes like `:hover`, as prohibiting them would leave
               | you to handle any interactivity you'd get for free from
               | CSS via JavaScript.
        
               | blowski wrote:
               | This is effectively how Tailwind works. You end up with
               | classes like `hover:text-black`.
        
             | [deleted]
        
             | masklinn wrote:
             | Nesting is not actually more specific.
             | 
             | Rather specificity is a triplet of (ids sub-selectors,
             | class sub-selectors, element sub-selectors). When
             | attributes conflict, the one whose rule has the more
             | specific selector wins.
             | 
             | The specificities of the rules you wrote out are (1,0,0),
             | (0,1,0), (0,2,0), (0,1,0), (0,1,0), and (0,0,1).
             | 
             | In-line attributes (@style) beat out out-out-of line ones
             | except if they're !important. Specificity also
             | disambiguates between !important attributes.
        
               | blowski wrote:
               | Thank you for the clarification, I hadn't realised that.
        
         | rapind wrote:
         | I would prefer a convention... but first wins is backwards IMO.
         | It really sucks when a bad convention gets adopted, like this
         | first wins, or spaces instead of tabs. ;)
        
           | deredede wrote:
           | First wins makes some sense from a security pov. You want to
           | load the more "trusted" configuration files first because
           | they must be able to further restrict the less trusted files,
           | but don't want to let the less trusted files override the
           | settings set by the trusted files.
           | 
           | Rejecting multiple definitions is better, unless you care
           | about DoS (I would be pissed if I got locked out of ssh
           | access due to an option being defined twice, for instance).
        
           | galleywest200 wrote:
           | At least with the spaces/tabs my IDE can automatically
           | convert it for me.
        
           | AlecSchueler wrote:
           | First/last is ambiguous anyway and implementation dependant.
        
             | nebulous1 wrote:
             | How so?
        
               | jonhohle wrote:
               | If there are multiple files in a wildcard pattern, what
               | order are they resolved? I know for classpath loading,
               | for example, it's in directory order, which is file
               | system dependent, and often based on the order the files
               | were written to the directory and/or the size of the
               | directory inode. Lots of fun figuring out why the wrong
               | version of a class is consistently loaded on one or two
               | servers out of twenty. (Always check your classpaths for
               | duplicates kids.)
        
               | usrusr wrote:
               | Oh yes! Good thing if it only happens in the build server
               | and not on deployments, but that can be "fun" enough.
               | Bonus points if you have a culture of repeat builds being
               | "special".
        
               | cesarb wrote:
               | > Always check your classpaths for duplicates kids.
               | 
               | I recently discovered extra-enforcer-rules which can help
               | with that, as long as your classpath comes from Maven
               | dependencies.
        
               | justsomehnguy wrote:
               | > If there are multiple files in a wildcard pattern, what
               | order are they resolved
               | 
               | If you don't care (eg [0]) then do nothing and let the
               | user bang it's head and reinvent the wheel.
               | 
               | If you care - just sort it and mark it as 'platform
               | dependent' or somehow. Nobody really cares for the exact
               | rules and a simple \d\d\\-\w+\\.conf pattern for the
               | filenames is more than enough in 99% of cases.
               | 
               | [0] https://www.zabbix.com/documentation/6.0/en/manual/ap
               | pendix/...
        
               | ycombobreaker wrote:
               | I've always seen this solved by sorting (lexicographical
               | order of bytes, originally). First two characters were
               | digits, for all files within a wildcard directory.
        
               | anilakar wrote:
               | Because "first" and "last" don't convey priority. You
               | have to know how the configuration parser works with
               | defaults and overrides. Does the parser stop reading
               | after the first match? Do later configuration directives
               | override previous ones or are they appended to them, and
               | if they are appended, in which order are they evaluated?
        
               | rapind wrote:
               | > and if they are appended, in which order are they
               | evaluated?
               | 
               | This would be a problem for first wins too.
        
               | nebulous1 wrote:
               | First and last are only ambiguous if we make the order
               | ambiguous though. There's no reason for the order to be
               | ambiguous, and if it is then obviously we can't use
               | first/last. I don't think that first/last are either
               | ambiguous or implementation dependent concepts. The other
               | questions are simply other questions, and aren't directly
               | related to whether the ordering is ambiguous or not.
               | 
               | There are plenty of applications that read a set list of
               | configuration files and use either the first or last
               | setting found. I agree with the responder that the last
               | setting usually makes more sense.
        
         | hinkley wrote:
         | Ant also had first writer wins. I tried to explain this so, so
         | many times to so many people, and only rarely did it stick. On
         | that project I spent way too much time fixing build errors, and
         | ended up rearranging things to make the behavior more obvious
         | rather than less, because without it people would fool
         | themselves into thinking they had it right, because sometimes
         | it would appear to work.
         | 
         | And the thing with developers is that they make lousy
         | scientists. If they want something to work, they'll take any
         | information that supports that theory and run straight to the
         | repository with it.
         | 
         | The trick is not to fool yourself, and you're the easiest
         | person to fool.
        
         | amelius wrote:
         | Also, they should report where logs are written.
        
         | m4lvin wrote:
         | Nice example, which opened a small rabbit hole for me: what
         | does "first occurrence wins" mean for options that are meant to
         | be used multiple times, such as "Port" in sshd_config. The man
         | page only says "Multiple options of this type are permitted.",
         | but now I wonder what happens when I put my own Port into
         | /etc/ssh/sshd_config.d/whatever.conf but leave "Port 22" in
         | sshd_config? Or is the (new since bookworm) default sshd_config
         | commenting it out for this reason?
         | 
         | More generally, for multi-options do we maybe want "first file
         | wins"?
        
           | florbo wrote:
           | Reading in general to more specific configuration directories
           | in order and using the last value read makes the most sense
           | to me. This is usually how I write my own applications.
           | 
           | Anyway, I thoroughly document the order and precedence, but
           | the suggestion from Chris' blog to report more detail about
           | the process is a good one.
        
         | __MatrixMan__ wrote:
         | I prefer the "setting it twice to different values is an error"
         | mode, which isn't especially common.
        
         | Eduard wrote:
         | And yet another gotcha with configuration file loading:
         | 
         | Over-elaborated hierarchies where configuration files may
         | reside, and their precedence schemes.
         | 
         | E.g. from systemd.unit manpage (
         | https://www.freedesktop.org/software/systemd/man/systemd.uni...
         | ):
         | 
         | >...
         | 
         | > In addition to /etc/systemd/system, the drop-in ".d/"
         | directories for system services can be placed in
         | /usr/lib/systemd/system or /run/systemd/system directories.
         | Drop-in files in /etc/ take precedence over those in /run/
         | which in turn take precedence over those in /usr/lib/. Drop-in
         | files under any of these directories take precedence over unit
         | files wherever located. Multiple drop-in files with different
         | names are applied in lexicographic order, regardless of which
         | of the directories they reside in.
         | 
         | > ...
         | 
         | And this is just an excerpt which doesn't cover the details.
         | Read the manpage for all the hilarity.
        
           | nick__m wrote:
           | systemd configuration lookups are lightweights and
           | straightforward compared to ansible variables lookups rules :
           | -- Understanding variable precedence                 Ansible
           | does apply variable precedence, and you might have a use for
           | it. Here is the order of precedence from least to greatest
           | (the last listed variables override all other variables):
           | 1 command line values (for example, -u my_user, these are not
           | variables)                  2 role defaults (defined in
           | role/defaults/main.yml) 1                  3 inventory file
           | or script group vars 2                  4 inventory
           | group_vars/all 3                  5 playbook group_vars/all 3
           | 6 inventory group_vars/* 3                  7 playbook
           | group_vars/* 3                  8 inventory file or script
           | host vars 2                  9 inventory host_vars/* 3
           | 10 playbook host_vars/* 3                  11 host facts /
           | cached set_facts 4                  12 play vars
           | 13 play vars_prompt                  14 play vars_files
           | 15 role vars (defined in role/vars/main.yml)
           | 16 block vars (only for tasks in block)                  17
           | task vars (only for the task)                  18
           | include_vars                  19 set_facts / registered vars
           | 20 role (and include_role) params                  21 include
           | params                  22 extra vars (for example, -e
           | "user=my_user")(always win precedence)
           | 
           | --
           | 
           | that is a RedHat-isim
        
             | hedora wrote:
             | I love how there are 21 places to look if you're trying to
             | figure out why a CLI parameter is being ignored. Does it at
             | least print a warning or something?
        
               | faangsticle wrote:
               | Other way around. Cli params have highest precedence.
        
               | Spivak wrote:
               | And CLI params override _everything_ , globally.
        
             | [deleted]
        
             | pferde wrote:
             | IIRC, Ansible had this exact variable precedence long
             | before they were acquired by RH.
             | 
             | I get that hating RH is in vogue currently, but let's keep
             | it grounded in reality please.
             | 
             | EDIT: And for the record, these Ansible precedence rules
             | are not a bad thing. Once you are somewhat familiar with
             | them, it allows you to write incredibly flexible and
             | extensible playbooks and roles.
        
             | oblio wrote:
             | Meh, it's not Red Hat. Configuration management tools do
             | this. Chef is similar.
        
               | eropple wrote:
               | Chef is _worse_. It 's discouraged to use `override` in
               | Chef cookbooks but nothing says that you can't, and
               | introducing spooky action at a distance is just part of
               | your life now.
        
           | crote wrote:
           | That doesn't look too bad to me.
           | 
           | ".d" directories are a well-established pattern to split a
           | complicated config file into logical units. In the case of
           | something like systemd this is absolutely essential, as you
           | wouldn't want the config for your web server in the same file
           | as the mail server.
           | 
           | /usr/lib is the location where the package manager will drop
           | config files. This is the default, distro-provided
           | configuration. /etc/ is where the administrator can place
           | config files, providing system-specific overrides. /run/ is
           | for files "created at runtime", I am not quite sure what the
           | point of those is.
        
             | andrewaylett wrote:
             | /run is useful for configuration generation. Sure, you
             | could maybe poke an API and have it do the right thing, but
             | if "everything is a file" then why not put your
             | configuration in a file? That way it's easier to see what's
             | actually happening.
             | 
             | Systemd is also a useful demonstration of how to show
             | people where configuration comes from -- `systemctl status
             | <unit>` will include a list of all the files found during
             | lookup, and `systemctl show <unit>` will give you the
             | resolved unit configuration including all the defaults.
        
           | Arnavion wrote:
           | >Over-elaborated hierarchies where configuration files may
           | reside, and their precedence schemes.
           | 
           | >Read the manpage for all the hilarity.
           | 
           | If you find it hilarious it's because you don't understand
           | the reason. /usr belongs to the distribution and /etc belongs
           | to the user. The distribution doesn't touch /etc and the user
           | doesn't touch /usr.
           | 
           | Upstream ships a unit with its own opinion of the defaults.
           | That unit goes in /usr.
           | 
           | Distribution would like to override a default. It can patch
           | the file but that is somewhat harder to discover (it would
           | require reading the package source). Alternatively it can add
           | a drop-in. That drop-in goes into /usr too since it's a
           | distribution file.
           | 
           | User would like to override a default. They should not edit
           | /usr because that belongs to the distribution. They drop
           | their override in /etc.
           | 
           | Some units are created at runtime on demand and thus
           | ephemeral, like mount units generated by generators. These go
           | in /run. These are functionally "system-provided units"
           | because users must be able to override them, so they're below
           | /etc in the hierarchy.
           | 
           | The "defaults" and "overrides" we're talking about are both
           | at the level of the individual setting as well as at the
           | level of the whole file. If a user wants one of the settings
           | to be different, they can add a new 99-foo.conf file that
           | unsets / changes it. If they want a whole file to be
           | different, they can add a new file with the same name that is
           | empty / has different values for its settings.
           | 
           | BTW `systemctl cat whatever.unit` will print all the files
           | that systemd considered in the order that it considered them.
           | 
           | >And this is just an excerpt which doesn't cover the details.
           | 
           | The only detail your excerpt doesn't include is the
           | consideration of `service.d/`, `socket.d/` etc directories
           | which provide overrides for all units of that type. It's just
           | one point, not commonly used, and not that big of a deal
           | either.
        
             | olliecornelia wrote:
             | At least acknowledge how retarded this all sounds.
        
             | gpm wrote:
             | This is why /usr/local/bin is located in /etc right?
        
             | squeaky-clean wrote:
             | I can't see how this doesn't make it more hilarious. It
             | gives me "There's no fighting in the war room" vibes.
        
             | stinos wrote:
             | _and the user doesn 't touch /usr._
             | 
             | So it's _not_ hilarious statements like this make it hard
             | to understand the reason? I almost cannot tell whether your
             | whole post is sarcasm, or just showcasing irony.
        
               | dreamcompiler wrote:
               | X11 clients and servers are now whispering "Hold my
               | beer."
        
               | nickdothutton wrote:
               | I think there is a gap here between those who routinely
               | (exclusively?) used UNIX machines along with 50, 100,
               | 1000 other people all logged in at once (generally pre-
               | Linux era) and those who only ever got to see and enjoy a
               | time when everyone could have a UNIX workstation on their
               | desktop (Linux, Mac, or other x86 flavour, take your
               | pick).
        
               | wpietri wrote:
               | Yeah, I really feel like we're in a "horseless carriage"
               | or "radio with pictures" era for computing. We have
               | incredibly powerful machines available. But the dominant
               | paradigm for managing that power is to slice it up into
               | things that simulate much less powerful processors in
               | software environments designed for a shared 1970s
               | university department minicomputer.
               | 
               | In many ways I love it, of course. It's what I grew up
               | on, and I'm sure I'll have a small Linux cluster in the
               | retirement home, because that's how computers are
               | "supposed to be". But I think the old paradigm has only
               | lasted so long because we have so much computing power to
               | burn.
        
               | jaystraw wrote:
               | I'm not sure I understand. When the "old paradigm" was
               | new, computing power was much more limited. They couldn't
               | afford to "burn" any computing power. But it's only stuck
               | around, because now we have more computing power? That
               | doesn't make sense
        
               | hedora wrote:
               | Back in the shared era, the machines were better-suited
               | to individual customization, and were more easily
               | understood by system administrators. Now, they're
               | optimized too... waste more computational resources when
               | idle?
        
               | marcosdumay wrote:
               | You mean that the top-level Linux directory are
               | hilariously badly named?
               | 
               | If so, I don't think anybody will disagree.
               | 
               | But if you meant that's a large problem, then well, no it
               | isn't. There are 7 of those badly named ones. It's a
               | matter of reading half a page of text to see what they
               | do, and after 2 or 3 times you read it as reference, you
               | have them memorized.
               | 
               | If would be nice to solve the issue, but it isn't
               | anybody's priority.
        
               | eviks wrote:
               | Or you'll never memorize them because those 2 or 3 times
               | are many months apart since you're just a user that
               | rarely tweaks those configs
               | 
               | But yeah, ease of use is nobody's priority
        
               | bayindirh wrote:
               | Yes, "The user (syadmin) doesn't touch /usr, except
               | /usr/local", where compiled in applications reside with
               | full path so /usr/local/{bin,sbin,share,...}.
               | 
               | If you're deploying an especially big application, you
               | may also prefer /opt/$APPNAME/{bin,etc,usr,...} (A full
               | filesystem tree, basically).
               | 
               | We manage a fleet of systems at work, and I don't
               | remember editing or touching a file under /usr, unless
               | the period I was developing .deb or .rpm packages to
               | deploy on said fleet.
               | 
               | There are many written and unwritten rules in Linux
               | world, and sometimes people disregard or ignore these
               | rules so blatantly, so I can't understand whether the
               | post I'm replying to is a sarcasm or irony.
        
               | hedora wrote:
               | The rules are very much written down. For instance, here
               | are the rules for /opt:
               | 
               | https://access.redhat.com/documentation/en-
               | us/red_hat_enterp...
               | 
               | There's also a section for /usr.
        
               | Eldt wrote:
               | It's both hilarious and unintuitive, but for some people
               | their personal familiarity trumps most other things
        
               | pierat wrote:
               | It's makes a lot more sense when you realize that /usr
               | doesn't stand for "user", but "user software resources".
        
               | [deleted]
        
             | hedora wrote:
             | > _Distribution would like to override a default. It can
             | patch the file but that is somewhat harder to discover (it
             | would require reading the package source). Alternatively it
             | can add a drop-in. That drop-in goes into /usr too since
             | it's a distribution file._
             | 
             | > _User would like to override a default. They should not
             | edit /usr because that belongs to the distribution. They
             | drop their override in /etc._
             | 
             | Larry Wall elegantly solved these problems 38 years ago
             | with the "patch" utility. Debian is a good example of how
             | its use has been standardized to solve these problems.
             | 
             | The patch approach to managing distribution-provided
             | configuration files is superior to the systemd unit
             | approach for at least three reasons:
             | 
             | - Non-experts can read the configuration files from top to
             | bottom in linear order, so the documentation can be inlined
             | by the distribution provider, which means they can add
             | maintainers notes as necessary.
             | 
             | - It also works better than the systemd unit style of
             | configuration for sophisticated users. In particular, if
             | you add a now-incompatible option to the file in the
             | suggested place (next to the documentation and commented
             | out default version of the setting), then the package
             | management system can detect that you've made a potentially
             | breaking change before installing the new software, and ask
             | you what to do. This works in the absence of sophisticated
             | data modeling, schema mapping tools, etc.
             | 
             | - The implementation of all this is factored out and
             | standardized across 1000's of packages, so it only needs to
             | be implemented once and understood once.
        
               | manuel_w wrote:
               | Rebasing patches is pretty hard I'd say. Much harder than
               | just explaining someone the logic behind /lib, /etc and
               | /run. I mean, this directories are seperate for a reason.
               | Knowing the idea behind the directory split (a.k.a. Linux
               | Filesystem Hierarchy Standard) is more essential than
               | knowing how to use the patch command line tool. There are
               | more and more people who don't want to use the command
               | line. And that's completely fine.
               | 
               | > - It also works better than the systemd unit style of
               | configuration for sophisticated users. In particular, if
               | you add a now-incompatible option to the file in the
               | suggested place (next to the documentation and commented
               | out default version of the setting), then the package
               | management system can detect that you've made a
               | potentially breaking change before installing the new
               | software, and ask you what to do. This works in the
               | absence of sophisticated data modeling, schema mapping
               | tools, etc.
               | 
               | Anecdata, but still: Every single time the package
               | manager asked me what to do, it was not because of a
               | breaking change, but simply because the base file changed
               | in a way that the patch didn't apply cleanly anymore.
               | That is, I, the user, had to work around limitations of
               | the patch format. If the distro configuration and the
               | user configuration had been separate files, things would
               | have just worked fine.
        
               | faangsticle wrote:
               | You don't have to be an expert to read multiple files. If
               | you do need expert assistance with something like that
               | please contact me and we can work something out.
        
               | eviks wrote:
               | The "expertise" is in finding those files and
               | understanding their hierarchy
        
             | wpietri wrote:
             | > If you find it hilarious it's because you don't
             | understand the reason.
             | 
             | I think it's hilarious that you think users are supposed to
             | understand "the reason" at this level of detail.
             | 
             | When we make a thing, we make choices about who it's for.
             | Sometimes those choices are explicit. But this is a good
             | example of an implicit choice. Clearly it grew into this
             | shape for reasons, but those reasons are about the people
             | doing the making, not the people using it.
             | 
             | Even if we grant that all of this hierarchy is necessary,
             | it still imposes a large burden on the person trying to
             | figure out "why is X doing Y?" And that might be fine if
             | the makers said, "Well this is going to be hard, so what
             | can we do to make it easy?"
             | 
             | But denying that users will reasonably find this hilarious
             | (or frustrating or impossible) is just digging the hole
             | deeper. Telling people that their understandable reactions
             | are wrong doesn't change their reactions, it just gets them
             | to stop mentioning the problems around you.
        
               | faangsticle wrote:
               | [flagged]
        
               | monkeywork wrote:
               | not sure how you thought your comment here would be
               | useful. If snark is the only option sometimes it's better
               | to just close the browser.
        
               | wpietri wrote:
               | Well that's hilarious too, in that I just pointed you to
               | a bigger context.
        
               | thayne wrote:
               | > it still imposes a large burden on the person trying to
               | figure out "why is X doing Y?"
               | 
               | Systemd has tools for that, such as systemctl cat which
               | shows all applicable configuration and what files they
               | come from.
               | 
               | Personally I have found the systemd hierarchy to be very
               | useful. It allows me to create overrides for certain
               | properties in a Unit without having to worry about
               | keeping the rest in sync with upstream, or my package
               | manager overwriting my configuration. And it allows me to
               | have different independent packages (or chef recipes or
               | ansible playbooks) that create different override files
               | for the same unit without stepping on each others toes.
               | 
               | Yes it is a little complicated, but for most end users,
               | you don't really need to worry about most of the
               | complexity, you just need to know where you put your
               | overrides. And for distributors and power users, that
               | complexity serves a useful purpose.
        
               | wpietri wrote:
               | > Systemd has tools for that, such as systemctl cat which
               | shows all applicable configuration and what files they
               | come from.
               | 
               | Sure, it could be that systemd does have amazing tooling
               | for helping users with the burdens they have created. Or,
               | given the very mixed feelings about systemd, maybe
               | they've tried to be user focused but not hit the mark. I
               | don't know enough to say.
               | 
               | But my point is that either way responses of the form
               | "it's so easy, you just have to remember [9 paragraphs of
               | detail users don't care about]" are part of the problem,
               | not the solution.
        
               | ibrahima wrote:
               | Systemd didn't create this problem. But it solves the
               | issue of distributions shipping config files as part of
               | packages and then on every package upgrade having to
               | reconcile between the distribution's config and your
               | modifications. Now with the drop in system you don't need
               | to do that.
               | 
               | I am not an expert but I think in general systemd has a
               | lot of complexity but it's to handle existing issues in a
               | better way. Some of the older init systems might be
               | simpler to describe or get started but lead to more
               | confusing situations in the long run.
        
               | darkwater wrote:
               | "Make it as easy as possible, but not simpler". I think
               | this applies perfectly here. Systemd has very complicated
               | requirements due to its very unique position in a Linux
               | distribution. And as a (power) end-user of it, you
               | basically need you basically needs to touch only /etc
        
               | danaris wrote:
               | > Systemd has very complicated requirements due to its
               | very unique position in a Linux distribution.
               | 
               | But are all those requirements _actually_ necessary for
               | the job it 's doing? Or have its developers imposed
               | artificial constraints through their choices in designing
               | systemd that make it _more_ complex than it could
               | otherwise be?
        
           | qbasic_forever wrote:
           | Drop in files (config in .d folders) are a core extension
           | point of systemd and not a symptom of an overly engineered
           | config system. These are how services are meant to be custom
           | tailored to specific machines and even user's needs.
           | 
           | Let's say you need to pass a special flag to sshd on your
           | system, a bad approach would be to go edit the distro shipped
           | sshd.service file. Your change will work until the distro
           | ships an updated file and you forget to hack in your change
           | again.
           | 
           | Instead place a sshd.service drop-in config file in the
           | appropriate place to customize the service as necessary. Your
           | config tweak takes precedence over the distro shipped config,
           | but doesn't live inside it or conflict with upstream changes.
        
         | micheles wrote:
         | This is good advice and my own software is following it:
         | 
         | $ oq info cfg
         | 
         | Looking at the following paths (the last wins)
         | 
         | /opt/openquake/oq-engine/openquake/engine/openquake.cfg
         | 
         | /opt/openquake/venv/openquake.cfg
         | 
         | However, I do not think there is any standard API to follow, I
         | used "info cfg" but many alternatives were possible. So
         | sysadmins have to explore to find out which is the
         | introspection command to give. Not ideal, but I don't think
         | there is a solution.
        
           | kataklasm wrote:
           | I would look for something like this in the help output, i.e.
           | --help or -h. And of course the manpage if you do supply one.
        
             | cesarb wrote:
             | Another good place for that is the --version output, if
             | your --version is one of those verbose multi-line ones
             | (instead of a basic single-line output).
        
       | bartq wrote:
       | I disagree it's responsibility of the tool. Program should just
       | reach out for files and some higher order or meta runner should
       | trace what the process does. One of the commenters mentioned
       | `strace`, this is the correct approach, but should be done in
       | well engineered way.
       | 
       | Other way is to run program in symbomlic interpreter and trace
       | what it wants to read in any of the branches.
        
         | ufo wrote:
         | Might work for config files but would it work for environment
         | variables?
        
           | bartq wrote:
           | It would for env vars as well, why not? Just trace program
           | trying to reach out for some var X from env.
        
             | mvnuweucxqokii wrote:
             | afaik reading env vars requires no sys calls and thus will
             | not appear in strace
        
               | bartq wrote:
               | So there should be a different tool used which will
               | intercept environment variables reads and will log them.
        
         | hermannj314 wrote:
         | This seems to be an interesting approach.
         | 
         | Why do you suggest this path over documentating the behavior
         | explicitly?
         | 
         | What makes one approach better the other? Is it faster to run a
         | trace? Should a developer trace their own code and auto-
         | generate documentation post-build?
        
       | rewmie wrote:
       | This is a high quality blog post. It raises awareness of a
       | usecase that's always been there but it might never surfaced, it
       | goes straight to the point, and provides clear examples.
       | 
       | It's a blog post where everyone ends up being slightly better
       | after reading it.
        
       | m0rissette wrote:
       | Strace, filter in open calls?
       | 
       | Lsof, find files open on running proc?
       | 
       | Problem solved?
        
       | swayvil wrote:
       | A daemon that watches everything that reads and writes. Reports
       | everything that looks like a config file, what accessed it, where
       | it's located ...
       | 
       | That might be useful.
        
       | bennettnate5 wrote:
       | I've found strace | grep "open" particularly useful for locating
       | config files. They're usually opened right at the start of the
       | program as well.
       | 
       | (For reference, strace prints out every system call used by a
       | program with the arguments that were called; occasionally, a
       | program may use something other than `open` or `fopen` to read in
       | a file, so that should be kept in mind when using this method)
        
         | remram wrote:
         | strace has its own filtering mechanism, so you can do `strace
         | -e open`. Though you might have to add `,openat,openat2` so
         | maybe your way is easier in practice.
        
       | seiferteric wrote:
       | I've mentioned this before in a comment long ago that I thought
       | there should be a library for configurations, like libconfig.
       | This would expose an API that a program could get it's config
       | from, then the user could decide in which format they would like
       | to keep their configs, like ini, json, yaml etc and could
       | translate between them. Then you could get like a unified config
       | for your system.
        
       | klabb3 wrote:
       | I maintained a CLI tool for a long time. I came to the conclusion
       | that good config is a bit harder and more subtle than most people
       | think. I agree with the premise of the article, but there are
       | more layers to it, literally.
       | 
       | Depending on how much config you have, sooner rather than later
       | you'll have multiple sources: system defaults, user config files,
       | sometimes profiles, env vars, and flags. Configuration may be
       | sourced from a combination of these, so overrides need to be
       | handled and naming needs to be consistent. Another source of mess
       | is deeply nested config, such as for a user-defined project.
       | Those are very awkward to add flags for, in which case it's
       | better to enforce a file (like kubernetes config).
       | 
       | To me, tools like git strikes a good balance. And by that I mean
       | that project-local config is in a project root directory that's
       | not necessarily checked in to VCS, but picks up the config even
       | if you're in a subdir. It rarely causes any unwanted surprises,
       | but at the cost of being somewhat flag heavy, which is then
       | alleviated with user-defined aliases.
        
       | samlittlewood wrote:
       | My goto for this is 'strace'
        
       | [deleted]
        
       | aaron695 wrote:
       | [dead]
        
       | nraynaud wrote:
       | thanks for pointing that out, I'll make sure to include it next
       | time I write a new application.
        
       | vaughands wrote:
       | A quick and dirty way to do this is run the program through
       | `strace` and find out what syscall it issues to read it.
       | 
       | I had to do this to figure out where Cold Steel was reading save
       | files from years back:
       | https://vaughanhilts.me/blog/2018/02/16/playing-trails-of-co...
        
         | userbinator wrote:
         | On Windows, Process Monitor does the same thing --- with the
         | additional feature that, since configuration is often stored in
         | the registry there, it will also show which registry keys it
         | touches.
        
         | rafark wrote:
         | Interesting. I didn't know you could do this. I can see how
         | this can come in handy. Apparently there's dtruss as an
         | alternative for OS X.
         | 
         | https://8thlight.com/insights/dtrace-even-better-than-strace...
        
           | sharikous wrote:
           | No more. At least with apple Silicon dtrace is completely
           | unusable.
        
             | tanelpoder wrote:
             | There's also fs_usage that doesn't require disabling SIP:
             | 
             | https://mohit.io/blog/fs_usage-trace-file-system-calls-on-
             | ma...
        
             | comex wrote:
             | It still works if you turn off SIP. This is the same on
             | Apple Silicon and Intel. However, for these purpose of
             | tracking file accesses, I recommend using `eslogger`
             | instead, as it doesn't require disabling SIP and is faster,
             | among other advantages.
        
               | viraptor wrote:
               | On M2 it is completely broken. Any usage of dtrace will
               | hang the whole desktop. (Not sure if just the desktop or
               | is it the whole kernel crashing)
               | 
               | Feel free to reference my feedback entry FB12061147 if
               | you're reporting the same.
        
               | k4ch0w wrote:
               | Use fs_usage. https://ss64.com/osx/fs_usage.html
               | 
               | It'll show all file events. No need to disable SIP. SIP
               | is doing a lot of good work for users and unless you're
               | doing kernel work or low level coding I'd keep it
               | enabled. Obv. There are other cases but for the general
               | public keep it on.
        
               | zarzavat wrote:
               | It's personal preference. If the security people had
               | their way we'd all be developing on iPads. If SIP
               | interferes with your work: turn it off. Linux doesn't
               | have SIP and it's just fine to develop on Linux as well.
        
               | djxfade wrote:
               | You can also use Activity Monitor and view process
               | details to see all open file handles etc
        
               | lost_tourist wrote:
               | Sure but I don't think that most programs keep their
               | config files open the whole time they're running.
        
             | chiggsy wrote:
             | There was a man who never existed named Thomas Covenant,
             | created by Stephen R Donaldson. Decades ago this character
             | said something that has stayed and will stay with me my
             | entire life:
             | 
             | "The best way to hurt somebody who's lost everything is to
             | give him back something that is broken."
             | 
             | For us, this thing is MacOS. I miss dtrace every damn day.
             | 
             | DTrace allowed you to ask the damn os what it was doing,
             | since the man pages are random and do not match the command
             | line help, new daemons constantly appear with docs like
             | this:
             | 
             | NAME rapportd - Rapport Daemon.
             | 
             | SYNOPSIS Daemon that enables Phone Call Handoff and other
             | communication features between Apple devices.
             | Use '/usr/libexec/rapportd -V' to get the version.
             | 
             | Dogshit.
        
               | gjvc wrote:
               | OS X was the last chance the industry had to make a
               | "commercial unix workstation", and Apple came >< close.
               | Stallman was right.
        
         | w4rh4wk5 wrote:
         | +1 for putting together that blog post on Cold Steel. Greetings
         | from PH3 ;)
        
           | vaughands wrote:
           | Thank you for your efforts!
           | 
           | These days Proton makes a lot of this unnecessary. I hope
           | Trails games will continue to at least function on Linux. :)
        
         | p-e-w wrote:
         | strace uses ptrace, which some programs disable with prctl as a
         | security measure.
         | 
         | So while this can be a useful hack, it doesn't always work.
        
           | patrec wrote:
           | You can use sysdig instead, which doesn't use ptrace[1] and
           | is much faster (as well as generally more pleasant and
           | powerful).
           | 
           | [1]It used to have its own kernel extension but is eEBF based
           | these days.
        
             | everybodyknows wrote:
             | Users should be aware that `sudo apt install sysdig` may
             | require reconfiguration of UEFI Secure Boot, and that there
             | is no apparent clean abort from this possible. The raw-mode
             | terminal screen contains the text:
             | +------------------------+ Configuring Secure Boot
             | +------------------------+       |
             | |        | Your system has UEFI Secure Boot enabled.
             | |        |
             | |        | UEFI Secure Boot requires additional
             | configuration to work with           |        | third-party
             | drivers.
             | |        |
             | |        | The system will assist you in configuring UEFI
             | Secure Boot. To permit     |        | the use of third-
             | party drivers, a new Machine-Owner Key (MOK) has been    |
             | | generated. This key now needs to be enrolled in your
             | system's firmware.   |        |
             | |        | To ensure that this change is being made by you
             | as an authorized user,    |        | and not by an
             | attacker, you must choose a password now and then confirm
             | |        | the change after reboot using the same password,
             | in both the "Enroll      |        | MOK" and "Change Secure
             | Boot state" menus that will be presented to you   |
             | | when this system reboots.
             | |        |
             | |        | If you proceed but do not confirm the password
             | upon reboot, Ubuntu will   |        | still be able to boot
             | on your system but any hardware that requires       |
             | | third-party drivers to work correctly may not be usable.
             | |        |
             | |        |                                  <Ok>
             | |        |
             | |        +-------------------------------------------------
             | --------------------------+
             | 
             | This leads to a second screen asking for a new password.
             | There is a <Cancel> option, but selecting it merely loops
             | back to the first screen.
             | 
             | Hitting C-c (Control-c) has no effect.
             | 
             | There are validity rules for the password, but they are
             | presented only after you've entered an invalid password,
             | twice, the second time to confirm.
             | 
             | After this installation proceeds, then terminates with a
             | warning:                 DKMS: install completed.
             | Processing triggers for man-db (2.9.1-1) ...
             | Processing triggers for libc-bin (2.31-0ubuntu9.9) ...
             | W: Operation was interrupted before it could finish
             | 
             | Where the "W:" above is colored red.
             | 
             | Distro was Ubuntu 20.04.
        
               | patrec wrote:
               | I suspect that's just because you're trying to install an
               | old version (as I wrote sysdig used to have a kernel
               | extension but now should use eBPF functionality provided
               | in stock kernels). I can't easily verify (no ubuntu at
               | hand), but presumably if you install the vendor supplied,
               | up-to-date version (first google hit I found:
               | https://www.linuxcapable.com/how-to-install-sysdig-on-
               | ubuntu...) it will work without UEFI changes.
        
           | chungy wrote:
           | Can't disable DTrace :)
           | 
           | Though DTrace is "only" available on Windows, Mac OS X,
           | Solaris, illumos, and FreeBSD.
           | 
           | Oracle has relicensed DTrace to be Linux-friendly and even
           | made kernel patches, but it'll probably never end up in the
           | mainline kernel.
        
             | viraptor wrote:
             | On Linux you can use bpftrace which is basically the same
             | thing with slightly different names.
        
             | oblio wrote:
             | > Though DTrace is "only" available on Windows
             | 
             | Is it stable and production ready for heavy duty workloads?
        
               | chungy wrote:
               | Microsoft ships it, so I assume so? I haven't personally
               | ran any versions beyond Windows 7, I can't directly
               | comment on any features after that.
        
         | westurner wrote:
         | ps wxa | grep <cmd>  # or pgrep       strace -f -f -e
         | trace=file <cmd> | grep -v '-1 ENOENT (No such file or
         | directory)$'
         | 
         | IIRC there's some way to filter ENOENT messages with strace
         | instead of grep?
         | 
         | Strace: https://en.wikipedia.org/wiki/Strace
        
           | msm_ wrote:
           | I use quick and dirty greps all the time, even when there is
           | a "better" option available. It just works and is very
           | intuitive in interactive contexts. Probably GP works in a
           | similar way.
        
         | hoherd wrote:
         | I do this with Brendan Gregg's opensnoop, which is standard on
         | macOS.
         | 
         | https://www.brendangregg.com/blog/2014-07-25/opensnoop-for-l...
         | 
         | https://github.com/brendangregg/perf-tools/blob/master/opens...
        
         | EdwardDiego wrote:
         | All that time I spent dicking around with lsof...
        
         | kevincox wrote:
         | I do this much more frequently than I would like. But
         | occasionally you have issues where the program lists a
         | directory then only acts on specific names. So the strace
         | output won't tell you what the expected name is.
        
       | egberts1 wrote:
       | Fastest way to identify hidden and dynamic configuration
       | filenames:                   strace -f <executable-file> | grep
       | openat
       | 
       | Yeah, I was just looking at the biggest offender that I have
       | encountered: Debian's update-ca-certificates, 37 hidden
       | configuration files.
        
         | egberts1 wrote:
         | Details of hidden files opened by Debian's update-ca-
         | certificates:
         | 
         | https://egbert.net/blog/articles/ca-certificates-rebuild-on-...
         | 
         | /etc/ca-certificates.conf file
         | 
         | /usr/share/ca-certificates/* directory
         | 
         | /usr/share/ca-certificates/mozilla/* directory
         | 
         | /usr/share/ca-certificates/ _/_ directory
         | 
         | /usr/local/share/ca-certificates/* directory
         | 
         | /usr/local/share/ca-certificates/ _/_ directory
         | 
         | /etc/ssl/certs directory $CWD/<all-certs-read-before> files
         | 
         | /usr/lib/ssl/openssl.cnf file
         | 
         | /etc/ca-certificates/update.d directory
         | 
         | /etc/ca-certificates/update.d/jks-keystore directory
         | 
         | /etc/default/cacerts directory
         | 
         | /etc/java-11-openjdk/security/nss.cfg file
         | 
         | /usr/share/ca-certificates-java directory
         | 
         | /usr/lib/jvm/java-11-openjdk-amd64/lib/jvm.cfg file
         | 
         | /usr/share/ca-certificates-java/ca-certificates-java.jar file
         | 
         | /etc/ca-certificates/update.d/mono-keystore directory
         | 
         | /etc/mono/4.5/machine.config file
         | 
         | /etc/mono/assemblies/cert-sync/cert-sync.config file
         | 
         | /etc/mono/assemblies/Mono.Security/Mono.Security.config file
         | 
         | /etc/mono/assemblies/mscorlib/mscorlib.config file
         | 
         | /etc/mono/assemblies/System/System.config file
         | 
         | /etc/mono/config file
         | 
         | /etc/ssl/certs/ca-certificates.crt file
         | 
         | $HOME/.mono/config file
         | 
         | /usr/lib/mono/4.5/cert-sync.exe.config file
         | 
         | /usr/lib/mono/4.5/cert-sync.exe.config file
         | 
         | /usr/lib/mono/4.5/mscorlib.dll.config file
         | 
         | /usr/lib/mono/gac/Mono.Security/4.0.0.0_0738eb9f132ed765/Mono.S
         | ecurity.dll.config file
         | 
         | /usr/lib/mono/gac/System/4.0.0.0__b77a5c561934e089/System.dll.c
         | onfig file
         | 
         | /usr/share/.mono/certs/Trust/ski-*.cer file
         | 
         | /usr/share/.mono/certs/new-certs/XXXXXXXX.0 file
         | 
         | $CWD/openssl EXECUTABLE!!! (why look in $CWD?)
         | 
         | /usr/bin/openssl
         | 
         | /usr/local/bin/openssl
         | 
         | /usr/local/sbin/openssl
         | 
         | /usr/sbin/openssl (VERY STRANGE ordering of
         | /usr/[local/][s]bin/
        
       | jmholla wrote:
       | This also applies to code generation. At my first job out of
       | college, it was difficult to piece together where a particular
       | bit auto-created code came from. At my second job, I pushed
       | everyone to ensure that code generated files pointed to their
       | sources (configuration files and generating code). Ultimately,
       | one of our engineers designed it into our codegen framework so
       | well, it basically came for free for our developers. And boy was
       | it so nice to not wonder where the knobs were that changed your
       | output.
       | 
       | On a side note, we also checked in the codegened files and that
       | was great for other reasons like reviewability and searchability.
        
       | malf wrote:
       | strace -e open
        
       | kaba0 wrote:
       | Easier option: sandbox each executable, so every output file will
       | be located in a special folder.
        
       | nilslindemann wrote:
       | Basically the location of everything should be exposed to the
       | user, especially if he is the reader of the source code.
        
       | radarsat1 wrote:
       | It should be easier to track file opening history of any running
       | program. There is strace, but grepping/parsing the output for
       | this purpose gets very messy.
        
       | WirelessGigabit wrote:
       | And... one of my pet peeves with configurations is that people
       | delete everything that is commented.
       | 
       | Like helm chart definitions. Now there is an upgrade of the
       | chart, and I need to go and trace down which value changed.
       | 
       | Well, if we would've kept the commented stuff I could overlay it
       | with the new defaults showing me where the defaults have changed.
       | At least that gives me some clue.
        
         | remram wrote:
         | I personally delete everything that I don't change. This
         | reduces the amount of breaking changes that I have to deal
         | with.
         | 
         | If I'm only setting `persistence.storageClass` and
         | `ingress.host`, my values.yaml will be two lines, not the
         | original 2,000.
        
       | thayne wrote:
       | Perhaps there should be an semi-standard flag similar to --help
       | and --version for showing help specifically about configuration
       | and environment variables. --cfg-help maybe?
        
       | clvx wrote:
       | If you are in k8s, I freaking love FluxCD for this reason. It
       | points where your sources are.
        
       | foolfoolz wrote:
       | i worked at a big company ($10B+) that was heavy on scala and
       | akka. we had tons of bugs across almost every team trying to
       | figure out which application.conf was setting something or
       | getting overwritten from somewhere else. we had many unnecessary
       | configs to force something we couldn't figure out. we had maybe 2
       | people who actually understood it and could debug it. what a
       | horrible system. no one ever walked away from akka and said i
       | enjoy the decisions they made to configure it
        
         | asimpletune wrote:
         | Haha I wonder if we worked at the same company. Anyways, I also
         | remember that a lot of those same teams never read the
         | documentation that explained how any of that stuff worked. In
         | general, most of Scala stuff was made out to be super hard and
         | complicated by other people, when really they just needed
         | someone to explain to them the basics in simple terms what was
         | happening.
         | 
         | I don't get to write Scala anymore and now I really miss it for
         | certain things.
        
           | foolfoolz wrote:
           | i wrote scala at work for like 12 years straight. it's a
           | great language and i really do miss it at times. scala code
           | always achieved its goal of being less code. but there were
           | some things like this where scala made it more difficult. and
           | i would like to chalk this up to "someone just needed to
           | learn the basics", but why was everyone having this issue?
           | it's a bad interface
        
       | the__alchemist wrote:
       | This article (And most notably its title) uses a narrow view of
       | _programs_ , how they're interacted with, and storage models.
       | Should your car's ECUs do this? Your washing machine? A GUI
       | program? What should they output if storage is the last page of
       | flash memory? What if it uses 2 pages? If it's offboard, should
       | it report the device ID? If it's a GUI, should it have a button
       | that displays this? Would an import/export feature meet the
       | intent?
        
         | cafeinux wrote:
         | I find the author's intent and meaning to be rather
         | straightforward to understand: he's a Unix sysadmin, so I think
         | it's understandable that he's speaking about programs executed
         | on a Unix-like system that a sysadmin is likely to
         | administrate.
         | 
         | So no, nor a washing machine nor a car ECU is expected to do
         | this (not until sysadmins are paid to administrate them at
         | least). As for technicians that might need to configure one
         | someday, those people are usually expected to already know
         | where to look, or at least to be able to read their
         | documentation correctly. And anyway, car ECUs and washing
         | machine usually provide a UI for configuration and don't rely
         | on config files as a primary mode of configuration.
         | 
         | As for GUI programs, if they use a human readable config file
         | under the hood, or if they accept a config file as input (some
         | let the user change some simple settings through their UI but
         | uses a config file to change more advanced settings), yes they
         | should have a way to show where it is (either through a
         | command, or through the settings UI for example).
         | 
         | I don't really know what you are talking about with the pages
         | of a flash memory... Since in Unix, everything is a file, it
         | will be read through a file anyway, not directly through pages.
         | Same thing for offboard: just display the path to the file,
         | wherever it might physically be. And if you really are in the
         | most rare and hypothetical scenario where your program reads
         | its config directly from the pages of a flash memory, just have
         | it display "The config is read from the last [two] page[s] of
         | <this flash memory> when invoqued with --help.
        
           | the__alchemist wrote:
           | The article makes sense in this context, and after a reread,
           | the hint is identification of background in the first
           | sentence. I misunderstood due to the title of "Everything
           | that uses configuration files should report where they're
           | located",and lines "if a program uses a configuration file
           | (or several), it should have an obvious command line way to
           | find out where it expects to find that configuration file.",
           | and use of "program" in general.
           | 
           | Specifically, "program" in this case refers to "CLI program
           | that runs on Linux, used by the IT field".
        
       | el_snark wrote:
       | Its got my vote. Speaking as someone contemplating a Solr
       | installation left without any documentation by a previous
       | employee.
        
       | est wrote:
       | and every configurtion file should be read-writable by some kind
       | of UI.
       | 
       | Especially those out-of-context .yaml files with lots of DSLs
       | embedded.
        
       | paveworld wrote:
       | just try using the unix command lsof
       | 
       | if you know the PID aka Process ID for the application yr running
       | try lsof -p PID_NUM_HERE
       | 
       | it will give you a list of every open file your application is
       | using along with it's full path
       | 
       | finally, if that gave you too many lines try lsof -p PID_NUM_HERE
       | | grep -E 'txt|properties|config'
       | 
       | I know you wanted the files listed it in a help file however this
       | will work 100% of the time
       | 
       | Best, Stephen
        
         | rossmohax wrote:
         | this will work 0% of the time if app closes config after
         | reading
        
       | p-e-w wrote:
       | I don't think I've ever encountered a widely used program that
       | doesn't have that information in its manpage. The manpage _is_
       | the canonical source the article calls for.
       | 
       | With the exception of New Age software like Go, that for some
       | reason doesn't use manpages, I'm not convinced that the problem
       | implied here actually exists.
        
         | vaughands wrote:
         | It's more common to have to guess in blackbox / proprietary
         | software, like games.
        
         | BaculumMeumEst wrote:
         | Doesn't the man page often list several potential locations
         | where it looks for the file and the ordering behavior, leaving
         | you to investigate and find which is actually loaded? It's
         | still annoying.
        
           | p-e-w wrote:
           | But that is exactly the information you need in order to
           | determine which config file is being read in all situations.
           | A single location doesn't cut it if the reality is more
           | complicated.
           | 
           | If the goal is to find out which _particular_ file is being
           | used _at this particular time, on this particular system,_
           | the maximum verbosity log might have that information, and
           | otherwise strace can help, as described in the other
           | comments.
        
             | lelanthran wrote:
             | Okay, but why should I have to determine what the program
             | already knew?
        
             | coldtea wrote:
             | These Stockhom Syndrome rationalizations are the reason we
             | can't have nice things
        
             | eptcyka wrote:
             | I really do not care about all the possible paths a config
             | file might be read from. I want a flag that I can pass to a
             | binary to see which paths it will actually read, and
             | ideally, I'd like those paths to be logged to STDOUT on
             | startup.
        
               | em-bee wrote:
               | but it reads all of them in a particular order and in
               | case of conflicting settings you have to figure out which
               | one takes precedence.
        
               | _dain_ wrote:
               | Yes. Exactly. Which is why _the program_ should tell you
               | which one takes precedence.
               | 
               | The program already knows what config files it's loading
               | and in what order, so why is it left up to the human to
               | do all that work again? There should be a flag like
               | --manifest or something that would spit out what actually
               | got loaded from where.
        
               | eptcyka wrote:
               | Yes, I want to know which files in which order.cI don't
               | want a static list of all possible locations, I want it
               | to deduce what files would take effect in a given
               | environment and with the given config files - a program
               | must already know this when it is ran - so let's just be
               | open and print said paths.
        
               | Joker_vD wrote:
               | Absolutely. For example, if you pass "-v" to ssh, it
               | prints paths to configs that it tried to open, paths to
               | identity files that it tried to open, to known_hosts
               | files, etc. This info is not needed so very often, but
               | when it is, it's incredibly useful.
        
               | coldtea wrote:
               | That would be stderr but hell yes
        
         | DangitBobby wrote:
         | A short way in to TFA:
         | 
         | > Ideally I'd like to avoid scanning all the way through the
         | manual page or other documentation for the program to find out,
         | because that's slow and annoying.
        
         | formerly_proven wrote:
         | > With the exception of New Age software like Go, that for some
         | reason doesn't use manpages
         | 
         | Primarily because man pages need to go in the MANPATH to be
         | useful but these tools tend to dwell somewhere in ~/.
        
           | em-bee wrote:
           | my manpath includes $HOME/.local/share/man; and that is with
           | $MANPATH unset, so it's a distribution default
        
           | unnah wrote:
           | Out of interest, I checked out _man man_ on Linux and found
           | the search logic documented in _man 5 manpath_. In addition
           | to system directories specified in  /etc/manpath.config, the
           | man command checks directories in the user's PATH and maps
           | them to related man directories: pathdir, pathdir/../man,
           | pathdir/man, pathdir/../share/man, and pathdir/share/man are
           | all considered. The MANPATH environment variable overrides
           | all other configuration and should not be necessary.
           | 
           | So, following current practices, installing binaries in
           | ~/.local/bin and man pages in ~/.local/share/man should work
           | without any additional configuration.
        
       | timokoesters wrote:
       | In Conduit (https://conduit.rs) there is no default config path.
       | In order to start Conduit, you need to specify the CONDUIT_CONFIG
       | environment variable, which is the path to your config. This will
       | typically be done in a systemd service.
       | 
       | This has multiple benefits:
       | 
       | - You can't accidentally start Conduit with a wrong config (e.g.
       | the config in the current working directory)
       | 
       | - You can have multiple Conduits running at the same time with
       | different config
       | 
       | - It's easier to understand for the system administrator because
       | there is no hidden information
        
       | peter_d_sherman wrote:
       | https://unix.stackexchange.com/questions/58887/how-do-i-moni...
       | 
       | https://stackoverflow.com/questions/27428150/linux-how-to-tr...
       | 
       | https://superuser.com/questions/348738/continuously-monitor-...
       | 
       | https://serverfault.com/questions/138297/how-to-track-all-fi...
        
       | YourDadVPN wrote:
       | I think the best way to achieve this is by providing an OS API
       | that results in the files always being created in the same place.
       | Applications/libraries could still choose their own filenames and
       | syntax, just the location would be OS controlled. I think there
       | is room for a new desktop/laptop OS to emerge and one good idea
       | from mobile OS design I would like to see is having everything be
       | an API call that allows the OS to impose standardisation,
       | permissions and user preferences rather than the free-for-all
       | desktop OSes have (though I propose letting the user run non-
       | compliant applications, and not porting the iOS app store only
       | model into the OS).
        
         | AeroNotix wrote:
         | You're basically suggesting the windows registry.
        
           | angulardragon03 wrote:
           | macOS has something similar also with defaults [1].
           | 
           | https://macos-defaults.com/#%F0%9F%99%8B-what-s-a-
           | defaults-c...
        
           | aeonik wrote:
           | The problem with the Windows registry, at least back in the
           | day, was that it was a single file that could be corrupted
           | and it would wreck your whole system.
           | 
           | I think having a standard utility API for *nix configs makes
           | a lot of sense. I'm surprised it doesn't exist.
           | 
           | I tried to find one, and there are some libraries for reading
           | and parsing in every language, but nothing that seems to
           | cover everything.
           | 
           | This bash script seems to be a fairly "built in" way to parse
           | them: https://unix.stackexchange.com/questions/441076/which-
           | is-the...
        
             | feldrim wrote:
             | > The problem with the Windows registry, at least back in
             | the day, was that it was a single file that could be
             | corrupted and it would wreck your whole system.
             | 
             | Exactly. But Registry has been using NTFS and it's
             | capabilities for rollbacks and recovery. Therefore, the
             | problem is mostly solved. There are occasions [0] of bugs
             | causing corruptions though but they are very rare.
             | 
             | 0. https://www.bleepingcomputer.com/news/microsoft/windows-
             | 10-n...
        
       | crabbone wrote:
       | Wasn't Windows Registry a (failed) attempt at unifying this
       | stuff?
       | 
       | Now, hear me out. The problem is not the location of
       | configuration. The problem is the crippled and anemic way UNIX
       | (and the likes) programs take configuration. These can only
       | _predictably_ take environment variables and command-line
       | arguments. Both ways are crippled due to size limit (especially
       | the command-line arguments) and structure (you cannot even have
       | lists  / arrays in environment variables). This is the reason why
       | every application author believes they must write their own
       | configuration, with their own (crippled) configuration format and
       | logic for locating their configuration.
       | 
       | On the bright side, I think, systemd is moving towards making
       | this mess more uniform. On the not so bright side, systemd
       | doesn't appreciate the difficulties associated with the problem
       | and doesn't seem to have any sort of plan moving forward. So,
       | unit files are kind of configuration, but because the format is
       | so crippled and anemic, they immediately added a way to source
       | random external files for process environment etc.
       | 
       | Finally, systemd, even if they understood the problem well and
       | put a good effort towards solving it are still powerless against
       | the format in which system supplies input to processes. What
       | really needs to change is all the family of execve, execlp and so
       | on. This was always a stop-gap / bad idea, but it was OK for a
       | while, before programs started to require more complex input. It
       | should've died in the 80s... but today it is so deeply entrenched
       | that removing it will take a very long time.
       | 
       | Another problem here is the approach that "everything is a file".
       | So, the only way to provide configuration beyond command-line
       | arguments and environment variables is a file... But, imagine an
       | alternative reality in which OS is capable of providing basic
       | data-structures, which can also be persisted and queried? Kind of
       | like you do it with a relational database? I think this idea is
       | so much not novel that it's older than most people commenting in
       | this thread... And, even though this would make it so much easier
       | for so many application authors to provide consistent and easy to
       | inspect, better tested interface to their programs... nobody's
       | doing that :) Because files are good enough.
        
         | jeroenhd wrote:
         | I significantly prefer using DConf over brute forcing some new
         | configuration file format.
         | 
         | It works like the Windows registry, but now the fields also
         | have native support for a description that tells you what the
         | settings do.
        
           | Joe_Boogz wrote:
           | So like Windows Group Policy?
        
         | Roark66 wrote:
         | Having spent many years in the windows land I definitely get
         | where you're coming from. However, I find the Unix way where
         | everything is a file, much simpler to work with.
         | 
         | Just take a simple task of copying a subset of some system's
         | configuration to another one. On Unix it's just a matter of
         | copying some files. On Windows (and our imaginary is that
         | provides object storage) we would need to find the relevant
         | objects, then write a script to export/import it (or mess with
         | export/import tools for a while).
         | 
         | Personally I see "everything is a file" as strength not
         | weakness. In addition to my personal preference having a
         | centralised configuration system not only restricts in many
         | ways, presents a potential performance bottleneck, but also is
         | an extra point of failure.
         | 
         | Additionally, I think most Unix software uses a fairly simple
         | text format for config files. There really is little reason for
         | using anything else. If you need complex data structures use
         | YAML. I've found many more proprietary binary config file
         | formats on Windows (despite registry) than on Unix. So if the
         | os would make something like this available there would still
         | be no guarantee all apps use it. It would just be an extra
         | thing to deal with for little benefit IMO.
        
           | crabbone wrote:
           | > much simpler to work with.
           | 
           | It's simple when the task is simple, and it becomes a lot
           | more complex than necessary when problems become more
           | complex.
           | 
           | Consider the joy of sysfs / procfs and similar. These are
           | filesystems that, through files, expose information that is
           | numbers, strings, lists, even trees. There's no uniformity
           | there, no way to predict where and what sort of files with
           | what sort of data will appear... Sometimes you get extra
           | files with "metadata" that describes the format found in
           | other files, sometimes it's in the same file, and sometimes
           | it just doesn't exist. Sometimes numbers are encoded as
           | strings, and sometimes as bytes. Booleans can be encoded as
           | numbers, (which are either strings or bytes).
           | 
           | There's plenty of weird behavior that isn't described by
           | files / their properties. For example, suppose you want to
           | delete a RAID device, but if fails because it turns out that
           | it's used by LVM volume, but you didn't even know you were
           | supposed to look for that...
           | 
           | It gets even worse with proprietary stuff that doesn't follow
           | conventions. Take for instance NVidia GPUs. They do appear in
           | sysfs as PCIe devices... but most interesting properties just
           | aren't listed there. Instead, NVidia's driver creates
           | "devices" in udevfs (i.e. /dev) with arbitrary properties
           | that you cannot predict because the format is whatever the
           | vendor wanted it to be at any version of their product.
           | 
           | In other words, files are a very poor mechanism for
           | describing data. In order to work with them you need
           | conventions that aren't part of any file mechanism. Take
           | network interface names, or block device names, stuff like
           | eth0 or nvme0n1p1 -- you need to know the convention and how
           | to interpret the name (i.e. the first suggests that the
           | device is using Ethernet driver and is the first one
           | connected, the second means that the device is using NVMe
           | driver, it's the first device of its kind attached to PCIe
           | bus, first namespace, first partition.) Specifically, in the
           | case of block devices, you could discover the same
           | information given in the file name by traversing the relevant
           | filesystem subtree, but in some cases the information is just
           | encoded as a file name or as it contents, but it doesn't
           | utilize the filesystem primitives. It just relies on
           | convention.
           | 
           | ----
           | 
           | > I think most Unix software uses a fairly simple text format
           | for config files
           | 
           | How did you count?
           | 
           | Do you mean software that is part of UNIX standard or
           | software that runs on UNIX?
           | 
           | What makes the majority an interesting metric? (I.e. suppose
           | there are 10M of different programs that run on UNIX, and 6M
           | of them are simple enough that they don't require complicated
           | configuration, there are still 4M of those that do, and some
           | of them are probably used daily by millions of users.
           | 
           | I mean, who cares if simple programs don't need complicated
           | configuration? The problem is the configuration of complex
           | programs, and they are indispensible in our daily lives.
        
           | crabbone wrote:
           | > If you need complex data structures use YAML
           | 
           | YAML is a poorly engineered format. It doesn't think about
           | storage at all, for example (i.e. in its definition, it's
           | just a single text blob. What if you need to split it?
           | 
           | The format is awful for random access: you need to read the
           | whole thing to extract a single data item. If you need to
           | query such a configuration multiple times you'll do a lot of
           | unnecessary work.
           | 
           | YAML poorly defines numerical types (how many digits can a
           | float have? what about integers? Are floats and integers the
           | same thing?) YAML lists... allow mixed types. Not sure it's
           | such a good thing from performance and correctness
           | perspective.
           | 
           | YAML has unnecessary "hash-table" type. Hash-tables aren't a
           | data format, they require function in the reader that makes
           | asymptotic properties of hash-tables work. In fact, YAML has
           | just a weird sub-type of list, where elements come in pairs.
           | Since it inherited all this from JSON, there's also the
           | ambiguity related to repeated keys in such hash-tables --
           | what should an application do with those nobody knows.
           | 
           | YAML sucks for transmission due to the ambiguity caused by
           | repeated keys in "hash-tables". You cannot stream such a
           | format if you have the policy that the last key wins or if
           | you have the policy that repetition is not allowed. Also,
           | since YAML allows references but doesn't require that the
           | reference lexically point to a previously defined element,
           | you may have unresolved references which, again, will prevent
           | you from streaming.
           | 
           | YAML defines mappings to "native" elements of different other
           | languages... but what should you do if you are parsing it in
           | Ruby, but get a mapping to Python?
           | 
           | YAML schema sucks. It would require a separate "expose" to
           | describe why.
           | 
           | YAML comes with no concept of users or namespaces which would
           | be necessary for ownership / secure sharing of information.
           | It also comes without triggers which would allow an
           | application to respond to changes in data.
           | 
           | YAML is very hard to parse for no reason. It's very easy to
           | make a typo in YAML that will not make it invalid, but will
           | be interpreted contrary to what was intended.
           | 
           | YAML doesn't have a canoncial form which makes comparing two
           | elements a non-trivial and in some cases undefined task.
           | 
           | YAML doesn't have variables, nor does it have forall / exists
           | functionality. This results in a lot of tools that work with
           | YAML overlaying it with yet another layer of configuration,
           | which includes variables (eg. Helm charts, Ansible
           | playbooks).
           | 
           | ----
           | 
           | I mean, honestly, people who created YAML probably saw it as
           | an inconsequential, sketchy project that should take maybe a
           | weekend or two. They didn't plan for this format to be the
           | best... they just made something... that sort of did
           | something... but not really. I have no idea why something
           | like this received the acclaim that it did.
        
           | genman wrote:
           | Actually, why not both?
           | 
           | Why not have files and an database like interface for them?
           | 
           | Even better, databases normally provide a query plan
           | explanation, quite like what is demanded here.
        
             | indymike wrote:
             | I once thought the same, but there is not a universal
             | answer on how to store data that delivers the combination
             | of performance, reliability for every use case. Files are
             | the lcd and leave room for optimization - and end up being
             | a nice abstraction to hide the inner workings of decades of
             | different storage devices and apis.
        
           | _dain_ wrote:
           | _> If you need complex data structures use YAML._
           | 
           | Please god no. JSON or TOML at most. YAML is too complicated.
        
             | nucleardog wrote:
             | JSON requires too much escaping to be reasonable to edit by
             | hand in many cases. TOML is only marginally better.
             | 
             | With any significant level of nesting TOML starts to
             | obscure the structure more than it helps anything.
             | 
             | I tend to start with a basic K=V ("dotenv") format. Past
             | that though I'm going straight to YAML.
             | 
             | I agree that the "everything and the kitchen sink"
             | specification is ridiculous and rarely (if ever) use much
             | of the functionality, but as far as representing arbitrary
             | structured data in human readable and editable text... it
             | sucks less than the alternatives if you stay away from the
             | weird stuff.
        
             | Spivak wrote:
             | For who? Yaml gives you all the standard containers, tools
             | to avoid repeating yourself, lord of ways to format strings
             | so they stay readable and arbitrary object serialization.
             | 
             | Yaml only gets weird if you want to use complex objects as
             | dict keys but that complexity is on you then.
        
               | _dain_ wrote:
               | _> Yaml gives you all the standard containers_
               | 
               | So do JSON and TOML. If you think you need more than what
               | they provide, something has gone very wrong.
               | 
               |  _> tools to avoid repeating yourself,_
               | 
               | Bad. Config is not code. Settings should be explicit. DRY
               | is not helpful.
               | 
               | Because of the lack of anchors/aliasing/variables etc,
               | JSON has the nice property that you can parse it with
               | exactly one upfront memory allocation: N bytes of JSON
               | requires at most N words of memory.
               | 
               |  _> lord of ways to format strings so they stay readable_
               | 
               | Bad. Too many ways:
               | https://stackoverflow.com/a/21699210/6107981 No normal
               | human being can remember all the rules for how a string
               | gets parsed. Therefore it isn't actually human-readable
               | or human-writeable, despite masquerading as such.
               | 
               |  _> arbitrary object serialization_
               | 
               | You can write out the fields as a JSON object. If this
               | isn't enough, then what you're trying to serialize
               | doesn't belong in a human-readable text config file.
               | 
               |  _> Yaml only gets weird if you want to use complex
               | objects as dict keys but that complexity is on you then._
               | 
               | This assumes the guy who wrote the config schema is the
               | same as the guy who has to later use and edit it, which
               | is seldom the case. When people do needlessly complicated
               | config like this, they're taking an enormous stinking
               | shit on my lawn for me to clean up.
        
       | nikau wrote:
       | Alternately, every aysadmin should learn how to drive strace
        
       | someonewhocar3s wrote:
       | [dead]
        
       | sleepytimetea wrote:
       | Let me introduce you to the nightmare that is the Windows
       | Registry...
        
         | poisonborz wrote:
         | Luckily modern programs rarely use it.
        
         | fsckboy wrote:
         | don't give the systemd crowd any ideas, the Windows Registry is
         | right up their alley
        
           | fsh wrote:
           | All parts of systemd are configured entirely using plain text
           | config files and symlinks.
        
             | mike_hock wrote:
             | It's indeed "configured using symlinks" but not in the
             | sense that you're free to use symlinks the way they're
             | supposed to work but in the sense that if you don't want to
             | use systemctl to place them, you can place them "by hand"
             | if you know all the magic ways in which systemd interprets
             | them and will remove them as it sees fit when you invoke a
             | management command.
        
               | fsh wrote:
               | I have no idea what you mean by that. A systemd target is
               | a folder in _/ etc/systemd/system/_ which contains a
               | bunch of symlinks to unit config files. When the target
               | is requested, systemd makes sure that all these units are
               | running. This is how symlinks have been used for
               | configurations since forever (for example by apache on
               | Debian).
        
               | mike_hock wrote:
               | ln -s /path/to/mydaemon.service /etc/systemd/system/
               | 
               | systemctl daemon-reload
               | 
               | systemctl disable mydaemon.service
               | 
               | ls /etc/systemd/system/mydaemon.service
               | 
               | ls: cannot access '/etc/systemd/system/mydaemon.service':
               | No such file or directory
               | 
               | It has no business removing that symlink. It was placed
               | there by me, and it should be treated no differently than
               | if it was a regular file.
               | 
               | I have no problem with systemctl enable/disable creating
               | and removing links in the appropriate target.d
               | directories, but this symlink had nothing to do with that
               | mechanism. Leave my stuff alone.
        
               | fsh wrote:
               | This doesn't work because unit files have to be in one of
               | the load paths. Have you tried adding /path/to/ to
               | $SYSTEMD_UNIT_PATH? This is documented in the Unit File
               | Load Path section of the manpage [1].
               | 
               | [1] https://www.freedesktop.org/software/systemd/man/syst
               | emd.uni...
        
               | mike_hock wrote:
               | > This doesn't work because ...
               | 
               | > This is how symlinks have been used for configurations
               | since forever (for example by apache on Debian).
               | 
               | This is not how symlinks have been used for configuration
               | "since forever." You didn't have to add the _link target_
               | to some  "load path" variable when the link itself was in
               | the correct directory.
        
               | fsh wrote:
               | I have a suspicion that you are not really interested in
               | using the software which makes this discussion entirely
               | pointless.
               | 
               | P.S. Debian's a2ensite and a2dissite also assume that
               | your configs are in the _sites-available_ folder, not
               | elsewhere in the file system.
        
               | mike_hock wrote:
               | a2dissite doesn't delete symlinks outside sites-enabled,
               | right?
               | 
               | I think it's a reasonable complaint.
        
               | SSLy wrote:
               | It's best not to engage with concern trolls.
        
           | arielcostas wrote:
           | GNOME's GConf says hi
        
           | RandomBK wrote:
           | Dbus says hi
        
         | rm445 wrote:
         | A system-wide key-value store, that's distinct from file
         | storage, seems like a pretty great idea. The Windows Registry
         | is icky, we all know that, it somehow appeared out of nowhere
         | in Windows 95 already crusty as hell. But if it were designed
         | by people with taste and discretion, would it be good?
        
           | grenoire wrote:
           | When you give people the freedom to use the KV store as they
           | wish, you inevitably run into a meta-problem whereby the way
           | they write their data structures in to the KV store is varied
           | across applications. I don't know if you could standardise
           | this structure beyond enforcing applications to use an OS-
           | assigned private store, but I don't see how that would work
           | with portable executables etc.
           | 
           | I suppose you'd need to be very opinionated for it to work,
           | but people will still bodge it to make it work with their
           | needs that your system doesn't natively satisfy (people
           | putting JSON strings in the values, for example).
        
             | mike_hock wrote:
             | And how is that a bigger problem than people using the
             | filesystem any way they wish and putting arbitrary content
             | in files?
        
               | kevin_thibedeau wrote:
               | The filesystem is manageable by users (with few
               | exceptions). You can't easily discover which part of a
               | registry hive is associated with an application.
        
               | mike_hock wrote:
               | It's precisely as discoverable as the filesystem. It's a
               | tree like the filesystem. With names given to nodes by
               | the application, just like the filesystem.
        
       | fsckboy wrote:
       | The operating system should tell everything that uses
       | configuration files where to put them, and what formats are
       | acceptable.
       | 
       | The operating system should tell systemd where to put them.
       | 
       | The operating system does not use JSON.
       | 
       | Users can then ask the operating system.
        
       | morkalork wrote:
       | That's something I think anyone who remembers what being a newbie
       | linux user is like will agree with.
        
       | throwawaaarrgh wrote:
       | We could use pkg-config for that. It's meant for build systems
       | but you could store any metadata in there, in theory.
       | https://en.m.wikipedia.org/wiki/Pkg-config
       | https://people.freedesktop.org/~dbn/pkg-config-guide.html
        
       | [deleted]
        
       | jdwyah wrote:
       | Strong agreement. I'm building a tool for dynamic configuration
       | and that makes this doubly fun, because now the configuration can
       | come from a remote, live updating source as well.
       | 
       | In Prefab, the source can be a default file, env specific
       | defaults, live values, or machine specific overrides when doing
       | local development.
       | 
       | Right now I've landed on printing out the name, value & source
       | type and path on boot. It looks like
       | https://gist.github.com/jdwyah/5ca4b0eacdc04414540af0761b8a0...
       | 
       | I think it's allright, but I'm still thinking about how to make
       | it better. More details in:
       | https://docs.prefab.cloud/docs/explanations/bootstrapping
        
         | jdwyah wrote:
         | And if you are interested in making all of your configuration
         | typesafe, please get in touch. I have things I want to show
         | you.
        
       | dumpster_fire wrote:
       | Wait till you get to template configs that automatically generate
       | fan out config files during build time. You can report it, but
       | you can't find it.
       | 
       | Really enhances the debugging experience.
        
       | smcameron wrote:
       | List them in the FILES section of the man page. You have a man
       | page, right?
       | 
       | Also, follow the XDG base directory specification[1].
       | 
       | [1] https://specifications.freedesktop.org/basedir-
       | spec/basedir-...
        
         | JdeBP wrote:
         | systemd has manual pages. I pointed out some missing
         | configuration file locations back in 2016. They are still
         | undocumented today.
         | 
         | * https://jdebp.uk/FGA/systemd-documentation-errata.html
        
         | Rediscover wrote:
         | And also `strace`.
        
       | opentokix wrote:
       | Tell me again that you run a terrible system and don't know what
       | you are doing like 99.9% of the IT-"professionals" out there.
        
       | smcin wrote:
       | The title read without context sounds like it's suggesting they
       | should report which IP address/country/jurisdiction they're in.
       | To any random user on the internet. Which would be insane. But
       | it's really only saying "which system path they're in, to e.g. a
       | sys admin".
        
         | mdekkers wrote:
         | Possibly if you are not familiar with how software is
         | configured. It was immediately clear to me.
        
           | smcin wrote:
           | I am familiar with how software is configured, and the
           | implied context is not clear from only the headline, hence
           | the headline needs fixing. "Everything" is massive
           | overstatement: bank websites use configuration files, so if
           | hackers try to log in to the bank, the website should report
           | where the config files are located? Nope. Headline way too
           | broad.
        
       | personjerry wrote:
       | Also log files!
        
       | elihu wrote:
       | I would go one further and say that the default should be that
       | programs cannot read, open, or see files at all unless they're
       | either explicitly allow-listed to open those files, or the user
       | has given permission for them to open those files (i.e. by using
       | the file name as a command-line argument, or selecting the file
       | in an os-provided file selection dialog box).
        
         | theobeers wrote:
         | I like this about Deno (not to suggest that the runtime is
         | without its flaws). Whenever I try to run a script and it tells
         | me I need to allow e.g. read access to the filesystem, I'm more
         | grateful than annoyed. And it lets you choose the granularity
         | of the permissions that you grant. Hopefully this approach will
         | become more common.
         | 
         | https://deno.com/manual@v1.34.3/basics/permissions
        
         | jjtheblunt wrote:
         | Is that what macOS does? (I'm thinking it's coarser
         | granularity, like asks if a program can see a filesystem tree,
         | for a few such checked trees.)
        
           | elihu wrote:
           | I don't know; I don't use a Mac.
        
       | tomaaron wrote:
       | Configuration files are like parents' advice - carefully thought
       | out, well-intentioned, but often overwritten by the 'environment
       | variables' of real life experiences!
        
         | formerly_proven wrote:
         | I have this tool, which is used in a few different
         | environments, so I gave it a "xxx config" command which tells
         | which config files were read, which environment variables were
         | used, which environment variables from the tool's XXX_
         | namespace are unknown, what configuration values are effective
         | etc.
         | 
         | I don't think anyone ever used that function.
        
       | quickthrower2 wrote:
       | So a "registry", of sorts :-)
        
       | yread wrote:
       | Especially if there are multiple places to read them from:
       | current dir, PATH, classpath, $PROJECT_HOME, database, env
       | vars... With env vars it would be handy to also know where they
       | come from, is there a way? like having a timestamp when it was
       | set, by what user and process.
        
       | dclowd9901 wrote:
       | Maybe tangential to this, I've been thinking about the idea of
       | "conceptually linked items" in a system and how to ensure things
       | don't become desynced. Static type systems help keep linked
       | objects synced across code. But what about documentation? What
       | about configuration code? It quickly falls out of sync.
       | 
       | I was thinking a possible naive solution to this in a file system
       | would be some sort of pragma you could put on a file: other files
       | it should be synced with and a date of last change. If you update
       | a file, any file it's supposed to be synced with must be updated,
       | if only at the very least, the date of last change. It's sort of
       | a forcing function to make sure everything's up to date that
       | needs to be.
       | 
       | Could be onerous in a large system but I'm not sure.
        
       | Aissen wrote:
       | That's one thing I like about "systemctl cat <service/unit
       | name>": it shows both the content and the path of the config
       | file.
        
       | guggle wrote:
       | All the software I write is configured through env vars... why
       | use anything else ?
        
         | withinboredom wrote:
         | You can't change env vars after a program is running, but I can
         | change a file and send a SIGHUP.
        
           | [deleted]
        
           | ilyt wrote:
           | Programs reconfigurable at runtime are by far rarity, as
           | that's generally pretty hard thing to do. But yes, just have
           | a config file, ENVs are nice as a backup for small apps, but
           | never as only way
        
             | withinboredom wrote:
             | Anything running as a daemon/service should support this
             | capability IMHO, especially if it is servicing active
             | traffic.
        
               | ilyt wrote:
               | It's definitely nice when it does but it's also a whole
               | lot of complexity to add to the code. You have to re-
               | create all structures relying on configs, reconnect if
               | needed, clear all previous ones, but only after any
               | ongoing processing of requests received before the reload
               | signal finishes.
               | 
               | Some go half-way, like HAProxy where it does spawn a new
               | process but that process just binds with SO_REUSEPORT and
               | signal old one to close the socket and finish all
               | remaining connections. So you effectively get hitless
               | reload, it's just that old process is the one finishing
               | in-flight requests
        
               | withinboredom wrote:
               | Yeah, it def adds complexity but if you want it used in
               | real world applications, it's a must-have. With only env
               | vars, it's an impossibility to ever have (without
               | supporting infrastructure and processes), which was the
               | point I was trying to make.
        
               | ilyt wrote:
               | Hardly. "Real world applications" need to tolerate single
               | node failure anyway so reload functionality doesn't add
               | all that much. Some system daemons, sure, them not
               | working for a second can be disruptive so it is worthy
               | endeavor there, but the amount of added complexity is
               | nontrivial and the added complexity scales with apps' own
               | complexity.
               | 
               | It's a bit different for desktop apps, as restarting app
               | every time you change some config options would be far
               | bigger PITA than some server app.
        
               | withinboredom wrote:
               | Unless you're working for a tech company, it's running on
               | a single server (and it's worth pointing out that most
               | companies aren't tech companies). That's what I meant by
               | "real world", AKA, outside the tech bubble.
        
         | nlnn wrote:
         | Sometimes configuration is fairly complex (e.g. nested map data
         | structures) which gets pretty complex with simple key/value env
         | variables.
         | 
         | I'm thinking of things like config for nginx, Apache,
         | Kubernetes, etc.
        
           | guggle wrote:
           | Indeed, I only had "simple" cases in mind. But hey...
           | shouldn't the complex config files paths be specified through
           | env vars ? ;)
        
           | mekoka wrote:
           | I've had rare cases of needing nested data structures in the
           | environment. My solution was to specify them as JSON strings
           | and load the value in code. It works.
           | USER='{             "name": "joe",
           | "email":"joe@example.com"         }'
        
         | nomilk wrote:
         | For anything more than trivial configurations it can be nice to
         | commit them to source control, giving some reversion
         | capabilities, and easy replication on other projects.
        
         | laeri wrote:
         | - If your configuration has more than 5-10 options then env
         | vars become a mess while a configuration file is more
         | maintainable - Nested configuration / scoping is a mature
         | advantage of configuration files - You can reload configuration
         | files whereas you can't reload environment variables during
         | runtime - A configuration file is a transparent record of your
         | configuration and easier to backup and restore than env
         | variables. Env variables can be loaded from many different
         | locations depending on your os. - In configuration files you
         | can have typed values that are parsed automatically with env
         | variables you need to parse them yourself. This is just a
         | difference not that bad for env variables per se.
        
         | ilyt wrote:
         | Coz it's entirely miserable experience when you get like...
         | more than 4 config options
        
           | jdwyah wrote:
           | Yes. Env vars beat constants but have stunted our thinking
           | because we know deep down it's not a great idea to have too
           | too many.
           | 
           | Config files are better, but can lead to the mess described
           | here and typically only give us crude axes for overriding.
           | 
           | It's time for us to embrace & tame the complexity. If you use
           | a feature flag tool already, you know what it's like to
           | target different values based on rules.
           | 
           | If I want to experiment with changing the http timeout for
           | specific calls from a single service in a single region I
           | should be able to roll that out.
           | 
           | It's time to expand our brains and bring this feature flag
           | style thinking to the rest of our configuration.
        
             | ilyt wrote:
             | > If I want to experiment with changing the http timeout
             | for specific calls from a single service in a single region
             | I should be able to roll that out.
             | 
             | ...why ? how often you do it ? What actual app feature it
             | fills ? Why would you throw permanent code at something
             | that you need to do once or twice?
             | 
             | That kind of thing is FAR better served as customizable
             | hooks (loadable .so/.dll, maybe even attached Lua
             | interpreter) rather than bazillion random flags for
             | everything and checks cluttering code.
        
               | jdwyah wrote:
               | May need to agree to disagree :) I'm saying that we
               | should write:
               | 
               | httpClient.get("my/url", timeout:
               | config.get("http.timeout"))
               | 
               | Where config is a library smart enough to do some rule
               | evaluation over a live updated backing store to get the
               | right value.
               | 
               | I'm not sure how .so/dll or lua is going to help here.
        
       | atoav wrote:
       | I'd add: everything should use configuration files that are
       | stored on the machine. I know services that use configuration
       | files and you are expected to upload them into the service using
       | an IDE and a plugin to then store the config in it's database.
        
         | em-bee wrote:
         | not supporting configuration files on disk allows a service to
         | work without needing read or worse write access to the disk.
         | storing configuration in the database is a benefit.
         | (potentially even for security)
        
           | atoav wrote:
           | Yeah but then at least include a cli interface that runs on
           | that machine which allows you to edit the config.
        
       | tester756 wrote:
       | Also, I do believe that programs should be capable of self-
       | configuration
       | 
       | like if you need LLVM and didnt manage to find it under
       | 
       | "app_folder/llvm"
       | 
       | then let's go find it somewhere on the disk(s) and ask user if he
       | wants to use it
        
         | hughesjj wrote:
         | System environment variables/system registry sounds like the
         | best way to do that from a pragmatic perspective
        
       | zapw wrote:
       | For git config, the --show-origin flag is really useful for this,
       | e.g.                 git config --show-origin --list
        
       | joelthelion wrote:
       | A good and underused tool to figure this out when the tool
       | doesn't help is strace.
       | 
       | It allows you to trace system calls, and, crucially, file opens.
        
       | kazinator wrote:
       | If I need to know where some program is looking for startup files
       | and in what exact order, I just use strace on it.
        
       | digitalsanctum wrote:
       | As I read this I wonder if SBOM (Software Bill of Materials)[1]
       | could be used? I'm not sure if it already has configuration files
       | as part of it's definition but doesn't seem like a stretch to
       | add? Btw, I've never used SBOM in practice but seems like
       | something worthwhile implementing.
       | 
       | [1]
       | https://www.cisa.gov/sbom#:~:text=A%20%E2%80%9Csoftware%20bi....
        
       | js2 wrote:
       | I needed to update /etc/resolv.conf under RedHat the other day
       | and I was surprised by how much this has changed. You don't edit
       | /etc/resolv.conf directly anymore because it's maintained by
       | Network Manager[1]. Instead you edit either one of the interface
       | configuration files and tell NM (via nmcli) to reload it, or you
       | use nmcli to update the interface config file.
       | 
       | Fine, I can deal with that.
       | 
       | What really surprised me were a couple programs that needed to be
       | restarted to see the updated /etc/resolv.conf as they apparently
       | don't use glibc for DNS resolution. I used lsof to figure out
       | what was sending DNS requests to the old name server IPs.
       | 
       | It turned out to be osqueryd and Apache Traffic Server.
       | 
       | 1. There are various ways to put /etc/resolv.conf back under
       | manual control if you don't want NM to maintain it.
        
         | marcosdumay wrote:
         | > Instead you edit either one of the interface configuration
         | files and tell NM (via nmcli) to reload it
         | 
         | Yeah, and this would be fine if both /etc/resolv.conf told you
         | what is creating that file _and_ NM didn 't rewrite its own
         | configuration files all the time.
         | 
         | Anyway, it would be not that bad if NM was kept restricted to
         | RedHat, because the entire philosophy of that distro is that
         | configuration files are just suggestions and the system is free
         | to change anything at any time. But instead, that behavior
         | infected everything.
        
           | js2 wrote:
           | The first line of resolv.conf is a comment indicating it's
           | written by Network Manager. So that part didn't trip me up at
           | least.
        
             | marcosdumay wrote:
             | On Debian it only says it's auto-generated and you
             | shouldn't edit. It's not necessarily created by NM either1,
             | so it would be really helpful to have it.
             | 
             | 1 - The policy of whatever configures your network last
             | rewrites this file is spreading. Apparently systemd creates
             | it first, and Debian has more than one network configurator
             | for you to choose.
        
       | hamburglar wrote:
       | Lately I've written all my tools to not only announce where
       | they're reading their configs from (which isn't precisely what OP
       | is asking for but is close), but also to have an option to
       | _generate_ the default config that will be presumed if a config
       | file is not found.  "mytool --gen-config /tmp/newconfig.txt"
       | should produce a fully-formed config with all defaults explicitly
       | set which can be moved into /etc/mytool.conf or wherever it's
       | supposed to go, all ready for me to tweak without having to look
       | up settings names.
        
       | siliconc0w wrote:
       | "just make everything a protobuf" (or whichever system you
       | prefer). The config file is essentially an API and APIs really
       | benefit when they're typed.
       | 
       | You can make a actual API to expose application configuration
       | knobs too which is nice but you should tie this into your
       | rollout/CICD system so you're just as careful pushing new
       | configuration values as you are when pushing new binaries
       | (multiple envs, slow rollouts, blue/green etc).
        
       | gavinray wrote:
       | It ought to be _" $XDG_CONFIG_HOME/<program-name>"_
       | 
       | I have trouble seeing the rationale for other locations when the
       | XDG standard exists
        
       | dschuetz wrote:
       | Read The Freaking Manpages.
        
       | hyperman1 wrote:
       | I also vastly prefer it when error messages give a hint about
       | what reconfiguration you can do to fix it, including correct
       | syntax and googleable terms.
       | 
       | So don't do: farblewarble too low.
       | 
       | Instead:
       | 
       | FarbleWarble is 1234 but need at least 5678. Edit
       | /etc/whatever.conf and add: FarbleWarble="5678"
       | 
       | There is a special hell for programs that talk abut how the
       | Burble is configured incorrectly , without any mention of
       | FarbleWarble
        
       | dmckeon wrote:
       | Programs that use configuration files should provide ways to:
       | show which sources of config data were used: files, CLI, env
       | vars, etc.             with --verbose, also show which potential
       | sources were not used              show any conflicts or
       | overrides from config sources              show config settings
       | differing from program defaults             in the same format as
       | their source, or              in an appropriate format for a
       | config file
       | 
       | For the last item, it should be possible to capture the output
       | showing non-default settings and append it to a config file,
       | without any editing or processing, to reproduce the program
       | configuration state exactly.
        
       | baby wrote:
       | I think good programming languages enforce that. I really like
       | that in Golang you import a library, and them have to qualify any
       | calls with that library name. For example, id you imported
       | library foo, calls will look like foo.Bar and foo.Gu. I think
       | that's one thing that Rust didn't steal from Golang when they
       | should have
        
       | Footnote7341 wrote:
       | [dead]
        
       | mixcocam wrote:
       | The config should also come with a short explanation on how to
       | use it on it!
        
       | markstos wrote:
       | A hack I use: run `strace someprog` and look for the system calls
       | that open files. This works no matter how badly the thing is
       | documented.
        
       | bombcar wrote:
       | php.ini is my experience of the worst of this, finding which of
       | the fifty five billion config files is the actual one controlling
       | the web server's php and not the console's is always a fun
       | journey.
       | 
       | Luckily ctrl-r helps the second time.
        
       | alentred wrote:
       | Agree! Also any other locations where any state that impacts the
       | program behavior is stored: cache, temporary files, etc.
       | Ultimately I want to be able to debug things or do a sort of a
       | "factory reset". Or maybe I need to move to NixOS.
        
       | lewo wrote:
       | The main issue is to use configuration files residing somewhere
       | in the filesystem. This looks like a global variable in a
       | codebase (something we generally try to avoid). Instead, the
       | configuration file should be explicitly provided as a command
       | line argument. Systemd sandboxing can also be useful to ensure
       | the program only uses the expected set of files.
       | 
       | For instance, on my NixOS machine, the Nginx configuration is not
       | in `/etc/nginx` but explicitly provided and can then be known
       | with ps:
       | 
       | $ ps aux | grep nginx
       | 
       | nginx: master process /nix/store/9iiqv6c3q8zlsqfp75vd2r7f1grwbxh7
       | -nginx-1.24.0/bin/nginx -c
       | /nix/store/9ffljwl3nlw4rkzbyhhirycb9hjv89lr-nginx.conf
        
         | Karellen wrote:
         | > This looks like a global variable in a codebase (something we
         | generally try to avoid).
         | 
         | Aren't they more like global _constants_ than variables? Loaded
         | at startup, and never change during that run of the program.
         | (With the exception of only explicitly being re-read on SIGUSR1
         | for daemon-like programs.)
         | 
         | And global consts, or #defines, or whatever, are things we
         | generally don't try to avoid?
        
         | jamann wrote:
         | How long does it take you to type out that path?
        
           | em-bee wrote:
           | /nix/store/9ii<tab>nginx.conf
        
         | ris58h wrote:
         | It's not a bad idea but it's not applicable to every piece of
         | software. I don't think that passing a config file for every
         | git command would be convenient.
        
           | viraptor wrote:
           | You can change the commandline string at runtime. You could
           | inject a fake "-c correct/path" even if it's not there.
           | (That's useful for other things too, like injecting the git
           | revision of the app into the commandline)
        
       | em500 wrote:
       | I wonder if there is any mainstream program with a more
       | convoluted configuration scheme than bash? Just when think you
       | understand the various invocations of .profile, .bash_profile,
       | .bashrc in login/non-login/interactive/non-interactive modes in
       | home and/or /etc after digesting an article with flowcharts[1],
       | you realize that any invocation can execute arbitrary code from
       | any location, and different distributions (not to mention, macOS,
       | WSL, git-for-Windows, etc) all source different stuff in their
       | default configs (like executing .bashrc in .profile).
       | 
       | [1] https://blog.flowblok.id.au/2013-02/shell-startup-
       | scripts.ht...
        
         | nxpnsv wrote:
         | That graph is wild! Bash is crrrraazy
        
         | hnlmorg wrote:
         | This is a why Murex (my shell) has a 'runtime' builtin which
         | lets you query which script updates what. Every function,
         | variable etc can be queried to find where they were set and
         | even when (time stamped) too.
        
       | [deleted]
        
       | WeylandYutani wrote:
       | I use Pcgamingwiki so that I can find out where the hell the
       | developers decided to put their config and save game location.
       | Windows is wild.
        
       | vaughan wrote:
       | This is the central problem with all programming today.
       | 
       | You can think of everything as configuration. Parameters of a
       | function are just configuration for that function.
       | 
       | What we need is traceability of every value in a system, not just
       | configuration. You click on any value and you see a graph/chain
       | of all the transformations this data goes through right back to
       | the source of truth. This is how we should code. Think about how
       | difficult this is to do today with your current IDE/editor.
       | 
       | Every task in software is wanting to change what is displayed in
       | a user interface of some sort. Usually you have to make your way
       | through a labyrinth to figure out what to change where, and also
       | what side-effects will occur.
       | 
       | If this is not smack bang in front of your face when you are
       | coding, then you are just adding more and more tangled data flows
       | and complexity to your system.
        
         | asimpletune wrote:
         | > What we need is traceability of every value in a system, not
         | just configuration.
         | 
         | Man, you would love functional programming. I'm' not even
         | joking.
        
           | hoosieree wrote:
           | anyParadigm :: RAM -> RAM
        
         | cmrdporcupine wrote:
         | So it's an interesting thought experiment, but... I suspect the
         | Rust compiler could statically figure this out for a large # of
         | cases .... based on following the borrow/copy/clone tree for
         | any particular variable. It could in theory be possible to
         | write a tool which traces that graph back to the snippets of
         | code where it originates, though that would usually end up
         | being a command-line args parser, or a config file reader...
         | 
         | It's mostly feasible in other languages to, but probably not
         | with the same level of rigor.
         | 
         | Anybody here from JetBrains?
        
           | catlifeonmars wrote:
           | This should be provided by the PLS for the language, not by
           | an IDE.
        
         | n40487171 wrote:
         | Yes but wouldn't the logging take up quite a bit of memory?
         | Something like O(compute cycles* (log(lines of code)+log(memory
         | allocated))) before compression.
        
           | vaughan wrote:
           | Check out https://pernos.co/.
        
           | bg46z wrote:
           | In complex prod systems, logging and traceability are
           | generally more important than memory consumption and disk
           | space. Memory and Disk are cheaper than a lawsuit if
           | something goes awry
        
         | reasonabl_human wrote:
         | Look into Nix / NixOS
        
         | marcosnils wrote:
         | Sounds a lot like what systeminit is working on:
         | https://www.systeminit.com/
        
           | giovannibonetti wrote:
           | It seemed very promising until it showed DevOps engineers
           | dragging blocks in a shared (synchronous) canvas like Figma.
           | 
           | Am I the only one that thinks pull requests (asynchronous)
           | are a more appropriate medium of collaboration for this kind
           | of work that requires strong consistency between elements?
        
             | aedocw wrote:
             | It works with pull requests too AFAIK.
        
         | Yajirobe wrote:
         | > You click on any value and you see a graph/chain of all the
         | transformations this data goes through right back to the source
         | of truth
         | 
         | Isn't that just a debugger?
        
           | snapcaster wrote:
           | Not in a distributed system
        
             | smrtinsert wrote:
             | This is what's really needed. In one code base it's
             | relatively easy for the dev team. Across your microservices
             | it's practically impossible unless all teams are involved.
             | This is a nadir in dev productivity currently
        
           | olejorgenb wrote:
           | Which debugger are you using?
        
         | dreamcompiler wrote:
         | First thing I thought of after reading your comment was web
         | inspectors which do help a little bit in figuring out stuff
         | like "Why is this line in italics?" by showing you computed
         | styles. But they could go a lot farther. I'd like to see a
         | temporal graph of everything (e.g. HTML, JS, CSS, Virtual DOM,
         | whatever) that had any visual or behavioral impact on an
         | object, and the reasons why things changed in that order, why
         | some changes overrode others, etc.
        
         | josephcsible wrote:
         | > You click on any value and you see a graph/chain of all the
         | transformations this data goes through right back to the source
         | of truth.
         | 
         | This kind of reminds me of the Whyline:
         | https://www.cs.cmu.edu/~NatProg/whyline.html
        
           | aendruk wrote:
           | > Now Patented!
           | 
           | Yippee. /s
        
         | yawboakye wrote:
         | i wonder whether our current strong compile-time/runtime
         | distinction can support this. it may be slightly easier for
         | interpreted and vm-based languages but i'm not sure we can have
         | it more broadly.
         | 
         | lately i've been playing with prolog and revisiting computer
         | science/computer programming before imperative languages drew a
         | curtain on innovation and i think we have lost a lot. our
         | modern programming isn't the programming the founders had in
         | mind, it seems.
        
           | cmrdporcupine wrote:
           | I think it could be done for Rust
        
           | marcosdumay wrote:
           | Compiled languages absolutely can support this.
           | 
           | But imperative ones create a bit of a problem. Nothing
           | impossible to deal with, but it becomes harder.
           | 
           | But any choice of language, the OS can enforce it too, and
           | maybe in a much easier way than messing with your language.
        
         | maximaximal wrote:
         | Sounds quite a lot like the Common Lisp experience when using
         | Sly and Emacs. You can (trace) every function and see lexical
         | scopes of variables, even bind them if you execute some s-expr
         | that does not currently have some variable under that symbol.
         | 
         | The distributed aspect is a bit more difficult though. I don't
         | know if there is a system that truly got this right. Maybe
         | Erlang's BEAM VM together with a good debugger I don't yet know
         | about.
        
         | pmarreck wrote:
         | This is a minor thing which I found useful- The "help"
         | functions of all my bash-defined functions report which file
         | they're defined in (such as: `echo "This function is defined in
         | ${BASH_SOURCE[0]}"`). If I could do something similar for my
         | environment-defined values (hmmm, now I'm thinking...), I
         | would. (I could create a function that tracks at least the
         | changes _I'VE_ made to these values, which could help...)
        
         | tgamblin wrote:
         | FWIW, we do something like this in Spack[1] with `spack config
         | blame`. There are different YAML configs, they can be merged
         | and override each other based on precedence, but we tell you
         | where all the merged values are coming from. Here's a
         | simplified example -- you can see that some settings are coming
         | from the user's "default" environment, some from Spack's
         | defaults, and some from specialized defaults for Darwin:
         | > spack -e default config blame packages         ---
         | packages:         spack/environments/default/spack.yaml:59
         | fftw:         spack/environments/default/spack.yaml:60
         | require: ~mpi
         | spack/etc/spack/defaults/darwin/packages.yaml:17    all:
         | spack/defaults/packages.yaml:18                       compiler:
         | [apple-clang, gcc, clang]
         | spack/defaults/darwin/packages.yaml:20
         | providers:         spack/defaults/darwin/packages.yaml:21
         | unwind: [apple-libunwind]
         | spack/defaults/packages.yaml:20.                        blas:
         | [openblas, amdblis]         spack/defaults/packages.yaml:21
         | jpeg: [libjpeg-turbo, libjpeg]
         | spack/defaults/packages.yaml:22                         lapack:
         | [openblas, amdlibflame]
         | spack/defaults/packages.yaml:23.                        mpi:
         | [openmpi, mpich]         spack/defaults/darwin/packages.yaml:22
         | apple-libunwind:         spack/defaults/darwin/packages.yaml:23
         | buildable: False         spack/defaults/darwin/packages.yaml:24
         | externals:         spack/defaults/darwin/packages.yaml:27
         | - spec: apple-libunwind@35.3
         | spack/defaults/darwin/packages.yaml:28                  prefix:
         | /usr
         | 
         | The filenames are shown in color in the UI; you can see what it
         | really looks like here: https://imgur.com/uqeiBb5
         | 
         | For the curious, there is more on scopes and merging [2]. This
         | isn't exactly easy to do -- we use ruamel.yaml [3], but had to
         | add our own finer-grained source attribution to get this level
         | of detail. There are also tricky things to deal with to
         | maintain provenance on plain old Python dict/str/list/etc.
         | objects [4,5].
         | 
         | [1] https://github/spack/spack
         | 
         | [2] https://spack.readthedocs.io/en/latest/configuration.html
         | 
         | [3] https://yaml.readthedocs.io/en/latest/
         | 
         | [4]
         | https://github.com/spack/spack/blob/95ca9de/lib/spack/spack/...
         | 
         | [5]
         | https://github.com/spack/spack/blob/95ca9de/lib/spack/spack/...
        
         | inopinatus wrote:
         | > You can think of everything as configuration
         | 
         | I wouldn't call this a problem, so much as I'd call it the most
         | consistent and coherent view of what "programming" is, and
         | being foundational to mechanical sympathy this is not an
         | abstract perspective.
        
         | Blackthorn wrote:
         | This would be sooooo nice, especially in DI heavy languages
         | like Java. It might not be turtles all the way down, but
         | finding the final turtle can be so difficult.
        
           | giovannibonetti wrote:
           | Object orientation kills traceability. Classes are
           | instantiated in one trace, then methods are called in another
           | trace, and if something goes wrong in the latter, it is not
           | trivial to find the wrong settings passed in the former.
           | 
           | I think some functional programming languages solve that by
           | running a good chunk (if not all) of the application in a
           | single trace.
        
             | Blackthorn wrote:
             | I disagree. Pretty much any program of enough size,
             | including those written in functional languages, are going
             | to have state that outlives the lifetime of a single call
             | stack.
        
             | gombosg wrote:
             | Yes, this is why we love functional programming! "What
             | happened along the way" equals to the call stack, as long
             | as there is no field mutation involved.
             | 
             | And, of course, async/non-blocking calls, as tracing a call
             | along different threads or promises may not be available
             | all the time.
        
               | asimpletune wrote:
               | Yeah, exactly. Referring back to the DI comment
               | earlier... In FP, "DI" is literally just calling a
               | function.
        
               | gpderetta wrote:
               | """The venerable master Qc Na was walking with his
               | student, Anton. Hoping to prompt the master into a
               | discussion, Anton said "Master, I have heard that objects
               | are a very good thing - is this true?" Qc Na looked
               | pityingly at his student and replied, "Foolish pupil -
               | objects are merely a poor man's closures."
               | 
               | Chastised, Anton took his leave from his master and
               | returned to his cell, intent on studying closures. He
               | carefully read the entire "Lambda: The Ultimate..."
               | series of papers and its cousins, and implemented a small
               | Scheme interpreter with a closure-based object system. He
               | learned much, and looked forward to informing his master
               | of his progress.
               | 
               | On his next walk with Qc Na, Anton attempted to impress
               | his master by saying "Master, I have diligently studied
               | the matter, and now understand that objects are truly a
               | poor man's closures." Qc Na responded by hitting Anton
               | with his stick, saying "When will you learn? Closures are
               | a poor man's object." At that moment, Anton became
               | enlightened."""
        
               | afiori wrote:
               | OOP is actually class oriented programming and classes
               | are orthogonal the object/closure duality.
               | 
               | For example in php class A { public $a = new B;} is not
               | valid
               | 
               | https://onlinephp.io/c/31246
               | 
               | Such a restriction makes no sense in a "closures are a
               | poor man's object" world.
        
               | gpderetta wrote:
               | Not sure what are you trying to say. My point was that a
               | invoking a function that will act on arguments that have
               | been defined away from the callsite is not a OO specific
               | feature.
        
           | louzell wrote:
           | It drives me nuts when systems are unnecessarily built with
           | "magic DI" frameworks rather than initializer/constructor DI.
           | Why is it so hard to pass a dep into the initializer? Make
           | the initializer parameter a protocol/interface and you can
           | pass a mock in at testing. And you can also grep the whole
           | codebase for callers and find the exact concrete type passed
           | in at runtime.
        
             | inoffensivename wrote:
             | IMO, automatic DI frameworks were a big mistake. An idea
             | that looks useful at the time, but actually leads to
             | spaghetti mess code that is harder to maintain than it
             | would be without any automatic DI.
        
               | erickf1 wrote:
               | Agreed.
        
             | Blackthorn wrote:
             | Eh, it's not like it's much easier to find the last turtle
             | in python. Or C++ when people are extensively using
             | patterns like PointerToImpl*, which can really obfuscate
             | things.
        
         | opensourceac wrote:
         | A feature of actuarial software is generating dependency graphs
         | of functions. Actuaries don't write the financial models that
         | power reporting processes in standard languages (Python, Julia,
         | C++) and instead have proprietary systems with features like
         | this.
        
           | etothepii wrote:
           | What systems are you thinking if?
           | 
           | In my experience most actuaries I interact with maintain
           | truly horrendous spreadsheets with labyrinthine complexity.
        
         | spawarotti wrote:
         | Truer words have never been spoken.
         | 
         | Microsoft IntelliTest (formerly Pex) [1] is internally using Z3
         | constraint solver that traces program data and control flow
         | graph well enough to be able to generate desired values to
         | reach given statement of code. It can even run the program to
         | figure out runtime values. Hence the technique is called
         | Dynamic Symbolic Execution [3]. We have technology for this,
         | just not yet applied correctly.
         | 
         | I would also like to be able to point at any function in my IDE
         | and ask it:
         | 
         | - "Can you show me the usual runtime input/output pairs for
         | this function?"
         | 
         | - "Can you show me the preconditions and postconditions this
         | function obeys?"
         | 
         | There is plenty of research prototypes doing it (Whyline [4],
         | Daikon [5], ...) but sadly, not a tool usable for the daily
         | grind.
         | 
         | [1] https://learn.microsoft.com/en-
         | us/visualstudio/test/intellit...
         | 
         | [2]
         | https://link.springer.com/chapter/10.1007/978-3-642-38916-0_...
         | 
         | [3] https://queue.acm.org/detail.cfm?id=2094081
         | 
         | [4] https://www.cs.cmu.edu/~NatProg/whyline.html
         | 
         | [5] https://plse.cs.washington.edu/daikon/
        
         | CodeWriter23 wrote:
         | The perfect is the enemy of the good.
        
         | fasterik wrote:
         | I suspect this is an area that is part of the essential
         | complexity [1] of programming. Reachability, variable liveness,
         | pointer aliasing, etc. are undecidable problems for arbitrary
         | programs. Also, the control flow graph of most non-trivial
         | programs is probably too complex to visualize in a usable way.
         | 
         | However, there is still a lot of room for improvement in
         | compilers and debuggers. If I could tell the compiler to
         | instrument my code to track the values that I care about, and
         | then have the debugger visualize the flow of information
         | through the system, that would be very useful. It wouldn't
         | guarantee that the data flow analysis applies to subsequent
         | runs of the program, but it could reduce the amount of time
         | spent reading and debugging code.
         | 
         | [1] https://en.wikipedia.org/wiki/No_Silver_Bullet
        
           | vaughan wrote:
           | Something that gives me hope is that I haven't seen anyone
           | prioritize debuggability in a modern programming language or
           | even a framework. Vale is maybe the first getting close:
           | https://verdagon.dev/blog/perfect-replayability-prototyped.
           | 
           | I think there is a new era yet to come.
           | 
           | > probably too complex to visualize in a usable way
           | 
           | You can always abstract the complexity. A simplification of
           | the control flow graph at the function level.
           | 
           | As an example, I want to understand the Postgres codebase
           | better...there are a lot of very visualizable things going on
           | there. If you look at lecture slides on relational DBMS,
           | there are lots of diagrams...so why can't be view those
           | animating diagrams as the code executes.
           | 
           | I was thinking of instrumenting the code to get a trace of
           | every function call and its arguments, and then filter that
           | and visualize it.
           | 
           | The key to this approach working though is a think ultimately
           | we need to write our code and organize our code such that it
           | can be easily visualizable. The purpose of code is for humans
           | to understand it, otherwise we are writing assembly.
        
             | Terr_ wrote:
             | > I haven't seen anyone prioritize debuggability
             | 
             | Static-checking tools and strongly-typed languages: "Are we
             | a joke to you?"
             | 
             | Finding and removing bugs _before_ the code runs is still
             | debugging.
        
         | eikenberry wrote:
         | This is mostly due to the procedural "recipe" style programming
         | paradigm that most developers seem to default to. It doesn't
         | scale well past small programs with the control flow being
         | embedded in the code so the only good way to follow the flow is
         | to track things through the callers. This is one of the reasons
         | I prefer dataflow programming styles that makes the control
         | flow explicit.
        
       | runeks wrote:
       | I would go one step further and say that all sources of runtime
       | configuration should be reportable:
       | 
       | * Config files
       | 
       | * CLI options
       | 
       | * Environment variables
       | 
       | And what takes precedence when.
        
         | nmz wrote:
         | this would also really help the CLI in terms of auto
         | completion, I see people go above and beyond writing completion
         | scripts, which could be simplified instead by running
         | --autocomplete or checking some file somewhere.
        
         | bbkane wrote:
         | I try to write all my CLIs this way - to the point of writing
         | my own Go CLI parsing library [0] to do it.
         | 
         | Now, when I run `cmd -h`, I get output like the following for
         | all flags (example from [1]):                 --count , -c :
         | Number of times to dig         type : int         default : 1
         | configpath : dig.combine.count         required : true
         | currentvalue (set by config) : 1
         | 
         | It's sometimes more verbose than I'd like, but it's quite
         | useful for figuring out how a flag got its current value
         | 
         | [0] https://github.com/bbkane/warg [1]
         | https://github.com/bbkane/shovel
        
       | sgtnasty wrote:
       | Are there any good examples of projects that do this really well?
        
       | MattPalmer1086 wrote:
       | I just implemented a "--config" command in my latest code that
       | reports exactly what was used for configuration, files and
       | environment variables, and where the files are actually located.
       | 
       | Makes life a lot easier imho.
        
       | c0nsumer wrote:
       | In my day job I do a lot of troubleshooting. That's most of my
       | job... helping other IT folks figure out what the heck is
       | happening with something.
       | 
       | I'd say that in 70% of things I work on, part of that time is
       | figuring out what config files are used because the
       | app/service/process/whatever is doing something the
       | owner/tech/whatever doesn't expect, yet is rational, and they
       | "didn't tell it to do that".
       | 
       | It'd be great if everything reported as the article mentions --
       | amazing, in fact -- but I feel like it's a pie in the sky wish.
       | Like asking that all programs always exit cleanly or something. I
       | feel like there'll always be inevitable edge cases -- libraries
       | that themselves pick up config files or registry values or
       | environment variables that aren't expected, who knows -- that'll
       | need to be discovered. If things are already not going right with
       | a program, I'm less likely to trust what it says it's doing and
       | more likely to just watch it and see what it's actually reading
       | and doing.
        
         | CoastalCoder wrote:
         | If any of the frequent offenders are open source, I wonder if
         | ot would be worth your while to submit (or get someone else to)
         | a change to add this functionality.
        
           | coldtea wrote:
           | "Submit a change and they'll include it" is the
           | demo/promotional version of FOSS
        
             | CoastalCoder wrote:
             | I suspect that varies from one project to the next.
        
         | johnchristopher wrote:
         | Yesterday I was wondering why the self signed root certificate
         | and the certificates I added to my debian install didn't work
         | with httpie (ssl warning) but did work with curl (and the
         | browsers I added the RootCA to).
         | 
         | I found the explanation:
         | https://github.com/httpie/httpie/issues/480 httpie doesn't look
         | into /usr/local/share/ca-certificates but apparently it's not
         | httpie's fault, it's the python requests library that doesn't
         | check that folder.
         | 
         | I don't know what to think of it and who is supposed to fix it.
         | But I am back to curl with my tail between the legs (because I
         | oversold httpie to my coworkers) for now. There's only one
         | place where the bucket stops with curl.
        
           | IshKebab wrote:
           | For once I would say it isn't Python's fault either. There
           | are at least 10 different locations that certificates can be
           | stored at on various Unix variants and Linux distros. Go
           | checks them all, which is probably the only sane solution,
           | but seriously come on Unix devs... Is it that hard to pick a
           | standard location?
        
           | EdwardDiego wrote:
           | Gosh sigmavirus24 is a salty chap.
        
             | imron wrote:
             | I read the thread after seeing your comment, and it strikes
             | me that besides the first comment being a little brusque,
             | sigmavirus24 comes across as both calm and helpful - doubly
             | so given that the original issue appears to have been
             | PEBKAC related
             | 
             | > I think I forgot to run "pip3 uninstall" and ran only
             | "pip uninstall" as I had to use python3 to get working ssl
             | in the first place.
        
               | DangitBobby wrote:
               | The issue is still open, so it has nothing to do with
               | PEBKAC. "A little brusque" is definitely underselling it.
               | That was a fine display of internet assholery.
        
               | EdwardDiego wrote:
               | My interpretation of saltiness was also formed by reading
               | the linked requests issue. Just sarcasm went unnecessary.
        
           | drunkpotato wrote:
           | I ran into this the other day as well.
           | 
           | You can override the REQUESTS_CA_BUNDLE env var to point to
           | your own certs.
           | 
           | https://stackoverflow.com/a/37447847
        
         | EdwardDiego wrote:
         | My favourite is a very bad pattern common in Docker images.
         | Just configure it with env vars, and then a script plucks them
         | into a config file somewhere.
         | 
         | And then document it misleadingly badly. These options are
         | mandatory! (lists 5 of the 10 actual mandatory options).
         | 
         | Then a script branches on a env var value, which isn't one
         | that's documented, and then fails opaquely if it took the wrong
         | branch because you didn't know you needed to set that env var.
         | 
         | Best ones are the ones that consume your env vars and set
         | _other_ env vars, it's great!
        
           | mch82 wrote:
           | How should this be done instead? Are there any good
           | docs/tutorials?
        
             | EdwardDiego wrote:
             | 1) Document _all_ the config options, and ensure you
             | highlight any interactions between settings, and explain
             | them. I 'm biased because I used to work on this project at
             | RH, but I really did like the documentation for Strimzi,
             | here's how their env vars are documented [0].
             | 
             | To highlight a few examples of how I think they're good:
             | 
             | > STRIMZI_ZOOKEEPER_ADMIN_SESSION_TIMEOUT_MS Optional,
             | default 10000 ms. The session timeout for the Cluster
             | Operator's ZooKeeper admin client, in milliseconds.
             | Increase the value if ZooKeeper requests from the Cluster
             | Operator are regularly failing due to timeout issues.
             | 
             | We know if it's required, what it defaults, and what I love
             | to see, why we might want to use it.
             | 
             | > STRIMZI_KAFKA_MIRROR_MAKER_IMAGES ... This [provided
             | prop] is used when a KafkaMirrorMaker.spec.version property
             | is specified but not the KafkaMirrorMaker.spec.image
             | 
             | I like this, explaining when this env var will or will not
             | be used.
             | 
             | > STRIMZI_IMAGE_PULL_POLICY Optional. The ImagePullPolicy
             | that is applied to containers in all pods managed by the
             | Cluster Operator. The valid values are Always,
             | IfNotPresent, and Never. If not specified, the Kubernetes
             | defaults are used. Changing the policy will result in a
             | rolling update of all your Kafka, Kafka Connect, and Kafka
             | MirrorMaker clusters.
             | 
             | Firstly, always great to enumerate all accepted values for
             | enum-like props. But what I really like here is that the
             | consequences of altering this value are explained.
             | 
             | > STRIMZI_LEADER_ELECTION_IDENTITY Required when leader
             | election is enabled. Configures the identity of a given
             | Cluster Operator instance used during the leader election.
             | The identity must be unique for each operator instance. You
             | can use the downward API to configure it to the name of the
             | pod where the Cluster Operator is deployed. (Code snippet
             | omitted)
             | 
             | Interactions between config options highlighted - if you
             | set STRIMZI_LEADER_ELECTION_ENABLED to true, this option is
             | now required.
             | 
             | We're told that this must be unique. And a suggestion on
             | one straightforward way to do this, with example code.
             | 
             | One more thing to call out as good:
             | 
             | > The environment variables are specified for the container
             | image of the Cluster Operator in its Deployment
             | configuration file. (install/cluster-
             | operator/060-Deployment-strimzi-cluster-operator.yaml)
             | 
             | Being told _where_ in the source code the env var is being
             | consumed is great.
             | 
             | Now compare the Confluent docs for their Kafka Connect
             | image. [1] A colleague of mine was using this image, and
             | was connecting to Confluent Cloud, so needs to use an API
             | key and secret. There's no mention of doing that at all.
             | But you can. Just merely set the CONNECT_SASL_JAAS_CONFIG
             | option, and make sure you also set
             | CONNECT_SSL_ENDPOINT_IDENTIFICATION_ALGORITHM and
             | CONNECT_SASL_MECHANISM.
             | 
             | And very importantly, don't forget
             | CONNECT_SECURITY_PROTOCOL, as not only will you have odd
             | connection failures (usually manifests as the client dying
             | at the ApiVersions negotiation stage of the Kafka
             | protocol's handshake), but because a script run in the
             | image uses the value of that undocumented setting to
             | execute a prerequisite in different ways [2], and you'll
             | get weird behaviour that obscures the real issue.
             | 
             | 2) Support more than one way of configuring things - maybe
             | I want to mount in a config file, maybe I want to provide a
             | ConfigMap, maybe I want to do it via env vars. Well... [3]
             | 
             | [0]: https://strimzi.io/docs/operators/latest/deploying.htm
             | l#ref-...
             | 
             | [1]: https://docs.confluent.io/platform/current/installatio
             | n/dock...
             | 
             | [2]: https://github.com/confluentinc/kafka-
             | images/blob/master/kaf...
             | 
             | [3]: https://strimzi.io/docs/operators/latest/deploying.htm
             | l#asse...
        
       | parentheses wrote:
       | This is a great idea. I feel that the best total situation is 2
       | things:
       | 
       | 1. A way to print the paths to all files visible that will be
       | read for configuration. This means that if the user config file
       | means the system config file is ignored, print only the user
       | config file path. Alternatively print that the system file will
       | not be read but show its path anyways. There's many ways to solve
       | this and it depends on the way the app loads configs.
       | 
       | 2. A way to print the final configuration after it's been loaded
       | and validated. This should show what settings override others.
       | For example if the user misunderstands the config merging or
       | erroneously quotes a numeric value causing validation to fail,
       | this would be a great way to triangulate that.
       | 
       | I've seen quite a few apps implement #2 but rarely do they have
       | #1.
        
       | kdeldycke wrote:
       | If you maintain a Python CLI, you can use Click-Extra [1].
       | 
       | It provides a ready-to-use --config option which reports how it
       | sources the configuration file [2]:                 $ my-cli
       | --verbosity DEBUG subcommand       debug: Load configuration
       | matching ~/.config/my-cli/*.{toml,yaml,yml,json,ini,xml}
       | debug: Pattern is not an URL.       debug: Search local file
       | system.       debug: No configuration file found.       (...)
       | 
       | It also adds an auto-magic --show-params [3] to help you see
       | where parameters are coming from:                 $ cli --int-
       | param1 3 --show-params       +-----------------+-----------------
       | ------------------------+----------------------------------------
       | -+------+------------------+---------+-----------------+---------
       | ------------------------------------------------+----------------
       | -----------------------------------------+-------------+       |
       | ID              | Class                                   | Spec.
       | | Type | Allowed in conf? | Exposed | Env. vars.      | Default
       | | Value                                                   |
       | Source      |       +-----------------+--------------------------
       | ---------------+-----------------------------------------+------+
       | ------------------+---------+-----------------+------------------
       | ---------------------------------------+-------------------------
       | --------------------------------+-------------+       | cli.color
       | | click_extra.colorize.ColorOption        | --color, --ansi /
       | --no-color, --no-ansi | bool |                 |        |
       | CLI_COLOR       | True
       | | True                                                    |
       | DEFAULT     |       | cli.config      |
       | click_extra.config.ConfigOption         | -C, --config
       | CONFIG_PATH                | str  |                 |        |
       | CLI_CONFIG      |
       | /home/runner/.config/cli/*.{toml,yaml,yml,json,ini,xml} |
       | /home/runner/.config/cli/*.{toml,yaml,yml,json,ini,xml} | DEFAULT
       | |       | cli.help        | click_extra.colorize.HelpOption
       | | -h, --help                              | bool |
       | |        | CLI_HELP        | False
       | | False                                                   |
       | DEFAULT     |       | cli.int_param1  | cloup._params.Option
       | | --int-param1 INTEGER                    | int  |
       | |        | CLI_INT_PARAM1  | 10
       | | 3                                                       |
       | COMMANDLINE |       | cli.int_param2  | cloup._params.Option
       | | --int-param2 INTEGER                    | int  |
       | |        | CLI_INT_PARAM2  | 555
       | | 555                                                     |
       | DEFAULT     |       | cli.show_params |
       | click_extra.parameters.ShowParamsOption | --show-params
       | | bool |                 |        | CLI_SHOW_PARAMS | False
       | | True                                                    |
       | COMMANDLINE |       | cli.time        |
       | click_extra.timer.TimerOption           | --time / --no-time
       | | bool |                 |        | CLI_TIME        | False
       | | False                                                   |
       | DEFAULT     |       | cli.verbosity   |
       | click_extra.logging.VerbosityOption     | -v, --verbosity LEVEL
       | | str  |                 |        | CLI_VERBOSITY   | WARNING
       | | Debug                                                   |
       | COMMANDLINE |       | cli.version     |
       | click_extra.version.VersionOption       | --version
       | | bool |                 |        | CLI_VERSION     | False
       | | False                                                   |
       | DEFAULT     |       +-----------------+--------------------------
       | ---------------+-----------------------------------------+------+
       | ------------------+---------+-----------------+------------------
       | ---------------------------------------+-------------------------
       | --------------------------------+-------------+
       | 
       | [1]: https://github.com/kdeldycke/click-extra
       | 
       | [2]: https://kdeldycke.github.io/click-extra/config.html
       | 
       | [3]: https://kdeldycke.github.io/click-
       | extra/parameters.html#show...
        
       | antirez wrote:
       | $ redis-cli INFO         ...
       | executable:/Users/antirez/hack/redis/src/./redis-server
       | config_file:/etc/redis/redis.conf         ...
       | 
       | In the case of Redis, it is possible to do much more. With the
       | CONFIG command you can check specific configuration parameters at
       | runtime, and even change most of them.
       | 
       | There are commands to get reports about latency and memory usage,
       | performing a self-analysis of the instance condition. You can see
       | counters for commands called, and even obtian a live stream of
       | the commands the instance is executing.
       | 
       | This should all be obvious features to make system software
       | approachable, observable, and to make people able to act easily
       | when shit happens, without having to guess where the
       | configuration file is from the system startup scripts or alike.
       | UX is not only about GUIs.
        
         | themoonisachees wrote:
         | Redis has consitently been the nicest program to admin
         | everytime i have to interact with it as a sysadmin
        
       | thecosmicfrog wrote:
       | I wish more programs had an obvious way of showing what
       | configuration values are _currently_ set. Something like `program
       | --config` with no arguments should print all configuration keys
       | and their current values.
        
         | reidacdc wrote:
         | Seconding this, for sure. "/usr/sbin/sshd -T" (T for "test")
         | has been a life-saver more than once.
         | 
         | My strongest version of this is that _any_ application that
         | manages _any_ state should be able to report on that state in a
         | human- and machine-readable way.
        
       | itomato wrote:
       | This is how we wind up with three implementations of a "Windows-
       | style Registry" while also having all the other management modes;
       | local dotfiles,system dotfiles, all of /etc and whatever is
       | allowed under /opt.
       | 
       | Be smarter about package management and this is a non-issue;
       | checksums, install-time dumps of file modifications, and the
       | like.
       | 
       | It's why tools like CFEngine and the rest were invented, and I'm
       | upset this is still an issue for people like OP twenty years
       | later.
        
       | sammy2255 wrote:
       | The popular VLC alternative MPV is very guilty of this. I got
       | shut down when I tried to discuss it in a Github issue
        
       | usrbinbash wrote:
       | Not only that, but past a certain complexity of the config,
       | programs should have a way to dump their runtime config to the
       | command line. Yes, I am talking to you, server daemons that take
       | configs from 2-3 different rc-file locations, hardcoded defaults,
       | envvars, the moon phase and the current market value of dried
       | parsnips.
       | 
       | If you don't have a way to simply tell me what your current
       | config is, then you have no earthly right to run it.
        
       | maxk42 wrote:
       | Perhaps we could implement some sort of standard switches, such
       | as _--locate-conf_ for reporting which configuration file(s) are
       | being read (and in which order) or _--show-conf_ to produce a
       | comprehensive list of set configurations.
        
       | koromak wrote:
       | Managing environments / staging / cicd / configurations is like
       | the hardest part of my job. Its fundamentally messy.
        
         | marcosnils wrote:
         | Have you seen https://dagger.io/? Managing all that with code
         | has been a life changer to me.
        
       | xbmcuser wrote:
       | I feel no standards for config files is probably the biggest
       | reason app containers got traction with advanced home users. Save
       | your docker containers nuke your server install move to a new
       | distro and reimport back the app container.
        
         | laeri wrote:
         | There are standards. The article even mentions the xdg base dir
         | standard. The problem is that not everyone follows them but a
         | large number still do and then it is easy to find them. I still
         | agree that app containers are still a good idea.
        
           | metaltyphoon wrote:
           | When standards are not enforced, they became optional and IMO
           | not really a standard.
        
             | laeri wrote:
             | The main culprits are programs that were written before the
             | standard existed in addition to many people that just don't
             | know about it.
             | 
             | Who should enforce this standard? I would say community
             | pressure does it pretty well at the moment. A standard does
             | not need to be enforced and the XDG base directory one is
             | still useful. The more awareness exists and the more people
             | want this and think it is useful the better. It also has
             | the advantage that no other competing standard exists as
             | far as I know but it still has some downsides.
        
       | markus23 wrote:
       | It should also report the syntax and so on, and actually you want
       | a way to directly modify configuration values. So if you think
       | this through, you will end up with something like
       | https://www.libelektra.org
        
       | leecommamichael wrote:
       | This has been the default (pun intended) on Apple OSes for a long
       | time. At the end of the day, the developer has the ability to
       | create/destroy files at will.
        
       | mberning wrote:
       | It would also be nice to have an "explain" option where it shows
       | how or why a value was updated. I am specifically thinking of
       | Ansible which has a multitude of locations from which it sources
       | variables. It would be nice to be able to spy on a variable and
       | report every value change and where that change came from.
        
       | irrational wrote:
       | Log files too.
        
       | jmbwell wrote:
       | Further: programs should use well-defined libraries to manage
       | config and data file location. As easy as it is to roll your own,
       | a library can and should handle cases you don't need to worry
       | about.
       | 
       | Python has platformdirs for this. It handles XDG and a number of
       | corner cases.
       | 
       | https://pypi.org/project/platformdirs/
       | 
       | Ideally the OS you deploy to should handle this as well.
        
         | hooverd wrote:
         | Thanks! You find a new Python lib every day.
        
       | firefoxd wrote:
       | phpinfo(); for all other languages.
        
       | tgv wrote:
       | I'm of the opinion that most programs should get their config
       | files explicitly from the command line. None of that ~/.apprc or
       | $APP_PORT=8080. That's inconvenient for tools you use often, like
       | ls or grep. If they read config files, an option like --ls-config
       | would be very welcome.
        
         | remram wrote:
         | Interestingly `LS_COLORS` is set by default on most
         | distributions... and you definitely wouldn't want to type that
         | in every time.
        
           | tgv wrote:
           | Every new account/os installation, I have to hunt around to
           | turn that off. I absolutely dislike colored output in almost
           | all cases. Might be because I'm color-blind. But they keep
           | moving those settings around. Perhaps that part is done in
           | their spare time by the MS Office menu bar team.
        
       | twunde wrote:
       | This brings to mind php's phpinfo. While often left publicly
       | available, it provided (provides?) information on all loaded
       | configurations.
        
       | bighoki2885000 wrote:
       | [dead]
        
       | paulddraper wrote:
       | Like                 cat /var/lib/dpkg/info/<package>.conffiles
       | ?
        
       | ilyt wrote:
       | As a system administrator I want 2 things from config files:
       | 
       | * loading a directory of config files, so various Configuration
       | Management tools have easier time deploying config (especially
       | for multi-use apps like say syslog daemon, where multiple
       | disparate apps might want to put a part of the config in)
       | 
       | * a function to dry-run config validation, so CM can alert about
       | that instead of restarting an app to a wrong config
       | 
       | Finding where is one has never been a problem.
        
         | themoonisachees wrote:
         | Seconding dry-run, while looking intently aws-cli for haveing
         | the worst possible dry-run option imaginable.
        
       ___________________________________________________________________
       (page generated 2023-06-25 23:01 UTC)