You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Feature request: per-school hardware groups (start.conf) on multi-school servers #178
Allow hardware groups to belong to a school, so that on a multi-school server each school can have its own hardware groups, and school administrators can manage only their own school's groups.
Filed here at kiarn's request in linuxmuster/linuxmuster-tools#36: lmntools can only scope hardware groups per school once LINBO itself supports it.
How it works today
LINBO knows a hardware group only by its name, and that name is the same for the whole server:
GRUB takes the group from the DHCP extensions-path option and loads ${group}.cfg (templates/grub.cfg.pxe).
The client then downloads start.conf.$HOSTGROUP from the linbo rsync module, which is /srv/linbo (linbofs/init.sh).
The server looks up $LINBODIR/start.conf.$group the same way (rsync-pre-download.sh).
Because no school appears anywhere along this path, three things follow on a server with more than one school:
Two schools cannot use the same group name with different contents. If both have a group called raum101, they share one start.conf.raum101.
A school administrator cannot be allowed to edit hardware groups safely. Every start.conf is used by the whole server, so a change for one school also changes the clients of every other school using that group. This is why linuxmuster-api keeps the start.conf routes limited to global administrators; its routers_v1/linbo.py notes that this "needs real per-school ownership in lmntools first".
Tools built on top of LINBO cannot show a school's own groups. The group list is simply every start.conf.* under /srv/linbo.
What would help
A way for LINBO to resolve a client's hardware group within the client's school. For example:
A per-school layout such as /srv/linbo/<school>/start.conf.<group> and a per-school GRUB group config, with the school passed along the same boot path the group already takes.
Or a school-qualified group name, if changing the directory layout is not an option.
Existing single-school installations and default-school would need to keep working unchanged. Resolving the flat /srv/linbo/start.conf.<group> as default-school might be one way to do that.
If per-school groups are a deliberate non-goal, for instance because of how PXE and TFTP have to resolve a boot path before the client's school is known, that would also be useful to know. Tools like ours would then document the server-wide scope as the intended design rather than as a gap waiting to be closed.
Context
We build the LINBO interface in edulution-ui. On a multi-school server it currently shows a notice that hardware groups apply to every school, because nothing downstream can scope them until LINBO does.
Thanks for the detailed write-up. Per-school hardware groups are not a deliberate non-goal, and PXE/TFTP does not block them. The school is already known before the client boots.
Why PXE is not a blocker
The group is not worked out at boot time. linuxmuster-import-devices writes it into each host's DHCP declaration as option extensions-path / option nis-domain (import_devices.py:313), and that DHCP config is already generated per school (devices/<school>.conf). The rest of the boot path just reuses that string unchanged: GRUB loads ${group}.cfg, the client fetches start.conf.$HOSTGROUP, and the rsync hooks read the group back out of the file name. So the school only has to travel inside the group string.
Preferred approach: school-qualified group names
We prefer your second option, a school-qualified group name, over a per-school directory layout:
For every school other thandefault-school, base7 uses <school>-<group> in place of <group> everywhere it derives LINBO artefacts: the DHCP options, start.conf.<school>-<group> and <school>-<group>.cfg (plus the start.conf-<ip> / hostcfg links).
default-school keeps the flat names exactly as today, so single-school installations are unaffected.
This matches the <school>- prefix that hostnames of non-default schools already carry (see linbo_remote_cli.py:249).
The main advantage is that linbofs (client), the GRUB templates and the rsync hooks need no changes, only testing. The separator must not be a dot: the hooks split file names on . (awk -F. in rsync-pre-download.sh, ${BASENAME##*.} in rsync-post-download.sh).
A per-school directory layout (/srv/linbo/<school>/…) would also mean changing the client's rsync path (so every client needs a new linbofs), the GRUB templates, the path logic in the hooks and every path in linuxmuster-tools. It would also break third-party scripts that expect /srv/linbo/start.conf.*. We estimate that at two to three times the effort with no functional gain, so we'd rather not go that way.
Scope and rough effort estimate
Area
Work
Estimate
linuxmuster-base7cli/import_devices.py
one helper (e.g. getLinboGroupId(school, group)), used in the DHCP declaration, doLinboStartconf(), doGrubCfg() and the PXE links
0.5–1 day
linuxmuster-base7 migration
one-time step per non-default school: copy each start.conf.<group> that school uses to start.conf.<school>-<group> (a group shared across schools gets one copy per school), then re-import
~1 day
linuxmuster-linbo7
linbo_mkgrubimg.py reads the group from devices.csv and must build the qualified name; check linbo_register
~0.5 day
Testing
lab with two schools using the same group name; BIOS and EFI; offline boot from the cached start.conf; linbo-remote -g <group> -s <school>
1–2 days
linuxmuster-tools
linbo/config.py (glob, read/write, backups, .vdi sidecars), changes.py, grub_generator.py, linbo_sync.py: filter by school and map <school>-<group> ↔ <group>
2–3 days
linuxmuster-api
open the start.conf routes to school admins, with a school ownership check
~1 day
That comes to roughly 7–10 days across all repos, and edulution-ui is extra.
Open points to settle in the PR
Name collisions: a default-school group that happens to be named abc-raum101 would collide with group raum101 of school abc. Please check which characters group names may contain (sophomorix validation). If - is allowed, pick a separator that is not allowed in group names, or reject colliding names at import time.
Migration of shared groups: a non-default school that used to share a start.conf with default-school gets its own copy afterwards. That is intended, but it has to go in the changelog.
Images stay server-wide: this issue scopes start.conf only. With their own start.conf a school admin can still reference any image, and uploading can overwrite an image another school uses. That is outside this issue but relevant if the goal is that school admins can work safely.
Next step
We agree with the approach, but we don't have capacity to implement it ourselves right now. A PR would be very welcome. Since you already know the consumer side (linuxmuster-tools, linuxmuster-api, edulution-ui), you are probably in the best position to do it end to end. Please open the PRs against the 7.4 branches of linuxmuster-base7 and linuxmuster-linbo7 (the LINBO part should be small) and link them here. We'll review them. For the linuxmuster-tools side, please coordinate with @kiarn in linuxmuster/linuxmuster-tools#36.
One addition to "end to end" above: please don't send this as one large PR. We'd like small PRs that can be reviewed and merged separately, each one fitting into the existing code (reusing existing helpers, no parallel structures). For example:
linuxmuster-base7: the group-id helper and its use in import_devices.py
linuxmuster-base7: the migration of existing start.conf files for non-default schools
linuxmuster-linbo7:linbo_mkgrubimg.py (and linbo_register, if needed)
linuxmuster-tools / linuxmuster-api: step by step, coordinated with @kiarn
It would help to agree on the naming (separator, collision handling) here in the issue before the first PR.
Thanks, small PRs in that order work for us. Here is a naming proposal to settle before the first one, plus three things the migration and PR 3 need to cover.
Separator: +
Proposal: <school>+<group> for every school other than default-school, e.g. start.conf.abc+raum101 and abc+raum101.cfg. default-school keeps the flat names.
Why not -:
Group names may contain - and _: sophomorix check_dgr allows [A-Za-z0-9_-] (sophomorix-device#L1854), and base7 adds no check of its own.
School names may contain - as well. sophomorix only splits SCHOOLS= on commas (SophomorixBase.pm#L4739-L4746). A school that has devices is effectively limited to [A-Za-z0-9-], because base7 validates the prefixed hostname with isValidHostname (network.py#L128-L140).
So with -, names collide not only with default-school (abc-raum101) but also between two non-default schools: school a + group b-x and school a-b + group x both give a-b-x. Hostnames get away with the same prefix only because the AD computer account must be unique; nothing enforces that for group files.
The owning school could then only be recovered with the full school list, and not at all when one school name is another plus -. linuxmuster-api will derive ownership from the file name for its school-admin check, so an ambiguous parse there becomes an authorization problem.
With +, neither part can contain the separator, so there are no collisions to reject at import time. A name without + is default-school, a name with + splits on the first + into school and group, no school list needed. linuxmuster-tools' linbo_conf name check already accepts + (names.py#L14). It is not a dot, so the rsync hooks keep working.
To verify in the lab: the quoted DHCP string, GRUB's ${group}.cfg over TFTP and HTTP, rsync, and FAT long file names on the EFI partition. Consumers must not put the name into a URL query string unencoded (+ decodes to a space).
For "no parallel structures": both directions (school + group → name, name → school + group) as one pair of helpers in linuxmuster_base7.functions, which linbo_mkgrubimg.py already imports from.
Migration: group-keyed boot files inside Windows images
On image creation the client stores BCD.$HOSTGROUP, bsmbr.$HOSTGROUP and gptlabel.$HOSTGROUP inside the image (linbo_create_image#L90-L104), and linbo_sync restores them by the same name (linbo_sync#L400-L438). After the rename, a client of a non-default school syncing an existing image looks for BCD.abc+raum101, finds nothing, and skips the BCD, boot sector and GPT label restore. On EFI that can leave Windows unbootable.
Two options:
Document that affected Windows images must be re-created after the migration (changelog + release notes).
A fallback in linbo_sync to the unqualified name when the qualified file is missing. That is a small linbofs change, so every client needs the new linbofs.
We would lean towards 2, since it keeps existing images working. Which do you prefer? Either way, the test plan should add restoring an existing Windows image (BIOS and EFI) on a migrated non-default-school client.
Migration: Group = inside start.conf
In offline mode the client takes HOSTGROUP from the Group = line of the cached start.conf (init.sh#L421-L424). The migration therefore rewrites Group = to the qualified name in each copy, and linuxmuster-tools does the same when it writes a school's start.conf.
PR 3: linbo_mkgrubimg.py and non-default schools
linbo-mkgrubimg -w <school devices.csv> does not handle non-default schools yet: getHostname returns the unprefixed hostname, so the lookup for host pc01 never matches the DHCP entry host abc-pc01 and --setfilename silently changes nothing. The DHCP entry it writes also drops nis-domain. PR 3 first needs to know the school (from -w or a new -s <school>), then builds the prefixed hostname and the qualified group with the base7 helper.
linbo_register
It needs no change: it writes the plain group into devices.csv, and the qualified name is only derived at import.
If + works for you, the first PR will be the base7 helper pair and its use in import_devices.py.
The linuxmuster-base7 part (group id helper, migration, collision handling) is now tracked separately in linuxmuster/linuxmuster-base7#206. Design questions that affect all repos, in particular the separator, stay here. Where the migration runs is discussed in base7#206.
Thanks, that's a thorough follow-up, and the points check out against the code.
Separator: agreed, <school>+<group>. The collision argument against - is convincing, and an unambiguous parse matters for the api's ownership check. The helper pair belongs in linuxmuster_base7.functions as you suggest. Please follow the project conventions there: camelCase function names, snake_case variables.
Windows boot files: we prefer option 2, the fallback in linbo_sync. When the qualified file is missing, it should fall back to the plain group name, i.e. the part after the +, not the full HOSTGROUP. That's a separate small linbo7 PR. Please add restoring an existing Windows image (BIOS and EFI) on a migrated non-default-school client to the test plan, as you proposed.
Group =: agreed. The migration rewrites it in each copy, and linuxmuster-tools does the same when it writes a school's start.conf.
linbo_mkgrubimg.py: good catch. The missing hostname prefix and the dropped nis-domain are existing bugs, independent of this issue. Please fix them first, as a separate small linbo7 PR, before PR 3 builds on them.
linbo_register: agreed, no change needed.
The base7 work is tracked in linuxmuster/linuxmuster-base7#206. I've updated it with the + separator and the Group = rewrite. Where the migration runs (package upgrade or explicit command) is still open and will be discussed there. Please go ahead with the first PR (the base7 helper pair and its use in import_devices.py).
Lab result: + does not reach the LINBO client through DHCP
While setting up the lab test for #181 (Proxmox VM on the 7.4 dev server, school agy, group win11_edu → agy+win11_edu, DHCP entry and files generated by import-devices from the #207 code) I checked what the client actually receives. The client does not get the qualified group.
The server sends option nis-domain "agy+win11_edu" (/etc/dhcp/devices/agy.conf).
The client's /tmp/dhcp.log has nisdomain='bad', and /.env has export HOSTGROUP='bad'. init.sh maps NISDOMAIN to HOSTGROUP, so start.conf.$HOSTGROUP becomes start.conf.bad.
Cause: BusyBox udhcpc (Ubuntu 1.37.0) types option 40 as a host name (OPTION_STRING_HOST). With FEATURE_UDHCPC_SANITIZEOPT it replaces any value that is not [A-Za-z0-9_.-], or that starts with -, by the literal bad (networking/udhcp/dhcpc.c, good_hostname()). + is rejected.
Option 18 (extensions-path), which GRUB uses, is not exported by udhcpc at all (not present in dhcp.log), so the client cannot read the group from there instead.
This differs from what I assumed in #178 ("linbofs needs no changes"); I listed the DHCP string as something to verify in the lab, and it fails there. It affects every host of a non-default school: its HOSTGROUP is bad, so it cannot fetch its start.conf from the server, and the linbo_sync fallback in #181 cannot match either (${HOSTGROUP#*+} of bad is bad).
Constraint on the separator
Only -, _ and . are allowed besides letters and digits:
. cannot occur in group or school names, so it would parse unambiguously, but the rsync hooks split file names on . (the reason it was excluded here).
- and _ occur in group names. A default-school group such as win11_edu would be indistinguishable from group edu of school win11, so "no separator means default-school" no longer holds without reserving a character sequence that base7 rejects in group names.
Options we see
A multi-character separator from the allowed set (e.g. __), with base7 rejecting group names that contain it (like #209 does for +). linbofs and the hooks stay unchanged, but the default-school groups are only unambiguous if they are checked as well.
., with the hook changes (rsync-pre-download.sh, rsync-post-download.sh) and a check of every place that derives the group from a file name.
Keep + and change linbofs so the group does not depend on option 40 (e.g. a kernel parameter set by the group's grub cfg). That needs a new linbofs on every client.
Which do you prefer? Verified so far on one client VM and in the BusyBox source; I have not tried the alternatives on a live client. The lab test for #181 is on hold until the group reaches the client.
Activity
HappyBasher commentedon Sep 25, 2026
Thanks for the detailed write-up. Per-school hardware groups are not a deliberate non-goal, and PXE/TFTP does not block them. The school is already known before the client boots.
Why PXE is not a blocker
The group is not worked out at boot time.
linuxmuster-import-deviceswrites it into each host's DHCP declaration asoption extensions-path/option nis-domain(import_devices.py:313), and that DHCP config is already generated per school (devices/<school>.conf). The rest of the boot path just reuses that string unchanged: GRUB loads${group}.cfg, the client fetchesstart.conf.$HOSTGROUP, and the rsync hooks read the group back out of the file name. So the school only has to travel inside the group string.Preferred approach: school-qualified group names
We prefer your second option, a school-qualified group name, over a per-school directory layout:
default-school, base7 uses<school>-<group>in place of<group>everywhere it derives LINBO artefacts: the DHCP options,start.conf.<school>-<group>and<school>-<group>.cfg(plus thestart.conf-<ip>/hostcfglinks).default-schoolkeeps the flat names exactly as today, so single-school installations are unaffected.<school>-prefix that hostnames of non-default schools already carry (seelinbo_remote_cli.py:249).The main advantage is that linbofs (client), the GRUB templates and the rsync hooks need no changes, only testing. The separator must not be a dot: the hooks split file names on
.(awk -F.inrsync-pre-download.sh,${BASENAME##*.}inrsync-post-download.sh).A per-school directory layout (
/srv/linbo/<school>/…) would also mean changing the client's rsync path (so every client needs a new linbofs), the GRUB templates, the path logic in the hooks and every path in linuxmuster-tools. It would also break third-party scripts that expect/srv/linbo/start.conf.*. We estimate that at two to three times the effort with no functional gain, so we'd rather not go that way.Scope and rough effort estimate
cli/import_devices.pygetLinboGroupId(school, group)), used in the DHCP declaration,doLinboStartconf(),doGrubCfg()and the PXE linksstart.conf.<group>that school uses tostart.conf.<school>-<group>(a group shared across schools gets one copy per school), then re-importlinbo_mkgrubimg.pyreads the group fromdevices.csvand must build the qualified name; checklinbo_registerlinbo-remote -g <group> -s <school>linbo/config.py(glob, read/write, backups,.vdisidecars),changes.py,grub_generator.py,linbo_sync.py: filter by school and map<school>-<group>↔<group>That comes to roughly 7–10 days across all repos, and edulution-ui is extra.
Open points to settle in the PR
default-schoolgroup that happens to be namedabc-raum101would collide with groupraum101of schoolabc. Please check which characters group names may contain (sophomorix validation). If-is allowed, pick a separator that is not allowed in group names, or reject colliding names at import time.start.confwithdefault-schoolgets its own copy afterwards. That is intended, but it has to go in the changelog.Next step
We agree with the approach, but we don't have capacity to implement it ourselves right now. A PR would be very welcome. Since you already know the consumer side (linuxmuster-tools, linuxmuster-api, edulution-ui), you are probably in the best position to do it end to end. Please open the PRs against the
7.4branches of linuxmuster-base7 and linuxmuster-linbo7 (the LINBO part should be small) and link them here. We'll review them. For the linuxmuster-tools side, please coordinate with @kiarn in linuxmuster/linuxmuster-tools#36.HappyBasher commentedon Sep 25, 2026
One addition to "end to end" above: please don't send this as one large PR. We'd like small PRs that can be reviewed and merged separately, each one fitting into the existing code (reusing existing helpers, no parallel structures). For example:
import_devices.pylinbo_mkgrubimg.py(andlinbo_register, if needed)It would help to agree on the naming (separator, collision handling) here in the issue before the first PR.
TomlDev commentedon Sep 25, 2026
Thanks, small PRs in that order work for us. Here is a naming proposal to settle before the first one, plus three things the migration and PR 3 need to cover.
Separator:
+Proposal:
<school>+<group>for every school other thandefault-school, e.g.start.conf.abc+raum101andabc+raum101.cfg.default-schoolkeeps the flat names.Why not
-:-and_: sophomorixcheck_dgrallows[A-Za-z0-9_-](sophomorix-device#L1854), and base7 adds no check of its own.-as well. sophomorix only splitsSCHOOLS=on commas (SophomorixBase.pm#L4739-L4746). A school that has devices is effectively limited to[A-Za-z0-9-], because base7 validates the prefixed hostname withisValidHostname(network.py#L128-L140).-, names collide not only withdefault-school(abc-raum101) but also between two non-default schools: schoola+ groupb-xand schoola-b+ groupxboth givea-b-x. Hostnames get away with the same prefix only because the AD computer account must be unique; nothing enforces that for group files.-. linuxmuster-api will derive ownership from the file name for its school-admin check, so an ambiguous parse there becomes an authorization problem.With
+, neither part can contain the separator, so there are no collisions to reject at import time. A name without+isdefault-school, a name with+splits on the first+into school and group, no school list needed. linuxmuster-tools'linbo_confname check already accepts+(names.py#L14). It is not a dot, so the rsync hooks keep working.To verify in the lab: the quoted DHCP string, GRUB's
${group}.cfgover TFTP and HTTP, rsync, and FAT long file names on the EFI partition. Consumers must not put the name into a URL query string unencoded (+decodes to a space).For "no parallel structures": both directions (school + group → name, name → school + group) as one pair of helpers in
linuxmuster_base7.functions, whichlinbo_mkgrubimg.pyalready imports from.Migration: group-keyed boot files inside Windows images
On image creation the client stores
BCD.$HOSTGROUP,bsmbr.$HOSTGROUPandgptlabel.$HOSTGROUPinside the image (linbo_create_image#L90-L104), andlinbo_syncrestores them by the same name (linbo_sync#L400-L438). After the rename, a client of a non-default school syncing an existing image looks forBCD.abc+raum101, finds nothing, and skips the BCD, boot sector and GPT label restore. On EFI that can leave Windows unbootable.Two options:
linbo_syncto the unqualified name when the qualified file is missing. That is a small linbofs change, so every client needs the new linbofs.We would lean towards 2, since it keeps existing images working. Which do you prefer? Either way, the test plan should add restoring an existing Windows image (BIOS and EFI) on a migrated non-default-school client.
Migration:
Group =inside start.confIn offline mode the client takes
HOSTGROUPfrom theGroup =line of the cached start.conf (init.sh#L421-L424). The migration therefore rewritesGroup =to the qualified name in each copy, and linuxmuster-tools does the same when it writes a school's start.conf.PR 3:
linbo_mkgrubimg.pyand non-default schoolslinbo-mkgrubimg -w <school devices.csv>does not handle non-default schools yet:getHostnamereturns the unprefixed hostname, so the lookup forhost pc01never matches the DHCP entryhost abc-pc01and--setfilenamesilently changes nothing. The DHCP entry it writes also dropsnis-domain. PR 3 first needs to know the school (from-wor a new-s <school>), then builds the prefixed hostname and the qualified group with the base7 helper.linbo_registerIt needs no change: it writes the plain group into
devices.csv, and the qualified name is only derived at import.If
+works for you, the first PR will be the base7 helper pair and its use inimport_devices.py.HappyBasher commentedon Sep 25, 2026
The linuxmuster-base7 part (group id helper, migration, collision handling) is now tracked separately in linuxmuster/linuxmuster-base7#206. Design questions that affect all repos, in particular the separator, stay here. Where the migration runs is discussed in base7#206.
HappyBasher commentedon Sep 25, 2026
Thanks, that's a thorough follow-up, and the points check out against the code.
Separator: agreed,
<school>+<group>. The collision argument against-is convincing, and an unambiguous parse matters for the api's ownership check. The helper pair belongs inlinuxmuster_base7.functionsas you suggest. Please follow the project conventions there: camelCase function names, snake_case variables.Windows boot files: we prefer option 2, the fallback in
linbo_sync. When the qualified file is missing, it should fall back to the plain group name, i.e. the part after the+, not the fullHOSTGROUP. That's a separate small linbo7 PR. Please add restoring an existing Windows image (BIOS and EFI) on a migrated non-default-school client to the test plan, as you proposed.Group =: agreed. The migration rewrites it in each copy, and linuxmuster-tools does the same when it writes a school's start.conf.linbo_mkgrubimg.py: good catch. The missing hostname prefix and the droppednis-domainare existing bugs, independent of this issue. Please fix them first, as a separate small linbo7 PR, before PR 3 builds on them.linbo_register: agreed, no change needed.The base7 work is tracked in linuxmuster/linuxmuster-base7#206. I've updated it with the
+separator and theGroup =rewrite. Where the migration runs (package upgrade or explicit command) is still open and will be discussed there. Please go ahead with the first PR (the base7 helper pair and its use inimport_devices.py).feat(linbo_sync): fall back to the plain group for windows boot files
fix(linbo_sync): fall back to the plain group for windows boot files
fix(linbo_mkgrubimg): handle hosts of non-default schools
fix(linbo_mkgrubimg): handle hosts of non-default schools
fix(linbo_sync): fall back to the plain group for windows boot files
fix(linbo_mkgrubimg): handle hosts of non-default schools
TomlDev commentedon Oct 7, 2026
Lab result:
+does not reach the LINBO client through DHCPWhile setting up the lab test for #181 (Proxmox VM on the 7.4 dev server, school
agy, groupwin11_edu→agy+win11_edu, DHCP entry and files generated by import-devices from the #207 code) I checked what the client actually receives. The client does not get the qualified group.option nis-domain "agy+win11_edu"(/etc/dhcp/devices/agy.conf)./tmp/dhcp.loghasnisdomain='bad', and/.envhasexport HOSTGROUP='bad'.init.shmapsNISDOMAINtoHOSTGROUP, sostart.conf.$HOSTGROUPbecomesstart.conf.bad.udhcpc(Ubuntu 1.37.0) types option 40 as a host name (OPTION_STRING_HOST). WithFEATURE_UDHCPC_SANITIZEOPTit replaces any value that is not[A-Za-z0-9_.-], or that starts with-, by the literalbad(networking/udhcp/dhcpc.c,good_hostname()).+is rejected.extensions-path), which GRUB uses, is not exported byudhcpcat all (not present indhcp.log), so the client cannot read the group from there instead.This differs from what I assumed in #178 ("linbofs needs no changes"); I listed the DHCP string as something to verify in the lab, and it fails there. It affects every host of a non-default school: its
HOSTGROUPisbad, so it cannot fetch its start.conf from the server, and thelinbo_syncfallback in #181 cannot match either (${HOSTGROUP#*+}ofbadisbad).Constraint on the separator
Only
-,_and.are allowed besides letters and digits:.cannot occur in group or school names, so it would parse unambiguously, but the rsync hooks split file names on.(the reason it was excluded here).-and_occur in group names. A default-school group such aswin11_eduwould be indistinguishable from groupeduof schoolwin11, so "no separator means default-school" no longer holds without reserving a character sequence that base7 rejects in group names.Options we see
__), with base7 rejecting group names that contain it (like #209 does for+). linbofs and the hooks stay unchanged, but the default-school groups are only unambiguous if they are checked as well.., with the hook changes (rsync-pre-download.sh,rsync-post-download.sh) and a check of every place that derives the group from a file name.+and change linbofs so the group does not depend on option 40 (e.g. a kernel parameter set by the group's grub cfg). That needs a new linbofs on every client.Which do you prefer? Verified so far on one client VM and in the BusyBox source; I have not tried the alternatives on a live client. The lab test for #181 is on hold until the group reaches the client.