diff --git a/docs/markdown/Using-the-WrapDB.md b/docs/markdown/Using-the-WrapDB.md index 93be834b68f6..baccfdc17c02 100644 --- a/docs/markdown/Using-the-WrapDB.md +++ b/docs/markdown/Using-the-WrapDB.md @@ -45,15 +45,3 @@ The contents of the Wrap database are tracked in git repos of the [Mesonbuild project](https://github.com/mesonbuild). The actual process is simple and described in [submission documentation](Adding-new-projects-to-wrapdb.md). - -## Self-hosted Wrap database - -If for whatever reason you want to use self-hosted or proxied Wrap database *(since 1.X.X)* you may override server address with the `MESON_WRAPDB_MIRROR` environment variable: - -```console -$ export MESON_WRAPDB_MIRROR=user:password@wrapdb.mydomain.invalid:8080 -$ meson wrap update-db -$ meson wrap install zlib -``` - -You will be limited to the wraps available on the mirror. \ No newline at end of file diff --git a/docs/markdown/Using-wraptool.md b/docs/markdown/Using-wraptool.md index edbceaadaec3..1eec0d34fc5e 100644 --- a/docs/markdown/Using-wraptool.md +++ b/docs/markdown/Using-wraptool.md @@ -96,3 +96,16 @@ but available in WrapDB will automatically be downloaded. Automatic fetch of WrapDB subprojects can be disabled by removing the file `subprojects/wrapdb.json`, or by using `--wrap-mode=nodownload`. + +## Self-hosted Wrap database + +If for whatever reason you want to use self-hosted or proxied Wrap database *(since 1.X.X)* you may set mirror address to be used for the workspace: + +```console +$ meson wrap set-db-mirror user:password@wrapdb.mydomain.invalid:8080 +$ meson wrap update-db +$ meson wrap install zlib +``` + +You will be limited to the wraps available on the mirror, only one source is used at a time. +The address is stored in `subprojects/wrapdb-mirrors.json`, remove the file to use upstream address. diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index c163d70eda40..59a7bc9b0d83 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -49,18 +49,29 @@ has_ssl = False REQ_TIMEOUT = 30.0 - WRAPDB_UPSTREAM_HOSTNAME = 'wrapdb.mesonbuild.com' -WRAPDB_NETLOC = os.environ.get('MESON_WRAPDB_MIRROR', WRAPDB_UPSTREAM_HOSTNAME) ALL_TYPES = ['file', 'git', 'hg', 'svn', 'redirect'] PATCH = shutil.which('patch') +@lru_cache(maxsize=None) +def wrapdb_netloc() -> str: + try: + with Path('subprojects/wrapdb-mirrors.json').open('r', encoding='utf-8') as f: + mirrorlist = json.load(f) + version = mirrorlist['version'] + if version > 1: + m = f'WrapDB mirrors file (v{version}) was created with the newer version of meson' + raise WrapException(m) + return str(mirrorlist['mirrors'][0]) + except FileNotFoundError: + return WRAPDB_UPSTREAM_HOSTNAME + def is_trusted_subdomain(hostname: str) -> bool: trusted_subdomains = { WRAPDB_UPSTREAM_HOSTNAME, - urllib.parse.urlparse(f'//{WRAPDB_NETLOC}').hostname, + urllib.parse.urlparse(f'//{wrapdb_netloc()}').hostname, } for entry in trusted_subdomains: if hostname.endswith(entry): @@ -74,7 +85,7 @@ def expand_wrapdburl(urlstr: str) -> urllib.parse.ParseResult: if url.scheme == 'wrapdb': if url.netloc: raise WrapException(f'{urlstr} with wrapdb: scheme should not have a netloc') - url = url._replace(scheme='https', netloc=WRAPDB_NETLOC) + url = url._replace(scheme='https', netloc=wrapdb_netloc()) if not url.hostname: raise WrapException(f'{urlstr} is not a valid URL') if not is_trusted_subdomain(url.hostname): @@ -128,7 +139,7 @@ def get_releases(allow_insecure: bool) -> T.Dict[str, T.Any]: def update_wrap_file(wrapfile: str, name: str, new_version: str, new_revision: str, allow_insecure: bool) -> None: resp = open_wrapdburl(f'wrapdb:///v2/{name}_{new_version}-{new_revision}/{name}.wrap', - allow_insecure, True) + allow_insecure, True) with open(wrapfile, 'wb') as f: f.write(resp.read()) diff --git a/mesonbuild/wrap/wraptool.py b/mesonbuild/wrap/wraptool.py index 1221d4c24ebb..1a8c9753f91a 100644 --- a/mesonbuild/wrap/wraptool.py +++ b/mesonbuild/wrap/wraptool.py @@ -7,6 +7,7 @@ import configparser import shutil import typing as T +import json from glob import glob from .wrap import (open_wrapdburl, WrapException, get_releases, get_releases_data, @@ -59,6 +60,10 @@ def add_arguments(parser: 'argparse.ArgumentParser') -> None: p.add_argument('project_path') p.set_defaults(wrap_func=promote) + p = subparsers.add_parser('set-db-mirror', help='Set WrapDB mirror address (RFC 3986 authority) to use') + p.add_argument('authority') + p.set_defaults(wrap_func=set_db_mirror) + p = subparsers.add_parser('update-db', help='Update list of projects available in WrapDB (Since 0.61.0)') p.add_argument('--allow-insecure', default=False, action='store_true', help='Allow insecure server connections.') @@ -187,6 +192,14 @@ def status(options: 'argparse.Namespace') -> None: else: print('', name, f'not up to date. Have {current_branch} {current_revision}, but {latest_branch} {latest_revision} is available.') +def set_db_mirror(options: 'argparse.Namespace') -> None: + Path('subprojects').mkdir(exist_ok=True) + with Path('subprojects/wrapdb-mirrors.json').open('w', encoding='utf-8') as f: + json.dump({ + "version": 1, # If the stored format changes, don't want to guess how to preserve forward compatibility, + "mirrors": [options.authority], + }, f) + def update_db(options: 'argparse.Namespace') -> None: data = get_releases_data(options.allow_insecure) Path('subprojects').mkdir(exist_ok=True)