2024-01-06 05:24:57 +00:00
< ? php
namespace App\Livewire\Project\Database ;
2025-11-02 14:19:13 +00:00
use App\Models\S3Storage ;
2024-01-06 05:24:57 +00:00
use App\Models\Server ;
2025-08-23 16:50:35 +00:00
use Illuminate\Foundation\Auth\Access\AuthorizesRequests ;
2024-11-04 13:18:16 +00:00
use Illuminate\Support\Facades\Auth ;
2024-01-10 14:42:54 +00:00
use Illuminate\Support\Facades\Storage ;
2024-06-10 20:43:34 +00:00
use Livewire\Component ;
2024-01-06 05:24:57 +00:00
class Import extends Component
{
2025-08-23 16:50:35 +00:00
use AuthorizesRequests ;
2024-04-11 11:20:46 +00:00
public bool $unsupported = false ;
2024-06-10 20:43:34 +00:00
2024-01-06 05:24:57 +00:00
public $resource ;
2024-06-10 20:43:34 +00:00
2024-01-06 05:24:57 +00:00
public $parameters ;
2024-06-10 20:43:34 +00:00
2024-01-10 14:42:54 +00:00
public $containers ;
2024-06-10 20:43:34 +00:00
2024-01-06 05:24:57 +00:00
public bool $scpInProgress = false ;
2024-06-10 20:43:34 +00:00
2024-01-06 05:24:57 +00:00
public bool $importRunning = false ;
2024-04-11 10:13:11 +00:00
public ? string $filename = null ;
2024-06-10 20:43:34 +00:00
2024-04-11 10:13:11 +00:00
public ? string $filesize = null ;
2024-06-10 20:43:34 +00:00
2024-04-11 10:13:11 +00:00
public bool $isUploading = false ;
2024-06-10 20:43:34 +00:00
2024-04-11 10:13:11 +00:00
public int $progress = 0 ;
2024-06-10 20:43:34 +00:00
2024-04-11 10:13:11 +00:00
public bool $error = false ;
2024-01-06 05:24:57 +00:00
public Server $server ;
2024-06-10 20:43:34 +00:00
2024-01-06 05:24:57 +00:00
public string $container ;
2024-06-10 20:43:34 +00:00
2024-01-06 05:24:57 +00:00
public array $importCommands = [];
2024-06-10 20:43:34 +00:00
2025-01-07 12:00:41 +00:00
public bool $dumpAll = false ;
public string $restoreCommandText = '' ;
2025-01-07 13:02:19 +00:00
public string $customLocation = '' ;
2024-01-10 14:42:54 +00:00
public string $postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB' ;
2024-06-10 20:43:34 +00:00
2024-02-24 20:12:34 +00:00
public string $mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE' ;
2024-06-10 20:43:34 +00:00
2024-02-24 20:12:34 +00:00
public string $mariadbRestoreCommand = 'mariadb -u $MARIADB_USER -p$MARIADB_PASSWORD $MARIADB_DATABASE' ;
2024-06-10 20:43:34 +00:00
2024-04-25 21:44:55 +00:00
public string $mongodbRestoreCommand = 'mongorestore --authenticationDatabase=admin --username $MONGO_INITDB_ROOT_USERNAME --password $MONGO_INITDB_ROOT_PASSWORD --uri mongodb://localhost:27017 --gzip --archive=' ;
2024-01-06 05:24:57 +00:00
2025-11-02 14:19:13 +00:00
// S3 Restore properties
public $availableS3Storages = [];
public ? int $s3StorageId = null ;
public string $s3Path = '' ;
public ? string $s3DownloadedFile = null ;
public ? int $s3FileSize = null ;
public bool $s3DownloadInProgress = false ;
2025-11-02 15:57:00 +00:00
public ? int $currentActivityId = null ;
2024-01-10 14:42:54 +00:00
public function getListeners ()
{
2024-11-04 13:18:16 +00:00
$userId = Auth :: id ();
2024-06-10 20:43:34 +00:00
2024-01-10 14:42:54 +00:00
return [
" echo-private:user. { $userId } ,DatabaseStatusChanged " => '$refresh' ,
2025-11-02 16:03:24 +00:00
'S3DownloadFinished' => 'handleS3DownloadFinished' ,
2024-01-10 14:42:54 +00:00
];
}
2024-06-10 20:43:34 +00:00
2025-11-02 16:03:24 +00:00
public function handleS3DownloadFinished () : void
{
$this -> s3DownloadInProgress = false ;
}
2024-01-06 05:24:57 +00:00
public function mount ()
{
2025-01-07 13:02:19 +00:00
if ( isDev ()) {
$this -> customLocation = '/data/coolify/pg-dump-all-1736245863.gz' ;
}
2024-01-06 05:24:57 +00:00
$this -> parameters = get_route_parameters ();
$this -> getContainers ();
2025-11-02 14:19:13 +00:00
$this -> loadAvailableS3Storages ();
2024-01-06 05:24:57 +00:00
}
2025-01-07 12:00:41 +00:00
public function updatedDumpAll ( $value )
{
switch ( $this -> resource -> getMorphClass ()) {
2025-01-07 14:31:43 +00:00
case \App\Models\StandaloneMariadb :: class :
2025-01-07 12:00:41 +00:00
if ( $value === true ) {
$this -> mariadbRestoreCommand = <<< 'EOD'
for pid in $ ( mariadb - u root - p $MARIADB_ROOT_PASSWORD - N - e " SELECT id FROM information_schema.processlist WHERE user != 'root'; " ); do
mariadb - u root - p $MARIADB_ROOT_PASSWORD - e " KILL $pid " 2 >/ dev / null || true
done && \
mariadb - u root - p $MARIADB_ROOT_PASSWORD - N - e " SELECT CONCAT('DROP DATABASE IF EXISTS \ `',schema_name,' \ `;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys'); " | mariadb - u root - p $MARIADB_ROOT_PASSWORD && \
mariadb - u root - p $MARIADB_ROOT_PASSWORD - e " CREATE DATABASE IF NOT EXISTS \ `default \ `; " && \
( gunzip - cf $tmpPath 2 >/ dev / null || cat $tmpPath ) | sed - e '/^CREATE DATABASE/d' - e '/^USE \`mysql\`/d' | mariadb - u root - p $MARIADB_ROOT_PASSWORD default
EOD ;
$this -> restoreCommandText = $this -> mariadbRestoreCommand . ' && (gunzip -cf <temp_backup_file> 2>/dev/null || cat <temp_backup_file>) | mariadb -u root -p$MARIADB_ROOT_PASSWORD default' ;
} else {
$this -> mariadbRestoreCommand = 'mariadb -u $MARIADB_USER -p$MARIADB_PASSWORD $MARIADB_DATABASE' ;
}
break ;
2025-01-07 14:31:43 +00:00
case \App\Models\StandaloneMysql :: class :
2025-01-07 12:00:41 +00:00
if ( $value === true ) {
$this -> mysqlRestoreCommand = <<< 'EOD'
for pid in $ ( mysql - u root - p $MYSQL_ROOT_PASSWORD - N - e " SELECT id FROM information_schema.processlist WHERE user != 'root'; " ); do
mysql - u root - p $MYSQL_ROOT_PASSWORD - e " KILL $pid " 2 >/ dev / null || true
done && \
mysql - u root - p $MYSQL_ROOT_PASSWORD - N - e " SELECT CONCAT('DROP DATABASE IF EXISTS \ `',schema_name,' \ `;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys'); " | mysql - u root - p $MYSQL_ROOT_PASSWORD && \
mysql - u root - p $MYSQL_ROOT_PASSWORD - e " CREATE DATABASE IF NOT EXISTS \ `default \ `; " && \
( gunzip - cf $tmpPath 2 >/ dev / null || cat $tmpPath ) | sed - e '/^CREATE DATABASE/d' - e '/^USE \`mysql\`/d' | mysql - u root - p $MYSQL_ROOT_PASSWORD default
EOD ;
$this -> restoreCommandText = $this -> mysqlRestoreCommand . ' && (gunzip -cf <temp_backup_file> 2>/dev/null || cat <temp_backup_file>) | mysql -u root -p$MYSQL_ROOT_PASSWORD default' ;
} else {
$this -> mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE' ;
}
break ;
2025-01-07 14:31:43 +00:00
case \App\Models\StandalonePostgresql :: class :
2025-01-07 12:00:41 +00:00
if ( $value === true ) {
$this -> postgresqlRestoreCommand = <<< 'EOD'
psql - U $POSTGRES_USER - c " SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname IS NOT NULL AND pid <> pg_backend_pid() " && \
psql - U $POSTGRES_USER - t - c " SELECT datname FROM pg_database WHERE NOT datistemplate " | xargs - I {} dropdb - U $POSTGRES_USER -- if - exists {} && \
createdb - U $POSTGRES_USER postgres
EOD ;
$this -> restoreCommandText = $this -> postgresqlRestoreCommand . ' && (gunzip -cf <temp_backup_file> 2>/dev/null || cat <temp_backup_file>) | psql -U $POSTGRES_USER postgres' ;
} else {
$this -> postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB' ;
}
break ;
}
}
2024-01-06 05:24:57 +00:00
public function getContainers ()
{
$this -> containers = collect ();
2024-06-10 20:43:34 +00:00
if ( ! data_get ( $this -> parameters , 'database_uuid' )) {
2024-01-06 05:24:57 +00:00
abort ( 404 );
}
2024-04-11 10:13:11 +00:00
$resource = getResourceByUuid ( $this -> parameters [ 'database_uuid' ], data_get ( auth () -> user () -> currentTeam (), 'id' ));
2024-01-06 05:24:57 +00:00
if ( is_null ( $resource )) {
2024-04-10 13:00:46 +00:00
abort ( 404 );
2024-01-06 05:24:57 +00:00
}
2025-10-14 15:33:42 +00:00
$this -> authorize ( 'view' , $resource );
2024-01-06 05:24:57 +00:00
$this -> resource = $resource ;
$this -> server = $this -> resource -> destination -> server ;
$this -> container = $this -> resource -> uuid ;
2024-01-10 14:42:54 +00:00
if ( str ( data_get ( $this , 'resource.status' )) -> startsWith ( 'running' )) {
2024-01-06 05:24:57 +00:00
$this -> containers -> push ( $this -> container );
}
2024-01-10 14:42:54 +00:00
if (
2025-01-07 14:31:43 +00:00
$this -> resource -> getMorphClass () === \App\Models\StandaloneRedis :: class ||
$this -> resource -> getMorphClass () === \App\Models\StandaloneKeydb :: class ||
$this -> resource -> getMorphClass () === \App\Models\StandaloneDragonfly :: class ||
$this -> resource -> getMorphClass () === \App\Models\StandaloneClickhouse :: class
2024-01-10 14:42:54 +00:00
) {
2024-04-11 11:20:46 +00:00
$this -> unsupported = true ;
2024-01-06 05:24:57 +00:00
}
}
2024-01-10 14:42:54 +00:00
2025-01-07 13:02:19 +00:00
public function checkFile ()
{
if ( filled ( $this -> customLocation )) {
try {
$result = instant_remote_process ([ " ls -l { $this -> customLocation } " ], $this -> server , throwError : false );
if ( blank ( $result )) {
$this -> dispatch ( 'error' , 'The file does not exist or has been deleted.' );
2025-01-07 14:31:43 +00:00
return ;
2025-01-07 13:02:19 +00:00
}
$this -> filename = $this -> customLocation ;
$this -> dispatch ( 'success' , 'The file exists.' );
2025-01-07 14:31:43 +00:00
} catch ( \Throwable $e ) {
2025-01-07 13:02:19 +00:00
return handleError ( $e , $this );
}
}
}
2024-01-06 05:24:57 +00:00
public function runImport ()
{
2025-08-23 16:50:35 +00:00
$this -> authorize ( 'update' , $this -> resource );
2024-10-31 14:23:19 +00:00
if ( $this -> filename === '' ) {
2024-04-11 10:13:11 +00:00
$this -> dispatch ( 'error' , 'Please select a file to import.' );
2024-06-10 20:43:34 +00:00
2025-01-07 14:31:43 +00:00
return ;
2024-04-11 10:13:11 +00:00
}
2024-01-06 05:24:57 +00:00
try {
2025-08-26 08:27:31 +00:00
$this -> importRunning = true ;
2025-01-07 13:02:19 +00:00
$this -> importCommands = [];
if ( filled ( $this -> customLocation )) {
$backupFileName = '/tmp/restore_' . $this -> resource -> uuid ;
$this -> importCommands [] = " docker cp { $this -> customLocation } { $this -> container } : { $backupFileName } " ;
$tmpPath = $backupFileName ;
} else {
$backupFileName = " upload/ { $this -> resource -> uuid } /restore " ;
$path = Storage :: path ( $backupFileName );
if ( ! Storage :: exists ( $backupFileName )) {
$this -> dispatch ( 'error' , 'The file does not exist or has been deleted.' );
2025-01-07 14:31:43 +00:00
return ;
2025-01-07 13:02:19 +00:00
}
$tmpPath = '/tmp/' . basename ( $backupFileName ) . '_' . $this -> resource -> uuid ;
instant_scp ( $path , $tmpPath , $this -> server );
Storage :: delete ( $backupFileName );
$this -> importCommands [] = " docker cp { $tmpPath } { $this -> container } : { $tmpPath } " ;
2024-04-11 10:13:11 +00:00
}
2024-01-06 05:24:57 +00:00
2025-01-07 12:00:41 +00:00
// Copy the restore command to a script file
$scriptPath = " /tmp/restore_ { $this -> resource -> uuid } .sh " ;
2024-01-06 05:24:57 +00:00
switch ( $this -> resource -> getMorphClass ()) {
2025-01-07 14:31:43 +00:00
case \App\Models\StandaloneMariadb :: class :
2025-01-07 12:00:41 +00:00
$restoreCommand = $this -> mariadbRestoreCommand ;
if ( $this -> dumpAll ) {
$restoreCommand .= " && (gunzip -cf { $tmpPath } 2>/dev/null || cat { $tmpPath } ) | mariadb -u root -p \$ MARIADB_ROOT_PASSWORD " ;
} else {
2025-01-07 13:08:38 +00:00
$restoreCommand .= " < { $tmpPath } " ;
2025-01-07 12:00:41 +00:00
}
2024-01-10 14:42:54 +00:00
break ;
2025-01-07 14:31:43 +00:00
case \App\Models\StandaloneMysql :: class :
2025-01-07 12:00:41 +00:00
$restoreCommand = $this -> mysqlRestoreCommand ;
if ( $this -> dumpAll ) {
$restoreCommand .= " && (gunzip -cf { $tmpPath } 2>/dev/null || cat { $tmpPath } ) | mysql -u root -p \$ MYSQL_ROOT_PASSWORD " ;
} else {
2025-01-07 13:08:38 +00:00
$restoreCommand .= " < { $tmpPath } " ;
2025-01-07 12:00:41 +00:00
}
2024-01-10 14:42:54 +00:00
break ;
2025-01-07 14:31:43 +00:00
case \App\Models\StandalonePostgresql :: class :
2025-01-07 12:00:41 +00:00
$restoreCommand = $this -> postgresqlRestoreCommand ;
if ( $this -> dumpAll ) {
$restoreCommand .= " && (gunzip -cf { $tmpPath } 2>/dev/null || cat { $tmpPath } ) | psql -U \$ POSTGRES_USER postgres " ;
} else {
$restoreCommand .= " { $tmpPath } " ;
}
2024-01-10 14:42:54 +00:00
break ;
2025-01-07 14:31:43 +00:00
case \App\Models\StandaloneMongodb :: class :
2025-01-07 12:00:41 +00:00
$restoreCommand = $this -> mongodbRestoreCommand ;
if ( $this -> dumpAll === false ) {
2025-01-28 11:41:22 +00:00
$restoreCommand .= " { $tmpPath } " ;
2025-01-07 12:00:41 +00:00
}
2024-04-14 20:31:55 +00:00
break ;
2024-01-06 05:24:57 +00:00
}
2025-09-15 15:56:48 +00:00
$restoreCommandBase64 = base64_encode ( $restoreCommand );
$this -> importCommands [] = " echo \" { $restoreCommandBase64 } \" | base64 -d > { $scriptPath } " ;
2025-01-07 12:00:41 +00:00
$this -> importCommands [] = " chmod +x { $scriptPath } " ;
$this -> importCommands [] = " docker cp { $scriptPath } { $this -> container } : { $scriptPath } " ;
$this -> importCommands [] = " docker exec { $this -> container } sh -c ' { $scriptPath } ' " ;
2024-01-06 05:24:57 +00:00
$this -> importCommands [] = " docker exec { $this -> container } sh -c 'echo \" Import finished with exit code $ ? \" ' " ;
2025-01-07 14:31:43 +00:00
if ( ! empty ( $this -> importCommands )) {
2025-01-07 13:02:19 +00:00
$activity = remote_process ( $this -> importCommands , $this -> server , ignore_errors : true , callEventOnFinish : 'RestoreJobFinished' , callEventData : [
'scriptPath' => $scriptPath ,
'tmpPath' => $tmpPath ,
'container' => $this -> container ,
'serverId' => $this -> server -> id ,
]);
2025-11-02 15:57:00 +00:00
$this -> currentActivityId = $activity -> id ;
2024-01-06 05:24:57 +00:00
}
2025-01-07 14:31:43 +00:00
} catch ( \Throwable $e ) {
2024-04-11 10:13:11 +00:00
return handleError ( $e , $this );
2025-01-07 12:00:41 +00:00
} finally {
$this -> filename = null ;
2025-01-07 13:02:19 +00:00
$this -> importCommands = [];
2024-01-06 05:24:57 +00:00
}
}
2025-11-02 14:19:13 +00:00
public function loadAvailableS3Storages ()
{
try {
$this -> availableS3Storages = S3Storage :: ownedByCurrentTeam ([ 'id' , 'name' , 'description' ])
-> where ( 'is_usable' , true )
-> get ();
} catch ( \Throwable $e ) {
$this -> availableS3Storages = collect ();
ray ( $e );
}
}
public function checkS3File ()
{
if ( ! $this -> s3StorageId ) {
$this -> dispatch ( 'error' , 'Please select an S3 storage.' );
return ;
}
if ( blank ( $this -> s3Path )) {
$this -> dispatch ( 'error' , 'Please provide an S3 path.' );
return ;
}
try {
2025-11-02 15:33:34 +00:00
$s3Storage = S3Storage :: ownedByCurrentTeam () -> findOrFail ( $this -> s3StorageId );
2025-11-02 14:19:13 +00:00
// Test connection
$s3Storage -> testConnection ();
// Build S3 disk configuration
$disk = Storage :: build ([
'driver' => 's3' ,
'region' => $s3Storage -> region ,
'key' => $s3Storage -> key ,
'secret' => $s3Storage -> secret ,
'bucket' => $s3Storage -> bucket ,
'endpoint' => $s3Storage -> endpoint ,
'use_path_style_endpoint' => true ,
]);
// Clean the path (remove leading slash if present)
$cleanPath = ltrim ( $this -> s3Path , '/' );
// Check if file exists
if ( ! $disk -> exists ( $cleanPath )) {
$this -> dispatch ( 'error' , 'File not found in S3. Please check the path.' );
return ;
}
// Get file size
$this -> s3FileSize = $disk -> size ( $cleanPath );
$this -> dispatch ( 'success' , 'File found in S3. Size: ' . formatBytes ( $this -> s3FileSize ));
} catch ( \Throwable $e ) {
$this -> s3FileSize = null ;
return handleError ( $e , $this );
}
}
public function downloadFromS3 ()
{
$this -> authorize ( 'update' , $this -> resource );
if ( ! $this -> s3StorageId || blank ( $this -> s3Path )) {
$this -> dispatch ( 'error' , 'Please select S3 storage and provide a path first.' );
return ;
}
if ( is_null ( $this -> s3FileSize )) {
$this -> dispatch ( 'error' , 'Please check the file first by clicking "Check File".' );
return ;
}
try {
$this -> s3DownloadInProgress = true ;
2025-11-02 15:33:34 +00:00
$s3Storage = S3Storage :: ownedByCurrentTeam () -> findOrFail ( $this -> s3StorageId );
2025-11-02 14:19:13 +00:00
$key = $s3Storage -> key ;
$secret = $s3Storage -> secret ;
$bucket = $s3Storage -> bucket ;
$endpoint = $s3Storage -> endpoint ;
// Clean the path
$cleanPath = ltrim ( $this -> s3Path , '/' );
// Create temporary download directory
$downloadDir = " /tmp/s3-restore- { $this -> resource -> uuid } " ;
$downloadPath = " { $downloadDir } / " . basename ( $cleanPath );
// Get helper image
$helperImage = config ( 'constants.coolify.helper_image' );
$latestVersion = instanceSettings () -> helper_version ;
$fullImageName = " { $helperImage } : { $latestVersion } " ;
// Prepare download commands
$commands = [];
// Create download directory on server
$commands [] = " mkdir -p { $downloadDir } " ;
// Check if container exists and remove it
$containerName = " s3-restore- { $this -> resource -> uuid } " ;
$containerExists = instant_remote_process ([ " docker ps -a -q -f name= { $containerName } " ], $this -> server , false );
if ( filled ( $containerExists )) {
instant_remote_process ([ " docker rm -f { $containerName } " ], $this -> server , false );
}
// Run MinIO client container to download file
$commands [] = " docker run -d --name { $containerName } --rm -v { $downloadDir } : { $downloadDir } { $fullImageName } sleep 30 " ;
$commands [] = " docker exec { $containerName } mc alias set temporary { $endpoint } { $key } \" { $secret } \" " ;
$commands [] = " docker exec { $containerName } mc cp temporary/ { $bucket } / { $cleanPath } { $downloadPath } " ;
// Execute download commands
$activity = remote_process ( $commands , $this -> server , ignore_errors : false , callEventOnFinish : 'S3DownloadFinished' , callEventData : [
'downloadPath' => $downloadPath ,
'containerName' => $containerName ,
'serverId' => $this -> server -> id ,
'resourceUuid' => $this -> resource -> uuid ,
]);
$this -> s3DownloadedFile = $downloadPath ;
$this -> filename = $downloadPath ;
2025-11-02 15:57:00 +00:00
$this -> currentActivityId = $activity -> id ;
2025-11-02 14:19:13 +00:00
$this -> dispatch ( 'info' , 'Downloading file from S3. This may take a few minutes for large backups...' );
} catch ( \Throwable $e ) {
$this -> s3DownloadInProgress = false ;
$this -> s3DownloadedFile = null ;
return handleError ( $e , $this );
}
}
public function restoreFromS3 ()
{
$this -> authorize ( 'update' , $this -> resource );
if ( ! $this -> s3DownloadedFile ) {
$this -> dispatch ( 'error' , 'Please download the file from S3 first.' );
return ;
}
try {
$this -> importRunning = true ;
$this -> importCommands = [];
// Use the downloaded file path
$backupFileName = '/tmp/restore_' . $this -> resource -> uuid ;
$this -> importCommands [] = " docker cp { $this -> s3DownloadedFile } { $this -> container } : { $backupFileName } " ;
$tmpPath = $backupFileName ;
// Copy the restore command to a script file
$scriptPath = " /tmp/restore_ { $this -> resource -> uuid } .sh " ;
switch ( $this -> resource -> getMorphClass ()) {
case \App\Models\StandaloneMariadb :: class :
$restoreCommand = $this -> mariadbRestoreCommand ;
if ( $this -> dumpAll ) {
$restoreCommand .= " && (gunzip -cf { $tmpPath } 2>/dev/null || cat { $tmpPath } ) | mariadb -u root -p \$ MARIADB_ROOT_PASSWORD " ;
} else {
$restoreCommand .= " < { $tmpPath } " ;
}
break ;
case \App\Models\StandaloneMysql :: class :
$restoreCommand = $this -> mysqlRestoreCommand ;
if ( $this -> dumpAll ) {
$restoreCommand .= " && (gunzip -cf { $tmpPath } 2>/dev/null || cat { $tmpPath } ) | mysql -u root -p \$ MYSQL_ROOT_PASSWORD " ;
} else {
$restoreCommand .= " < { $tmpPath } " ;
}
break ;
case \App\Models\StandalonePostgresql :: class :
$restoreCommand = $this -> postgresqlRestoreCommand ;
if ( $this -> dumpAll ) {
$restoreCommand .= " && (gunzip -cf { $tmpPath } 2>/dev/null || cat { $tmpPath } ) | psql -U \$ POSTGRES_USER postgres " ;
} else {
$restoreCommand .= " { $tmpPath } " ;
}
break ;
case \App\Models\StandaloneMongodb :: class :
$restoreCommand = $this -> mongodbRestoreCommand ;
if ( $this -> dumpAll === false ) {
$restoreCommand .= " { $tmpPath } " ;
}
break ;
}
$restoreCommandBase64 = base64_encode ( $restoreCommand );
$this -> importCommands [] = " echo \" { $restoreCommandBase64 } \" | base64 -d > { $scriptPath } " ;
$this -> importCommands [] = " chmod +x { $scriptPath } " ;
$this -> importCommands [] = " docker cp { $scriptPath } { $this -> container } : { $scriptPath } " ;
$this -> importCommands [] = " docker exec { $this -> container } sh -c ' { $scriptPath } ' " ;
$this -> importCommands [] = " docker exec { $this -> container } sh -c 'echo \" Import finished with exit code $ ? \" ' " ;
if ( ! empty ( $this -> importCommands )) {
$activity = remote_process ( $this -> importCommands , $this -> server , ignore_errors : true , callEventOnFinish : 'S3RestoreJobFinished' , callEventData : [
'scriptPath' => $scriptPath ,
'tmpPath' => $tmpPath ,
'container' => $this -> container ,
'serverId' => $this -> server -> id ,
's3DownloadedFile' => $this -> s3DownloadedFile ,
'resourceUuid' => $this -> resource -> uuid ,
]);
2025-11-02 15:57:00 +00:00
$this -> currentActivityId = $activity -> id ;
2025-11-02 14:19:13 +00:00
}
} catch ( \Throwable $e ) {
return handleError ( $e , $this );
} finally {
$this -> importCommands = [];
}
}
public function cancelS3Download ()
{
if ( $this -> s3DownloadedFile ) {
try {
// Cleanup downloaded file and directory
$downloadDir = " /tmp/s3-restore- { $this -> resource -> uuid } " ;
instant_remote_process ([ " rm -rf { $downloadDir } " ], $this -> server , false );
// Cleanup container if exists
$containerName = " s3-restore- { $this -> resource -> uuid } " ;
instant_remote_process ([ " docker rm -f { $containerName } " ], $this -> server , false );
$this -> dispatch ( 'success' , 'S3 download cancelled and temporary files cleaned up.' );
} catch ( \Throwable $e ) {
ray ( $e );
}
}
// Reset S3 download state
$this -> s3DownloadedFile = null ;
$this -> s3DownloadInProgress = false ;
2025-11-02 15:57:00 +00:00
$this -> currentActivityId = null ;
2025-11-02 14:19:13 +00:00
$this -> filename = null ;
}
2024-01-06 05:24:57 +00:00
}