Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
bobimicroweber committed Apr 24, 2024
1 parent b265c15 commit 2325192
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 13 deletions.
44 changes: 44 additions & 0 deletions web/app/Console/Commands/RunBackup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace App\Console\Commands;

use App\Models\Backup;
use App\Models\HostingSubscription;
use Illuminate\Console\Command;

class RunBackup extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'phyre:run-backup';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';

/**
* Execute the console command.
*/
public function handle()
{
// Delete backups older than 7 days
$findBackupsForDeleting = Backup::where('created_at', '<', now()->subDays(7))->get();
foreach ($findBackupsForDeleting as $backup) {
$backup->delete();
}

$getBackups = Backup::where('backup_type', 'hosting_subscription')->get();
if ($getBackups->count() > 0) {
foreach ($getBackups as $backup) {
$status = $backup->startBackup();
}
}

}
}
45 changes: 45 additions & 0 deletions web/app/Filament/Enums/BackupType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace App\Filament\Enums;

use Filament\Support\Contracts\HasLabel;
use JaOcero\RadioDeck\Contracts\HasDescriptions;
use JaOcero\RadioDeck\Contracts\HasIcons;

enum BackupType: string implements HasLabel, HasDescriptions, HasIcons
{

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

public function getDescriptions(): ?string
{
return match ($this) {
self::FULL_BACKUP => 'A full backup is a complete copy of your website files and database. It is the best way to protect your website data.',
self::SYSTEM_BACKUP => 'A system backup is a copy of your website files and system files. It is useful for restoring your website if there is a problem with the system files.',
self::DATABASE_BACKUP => 'A database backup is a copy of your website database. It is useful for restoring your website if there is a problem with the database.',
self::HOSTING_SUBSCRIPTION_BACKUP => 'A hosting subscription backup is a copy of your website files and database. It is useful for restoring your website if there is a problem with the hosting subscription.',
};
}

public function getIcons(): ?string
{
return match ($this) {
self::FULL_BACKUP => 'heroicon-o-inbox-stack',
self::SYSTEM_BACKUP => 'heroicon-o-cog',
self::DATABASE_BACKUP => 'phyre-mysql',
self::HOSTING_SUBSCRIPTION_BACKUP => 'heroicon-o-server',
};
}
}
40 changes: 37 additions & 3 deletions web/app/Filament/Resources/BackupResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,22 @@

namespace App\Filament\Resources;

use App\Filament\Enums\BackupType;
use App\Filament\Resources\BackupResource\Pages;
use App\Models\Backup;
use App\Models\HostingSubscription;
use Filament\Forms\Components\Select;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;
use JaOcero\RadioDeck\Forms\Components\RadioDeck;

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;


class BackupResource extends Resource
{
Expand All @@ -23,15 +33,39 @@ public static function form(Form $form): Form
{
return $form
->schema([
//

RadioDeck::make('backup_type')
->live()
->default('full_backup')
->options(BackupType::class)
->icons(BackupType::class)
->descriptions(BackupType::class)
->required()
->color('primary')
->columnSpanFull(),


Select::make('hosting_subscription_id')
->label('Hosting Subscription')
->hidden(function (Get $get) {
return $get('backup_type') !== 'hosting_subscription';
})
->options(
HostingSubscription::all()->pluck('domain', 'id')
)
->columnSpanFull()
->required(),

]);
}

public static function table(Table $table): Table
{
return $table
->columns([
//
Tables\Columns\TextColumn::make('backup_type'),
Tables\Columns\TextColumn::make('backupRelated'),
Tables\Columns\TextColumn::make('status'),
])
->filters([
//
Expand Down Expand Up @@ -59,7 +93,7 @@ public static function getPages(): array
return [
'index' => Pages\ListBackups::route('/'),
'create' => Pages\CreateBackup::route('/create'),
'edit' => Pages\EditBackup::route('/{record}/edit'),
'view' => Pages\ViewBackup::route('/{record}'),
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

use App\Filament\Resources\BackupResource;
use Filament\Actions;
use Filament\Resources\Pages\EditRecord;
use Filament\Resources\Pages\ViewRecord;

class EditBackup extends EditRecord
class ViewBackup extends ViewRecord
{
protected static string $resource = BackupResource::class;

Expand Down
97 changes: 97 additions & 0 deletions web/app/Models/Backup.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,104 @@

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Support\Str;

class Backup extends Model
{
use HasFactory;

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

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 startBackup()
{

if ($this->status == 'running') {
return [
'status' => 'running',
'message' => 'Backup already running'
];
}

$storagePath = storage_path('backups');
if (! is_dir($storagePath)) {
mkdir($storagePath);
}
$backupPath = $storagePath.'/'.$this->id;
if (! is_dir($backupPath)) {
mkdir($backupPath);
}
$backupTempPath = $backupPath.'/temp';
if (! is_dir($backupTempPath)) {
mkdir($backupTempPath);
}
if ($this->backup_type == 'hosting_subscription') {
$findHostingSubscription = HostingSubscription::where('id', $this->hosting_subscription_id)->first();
if ($findHostingSubscription) {

$backupFileName = Str::slug($findHostingSubscription->domain .'-'. date('Y-m-d-H-i-s')) . '.zip';
$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 .' && zip -r '.$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;

$this->status = 'running';
$this->queued = true;
$this->queued_at = now();
$this->save();

file_put_contents($backupTempScript, $shellFileContent);
shell_exec('bash '.$backupTempScript.' >> ' . $backupLogFilePath . ' &');

return [
'status' => 'running',
'message' => 'Backup started'
];

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

}
}
1 change: 0 additions & 1 deletion web/app/Models/HostingSubscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ private function _createLinuxWebUser($model): array
return [];

}

private static function _generateUsername($string)
{
$removedMultispace = preg_replace('/\s+/', ' ', $string);
Expand Down
16 changes: 9 additions & 7 deletions web/app/Providers/Filament/AdminPanelProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ public function panel(Panel $panel): Panel
$defaultColor = Color::Yellow;
$brandLogo = asset('images/phyre-logo.svg');

$isAppInstalled = file_exists(storage_path('installed'));
if ($isAppInstalled) {
if (setting('general.brand_logo_url')) {
$brandLogo = setting('general.brand_logo_url');
}
if (setting('general.brand_primary_color')) {
$defaultColor = Color::hex(setting('general.brand_primary_color'));
if (!app()->runningInConsole()) {
$isAppInstalled = file_exists(storage_path('installed'));
if ($isAppInstalled) {
if (setting('general.brand_logo_url')) {
$brandLogo = setting('general.brand_logo_url');
}
if (setting('general.brand_primary_color')) {
$defaultColor = Color::hex(setting('general.brand_primary_color'));
}
}
}

Expand Down
51 changes: 51 additions & 0 deletions web/database/migrations/2024_04_24_144158_create_backups_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('backups', function (Blueprint $table) {
$table->id();
$table->bigInteger('hosting_subscription_id')->nullable();
$table->string('backup_type')->nullable();
$table->string('status')->nullable();
$table->string('path')->nullable();
$table->string('size')->nullable();
$table->string('disk')->nullable();
$table->longText('settings')->nullable();


$table->tinyInteger('queued')->nullable();
$table->timestamp('queued_at')->nullable();

$table->tinyInteger('started')->nullable();
$table->timestamp('started_at')->nullable();

$table->tinyInteger('completed')->nullable();
$table->timestamp('completed_at')->nullable();

$table->tinyInteger('failed')->nullable();
$table->timestamp('failed_at')->nullable();

$table->tinyInteger('cancelled')->nullable();
$table->timestamp('cancelled_at')->nullable();

$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('backups');
}
};

0 comments on commit 2325192

Please sign in to comment.