mirror of
https://github.com/PhyreApps/PhyrePanel.git
synced 2024-11-26 09:30:31 +00:00
229 lines
7.1 KiB
PHP
229 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\GitClient;
|
|
use App\Models\Scopes\CustomerDomainScope;
|
|
use App\Models\Scopes\CustomerHostingSubscriptionScope;
|
|
use App\ShellApi;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use function Psy\sh;
|
|
|
|
class GitRepository extends Model
|
|
{
|
|
use HasFactory;
|
|
|
|
public $timestamps = true;
|
|
|
|
const STATUS_PENDING = 'pending';
|
|
|
|
const STATUS_CLONING = 'cloning';
|
|
const STATUS_CLONED = 'cloned';
|
|
const STATUS_FAILED = 'failed';
|
|
|
|
const STATUS_PULLING = 'pulling';
|
|
|
|
const STATUS_UP_TO_DATE = 'up_to_date';
|
|
|
|
protected $fillable = [
|
|
'name',
|
|
'url',
|
|
'branch',
|
|
'tag',
|
|
'clone_from',
|
|
'last_commit_hash',
|
|
'last_commit_message',
|
|
'last_commit_date',
|
|
'status',
|
|
'status_message',
|
|
'dir',
|
|
'domain_id',
|
|
'git_ssh_key_id',
|
|
];
|
|
|
|
/**
|
|
* The "booted" method of the model.
|
|
*/
|
|
protected static function booted(): void
|
|
{
|
|
static::addGlobalScope(new CustomerDomainScope());
|
|
}
|
|
|
|
public static function boot()
|
|
{
|
|
parent::boot();
|
|
|
|
static::created(function ($model) {
|
|
$model->clone();
|
|
});
|
|
|
|
static::deleting(function ($model) {
|
|
$projectDir = $model->domain->domain_root . '/' . $model->dir;
|
|
ShellApi::safeDelete($projectDir,[
|
|
$model->domain->domain_root . '/',
|
|
]);
|
|
});
|
|
}
|
|
|
|
public function domain()
|
|
{
|
|
return $this->belongsTo(Domain::class);
|
|
}
|
|
|
|
private function _getSSHKey($gitSshKeyId, $findHostingSubscription)
|
|
{
|
|
$gitSSHKey = GitSshKey::where('id', $gitSshKeyId)
|
|
->where('hosting_subscription_id', $findHostingSubscription->id)
|
|
->first();
|
|
|
|
if ($gitSSHKey) {
|
|
$sshPath = '/home/'.$findHostingSubscription->system_username .'/.ssh';
|
|
$privateKeyFile = $sshPath.'/id_rsa_'. $gitSSHKey->id;
|
|
$publicKeyFile = $sshPath.'/id_rsa_'.$gitSSHKey->id.'.pub';
|
|
|
|
if (!is_dir($sshPath)) {
|
|
shell_exec('mkdir -p ' . $sshPath);
|
|
shell_exec('chown '.$findHostingSubscription->system_username.':'.$findHostingSubscription->system_username.' -R ' . dirname($sshPath));
|
|
shell_exec('chmod 0700 ' . dirname($sshPath));
|
|
}
|
|
|
|
if (!file_exists($privateKeyFile)) {
|
|
file_put_contents($privateKeyFile, $gitSSHKey->private_key);
|
|
|
|
shell_exec('chown '.$findHostingSubscription->system_username.':'.$findHostingSubscription->system_username.' ' . $privateKeyFile);
|
|
shell_exec('chmod 0400 ' . $privateKeyFile);
|
|
|
|
}
|
|
|
|
if (!file_exists($publicKeyFile)) {
|
|
file_put_contents($publicKeyFile, $gitSSHKey->public_key);
|
|
shell_exec('chown '.$findHostingSubscription->system_username.':'.$findHostingSubscription->system_username.' ' . $publicKeyFile);
|
|
shell_exec('chmod 0400 ' . $publicKeyFile);
|
|
}
|
|
|
|
return [
|
|
'privateKeyFile' => $privateKeyFile,
|
|
'publicKeyFile' => $publicKeyFile,
|
|
];
|
|
}
|
|
}
|
|
|
|
public function pull()
|
|
{
|
|
$this->status = self::STATUS_PULLING;
|
|
$this->save();
|
|
|
|
$findDomain = Domain::find($this->domain_id);
|
|
if (!$findDomain) {
|
|
$this->status = self::STATUS_FAILED;
|
|
$this->status_message = 'Domain not found';
|
|
$this->save();
|
|
return;
|
|
}
|
|
|
|
$findHostingSubscription = HostingSubscription::find($findDomain->hosting_subscription_id);
|
|
if (!$findHostingSubscription) {
|
|
$this->status = self::STATUS_FAILED;
|
|
$this->status_message = 'Hosting Subscription not found';
|
|
$this->save();
|
|
return;
|
|
}
|
|
|
|
$projectDir = $findDomain->domain_root . '/' . $this->dir;
|
|
|
|
$privateKeyFile = null;
|
|
$getSSHKey = $this->_getSSHKey($this->git_ssh_key_id, $findHostingSubscription);
|
|
if (isset($getSSHKey['privateKeyFile'])) {
|
|
$privateKeyFile = $getSSHKey['privateKeyFile'];
|
|
}
|
|
|
|
$gitSSHUrl = GitClient::parseGitUrl($this->url);
|
|
if (!isset($gitSSHUrl['provider'])) {
|
|
$this->status = self::STATUS_FAILED;
|
|
$this->status_message = 'Provider not found';
|
|
$this->save();
|
|
return;
|
|
}
|
|
|
|
$cloneUrl = 'git@'.$gitSSHUrl['provider'].':'.$gitSSHUrl['owner'].'/'.$gitSSHUrl['name'].'.git';
|
|
|
|
$shellFile = '/tmp/git-pull-' . $this->id . '.sh';
|
|
$shellLog = '/tmp/git-pull-' . $this->id . '.log';
|
|
|
|
$shellContent = view('actions.git.pull-repo', [
|
|
'gitProvider' => $gitSSHUrl['provider'],
|
|
'systemUsername' => $findHostingSubscription->system_username,
|
|
'gitRepositoryId' => $this->id,
|
|
'cloneUrl' => $cloneUrl,
|
|
'projectDir' => $projectDir,
|
|
'privateKeyFile' => $privateKeyFile,
|
|
])->render();
|
|
|
|
file_put_contents($shellFile, $shellContent);
|
|
|
|
shell_exec('chmod +x ' . $shellFile);
|
|
shell_exec('bash '.$shellFile.' >> ' . $shellLog . ' &');
|
|
|
|
}
|
|
|
|
public function clone()
|
|
{
|
|
$this->status = self::STATUS_CLONING;
|
|
$this->save();
|
|
|
|
$findDomain = Domain::find($this->domain_id);
|
|
if (!$findDomain) {
|
|
$this->status = self::STATUS_FAILED;
|
|
$this->status_message = 'Domain not found';
|
|
$this->save();
|
|
return;
|
|
}
|
|
|
|
$findHostingSubscription = HostingSubscription::find($findDomain->hosting_subscription_id);
|
|
if (!$findHostingSubscription) {
|
|
$this->status = self::STATUS_FAILED;
|
|
$this->status_message = 'Hosting Subscription not found';
|
|
$this->save();
|
|
return;
|
|
}
|
|
|
|
$projectDir = $findDomain->domain_root . '/' . $this->dir;
|
|
|
|
$privateKeyFile = null;
|
|
$getSSHKey = $this->_getSSHKey($this->git_ssh_key_id, $findHostingSubscription);
|
|
if (isset($getSSHKey['privateKeyFile'])) {
|
|
$privateKeyFile = $getSSHKey['privateKeyFile'];
|
|
}
|
|
|
|
|
|
$gitSSHUrl = GitClient::parseGitUrl($this->url);
|
|
if (!isset($gitSSHUrl['provider'])) {
|
|
$this->status = self::STATUS_FAILED;
|
|
$this->status_message = 'Provider not found';
|
|
$this->save();
|
|
return;
|
|
}
|
|
|
|
$cloneUrl = 'git@'.$gitSSHUrl['provider'].':'.$gitSSHUrl['owner'].'/'.$gitSSHUrl['name'].'.git';
|
|
|
|
$shellFile = '/tmp/git-clone-' . $this->id . '.sh';
|
|
$shellLog = '/tmp/git-clone-' . $this->id . '.log';
|
|
|
|
$shellContent = view('actions.git.clone-repo', [
|
|
'gitProvider' => $gitSSHUrl['provider'],
|
|
'systemUsername' => $findHostingSubscription->system_username,
|
|
'gitRepositoryId' => $this->id,
|
|
'cloneUrl' => $cloneUrl,
|
|
'projectDir' => $projectDir,
|
|
'privateKeyFile' => $privateKeyFile,
|
|
])->render();
|
|
|
|
file_put_contents($shellFile, $shellContent);
|
|
|
|
shell_exec('chmod +x ' . $shellFile);
|
|
shell_exec('bash '.$shellFile.' >> ' . $shellLog . ' &');
|
|
|
|
}
|
|
|
|
}
|