sqlite.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package sqlite
  2. import (
  3. "fmt"
  4. "strconv"
  5. "sync"
  6. "time"
  7. "github.com/crowdsecurity/crowdsec/pkg/types"
  8. "github.com/pkg/errors"
  9. log "github.com/sirupsen/logrus"
  10. "github.com/jinzhu/gorm"
  11. _ "github.com/jinzhu/gorm/dialects/sqlite"
  12. _ "github.com/mattn/go-sqlite3"
  13. "gopkg.in/tomb.v2"
  14. )
  15. type Context struct {
  16. Db *gorm.DB //Pointer to sqlite db
  17. tx *gorm.DB //Pointer to current transaction (flushed on a regular basis)
  18. lastCommit time.Time
  19. flush bool
  20. count int32
  21. lock sync.Mutex //booboo
  22. PusherTomb tomb.Tomb
  23. //to manage auto cleanup : max number of records *or* oldest
  24. maxEventRetention int
  25. maxDurationRetention time.Duration
  26. }
  27. func NewSQLite(cfg map[string]string) (*Context, error) {
  28. var err error
  29. c := &Context{}
  30. if v, ok := cfg["max_records"]; ok {
  31. c.maxEventRetention, err = strconv.Atoi(v)
  32. if err != nil {
  33. log.Errorf("Ignoring invalid max_records '%s' : %s", v, err)
  34. }
  35. }
  36. if v, ok := cfg["max_records_age"]; ok {
  37. c.maxDurationRetention, err = time.ParseDuration(v)
  38. if err != nil {
  39. log.Errorf("Ignoring invalid duration '%s' : %s", v, err)
  40. }
  41. }
  42. if _, ok := cfg["db_path"]; !ok {
  43. return nil, fmt.Errorf("please specify a 'db_path' to SQLite db in the configuration")
  44. }
  45. if cfg["db_path"] == "" {
  46. return nil, fmt.Errorf("please specify a 'db_path' to SQLite db in the configuration")
  47. }
  48. log.Debugf("Starting SQLite backend, path:%s", cfg["db_path"])
  49. c.Db, err = gorm.Open("sqlite3", cfg["db_path"]+"?_busy_timeout=1000")
  50. if err != nil {
  51. return nil, fmt.Errorf("failed to open %s : %s", cfg["db_path"], err)
  52. }
  53. if val, ok := cfg["debug"]; ok && val == "true" {
  54. log.Infof("Enabling debug for sqlite")
  55. c.Db.LogMode(true)
  56. }
  57. c.flush, err = strconv.ParseBool(cfg["flush"])
  58. if err != nil {
  59. return nil, errors.Wrap(err, "Unable to parse 'flush' flag")
  60. }
  61. // Migrate the schema
  62. c.Db.AutoMigrate(&types.EventSequence{}, &types.SignalOccurence{}, &types.BanApplication{})
  63. c.Db.Model(&types.SignalOccurence{}).Related(&types.EventSequence{})
  64. c.Db.Model(&types.SignalOccurence{}).Related(&types.BanApplication{})
  65. c.tx = c.Db.Begin()
  66. c.lastCommit = time.Now()
  67. ret := c.tx.Commit()
  68. if ret.Error != nil {
  69. return nil, fmt.Errorf("failed to commit records : %v", ret.Error)
  70. }
  71. c.tx = c.Db.Begin()
  72. if c.tx == nil {
  73. return nil, fmt.Errorf("failed to begin sqlite transac : %s", err)
  74. }
  75. return c, nil
  76. }