shark expose: put a local port on the internet through Hammerhead

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
VeillaxandClaude Sonnet 5.5 committed 2026-10-27 17:00:53 -06:00
commit 61143d107c
15 files changed
+1538

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
// Package config keeps the Hammerhead address and token between runs.
package config
import (
"encoding/json"
"errors"
"os"
"path/filepath"
"strings"
)
type Config struct {
Hammerhead string `json:"hammerhead"`
Token string `json:"token"`
}
// Path is where `shark login` saves the settings; SHARK_CONFIG overrides it.
func Path() (string, error) {
if p := os.Getenv("SHARK_CONFIG"); p != "" {
return p, nil
}
dir, err := os.UserConfigDir()
if err != nil {
return "", err
}
return filepath.Join(dir, "shark", "config.json"), nil
}
// Load reads the saved settings, then lets SHARK_HAMMERHEAD and SHARK_TOKEN override them.
// A missing file is not an error.
func Load() (Config, error) {
var c Config
p, err := Path()
if err == nil {
b, rerr := os.ReadFile(p)
switch {
case rerr == nil:
if err := json.Unmarshal(b, &c); err != nil {
return c, errors.New(p + " is not valid JSON: " + err.Error())
}
case !errors.Is(rerr, os.ErrNotExist):
return c, rerr
}
}
if v := os.Getenv("SHARK_HAMMERHEAD"); v != "" {
c.Hammerhead = v
}
if v := os.Getenv("SHARK_TOKEN"); v != "" {
c.Token = v
}
c.Hammerhead = strings.TrimRight(c.Hammerhead, "/")
return c, nil
}
// Save writes the settings so that only the user can read them (the token is a credential).
func Save(c Config) (string, error) {
p, err := Path()
if err != nil {
return "", err
}
if err := os.MkdirAll(filepath.Dir(p), 0o700); err != nil {
return "", err
}
b, _ := json.MarshalIndent(c, "", " ")
return p, os.WriteFile(p, append(b, '\n'), 0o600)
}