Centos7搭建Nitrate

基于python+Django,测试用例管理平台Nitrate搭建

前言

基于目前Jira+confluence已经成为日常流程管控,老大就琢磨着我们测试用例需要个专门的平台进行管控,所以也就产生了调研的需求,候选有俩:testlink和Nitrate,由于目前组内python氛围较活跃,自动化测试用例也是基于python,所以也就是希望能找到一个基于python写的系统,方便定制,二次开发嘛~

开篇

在有搭建Nitrate这个任务之后,本着偷懒的心态,首先搜了一圈搭建教程,然而,一篇都没找到!!!也就是说,我得自己折腾了!!!没办法,直接上github找项目地址,说不定在说明里面有介绍呢

Nitrate项目地址

里面的确是有介绍,搭建教程貌似也有,还是各种环境的搭建教程,好像看到些光辉啊..

Nitrate Doc

文档介绍了各种搭建教程,选你看着比较顺眼的,动手吧~

坎坷的系统搭建

平时Linux还算是比较顺手,直接选Installing nitrate on RHEL6 with Apache and MySQL,虽然介绍的Redhat的,不都涨一样嘛~开工:
由于自己电脑还是Windows的(别提了,测试嘛,需要太多工具,唉),首先就是搭个Centos7的虚拟机,轻车熟路了,非常迅速的完工,Xshell远程连上,开始愉快的黑窗口作业。。

环境准备

由于搭建的centos7是所谓的CentOS-7-x86_64-Everything-1611版本,网卡什么的驱动都是装好了,如果你装的是最间版,那么ifconfig命令都敲不了。。。自己百度怎么开网吧。。

Git

由于是需要从github仓库直接拉项目,所以git就必须先搭个了:

1
yum install git

就完成了,如果遇到yum不让用,日志显示XX进程正在使用yum,那要么等,要么就是暴力点,直接杀:

1
rm -rf /var/run/yum.pid

然后就可以安心的yum install了。

Django

由于Nitrate是基于Django的,所以,必不可少的需要装个Django;装Django,有三种方法:

pip

最简单就是一条命令带走:

1
pip install Django
setuptools

使用setuptools安装,首先需要先装它:

1
yum install python-setuptools

安装完成之后,再使用easy_install 安装django:

1
easy_install django
源码安装

首先是上官网下载个tar.gz格式的源码包:

官方源码下载地址

然后就可以开始正常的解压安装了:

cd your_path
rz    (windows拷包到linux)
tar -zxvf Django-x.x.tar.gz
python setup.py install
1
即可完成安装,验证:
django-admin.py
1
正确安装会出现很多选项,类似这样:
[root@localhost run]# django-admin.py Type 'django-admin.py help <subcommand>' for help on a specific subcommand. Available subcommands: [django] check compilemessages createcachetable dbshell diffsettings dumpdata
1
2
3
4
5
6

好了,这这里来说说遇到的**第一个坑**,鬼知道是为了个什么,Nitrate限制Django版本,当你使用pip或者easy_install安装个2.0版本之后,后面编译安装Nitrate时候,就会开始报错给你了,到时候就知道是多么北京的事了,印象中Django版本要求是`1.8<=Django版本<1.11` ,唉,所以,如果谁正准备装这个,或者偶尔看到我写的这玩意,真的,记住,还是源码安装Django吧。。。另外,强烈建议你就要你装完系统的python版本(多半是2.7.5),千万别升3.6,不然可能还要哭一会。

#### pip
上面说的可以使用pip来装Django,但是,貌似2.7.5的python压根就没自带个pip,好吧,反正后面还需要pip,还是先装上吧:
首先安装epel扩展
yum -y install epel-release
1
然后就可以装pip了:
yum -y install python-pip
1
完了清个cache:
yum clean all
1
2
3
#### MySQL
数据库选MySQL也没什么可纠结了,安装:
下载源包:
wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
1
安装mysql源:
yum localinstall mysql57-community-release-el7-8.noarch.rpm
1
检查是否安装成功:
yum repolist enabled | grep "mysql.*-community.*"
1
2
3
4
```
mysql-connectors-community/x86_64 MySQL Connectors Community 51
mysql-tools-community/x86_64 MySQL Tools Community 63
mysql57-community/x86_64 MySQL 5.7 Community Server 267
可以修改源配置,安装你喜欢的版本:
1
vim /etc/yum.repos.d/mysql-community.repo
只需要把对应的enable改成1即可。 ##### 安装
1
yum install mysql-community-server
这里再次吐槽下公司的网,烂的不是一点半点,这个包印象中有近200M,公司网以20k速度给我下。。。直接流量开热点才下好。 ##### 启动服务 systemctl start mysqld ##### 查看状态 systemctl status mysqld ##### 配置开机启动
1
2
systemctl enable mysqld
systemctl daemon-reload
##### 修改root密码 查看默认密码:
1
grep 'temporary password' /var/log/mysqld.log
修改密码很简单,`mysql -uroot -p`进入控制台,改:
1
ALTER USER 'root'@'localhost' IDENTIFIED BY 'pwd';
顺便改个权限:
1
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'pwd' WITH GRANT OPTION;
再配个防火墙,3306端口打开,那么在Windows中就能使用工具连接数据库了。 ##### 修改字符编码 编辑`/etc/my.cnf`,在[mysqld]下添加配置:
1
2
3
[mysqld]
character_set_server=utf8
init_connect='SET NAMES utf8'
重启mysql服务即可。 ### 开始搭建 #### 项目clone 首先是clone到本地:
1
2
cd /usr/local/src
git clone https://github.com/Nitrate/Nitrate.git
大概有这么些东西:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@localhost Nitrate]# ll
total 160
-rw-r--r--. 1 root root 609 Apr 22 12:23 AUTHORS
drwxr-xr-x. 4 root root 43 Apr 22 12:41 build
-rw-r--r--. 1 root root 66430 Apr 22 12:23 CHANGELOG.rst
drwxr-xr-x. 4 root root 60 Apr 22 12:23 contrib
drwxr-xr-x. 2 root root 35 Apr 22 12:41 dist
drwxr-xr-x. 3 root root 76 Apr 22 12:23 docs
-rw-r--r--. 1 root root 18092 Apr 22 12:23 LICENSE
-rw-r--r--. 1 root root 1690 Apr 22 12:23 Makefile
-rwxr-xr-x. 1 root root 279 Apr 22 12:23 manage.py
-rw-r--r--. 1 root root 256 Apr 22 12:23 MANIFEST.in
drwxr-xr-x. 2 root root 110 Apr 22 12:41 Nitrate.egg-info
-rw-r--r--. 1 root root 25090 Apr 22 12:23 nitrate.spec
-rw-r--r--. 1 root root 1753 Apr 22 12:23 README.rst
-rw-r--r--. 1 root root 1127 Apr 22 12:23 requirements.txt
-rw-r--r--. 1 root root 657 Apr 22 12:23 setup.cfg
-rw-r--r--. 1 root root 2234 Apr 22 12:23 setup.py
drwxr-xr-x. 19 root root 4096 Apr 22 12:23 tcms
-rw-r--r--. 1 root root 827 Apr 22 12:23 tox.ini
-rw-r--r--. 1 root root 4 Apr 22 12:23 VERSION.txt
#### 安装开发包
1
yum install gcc python-devel mysql-devel krb5-devel libxml2-devel libxslt-devel
安装完成之后,还要项目依赖 #### 安装依赖 进入项目目录:
1
cd /usr/local/src/Nitrate
开始安装:
1
pip install .
这个过程会在你本地检查一个个的依赖,没有就装,其中就会检查Django,这破版本的问题,真的是害我又重装一遍。安装速度取决于你的网速和电脑硬件性能,安心等着successful。 #### 源码安装Nitrate 还是在这个目录,执行:
1
python setup.py install
使用源码安装Nitrate,等着就好,安装完成之后,可以到`/usr/lib/python2.7/site-packages`下找到你安装的Nitrate:
1
2
3
[root@localhost site-packages]# ls | grep Nitrate
Nitrate-4.1-py2.7.egg
Nitrate-4.1-py2.7.egg-info
看看里面有啥:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@localhost site-packages]# cd Nitrate-4.1-py2.7.egg
[root@localhost Nitrate-4.1-py2.7.egg]# ls
EGG-INFO tcms
[root@localhost Nitrate-4.1-py2.7.egg]# ll
total 4
drwxr-xr-x. 2 root root 130 Apr 22 14:52 EGG-INFO
drwxr-xr-x. 18 root root 4096 Apr 22 14:52 tcms
[root@localhost Nitrate-4.1-py2.7.egg]# cd tcms/
[root@localhost tcms]# ll
total 56
-rw-r--r--. 1 root root 307 Apr 22 14:52 celery.py
-rw-r--r--. 1 root root 586 Apr 22 14:52 celery.pyc
drwxr-xr-x. 11 root root 4096 Apr 22 14:52 core
-rw-r--r--. 1 root root 301 Apr 22 14:52 __init__.py
-rw-r--r--. 1 root root 422 Apr 22 14:52 __init__.pyc
drwxr-xr-x. 4 root root 75 Apr 22 14:52 integration
drwxr-xr-x. 4 root root 32 Apr 22 14:52 locale
drwxr-xr-x. 3 root root 261 Apr 22 14:52 management
drwxr-xr-x. 3 root root 228 Apr 22 14:52 profiles
drwxr-xr-x. 2 root root 272 Apr 22 14:52 report
drwxr-xr-x. 2 root root 241 Apr 22 14:52 search
drwxr-xr-x. 2 root root 224 Apr 22 16:15 settings
drwxr-xr-x. 8 root root 94 Apr 22 15:09 static
drwxr-xr-x. 14 root root 4096 Apr 22 16:06 templates
drwxr-xr-x. 6 root root 4096 Apr 22 14:52 testcases
drwxr-xr-x. 6 root root 4096 Apr 22 14:52 testplans
drwxr-xr-x. 6 root root 4096 Apr 22 14:52 testruns
drwxr-xr-x. 2 root root 86 Apr 22 14:52 tests
-rw-r--r--. 1 root root 2334 Apr 22 14:52 urls.py
-rw-r--r--. 1 root root 2299 Apr 22 14:52 urls.pyc
drwxr-xr-x. 2 root root 123 Apr 22 14:52 utils
-rw-r--r--. 1 root root 1896 Apr 22 14:52 wsgi.py
-rw-r--r--. 1 root root 1605 Apr 22 14:52 wsgi.pyc
drwxr-xr-x. 4 root root 4096 Apr 22 14:52 xmlrpc
记住`tcms/`这个文件夹,后面的配置,全都在这里面。 ### 配置 #### 初始化数据 首先是创建`nitrate`这数据库,然后创建用户,赋权限,初始化数据:
1
2
create database nitrate;
GRANT ALL PRIVILEGES ON *.* TO 'nitrate'@'%' IDENTIFIED BY 'pwd' WITH GRANT OPTION;
#### 修改配置 之前接触过Django的,应该都知道有个文件`setting.py`这里面是你app的一些重要配置,我们要改的,也就是它。 Nitrate把传统意义上的`setting.py`分成了两个文件(其实是一个文件):
1
2
common.py
project.py
文件路径:`/usr/lib/python2.7/site-packages/Nitrate-4.1-py2.7.egg/tcms/settings` 几乎所有配置都可以在`common.py`中完成,但是`project.py`在文件开头就是一句话:
1
from common import *
所以,我们常用的配置,在`project.py`中完成即可。 内容大概长这样,可以参考我的配:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# Django settings for product env.

from common import *

# Debug settings
DEBUG = True
TEMPLATE_DEBUG = DEBUG

# Database settings
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'nitrate',
'USER': 'nitrate',
'PASSWORD': 'pwd',
'HOST': '192.168.98.133',
'PORT': '3306',
},
'slave_1': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'nitrate',
'USER': 'nitrate',
'PASSWORD': 'pwd',
'HOST': '192.168.98.133',
'PORT': '3306',
},
}

# add RemoteUserMiddleWare if kerberos authentication is enabled
MIDDLEWARE_CLASSES += (
# 'django.contrib.auth.middleware.RemoteUserMiddleware',
)

# Remote kerberos authentication backends
#AUTHENTICATION_BACKENDS = (
# 'tcms.core.contrib.auth.backends.ModAuthKerbBackend',
#)

DATABASE_ROUTERS = ['tcms.core.utils.tcms_router.RWRouter']

# Kerberos realm
#KRB5_REALM = 'EXAMPLE.COM'

# Bugzilla integration setttings
# Config following settings if your want to integrate with bugzilla
BUGZILLA3_RPC_SERVER = ''
BUGZILLA_URL = ''
BUGZILLA_USER = ''
BUGZILLA_PASSWORD = ''

# JIRA integration setttings
# Config following settings if your want to integrate with JIRA
JIRA_URL = ''

# Set the default send mail address
EMAIL_HOST = 'smtp.example.com'
EMAIL_FROM = 'noreply@example.com'

# Site-specific messages

# First run - to detemine need port user or not.
FIRST_RUN = False

# You can add a help link on the footer of home page as following format:
# ('http://foo.com', 'foo')
FOOTER_LINKS = (
('/xmlrpc/', 'XML-RPC service'),
)

# added for nitrate3.4 compatibility
DEFAULT_GROUPS = ['default']
TESTOPIA_XML_VERSION = '1.0'

# admin settings
ADMINS = (
# ('Your Name', 'your_email@domain.com'),
)

# user guide URL
USER_GUIDE_URL = ""

DEFAULT_PAGE_SIZE = 100
基本需要修改的,一是DEBUG开关,第二个是数据库配置,开启DEBUG开关是为了后面初始化数据时候获取`staticfile`,开始**第二个坑**:
1
2
AUTHENTICATION_BACKENDS
MIDDLEWARE_CLASSES
注释别放开啊别放开,千万别手痒,惨痛的教训,就是手痒在不知道这俩什么含义就放开了,然后在搭建完成之后,登录都登录不了。。一直在报`jquery.min.js 404`,这个问题真的是折腾死,开始根本想不到是这边的问题,造成把`common.py`文件研究了个遍,环境重新又搭建两遍,一遍使用`venv`开启,一遍按原来的来,最终在万念俱灰,把注释又加上才解决,唉。。。 #### 配置common.py 首先,直接上我配完的,可参考:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# -*- coding: utf-8 -*-

import django.conf.global_settings as DEFAULT_SETTINGS
import os.path

NITRATE_VERSION = '4.0.0'

DEBUG = False

# Administrators error report email settings
ADMINS = (
# ('Your Name', 'your_email@example.com'),
)

TCMS_ROOT_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..').replace('\\', '/'))

MANAGERS = ADMINS

DATABASES = {
# Master DB for writing
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'nitrate',
'USER': 'nitrate',
'PASSWORD': 'pwd',
'HOST': '192.168.98.133',
'PORT': '3306',
},
# First slave DB for reading
'slave_1': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'nitrate',
'USER': 'nitrate',
'PASSWORD': 'pwd',
'HOST': '192.168.98.133',
'PORT': '3306',
},
# Second slave DB for reporting, optional
'slave_report': {
'ENGINE': 'django.db.backends.3306',
'NAME': 'nitrate',
'USER': 'nitrate',
'PASSWORD': 'pwd',
'HOST': '192.168.98.133',
'PORT': '3306',
}
}

# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = ['*']

# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# In a Windows environment this must be set to your system time zone.
TIME_ZONE = 'UTC'

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'

SITE_ID = 1

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True

# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = False

# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/var/www/example.com/media/"
MEDIA_ROOT = ''

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://example.com/media/", "http://media.example.com/"
MEDIA_URL = ''

# URL prefix for admin absolute URL
ADMIN_PREFIX = '/admin'

LOGIN_URL = 'nitrate-login'
LOGIN_REDIRECT_URL = 'user-profile-redirect'
LOGOUT_REDIRECT_URL = 'nitrate-login'

# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/var/www/example.com/static/"
#BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..').replace('\\', '/'))
#STATIC_ROOT = '/usr/lib/python2.7/site-packages/Nitrate-4.1-py2.7.egg/tcms/static/'
STATIC_ROOT = '/home/nitrate/projects/site/assets'
#STATIC_ROOT = os.path.join(TCMS_ROOT_PATH, 'static')

# URL prefix for static files.
# Example: "http://example.com/static/", "http://static.example.com/"
STATIC_URL = '/static/'

# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
os.path.join(TCMS_ROOT_PATH,'static'),
#'/usr/lib/python2.7/site-packages/Nitrate-4.1-py2.7.egg/tcms/static/',
# '/home/nitrate/projects/site/assets',
)

# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

# Make this unique, and don't share it with anybody.
SECRET_KEY = '^8y!)$0t7yq2+65%&_#@i^_o)eb3^q--y_$e7a_=t$%$1i)zuv'

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(TCMS_ROOT_PATH, 'templates/').replace('\\', '/'),
],
'APP_DIRS': True,
'OPTIONS': {
'debug': True,
'context_processors': [
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',

# Added for Nitrate
'django.template.context_processors.request',
'tcms.core.context_processors.admin_prefix_processor',
'tcms.core.context_processors.auth_backend_processor',
'tcms.core.context_processors.request_contents_processor',
'tcms.core.context_processors.settings_processor',
],
},
},
]


MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'tcms.core.middleware.CsrfDisableMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)

ROOT_URLCONF = 'tcms.urls'

# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'tcms.wsgi.application'

INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.staticfiles',

'django_comments',
'kobo.django.xmlrpc',
'tinymce',

'tcms.core.contrib.auth.apps.AppConfig',
'tcms.core.contrib.comments.apps.AppConfig',
'tcms.core.contrib.linkreference',
'tcms.core.logs',
'tcms.integration.bugzilla',
'tcms.integration.errata',
'tcms.management',
'tcms.profiles',
'tcms.testcases',
'tcms.testplans',
'tcms.testruns',
'tcms.xmlrpc.apps.AppConfig',

# core app must be here in order to use permissions created during creating
# modules for above apps.
'tcms.core.apps.AppConfig',
)

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'

#
# Default apps settings
#

# Define the custom comment app
# http://docs.djangoproject.com/en/dev/ref/contrib/comments/custom/

COMMENTS_APP = 'tcms.core.contrib.comments' # 'nitrate_comments'

#
# XML-RPC interface settings
#
# XML-RPC methods

XMLRPC_METHODS = {
'TCMS_XML_RPC': (
('tcms.xmlrpc.api.auth', 'Auth'),
('tcms.xmlrpc.api.build', 'Build'),
('tcms.xmlrpc.api.env', 'Env'),
('tcms.xmlrpc.api.product', 'Product'),
('tcms.xmlrpc.api.testcase', 'TestCase'),
('tcms.xmlrpc.api.testcaserun', 'TestCaseRun'),
('tcms.xmlrpc.api.testcaseplan', 'TestCasePlan'),
('tcms.xmlrpc.api.testopia', 'Testopia'),
('tcms.xmlrpc.api.testplan', 'TestPlan'),
('tcms.xmlrpc.api.testrun', 'TestRun'),
('tcms.xmlrpc.api.user', 'User'),
('tcms.xmlrpc.api.version', 'Version'),
('tcms.xmlrpc.api.tag', 'Tag'),
),
}

XMLRPC_TEMPLATE = 'xmlrpc.html'

# Cache backend
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}

SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'

# Needed by django.core.context_processors.debug:
# See http://docs.djangoproject.com/en/dev/ref/templates/api/#django-core-context-processors-debug
INTERNAL_IPS = ('127.0.0.1', )

# Authentication backends
# For the login/register/logout reaon, we only support the internal auth backends.
AUTHENTICATION_BACKENDS = (
'tcms.core.contrib.auth.backends.DBModelBackend',
)

#
# Mail settings
#
# Set the default send mail address
# See http://docs.djangoproject.com/en/dev/ref/settings/#email-backend
EMAIL_HOST = ''
EMAIL_PORT = 25
EMAIL_FROM = 'noreply@foo.com'
EMAIL_SUBJECT_PREFIX = '[TCMS] '

EMAILS_FOR_DEBUG = []
ENABLE_ASYNC_EMAIL = True

CELERY_BROKER_URL = 'redis://'

# Celery worker settings
CELERY_TASK_RESULT_EXPIRES = 60 * 2
CELERY_RESULT_BACKEND = 'db+sqlite:///celery-results.db'
CELERYD_TIMER_PRECISION = 120
CELERY_IGNORE_RESULT = True
CELERY_MAX_CACHED_RESULTS = -1
CELERY_DEFAULT_RATE_LIMIT = '250/m'

# TCMS email behavior settings
PLAN_EMAIL_TEMPLATE = 'mail/change_plan.txt'
PLAN_DELELE_EMAIL_TEMPLATE = 'mail/delete_plan.txt'
CASE_EMAIL_TEMPLATE = 'mail/edit_case.txt'
CASE_DELETE_EMAIL_TEMPLATE = 'mail/delete_case.txt'

# TCMS Bug System settings
# Set default bug system to bugzilla
DEFAULT_BUG_SYSTEM_ID = 1

# Maximum upload file size, default set to 5MB.
# 2.5MB - 2621440
# 5MB - 5242880
# 10MB - 10485760
# 20MB - 20971520
# 50MB - 5242880
# 100MB 104857600
# 250MB - 214958080
# 500MB - 429916160
MAX_UPLOAD_SIZE = 5242880

# Pagination
PLAN_RUNS_PAGE_SIZE = 20

# Site-specific messages

# The site can supply optional "message of the day" style banners, similar to
# /etc/motd. They are fragments of HTML.

# This if set, is shown on the login/registration screens.
# MOTD_LOGIN = ''

# The URLS will be list in footer
# Example:
#FOOTER_LINKS = (
# ('mailto:nitrate-dev-list@example.com', 'Contact Us'),
# ('mailto:nitrate-admin@example.com', 'Request Permission'),
# ('http://foo.com', 'foo')
#)
FOOTER_LINKS = ()

# Attachement file download path
# it could be spcified to a different out of MEDIA_URL
# FILE_UPLOAD_DIR = path.join(MEDIA_DIR, 'uploads').replace('\\','/'),
FILE_UPLOAD_DIR = '/var/nitrate/uploads'

# Enable the administrator delete permission
# In another word it's set the admin to super user or not.
SET_ADMIN_AS_SUPERUSER = False

#
# Authentication backend settings
#
# Bugzilla author xmlrpc url
# Required by bugzilla authentication backend
BUGZILLA3_RPC_SERVER = ''
BUGZILLA_URL = ''

# JIRA URL
JIRA_URL = ''

# Turn on/off bugzilla external tracker
BUGZILLA_EXTERNAL_TRACKER = False

# Turn on/off listening signals sent by models.
LISTENING_MODEL_SIGNAL = True

# Kerberos settings
# Required by kerberos authentication backend
KRB5_REALM = ''

# Integration with Errata system, used to linkify the Errata ID
# A valid Errata URL:
# https://errata.devel.example.com/errata/stateview/{Errata ID}
ERRATA_URL_PREFIX = ''

# user guide url:
USER_GUIDE_URL = ''

# Default page size for showing each possible query result. This provides a
# consistent user experiece to users.
DEFAULT_PAGE_SIZE = 20

# Disable TCMS to produce test run progress info to consumers by qpid for
# reducing unnecessary I/O access and errata does not subscribe tcms msg now.
# If you want to continue sending msg to qpid, please overwrite it in product
# .py and make sure qpid config is correct.
ENABLE_QPID = False

# TCMS use Piwik to track request.
ENABLE_PIWIK_TRACKING = False
# Piwik site id, generate by eng-ops
PIWIK_SITE_ID = ''
# Piwik api url without schema.
PIWIK_SITE_API_URL = ''
# Piwik js lib url without schema
PIWIK_SITE_JS_URL = ''

# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
},
'simple': {
'format': '[%(asctime)s] %(levelname)s %(message)s'
},
'xmlrpc_log': {
'format': '[%(asctime)s] %(levelname)s XMLRPC %(process)d "%(message)s"'
},
},
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'xmlrpc': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'xmlrpc_log',
},
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
},
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
'nitrate.xmlrpc': {
'handlers': ['xmlrpc'],
'level': 'DEBUG',
'propagate': True,
},
}
}

TINYMCE_DEFAULT_CONFIG = {
'mode': "exact",
'theme': "advanced",
'language': "en",
'skin': "o2k7",
'browsers': "gecko",
'dialog_type': "modal",
'object_resizing': 'true',
'cleanup_on_startup': 'true',
'forced_root_block': "p",
'remove_trailing_nbsp': 'true',
'theme_advanced_toolbar_location': "top",
'theme_advanced_toolbar_align': "left",
'theme_advanced_statusbar_location': "none",
'theme_advanced_buttons1': "formatselect,"
"bold,italic,"
"underline,"
"bullist,"
"numlist,"
"link,"
"unlink,"
"image,"
"search,"
"|,"
"outdent,"
"indent,"
"hr,"
"fullscreen,"
"|,"
"help",
'theme_advanced_buttons2': "tablecontrols",
'theme_advanced_buttons3': "",
'theme_advanced_path': 'false',
'theme_advanced_blockformats': "p,h2,h3,h4,div,code,pre",
'theme_advanced_styles': "[all] clearfix=clearfix;"
"[p] summary=summary;"
"[div] code=code;"
"[img] img_left=img_left;"
"[img] img_left_nospacetop=img_left_nospacetop;"
"[img] img_right=img_right;"
"[img] img_right_nospacetop=img_right_nospacetop;"
"[img] img_block=img_block;"
"[img] img_block_nospacetop=img_block_nospacetop;"
"[div] column span-2=column span-2;"
"[div] column span-4=column span-4;"
"[div] column span-8=column span-8",
'height': '300',
'width': '100%',
'urlconverter_callback': 'myCustomURLConverter',
'plugins': "table,safari,"
"advimage,"
"advlink,"
"fullscreen,"
"visualchars,"
"paste,"
"media,"
"template,"
"searchreplace,"
"emotions,",
'table_styles': "Header 1=header1;"
"Header 2=header2;"
"Header 3=header3",
'table_cell_styles': "Header 1=header1;"
"Header 2=header2;"
"Header 3=header3;"
"Table Cell=tableCel1",
'table_row_styles': "Header 1=header1;"
"Header 2=header2;"
"Header 3=header3;"
"Table Row=tableRow1",
}

LOCALE_PATHS = (
os.path.join(TCMS_ROOT_PATH, 'locale'),
)

TESTOPIA_XML_VERSION = '1.1'
需要注意的: 1. 检查`INSTALLED_APPS`中,是否有`django.contrib.staticfiles`,很重要! 2. DEBUG开关 3. 数据库配置 4. `STATIC_ROOT`,`STATIC_URL`,`STATICFILES_DIRS`,这三个,真的真的很重要!并且很容易就出问题,看我注释了那么多行就知道我是试了多少种组合了 前三条没什么可说的,关键就是第四条,先贴出个`第三个坑`:
1
django.core.exceptions.ImproperlyConfigured: The STATICFILES_DIRS setting should not contain the STATIC_ROOT setting
这个是在进行数据初始化时候报的错,问题很好看,字面意思就是,然后我就开始各种尝试配置`STATIC_ROOT`和`STATICFILES_DIRS`,首先先解释一下这个配置的作用,首先,配置的是路径,文件夹的路径,作用就是存放静态文件,各种js,css等,在你页面加载的静态文件,都在这个文件夹里。在Django项目进行部署时:
1
python manage.py collectstatic
命令就会把所有需要的静态文件都复制到你配置的`STATIC_ROOT`文件夹中。所以`STATIC_ROOT`配置的是你app级的静态文件保存地址。 那么`STATICFILES_DIRS`呢,这个文件夹,可以看成是所有app公共的静态文件的保存地址,当需要加载静态文件时,django会首先在公共的文件中查找,然后去app级的文件夹查找。 至于`STATIC_URL`这个配置其实就是为了映射`STATIC_ROOT`,值基本配`STATIC_URL = '/static/'`即可。 ### 开启服务 首先是初始化数据:
1
django-admin.py migrate --settings=tcms.settings.product
将Nitrate一些必须的数据,表初始化; 然后是加载静态文件:
1
django-admin.py collectstatic --settings=tcms.settings.product
根据你指定的配置,将静态文件拷贝到指定文件夹; 然后是创建超级管理员:
1
django-admin.py createsuperuser --settings=tcms.settings.product
最后,起服务:
1
django-admin.py runserver --settings=tcms.settings.product
到浏览器上`http://127.0.0.1:8000`开始折腾吧~~~ ## 几个问题 ### debug-toolbar 当打开DEBUG,在进行初始化时,可能会报错:
1
no module named debug-toolbar
很明显,缺包,装包,不过包名不叫`debug-toolbar`,
1
yum install django-debug-toolbar
即可。 ### django.core.exceptions.ImproperlyConfigured: The STATICFILES_DIRS setting should not contain the STATIC_ROOT setting 也是字面意思,STATIC_ROOT配置不能包含在STATICFILES_DIRS中,为什么会遇到这个问题,这玩意是我在第一次起服务没报错,但是页面静态文件一个都获取不到,整个页面朴素的不像话时候,尝试解决引发的另一个问题。先说说页面元素不加载,当初我配置是看网上有介绍`STATICFILES_DIRS`可以注释,不需要配,然后我就把`STATIC_ROOT`配成公共文件地址,结果在页面打开Nitrate时候,所有静态文件都是类似于:
1
"GET /static/media/css/bootstrap/bootstrap.css HTTP/1.1" 404 5904
这样的问题,整个页面就朴素的不行。。。然后又尝试把`STATIC_ROOT`注释,这次报的是代码中指明了app配置,STATIC_ROOT该项不能少这样的报错;然后两个都保留,这次就出现了上面那个错;再一次,在没看`setting.py`文件前,把`STATIC_ROOT`设置成了公共的,`STATICFILES_DIRS`设置成了app的,一如既往,静态文件全部加载不出来。。最后才修改成上述配置文件样(试过的组合不止这些,反正是折腾死,还怀疑过是copy静态文件时,少拷了个文件,都想改源码了,唉。。。) 所以这个问题解决很简单,把`STATIC_ROOT`设置成了app的,`STATICFILES_DIRS`设置成了公共的。 ### DATABASES is improperly configured. Please supply the ENGINE value 这个报错遇到过好几个,基本是俩原因: 1. 改配置文件,输错了 2. nitrate用户没有权限 检查的改了即可。 ## 后记 周五下午在公司没有搭建成功,搭的都心累了,成果就是一及其朴素的页面;周天早上6点钟开始折腾,一直弄到下午,才完完整整的搭完,唉,真的是个充实的周末... 目前环境是搭建在虚拟机中,访问也是只能虚拟机中的Firefox输入`http://127.0.0.1:8000`才能访问,后面需要结合appach和wsgi,至少是完成公司局域网内访问,这个应该挺简单,再弄。。。 ### 参考文档 > [Collecting staticfiles throws ImproperlyConfigured ](https://stackoverflow.com/questions/27213752/collecting-staticfiles-throws-improperlyconfigured/27213753) [Managing static files](https://docs.djangoproject.com/en/2.0/howto/static-files/) [Django 使用 Bootstrap,在 DEBUG = True 模式下,部分 js、css 提示 404 错误](https://www.v2ex.com/t/270503) [settings.py中的静态文件管理设置](https://www.jianshu.com/p/2e5515032db0) [django中的setting最佳配置小结](http://www.jb51.net/article/128678.htm) ============================================================================================================================================================================================来更新接下来的部署了! ****************************** 使用apache&mod_wsgi部署django项目 使用apache和mod_wsgi来部署Nitrate,使得不需要一直在虚拟机里面的浏览器才能打开Nitrate。 ### 安装httpd&mod_wsgi
1
yum install httpd mod_wsgi
### 创建上传文件夹 创建长传文件夹,并且修改用户及属组:
1
2
mkdir -p /var/nitrate/uploads
chown apache:apache /var/nitrate/uploads
### 配置mod_wsgi 在`/etc/httpd/conf.d`文件夹下,创建文件`wsgi.conf`,修改内容:
1
LoadModule wsgi_module modules/mod_wsgi.so
### 配置Apache&mod_wsgi 在`/etc/httpd/conf.d`文件夹下创建nitrate的配置文件`nitrate-httpd.conf`,具体内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# Deployment using mod_wsgi
#
# Useful documentation:
# https://docs.djangoproject.com/en/1.5/howto/deployment/wsgi/

# Force the use of ssl:
#<IfModule mod_rewrite.c>
# RewriteEngine on
# RewriteCond %{HTTPS} off
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}
#</IfModule>

# Make sure static files collected to this dir
# Ref https://docs.djangoproject.com/en/1.5/ref/contrib/staticfiles/#django-admin-collectstatic
#Alias /static /usr/share/nitrate/statici
Alias /static /home/nitrate/projects/site/assets
#Alias /usr/lib/python2.7/site-packages/Nitrate-4.1-py2.7.egg/tcms/static

# Limit threads forked:
# prefork MPM
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 256
MaxRequestsPerChild 0

# Configurations for mod_wsgi
WSGIScriptAlias / /usr/lib/python2.7/site-packages/tcms/wsgi.py
WSGIPythonPath /usr/lib/python2.7/site-packages
WSGIPassAuthorization On

<Location "/">
# ====================
# Handler for mod_wsgi
# ====================
SetHandler wsgi-script

Options All
AllowOverride All
Require all granted
LimitRequestBody 10485760
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript application/x-javascript text/css

ErrorDocument 401 "Your request is unauthorization."
</Location>

<Location "/static">
SetHandler None

# Disable auth on the static content, so that we're aren't forced to
# use Kerberos. Doing so would remove "Expires" headers from the static
# content, which would lead to poor page-load times.
AuthType none
Satisfy Any
Allow from All

# Many file types are likely to benefit from compression
# Enable gzip compression on them:
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript application/x-javascript text/css

# Set far-future Expires headers on static content
# (trac 184):
ExpiresActive On
ExpiresDefault "access plus 10 years"
</Location>
需要注意的几个配置:
1
2
3
Alias /static /home/nitrate/projects/site/assets
WSGIScriptAlias / /usr/lib/python2.7/site-packages/tcms/wsgi.py
WSGIPythonPath /usr/lib/python2.7/site-packages
都修改成你自己的本地路径 ### httpd.conf 说实话,我对这玩意是真的不熟悉,就基本没改,路径:`/etc/httpd/conf/httpd.conf`,只需要修改:
1
2
ServerName example.com:80
Listen ip_address:80
我比较懒,直接一个改成`localhost`,另一个改为`80`,就完工了。 然后就可以起服务了!!!
1
systemctl start httpd.service
在本地windows下的浏览器应该就可以直接访问虚拟机的ip来访问nitrate了 ### 可能遇到的问题 反正对我来说不是可能,全遇到了。。 #### httpd服务启动失败 这个问题,原因很多,直接看日志比较正常,我是因为端口配错了才出现 #### 页面报错,无法连接mysql,报权限问题 首先,检查是否有权限,在确定有权限情况下,基本是系统的问题了。 解释一下,虚拟机装的是centos,centos在默认情况下SELinux是打开的,这玩意,是不允许远程连接MySQL资源的。。。所以简单的解决:
1
setenforce 0
网上有个建议做法:
1
setsebool httpd_can_network_connect_db 1
允许Apache访问外部MySQL资源 #### 浏览器访问虚拟机IP,静态文件不加载 和之前碰到的配路径一样,所有静态文件加载都是403,加载不了,这次,确定不是路径配置的问题,那就是权限问题呗,给你`/static`目录下的文件赋权限,有可执行权限即可。
1
chmod -R 755 /static
文章目录
  1. 前言
  2. 开篇
  3. 坎坷的系统搭建
    1. 环境准备
      1. Git
      2. Django
        1. pip
        2. setuptools
        3. 源码安装
|