From 030a6d95164bb40ee93fda856d8f0e249f1664ba Mon Sep 17 00:00:00 2001 From: Samuel N Cui Date: Fri, 6 Oct 2023 09:04:10 +0800 Subject: [PATCH] feat: add export library --- build.sh | 2 +- build_backend.sh | 1 + cmd/export-library/main.go | 97 +++++++++++++++++++ cmd/httpd/main.go | 30 +----- ...config.example.yaml => config.example.yaml | 0 config/config.go | 40 ++++++++ entity/utils.go | 10 ++ 7 files changed, 152 insertions(+), 28 deletions(-) create mode 100644 cmd/export-library/main.go rename cmd/httpd/config.example.yaml => config.example.yaml (100%) create mode 100644 config/config.go diff --git a/build.sh b/build.sh index 3101b6d..bf4f02a 100755 --- a/build.sh +++ b/build.sh @@ -12,7 +12,7 @@ mkdir -p output/captured_indices; cp -r scripts ./output/; cp ./cmd/httpd/yatm-httpd.service ./output/ -cp ./cmd/httpd/config.example.yaml ./output/ +cp ./config.example.yaml ./output/ cp ./LICENSE ./output/ cp ./README.md ./output/ echo "${RELEASE_VERSION}" > ./output/VERSION diff --git a/build_backend.sh b/build_backend.sh index 8297cf6..2dc0b59 100755 --- a/build_backend.sh +++ b/build_backend.sh @@ -5,4 +5,5 @@ CURDIR=$(cd $(dirname $0); pwd); cd ${CURDIR}; go build -o ./output/yatm-httpd ./cmd/httpd; +go build -o ./output/yatm-export-library ./cmd/export-library; go build -o ./output/yatm-lto-info ./cmd/lto-info; diff --git a/cmd/export-library/main.go b/cmd/export-library/main.go new file mode 100644 index 0000000..8547e1d --- /dev/null +++ b/cmd/export-library/main.go @@ -0,0 +1,97 @@ +package main + +import ( + "context" + "flag" + "fmt" + "io" + "os" + "strings" + "time" + + rotatelogs "github.com/lestrrat-go/file-rotatelogs" + "github.com/rifflock/lfshook" + "github.com/samuelncui/yatm/config" + "github.com/samuelncui/yatm/entity" + "github.com/samuelncui/yatm/library" + "github.com/samuelncui/yatm/resource" + "github.com/sirupsen/logrus" +) + +var ( + configOpt = flag.String("config", "./config.yaml", "config file path") + typesOpt = flag.String("types", "file,tape,position", "types wants to be exported") + outputOpt = flag.String("output", "stdout", "output file path, default use stdout") +) + +func main() { + ctx := context.Background() + + logWriter, err := rotatelogs.New( + "./run.log.%Y%m%d%H%M", + rotatelogs.WithLinkName("./run.log"), + rotatelogs.WithMaxAge(time.Duration(86400)*time.Second), + rotatelogs.WithRotationTime(time.Duration(604800)*time.Second), + ) + if err != nil { + panic(err) + } + logrus.AddHook(lfshook.NewHook( + lfshook.WriterMap{ + logrus.InfoLevel: logWriter, + logrus.ErrorLevel: logWriter, + }, + &logrus.TextFormatter{}, + )) + + flag.Parse() + conf := config.GetConfig(*configOpt) + + db, err := resource.NewDBConn(conf.Database.Dialect, conf.Database.DSN) + if err != nil { + panic(err) + } + + lib := library.New(db) + if err := lib.AutoMigrate(); err != nil { + panic(err) + } + + parts := strings.Split(*typesOpt, ",") + + toEnum := entity.ToEnum(entity.LibraryEntityType_value, entity.LibraryEntityType_NONE) + types := make([]entity.LibraryEntityType, 0, len(parts)) + for _, part := range parts { + e := toEnum(strings.ToUpper(strings.TrimSpace(part))) + if e == entity.LibraryEntityType_NONE { + continue + } + + types = append(types, e) + } + if len(types) == 0 { + panic(fmt.Errorf("cannot found types, use 'types' option to specify at least one type")) + } + + jsonBuf, err := lib.Export(ctx, types) + if err != nil { + panic(fmt.Errorf("export json fail, %w", err)) + } + + f := func() io.WriteCloser { + if *outputOpt == "stdout" { + return os.Stdout + } + + f, err := os.Create(*outputOpt) + if err != nil { + panic(fmt.Errorf("open output file fail, path= '%s', %w", *outputOpt, err)) + } + return f + }() + + defer f.Close() + if _, err := f.Write(jsonBuf); err != nil { + panic(fmt.Errorf("write output file fail, %w", err)) + } +} diff --git a/cmd/httpd/main.go b/cmd/httpd/main.go index cb5a968..c8f149e 100644 --- a/cmd/httpd/main.go +++ b/cmd/httpd/main.go @@ -16,6 +16,7 @@ import ( rotatelogs "github.com/lestrrat-go/file-rotatelogs" "github.com/rifflock/lfshook" "github.com/samuelncui/yatm/apis" + "github.com/samuelncui/yatm/config" "github.com/samuelncui/yatm/entity" "github.com/samuelncui/yatm/executor" "github.com/samuelncui/yatm/library" @@ -25,26 +26,10 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "gopkg.in/yaml.v2" ) -type config struct { - Domain string `yaml:"domain"` - Listen string `yaml:"listen"` - DebugListen string `yaml:"debug_listen"` - - Database struct { - Dialect string `yaml:"dialect"` - DSN string `yaml:"dsn"` - } `yaml:"database"` - - Paths executor.Paths `yaml:"paths"` - TapeDevices []string `yaml:"tape_devices"` - Scripts executor.Scripts `yaml:"scripts"` -} - var ( - configPath = flag.String("config", "./config.yaml", "config file path") + configOpt = flag.String("config", "./config.yaml", "config file path") ) func main() { @@ -66,16 +51,7 @@ func main() { )) flag.Parse() - cf, err := os.Open(*configPath) - if err != nil { - panic(err) - } - - conf := new(config) - if err := yaml.NewDecoder(cf).Decode(conf); err != nil { - panic(err) - } - logrus.Infof("read config success, conf= '%+v'", conf) + conf := config.GetConfig(*configOpt) if conf.DebugListen != "" { go tools.Wrap(context.Background(), func() { tools.NewDebugServer(conf.DebugListen) }) diff --git a/cmd/httpd/config.example.yaml b/config.example.yaml similarity index 100% rename from cmd/httpd/config.example.yaml rename to config.example.yaml diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..01ce120 --- /dev/null +++ b/config/config.go @@ -0,0 +1,40 @@ +package config + +import ( + "fmt" + "os" + + "github.com/samuelncui/yatm/executor" + "github.com/sirupsen/logrus" + "gopkg.in/yaml.v2" +) + +type Config struct { + Domain string `yaml:"domain"` + Listen string `yaml:"listen"` + DebugListen string `yaml:"debug_listen"` + + Database struct { + Dialect string `yaml:"dialect"` + DSN string `yaml:"dsn"` + } `yaml:"database"` + + Paths executor.Paths `yaml:"paths"` + TapeDevices []string `yaml:"tape_devices"` + Scripts executor.Scripts `yaml:"scripts"` +} + +func GetConfig(path string) *Config { + cf, err := os.Open(path) + if err != nil { + panic(fmt.Errorf("open config file failed, %w", err)) + } + + conf := new(Config) + if err := yaml.NewDecoder(cf).Decode(conf); err != nil { + panic(fmt.Errorf("decode config file failed, %w", err)) + } + + logrus.Infof("read config success, conf= '%+v'", conf) + return conf +} diff --git a/entity/utils.go b/entity/utils.go index 5a0724c..7d54ba4 100644 --- a/entity/utils.go +++ b/entity/utils.go @@ -104,3 +104,13 @@ func Value(src proto.Message) (driver.Value, error) { return buf, nil } + +func ToEnum[T ~int32](pbmap map[string]int32, default_ T) func(str string) T { + return func(str string) T { + v, ok := pbmap[string(str)] + if !ok { + return default_ + } + return T(v) + } +}