Browse Source

增加对不同Subversion的兼容性(针对Subversion 1.9及以下)

docker-svn
witersen 3 years ago
parent
commit
0c95096cb9
  1. 15
      01.web/src/views/repositoryInfo/index.vue
  2. 6
      02.php/api.php
  3. 8
      02.php/app/service/Common.php
  4. 6
      02.php/app/service/Mail.php
  5. 4
      02.php/app/service/Svn.php
  6. 7
      02.php/app/service/Svnrep.php
  7. 15
      02.php/app/util/SVNAdmin/Rep.php
  8. 46
      02.php/config/database.php
  9. 11
      02.php/config/svn.php
  10. 18
      02.php/config/update.php
  11. 91
      02.php/server/install.php
  12. 8
      02.php/server/svnadmind.php

15
01.web/src/views/repositoryInfo/index.vue

@ -249,6 +249,14 @@
> >
</Col> </Col>
</Row> </Row>
<Alert type="warning"
>请注意当前的文件下载方案采用
<a href="https://github.com/jimmywarting/StreamSaver.js" target="_blank"
>StreamSaver</a
>
<br />
如要获取良好的下载体验请为站点配置HTTPS</Alert
>
<Table <Table
height="200" height="200"
border border
@ -619,8 +627,9 @@
<Spin size="large" fix v-if="loadingGetRepHooks"></Spin> <Spin size="large" fix v-if="loadingGetRepHooks"></Spin>
</TabPane> </TabPane>
<TabPane label="常用钩子"> <TabPane label="常用钩子">
<Alert>如需将自己常用的钩子显示在此处<br/><br/> <Alert
以新增 pre-commit 功能为例操作步骤如下<br><br/> >如需将自己常用的钩子显示在此处<br /><br />
以新增 pre-commit 功能为例操作步骤如下<br /><br />
1 /home/svnadmin/hooks/ 目录下创建任意名称的文件夹<br /> 1 /home/svnadmin/hooks/ 目录下创建任意名称的文件夹<br />
2创建文件 hookDescription 并写入此钩子的主要功能描述<br /> 2创建文件 hookDescription 并写入此钩子的主要功能描述<br />
3创建文件 hookName 并写入钩子的类型 pre-commit<br /> 3创建文件 hookName 并写入钩子的类型 pre-commit<br />
@ -2563,7 +2572,7 @@ export default {
*/ */
ViewRecommendHook(hookName) { ViewRecommendHook(hookName) {
var temp = this.recommendHooks.filter( var temp = this.recommendHooks.filter(
(item) => item.hookName = hookName (item) => (item.hookName = hookName)
); );
// //
this.tempSelectRepHookRecommend = temp[0].hookContent; this.tempSelectRepHookRecommend = temp[0].hookContent;

6
02.php/api.php

@ -3,12 +3,14 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:06 * @Date: 2022-04-24 23:37:06
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-09 21:11:05 * @LastEditTime: 2022-05-11 23:48:29
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
/** /**
* 需要PHP版本大于等于5.5同时小于8.0 * 需要PHP版本大于等于5.5同时小于8.0
*
* 不考虑扩展的情况下,本系统兼容php 5.4 ,但是由于 phpmailer 插件的引入需要兼容 php 5.4
*/ */
/** /**
@ -96,6 +98,8 @@ foreach ($disable_functions as $disable) {
//检测守护进程状态 //检测守护进程状态
$state = FunDetectState(); $state = FunDetectState();
// echo $state;
// return;
if ($state == 0) { if ($state == 0) {
json1(401, 0, '守护进程响应超时'); json1(401, 0, '守护进程响应超时');
} else if ($state == 2) { } else if ($state == 2) {

8
02.php/app/service/Common.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-10 14:43:54 * @LastEditTime: 2022-05-12 00:01:12
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -101,8 +101,8 @@ class Common extends Base
//日志 //日志
$this->Logs->InsertLog( $this->Logs->InsertLog(
'用户登录', '用户登录',
sprintf("账号 %s IP地址", $this->payload['user_name'], $_SERVER["REMOTE_ADDR"]), sprintf("账号 %s IP地址 %s", $this->payload['user_name'], $_SERVER["REMOTE_ADDR"]),
$this->userName $this->payload['user_name']
); );
//邮件 //邮件
@ -131,7 +131,7 @@ class Common extends Base
//日志 //日志
$this->Logs->InsertLog( $this->Logs->InsertLog(
'用户注销', '用户注销',
sprintf("账号 %s IP地址", $this->userName, $_SERVER["REMOTE_ADDR"]), sprintf("账号 %s IP地址 %s", $this->userName, $_SERVER["REMOTE_ADDR"]),
$this->userName $this->userName
); );

6
02.php/app/service/Mail.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-10 14:31:29 * @LastEditTime: 2022-05-11 15:48:55
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -284,11 +284,11 @@ class Mail extends Base
$message_push = $this->GetPush(); $message_push = $this->GetPush();
$message_push = $message_push['data']; $message_push = $message_push['data'];
$triggers = array_column($message_push, 'trigger'); $triggers = FunArrayColumn($message_push, 'trigger');
if (!in_array($trigger, $triggers)) { if (!in_array($trigger, $triggers)) {
return message(200, 0, '触发条件不存在'); return message(200, 0, '触发条件不存在');
} }
$options = array_combine($triggers, array_column($message_push, 'enable')); $options = array_combine($triggers, FunArrayColumn($message_push, 'enable'));
if (!$options[$trigger]) { if (!$options[$trigger]) {
return message(200, 0, '触发条件未开启'); return message(200, 0, '触发条件未开启');
} }

4
02.php/app/service/Svn.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-11 02:15:44 * @LastEditTime: 2022-05-12 00:20:14
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -25,7 +25,7 @@ class Svn extends Base
$result = $result['result']; $result = $result['result'];
if ($result == '') { if ($result == '') {
return message(200, 0, 'svnserve服务未在运行,SVN用户将无法使用系统的仓库在线内容浏览功能'); return message(200, 0, 'svnserve服务未在运行,出于安全原因,SVN用户将无法使用系统的仓库在线内容浏览功能,其它功能不受影响');
} else { } else {
return message(); return message();
} }

7
02.php/app/service/Svnrep.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:05 * @Date: 2022-04-24 23:37:05
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-11 15:24:12 * @LastEditTime: 2022-05-12 00:51:04
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -62,9 +62,12 @@ class Svnrep extends Base
$cmd = sprintf("export LC_CTYPE=en_US.UTF-8 && '%s' create " . $this->config_svn['rep_base_path'] . $this->payload['rep_name'], $this->config_bin['svnadmin']); $cmd = sprintf("export LC_CTYPE=en_US.UTF-8 && '%s' create " . $this->config_svn['rep_base_path'] . $this->payload['rep_name'], $this->config_bin['svnadmin']);
FunShellExec($cmd); FunShellExec($cmd);
//关闭selinux
FunShellExec('setenforce 0');
if ($this->payload['rep_type'] == '2') { if ($this->payload['rep_type'] == '2') {
//以指定的目录结构初始化仓库 //以指定的目录结构初始化仓库
$this->SVNAdminRep->InitRepStruct($this->config_svn['templete_init_struct'], $this->config_svn['rep_base_path'] . $this->payload['rep_name']); $this->SVNAdminRep->InitRepStruct($this->config_svn['templete_init_struct_01'], $this->config_svn['rep_base_path'] . $this->payload['rep_name']);
} }
//检查是否创建成功 //检查是否创建成功

15
02.php/app/util/SVNAdmin/Rep.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-27 15:45:45 * @Date: 2022-04-27 15:45:45
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-09 16:58:20 * @LastEditTime: 2022-05-12 11:09:39
* @Description: QQ:1801168257 * @Description: QQ:1801168257
* @copyright: https://github.com/witersen/ * @copyright: https://github.com/witersen/
*/ */
@ -869,6 +869,8 @@ class Rep extends Core
* FSFS Shard Size * FSFS Shard Size
* FSFS Shards Packed * FSFS Shards Packed
* FSFS Logical Addressing * FSFS Logical Addressing
*
* 此函数暂未使用因为包含兼容性问题 需要 Subversion > 1.9
*/ */
function GetRepInfo($repName) function GetRepInfo($repName)
{ {
@ -1199,12 +1201,19 @@ class Rep extends Core
/** /**
* 获取仓库的修订版本数量 * 获取仓库的修订版本数量
* svnadmin info * svnadmin info
*
* Subversion 1.9 及以前没有 svnadmin info 子指令
* 因此使用 svnlook youngest 来代替
*/ */
function GetRepRev($repName) function GetRepRev($repName)
{ {
$cmd = sprintf("'%s' info '%s' | grep 'Revisions' | awk '{print $2}'", $this->config_bin['svnadmin'], $this->config_svn['rep_base_path'] . $repName); // $cmd = sprintf("'%s' info '%s' | grep 'Revisions' | awk '{print $2}'", $this->config_bin['svnadmin'], $this->config_svn['rep_base_path'] . $repName);
$cmd = sprintf("'%s' youngest '%s'", $this->config_bin['svnlook'], $this->config_svn['rep_base_path'] . $repName);
$result = FunShellExec($cmd); $result = FunShellExec($cmd);
return (int)$result['result'];
return (int)trim($result['result']);
} }
/** /**

46
02.php/config/database.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-05-07 00:38:48 * @Date: 2022-05-07 00:38:48
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-10 10:51:59 * @LastEditTime: 2022-05-11 18:24:28
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -11,24 +11,24 @@
* for MySQL * for MySQL
* config from Medoo 1.7.10 * config from Medoo 1.7.10
*/ */
return [ // return [
'database_type' => 'mysql', // 'database_type' => 'mysql',
'server' => 'sas2.witersen.com', // 'server' => 'localhost',
'database_name' => 'svnadmin', // 'database_name' => 'svnadmin',
'username' => 'svnadmin', // 'username' => 'svnadmin',
'password' => 'svnadmin', // 'password' => 'svnadmin',
'charset' => 'utf8mb4', // 'charset' => 'utf8mb4',
'collation' => 'utf8mb4_general_ci', // 'collation' => 'utf8mb4_general_ci',
'port' => 3306, // 'port' => 3306,
'prefix' => '', // 'prefix' => '',
'logging' => false, // 'logging' => false,
'option' => [ // 'option' => [
PDO::ATTR_CASE => PDO::CASE_NATURAL // PDO::ATTR_CASE => PDO::CASE_NATURAL
], // ],
'command' => [ // 'command' => [
'SET SQL_MODE=ANSI_QUOTES' // 'SET SQL_MODE=ANSI_QUOTES'
] // ]
]; // ];
/** /**
* for SQLite * for SQLite
@ -37,7 +37,7 @@ return [
* %s 为占位符 无需修改 * %s 为占位符 无需修改
*/ */
// return [ return [
// 'database_type' => 'sqlite', 'database_type' => 'sqlite',
// 'database_file' => '%ssvnadmin.db' 'database_file' => '%ssvnadmin.db'
// ]; ];

11
02.php/config/svn.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:06 * @Date: 2022-04-24 23:37:06
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-11 11:32:27 * @LastEditTime: 2022-05-12 00:52:40
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -23,6 +23,8 @@ $temp_base_path = $home_path . 'temp/';
$templete_base_path = $home_path . 'templete/'; $templete_base_path = $home_path . 'templete/';
$templete_init_struct = $templete_base_path . 'initStruct/';
return [ return [
/** /**
* SVNAdmin软件配置信息的主目录 * SVNAdmin软件配置信息的主目录
@ -97,5 +99,10 @@ return [
/** /**
* 初始化仓库结构模板目录 * 初始化仓库结构模板目录
*/ */
'templete_init_struct' => $templete_base_path . '01/', 'templete_init_struct' => $templete_init_struct,
/**
* 默认使用的仓库模板
*/
'templete_init_struct_01' => $templete_init_struct . '01/',
]; ];

18
02.php/config/update.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:06 * @Date: 2022-04-24 23:37:06
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-09 11:41:24 * @LastEditTime: 2022-05-11 19:58:31
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -12,17 +12,13 @@
*/ */
return [ return [
'update_server' => [ 'update_server' => [
// [
// 'nodeName' => 'gitee.com',
// 'url' => 'https://gitee.com/witersen/update/raw/master/SvnAdmin/update2.json'
// ],
// [
// 'nodeName' => 'github.com',
// 'url' => 'https://gitee.com/witersen/update/raw/master/SvnAdmin/update2.json'
// ],
[ [
'nodeName' => 'witersen.com', 'nodeName' => 'gitee.com',
'url' => 'http://dev.witersen.com/server/update.json' 'url' => 'https://gitee.com/witersen/update/raw/master/SvnAdmin/update2.json'
],
[
'nodeName' => 'github.com',
'url' => 'https://gitee.com/witersen/update/raw/master/SvnAdmin/update2.json'
] ]
] ]
]; ];

91
02.php/server/install.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-05-08 13:31:07 * @Date: 2022-05-08 13:31:07
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-11 13:46:48 * @LastEditTime: 2022-05-12 00:11:29
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -64,6 +64,23 @@ class Install
$this->config_version = Config::get('version'); $this->config_version = Config::get('version');
} }
/**
* 由于array_column到php5.5+才支持
* 为了兼容php5.4
* 这里选择手动实现 可能性能不高
*/
function FunArrayColumn($array, $columnKey)
{
$resultArray = [];
foreach ($array as $key => $value) {
if (!array_key_exists($columnKey, $value)) {
return false;
}
array_push($resultArray, $value[$columnKey]);
}
return $resultArray;
}
/** /**
* 检测SVNAdmin的新版本并选择更新 * 检测SVNAdmin的新版本并选择更新
*/ */
@ -129,7 +146,7 @@ class Install
//下载并执行升级脚本 //下载并执行升级脚本
$packages = $array['update']['download'][$key1]['packages']; $packages = $array['update']['download'][$key1]['packages'];
$forList = array_column($packages, 'for'); $forList = $this->FunArrayColumn($packages, 'for');
$current = [ $current = [
'source' => $this->config_version['version'], 'source' => $this->config_version['version'],
'dest' => $last 'dest' => $last
@ -194,6 +211,22 @@ class Install
*/ */
function ConfigSubversion() function ConfigSubversion()
{ {
echo PHP_EOL . '===============================================' . PHP_EOL;
echo '确定要开始配置Subversion程序吗[y/n]:';
$continue = strtolower(trim(fgets(STDIN)));
if (!in_array($continue, ['y', 'n'])) {
echo '不正确的选项!' . PHP_EOL;
echo '===============================================' . PHP_EOL;
exit();
}
if ($continue == 'n') {
echo '已取消!' . PHP_EOL;
echo '===============================================' . PHP_EOL;
exit();
}
/** /**
* 1、检测Subversion的安装情况 * 1、检测Subversion的安装情况
*/ */
@ -219,6 +252,10 @@ class Install
'svnmucc' => '' 'svnmucc' => ''
]; ];
echo '===============================================' . PHP_EOL;
echo '开始配置Subversion程序!' . PHP_EOL;
echo '===============================================' . PHP_EOL;
foreach ($needBin as $key => $value) { foreach ($needBin as $key => $value) {
echo "请输入 $key 程序位置:" . PHP_EOL; echo "请输入 $key 程序位置:" . PHP_EOL;
echo '自动检测到以下程序路径:' . PHP_EOL; echo '自动检测到以下程序路径:' . PHP_EOL;
@ -280,7 +317,7 @@ CON;
//创建推荐钩子目录 //创建推荐钩子目录
is_dir($this->config_svn['recommend_hook_path']) ? '' : mkdir($this->config_svn['recommend_hook_path'], 0700, true); is_dir($this->config_svn['recommend_hook_path']) ? '' : mkdir($this->config_svn['recommend_hook_path'], 0700, true);
shell_exec(sprintf("cp -r '%s' '%s'", $templete_path . '/hooks', $this->config_svn['recommend_hook_path'])); shell_exec(sprintf("cp -r '%s' '%s'", $templete_path . '/hooks', $this->config_svn['home_path']));
//创建备份目录 //创建备份目录
is_dir($this->config_svn['backup_base_path']) ? '' : mkdir($this->config_svn['backup_base_path'], 0700, true); is_dir($this->config_svn['backup_base_path']) ? '' : mkdir($this->config_svn['backup_base_path'], 0700, true);
@ -291,6 +328,13 @@ CON;
//创建临时数据目录 //创建临时数据目录
is_dir($this->config_svn['temp_base_path']) ? '' : mkdir($this->config_svn['temp_base_path'], 0700, true); is_dir($this->config_svn['temp_base_path']) ? '' : mkdir($this->config_svn['temp_base_path'], 0700, true);
//创建模板文件目录
is_dir($this->config_svn['templete_base_path']) ? '' : mkdir($this->config_svn['templete_base_path'], 0700, true);
//创建仓库结构模板目录
// is_dir($this->config_svn['templete_init_struct']) ? '' : mkdir($this->config_svn['templete_init_struct'], 0700, true);
shell_exec(sprintf("cp -r '%s' '%s'", $templete_path . '/initStruct', $this->config_svn['templete_base_path']));
echo '===============================================' . PHP_EOL; echo '===============================================' . PHP_EOL;
echo '创建相关文件' . PHP_EOL; echo '创建相关文件' . PHP_EOL;
@ -321,17 +365,42 @@ CON;
echo '===============================================' . PHP_EOL; echo '===============================================' . PHP_EOL;
/** /**
* 4、配置SQLite数据库文件 * 4、关闭selinux
* 包括临时关闭和永久关闭
*/
echo '临时关闭并永久关闭seliux' . PHP_EOL;
//临时关闭selinux
shell_exec('setenforce 0');
//永久关闭selinux
shell_exec("sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config");
echo '===============================================' . PHP_EOL;
/**
* 5、配置SQLite数据库文件
*/ */
echo '配置并启用SQLite数据库' . PHP_EOL; echo '配置并启用SQLite数据库' . PHP_EOL;
copy($templete_path . '/database/sqlite/svnadmin.db', $this->config_svn['home_path'] . 'svnadmin.db'); copy($templete_path . '/database/sqlite/svnadmin.db', $this->config_svn['home_path'] . 'svnadmin.db');
echo '===============================================' . PHP_EOL;
//配置SQLite数据库文件的父目录权限配置为777 解决无法写入且不报错的问题 //配置SQLite数据库文件的父目录权限配置为777 解决无法写入且不报错的问题
shell_exec('chmod 777 ' . $this->config_svn['home_path']); shell_exec('chmod 777 ' . $this->config_svn['home_path']);
echo '===============================================' . PHP_EOL;
/** /**
* 5、将svnserve注册为系统服务 * 6、主目录授权
*/
echo '配置主目录权限' . PHP_EOL;
shell_exec(sprintf("chmod 777 -R '%s'", $this->config_svn['home_path']));
echo '===============================================' . PHP_EOL;
/**
* 7、将svnserve注册为系统服务
*/ */
echo '清理之前注册的svnserve服务' . PHP_EOL; echo '清理之前注册的svnserve服务' . PHP_EOL;
@ -389,7 +458,7 @@ CON;
echo '===============================================' . PHP_EOL; echo '===============================================' . PHP_EOL;
if (!in_array($answer, array_column($this->scripts, 'index'))) { if (!in_array($answer, $this->FunArrayColumn($this->scripts, 'index'))) {
exit('错误的命令编号:' . PHP_EOL); exit('错误的命令编号:' . PHP_EOL);
} }
@ -404,6 +473,14 @@ CON;
$shell = scandir($shellPath); $shell = scandir($shellPath);
echo '安装脚本来自 WANdiso' . PHP_EOL;
echo '如果由于网络延迟原因安装失败,可手动停止后多尝试几次' . PHP_EOL;
echo '在通过脚本安装Subversion的过程中,请注意信息交互!' . PHP_EOL;
echo '===============================================' . PHP_EOL;
echo '可选择的Subversion版本如下:' . PHP_EOL; echo '可选择的Subversion版本如下:' . PHP_EOL;
$noShell = true; $noShell = true;

8
02.php/server/svnadmind.php

@ -3,7 +3,7 @@
* @Author: witersen * @Author: witersen
* @Date: 2022-04-24 23:37:06 * @Date: 2022-04-24 23:37:06
* @LastEditors: witersen * @LastEditors: witersen
* @LastEditTime: 2022-05-11 01:54:56 * @LastEditTime: 2022-05-12 00:17:45
* @Description: QQ:1801168257 * @Description: QQ:1801168257
*/ */
@ -130,6 +130,7 @@ class Daemon
{ {
//接收客户端发送的数据 //接收客户端发送的数据
$receive = socket_read($client, $this->config_daemon['SOCKET_READ_LENGTH']); $receive = socket_read($client, $this->config_daemon['SOCKET_READ_LENGTH']);
$receive = unserialize($receive); $receive = unserialize($receive);
$type = $receive['type']; $type = $receive['type'];
@ -273,7 +274,10 @@ class Daemon
} }
} }
$this->UpdateSign(); $this->UpdateSign();
echo '已在启动时自动更改系统的加密密钥,正在登录的用户会退出登录' . PHP_EOL; echo '启动成功' . PHP_EOL;
echo '可进行网站访问' . PHP_EOL;
echo '检出SVN仓库前请注意放行协议端口(默认3690)' . PHP_EOL;
echo '已自动更改系统加密密钥,在线用户会退出登录' . PHP_EOL;
$this->InitDeamon(); $this->InitDeamon();
} }

Loading…
Cancel
Save