mirror of
https://github.com/dolthub/dolt.git
synced 2026-04-28 04:28:53 -05:00
When DB files can't be read off disk, fail with a clear error rather than a panic
This commit is contained in:
@@ -192,7 +192,11 @@ func ConfigureServices(
|
||||
AssertNoDatabasesInAccessModeReadOnly := &svcs.AnonService{
|
||||
InitF: func(ctx context.Context) (err error) {
|
||||
return mrEnv.Iter(func(name string, dEnv *env.DoltEnv) (stop bool, err error) {
|
||||
if dEnv.IsAccessModeReadOnly(ctx) {
|
||||
readOnly, err := dEnv.IsAccessModeReadOnly(ctx)
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
if readOnly {
|
||||
return true, ErrCouldNotLockDatabase.New(name)
|
||||
}
|
||||
return false, nil
|
||||
|
||||
+21
-4
@@ -708,7 +708,15 @@ If you're interested in running this command against a remote host, hit us up on
|
||||
}
|
||||
|
||||
var lookForServer bool
|
||||
if targetEnv.DoltDB(ctx) != nil && targetEnv.IsAccessModeReadOnly(ctx) {
|
||||
readOnly, err := targetEnv.IsAccessModeReadOnly(ctx)
|
||||
if err != nil {
|
||||
// Missing dolt data dir is expected if we are in a top level server directory. Other errors are not.
|
||||
if !errors.Is(err, doltdb.ErrMissingDoltDataDir) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if readOnly {
|
||||
// If the loaded target environment has a doltDB and we do not
|
||||
// have access to it, we look for a server.
|
||||
lookForServer = true
|
||||
@@ -718,12 +726,21 @@ If you're interested in running this command against a remote host, hit us up on
|
||||
// repositories in our MultiEnv are ReadOnly. This includes the
|
||||
// case where there are no repositories in our MultiEnv
|
||||
var allReposAreReadOnly bool = true
|
||||
mrEnv.Iter(func(name string, dEnv *env.DoltEnv) (stop bool, err error) {
|
||||
if dEnv.DoltDB(ctx) != nil {
|
||||
allReposAreReadOnly = allReposAreReadOnly && dEnv.IsAccessModeReadOnly(ctx)
|
||||
err = mrEnv.Iter(func(name string, dEnv *env.DoltEnv) (stop bool, err error) {
|
||||
readOnly, err := dEnv.IsAccessModeReadOnly(ctx)
|
||||
if err != nil {
|
||||
return true, fmt.Errorf("Failed to load database %s due to error: %w", name, err)
|
||||
}
|
||||
|
||||
allReposAreReadOnly = allReposAreReadOnly && readOnly
|
||||
|
||||
return !allReposAreReadOnly, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lookForServer = allReposAreReadOnly
|
||||
}
|
||||
if lookForServer {
|
||||
|
||||
+12
-2
@@ -110,6 +110,8 @@ func NewDoltEnv(version string, config *DoltCliConfig, repoState *RepoState, dol
|
||||
}
|
||||
}
|
||||
|
||||
// DoltDB returns the dolt database for this environment, loading it if necessary. If loading fails,
|
||||
// |dEnv.DBLoadError| will be non-nil. The caller is responsible for checking this error.
|
||||
func (dEnv *DoltEnv) DoltDB(ctx context.Context) *doltdb.DoltDB {
|
||||
if dEnv.doltDB == nil {
|
||||
LoadDoltDB(ctx, dEnv.FS, dEnv.urlStr, dEnv)
|
||||
@@ -1319,6 +1321,14 @@ func (dEnv *DoltEnv) BulkDbEaFactory(ctx context.Context) editor.DbEaFactory {
|
||||
return editor.NewBulkImportTEAFactory(dEnv.DoltDB(ctx).ValueReadWriter(), tmpDir)
|
||||
}
|
||||
|
||||
func (dEnv *DoltEnv) IsAccessModeReadOnly(ctx context.Context) bool {
|
||||
return dEnv.DoltDB(ctx).AccessMode() == chunks.ExclusiveAccessMode_ReadOnly
|
||||
func (dEnv *DoltEnv) IsAccessModeReadOnly(ctx context.Context) (bool, error) {
|
||||
db := dEnv.DoltDB(ctx)
|
||||
if db == nil {
|
||||
if dEnv.DBLoadError != nil {
|
||||
return false, dEnv.DBLoadError
|
||||
}
|
||||
return false, errors.New("DoltDB failed to initialize but no error was recorded")
|
||||
}
|
||||
|
||||
return db.AccessMode() == chunks.ExclusiveAccessMode_ReadOnly, nil
|
||||
}
|
||||
|
||||
@@ -2265,3 +2265,25 @@ EOF
|
||||
[ "$status" -eq 0 ]
|
||||
[[ ! "$output" =~ "Empty database name" ]] || false
|
||||
}
|
||||
|
||||
@test "sql-server: read permission failure clearly communicated" {
|
||||
start_sql_server > server_log.txt 2>&1 && sleep 0.5
|
||||
|
||||
stop_sql_server 1 && sleep 0.5
|
||||
|
||||
# Server log should say nothing about permissions.
|
||||
run grep -F "permission denied" server_log.txt
|
||||
[ $status -eq 1 ]
|
||||
|
||||
chmod 0000 repo1/.dolt/noms/manifest
|
||||
start_sql_server > server_log.txt 2>&1 && sleep 0.5
|
||||
|
||||
grep -F "permission denied" server_log.txt
|
||||
|
||||
# revert, and do the same with the journal file.
|
||||
chmod 0600 repo1/.dolt/noms/manifest
|
||||
chmod 0000 repo1/.dolt/noms/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||
|
||||
start_sql_server > server_log.txt 2>&1 && sleep 0.5
|
||||
grep -F "permission denied" server_log.txt
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user