new deployer command

This commit is contained in:
Mark Gregory
2026-09-16 11:01:02 +01:00
parent 0756b1de79
commit 45a370ed91
20 changed files with 193 additions and 161 deletions
+51 -51
View File
@@ -40,11 +40,11 @@ class DatabaseStage extends Command
];
foreach ([
'STAGE_SSH_HOST' => $stage['ssh_host'],
'STAGE_SSH_USER' => $stage['ssh_user'],
'STAGE_DB_DATABASE' => $stage['database'],
'STAGE_DB_USERNAME' => $stage['username'],
] as $name => $value) {
'STAGE_SSH_HOST' => $stage['ssh_host'],
'STAGE_SSH_USER' => $stage['ssh_user'],
'STAGE_DB_DATABASE' => $stage['database'],
'STAGE_DB_USERNAME' => $stage['username'],
] as $name => $value) {
if (! $value) {
$this->error("Missing {$name}.");
@@ -69,14 +69,14 @@ class DatabaseStage extends Command
['Stage server', "{$stage['ssh_user']}@{$stage['ssh_host']}"],
['Stage database', $stage['database']],
['Stage owner', $stage['username']],
]
],
);
if (
! $this->option('force') &&
! $this->confirm(
"This will DROP and completely RECREATE '{$stage['database']}'. Continue?",
false
false,
)
) {
$this->warn('Cancelled.');
@@ -110,9 +110,9 @@ class DatabaseStage extends Command
'PGPASSWORD' => $local['password'],
])->timeout(3600)->run([
'pg_dump',
'--host='.$local['host'],
'--port='.$local['port'],
'--username='.$local['username'],
'--host=' . $local['host'],
'--port=' . $local['port'],
'--username=' . $local['username'],
// Custom archive format.
'--format=custom',
@@ -127,14 +127,14 @@ class DatabaseStage extends Command
'--no-acl',
// Include everything in the database.
'--file='.$localDump,
'--file=' . $localDump,
$local['database'],
]);
if ($result->failed()) {
throw new RuntimeException(
"pg_dump failed:\n".$result->errorOutput()
"pg_dump failed:\n" . $result->errorOutput(),
);
}
@@ -143,7 +143,7 @@ class DatabaseStage extends Command
}
return true;
}
},
);
$dumpSize = $this->formatBytes(filesize($localDump));
@@ -167,12 +167,12 @@ class DatabaseStage extends Command
if ($result->failed()) {
throw new RuntimeException(
"Invalid PostgreSQL archive:\n".$result->errorOutput()
"Invalid PostgreSQL archive:\n" . $result->errorOutput(),
);
}
return true;
}
},
);
/*
@@ -194,12 +194,12 @@ class DatabaseStage extends Command
if ($result->failed()) {
throw new RuntimeException(
"Upload failed:\n".$result->errorOutput()
"Upload failed:\n" . $result->errorOutput(),
);
}
return true;
}
},
);
/*
@@ -220,7 +220,7 @@ class DatabaseStage extends Command
$terminateDatabase = str_replace(
"'",
"''",
$stage['database']
$stage['database'],
);
$sql = <<<SQL
@@ -238,7 +238,7 @@ SQL;
$remoteCommand = sprintf(
'sudo -u %s psql --set ON_ERROR_STOP=on --dbname=postgres',
escapeshellarg($stage['admin_username'])
escapeshellarg($stage['admin_username']),
);
$result = Process::input($sql)
@@ -253,13 +253,13 @@ SQL;
if ($result->failed()) {
throw new RuntimeException(
"Unable to recreate stage database:\n".
$result->errorOutput()
"Unable to recreate stage database:\n" .
$result->errorOutput(),
);
}
return true;
}
},
);
/*
@@ -272,15 +272,15 @@ SQL;
'Restoring complete stage database',
function () use ($stage, $remoteDump) {
$restore = sprintf(
'PGPASSWORD=%s pg_restore '.
'--host=%s '.
'--port=%s '.
'--username=%s '.
'--dbname=%s '.
'--no-owner '.
'--no-acl '.
'--exit-on-error '.
'--verbose '.
'PGPASSWORD=%s pg_restore ' .
'--host=%s ' .
'--port=%s ' .
'--username=%s ' .
'--dbname=%s ' .
'--no-owner ' .
'--no-acl ' .
'--exit-on-error ' .
'--verbose ' .
'%s',
escapeshellarg($stage['password']),
escapeshellarg($stage['db_host']),
@@ -300,13 +300,13 @@ SQL;
if ($result->failed()) {
throw new RuntimeException(
"Database restore failed:\n".
$result->errorOutput()
"Database restore failed:\n" .
$result->errorOutput(),
);
}
return true;
}
},
);
/*
@@ -319,12 +319,12 @@ SQL;
'Verifying restored database',
function () use ($stage) {
$command = sprintf(
'PGPASSWORD=%s psql '.
'--host=%s '.
'--port=%s '.
'--username=%s '.
'--dbname=%s '.
'--tuples-only '.
'PGPASSWORD=%s psql ' .
'--host=%s ' .
'--port=%s ' .
'--username=%s ' .
'--dbname=%s ' .
'--tuples-only ' .
'--command=%s',
escapeshellarg($stage['password']),
escapeshellarg($stage['db_host']),
@@ -332,7 +332,7 @@ SQL;
escapeshellarg($stage['username']),
escapeshellarg($stage['database']),
escapeshellarg(
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';"
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';",
),
);
@@ -346,8 +346,8 @@ SQL;
if ($result->failed()) {
throw new RuntimeException(
"Database verification failed:\n".
$result->errorOutput()
"Database verification failed:\n" .
$result->errorOutput(),
);
}
@@ -356,7 +356,7 @@ SQL;
$this->line(" Stage public tables: {$count}");
return true;
}
},
);
/*
@@ -381,11 +381,11 @@ SQL;
$this->newLine();
$this->components->info(
'Stage PostgreSQL database cloned successfully.'
'Stage PostgreSQL database cloned successfully.',
);
$this->line(
"Local {$local['database']} → Stage {$stage['database']}"
"Local {$local['database']} → Stage {$stage['database']}",
);
return self::SUCCESS;
@@ -396,7 +396,7 @@ SQL;
$this->newLine();
$this->warn(
"The dump may still exist at {$localDump} and/or {$remoteDump}."
"The dump may still exist at {$localDump} and/or {$remoteDump}.",
);
return self::FAILURE;
@@ -405,7 +405,7 @@ SQL;
private function quoteSqlIdentifier(string $identifier): string
{
return '"'.str_replace('"', '""', $identifier).'"';
return '"' . str_replace('"', '""', $identifier) . '"';
}
private function formatBytes(int $bytes): string
@@ -418,8 +418,8 @@ SQL;
: 0;
return number_format(
$bytes / (1024 ** $power),
$power === 0 ? 0 : 2
).' '.$units[$power];
$bytes / (1024 ** $power),
$power === 0 ? 0 : 2,
) . ' ' . $units[$power];
}
}