拼接目标机要发布的目录
{release_library}/{project}/{version}
public static getReleaseVersionDir ( $version = '' ) : string | ||
$version | ||
return | string |
/** * 打软链 * * @param null $version * @return bool */ public function getLinkCommand($version) { $user = $this->config->release_user; $project = Project::getGitProjectName($this->getConfig()->repo_url); $currentTmp = sprintf('%s/%s/current-%s.tmp', rtrim($this->getConfig()->release_library, '/'), $project, $project); // 遇到回滚,则使用回滚的版本version $linkFrom = Project::getReleaseVersionDir($version); $cmd[] = sprintf('ln -sfn %s %s', $linkFrom, $currentTmp); $cmd[] = sprintf('chown -h %s %s', $user, $currentTmp); $cmd[] = sprintf('mv -fT %s %s', $currentTmp, $this->getConfig()->release_to); return join(' && ', $cmd); }
/** * 获取远程服务器要操作的任务命令 * * @param $task string * @param $version string * @return string string */ public static function getRemoteTaskCommand($task, $version) { $tasks = GlobalHelper::str2arr($task); if (empty($tasks)) { return ''; } $cmd = []; $workspace = rtrim(Project::getDeployWorkspace($version), '/'); $version = Project::getReleaseVersionDir($version); $pattern = ['#{WORKSPACE}#', '#{VERSION}#']; $replace = [$workspace, $version]; foreach ($tasks as $task) { $cmd[] = preg_replace($pattern, $replace, $task); } return join(' && ', $cmd); }
/** * 同步代码之后触发任务 * 所有目标机器都部署完毕之后,做一些清理工作,如删除缓存、重启服务(nginx、php、task) * * @return bool */ public function postRelease($version) { $tasks = GlobalHelper::str2arr($this->getConfig()->post_release); if (empty($tasks)) { return true; } $cmd = []; $workspace = rtrim(Project::getDeployWorkspace($version), '/'); $version = Project::getReleaseVersionDir($version); $pattern = ['#{WORKSPACE}#', '#{VERSION}#']; $replace = [$workspace, $version]; foreach ($tasks as $task) { $cmd[] = preg_replace($pattern, $replace, $task); } $command = join(' && ', $cmd); return $this->runRemoteCommand($command); }
/** * 项目配置检测,提前发现配置不当之处。 * * @return string */ public function actionDetection($projectId) { $project = Project::getConf($projectId); $log = []; $code = 0; // 本地git ssh-key是否加入deploy-keys列表 $revision = Repo::getRevision($project); try { $ret = $revision->updateRepo(); if (!$ret) { $code = -1; $error = $project->repo_type == Project::REPO_GIT ? '把ssh-key加入git的deploy-keys列表' : '用户名密码无误'; $log[] = sprintf('宿主机代码检出检测出错,请确认php进程用户%s有代码存储仓库%s读写权限, 并且%s。详细错误:%s<br>', getenv("USER"), $project->deploy_from, $error, $revision->getExeLog()); } } catch (\Exception $e) { $code = -1; $log[] = sprintf('宿主机检测时发生系统错误:%s<br>', $e->getMessage()); } // 权限与免密码登录检测 $this->walleTask = new WalleTask($project); try { $command = sprintf('mkdir -p %s', Project::getReleaseVersionDir('detection')); $ret = $this->walleTask->runRemoteTaskCommandPackage([$command]); if (!$ret) { $code = -1; $log[] = sprintf('目标机器部署出错,请确认php进程用户%s用户ssh-key加入目标机器的%s用户ssh-key信任列表, 且%s有目标机器发布版本库%s写入权限。详细错误:%s<br>', getenv("USER"), $project->release_user, $project->release_user, $project->release_to, $this->walleTask->getExeLog()); } // 清除 $command = sprintf('rm -rf %s', Project::getReleaseVersionDir('detection')); $this->walleTask->runRemoteTaskCommandPackage([$command]); } catch (\Exception $e) { $code = -1; $log[] = sprintf('目标机检测时发生系统错误:%s<br>', $e->getMessage()); } // task 检测todo... if ($code === 0) { $log[] = '配置检测通过,恭喜:)'; } $this->renderJson(join("<br>", $log), $code); }
/** * 项目配置检测,提前发现配置不当之处。 * * @return string */ public function actionDetection($projectId) { $project = Project::getConf($projectId); $log = []; $code = 0; // 本地git ssh-key是否加入deploy-keys列表 $revision = Repo::getRevision($project); try { // 1.检测宿主机检出目录是否可读写 $codeBaseDir = Project::getDeployFromDir(); $isWritable = is_dir($codeBaseDir) ? is_writable($codeBaseDir) : @mkdir($codeBaseDir, 0755, true); if (!$isWritable) { $code = -1; $log[] = yii::t('walle', 'hosted server is not writable error', ['user' => getenv("USER"), 'path' => $project->deploy_from]); } // 2.检测宿主机ssh是否加入git信任 $ret = $revision->updateRepo(); if (!$ret) { $code = -1; $error = $project->repo_type == Project::REPO_GIT ? yii::t('walle', 'ssh-key to git', ['user' => getenv("USER")]) : yii::t('walle', 'correct username passwd'); $log[] = yii::t('walle', 'hosted server ssh error', ['error' => $error]); } if ($project->ansible) { $this->ansible = new Ansible($project); // 3.检测 ansible 是否安装 $ret = $this->ansible->test(); if (!$ret) { $code = -1; $log[] = yii::t('walle', 'hosted server ansible error'); } } } catch (\Exception $e) { $code = -1; $log[] = yii::t('walle', 'hosted server sys error', ['error' => $e->getMessage()]); } // 权限与免密码登录检测 $this->walleTask = new WalleTask($project); try { // 4.检测php用户是否加入目标机ssh信任 $command = 'id'; $ret = $this->walleTask->runRemoteTaskCommandPackage([$command]); if (!$ret) { $code = -1; $log[] = yii::t('walle', 'target server ssh error', ['local_user' => getenv("USER"), 'remote_user' => $project->release_user, 'path' => $project->release_to]); } if ($project->ansible) { // 5.检测 ansible 连接目标机是否正常 $ret = $this->ansible->ping(); if (!$ret) { $code = -1; $log[] = yii::t('walle', 'target server ansible ping error'); } } // 6.检测php用户是否具有目标机release目录读写权限 $tmpDir = 'detection' . time(); $command = sprintf('mkdir -p %s', Project::getReleaseVersionDir($tmpDir)); $ret = $this->walleTask->runRemoteTaskCommandPackage([$command]); if (!$ret) { $code = -1; $log[] = yii::t('walle', 'target server is not writable error', ['remote_user' => $project->release_user, 'path' => $project->release_to]); } // 清除 $command = sprintf('rm -rf %s', Project::getReleaseVersionDir($tmpDir)); $this->walleTask->runRemoteTaskCommandPackage([$command]); } catch (\Exception $e) { $code = -1; $log[] = yii::t('walle', 'target server sys error', ['error' => $e->getMessage()]); } // 7.路径必须为绝对路径 $needAbsoluteDir = [Yii::t('conf', 'deploy from') => Project::getConf()->deploy_from, Yii::t('conf', 'webroot') => Project::getConf()->release_to, Yii::t('conf', 'releases') => Project::getConf()->release_library]; foreach ($needAbsoluteDir as $tips => $dir) { if (0 !== strpos($dir, '/')) { $code = -1; $log[] = yii::t('walle', 'config dir must absolute', ['path' => sprintf('%s:%s', $tips, $dir)]); } } // task 检测todo... if ($code === 0) { $log[] = yii::t('walle', 'project configuration works'); } $this->renderJson(join("<br>", $log), $code); }
/** * 项目配置检测,提前发现配置不当之处。 * * @return string */ public function actionDetection($projectId) { $project = Project::getConf($projectId); $log = []; $code = 0; // 本地git ssh-key是否加入deploy-keys列表 $revision = Repo::getRevision($project); try { $ret = $revision->updateRepo(); if (!$ret) { $code = -1; $error = $project->repo_type == Project::REPO_GIT ? yii::t('walle', 'ssh-key to git') : yii::t('walle', 'correct username passwd'); $log[] = yii::t('walle', 'hosted server error', ['user' => getenv("USER"), 'path' => $project->deploy_from, 'ssh_passwd' => $error, 'error' => $revision->getExeLog()]); } } catch (\Exception $e) { $code = -1; $log[] = yii::t('walle', 'hosted server sys error', ['error' => $e->getMessage()]); } // 权限与免密码登录检测 $this->walleTask = new WalleTask($project); try { $command = sprintf('mkdir -p %s', Project::getReleaseVersionDir('detection')); $ret = $this->walleTask->runRemoteTaskCommandPackage([$command]); if (!$ret) { $code = -1; $log[] = yii::t('walle', 'target server error', ['local_user' => getenv("USER"), 'remote_user' => $project->release_user, 'path' => $project->release_to, 'error' => $this->walleTask->getExeLog()]); } // 清除 $command = sprintf('rm -rf %s', Project::getReleaseVersionDir('detection')); $this->walleTask->runRemoteTaskCommandPackage([$command]); } catch (\Exception $e) { $code = -1; $log[] = yii::t('walle', 'target server sys error', ['error' => $e->getMessage()]); } // task 检测todo... if ($code === 0) { $log[] = yii::t('walle', 'project configuration works'); } $this->renderJson(join("<br>", $log), $code); }
/** * 获取远程服务器要操作的任务命令 * * @param $task string * @param $version string * @return string string */ public static function getRemoteTaskCommand($task, $version) { $tasks = GlobalHelper::str2arr($task); if (empty($tasks)) { return ''; } // 可能要做一些依赖环境变量的命令操作 $cmd = ['source /etc/profile']; $workspace = Project::getTargetWorkspace(); $version = Project::getReleaseVersionDir($version); $pattern = ['#{WORKSPACE}#', '#{VERSION}#']; $replace = [$workspace, $version]; // 简化用户切换目录,直接切换到当前的版本目录:{release_library}/{project}/{version} $cmd[] = "cd {$version}"; foreach ($tasks as $task) { $cmd[] = preg_replace($pattern, $replace, $task); } return join(' && ', $cmd); }
/** * 项目配置检测,提前发现配置不当之处。 * * @return string */ public function actionDetection($projectId) { $project = Project::getConf($projectId); $log = []; $code = 0; // 本地git ssh-key是否加入deploy-keys列表 $git = new Git(); try { $ret = $git->setConfig($project)->updateRepo(); if (!$ret) { $code = -1; $log[] = sprintf('宿主机代码检出检测出错,请确认php进程用户%s有代码存储仓库权限, 并且把ssh-key加入git的deploy-keys列表。详细错误:%s', Get_Current_User(), $git->getExeLog()); } } catch (\Exception $e) { $code = -1; $log[] = sprintf('宿主机检测时发生系统错误:%s', $e->getMessage()); } // 权限与免密码登录检测 $task = new WalleTask(); try { $task->setConfig($project); $command = sprintf('mkdir -p %s', Project::getReleaseVersionDir('detection')); $ret = $task->runRemoteTaskCommandPackage([$command]); if (!$ret) { $code = -1; $log[] = sprintf('目标机器代码检出检测出错,请确认php进程用户%s用户加入目标机器的%s用户ssh-key信任列表, 且%s有目标机器发布版本库写入权限。详细错误:%s', Get_Current_User(), $project->release_user, $project->release_user, $task->getExeLog()); } // 清除 $command = sprintf('rm -rf %s', Project::getReleaseVersionDir('detection')); $task->runRemoteTaskCommandPackage([$command]); } catch (\Exception $e) { $code = -1; $log[] = sprintf('目标机检测时发生系统错误:%s', $e->getMessage()); } // task 检测todo... if ($code === 0) { $log[] = '配置检测通过,恭喜:)'; } $this->renderJson(join("<br>", $log), $code); }