Implement /fromcurto/ to make use of kept state
This commit is contained in:
parent
3d77d98d50
commit
47c3077524
|
@ -1,20 +1,24 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
type TargetId string
|
||||
type Command string
|
||||
|
||||
func (c *Command) Exec() ([]byte, error) {
|
||||
return exec.Command("/bin/sh", "-c", string(*c)).Output()
|
||||
}
|
||||
|
||||
type Target struct {
|
||||
Id TargetId `toml:"id"`
|
||||
Id string `toml:"id"`
|
||||
CommandsTo []Command `toml:"commands_to"`
|
||||
CommandsFrom []Command `toml:"commands_from"`
|
||||
}
|
||||
type Targets []Target
|
||||
|
||||
const HostTarget TargetId = "host"
|
||||
|
||||
type T struct {
|
||||
Globals struct {
|
||||
Listen *string
|
||||
|
|
98
server.go
98
server.go
|
@ -6,25 +6,26 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"regexp"
|
||||
|
||||
"gitea.elkins.co/Networking/kvmswitcher/internal/config"
|
||||
)
|
||||
|
||||
var (
|
||||
confFile = flag.String("config",
|
||||
path.Join(os.Getenv("HOME"), ".config", "kvmswitcher", "config.toml"),
|
||||
"Path to the configuration file",
|
||||
)
|
||||
listen = flag.String("listen", ":5001", "Address and port to listen on")
|
||||
targets config.Targets
|
||||
curTargetId config.TargetId // currently unused, but keeps track of what is activated
|
||||
const (
|
||||
hostTgt = "host"
|
||||
dirTo = true
|
||||
dirFrom = false
|
||||
)
|
||||
|
||||
func targetIds(t config.Targets) []config.TargetId {
|
||||
x := make([]config.TargetId, len(t))
|
||||
var (
|
||||
confFile = flag.String("config", "/etc/kvmswitcher/config.toml", "Path to the configuration file")
|
||||
listen = flag.String("listen", ":5001", "Address and port to listen on")
|
||||
curTargetId = flag.String("initial", "host", "Intitially active target")
|
||||
targets config.Targets
|
||||
)
|
||||
|
||||
func targetIds(t config.Targets) []string {
|
||||
x := make([]string, len(t))
|
||||
for i := range t {
|
||||
x[i] = t[i].Id
|
||||
}
|
||||
|
@ -45,8 +46,6 @@ func main() {
|
|||
log.Fatal("No targets configured")
|
||||
}
|
||||
|
||||
curTargetId = config.HostTarget
|
||||
|
||||
if c.Globals.Listen != nil {
|
||||
listen = c.Globals.Listen
|
||||
}
|
||||
|
@ -55,60 +54,83 @@ func main() {
|
|||
log.Printf("listening on %s\n", *listen)
|
||||
http.HandleFunc("/to/", doSwitchTo)
|
||||
http.HandleFunc("/from/", doSwitchFrom)
|
||||
http.HandleFunc("/fromcurto/", doSwitchFromCurTo)
|
||||
http.ListenAndServe(*listen, nil)
|
||||
}
|
||||
|
||||
func getTarget(r *http.Request) (string, error) {
|
||||
ct, _ := regexp.Compile("^/(from|to|fromcurto)/")
|
||||
u := ct.ReplaceAllString(r.URL.String(), "")
|
||||
if u == r.URL.String() {
|
||||
log.Printf("Malformed request: %s\n", u)
|
||||
return "", fmt.Errorf("Malformed request: %s", u)
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func doSwitchFrom(w http.ResponseWriter, r *http.Request) {
|
||||
doSwitch(false, w, r)
|
||||
t, err := getTarget(r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "%s", err)
|
||||
}
|
||||
doSwitch(dirFrom, t, w)
|
||||
}
|
||||
|
||||
func doSwitchTo(w http.ResponseWriter, r *http.Request) {
|
||||
doSwitch(true, w, r)
|
||||
t, err := getTarget(r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "%s", err)
|
||||
}
|
||||
doSwitch(dirTo, t, w)
|
||||
}
|
||||
|
||||
func doSwitch(to bool, w http.ResponseWriter, r *http.Request) {
|
||||
ct, _ := regexp.Compile("^/(from|to)/")
|
||||
u := config.TargetId(ct.ReplaceAllString(r.URL.String(), ""))
|
||||
if u == config.TargetId(r.URL.String()) {
|
||||
fmt.Fprintf(w, "Malformed request: %s\n", u)
|
||||
return
|
||||
func doSwitchFromCurTo(w http.ResponseWriter, r *http.Request) {
|
||||
t, err := getTarget(r)
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "%s", err)
|
||||
}
|
||||
doSwitch(dirFrom, *curTargetId, w)
|
||||
doSwitch(dirTo, t, w)
|
||||
}
|
||||
|
||||
func doSwitch(dir bool, tgt string, w http.ResponseWriter) {
|
||||
var t *config.Target
|
||||
for i := range targets {
|
||||
if targets[i].Id == config.TargetId(u) {
|
||||
if targets[i].Id == tgt {
|
||||
t = &targets[i]
|
||||
}
|
||||
}
|
||||
if t == nil {
|
||||
fmt.Fprintf(w, "Invalid Target: %s\n", u)
|
||||
fmt.Fprintf(w, "Invalid Target: %s\n", tgt)
|
||||
return
|
||||
}
|
||||
|
||||
cmds := t.CommandsFrom
|
||||
toFrom := "from"
|
||||
curTargetId = config.HostTarget
|
||||
if to {
|
||||
h := hostTgt
|
||||
curTargetId = &h
|
||||
if dir == dirTo {
|
||||
cmds = t.CommandsTo
|
||||
toFrom = "to"
|
||||
curTargetId = t.Id
|
||||
curTargetId = &t.Id
|
||||
}
|
||||
|
||||
log.Printf("Switching %s %s\n", toFrom, u)
|
||||
out, err := runCommands(cmds)
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, "ERROR:\n%s", err)
|
||||
log.Printf("Error on command execution (switching %s %s): %s\n", toFrom, u, err)
|
||||
log.Printf("Switching %s %s\n", toFrom, tgt)
|
||||
|
||||
out := make(chan string)
|
||||
go runCommands(cmds, out)
|
||||
for o := range out {
|
||||
fmt.Fprint(w, o)
|
||||
}
|
||||
fmt.Fprintf(w, "OUTPUT:\n%s", out)
|
||||
}
|
||||
|
||||
func runCommands(cmds []config.Command) (out string, err error) {
|
||||
func runCommands(cmds []config.Command, out chan string) {
|
||||
for _, c := range cmds {
|
||||
o, err := exec.Command("/bin/sh", "-c", string(c)).Output()
|
||||
o, err := c.Exec()
|
||||
if err != nil {
|
||||
return out, fmt.Errorf("Error executing %s: %s\n", c, err)
|
||||
log.Printf("Error on command execution (cmd = %s): %s\n", c, err)
|
||||
}
|
||||
out = out + string(o)
|
||||
out <- string(o)
|
||||
}
|
||||
return
|
||||
close(out)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue