2022-10-20 19:59:46 +00:00
|
|
|
package main
|
2021-04-20 21:31:37 +00:00
|
|
|
|
|
|
|
import (
|
2022-10-26 22:37:03 +00:00
|
|
|
"context"
|
2024-11-14 20:49:35 +00:00
|
|
|
"fmt"
|
2024-12-09 17:09:45 +00:00
|
|
|
"isle/toolkit"
|
2021-04-20 21:31:37 +00:00
|
|
|
"os"
|
2022-10-26 22:37:03 +00:00
|
|
|
"os/signal"
|
|
|
|
"path/filepath"
|
2024-12-09 17:09:45 +00:00
|
|
|
"sync"
|
2022-10-26 22:37:03 +00:00
|
|
|
"syscall"
|
2021-04-20 21:31:37 +00:00
|
|
|
|
2024-06-22 15:49:56 +00:00
|
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mctx"
|
|
|
|
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
|
2024-12-09 17:09:45 +00:00
|
|
|
"github.com/adrg/xdg"
|
2021-04-20 21:31:37 +00:00
|
|
|
)
|
|
|
|
|
2022-10-26 22:37:03 +00:00
|
|
|
func getAppDirPath() string {
|
|
|
|
appDirPath := os.Getenv("APPDIR")
|
|
|
|
if appDirPath == "" {
|
|
|
|
appDirPath = "."
|
|
|
|
}
|
|
|
|
return appDirPath
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
2024-06-24 12:45:57 +00:00
|
|
|
envAppDirPath = getAppDirPath()
|
2024-06-17 18:51:02 +00:00
|
|
|
envBinDirPath = filepath.Join(envAppDirPath, "bin")
|
2024-12-09 17:09:45 +00:00
|
|
|
envCacheDir = sync.OnceValue(func() toolkit.Dir {
|
|
|
|
cacheHome, err := toolkit.MkDir(xdg.CacheHome, true)
|
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Errorf("creating cache directory %q: %w", xdg.CacheHome, err))
|
|
|
|
}
|
|
|
|
|
|
|
|
cacheDir, err := cacheHome.MkChildDir("isle", true)
|
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Errorf("creating isle cache directory: %w", err))
|
|
|
|
}
|
|
|
|
|
|
|
|
return cacheDir
|
|
|
|
})
|
2022-10-26 22:37:03 +00:00
|
|
|
)
|
|
|
|
|
2023-04-23 14:30:47 +00:00
|
|
|
func binPath(name string) string {
|
2024-06-17 18:51:02 +00:00
|
|
|
return filepath.Join(envBinDirPath, name)
|
2023-04-23 14:30:47 +00:00
|
|
|
}
|
|
|
|
|
2024-11-14 20:49:35 +00:00
|
|
|
var rootCmd = subCmd{
|
2024-12-10 21:07:25 +00:00
|
|
|
name: "isle",
|
|
|
|
descr: "All Isle sub-commands",
|
2024-11-14 20:49:35 +00:00
|
|
|
do: func(ctx subCmdCtx) error {
|
|
|
|
return ctx.doSubCmd(
|
|
|
|
subCmdDaemon,
|
|
|
|
subCmdGarage,
|
|
|
|
subCmdHost,
|
|
|
|
subCmdNetwork,
|
|
|
|
subCmdStorage,
|
|
|
|
subCmdVersion,
|
2024-12-08 15:59:01 +00:00
|
|
|
subCmdVPN,
|
2024-11-14 20:49:35 +00:00
|
|
|
)
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
func doRootCmd(
|
|
|
|
ctx context.Context,
|
|
|
|
logger *mlog.Logger,
|
|
|
|
opts *subCmdCtxOpts,
|
|
|
|
) error {
|
2024-12-16 13:59:11 +00:00
|
|
|
subCmdCtx := newSubCmdCtx(ctx, logger, rootCmd, opts)
|
2024-11-14 20:49:35 +00:00
|
|
|
return subCmdCtx.subCmd.do(subCmdCtx)
|
|
|
|
}
|
|
|
|
|
2022-10-20 19:59:46 +00:00
|
|
|
func main() {
|
2024-11-09 16:08:39 +00:00
|
|
|
logger := mlog.NewLogger(nil)
|
2022-11-13 15:45:42 +00:00
|
|
|
defer logger.Close()
|
|
|
|
|
2022-10-26 22:37:03 +00:00
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
|
|
|
|
signalCh := make(chan os.Signal, 2)
|
|
|
|
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
sig := <-signalCh
|
|
|
|
cancel()
|
2022-11-13 15:45:42 +00:00
|
|
|
|
|
|
|
ctx := mctx.Annotate(ctx, "signal", sig.String())
|
|
|
|
logger.Info(ctx, "got signal, exiting gracefully")
|
2022-10-26 22:37:03 +00:00
|
|
|
|
|
|
|
sig = <-signalCh
|
|
|
|
|
2022-11-13 15:45:42 +00:00
|
|
|
ctx = mctx.Annotate(ctx, "signal", sig.String())
|
|
|
|
logger.FatalString(ctx, "second signal received, force quitting, there may be zombie children left behind, good luck!")
|
2022-10-26 22:37:03 +00:00
|
|
|
}()
|
2021-04-20 21:31:37 +00:00
|
|
|
|
2024-12-16 13:59:11 +00:00
|
|
|
if err := doRootCmd(ctx, logger, nil); err != nil {
|
2024-11-14 20:49:35 +00:00
|
|
|
fmt.Fprintln(os.Stderr, err)
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
}
|