Systemd Home Directories
systemd.io
systemd.io
Maybe because they are not web devs so that they haven't had an annoying moment when they realize there is no proper way to add comments in package.json?
> Why JSON?
> JSON is nicely extensible and widely used. In particular it’s easy to synthesize and process with numerous programming languages. It’s particularly popular in the web communities, which hopefully should make it easy to link user credential data from the web and from local systems more closely together.
Was this written by a CSI or NCIS screenwriter?
Is a closer coupling between ‘the Web’ and local systems (especially concerning login and personal id) really what anyone needs?
I don’t even think it’s what anyone really wants, but sure, let’s find a way to make some random server located somewhere run by some SaaS be responsible for negotiating rights to access our own hardware.
It may not be the only way to access things, and I don't think the systemd maintainers will argue with you over the importance of single-box authentication robustness, only that compatibility is worthwhile and among the arbitrary formats there is a clear winner.
Why would anyone want to do such a thing? This sounds like an anti-feature (non-goal?) to me.
JSON and YAML do not belong in *nix config files.
What else will systemd do next? Audio? Kernel functions? Send mail? Read news? Become a web browser?
So I figure it will no later then 2023 before RedHat becomes IBM...
It gives you lots of niceties when you editing a file by hand and then you can just output a JSON object if you're generating the config with code.
It's my favorite thing ever to do something like:
- name: Configure $service.
copy:
dest: /path/to/config.yml
content: >-
---
{{ config_obj | to_nice_json }}
in Ansible.YAML's super clever upgrading of strings into other types is irritating ("foo: yes" is type {foo boolean}). Indentation-based semantics are not for everyone, and I think most of us would not mind the "noise" of braces. Other than that it's pretty OK. It's easy to write code that reads and writes it. It's very easy to read. It's above average but not prefect for writing (again, braces are pretty okay, not sure why they went the indentation route).
I agree with the article you linked that a lot of YAML implementations in scripting languages do dumb things like letting you put code in the file, and they all parse their special features differently. A config format does not need to be portable; while all these implementations do different things, they follow a format that continues to allow something to parse the entire file. So you can write an auto-formatter in Javascript (prettier) even though a Go program (kubectl) is going to actually read the file, and it all works.
I have used many other formats for config files. They all suffer from their fair share of problems. TOML/INI handles nesting very poorly (making you retype the names of all parent keys). JSON doesn't let you write comments or trailing commas, so it's hard to work on in your editor (running prettier on save fixes the trailing commas though). Text protobuffers are great but people look at you weird when you use them.
XML is a travesty. It is hard to write and hard to parse. It does all sorts of confusing things that humans do not expect, so it's really more of a binary format for computers to use than a text format for humans to write. (Remember, the XML spec says:
<foo>
bar
</foo>
is different from "<foo>bar</foo>" even though humans think they're the same.)XPath querying is great, I love it. But we have "jq" now that works on JSON and YAML.
Anyway, I think YAML is basically a fine format for config files. Perfect? Nope. OK? Yup. I will happily read or write a YAML file in a computer program or by hand. It's pretty OK.
This is because JSON is not a configuration format but a machine-to-machine data exchange format. Using it for configurations is using it for something it was not designed to do.
And comments were left out of JSON on purpose:
> Comments were purposefully excluded from JSON. In 2012, Douglas Crockford described his design decision thus: "I removed comments from JSON because I saw people were using them to hold parsing directives, a practice which would have destroyed interoperability." [27]
* https://en.wikipedia.org/wiki/JSON#Data_portability_issues
This is where you lose me. AFAICT, no two YAML parsers agree on what YAML is, so it's actually very hard to write code that reads and writes YAML because it has to be carefully tailored to work with whatever other YAML parsers are in your toolchain.
{
...
"comment": "this is a comment",
...
}Surely "#__comment__!11!!1#" would reduce the confusion !
grep -Pv '^\s*#'
to remove comments, passing the output of that to the JSON parser. The extension could be modified to .cjson, .json.commented, or something.Good thing JSON doesn't permit literal newlines in strings. Any valid JSON should be able to go through that comment filter without getting modified.
Sure. I wouldn't even try.
> And if you don't have that, you have a config file which can only be read, not written.
Just like most config files.
> And if you accept that, then what was the point of using JSON in the first place?
To not define your own format and be able to use ready-made parsers.
It's not like I'm advocating for the use of JSON over other choices like YAML. I'm just replying to a comment about how to add comments to a JSON with a better alternative. If someone wants to use JSON over other choices for whatever reason and the only thing holding them back is the lack of comments, then this is a valid way to add comments, I believe.
If you use a string property, you can't split your comment among multiple lines. You could perhaps do an array of strings or something, but I think adding a simple commenting syntax like this is neater.
EDIT: Fixed double negative in penultimate paragraph.
I'm not too worried about this being a "predictable interface names" type of solution to a problem I'm not having. What I'm really worried about is that of those 21K lines of code, only about 100 lines deal with testing, in the form of two bash scripts performing end-to-end tests against the main executable `homectl`.
At $DAYJOB, we find that to achieve any sort of acceptable coverage (which we've arbitrarily defined as 80% or better) -- you'd expect the ratio of production code to unit test code to be close to 1:1, and not anywhere near the 200:1 like this code here.
I mean, either those are some _very_ efficient E2E tests, or we have a small number of happy paths being covered here, and we the users will have to weed out all the corner cases that weren't tested.
Moreover, since these are E2E tests and not unit tests, that makes me immediately worry about the quality of the code. I know that unit testing is not very common on C-land, but is it really that unheard of in C-land in 2020?
https://hackaday.com/2019/10/16/pack-your-bags-systemd-is-ta...
That would require having the same software versions installed on every system. But even then it wouldn't work because the user-settings stored in $HOME might depend on the hardware, e.g. monitor setup etc.
That said, JSON? Pick a format and stick with it. Camel-cased ini files wasn't my first choice but consistency matters more at this point.
Only if you don't care if it works or not. Or runs or not. Or don't care about dependencies.
Stuff like 'what will happen if the NFS server my job depends on is unavailable for the 10 minutes in which my job executes'. Is it ok for a bunch of cron jobs to hit a stale nfs share and hang and then execute all at once?
If any of those things matter then you have to then orchestrate a combination of logging solutions, monitoring solutions, and a bunch of extra logic to your scripts to make sure they work.
This is why it's foolish for enterprises to depend on cron for anything serious and why people use complex batch management software for critical batch.
Systemd timers offers a intermediate solution built into the OS.
And then your cron job runs again, because the first instance didn't finish in time. So you need to protect agains parallel execution.
And then your cron job doesn't run, because your machine was off when it was supposed to. So you need to track when it was supposed to run, and run it.
And on and on and on. Systemd timers manages all this bookkeeping stuff so you can focus on one thing only: what your script needs to do.
Which it already does. Success on Unix/Linux is silent and any output from a cron job gets emailed by default.
> And then your cron job runs again, because the first instance didn't finish in time. So you need to protect agains parallel execution.
So you use flock(1) with --timeout equal to the launch interval. Assuming parallel execution is actually undesired; maybe you want it. Suppose you have a job to gzip the day's data, and if it takes 30 hours to do it, you still want to run tomorrow's job on time because tomorrow's job is running on a different day's data.
> And then your cron job doesn't run, because your machine was off when it was supposed to. So you need to track when it was supposed to run, and run it.
What do you propose to do instead if the machine is powered off? If it's supposed to run once a day and the machine is unplugged for three days, should it immediately run three times as soon as you turn it back on? Should it run once, but then run again only an hour later at the time scheduled for today, thereby still running twice in the same day? If the launch arguments take today's date, which day do you pass?
You still have to specify what you want one way or another. It's not clear how specifying it in a shell script is any worse than specifying it in a unit file, and it can certainly be better, because arbitrary code can solve arbitrary problems. Unit files are limited to specific directives unless you want to rely on unit files calling shell scripts, and in that case why do I want to write a unit file and a shell script instead of only writing a shell script?
The flaw in systemd is that it doesn't do one thing, it tries to do everything. Instead of launching tasks with cron, logging errors with syslog, preventing parallel execution with flock etc., systemd tries to do all of that. Worse, it assumes that once you use it for anything you'll use it for everything, so if any piece of it is unsuitable it's not as easy to swap out only the unsuitable bit for an alternative.
The result is that the things it was specifically designed for are easy, but they were pretty easy already, meanwhile the things it wasn't specifically designed for become significantly more convoluted than they used to be.
That's for Lennart Poettering to decide[0].
[0] I don't make the rules
Hmmm, maybe it'd be worthwhile to just make emacs PID 1.
In particular, this bit from the article sounds like hand-rolled, informally-specified canonical S-expressions[0]:
> It is recommended to bring the record into ‘normalized’ form (i.e. all objects should contain their fields sorted alphabetically by their key) before storing it there, though this is not required nor enforced.
It really is true that those who do not understand Lisp are doomed to reinvent it.
You mean, we want to be nice Windows, before the Registry?
https://en.wikipedia.org/wiki/GNU_Guix#GNU_Shepherd_Init_sys...
So does Linus Torvald's git version control utility.
TOML has a formal standard while ini files have no formal standard being the big difference.
There is no formal git-config standard other than what's deployed in git.
Will it work? Will the small tradeoffs be worth it? (Like remotely logging in via ssh to a locked desktop machine somewhere...) ...
I guess I'm thinking the Chromebook style experience, but without the google involvement.
Separately - I've often wondered if iPhones couldn't be a bit more user agnostic in this way, perhaps among a family. Couldn't a son pick up his mother's iphone, log on with is Apple ID from the lock screen (assuming she has enabled 'family share') and have access to his messages, accounts, contacts, etc, but not large media? I can't see Android getting there sooner, but this would be a very useful feature I think.
Why? iPhones still don't support multiple users natively as far as I can tell. Android has this by default since... 7? 8?
Once you have everything set to sync to google services, it's really close to having this behaviour.
Yet, all the things he mentioned, like, remotely accessing a locked laptop via ssh, or maintaining a external user database for a cluster of machines in LDAP, are things I do on a regular basis.
He also mentioned something about requiring a privileged daemon to change your ssh keys? Is there any more information about that?
Given the gravity of systemd, and all it's ancillary services, how long till this is the one true way? How does this work in the case of true remotely accessible multi-user systems?
And they might actually achieve this there, since SSSD is another abomination that kinda does that and mostly works, but once it doesn't and you try to debug it, you want to stab yourself in the brain with a dumb object.
For any other distro, I very much hope this thing is not enabled or even installed by default. Since I don't get the complaints about ecryptfs. I've been using it since around 2012 on multiple machines, multiple dist-upgrades and password changes and it never failed me once. Oh and SSHing into the machine works as expected!
This was impossible to debug. You could send some signal (USR1 or 2 iirc) to sssd to force it into online mode, we even tried a crude script that would run after system resume and spam sssd with that signal for a minute to no avail. Shortly after I left that department the decision was made to move to Centrify. It's a pita in other ways apparently, but everything I know about it is just from hearsay from old colleagues aynways.
As you eluded to, the problems this is trying to solve include better integration/less rough edges with enterprise authentication (AD and the like), encrypting home directories, and making home directories and user accounts more portable. Anyone that does desktop fleet management will find a lot of stuff to be excited about here.
What do you do if you've left files on your desktop at home/work and need them from work/home?
Im personally curious to see how this works with a tool like Syncthing
Microsoft and Google do this because they make money out of monetizing their users. What's systemd's excuse?
As far as USB goes-- can you suggest a currently manufactured _good_ usb storage device? I've found myself scrounging for old ones because anything currently made are unreliable, slow (in spite of amazing performance claims), or usually both.
This doesn't really make sense as a response to comment mentioning Syncthing which works with any backend, including your other machines.
> What's systemd's excuse?
Systemd's excuse for what exactly?
Who do you think is putting the resources (manhours/money/etc) into mainlining this crap into Linux? It's the corps. Add Intel to the list.
For now. Until GNOME pulls it in as a dependency.
And also, this is just the default, the mechanism is general, how to do this unlocking can be done in many ways by other people who want to use these tools.
Is this really so common as to deserved two questions marks and an exclamation point? As one datapoint, if I've left files on my desktop at home that I need from work, I get fired.
Is it what most "normal people" do? Of course not! Most normal people buy a spyware 'smart TV', roku, or some other proprietary appliance. So why the hell should the common habits of the general population be considered? If their habits are to be the guiding principle of the linux desktop, I'll soon have no reason to use the linux desktop.
Incidentally at one of my former (FANG) workplaces, each developer was given a RHEL workstation and a windows or mac laptop. Using ssh from one's laptop to access the workstation while in meetings, working from home (including oncall in the middle of the night), etc was common and permitted. This is not as crazy as you seem to think.
https://www.freedesktop.org/software/systemd/man/homectl.htm...
> Takes an RFC 7512 PKCS#11 URI referencing a security token (e.g. YubiKey or PIV smartcard) that shall be able to unlock the user account. The security token URI should reference a security token with exactly one pair of X.509 certificate and private key. A random secret key is then generated, encrypted with the public key of the X.509 certificate, and stored as part of the user record. At login time it is decrypted with the PKCS#11 module and then used to unlock the account and associated resources. See below for an example how to set up authentication with security token.
Key hierarchy management can probably be delegated to an external system.
In fedora, at least, it requires only three lines of configuration changes (adding the pam hooks, and setting up the mount point in the pam_mount config).
What if your password is in LDAP, and you change it the OpenLDAP back-end? Or if you have OpenLDAP talk to AD (via SASL) for password checks, but the rest of the GECOS & group is in LDAP? Is Kerberos covered? How is NFS handled? Automounts?
Doing a ^F I find no mention in the man page of either LDAP or Kerberos.
We already sorta have this now. What I'm (half-jokingly) suggesting is a big ugly fork a la Emacs/XEmacs, where the world visibly and somewhat incompatibly separates.
And like that fork we'll end up with everything more-or-less reconciling eventually, but it's going a weird ride until then.
BTW, among other problems that the plan 9 paradigm alreay solved, I'm pretty sure they solved the security issues that Wayland was intended to solve, and from what I understand, I'm pretty sure they did a better job, too.
My religious view, having started since the Slackware on CD days with original rc and experienced upstart, launchd, openrc, daemontools, runit, daemontools-encore and s6 is: SystemD does too much, has too many dependencies, does it awkwardly and is unfriendly to configuration management, robustness, troubleshooting, "least surprise" principle and simplicity.
If I were Debian devs, there are two choices to init-agnosticism: a) pick one init provider at a time or b) manage multiple init systems simultaneously. For the latter, a very simple meta-init process could either exec() the only init system if one is used or supervise 2+ init systems. Then, there would need to be a tool to manage the lifecycle of a service no matter which init system it belonged to.
It might be easier to pick a), but a common use-case is to use daemontools for custom or other services that need to be kept running. Granted, there are probably packages that already run daemontools, runit or daemontools-encore as a child under the existing system init.
It's times like these that I wish there were a capabilities-oriented standard file layout such that every service knew how to start, soft-stop, hard-stop, enable, disable, reload-config and validate-config itself rather than every N init system having to find magic command-line args to not spawn in the background, change the user/group and change the log level, ports, bound address(es) and log destination. And then Cfengine, augeas, puppet, chef, salt, etc. reimplemented all of that logic per service. Services should also know how to backup/restore/wipe their own data (if not a 12Factor service themselves), whether they're up/down and how to gather their own metrics... and then cacti, nagios, nrpe and so on implemented all of that sort of logic per service too. sigh Cross-cutting concerns should be managed at the place that knows best how to manage the data and process lifecycle best: per service. Then, once that's done in a standard way, /etc configuration and configuration management can customize away. Having each service become enumerable and discoverable like a Bluetooth profile is another matter.
Experimenting with FreeBSD has been a breath of fresh air. Things I've come to expect to take an extended amount of time figuring out just work out of the box.
Some systemd advocates say the critics are just upset at change. I don't dislike change in general, but changing defaults out from under me? Defaults like this? That irks me. I lost a several tmux sessions before I realized what was happening. I thought I was doing something wrong because SystemD violated my expectations so severely.
The whole point is for the administrators to be able to avoid users running long-running processes on shared systems (e.g. university systems).
Of course not. But I do want to have the nohup software they have running to keep running when they log out.
> The whole point is for the administrators to be able to avoid users running long-running processes on shared systems (e.g. university systems).
Right, which is why it should be possible to do this. The issue is that the default behavior has changed from honoring nohup to not honoring nohup. Defaulting to honoring nohup is what's expected, and is reasonable.
It not supposed to be the 'true' way. Its supposed to be an option for specific envoirmentments.
Now Linux feels like all the other “enterprise” systems I deal with on a daily basis: baroque, complex, confusing, and over-engineered.
with USER COMMAND: This command is useful for running privileged backup scripts and such, but requires authentication with the user's credentials in order to be able to unlock the user's home directory.
resize USER BYTES: Change the disk space assigned to the specified home directory.
https://www.freedesktop.org/software/systemd/man/homectl.htm...
Also, if this makes setting up an encrypted home directory even slightly easier I am all for it. I setup ecryptfs on Rasbian a few weeks ago and there are a few steps that feel hacky if using a headless host and ssh.
See minute 20:00: https://media.ccc.de/v/ASG2019-164-reinventing-home-director...
Why couldn't this have gone into ~/.config/? There's enough garbage cluttering my home directory.
Since the user record is cryptographically signed the user cannot make modifications to the file on their own (at least not without corrupting it, or knowing the private key used for signing the record).
That sounds like something that shouldn't even be in the user's own home directory.
...and JSON, of all things. Every aspect of systemd which I've worked with seems to be full of sprawling complexity and overengineering, and this is no exception. I know "it's not the UNIX philosophy" is a common dismissive complait about it, but looking at the design gives a very different feeling than the "original UNIX" designs, which felt humble and simple.
Right? Reasoning was "the web people are using it too". Why not just use key value based config files like every other system tool?
boolean, number, string, array, object, null
Sounds simple to me.
This is not an academic question: large integers are common, for example, as cryptographic keys.
But in this case I can't complain. It's literally about the behavior of the home folder. This one makes complete sense to me.
I used to be that guy. Now I’m not. Re workarounds: usually that means env vars, but all that crap in env is copied to the execution environment of every single process, which is pretty awful. Re bug reports: usually only a few “that guy”s care at all, sometimes there’s endless debate about whether things go into XDG_DATA_HOME or XDG_CACHE_HOME, the occasional accepted PR requires so much effort I might as well just try to forget about all the garbage sitting in the $HOME.
> Since the user record is cryptographically signed the user cannot make modifications to the file on their own (at least not without corrupting it, or knowing the private key used for signing the record).
> This file system should contain a single directory named after the user. This directory will become the home directory of the user when activated. It contains a second copy of the user record in the ~/.identity file, like in the other storage mechanisms.
Not quite sure what the purpose of this copy is, given users can delete / replace it?
https://specifications.freedesktop.org/basedir-spec/basedir-...
There's also the deal with recovery from bad situations (tm) or reviving long-dead home accounts.
Edit: isn't JSON technically not free-as-in-freedom?
One implementation was nonfree due to that whole don't be evil clause. Systemd uses json-c, which is permissively licensed from what I remember.
Eg this project (note, it appears to be early stages - but have a look at the zfs commands in the readme for a ses se of what zfs already supports):
https://github.com/BenKerry/zfscrypt/blob/master/README.md
Apparently systemd doesn't consider zfs a friend, though. So I doubt we'll see integration from upstream systemd.
Then how will they verifiy the signature of the user json file?
So I can't simply remount the user profile on another system?
Seems like a step back.
I've been able to do this for decades, just copy the files. Why would I want systemd for that?
systemd has already made my textual log files binary and only accessible with their own viewer. Now it's going to apply its philosophy to my home directory too?
This could genuinely be a viable lightweight alternative to LDAP/IPA in offices that hotdesk. Just sign the user's drive once and they can plug-in to any workstation.
I guess it would only be a problem when migrating, systemd is presumably happy to have lennart's home dir in lennart.homedir, and lennart.homedir's homedir in lennart.homedir.homedir...
Ed: actually km more concerned with how this (doesn't) work with Pam, getent etc. If ldap, yellow pages or /etc/paaswd specify a home-dir that's not at /home/<username>... Should the system still look at <whatever path>.homedir? But only for interactive logins? Will a daemon running as the user have a different home dir? Will cron? At? The system processing dot.foward/sieve filters?
Q: am I understanding correctly that you cannot use btrfs subvolumes while also using fscrypt? does it not make sense to use both?
CIFS home directories is another feature I’m excited for. I’m sure it would have plenty of downsides to using a local filesystem but as of right now I find it cumbersome to have non-local home directories at all.
Without key revokation and online-only, ex-employees plugging in their home directories and regaining their employee privileges, because the trusted .identity file says they are in the staff group.
Buy systemd has no business sticking its nose in authentication or storage, or more generally telling me how to manage users. This is a no.
You may as well ask why Lennart rages so hard against ZFS.
Also remarks and doubts on the use of json for this purpose is completely irrational?
If another open source program depends on it by default, then you can patch it to remove the dependency. If you disagree with the concept of JSON, feel free to write your own data format.
I have zero interest in using this feature, but still I find it really embarrassing that I have to regularly explain this basic concept of open source here. And I don't mean that as a dig at you, I mean it in the sense that there is a lot more work we have to do.
Especially this: "If another open source program depends on it by default, then you can patch it to remove the dependency." and "then it's up to you if you want to use some feature or you want to do it a different way."
Now recently also Debian has decided to drop support for other init systems. It just wasn't practical anymore. Now you get to be on the lookout when you "want to use some feature or you want to do it a different way." because if you don't you end up with shit like this: https://news.ycombinator.com/item?id=19291067 Now we get to see hilarious stuff like a systemd developer asking tmux to add systemd specific code to work around systemd's own default behaviour. Now we get BSD's putting in work to deal with the prevalence of Systemd. Now we get those working with embedded linux putting in work to deal with the prevalence and dependency on SystemD. Because at the end of the day the systemd devs don't care about ulibc, non linux and what have you whilst at the same time seeming to really want to set the standard for as much as possible.
My problem with systemd really isn't what it does, though: it's how it does it. It's as though someone looked at late-90s Microsoft and admired the taste.
$ man systemd
NAME
systemd, init — systemd **system** and service manager
managing your whole Linux system in an unified way, with a single configuration language to learn, a single syntax for commands, and a shared framework allowing to refer to systemd domain objects (units) from everywhere where they can be relevant (journal, network, fstab, etc) is the raison d'être of systemd. It's why it has been created.So has anybody tried filing a bug for homed using JSON yet? Either homed is wrong, or that manpage is wrong.
+ JSON