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"
|
2021-04-20 21:31:37 +00:00
|
|
|
"os"
|
2022-10-26 22:37:03 +00:00
|
|
|
"os/signal"
|
|
|
|
"path/filepath"
|
|
|
|
"syscall"
|
2021-04-20 21:31:37 +00:00
|
|
|
|
2022-10-26 22:37:03 +00:00
|
|
|
"github.com/adrg/xdg"
|
2022-11-13 15:45:42 +00:00
|
|
|
"github.com/mediocregopher/mediocre-go-lib/v2/mctx"
|
|
|
|
"github.com/mediocregopher/mediocre-go-lib/v2/mlog"
|
2021-04-20 21:31:37 +00:00
|
|
|
)
|
|
|
|
|
2023-08-05 21:53:17 +00:00
|
|
|
// The purpose of this binary is to act as the entrypoint of the isle
|
2021-04-20 21:31:37 +00:00
|
|
|
// process. It processes the command-line arguments which are passed in, and
|
|
|
|
// then passes execution along to an appropriate binary housed in AppDir/bin
|
|
|
|
// (usually a bash script, which is more versatile than a go program).
|
|
|
|
|
2022-10-26 22:37:03 +00:00
|
|
|
func getAppDirPath() string {
|
|
|
|
appDirPath := os.Getenv("APPDIR")
|
|
|
|
if appDirPath == "" {
|
|
|
|
appDirPath = "."
|
|
|
|
}
|
|
|
|
return appDirPath
|
|
|
|
}
|
|
|
|
|
2024-06-16 21:25:23 +00:00
|
|
|
func envOr(name, fallback string) string {
|
|
|
|
if v := os.Getenv(name); v != "" {
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
return fallback
|
|
|
|
}
|
|
|
|
|
|
|
|
// RUNTIME_DIRECTORY/STATE_DIRECTORY are used by the systemd service in
|
|
|
|
// conjunction with the RuntimeDirectory/StateDirectory directives.
|
2022-10-26 22:37:03 +00:00
|
|
|
var (
|
|
|
|
envAppDirPath = getAppDirPath()
|
2024-06-16 21:25:23 +00:00
|
|
|
envRuntimeDirPath = envOr(
|
|
|
|
"RUNTIME_DIRECTORY",
|
|
|
|
filepath.Join(xdg.RuntimeDir, "isle"),
|
|
|
|
)
|
|
|
|
envStateDirPath = envOr(
|
|
|
|
"STATE_DIRECTORY",
|
|
|
|
filepath.Join(xdg.StateHome, "isle"),
|
|
|
|
)
|
2024-06-17 18:51:02 +00:00
|
|
|
envBinDirPath = filepath.Join(envAppDirPath, "bin")
|
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
|
|
|
}
|
|
|
|
|
2022-10-20 19:59:46 +00:00
|
|
|
func main() {
|
2021-04-20 21:31:37 +00:00
|
|
|
|
2022-11-13 15:45:42 +00:00
|
|
|
logger := mlog.NewLogger(&mlog.LoggerOpts{
|
|
|
|
MessageHandler: newLogMsgHandler(),
|
|
|
|
MaxLevel: mlog.LevelInfo.Int(),
|
|
|
|
})
|
|
|
|
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
|
|
|
|
2022-10-26 22:23:39 +00:00
|
|
|
err := subCmdCtx{
|
2022-11-13 15:45:42 +00:00
|
|
|
args: os.Args[1:],
|
|
|
|
ctx: ctx,
|
|
|
|
logger: logger,
|
2021-04-20 21:31:37 +00:00
|
|
|
}.doSubCmd(
|
2022-10-16 15:18:50 +00:00
|
|
|
subCmdAdmin,
|
2021-04-20 21:31:37 +00:00
|
|
|
subCmdDaemon,
|
|
|
|
subCmdGarage,
|
2022-10-16 15:18:50 +00:00
|
|
|
subCmdHosts,
|
2023-08-27 14:09:03 +00:00
|
|
|
subCmdNebula,
|
2021-04-20 21:31:37 +00:00
|
|
|
subCmdVersion,
|
|
|
|
)
|
|
|
|
|
|
|
|
if err != nil {
|
2022-11-13 15:45:42 +00:00
|
|
|
logger.Fatal(ctx, "error running command", err)
|
2021-04-20 21:31:37 +00:00
|
|
|
}
|
|
|
|
}
|