| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026 |
- <?php
- namespace services\common;
- use common\enums\RedisKeyEnum;
- use common\enums\StatusEnum;
- use common\helpers\CurlHelper;
- use common\helpers\LockHelper;
- use common\models\backend\SystemVersionLog;
- use common\models\backend\SystemVersionSlb;
- use common\models\common\Addons;
- use common\models\mall\Mall;
- use RuntimeException;
- use Yii;
- use yii\data\Pagination;
- use yii\web\NotFoundHttpException;
- use common\components\Service;
- use GuzzleHttp\Client;
- use GuzzleHttp\Exception\TransferException;
- use GuzzleHttp\TransferStats;
- use Exception;
- use PhpZip\Exception\ZipException;
- use PhpZip\ZipFile;
- use common\traits\ErrorTrait;
- /**
- *
- * 版本更新服务
- * Class UpgradeService
- * @package services\common
- */
- class UpgradeService extends Service
- {
- use ErrorTrait;
- const DEPLOY_ENV_BT = 'bt';
- const DEPLOY_ENV_DOCKER = 'docker';
- const DEPLOY_ENV_DEFAULT = 'default';
- // public $service_url = 'https://testapi.qijianshigw.com/version-upgrade/upgrade';
- public $service_url = 'https://service-api.qijianshigw.com/version-upgrade/upgrade';
- /**
- * 获取新版本
- * @param $now_version
- * @return mixed
- * @throws
- */
- public function getNewVersion($now_version)
- {
- $post = ['system_info' => $now_version,'web_api_url' => Yii::getAlias('@apiUrl'),'sign' => ''];
- //$result = CurlHelper::post($this->service_url,$post);
- $result = self::sendRequest($this->service_url,$post,'POST');
- return $result;
- }
- /**
- * 升级版本
- * @param array $data
- * @throws
- * @return bool
- */
- public static function upgrade($params)
- {
- ini_set('memory_limit',-1);
- $data = $params['upgrade'];
- $now_version = $params['now_version'];
- $log = self::addLog($now_version,$data);
- // 备份插件文件
- //self::backup(); //todo
- $sqlFiles = [];
- $addons_arr = [];
- foreach($data as $key => $value){
- $addons_name = $key;
- $download_url = $value['download_url'] ?? '';
- if(!$download_url){
- continue;
- }
- $tmpFile = self::download($download_url);
- try {
- if(strpos($addons_name,'mian') === false){
- if(in_array($addons_name, ['h5', 'salary-h5'])){
- //h5更新
- $dir = self::getH5TmpDir($addons_name);
- }else{
- //插件更新
- $dir = Yii::getAlias('@addons').DIRECTORY_SEPARATOR;
- }
- }else{
- //主包更新
- $addons_name = 'mian';
- $dir = self::getWorkDir();
- }
- // 解压插件
- self::unzip($tmpFile,$dir);
- if($addons_name == 'h5'){
- self::handleH5();
- }
- if($addons_name == 'salary-h5'){
- self::handleSalaryH5();
- }
- } catch (Exception $e) {
- throw new Exception($download_url.','.$e->getMessage());
- } finally {
- // 移除临时文件
- @unlink($tmpFile);
- }
- if($value['is_install']){
- //需要导入sql
- if($addons_name == 'mian'){
- $sqlFiles[] = self::getWorkDir() . 'install.sql';
- }else{
- $sqlFiles[] = Yii::getAlias('@addons').DIRECTORY_SEPARATOR.$addons_name.DIRECTORY_SEPARATOR.'install.sql';
- }
- }
- if(!in_array($addons_name,['mian','h5'])){
- //插件更新配置
- $addons_arr[] = $addons_name;
- //Addons::install($addons_name);
- }
- }
- //更新文件所有者
- // $shell = "chown www:www -R ".\Yii::getAlias('@webpath');
- // exec($shell, $result, $status);
- //判断是否安装mycat,如果按照 则不能执行以下操作
- $dbConfig = \Yii::$app->getComponents()['db'];
- $dsn = $dbConfig['dsn'];
- preg_match('|port=(.*?);|',$dsn,$match);
- $port = $match[1] ?? '';
- $status = 1;
- if($port == 3306){
- //mysql 端口
- if($sqlFiles){
- // 导入
- foreach($sqlFiles as $sql){
- $res = self::importsql($sql);
- if(!$res) $status = -1;
- }
- }
- $result = self::migrate();
- $status = $result === false ? -1 : $status;
- }else{
- Yii::$app->custom->logs('数据库未处理,数据迁移迁移未处理,'.implode(',',$sqlFiles) );
- self::$static_error = '请联系技术专员处理数据库';
- }
- //更新完成:释放锁
- self::unlockUpgrade();
- //更新记录状态
- self::updateLogStatus($log,$status);
- //异步处理更新插件配置
- self::asynchAddonsConfig($addons_arr);
- //重启服务
- self::restartService();
- return true;
- }
- /**
- * 获取远程服务器
- * @return string
- */
- protected static function getServerUrl()
- {
- return Yii::getAlias('@serverUrl');
- }
- /**
- * 获取备份目录
- */
- public static function getBackupDir()
- {
- $dir = Yii::$app->getRuntimePath().DIRECTORY_SEPARATOR.'bak'.DIRECTORY_SEPARATOR;
- if (!is_dir($dir)) {
- @mkdir($dir, 0755, true);
- }
- return $dir;
- }
- /**
- * 获取项目备份地址
- * @return string
- */
- public static function getWorkBackupDir(){
- //$dir = Yii::getAlias('@webpath').DIRECTORY_SEPARATOR.'../';
- $dir = Yii::$app->getRuntimePath().DIRECTORY_SEPARATOR.'bak_up'.DIRECTORY_SEPARATOR;
- if (!is_dir($dir)) {
- @mkdir($dir, 0755, true);
- }
- return $dir;
- }
- /**
- * 获取项目根目录
- */
- public static function getWorkDir()
- {
- $dir = Yii::getAlias('@webpath').DIRECTORY_SEPARATOR;
- return $dir;
- }
- /**
- * 远程下载更新包
- * @param string $url 下载地址
- * @return string
- * @throws
- */
- public static function download($url)
- {
- $tempDir = self::getBackupDir();
- $tmpFile = $tempDir . date('Y_m_d_H_i_s') . ".zip";
- try {
- $client = self::getClient();
- $response = $client->get($url);
- $statusCode = $response->getStatusCode();
- if($statusCode != 200) throw new Exception("query result code error:".$statusCode.',url='.$url);
- $body = $response->getBody();
- $content = $body->getContents();
- } catch (TransferException $e) {
- throw new Exception("package download failed:".$url);
- }
- if ($write = fopen($tmpFile, 'w')) {
- fwrite($write, $content);
- fclose($write);
- return $tmpFile;
- }
- throw new Exception("No permission to write temporary files");
- }
- /**
- * 解压压缩包
- *
- * @param string $name 压缩包名称
- * @return string
- * @throws Exception
- */
- public static function unzip($file,$dir)
- {
- if (!$file || !file_exists($file)) {
- throw new Exception('Invalid parameters');
- }
- // 打开插件压缩包
- $zip = new ZipFile();
- try {
- $zip->openFile($file);
- } catch (ZipException $e) {
- $zip->close();
- throw new Exception('Unable to open the zip file');
- }
- // if (!is_dir($dir)) {
- // @mkdir($dir, 0755);
- // }
- // 解压插件压缩包
- try {
- $zip->extractTo($dir);
- } catch (ZipException $e) {
- throw new Exception('Unable to extract the file:'.$e->getMessage().' ,dir:'.$dir);
- } finally {
- $zip->close();
- }
- return $dir;
- }
- /**
- * 获取请求对象
- * @return Client
- */
- public static function getClient()
- {
- $options = [
- //'base_uri' => self::getServerUrl(),
- 'timeout' => 30,
- 'connect_timeout' => 30,
- 'verify' => false,
- 'http_errors' => false,
- 'headers' => [
- 'X-REQUESTED-WITH' => 'XMLHttpRequest',
- //'Referer' => dirname(request()->root(true)),
- 'User-Agent' => 'qimall',
- ]
- ];
- static $client;
- if (empty($client)) {
- $client = new Client($options);
- }
- return $client;
- }
- /**
- * 发送请求
- * @return array
- * @throws Exception
- * @throws \GuzzleHttp\Exception\GuzzleException
- */
- public static function sendRequest($url, $params = [], $method = 'POST')
- {
- $json = [];
- try {
- $client = self::getClient();
- $options = strtoupper($method) == 'POST' ? ['form_params' => $params] : ['query' => $params];
- $response = $client->request($method, $url, $options);
- $body = $response->getBody();
- $content = $body->getContents();
- $json = (array)json_decode($content, true);
- } catch (TransferException $e) {
- throw new Exception('Network error');
- } catch (\Exception $e) {
- throw new Exception('Unknown data format');
- }
- return $json;
- }
- /**
- * 备份项目
- * @return bool
- * @throws Exception
- */
- public static function backup()
- {
- //$workDir = self::getWorkDir();
- $backupDir = self::getWorkBackupDir();
- $file = $backupDir . 'qimall-backup-' . date("YmdHis") . '.zip';
- $zipFile = new ZipFile();
- try {
- $zipFile
- //->addDirRecursive($workDir)
- ->addDirRecursive(Yii::getAlias('@common'),'common')
- ->addDirRecursive(Yii::getAlias('@frontend'),'frontend')
- ->addDirRecursive(Yii::getAlias('@api'),'api')
- ->addDirRecursive(Yii::getAlias('@backend'),'backend')
- ->addDirRecursive(Yii::getAlias('@console'),'console')
- ->addDirRecursive(Yii::getAlias('@addons'),'addons')
- ->addDirRecursive(Yii::getAlias('@services'),'services')
- ->saveAsFile($file)
- ->close();
- } catch (ZipException $e) {
- } finally {
- $zipFile->close();
- }
- return true;
- }
- /**
- * 备份H5文件夹
- * @return bool
- */
- public static function backupH5()
- {
- $backupDir = self::getWorkBackupDir();
- $file = $backupDir . 'h5-backup-' . date("YmdHis") . '.zip';
- $zipFile = new ZipFile();
- try {
- $zipFile
- ->addDirRecursive(self::getWorkDir().'h5'.DIRECTORY_SEPARATOR)
- ->saveAsFile($file)
- ->close();
- } catch (ZipException $e) {
- } finally {
- $zipFile->close();
- }
- return true;
- }
- /**
- * 执行SQL
- * @param $fileName
- */
- public static function importsql($fileName)
- {
- //$fileName = is_null($fileName) ? 'qimall.sql' : $fileName;
- //$sqlFile = self::getWorkDir() . $fileName;
- $sqlFile = $fileName;
- $result = true;
- if (is_file($sqlFile)) {
- $lines = file($sqlFile);
- $templine = '';
- foreach ($lines as $line) {
- if (substr($line, 0, 2) == '--' || $line == '' || substr($line, 0, 2) == '/*') {
- continue;
- }
- $templine .= $line;
- if (substr(trim($line), -1, 1) == ';') {
- //$templine = str_ireplace('__PREFIX__', config('database.prefix'), $templine);
- $templine = str_ireplace('INSERT INTO ', 'INSERT IGNORE INTO ', $templine);
- try {
- Yii::$app->db->createCommand($templine)->execute();
- } catch (Exception $e) {
- echo $e->getMessage();
- $result = false;
- }
- $templine = '';
- }
- }
- }
- return $result;
- }
- /**
- * 执行数据迁移
- */
- public static function migrate()
- {
- //执行yii migrate
- //exec('sh /www/wwwroot/qimall/run_migrate.sh', $result, $status);
- $sh = self::getWorkDir().'run_migrate.sh';
- if(file_exists($sh)){
- //执行yii migrate
- exec('sh '.$sh, $result, $status);
- if( $status ){
- echo "yii migrate执行失败";
- print_r( $result );
- return false;
- }else{
- echo "yii migrate成功执行, 结果如下<hr>";
- print_r( $result );
- return true;
- }
- }
- }
- /**
- * 重启队列服务:重启supervisorctl
- */
- public static function restartService()
- {
- //判断是否docker部署
- if (is_dir('/www/wwwroot/qimall')) {
- $is_docker_deploy = \Yii::$app->params['is_docker_deploy'] ?? false;
- if($is_docker_deploy){
- $restart_docker_file = self::getWorkDir().'consume_docker.txt';
- if(!file_exists($restart_docker_file)){
- fopen($restart_docker_file, "w");
- chown($restart_docker_file,'www');
- }
- file_put_contents($restart_docker_file,1);
- }else{
- //需要加上全路径
- $shell = "sudo /www/server/panel/pyenv/bin/supervisorctl restart rabbitmq-consume:*";
- exec($shell, $result, $status);
- if( $status ){
- echo "shell命令{$shell}执行失败";
- } else {
- echo "shell命令{$shell}成功执行, 结果如下<hr>";
- print_r( $result );
- }
- }
- } else {
- // 此部署方式的文件夹路径为data/wwwroot/qimall
- $swoole_consume_num = \Yii::$app->params['swoole_consume_num'] ?? 1;
- if($swoole_consume_num > 1){
- for($i = 1;$i<= $swoole_consume_num;$i++){
- $shell = "sudo systemctl restart swoole_consume_run@".$i;
- exec($shell, $result, $status);
- if( $status ){
- echo "shell命令{$shell}执行失败";
- } else {
- echo "shell命令{$shell}成功执行, 结果如下<hr>";
- print_r( $result );
- }
- }
- }else{
- $shell = "sudo systemctl restart swoole_consume_run";
- exec($shell, $result, $status);
- if( $status ){
- echo "shell命令{$shell}执行失败";
- } else {
- echo "shell命令{$shell}成功执行, 结果如下<hr>";
- print_r( $result );
- }
- }
- }
- }
- /**
- * 更新加锁
- * @return bool
- * @throws Exception
- */
- public static function lockUpgrade()
- {
- $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_VERSION_UPGRADE);
- $identification = 'system';
- if (!LockHelper::lock($lock_key, $identification, 1200, 1)){
- throw new Exception('系统更新中,请等待...');
- }
- return true;
- }
- /**
- * 版本更新完成释放锁
- * @return bool
- */
- public static function unlockUpgrade()
- {
- $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_VERSION_UPGRADE);
- $identification = 'system';
- LockHelper::uLock($lock_key,$identification);
- return true;
- }
- /**
- * 添加记录
- * @param $now_version
- * @param $new_version
- * @return int
- */
- public static function addLog($now_version,$new_version)
- {
- preg_match('|mian:(.*?),|is',$now_version,$match);
- $mian_version = $match[1] ?? '';
- $addons_version = str_replace('mian:'.$mian_version.',','',$now_version);
- $upgrade_addons_version = [];
- $new_mian_version = '';
- foreach($new_version as $key => $value){
- if(strpos($key,'mian') === false){
- $upgrade_addons_version[] = $key.':'.$value['version'];
- }else{
- $new_mian_version = $value['version'];
- }
- }
- $params = [
- 'mian_version' => $mian_version,
- 'addons_version' => $addons_version,
- 'upgrade_mian_version' => $new_mian_version,
- 'upgrade_addons_version' => implode(',',$upgrade_addons_version),
- 'upgrade_params' => json_encode($new_version),
- 'status' => 0
- ];
- $result = SystemVersionLog::setData($params);
- return $result;
- }
- /**
- * 更新记录状态
- * @param $log
- * @param $status
- * @return mixed
- */
- public static function updateLogStatus($log,$status)
- {
- $log->status = $status;
- return $log->save();
- }
- /**
- * 获取h5临时目录
- */
- public static function getH5TmpDir($dirName = 'h5')
- {
- $dirName .= '_tmp';
- $dir = self::getWorkDir(). $dirName .DIRECTORY_SEPARATOR;
- if (!is_dir($dir)) {
- @mkdir($dir, 0755, true);
- }
- return $dir;
- }
- /**
- * @param $tmpDirName string 备份目录名
- * @param $targetDirName string 目标目录名
- *
- * @return bool
- */
- public static function handleH5($tmpDirName = 'h5', $targetDirName = 'h5')
- {
- //1. 压缩原来H5目录
- // self::backupH5();
- $h5_tmp_dir = self::getH5TmpDir($tmpDirName);
- $tmp_js_dir = $h5_tmp_dir.'static/js/';
- if (!is_dir($tmp_js_dir)) {
- echo $tmpDirName . '_tmp/static/js/ 目录不存在';
- return false;
- }
- $apiUrl = Yii::getAlias('@apiUrl') ?? '';
- $attachurl = Yii::getAlias('@attachurl') ?? '';
- if(!$apiUrl || !$attachurl){
- return false;
- }
- //apiUrl attachurl 去除前面的https:// , http://
- $apiUrl = str_replace('https://','',$apiUrl);
- $apiUrl = str_replace('http://','',$apiUrl);
- $attachurl = str_replace('https://','',$attachurl);
- $attachurl = str_replace('http://','',$attachurl);
- // 地图密钥
- $config = Yii::$app->services->setting->platform->get('map');
- $qq_map_key = $config['qq_jsapi_key_h5'] ? $config['qq_jsapi_key_h5'] : 'TSOBZ-PHCWT-MPBX5-LZLSP-4WSW6-UIFVJ';
- $mall = Mall::find()->where(['=','status',StatusEnum::ENABLED])->andWhere(['=','is_recycle',StatusEnum::DISABLED])->orderBy('id asc')->asArray()->one();
- $search = ['---sign---','---api---','---static---', 'TSOBZ-PHCWT-MPBX5-LZLSP-4WSW6-UIFVJ'];
- $replace = [
- $mall['mall_sign'] ?? '',
- $apiUrl,
- $attachurl,
- $qq_map_key
- ];
- //2.读取h5_tmp 目录:/static/js/ , 替换js文件
- $js_list = [];
- $resource = opendir($tmp_js_dir);
- while ($file = readdir($resource))
- {
- //排除根目录
- if ($file != ".." && $file != ".")
- {
- $con = file_get_contents($tmp_js_dir.$file);
- $con = str_replace($search,$replace,$con);
- file_put_contents($tmp_js_dir.$file,$con);
- //根目录下的文件
- $js_list[] = $file;
- }
- }
- closedir($resource);
- $h5_all_files = self::getFileList($h5_tmp_dir,'');
- foreach($h5_all_files as $key => $file){
- $source = $tmpDirName . '_tmp'.'/'.$file;
- $target = $targetDirName .'/'.$file;
- self::copyFile(self::getWorkDir(),$source,$target);
- //删除h5_tmp
- @unlink(self::getWorkDir() . '/' . $source);
- }
- return true;
- }
- /**
- * 处理发薪猫h5包
- *
- * @return void
- */
- public static function handleSalaryH5()
- {
- $salaryDir = self::getWorkDir() . 'salary';
- // 如果已经存在salary目录,考虑旧目录不是nobody情况,修改目录归属为nobody
- if (is_dir($salaryDir)) {
- exec('sudo chown -R nobody:nobody ' . $salaryDir);
- }
- self::handleH5('salary-h5', 'salary');
- // 生成发薪猫h5 Vhosts文件
- try {
- self::makeSalaryVhosts();
- }catch (Exception $e) {
- echo PHP_EOL . $e->getMessage();
- }
- }
- /**
- * 生成发薪猫h5 Vhosts文件
- *
- * @return void
- */
- public static function makeSalaryVhosts()
- {
- $deployEnv = self::getDeployEnv();
- // 如果是宝塔部署,不生成Vhosts文件
- if ($deployEnv === self::DEPLOY_ENV_BT) {
- return;
- }
- $workDir = self::getWorkDir();
- if (!is_dir($workDir . 'salary')) {
- return;
- }
- $salaryHost = parse_url(Yii::$app->services->setting->platform->get('system.cat_h5_url') ?: '')['host'] ?? '';
- if (!$salaryHost) {
- throw new RuntimeException('获取发薪猫域名失败');
- }
- // 检测发薪猫域名证书是否上传,不存在则不生成Vhosts文件
- if (!self::isExistsSalaryCert($salaryHost, $deployEnv)) {
- throw new RuntimeException('未检测到发薪猫域名证书');
- }
- $h5Host = parse_url(Yii::$app->services->setting->platform->get('system.h5_url') ?: '')['host'] ?? '';
- if (!$h5Host) {
- throw new RuntimeException('获取h5域名失败');
- }
- // nginx 配置文件目录
- $vhostsDir = self::getVhostsPath($deployEnv);
- if (!$vhostsDir) {
- throw new RuntimeException('获取nginx 配置文件目录失败');
- }
- $salaryConfFile = $vhostsDir . $salaryHost . '.conf';
- // 检查是否存在此文件,已存在则不再生成
- if (file_exists($salaryConfFile)) {
- return;
- }
- $h5ConfFile = $vhostsDir . $h5Host . '.conf';
- if (!file_exists($h5ConfFile)) {
- throw new RuntimeException('获取h5 vhosts conf 文件失败');
- }
- // 复制主商城h5Vhosts文件
- exec(sprintf('sudo cp %s %s', $h5ConfFile, $salaryConfFile));
- // 检查复制情况
- if (!file_exists($salaryConfFile)) {
- throw new RuntimeException('复制h5 vhosts conf 文件失败');
- }
- // 替换域名
- exec(sprintf('sudo sed -i "s/%s/%s/g" %s', $h5Host, $salaryHost, $salaryConfFile));
- // 替换指向目录
- exec(sprintf('sudo sed -i "s|%sh5|%ssalary|g" %s', $workDir, $workDir, $salaryConfFile));
- // 热重启nginx
- self::restartNginx($deployEnv);
- }
- /**
- * 获取部署环境
- *
- * @return string
- */
- public static function getDeployEnv(): string
- {
- if (is_dir('/www/wwwroot/qimall')) {
- if (Yii::$app->params['is_docker_deploy'] ?? false) {
- return self::DEPLOY_ENV_DOCKER;
- }
- return self::DEPLOY_ENV_BT;
- }
- return self::DEPLOY_ENV_DEFAULT;
- }
- /**
- * 根据部署环境重启nginx(如果是宝塔则不重启)
- *
- * @param string $deployEnv
- *
- * @return void
- */
- public static function restartNginx(string $deployEnv)
- {
- switch ($deployEnv) {
- case self::DEPLOY_ENV_DEFAULT:
- exec('sudo /application/nginx/sbin/nginx -s reload');
- break;
- case self::DEPLOY_ENV_DOCKER:
- exec('sudo docker restart nginx');
- break;
- default:
- break;
- }
- }
- /**
- * 根据部署环境获取nginx vhosts文件路径
- *
- * @param string $deployEnv
- *
- * @return string
- */
- public static function getVhostsPath(string $deployEnv): string
- {
- switch ($deployEnv) {
- case self::DEPLOY_ENV_DEFAULT:
- return '/application/nginx/conf/vhosts/';
- case self::DEPLOY_ENV_DOCKER:
- return '/data/confs/nginx/conf.d/';
- default:
- return '';
- }
- }
- /**
- * 检测是否存在发薪猫证书
- *
- * @param string $deployEnv 部署环境
- *
- * @return string
- */
- public static function getSshPath(string $deployEnv): string
- {
- switch ($deployEnv) {
- case self::DEPLOY_ENV_DEFAULT:
- return '/application/nginx/conf/ssl/';
- case self::DEPLOY_ENV_DOCKER:
- return '/data/confs/nginx/ssl/';
- default:
- return '';
- }
- }
- /**
- * 检测是否存在发薪猫证书
- *
- * @param string $host
- * @param string $deployEnv
- *
- * @return bool
- */
- public static function isExistsSalaryCert(string $host, string $deployEnv): bool
- {
- $sshBasePath = self::getSshPath($deployEnv) . $host;
- return file_exists($sshBasePath . '.key') && file_exists($sshBasePath . '.pem');
- }
- private static function getFileList($root, $basePath = '')
- {
- $files = [];
- $handle = opendir($root);
- while (($path = readdir($handle)) !== false) {
- if ($path === '.git' || $path === '.svn' || $path === '.' || $path === '..') {
- continue;
- }
- $fullPath = "$root/$path";
- $relativePath = $basePath === '' ? $path : "$basePath/$path";
- if (is_dir($fullPath)) {
- $files = array_merge($files, self::getFileList($fullPath, $relativePath));
- } else {
- $files[] = $relativePath;
- }
- }
- closedir($handle);
- return $files;
- }
- private static function copyFile($root, $source, $target)
- {
- if (!is_file($root . '/' . $source)) {
- echo " skip $target ($source not exist)\n";
- return true;
- }
- if (is_file($root . '/' . $target)) {
- file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
- return true;
- }
- //echo " generate $target\n";
- @mkdir(dirname($root . '/' . $target), 0777, true);
- file_put_contents($root . '/' . $target, file_get_contents($root . '/' . $source));
- return true;
- }
- /**
- * 异步更新插件配置
- * @param $addons_arr
- * @throws Exception
- */
- private static function asynchAddonsConfig($addons_arr)
- {
- if(!$addons_arr) return ;
- Yii::$app->services->rabbitMq->delay(10, $addons_arr, self::class, 'updateAddonsConfig');
- }
- /**
- * 更新插件配置
- * @param $addons_arr
- * @return bool
- */
- public static function updateAddonsConfig($addons_arr)
- {
- if(!$addons_arr) return true;
- try{
- foreach($addons_arr as $addons_name){
- $res = Addons::install($addons_name);
- if(!$res){
- Yii::$app->custom->logs('updateAddonsConfig error:'.Addons::getStaticError());
- }
- }
- }catch(Exception $e){
- Yii::$app->custom->logs('updateAddonsConfig Exception:'.$e->getMessage());
- return false;
- }
- return true;
- }
- /**
- * 从服务器下载更新代码
- * @Author: lun
- * @DateTime: 2023/5/18 0018 9:45
- * @Copyright: copyright (c) 2021 广东七件事集团
- * @param $data
- * @param $slbId
- * @return bool
- * @throws Exception
- */
- public static function slbUpgrade($data, $slbId)
- {
- foreach($data as $key => $value){
- $addons_name = $key;
- $download_url = $value['download_url'] ?? '';
- if(!$download_url){
- continue;
- }
- $tmpFile = self::download($download_url);
- try {
- if(strpos($addons_name,'mian') === false){
- if(in_array($addons_name, ['h5', 'salary-h5'])){
- //h5更新
- $dir = self::getH5TmpDir($addons_name);
- }else{
- //插件更新
- $dir = Yii::getAlias('@addons').DIRECTORY_SEPARATOR;
- }
- }else{
- //主包更新
- $addons_name = 'mian';
- $dir = self::getWorkDir();
- }
- // 解压插件
- self::unzip($tmpFile,$dir);
- if($addons_name == 'h5'){
- self::handleH5();
- }
- if($addons_name == 'salary-h5'){
- self::handleSalaryH5();
- }
- } catch (Exception $e) {
- SystemVersionSlb::setStatus($slbId, -1);
- throw new Exception('从服务器更新失败:'.$e->getMessage());
- } finally {
- // 移除临时文件
- @unlink($tmpFile);
- }
- }
- // 更新状态
- SystemVersionSlb::setStatus($slbId, 1);
- return true;
- }
- /**
- * 强制降级H5版本
- * @return bool
- * @throws Exception
- */
- public static function forceDowngradeH5()
- {
- $h5_version_file = self::getWorkDir() . 'h5/version';
- if (!file_exists($h5_version_file)) {
- throw new Exception('h5版本文件不存在');
- }
- file_put_contents($h5_version_file, '1.0.0');
- return true;
- }
- }
|