cleanup: drop pre-v0.1 migration scaffolding + legacy-behavior refs
banger hasn't shipped a public release — every "legacy", "pre-opt-in",
"previously", "migration note", "no longer" reference in the tree is
pinning against a state no real user's install has ever been in.
That scaffolding has weight: it's a coordinate system future readers
have to decode, and it keeps dead code alive.
Removed (code):
- internal/daemon/ssh_client_config.go
- vmSSHConfigIncludeBegin / vmSSHConfigIncludeEnd constants and
every `removeManagedBlock(existing, vm...)` call they enabled
(legacy inline `Host *.vm` block scrub)
- cleanupLegacySSHConfigDir (+ its caller in syncVMSSHClientConfig)
— wiped a pre-opt-in sibling file under $ConfigDir/ssh
- sameDirOrParent + resolvePathForComparison — only ever used
by cleanupLegacySSHConfigDir
- the "also check legacy marker" fallback in
UserSSHIncludeInstalled / UninstallUserSSHInclude
- internal/store/migrations.go
- migrateDropDeadImageColumns (migration 2) + its slice entry
- dropColumnIfExists (orphaned after the above)
- addColumnIfMissing + the whole "columns added across the pre-
versioning lifetime" block at the end of migrateBaseline —
subsumed into the baseline CREATE TABLE
- `packages_path TEXT` column on the images table (the
throwaway migration 2 dropped it, but there was never any
reader)
- internal/daemon/vm.go
- vmDNSRecordName local wrapper — was justified as "avoid
pulling vmdns into every file"; three of four callers already
imported vmdns directly, so inline the one stray call
- internal/cli/cli_test.go
- TestLegacyRemovedCommandIsRejected (`tui` subcommand never
shipped)
Removed / simplified (tests):
- ssh_client_config_test.go: dropped TestSameDirOrParentHandlesSymlinks,
TestSyncVMSSHClientConfigPreservesUserKeyInLegacyDir,
TestSyncVMSSHClientConfigNarrowsCleanupToLegacyFile,
TestSyncVMSSHClientConfigLeavesUnexpectedLegacyContents,
TestInstallUserSSHIncludeMigratesLegacyInlineBlock, plus the
"legacy posture" regression strings in the remaining happy-path
test; TestUninstallUserSSHIncludeRemovesBothMarkerBlocks collapsed
to a single-block test
- migrations_test.go: dropped TestMigrateDropDeadImageColumns_AcrossInstallPaths,
TestDropColumnIfExistsIsIdempotent; TestOpenReadOnlyDoesNotRunMigrations
simplified to test against the baseline marker
Removed (docs):
- README.md "**Migration note.**" blockquote about the SSH-key path move
- docs/advanced.md parenthetical "(the old behaviour)"
Reworded (comments):
- Dropped "Previously this file also contained LogLevel DEBUG3..."
history from vm_disk.go's sshdGuestConfig doc
- Dropped "Call sites that previously read vm.Runtime.{PID,...}"
from vm_handles.go; now documents the current contract
- Dropped "Pre-v0.1 the defaults are" scaffolding in doctor_test.go
- Dropped "no longer does its own git inspection" phrasing in vm_run.go
- Dropped the "(also cleans up legacy inline block from pre-opt-in
builds)" aside on the `ssh-config` CLI docstring
- Renamed test var `legacyKey` → `existingKey` in vm_test.go; its
purpose was "pre-existing authorized_keys line," not banger-legacy
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5791466498
commit
700a1e6e60
16 changed files with 54 additions and 735 deletions
|
|
@ -141,98 +141,18 @@ func TestApplyMigrationRollsBackOnBodyError(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestMigrateDropDeadImageColumns_AcrossInstallPaths verifies the
|
||||
// drop-column migration is correct on both paths it can land on:
|
||||
// a fresh install (baseline created the column, migration 2 drops
|
||||
// it) and a legacy DB that somehow lost or never had the column
|
||||
// (migration 2 is a no-op). Runs migrations end-to-end so the
|
||||
// invariant-check is the real system, not the helper in isolation.
|
||||
func TestMigrateDropDeadImageColumns_AcrossInstallPaths(t *testing.T) {
|
||||
hasColumn := func(t *testing.T, db *sql.DB, table, column string) bool {
|
||||
t.Helper()
|
||||
rows, err := db.Query("PRAGMA table_info(" + table + ")")
|
||||
if err != nil {
|
||||
t.Fatalf("PRAGMA table_info: %v", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var (
|
||||
cid int
|
||||
name string
|
||||
valueType string
|
||||
notNull int
|
||||
defaultV sql.NullString
|
||||
pk int
|
||||
)
|
||||
if err := rows.Scan(&cid, &name, &valueType, ¬Null, &defaultV, &pk); err != nil {
|
||||
t.Fatalf("scan table_info row: %v", err)
|
||||
}
|
||||
if name == column {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
t.Fatalf("rows.Err: %v", err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
t.Run("fresh install drops packages_path", func(t *testing.T) {
|
||||
db := openRawDB(t)
|
||||
if err := runMigrations(db); err != nil {
|
||||
t.Fatalf("runMigrations: %v", err)
|
||||
}
|
||||
if hasColumn(t, db, "images", "packages_path") {
|
||||
t.Fatal("packages_path column survived migration 2 on fresh install")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("legacy DB without column is a no-op", func(t *testing.T) {
|
||||
db := openRawDB(t)
|
||||
// Simulate a DB whose baseline was applied against a modified
|
||||
// schema that never had packages_path: seed schema_migrations,
|
||||
// run baseline, drop the column out-of-band, then run
|
||||
// runMigrations and expect migration 2 to succeed regardless.
|
||||
if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
applied_at TEXT NOT NULL
|
||||
)`); err != nil {
|
||||
t.Fatalf("seed schema_migrations: %v", err)
|
||||
}
|
||||
if err := applyMigration(db, migrations[0]); err != nil {
|
||||
t.Fatalf("apply baseline: %v", err)
|
||||
}
|
||||
if _, err := db.Exec("ALTER TABLE images DROP COLUMN packages_path"); err != nil {
|
||||
t.Fatalf("pre-drop packages_path: %v", err)
|
||||
}
|
||||
if err := runMigrations(db); err != nil {
|
||||
t.Fatalf("runMigrations after manual pre-drop: %v", err)
|
||||
}
|
||||
if hasColumn(t, db, "images", "packages_path") {
|
||||
t.Fatal("packages_path reappeared after runMigrations")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestOpenReadOnlyDoesNotRunMigrations pins the doctor contract:
|
||||
// OpenReadOnly must not mutate the DB. We create a DB without the
|
||||
// schema_migrations row for migration 2 present (simulating a
|
||||
// daemon-not-yet-run state), open it read-only, and confirm no row
|
||||
// was added and no column dropped.
|
||||
// OpenReadOnly must not mutate the DB. Seed a DB whose baseline
|
||||
// migration row has been forcibly removed (simulating a "behind"
|
||||
// state), open it read-only, and confirm nothing was re-applied.
|
||||
func TestOpenReadOnlyDoesNotRunMigrations(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "state.db")
|
||||
// Seed the file by running full Open once, then roll migration 2
|
||||
// backwards manually so the DB is "behind" current code.
|
||||
full, err := Open(path)
|
||||
if err != nil {
|
||||
t.Fatalf("Open: %v", err)
|
||||
}
|
||||
if _, err := full.db.Exec("ALTER TABLE images ADD COLUMN packages_path TEXT"); err != nil {
|
||||
t.Fatalf("re-add packages_path: %v", err)
|
||||
}
|
||||
if _, err := full.db.Exec("DELETE FROM schema_migrations WHERE id = 2"); err != nil {
|
||||
t.Fatalf("remove migration 2 marker: %v", err)
|
||||
if _, err := full.db.Exec("DELETE FROM schema_migrations WHERE id = 1"); err != nil {
|
||||
t.Fatalf("remove baseline marker: %v", err)
|
||||
}
|
||||
_ = full.Close()
|
||||
|
||||
|
|
@ -242,39 +162,12 @@ func TestOpenReadOnlyDoesNotRunMigrations(t *testing.T) {
|
|||
}
|
||||
defer ro.Close()
|
||||
|
||||
// Migration 2 marker must still be absent; packages_path must
|
||||
// still exist.
|
||||
var migCount int
|
||||
if err := ro.db.QueryRow("SELECT COUNT(*) FROM schema_migrations WHERE id = 2").Scan(&migCount); err != nil {
|
||||
if err := ro.db.QueryRow("SELECT COUNT(*) FROM schema_migrations WHERE id = 1").Scan(&migCount); err != nil {
|
||||
t.Fatalf("query schema_migrations: %v", err)
|
||||
}
|
||||
if migCount != 0 {
|
||||
t.Fatal("OpenReadOnly recorded migration 2 — the open path mutated the DB")
|
||||
}
|
||||
rows, err := ro.db.Query("PRAGMA table_info(images)")
|
||||
if err != nil {
|
||||
t.Fatalf("PRAGMA table_info: %v", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
var sawColumn bool
|
||||
for rows.Next() {
|
||||
var (
|
||||
cid int
|
||||
name string
|
||||
valueType string
|
||||
notNull int
|
||||
defaultV sql.NullString
|
||||
pk int
|
||||
)
|
||||
if err := rows.Scan(&cid, &name, &valueType, ¬Null, &defaultV, &pk); err != nil {
|
||||
t.Fatalf("scan: %v", err)
|
||||
}
|
||||
if name == "packages_path" {
|
||||
sawColumn = true
|
||||
}
|
||||
}
|
||||
if !sawColumn {
|
||||
t.Fatal("packages_path disappeared — OpenReadOnly ran the drop migration")
|
||||
t.Fatal("OpenReadOnly re-recorded a migration row — the open path mutated the DB")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -351,72 +244,6 @@ func TestRunMigrationsIgnoresUnknownAppliedIDs(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestDropColumnIfExistsIsIdempotent pins the "run twice, no harm"
|
||||
// property. A daemon that restarts after a successful migration 2
|
||||
// on a fresh install shouldn't fail because the column is already
|
||||
// gone. migrateDropDeadImageColumns calls dropColumnIfExists, which
|
||||
// must silently succeed when the column is absent.
|
||||
func TestDropColumnIfExistsIsIdempotent(t *testing.T) {
|
||||
db := openRawDB(t)
|
||||
// Set up a tiny table with a known column we're going to drop.
|
||||
if _, err := db.Exec(`CREATE TABLE throwaway (keeper TEXT, victim TEXT)`); err != nil {
|
||||
t.Fatalf("CREATE: %v", err)
|
||||
}
|
||||
|
||||
run := func(label string) error {
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
t.Fatalf("%s Begin: %v", label, err)
|
||||
}
|
||||
if err := dropColumnIfExists(tx, "throwaway", "victim"); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
if err := run("first"); err != nil {
|
||||
t.Fatalf("first dropColumnIfExists: %v", err)
|
||||
}
|
||||
// Second call against a table that no longer has the column.
|
||||
if err := run("second"); err != nil {
|
||||
t.Fatalf("second dropColumnIfExists (column already gone): %v", err)
|
||||
}
|
||||
|
||||
// The keeper column must still be there; victim is gone.
|
||||
rows, err := db.Query("PRAGMA table_info(throwaway)")
|
||||
if err != nil {
|
||||
t.Fatalf("PRAGMA: %v", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
var haveKeeper, haveVictim bool
|
||||
for rows.Next() {
|
||||
var (
|
||||
cid int
|
||||
name string
|
||||
valueType string
|
||||
notNull int
|
||||
defaultV sql.NullString
|
||||
pk int
|
||||
)
|
||||
if err := rows.Scan(&cid, &name, &valueType, ¬Null, &defaultV, &pk); err != nil {
|
||||
t.Fatalf("scan: %v", err)
|
||||
}
|
||||
switch name {
|
||||
case "keeper":
|
||||
haveKeeper = true
|
||||
case "victim":
|
||||
haveVictim = true
|
||||
}
|
||||
}
|
||||
if !haveKeeper {
|
||||
t.Fatal("keeper column disappeared — dropColumnIfExists is too aggressive")
|
||||
}
|
||||
if haveVictim {
|
||||
t.Fatal("victim column survived — dropColumnIfExists didn't actually drop")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunMigrationsRejectsDuplicateID(t *testing.T) {
|
||||
db := openRawDB(t)
|
||||
orig := migrations
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue