Multi-valued by design
Uniqueness is on the triple, not the pair — so a node can carry two VLANs, three networks, any repeated key, with nothing clobbered.
HPC · cluster node attributes
Classic genders is a flat (node, key)=value bag — no
multi-values, no real relationships, no query language. gendersdb
puts SQLite where genders kept a text file: an (entity, name, value)
triple model plus typed relations. Your nodeattr and pdsh
muscle memory still works — everything else gets an upgrade.
the model, fixed
The flat file couldn't say a node has two VLANs, or that a rack is powered by a phase-B PDU. gendersdb makes attributes multi-valued and relationships first-class — so the questions you always wanted to ask become one line.
/etc/genders · flat
# one (node,key)=value bag; last write wins node[01-08] compute,eth0=e%n,bmc=%n-ipmi node[01-04] gpu node01 vlan=10 node01 vlan=20 # clobbers 10 # racks? PDUs? phases? nowhere to put them.
gendersdb · triple + relations
set node01 vlan=10 set node01 vlan=20 # both kept link node01 member_of rack-b link rack-b powered_by pdu-b set pdu-b phase=B
what you get
Uniqueness is on the triple, not the pair — so a node can carry two VLANs, three networks, any repeated key, with nothing clobbered.
Typed edges model real topology — node→rack→PDU. Attributes inherit one hop along member_of, opt-in when you want it.
Booleans, numeric comparison, regex, relational hops and aggregation — compiled to safe, parameterized SQL. compute && mem>=256 && !gpu.
Ask in English; gendersdb translates to the DSL, echoes it, and waits for your yes. It proposes a verifiable expression — it never selects nodes on its own. Local, never cloud.
A REPL over your database — tab-completion of live names, history, hostlist expansion, and staged begin/commit/rollback transactions.
A nodeattr shim speaks the classic CLI, and export emits a flat genders file — so existing nodeattr/pdsh scripts run unchanged.
Standard library only — no pip install, no daemon, no cache. It drops onto a locked-down HPC head node with just Python 3.8+ and SQLite.
the DSL in anger
Every value is a bound parameter; every attribute and relation name is charset-validated. The same grammar drives the CLI, the shell and natural language.
download · install · run
Download the package, unpack, and run the installer — no pip, no clone.
Already have an /etc/genders? Import it and keep going; a sample
flat file ships in the box.
the migration story, end to end
$ gendersdb --db cluster.gdb init
$ gendersdb --db cluster.gdb import /etc/genders
$ gendersdb --db cluster.gdb select 'compute && !gpu'
$ gendersdb --db cluster.gdb nl "gpu nodes with 512+ of ssd"
$ gshell --db cluster.gdb
v1.0 · per-user or system-wide; no pip
# unpack, then:
$ tar xzf gendersdb-1.0.tar.gz
$ cd gendersdb-1.0
$ ./install.sh # ~/.local
$ sudo ./install.sh # /usr/local