mirror of
https://github.com/d9pouces/id_configurator.git
synced 2026-11-09 01:47:21 +01:00
feat: add plain-HTTP listeners for various repository configurations to support non-HTTPS access
Signed-off-by: d9pouces <github@19pouces.net>
This commit is contained in:
@@ -28,12 +28,20 @@ tool targets Docker images, which are built and run as root:
|
||||
- Ivy: `~/.ivy2/ivysettings.xml`, as a chain of `ibiblio` resolvers.
|
||||
- SBT: `~/.sbt/repositories`, the resolver override file SBT reads for its
|
||||
own bootstrapping and, when combined with the `sbt.override.build.repos`
|
||||
system property, for every project's resolvers as well.
|
||||
system property, for every project's resolvers as well. A repository
|
||||
whose URL isn't HTTPS gets `, allowInsecureProtocol` appended to its
|
||||
line - SBT's Coursier-backed resolver otherwise refuses it outright
|
||||
("insecure protocol is unsupported"), unlike every other entry in
|
||||
`~/.sbt/repositories` which takes no such suffix.
|
||||
- Leiningen: `~/.lein/profiles.clj`, adding the repositories to the `:user`
|
||||
profile. Leiningen, alone among these, refuses a plain-HTTP repository
|
||||
outright ("Tried to use insecure HTTP repository without TLS"); a
|
||||
repository whose URL isn't HTTPS gets `:insecure true` added to its entry,
|
||||
Leiningen's own documented escape hatch for this.
|
||||
outright ("Tried to use insecure HTTP repository without TLS") - its
|
||||
standalone `lein` launcher (`leiningen.core.main/-main`) unconditionally
|
||||
registers an aborting wagon for the "http" scheme before even reading the
|
||||
project/profile config, so there is no project.clj/profiles.clj setting
|
||||
(there is no `:insecure` key anywhere in Leiningen's own source) that
|
||||
can work around this: a non-HTTPS repository configured here will not be
|
||||
usable from Leiningen specifically, regardless of what this module does.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -237,27 +245,26 @@ def _write_ivy_settings(context: Context, repositories: list[JavaRepository]) ->
|
||||
logger.info("configured ivy to use %d repositories", len(repositories))
|
||||
|
||||
|
||||
def _sbt_repository_line(repository: JavaRepository) -> str:
|
||||
line = f" {repository.name}: {repository.url}"
|
||||
if urlparse(repository.url).scheme.lower() != "https":
|
||||
line += ", allowInsecureProtocol"
|
||||
return line
|
||||
|
||||
|
||||
def _write_sbt_repositories(
|
||||
context: Context, repositories: list[JavaRepository]
|
||||
) -> None:
|
||||
lines = ["[repositories]", " local"]
|
||||
lines.extend(
|
||||
f" {repository.name}: {repository.url}" for repository in repositories
|
||||
)
|
||||
lines.extend(_sbt_repository_line(repository) for repository in repositories)
|
||||
context.write_file(_SBT_REPOSITORIES, ("\n".join(lines) + "\n").encode("utf-8"))
|
||||
logger.info("configured sbt to use %d repositories", len(repositories))
|
||||
|
||||
|
||||
def _lein_repository_entry(repository: JavaRepository) -> str:
|
||||
options = f":url {_string_literal(repository.url)}"
|
||||
if urlparse(repository.url).scheme.lower() != "https":
|
||||
options += " :insecure true"
|
||||
return f"[{_string_literal(repository.name)} {{{options}}}]"
|
||||
|
||||
|
||||
def _write_lein_profiles(context: Context, repositories: list[JavaRepository]) -> None:
|
||||
entries = " ".join(
|
||||
_lein_repository_entry(repository) for repository in repositories
|
||||
f"[{_string_literal(repository.name)} {{:url {_string_literal(repository.url)}}}]"
|
||||
for repository in repositories
|
||||
)
|
||||
content = f"{{:user {{:repositories [{entries}]}}}}\n"
|
||||
context.write_file(_LEIN_PROFILES, content.encode("utf-8"))
|
||||
|
||||
@@ -4,6 +4,7 @@ COPY --from=target / /src/
|
||||
COPY --from=generated-config Java.yaml /config.yaml
|
||||
RUN id-configurator apply --config /config.yaml --src /src --dst /dst
|
||||
FROM target AS runtime
|
||||
ARG JAVA_REPO_SCHEME
|
||||
# Every build tool the `java` module configures: Maven itself (already part
|
||||
# of this image), Gradle, Ivy and Leiningen (all packaged for this Ubuntu
|
||||
# base), and SBT (no package available, fetched as a plain release tarball).
|
||||
@@ -43,12 +44,23 @@ RUN java -jar /usr/share/java/ivy.jar -settings /root/.ivy2/ivysettings.xml \
|
||||
-retrieve "/tmp/ivyretrieve/[artifact]-[revision].[ext]" \
|
||||
&& test -f /tmp/ivyretrieve/idconfiguratortestpkg-0.0.1.jar
|
||||
|
||||
# Leiningen's standalone launcher unconditionally refuses any plain-HTTP
|
||||
# repository ("Tried to use insecure HTTP repository without TLS") before
|
||||
# even reading project.clj/profiles.clj - there is no `:insecure` key or
|
||||
# other configuration escape hatch for this (confirmed from Leiningen's own
|
||||
# source: leiningen.core.main/-main registers an aborting wagon for the
|
||||
# "http" scheme unconditionally). So this check is skipped for the
|
||||
# module-java-http variant: no id-configurator config could make it pass.
|
||||
RUN mkdir -p /tmp/leintest && cd /tmp/leintest \
|
||||
&& cat > project.clj <<'EOF'
|
||||
(defproject leintest "0.1.0"
|
||||
:dependencies [[org.interdiode/idconfiguratortestpkg "0.0.1"]])
|
||||
EOF
|
||||
RUN cd /tmp/leintest && lein deps :tree | grep -q idconfiguratortestpkg
|
||||
RUN if [ "$JAVA_REPO_SCHEME" = "https" ]; then \
|
||||
cd /tmp/leintest && lein deps :tree | grep -q idconfiguratortestpkg; \
|
||||
else \
|
||||
echo "skipping leiningen: it cannot use a non-HTTPS repository"; \
|
||||
fi
|
||||
|
||||
RUN mkdir -p /tmp/sbttest/project \
|
||||
&& cat > /tmp/sbttest/build.sbt <<'EOF'
|
||||
|
||||
+17
-16
@@ -339,21 +339,7 @@ def test_apply_writes_sbt_repositories(tmp_path) -> None:
|
||||
)
|
||||
|
||||
|
||||
def test_apply_writes_lein_profiles(tmp_path) -> None:
|
||||
dst = tmp_path / "dst"
|
||||
context = Context(config=make_config(TWO_REPOS_CONFIG), dst=dst, src=None)
|
||||
|
||||
JavaModule().apply(context)
|
||||
|
||||
profiles = (dst / "root/.lein/profiles.clj").read_text(encoding="utf-8")
|
||||
assert profiles == (
|
||||
"{:user {:repositories "
|
||||
'[["interdiode" {:url "https://example.invalid/maven"}] '
|
||||
'["interdiode-extra" {:url "https://example2.invalid/maven"}]]}}\n'
|
||||
)
|
||||
|
||||
|
||||
def test_apply_marks_non_https_lein_repository_as_insecure(tmp_path) -> None:
|
||||
def test_apply_marks_non_https_sbt_repository_as_insecure(tmp_path) -> None:
|
||||
data = {
|
||||
"uuid": "12345678-1234-5678-1234-567812345678",
|
||||
"organisation": "InterDiode",
|
||||
@@ -370,10 +356,25 @@ def test_apply_marks_non_https_lein_repository_as_insecure(tmp_path) -> None:
|
||||
|
||||
JavaModule().apply(context)
|
||||
|
||||
repositories = (dst / "root/.sbt/repositories").read_text(encoding="utf-8")
|
||||
assert repositories == (
|
||||
"[repositories]\n"
|
||||
" local\n"
|
||||
" interdiode: http://example.invalid/maven, allowInsecureProtocol\n"
|
||||
)
|
||||
|
||||
|
||||
def test_apply_writes_lein_profiles(tmp_path) -> None:
|
||||
dst = tmp_path / "dst"
|
||||
context = Context(config=make_config(TWO_REPOS_CONFIG), dst=dst, src=None)
|
||||
|
||||
JavaModule().apply(context)
|
||||
|
||||
profiles = (dst / "root/.lein/profiles.clj").read_text(encoding="utf-8")
|
||||
assert profiles == (
|
||||
"{:user {:repositories "
|
||||
'[["interdiode" {:url "http://example.invalid/maven" :insecure true}]]}}\n'
|
||||
'[["interdiode" {:url "https://example.invalid/maven"}] '
|
||||
'["interdiode-extra" {:url "https://example2.invalid/maven"}]]}}\n'
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ set_env =
|
||||
JAVA_REPO_SCHEME = https
|
||||
commands =
|
||||
python3 -m id_tools test render-config {tox_root}/tests/configs/Java.yaml.j2 {env_dir}/configs/Java.yaml
|
||||
docker buildx build --platform linux/amd64 --add-host=host.docker.internal:host-gateway --build-context generated-config={env_dir}/configs -f {tox_root}/tests/dockerfiles/Java.Dockerfile -t id-configurator-java .
|
||||
docker buildx build --platform linux/amd64 --add-host=host.docker.internal:host-gateway --build-arg JAVA_REPO_SCHEME={env:JAVA_REPO_SCHEME} --build-context generated-config={env_dir}/configs -f {tox_root}/tests/dockerfiles/Java.Dockerfile -t id-configurator-java .
|
||||
docker rmi id-configurator-java
|
||||
|
||||
[testenv:module-java-http]
|
||||
@@ -323,12 +323,14 @@ docker =
|
||||
allowlist_externals =
|
||||
docker
|
||||
description =
|
||||
Same as module-java, but against a plain-HTTP repository.
|
||||
Same as module-java, but against a plain-HTTP repository. Leiningen is
|
||||
skipped here (see Java.Dockerfile): it refuses any non-HTTPS repository
|
||||
unconditionally, with no configuration able to change that.
|
||||
set_env =
|
||||
JAVA_REPO_SCHEME = http
|
||||
commands =
|
||||
python3 -m id_tools test render-config {tox_root}/tests/configs/Java.yaml.j2 {env_dir}/configs/Java.yaml
|
||||
docker buildx build --platform linux/amd64 --add-host=host.docker.internal:host-gateway --build-context generated-config={env_dir}/configs -f {tox_root}/tests/dockerfiles/Java.Dockerfile -t id-configurator-java-http .
|
||||
docker buildx build --platform linux/amd64 --add-host=host.docker.internal:host-gateway --build-arg JAVA_REPO_SCHEME={env:JAVA_REPO_SCHEME} --build-context generated-config={env_dir}/configs -f {tox_root}/tests/dockerfiles/Java.Dockerfile -t id-configurator-java-http .
|
||||
docker rmi id-configurator-java-http
|
||||
|
||||
[docker:certificate-repo]
|
||||
|
||||
Reference in New Issue
Block a user