package main import ( "bytes" "encoding/json" "flag" "fmt" "io" "mime/multipart" "net/http" "os" "os/exec" "path/filepath" "time" ) var version = "dev" // sätts av CI via -ldflags var exec_LookPath = exec.LookPath func main() { if len(os.Args) < 2 { usage() os.Exit(2) } switch os.Args[1] { case "serve": fs := flag.NewFlagSet("serve", flag.ExitOnError) listen := fs.String("listen", "", "override listen-adress (t.ex. 0.0.0.0:8788)") confPath := fs.String("config", configPath(), "sökväg till config.json") fs.Parse(os.Args[2:]) cfg, err := loadConfig(*confPath) if err != nil { fatal(err) } if *listen != "" { cfg.Listen = *listen } if err := serve(cfg); err != nil { fatal(err) } case "token": cfg, err := loadConfig(configPath()) if err != nil { fatal(err) } fmt.Println(cfg.Token) case "share": fs := flag.NewFlagSet("share", flag.ExitOnError) server := fs.String("server", "http://127.0.0.1:8788", "helmd-serverns adress") note := fs.String("note", "", "beskrivning som visas i klienten") session := fs.String("session", "", "session som delningen hör till") fs.Parse(os.Args[2:]) if fs.NArg() != 1 { fatal(fmt.Errorf("användning: helmd share [flaggor] ")) } cfg, err := loadConfig(configPath()) if err != nil { fatal(err) } id, err := shareFile(*server, cfg.Token, fs.Arg(0), *note, *session) if err != nil { fatal(err) } fmt.Printf("delad: %s (id %s)\n%s/api/shares/%s/raw\n", filepath.Base(fs.Arg(0)), id, *server, id) case "version", "--version", "-v": fmt.Println("helmd", version) default: usage() os.Exit(2) } } func usage() { fmt.Fprintln(os.Stderr, `helmd — agent-helm-server: styr en CLI-agent i tmux via REST-API användning: helmd serve [--listen host:port] [--config fil] starta servern helmd share [--note text] [--session namn] dela en fil till klienterna helmd token skriv ut API-token helmd version`) } func fatal(err error) { fmt.Fprintln(os.Stderr, "helmd:", err) os.Exit(1) } // shareFile uploads a file to a running helmd and returns the share id. func shareFile(server, token, path, note, session string) (string, error) { f, err := os.Open(path) if err != nil { return "", err } defer f.Close() var buf bytes.Buffer mw := multipart.NewWriter(&buf) fw, err := mw.CreateFormFile("file", filepath.Base(path)) if err != nil { return "", err } if _, err := io.Copy(fw, f); err != nil { return "", err } mw.WriteField("note", note) mw.WriteField("session", session) mw.Close() req, err := http.NewRequest("POST", server+"/api/shares", &buf) if err != nil { return "", err } req.Header.Set("Content-Type", mw.FormDataContentType()) req.Header.Set("Authorization", "Bearer "+token) client := &http.Client{Timeout: 60 * time.Second} resp, err := client.Do(req) if err != nil { return "", err } defer resp.Body.Close() body, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) if resp.StatusCode >= 300 { return "", fmt.Errorf("servern svarade %s: %s", resp.Status, bytes.TrimSpace(body)) } var out struct { ID string `json:"id"` } if err := json.Unmarshal(body, &out); err != nil { return "", err } return out.ID, nil }