mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-08-01 02:11:15 -04:00
add posixfs index command
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/options"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/registry"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/storage/utils/decomposedfs/spaceidindex"
|
||||
|
||||
"github.com/pkg/xattr"
|
||||
"github.com/rs/zerolog"
|
||||
@@ -62,6 +63,7 @@ func PosixfsCommand(cfg *config.Config) *cobra.Command {
|
||||
}
|
||||
|
||||
posixCmd.AddCommand(consistencyCmd(cfg))
|
||||
posixCmd.AddCommand(indexCmd(cfg))
|
||||
posixCmd.AddCommand(scanCmd(cfg))
|
||||
|
||||
return posixCmd
|
||||
@@ -138,6 +140,148 @@ func scanCmd(ocCfg *config.Config) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
func indexCmd(ocCfg *config.Config) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "index",
|
||||
Short: "Add spaces from the filesystem to the index",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return rebuildIndexes(cmd)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringP("root", "r", "", "Path to the root directory of the posixfs storage")
|
||||
cmd.Flags().StringSliceP("dirs", "d", []string{"users", "projects"}, "Subdirectories to scan for spaces")
|
||||
cmd.Flags().StringP("space", "s", "", "Only index a specific space by ID")
|
||||
_ = cmd.MarkFlagRequired("root")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func rebuildIndexes(cmd *cobra.Command) error {
|
||||
rootPath, _ := cmd.Flags().GetString("root")
|
||||
spaceFilter, _ := cmd.Flags().GetString("space")
|
||||
indexesDir := filepath.Join(rootPath, "indexes")
|
||||
|
||||
if _, err := os.Stat(indexesDir); err != nil {
|
||||
return fmt.Errorf("'%s' is not a posixfs root: %w", rootPath, err)
|
||||
}
|
||||
|
||||
userIndex := spaceidindex.New(indexesDir, "by-user-id")
|
||||
if err := userIndex.Init(); err != nil {
|
||||
return fmt.Errorf("failed to init by-user-id index: %w", err)
|
||||
}
|
||||
groupIndex := spaceidindex.New(indexesDir, "by-group-id")
|
||||
if err := groupIndex.Init(); err != nil {
|
||||
return fmt.Errorf("failed to init by-group-id index: %w", err)
|
||||
}
|
||||
typeIndex := spaceidindex.New(indexesDir, "by-type")
|
||||
if err := typeIndex.Init(); err != nil {
|
||||
return fmt.Errorf("failed to init by-type index: %w", err)
|
||||
}
|
||||
|
||||
userEntries := map[string]map[string]string{}
|
||||
groupEntries := map[string]map[string]string{}
|
||||
typeEntries := map[string]map[string]string{}
|
||||
|
||||
dirs, _ := cmd.Flags().GetStringSlice("dirs")
|
||||
for _, dir := range dirs {
|
||||
basePath := filepath.Join(rootPath, dir)
|
||||
entries, err := os.ReadDir(basePath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("failed to read '%s': %w", basePath, err)
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
spacePath := filepath.Join(basePath, entry.Name())
|
||||
|
||||
spaceID, err := xattr.Get(spacePath, idAttrName)
|
||||
if err != nil || len(spaceID) == 0 {
|
||||
fmt.Fprintf(os.Stderr, " - Skipping '%s': missing space ID\n", spacePath)
|
||||
continue
|
||||
}
|
||||
|
||||
sid := string(spaceID)
|
||||
if spaceFilter != "" && sid != spaceFilter {
|
||||
continue
|
||||
}
|
||||
|
||||
spaceType, err := xattr.Get(spacePath, "user.oc.space.type")
|
||||
if err != nil || len(spaceType) == 0 {
|
||||
fmt.Fprintf(os.Stderr, " - Skipping '%s': missing space type\n", spacePath)
|
||||
continue
|
||||
}
|
||||
|
||||
stype := string(spaceType)
|
||||
fmt.Printf("Collecting space '%s' (%s)\n", sid, stype)
|
||||
|
||||
if typeEntries[stype] == nil {
|
||||
typeEntries[stype] = map[string]string{}
|
||||
}
|
||||
typeEntries[stype][sid] = sid
|
||||
|
||||
ownerType, _ := xattr.Get(spacePath, "user.oc.owner.type")
|
||||
if string(ownerType) != "spaceowner" {
|
||||
ownerID, err := xattr.Get(spacePath, ownerIDAttrName)
|
||||
if err == nil && len(ownerID) > 0 {
|
||||
oid := string(ownerID)
|
||||
if userEntries[oid] == nil {
|
||||
userEntries[oid] = map[string]string{}
|
||||
}
|
||||
userEntries[oid][sid] = sid
|
||||
}
|
||||
}
|
||||
|
||||
attrs, err := xattr.List(spacePath)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, " - Failed to list xattrs for '%s': %v\n", spacePath, err)
|
||||
continue
|
||||
}
|
||||
for _, attr := range attrs {
|
||||
switch {
|
||||
case strings.HasPrefix(attr, "user.oc.grant.u:"):
|
||||
grantee := strings.TrimPrefix(attr, "user.oc.grant.u:")
|
||||
if userEntries[grantee] == nil {
|
||||
userEntries[grantee] = map[string]string{}
|
||||
}
|
||||
userEntries[grantee][sid] = sid
|
||||
case strings.HasPrefix(attr, "user.oc.grant.g:"):
|
||||
grantee := strings.TrimPrefix(attr, "user.oc.grant.g:")
|
||||
if groupEntries[grantee] == nil {
|
||||
groupEntries[grantee] = map[string]string{}
|
||||
}
|
||||
groupEntries[grantee][sid] = sid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Writing indexes...")
|
||||
|
||||
for spaceType, entries := range typeEntries {
|
||||
if err := typeIndex.AddAll(spaceType, entries); err != nil {
|
||||
fmt.Fprintf(os.Stderr, " - Failed to write type index '%s': %v\n", spaceType, err)
|
||||
}
|
||||
}
|
||||
for userID, entries := range userEntries {
|
||||
if err := userIndex.AddAll(userID, entries); err != nil {
|
||||
fmt.Fprintf(os.Stderr, " - Failed to write user index '%s': %v\n", userID, err)
|
||||
}
|
||||
}
|
||||
for groupID, entries := range groupEntries {
|
||||
if err := groupIndex.AddAll(groupID, entries); err != nil {
|
||||
fmt.Fprintf(os.Stderr, " - Failed to write group index '%s': %v\n", groupID, err)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Done.")
|
||||
return nil
|
||||
}
|
||||
|
||||
// consistencyCmd returns a command to check the consistency of the posixfs storage.
|
||||
func consistencyCmd(cfg *config.Config) *cobra.Command {
|
||||
consCmd := &cobra.Command{
|
||||
|
||||
Reference in New Issue
Block a user