~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
87 lines · 2.7 KB Raw History
package main

import (
	"context"
	"errors"
	"flag"
	"fmt"
	"log/slog"
	"os"
	"os/signal"
	"strings"
	"syscall"

	"github.com/johnandersen777/socialweb-computer-kcp/internal/guestagent"
	"github.com/johnandersen777/socialweb-computer-kcp/internal/notify"
)

func main() {
	os.Exit(run(os.Args[1:]))
}

func run(args []string) int {
	if len(args) > 0 && args[0] == "wait-secrets" {
		return waitSecrets(args[1:])
	}
	fs := flag.NewFlagSet("socialweb-guest-agent", flag.ContinueOnError)
	fs.SetOutput(os.Stderr)
	configDir := fs.String("config-dir", guestagent.DefaultConfigDir, "the directory of tunnels.json and bidder.json")
	stateDir := fs.String("state-dir", guestagent.DefaultStateDir, "the directory of the subscription cursor")
	login := fs.String("login", guestagent.DefaultLoginHelper, "the guest login helper that prints a token for an audience")
	level := fs.String("log-level", "info", "debug, info, warn or error")
	if err := fs.Parse(args); err != nil {
		if errors.Is(err, flag.ErrHelp) {
			return 0
		}
		return 2
	}
	var lvl slog.Level
	if err := lvl.UnmarshalText([]byte(strings.TrimSpace(*level))); err != nil {
		fmt.Fprintf(os.Stderr, "socialweb-guest-agent: -log-level %q: %v\n", *level, err)
		return 2
	}
	log := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: lvl}))
	cfg, err := guestagent.LoadConfig(*configDir, *stateDir, *login)
	if err != nil {
		log.Error("the guest agent config is invalid", "err", err.Error())
		return 1
	}
	agent, err := guestagent.New(cfg, log)
	if err != nil {
		log.Error("the guest agent cannot start", "err", err.Error())
		return 1
	}
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()
	ready := func() {
		if err := notify.Ready(); err != nil {
			log.Warn("sd_notify READY failed", "err", err.Error())
		}
	}
	if err := agent.Run(ctx, ready); err != nil {
		log.Error("the guest agent failed", "err", err.Error())
		return 1
	}
	return 0
}

func waitSecrets(args []string) int {
	fs := flag.NewFlagSet("socialweb-guest-agent wait-secrets", flag.ContinueOnError)
	fs.SetOutput(os.Stderr)
	stateDir := fs.String("state-dir", guestagent.DefaultStateDir, "the directory of secrets.ready")
	if err := fs.Parse(args); err != nil {
		if errors.Is(err, flag.ErrHelp) {
			return 0
		}
		return 2
	}
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()
	fmt.Fprintf(os.Stderr, "socialweb-guest-agent: waiting for %s/%s\n", *stateDir, guestagent.SecretsReadyFile)
	if err := guestagent.WaitSecrets(ctx, *stateDir); err != nil {
		fmt.Fprintf(os.Stderr, "socialweb-guest-agent: wait-secrets: %v\n", err)
		return 1
	}
	fmt.Fprintf(os.Stderr, "socialweb-guest-agent: the secrets are written\n")
	return 0
}