You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
1.5 KiB
Go

package main
import (
"context"
"log"
"net/http"
"os/exec"
"sync"
flag "github.com/spf13/pflag"
)
type State int
const (
Running State = iota
Ready
)
type Worker struct {
status State
mx *sync.Mutex
}
var (
command = flag.String("command", "", "command to execute")
args = flag.StringSlice("args", []string{}, "arguments to pass to command")
)
func (w *Worker) Start(ctx context.Context) ([]byte, error) {
w.mx.Lock()
defer w.mx.Unlock()
w.status = Running
defer w.SetTerminated()
o, err := exec.CommandContext(ctx, *command, *args...).Output()
if err != nil {
return nil, err
}
return o, nil
}
func (w *Worker) SetTerminated() {
w.status = Ready
}
func (w *Worker) Status() string {
switch w.status {
case Running:
return "running"
default:
return "ready"
}
}
func main() {
flag.Parse()
if *command == "" {
log.Fatalln("Please provide command")
}
worker := &Worker{
status: Ready,
mx: &sync.Mutex{},
}
mux := http.NewServeMux()
mux.HandleFunc("/start", func(w http.ResponseWriter, r *http.Request) {
if worker.status == Running {
http.Error(w, "target is busy", http.StatusServiceUnavailable)
return
}
o, err := worker.Start(r.Context())
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Write(o)
return
})
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(worker.Status()))
return
})
http.ListenAndServe(":8080", mux)
}