From 556f640fbe857eec1771e7f078e17221b6baaf86 Mon Sep 17 00:00:00 2001 From: Christopher Ostrouchov Date: Sat, 24 Jul 2021 11:44:51 -0400 Subject: [PATCH] Adding conda env export (#92) * Adding conda env export Closes #12 * Black formatting --- conda-store-server/conda_store_server/app.py | 1 + .../conda_store_server/build.py | 20 +++++++++++++++++++ conda-store-server/conda_store_server/orm.py | 4 ++++ .../server/templates/build.html | 1 + .../server/templates/home.html | 3 ++- .../conda_store_server/server/views/ui.py | 7 +++++++ .../conda_store_server/worker/tasks.py | 8 ++++++++ 7 files changed, 43 insertions(+), 1 deletion(-) diff --git a/conda-store-server/conda_store_server/app.py b/conda-store-server/conda_store_server/app.py index d7626baba..9e13676b9 100644 --- a/conda-store-server/conda_store_server/app.py +++ b/conda-store-server/conda_store_server/app.py @@ -244,6 +244,7 @@ def create_build(self, specification_sha256): ( tasks.task_update_storage_metrics.si() | tasks.task_build_conda_environment.si(build.id) + | tasks.task_build_conda_env_export.si(build.id) | tasks.task_build_conda_pack.si(build.id) | tasks.task_build_conda_docker.si(build.id) | tasks.task_update_storage_metrics.si() diff --git a/conda-store-server/conda_store_server/build.py b/conda-store-server/conda_store_server/build.py index dd30490f1..b9bffa344 100644 --- a/conda-store-server/conda_store_server/build.py +++ b/conda-store-server/conda_store_server/build.py @@ -151,6 +151,26 @@ def build_conda_environment(conda_store, build): set_build_failed(conda_store, build, traceback.format_exc().encode("utf-8")) +def build_conda_env_export(conda_store, build): + conda_prefix = build.build_path(conda_store.store_directory) + + output = subprocess.check_output( + [conda_store.conda_command, "env", "export", "-p", conda_prefix] + ) + + parsed = yaml.safe_load(output) + if "dependencies" not in parsed: + raise ValueError(f"conda env export` did not produce valid YAML:\n{output}") + + conda_store.storage.set( + conda_store.db, + build.id, + build.conda_env_export_key, + output, + content_type="text/yaml", + ) + + def build_conda_pack(conda_store, build): conda_prefix = build.build_path(conda_store.store_directory) diff --git a/conda-store-server/conda_store_server/orm.py b/conda-store-server/conda_store_server/orm.py index 959e46db4..50e57cddf 100644 --- a/conda-store-server/conda_store_server/orm.py +++ b/conda-store-server/conda_store_server/orm.py @@ -112,6 +112,10 @@ def build_key(self): def log_key(self): return f"logs/{self.build_key}.log" + @property + def conda_env_export_key(self): + return f"yaml/{self.build_key}.yml" + @property def conda_pack_key(self): return f"archive/{self.build_key}.tar.gz" diff --git a/conda-store-server/conda_store_server/server/templates/build.html b/conda-store-server/conda_store_server/server/templates/build.html index f66803ea2..41097148f 100644 --- a/conda-store-server/conda_store_server/server/templates/build.html +++ b/conda-store-server/conda_store_server/server/templates/build.html @@ -65,6 +65,7 @@

Conda Packages

Conda Environment Artifacts

diff --git a/conda-store-server/conda_store_server/server/templates/home.html b/conda-store-server/conda_store_server/server/templates/home.html index 395e55746..93359242e 100644 --- a/conda-store-server/conda_store_server/server/templates/home.html +++ b/conda-store-server/conda_store_server/server/templates/home.html @@ -11,7 +11,8 @@
{{ environment.namespace }}/{{ environment.name }} {{ (environment.build.size or 0) | filesizeformat(true) }}
- {% if environment.build_id is not none %} + {% if environment.build.status.value == 'COMPLETED' %} + YAML Lockfile Archive Docker diff --git a/conda-store-server/conda_store_server/server/views/ui.py b/conda-store-server/conda_store_server/server/views/ui.py index a0d61e277..86fefdf6c 100644 --- a/conda-store-server/conda_store_server/server/views/ui.py +++ b/conda-store-server/conda_store_server/server/views/ui.py @@ -95,6 +95,13 @@ def api_get_build_lockfile(build_id): return Response(lockfile, mimetype="text/plain") +@app_ui.route("/build//yaml/", methods=["GET"]) +def api_get_build_yaml(build_id): + conda_store = get_conda_store() + key = api.get_build(conda_store.db, build_id).conda_env_export_key + return redirect(conda_store.storage.get_url(key)) + + @app_ui.route("/build//archive/", methods=["GET"]) def api_get_build_archive(build_id): conda_store = get_conda_store() diff --git a/conda-store-server/conda_store_server/worker/tasks.py b/conda-store-server/conda_store_server/worker/tasks.py index bd36e4b51..e0c7000a6 100644 --- a/conda-store-server/conda_store_server/worker/tasks.py +++ b/conda-store-server/conda_store_server/worker/tasks.py @@ -5,6 +5,7 @@ from conda_store_server import api, environment from conda_store_server.build import ( build_conda_environment, + build_conda_env_export, build_conda_pack, build_conda_docker, ) @@ -47,6 +48,13 @@ def task_build_conda_environment(build_id): build_conda_environment(conda_store, build) +@task(name="task_build_conda_env_export") +def task_build_conda_env_export(build_id): + conda_store = create_worker().conda_store + build = api.get_build(conda_store.db, build_id) + build_conda_env_export(conda_store, build) + + @task(name="task_build_conda_pack") def task_build_conda_pack(build_id): conda_store = create_worker().conda_store