agentleFS
teacupukteacupuk/tpstack/skills/librenms-os-support/SKILL.md

librenms-os-support

Skill0 starsChanged 15 days agoMITView on GitHub

Add or improve network device OS support in LibreNMS. Use this skill whenever adding support for a new operating system, device, vendor, or hardware model; writing OS detection (sysObjectID, sysDescr) or OS discovery definitions; adding health sensors (temperature, fan speed, voltage, current, power, state), mempools, processors, or wireless metrics; adding vendor MIBs; or generating and verifying OS test fixtures (.snmprec files and dev:generate-test-data JSON).

The file

Show its rules and text

We split this skill into the rules it gives an agent

60 rules. About 0 are common, 22 are distinctive, and 38 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈22

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 38

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Follow these instructions to add a new OS or update existing OS support in LibreNMS.

    line 8
  2. Distinctive:

    Use this workflow when LibreNMS does not yet support the operating system.

    line 15
  3. Very specific:

    Add vendor MIBs to mibs/<vendor>/ (name equals module definition, no extension).

    line 16
  4. Very specific:

    Create detection YAML in resources/definitions/os_detection/<os>.yaml.

    line 17
  5. Very specific:

    Create discovery YAML in resources/definitions/os_discovery/<os>.yaml.

    line 18
  6. Very specific:

    Add an icon to html/images/os/<os>.svg and optionally a logo to html/images/logos/<os>.svg.

    line 19
  7. Very specific:

    Verify all tests pass with ./lnms dev:check unit -o <os>.

    line 22
  8. Distinctive:

    Use this workflow when you add sensors, processors, mempools, or support for a new hardware model to an existing OS.

    line 25
  9. Distinctive:

    Add new sensor, processor, or mempool definitions in YAML.

    line 27
  10. Distinctive:

    If new hardware models use different MIB OIDs:

    line 28
  11. Distinctive:

    Check if discovery probe walks naturally find the OID.

    line 29
  12. Very specific:

    Use skip_values with identical indexes when defining alternative definitions of the same physical sensor.

    line 30
  13. Very specific:

    Add vendor MIBs to mibs/<vendor>/ if needed.

    line 31
  14. Very specific:

    Run fast verification with ./lnms dev:check unit -o <os> --os-modules-only.

    line 35
  15. Very specific:

    Use only lowercase letters, digits, and hyphens (/^[a-z0-9\-]+$/).

    line 42
  16. Very specific:

    Prefer the actual OS name over marketing names if known (for example, ftos, routeros, ironware).

    line 43
  17. Distinctive:

    OS Scope: If multiple devices use the same MIB (or mostly the same MIBs), they belong to the same OS.

    line 44
  18. Distinctive:

    YAML Over PHP: Always use YAML definitions for discovery.

    line 45
  19. Very specific:

    Use sysObjectID (prefix match) or sysDescr (substring match).

    line 47
  20. Very specific:

    Do not use snmpget: in OS detection except as a last resort.

    line 48
  21. Very specific:

    Do not set discovery or poller modules to false in OS definitions.

    line 53
  22. Very specific:

    Always prefer textual OIDs over numeric OIDs in discovery files (for example, ENTITY-MIB::entPhysicalName).

    line 55
  23. Very specific:

    Do not use *Entry OID names for oid:.

    line 59
  24. Very specific:

    Avoid options:. Define settings explicitly on each sensor entry in data:.

    line 63
  25. Very specific:

    Use skip_values with identical indexes only for alternative definitions of the same physical sensor (for example, a different OID, status …

    line 67
  26. Distinctive:

    Check for existing vendor MIBs first.

    line 69
  27. Distinctive:

    If no MIB exists, but you have detailed SNMP information, you can create a MIB from the vendor's SNMP specification documentation.

    line 71
  28. Distinctive:

    Do not include standard RFC MIBs in vendor directories.

    line 74
  29. Very specific:

    Every OS must include test data (tests/snmpsim/<os>_<variant>.snmprec and tests/data/<os>_<variant>.json).

    line 77
  30. Very specific:

    Always name a variant: the lowercase hardware model or similar (for example, ios_2960x).

    line 78
  31. Very specific:

    Do not fabricate snmprec files.

    line 79
  32. Distinctive:

    Do not break the data when you sanitize it.

    line 80
  33. Very specific:

    Check mibs/ for existing vendor MIBs first.

    line 101
  34. Distinctive:

    If vendor MIBs exist:

    line 102
  35. Very specific:

    Do not add standard RFC MIBs (for example, IF-MIB, ENTITY-MIB, HOST-RESOURCES-MIB).

    line 106
  36. Distinctive:

    Add only the MIB files that the OS definition uses.

    line 107
  37. Distinctive:

    If no MIB exists:

    line 108
  38. Distinctive:

    If you have detailed SNMP information from the vendor's SNMP specification documentation, you can create a MIB from the vendor …

    line 109
  39. Distinctive:

    Write standard SMIv2 MIB syntax with valid module headers, imports, object identifiers, and object types.

    line 110
  40. Very specific:

    No Disabled Modules: Do not set discovery_modules or poller_modules to false in the OS definition.

    line 138
  41. Very specific:

    Use sysDescr_except or sysObjectID_except to reject specific matches.

    line 147
  42. Very specific:

    Prefer the most specific sysObjectID prefix available (vendors often encode a product family in it).

    line 148
  43. Very specific:

    Avoid snmpget: in discovery:.

    line 149
  44. Distinctive:

    Use one of these valid device types:

    line 153
  45. Very specific:

    Textual OIDs Only: Always prefer textual OIDs over numeric OIDs in discovery files.

    line 237
  46. Very specific:

    Avoid options:: Avoid options: at the class level.

    line 238
  47. Very specific:

    If sensors use an SNMP table, oid: must be the table and value: must be the column in that table.

    line 242
  48. Very specific:

    If the sensor is a scalar OID, specify the scalar OID in oid: without the .0 and omit value:.

    line 259
  49. Very specific:

    When omitted, LibreNMS uses the SNMP table index $index (or 0 for scalars).

    line 278
  50. Distinctive:

    If you have two different tables in the same sensor class that produce identical row indexes (for example, row 1 in inlet temps and row 1 …

    line 280
  51. Very specific:

    When you define alternative OIDs for the same sensor across different models or firmware versions using skip_values, use the same index (or …

    line 285
  52. Very specific:

    Always set state_name and provide generic mapping:

    line 291
  53. Very specific:

    Use skip_values to ignore unpopulated sensors or select model-specific definitions:

    line 316
  54. Very specific:

    Add --full to walk the whole device instead, or --modules=<module>,<module> to limit collection to specific modules.

    line 360
  55. Very specific:

    Do not edit tests/data/<os>_<variant>.json manually.

    line 374
  56. Distinctive:

    Run the test suite for the OS:

    line 380
  57. Distinctive:

    If you make changes to YAML discovery files during testing, clear the cache:

    line 395
  58. Very specific:

    Use --filter testOSDefinitionSchema for detection YAML.

    line 404
  59. Very specific:

    If a sensor discovers on the real device but is missing from the generated test data, check whether its OID is the last entry in the …

    line 406
  60. Distinctive:

    All tests must pass before the task is complete.

    line 408

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Adding or Updating Device OS Support in LibreNMS

Follow these instructions to add a new OS or update existing OS support in LibreNMS.

Dual-Purpose Workflows

This skill handles two primary workflows:

Workflow 1: Add a New OS

Use this workflow when LibreNMS does not yet support the operating system.

  1. Add vendor MIBs to mibs/<vendor>/ (name equals module definition, no extension).
  2. Create detection YAML in resources/definitions/os_detection/<os>.yaml.
  3. Create discovery YAML in resources/definitions/os_discovery/<os>.yaml.
  4. Add an icon to html/images/os/<os>.svg and optionally a logo to html/images/logos/<os>.svg. Prefer vector (SVG) over bitmap (PNG).
  5. Capture real SNMP test data in tests/snmpsim/<os>_<variant>.snmprec.
  6. Generate test data JSON with ./lnms dev:generate-test-data <os> --variant="<variant>".
  7. Verify all tests pass with ./lnms dev:check unit -o <os>.

Workflow 2: Update an Existing OS

Use this workflow when you add sensors, processors, mempools, or support for a new hardware model to an existing OS.

  1. Inspect existing definitions in resources/definitions/os_discovery/<os>.yaml.
  2. Add new sensor, processor, or mempool definitions in YAML.
  3. If new hardware models use different MIB OIDs:
    • Check if discovery probe walks naturally find the OID.
    • Use skip_values with identical indexes when defining alternative definitions of the same physical sensor.
  4. Add vendor MIBs to mibs/<vendor>/ if needed.
  5. Update test fixtures:
    • To update modules in existing fixtures: ./lnms dev:generate-test-data <os> -m <module>.
    • To add a new hardware variant: record tests/snmpsim/<os>_<variant>.snmprec and generate with ./lnms dev:generate-test-data <os> --variant="<variant>".
  6. Run fast verification with ./lnms dev:check unit -o <os> --os-modules-only.

Core Rules

  1. OS Name Syntax:
    • Use only lowercase letters, digits, and hyphens (/^[a-z0-9\-]+$/). Do not use uppercase letters, underscores, or spaces.
    • Prefer the actual OS name over marketing names if known (for example, ftos, routeros, ironware).
  2. OS Scope: If multiple devices use the same MIB (or mostly the same MIBs), they belong to the same OS. Do not create an OS for each hardware model. Discovery must handle model differences.
  3. YAML Over PHP: Always use YAML definitions for discovery. Only use PHP classes when YAML cannot do the task.
  4. OS Detection:
    • Use sysObjectID (prefix match) or sysDescr (substring match).
    • Do not use snmpget: in OS detection except as a last resort. It sends network queries that slow all device discoveries.
  5. Defaults for icon and mib_dir:
    • The OS name is included in the MIB search path by default (mibs/<os>). Do not add mib_dir: <os>. Only add mib_dir: if the MIB directory differs from the OS name.
    • icon: defaults to the OS name. Do not add icon: if it matches the OS name. Only set icon: if it differs from the OS name.
  6. No Disabled Modules in OS Definition:
    • Do not set discovery or poller modules to false in OS definitions. That is what discovery is for. Discovery automatically probes and detects supported features.
  7. OID and Value Format:
    • Always prefer textual OIDs over numeric OIDs in discovery files (for example, ENTITY-MIB::entPhysicalName).
    • The sensors module only supports textual OIDs for oid: and value:. Never use numeric OIDs for oid: or value: in sensor definitions.
    • Sensors can be scalar OIDs or table columns.
    • For SNMP tables: oid: must be the table (for example, ENTITY-SENSOR-MIB::entPhySensorTable), and value: must be the column in that table (for example, ENTITY-SENSOR-MIB::entPhySensorValue).
    • Do not use *Entry OID names for oid:. Use *Table instead.
    • For scalars: specify the scalar OID in oid: without the .0 instance (for example, MY-MIB::myScalar) and omit value: (because value: matches oid:). The walked value is stored under the name without .0, so oid: MY-MIB::myScalar.0 without a matching value: finds no data.
    • num_oid: must end in .{{ $index }} (or {{ $noindex }}), including for scalars, where $index is 0 (for example, '.1.3.6.1.4.1.99999.3.2.{{ $index }}'). The schema rejects literal indexes.
  8. Sensor Indexing & Options:
    • Avoid options:. Define settings explicitly on each sensor entry in data:.
    • Omit index: unless auto-generated table indexes collide. LibreNMS uses the SNMP table index $index automatically.
    • Scalars all have index 0, so multiple scalars in the same sensor class need a distinct index: each.
    • Let discovery probe walks to detect whether the device supports an OID.
    • Use skip_values with identical indexes only for alternative definitions of the same physical sensor (for example, a different OID, status mapping, or unit per model or firmware), not for different sensors.
  9. MIB Files:
    • Check for existing vendor MIBs first.
    • Include vendor MIBs verbatim as provided by the vendor. Do not make any modifications to MIB files.
    • If no MIB exists, but you have detailed SNMP information, you can create a MIB from the vendor's SNMP specification documentation.
    • Save vendor MIBs in mibs/<vendor>/.
    • Name the file to match the MIB module definition line exactly (for example, MYVENDOR-SYSTEM-MIB). Do not add a file extension.
    • Do not include standard RFC MIBs in vendor directories.
    • Include only the MIBs that LibreNMS uses.
  10. Mandatory Real Test Data:
    • Every OS must include test data (tests/snmpsim/<os>_<variant>.snmprec and tests/data/<os>_<variant>.json).
    • Always name a variant: the lowercase hardware model or similar (for example, ios_2960x). Do not create a bare <os>.snmprec.
    • Do not fabricate snmprec files. You must only capture snmprec files from an actual device or convert them from snmpwalk output from an actual device.
    • Do not break the data when you sanitize it.
    • Tests must pass before you finish.

File Locations

File TypePathNotes
OS Detectionresources/definitions/os_detection/<os>.yamlMatches device during discovery
OS Discoveryresources/definitions/os_discovery/<os>.yamlExtracts metadata, sensors, CPU, memory
Vendor MIBsmibs/<vendor>/<MIB-NAME>File name equals MIB module, no extension
OS Iconhtml/images/os/<os>.svgSquare, no padding. Vector (SVG) preferred; PNG at least 32x32 px
OS Logohtml/images/logos/<os>.svgOptional wide logo. Vector (SVG) preferred over bitmap (PNG)
SNMP Recordingtests/snmpsim/<os>_<variant>.snmprecSNMP test data from a real device; variant is the lowercase model
Test Data JSONtests/data/<os>_<variant>.jsonExpected database dump

Step 1: Add Vendor MIBs

  1. Check mibs/ for existing vendor MIBs first. Otherwise, check if a MIB exists for the device (check the vendor website, support downloads, device firmware, or MIB repositories).
  2. If vendor MIBs exist:
    • Include vendor MIBs verbatim as provided by the vendor. Do not make any modifications to MIB files.
    • Identify the module name inside the MIB file: <MODULE-NAME> DEFINITIONS ::= BEGIN.
    • Save the file as mibs/<vendor>/<MODULE-NAME> without any extension (such as .mib or .txt).
    • Do not add standard RFC MIBs (for example, IF-MIB, ENTITY-MIB, HOST-RESOURCES-MIB).
    • Add only the MIB files that the OS definition uses.
  3. If no MIB exists:
    • If you have detailed SNMP information from the vendor's SNMP specification documentation, you can create a MIB from the vendor documentation.
    • Write standard SMIv2 MIB syntax with valid module headers, imports, object identifiers, and object types.
    • Save the file as mibs/<vendor>/<MODULE-NAME> without any file extension.

Step 2: Define OS Detection

Create resources/definitions/os_detection/<os>.yaml.

Detection Example

os: acme
text: 'Acme OS'
type: network
over:
    - { graph: device_bits, text: 'Device Traffic' }
    - { graph: device_processor, text: 'CPU Usage' }
    - { graph: device_mempool, text: 'Memory Usage' }
discovery:
    - sysObjectID:
        - .1.3.6.1.4.1.99999.1.

Default Values and Rules

  • Icon: icon: defaults to the OS name (html/images/os/<os>.svg). Do not set icon: if it matches the OS name. Only set icon: if it differs from the OS name (for example, icon: cisco when sharing another vendor's icon).
  • MIB Directory: LibreNMS includes mibs/<os> in the MIB search path by default. Do not add mib_dir: <os>. Only set mib_dir: if the directory differs from the OS name (for example, mib_dir: cisco).
  • No Disabled Modules: Do not set discovery_modules or poller_modules to false in the OS definition. That is what discovery is for. Discovery dynamically tests whether the device supports each module.

Detection Logic

  • Root items in discovery: use logical OR.
  • Keys inside an item (sysObjectID, sysDescr) use logical AND.
  • Values under a key use logical OR.
  • sysObjectID tests if the device sysObjectID starts with the string.
  • sysDescr tests if the device sysDescr contains the string.
  • Use sysDescr_except or sysObjectID_except to reject specific matches.
  • Prefer the most specific sysObjectID prefix available (vendors often encode a product family in it). Fall back to explicit sysObjectIDs, or sysObjectID_except on an existing OS that matches a broader prefix, only when the vendor does not.
  • Avoid snmpget: in discovery:. It sends network queries that slow all device discoveries. Only use it as a last resort when sysObjectID and sysDescr are identical across different operating systems.

Valid Device Types

Use one of these valid device types:

  • network
  • wireless
  • power
  • appliance
  • server
  • storage
  • firewall
  • environment
  • loadbalancer
  • management
  • collaboration
  • printer
  • workstation

Step 3: Define OS Discovery

Create resources/definitions/os_discovery/<os>.yaml.

1. OS Metadata (Hardware, Version, Serial)

modules:
    os:
        hardware: ACME-SYSTEM-MIB::acmeHardwareModel.0
        version: ACME-SYSTEM-MIB::acmeSoftwareVersion.0
        serial: ACME-SYSTEM-MIB::acmeSerialNumber.0

You can also use regex on sysDescr:

modules:
    os:
        sysDescr_regex: '/Acme OS (?<version>\S+), Hardware: (?<hardware>[\w-]+), S\/N: (?<serial>\S+)/'

2. Processors

modules:
    processors:
        data:
            -
                oid: ACME-SYSTEM-MIB::acmeCpuTable
                value: ACME-SYSTEM-MIB::acmeCpuUtilization
                num_oid: '.1.3.6.1.4.1.99999.2.1.1.2.{{ $index }}'
                descr: 'CPU {{ $index }}'

For scalar processors:

modules:
    processors:
        data:
            -
                oid: ACME-SYSTEM-MIB::acmeCpuUtil
                num_oid: '.1.3.6.1.4.1.99999.2.1.{{ $index }}'
                descr: 'Processor'

3. Mempools

Provide at least two of these keys: total, used, free, percent_used.

modules:
    mempools:
        data:
            -
                total: ACME-SYSTEM-MIB::acmeMemoryTotal.0
                used: ACME-SYSTEM-MIB::acmeMemoryUsed.0
                precision: 1024
                descr: 'Main Memory'

4. Health Sensors

Sensor classes are the cases in LibreNMS/Enum/SensorType.php. Common ones: temperature, fanspeed, voltage, current, power, state, humidity, frequency, dbm.

Rules for Sensors

  • Scalars Supported: Sensors can be scalar OIDs or table columns.
  • Textual OIDs Only: Always prefer textual OIDs over numeric OIDs in discovery files. The sensors module only supports textual OIDs for oid: and value:.
  • Avoid options:: Avoid options: at the class level. Define settings (such as divisor:, multiplier:, or skip_value_lt:) explicitly on each sensor entry in data:.
  • Let Discovery Probe: Let discovery probe walks detect whether the device supports an OID.

Table-Based Sensors

If sensors use an SNMP table, oid: must be the table and value: must be the column in that table. Do not use *Entry names for oid:.

modules:
    sensors:
        temperature:
            data:
                -
                    oid: ACME-SYSTEM-MIB::acmeTempTable
                    value: ACME-SYSTEM-MIB::acmeTempValue
                    num_oid: '.1.3.6.1.4.1.99999.3.1.1.2.{{ $index }}'
                    descr: '{{ ACME-SYSTEM-MIB::acmeTempDescr }}'
                    high_limit: ACME-SYSTEM-MIB::acmeTempHighLimit
                    warn_limit: ACME-SYSTEM-MIB::acmeTempWarnLimit

Scalar Sensors

If the sensor is a scalar OID, specify the scalar OID in oid: without the .0 and omit value:. Omit value: whenever it matches oid:.

modules:
    sensors:
        temperature:
            data:
                -
                    oid: ACME-SYSTEM-MIB::acmeChassisTemp
                    num_oid: '.1.3.6.1.4.1.99999.3.2.{{ $index }}'
                    descr: 'Chassis Temperature'

5. Sensor Indexing and Collision Rules

The composite key for a sensor in the database is: $poller_type-$sensor_class-$device_id-$sensor_type-$sensor_index

  • Omit index: by default: When omitted, LibreNMS uses the SNMP table index $index (or 0 for scalars).
  • When to specify index:: If you have two different tables in the same sensor class that produce identical row indexes (for example, row 1 in inlet temps and row 1 in outlet temps), they will collide. In this case, prefix the index:
    index: 'inlet.{{ $index }}'
  • When colliding indexes are desired: When you define alternative OIDs for the same sensor across different models or firmware versions using skip_values, use the same index (or omit index: in both). Only the matching definition discovers the sensor, and both models keep a consistent sensor index and RRD path.

6. State Sensors

Take state values from the MIB (enumerated INTEGER syntax or descriptions) or vendor documentation. If neither defines them, infer them from sample data only when it shows enough distinct values to be confident; otherwise leave the sensor out.

Always set state_name and provide generic mapping:

  • generic: 0 = OK / Normal
  • generic: 1 = Warning
  • generic: 2 = Critical / Error
  • generic: 3 = Unknown
modules:
    sensors:
        state:
            data:
                -
                    oid: ACME-SYSTEM-MIB::acmePsuTable
                    value: ACME-SYSTEM-MIB::acmePsuStatus
                    num_oid: '.1.3.6.1.4.1.99999.4.1.1.2.{{ $index }}'
                    descr: 'PSU {{ $index }}'
                    state_name: acmePsuStatus
                    states:
                        - { value: 1, descr: 'normal', generic: 0 }
                        - { value: 2, descr: 'warning', generic: 1 }
                        - { value: 3, descr: 'faulty', generic: 2 }

7. Filter Rows with skip_values

Use skip_values to ignore unpopulated sensors or select model-specific definitions:

skip_values:
    -
        oid: ACME-SYSTEM-MIB::acmeTempStatus
        op: '!='
        value: 1
    -
        device: hardware
        op: 'starts'
        value: 'Model-X'

Supported op values: =, !=, ==, !==, <, <=, >, >=, starts, not_starts, ends, not_ends, contains, not_contains, regex, not_regex, in_array, not_in_array, exists.

Caution: Do not skip valid 0 readings (such as 0 RPM on a failed fan). Discovery re-runs every 6 hours by default; skipping 0 can delete a failed sensor. Only skip when the physical hardware is absent.


Step 4: Add Icons

Save the image files. Prefer vector (SVG) over bitmap (PNG, saved as <os>.png in the same directory):

  • OS Icon: html/images/os/<os>.svg (Square, no margins; PNG at least 32x32 px)
  • OS Logo: html/images/logos/<os>.svg (Optional, wide format)

Step 5: Create Test Data (Mandatory)

Tests verify OS detection and module polling. Every OS must have test files.

1. SNMP Recording (tests/snmpsim/<os>_<variant>.snmprec)

Always name a variant: the lowercase hardware model or similar (for example, ios_2960x). Do not create a bare <os>.snmprec.

Do not fabricate snmprec files. You must only capture snmprec files from an actual device or convert them from snmpwalk output from an actual device.

Methods to acquire .snmprec data:

  1. Capture from a device added to LibreNMS (<device> is the device ID, IP, or hostname), after the OS detection and discovery definitions are in place and the device has been rediscovered. By default this collects only the OIDs that discovery and polling use:
    ./lnms dev:collect-snmprec <device> --variant="<variant>"
    Add --full to walk the whole device instead, or --modules=<module>,<module> to limit collection to specific modules.
  2. Convert snmpwalk output from the actual device: Convert walk output into <numeric_oid>|<type_code>|<value> format using snmpsim tools or scripts.

Important: Sanitize the recording to remove real credentials, SNMP community strings, public IP addresses, and private names. Do not break the data format or SNMP types when sanitizing. Add all OIDs that your OS discovery and polling definitions query.

2. Generate Test Data JSON (tests/data/<os>_<variant>.json)

The variant must be lowercase and match the snmprec file name:

./lnms dev:generate-test-data <os> --variant="<variant>"

Note: You must pass --variant when creating a new fixture for the first time. Without it, the tool searches only for existing fixtures and will exit with an error.

Do not edit tests/data/<os>_<variant>.json manually. Always use dev:generate-test-data to update it.


Step 6: Verify Tests

Run the test suite for the OS:

./lnms dev:check unit -o <os>

This command runs:

  1. OSDiscoveryTest: Verifies OS name validity and detection against .snmprec.
  2. OSModulesTest: Simulates the device with snmpsim and verifies discovered data against the JSON fixture.

You can also run specific unit tests:

./lnms test --filter=OSDiscoveryTest
./lnms test --filter=OSModulesTest

If you make changes to YAML discovery files during testing, clear the cache:

./lnms config:clear

Validate the discovery YAML against the schema:

php vendor/bin/phpunit --filter testDiscoveryDefinitionSchema tests/Unit/YamlSchemaTest.php

Use --filter testOSDefinitionSchema for detection YAML.

If a sensor discovers on the real device but is missing from the generated test data, check whether its OID is the last entry in the .snmprec. snmpsim answers a bulk walk of the final OID with end-of-MIB, which some modules do not handle.

All tests must pass before the task is complete.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.