Skip to content

facts.server.Mounts broken on 3.4 #1398

@DtxdF

Description

@DtxdF

Describe the bug

  1. Calling the facts.server.Mounts fact from the fact operation results in the AttributeError: 'gevent._gevent_clocal.local' object has no attribute 'module' exception.
  2. Calling the facts.server.Mounts fact from a deployment file results in the ValueError: not enough values to unpack (expected 2, got 1) exception.

To Reproduce

  1. AttributeError: 'gevent._gevent_clocal.local' object has no attribute 'module':
    console:

    $ pyinfra --limit control-r2 inventory.py fact server.Mounts
    ...
    AttributeError: 'gevent._gevent_clocal.local' object has no attribute 'module'
  2. ValueError: not enough values to unpack (expected 2, got 1)
    deployments/appjail.py (excerpt):

    if host.data.get("tmpfs"):             
      files.directory(                     
        name="Create directory for temporary directory",
        path="/usr/local/appjail/cache/tmp/.appjail"
      )                            
                                           
      files.line(
        name="Configure fstab to mount the in-memory temporary directory",
        line="tmpfs /usr/local/appjail/cache/tmp/.appjail tmpfs rw,late 0 0",      
        path="/etc/fstab"               
      )                                                                            
                                           
      server.mount(                  
        name="Mount tmpfs as the temporary directory",                             
        path="/usr/local/appjail/cache/tmp/.appjail",                              
        options=["rw"],                                                            
        device="tmpfs",
        fs_type="tmpfs"                    
      )

    console:

    $ pyinfra -y --limit control-r2 inventory.py deployments/appjail.py
    ...
    ValueError: not enough values to unpack (expected 2, got 1)

Meta

  • Include output of pyinfra --support:
     /home/user/Devel/pyinfra/env/lib/python3.11/site-packages/paramiko/pkey.py:82: CryptographyDeprecationWarning: TripleDES has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES and will be removed from cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.
       "cipher": algorithms.TripleDES,
     /home/user/Devel/pyinfra/env/lib/python3.11/site-packages/paramiko/transport.py:253: CryptographyDeprecationWarning: TripleDES has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES and will be removed from cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.
       "class": algorithms.TripleDES,
     
         If you are having issues with pyinfra or wish to make feature requests, please
         check out the GitHub issues at https://github.com/Fizzadar/pyinfra/issues .
         When adding an issue, be sure to include the following:
     
         System: FreeBSD
           Platform: FreeBSD-14.3-RELEASE-amd64-64bit-ELF
           Release: 14.3-RELEASE
           Machine: amd64
         pyinfra: v3.4
           click: v8.2.1
           click: v8.2.1
           click: v8.2.1
           distro: v1.9.0
           gevent: v25.5.1
           jinja2: v3.1.6
           packaging: v25.0
           paramiko: v2.11.0
           python-dateutil: v2.9.0.post0
           pywinrm: v0.5.0
           typeguard: v4.4.4
           typing-extensions: v4.14.1
         Executable: /home/user/Devel/pyinfra/env/bin/pyinfra
         Python: 3.11.13 (CPython, Clang 18.1.6 (https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c2)
    
  • How was pyinfra installed (source/pip):
    virtualenv env && . env/bin/activate && pip install -e .
  • Include pyinfra-debug.log (if one was created)
    • ValueError: not enough values to unpack (expected 2, got 1):
     File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 225, in cli
       _main(*args, **kwargs)
     File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 394, in _main
       run_ops(state, serial=serial, no_wait=no_wait)
     File "/home/user/Devel/pyinfra/pyinfra/api/operations.py", line 334, in run_ops
       _run_single_op(state, op_hash)
     File "/home/user/Devel/pyinfra/pyinfra/api/operations.py", line 302, in _run_single_op
       if not greenlet.get():
              ^^^^^^^^^^^^^^
     File "src/gevent/greenlet.py", line 797, in gevent._gevent_cgreenlet.Greenlet.get
     File "src/gevent/greenlet.py", line 373, in gevent._gevent_cgreenlet.Greenlet._raise_exception
     File "/home/user/Devel/pyinfra/env/lib/python3.11/site-packages/gevent/_compat.py", line 51, in reraise
       raise value.with_traceback(tb)
     File "src/gevent/greenlet.py", line 900, in gevent._gevent_cgreenlet.Greenlet.run
     File "/home/user/Devel/pyinfra/pyinfra/api/operations.py", line 184, in _run_host_op_with_context
       return run_host_op(state, host, op_hash)
       ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/operations.py", line 53, in run_host_op
       return _run_host_op(state, host, op_hash)
       ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/operations.py", line 81, in _run_host_op
       for command in op_data.command_generator():
         ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/operation.py", line 283, in command_generator
       for command in func(*args, **kwargs):
       ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/operations/server.py", line 314, in mount
       mounts = host.get_fact(Mounts)
         ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/host.py", line 367, in get_fact
       return get_fact(self.state, self, name_or_cls, args=args, kwargs=kwargs)
       ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 185, in get_fact
       return _get_fact(
         ^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 269, in _get_fact
       data = fact.process(stdout_lines)
       ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/facts/server.py", line 253, in process
       optional, line = line.split(sep=" ", maxsplit=1)
       ^^^^^^^^^^^^^^^^^
    ValueError: not enough values to unpack (expected 2, got 1)
    
    • AttributeError: 'gevent._gevent_clocal.local' object has no attribute 'module':
     File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 225, in cli
       _main(*args, **kwargs)
     File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 354, in _main
       can_diff, state, config = _handle_commands(
                                 ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 656, in _handle_commands
       state, fact_data = _run_fact_operations(state, config, operations)
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 697, in _run_fact_operations
       fact_data[fact_key] = get_facts(
                             ^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 159, in get_facts
       results[host] = greenlet.get()
                       ^^^^^^^^^^^^^^
     File "src/gevent/greenlet.py", line 797, in gevent._gevent_cgreenlet.Greenlet.get
     File "src/gevent/greenlet.py", line 373, in gevent._gevent_cgreenlet.Greenlet._raise_exception
     File "/home/user/Devel/pyinfra/env/lib/python3.11/site-packages/gevent/_compat.py", line 51, in reraise
       raise value.with_traceback(tb)
     File "src/gevent/greenlet.py", line 900, in gevent._gevent_cgreenlet.Greenlet.run
     File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 147, in get_host_fact
       return get_fact(state, host, *args, **kwargs)
       ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 185, in get_fact
       return _get_fact(
         ^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 228, in _get_fact
       command = _make_command(fact.command, fact_kwargs)
         ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 118, in _make_command
       return command_attribute(**host_args)
       ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/facts/server.py", line 211, in command
       self._kernel = host.get_fact(Kernel)
       ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/context.py", line 53, in __getattr__
       if self._get_module() is None:
       ^^^^^^^^^^^^^^^^^
     File "/home/user/Devel/pyinfra/pyinfra/context.py", line 35, in _get_module
       return self._container.module
       ^^^^^^^^^^^^^^^^^
     File "src/gevent/local.py", line 410, in gevent._gevent_clocal.local.__getattribute__
    AttributeError: 'gevent._gevent_clocal.local' object has no attribute 'module'
    
  • Consider including output with -vv and --debug
    • ValueError: not enough values to unpack (expected 2, got 1):
       /home/user/Devel/pyinfra/env/lib/python3.11/site-packages/paramiko/pkey.py:82: CryptographyDeprecationWarning: TripleDES has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES and will be removed from cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.
         "cipher": algorithms.TripleDES,
       /home/user/Devel/pyinfra/env/lib/python3.11/site-packages/paramiko/transport.py:253: CryptographyDeprecationWarning: TripleDES has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES and will be removed from cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.
         "class": algorithms.TripleDES,
       --> Loading config...
       --> Loading inventory...
           [pyinfra_cli.inventory] Creating fake inventory...
           [pyinfra_cli.inventory] Checking possible group_data at: /home/user/Automation.pyinfra/group_data
           [pyinfra_cli.inventory] Looking for group data in: /home/user/Automation.pyinfra/group_data/all.py
           [pyinfra_cli.inventory] Looking for group data in: /home/user/Automation.pyinfra/group_data/vm.py
           [pyinfra_cli.inventory] Adding data to group all: {'promtail_conf': 'templates/promtail.yaml.j2', 'dnsmasq_conf': 'files/dnsmasq.conf', 'tmpfs': False, 'pf_conf': 'files/pf.conf', 'appjail_conf': 'templates/appjail.conf.j2', 'appjail_resolv_conf': 'files/appjail-resolv.conf', 'enable_zfs': False, 'enable_debug': False, 'freebsd_version': '14.3', 'overlord_conf': 'files/overlord.yml', '_get_pty': True}
           [pyinfra_cli.inventory] Adding data to group vm: {'ext_if': 'vtnet0', 'tmpfs': True}
       
       --> Connecting to hosts...
           [pyinfra.connectors.ssh] Connecting to: control-r2 ({'allow_agent': True, 'look_for_keys': True, '_pyinfra_ssh_forward_agent': False, '_pyinfra_ssh_config_file': None, '_pyinfra_ssh_known_hosts_file': None, '_pyinfra_ssh_strict_host_key_checking': 'accept-new', '_pyinfra_ssh_paramiko_connect_kwargs': None, 'timeout': 10})
           [pyinfra.connectors.sshuserclient.client] Loading SSH config: None
           [control-r2]         Connected
           [pyinfra.api.state] Activating host: control-r2
       
       --> Preparing operation files...
           Loading: deployments/appjail.py
           [pyinfra.api.operation] Adding operation, {'Create directory for temporary directory'}, opOrder=(0, 10), opHash=3b2f90227d43a40a2288506c2a99bdc5e71f32b2
           [pyinfra.api.facts] Getting fact: files.Directory (path=/usr/local/appjail/cache/tmp/.appjail) (ensure_hosts: None)
           [pyinfra.connectors.ssh] Running command on control-r2: (pty=True) sh -c '! (test -e /usr/local/appjail/cache/tmp/.appjail || test -L /usr/local/appjail/cache/tmp/.appjail ) || ( stat -c '"'"'user=%U group=%G mode=%A atime=%X mtime=%Y ctime=%Z size=%s %N'"'"' /usr/local/appjail/cache/tmp/.appjail 2> /dev/null || stat -f '"'"'user=%Su group=%Sg mode=%Sp atime=%a mtime=%m ctime=%c size=%z %N%SY'"'"' /usr/local/appjail/cache/tmp/.appjail )'
       [control-r2]         >>> sh -c '! (test -e /usr/local/appjail/cache/tmp/.appjail || test -L /usr/local/appjail/cache/tmp/.appjail ) || ( stat -c '"'"'user=%U group=%G mode=%A atime=%X mtime=%Y ctime=%Z size=%s %N'"'"' /usr/local/appjail/cache/tmp/.appjail 2> /dev/null || stat -f '"'"'user=%Su group=%Sg mode=%Sp atime=%a mtime=%m ctime=%c size=%z %N%SY'"'"' /usr/local/appjail/cache/tmp/.appjail )'
           [pyinfra.connectors.ssh] Waiting for exit status...
           [pyinfra.connectors.ssh] Command exit status: 0
           [control-r2]         Loaded fact files.Directory (path=/usr/local/appjail/cache/tmp/.appjail)
           [control-r2]         noop: directory /usr/local/appjail/cache/tmp/.appjail already exists
           [pyinfra.api.operation] Adding operation, {'Configure fstab to mount the in-memory temporary directory'}, opOrder=(0, 15), opHash=51f6b23b4aa3365d626750a07950b82d1a301941
           [pyinfra.api.facts] Getting fact: files.FindInFile (interpolate_variables=False, path=/etc/fstab, pattern=^.*tmpfs /usr/local/appjail/cache/tmp/.appjail tmpfs rw,late 0 0.*$) (ensure_hosts: None)
           [pyinfra.connectors.ssh] Running command on control-r2: (pty=True) sh -c 'grep -e '"'"'^.*tmpfs /usr/local/appjail/cache/tmp/.appjail tmpfs rw,late 0 0.*$'"'"' /etc/fstab 2> /dev/null || ( find /etc/fstab -type f > /dev/null && echo __pyinfra_exists_/etc/fstab || true )'
       [control-r2]         >>> sh -c 'grep -e '"'"'^.*tmpfs /usr/local/appjail/cache/tmp/.appjail tmpfs rw,late 0 0.*$'"'"' /etc/fstab 2> /dev/null || ( find /etc/fstab -type f > /dev/null && echo __pyinfra_exists_/etc/fstab || true )'
           [pyinfra.connectors.ssh] Waiting for exit status...
           [pyinfra.connectors.ssh] Command exit status: 0
           [control-r2]         Loaded fact files.FindInFile (interpolate_variables=False, path=/etc/fstab, pattern=^.*tmpfs /usr/local/appjail/cache/tmp/.appjail tmpfs rw,late 0 0.*$)
           [control-r2]         noop: line "tmpfs /usr/local/appjail/cache/tmp/.appjail tmpfs rw,late 0 0" exists in /etc/fstab
           [pyinfra.api.operation] Adding operation, {'Mount tmpfs as the temporary directory'}, opOrder=(0, 21), opHash=b1d1da4808a9765a47e35b9cfb13e271e108f5f0
           [pyinfra.api.facts] Getting fact: server.Mounts () (ensure_hosts: None)
           [pyinfra.api.facts] Getting fact: server.Kernel () (ensure_hosts: None)
           [pyinfra.connectors.ssh] Running command on control-r2: (pty=True) sh -c 'uname -s'
       [control-r2]         >>> sh -c 'uname -s'
           [pyinfra.connectors.ssh] Waiting for exit status...
           [pyinfra.connectors.ssh] Command exit status: 0
           [control-r2]         Loaded fact server.Kernel
           [pyinfra.connectors.ssh] Running command on control-r2: (pty=True) sh -c 'mount -p --libxo json'
       [control-r2]         >>> sh -c 'mount -p --libxo json'
           [pyinfra.connectors.ssh] Waiting for exit status...
           [pyinfra.connectors.ssh] Command exit status: 0
       
       --> Disconnecting from hosts...
       --> An exception occurred in: deployments/appjail.py:
       
       Traceback (most recent call last):
         File "/home/user/Devel/pyinfra/pyinfra_cli/util.py", line 65, in exec_file
           exec(PYTHON_CODES[filename], data)
         File "deployments/appjail.py", line 21, in <module>
           server.mount(
         File "/home/user/Devel/pyinfra/pyinfra/api/operation.py", line 296, in decorated_func
           for _ in command_generator():
         File "/home/user/Devel/pyinfra/pyinfra/api/operation.py", line 283, in command_generator
           for command in func(*args, **kwargs):
         File "/home/user/Devel/pyinfra/pyinfra/operations/server.py", line 314, in mount
           mounts = host.get_fact(Mounts)
                    ^^^^^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/host.py", line 367, in get_fact
           return get_fact(self.state, self, name_or_cls, args=args, kwargs=kwargs)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 185, in get_fact
           return _get_fact(
                  ^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 269, in _get_fact
           data = fact.process(stdout_lines)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/facts/server.py", line 253, in process
           optional, line = line.split(sep=" ", maxsplit=1)
           ^^^^^^^^^^^^^^
       ValueError: not enough values to unpack (expected 2, got 1)
      
    • AttributeError: 'gevent._gevent_clocal.local' object has no attribute 'module':
       /home/user/Devel/pyinfra/env/lib/python3.11/site-packages/paramiko/pkey.py:82: CryptographyDeprecationWarning: TripleDES has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES and will be removed from cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.
         "cipher": algorithms.TripleDES,
       /home/user/Devel/pyinfra/env/lib/python3.11/site-packages/paramiko/transport.py:253: CryptographyDeprecationWarning: TripleDES has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.TripleDES and will be removed from cryptography.hazmat.primitives.ciphers.algorithms in 48.0.0.
         "class": algorithms.TripleDES,
       --> Loading config...
       --> Loading inventory...
           [pyinfra_cli.inventory] Creating fake inventory...
           [pyinfra_cli.inventory] Checking possible group_data at: /home/user/Automation.pyinfra/group_data
           [pyinfra_cli.inventory] Looking for group data in: /home/user/Automation.pyinfra/group_data/all.py
           [pyinfra_cli.inventory] Looking for group data in: /home/user/Automation.pyinfra/group_data/vm.py
           [pyinfra_cli.inventory] Adding data to group all: {'promtail_conf': 'templates/promtail.yaml.j2', 'dnsmasq_conf': 'files/dnsmasq.conf', 'tmpfs': False, 'pf_conf': 'files/pf.conf', 'appjail_conf': 'templates/appjail.conf.j2', 'appjail_resolv_conf': 'files/appjail-resolv.conf', 'enable_zfs': False, 'enable_debug': False, 'freebsd_version': '14.3', 'overlord_conf': 'files/overlord.yml', '_get_pty': True}
           [pyinfra_cli.inventory] Adding data to group vm: {'ext_if': 'vtnet0', 'tmpfs': True}
       
       --> Connecting to hosts...
           [pyinfra.connectors.ssh] Connecting to: control-r2 ({'allow_agent': True, 'look_for_keys': True, '_pyinfra_ssh_forward_agent': False, '_pyinfra_ssh_config_file': None, '_pyinfra_ssh_known_hosts_file': None, '_pyinfra_ssh_strict_host_key_checking': 'accept-new', '_pyinfra_ssh_paramiko_connect_kwargs': None, 'timeout': 10})
           [pyinfra.connectors.sshuserclient.client] Loading SSH config: None
           [control-r2]         Connected
           [pyinfra.api.state] Activating host: control-r2
       
       --> Gathering facts...
           [pyinfra.api.facts] Getting fact: server.Mounts () (ensure_hosts: None)
       Traceback (most recent call last):
         File "src/gevent/greenlet.py", line 900, in gevent._gevent_cgreenlet.Greenlet.run
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 147, in get_host_fact
           return get_fact(state, host, *args, **kwargs)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 185, in get_fact
           return _get_fact(
                  ^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 228, in _get_fact
           command = _make_command(fact.command, fact_kwargs)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 118, in _make_command
           return command_attribute(**host_args)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/facts/server.py", line 211, in command
           self._kernel = host.get_fact(Kernel)
                          ^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/context.py", line 53, in __getattr__
           if self._get_module() is None:
              ^^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/context.py", line 35, in _get_module
           return self._container.module
                  ^^^^^^^^^^^^^^^^^^^^^^
         File "src/gevent/local.py", line 410, in gevent._gevent_clocal.local.__getattribute__
       AttributeError: 'gevent._gevent_clocal.local' object has no attribute 'module'
       2025-07-12T20:35:13Z <Greenlet at 0x2e43b58b04a0: get_host_fact(Host(control-r2), <class 'pyinfra.facts.server.Mounts'>, args=(), kwargs={}, apply_failed_hosts=False)> failed with AttributeError
       
       
       --> Disconnecting from hosts...
       --> An internal exception occurred:
       
         File "src/gevent/local.py", line 410, in gevent._gevent_clocal.local.__getattribute__
       AttributeError: 'gevent._gevent_clocal.local' object has no attribute 'module'
       
           [pyinfra_cli.exceptions]   File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 225, in cli
           _main(*args, **kwargs)
         File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 354, in _main
           can_diff, state, config = _handle_commands(
                                     ^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 656, in _handle_commands
           state, fact_data = _run_fact_operations(state, config, operations)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra_cli/main.py", line 697, in _run_fact_operations
           fact_data[fact_key] = get_facts(
                                 ^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 159, in get_facts
           results[host] = greenlet.get()
                           ^^^^^^^^^^^^^^
         File "src/gevent/greenlet.py", line 797, in gevent._gevent_cgreenlet.Greenlet.get
         File "src/gevent/greenlet.py", line 373, in gevent._gevent_cgreenlet.Greenlet._raise_exception
         File "/home/user/Devel/pyinfra/env/lib/python3.11/site-packages/gevent/_compat.py", line 51, in reraise
           raise value.with_traceback(tb)
         File "src/gevent/greenlet.py", line 900, in gevent._gevent_cgreenlet.Greenlet.run
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 147, in get_host_fact
           return get_fact(state, host, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 185, in get_fact
           return _get_fact(
             ^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 228, in _get_fact
           command = _make_command(fact.command, fact_kwargs)
             ^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/api/facts.py", line 118, in _make_command
           return command_attribute(**host_args)
           ^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/facts/server.py", line 211, in command
           self._kernel = host.get_fact(Kernel)
           ^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/context.py", line 53, in __getattr__
           if self._get_module() is None:
           ^^^^^^^^^^^^^^^^^
         File "/home/user/Devel/pyinfra/pyinfra/context.py", line 35, in _get_module
           return self._container.module
           ^^^^^^^^^^^^^^^^^
         File "src/gevent/local.py", line 410, in gevent._gevent_clocal.local.__getattribute__
       
           [pyinfra_cli.exceptions] AttributeError: 'gevent._gevent_clocal.local' object has no attribute 'module'
       
       --> The full traceback has been written to pyinfra-debug.log
       --> If this is unexpected please consider submitting a bug report on GitHub, for more information run `pyinfra --support`.
      

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugLabel for all kind of bugs.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions