Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

home-manager: Try short hostname in flake config lookup #3458

Merged
merged 1 commit into from
Dec 19, 2022

Conversation

kamalmarhubi
Copy link
Contributor

@kamalmarhubi kamalmarhubi commented Nov 29, 2022

Description

Depending on DHCP settings you might end up with different output from running hostname. Eg, your local hostname is mylaptop, and your home router is configured with a local domain of .home.arpa. In this case:

$ hostname
mylaptop.home.arpa
$ hostname -s
mylaptop

If you then go to cafe which has its router configured with .lan as its local domain. Then, if your DHCP settings accept the local domain from the router,

$ hostname
myalaptop.lan
$ hostname -s
mylaptop

With the pre-existing behaviour, if you had a "me@mylaptop.home.arpa" entry in outputs.homeConfigurations, running home-manager switch would fail:

$ home-manager switch
error: flake 'git+file:///home/me/.config/nixpkgs' does not provide
attribute 'packages.aarch64-darwin.homeConfigurations."me".activationPackage',
'legacyPackages.aarch64-darwin.homeConfigurations."me".activationPackage'
or 'homeConfigurations."me".activationPackage'

After this commit, you can put configuration in a "me@mylaptop" entry in outputs.homeConfigurations, and everything will work on either network.

Checklist

  • Change is backwards compatible.

  • Code formatted with ./format.

  • Code tested through nix-shell --pure tests -A run.all.

  • Test cases updated/added. See example.

  • Commit messages are formatted like

    {component}: {description}
    
    {long description}
    

    See CONTRIBUTING for more information and recent commit messages for examples.

  • If this PR adds a new module

    • Added myself as module maintainer. See example.

    • Added myself and the module files to .github/CODEOWNERS.

@kamalmarhubi
Copy link
Contributor Author

On the unchecked items:

  • tests: the home-manager executable is untested as far as I can see, so I didn't add anything
  • not adding a new module, so no changes there

I have not included a news item for this as I wasn't sure if it was news-worthy or not. Let me know either way.

@rycee
Copy link
Member

rycee commented Dec 3, 2022

I think this is a bug. It seems the call to hostname is done using the system version of hostname, which is incorrect. In particular I think the intention is to use the configured hostname. You could try replacing $(hostname) by $HOSTNAME instead.

@rycee
Copy link
Member

rycee commented Dec 4, 2022

I suspect that $HOSTNAME also would return the same as the hostname command, i.e., fqdn on macos.

Perhaps there is some other command that could be used on macos to get the configured host name?

@kamalmarhubi
Copy link
Contributor Author

kamalmarhubi commented Dec 7, 2022

Using $HOSTNAME—as you suspected, it doesn't do the trick; at the cafe:

$ bash -c 'echo $HOSTNAME'
gruyere.local

but at home:

$ bash -c 'echo $HOSTNAME'
gruyere.home.arpa

Re "configured host name", there are at least a couple of things that could mean on macos, and they can all be set / retrieved with scutil:

  • ComputerName: this corresponds to what someone sets in system settings, and it may contain spaces
  • HostName: this is unset on my machine; unsure in which conditions it is set it gets set
  • LocalHostName: this appears to be the same as ComputerName but with runs of non-domain-safe characters replaced by a hyphen (unsure of the precise substitution logic)

hostname -s appears to return the same thing as scutil --get LocalHostName.


Aside: from what I can see, HOSTNAME is only set in bash. The default zsh setup on macos does not set HOSTNAME at all. It appears to be special-cased in bash (source), and set during shell initialization to whatever gethostname(3) returns (source).

Testing this at the cafe that is one of the places that causes me hostname headaches:

$ cd "$(mktemp -d)"
$ cat <<EOF > gethostname.c
#include <stdio.h>
#include <unistd.h>

int main(void) {
  char n[1024];
  if (gethostname(n, sizeof(n))) {
    perror("gethostname failed");
  }
  printf("%s\n", n);

  return 0;
}
EOF
$ cc gethostname.c
$ ./a.out
gruyere.local

For comparison, hostname and scutil output:

$ hostname
gruyere.local
$ hostname -s
gruyere
$ scutil --get ComputerName
gruyere
$ scutil --get HostName
HostName: not set
$ scutil --get LocalHostName
gruyere

I'm not sure which would cause the least confusion: calling hostname -s as in this PR, or conditionally calling scutil --get LocalHostName on macos. Also the logic could be tidied up to make the failure error message less confusing, but I'd prefer to do that in a separate PR.

Let me know what you think the right next step should be :-)

@rycee
Copy link
Member

rycee commented Dec 7, 2022

@kamalmarhubi Thank you very much for the thorough investigation! It is very much appreciated.

I started reading https://apple.stackexchange.com/a/303411 and it seems to me that both hostname and hostname -s are a bit risky on macOS? From what I can tell, if you name your computer "foobar", then scutil --get LocalHostName would always return foobar. But if the DHCP server for some reason ignored your chosen name and gave your computer the host name baz.local then you would have

$ hostname
baz.local
$ hostname -s
baz

In other words, hostname would mislead us in both cases. Does that seem reasonable? If so then I think we'd have to use scutil --get LocalHostName in home-manager. That said, I notice that nix-darwin uses hostname -s so I think that would be good enough for us as well 🙂

@hauleth, I see you did the hostname -s change in nix-darwin. What do you think about the above?

@kamalmarhubi
Copy link
Contributor Author

@rycee @hauleth tiny bump: any further thoughts on the right solution here?

Depending on DHCP settings you might end up with different output from
running `hostname`. Eg, your local hostname is `mylaptop`, and your
home router is configured with a local domain of `.hoome.arpa`. In
this case:

    $ hostname
    mylaptop.home.arpa
    $ hostname -s
    mylaptop

If you then go to cafe which has its router configured with `.lan` as
its local domain. Then, if your DHCP settings accept the local domain
from the router,

    $ hostname
    myalaptop.lan
    $ hostname -s
    mylaptop

With the pre-existing behaviour, if you had a
`"me@mylaptop.home.arpa"` entry in `outputs.homeConfigurations`,
running `home-manager switch` would fail:

    $ home-manager switch
    error: flake 'git+file:///home/me/.config/nixpkgs' does not provide
    attribute 'packages.aarch64-darwin.homeConfigurations."me".activationPackage',
    'legacyPackages.aarch64-darwin.homeConfigurations."me".activationPackage'
    or 'homeConfigurations."me".activationPackage'

After this commit, you can put configuration in a `"me@mylaptop"`
entry in `outputs.homeConfigurations`, and everything will work on
either network.
@rycee rycee merged commit e7eba9c into nix-community:master Dec 19, 2022
@rycee
Copy link
Member

rycee commented Dec 19, 2022

I've merged it as-is to master. If there is any problem we can handle that in a separate issue. Thanks for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants