Skip to content

eko restore <id> silently no-ops (and can wipe the working tree) on an unknown snapshot ID #60

Description

@kavix

Description

cmd/restore.go ignores the error/no-rows case when looking up a snapshot:

id := args[0]
database := db.InitDB()
var path string
database.QueryRow("SELECT path FROM snapshots WHERE id=?", id).Scan(&path)
err := snapshot.RestoreSnapshot(path)

If id doesn't exist in the DB, Scan returns sql.ErrNoRows, which is
discarded — path stays "". Execution continues straight into
RestoreSnapshot("").

RestoreSnapshot (internal/snapshot/snapshot.go) does not check that
path is valid before Phase 1, which deletes every top-level file/dir in the
current directory (except .eko) concurrently via os.RemoveAll. Phase 2
then calls util.CopyDir("", ".") with an empty source.

Repro

eko init
eko save
eko restore not-a-real-id

Expected: a clear "snapshot not found" error, nothing touched.
Actual: the current directory's contents get deleted first, then a copy from
an empty path is attempted — no safe recovery path if that second step also
misbehaves.

Suggested fix

Check the query result before calling RestoreSnapshot:

row := database.QueryRow("SELECT path FROM snapshots WHERE id=?", id)
if err := row.Scan(&path); err != nil {
	if err == sql.ErrNoRows {
		return fmt.Errorf("no snapshot found with id %q", id)
	}
	return err
}

Return the error from Run (or use RunE) instead of proceeding.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions