##// END OF EJS Templates
updated installation instruction, made more user friendly way of creating all needed configs. All is done now from paster setup-app
marcink -
r327:0e87466a default
parent child Browse files
Show More
@@ -1,11 +1,13 b''
1
1
2 syntax: regexp
2 syntax: regexp
3 ^data$
3 ^data$
4 syntax: regexp
4 syntax: regexp
5 ^\.settings$
5 ^\.settings$
6 syntax: regexp
6 syntax: regexp
7 ^\.project$
7 ^\.project$
8 syntax: regexp
8 syntax: regexp
9 ^\.pydevproject$
9 ^\.pydevproject$
10 syntax: regexp
10 syntax: regexp
11 ^hg_app\.db$ No newline at end of file
11 ^hg_app\.db$
12 syntax: regexp
13 ^repositories\.config$ No newline at end of file
@@ -1,57 +1,56 b''
1 -------------------------------------
1 -------------------------------------
2 Pylons based replacement for hgwebdir
2 Pylons based replacement for hgwebdir
3 -------------------------------------
3 -------------------------------------
4
4
5 Fully customizable, with authentication, permissions. Based on vcs library.
5 Fully customizable, with authentication, permissions. Based on vcs library.
6
6
7 **Overview**
7 **Overview**
8
8
9 - has it's own middleware to handle mercurial protocol request each request can
9 - has it's own middleware to handle mercurial protocol request each request can
10 be logged and authenticated + threaded performance unlikely to hgweb
10 be logged and authenticated + threaded performance unlikely to hgweb
11 - full permissions per project read/write/admin access even on mercurial request
11 - full permissions per project read/write/admin access even on mercurial request
12 - mako templates let's you cusmotize look and feel of appplication.
12 - mako templates let's you cusmotize look and feel of appplication.
13 - diffs annotations and source code all colored by pygments.
13 - diffs annotations and source code all colored by pygments.
14 - mercurial branch graph
14 - mercurial branch graph
15 - admin interface for performing user/permission managments as well as repository
15 - admin interface for performing user/permission managments as well as repository
16 managment
16 managment
17 - backup scripts can do backup of whole app and send it over scp to desired location
17 - backup scripts can do backup of whole app and send it over scp to desired location
18 - setup project descriptions and info inside built in db for easy, non
18 - setup project descriptions and info inside built in db for easy, non
19 file-system operations
19 file-system operations
20 - added cache with invalidation on push/repo managment for high performance and
20 - added cache with invalidation on push/repo managment for high performance and
21 always upto date data.
21 always upto date data.
22 - rss /atom feed customizable
22 - rss /atom feed customizable
23 - future support for git
23 - future support for git
24 - based on pylons 1.0 / sqlalchemy 0.6
24 - based on pylons 1.0 / sqlalchemy 0.6
25
25
26 **Incoming**
26 **Incoming**
27
27
28 - code review based on hg-review (when it's stable)
28 - code review based on hg-review (when it's stable)
29 - git support (when vcs can handle it)
29 - git support (when vcs can handle it)
30 - other cools stuff that i can figure out
30 - other cools stuff that i can figure out
31
31
32 .. note::
32 .. note::
33 This software is still in beta mode. I don't guarantee that it'll work.
33 This software is still in beta mode. I don't guarantee that it'll work.
34
34
35
35
36 -------------
36 -------------
37 Installation
37 Installation
38 -------------
38 -------------
39 .. note::
39 .. note::
40 I recomend to install tip version of vcs while the app is in beta mode.
40 I recomend to install tip version of vcs while the app is in beta mode.
41
41
42
42
43 - create new virtualenv and activate it
43 - create new virtualenv and activate it - highly recommend that you use separate
44 virtual-env for whole application
44 - download hg app from default (not demo) branch from bitbucket and run
45 - download hg app from default (not demo) branch from bitbucket and run
45 'python setup.py install' this will install all required dependencies needed
46 'python setup.py install' this will install all required dependencies needed
46 - goto pylons_app/lib and run python db_manage.py it should create all
47 - run paster setup-app production.ini it should create all needed tables
47 needed tables and an admin account. You can play with this file if you wish to
48 and an admin account. Also it will create repositories.config for mercurial
48 use different db than sqlite
49 commands, remember that the given path for mercurial repositories must be write
49 - edit file repositories.config and change the [paths] where you keep your
50 accessible for the application
50 mercurial repositories, remember about permissions for accessing this dir by
51 - run paster serve development.ini - or you can use manage-hg_app script.
51 hg app.
52 - run paster serve development.ini
53 the app should be available at the 127.0.0.1:5000
52 the app should be available at the 127.0.0.1:5000
54 - use admin account you created to login.
53 - use admin account you created to login.
55 - default permissions on each repository is read, and owner is admin. So remember
54 - default permissions on each repository is read, and owner is admin. So remember
56 to update those.
55 to update those.
57 No newline at end of file
56
@@ -1,14 +1,14 b''
1 [hooks]
1 [hooks]
2 #to do push with autoupdate
2 #to do push with autoupdate
3 changegroup = hg update >&2
3 changegroup = hg update >&2
4
4
5 [web]
5 [web]
6 #for http requests push ssl to false
6 #for http requests push ssl to false
7 push_ssl = false
7 push_ssl = false
8 allow_archive = gz zip bz2
8 allow_archive = gz zip bz2
9 allow_push = *
9 allow_push = *
10 baseurl = /
10 baseurl = /
11
11
12 [paths]
12 [paths]
13 #this path should point to mercurial repositories remeber about '*' at the end
13 #this path should point to mercurial repositories remeber about '*' at the end
14 / = /home/marcink/python_workspace/*
14 / = %(repo_location)s
@@ -1,143 +1,134 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # database managment for hg app
3 # database managment for hg app
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
5
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
8 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
9 # of the License or (at your opinion) any later version of the license.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
19 # MA 02110-1301, USA.
20
20
21 """
21 """
22 Created on April 10, 2010
22 Created on April 10, 2010
23 database managment and creation for hg app
23 database managment and creation for hg app
24 @author: marcink
24 @author: marcink
25 """
25 """
26
26
27 from os.path import dirname as dn, join as jn
27 from os.path import dirname as dn, join as jn
28 import os
28 import os
29 import sys
29 import sys
30 import uuid
30 ROOT = dn(dn(dn(os.path.realpath(__file__))))
31 ROOT = dn(dn(dn(os.path.realpath(__file__))))
31 sys.path.append(ROOT)
32 sys.path.append(ROOT)
32
33
33 from pylons_app.lib.auth import get_crypt_password
34 from pylons_app.lib.auth import get_crypt_password
34 from pylons_app.model import init_model
35 from pylons_app.model import init_model
35 from pylons_app.model.db import User, Permission
36 from pylons_app.model.db import User, Permission
36 from pylons_app.model.meta import Session, Base
37 from pylons_app.model.meta import Session, Base
37 from sqlalchemy.engine import create_engine
38 from sqlalchemy.engine import create_engine
38 import logging
39 import logging
39
40
40 log = logging.getLogger('db manage')
41 log = logging.getLogger('db manage')
41 log.setLevel(logging.DEBUG)
42 log.setLevel(logging.DEBUG)
42 console_handler = logging.StreamHandler()
43 console_handler = logging.StreamHandler()
43 console_handler.setFormatter(logging.Formatter("%(asctime)s.%(msecs)03d"
44 console_handler.setFormatter(logging.Formatter("%(asctime)s.%(msecs)03d"
44 " %(levelname)-5.5s [%(name)s] %(message)s"))
45 " %(levelname)-5.5s [%(name)s] %(message)s"))
45 log.addHandler(console_handler)
46 log.addHandler(console_handler)
46
47
47 class DbManage(object):
48 class DbManage(object):
48 def __init__(self, log_sql):
49 def __init__(self, log_sql):
49 self.dbname = 'hg_app.db'
50 self.dbname = 'hg_app.db'
50 dburi = 'sqlite:////%s' % jn(ROOT, self.dbname)
51 dburi = 'sqlite:////%s' % jn(ROOT, self.dbname)
51 engine = create_engine(dburi, echo=log_sql)
52 engine = create_engine(dburi, echo=log_sql)
52 init_model(engine)
53 init_model(engine)
53 self.sa = Session()
54 self.sa = Session()
54 self.db_exists = False
55 self.db_exists = False
55
56
56 def check_for_db(self, override):
57 def check_for_db(self, override):
57 log.info('checking for exisiting db')
58 log.info('checking for exisiting db')
58 if os.path.isfile(jn(ROOT, self.dbname)):
59 if os.path.isfile(jn(ROOT, self.dbname)):
59 self.db_exists = True
60 self.db_exists = True
60 log.info('database exisist')
61 log.info('database exisist')
61 if not override:
62 if not override:
62 raise Exception('database already exists')
63 raise Exception('database already exists')
63
64
64 def create_tables(self, override=False):
65 def create_tables(self, override=False):
65 """
66 """
66 Create a auth database
67 Create a auth database
67 """
68 """
68 self.check_for_db(override)
69 self.check_for_db(override)
69 if override:
70 if override:
70 log.info("database exisist and it's going to be destroyed")
71 log.info("database exisist and it's going to be destroyed")
71 if self.db_exists:
72 if self.db_exists:
72 os.remove(jn(ROOT, self.dbname))
73 os.remove(jn(ROOT, self.dbname))
73 Base.metadata.create_all(checkfirst=override)
74 Base.metadata.create_all(checkfirst=override)
74 log.info('Created tables for %s', self.dbname)
75 log.info('Created tables for %s', self.dbname)
75
76
76 def admin_prompt(self):
77 def admin_prompt(self):
77 import getpass
78 import getpass
78 username = raw_input('Specify admin username:')
79 username = raw_input('Specify admin username:')
79 password = getpass.getpass('Specify admin password:')
80 password = getpass.getpass('Specify admin password:')
80 self.create_user(username, password, True)
81 self.create_user(username, password, True)
81
82
82 def create_user(self, username, password, admin=False):
83 def create_user(self, username, password, admin=False):
83
84
84 log.info('creating default user')
85 log.info('creating default user')
85 #create default user for handling default permissions.
86 #create default user for handling default permissions.
86 def_user = User()
87 def_user = User()
87 def_user.username = 'default'
88 def_user.username = 'default'
88 def_user.password = 'default'
89 def_user.password = get_crypt_password(str(uuid.uuid1())[:8])
89 def_user.name = 'default'
90 def_user.name = 'default'
90 def_user.lastname = 'default'
91 def_user.lastname = 'default'
91 def_user.email = 'default@default'
92 def_user.email = 'default@default.com'
92 def_user.admin = False
93 def_user.admin = False
93 def_user.active = False
94 def_user.active = False
94
95
95 self.sa.add(def_user)
96 self.sa.add(def_user)
96
97
97 log.info('creating administrator user %s', username)
98 log.info('creating administrator user %s', username)
98 new_user = User()
99 new_user = User()
99 new_user.username = username
100 new_user.username = username
100 new_user.password = get_crypt_password(password)
101 new_user.password = get_crypt_password(password)
101 new_user.name = 'Hg'
102 new_user.name = 'Hg'
102 new_user.lastname = 'Admin'
103 new_user.lastname = 'Admin'
103 new_user.email = 'admin@localhost'
104 new_user.email = 'admin@localhost'
104 new_user.admin = admin
105 new_user.admin = admin
105 new_user.active = True
106 new_user.active = True
106
107
107 try:
108 try:
108 self.sa.add(new_user)
109 self.sa.add(new_user)
109 self.sa.commit()
110 self.sa.commit()
110 except:
111 except:
111 self.sa.rollback()
112 self.sa.rollback()
112 raise
113 raise
113
114
114 def create_permissions(self):
115 def create_permissions(self):
115 #module.(access|create|change|delete)_[name]
116 #module.(access|create|change|delete)_[name]
116 #module.(read|write|owner)
117 #module.(read|write|owner)
117 perms = [('repository.none', 'Repository no access'),
118 perms = [('repository.none', 'Repository no access'),
118 ('repository.read', 'Repository read access'),
119 ('repository.read', 'Repository read access'),
119 ('repository.write', 'Repository write access'),
120 ('repository.write', 'Repository write access'),
120 ('repository.admin', 'Repository admin access'),
121 ('repository.admin', 'Repository admin access'),
121 ('hg.admin', 'Hg Administrator'),
122 ('hg.admin', 'Hg Administrator'),
122 ]
123 ]
123
124
124 for p in perms:
125 for p in perms:
125 new_perm = Permission()
126 new_perm = Permission()
126 new_perm.permission_name = p[0]
127 new_perm.permission_name = p[0]
127 new_perm.permission_longname = p[1]
128 new_perm.permission_longname = p[1]
128 try:
129 try:
129 self.sa.add(new_perm)
130 self.sa.add(new_perm)
130 self.sa.commit()
131 self.sa.commit()
131 except:
132 except:
132 self.sa.rollback()
133 self.sa.rollback()
133 raise
134 raise
134
135
136
137 if __name__ == '__main__':
138 dbmanage = DbManage(log_sql=True)
139 dbmanage.create_tables(override=True)
140 dbmanage.admin_prompt()
141 dbmanage.create_permissions()
142
143
@@ -1,9 +1,49 b''
1 """Setup the pylons_app application"""
1 """Setup the pylons_app application"""
2
3 from os.path import dirname as dn, join as jn
4 from pylons_app.config.environment import load_environment
5 from pylons_app.lib.db_manage import DbManage
2 import logging
6 import logging
3 from pylons_app.config.environment import load_environment
7 import os
8 import sys
9
4 log = logging.getLogger(__name__)
10 log = logging.getLogger(__name__)
5
11
12 ROOT = dn(dn(os.path.realpath(__file__)))
13 sys.path.append(ROOT)
14
15
16 def setup_repository():
17 log.info('Seting up repositories.config')
18 fname = 'repositories.config'
19
20 try:
21 tmpl = open(jn(ROOT, 'pylons_app', 'config', 'repositories.config_tmpl')).read()
22 except IOError:
23 raise
24
25 path = raw_input('Specify valid full path to your repositories'
26 ' you can change this later in repositories.config file:')
27
28 if not os.path.isdir(path):
29 log.error('You entered wrong path')
30 sys.exit()
31
32
33 path = jn(path, '*')
34 dest_path = jn(ROOT, fname)
35 f = open(dest_path, 'wb')
36 f.write(tmpl % {'repo_location':path})
37 f.close()
38 log.info('created repositories.config in %s', dest_path)
39
6
40
7 def setup_app(command, conf, vars):
41 def setup_app(command, conf, vars):
8 """Place any commands to setup pylons_app here"""
42 """Place any commands to setup pylons_app here"""
43 setup_repository()
44 dbmanage = DbManage(log_sql=True)
45 dbmanage.create_tables(override=True)
46 dbmanage.admin_prompt()
47 dbmanage.create_permissions()
9 load_environment(conf.global_conf, conf.local_conf)
48 load_environment(conf.global_conf, conf.local_conf)
49
General Comments 0
You need to be logged in to leave comments. Login now