mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-06 00:12:35 +00:00
Merge (#127)
This commit is contained in:
@ -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');
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user