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.
|
- Ivy: `~/.ivy2/ivysettings.xml`, as a chain of `ibiblio` resolvers.
|
||||||
- SBT: `~/.sbt/repositories`, the resolver override file SBT reads for its
|
- SBT: `~/.sbt/repositories`, the resolver override file SBT reads for its
|
||||||
own bootstrapping and, when combined with the `sbt.override.build.repos`
|
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`
|
- Leiningen: `~/.lein/profiles.clj`, adding the repositories to the `:user`
|
||||||
profile. Leiningen, alone among these, refuses a plain-HTTP repository
|
profile. Leiningen, alone among these, refuses a plain-HTTP repository
|
||||||
outright ("Tried to use insecure HTTP repository without TLS"); a
|
outright ("Tried to use insecure HTTP repository without TLS") - its
|
||||||
repository whose URL isn't HTTPS gets `:insecure true` added to its entry,
|
standalone `lein` launcher (`leiningen.core.main/-main`) unconditionally
|
||||||
Leiningen's own documented escape hatch for this.
|
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
|
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))
|
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(
|
def _write_sbt_repositories(
|
||||||
context: Context, repositories: list[JavaRepository]
|
context: Context, repositories: list[JavaRepository]
|
||||||
) -> None:
|
) -> None:
|
||||||
lines = ["[repositories]", " local"]
|
lines = ["[repositories]", " local"]
|
||||||
lines.extend(
|
lines.extend(_sbt_repository_line(repository) for repository in repositories)
|
||||||
f" {repository.name}: {repository.url}" for repository in repositories
|
|
||||||
)
|
|
||||||
context.write_file(_SBT_REPOSITORIES, ("\n".join(lines) + "\n").encode("utf-8"))
|
context.write_file(_SBT_REPOSITORIES, ("\n".join(lines) + "\n").encode("utf-8"))
|
||||||
logger.info("configured sbt to use %d repositories", len(repositories))
|
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:
|
def _write_lein_profiles(context: Context, repositories: list[JavaRepository]) -> None:
|
||||||
entries = " ".join(
|
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"
|
content = f"{{:user {{:repositories [{entries}]}}}}\n"
|
||||||
context.write_file(_LEIN_PROFILES, content.encode("utf-8"))
|
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
|
COPY --from=generated-config Java.yaml /config.yaml
|
||||||
RUN id-configurator apply --config /config.yaml --src /src --dst /dst
|
RUN id-configurator apply --config /config.yaml --src /src --dst /dst
|
||||||
FROM target AS runtime
|
FROM target AS runtime
|
||||||
|
ARG JAVA_REPO_SCHEME
|
||||||
# Every build tool the `java` module configures: Maven itself (already part
|
# Every build tool the `java` module configures: Maven itself (already part
|
||||||
# of this image), Gradle, Ivy and Leiningen (all packaged for this Ubuntu
|
# of this image), Gradle, Ivy and Leiningen (all packaged for this Ubuntu
|
||||||
# base), and SBT (no package available, fetched as a plain release tarball).
|
# 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]" \
|
-retrieve "/tmp/ivyretrieve/[artifact]-[revision].[ext]" \
|
||||||
&& test -f /tmp/ivyretrieve/idconfiguratortestpkg-0.0.1.jar
|
&& 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 \
|
RUN mkdir -p /tmp/leintest && cd /tmp/leintest \
|
||||||
&& cat > project.clj <<'EOF'
|
&& cat > project.clj <<'EOF'
|
||||||
(defproject leintest "0.1.0"
|
(defproject leintest "0.1.0"
|
||||||
:dependencies [[org.interdiode/idconfiguratortestpkg "0.0.1"]])
|
:dependencies [[org.interdiode/idconfiguratortestpkg "0.0.1"]])
|
||||||
EOF
|
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 \
|
RUN mkdir -p /tmp/sbttest/project \
|
||||||
&& cat > /tmp/sbttest/build.sbt <<'EOF'
|
&& 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:
|
def test_apply_marks_non_https_sbt_repository_as_insecure(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:
|
|
||||||
data = {
|
data = {
|
||||||
"uuid": "12345678-1234-5678-1234-567812345678",
|
"uuid": "12345678-1234-5678-1234-567812345678",
|
||||||
"organisation": "InterDiode",
|
"organisation": "InterDiode",
|
||||||
@@ -370,10 +356,25 @@ def test_apply_marks_non_https_lein_repository_as_insecure(tmp_path) -> None:
|
|||||||
|
|
||||||
JavaModule().apply(context)
|
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")
|
profiles = (dst / "root/.lein/profiles.clj").read_text(encoding="utf-8")
|
||||||
assert profiles == (
|
assert profiles == (
|
||||||
"{:user {:repositories "
|
"{: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
|
JAVA_REPO_SCHEME = https
|
||||||
commands =
|
commands =
|
||||||
python3 -m id_tools test render-config {tox_root}/tests/configs/Java.yaml.j2 {env_dir}/configs/Java.yaml
|
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
|
docker rmi id-configurator-java
|
||||||
|
|
||||||
[testenv:module-java-http]
|
[testenv:module-java-http]
|
||||||
@@ -323,12 +323,14 @@ docker =
|
|||||||
allowlist_externals =
|
allowlist_externals =
|
||||||
docker
|
docker
|
||||||
description =
|
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 =
|
set_env =
|
||||||
JAVA_REPO_SCHEME = http
|
JAVA_REPO_SCHEME = http
|
||||||
commands =
|
commands =
|
||||||
python3 -m id_tools test render-config {tox_root}/tests/configs/Java.yaml.j2 {env_dir}/configs/Java.yaml
|
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 rmi id-configurator-java-http
|
||||||
|
|
||||||
[docker:certificate-repo]
|
[docker:certificate-repo]
|
||||||
|
|||||||
Reference in New Issue
Block a user