mirror of
https://github.com/Walter-Sparrow/lunar-tear.git
synced 2026-07-02 05:43:41 +03:00
Add authentication server, dev CLI, Docker multi-service setup, and cross-platform improvements
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
//go:build !windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
func colorSupported() bool {
|
||||
return term.IsTerminal(int(os.Stdout.Fd()))
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
//go:build windows
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
func colorSupported() bool {
|
||||
fd := os.Stdout.Fd()
|
||||
if !term.IsTerminal(int(fd)) {
|
||||
return false
|
||||
}
|
||||
var mode uint32
|
||||
if windows.GetConsoleMode(windows.Handle(fd), &mode) != nil {
|
||||
return false
|
||||
}
|
||||
return windows.SetConsoleMode(windows.Handle(fd), mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) == nil
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
var (
|
||||
colorReset = "\033[0m"
|
||||
colorRed = "\033[31m"
|
||||
colorGreen = "\033[32m"
|
||||
colorYellow = "\033[33m"
|
||||
colorCyan = "\033[36m"
|
||||
)
|
||||
|
||||
type service struct {
|
||||
label string
|
||||
color string
|
||||
cmd *exec.Cmd
|
||||
}
|
||||
|
||||
func main() {
|
||||
// auth-server flags
|
||||
authListen := flag.String("auth.listen", "0.0.0.0:3000", "auth-server listen address (host:port)")
|
||||
authDB := flag.String("auth.db", "db/auth.db", "auth-server SQLite database path")
|
||||
|
||||
// octo-cdn flags
|
||||
cdnListen := flag.String("cdn.listen", "0.0.0.0:8080", "octo-cdn local bind address")
|
||||
cdnPublicAddr := flag.String("cdn.public-addr", "10.0.2.2:8080", "octo-cdn externally-reachable address")
|
||||
|
||||
// lunar-tear (grpc) flags
|
||||
grpcListen := flag.String("grpc.listen", "0.0.0.0:8003", "lunar-tear gRPC listen address (host:port)")
|
||||
grpcPublicAddr := flag.String("grpc.public-addr", "10.0.2.2:8003", "lunar-tear externally-reachable address")
|
||||
grpcOctoURL := flag.String("grpc.octo-url", "", "Octo CDN base URL passed to lunar-tear (default: derived from cdn.public-addr)")
|
||||
grpcAuthURL := flag.String("grpc.auth-url", "", "auth server base URL passed to lunar-tear (default: derived from auth.listen)")
|
||||
|
||||
noColor := flag.Bool("no-color", false, "disable colored output")
|
||||
flag.Parse()
|
||||
|
||||
if *grpcOctoURL == "" {
|
||||
*grpcOctoURL = fmt.Sprintf("http://%s", *cdnPublicAddr)
|
||||
}
|
||||
if *grpcAuthURL == "" {
|
||||
*grpcAuthURL = fmt.Sprintf("http://%s", *authListen)
|
||||
}
|
||||
|
||||
if *noColor || !colorSupported() {
|
||||
colorReset = ""
|
||||
colorRed = ""
|
||||
colorGreen = ""
|
||||
colorYellow = ""
|
||||
colorCyan = ""
|
||||
}
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
services := []service{
|
||||
{
|
||||
label: "auth",
|
||||
color: colorGreen,
|
||||
cmd: exec.CommandContext(ctx, "go", "run", "./cmd/auth-server",
|
||||
"--listen", *authListen,
|
||||
"--db", *authDB,
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "cdn",
|
||||
color: colorCyan,
|
||||
cmd: exec.CommandContext(ctx, "go", "run", "./cmd/octo-cdn",
|
||||
"--listen", *cdnListen,
|
||||
"--public-addr", *cdnPublicAddr,
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "grpc",
|
||||
color: colorYellow,
|
||||
cmd: exec.CommandContext(ctx, "go", "run", "./cmd/lunar-tear",
|
||||
"--listen", *grpcListen,
|
||||
"--public-addr", *grpcPublicAddr,
|
||||
"--octo-url", *grpcOctoURL,
|
||||
"--auth-url", *grpcAuthURL,
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
errCh := make(chan error, len(services))
|
||||
|
||||
for i := range services {
|
||||
svc := &services[i]
|
||||
stdout, err := svc.cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
log.Fatalf("[%s] stdout pipe: %v", svc.label, err)
|
||||
}
|
||||
stderr, err := svc.cmd.StderrPipe()
|
||||
if err != nil {
|
||||
log.Fatalf("[%s] stderr pipe: %v", svc.label, err)
|
||||
}
|
||||
|
||||
if err := svc.cmd.Start(); err != nil {
|
||||
log.Fatalf("[%s] start: %v", svc.label, err)
|
||||
}
|
||||
|
||||
prefix := fmt.Sprintf("%s[%s]%s ", svc.color, svc.label, colorReset)
|
||||
wg.Add(2)
|
||||
go prefixLines(&wg, prefix, stdout)
|
||||
go prefixLines(&wg, prefix, stderr)
|
||||
|
||||
wg.Add(1)
|
||||
go func(s *service) {
|
||||
defer wg.Done()
|
||||
if err := s.cmd.Wait(); err != nil {
|
||||
errCh <- fmt.Errorf("[%s] %w", s.label, err)
|
||||
}
|
||||
}(svc)
|
||||
|
||||
log.Printf("%s%s started (pid %d)%s", svc.color, svc.label, svc.cmd.Process.Pid, colorReset)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Println("shutting down all services...")
|
||||
case err := <-errCh:
|
||||
log.Printf("%s%s%s", colorRed, err, colorReset)
|
||||
stop()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func prefixLines(wg *sync.WaitGroup, prefix string, r io.Reader) {
|
||||
defer wg.Done()
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
fmt.Printf("%s%s\n", prefix, scanner.Text())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user