← index #12216PR #1095
Likely Duplicate · high · value 5.082
QUERY · ISSUE

ports/unix: please implement machine.unique_id()

openby paravoidopened 2023-08-11updated 2024-10-18
enhancement

What triggered this was my attempt to use micropython-mqtt from the Unix port, in order to run some tests with my code before moving this to an actual board.

The module uses a few things that are not implemented in the Unix port, and probably needs to be ported itself.

One of the issues, however, is machine.unique_id(), which seems... basic enough for the Unix port to have it.

One strategy could be to use gethostid(), which is deprecated in most Unix systems, as it's a 32-bit integer (not very unique). Another one could be to use /etc/machine-id, a UUID, which exists in -at least- modern Linux systems.

A search for /etc/machine-id yields:
https://codesearch.debian.net/search?q=%2Fetc%2Fmachine-id&literal=1
Most seem to be falling back to /var/lib/dbus/machine-id.

CANDIDATE · PULL REQUEST

machine: Retrieve an unique identifier if one is known.

mergedby agattiopened 2026-03-15updated 2026-03-19

Summary

This PR adds a proper implementation for machine.unique_id for selected systems, as opposed to returning a fixed value in every case.

On a Unix system there are several incompatible ways to retrieve something that can be called an unique machine identifier. However, the only semblance of a specification comes from freedesktop.org, which says that a file called /etc/machine-id has to exist and must contain a 32-digits long hexadecimal identifier - thus having a 128 bits unique identifier value.

Given that the current specification is the DBus unique identifier retrieval mechanism made official, if the identifier file is not found the code will attempt to read the file provided by DBus.

These changes only apply to Linux and recent BSD systems. On other systems the old, fixed value for the machine identifier will be returned instead, to avoid breaking compatibility with existing code.

The specification used in this commit is available at https://www.freedesktop.org/software/systemd/man/latest/machine-id.html.

<hr>

The manifest's version was bumped up by 0.0.1 since these changes only affect the behaviour of the module without making changes to the existing API.

Testing

This was tested on current MicroPython master, by adding require("machine") to ports/unix/variants/manifest.py and rebuilding the standard variant of the interpreter.

Then the output of import machine; machine.unique_id() was checked against the contents of /etc/machine-id on the host system. The fallback was tested by changing /etc into something else, and I/O error passthrough was tested by adding a directory that is not accessible by the running user to the front of the list of paths to check.

Trade-offs and Alternatives

These changes add 198 bytes to the machine module. Things could be made smaller by removing the identifier validation and skipping the DBus fallback.

Preliminary identifier value validation in theory could be removed, since the "unhexlification" step will raise an exception if the input data is not a series of hexadecimal digits. The current behaviour is to ignore the data read from the current machine identifier file and try the next one in the list. If stopping the identification process on unexpected data at any point is acceptable rather than gracefully handling the condition, this could shrink down by 43 bytes.

However, since there is an existing specification and a known alternative path for the same data, maybe it's not a bad idea to keep those two bits of code in.

Generative AI

I did not use generative AI tools when creating this PR.

2 comments
dpgeorge · 2026-03-19

Thanks for the patch! I never knew about /etc/machine-id until now.

Preliminary identifier value validation in theory could be removed

I think it's worth removing that validation step, to save code size.

agatti · 2026-03-19

Thanks for the review, I've removed the extra bits in question. The code still works as expected, and weirdly enough the size difference is now back to the initial iteration of this changeset (198 bytes, 317 - 119).

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied