Skip to content

facts.server, operations.server: Make Mount fact and operation portable #1382

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

Open
wants to merge 1 commit into
base: 3.x
Choose a base branch
from

Conversation

DtxdF
Copy link
Contributor

@DtxdF DtxdF commented Jun 25, 2025

Using platform.system(...) is not a good idea because it runs on the local machine and we need to take into account the operating system of the remote machine.

  • Pull request is based on the default branch (3.x at this time)
  • Pull request includes tests for any new/updated operations/facts
  • Pull request includes documentation for any new/updated operations/facts
  • Tests pass (see scripts/dev-test.sh)
  • Type checking & code style passes (see scripts/dev-lint.sh)

Using `platform.system(...)` is not a good idea because it runs on
the local machine and we need to take into account the operating
system of the remote machine.
@DtxdF DtxdF changed the title facts.server, operations.server: Make Mount fact portable facts.server, operations.server: Make Mount fact and operation portable Jun 25, 2025
@@ -208,7 +208,7 @@ class Mounts(FactBase[Dict[str, MountsDict]]):

@override
def command(self):
if platform.system() == "FreeBSD":
if host.get_fact(Kernel).strip() == "FreeBSD":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this won’t work (can’t call facts from facts). Will need to include the check condition within the command itself.

Also noting to self should make this error properly here, as shown by the failing test case.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow the check get_fact call does work though. It returns what it should on my remote FreeBSD machine:

pyinfra  inventories/physical.py fact server.Mounts
--> Fact data for: server.Mounts
{
    "xx.xx.xx.xx": {
        "/": {
            "device": "zroot/ROOT/FreeBSD",
            "type": "zfs",
...

WIthout this change it returns an error:

[x] Loaded fact server.Os
[x] cat: /proc/self/mountinfo: No such file or directory
[x] Error: could not load fact: server.Mounts

Unintentional side effect?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting! Not intentional (which is why unit tests fail since they don’t mock this path), but this feels like something that would be very useful..

Need to have a proper think about the implications, but this would be a good addition I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I had doubts about that change but I have the same result as @jgelens comments, it works. The other solution is to put a conditional check through sh(1) in the command(...) function but using pyinfra for this is better.

This is what happens when I run pyinfra (excerpt):

...
--> Gathering facts...
    [control-centralita] Loaded fact server.Kernel
    [control-centralita] Loaded fact server.Kernel
    [control-centralita] Loaded fact server.Mounts
...

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.

3 participants