feat(users): implemented basic user creation promise
This commit is contained in:
parent
d20734c275
commit
f51843f634
3 changed files with 129 additions and 0 deletions
|
@ -14,6 +14,14 @@ func EnableDebugLogs() {
|
||||||
|
|
||||||
func Resolve() (status Status) {
|
func Resolve() (status Status) {
|
||||||
for {
|
for {
|
||||||
|
// ----- Users -------------------------------------------------
|
||||||
|
status = resolveUsers()
|
||||||
|
switch status {
|
||||||
|
case BROKEN:
|
||||||
|
return BROKEN
|
||||||
|
case REPAIRED:
|
||||||
|
continue
|
||||||
|
}
|
||||||
// ----- Files -------------------------------------------------
|
// ----- Files -------------------------------------------------
|
||||||
status = resolveFiles()
|
status = resolveFiles()
|
||||||
switch status {
|
switch status {
|
||||||
|
|
95
pkg/users.go
Normal file
95
pkg/users.go
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
package gonf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ----- Globals ---------------------------------------------------------------
|
||||||
|
var users []*UserPromise
|
||||||
|
|
||||||
|
// users management functions
|
||||||
|
var user_add_function func(data UserData) (Status, error)
|
||||||
|
|
||||||
|
// ----- Init ------------------------------------------------------------------
|
||||||
|
func init() {
|
||||||
|
users = make([]*UserPromise, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----- Public ----------------------------------------------------------------
|
||||||
|
func SetUsersConfiguration(useradd func(data UserData) (Status, error)) {
|
||||||
|
user_add_function = useradd
|
||||||
|
}
|
||||||
|
|
||||||
|
func User(data UserData) *UserPromise {
|
||||||
|
if data.Name == "" {
|
||||||
|
panic("User() promise invoked without specifying a username")
|
||||||
|
}
|
||||||
|
return &UserPromise{
|
||||||
|
chain: nil,
|
||||||
|
data: data,
|
||||||
|
states: nil,
|
||||||
|
status: PROMISED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserData struct {
|
||||||
|
HomeDir string
|
||||||
|
Name string
|
||||||
|
System bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserPromise struct {
|
||||||
|
chain []Promise
|
||||||
|
data UserData
|
||||||
|
states []string
|
||||||
|
status Status
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserPromise) IfRepaired(p ...Promise) Promise {
|
||||||
|
u.chain = append(u.chain, p...)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserPromise) Promise() Promise {
|
||||||
|
users = append(users, u)
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserPromise) Resolve() {
|
||||||
|
var err error
|
||||||
|
u.status, err = user_add_function(u.data)
|
||||||
|
switch u.status {
|
||||||
|
case BROKEN:
|
||||||
|
slog.Error("user", "name", u.data.Name, "status", u.status, "error", err)
|
||||||
|
case KEPT:
|
||||||
|
slog.Debug("user", "name", u.data.Name, "status", u.status)
|
||||||
|
case REPAIRED:
|
||||||
|
slog.Info("user", "name", u.data.Name, "status", u.status)
|
||||||
|
if u.status == REPAIRED {
|
||||||
|
for _, pp := range u.chain {
|
||||||
|
pp.Resolve()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UserPromise) Status() Status {
|
||||||
|
return u.status
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----- Internal --------------------------------------------------------------
|
||||||
|
func resolveUsers() (status Status) {
|
||||||
|
status = KEPT
|
||||||
|
for _, c := range users {
|
||||||
|
if c.status == PROMISED {
|
||||||
|
c.Resolve()
|
||||||
|
switch c.status {
|
||||||
|
case BROKEN:
|
||||||
|
return BROKEN
|
||||||
|
case REPAIRED:
|
||||||
|
status = REPAIRED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
26
stdlib/os/linux/useradd.go
Normal file
26
stdlib/os/linux/useradd.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package linux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.adyxax.org/adyxax/gonf/v2/pkg"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Useradd(data gonf.UserData) (gonf.Status, error) {
|
||||||
|
getent := exec.Command("getent", "passwd", data.Name)
|
||||||
|
if err := getent.Run(); err == nil {
|
||||||
|
return gonf.KEPT, nil
|
||||||
|
}
|
||||||
|
args := make([]string, 0)
|
||||||
|
if data.HomeDir != "" {
|
||||||
|
args = append(args, "--home-dir="+data.HomeDir)
|
||||||
|
}
|
||||||
|
if data.System {
|
||||||
|
args = append(args, "--system")
|
||||||
|
}
|
||||||
|
args = append(args, data.Name)
|
||||||
|
cmd := exec.Command("useradd", args...)
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return gonf.BROKEN, err
|
||||||
|
}
|
||||||
|
return gonf.REPAIRED, nil
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue