twpayne / chezmoi

Manage your dotfiles across multiple diverse machines, securely.
https://www.chezmoi.io/
MIT License
12.9k stars 478 forks source link

Machine UUID variable #3896

Closed jloh closed 1 month ago

jloh commented 1 month ago

Is your feature request related to a problem? Please describe.

I backup my machines using Restic which attaches a hostname to each backup. The problem with this is a machines hostname can sometimes change depending on the network its on/if a DNS collision happens (with laptops for example). The fix for this is setting --host on your backup which forces the hostname to be a specific.

Describe the solution you'd like

I'll describe how I currently work around this below but I would like to be able to read a machines hardware UUID so I can easily ensure that specific machines (laptops in my base) always get the same host setting in Restic. This would let me template me Resticprofile config so that I always set host to the same value on that specific hardware, even if the hostname changes.

Describe alternatives you've considered

I currently handle this using a variable in my Chezmoi data called restic_hostname but that requires me remembering what I've set it to before when rebuilding.

I've thought about trying to use a script to read the file but I don't know if its possible to read data like that currently.

Additional context

On Linux the hardware UUID is available at /sys/class/dmi/id/product_uuid which seems to work well in my testing. I've tested a headless Debian based hardware server and a Debian based Hetzner VM. Inside a LXC container running under Proxmox that file doesn't work, the container doesn't have permission to access it.

On OSX things are a little bit more tricky. The command ioreg -rd1 -c IOPlatformExpertDevice prints the UUID in a semi-JSON blob that contains a lot of other data, so not sure how parseable that is.

Thanks in advance for considering and creating Chezmoi, absolutely love the tool.

jloh commented 1 month ago

I've just realised I could use a run_once script to populate a data value in .chezmoidata that gets ignored in git in the meantime, that makes things pretty easy.

halostatue commented 1 month ago

I think that this is not a bad request since it would be stable. There appears to be https://github.com/denisbrodbeck/machineid as a library for Go, but it hasn't seen any updates in a while (there are few updates required once solved, but there are open issues and PRs); there is a more recent fork at https://github.com/DarkiT/machineid and an alternate implementation at https://github.com/mycalf/mid.

With respect to your run_once script, I think that's the wrong approach. Instead, you should have this run using output in your .chezmoi.$FORMAT.tmpl configuration template, since that is not kept in git at all.

Also, for macOS, this is the best suggestion I have seen for getting the IOPlatformUUID:

ioreg -d2 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/ {print $(NF-1)}'
twpayne commented 1 month ago

With respect to your run_once script, I think that's the wrong approach. Instead, you should have this run using output in your .chezmoi.$FORMAT.tmpl configuration template, since that is not kept in git at all.

Closing this issue because @halostatue has the right answer. It's simultaneously more powerful, more generic, and more flexible than adding a machine UUID template function.

jloh commented 1 month ago

@halostatue thanks so much for the response, I had no idea the output function existed, thats exactly what I want.

I ended up with this:

hardwareUUID: {{ output "sh" "-c" "ioreg -d2 -c IOPlatformExpertDevice | awk -F'\"' '/IOPlatformUUID/ {print $(NF-1)}'" | trim | quote }}

Because I had some trouble escaping awk and getting pipes to work, otherwise its working great.

Thanks for creating Chezmoi @twpayne, its so powerful!