Googler, opinions are my own.
Sometimes we use flags on my team for controlling experiments and whatnot, flags tend to be used for more static settings, like the name of other jobs we call.
We have a few configuration languages at Google, and many of them will push to production very quickly. We tend to use these for experiment controls.
The problem with flags as experiment controls, if you need to roll back quickly. It's a lot slower because you have to wait for all the jobs to restart.
Also for us, we can't SSH onto hosts, and the scheduler that actually knows about args/pids/etc is fairly deep behind the curtain, but HTTP access is easy. But you could see different companies having different constraints.
a) log the entire config at startup.
or
b) create a specific file with config used, if logging is too messy.
or
c) make an API to return the running config.
or
d) use envvars in a container, that you can just dump from 'env' at will.
All of which would be cleaner and saner than browsing top.
Yes? With just flags, the only artifact that you depend on is the program. With a config file, now there is a separate artifact to maintain for every distinct configuration, which could be a lot. I'm not saying its not solvable, but it does strike me as more complicated.
There must be some kind of config system where the flags are being driven from though, unless someone is manually typing them out each time.
- open some descriptor on the system
- write the file content
- execute the command
- get rid of the file
Of course you'll also need to deal with the constraints/failure of any of these steps (write the file in a location the program can access, take care it still exists or is not overwritten when you run the command, so have pseudo random names and/or lock the file, etc.)
In comparison, passing it all as args is one single step.
+ Another artifact to ship and deploy
+ What file format to use? Obviously different teams will use different formats too. This compounds as you add engineers.
+ How do you find the initial file? Whichever mechanism you use besides hardcoding it is another gateway to configuring the program. It will be used in addition to the config file and compose in weird ways.
I think the limitations of the command line actually make it scalable especially in the Google context.
I arrived at this solution after getting tired of both having to track down where the value for a particular setting originated at runtime, as well as having multiple implementations of the same kinds of argparse/os.environ/file-based settings systems across our internal tools and scripts.
Problem solved.
Plus I have the full programming language available, not some textual subset with Yet Another Dependency to read it.
I made my hacks open-source, so if you have a Click-based Python CLI, try click-extra, contribute back, and help me solves this problem once and for all: https://kdeldycke.github.io/click-extra/config.html
With restraint and thought you can make the 2 equivalent from a data perspective. That's a ton of effort and if you get it wrong it is pretty hard to change it later on because someone is going to start relying on previous semantics.
Esr even contradicts himself at the end of that link when he says that site wide configs may be immutably set in the system directory.
I've lost count of the numbers of times I've straced commands to see where they pull configuration from or grepped thru codebases looking for getenv calls. Any unix consensus for configuration is in theory only not practice.
File location is actually pretty germane to precedence. A more "global" configuration cannot be applied if the program is looking for it in the wrong location in the first place. Let's not even discuss the horrible state of where to store local configurations in a users home directory. As long as it starts with a . it's fine :).
I've used Linux exclusively for nearly 20 years - but not because I loved its configuration management story.
We are arguing over whether the glass is half empty or half full. I can also come up with plenty of examples of poorly designed programs, but I can also bring up examples of programs which are not perfect but much more usable than ls. I’m sure you could have also picked a program which is better designed than ls as well.
I think people are overly focused on how crappy Unix tools from the previous millennia are (ls, sendmail, dd, etc…) but I do truly believe that cli tools can be ergonomic because I have used and built tools which feel ergonomic.
Flags at command line time can be equivalent to flags in file from a data perspective.
If you work on it they can behave with similar semantics too.
If you work even harder you can ensure you deploy the config file atomically with the binary. You can also make sure that the file is properly secured, and config values from it are observable and auditable.
Or you can just mandate that programs are configured by the command line flags passed to them and not have to do all that extra work.
But when the command line invocation is so big that you can barely even copy/paste it any more, and it exceeds the max command line length on a stock Linux kernel, you’re way past the point of convenience being the important factor. All the normal places you’d want to see the flags (set +e in a bash script echoing them back to you, etc) are suddenly overloaded with megabytes of text for a command line invocation… who’s gonna look at all that? Who is this serving any more?
“Flags for everything” would seem like a good idea taken way too far to me.