twpayne/chezmoi

.chezmoi.hostname has sometimes a bad value on linux

Closed this issue · 7 comments

Describe the bug

.chezmoi.hostname has sometimes a bad value on linux. It infers a value from /etc/hosts which is incorrect instead of using HOST when defined.

To reproduce

$ hostname
myname
$ env | grep HOST
myname
  • Ask chezmoi the hostname value
$ cm execute-template '{{ .chezmoi.hostname }}'
www
  • Comment the added line in /etc/hosts and everything is fine
$ chezmoi execute-template '{{ .chezmoi.hostname }}'
myname

Expected behavior

chezmoi should not be sensitive to /etc/hosts contents and use hostname or $HOST as value.

Output of command with the --verbose flag

$ cm --verbose execute-template '{{ .chezmoi.hostname }}' 
www

Output of chezmoi doctor

$ chezmoi doctor

RESULT CHECK MESSAGE
ok version v2.46.1, commit c65f66a, built at 2024-02-11T16:33:13Z, built by goreleaser
warning latest-version v2.47.2
ok os-arch linux/amd64 (Debian GNU/Linux)
ok uname Linux leda 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux
ok go-version go1.22.0 (gc)
ok executable /home/arc/system/chezmoi/chezmoi-linux-amd64-2.46.1
ok upgrade-method replace-executable
ok config-file ~/.config/chezmoi/chezmoi.toml, last modified 2024-02-26T10:56:41+01:00
ok source-dir ~/.local/share/chezmoi is a git working tree (clean)
ok suspicious-entries no suspicious entries
ok working-tree ~/.local/share/chezmoi is a git working tree (clean)
ok dest-dir ~ is a directory
warning umask 077
ok cd-command found /bin/zsh
ok cd-args /bin/zsh
info diff-command not set
ok edit-command found ~/.local/bin/eb
ok edit-args ~/.local/bin/eb
ok git-command found /usr/bin/git, version 2.43.0
ok merge-command found /usr/bin/vimdiff
ok shell-command found /bin/zsh
ok shell-args /bin/zsh
ok age-command found /usr/bin/age, version 1.1.1
ok gpg-command found /usr/bin/gpg, version 2.2.40
info pinentry-command not set
info 1password-command op not found in $PATH
info bitwarden-command bw not found in $PATH
info bitwarden-secrets-command bws not found in $PATH
info dashlane-command dcli not found in $PATH
info doppler-command doppler not found in $PATH
info gopass-command gopass not found in $PATH
ok keepassxc-command found /usr/bin/keepassxc-cli, version 2.7.6
info keepassxc-db not set
info keeper-command keeper not found in $PATH
info lastpass-command lpass not found in $PATH
info pass-command pass not found in $PATH
info passhole-command ph not found in $PATH
info rbw-command rbw not found in $PATH
info vault-command vault not found in $PATH
info vlt-command vlt not found in $PATH
info secret-command not set

Additional context

$HOST (as well as $HOSTNAME) is not standard variable. In fact, there is no environment variables corresponding to hostname

I don't know why do you have it in your environment, but others don't have it. So I suggest to not use $HOST in chezmoi

Exactly, you can't set hostnames through environment variables. If you want the value of an environment variable then you can use the env template function.

Yes the description is very misleading. Sorry for that. The problem has nothing to do with $HOST or $HOSTNAME. I know that some people rely on it to avoid calling hostname too often, but let's forget these variables.

The problem is that cm execute-template '{{ .chezmoi.hostname }}' just does not return the name of the machine. That is, it does not return the same result that hostname does in some conditions. Theses conditions depending on /etc/hosts contents.

That is correct. It turns out that getting the hostname of a machine in a reliable way that works across multiple operating systems is hard.

If you want to use the output of hostname on your machines then you can use the template:

{{ output "hostname" | trim }}

If you want to avoid calling hostname every time then put this in your config file template:

[data]
    hostname = {{ output "hostname" | trim | quote }}

and then use

{{ .hostname }}

in your templates.

First thanks for the trick, config file template are very powerful. I even cheated using chezmoi.hostname = instead of hostname = to avoid touching my templates and it is working.

For the bug, it seems this is a regression between version 2.31.0 and 2.46.1. I'll try to narrow it when I have a little bit more time (not a go expert). Maybe the order of the methods changed ...

Thanks for your help.

For the bug, it seems this is a regression between version 2.31.0 and 2.46.1. I'll try to narrow it when I have a little bit more time (not a go expert). Maybe the order of the methods changed ...

This is not going to be a regression, but an algorithmic change because of other bugs. There are some explicit changes made between those two versions (#3055, #3082, #3104).

As Tom says, this is hard and every source system does this slightly differently — even different Linux distributions do it slightly differently or may have different results in some contexts (e.g., inside Docker).

First thanks for the trick, config file template are very powerful. I even cheated using chezmoi.hostname = instead of hostname = to avoid touching my templates and it is working.

Don't do this. It’s not a supported behaviour and the contents of .chezmoi should be treated as read only data and not updated during templating. We do not guarantee that this will work in the future and may make changes in the future that rebind the chezmoi runtime data before template execution that will break this.

That's clear, thanks.