Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
bobimicroweber committed Apr 25, 2024
1 parent a5e691d commit 91deabb
Show file tree
Hide file tree
Showing 6 changed files with 211 additions and 106 deletions.
42 changes: 21 additions & 21 deletions web/app/Console/Commands/RunBackup.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,27 @@ public function handle()
$backup->delete();
}

// Find Hosting Subscriptions
$findHostingSubscriptions = HostingSubscription::all();
if ($findHostingSubscriptions->count() > 0) {
foreach ($findHostingSubscriptions as $hostingSubscription) {

$findBackup = Backup::where('hosting_subscription_id', $hostingSubscription->id)
->where('backup_type', 'hosting_subscription')
->where('created_at', '>=', Carbon::now()->subHours(24))
->first();
if (! $findBackup) {
$backup = new Backup();
$backup->hosting_subscription_id = $hostingSubscription->id;
$backup->backup_type = 'hosting_subscription';
$backup->status = 'pending';
$backup->save();
} else {
$this->error('Backup already exists for ' . $hostingSubscription->domain);
$this->error('Created before: ' . $findBackup->created_at->diffForHumans());
}
}
}
// // Find Hosting Subscriptions
// $findHostingSubscriptions = HostingSubscription::all();
// if ($findHostingSubscriptions->count() > 0) {
// foreach ($findHostingSubscriptions as $hostingSubscription) {
//
// $findBackup = Backup::where('hosting_subscription_id', $hostingSubscription->id)
// ->where('backup_type', 'hosting_subscription')
// ->where('created_at', '>=', Carbon::now()->subHours(24))
// ->first();
// if (! $findBackup) {
// $backup = new Backup();
// $backup->hosting_subscription_id = $hostingSubscription->id;
// $backup->backup_type = 'hosting_subscription';
// $backup->status = 'pending';
// $backup->save();
// } else {
// $this->error('Backup already exists for ' . $hostingSubscription->domain);
// $this->error('Created before: ' . $findBackup->created_at->diffForHumans());
// }
// }
// }

// Check for pending backups
$getPendingBackups = Backup::where('status', 'pending')
Expand Down
8 changes: 4 additions & 4 deletions web/app/Filament/Enums/BackupType.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ enum BackupType: string implements HasLabel, HasDescriptions, HasIcons

case FULL_BACKUP = 'full';
case SYSTEM_BACKUP = 'system';
case HOSTING_SUBSCRIPTION_BACKUP = 'hosting_subscription';
//case HOSTING_SUBSCRIPTION_BACKUP = 'hosting_subscription';
public function getLabel(): ?string
{
return match ($this) {
self::FULL_BACKUP => 'Full Backup',
self::SYSTEM_BACKUP => 'System',
self::HOSTING_SUBSCRIPTION_BACKUP => 'Hosting Subscription Backup',
// self::HOSTING_SUBSCRIPTION_BACKUP => 'Hosting Subscription Backup',
};
}

Expand All @@ -26,7 +26,7 @@ public function getDescriptions(): ?string
return match ($this) {
self::FULL_BACKUP => 'A full backup of the server. Includes phyre system full configuration and hosting subscriptions.',
self::SYSTEM_BACKUP => 'A backup of the phyre system full configuration',
self::HOSTING_SUBSCRIPTION_BACKUP => 'A backup of a hosting subscription',
// self::HOSTING_SUBSCRIPTION_BACKUP => 'A backup of a hosting subscription',
};
}

Expand All @@ -35,7 +35,7 @@ public function getIcons(): ?string
return match ($this) {
self::FULL_BACKUP => 'heroicon-o-inbox-stack',
self::SYSTEM_BACKUP => 'heroicon-o-cog',
self::HOSTING_SUBSCRIPTION_BACKUP => 'heroicon-o-server',
// self::HOSTING_SUBSCRIPTION_BACKUP => 'heroicon-o-server',
};
}
}
5 changes: 2 additions & 3 deletions web/app/Filament/Resources/BackupResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,8 @@ public static function table(Table $table): Table
{
return $table
->columns([
// Tables\Columns\TextColumn::make('process_id'),
// Tables\Columns\TextColumn::make('backup_type'),
Tables\Columns\TextColumn::make('backupRelated'),
Tables\Columns\TextColumn::make('backup_type'),

Tables\Columns\BadgeColumn::make('status')
->badge(),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ public function getTabs(): array
{
return [
null => Tab::make('All'),
'system' => Tab::make()->query(fn ($query) => $query->where('backup_type', 'system')),
'completed' => Tab::make()->query(fn ($query) => $query->where('status', 'completed')),
'processing' => Tab::make()->query(fn ($query) => $query->where('status', 'processing')),
'failed' => Tab::make()->query(fn ($query) => $query->where('status', 'failed')),
Expand Down
77 changes: 0 additions & 77 deletions web/app/Models/Backup.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ class Backup extends Model
const STATUS_CANCELLED = 'cancelled';

protected $fillable = [
'hosting_subscription_id',
'backup_type',
'status',
'path',
Expand Down Expand Up @@ -68,21 +67,6 @@ public function checkCronJob()
return true;
}

protected function backupRelated() : Attribute
{
$relatedWith = $this->backup_type;
if ($this->backup_type === 'hosting_subscription') {
$findHostingSubscription = HostingSubscription::where('id', $this->hosting_subscription_id)->first();
if ($findHostingSubscription) {
$relatedWith = $findHostingSubscription->domain;
}
}

return Attribute::make(
get: fn () => $relatedWith
);
}

public function checkBackup()
{
if ($this->status == BackupStatus::Processing) {
Expand Down Expand Up @@ -146,67 +130,6 @@ public function startBackup()
mkdir($backupTempPath);
}

if ($this->backup_type == 'hosting_subscription') {
$findHostingSubscription = HostingSubscription::where('id', $this->hosting_subscription_id)->first();
if ($findHostingSubscription) {

$backupFileName = Str::slug($findHostingSubscription->system_username .'-'. date('Ymd-His')) . '.tar.gz';
$backupFilePath = $backupPath.'/'.$backupFileName;

$backupLogFileName = 'backup.log';
$backupLogFilePath = $backupPath.'/'.$backupLogFileName;

$backupTempScript = '/tmp/backup-script-'.$this->id.'.sh';
$shellFileContent = '';
$shellFileContent .= 'echo "Backup up domain: '.$findHostingSubscription->domain . PHP_EOL;
$shellFileContent .= 'echo "Backup filename: '.$backupFileName. PHP_EOL;
$shellFileContent .= 'cp -r /home/'.$findHostingSubscription->system_username.' '.$backupTempPath.PHP_EOL;

$shellFileContent .= 'cd '.$backupTempPath .' && tar -czvf '.$backupFilePath.' ./* '. PHP_EOL;

$shellFileContent .= 'rm -rf '.$backupTempPath.PHP_EOL;
$shellFileContent .= 'echo "Backup complete"' . PHP_EOL;
$shellFileContent .= 'touch ' . $backupPath. '/backup.done' . PHP_EOL;
$shellFileContent .= 'rm -rf ' . $backupTempScript;

file_put_contents($backupTempScript, $shellFileContent);

$processId = shell_exec('bash '.$backupTempScript.' >> ' . $backupLogFilePath . ' & echo $!');
$processId = intval($processId);

if ($processId > 0 && is_numeric($processId)) {

$this->path = $backupPath;
$this->filepath = $backupFilePath;
$this->status = 'processing';
$this->queued = true;
$this->queued_at = now();
$this->process_id = $processId;
$this->save();

return [
'status' => 'processing',
'message' => 'Backup started'
];
} else {
$this->status = 'failed';
$this->save();
return [
'status' => 'failed',
'message' => 'Backup failed to start'
];
}

} else {
$this->status = 'failed';
$this->save();
return [
'status' => 'failed',
'message' => 'Hosting subscription not found'
];
}
}

if ($this->backup_type == 'system') {

// Export Phyre Panel database
Expand Down
184 changes: 184 additions & 0 deletions web/app/Models/HostingSubscriptionBackup.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,194 @@

namespace App\Models;

use App\Filament\Enums\BackupStatus;
use App\Helpers;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class HostingSubscriptionBackup extends Model
{
use HasFactory;

const STATUS_PENDING = 'pending';
const STATUS_PROCESSING = 'processing';
const STATUS_COMPLETED = 'completed';
const STATUS_FAILED = 'failed';
const STATUS_CANCELLED = 'cancelled';

protected $fillable = [
'hosting_subscription_id',
'backup_type',
'status',
'path',
'size',
'disk',
];

protected $casts = [
'status' => BackupStatus::class,
];

public static function boot()
{
parent::boot();

static::creating(function ($model) {
$model->status = 'pending';
$model->checkCronJob();
});

static::created(function ($model) {
$model->startBackup();
});

static::deleting(function ($model) {
if (is_dir($model->path)) {
shell_exec('rm -rf ' . $model->path);
}
});
}

public function checkCronJob()
{
$cronJobCommand = 'phyre-php /usr/local/phyre/web/artisan phyre:run-hosting-subscriptions-backup';
$findCronJob = CronJob::where('command', $cronJobCommand)->first();
if (! $findCronJob) {
$cronJob = new CronJob();
$cronJob->schedule = '*/5 * * * *';
$cronJob->command = $cronJobCommand;
$cronJob->user = 'root';
$cronJob->save();
return false;
}
return true;
}

public function checkBackup()
{
if ($this->status == BackupStatus::Processing) {

$backupDoneFile = $this->path.'/backup.done';
if (file_exists($backupDoneFile)) {
$this->size = Helpers::checkPathSize($this->path);
$this->status = 'completed';
$this->completed = true;
$this->completed_at = now();
$this->save();
return [
'status' => 'completed',
'message' => 'Backup completed'
];
}

$checkProcess = shell_exec('ps -p ' . $this->process_id . ' | grep ' . $this->process_id);
if (Str::contains($checkProcess, $this->process_id)) {

$this->size = Helpers::checkPathSize($this->path);
$this->save();

return [
'status' => 'processing',
'message' => 'Backup is still processing'
];
} else {
$this->status = 'failed';
$this->save();
return [
'status' => 'failed',
'message' => 'Backup failed'
];
}
}
}

public function startBackup()
{
if ($this->status == BackupStatus::Processing) {
return [
'status' => 'processing',
'message' => 'Backup is already processing'
];
}

$storagePath = storage_path('backups');
if (! is_dir($storagePath)) {
mkdir($storagePath);
}
$backupPath = $storagePath.'/'.$this->backup_type.'/'.$this->id;
if (!is_dir(dirname($backupPath))) {
mkdir(dirname($backupPath));
}
if (! is_dir($backupPath)) {
mkdir($backupPath);
}
$backupTempPath = $backupPath.'/temp';
if (! is_dir($backupTempPath)) {
mkdir($backupTempPath);
}

if ($this->backup_type == 'full') {

$findHostingSubscription = HostingSubscription::where('id', $this->hosting_subscription_id)->first();
if ($findHostingSubscription) {

$backupFileName = Str::slug($findHostingSubscription->system_username .'-'. date('Ymd-His')) . '.tar.gz';
$backupFilePath = $backupPath.'/'.$backupFileName;

$backupLogFileName = 'backup.log';
$backupLogFilePath = $backupPath.'/'.$backupLogFileName;

$backupTempScript = '/tmp/backup-script-'.$this->id.'.sh';
$shellFileContent = '';
$shellFileContent .= 'echo "Backup up domain: '.$findHostingSubscription->domain . PHP_EOL;
$shellFileContent .= 'echo "Backup filename: '.$backupFileName. PHP_EOL;
$shellFileContent .= 'cp -r /home/'.$findHostingSubscription->system_username.' '.$backupTempPath.PHP_EOL;

$shellFileContent .= 'cd '.$backupTempPath .' && tar -czvf '.$backupFilePath.' ./* '. PHP_EOL;

$shellFileContent .= 'rm -rf '.$backupTempPath.PHP_EOL;
$shellFileContent .= 'echo "Backup complete"' . PHP_EOL;
$shellFileContent .= 'touch ' . $backupPath. '/backup.done' . PHP_EOL;
$shellFileContent .= 'rm -rf ' . $backupTempScript;

file_put_contents($backupTempScript, $shellFileContent);

$processId = shell_exec('bash '.$backupTempScript.' >> ' . $backupLogFilePath . ' & echo $!');
$processId = intval($processId);

if ($processId > 0 && is_numeric($processId)) {

$this->path = $backupPath;
$this->filepath = $backupFilePath;
$this->status = 'processing';
$this->queued = true;
$this->queued_at = now();
$this->process_id = $processId;
$this->save();

return [
'status' => 'processing',
'message' => 'Backup started'
];
} else {
$this->status = 'failed';
$this->save();
return [
'status' => 'failed',
'message' => 'Backup failed to start'
];
}

} else {
$this->status = 'failed';
$this->save();
return [
'status' => 'failed',
'message' => 'Hosting subscription not found'
];
}
}
}
}

0 comments on commit 91deabb

Please sign in to comment.