Select Git revision
batch.go 3.82 KiB
// Package batch contains the non-interactive maintenence commands.
package batch
import (
_ "embed"
"errors"
"fmt"
"os"
"path"
"strings"
"text/template"
"time"
"git.lyda.ie/kevin/bulletin/ask"
"git.lyda.ie/kevin/bulletin/key"
"git.lyda.ie/kevin/bulletin/storage"
"github.com/adrg/xdg"
)
//go:embed crontab
var crontabTemplate string
// Reboot deletes all messages with `shutdown` set.
func Reboot() int {
ctx := storage.Context()
store, err := storage.Open()
ask.CheckErr(err)
q := storage.New(store.DB)
rows, err := q.DeleteAllShutdownMessages(ctx)
ask.CheckErr(err)
fmt.Printf("Removed %d shutdown messages\n", rows)
return 0
}
// Expire deletes all messages that have hit their expiration date.
func Expire() int {
ctx := storage.Context()
store, err := storage.Open()
ask.CheckErr(err)
q := storage.New(store.DB)
rows, err := q.DeleteAllExpiredMessages(ctx)
ask.CheckErr(err)
fmt.Printf("Expired %d messages\n", rows)
return 0
}
// Install is an interactive command used to install the crontab.
func Install() int {
ctx := storage.Context()
// Check if install has run before.
touchfile := path.Join(xdg.Home, ".bulletin-installed")
if _, err := os.Stat(touchfile); err == nil {
ask.CheckErr(errors.New("~/.bulletin-installed exists; BULLETIN install has run"))
} else {
if !errors.Is(err, os.ErrNotExist) {
fmt.Println("ERROR: Unknown error checking in ~/.bulletin-installed exists.")
fmt.Println("ERROR: Can't see if BULLETIN has been installed.")
ask.CheckErr(err)
}
}
// Connect to the database.
store, err := storage.Open()
ask.CheckErr(err)
q := storage.New(store.DB)
// Create the initial users.
fmt.Println(`Welcome to the BULLETIN install process. This will create
the following files:
* ~/.local/share/BULLETIN/bulletin.db - BULLETIN's folder and user db.
* ~/.bulletin-installed - A file to make sure install isn't run again.
* ~/.config/BULLETIN/* - history files for each user.
* ~/.ssh/authorized_keys - key lines to let users connect to BULLETIN
To complete the installation, please enter the login, name and ssh key for
the first user.`)
login, err := ask.GetLine("Enter login of initial user: ")
login = strings.ToUpper(login)
ask.CheckErr(err)
name, err := ask.GetLine("Enter name of initial user: ")
ask.CheckErr(err)
sshkey, err := ask.GetLine("Enter ssh public key of initial user: ")
ask.CheckErr(err)
// Seed data.
seedMsgs, err := GetSeedMessages()
ask.CheckErr(err)
ask.CheckErr(q.SeedUserSystem(ctx))
ask.CheckErr(q.SeedFolderGeneral(ctx))
ask.CheckErr(q.SeedGeneralOwner(ctx))
_, err = q.AddUser(ctx, storage.AddUserParams{
Login: login,
Name: name,
})
key.Add(login, sshkey)
userCreated := map[string]bool{
"SYSTEM": true,
login: true,
}
for i := range seedMsgs {
if !userCreated[seedMsgs[i].Login] {
_, err = q.AddUser(ctx, storage.AddUserParams{
Login: seedMsgs[i].Login,
Name: seedMsgs[i].Name,
Disabled: 1,
})
ask.CheckErr(err)
userCreated[seedMsgs[i].Login] = true
}
ask.CheckErr(q.SeedCreateMessage(ctx, storage.SeedCreateMessageParams{
Folder: "GENERAL",
Author: seedMsgs[i].Login,
Subject: seedMsgs[i].Subject,
Message: seedMsgs[i].Message,
CreateAt: seedMsgs[i].Date,
Expiration: time.Now(),
}))
}
// Install crontab.
bulletin, err := os.Executable()
if err != nil {
panic(err) // TODO: cleanup error handling.
}
crontab := &strings.Builder{}
template.Must(template.New("crontab").Parse(crontabTemplate)).
Execute(crontab, map[string]string{"Bulletin": bulletin})
fmt.Printf("Adding this to crontab:\n\n%s\n", crontab.String())
err = installCrontab(crontab.String())
if err != nil {
panic(err) // TODO: cleanup error handling.
}
// Mark that install has happened. err = touch(touchfile)
if err != nil {
panic(err) // TODO: cleanup error handling.
}
return 0
}