Hallvard B Furuseth wrote:
I'd like a simple way to manipulate an off-line database while slapd is running, e.g. to slapadd it from scratch and activate it when done.
Here is one suggestion:
Make olcHidden a dynamic attribute computed from an attribute olcLabel="some text" + a startup option -L "label to activate,...". Updates to olcHidden could fail or update olcLabel for backwards compatibility, depending on configuration.
I see your goal but I think this is the wrong approach. With olcHidden the database is still fully operational, it is merely hidden from the frontend. You're talking about an actual "olcOffline" switch, which would tell slapd not to bother calling the backend db_open() function for a particular database on startup, or to call its db_close() if already running. I don't believe this particular switch should be rolled into your "olcLabel" proposal.
Then to rebuild database X off-line, maybe with a different config:
- Copy ldapadd X's config to a new database Y, except set olcLabel = "offline" and olcDbDirectory = "<new dir>".
- Set olcReadOnly=TRUE in X's config, so we won't lose any changes.
- Slapcat<X> | slapadd -L offline
No need for -L, just use slapadd -n<X>.
Most of this manipulation is unnecessary; just use an alternate config for your offline build.
- Set X's olcDbDirectory="<new dir>" and olcReadOnly=FALSE, to pick up the changes and resume normal operation.
Without writing any additional code, you can do all of this already. 1: slapcat -n0 > /tmp/config.ldif 2: edit database X's olcDBDirectory in /tmp/config.ldif 3: slapadd -n0 -F /some/new/config -l /tmp/config.ldif 4: set olcReadOnly=TRUE in database X's config on running slapd 5: slapcat X | slapadd -F /some/new/config 6: set olcDbDirectory="<new dir>" and olcReadOnly=FALSE
This doesn't cover all cases of reconfiguring a database, e.g. we can't modify a global option like olcIndexIntLen this way. But it's a start.
Also instead of pointing X's olcDbDirectory at Y's directory, one might want to atomically hide database X and un-hide Y, by removing Y's label and then labelling X. That works if one can have two active databases with the same suffix where the former hides the latter. (Maybe the hidden database would be treated as if it had olcHidden.)
Your use case is not a compelling reason for doing this.