aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/set_versions.py
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2023-03-15 04:49:06 +0400
committerGravatar Hassan Abouelela <[email protected]>2023-03-15 04:49:06 +0400
commit47a9e0d72d5225f9c503775530d4e5f0ff63fe6d (patch)
treedbbe21c54d5ae66215b576ba998fd5dbf2e6f679 /scripts/set_versions.py
parentUpdate Sentry SDK to support Falcon 3 (diff)
Add Multi-version Capability
Adds support for having multiple evaluation python versions installed in the docker container. A utility to automatically generate correct dockerfile instructions and nsjail mounts based on the available versions is also included. Signed-off-by: Hassan Abouelela <[email protected]>
Diffstat (limited to 'scripts/set_versions.py')
-rw-r--r--scripts/set_versions.py68
1 files changed, 68 insertions, 0 deletions
diff --git a/scripts/set_versions.py b/scripts/set_versions.py
new file mode 100644
index 0000000..f98c52c
--- /dev/null
+++ b/scripts/set_versions.py
@@ -0,0 +1,68 @@
+"""Generate a Dockerfile from in.Dockerfile and a version JSON file, and write version info."""
+
+import re
+from pathlib import Path
+from textwrap import dedent
+
+from scripts import python_version
+
+DOCKERFILE_TEMPLATE = Path("scripts/in.Dockerfile").read_text("utf-8")
+DOCKERFILE = Path("Dockerfile")
+JAIL_CONFIG = Path("config/snekbox.cfg")
+
+versions, main_version = python_version.get_all_versions()
+
+# Download and copy multiple python images into one layer
+python_build = ""
+jail_mounts = ""
+previous_layer = "first"
+
+for version in versions:
+ # Configure NSJail mounts
+ jail_mounts += dedent(
+ f"""
+ mount {{
+ src: "/usr/local/bin/python{version.version_name}"
+ dst: "/usr/local/bin/python{version.version_name}"
+ is_bind: true
+ rw: false
+ }}
+ """
+ )
+
+ if version.is_main:
+ # Main is handled separately later
+ continue
+
+ # Add the current version to the Dockerfile
+ layer_name = version.version_name.replace(".", "-") # Dots aren't valid in layer names
+ python_build += dedent(
+ f"""
+ FROM python:{version.image_tag} as base-{layer_name}
+ COPY --from=base-{previous_layer} / /
+ """
+ )
+ previous_layer = layer_name
+
+# Main version is installed twice, once at the very beginning to make sure
+# its files aren't overwritten, and once at the end which actually makes use of the version
+python_build = f"FROM python:{main_version.image_tag} as base-first\n" + python_build
+
+# Update mounts for python binaries in the NSJail config
+new_config = re.sub(
+ r"(?<=# mount-section-key)[\s\S]+(?=# mount-section-key-end)",
+ jail_mounts,
+ JAIL_CONFIG.read_text("utf-8"),
+)
+JAIL_CONFIG.write_text(new_config, "utf-8")
+
+# Write new dockerfile
+DOCKERFILE.write_text(
+ "# THIS FILE IS AUTOGENERATED, DO NOT MODIFY! #\n"
+ + DOCKERFILE_TEMPLATE.replace("{python_install_commands}", python_build)
+ .replace("{final_base}", previous_layer)
+ .replace("{main_version_tag}", main_version.image_tag),
+ "utf-8",
+)
+
+print("Finished!")