diff --git a/conda-store-server/conda_store_server/api.py b/conda-store-server/conda_store_server/api.py index 7b3c8437c..1f1f616aa 100644 --- a/conda-store-server/conda_store_server/api.py +++ b/conda-store-server/conda_store_server/api.py @@ -268,6 +268,12 @@ def list_conda_channels(db): return db.query(orm.CondaChannel).filter(*filters) +def create_conda_channel(db, channel_name: str): + channel = orm.CondaChannel(name=channel_name, last_update=None) + db.add(channel) + return channel + + def get_conda_channel(db, channel_name: str): return ( db.query(orm.CondaChannel).filter(orm.CondaChannel.name == channel_name).first() diff --git a/conda-store-server/conda_store_server/app.py b/conda-store-server/conda_store_server/app.py index 90541c526..25c49dc6d 100644 --- a/conda-store-server/conda_store_server/app.py +++ b/conda-store-server/conda_store_server/app.py @@ -103,7 +103,7 @@ class CondaStore(LoggingConfigurable): "conda-forge", "https://repo.anaconda.com/pkgs/main", ], - help="Allowed conda channels to be used in conda environments", + help="Allowed conda channels to be used in conda environments. If set to empty list all channels are accepted. Defaults to main and conda-forge", config=True, ) diff --git a/conda-store-server/conda_store_server/build.py b/conda-store-server/conda_store_server/build.py index 1403e63a9..246eddf5c 100644 --- a/conda-store-server/conda_store_server/build.py +++ b/conda-store-server/conda_store_server/build.py @@ -40,12 +40,16 @@ def set_build_completed(conda_store, build, logs, packages): # ignore pypi package for now continue - channel_id = api.get_conda_channel(conda_store.db, channel) - if channel_id is None: - raise ValueError( - f"channel url={channel} not recognized in conda-store channel database" - ) - package["channel_id"] = channel_id.id + channel_orm = api.get_conda_channel(conda_store.db, channel) + if channel_orm is None: + if len(conda_store.conda_allowed_channels) == 0: + channel_orm = api.create_conda_channel(conda_store.db, channel) + conda_store.db.commit() + else: + raise ValueError( + f"channel url={channel} not recognized in conda-store channel database" + ) + package["channel_id"] = channel_orm.id _package = ( conda_store.db.query(orm.CondaPackage) @@ -203,12 +207,16 @@ def solve_conda_environment(conda_store, solve): # ignore pypi package for now continue - channel_id = api.get_conda_channel(conda_store.db, channel) - if channel_id is None: - raise ValueError( - f"channel url={channel} not recognized in conda-store channel database" - ) - package["channel_id"] = channel_id.id + channel_orm = api.get_conda_channel(conda_store.db, channel) + if channel_orm is None: + if len(conda_store.conda_allowed_channels) == 0: + channel_orm = api.create_conda_channel(conda_store.db, channel) + conda_store.db.commit() + else: + raise ValueError( + f"channel url={channel} not recognized in conda-store channel database" + ) + package["channel_id"] = channel_orm.id _package = ( conda_store.db.query(orm.CondaPackage) diff --git a/conda-store-server/conda_store_server/environment.py b/conda-store-server/conda_store_server/environment.py index b0bf2b96c..bd25f522b 100644 --- a/conda-store-server/conda_store_server/environment.py +++ b/conda-store-server/conda_store_server/environment.py @@ -54,7 +54,9 @@ def validate_environment_channels( conda.normalize_channel_name(conda_channel_alias, _) for _ in allowed_channels ) - if not (normalized_conda_channels <= normalized_conda_allowed_channels): + if len(allowed_channels) and not ( + normalized_conda_channels <= normalized_conda_allowed_channels + ): raise ValueError( f"Conda channels {normalized_conda_channels - normalized_conda_allowed_channels} not allowed in specification" ) diff --git a/docs/administration.md b/docs/administration.md index 2afb840db..d9f8cca82 100644 --- a/docs/administration.md +++ b/docs/administration.md @@ -117,8 +117,9 @@ are by default added if channels within the specification is empty. `CondaStore.conda_allowed_channels` is a list of Conda channels that are allowed. This also tells conda-store which channels to prefetch -the channel `repodata` and `channeldata` from. The default is `main` and -`conda-forge`. +the channel `repodata` and `channeldata` from. The default is `main` +and `conda-forge`. If `conda_allowed_channels` is an empty list all +Channels are accepted by users. `CondaStore.conda_default_packages` is a list of Conda packages that are included by default if none are specified within the specification