代码拉取完成,页面将自动刷新
package main
import (
"context"
"errors"
"fmt"
"gitee.com/anesec/chameleon/pkg/build"
"gitee.com/anesec/chameleon/pkg/daemon"
"gitee.com/anesec/chameleon/pkg/types"
"gitee.com/anesec/mobius"
"gitee.com/anesec/mobius/goroutine"
mtypes "gitee.com/anesec/mobius/types"
"github.com/derekhjray/rotatelogs"
"github.com/samber/lo"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"os"
"os/signal"
"path/filepath"
"runtime"
"sync"
"syscall"
"time"
)
type App struct {
cobra.Command
backend string
endpoint string
logFile string
logLevel string
version bool
help bool
}
func Run() {
app := &App{
Command: cobra.Command{
Use: "chameleond [options]",
Long: "Chameleond is a daemon service for chameleon engine schedule and management, Designed for ACES (Advance Cloud Environment Security)",
DisableFlagsInUseLine: true,
SilenceErrors: true,
SilenceUsage: true,
},
}
app.initialize()
if err := app.Execute(); err != nil {
if !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) {
log.Fatalf("Chameleond service exits with error, %v", err)
}
}
}
func (app *App) initialize() {
if home := os.Getenv(types.ChameleonHome); home == "" {
home = "/opt/chameleon"
_ = os.Setenv(types.ChameleonHome, home)
}
app.setupLogger()
app.RunE = app.run
app.addVersionCommand()
app.setUsageTemplate()
app.PersistentFlags().StringVar(&app.backend, "backend", "localhost:443", "specify remote backend address")
app.PersistentFlags().StringVar(&app.endpoint, "endpoint", "/run/chameleon/chameleon.sock", "specify chameleond local unix socket")
app.PersistentFlags().StringVar(&app.logFile, "log", "", "specify log file path")
app.PersistentFlags().StringVar(&app.logLevel, "level", "info", "specify log level, available levels: trace,debug,info,warn,fatal,panic")
app.PersistentFlags().BoolVarP(&app.version, "version", "v", false, "show chameleon version")
app.PersistentFlags().BoolVarP(&app.help, "help", "h", false, "show help info")
}
func (app *App) run(cmd *cobra.Command, _ []string) (err error) {
if app.version {
return app.showVersion()
}
if app.help {
return cmd.Help()
}
app.addLoggerFileHook()
mobius.SetProcTitle("chameleon: daemon")
var rc string
if build.Info.RC > 0 {
rc = fmt.Sprintf(", RC: %d", build.Info.RC)
}
log.Infof("Chameleond version: %s%s, Revision: %d, Git commit: %s, Mode: %s", build.Info.Version, rc, build.Info.Revision, build.Info.GitCommit, build.Info.BuildMode)
if err = app.setup(); err != nil {
return err
}
var wg sync.WaitGroup
wg.Add(1)
ctx, cancel := context.WithCancel(cmd.Context())
defer func() {
cancel()
wg.Wait()
}()
goroutine.Run(ctx, func(ctx context.Context) {
defer func() {
cancel()
wg.Done()
}()
if err = daemon.Run(ctx, daemon.Endpoint(app.endpoint)); err != nil && errors.Is(err, context.Canceled) {
err = nil
}
}, "chameleon::daemon")
app.processSignalEvents(ctx)
return
}
func (app *App) addVersionCommand() {
versionCmd := &cobra.Command{
Use: "version",
Short: "Show chameleon version",
Long: "Show chameleon version",
RunE: func(cmd *cobra.Command, args []string) error {
return app.showVersion()
},
DisableFlagsInUseLine: true,
SilenceErrors: true,
}
app.AddCommand(versionCmd)
}
func (app *App) processSignalEvents(ctx context.Context) {
var (
level log.Level
err error
)
signals := make(chan os.Signal)
signal.Notify(signals, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGINT, syscall.SIGHUP, syscall.SIGABRT, syscall.SIGSEGV, syscall.SIGUSR1)
defer close(signals)
if level, err = log.ParseLevel(os.Getenv(types.ChameleonLogLevel)); err != nil {
level = log.InfoLevel
}
defLevel := level
for {
select {
case <-ctx.Done():
return
case sig, ok := <-signals:
if !ok {
return
}
switch sig {
case syscall.SIGKILL, syscall.SIGINT, syscall.SIGHUP, syscall.SIGTERM:
log.Infof("Chameleond service stopped by signal %q", sig)
return
case syscall.SIGUSR1:
level = log.GetLevel()
if level < log.DebugLevel {
level = lo.Ternary(defLevel < log.DebugLevel, log.DebugLevel, defLevel)
} else {
level = lo.Ternary(defLevel < log.DebugLevel, defLevel, log.InfoLevel)
}
daemon.SetLogLevel(level)
log.SetLevel(level)
_ = os.Setenv(mtypes.LogLevel, level.String())
log.Infof("Chameleond service switches log level to %q", level)
}
}
}
}
func (app *App) showVersion() error {
fmt.Printf(`Advance Cloud Environment Security - Chameleond
Version: %s
RC: %d
Revision: %d
Git commit: %s
Go version: %s
Platform: %s/%s
Build: %s
Mode: %s
`, build.Info.Version, build.Info.RC, build.Info.Revision, build.Info.GitCommit, runtime.Version(), runtime.GOOS, runtime.GOARCH, build.Info.BuildDate.Local().Format("2006-01-02 15:04:05"), build.Info.BuildMode)
return nil
}
func (app *App) setup() (err error) {
home := os.Getenv(types.ChameleonHome)
if _, err = os.Stat(home); err != nil {
if err = os.MkdirAll(home, 0750); err != nil {
return fmt.Errorf("unable to create home directory, %w", err)
}
}
if backend := os.Getenv(types.ChameleonBackend); backend != "" {
app.backend = backend
}
if app.backend == "" {
return fmt.Errorf("no backend address specified")
}
_ = os.Setenv(types.ChameleonBackend, app.backend)
_ = os.Setenv(mtypes.AuthorizeURL, app.backend)
if procfs := os.Getenv(types.ChameleonHostProcfs); procfs == "" {
_ = os.Setenv(types.ChameleonHostProcfs, "/proc")
}
return nil
}
func (app *App) addLoggerFileHook() {
if app.logFile == "" {
app.logFile = filepath.Join(os.Getenv(types.ChameleonHome), "log/chameleon.log")
}
logPath := filepath.Dir(app.logFile)
if _, err := os.Stat(logPath); err != nil {
if err = os.MkdirAll(logPath, 0750); err != nil {
log.Fatalf("Chameleon service log directory could not be created, %v", err)
}
}
hook, err := rotatelogs.NewHook(filepath.Join(logPath, "chameleon.%Y%m%d"),
rotatelogs.WithLocation(time.Local),
rotatelogs.WithLinkName(app.logFile),
rotatelogs.WithRotationSize(50<<20),
rotatelogs.WithRotationTime(time.Hour*24*7),
rotatelogs.Compress(),
rotatelogs.WithRotationCount(5))
if err != nil {
log.Warnf("Create rotatelogs hook failed(%v), there will no logs persisted on disk", err)
return
}
log.AddHook(hook)
}
func (app *App) setupLogger() {
var (
level log.Level
err error
)
devTags := []string{"dev", "debug", "devel"}
if lo.Contains(devTags, os.Getenv(types.ChameleonBuildMode)) {
level = log.DebugLevel
} else {
if levelConfig := os.Getenv(types.ChameleonLogLevel); levelConfig == "" {
levelConfig = app.logLevel
}
if level, err = log.ParseLevel(app.logLevel); err != nil {
level = log.InfoLevel
}
}
log.SetLevel(level)
log.SetOutput(os.Stdout)
log.SetFormatter(rotatelogs.NewTextFormatter(false))
}
func (app *App) setUsageTemplate() {
app.SetUsageTemplate(`Usage: {{if .Runnable}}{{.UseLine}}{{end}} {{if gt (len .Aliases) 0}}
Aliases:
{{.NameAndAliases}}{{end}}{{if .HasExample}}
Examples:
{{.Example}}{{end}}{{if .HasAvailableSubCommands}}
Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}}
{{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}
Options:
{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}
Global Options:
{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}
Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
{{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}
Use "{{.CommandPath}} help [command]" for more information about a command.{{end}}
`)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。