feat(stdlib): added borg server custom promise
This commit is contained in:
parent
1a4192b5c9
commit
07db4ab5bd
2 changed files with 109 additions and 0 deletions
9
stdlib/backups/borg/common.go
Normal file
9
stdlib/backups/borg/common.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package borg
|
||||||
|
|
||||||
|
import gonf "git.adyxax.org/adyxax/gonf/v2/pkg"
|
||||||
|
|
||||||
|
func installBorgPackage() gonf.Status {
|
||||||
|
packag := gonf.Package("borgbackup")
|
||||||
|
packag.Resolve()
|
||||||
|
return packag.Status()
|
||||||
|
}
|
100
stdlib/backups/borg/server.go
Normal file
100
stdlib/backups/borg/server.go
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
package borg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log/slog"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
gonf "git.adyxax.org/adyxax/gonf/v2/pkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BorgServer struct {
|
||||||
|
chain []gonf.Promise
|
||||||
|
clients map[string][]byte // name -> publicKey
|
||||||
|
path string
|
||||||
|
user string
|
||||||
|
status gonf.Status
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BorgServer) IfRepaired(p ...gonf.Promise) gonf.Promise {
|
||||||
|
b.chain = append(b.chain, p...)
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BorgServer) Promise() gonf.Promise {
|
||||||
|
gonf.MakeCustomPromise(b).Promise()
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BorgServer) Resolve() {
|
||||||
|
b.status = gonf.KEPT
|
||||||
|
// Borg user
|
||||||
|
user := gonf.User(gonf.UserData{
|
||||||
|
HomeDir: b.path,
|
||||||
|
Name: "borg",
|
||||||
|
System: true,
|
||||||
|
})
|
||||||
|
user.Resolve()
|
||||||
|
switch user.Status() {
|
||||||
|
case gonf.BROKEN:
|
||||||
|
b.status = gonf.BROKEN
|
||||||
|
return
|
||||||
|
case gonf.REPAIRED:
|
||||||
|
b.status = gonf.REPAIRED
|
||||||
|
}
|
||||||
|
// borg package
|
||||||
|
switch installBorgPackage() {
|
||||||
|
case gonf.BROKEN:
|
||||||
|
b.status = gonf.BROKEN
|
||||||
|
return
|
||||||
|
case gonf.REPAIRED:
|
||||||
|
b.status = gonf.REPAIRED
|
||||||
|
}
|
||||||
|
// authorized_keys
|
||||||
|
borgDir := gonf.ModeUserGroup(0700, "borg", "borg")
|
||||||
|
borgRO := gonf.ModeUserGroup(0400, "borg", "borg")
|
||||||
|
file := gonf.File(filepath.Join(b.path, ".ssh/authorized_keys")).
|
||||||
|
DirectoriesPermissions(borgDir).
|
||||||
|
Permissions(borgRO)
|
||||||
|
authorizedKeys := ""
|
||||||
|
// we sort the names so that the file contents are stable
|
||||||
|
names := make([]string, len(b.clients)-1)
|
||||||
|
for name := range b.clients {
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
for _, name := range names {
|
||||||
|
key := b.clients[name]
|
||||||
|
authorizedKeys += "command=\"borg serve --restrict-to-path " + filepath.Join(b.path, name) + "\",restrict " + string(key) + "\n"
|
||||||
|
}
|
||||||
|
file.Contents(authorizedKeys).Resolve()
|
||||||
|
switch file.Status() {
|
||||||
|
case gonf.BROKEN:
|
||||||
|
b.status = gonf.BROKEN
|
||||||
|
return
|
||||||
|
case gonf.REPAIRED:
|
||||||
|
b.status = gonf.REPAIRED
|
||||||
|
}
|
||||||
|
// TODO init repositories? or let the borg client do it?
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b BorgServer) Status() gonf.Status {
|
||||||
|
return b.status
|
||||||
|
}
|
||||||
|
|
||||||
|
func Server() *BorgServer {
|
||||||
|
return &BorgServer{
|
||||||
|
chain: nil,
|
||||||
|
clients: make(map[string][]byte),
|
||||||
|
path: "/srv/borg/",
|
||||||
|
user: "borg",
|
||||||
|
status: gonf.PROMISED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BorgServer) Add(name string, publicKey []byte) *BorgServer {
|
||||||
|
if _, ok := b.clients[name]; ok {
|
||||||
|
slog.Debug("Duplicate name for BorgServer", "name", name)
|
||||||
|
panic("Duplicate name for BorgServer")
|
||||||
|
}
|
||||||
|
b.clients[name] = publicKey
|
||||||
|
return b
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue