| OLD | NEW |
| 1 # Copyright 2013 The LUCI Authors. All rights reserved. | 1 # Copyright 2013 The LUCI Authors. All rights reserved. |
| 2 # Use of this source code is governed by the Apache v2.0 license that can be | 2 # Use of this source code is governed by the Apache v2.0 license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Instance specific settings.""" | 5 """Instance specific settings.""" |
| 6 | 6 |
| 7 import logging | 7 import logging |
| 8 import posixpath | 8 import posixpath |
| 9 import re |
| 9 | 10 |
| 10 from components import config | 11 from components import config |
| 11 from components import gitiles | 12 from components import gitiles |
| 12 from components import net | 13 from components import net |
| 13 from components import utils | 14 from components import utils |
| 14 from components.config import validation | 15 from components.config import validation |
| 15 | 16 |
| 16 from proto import config_pb2 | 17 from proto import config_pb2 |
| 17 from server import task_request | |
| 18 | 18 |
| 19 import cipd |
| 19 | 20 |
| 20 SETTINGS_CFG_FILENAME = 'settings.cfg' | 21 SETTINGS_CFG_FILENAME = 'settings.cfg' |
| 21 SECONDS_IN_YEAR = 60 * 60 * 24 * 365 | 22 SECONDS_IN_YEAR = 60 * 60 * 24 * 365 |
| 23 NAMESPACE_RE = re.compile(r'^[a-z0-9A-Z\-._]+$') |
| 22 | 24 |
| 23 | 25 |
| 24 ConfigApi = config.ConfigApi | 26 ConfigApi = config.ConfigApi |
| 25 | 27 |
| 26 | 28 |
| 27 def validate_isolate_settings(cfg, ctx): | 29 def validate_isolate_settings(cfg, ctx): |
| 28 if bool(cfg.default_server) != bool(cfg.default_namespace): | 30 if bool(cfg.default_server) != bool(cfg.default_namespace): |
| 29 ctx.error( | 31 ctx.error( |
| 30 'either specify both default_server and default_namespace or none') | 32 'either specify both default_server and default_namespace or none') |
| 31 elif cfg.default_server: | 33 elif cfg.default_server: |
| 32 if not cfg.default_server.startswith(('https://', 'http://')): | 34 if not cfg.default_server.startswith(('https://', 'http://')): |
| 33 ctx.error('default_server must start with "https://" or "http://"') | 35 ctx.error('default_server must start with "https://" or "http://"') |
| 34 | 36 |
| 35 if not task_request.NAMESPACE_RE.match(cfg.default_namespace): | 37 if not NAMESPACE_RE.match(cfg.default_namespace): |
| 36 ctx.error('invalid namespace "%s"', cfg.default_namespace) | 38 ctx.error('invalid namespace "%s"', cfg.default_namespace) |
| 37 | 39 |
| 38 | 40 |
| 41 def validate_cipd_settings(cfg, ctx=None): |
| 42 """Validates CipdSettings message stored in settings.cfg.""" |
| 43 ctx = ctx or validation.Context.raise_on_error() |
| 44 if not cfg.server_host: |
| 45 ctx.error('server_host is not set') |
| 46 |
| 47 if not cipd.is_valid_package_name_template(cfg.client_package_name): |
| 48 ctx.error('invalid client_package_name "%s"', cfg.client_package_name) |
| 49 elif cipd.PARAM_PLATFORM not in cfg.client_package_name: |
| 50 ctx.error( |
| 51 'client_package_name does not use %s parameter', cipd.PARAM_PLATFORM) |
| 52 |
| 53 if not cipd.is_valid_version(cfg.client_package_version): |
| 54 ctx.error('invalid client_package_version "%s"', cfg.client_package_version) |
| 55 |
| 56 |
| 39 @validation.self_rule(SETTINGS_CFG_FILENAME, config_pb2.SettingsCfg) | 57 @validation.self_rule(SETTINGS_CFG_FILENAME, config_pb2.SettingsCfg) |
| 40 def validate_settings(cfg, ctx): | 58 def validate_settings(cfg, ctx): |
| 41 """Validates settings.cfg file against proto message schema.""" | 59 """Validates settings.cfg file against proto message schema.""" |
| 42 def within_year(value): | 60 def within_year(value): |
| 43 if value < 0: | 61 if value < 0: |
| 44 ctx.error('cannot be negative') | 62 ctx.error('cannot be negative') |
| 45 elif value > SECONDS_IN_YEAR: | 63 elif value > SECONDS_IN_YEAR: |
| 46 ctx.error('cannot be more than a year') | 64 ctx.error('cannot be more than a year') |
| 47 | 65 |
| 48 with ctx.prefix('bot_death_timeout_secs '): | 66 with ctx.prefix('bot_death_timeout_secs '): |
| 49 within_year(cfg.bot_death_timeout_secs) | 67 within_year(cfg.bot_death_timeout_secs) |
| 50 with ctx.prefix('reusable_task_age_secs '): | 68 with ctx.prefix('reusable_task_age_secs '): |
| 51 within_year(cfg.reusable_task_age_secs) | 69 within_year(cfg.reusable_task_age_secs) |
| 52 | 70 |
| 53 if cfg.HasField('isolate'): | 71 if cfg.HasField('isolate'): |
| 54 with ctx.prefix('isolate: '): | 72 with ctx.prefix('isolate: '): |
| 55 validate_isolate_settings(cfg.isolate, ctx) | 73 validate_isolate_settings(cfg.isolate, ctx) |
| 56 | 74 |
| 75 if cfg.HasField('cipd'): |
| 76 with ctx.prefix('cipd: '): |
| 77 validate_cipd_settings(cfg.cipd, ctx) |
| 78 |
| 57 | 79 |
| 58 @utils.memcache('config:get_configs_url', time=60) | 80 @utils.memcache('config:get_configs_url', time=60) |
| 59 def _get_configs_url(): | 81 def _get_configs_url(): |
| 60 """Returns URL where luci-config fetches configs from.""" | 82 """Returns URL where luci-config fetches configs from.""" |
| 61 url = None | 83 url = None |
| 62 try: | 84 try: |
| 63 url = config.get_config_set_location(config.self_config_set()) | 85 url = config.get_config_set_location(config.self_config_set()) |
| 64 except net.Error: | 86 except net.Error: |
| 65 logging.info( | 87 logging.info( |
| 66 'Could not get configs URL. Possibly config directory for this ' | 88 'Could not get configs URL. Possibly config directory for this ' |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 'config_service_url': ( | 144 'config_service_url': ( |
| 123 'https://%s' % cfg_service_hostname if cfg_service_hostname else '' | 145 'https://%s' % cfg_service_hostname if cfg_service_hostname else '' |
| 124 ), | 146 ), |
| 125 } | 147 } |
| 126 | 148 |
| 127 | 149 |
| 128 @utils.cache_with_expiration(60) | 150 @utils.cache_with_expiration(60) |
| 129 def settings(): | 151 def settings(): |
| 130 """Loads settings from an NDB-based cache or a default one if not present.""" | 152 """Loads settings from an NDB-based cache or a default one if not present.""" |
| 131 return _get_settings()[1] | 153 return _get_settings()[1] |
| OLD | NEW |