package importer import ( "context" "fmt" "log" "github.com/darroyo/nasctl/internal/db" "github.com/darroyo/nasctl/internal/modules/nfs" "github.com/darroyo/nasctl/internal/modules/samba" "github.com/darroyo/nasctl/internal/modules/users" ) type ImportResult struct { SambaImported int NFSImported int UsersImported int SambaSkipped bool NFSSkipped bool UsersSkipped bool SambaError string NFSError string UsersError string } type ImporterDB interface { ListSambaShares() ([]db.SambaShare, error) ListNFSExports() ([]db.NFSExport, error) ListUsers() ([]db.User, error) ReplaceSambaShares(shares []db.SambaShare) error ReplaceNFSExports(exports []db.NFSExport) error ReplaceUsers(users []db.User) error GetSetting(key string) (string, bool, error) SetSetting(key, value string) error MarkDirty(module string) error } func ImportOnBoot(ctx context.Context, database ImporterDB, smbPath, exportsPath, adminUsername string) ImportResult { result := ImportResult{} sambaDone, _, _ := database.GetSetting("import.samba.done") nfsDone, _, _ := database.GetSetting("import.nfs.done") usersDone, _, _ := database.GetSetting("import.users.done") allDone := sambaDone == "true" && nfsDone == "true" && usersDone == "true" if allDone { return result } if sambaDone != "true" { sr := importSamba(ctx, database, smbPath) result.SambaImported = sr.count result.SambaSkipped = sr.skipped result.SambaError = sr.err if sr.err == "" { _ = database.SetSetting("import.samba.done", "true") } } if nfsDone != "true" { nr := importNFS(ctx, database, exportsPath) result.NFSImported = nr.count result.NFSSkipped = nr.skipped result.NFSError = nr.err if nr.err == "" { _ = database.SetSetting("import.nfs.done", "true") } } if usersDone != "true" { ur := importUsers(ctx, database, adminUsername) result.UsersImported = ur.count result.UsersSkipped = ur.skipped result.UsersError = ur.err if ur.err == "" { _ = database.SetSetting("import.users.done", "true") } } if result.SambaImported > 0 || result.NFSImported > 0 || result.UsersImported > 0 { log.Printf("[importer] imported %d samba shares, %d nfs exports, %d users", result.SambaImported, result.NFSImported, result.UsersImported) } return result } func ResetImportFlags(ctx context.Context, database ImporterDB) error { _ = database.SetSetting("import.samba.done", "") _ = database.SetSetting("import.nfs.done", "") _ = database.SetSetting("import.users.done", "") return nil } type importStep struct { count int skipped bool err string } func importSamba(ctx context.Context, database ImporterDB, path string) importStep { shares, err := ImportSambaShares(path) if err != nil { return importStep{err: err.Error()} } if shares == nil { return importStep{skipped: true} } existing, err := database.ListSambaShares() if err != nil { return importStep{err: err.Error()} } if len(existing) > 0 { return importStep{skipped: true} } if err := database.ReplaceSambaShares(shares); err != nil { return importStep{err: err.Error()} } if err := database.MarkDirty(samba.ModuleName); err != nil { return importStep{count: len(shares), err: fmt.Sprintf("imported but could not mark dirty: %v", err)} } return importStep{count: len(shares)} } func importNFS(ctx context.Context, database ImporterDB, path string) importStep { exports, err := ImportNFSExports(path) if err != nil { return importStep{err: err.Error()} } if exports == nil { return importStep{skipped: true} } existing, err := database.ListNFSExports() if err != nil { return importStep{err: err.Error()} } if len(existing) > 0 { return importStep{skipped: true} } if err := database.ReplaceNFSExports(exports); err != nil { return importStep{err: err.Error()} } if err := database.MarkDirty(nfs.ModuleName); err != nil { return importStep{count: len(exports), err: fmt.Sprintf("imported but could not mark dirty: %v", err)} } return importStep{count: len(exports)} } func importUsers(ctx context.Context, database ImporterDB, adminUsername string) importStep { imported, err := ImportSystemUsers(ctx, adminUsername) if err != nil { return importStep{err: err.Error()} } if imported == nil { return importStep{skipped: true} } existing, err := database.ListUsers() if err != nil { return importStep{err: err.Error()} } if len(existing) > 0 { return importStep{skipped: true} } if err := database.ReplaceUsers(imported); err != nil { return importStep{err: err.Error()} } if err := database.MarkDirty(users.ModuleName); err != nil { return importStep{count: len(imported), err: fmt.Sprintf("imported but could not mark dirty: %v", err)} } return importStep{count: len(imported)} }