diff --git a/runbot/controllers/frontend.py b/runbot/controllers/frontend.py index aa3b71dd..810f21b7 100644 --- a/runbot/controllers/frontend.py +++ b/runbot/controllers/frontend.py @@ -603,6 +603,6 @@ class Runbot(Controller): ], type='http', auth="public", website=True, sitemap=False) def access_running(self, build_id, db_suffix=None, **kwargs): build = request.env['runbot.build'].browse(int(build_id)).exists() - if db_suffix is None: - db_suffix = build.mapped('database_ids')[0].db_suffix - return werkzeug.utils.redirect(f'http://{build.dest}-{db_suffix}.{build.host}') + run_url = build._get_run_url(db_suffix) + _logger.info('Redirecting to %s', run_url) + return werkzeug.utils.redirect(run_url) diff --git a/runbot/models/build.py b/runbot/models/build.py index 4d7cc180..51944ba8 100644 --- a/runbot/models/build.py +++ b/runbot/models/build.py @@ -21,6 +21,7 @@ from pathlib import Path from psycopg2 import sql from psycopg2.extensions import TransactionRollbackError import getpass +import uuid _logger = logging.getLogger(__name__) @@ -236,6 +237,8 @@ class BuildResult(models.Model): static_run = fields.Char('Static run URL') + access_token = fields.Char('Token', default=lambda self: uuid.uuid4().hex) + @api.depends('description', 'params_id.config_id') def _compute_display_name(self): for build in self: @@ -324,6 +327,21 @@ class BuildResult(models.Model): def _get_result_score(self, result): return result_order.index(result) + def _get_run_token(self): + token = self.access_token or self.params_id.fingerprint + token_info = hex(hash(token or '' + str(self.env.user.id)))[-4:] + return (token[:8], token_info[:4]) + + def _get_run_url(self, db_suffix=None): + if db_suffix is None: + db_suffix = self.mapped('database_ids')[0].db_suffix + if request.env.user._is_internal(): + token, token_info = self._get_run_token() + db_suffix = f'{db_suffix}-{token}-{token_info}' + use_ssl = self.env['ir.config_parameter'].sudo().get_param('runbot.use_ssl', default=True) + scheme = 'https' if use_ssl else 'http' + return f'{scheme}://{self.dest}-{db_suffix}.{self.host}' + @api.depends('active_step') def _compute_job(self): for build in self: @@ -987,7 +1005,6 @@ class BuildResult(models.Model): child._ask_kill(lock=False) def _wake_up(self): - user = request.env.user if request else self.env.user self._log('wake_up', f'Wake up initiated by {user.name}') if self.local_state != 'done': diff --git a/runbot/models/build_config.py b/runbot/models/build_config.py index 13227e5d..4294d977 100644 --- a/runbot/models/build_config.py +++ b/runbot/models/build_config.py @@ -401,7 +401,11 @@ class ConfigStep(models.Model): docker_name = build._get_docker_name() build_port = build.port - self.env['runbot.runbot']._reload_nginx() + try: + self.env['runbot.runbot']._reload_nginx() + except Exception: + _logger.exception('An error occured while reloading nginx') + build._log('', "An error occured while reloading nginx, skipping") return dict(cmd=cmd, log_path=log_path, container_name=docker_name, exposed_ports=[build_port, build_port + 1], ro_volumes=exports, env_variables=env_variables) def _run_install_odoo(self, build, log_path): diff --git a/runbot/models/res_users.py b/runbot/models/res_users.py index c04aa380..a74e2b62 100644 --- a/runbot/models/res_users.py +++ b/runbot/models/res_users.py @@ -26,8 +26,3 @@ class ResUsers(models.Model): if list(values.keys()) == ['github_login'] and self.env.user.has_group('runbot.group_runbot_team_manager'): return super(ResUsers, self.sudo()).write(values) return super().write(values) - - # backport of 16.0 feature TODO remove after migration - def _is_internal(self): - self.ensure_one() - return not self.sudo().share diff --git a/runbot/templates/nginx.xml b/runbot/templates/nginx.xml index aff41ba9..11bf9f6a 100644 --- a/runbot/templates/nginx.xml +++ b/runbot/templates/nginx.xml @@ -51,13 +51,24 @@ server { } } - + +server { + listen 8080; + server_name ~^(-[a-z0-9_]+)?-(-[a-z0-9_]+)\.$; + + location / { + + return 307 http://$1.; + } +} + server { listen 8080; server_name ~^(-[a-z0-9_]+)?\.$; + location / { proxy_pass http://127.0.0.1:; } location /longpolling { proxy_pass http://127.0.0.1:; } location /websocket { @@ -68,7 +79,6 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } - } server {