commit 19b1834943b47cfc9a3211881e9da933210ab362 Author: t14 Date: Sun Jul 21 12:40:28 2024 +0200 initial commit diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..23c2d10 --- /dev/null +++ b/.air.toml @@ -0,0 +1,51 @@ +root = "." +testdata_dir = "testdata" +tmp_dir = "tmp" + +[build] + args_bin = [] + bin = "./tmp/main" + cmd = "go build -o ./tmp/main ." + delay = 1000 + exclude_dir = ["assets", "tmp", "vendor", "testdata"] + exclude_file = [] + exclude_regex = ["_test.go"] + exclude_unchanged = false + follow_symlink = false + full_bin = "" + include_dir = [] + include_ext = ["go", "tpl", "tmpl", "html"] + include_file = ["config.toml"] + kill_delay = "0s" + log = "build-errors.log" + poll = false + poll_interval = 0 + post_cmd = [] + pre_cmd = [] + rerun = false + rerun_delay = 500 + send_interrupt = false + stop_on_error = false + +[color] + app = "" + build = "yellow" + main = "magenta" + runner = "green" + watcher = "cyan" + +[log] + main_only = false + time = false + +[misc] + clean_on_exit = false + +[proxy] + app_port = 0 + enabled = false + proxy_port = 0 + +[screen] + clear_on_rebuild = false + keep_scroll = true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dfd6fd1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +tmp/ +ctrl diff --git a/config.go b/config.go new file mode 100644 index 0000000..3e1c933 --- /dev/null +++ b/config.go @@ -0,0 +1,45 @@ +package main + +import ( + "log" + + "github.com/BurntSushi/toml" +) + +type httpFeature struct { + Host string + Port int +} + +type sshFeature struct { + SSHKeyPath string + SSHKeyPassphrasePath string +} + +type wolTarget struct { + Name string + MAC string +} + +type limitsFeature struct { + RemoteCmds []string + WolHosts []wolTarget +} + +type tomlConfig struct { + HTTP httpFeature `toml:"http"` + SSH sshFeature `toml:"ssh"` + Limits limitsFeature `toml:"limits"` +} + +func readConfig(path string) *tomlConfig { + var conf tomlConfig + _, err := toml.DecodeFile(path, &conf) + if err != nil { + log.Fatal(err) + } + + // log.Println(meta.Keys()) + + return &conf +} diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..ce35912 --- /dev/null +++ b/config.toml @@ -0,0 +1,18 @@ +[http] +port = 8082 +host = "localhost" + +[ssh] +sshKeyPath = "path/to/key/file" +sshKeyPassphrasePath = "path/to/key/passphrase" + +[limits] +remoteCmds = ["systemctl suspend"] + +# wolHosts = [ + # {name = "w00t", mac = "01:10:10:aa:bb:cc"}, +# ] + + [[limits.wolHosts]] + name = "w00t" + mac = "01:10:10:aa:bb:cc" diff --git a/flag.go b/flag.go new file mode 100644 index 0000000..e392d62 --- /dev/null +++ b/flag.go @@ -0,0 +1,5 @@ +package main + +import "flag" + +var configFlag = flag.String("config", "./config.toml", "path to config.toml file") diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9972e91 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module git.dotya.ml/wanderer/ctrl + +go 1.22.4 + +require github.com/BurntSushi/toml v1.4.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8bc10f6 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= diff --git a/main.go b/main.go new file mode 100644 index 0000000..c4f22d4 --- /dev/null +++ b/main.go @@ -0,0 +1,6 @@ +// ctrl let's me control aspects of functioning of my other devices - via SSH. +package main + +func main() { + run() +} diff --git a/run.go b/run.go new file mode 100644 index 0000000..bbcf788 --- /dev/null +++ b/run.go @@ -0,0 +1,93 @@ +package main + +import ( + "flag" + "log" + "net/http" + "os" + "os/signal" + "strconv" + "strings" + "syscall" +) + +var ( + port = 8081 + host = "localhost" +) + +const tmplDir = "templates" + +func run() { + log.Println("starting ctrl") + + flag.Parse() + + c := readConfig(*configFlag) + + if c.HTTP.Port > 0 { + port = c.HTTP.Port + } + log.Println("port:", port) + + if c.HTTP.Host != "" { + host = c.HTTP.Host + } + log.Println("host:", host) + + if len(c.Limits.RemoteCmds) != 0 { + log.Println("available cmmands:", c.Limits.RemoteCmds) + } else { + log.Println("no remote commands configured") + } + + if len(c.Limits.WolHosts) != 0 { + log.Println("configured WoL hosts:") + for _, w := range c.Limits.WolHosts { + log.Println("\tname:", w.Name, "mac:", w.MAC) + } + } else { + log.Println("no WoL hosts configured") + } + + log.Println("ssh key path:", c.SSH.SSHKeyPath) + log.Println("ssh key passphrase path:", c.SSH.SSHKeyPassphrasePath) + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + if r.Method != "GET" && r.Method != "POST" { + http.Error(w, "method is not supported.", http.StatusNotFound) + return + } + http.ServeFile(w, r, r.URL.Path[1:]) + }) + + done := make(chan os.Signal, 1) + + signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + log.Println("starting server on host:", host, "port:", port) + + go func() { + if err := http.ListenAndServe(strings.Join([]string{host, strconv.Itoa(port)}, ":"), nil); err != nil { + + log.Println("could not start server on port", port, "error", err) + + done <- nil + + } + }() + + log.Println("started server on port", port) + + <-done + + log.Println("stopping HTTP server") + + // ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + + // defer func() { cancel() }() + + // if err := h.Shutdown(ctx); err != nil && !errors.Is(err, http.ErrServerClosed) { + // log.Println("could not stop server", "error", err) + // } +}