addCurrentUserToGroup adds the invoking user to the celer group. Under sudo this is SUDO_USER; otherwise it falls back to USER. usermod -aG is idempotent: adding an already-member user is a no-op.
(groupName string)
| 618 | // Under sudo this is SUDO_USER; otherwise it falls back to USER. |
| 619 | // usermod -aG is idempotent: adding an already-member user is a no-op. |
| 620 | func addCurrentUserToGroup(groupName string) error { |
| 621 | currentUser, err := currentUserForGroup() |
| 622 | if err != nil { |
| 623 | return err |
| 624 | } |
| 625 | |
| 626 | if output, err := cmd.NewExecutor("", "usermod", "-aG", groupName, currentUser).ExecuteOutput(); err != nil { |
| 627 | return fmt.Errorf("failed to add %q to %q group -> %s -> %w", currentUser, groupName, output, err) |
| 628 | } |
| 629 | |
| 630 | // Verify the membership actually took effect. usermod can return 0 without |
| 631 | // writing to /etc/group when the user record comes from a non-files NSS |
| 632 | // source (LDAP/SSSD/etc.), in which case the group add is silently a no-op. |
| 633 | groups, err := cmd.NewExecutor("", "id", "-nG", currentUser).ExecuteOutput() |
| 634 | if err != nil { |
| 635 | return fmt.Errorf("failed to verify groups for %q after usermod -> %w", currentUser, err) |
| 636 | } |
| 637 | if !slices.Contains(strings.Fields(groups), groupName) { |
| 638 | return fmt.Errorf("usermod succeeded but %q is not in group %q (user likely from LDAP/SSSD, not /etc/group)", currentUser, groupName) |
| 639 | } |
| 640 | |
| 641 | color.PrintHint("✔ %s is added to group %s. 💡 run `newgrp %s` or log out and log back in to take effect (opening a new terminal in the same session is NOT enough).", currentUser, groupName, groupName) |
| 642 | return nil |
| 643 | } |
| 644 | |
| 645 | // parseNFSClientDir parses the --nfs-client-dir flag value. |
| 646 | // Expected format: <mount_point>@<server>:<export_path> |
no test coverage detected