← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/lp-archive:service-config-env into lp-archive:main

 

Colin Watson has proposed merging ~cjwatson/lp-archive:service-config-env into lp-archive:main.

Commit message:
Accept SERVICE_CONFIG environment variable

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/lp-archive/+git/lp-archive/+merge/436338

This is used in some of our other services, and is easier to handle in deployments than just reading `config.toml` from the current directory.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/lp-archive:service-config-env into lp-archive:main.
diff --git a/lp_archive/__init__.py b/lp_archive/__init__.py
index dc1b052..70f6062 100644
--- a/lp_archive/__init__.py
+++ b/lp_archive/__init__.py
@@ -3,11 +3,14 @@
 
 """The Launchpad archive service."""
 
+import os
+from pathlib import Path
+from typing import Any
+
 try:
     import tomllib
 except ModuleNotFoundError:
     import tomli as tomllib  # type: ignore
-from typing import Any
 
 import talisker.flask
 from flask import Flask, jsonify
@@ -15,12 +18,20 @@ from flask import Flask, jsonify
 from lp_archive import archive, root, routing
 from lp_archive.cache import cache
 
+ROOT = Path(__file__).parent.parent.resolve()
+
 
 def create_app(test_config: dict[str, Any] | None = None) -> Flask:
     app = Flask(__name__, static_folder=None, host_matching=True)
     if test_config is None:
-        with open("config.toml", "rb") as f:
-            app.config.from_mapping(tomllib.load(f))
+        try:
+            config_text = Path(
+                os.environ.get("SERVICE_CONFIG", ROOT / "config.toml")
+            ).read_text()
+        except FileNotFoundError:
+            pass
+        else:
+            app.config.from_mapping(tomllib.loads(config_text))
     else:
         app.config.from_mapping(test_config)
     app.url_map.converters["primary"] = routing.PrimaryArchiveConverter
diff --git a/tests/test_factory.py b/tests/test_factory.py
index aaa9d81..70818d1 100644
--- a/tests/test_factory.py
+++ b/tests/test_factory.py
@@ -1,7 +1,6 @@
 # Copyright 2022 Canonical Ltd.  This software is licensed under the
 # GNU Affero General Public License version 3 (see the file LICENSE).
 
-import os
 import warnings
 from pathlib import Path
 from tempfile import TemporaryDirectory
@@ -9,17 +8,27 @@ from tempfile import TemporaryDirectory
 from lp_archive import create_app
 
 
-def test_config_from_file():
+def test_config_from_file(monkeypatch):
     with TemporaryDirectory() as empty:
-        old_cwd = os.getcwd()
-        try:
-            os.chdir(empty)
-            Path("config.toml").touch()
-            with warnings.catch_warnings():
-                warnings.filterwarnings("ignore", module="flask_caching")
-                assert not create_app().testing
-        finally:
-            os.chdir(old_cwd)
+        config_path = Path(empty) / "config.toml"
+        config_path.write_text('SENTINEL = "1"\n')
+        monkeypatch.setenv("SERVICE_CONFIG", str(config_path))
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", module="flask_caching")
+            app = create_app()
+            assert app.config["SENTINEL"] == "1"
+            assert not app.testing
+
+
+def test_missing_config_file(monkeypatch):
+    with TemporaryDirectory() as empty:
+        config_path = Path(empty) / "config.toml"
+        monkeypatch.setenv("SERVICE_CONFIG", str(config_path))
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", module="flask_caching")
+            app = create_app()
+            assert "SENTINEL" not in app.config
+            assert not app.testing
 
 
 def test_config_for_testing():