This commit is contained in:
Saeed Vaziry
2024-03-24 09:56:34 +01:00
committed by GitHub
parent 884f18db63
commit 4d051330d6
1055 changed files with 14493 additions and 20278 deletions

View File

@ -2,30 +2,14 @@
namespace App\Models;
use App\Contracts\SiteType;
use App\Enums\DeploymentStatus;
use App\Enums\SiteStatus;
use App\Enums\SslStatus;
use App\Events\Broadcast;
use App\Exceptions\SourceControlIsNotConnected;
use App\Facades\Notifier;
use App\Jobs\Site\ChangePHPVersion;
use App\Jobs\Site\Deploy;
use App\Jobs\Site\DeployEnv;
use App\Jobs\Site\UpdateBranch;
use App\Notifications\SiteInstallationFailed;
use App\Notifications\SiteInstallationSucceed;
use App\SSHCommands\Website\GetEnvCommand;
use Exception;
use App\SiteTypes\SiteType;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Throwable;
/**
* @property int $server_id
@ -34,7 +18,6 @@
* @property string $domain
* @property array $aliases
* @property string $web_directory
* @property string $web_directory_path
* @property string $path
* @property string $php_version
* @property string $source_control
@ -45,21 +28,14 @@
* @property string $status
* @property int $port
* @property int $progress
* @property bool $auto_deployment
* @property string $url
* @property Server $server
* @property ServerLog[] $logs
* @property Deployment[] $deployments
* @property ?GitHook $gitHook
* @property DeploymentScript $deploymentScript
* @property Redirect[] $redirects
* @property Queue[] $queues
* @property Ssl[] $ssls
* @property ?Ssl $activeSsl
* @property string $full_repository_url
* @property string $aliases_string
* @property string $deployment_script_text
* @property string $env
* @property string $ssh_key_name
*/
class Site extends AbstractModel
@ -90,22 +66,15 @@ class Site extends AbstractModel
'type_data' => 'json',
'port' => 'integer',
'progress' => 'integer',
'auto_deployment' => 'boolean',
'aliases' => 'array',
'source_control_id' => 'integer',
];
protected $appends = [
'url',
'auto_deployment',
];
public static function boot(): void
{
parent::boot();
static::deleting(function (Site $site) {
$site->redirects()->delete();
$site->queues()->delete();
$site->ssls()->delete();
$site->deployments()->delete();
@ -145,11 +114,6 @@ public function deploymentScript(): HasOne
return $this->hasOne(DeploymentScript::class);
}
public function redirects(): HasMany
{
return $this->hasMany(Redirect::class);
}
public function queues(): HasMany
{
return $this->hasMany(Queue::class);
@ -189,12 +153,12 @@ public function sourceControl(): SourceControl|HasOne|null|Model
/**
* @throws SourceControlIsNotConnected
*/
public function getFullRepositoryUrlAttribute()
public function getFullRepositoryUrl()
{
return $this->sourceControl()->provider()->fullRepoUrl($this->repository, $this->ssh_key_name);
return $this->sourceControl()->provider()->fullRepoUrl($this->repository, $this->getSshKeyName());
}
public function getAliasesStringAttribute(): string
public function getAliasesString(): string
{
if (count($this->aliases) > 0) {
return implode(' ', $this->aliases);
@ -210,19 +174,6 @@ public function type(): SiteType
return new $typeClass($this);
}
public function install(): void
{
$this->type()->install();
}
public function remove(): void
{
$this->update([
'status' => SiteStatus::DELETING,
]);
$this->type()->delete();
}
public function php(): ?Service
{
if ($this->php_version) {
@ -234,63 +185,9 @@ public function php(): ?Service
public function changePHPVersion($version): void
{
dispatch(new ChangePHPVersion($this, $version))->onConnection('ssh');
}
public function getDeploymentScriptTextAttribute(): string
{
/* @var DeploymentScript $script */
$script = $this->deploymentScript()->firstOrCreate([
'site_id' => $this->id,
], [
'site_id' => $this->id,
'name' => 'default',
]);
return $script->content;
}
/**
* @throws SourceControlIsNotConnected
*/
public function deploy(): Deployment
{
if ($this->sourceControl()) {
$this->sourceControl()->getRepo($this->repository);
}
$deployment = new Deployment([
'site_id' => $this->id,
'deployment_script_id' => $this->deploymentScript->id,
'status' => DeploymentStatus::DEPLOYING,
]);
$lastCommit = $this->sourceControl()->provider()->getLastCommit($this->repository, $this->branch);
if ($lastCommit) {
$deployment->commit_id = $lastCommit['commit_id'];
$deployment->commit_data = $lastCommit['commit_data'];
}
$deployment->save();
dispatch(new Deploy($deployment, $this->path))->onConnection('ssh');
return $deployment;
}
public function getEnvAttribute(): string
{
$typeData = $this->type_data;
if (! isset($typeData['env'])) {
$typeData['env'] = '';
$this->type_data = $typeData;
$this->save();
}
return $typeData['env'];
}
public function deployEnv(): void
{
dispatch(new DeployEnv($this))->onConnection('ssh');
$this->server->webserver()->handler()->changePHPVersion($this, $version);
$this->php_version = $version;
$this->save();
}
public function activeSsl(): HasOne
@ -300,33 +197,7 @@ public function activeSsl(): HasOne
->orderByDesc('id');
}
public function createFreeSsl(): void
{
$ssl = new Ssl([
'site_id' => $this->id,
'type' => 'letsencrypt',
'expires_at' => now()->addMonths(3),
'status' => SslStatus::CREATING,
]);
$ssl->save();
$ssl->deploy();
}
public function createCustomSsl(string $certificate, string $pk): void
{
$ssl = new Ssl([
'site_id' => $this->id,
'type' => 'custom',
'certificate' => $certificate,
'pk' => $pk,
'expires_at' => '',
'status' => SslStatus::CREATING,
]);
$ssl->save();
$ssl->deploy();
}
public function getUrlAttribute(): string
public function getUrl(): string
{
if ($this->activeSsl) {
return 'https://'.$this->domain;
@ -335,7 +206,7 @@ public function getUrlAttribute(): string
return 'http://'.$this->domain;
}
public function getWebDirectoryPathAttribute(): string
public function getWebDirectoryPath(): string
{
if ($this->web_directory) {
return $this->path.'/'.$this->web_directory;
@ -346,7 +217,6 @@ public function getWebDirectoryPathAttribute(): string
/**
* @throws SourceControlIsNotConnected
* @throws Throwable
*/
public function enableAutoDeployment(): void
{
@ -354,102 +224,50 @@ public function enableAutoDeployment(): void
return;
}
if (! $this->sourceControl()) {
if (! $this->sourceControl()?->getRepo($this->repository)) {
throw new SourceControlIsNotConnected($this->source_control);
}
DB::beginTransaction();
try {
$gitHook = new GitHook([
'site_id' => $this->id,
'source_control_id' => $this->sourceControl()->id,
'secret' => Str::uuid()->toString(),
'actions' => ['deploy'],
'events' => ['push'],
]);
$gitHook->save();
$gitHook->deployHook();
DB::commit();
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
$gitHook = new GitHook([
'site_id' => $this->id,
'source_control_id' => $this->sourceControl()->id,
'secret' => Str::uuid()->toString(),
'actions' => ['deploy'],
'events' => ['push'],
]);
$gitHook->save();
$gitHook->deployHook();
}
/**
* @throws Throwable
* @throws SourceControlIsNotConnected
*/
public function disableAutoDeployment(): void
{
if (! $this->sourceControl()?->getRepo($this->repository)) {
throw new SourceControlIsNotConnected($this->source_control);
}
$this->gitHook?->destroyHook();
}
public function getAutoDeploymentAttribute(): bool
public function isAutoDeployment(): bool
{
return (bool) $this->gitHook;
}
public function updateBranch(string $branch): void
{
dispatch(new UpdateBranch($this, $branch))->onConnection('ssh');
}
public function getSshKeyNameAttribute(): string
public function getSshKeyName(): string
{
return str('site_'.$this->id)->toString();
}
public function installationFinished(): void
{
$this->update([
'status' => SiteStatus::READY,
'progress' => 100,
]);
event(
new Broadcast('install-site-finished', [
'site' => $this,
])
);
Notifier::send($this, new SiteInstallationSucceed($this));
}
/**
* @throws Throwable
*/
public function installationFailed(Throwable $e): void
{
$this->update([
'status' => SiteStatus::INSTALLATION_FAILED,
]);
event(
new Broadcast('install-site-failed', [
'site' => $this,
])
);
Notifier::send($this, new SiteInstallationFailed($this));
Log::error('install-site-error', [
'error' => (string) $e,
]);
throw $e;
}
public function hasFeature(string $feature): bool
{
return in_array($feature, $this->type()->supportedFeatures());
}
public function isReady(): bool
{
return $this->status === SiteStatus::READY;
}
public function getEnv(): string
{
return $this->server->ssh()->exec(
new GetEnvCommand(
$this->domain
)
);
return $this->server->os()->readFile($this->path.'/.env');
}
}