mirror of
https://github.com/DaanSelen/meshbook.git
synced 2026-02-20 00:12:10 +00:00
Added OS filtering doc and supported (1 level deep) nested definition.
This commit is contained in:
65
docs/operating_system_filtering.md
Normal file
65
docs/operating_system_filtering.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# **Understanding the OS Filtering Mechanism**
|
||||
|
||||
## **Overview**
|
||||
This function filters devices based on their **reachability** and an optional **OS category filter**. It supports:
|
||||
|
||||
- **Broad OS categories** (e.g., `"Linux"` includes all OS versions under `"Linux"`)
|
||||
- **Specific OS categories** (e.g., `"Debian"` only includes OS versions under `"Linux" -> "Debian"`)
|
||||
- **Single category selection** (Only `target_os="Linux"` OR `target_os="Debian"` is used, never both at once)
|
||||
|
||||
---
|
||||
|
||||
## **How It Works (Simplified)**
|
||||
|
||||
### **1. OS Category Expansion**
|
||||
The function first expands the `target_os` category by retrieving all valid OS names under it.
|
||||
|
||||
#### **Example OS Category Structure:**
|
||||
```json
|
||||
{
|
||||
"Linux": {
|
||||
"Debian": [
|
||||
"Debian GNU/Linux 12 (bookworm)",
|
||||
"Debian GNU/Linux 11 (bullseye)"
|
||||
],
|
||||
"Ubuntu": [
|
||||
"Ubuntu 24.04.1 LTS"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### **Expanding Different `target_os` Values:**
|
||||
|
||||
| `target_os` | Expanded OS Versions |
|
||||
|--------------|---------------------------------------------------|
|
||||
| `"Linux"` | `{ "Debian GNU/Linux 12 (bookworm)", "Debian GNU/Linux 11 (bullseye)", "Ubuntu 24.04.1 LTS" }` |
|
||||
| `"Debian"` | `{ "Debian GNU/Linux 12 (bookworm)", "Debian GNU/Linux 11 (bullseye)" }` |
|
||||
|
||||
---
|
||||
|
||||
### **2. Device Filtering**
|
||||
Once the function has the allowed OS versions, it checks each device:
|
||||
|
||||
#### **Example Device List:**
|
||||
```json
|
||||
[
|
||||
{"device_id": "A1", "device_os": "Debian GNU/Linux 12 (bookworm)", "reachable": true},
|
||||
{"device_id": "A2", "device_os": "Ubuntu 24.04.1 LTS", "reachable": true},
|
||||
{"device_id": "A3", "device_os": "Windows 11", "reachable": true},
|
||||
{"device_id": "A4", "device_os": "Debian GNU/Linux 11 (bullseye)", "reachable": false}
|
||||
]
|
||||
```
|
||||
|
||||
#### **Filtering Behavior:**
|
||||
| Device ID | Device OS | Reachable | Matches `target_os="Linux"` | Matches `target_os="Debian"` |
|
||||
|-----------|----------------------------------|-----------|-------------------------------|-------------------------------|
|
||||
| A1 | Debian GNU/Linux 12 (bookworm) | ✅ | ✅ | ✅ |
|
||||
| A2 | Ubuntu 24.04.1 LTS | ✅ | ✅ | ❌ |
|
||||
| A3 | Windows 11 | ✅ | ❌ | ❌ |
|
||||
| A4 | Debian GNU/Linux 11 (bullseye) | ❌ | ❌ (Unreachable) | ❌ (Unreachable) |
|
||||
|
||||
#### **Final Output:**
|
||||
- If `target_os="Linux"`: `["A1", "A2"]`
|
||||
- If `target_os="Debian"`: `["A1"]`
|
||||
- If `target_os=None`: `["A1", "A2", "A3"]` or `target_os` is undefined
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Echo some text in the terminal of the device
|
||||
group: "Development"
|
||||
target_os: "Debian"
|
||||
target_os: "Linux" # <----
|
||||
variables:
|
||||
- name: package_manager
|
||||
value: "apt"
|
||||
|
||||
38
meshbook.py
38
meshbook.py
@@ -96,22 +96,40 @@ async def compile_group_list(session: meshctrl.Session) -> dict:
|
||||
return local_device_list
|
||||
|
||||
async def filter_targets(devices: list[dict], os_categories: dict, target_os: str = None) -> list[str]:
|
||||
"""Filters devices based on reachability and optional OS criteria."""
|
||||
"""Filters devices based on reachability and optional OS criteria, supporting nested OS categories."""
|
||||
valid_devices = []
|
||||
|
||||
def get_os_variants(category: str, os_map: dict) -> set:
|
||||
"""Extracts all OS names under a given category if it exists."""
|
||||
for key, value in os_map.items():
|
||||
if key == category:
|
||||
if isinstance(value, dict): # Expand nested categories
|
||||
os_set = set()
|
||||
for subcat in value:
|
||||
os_set.update(get_os_variants(subcat, value))
|
||||
return os_set
|
||||
elif isinstance(value, list): # Direct OS list
|
||||
return set(value)
|
||||
return set()
|
||||
|
||||
allowed_os = set()
|
||||
|
||||
# Identify correct OS filtering scope
|
||||
for key in os_categories:
|
||||
if key == target_os:
|
||||
allowed_os = get_os_variants(target_os, os_categories)
|
||||
break # Stop searching once a match is found
|
||||
|
||||
if isinstance(os_categories[key], dict) and target_os in os_categories[key]:
|
||||
allowed_os = get_os_variants(target_os, os_categories[key])
|
||||
break # Stop searching once a match is found
|
||||
|
||||
for device in devices:
|
||||
if not device["reachable"]:
|
||||
continue # Skip unreachable devices.
|
||||
|
||||
match target_os:
|
||||
case None: # No filtering needed.
|
||||
pass
|
||||
case _ if target_os in os_categories and device["device_os"] in os_categories[target_os]:
|
||||
pass # Allowed OS, continue processing.
|
||||
case _:
|
||||
continue # Skip if the OS is not in the allowed category.
|
||||
|
||||
valid_devices.append(device["device_id"])
|
||||
if not target_os or device["device_os"] in allowed_os:
|
||||
valid_devices.append(device["device_id"])
|
||||
|
||||
return valid_devices
|
||||
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
{
|
||||
"Debian": [
|
||||
"Debian GNU/Linux 12 (bookworm)",
|
||||
"Debian GNU/Linux 11 (bullseye)"
|
||||
],
|
||||
"Ubuntu": [
|
||||
"Ubuntu 24.04.1 LTS"
|
||||
]
|
||||
"Linux": {
|
||||
"Debian": [
|
||||
"Debian GNU/Linux 12 (bookworm)",
|
||||
"Debian GNU/Linux 11 (bullseye)"
|
||||
],
|
||||
"Ubuntu": [
|
||||
"Ubuntu 24.04.1 LTS"
|
||||
]
|
||||
},
|
||||
"MacOS": {
|
||||
"Sequoia": [
|
||||
"macOS 15.0.1"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user