func fsGetData(log *logging.Logger, section *common.Section, cfg *ini.File) { var previous int var res common.JSONFile var db database.DB if section.Dataset-1 == 0 { previous = cfg.Section("dataset").Key(section.Grace).MustInt() } else { previous = section.Dataset - 1 } db.Open(log, cfg) defer db.Close() for _, item := range []string{"directory", "file", "symlink"} { for res = range database.ListItems(log, &db, section, item) { switch item { case "directory": fsSaveData(log, cfg, section, res, false) case "symlink": fsSaveData(log, cfg, section, res, false) case "file": if database.ItemExist(log, &db, &res, section, previous) { fsSaveData(log, cfg, section, res, true) } else { fsSaveData(log, cfg, section, res, false) } } } } }
func Backup(log *logging.Logger, cfg *ini.File, grace string, reload bool) { const POOL = 5 var db database.DB var tx *sql.Tx var c = make(chan bool, POOL) var wg = new(sync.WaitGroup) var dataset, maxdatasets int var sections []*ini.Section sections = cfg.Sections() maxdatasets, _ = cfg.Section("dataset").Key(grace).Int() db.Open(log, cfg) defer db.Close() tx, _ = db.Conn.Begin() dataset = database.GetDataset(log, tx, grace) tx.Commit() if !reload { if nextds := dataset + 1; nextds > maxdatasets { dataset = 1 } else { dataset = dataset + 1 } } log.Info("Dataset processed: " + strconv.Itoa(dataset)) wg.Add(len(sections) - len(SECT_RESERVED)) for _, section := range sections { if !contains(SECT_RESERVED, section.Name()) { if section.Key("type").String() == "file" { // FIXME: useless? sect := common.Section{ Name: section.Name(), Grace: grace, Dataset: dataset, Compressed: section.Key("compress").MustBool(), } go fileBackup(log, §, cfg, c, wg) c <- true } } } wg.Wait() // Wait for all the children to die close(c) tx, _ = db.Conn.Begin() database.SetDataset(log, tx, dataset, grace) tx.Commit() }
func FileRestore(log *logging.Logger, section *common.Section, cfg *ini.File) { var cmd common.JSONMessage var res common.JSONFile var db database.DB var err error db.Open(log, cfg) defer db.Close() cmd.Context = "file" cmd.Command.Name = "put" if cfg.Section(section.Name).Key("path").String() == "" { log.Debug("About to full restore") cmd.Command.ACL = cfg.Section(section.Name).Key("acl").MustBool() for _, item := range []string{"directory", "file", "symlink"} { for res = range database.ListItems(log, &db, section, item) { if cmd.Command.ACL { log.Debug("About to restore ACLs for " + res.Name) res.Acl, err = database.GetAcls(log, &db, res.Name, section) if err != nil { log.Error("ACLs extraction error for " + res.Name) log.Debug("error: " + err.Error()) } } cmd.Command.Element = res put(log, section, cfg, &cmd) } } } else { log.Debug("About to restore path " + cfg.Section(section.Name).Key("path").String()) cmd.Command.Element, err = database.GetItem(log, &db, cfg.Section(section.Name).Key("path").String(), section) if err != nil { log.Error("Error when putting data to section " + section.Name) log.Debug("error: " + err.Error()) } else { cmd.Command.ACL = cfg.Section(section.Name).Key("acl").MustBool() put(log, section, cfg, &cmd) } } }
func DelDataset(log *logging.Logger, cfg *ini.File, section, grace string, dataset int) { var db database.DB log.Debug("About to delete dataset " + strconv.Itoa(dataset) + " for section " + section + " and grace " + grace) db.Open(log, cfg) defer db.Close() err := database.DelDataset(log, &db, section, grace, dataset) if err != nil { log.Error(err.Error()) } repository := Path(cfg, &common.Section{ Name: section, Grace: grace, Dataset: dataset, }, false) os.RemoveAll(repository) log.Debug("Dataset deleted") }
func fsGetMetadata(log *logging.Logger, section *common.Section, cfg *ini.File) { var conn net.Conn var cmd common.JSONMessage var db database.DB var buff *bufio.Reader var res common.JSONResult var tx *sql.Tx var data []byte var err error log.Debug("Getting metadata for " + section.Name) cmd.Context = "file" cmd.Command.Name = "list" cmd.Command.Paths = strings.Split(cfg.Section(section.Name).Key("path").String(), ",") cmd.Command.ACL = cfg.Section(section.Name).Key("acl").MustBool() cmd.Command.Exclude = cfg.Section(section.Name).Key("exclude").String() log.Debug("Metadata command request: %+v", cmd) conn, err = network.GetSocket(cfg.Section(section.Name)) if err != nil { log.Error("Error when opening connection with section " + section.Name) log.Debug("error: " + err.Error()) return } defer conn.Close() cmd.Send(conn) db.Open(log, cfg) defer db.Close() tx, err = db.Conn.Begin() if err != nil { log.Error("Transaction error for section " + section.Name) log.Debug("Trace: " + err.Error()) return } buff = bufio.NewReader(conn) for { res = common.JSONResult{} data, err = buff.ReadBytes('\n') if err != nil { if err == io.EOF { log.Debug("All files's metadata are saved") break } log.Error("Error when getting files metadata for section " + section.Name) log.Debug("error: " + err.Error()) return } err = json.Unmarshal(data, &res) if err != nil { log.Error("Error when parsing JSON data for section " + section.Name) log.Debug("error: " + err.Error()) return } log.Debug("Metadata received: %+v", res) if err = database.SaveAttrs(log, tx, section, res.Data); err != nil { log.Error("Failed saving database item: " + res.Data.Name) log.Debug("Trace: " + err.Error()) tx.Rollback() return } if err = database.SaveAcls(log, tx, section, res.Data.Name, res.Data.Acl); err != nil { log.Error("Failed saving ACLs into database for item: " + res.Data.Name) log.Debug("Trace: " + err.Error()) tx.Rollback() return } } tx.Commit() }