1
0
out-of-tree/main.go

189 lines
4.9 KiB
Go
Raw Permalink Normal View History

2023-01-31 07:13:33 +00:00
// Copyright 2023 Mikhail Klementev. All rights reserved.
2018-10-08 20:51:32 +00:00
// Use of this source code is governed by a AGPLv3 license
// (or later) that can be found in the LICENSE file.
package main
import (
2018-12-10 02:51:15 +00:00
"fmt"
2023-03-18 21:30:07 +00:00
"os"
"os/exec"
"runtime"
2023-04-06 12:50:44 +00:00
"runtime/debug"
"strings"
2023-04-06 17:32:42 +00:00
"github.com/natefinch/lumberjack"
2023-03-18 21:30:07 +00:00
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
2023-01-31 07:13:33 +00:00
"github.com/alecthomas/kong"
2018-11-17 20:18:50 +00:00
_ "code.dumpstack.io/tools/out-of-tree/distro/centos"
_ "code.dumpstack.io/tools/out-of-tree/distro/debian"
2023-06-15 15:24:29 +00:00
_ "code.dumpstack.io/tools/out-of-tree/distro/opensuse"
_ "code.dumpstack.io/tools/out-of-tree/distro/oraclelinux"
_ "code.dumpstack.io/tools/out-of-tree/distro/ubuntu"
2023-05-13 10:46:43 +00:00
"code.dumpstack.io/tools/out-of-tree/cache"
2024-02-17 22:38:43 +00:00
"code.dumpstack.io/tools/out-of-tree/cmd"
2024-02-20 13:25:31 +00:00
"code.dumpstack.io/tools/out-of-tree/config/dotfiles"
"code.dumpstack.io/tools/out-of-tree/container"
"code.dumpstack.io/tools/out-of-tree/fs"
)
2023-01-31 07:13:33 +00:00
type CLI struct {
2024-02-17 22:38:43 +00:00
cmd.Globals
Pew cmd.PewCmd `cmd:"" help:"build, run, and test module/exploit"`
2024-10-06 15:34:14 +00:00
Kernel cmd.KernelCmd `cmd:"" aliases:"kernels" help:"manipulate kernels"`
2024-02-17 22:38:43 +00:00
Debug cmd.DebugCmd `cmd:"" help:"debug environment"`
Log cmd.LogCmd `cmd:"" help:"query logs"`
Pack cmd.PackCmd `cmd:"" help:"exploit pack test"`
Gen cmd.GenCmd `cmd:"" help:"generate .out-of-tree.toml skeleton"`
2024-10-06 15:34:14 +00:00
Image cmd.ImageCmd `cmd:"" aliases:"images" help:"manage images"`
Container cmd.ContainerCmd `cmd:"" aliases:"containers" help:"manage containers"`
2024-02-17 22:38:43 +00:00
Distro cmd.DistroCmd `cmd:"" help:"distro-related helpers"`
2024-02-20 13:25:31 +00:00
Daemon cmd.DaemonCmd `cmd:"" help:"run daemon"`
2023-01-31 07:13:33 +00:00
Version VersionFlag `name:"version" help:"print version information and quit"`
2023-03-18 21:53:53 +00:00
2023-04-06 18:00:46 +00:00
LogLevel LogLevelFlag `enum:"trace,debug,info,warn,error" default:"info"`
ContainerRuntime string `enum:"podman,docker" default:"podman"`
2023-03-18 21:53:53 +00:00
}
func last(s []string) string {
return s[len(s)-1]
}
func debugLevel(pc uintptr, file string, line int) string {
function := runtime.FuncForPC(pc).Name()
if strings.Contains(function, ".") {
function = last(strings.Split(function, "."))
}
return function
}
func traceLevel(pc uintptr, file string, line int) string {
function := runtime.FuncForPC(pc).Name()
if strings.Contains(function, "/") {
function = last(strings.Split(function, "/"))
}
return fmt.Sprintf("%s:%s:%d", file, function, line)
}
2023-03-18 21:53:53 +00:00
type LogLevelFlag string
func (loglevel LogLevelFlag) AfterApply() error {
switch loglevel {
case "debug":
zerolog.CallerMarshalFunc = debugLevel
log.Logger = log.With().Caller().Logger()
case "trace":
zerolog.CallerMarshalFunc = traceLevel
log.Logger = log.With().Caller().Logger()
2023-03-18 21:53:53 +00:00
}
return nil
}
2023-01-31 07:13:33 +00:00
type VersionFlag string
2018-12-10 02:51:15 +00:00
2023-01-31 07:13:33 +00:00
func (v VersionFlag) Decode(ctx *kong.DecodeContext) error { return nil }
func (v VersionFlag) IsBool() bool { return true }
func (v VersionFlag) BeforeApply(app *kong.Kong, vars kong.Vars) error {
fmt.Println(vars["version"])
app.Exit(0)
return nil
}
2023-04-06 17:32:42 +00:00
func main() {
2023-01-31 07:13:33 +00:00
cli := CLI{}
ctx := kong.Parse(&cli,
kong.Name("out-of-tree"),
kong.Description("kernel {module, exploit} development tool"),
kong.UsageOnError(),
kong.ConfigureHelp(kong.HelpOptions{
Compact: true,
}),
kong.Vars{
2023-04-26 14:36:25 +00:00
"version": "2.1.2",
2023-01-31 07:13:33 +00:00
},
2018-10-27 08:14:10 +00:00
)
2023-04-06 17:32:42 +00:00
switch cli.LogLevel {
2023-04-06 18:00:46 +00:00
case "trace":
2024-02-17 22:38:43 +00:00
cmd.LogLevel = zerolog.TraceLevel
2023-04-06 17:32:42 +00:00
case "debug":
2024-02-17 22:38:43 +00:00
cmd.LogLevel = zerolog.DebugLevel
2023-04-06 17:32:42 +00:00
case "info":
2024-02-17 22:38:43 +00:00
cmd.LogLevel = zerolog.InfoLevel
2023-04-06 17:32:42 +00:00
case "warn":
2024-02-17 22:38:43 +00:00
cmd.LogLevel = zerolog.WarnLevel
2023-04-06 17:32:42 +00:00
case "error":
2024-02-17 22:38:43 +00:00
cmd.LogLevel = zerolog.ErrorLevel
2023-04-06 17:32:42 +00:00
}
2024-02-17 22:38:43 +00:00
cmd.ConsoleWriter = cmd.LevelWriter{Writer: zerolog.NewConsoleWriter(
func(w *zerolog.ConsoleWriter) {
w.Out = os.Stderr
2023-04-06 17:32:42 +00:00
},
),
2024-02-17 22:38:43 +00:00
Level: cmd.LogLevel,
}
2024-02-17 22:38:43 +00:00
cmd.FileWriter = cmd.LevelWriter{Writer: &lumberjack.Logger{
2024-02-20 13:25:31 +00:00
Filename: dotfiles.File("logs/out-of-tree.log"),
},
Level: zerolog.TraceLevel,
}
log.Logger = log.Output(zerolog.MultiLevelWriter(
2024-02-17 22:38:43 +00:00
&cmd.ConsoleWriter,
&cmd.FileWriter,
2023-04-06 17:32:42 +00:00
))
2023-04-06 18:13:56 +00:00
log.Trace().Msg("start out-of-tree")
2023-04-06 17:32:42 +00:00
log.Debug().Msgf("%v", os.Args)
log.Debug().Msgf("%v", cli)
2023-04-06 12:50:44 +00:00
if buildInfo, ok := debug.ReadBuildInfo(); ok {
log.Debug().Msgf("%v", buildInfo.GoVersion)
log.Debug().Msgf("%v", buildInfo.Settings)
}
2024-02-20 13:25:31 +00:00
path := dotfiles.Dir()
yes, err := fs.CaseInsensitive(path)
2023-05-11 02:42:34 +00:00
if err != nil {
log.Fatal().Err(err).Msg(path)
}
if yes {
log.Warn().Msg("case-insensitive file system not supported")
}
_, err = exec.LookPath(cli.ContainerRuntime)
if err != nil {
if cli.ContainerRuntime == "podman" { // default value
log.Debug().Msgf("podman is not found in $PATH, " +
"fall back to docker")
cli.ContainerRuntime = "docker"
}
_, err = exec.LookPath(cli.ContainerRuntime)
if err != nil {
log.Fatal().Msgf("%v is not found in $PATH",
cli.ContainerRuntime)
}
}
container.Runtime = cli.ContainerRuntime
if cli.Globals.CacheURL.String() != "" {
cache.URL = cli.Globals.CacheURL.String()
}
log.Debug().Msgf("set cache url to %s", cache.URL)
2023-05-13 10:46:43 +00:00
2023-04-06 17:32:42 +00:00
err = ctx.Run(&cli.Globals)
2023-01-31 07:13:33 +00:00
ctx.FatalIfErrorf(err)
}