build-cli.sh Simple shell script that builds inventory-cli inside Docker and extracts the binary to build/ (or a custom path). Replaces the need to use the heavier build-and-load.sh just to compile the CLI. --help Replaced the terse usage() stub with a full UNIX man-page style reference covering NAME, SYNOPSIS, DESCRIPTION, GLOBAL OPTIONS, COMMANDS (grouped by area), PART TYPES, FIELD KEYS, EXAMPLES, and NOTES. discover-only [--type <type>] New command that runs local hardware discovery without contacting the inventory server and prints results as an ASCII tree rooted at the hostname. Each section (CPUs, CPU Slots, Memory Sticks, Memory Slots, Disks, NICs) lists discovered components with key attributes inline. Useful for inspection and troubleshooting. discovery.cpp: store interface name in K_NAME for NICs ifname (e.g. "nic0", "eno1") is now emitted so discover-only and the server-side UI can display the kernel device name. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|---|---|---|
| .. | ||
| src | ||
| web-ui | ||
| build-and-load.sh | ||
| build-cli.sh | ||
| CMakeLists.txt | ||
| Dockerfile | ||
| Dockerfile.cli | ||
| instructions.md | ||
| README.md | ||
device-inventory
A lightweight hardware inventory tracker built in C++17. Uses a client/server model: the server owns the file-backed database and exposes a TCP interface on localhost; the CLI client connects to it to run commands.
Architecture
┌──────────────┐ TCP (localhost:9876) ┌─────────────────────┐
│ inventory-cli│ ─────────────────────► │ inventory-server │
│ (CLI client)│ ◄───────────────────── │ database ► file.db │
└──────────────┘ └─────────────────────┘
- inventory-server – loads the inventory file on start, accepts one command per connection, and flushes changes to disk after every mutation.
- inventory-cli – a thin CLI that translates subcommands into protocol messages, connects to the server, and pretty-prints the response.
Build
Requires CMake ≥ 3.16 and a C++17-capable compiler.
cd device-inventory
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
Binaries end up in build/inventory-server and build/inventory-cli.
Running
Start the server
./build/inventory-server # uses inventory.db in CWD
./build/inventory-server --port 9876 --db /var/lib/inventory/data.db
The server reloads the file every time it restarts. On the very first run the file is created automatically.
Use the CLI
# Shorthand for the examples below
cli="./build/inventory-cli"
Commands
Servers
# Add a server
$cli add-server "web01" "192.168.1.10" "Rack A" "Primary web server"
# List all servers
$cli list-servers
# Edit a field (fields: name | hostname | location | description)
$cli edit-server 1 hostname "10.0.0.1"
$cli edit-server 1 description "Retired – do not use"
Part types
# Add a part type
$cli add-part-type "RAM" "Memory modules"
$cli add-part-type "SSD" "Solid-state storage"
# List all part types
$cli list-part-types
# Edit a field (fields: name | description)
$cli edit-part-type 1 description "DDR4/DDR5 memory"
Parts
# Add a part to a server
# add-part <server_id> <part_type_id> <name> <serial> <description>
$cli add-part 1 1 "16 GB DDR4" "SN-MEM-001" "DIMM slot A1"
$cli add-part 1 2 "Samsung 870 EVO 1 TB" "SN-SSD-004" "Primary OS drive"
# List parts of a server
$cli list-parts 1
# Edit a field (fields: name | serial | description | server_id | part_type_id)
$cli edit-part 2 serial "SN-SSD-005"
$cli edit-part 2 server_id 3
Database file format
Plain text, one record per line – safe to inspect or diff with standard tools.
# device-inventory database
META|<next_server_id>|<next_part_type_id>|<next_part_id>
S|<id>|<name>|<hostname>|<location>|<description>
PT|<id>|<name>|<description>
P|<id>|<server_id>|<part_type_id>|<name>|<serial>|<description>
Pipe characters and backslashes inside field values are escaped with \|
and \\ respectively.
Wire protocol
Commands are newline-terminated lines; fields are separated by ASCII SOH
(0x01). Each connection carries exactly one request/response pair.
Client → Server: COMMAND\x01arg1\x01arg2\n
Server → Client: OK\n
field1\x01field2\x01...\n ← 0 or more data rows
END\n
-- or --
ERR <message>\n