##// END OF EJS Templates
bootstrap: allow setting certain env flags for usage in CLI scripts....
marcink -
r2651:95f21d33 default
parent child Browse files
Show More
@@ -1,81 +1,81 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2018 RhodeCode GmbH
3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22 import sys
22 import sys
23 import logging
23 import logging
24
24
25 import click
25 import click
26
26
27 from pyramid.paster import setup_logging
27 from pyramid.paster import setup_logging
28
28
29 from rhodecode.lib.pyramid_utils import bootstrap
29 from rhodecode.lib.pyramid_utils import bootstrap
30 from .backends import SshWrapper
30 from .backends import SshWrapper
31
31
32 log = logging.getLogger(__name__)
32 log = logging.getLogger(__name__)
33
33
34
34
35 def setup_custom_logging(ini_path, debug):
35 def setup_custom_logging(ini_path, debug):
36 if debug:
36 if debug:
37 # enabled rhodecode.ini controlled logging setup
37 # enabled rhodecode.ini controlled logging setup
38 setup_logging(ini_path)
38 setup_logging(ini_path)
39 else:
39 else:
40 # configure logging in a mode that doesn't print anything.
40 # configure logging in a mode that doesn't print anything.
41 # in case of regularly configured logging it gets printed out back
41 # in case of regularly configured logging it gets printed out back
42 # to the client doing an SSH command.
42 # to the client doing an SSH command.
43 logger = logging.getLogger('')
43 logger = logging.getLogger('')
44 null = logging.NullHandler()
44 null = logging.NullHandler()
45 # add the handler to the root logger
45 # add the handler to the root logger
46 logger.handlers = [null]
46 logger.handlers = [null]
47
47
48
48
49 @click.command()
49 @click.command()
50 @click.argument('ini_path', type=click.Path(exists=True))
50 @click.argument('ini_path', type=click.Path(exists=True))
51 @click.option(
51 @click.option(
52 '--mode', '-m', required=False, default='auto',
52 '--mode', '-m', required=False, default='auto',
53 type=click.Choice(['auto', 'vcs', 'git', 'hg', 'svn', 'test']),
53 type=click.Choice(['auto', 'vcs', 'git', 'hg', 'svn', 'test']),
54 help='mode of operation')
54 help='mode of operation')
55 @click.option('--user', help='Username for which the command will be executed')
55 @click.option('--user', help='Username for which the command will be executed')
56 @click.option('--user-id', help='User ID for which the command will be executed')
56 @click.option('--user-id', help='User ID for which the command will be executed')
57 @click.option('--key-id', help='ID of the key from the database')
57 @click.option('--key-id', help='ID of the key from the database')
58 @click.option('--shell', '-s', is_flag=True, help='Allow Shell')
58 @click.option('--shell', '-s', is_flag=True, help='Allow Shell')
59 @click.option('--debug', is_flag=True, help='Enabled detailed output logging')
59 @click.option('--debug', is_flag=True, help='Enabled detailed output logging')
60 def main(ini_path, mode, user, user_id, key_id, shell, debug):
60 def main(ini_path, mode, user, user_id, key_id, shell, debug):
61 setup_custom_logging(ini_path, debug)
61 setup_custom_logging(ini_path, debug)
62
62
63 command = os.environ.get('SSH_ORIGINAL_COMMAND', '')
63 command = os.environ.get('SSH_ORIGINAL_COMMAND', '')
64 if not command and mode not in ['test']:
64 if not command and mode not in ['test']:
65 raise ValueError(
65 raise ValueError(
66 'Unable to fetch SSH_ORIGINAL_COMMAND from environment.'
66 'Unable to fetch SSH_ORIGINAL_COMMAND from environment.'
67 'Please make sure this is set and available during execution '
67 'Please make sure this is set and available during execution '
68 'of this script.')
68 'of this script.')
69 connection_info = os.environ.get('SSH_CONNECTION', '')
69 connection_info = os.environ.get('SSH_CONNECTION', '')
70
70
71 with bootstrap(ini_path) as env:
71 with bootstrap(ini_path, env={'RC_CMD_SSH_WRAPPER': '1'}) as env:
72 try:
72 try:
73 ssh_wrapper = SshWrapper(
73 ssh_wrapper = SshWrapper(
74 command, connection_info, mode,
74 command, connection_info, mode,
75 user, user_id, key_id, shell, ini_path, env)
75 user, user_id, key_id, shell, ini_path, env)
76 except Exception:
76 except Exception:
77 log.exception('Failed to execute SshWrapper')
77 log.exception('Failed to execute SshWrapper')
78 sys.exit(-5)
78 sys.exit(-5)
79
79
80 return_code = ssh_wrapper.wrap()
80 return_code = ssh_wrapper.wrap()
81 sys.exit(return_code)
81 sys.exit(return_code)
@@ -1,56 +1,58 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2018 RhodeCode GmbH
3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22 from pyramid.compat import configparser
22 from pyramid.compat import configparser
23 from pyramid.paster import bootstrap as pyramid_bootstrap, setup_logging # noqa
23 from pyramid.paster import bootstrap as pyramid_bootstrap, setup_logging # noqa
24 from pyramid.request import Request
24 from pyramid.request import Request
25 from pyramid.scripting import prepare
25 from pyramid.scripting import prepare
26
26
27
27
28 def get_config(ini_path, **kwargs):
28 def get_config(ini_path, **kwargs):
29 parser = configparser.ConfigParser(**kwargs)
29 parser = configparser.ConfigParser(**kwargs)
30 parser.read(ini_path)
30 parser.read(ini_path)
31 return parser
31 return parser
32
32
33
33
34 def get_app_config(ini_path):
34 def get_app_config(ini_path):
35 from paste.deploy.loadwsgi import appconfig
35 from paste.deploy.loadwsgi import appconfig
36 return appconfig('config:{}'.format(ini_path), relative_to=os.getcwd())
36 return appconfig('config:{}'.format(ini_path), relative_to=os.getcwd())
37
37
38
38
39 def bootstrap(config_uri, request=None, options=None):
39 def bootstrap(config_uri, request=None, options=None, env=None):
40 if env:
41 os.environ.update(env)
40
42
41 config = get_config(config_uri)
43 config = get_config(config_uri)
42 base_url = 'http://rhodecode.local'
44 base_url = 'http://rhodecode.local'
43 try:
45 try:
44 base_url = config.get('app:main', 'app.base_url')
46 base_url = config.get('app:main', 'app.base_url')
45 except (configparser.NoSectionError, configparser.NoOptionError):
47 except (configparser.NoSectionError, configparser.NoOptionError):
46 pass
48 pass
47
49
48 request = request or Request.blank('/', base_url=base_url)
50 request = request or Request.blank('/', base_url=base_url)
49
51
50 return pyramid_bootstrap(config_uri, request=request, options=options)
52 return pyramid_bootstrap(config_uri, request=request, options=options)
51
53
52
54
53 def prepare_request(environ):
55 def prepare_request(environ):
54 request = Request.blank('/', environ=environ)
56 request = Request.blank('/', environ=environ)
55 prepare(request) # set pyramid threadlocal request
57 prepare(request) # set pyramid threadlocal request
56 return request
58 return request
@@ -1,103 +1,103 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2018 RhodeCode GmbH
3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 import logging
20 import logging
21
21
22 import click
22 import click
23 import pyramid.paster
23 import pyramid.paster
24
24
25 from rhodecode.lib.pyramid_utils import bootstrap, get_app_config
25 from rhodecode.lib.pyramid_utils import bootstrap, get_app_config
26 from rhodecode.lib.db_manage import DbManage
26 from rhodecode.lib.db_manage import DbManage
27 from rhodecode.model.db import Session
27 from rhodecode.model.db import Session
28
28
29
29
30 log = logging.getLogger(__name__)
30 log = logging.getLogger(__name__)
31
31
32
32
33 @click.command()
33 @click.command()
34 @click.argument('ini_path', type=click.Path(exists=True))
34 @click.argument('ini_path', type=click.Path(exists=True))
35 @click.option(
35 @click.option(
36 '--force-yes/--force-no', default=None,
36 '--force-yes/--force-no', default=None,
37 help="Force yes/no to every question")
37 help="Force yes/no to every question")
38 @click.option(
38 @click.option(
39 '--user',
39 '--user',
40 default=None,
40 default=None,
41 help='Initial super-admin username')
41 help='Initial super-admin username')
42 @click.option(
42 @click.option(
43 '--email',
43 '--email',
44 default=None,
44 default=None,
45 help='Initial super-admin email address.')
45 help='Initial super-admin email address.')
46 @click.option(
46 @click.option(
47 '--password',
47 '--password',
48 default=None,
48 default=None,
49 help='Initial super-admin password. Minimum 6 chars.')
49 help='Initial super-admin password. Minimum 6 chars.')
50 @click.option(
50 @click.option(
51 '--api-key',
51 '--api-key',
52 help='Initial API key for the admin user')
52 help='Initial API key for the admin user')
53 @click.option(
53 @click.option(
54 '--repos',
54 '--repos',
55 default=None,
55 default=None,
56 help='Absolute path to storage location. This is storage for all '
56 help='Absolute path to storage location. This is storage for all '
57 'existing and future repositories, and repository groups.')
57 'existing and future repositories, and repository groups.')
58 @click.option(
58 @click.option(
59 '--public-access/--no-public-access',
59 '--public-access/--no-public-access',
60 default=None,
60 default=None,
61 help='Enable public access on this installation. '
61 help='Enable public access on this installation. '
62 'Default is public access enabled.')
62 'Default is public access enabled.')
63 def main(ini_path, force_yes, user, email, password, api_key, repos,
63 def main(ini_path, force_yes, user, email, password, api_key, repos,
64 public_access):
64 public_access):
65 return command(ini_path, force_yes, user, email, password, api_key,
65 return command(ini_path, force_yes, user, email, password, api_key,
66 repos, public_access)
66 repos, public_access)
67
67
68
68
69 def command(ini_path, force_yes, user, email, password, api_key, repos,
69 def command(ini_path, force_yes, user, email, password, api_key, repos,
70 public_access):
70 public_access):
71 # mapping of old parameters to new CLI from click
71 # mapping of old parameters to new CLI from click
72 options = dict(
72 options = dict(
73 username=user,
73 username=user,
74 email=email,
74 email=email,
75 password=password,
75 password=password,
76 api_key=api_key,
76 api_key=api_key,
77 repos_location=repos,
77 repos_location=repos,
78 force_ask=force_yes,
78 force_ask=force_yes,
79 public_access=public_access
79 public_access=public_access
80 )
80 )
81 pyramid.paster.setup_logging(ini_path)
81 pyramid.paster.setup_logging(ini_path)
82
82
83 config = get_app_config(ini_path)
83 config = get_app_config(ini_path)
84
84
85 db_uri = config['sqlalchemy.db1.url']
85 db_uri = config['sqlalchemy.db1.url']
86 dbmanage = DbManage(log_sql=True, dbconf=db_uri, root='.',
86 dbmanage = DbManage(log_sql=True, dbconf=db_uri, root='.',
87 tests=False, cli_args=options)
87 tests=False, cli_args=options)
88 dbmanage.create_tables(override=True)
88 dbmanage.create_tables(override=True)
89 dbmanage.set_db_version()
89 dbmanage.set_db_version()
90 opts = dbmanage.config_prompt(None)
90 opts = dbmanage.config_prompt(None)
91 dbmanage.create_settings(opts)
91 dbmanage.create_settings(opts)
92 dbmanage.create_default_user()
92 dbmanage.create_default_user()
93 dbmanage.create_admin_and_prompt()
93 dbmanage.create_admin_and_prompt()
94 dbmanage.create_permissions()
94 dbmanage.create_permissions()
95 dbmanage.populate_default_permissions()
95 dbmanage.populate_default_permissions()
96 Session().commit()
96 Session().commit()
97
97
98 with bootstrap(ini_path) as env:
98 with bootstrap(ini_path, env={'RC_CMD_SETUP_RC': '1'}) as env:
99 msg = 'Successfully initialized database, schema and default data.'
99 msg = 'Successfully initialized database, schema and default data.'
100 print()
100 print()
101 print('*' * len(msg))
101 print('*' * len(msg))
102 print(msg.upper())
102 print(msg.upper())
103 print('*' * len(msg))
103 print('*' * len(msg))
@@ -1,52 +1,52 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2018 RhodeCode GmbH
3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22
22
23 import click
23 import click
24 import pyramid.paster
24 import pyramid.paster
25
25
26 from rhodecode.lib.pyramid_utils import bootstrap
26 from rhodecode.lib.pyramid_utils import bootstrap
27 from rhodecode.lib.db_manage import DbManage
27 from rhodecode.lib.db_manage import DbManage
28
28
29 log = logging.getLogger(__name__)
29 log = logging.getLogger(__name__)
30
30
31
31
32 @click.command()
32 @click.command()
33 @click.argument('ini_path', type=click.Path(exists=True))
33 @click.argument('ini_path', type=click.Path(exists=True))
34 @click.option('--force-yes/--force-no', default=None,
34 @click.option('--force-yes/--force-no', default=None,
35 help="Force yes/no to every question")
35 help="Force yes/no to every question")
36 def main(ini_path, force_yes):
36 def main(ini_path, force_yes):
37 return command(ini_path, force_yes)
37 return command(ini_path, force_yes)
38
38
39
39
40 def command(ini_path, force_yes):
40 def command(ini_path, force_yes):
41 pyramid.paster.setup_logging(ini_path)
41 pyramid.paster.setup_logging(ini_path)
42
42
43 with bootstrap(ini_path) as env:
43 with bootstrap(ini_path, env={'RC_CMD_UPGRADE_DB': '1'}) as env:
44 config = env['registry'].settings
44 config = env['registry'].settings
45 db_uri = config['sqlalchemy.db1.url']
45 db_uri = config['sqlalchemy.db1.url']
46 options = {}
46 options = {}
47 if force_yes is not None:
47 if force_yes is not None:
48 options['force_ask'] = force_yes
48 options['force_ask'] = force_yes
49 dbmanage = DbManage(
49 dbmanage = DbManage(
50 log_sql=True, dbconf=db_uri, root='.', tests=False,
50 log_sql=True, dbconf=db_uri, root='.', tests=False,
51 cli_args=options)
51 cli_args=options)
52 dbmanage.upgrade()
52 dbmanage.upgrade()
General Comments 0
You need to be logged in to leave comments. Login now