// Helper copied to the remote hosts to run commands and deploy configuration
// Copyright (C) 2021 Simon Ruderich
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
package main
import (
"fmt"
"log"
"os"
"golang.org/x/term"
"ruderich.org/simon/safcm"
"ruderich.org/simon/safcm/cmd/safcm-remote/ainsl"
"ruderich.org/simon/safcm/cmd/safcm-remote/info"
"ruderich.org/simon/safcm/cmd/safcm-remote/run"
"ruderich.org/simon/safcm/cmd/safcm-remote/sync"
)
func usage() {
log.Fatalf("usage: %[1]s sync\n"+
"usage: %[1]s ainsl [options] ",
os.Args[0])
}
func main() {
// Timestamps are added by `safcm`
log.SetFlags(0)
if len(os.Args) < 2 {
usage()
}
var err error
switch os.Args[1] {
case "sync":
if len(os.Args) != 2 {
usage()
}
err = mainLoop()
case "ainsl":
err = ainsl.Main(os.Args)
default:
usage()
}
if err != nil {
log.Fatalf("%s: %v", os.Args[0], err)
}
}
func mainLoop() error {
if term.IsTerminal(int(os.Stdin.Fd())) ||
term.IsTerminal(int(os.Stdout.Fd())) {
return fmt.Errorf("sync should only be called from `safcm` " +
"(redirect stdin/stdout to circumvent this check)")
}
conn := safcm.NewGobConn(os.Stdin, os.Stdout)
var logLevel safcm.LogLevel
logFunc := func(level safcm.LogLevel, format string, a ...interface{}) {
if logLevel >= level {
conn.Send(safcm.MsgLog{
Level: level,
Text: fmt.Sprintf(format, a...),
})
}
}
var quitResp safcm.MsgQuitResp
for {
x, err := conn.Recv()
if err != nil {
return err
}
var resp safcm.Msg
switch x := x.(type) {
case safcm.MsgInfoReq:
logLevel = x.LogLevel // set log level globally
resp = info.Handle(x, run.ExecRunner{}, logFunc)
case safcm.MsgSyncReq:
resp = sync.Handle(x, run.ExecRunner{}, logFunc)
case safcm.MsgQuitReq:
resp = quitResp
default:
return fmt.Errorf("unsupported message %#v", x)
}
err = conn.Send(resp)
if err != nil {
return err
}
if resp == quitResp {
break
}
}
return nil
}