func handleDataChanges(items []utils.DataTable, listener utils.Listener, listenerName string) { // Walking the directory to get files. fsItems := utils.ListFilesInDir(listener.Directory) itemsToDelete := findOnlyInFS(fsItems, items, listenerName) if len(itemsToDelete) > 0 { for _, delItem := range itemsToDelete { if !utils.MatchesIgnore(listener.Directory, delItem) { itemExists := datastore.PathExists(listenerName, delItem) if !itemExists { log.Infof("Removing untracked item: %s", delItem) err := os.Remove(delItem) if err != nil { log.Infof("Error deleting untracked file %s\n%s", delItem, err.Error()) } } } } } for _, item := range items { absPath := utils.GetAbsPath(listenerName, item.Path) itemMatch := getFileInDatabase(absPath, fsItems) perms := fmt.Sprintf("File Permissions: %#o", item.Perms) if itemMatch { // Check to make sure it's not a directory as directories don't need to be uploaded if !item.IsDirectory { fileMD5 := utils.GetMd5Checksum(absPath) if fileMD5 != item.Checksum { log.Info("Processing modified file: " + absPath) hostname, _ := os.Hostname() if item.HostUpdated != hostname { // File wasn't updated locally so get it from remote bNodeCopy := storage.GetNodeCopy(item, listenerName, listener.Uid, listener.Gid, perms) if bNodeCopy { // Item downloaded successfully so update db with new md5 newFileInfo, err := utils.GetFileInfo(absPath) if err != nil { log.Infof("Error occurred trying to get info on file: %s", absPath) } else { datastore.Insert(listenerName, newFileInfo) } } else { // Item didn't download from nodes (maybe ports are closed so lets get from backups) storage.GetFile(absPath, listenerName, listener.Uid, listener.Gid, perms) newFileInfo, err := utils.GetFileInfo(absPath) if err != nil { log.Infof("Error occurred trying to get info on file: %s", absPath) } else { datastore.Insert(listenerName, newFileInfo) } } } else { // Item was modified locally and does not match so lets fix it with what is in db storage.GetFile(absPath, listenerName, listener.Uid, listener.Gid, perms) newFileInfo, err := utils.GetFileInfo(absPath) if err != nil { log.Infof("Error occurred trying to get info on file: %s", absPath) } else { datastore.Insert(listenerName, newFileInfo) } } } } // Now we check to make sure the files match correct users etc } else { if !utils.MatchesIgnore(listener.Directory, absPath) { // Item doesn't exist locally but exists in DB so restore it log.Infof("Item Deleted Locally: %s restoring from DB marker", absPath) if item.IsDirectory { dirExists, _ := utils.ItemExists(absPath) if !dirExists { os.MkdirAll(absPath, 0775) } } else { if !storage.GetNodeCopy(item, listenerName, listener.Uid, listener.Gid, perms) { log.Infof("Server is down for %s going to backup storage", listenerName) // The server must be down so lets get it from S3 storage.GetFile(absPath, listenerName, listener.Uid, listener.Gid, perms) } } } } } }
func SysPathWatcher(path string) { log.Infof("Starting new watcher for %s:", path) watcher, err := fsnotify.NewWatcher() if err != nil { log.Criticalf("Cannot create new watcher for %s\n %s", path, err.Error()) } defer watcher.Close() done := make(chan bool) go func() { listener := utils.GetListenerFromDir(path) rel_path := utils.GetRelativePath(listener, path) for { select { case event := <-watcher.Events: //logs.WriteLn("event:", event) if event.Op&fsnotify.Chmod == fsnotify.Chmod { if !utils.MatchesIgnore(path, event.Name) { runFileChmod(path, event.Name) } } if event.Op&fsnotify.Rename == fsnotify.Rename { if !utils.MatchesIgnore(path, event.Name) { if checksumItem(path, rel_path, event.Name) { log.Infof("Rename occurred on:", event.Name) runFileRename(path, event.Name) } } } if (event.Op&fsnotify.Create == fsnotify.Create) || (event.Op&fsnotify.Write == fsnotify.Write) { if checksumItem(path, rel_path, event.Name) { if !utils.MatchesIgnore(path, event.Name) { log.Infof("New / Modified File: %s", event.Name) runFileCreateUpdate(path, event.Name, "create") } } } if event.Op&fsnotify.Remove == fsnotify.Remove { if !utils.MatchesIgnore(path, event.Name) { runFileRemove(path, event.Name) log.Infof("Removed File: %s", event.Name) } } case err := <-watcher.Errors: log.Errorf("error:", err) } } }() err = watcher.Add(path) if err != nil { log.Criticalf("Cannot add watcher to %s\n %s", path, err.Error()) } <-done }