func execCommand(log *logging.Logger, section *ini.Section, command string) error { var buff *bufio.Reader var conn net.Conn var cmd common.JSONMessage var res common.JSONResult var err error var result []byte if section.Key(command).String() != "" { conn, err = network.GetSocket(section) if err != nil { return errorMsg(log, 1, "Connection with "+command+" failed: "+err.Error()) } defer conn.Close() buff = bufio.NewReader(conn) cmd = common.JSONMessage{} cmd.Context = "system" cmd.Command.Name = "exec" cmd.Command.Cmd = section.Key(command).String() if err = cmd.Send(conn); err != nil { return errorMsg(log, 2, "Sending "+command+" failed: "+err.Error()) } else { result, err = buff.ReadBytes('\n') if err != nil { log.Error("Receive " + command + " result failed: " + err.Error()) } err = json.Unmarshal(result, &res) if err != nil { msg := "Response result for " + command + " failed: " + err.Error() log.Error(msg) return errorMsg(log, 3, msg) } if res.Result == "ok" { log.Debug("Executed " + command) return nil } else { return errorMsg(log, 4, "Error in "+command+" execution: "+res.Message) } } } else { return nil } }
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 fsSaveData(log *logging.Logger, cfg *ini.File, section *common.Section, data common.JSONFile, previous bool) { var item, source, dest, hash string var cmd common.JSONMessage var conn net.Conn var err error item = dataset.ConvertPath(data.Os, data.Name) source = dataset.Path(cfg, section, true) + string(filepath.Separator) + item dest = dataset.Path(cfg, section, false) + string(filepath.Separator) + item log.Debug("Save item: " + dest) switch data.Type { case "directory": os.MkdirAll(dest, 0755) case "symlink": if err := os.Symlink(data.Link, dest); err != nil { log.Error("Error when creating symlink for file %s", data.Name) log.Debug("Trace: %s", err.Error()) } case "file": if previous { if section.Compressed { source = source + ".compressed" dest = dest + ".compressed" } if err = os.Link(source, dest); err != nil { log.Error("Error when link file %s", data.Name) log.Debug("Trace: " + err.Error()) } } else { cmd.Context = "file" cmd.Command.Name = "get" cmd.Command.Element = data conn, err = network.GetSocket(cfg.Section(section.Name)) if err != nil { log.Error("Error when opening connection with section " + section.Name) log.Debug("Trace: " + err.Error()) return } defer conn.Close() cmd.Send(conn) if hash, err = common.ReceiveFile(dest, conn); err != nil { log.Error("Error when receiving file " + data.Name) log.Debug("Trace: " + err.Error()) } // TODO: check file's hash if hash == "" { log.Error("Hash for file " + dest + " mismatch") // TODO: remove file if hash mismatch } else { log.Debug("Hash for file " + dest + " is " + hash) if section.Compressed { dataset.CompressFile(log, dest) } } } } }
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() }