diff --git a/dbuild/docs.py b/dbuild/docs.py index a037a6c..65d8e49 100644 --- a/dbuild/docs.py +++ b/dbuild/docs.py @@ -932,8 +932,10 @@ def _render_director_override(director: dict) -> str: # quoted -- '!ENV ''${VAR}''' -- which director reads as literal text, not # a tag, and the jail gets the string "!ENV '${VAR}'" as its value. # Unquote so it is the tag pyaml-env resolves. - body = _re.sub(r"""'!ENV ''(\$\{[^}]+\}[^']*)'''""", r"!ENV '\1'", body) - body = _re.sub(r'''"!ENV '(\$\{[^}]+\}[^']*)'"''', r"!ENV '\1'", body) + # Any value with a ${VAR} in it, not only one that starts with one: immich's + # 'http://${IMMICH_ML_HOST:127.0.0.1}:3003' stayed quoted. + body = _re.sub(r"""'!ENV ''([^']*\$\{[^}]+\}[^']*)'''""", r"!ENV '\1'", body) + body = _re.sub(r'''"!ENV '([^'"]*\$\{[^}]+\}[^'"]*)'"''', r"!ENV '\1'", body) return "# appjail-director.yml\n\n" + body diff --git a/tests/test_docs.py b/tests/test_docs.py index ce5316d..e9686f2 100644 --- a/tests/test_docs.py +++ b/tests/test_docs.py @@ -739,3 +739,21 @@ def test_choices_for_fjord_database_kind(self): self.assertEqual(pg["env"]["TODO_DB_HOST"], "postgres") ext = next(o for o in db["options"] if o["id"] == "external") self.assertEqual([a["name"] for a in ext["ask"]][:2], ["TODO_DB_TYPE", "TODO_DB_HOST"]) + + +class TestDirectorEnvUnquote(unittest.TestCase): + """An !ENV value written as a string comes out as the tag, wherever its + ${VAR} sits: immich's ML URL starts with http:// and stayed a quoted + string, so the jail got the literal text "!ENV 'http://...'".""" + + def test_unquotes_a_variable_inside_a_value(self): + from dbuild.docs import _render_director_override + body = _render_director_override({"services": {"server": {"oci": {"environment": [ + {"ML_URL": "!ENV 'http://${ML_HOST:127.0.0.1}:3003'"}, + {"DB_HOST": "!ENV '${DB_HOST:127.0.0.1}'"}, + {"PLAIN": "no variable here"}, + ]}}}}) + self.assertIn("ML_URL: !ENV 'http://${ML_HOST:127.0.0.1}:3003'", body) + self.assertIn("DB_HOST: !ENV '${DB_HOST:127.0.0.1}'", body) + self.assertNotIn("'!ENV", body) + self.assertIn("PLAIN: no variable here", body)