Browse Source

fix: table location mappings to /etc/s3tables (#8457)

* fix: move table location mappings to /etc/s3tables to avoid bucket name validation

Fixes #8362 - table location mappings were stored under /buckets/.table-location-mappings
which fails bucket name validation because it starts with a dot. Moving them to
/etc/s3tables resolves the migration error for upgrades.

Changes:
- Table location mappings now stored under /etc/s3tables
- Ensure parent /etc directory exists before creating /etc/s3tables
- Normal writes go to new location only (no legacy compatibility)
- Removed bucket name validation exception for old location

* refactor: simplify lookupTableLocationMapping by removing redundant mappingPath parameter

The mappingPath function parameter was redundant as the path can be derived
from mappingDir and bucket using path.Join. This simplifies the code and
reduces the risk of path mismatches between parameters.
pull/8360/head
Chris Lu 2 days ago
committed by GitHub
parent
commit
641351da78
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 30
      weed/s3api/bucket_paths.go
  2. 4
      weed/s3api/s3tables/utils.go

30
weed/s3api/bucket_paths.go

@ -58,16 +58,7 @@ func (s3a *S3ApiServer) tableLocationDir(bucket string) (string, bool) {
s3a.bucketRegistry.tableLocationLock.RUnlock() s3a.bucketRegistry.tableLocationLock.RUnlock()
} }
entry, err := s3a.getEntry(s3tables.GetTableLocationMappingDir(), bucket)
tablePath := ""
if err == nil && entry != nil {
if entry.IsDirectory {
tablePath, err = s3a.readTableLocationMappingFromDirectory(bucket)
} else if len(entry.Content) > 0 {
// Backward compatibility with legacy single-file mappings.
tablePath = normalizeTableLocationMappingPath(string(entry.Content))
}
}
tablePath, err := s3a.lookupTableLocationMapping(bucket, s3tables.GetTableLocationMappingDir())
// Only cache definitive results: successful lookup (tablePath set) or definitive not-found (ErrNotFound) // Only cache definitive results: successful lookup (tablePath set) or definitive not-found (ErrNotFound)
// Don't cache transient errors to avoid treating temporary failures as permanent misses // Don't cache transient errors to avoid treating temporary failures as permanent misses
@ -89,8 +80,7 @@ func (s3a *S3ApiServer) tableLocationDir(bucket string) (string, bool) {
return tablePath, true return tablePath, true
} }
func (s3a *S3ApiServer) readTableLocationMappingFromDirectory(bucket string) (string, error) {
mappingDir := s3tables.GetTableLocationMappingPath(bucket)
func (s3a *S3ApiServer) readTableLocationMappingFromDirectory(mappingDir string) (string, error) {
var mappedPath string var mappedPath string
conflict := false conflict := false
@ -134,12 +124,26 @@ func (s3a *S3ApiServer) readTableLocationMappingFromDirectory(bucket string) (st
} }
if conflict { if conflict {
glog.V(1).Infof("table location mapping conflict for %s: multiple mapped roots found", bucket)
glog.V(1).Infof("table location mapping conflict under %s: multiple mapped roots found", mappingDir)
return "", nil return "", nil
} }
return mappedPath, nil return mappedPath, nil
} }
func (s3a *S3ApiServer) lookupTableLocationMapping(bucket, mappingDir string) (string, error) {
entry, err := s3a.getEntry(mappingDir, bucket)
if err != nil || entry == nil {
return "", err
}
if entry.IsDirectory {
return s3a.readTableLocationMappingFromDirectory(path.Join(mappingDir, bucket))
}
if len(entry.Content) == 0 {
return "", nil
}
return normalizeTableLocationMappingPath(string(entry.Content)), nil
}
func normalizeTableLocationMappingPath(rawPath string) string { func normalizeTableLocationMappingPath(rawPath string) string {
rawPath = strings.TrimSpace(rawPath) rawPath = strings.TrimSpace(rawPath)
if rawPath == "" { if rawPath == "" {

4
weed/s3api/s3tables/utils.go

@ -21,7 +21,7 @@ const (
) )
const ( const (
tableLocationMappingsDirName = ".table-location-mappings"
tableLocationMappingsDirPath = "/etc/s3tables"
tableObjectRootDirName = ".objects" tableObjectRootDirName = ".objects"
) )
@ -111,7 +111,7 @@ func GetTableObjectBucketPath(bucketName string) string {
// GetTableLocationMappingDir returns the root path for table location bucket mappings // GetTableLocationMappingDir returns the root path for table location bucket mappings
func GetTableLocationMappingDir() string { func GetTableLocationMappingDir() string {
return path.Join(TablesPath, tableLocationMappingsDirName)
return tableLocationMappingsDirPath
} }
// GetTableLocationMappingPath returns the filer path for a table location bucket mapping // GetTableLocationMappingPath returns the filer path for a table location bucket mapping

Loading…
Cancel
Save