Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qa-deploy-utils
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
QA
qa-deploy-utils
Commits
19e0e3e0
Commit
19e0e3e0
authored
Jan 28, 2019
by
智勇
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into 4.96
parents
114370a5
27a788c8
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
225 additions
and
98 deletions
+225
-98
daily_db_backup.sh
db-utils/daily_db_backup.sh
+2
-0
3_link_config_file_by_name.sh
qa_shell_script/3_link_config_file_by_name.sh
+1
-1
restartJava.sh
qa_shell_script/base_script/restartJava.sh
+16
-16
get_project_config_server.js
qa_shell_script/config_server/get_project_config_server.js
+50
-26
get_project_host.sh
qa_shell_script/config_server/get_project_host.sh
+0
-17
package.json
qa_shell_script/config_server/package.json
+7
-3
docker_env_name.sh
qa_shell_script/ngrok/docker_env_name.sh
+0
-0
make_frp_ini_V2.sh
qa_shell_script/ngrok/make_frp_ini_V2.sh
+105
-16
delete_All_Data.sh
qa_shell_script/script_by_Contorller/delete_All_Data.sh
+14
-7
landing_url.sh
qa_shell_script/script_by_Contorller/landing_url.sh
+2
-2
xhed_spider.sh
qa_shell_script/script_by_Contorller/xhed_spider.sh
+28
-10
No files found.
db-utils/daily_db_backup.sh
View file @
19e0e3e0
...
...
@@ -24,6 +24,8 @@ function db_schema_sync()
config_file_name
=
"
$sync_config_folder
/
${
database
}
_
${
uuid
}
_db_schema_sync_config.json"
db_backup_sub_folders
=
$db_backup_folder
/
${
database
}
echo
"rm -rf
$db_backup_sub_folders
"
rm
-rf
$db_backup_sub_folders
echo
"mkdir -p
$db_backup_sub_folders
"
mkdir
-p
$db_backup_sub_folders
mkdir
-p
$sync_config_folder
...
...
qa_shell_script/3_link_config_file_by_name.sh
View file @
19e0e3e0
...
...
@@ -18,7 +18,7 @@ then
sh
$config_server
/show_info.sh
$project
连接配置文件
$desc
$3
project_type
=
`
node
$config_server
/get_project_config.js
-name
$project
-attr
type
`
file
=
`
node
$config_server
/get_project_config.js
-name
$project
-attr
config_file
`
file
=
${
file
:
=
"application.properties"
}
#
file=${file:="application.properties"}
echo
"rm -rf /home/quant_group/
${
project
}
/
$file
"
rm
-rf
/home/quant_group/
$project
/
$file
...
...
qa_shell_script/base_script/restartJava.sh
View file @
19e0e3e0
...
...
@@ -83,22 +83,22 @@ fi
config_file
=
`
find ./
-maxdepth
2
-name
"application.properties"
`
if
[
-n
"
$config_file
"
]
then
echo
"
$project
already have config file"
else
echo
"
$project
have no config file"
if
$is_public_ip
&&
[
-n
"
$is_public_ip
"
]
then
rm
-rf
/home/quant_group/
${
project
}
/application.properties
echo
"ln -s
$config_path
/public/java/
${
project
}
.* /home/quant_group/
${
project
}
/application.properties"
ln
-s
$config_path
/public/java/
${
project
}
.
*
/home/quant_group/
${
project
}
/application.properties
else
rm
-rf
/home/quant_group/
${
project
}
/application.properties
echo
"ln -s
$config_path
/java/
${
project
}
.* /home/quant_group/
${
project
}
/application.properties"
ln
-s
$config_path
/java/
${
project
}
.
*
/home/quant_group/
${
project
}
/application.properties
fi
fi
#
if [ -n "$config_file" ]
#
then
#
echo "$project already have config file"
#
else
#
echo "$project have no config file"
#
if $is_public_ip && [ -n "$is_public_ip" ]
#
then
#
rm -rf /home/quant_group/${project}/application.properties
#
echo "ln -s $config_path/public/java/${project}.* /home/quant_group/${project}/application.properties"
#
ln -s $config_path/public/java/${project}.* /home/quant_group/${project}/application.properties
#
else
#
rm -rf /home/quant_group/${project}/application.properties
#
echo "ln -s $config_path/java/${project}.* /home/quant_group/${project}/application.properties"
#
ln -s $config_path/java/${project}.* /home/quant_group/${project}/application.properties
#
fi
#
fi
echo
"Project:
$project
will be start"
log_name
=
`
node
$config_server
/get_project_config.js
-name
$project
-attr
log_name
`
...
...
qa_shell_script/config_server/get_project_config_server.js
View file @
19e0e3e0
...
...
@@ -93,14 +93,15 @@ function parseJson2Str(json) {
function
getProjectConfigPromise
()
{
return
new
Promise
(
function
(
resolve
,
reject
)
{
// mongoose.model("ProConfig",new mongoose.Schema({}))
ProConfig
.
find
({}).
exec
().
then
(
res
=>
{
ProConfig
.
find
({
is_active
:
true
}).
exec
().
then
(
res
=>
{
let
_pros
=
JSON
.
parse
(
JSON
.
stringify
(
res
));
let
re
=
{},
hosts
=
{};
for
(
let
pro
of
_pros
)
{
hosts
[
pro
[
"
project_name
"
]]
=
pro
[
"
host_name
"
];
if
(
pro
[
"
project_name
"
]
==
"
xjd-ui
"
)
{
hosts
[
"
xyqb-ui--xjd-ui
"
]
=
pro
[
"
host_name
"
];
}
else
if
(
pro
[
"
project_name
"
]
==
"
new-paycenter-ui
"
)
{
// if (pro["project_name"] == "xjd-ui") {
// hosts["xyqb-ui--xjd-ui"] = pro["host_name"];
// } else
if
(
pro
[
"
project_name
"
]
==
"
new-paycenter-ui
"
)
{
hosts
[
"
paycenter-ui--new-paycenter-ui
"
]
=
pro
[
"
host_name
"
];
}
...
...
@@ -255,7 +256,20 @@ admin.get('/get_project_attr/:name', async function (req, res) {
res
.
send
(
e
)
}
});
// 获取项目配置具体属性
admin
.
get
(
'
/get_attr_from_project/:name/:attr
'
,
async
function
(
req
,
res
)
{
// res.setHeader("Content-Type", "text");
var
names
=
req
.
params
.
name
.
split
(
"
--
"
);
var
p_name
=
""
;
if
(
names
.
length
>
1
)
{
p_name
=
names
[
0
]
}
else
{
p_name
=
req
.
params
.
name
}
let
pro
=
await
getProjectConfigPromiseByDb
({
project_name
:
req
.
params
.
name
});
let
val
=
pro
[
0
][
req
.
params
.
attr
];
res
.
send
(
val
);
});
// 获取所有域名
admin
.
get
(
'
/get_hosts
'
,
async
function
(
req
,
res
)
{
...
...
@@ -279,12 +293,13 @@ function getfrontendbackend(pros) {
for
(
let
key
of
keys
)
{
let
pro
=
pros
[
key
]
if
(
pro
.
type
==
"
ui
"
)
{
// && pro.name != "spider-center-ui"
if
(
pro
.
name
!=
"
xyqb-ui
"
&&
pro
.
name
!=
"
paycenter-ui
"
)
{
if
(
pro
.
name
==
"
xjd-ui
"
)
{
temp
.
frontend
.
push
(
"
xyqb-ui--xjd-ui
"
);
temp
[
pro
.
type
].
push
(
"
xyqb-ui--xjd-ui
"
)
}
else
if
(
pro
.
name
==
"
new-paycenter-ui
"
)
{
// && pro.name != "spider-center-ui" pro.name != "xyqb-ui" &&
if
(
pro
.
name
!=
"
paycenter-ui
"
)
{
// if (pro.name == "xjd-ui") {
// temp.frontend.push("xyqb-ui--xjd-ui");
// temp[pro.type].push("xyqb-ui--xjd-ui")
// } else
if
(
pro
.
name
==
"
new-paycenter-ui
"
)
{
temp
.
frontend
.
push
(
"
paycenter-ui--new-paycenter-ui
"
);
temp
[
pro
.
type
].
push
(
"
paycenter-ui--new-paycenter-ui
"
)
}
...
...
@@ -310,7 +325,7 @@ admin.get('/get_systems_by_type', async function (req, res) {
let
pros
=
configs
.
projects
;
let
fb
=
getfrontendbackend
(
pros
);
res
.
send
({
common
:
"
db,redis,rabbitmq,zookeeper
"
,
common
:
"
db,redis,rabbitmq,zookeeper
,kong,postgres,mongodb
"
,
frontend
:
fb
.
frontend
.
join
(
"
,
"
),
backend
:
fb
.
backend
.
join
(
"
,
"
)
});
...
...
@@ -329,6 +344,12 @@ admin.get('/get_systems_by_type_for_jenkins/:_type', async function (req, res) {
}
});
// 提供所有项目的所有配置
admin
.
get
(
'
/get_pro_configs
'
,
async
function
(
req
,
res
)
{
let
configs
=
await
getProjectConfigPromise
();
res
.
send
(
configs
.
projects
);
});
// 给jenkins使用根据类型获取系统名称
admin
.
get
(
'
/get_systems_by_type_for_temp
'
,
async
function
(
req
,
res
)
{
let
configs
=
await
getProjectConfigPromise
();
...
...
@@ -356,15 +377,15 @@ admin.get('/get_namespace_by_type_for_jenkins/:_type', async function (req, res)
res
.
send
(
ns_array
.
join
(
"
\n
"
));
});
// 获取这个服务的所有配置
admin
.
get
(
'
/get_config/:_name
'
,
async
function
(
req
,
res
)
{
let
config
=
await
getProjectConfigPromiseByDb
({
project_name
:
req
.
params
.
_name
});
res
.
send
(
config
[
0
])
admin
.
get
(
'
/get_config/:_name
'
,
async
function
(
req
,
res
)
{
let
config
=
await
getProjectConfigPromiseByDb
({
project_name
:
req
.
params
.
_name
});
res
.
send
(
config
[
0
])
})
// 给jenkins使用获取服务groupname_projectname
admin
.
get
(
'
/get_groupname_by_type_for_jenkins/:_type
'
,
async
function
(
req
,
res
)
{
let
configs
=
await
getProjectConfigPromiseByDb
({});
let
configs
=
await
getProjectConfigPromiseByDb
({
is_active
:
true
});
let
re
=
{
ui
:
[],
java
:
[],
...
...
@@ -373,15 +394,16 @@ admin.get('/get_groupname_by_type_for_jenkins/:_type', async function (req, res)
};
let
xjdui
=
[[
""
,
""
],
[
""
,
""
]],
payui
=
[[
""
,
""
],
[
""
,
""
]]
for
(
let
o
of
configs
)
{
if
(
o
.
project_name
==
"
xyqb-ui
"
)
{
xjdui
[
0
][
0
]
=
o
.
git_path_group
xjdui
[
1
][
0
]
=
o
.
project_name
}
else
if
(
o
.
project_name
==
"
paycenter-ui
"
)
{
// if (o.project_name == "xyqb-ui") {
// xjdui[0][0] = o.git_path_group
// xjdui[1][0] = o.project_name
// } else if (o.project_name == "xjd-ui") {
// xjdui[0][1] = o.git_path_group
// xjdui[1][1] = o.project_name
// } else
if
(
o
.
project_name
==
"
paycenter-ui
"
)
{
payui
[
0
][
0
]
=
o
.
git_path_group
payui
[
1
][
0
]
=
o
.
project_name
}
else
if
(
o
.
project_name
==
"
xjd-ui
"
)
{
xjdui
[
0
][
1
]
=
o
.
git_path_group
xjdui
[
1
][
1
]
=
o
.
project_name
}
else
if
(
o
.
project_name
==
"
new-paycenter-ui
"
)
{
payui
[
0
][
1
]
=
o
.
git_path_group
payui
[
1
][
1
]
=
o
.
project_name
...
...
@@ -399,9 +421,10 @@ admin.get('/get_groupname_by_type_for_jenkins/:_type', async function (req, res)
}
let
lua_ui
=
[],
cb
=
""
;
if
(
req
.
params
.
_type
==
"
lua_ui
"
)
{
lua_ui
.
push
(
getLuaUiStr
(
xjdui
));
//
lua_ui.push(getLuaUiStr(xjdui));
lua_ui
.
push
(
getLuaUiStr
(
payui
));
cb
=
lua_ui
.
join
(
"
\n
"
);
res
.
send
(
cb
);
}
else
{
res
.
send
(
re
[
req
.
params
.
_type
].
join
(
"
\n
"
));
}
...
...
@@ -460,5 +483,6 @@ admin.get('/get_proxy', function (req, res) {
});
app
.
use
(
'
/config_server
'
,
admin
)
console
.
log
(
"
http://192.168.4.3:10088/config_server/get_node_command
"
)
app
.
listen
(
10088
)
app
.
listen
(
10086
,
function
()
{
console
.
log
(
"
http://192.168.4.3:10088/config_server/get_node_command
"
)
})
qa_shell_script/config_server/get_project_host.sh
deleted
100644 → 0
View file @
114370a5
7001|m.xyqb.com|xyqb-ui
7050|bt.xyqb.com|bt-ui
7003|api.xyqb.com|xyqb
7004|r.xyqb.com|di-ting-ui
7005|rapi.xyqb.com|di-ting
7006|payapi.xyqb.com|gu-bei
7007|pay.xyqb.com|pay-center-ui
7008|off.xyqb.com|offline-ui
7010|offapi.xyqb.com|xyqb-offline
7011|financial.xyqb.com|financial-system-ui
7012|fsapi.xyqb.com|financial-system
7013|auth.xyqb.com|han-gu-guan
7037|qapi.xyqb.com|cash-loan-flow
7019|mallapi.xyqb.com|xyqb-mall
7021|scapi.xyqb.com|spider-center
7029|gyxdapi.xyqb.com|gyxd
7025|btapi.xyqb.com|baitiao
\ No newline at end of file
qa_shell_script/config_server/package.json
View file @
19e0e3e0
{
"name"
:
"config_server"
,
"version"
:
"1.0.0"
,
"description"
:
""
,
"main"
:
"get_project_config.js"
,
"scripts"
:
{
"test"
:
"echo
\"
Error: no test specified
\"
&& exit 1"
"test"
:
"echo
\"
Error: no test specified
\"
&& exit 1"
,
"start"
:
"nodemon get_project_config_server"
},
"author"
:
""
,
"license"
:
"ISC"
,
...
...
@@ -16,5 +16,9 @@
"mongoose"
:
"^5.0.11"
,
"pm2"
:
"^2.7.2"
,
"request"
:
"^2.83.0"
}
},
"devDependencies"
:
{
"nodemon"
:
"^1.18.3"
},
"description"
:
""
}
qa_shell_script/ngrok/docker_env_name.sh
deleted
100644 → 0
View file @
114370a5
qa_shell_script/ngrok/make_frp_ini_V2.sh
View file @
19e0e3e0
This diff is collapsed.
Click to expand it.
qa_shell_script/script_by_Contorller/delete_All_Data.sh
View file @
19e0e3e0
...
...
@@ -2,6 +2,8 @@
ip
=
$1
phone_no
=
$2
port
=
$3
redis_ip
=
$4
redis_port
=
$5
DBNAME
=
"xyqb_user"
DBNAME1
=
"payment_center"
DBNAME2
=
"xyqb"
...
...
@@ -61,6 +63,11 @@ function deleteAlldata()
mysql
$mysqld
${
DBNAME2
}
-e
"delete from pay_center_bank_card where phone_no=
$phone_no
"
mysql
$mysqld
${
DBNAME2
}
-e
"delete from pay_center_biao_tiao_bank_card where phone_no=
$phone_no
"
mysql
$mysqld
${
DBNAME2
}
-e
"delete from repayment_plan where user_id=
$xyqb_user_id
"
mysql
$mysqld
${
DBNAME2
}
-e
"delete from quota_credit where user_id=
$xyqb_user_id
"
mysql
$mysqld
${
DBNAME2
}
-e
"delete from quota_distribute_limit where user_id=
$xyqb_user_id
"
mysql
$mysqld
${
DBNAME2
}
-e
"delete from quota_account where user_id=
$xyqb_user_id
"
mysql
$mysqld
cash_loan_flow
-e
"delete from order_mapping where qg_user_id=
$xyqb_user_id
"
mysql
$mysqld
cash_loan_flow
-e
"delete from user_mapping where qg_user_id=
$xyqb_user_id
"
if
[
-n
"
$loan_id
"
]
;
then
mysql
$mysqld
${
DBNAME2
}
-e
"delete from loan_demand_history where loan_application_history_id in (
$loan_id
)"
mysql
$mysqld
${
DBNAME2
}
-e
"delete from loan_submit_info where loan_id in (
$loan_id
)"
...
...
@@ -73,19 +80,19 @@ function deleteAlldata()
mysql
$mysqld
cash_loan_flow
-e
"delete from order_progress_record where loan_id in (
$loan_id
)"
fi
echo
"删除redis缓存"
redis_key
=
`
redis-cli
-h
$
ip
-p
6379
keys
*
$phone_no
*
`
redis_key
=
`
redis-cli
-h
$
redis_ip
-p
$redis_port
keys
*
$phone_no
*
`
if
[
-n
"
$redis_key
"
]
;
then
echo
$redis_key
redis-cli
-h
$
ip
-p
6379
del
$redis_key
redis-cli
-h
$
redis_ip
-p
$redis_port
del
$redis_key
fi
redis_key
=
`
redis-cli
-h
$
ip
-p
6379
keys
*
$xyqb_user_id
*
`
redis_key
=
`
redis-cli
-h
$
redis_ip
-p
$redis_port
keys
*
$xyqb_user_id
*
`
if
[
-n
"
$redis_key
"
]
;
then
echo
$redis_key
token
=
`
redis-cli
-h
$
ip
-p
6379
get userid-sessionvalue:cache::
$xyqb_user_id
:xyqb
`
redis-cli
-h
$
ip
-p
6379
del
$redis_key
redis_key
=
`
redis-cli
-h
$
ip
-p
6379
keys
*
$token
*
`
token
=
`
redis-cli
-h
$
redis_ip
-p
$redis_port
get userid-sessionvalue:cache::
$xyqb_user_id
:xyqb
`
redis-cli
-h
$
redis_ip
-p
$redis_port
del
$redis_key
redis_key
=
`
redis-cli
-h
$
redis_ip
-p
$redis_port
keys
*
$token
*
`
echo
$redis_key
redis-cli
-h
$
ip
-p
6379
del
$redis_key
redis-cli
-h
$
redis_ip
-p
$redis_port
del
$redis_key
#redis-cli -h $ip -p 6379 keys *$token* | xargs redis-cli -h $ip -p 6379 del
fi
fi
...
...
qa_shell_script/script_by_Contorller/landing_url.sh
View file @
19e0e3e0
...
...
@@ -16,8 +16,8 @@ if [ -z "$registerFrom" ];then
registerFrom
=
214
fi
cash_domain
=
"qapi-
$namespace
.
q-gp
.com"
xyqb_domain
=
"m-
$namespace
.
q-gp
.com"
cash_domain
=
"qapi-
$namespace
.
liangkebang
.com"
xyqb_domain
=
"m-
$namespace
.
liangkebang
.com"
if
[
-z
"
$namespace
"
]
;
then
cash_domain
=
$ip
:7037
...
...
qa_shell_script/script_by_Contorller/xhed_spider.sh
View file @
19e0e3e0
#!/bin/bash
ip
=
$1
phone_no
=
$2
HOSTNAME
=
'$ip'
PORT
=
'$4'
namespace
=
$4
HOSTNAME
=
"
${
ip
}
"
PORT
=
$3
USERNAME
=
'qa'
PASSWORD
=
'qatest'
date
=
"
`
date
+%Y%m%d%H%M%S
`
"
date_now
=
`
date
+
"%Y-%m-%d %T"
`
date
=
$(
date
"+ %Y-%m-%d %H:%M:%S"
)
mysql
=
"-h
${
HOSTNAME
}
-P
${
PORT
}
-u
${
USERNAME
}
-p
${
PASSWORD
}
"
uid
=
"SELECT uuid,id from xyqb_user.user where phone_no=
${
phone_no
}
"
spider
=
"INSERT INTO spider_center.user_auth_info (auth_type, last_auth_time, auth_account_name, user_id, auth_status) VALUES(14,
${
date
}
,
${
phone_no
}
,
${
uid
}
, 1),(7,
${
date_now
}
,
${
phone_no
}
,
${
uid
}
, 1),(0,
${
date_now
}
,
${
phone_no
}
,
${
uid
}
, 1);"
address
=
"INSERT INTO xyqb_user.address (user_id, province_code, province, city_code, city, district_code, district, address, created_at, updated_at) VALUES("
+userid+
", 450000, '广西壮族自治区', 450500, '北海市', 450503, '银海区', '海淀区中关村102号', '"
+date+
"', '"
+date+
"');"
contact
=
"INSERT INTO xyqb_user.contact (user_id, name, phone_no, relation, created_at, updated_at)VALUES("
+userid+
", '张三', '138888888899', 3, '"
+date+
"', '"
+date+
"'),( "
+userid+
", '李四', '13888888888', 3, '"
+date+
"', '"
+date+
"');"
print:
function
basicData
()
{
#查询用户ID
uuid
=
"SELECT uuid from user where phone_no=
${
phone_no
}
"
id
=
"SELECT id from user where phone_no=
${
phone_no
}
"
uid
=
`
mysql
-N
$mysql
xyqb_user
-e
"set names utf8;
${
uuid
}
"
`
userid
=
`
mysql
-N
$mysql
xyqb_user
-e
"set names utf8;
${
id
}
"
`
#spider_center.user_auth_info插入基础资料、拍照、运营商认证
spider
=
"INSERT INTO spider_center.user_auth_info (auth_type, last_auth_time, auth_account_name, user_id, auth_status) VALUES (14, '
${
date
}
',
${
phone_no
}
, '
${
uid
}
', 1),(7, '
${
date
}
',
${
phone_no
}
, '
${
uid
}
', 1),(0,'
${
date
}
',
${
phone_no
}
, '
${
uid
}
', 1)"
#xyqb_user.address插入地址
address
=
"INSERT INTO xyqb_user.address (user_id, province_code, province, city_code, city, district_code, district, address, created_at, updated_at) VALUES(
${
userid
}
, 450000, '广西壮族自治区', 450500, '北海市', 450503, '银海区', '海淀区中关村102号', '
${
date
}
', '
${
date
}
')"
#xyqb_user.contact插入联系人信息
contact
=
"INSERT INTO xyqb_user.contact (user_id, name, phone_no, relation, created_at, updated_at)VALUES(
${
userid
}
, '张三', '13888888889', 3, '
${
date
}
', '
${
date
}
'),(
${
userid
}
, '李四', '13888888888', 3, '
${
date
}
', '
${
date
}
')"
#xyqb_user.user_detail添加联系人邮箱
userDetail
=
"update xyqb_user.user_detail set email='19925632562@163.com' where user_id=
${
userid
}
"
#xyqb_user.user_ext_info插入用户职业、学历
userExtInfo
=
"INSERT INTO xyqb_user.user_ext_info (user_id, means_of_income_payment, monthly_income_range, occupation, education, has_car, has_social_security, has_house, has_credit_card, marry_status, created_at, updated_at) VALUES(
${
userid
}
, 0, 3, 3, 3, 0, 0, 0, 0, 0, '
${
date
}
', '
${
date
}
')"
#执行sql
mysql
${
mysql
}
-e
"set names utf8;
${
spider
}
;
${
address
}
;
${
contact
}
;
${
userDetail
}
;
${
userExtInfo
}
"
echo
"done!!!!
${
date
}
"
}
basicData
$ip
$phone_no
$namespace
$PORT
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment