diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml deleted file mode 100644 index 9138f7723..000000000 --- a/.github/workflows/docs.yaml +++ /dev/null @@ -1,44 +0,0 @@ -name: Documentation - -env: - DEFAULT_PYTHON_VERSION: "3.10" - -on: - pull_request: - paths: - - "**.md" - push: - branches: - - main - paths: - - "**.md" - -jobs: - build-docs: - name: "documentation" - runs-on: ubuntu-latest - defaults: - run: - working-directory: conda-store-server - steps: - - name: "Checkout Repository" - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: ${{ env.DEFAULT_PYTHON_VERSION }} - - - name: Install Dependencies - run: | - pip install hatch - - - name: Build Documentation - run: | - hatch env run -e dev docs - - - uses: actions/upload-artifact@v3 - if: ${{ always() }} - with: - name: documentation - path: docs/_build diff --git a/.gitignore b/.gitignore index 0e4805153..0629b3e27 100644 --- a/.gitignore +++ b/.gitignore @@ -15,9 +15,6 @@ data node_modules .nuxt -# sphinx -docs/_build - # nix .direnv **/.DS_Store diff --git a/.readthedocs.yaml b/.readthedocs.yaml deleted file mode 100644 index 4d570d741..000000000 --- a/.readthedocs.yaml +++ /dev/null @@ -1,4 +0,0 @@ -version: 2 - -conda: - environment: docs/environment-docs.yml diff --git a/README.md b/README.md index 0987a6000..60ddef78a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
- conda-store logo + conda-store logo

Data science environments, for collaboration. diff --git a/conda-store-server/README.md b/conda-store-server/README.md index 262d21ea7..39d786da1 100644 --- a/conda-store-server/README.md +++ b/conda-store-server/README.md @@ -1,7 +1,4 @@ # conda-store server -Check the full documentation at [conda.store](https://conda.store/). - -A multi-tenant server for managing Conda environments. See the -[documentation](https://conda-store.readthedocs.io/en/latest/) for -more information. +A multi-tenant server for managing conda environments. +See the [documentation](https://conda.store/) for more information. diff --git a/conda-store-server/conda_store_server/server/templates/navigation.html b/conda-store-server/conda_store_server/server/templates/navigation.html index 8b24508ad..07a7456b7 100644 --- a/conda-store-server/conda_store_server/server/templates/navigation.html +++ b/conda-store-server/conda_store_server/server/templates/navigation.html @@ -35,7 +35,7 @@ {% endif %}

  • - Help diff --git a/conda-store-server/conda_store_server/server/templates/user.html b/conda-store-server/conda_store_server/server/templates/user.html index a50a07f3f..d99ac4f0c 100644 --- a/conda-store-server/conda_store_server/server/templates/user.html +++ b/conda-store-server/conda_store_server/server/templates/user.html @@ -49,7 +49,7 @@
    Namespace
    Permissions
    -

    Below are your current permissions within the conda-store application. The "*" will match any string of characters e.g. "na*ce" will match "namespace". This allows conda-store to have flexible and powerful authorization. For further information on authorization see the docs

    +

    Below are your current permissions within the conda-store application. The "*" will match any string of characters e.g. "na*ce" will match "namespace". This allows conda-store to have flexible and powerful authorization. For further information on authorization see the docs

    diff --git a/conda-store-server/pyproject.toml b/conda-store-server/pyproject.toml index 448254afa..38cca0ed7 100644 --- a/conda-store-server/pyproject.toml +++ b/conda-store-server/pyproject.toml @@ -73,7 +73,6 @@ dependencies = [ [tool.hatch.envs.dev.scripts] lint = ["pre-commit run --all"] -docs = "sphinx-build -b html ../docs ../docs/_build" unit-test = "pytest tests -v" playwright-test = [ "playwright install", diff --git a/conda-store/README.md b/conda-store/README.md index 8d2719520..5839905cd 100644 --- a/conda-store/README.md +++ b/conda-store/README.md @@ -2,26 +2,8 @@ Check the full documentation at [conda.store](https://conda.store/). -A client library for interacting with a conda-store server. See the -[documentation](https://conda-store.readthedocs.io/en/latest/) for -more information. The client library provides a CLI for interacting -with conda-store. +A client library which provides a CLI for interacting with conda-store-server. ```shell $ conda-store --help -Usage: conda-store [OPTIONS] COMMAND [ARGS]... - -Options: - --conda-store-url TEXT conda-store base url including prefix - --auth [none|token|basic] conda-store authentication to use - --no-verify-ssl Disable tls verification on API requests - --help Show this message and exit. - -Commands: - download Download artifacts for given build - info Get current permissions and default namespace - list - run Execute given environment specified as a URI with COMMAND - solve Remotely solve given environment.yaml - wait Wait for given URI to complete or fail building ``` diff --git a/conda-store/pyproject.toml b/conda-store/pyproject.toml index d47b073f4..012a8dded 100644 --- a/conda-store/pyproject.toml +++ b/conda-store/pyproject.toml @@ -58,7 +58,6 @@ dependencies = [ [tool.hatch.envs.dev.scripts] lint = ["pre-commit run --all"] -docs = "sphinx-build -b html ../docs ../docs/_build" test = "pytest tests" [project.scripts] diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d4bb2cbb9..000000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css deleted file mode 100644 index 123c5e542..000000000 --- a/docs/_static/css/custom.css +++ /dev/null @@ -1,53 +0,0 @@ -/* Set conda-store theme as primary color */ - -html[data-theme="light"] { - --pst-color-primary: #40af2fff; -} - -html[data-theme="dark"] { - --pst-color-primary: #40af2fff; -} - -.hide h1 { - display: none; -} - -/* Special classes to use inline with sphinx */ - -.center { - text-align: center; -} - -.border { - border-style: solid; - border-width: thin; -} - -.left { - text-align: left; -} - -/* Center align footer elements */ - -.bd-footer { - text-align: center; -} - -.footer-item { - display: inline-block; -} - -/* Color fixes for Swagger UI and dark mode. Ref: gh#410 */ - -html[data-theme="dark"] .fa-magnifying-glass:before { - color: var(--pst-color-text-muted); -} - -html[data-theme="dark"] .swagger-ui { - filter: invert(100%) hue-rotate(180deg); -} - -.swagger-ui pre { - border: none; - background-color: transparent; -} diff --git a/docs/_static/images/conda-store-architecture.png b/docs/_static/images/conda-store-architecture.png deleted file mode 100644 index b1c142857..000000000 Binary files a/docs/_static/images/conda-store-architecture.png and /dev/null differ diff --git a/docs/_static/images/conda-store-authenticated.png b/docs/_static/images/conda-store-authenticated.png deleted file mode 100644 index 76ac3b70c..000000000 Binary files a/docs/_static/images/conda-store-authenticated.png and /dev/null differ diff --git a/docs/_static/images/conda-store-build-complete.png b/docs/_static/images/conda-store-build-complete.png deleted file mode 100644 index cd0a24e61..000000000 Binary files a/docs/_static/images/conda-store-build-complete.png and /dev/null differ diff --git a/docs/_static/images/conda-store-create-environment.png b/docs/_static/images/conda-store-create-environment.png deleted file mode 100644 index 4806499d4..000000000 Binary files a/docs/_static/images/conda-store-create-environment.png and /dev/null differ diff --git a/docs/_static/images/conda-store-database-architecture.png b/docs/_static/images/conda-store-database-architecture.png deleted file mode 100644 index a79033388..000000000 Binary files a/docs/_static/images/conda-store-database-architecture.png and /dev/null differ diff --git a/docs/_static/images/conda-store-entity-relationship-diagram.png b/docs/_static/images/conda-store-entity-relationship-diagram.png deleted file mode 100644 index 0d9405d48..000000000 Binary files a/docs/_static/images/conda-store-entity-relationship-diagram.png and /dev/null differ diff --git a/docs/_static/images/conda-store-environment.png b/docs/_static/images/conda-store-environment.png deleted file mode 100644 index ac0d40568..000000000 Binary files a/docs/_static/images/conda-store-environment.png and /dev/null differ diff --git a/docs/_static/images/conda-store-installation-kubernetes.png b/docs/_static/images/conda-store-installation-kubernetes.png deleted file mode 100644 index 05e3943ec..000000000 Binary files a/docs/_static/images/conda-store-installation-kubernetes.png and /dev/null differ diff --git a/docs/_static/images/conda-store-login-jupyterhub-oauth.png b/docs/_static/images/conda-store-login-jupyterhub-oauth.png deleted file mode 100644 index 978bf86c6..000000000 Binary files a/docs/_static/images/conda-store-login-jupyterhub-oauth.png and /dev/null differ diff --git a/docs/_static/images/conda-store-logo-symbol.svg b/docs/_static/images/conda-store-logo-symbol.svg deleted file mode 100644 index 5ed21a26a..000000000 --- a/docs/_static/images/conda-store-logo-symbol.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/_static/images/conda-store-logo-vertical-lockup.png b/docs/_static/images/conda-store-logo-vertical-lockup.png deleted file mode 100644 index 1e3fc9d66..000000000 Binary files a/docs/_static/images/conda-store-logo-vertical-lockup.png and /dev/null differ diff --git a/docs/_static/images/conda-store-namespace.png b/docs/_static/images/conda-store-namespace.png deleted file mode 100644 index 185dd2524..000000000 Binary files a/docs/_static/images/conda-store-namespace.png and /dev/null differ diff --git a/docs/_static/images/conda-store-single-environment.png b/docs/_static/images/conda-store-single-environment.png deleted file mode 100644 index 500c13176..000000000 Binary files a/docs/_static/images/conda-store-single-environment.png and /dev/null differ diff --git a/docs/_static/images/conda-store-terminology.png b/docs/_static/images/conda-store-terminology.png deleted file mode 100644 index 183a249a1..000000000 Binary files a/docs/_static/images/conda-store-terminology.png and /dev/null differ diff --git a/docs/_static/images/conda-store-triangle-all.png b/docs/_static/images/conda-store-triangle-all.png deleted file mode 100644 index 0adbf3876..000000000 Binary files a/docs/_static/images/conda-store-triangle-all.png and /dev/null differ diff --git a/docs/_static/images/conda-store-triangle-it-reproducibility.png b/docs/_static/images/conda-store-triangle-it-reproducibility.png deleted file mode 100644 index 20a32300f..000000000 Binary files a/docs/_static/images/conda-store-triangle-it-reproducibility.png and /dev/null differ diff --git a/docs/_static/images/conda-store-triangle-it-users.png b/docs/_static/images/conda-store-triangle-it-users.png deleted file mode 100644 index 56ba8ab87..000000000 Binary files a/docs/_static/images/conda-store-triangle-it-users.png and /dev/null differ diff --git a/docs/_static/images/conda-store-triangle-users-reproducibility.png b/docs/_static/images/conda-store-triangle-users-reproducibility.png deleted file mode 100644 index 91cc29f48..000000000 Binary files a/docs/_static/images/conda-store-triangle-users-reproducibility.png and /dev/null differ diff --git a/docs/_static/images/conda-store-ui.webp b/docs/_static/images/conda-store-ui.webp deleted file mode 100644 index 9f0e05f60..000000000 Binary files a/docs/_static/images/conda-store-ui.webp and /dev/null differ diff --git a/docs/_static/images/conda-store-unauthenticated.png b/docs/_static/images/conda-store-unauthenticated.png deleted file mode 100644 index f77ae95ed..000000000 Binary files a/docs/_static/images/conda-store-unauthenticated.png and /dev/null differ diff --git a/docs/_static/images/conda-store-user.png b/docs/_static/images/conda-store-user.png deleted file mode 100644 index ce9eb5ecc..000000000 Binary files a/docs/_static/images/conda-store-user.png and /dev/null differ diff --git a/docs/_static/images/favicon.ico b/docs/_static/images/favicon.ico deleted file mode 100644 index 657b55ef4..000000000 --- a/docs/_static/images/favicon.ico +++ /dev/null @@ -1 +0,0 @@ -../../../conda-store-server/conda_store_server/server/static/favicon.ico diff --git a/docs/_static/openapi.json b/docs/_static/openapi.json deleted file mode 100644 index ded3e6602..000000000 --- a/docs/_static/openapi.json +++ /dev/null @@ -1,1889 +0,0 @@ -{ - "openapi": "3.0.2", - "info": { - "title": "conda-store", - "contact": { "name": "Quansight", "url": "https://quansight.com" }, - "license": { - "name": "BSD 3-Clause", - "url": "https://opensource.org/licenses/BSD-3-Clause" - }, - "version": "0.4.12" - }, - "paths": { - "/conda-store/login/": { - "get": { - "tags": ["auth"], - "summary": "Get Login Method", - "operationId": "get_login_method_conda_store_login__get", - "parameters": [ - { - "required": false, - "schema": { "title": "Next", "type": "string" }, - "name": "next", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - }, - "post": { - "tags": ["auth"], - "summary": "Post Login Method", - "operationId": "post_login_method_conda_store_login__post", - "parameters": [ - { - "required": false, - "schema": { "title": "Next", "type": "string" }, - "name": "next", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/logout/": { - "post": { - "tags": ["auth"], - "summary": "Post Logout Method", - "operationId": "post_logout_method_conda_store_logout__post", - "parameters": [ - { - "required": false, - "schema": { "title": "Next", "type": "string" }, - "name": "next", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/": { - "get": { - "tags": ["api"], - "summary": "Api Status", - "operationId": "api_status_conda_store_api_v1__get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIGetStatus" } - } - } - } - } - } - }, - "/conda-store/api/v1/permission/": { - "get": { - "tags": ["api"], - "summary": "Api Get Permissions", - "operationId": "api_get_permissions_conda_store_api_v1_permission__get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIGetPermission" } - } - } - } - } - } - }, - "/conda-store/api/v1/token/": { - "post": { - "tags": ["api"], - "summary": "Api Post Token", - "operationId": "api_post_token_conda_store_api_v1_token__post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Body_api_post_token_conda_store_api_v1_token__post" - } - } - } - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIPostToken" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/namespace/": { - "get": { - "tags": ["api"], - "summary": "Api List Namespaces", - "operationId": "api_list_namespaces_conda_store_api_v1_namespace__get", - "parameters": [ - { - "required": false, - "schema": { "title": "Page", "type": "integer", "default": 1 }, - "name": "page", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Order", "type": "string" }, - "name": "order", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Size", "type": "integer" }, - "name": "size", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Sort By", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "sort_by", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIListNamespace" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/namespace/{namespace}/": { - "get": { - "tags": ["api"], - "summary": "Api Get Namespace", - "operationId": "api_get_namespace_conda_store_api_v1_namespace__namespace___get", - "parameters": [ - { - "required": true, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIGetNamespace" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - }, - "post": { - "tags": ["api"], - "summary": "Api Create Namespace", - "operationId": "api_create_namespace_conda_store_api_v1_namespace__namespace___post", - "parameters": [ - { - "required": true, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIAckResponse" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - }, - "delete": { - "tags": ["api"], - "summary": "Api Delete Namespace", - "operationId": "api_delete_namespace_conda_store_api_v1_namespace__namespace___delete", - "parameters": [ - { - "required": true, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIAckResponse" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/environment/": { - "get": { - "tags": ["api"], - "summary": "Api List Environments", - "operationId": "api_list_environments_conda_store_api_v1_environment__get", - "parameters": [ - { - "required": false, - "schema": { "title": "Search", "type": "string" }, - "name": "search", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Name", "type": "string" }, - "name": "name", - "in": "query" - }, - { - "required": false, - "schema": { "$ref": "#/components/schemas/BuildStatus" }, - "name": "status", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Packages", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "packages", - "in": "query" - }, - { - "required": false, - "schema": { "$ref": "#/components/schemas/BuildArtifactType" }, - "name": "artifact", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Page", "type": "integer", "default": 1 }, - "name": "page", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Order", "type": "string" }, - "name": "order", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Size", "type": "integer" }, - "name": "size", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Sort By", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "sort_by", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIListEnvironment" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/environment/{namespace}/{environment_name}/": { - "get": { - "tags": ["api"], - "summary": "Api Get Environment", - "operationId": "api_get_environment_conda_store_api_v1_environment__namespace___environment_name___get", - "parameters": [ - { - "required": true, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "path" - }, - { - "required": true, - "schema": { "title": "Environment Name", "type": "string" }, - "name": "environment_name", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIGetEnvironment" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/environment/{namespace}/{name}/": { - "put": { - "tags": ["api"], - "summary": "Api Update Environment Build", - "operationId": "api_update_environment_build_conda_store_api_v1_environment__namespace___name___put", - "parameters": [ - { - "required": true, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "path" - }, - { - "required": true, - "schema": { "title": "Name", "type": "string" }, - "name": "name", - "in": "path" - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Body_api_update_environment_build_conda_store_api_v1_environment__namespace___name___put" - } - } - } - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIAckResponse" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - }, - "delete": { - "tags": ["api"], - "summary": "Api Delete Environment", - "operationId": "api_delete_environment_conda_store_api_v1_environment__namespace___name___delete", - "parameters": [ - { - "required": true, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "path" - }, - { - "required": true, - "schema": { "title": "Name", "type": "string" }, - "name": "name", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIAckResponse" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/specification/": { - "get": { - "tags": ["api"], - "summary": "Api Get Specification", - "operationId": "api_get_specification_conda_store_api_v1_specification__get", - "parameters": [ - { - "required": false, - "schema": { - "title": "Channel", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "channel", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Conda", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "conda", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Pip", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "pip", - "in": "query" - }, - { - "required": false, - "schema": { - "allOf": [ - { "$ref": "#/components/schemas/APIGetSpecificationFormat" } - ], - "default": "yaml" - }, - "name": "format", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - }, - "post": { - "tags": ["api"], - "summary": "Api Post Specification", - "operationId": "api_post_specification_conda_store_api_v1_specification__post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Body_api_post_specification_conda_store_api_v1_specification__post" - } - } - } - }, - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/APIPostSpecification" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/build/": { - "get": { - "tags": ["api"], - "summary": "Api List Builds", - "operationId": "api_list_builds_conda_store_api_v1_build__get", - "parameters": [ - { - "required": false, - "schema": { "$ref": "#/components/schemas/BuildStatus" }, - "name": "status", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Packages", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "packages", - "in": "query" - }, - { - "required": false, - "schema": { "$ref": "#/components/schemas/BuildArtifactType" }, - "name": "artifact", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Environment Id", "type": "integer" }, - "name": "environment_id", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Name", "type": "string" }, - "name": "name", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Page", "type": "integer", "default": 1 }, - "name": "page", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Order", "type": "string" }, - "name": "order", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Size", "type": "integer" }, - "name": "size", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Sort By", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "sort_by", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIListBuild" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/build/{build_id}/": { - "get": { - "tags": ["api"], - "summary": "Api Get Build", - "operationId": "api_get_build_conda_store_api_v1_build__build_id___get", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIGetBuild" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - }, - "put": { - "tags": ["api"], - "summary": "Api Put Build", - "operationId": "api_put_build_conda_store_api_v1_build__build_id___put", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/APIPostSpecification" - } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - }, - "delete": { - "tags": ["api"], - "summary": "Api Delete Build", - "operationId": "api_delete_build_conda_store_api_v1_build__build_id___delete", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIAckResponse" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/build/{build_id}/packages/": { - "get": { - "tags": ["api"], - "summary": "Api Get Build Packages", - "operationId": "api_get_build_packages_conda_store_api_v1_build__build_id__packages__get", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - }, - { - "required": false, - "schema": { "title": "Search", "type": "string" }, - "name": "search", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Exact", "type": "string" }, - "name": "exact", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Build", "type": "string" }, - "name": "build", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Page", "type": "integer", "default": 1 }, - "name": "page", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Order", "type": "string" }, - "name": "order", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Size", "type": "integer" }, - "name": "size", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Sort By", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "sort_by", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIListCondaPackage" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/build/{build_id}/logs/": { - "get": { - "tags": ["api"], - "summary": "Api Get Build Logs", - "operationId": "api_get_build_logs_conda_store_api_v1_build__build_id__logs__get", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/channel/": { - "get": { - "tags": ["api"], - "summary": "Api List Channels", - "operationId": "api_list_channels_conda_store_api_v1_channel__get", - "parameters": [ - { - "required": false, - "schema": { "title": "Page", "type": "integer", "default": 1 }, - "name": "page", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Order", "type": "string" }, - "name": "order", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Size", "type": "integer" }, - "name": "size", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Sort By", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "sort_by", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIListCondaChannel" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/package/": { - "get": { - "tags": ["api"], - "summary": "Api List Packages", - "operationId": "api_list_packages_conda_store_api_v1_package__get", - "parameters": [ - { - "required": false, - "schema": { "title": "Search", "type": "string" }, - "name": "search", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Exact", "type": "string" }, - "name": "exact", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Build", "type": "string" }, - "name": "build", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Distinct On", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "distinct_on", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Page", "type": "integer", "default": 1 }, - "name": "page", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Order", "type": "string" }, - "name": "order", - "in": "query" - }, - { - "required": false, - "schema": { "title": "Size", "type": "integer" }, - "name": "size", - "in": "query" - }, - { - "required": false, - "schema": { - "title": "Sort By", - "type": "array", - "items": { "type": "string" }, - "default": [] - }, - "name": "sort_by", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/APIListCondaPackage" } - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/build/{build_id}/yaml/": { - "get": { - "tags": ["api"], - "summary": "Api Get Build Yaml", - "operationId": "api_get_build_yaml_conda_store_api_v1_build__build_id__yaml__get", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/build/{build_id}/lockfile/": { - "get": { - "tags": ["api"], - "summary": "Api Get Build Lockfile", - "operationId": "api_get_build_lockfile_conda_store_api_v1_build__build_id__lockfile__get", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "text/plain": { "schema": { "type": "string" } } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/build/{build_id}/archive/": { - "get": { - "tags": ["api"], - "summary": "Api Get Build Archive", - "operationId": "api_get_build_archive_conda_store_api_v1_build__build_id__archive__get", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/api/v1/build/{build_id}/docker/": { - "get": { - "tags": ["api"], - "summary": "Api Get Build Docker Image Url", - "operationId": "api_get_build_docker_image_url_conda_store_api_v1_build__build_id__docker__get", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/v2/": { - "get": { - "tags": ["registry"], - "summary": "V2", - "operationId": "v2_v2__get", - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - } - } - } - }, - "/v2/{rest}": { - "get": { - "tags": ["registry"], - "summary": "List Tags", - "operationId": "list_tags_v2__rest__get", - "parameters": [ - { - "required": true, - "schema": { "title": "Rest", "type": "string" }, - "name": "rest", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/create/": { - "get": { - "tags": ["ui"], - "summary": "Ui Create Get Environment", - "operationId": "ui_create_get_environment_conda_store_create__get", - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - } - } - } - }, - "/conda-store/": { - "get": { - "tags": ["ui"], - "summary": "Ui List Environments", - "operationId": "ui_list_environments_conda_store__get", - "parameters": [ - { - "required": false, - "schema": { "title": "Search", "type": "string" }, - "name": "search", - "in": "query" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/namespace/": { - "get": { - "tags": ["ui"], - "summary": "Ui List Namespaces", - "operationId": "ui_list_namespaces_conda_store_namespace__get", - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - } - } - } - }, - "/conda-store/environment/{namespace}/{environment_name}/": { - "get": { - "tags": ["ui"], - "summary": "Ui Get Environment", - "operationId": "ui_get_environment_conda_store_environment__namespace___environment_name___get", - "parameters": [ - { - "required": true, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "path" - }, - { - "required": true, - "schema": { "title": "Environment Name", "type": "string" }, - "name": "environment_name", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/environment/{namespace}/{environment_name}/edit/": { - "get": { - "tags": ["ui"], - "summary": "Ui Edit Environment", - "operationId": "ui_edit_environment_conda_store_environment__namespace___environment_name__edit__get", - "parameters": [ - { - "required": true, - "schema": { "title": "Namespace", "type": "string" }, - "name": "namespace", - "in": "path" - }, - { - "required": true, - "schema": { "title": "Environment Name", "type": "string" }, - "name": "environment_name", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/build/{build_id}/": { - "get": { - "tags": ["ui"], - "summary": "Ui Get Build", - "operationId": "ui_get_build_conda_store_build__build_id___get", - "parameters": [ - { - "required": true, - "schema": { "title": "Build Id", "type": "integer" }, - "name": "build_id", - "in": "path" - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/HTTPValidationError" } - } - } - } - } - } - }, - "/conda-store/user/": { - "get": { - "tags": ["ui"], - "summary": "Ui Get User", - "operationId": "ui_get_user_conda_store_user__get", - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - } - } - } - }, - "/": { - "get": { - "summary": "Redirect Home", - "operationId": "redirect_home__get", - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - } - } - } - }, - "/conda-store/metrics": { - "get": { - "tags": ["metrics"], - "summary": "Prometheus Metrics", - "operationId": "prometheus_metrics_conda_store_metrics_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { "text/plain": { "schema": { "type": "string" } } } - } - } - } - }, - "/conda-store/celery": { - "get": { - "tags": ["metrics"], - "summary": "Trigger Task", - "operationId": "trigger_task_conda_store_celery_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { "application/json": { "schema": {} } } - } - } - } - } - }, - "components": { - "schemas": { - "APIAckResponse": { - "title": "APIAckResponse", - "required": ["status"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "message": { "title": "Message", "type": "string" } - } - }, - "APIGetBuild": { - "title": "APIGetBuild", - "required": ["status", "data"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { "$ref": "#/components/schemas/Build" }, - "message": { "title": "Message", "type": "string" } - } - }, - "APIGetEnvironment": { - "title": "APIGetEnvironment", - "required": ["status", "data"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { "$ref": "#/components/schemas/Environment" }, - "message": { "title": "Message", "type": "string" } - } - }, - "APIGetNamespace": { - "title": "APIGetNamespace", - "required": ["status", "data"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { "$ref": "#/components/schemas/Namespace" }, - "message": { "title": "Message", "type": "string" } - } - }, - "APIGetPermission": { - "title": "APIGetPermission", - "required": ["status", "data"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { "$ref": "#/components/schemas/APIGetPermissionData" }, - "message": { "title": "Message", "type": "string" } - } - }, - "APIGetPermissionData": { - "title": "APIGetPermissionData", - "required": [ - "authenticated", - "primary_namespace", - "entity_permissions", - "entity_roles" - ], - "type": "object", - "properties": { - "authenticated": { "title": "Authenticated", "type": "boolean" }, - "primary_namespace": { - "title": "Primary Namespace", - "type": "string" - }, - "entity_permissions": { - "title": "Entity Permissions", - "type": "object", - "additionalProperties": { - "type": "array", - "items": { "type": "string" } - } - }, - "entity_roles": { - "title": "Entity Roles", - "type": "object", - "additionalProperties": { - "type": "array", - "items": { "type": "string" } - } - }, - "expiration": { - "title": "Expiration", - "type": "string", - "format": "date-time" - } - } - }, - "APIGetSpecificationFormat": { - "title": "APIGetSpecificationFormat", - "enum": ["yaml", "lockfile"], - "description": "An enumeration." - }, - "APIGetStatus": { - "title": "APIGetStatus", - "required": ["status", "data"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { "$ref": "#/components/schemas/APIGetStatusData" }, - "message": { "title": "Message", "type": "string" } - } - }, - "APIGetStatusData": { - "title": "APIGetStatusData", - "required": ["version"], - "type": "object", - "properties": { "version": { "title": "Version", "type": "string" } } - }, - "APIListBuild": { - "title": "APIListBuild", - "required": ["status", "data", "page", "size", "count"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { - "title": "Data", - "type": "array", - "items": { "$ref": "#/components/schemas/Build" } - }, - "message": { "title": "Message", "type": "string" }, - "page": { "title": "Page", "type": "integer" }, - "size": { "title": "Size", "type": "integer" }, - "count": { "title": "Count", "type": "integer" } - } - }, - "APIListCondaChannel": { - "title": "APIListCondaChannel", - "required": ["status", "data", "page", "size", "count"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { - "title": "Data", - "type": "array", - "items": { "$ref": "#/components/schemas/CondaChannel" } - }, - "message": { "title": "Message", "type": "string" }, - "page": { "title": "Page", "type": "integer" }, - "size": { "title": "Size", "type": "integer" }, - "count": { "title": "Count", "type": "integer" } - } - }, - "APIListCondaPackage": { - "title": "APIListCondaPackage", - "required": ["status", "data", "page", "size", "count"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { - "title": "Data", - "type": "array", - "items": { "$ref": "#/components/schemas/CondaPackage" } - }, - "message": { "title": "Message", "type": "string" }, - "page": { "title": "Page", "type": "integer" }, - "size": { "title": "Size", "type": "integer" }, - "count": { "title": "Count", "type": "integer" } - } - }, - "APIListEnvironment": { - "title": "APIListEnvironment", - "required": ["status", "data", "page", "size", "count"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { - "title": "Data", - "type": "array", - "items": { "$ref": "#/components/schemas/Environment" } - }, - "message": { "title": "Message", "type": "string" }, - "page": { "title": "Page", "type": "integer" }, - "size": { "title": "Size", "type": "integer" }, - "count": { "title": "Count", "type": "integer" } - } - }, - "APIListNamespace": { - "title": "APIListNamespace", - "required": ["status", "data", "page", "size", "count"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { - "title": "Data", - "type": "array", - "items": { "$ref": "#/components/schemas/Namespace" } - }, - "message": { "title": "Message", "type": "string" }, - "page": { "title": "Page", "type": "integer" }, - "size": { "title": "Size", "type": "integer" }, - "count": { "title": "Count", "type": "integer" } - } - }, - "APIPostSpecification": { - "title": "APIPostSpecification", - "required": ["status", "data"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { "$ref": "#/components/schemas/APIPostSpecificationData" }, - "message": { "title": "Message", "type": "string" } - } - }, - "APIPostSpecificationData": { - "title": "APIPostSpecificationData", - "required": ["build_id"], - "type": "object", - "properties": { "build_id": { "title": "Build Id", "type": "integer" } } - }, - "APIPostToken": { - "title": "APIPostToken", - "required": ["status", "data"], - "type": "object", - "properties": { - "status": { "$ref": "#/components/schemas/APIStatus" }, - "data": { "$ref": "#/components/schemas/APIPostTokenData" }, - "message": { "title": "Message", "type": "string" } - } - }, - "APIPostTokenData": { - "title": "APIPostTokenData", - "required": ["token"], - "type": "object", - "properties": { "token": { "title": "Token", "type": "string" } } - }, - "APIStatus": { - "title": "APIStatus", - "enum": ["ok", "error"], - "description": "An enumeration." - }, - "Body_api_post_specification_conda_store_api_v1_specification__post": { - "title": "Body_api_post_specification_conda_store_api_v1_specification__post", - "type": "object", - "properties": { - "specification": { - "title": "Specification", - "type": "string", - "default": "" - }, - "namespace": { "title": "Namespace", "type": "string" } - } - }, - "Body_api_post_token_conda_store_api_v1_token__post": { - "title": "Body_api_post_token_conda_store_api_v1_token__post", - "type": "object", - "properties": { - "primary_namespace": { - "title": "Primary Namespace", - "type": "string" - }, - "expiration": { - "title": "Expiration", - "type": "string", - "format": "date-time" - }, - "role_bindings": { - "title": "Role Bindings", - "type": "object", - "additionalProperties": { - "type": "array", - "items": { "type": "string" } - } - } - } - }, - "Body_api_update_environment_build_conda_store_api_v1_environment__namespace___name___put": { - "title": "Body_api_update_environment_build_conda_store_api_v1_environment__namespace___name___put", - "type": "object", - "properties": { - "build_id": { "title": "Build Id", "type": "integer" }, - "description": { "title": "Description", "type": "string" } - } - }, - "Build": { - "title": "Build", - "required": ["id", "environment_id", "status", "size", "scheduled_on"], - "type": "object", - "properties": { - "id": { "title": "Id", "type": "integer" }, - "environment_id": { "title": "Environment Id", "type": "integer" }, - "specification": { "$ref": "#/components/schemas/Specification" }, - "packages": { - "title": "Packages", - "type": "array", - "items": { "$ref": "#/components/schemas/CondaPackage" } - }, - "status": { "$ref": "#/components/schemas/BuildStatus" }, - "size": { "title": "Size", "type": "integer" }, - "scheduled_on": { - "title": "Scheduled On", - "type": "string", - "format": "date-time" - }, - "started_on": { - "title": "Started On", - "type": "string", - "format": "date-time" - }, - "ended_on": { - "title": "Ended On", - "type": "string", - "format": "date-time" - }, - "build_artifacts": { - "title": "Build Artifacts", - "type": "array", - "items": { "$ref": "#/components/schemas/BuildArtifact" } - } - } - }, - "BuildArtifact": { - "title": "BuildArtifact", - "required": ["id", "artifact_type", "key"], - "type": "object", - "properties": { - "id": { "title": "Id", "type": "integer" }, - "artifact_type": { "$ref": "#/components/schemas/BuildArtifactType" }, - "key": { "title": "Key", "type": "string" } - } - }, - "BuildArtifactType": { - "title": "BuildArtifactType", - "enum": [ - "DIRECTORY", - "LOCKFILE", - "LOGS", - "YAML", - "CONDA_PACK", - "DOCKER_BLOB", - "DOCKER_MANIFEST", - "CONTAINER_REGISTRY" - ], - "description": "An enumeration." - }, - "BuildStatus": { - "title": "BuildStatus", - "enum": ["QUEUED", "BUILDING", "COMPLETED", "FAILED"], - "description": "An enumeration." - }, - "CondaChannel": { - "title": "CondaChannel", - "required": ["id", "name"], - "type": "object", - "properties": { - "id": { "title": "Id", "type": "integer" }, - "name": { "title": "Name", "type": "string" }, - "last_update": { - "title": "Last Update", - "type": "string", - "format": "date-time" - } - } - }, - "CondaPackage": { - "title": "CondaPackage", - "required": ["id", "channel", "build", "sha256", "name", "version"], - "type": "object", - "properties": { - "id": { "title": "Id", "type": "integer" }, - "channel": { "$ref": "#/components/schemas/CondaChannel" }, - "build": { "title": "Build", "type": "string" }, - "license": { "title": "License", "type": "string" }, - "sha256": { "title": "Sha256", "type": "string" }, - "name": { "title": "Name", "type": "string" }, - "version": { "title": "Version", "type": "string" }, - "summary": { "title": "Summary", "type": "string" } - } - }, - "Environment": { - "title": "Environment", - "required": ["id", "namespace", "name", "current_build_id"], - "type": "object", - "properties": { - "id": { "title": "Id", "type": "integer" }, - "namespace": { "$ref": "#/components/schemas/Namespace" }, - "name": { "title": "Name", "type": "string" }, - "current_build_id": { - "title": "Current Build Id", - "type": "integer" - }, - "current_build": { "$ref": "#/components/schemas/Build" }, - "description": { "title": "Description", "type": "string" } - } - }, - "HTTPValidationError": { - "title": "HTTPValidationError", - "type": "object", - "properties": { - "detail": { - "title": "Detail", - "type": "array", - "items": { "$ref": "#/components/schemas/ValidationError" } - } - } - }, - "Namespace": { - "title": "Namespace", - "required": ["id", "name"], - "type": "object", - "properties": { - "id": { "title": "Id", "type": "integer" }, - "name": { - "title": "Name", - "pattern": "^[A-Za-z0-9-+_@$&?^~.=]+$", - "type": "string" - } - } - }, - "Specification": { - "title": "Specification", - "required": ["id", "name", "spec", "sha256", "created_on"], - "type": "object", - "properties": { - "id": { "title": "Id", "type": "integer" }, - "name": { "title": "Name", "type": "string" }, - "spec": { "title": "Spec", "type": "object" }, - "sha256": { "title": "Sha256", "type": "string" }, - "created_on": { - "title": "Created On", - "type": "string", - "format": "date-time" - } - } - }, - "ValidationError": { - "title": "ValidationError", - "required": ["loc", "msg", "type"], - "type": "object", - "properties": { - "loc": { - "title": "Location", - "type": "array", - "items": { "anyOf": [{ "type": "string" }, { "type": "integer" }] } - }, - "msg": { "title": "Message", "type": "string" }, - "type": { "title": "Error Type", "type": "string" } - } - } - } - } -} diff --git a/docs/administration.md b/docs/administration.md deleted file mode 100644 index 899f452aa..000000000 --- a/docs/administration.md +++ /dev/null @@ -1,702 +0,0 @@ -# Administration - -## Resource Requirements - -- `conda-store-server` is simply a web server and should not require - any specific resources. 1 GB of RAM and 1 CPU should be plenty. -- `conda-store-worker` does the actual builds of the Conda - environments. Solving for Conda environments can take a lot of - memory in some circumstances. So make sure to allocate at least 4 - GB of RAM to the worker along with at least one CPU. - -## Performance - -There are several parts of conda-store to consider for performance. We -have tried to list them in order of performance impact that may be -seen. - -### Worker Storage - -When conda-store builds a given environment it has to locally install -the environment in the directory specified in the -[Traitlets](https://traitlets.readthedocs.io/en/stable/using_traitlets.html) -configuration `CondaStore.store_directory`. Conda environments consist -of many hardlinks to small files. This means that the -`store_directory` is limited to the number of -[IOPS](https://en.wikipedia.org/wiki/IOPS) the directory can -perform. Many cloud providers have high performance storage -options. These include: - -If you do not need to mount the environments via NFS into the -containers we highly recommend not using NFS and using traditional -block storage. Not only is it significantly cheaper but the IOPs -performance will be better as well. - -If you want to mount the environments in containers or running VMs NFS -may be a good option for you. With NFS many cloud providers provide a -high performance filesystem option at a significant premium in -cost. Example of these include [GCP -Filestore](https://cloud.google.com/filestore/docs/performance#expected_performance), -[AWS EFS](https://aws.amazon.com/efs/features/), and [Azure -files](https://docs.microsoft.com/en-us/azure/storage/files/understanding-billing#provisioning-method). Choosing -an nfs storage option with low IOPS will result in long environment -install times. - -### Network Speed - -While Conda does its best to cache packages, it will have to reach out -to download the `repodata.json` along with the packages as well. Thus -network speeds may be important. Typically cloud environments have -plenty fast Internet. - -### S3 Storage - -All build artifacts from conda-store are stored in object storage that -behaves S3 like. S3 traditionally has great performance if you use the -cloud provider implementation. - -## Configuration - -conda-store is configured via -[Traitlets](https://traitlets.readthedocs.io/en/stable/). Originally -this configuration was done via command line options but as the -options grew this seems untenable. conda-store server and worker can -be launched via configuration easily. - -```shell -conda-store-server --config -``` - -```shell -conda-store-worker --config -``` - -Below we outline the options for conda-store. - -### `conda_store_server.app.CondaStore` - -`CondaStore.storage_class` configures the storage backend to use for -storing build artifacts from -conda-store. [S3](https://en.wikipedia.org/wiki/Amazon_S3) storage is -the default. File based storage is also supported but not nearly as -well tested. - -`CondaStore.conda_solve_platforms` configures which platforms to solve environments for, via conda-lock. It must include the current platform conda-store is running on. By default, contains only the platform on which conda-store is running. - -`CondaStore.store_directory` is the directory used for conda-store to -build the environments. - -`CondaStore.build_directory` template used to form the directory for -storing Conda environment builds. Available keys: `store_directory`, -`namespace`, `name`. The default will put all built environments in the -same namespace within the same directory. - -`CondaStore.environment_directory` template used to form the directory -for symlinking Conda environment builds. Available keys: -store_directory, namespace, name. The default will put all -environments in the same namespace within the same directory. - -`CondaStore.build_key_version` is the [build key version](#build-key-versions) -to use: 1 (long, legacy), 2 (short, default). - -`CondaStore.validate_specification` callable function taking -`conda_store` and `specification` as input arguments to apply for -validating and modifying a given specification. If there are -validation issues with the environment ValueError with message will be -raised. - -`CondaStore.validate_action` callable function taking conda_store, -namespace, and action. If there are issues with performing the given -action raise a CondaStoreError should be raised. - -`CondaStore.conda_command` is the `command` to use for creation of -Conda environments. Currently `mamba` is the default which will -usually result in lower peak memory usage and faster builds. - -`CondaStore.conda_channel_alias` is the url to prepend to all -shorthand Conda channels that do not specify a url. The default is -`https://conda.anaconda.org`. - -`CondaStore.conda_platforms` are the platforms to download package -repodata.json from. By default includes current architecture and -`noarch`. - -`CondaStore.conda_default_channels` is a list of Conda channels that -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`. If `conda_allowed_channels` is an empty list all -Channels are accepted by users. - -`CondaStore.conda_indexed_channels` tells conda-store which channels to prefetch -the channel `repodata` and `channeldata` from. The default is `main` -and `conda-forge`. - -`CondaStore.conda_default_packages` is a list of Conda packages that -are included by default if none are specified within the specification -dependencies. - -`CondaStore.conda_required_packages` is a list of Conda packages that -are required upon validation of the specification dependencies. This -will not auto add the packages but instead throw an error that they -are missing. - -`CondaStore.conda_included_packages` is a list of Conda packages that -if not specified within the specification dependencies will be auto -added. - -`CondaStore.pypi_default_packages` is a list of PyPi packages that -are included by default if none are specified within the specification -dependencies. - -`CondaStore.pypi_required_packages` is a list of PyPi packages that -are required upon validation of the specification dependencies. This -will not auto add the packages but instead throw an error that they -are missing. - -`CondaStore.pypi_included_packages` is a list of PyPi packages that -if not specified within the specification dependencies will be auto -added. - -`CondaStore.storage_thresold` storage threshold in bytes of minimum -available storage required in order to perform builds. - -`CondaStore.database_url` is the url string for connecting to the -database. Behind the scenes [SQLAlchemy](https://www.sqlalchemy.org/) -is used for the connection so [consult their -docs](https://docs.sqlalchemy.org/en/14/core/engines.html) for -connecting to your specific database. conda-store will automatically -create the tables if they do not already exist. - -`CondaStore.redis_url` is an optional argument to a running Redis -instance. This was removed as a dependency as of release `0.4.10` due -to the need to have a simple deployment option for conda-store. See -[documentation](https://github.com/redis/redis-py/#connecting-to-redis) -for proper specification. This url is used by default for the Celery -broker and results backend. - -`CondaStore.celery_broker_url` is the broker use to use for -celery. Celery supports a [wide range of -brokers](https://docs.celeryproject.org/en/stable/getting-started/backends-and-brokers/index.html) -each with different guarantees. By default the Redis based broker is -used if a `CondaStore.redis_url` if provided otherwise defaults to -sqlalchemy. It is production ready and has worked well in -practice. The url must be provided in a format that celery -understands. The default value is `CondaStore.redis_url`. - -`CondaStore.build_artifacts` is the list of artifacts for conda-store -to build. By default it is all the artifacts that conda-store is -capable of building. These are the -[lockfile](https://github.com/conda-incubator/conda-lock), -[YAML](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#create-env-file-manually), -[Conda-Pack](https://conda.github.io/conda-pack/), and -[Docker](https://github.com/conda-incubator/conda-docker). Currently -the `lockfile` one is ignored since it is always created upon build. - -`CondaStore.build_artifacts_kept_on_deletion` is a list of artifacts -to keep after a given build is deleted. Often an administrator will -want to keep around the logs etc. of a build and the Conda solve for -the given build. - -`CondaStore.celery_results_backend` is the backend to use for storing -all results from celery task execution. conda-store currently does not -leverage the backend results but it may be needed for future work -using celery. The backend defaults to using the Redis backend if -`CondaStore.redis_url` is specified otherwise uses the -`CondaStore.database_url`. This choice works great in -production. Please consult the [celery docs on -backend](https://docs.celeryproject.org/en/stable/getting-started/backends-and-brokers/index.html). - -`CondaStore.default_namespace` is the default namespace for -conda-store to use. All environments are built behind a given -namespace. - -`CondaStore.filesystem_namespace` is the namespace to use for -environments picked up via `CondaStoreWorker.watch_paths` on the -filesystem. - -`CondaStore.default_uid` is the uid (user id) to assign to all -files and directories in a given built environment. This setting is -useful if you want to protect environments from modification from -certain users and groups. Note: this configuration option is not -supported on Windows. - -`CondaStore.default_gid` is the gid (group id) to assign to all -files and directories in a given built environment. This setting is -useful if you want to protect environments from modification from -certain users and groups. Note: this configuration option is not -supported on Windows. - -`CondaStore.default_permissions` is the filesystem permissions to -assign to all files and directories in a given built environment. This -setting is useful if you want to protect environments from -modification from certain users and groups. Note: this configuration -option is not supported on Windows. - -`CondaStore.default_docker_base_image` default base image used for the -Dockerized environments. Make sure to have a proper glibc within image -(highly discourage alpine/musl based images). Can also be callable -function which takes the `orm.Build` object as input which has access -to all attributes about the build such as installed packages, requested -packages, name, namespace, etc. This package at a minimum should have -the [following packages -installed](https://docs.anaconda.com/anaconda/install/linux/). Often -times for non-graphic and non-gpu environments glibc is enough. Hence -the default docker image `library/debian:sid-slim`. - -`CondaStore.serialize_builds` DEPRECATED no longer has any effect - -`CondaStore.post_update_environment_build_hook` is an optional configurable to -allow for custom behavior that will run after an environment's current build changes. - -### `conda_store_server.storage.S3Storage` - -conda-store uses [minio-py](https://github.com/minio/minio-py) as a -client to connect to S3 "like" object stores. - -`S3Storage.internal_endpoint` is the internal endpoint for conda-store -reaching out to s3 bucket. This is the url that conda-store use for -get/set s3 blobs. For AWS S3 use the endpoint `s3.amazonaws.com`. - -`S3Storage.external_endpoint` is the external s3 endpoint for users to -reach out to in the presigned url. This is the url that users use -for fetching s3 blobs. For AWS S3 use the endpoint `s3.amazonaws.com`. - -`S3Storage.access_key` is the access key for S3 bucket. - -`S3Storage.secret_key` is the secret key for S3 bucket. - -`S3Storage.region` is the region to use for connecting to the S3 -bucket. The default is `us-east-1`. - -`S3Storage.bucket_name` is the bucket name to use for connecting to -the S3 bucket. - -`S3Storage.internal_secure` Boolean to indicate if connecting via -`http` (False) or `https` (True) internally. The internal connection -is the url that will be exclusively used by conda-store and not shared -with users. - -`S3Storage.external_secure` Boolean to indicate if connecting via -`http` (False) or `https` (True) internally. The external connection -is the url that will be served to users of conda-store. - -`S3Storage.credentials` provider to use to get credentials for s3 -access. see examples -https://github.com/minio/minio-py/tree/master/examples and -documentation -https://github.com/minio/minio-py/blob/master/docs/API.md#1-constructor. An -example of this could be to use `minio.credentials.IamAwsProvider` to -get S3 credentials via IAM. - -`S3Storage.credentials_args` arguments to pass for creation of -credentials class. - -`S3Storage.credentials_kwargs` keyword arguments to pass for creation -of credentials class. - -### `conda_store_server.storage.LocalStorage` - -`LocalStorage.storage_path` is the base directory to use for storing -build artifacts. - -`LocalStorage.storage_url` is the base url for serving of build -artifacts. This url assumes that the base will be a static server -serving `LocalStorage.storage_path`. - -### `conda_store_server.server.auth.AuthenticationBackend` - -`AuthenticationBackend.secret` is the symmetric secret to use for -encrypting tokens. - -`AuthenticationBackend.jwt_algorithm` is the algorithm for encrypting -the JSON Web Tokens. - -`AuthenticationBackend.predefined_tokens` is a set of tokens with -predefined permission. This is useful for setting up service accounts -in a similar manner to how things are done with jupyterhub. Format for -the values is a dictionary with keys being the tokens and values being -the `schema.AuthenticaitonToken` all fields are optional. - -### `conda_store_server.server.auth.AuthorizationBackend` - -`AuthorizationBackend.role_mappings` is a dictionary that maps `roles` -to application `permissions`. There are three default roles at the -moment `viewer`, `developer`, and `admin`. - -`AuthorizationBackend.unauthenticated_role_bindings` are the role -bindings that an unauthenticated user assumes. - -`AuthorizationBackend.authenticated_role_bindings` are the base role -bindings that an authenticated user assumes. - -### `conda_store_server.server.auth.Authentication` - -`Authentication.cookie_name` is the name for the browser cookie used -to authenticate users. - -`Authentication.cookie_domain` use when wanting to set a subdomain wide cookie. For example setting this to `example.com` would allow the cookie to be valid for `example.com` along with `*.example.com`. - -`Authentication.authentication_backend` is the class to use for -authentication logic. The default is `AuthenticationBackend` and will -likely not need to change. - -`Authentication.authorization_backend` is the class to use for -authentication logic. The default is `AuthorizationBackend` and will -likely not need to change. - -`Authentication.login_html` is the HTML to display for a given user as -the login form. - -### `conda_store_server.server.auth.DummyAuthentication` - -Has all the configuration settings of `Authetication`. This class is -modeled after the [JupyterHub DummyAuthentication -class](https://github.com/jupyterhub/jupyterhub/blob/9f3663769e96d2e4f665fd6ef485c101704c4645/jupyterhub/auth.py#L1142). - -`DummyAuthentication.password` sets a global password for all users to -login with. Effectively a static password. This rarely if ever should -be used outside of testing. - -### `conda_store_server.server.auth.GenericOAuthAuthentication` - -A provider-agnostic OAuth authentication provider. Configure -endpoints, secrets and other parameters to enable any OAuth-compatible -platform. This class is modeled after the [OAuthenticator OAuth2 -classes](https://github.com/jupyterhub/oauthenticator). All -configuration settings of `Authentication` are available. - -`GenericOAuthAuthentication.access_token_url` is the URL used to -request an access token once app has been authorized. - -`GenericOAuthAuthentication.authorizie_url` is the URL used to request -authorization to OAuth provider. - -`GenericOAuthAuthentication.client_id` is the unique string that -identifies the app against the OAuth provider. - -`GenericOAuthAuthentication.client_secret` is the secret string used -to authenticate the app against the OAuth provider. - -`GenericOauthAuthentication.access_scope` is the permissions that will -be requested to OAuth2 provider. This is space separated list of -scopes. Generally only one scope is requested. - -`GenericOauthAuthentication.user_data_url` is the API endpoint for -OAuth provider that returns a JSON dict with user data after the user -has successfully authenticated. - -`GenericOauthAuthentication.user_data_key` is the key in the payload -returned by `user_data_url` endpoint that provides the `username`. - -`GenericOAuthAuthentication.oauth_callback_url` custom callback url -especially useful when web service is behind a proxy. - -`GenericOAuthAuthentication.tls_verify` to optionally turn of TLS -verification useful for custom signed certificates. - -### `conda_store_server.server.auth.GithubOAuthAuthentication` - -Inherits from `Authentication` and `GenericOAuthAuthentication` so -should be fully configurable from those options. - -`GithubOAuthAuthentication.github_url` is the url for GitHub. Default -is `https://github.com`. - -`GithubOAuthAuthentication.github_api` is the REST API url for -GitHub. Default is `https://api.github.com`. - -### `conda_store_server.server.auth.JupyterHubOAuthAuthentication` - -Inherits from `Authentication` and `GenericOAuthAuthentication` so -should be fully configurable from those options. - -`GithubOAuthAuthentication.jupyterhub_url` is the url for connecting -to JupyterHub. The URL should not include the `/hub/`. - -### `conda_store_server.server.auth.RBACAuthorizationBackend` - -`RBACAuthorizationBackend.role_mappings_version` specifies the role mappings -version to use: 1 (default, legacy), 2 (new, recommended). - -This option can be set via the config as follows: - -```python -c.RBACAuthorizationBackend.role_mappings_version = -``` - -When an invalid version is specified, an error message will be printed to the -terminal when attempting to log in: - -``` -c.RBACAuthorizationBackend.role_mappings_version: invalid role mappings version: , expected: (1, 2) -``` - -The role mappings version determines which database table is used when a call to -`RBACAuthorizationBackend.authorize` is made in one of the HTTP route handlers. - -For authorization to work properly, clients must use a set of HTTP APIs matching -the selected role mappings version. - -Role mappings version 2 is the recommended version to use. It relies on the -following HTTP APIs to update namespace metadata and set the roles: - -``` -PUT /api/v1/namespace/{namespace}/metadata -GET /api/v1/namespace/{namespace}/roles -DELETE /api/v1/namespace/{namespace}/roles -GET /api/v1/namespace/{namespace}/role -POST /api/v1/namespace/{namespace}/role -PUT /api/v1/namespace/{namespace}/role -DELETE /api/v1/namespace/{namespace}/role -``` - -Role mappings version 1 is a legacy version that exists for compatibility -reasons and is not recommended. It uses this API endpoint to update namespace -metadata and set the roles: - -``` -PUT /api/v1/namespace/{namespace}/ -``` - -### `conda_store_server.server.app.CondaStoreServer` - -`CondaStoreServer.log_level` is the level for all server -logging. Default is `INFO`. Common options are `DEBUG`, `INFO`, -`WARNING`, and `ERROR`. - -`CondaStoreServer.enable_ui` a Boolean on whether to expose the UI -endpoints. Default True. - -`CondaStoreServer.enable_api` a Boolean on whether to expose the API -endpoints. Default True. - -`CondaStoreServer.enable_registry` a Boolean on whether to expose the -registry endpoints. Default True. - -`CondaStoreServer.enable_metrics` a Boolean on whether to expose the -metrics endpoints. Default True. - -`CondaStoreServer.address` is the address for the server to bind -to. The default is all IP addresses `0.0.0.0`. - -`CondaStoreServer.port` is the port for conda-store server to -use. Default is `8080`. - -`CondaStoreServer.registry_external_url` is the external hostname and -port to access docker registry cannot contain `http://` or `https://`. - -`CondaStoreServer.url_prefix` is the prefix URL (subdirectory) for the -entire application. All but the registry routes obey this. This is due -to the docker registry API specification not supporting url prefixes. - -`CondaStoreServer.authentication_class` is the authentication class -for the web server to use. Default is `DummyAuthentication`. - -`CondaStoreServer.secret_key` is a secret key needed for some -authentication methods, session storage, etc. TODO: remove at some -point since also used in `AuthenticationBackend`. - -`CondaStoreServer.max_page_size` is maximum number of items to return -in a single UI page or API response. - -`CondaStoreServer.behind_proxy` indicates if server is behind web -reverse proxy such as Nginx, Traefik, Apache. Will use -`X-Forward-...` headers to determine scheme. Do not set to true if not -behind proxy since Flask will trust any `X-Forward-...` header. - -`CondaStoreServer.template` initialized -`fastapi.templating.Jinja2Templates` to use for html templates. - -`CondaStoreServer.template_vars` extra variables to be passed into -jinja templates for page rendering. - -`CondaStoreServer.additional_routes` additional routes for conda-store -to serve in form `[(path, method, function), ...]`. `path` is a -string, `method` is `get`, `post`, `put`, `delete` etc. and function -is a regular python fastapi function. - -### `conda_store_server.worker.app.CondaStoreWorker` - -`CondaStoreWorker.log_level` is the level for all server -logging. Default is `INFO`. Common options are `DEBUG`, `INFO`, -`WARNING`, and `ERROR`. - -`CondaStoreWorker.watch_paths` is a list of paths for conda-store to -watch for changes to directories of `environment.yaml` files or a -single filename to watch. - -`CondaStoreWorker.concurrency` by default is not set and defaults to -the number of threads on your given machine. If set will limit the -number of concurrent celery tasks to the integer. - -### `conda_store_server.registry.ContainerRegistry` - -`ContainerRegistry.container_registries` dictionary of registries_url -to upload built container images with callable function to configure -registry instance with credentials. Example configuration shown -bellow. Some registries are more complex to setup such as ECR, GCR, -etc. `password` is often the token generated from the AWS, GCP, Azure, -and Digital Ocean clients. - -```python -from python_docker.registry import Registry -import os - -def _configure_docker_registry(registry_url: str): - return Registry( - "https://registry-1.docker.io", - username=os.environ.get('DOCKER_USERNAME'), - password=os.environ.get('DOCKER_PASSWORD')) - -c.ContainerRegistry.container_registries = { - 'https://registry-1.docker.io': _configure_docker_registry -} -``` - -`ContainerRegistry.container_registry_image_name` image name -to assign to docker image pushed for particular registry via a -callable function with arguments of registry and build. - -`ContainerRegistry.container_registry_image_tag` image tag -to assign to docker image pushed for particular registry via a -callable function with arguments of registry and build. - -## Frequently Asked Questions - -### conda-store fails to build Conda environment and worker is spontaneously killed (9 SIGKILL) - -The following error most likely indicates that you have not allocated -enough memory to `conda-store-workers` for solving and building the -given environment. Solve this by increasing the memory allocated to -the container. - -```shell -Process 'ForkPoolWorker-31' pid:90 exited with 'signal 9 (SIGKILL)' - -Task handler raised error: WorkerLostError('Worker exited prematurely: signal 9 (SIGKILL) Job: 348.') - -Traceback (most recent call last): -File "/opt/conda/envs/conda-store-server/lib/python3.9/site-packages/billiard/pool.py", line 1265, in mark_as_worker_lost - - raise WorkerLostError( - -billiard.exceptions.WorkerLostError: Worker exited prematurely: signal 9 (SIGKILL) Job: 348. -``` - -### Why are environment builds stuck in building state? - -Recently conda-store added a feature to cleanup builds which are stuck -in the BUILDING state and are not currently running on the -workers. This feature only works for certain brokers -e.g. redis. Database celery brokers are not supported. - -This issue occurs when the worker spontaneously dies. This can happen -for several reasons: - -- worker is killed due to consuming too much memory (conda solver/builds can consume a lot of memory) -- worker was killed for other reasons e.g. forced restart -- bugs in conda-store - -### Build path length - -Conda packages are guaranteed to be [relocatable] as long as the environment -prefix length is <= 255 characters. In conda-store, the said prefix is specified -in `Build.build_path`. When building an environment, you might see an error like -this: - -``` -build_path too long: must be <= 255 characters -``` - -If so, try configuring the conda-store `CondaStore.store_directory` to be as -close to the filesystem root as possible. Additionally, 255 characters is also a -common limit for individual files on many filesystems. When creating -environments, try using shorter `namespace` and `environment` names since they -affect both the `build_path` length and the filename length. - -[relocatable]: https://docs.conda.io/projects/conda-build/en/latest/resources/make-relocatable.html - -### Build key versions - -The part of the build path that identifies a particular environment build is the -build key. Originally, conda-store used the following format, known as version -1: - -``` -c7afdeffbe2bda7d16ca69beecc8bebeb29280a95d4f3ed92849e4047710923b-20231105-035410-510258-12345678-this-is-a-long-environment-name -^ (1) ^ (2) ^ (3) ^ (4) -``` - -It consists of: -1. a SHA-256 hash of the environment specification - (`CondaSpecification`, which represents a user-provided environment, is - converted to a dict and passed to `datastructure_hash`, which recursively sorts - it and calculates the SHA-256 hash) -2. a human-readable timestamp (year, month, day, `-`, hour, minute, second, `-`, microsecond) -3. the id of a build -4. the environment name. - -To help mitigate build path length issues, a shorter build key format was -introduced, known as version 2: - -``` -c7afdeff-1699156450-12345678-this-is-a-long-environment-name -^ (1) ^ (2) ^ (3) ^ (4) -``` - -It consists of: -1. a truncated SHA-256 hash of the environment specification - (`CondaSpecification`, which represents a user-provided environment, is - converted to a dict and passed to `datastructure_hash`, which recursively sorts - it and calculates the SHA-256 hash) -2. a Unix timestamp -3. the id of a build -4. the environment name. - -The version 2 format is now the default. Environments created using the version -1 format will continue to be accessible in the UI, but new builds will use the -version 2 format. No changes are needed for existing deployments of conda-store. - -There is no real reason to use the version 1 format anymore, but it can be -explicitly set via the config: - -``` -c.CondaStore.build_key_version = 1 -``` - -The version 2 format can also be explicitly set if needed (this is the same as -the default): - -``` -c.CondaStore.build_key_version = 2 -``` - -### Long paths on Windows - -conda-store supports Windows in standalone mode. However, when creating -environments with certain packages, you may see errors like - -``` -ERROR:root:[WinError 206] The filename or extension is too long: 'C:\\...' -``` - -This error is due to the fact that Windows has a limitation that file paths -cannot be more than 260 characters. The fix is to set the registry key -`Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled -(Type: REG_DWORD)` to `1`, which removes this MAX_PATH limitation. See [this -Microsoft support -article](https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation) -for more details on how to set this registry key. - -If it is not possible to set this registry key, for instance, because you do -not have access to administrator privileges, you should configure the -conda-store `CondaStore.store_directory` to be as close to the filesystem root -as possible, so that the total length of the paths of package files is -minimized. - -See [conda-store issue -#588](https://github.com/conda-incubator/conda-store/issues/588) for more -details. diff --git a/docs/api.md b/docs/api.md deleted file mode 100644 index fe5789d3b..000000000 --- a/docs/api.md +++ /dev/null @@ -1,27 +0,0 @@ -# REST API - -Below is an interactive view of conda-store's OpenAPI specification. - - - - - - - - -
    - - diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 20b579053..000000000 --- a/docs/conf.py +++ /dev/null @@ -1,40 +0,0 @@ -project = 'conda-store' -copyright = '2022, Quansight' -author = 'Quansight' -release = '0.4.15' - -extensions = [ - 'myst_parser', - 'sphinx_panels', - 'sphinx_copybutton' -] - -templates_path = ['_templates'] -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -html_theme = "pydata_sphinx_theme" -html_static_path = ['_static'] -html_css_files = ['css/custom.css'] -html_logo = "_static/images/conda-store-logo-symbol.svg" -html_favicon = '_static/images/favicon.ico' -html_theme_options = { - "logo": { - "text": "conda-store", - }, - "show_prev_next": True, - "icon_links": [ - { - "name": "GitHub", - "url": "https://github.com/conda-incubator/conda-store", - "icon": "fa-brands fa-github", - } - ], -} -html_sidebars = { - "**": [], -} - -# MyST-parser configurations - -myst_heading_anchors = 3 -myst_enable_extensions = ["colon_fence"] diff --git a/docs/contributing.md b/docs/contributing.md deleted file mode 100644 index 72c332509..000000000 --- a/docs/contributing.md +++ /dev/null @@ -1,650 +0,0 @@ -# Contributing - -## Naming - -When refering to `conda-store` it should always be written all -lowercase with a dash in between. `conda-store` should also be -lowercase when beginning a sentence. - -## Development - -Significant effort has been put into simplifying the development and -deployment process of `conda-store`. There is a docker based -development workflow along with a non-containerized workflow if you -are using Linux. - -### Containerized development - -Install the following dependencies before developing on conda-store. - -- [docker](https://docs.docker.com/engine/install/) -- [docker-compose](https://docs.docker.com/compose/install/) - -To deploy `conda-store` run the following command - -```shell -docker-compose up --build -d -``` - -:::{important} -Many of the conda-store docker images are built/tested for amd64(x86-64) -there will be a performance impact when building and running on -arm architectures. Otherwise this workflow has been shown to run and build on OSX. -Notice the `architecture: amd64` whithin the docker-compose.yaml files. -::: - -The following resources will be available: - -- conda-store web server running at [http://localhost:8080](http://localhost:8080) -- [MinIO](https://min.io/) s3 running at [http://localhost:9000](http://localhost:9000) with username `admin` and password `password` -- [PostgreSQL](https://www.postgresql.org/) running at [localhost:5432](http://localhost:5432) with username `admin` and password `password` database `conda-store` -- [Redis](https://www.redis.com/) running at [localhost:6379](http://localhost:6379) with password `password` -- [JupyterHub](https://jupyter.org/hub) running at [http://localhost:8000](http://localhost:8000) with any username and password `test` - -On a fast machine this deployment should only take 10 or so seconds -assuming the docker images have been partially built before. If you -are making and changes to conda-store-server and would like to see -those changes in the deployment. Run. - -```shell -docker-compose down -v # not always necessary -docker-compose up --build -``` - -### Linux development - -Install the following dependencies before developing on conda-store. - -- [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/linux.html) - -Install the development dependencies and activate the environment. - -```shell -# replace this with environment-macos-dev.yaml or environment-windows-dev.yaml -# if you are on Mac or Windows -conda env create -f conda-store-server/environment-dev.yaml -conda activate conda-store-server-dev -``` - -Running `conda-store`. `--standalone` mode launched celery as a -subprocess of the web server. Run - -``` -python -m conda_store_server.server --standalone -``` - -Then visit [localhost:8080](http://localhost:8080/). - -### Changes to API - -The REST API is considered somewhat stable. If any changes are made to -the API make sure the update the OpenAPI/Swagger specification in -`docs/_static/openapi.json`. This may be downloaded from the `/docs` -endpoint when running conda-store. Ensure that the -`c.CondaStoreServer.url_prefix` is set to `/` when generating the -endpoints. - -## Documentation - -Install the following dependencies before contributing to the -documentation. - - - [Conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/) - -To build the documentation install the development environment via -Conda. - -```shell -# replace this with environment-macos-dev.yaml or environment-windows-dev.yaml -# if you are on Mac or Windows -conda env create -f conda-store-server/environment-dev.yaml -conda activate conda-store-server-dev -```` - -Then go in the documentation directory `docs` and build the -documentation. - -```shell -cd docs -sphinx-build -b html . _build -``` - -Then open the documentation via your favorite web browser. - -```shell -firefox _build/index.html -``` - -The documentation has been primarily written in markdown as to make it -easier to contribute to the documentation. - -### Testing - -The `conda-store` repository is two packages. - -- `conda-store-server/` which is the worker + web server responsible for the `conda-store` service -- `conda-store/` is the client which interacts with the service - -#### conda-store - -Linting and formatting checks can be performed via hatch. - -```shell -$ cd conda-store -$ hatch env run -e dev lint -``` - -Running integration tests. These tests are stateful! So you will need -to clear the state if you have run the conda-store-server service on -docker. - -```shell -$ cd conda-store -$ docker-compose down -v # ensure you've cleared state -$ docker-compose up --build -# wait until the conda-store-server is running check by visiting localhost:8080 - -$ pip install -e . -$ ./tests/unauthenticated-tests.sh -$ ./tests/authenticated-tests.sh -$ export CONDA_STORE_URL=http://localhost:8080/conda-store -$ export CONDA_STORE_AUTH=basic -$ export CONDA_STORE_USERNAME=username -$ export CONDA_STORE_PASSWORD=password -$ ./tests/shebang.sh -``` - -#### conda-store-server - -Linting and formatting checks can be performed via hatch. - -```shell -$ cd conda-store-server -$ hatch env run -e dev lint -``` - -Checking that package builds - -```shell -$ cd conda-store-server -$ hatch build -``` - -Running unit tests - -```shell -$ cd conda-store-server -$ pytest -``` - -Running integration tests. These tests are stateful! So you will need -to clear the state if you have run the conda-store-server service on -docker. - -```shell -$ cd conda-store-server -$ docker-compose down -v # ensure you've cleared state -$ docker-compose up --build -# wait until the conda-store-server is running check by visiting localhos:8080 -$ hatch env run -e dev playwright-test -$ hatch env run -e dev integration-test -``` - -## Release process - -Choose the `` number. It should follow [Semantic -Versioning](https://semver.org/) and the established pattern of -`v..`. - -Ensure that [`CHANGELOG.md`](https://github.com/conda-incubator/conda-store/blob/main/CHANGELOG.md) is up-to-date with all the changes since -the last release following the template provided within the markdown -file. - -All docker images within `docker/kubernetes` should be updated to the -release version. `spec.template.spec.containers[0].image` is the path -within the YAML files. - -Update the version number in `conda-store-server/conda_store_server/__init__.py` and -`conda-store/conda_store/__init__.py` to reflect the release version. - -Once those changes have been made make a commit titled `bump to -version `. - -Finally create a [new release within the GitHub -interface](https://github.com/conda-incubator/conda-store/releases/new). Do -this instead of a git TAG since you can include release notes on the -repository. The Release should be titled `Release - -//` with the description being the changelog -markdown for the particular release. - -Once you have create a release the GitHub actions with the build the -release and make it available on [PyPi](https://pypi.org/), -[Conda](https://anaconda.org/), and -[DockerHub](https://hub.docker.com/). - -After the PyPi release a release on -[Conda-Forge](https://conda-forge.org/) and it located at -[conda-forge/conda-store-feedstock](https://github.com/conda-forge/conda-store-feedstock). A -PR must be created that updates to the released version -``. - -conda-store has two PyPi packages `conda-store-server` and `conda-store`. - -- update `recipies/meta.yaml` with the new version `{% set version = "" %}` -- update `recipies/meta.yaml` with the appropriate sha256 for each - package. The sha256 can be found at - `https://pypi.org/project/conda-store/#files` by clicking the - `view` button. - -Once the PR has been created ensure that you request a `rerender` of -the feedstock with the following comment `@conda-forge-admin please -rerender`. An example of this can be found in [PR -#2](https://github.com/conda-forge/conda-store-feedstock/pull/2) - -## Architecture - -conda-store was designed with the idea of scalable enterprise -management of reproducible Conda environments. - -![conda-store architecture diagram](_static/images/conda-store-architecture.png) - -### Configuration - -[Traitlets](https://traitlets.readthedocs.io/en/stable/) is used for -all configuration of conda-store. In the beginning command line -options were used but eventually we learned that there were too many -options for the user. Traitlets provides a python configuration file -that you can use to configure values of the applications. It is used -for both the server and worker. See -[`tests/assets/conda_store_config.py`](https://github.com/conda-incubator/conda-store/blob/main/tests/assets/conda_store_config.py) -for a full example. - -### Workers and server - -conda-store can be broken into two components. The workers which have -the following responsibilities: - -- build Conda environments from Conda `environment.yaml` specifications -- build Conda pack archives -- build Conda docker images -- remove Conda builds -- modify symlinks to point current environment to given build -- generally any tasks that can take an unbounded amount of time - -All of the worker logic is in `conda_store_server/build.py` and -`conda_store_server/worker/*.py`. Celery is used for managing tasks so -you will see the celery tasks defined in -`conda_store_server/worker/tasks.py` which in turn usually call built -in `CondaStore` functions in `conda_store_server/app.py` or -`conda_store_server/build.py`. - -The web server has several responsibilities: - -- serve a UI for interacting with Conda environments -- serve a REST API for managing Conda environments -- serve a programmatic Docker registry for interesting docker-conda abilities - -The web server is based on -[FastAPI](https://fastapi.tiangolo.com/). Originally Flask was chosen -due to it being battle tested and that conda-store is not doing any -special things with the web server. However, over time the ability for -robust input and output guarantees from the endpoints along with auto -documentation made FastAPI appealing. The backend web app is defined -in `conda_store_server.server.app`. There are several components to -the server: - -- UI :: `conda_store_server/server/views/ui.py` -- REST API :: `conda_store_server/server/views/api.py` -- registry :: `conda_store_server/server/views/registry.py` - -Both the worker and server need a connection to a SQLAchemy compatible -database, Redis, and S3 compatible object storage. The S3 server is -used to store all build artifacts for example logs, docker layers, and -the [Conda-Pack](https://conda.github.io/conda-pack/) tarball. The -PostgreSQL database is used for storing all states on environments and -builds along with powering the conda-store web server UI, REST API, -and Docker registry. Redis is used for keeping track of task state and -results along with enabling locks and realtime streaming of logs. - -### Terminology - -![conda-store terminology](_static/images/conda-store-terminology.png) - -`conda_environment = f(open("environment.yaml"), datatime.utcnow())` - -- namespace :: a way of providing scopes between environments. This - prevents Joe's environment named `data-science` from colliding from - Alice's environment name `data-science`. -- environment :: a pointer to a current build of a given specification -- specification :: a [Conda environment.yaml file](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#create-env-file-manually) -- build :: a attempt of `conda env install -f environment.yaml` at a - given point in time - -In order to understand why we have the complicated terminology for an -environment it helps to understand how Conda builds a given -environment. - -### Reproducibility of Conda - -```yaml -name: example -channels: - - defaults - - conda-forge -dependencies: - - python >=3.7 -``` - -Suppose we have the given `environment.yaml` file. How does Conda -perform a build? - -1. Conda downloads `channeldata.json` from each of the channels which - list the available architectures. - -2. Conda then downloads `repodata.json` for each of the architectures - it is interested in (specifically your compute architecture along - with noarch). The `repodata.json` has fields like package name, - version, and dependencies. - -You may notice that the channels listed above do not have a url. This -is because in general you can add -`https://conda.anaconda.org/` to a non-url channel. - -3. Conda then performs a solve to determine the exact version and - sha256 of each package that it will download - -4. The specific packages are downloaded - -5. Conda does magic to fix the path prefixes of the install - -There are two spots that introduce issues to reproducibility. The -first issue is tracking when an `environment.yaml` file has -changes. This can be easily tracked by taking a sha256 of the file -. This is what conda-store does but sorts the dependencies to make -sure it has a way of not triggering a rebuild if the order of two -packages changes in the dependencies list. In step (2) `repodata.json` -is updated regularly. When Conda solves for a user's environment it -tries to use the latest version of each package. Since `repodata.json` -could be updated the next minute the same solve for the same -`environment.yaml` file can result in different solves. - -### Authentication Model - -Authentication was modeled after JupyterHub for implementation. There -is a base class `conda_store_server.server.auth.Authenticaiton`. If -you are extending and using a form of OAuth2 use the -`conda_store_server.server.auth.GenericOAuthAuthentication`. Similar -to JupyterHub all configuration is modified via -[Traitlets](https://traitlets.readthedocs.io/en/stable/). Below shows -an example of setting us OAuth2 via JupyterHub for conda-store. - -```python -c.CondaStoreServer.authentication_class = JupyterHubOAuthAuthentication -c.JupyterHubOAuthAuthentication.jupyterhub_url = "http://jupyterhub:8000" -c.JupyterHubOAuthAuthentication.client_id = "service-this-is-a-jupyterhub-client" -c.JupyterHubOAuthAuthentication.client_secret = "this-is-a-jupyterhub-secret" -``` - -Once a user is authenticated a cookie or [JSON Web -Token](https://jwt.io/) is created to store the user credentials to -ensure that conda-store is as stateless as possible. At this current -point in time conda-store does not differentiate between a service and -user. Similar to JupyterHub -`conda_store_server.server.auth.Authentication` has an `authenticate` -method. This method is the primary way to customize authentication. It -is responsible for checking that the user credentials to login are -correct as well as returning a dictionary following the schema -`conda_store_server.schema.AuthenticationToken`. This stores a -`primary_namespace` for a given authenticated service or user. In -addition a dictionary of `/` map to a set of -roles. See the Authorization model to better understand the key to set -of roles meaning. - -### Authorization Model - -conda-store implements role based authorization to supports a flexible -authorization model. A user or service is either authenticated or -not. There are a set of default permissions assigned to authenticated -and unauthenticated users via Traitlets. These can all be modified in -the configuration. These roles are inherited based on the -authentication status of the user or service. To support hierarchies -we map a key such as `default/*` to a set of roles. The `/` separates -the `` from the `` and `*` signifies match any (zero -or more) characters. This was chosen to support rich authorization -models while also being easy and efficient to implement in a -database. `*` are supported anywhere in the `key` such as -`*n*viron*/n*me`. Configure the following Traitlets to modify the -inherited permissions for authenticated and unauthenticated users. - -```python -c.RBACAuthorizationBackend.unauthenticated_role_bindings = { - "default/*": {"viewer"}, -} - -c.RBACAuthorizationBackend.authenticated_role_bindings = { - "default/*": {"viewer"}, - "filesystem/*": {"viewer"}, -} -``` - -Once we have collected the role mappings that a given user has we then -map `roles` to sets of permissions. Currently there are only a few -permissions but conda-store is capable of adapting in the future. - -```python -class Permissions(enum.Enum): - ENVIRONMENT_CREATE = "build::create" - ENVIRONMENT_READ = "build::read" - ENVIRONMENT_UPDATE = "build::update" - ENVIRONMENT_DELETE = "build::delete" -``` - -The role name to permission is configured via a single trait shown -below `c.RBACAuthorizationBackend.role_mappings`. - -```python -c.RBACAuthorizationBackend.role_mappings = { - "viewer": { - Permissions.ENVIRONMENT_READ - }, - "developer": { - Permissions.ENVIRONMENT_CREATE, - Permissions.ENVIRONMENT_READ, - Permissions.ENVIRONMENT_UPDATE, - }, - "admin": { - Permissions.ENVIRONMENT_CREATE, - Permissions.ENVIRONMENT_READ, - Permissions.ENVIRONMENT_UPDATE, - Permissions.ENVIRONMENT_DELETE, - }, -} -``` - -Lets go through a few examples to make this more concrete and assume -the default configuration of conda-store. - -> Suppose we have an unauthenticated user trying to view the -> environment `quansight/datascience`. - -First since the user is unauthenticated they inherit the default role -mappings. - -```python -{ - "default/*": {"viewer"}, -} -``` - -We go through each role mapping and try to match the expression -`default/*` to `quansight/datascience`. In this case this does not -match and thus for the given environment `quansight/datascience` the -unauthenticated user has no roles. This user does not have any roles -for the given environment but if they did we would iterate through all -roles and combine the permissions. The next example will show this. So -for this example the user has permissions `{}` in the given -environment. The action of viewing a given environment requires -`build::read` which the unauthenticated user does not have. - -> Suppose we have an unauthenticated user trying to delete the -> environment `default/web-dev`. - -First since the user is unauthenticated they inherit the default role -mappings. - -``` -{ - "default/*": {"viewer"}, -} -``` - -We go through each role mapping and try to match the expression -`default/*` to `default/web-dev`. In this case this does match and -thus for the given environment `default/web-dev` the unauthenticated -user has a set of roles `{viewer}`. For each role we map the role to -permissions. We get `{build::read}`. The delete environment action -requires `build::delete` permissions and thus the user is not -authenticated to perform the action. - -> Suppose we have an authenticated user trying to delete the -> environment `default/web-dev`. - -First since the user is authenticated they inherit the default role -mappings. - -```python -{ - "default/*": {"viewer"}, - "filesystem/*": {"viewer"}, -} -``` - -In addition to the default role bindings the user was authenticated -via the `authenticate` method and has the following bindings added. - -```python -{ - "*/*": {"admin"} -} -``` - -In total the user has the following bindings. - -```python -{ - "default/*": {"viewer"}, - "filesystem/*": {"viewer"}, - "*/*": {"admin"}, -} -``` - -Following the same process as before we iterate through each binding -if it matches we add the given roles. For this example we get -`{viewer, admin}`. Next we iterate through each role and map it to -permissions and we get the following `{build::create, build::read, -build::update, build::delete}`. The delete environment action requires -`build::delete` permissions which the user has thus the action is -permitted. - -## Database - -### Model - -At a high level the database model can be described in the image -bellow. - -![high level diagram](_static/images/conda-store-database-architecture.png) - -Important things to note about the relationship: - -- An `environment` exists within a given `namespace` and always has a current `build` -- A `build` belongs to a particular `environment` and has associated `condapackage` and `buildartfacts` -- A `buildartifact` is a way for the database to keep track of - external resources for example s3 artifacts, filesystem directories, - etc -- A `condapackage` is a representation of a given Conda package which belongs to a given `condachannel` -- A `specification` is the environment.yaml using in `conda env create -f ` - -The following will generate the database model shown bellow. It was -generated from the `examples/docker` example. You'll see in the -command that we are excluding several tables. These tables are managed -by [celery](https://docs.celeryproject.org/en/stable/). - -```shell -pip install eralchemy # not available on conda-forge -eralchemy -i "postgresql+psycopg2://admin:password@localhost:5432/conda-store" \ - -x celery_tasksetmeta celery_taskmeta kombu_queue kombu_message alembic_version \ - -o output.png -``` - -![entity relationship diagram](_static/images/conda-store-entity-relationship-diagram.png) - -### Migrations - -conda-store relies on [SQLAlchemy](https://www.sqlalchemy.org/) for ORM mapping, and on [Alembic](https://alembic.sqlalchemy.org/en/latest/) for DB migrations. - -The procedure to modify the database is the following : - -- First, modify [the ORM Model](https://github.com/conda-incubator/conda-store/blob/main/conda-store-server/conda_store_server/orm.py) according to the changes you want to make -- edit the file `conda-store-server/alembic.ini` and replace the value for entry `sqlalchemy.url` to match the connection URL of your database. - -For example (when postgres was started via docker-compose): -``` -script_location = alembic -sqlalchemy.url = postgresql+psycopg2://postgres:password@localhost:5432/conda-store -``` - -- in your command line, run the following : - -```sh -cd conda-store-server/conda_store_server -alembic revision --autogenerate -m "description of your changes" -``` - -- You should have a new file in `conda-store-server/conda_store_server/alembic/versions/` . **Review it thoroughly**. It contains the [`alembic` operations](https://alembic.sqlalchemy.org/en/latest/ops.html) (`op`) to actually modify the database, either when upgrading (`upgrade` function) or downgrading (`downgrade`) - -- You can migrate your data within these `upgrade`/`downgrade` functions, for example : - -```python -from alembic import op - -# revision identifiers, used by Alembic. -revision = 'abcdef01234567' -down_revision = '987654321f0edc' -branch_labels = None -depends_on = None - -def upgrade(): - - # operations to modify the database structure - # ... - op.create_table( - 'new_table', - Column('id', INTEGER, primary_key=True), - Column('field1', VARCHAR(50), nullable=False), - Column('field2', INTEGER), - Column('timestamp', TIMESTAMP, server_default=func.now()) - ) - # ... - - op.execute('''INSERT INTO new_table (field1, field2) - SELECT field1, field2 - FROM old_table''') - - # other operations to modify the database structure - # ... - - -def downgrade(): - - op.drop_table('new_table') - -``` - -- Once you're sure about the changes generated, you can apply them by running : - -```sh -alembic upgrade head -``` - -- Check your database : your changes should be reflected. If not, refer to [Alembic's documentation](https://alembic.sqlalchemy.org/en/latest/). diff --git a/docs/diagrams_sources/conda-store-database-architecture.drawio b/docs/diagrams_sources/conda-store-database-architecture.drawio deleted file mode 100644 index f8e8d82e8..000000000 --- a/docs/diagrams_sources/conda-store-database-architecture.drawio +++ /dev/null @@ -1 +0,0 @@ -7Vtbd6M2EP41fkwOQlzMo+0427OXnrTZ09vLHgVkUAOIYjm2++srQOJuQrxgexsnD0EjaSRG3zejkcgELoLdhxhF3hfqYH+iKs5uAu8mqqoBY8r/JJJ9JlEtVUjcmDiZDBSCR/IvFkJFSDfEwetKQ0apz0hUFdo0DLHNKjIUx3RbbbaifnXUCLm4IXi0kd+U/k4c5mVSS1EK+U+YuJ4cGciaAMnGQrD2kEO3JRFcTuAippRlT8Fugf3EetIuWb/7A7X5xGIcsj4dnj/9sjf3W/TR3c6+EO/zDn6NbvRMywvyN+KFxWTZXlrAjekmEs1wzPCuze7oSTZXmvMC+dtynGAaYBbveROpyBBdBESAVLEt7K1qmhB6JWNPVVMstFhkN1de2IE/CFMcsOMn+7ePBASb+79WMAqQ/vLi34AWsxg+H3a+ovytyvYx/tlQWXGzTvE74w00NeLvNy/q+ZOb/P0ZBXgdIRtLjXyCmdKsvmF/bv7QwclsAa/eeoThx7Q/vNty0nGZxwJfVK9ZTJ/xgvo0TnvDWfor5ifopfHVmPvoCftzZD+76QCyS0hDnLQmvi9FDl6hTTrVTLvkgSa0to2WIIVwFs184oa8LiCOk7zQvImOTlzWAddEUQklmtECkhxOw4MEjoeSZfhCYhoGOAXGFSffjxMZgGDTu7TjBoyGG2083DxG2CYrblFGaHhFziDIEbXGtBqnWpGknxRJci9VWkvs8O2LKNKYedSlIfKXhXReXe2izWdKIyH8GzO2F0uJNoxWEYB3hP3Bn5VbVRfFP0tVd4m9FFnYy0LIXzjrpcti3ispFN3Skux3GG5VqOgtADwEnTVDMZslm0Nesfw1QOFeSu9JsgJiHo5s8+RT+/mrR8JMLBoB2UmMqVpZtSym06eb2MYPOCZ8xXGc0IqErhiB93UxO1D5Nhhn43Q5HdEwG7NHVEuA1EmLGPvcy7xU98ltEE+7clOifalBREnI1iXND4mgtCvUoFqhm6TW/YEOOR3b2/OHbAoF2/J3+Q5X3rZ/HsiVzzeE5ypXFz6gCwdQvTgfDoyRITTjRl4h+7qPHBZKlnV5UDJHhtK3BQ0d9MAXMTk1ueJpTNekWefH03Q8PF2RNBaSTFAFkindwhmBZI0MpIWHwjA5er4CaTggTS8OR9JFdh1XH0jbSgtarL7yhqSxyHrLSW+e554o6X1j9tlIkfulvp2JaWdKO3TWCvtmrT2T1hJ226ArZW/LbRu5qFVzwbpeY4SwYdarI6m1ancjulJTJFaqrmio/FZesJzrgMk86oAJGGqZbcqtZcGjGTfQMZMIAhd2yJQaIa87N4f1niQe9+QJanp1Iw66D54AtGBXh3FOnmTkO2soLAfCPCy+Qk9QpaZ+NDHfWyjsfYCrXVQsBMCsxjBoHRkMG5ryHeqpomHbhe+Vc/9jzhlDh64Tcc6q31Va+pGcM+vHnHVNY3Ou7bL8glO+K3dqh9E/HHfMWpTR6h8Q9eZOnvYd0jQ2d3p83TcWd35cHrSz/rivG4rY2h5pT8C5VoXqZVFOrx1zGNrRlKtpmp76wKTtNve6Rbwgeg9NuWnfMGddFudg7YzSOD4tU1/RNBznupzZ2LeU7/57nJav//vRqP+l92nvmFpnfM58450645pL7O+dX3e60/P62Dq8zWN9rKrUNYFbZWoVPwN5XF4s/iMpa178Yxdc/gc= diff --git a/docs/environment-docs.yml b/docs/environment-docs.yml deleted file mode 100644 index 05aacb953..000000000 --- a/docs/environment-docs.yml +++ /dev/null @@ -1,10 +0,0 @@ -name: conda-store-docs -channels: - - conda-forge -dependencies: - - python ==3.10 - - sphinx - - myst-parser - - sphinx-panels - - sphinx-copybutton - - pydata-sphinx-theme diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 9505a839a..000000000 --- a/docs/index.rst +++ /dev/null @@ -1,87 +0,0 @@ -:html_theme.sidebar_secondary.remove: - -.. rst-class:: hide - -conda-store -=========== - -.. toctree:: - :maxdepth: 2 - :hidden: - - installation - user_guide - administration - contributing - api - -.. image:: _static/images/conda-store-logo-vertical-lockup.png - :alt: conda-store logo - :scale: 50% - :align: center - :class: dark-light p-2 - - -.. rst-class:: center - -**Data science environments, for collaboration.** - ----- - -.. rst-class:: center - -conda-store is an open source tool for managing data science environments in collaborative teams. -It provides flexible, yet reproducible, environments while enforcing best practices throughout your environment's life cycle. - -.. panels:: - :container: container-lg pb-3 - :column: col-lg-4 col-md-4 col-sm-6 col-xs-12 p-2 - - **🧶 Flexible** - ^^^^^^^^^^^^^^ - - .. rst-class:: left - - Create and update environments quickly using a graphical UI or a YAML editor. - - .. rst-class:: left - - All environments are automatically version-controlled, and available for use. - - --- - **💫 Reproducible** - ^^^^^^^^^^^^^^^^^^ - - .. rst-class:: left - - Share environments effortlessly through the auto-generated artifacts: lockfile, docker image, YAML file, or tarball. - - .. rst-class:: left - - Exact versions of all packages and their dependencies are pinned in these artifacts. - - --- - **⚖️ Governance** - ^^^^^^^^^^^^^ - - .. rst-class:: left - - Access admin-approved packages and channels, and request new ones when needed. - - .. rst-class:: left - - Admins have role-based access management, to allow users to share environments across (and only with) their team. - -.. rst-class:: center - -The conda packaging system works well for individual users, but it can get tricky to reproduce environments reliably to share with colleagues. On the other hand, Docker containers can ensure reproducibility, but aren't friendly to individual users who may need new packages or versions for daily work. conda-store resolves this friction, and provides a balance of both the familiarity of conda and the robustness of containers. - - -.. rst-class:: border - -.. figure:: _static/images/conda-store-ui.webp - :alt: conda-store video - :align: center - :class: dark-light p-2 - - Preview of a new graphical user interface for conda-store, which will also be available as a JupyterLab extension! diff --git a/docs/installation.md b/docs/installation.md deleted file mode 100644 index df941a389..000000000 --- a/docs/installation.md +++ /dev/null @@ -1,118 +0,0 @@ -# Installation - -## Linux - -You can install conda-store using conda : - -```shell -conda install conda-store-server>=0.4.10 -``` - -Once installed, start conda-store using : - -```shell -conda-store-server --standalone -``` - -You can then access conda-store on port 8080 of the machine running it. - -## Kubernetes - -![conda-store Kubernetes architecture diagram](_static/images/conda-store-installation-kubernetes.png) - -The following will describe a local -[Kubernetes](https://kubernetes.io/) installation via [minikube](https://minikube.sigs.k8s.io/docs/). The -files required are in `examples/kubernetes` - -```shell -minikube start --cpus 2 --memory 4096 --driver=docker -``` - -Now we deploy the `conda-store` components. Note that conda-store is -compatible with any general s3 like provider and any general database -via SQLAlchemy. Currently the docker image is build with support for -PostgreSQL and SQLite. Consult the [SQLAlchemy -documentation](https://docs.sqlalchemy.org/en/14/core/engines.html#database-urls) -on supporting your given database and then creating a custom docker -image with your required database. Not all database engines were added -to save on image size. Additionally You may not need to use MinIO and -PostgreSQL deployments and use existing infrastructure. In the case of -AWS this may mean using [Amazon RDS](https://aws.amazon.com/rds/) and -[s3](https://aws.amazon.com/s3/). Consult your cloud provider for -compatible services. In general if it is supported by SQLAlchemy and -there is a s3 compatible object store conda-store will -work. [kustomize](https://github.com/kubernetes-sigs/kustomize) is -being used for the deployment which is part to the Kubernetes project -itself. - -```shell -kubectl apply -k examples/kubernetes -``` - -Make sure to change all the usernames and passwords for the -deployment. - -If your installation worked you should be able to port forward the -conda-store web server. - -```shell -kubectl port-forward service/conda-store-server 8080:8080 -``` - -Then visit via your web browser [http://localhost:8080](http://localhost:8080) - -For additional configuration options see the [administrative -guide](./administration.md) - -A good test that conda-store is functioning properly is to apply the -`jupyterlab-conda-store` pod as a quick test. It will cause -conda-store to build an environment with JupyterLab and NumPy. This -pod is not needed for running conda-store. - -```shell -kubectl apply -f examples/kubernetes/test/jupyterlab-conda-store.yaml -``` - -If you instead mount a -[ReadWriteMany](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) -volume to the container `conda-store-worker` like nfs or -[Amazon EFS](https://aws.amazon.com/efs/). You can mount the environments -built via conda-store and use environments this way. Note that NFS can -be significantly slower when it comes to creating environments (see [performance docs](./administration.md#performance)). - -## Docker - -To install on a local docker daemon there is an existing -`docker-compose.yaml` for deployment. The example files required are in -`examples/docker` - -```shell -docker-compose up --build -``` - -Then visit via your web browser [https://conda-store.localhost/conda-store](https://conda-store.localhost/conda-store). By default, you can log in with any username and use the password `password`, since [we are using](https://github.com/Quansight/conda-store/blob/a679e5c4d2f2fe7d992fd93c5d90c34b38c513ef/tests/assets/jupyterhub_config.py#L4) the [DummyAuthenticator](https://github.com/jupyterhub/jupyterhub/blob/4e7936056744cdad31d608388a349207196efa56/jupyterhub/auth.py#L1122) - -## Local Automated systemd Install - -Not all environment are containerized and conda-store recognizes -that. The goal of CONDA-STORE is to provide Conda environments in as -many ways as possible so it SHOULD support non-contianerized -environments. The example files required are in -`examples/ubuntu2004`. - -This example is not fully complete in that it does not install -`conda-store` and get it running due to the [conda-forge -package](https://github.com/conda-forge/staged-recipes/pull/13933). - -If you would like to test it in a VM use the following. The following -`Vagrantfile` is only compatible with [libvirt](https://libvirt.org/). - -```shell -vagrant up -``` - -However if you want to do a local deployment use - -```shell -ansible-playbook -i playbook.yaml -``` diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 2119f5109..000000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/user_guide.md b/docs/user_guide.md deleted file mode 100644 index 118948ff3..000000000 --- a/docs/user_guide.md +++ /dev/null @@ -1,333 +0,0 @@ -# User Guide - -## Environments - -Below is an image of a single environment. The following will describe -what the `yaml`, `lockfile`, `archive`, and `docker` represent. - -![YAML button](_static/images/conda-store-single-environment.png) - -### Pinned YAML - -A pinned YAML file is generated for each environment is built. This -includes pinning of the pip packages as well. Note that there are -cases where the completely pinned packages do not solve. Packages are -routinely marked as broken and removed. Note however -[conda-forge](https://conda-forge.org/docs/maintainer/updating_pkgs.html#packages-on-conda-forge-are-immutable) -has a policy that packages are never removed but are marked as -broken. Most channels do not obey this policy. When you click the -`yaml` button a YAML file will then be downloaded. To install the -environment locally run the following. - -```shell -conda env create -f -``` - -### Conda lockfile - -A Conda lockfile is a representation of only the Conda dependencies in -a given environment. The lockfile feature was inspired from -[conda-lock](https://github.com/conda-incubator/conda-lock). This file -will not reproduce the pip dependencies in a given environment. When -working with Conda it is generally not a good idea to mix Conda and -pip dependencies. Click the `lockfile` icon to download the -lockfile. First install `conda-lock` if it is not already installed. - -```shell -conda install -c conda-forge lockfile -``` - -Install the locked environment file from conda-store. - -```shell -conda-lock install -``` - -### Conda-Pack archive - -[Conda-Pack](https://conda.github.io/conda-pack/) is a package for -creating tarballs of given Conda environments. Creating a Conda archive -is not as simple as packing and unpacking a given directory. This is -due to the base path for the environment that may -change. [Conda-Pack](https://conda.github.io/conda-pack/) handles all -of these issues. Click the `archive` button and download the given -environment. The size of the archive will be less than the size seen -on the environment UI element due to compression. - -```shell -conda install -c conda-forge conda-pack -``` - -Install the Conda-Pack tarball. The directions are [slightly -complex](https://conda.github.io/conda-pack/#commandline-usage). Note -that `my_env` can be any name in any given prefix. - -```shell -mkdir -p my_env -tar -xzf .tar.gz -C my_env - -source my_env/bin/activate - -conda-unpack -``` - -### Docker Registry - -```{note} -Docker image creation is currently only supported on Linux. -``` - -conda-store acts as a docker registry which allows for interesting -ways to handle Conda environment. In addition this registry leverages -[conda-docker](https://github.com/conda-incubator/conda-docker) which -builds docker images without docker allowing for advanced caching, -reduced image sizes, and does not require elevated privileges. Click -on the `docker` link this will copy a url to your clipboard. Note the -beginning of the url for example `localhost:8080/`. This is required to tell -docker where the docker registry is located. Otherwise by default it -will try and user docker hub. Your url will likely be different. - -The `conda-store` docker registry requires authentication via any -username with password set to a token that is generated by visiting -the user page to generate a token. Alternatively in the -`conda_store_config.py` you can set -`c.AuthenticationBackend.predefined_tokens` which have environment -read permissions on the given docker images needed for pulling. - -``` -docker login -u token -p -docker pull -docker run -it python -``` - -#### General usage - -```shell -docker run -it localhost:8080// -``` - -If you want to use a specific build (say one that was built in the -past and is not the current environment) you can visit the specific -build that you want in the UI and copy its docker registry tag -name. The tag name is a combination of `---` that we will refer to as build -key. An example would be -`localhost:8080/filesystem/python-numpy-env:583dd55140491c6b4cfa46e36c203e10280fe7e180190aa28c13f6fc35702f8f-20210825-180211-244815-3-python-numpy-env`. - -```shell -docker run -it localhost:8080//: -``` - -#### On Demand Docker Image - -conda-store has an additional feature which allow for specifying the -packages within the docker image name itself without requiring an -actual environment to be created on the conda-store UI side. - -The following convention is used -`:/conda-store-dynamic/`. After -`conda-store-dynamic` you specify packages needed separated by -slashes. Additionally you may specify package constraints -for example `<=1.10` as `.lt.1.10`. - -As full example support we want python less than `3.8` and NumPy -greater than `1.0`. This would be the following docker image -name. `:/conda-store-dynamic/python.lt.3.8/numpy.gt.1.0`. conda-store -will then create the following environment and the docker image will -download upon the docker image being built. - -## conda-store UI - -### `/` Home Page - -![conda-store Homepage](_static/images/conda-store-authenticated.png) - -The home page shows all of the available environments in the form -`/`. If you are authenticated there with -be a `User` button in the top right hand corner to view information -about the currently logged in user. Otherwise there is a `login` -button and few if any environments will be visible. Additionally there -is a convenient `Create Environment` button to easily create a given -environment. There is a `Docs` button that will take you to this -documentation at any time. - -Shortcuts are available below each of the available environments that allow you -to download or view the [Conda -lockfile](https://github.com/conda-incubator/conda-lock), -[YAML](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#creating-an-environment-from-an-environment-yml-file), or -[Conda-Pack](https://github.com/conda/conda-pack) files. - -### `/login/` Login - -![conda-store Login](_static/images/conda-store-login-jupyterhub-oauth.png) - -If you are unauthenticated there is a `login` button on the top -navigation bar. This will direct you to the login page. The example -above shows what you will get with JupyterHub authentication. - -### `/user/` User - -![conda-store User](_static/images/conda-store-user.png) - -Once a user has completed the authentication flow they will be -directed to the user page. This page gives information about the -current authenticated user along with the permissions. - -### `/create/` Create Environment - -![conda-store Create Environment](_static/images/conda-store-create-environment.png) - -A user authenticated or unauthenticated has set permissions that allow -the user to create environments in a given namespace. Currently the -create page allows for dragging and uploading of current -`environment.yaml` files in the UI. The specification is the format of -a traditional `environment.yaml` and will report errors if there are -issues with the format of the environment file. - -### `/environment///` Environments - -![conda-store Environment](_static/images/conda-store-environment.png) - -The environment page contains a lot of information for the -developer. First we see the environment name and namespace along with -the disk space that the environment consumes. Right below this -information is the full `environment.yaml` specification of the -currently active build. Users can quickly edit this existing -environment by clicking the `edit` button. Additionally the entire -environment can be deleted via the `delete` button. - -Below this is a list of the current builds of the given -environment. The environment highlighted in `green` is the current -build for the given environment that is active. The environment -highlighted in `grey` indicates that the build was deleted. Even -though a build may be deleted the logs, lockfile, and a other build -information is preserved for the record. - -For each build several options are available to the user: - -- The `checkmark` icon allow the user to switch that given build to the - active build for the environment. This may be useful if you need - to rollback a given environment if the new build environment caused - some scripts to fail. -- The `refresh` icon indicates that a user would like the given - environment to build again. Conda `environment.yaml` files are not - reproducible thus this will likely lead to an entirely new - solve. This is useful when you would like to update all the - packages in a given environment without having to change the - specification. -- The `trashcan icon` marks the given build for - deletion. `CondaStore.build_artifacts_kept_on_deletion` allows some - artifacts to be kept on deletion. These include logs, YAML, etc. - -### `/build/` builds - -![conda-store Build](_static/images/conda-store-build-complete.png) - -The build page gives all the information about a given build in -conda-store. At the top we see high level build metadata. - -conda-store downloads Conda channel data so that it fully understands -the packages that exist within a given environment. A list is provided -to the user of all packages within that environment. - -Below this are all artifacts associated with a given build e.g -lockfile, pinned YAML specification, Conda-Pack, and docker image. - -Finally a log of the given build regardless of whether the build -succeeded or failed. - -### `/namespace/` manage namespaces - -![conda-store Namespace](_static/images/conda-store-namespace.png) - -This namespace page allows a user with correct permissions to list, -create, and delete namespaces. Note that the deletion of a namespace -is destructive and deletes all environments and builds within that -namespace. - -## conda-store cli - -The conda-store client can be easily installed via pip and conda. - -```shell -pip install conda-store -conda install -c conda-forge conda-store -``` - -The base cli is inspired by tools such as -[conda](https://docs.conda.io/en/latest/), -[kubectl](https://kubernetes.io/docs/reference/kubectl/), and -[docker](https://docs.docker.com/get-docker/). The base commands are -`download`, `info`, `list`, `run`, `wait`. - -```shell -$ conda-store --help -Usage: conda-store [OPTIONS] COMMAND [ARGS]... - -Options: - --conda-store-url TEXT conda-store base url including prefix - --auth [none|token|basic] conda-store authentication to use - --no-verify-ssl Disable tls verification on API requests - --help Show this message and exit. - -Commands: - download Download artifacts for given build - info Get current permissions and default namespace - list - run Execute given environment specified as a URI with COMMAND - solve Remotely solve given environment.yaml - wait Wait for given URI to complete or fail building -``` - -### `conda-store run` - -One of the motivating features of the `conda-store` cli is that you -can directly execute conda-store environments that exist remotely. - -```shell -conda-store run devops/datascience -- python -m "print(1)" -``` - -### `conda-store solve` - -conda-store is capable to remote solves of environment files. If -requested conda-store can perform intelligent solves with caching. - -### `conda-store download` - -### `conda-store info` - -### `conda-store wait` - -### `conda-store list [namespace|environment|build]` - -## conda-store shebang - -`conda-store` can be used as a -[shebang]() within Linux -allowing users to embed Conda environments within scripts for -reproducibility. Basic usage is as follows. Notice that the -`conda-store run` command is just the normal usage of the command. - -```shell -#!/usr/bin/env conda-store -#! conda-store run /: -- python - -print('script running within the conda-store environnent') -``` - -The first line must begin with the shebang `#!` along with ending in -`conda-store`. You cannot put arguments on the first line due to -limits in the shebang specification. Additional lines are then added -starting with `#! conda-store run ...` with are then used as arguments -to `conda-store run`. - -The path to the script being run is always appended as the last -argument to the command so the example above is interpreted as: - -``` -conda-store run /: -- python -``` - -This feature was heavily inspired by [`nix-shell` -shebangs](https://nixos.wiki/wiki/Nix-shell_shebang). diff --git a/docs/_static/images/conda-store-logo-vertical-lockup.svg b/docusaurus-docs/community/images/logos/conda-store-logo-vertical-lockup.svg similarity index 100% rename from docs/_static/images/conda-store-logo-vertical-lockup.svg rename to docusaurus-docs/community/images/logos/conda-store-logo-vertical-lockup.svg diff --git a/docusaurus-docs/community/maintenance/release.md b/docusaurus-docs/community/maintenance/release.md index a034aa232..f97f1cc8e 100644 --- a/docusaurus-docs/community/maintenance/release.md +++ b/docusaurus-docs/community/maintenance/release.md @@ -53,7 +53,7 @@ For the release tag, there should be **NO** prepended `v`. ### Release checklist (conda-store) -Create an issue and copy & paste the steps below to release a new conda-store version. Close the issue when it is done. +Create an [issue with the release template](https://github.com/conda-incubator/conda-store/issues/new?assignees=&labels=release+%F0%9F%8F%B7&projects=&template=new-release.md&title=%5BREL%5D+-+%3Crelease+number%3E), or copy & paste the steps below, to release a new conda-store version. Close the issue when it is done. :::caution There are two packages: the [conda-store](https://github.com/conda-incubator/conda-store) repository; [`conda-store`](https://github.com/conda-incubator/conda-store/tree/main/conda-store) and [`conda-store-server`](https://github.com/conda-incubator/conda-store/tree/main/conda-store-server). Make sure to update both packages when releasing a new version. @@ -117,5 +117,6 @@ Release captain responsible - <@gh_username> [^github-activity]: If you wish, use [`github-activity` to generate a changelog](https://github.com/choldgraf/github-activity), eg `github-activity conda-incubator/conda-store --since 2023.9.1 --until 2023.10.1`. +```