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) {
|
||||
for {
|
||||
// ----- Users -------------------------------------------------
|
||||
status = resolveUsers()
|
||||
switch status {
|
||||
case BROKEN:
|
||||
return BROKEN
|
||||
case REPAIRED:
|
||||
continue
|
||||
}
|
||||
// ----- Files -------------------------------------------------
|
||||
status = resolveFiles()
|
||||
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