summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile22
-rwxr-xr-xcompile-and-run.sh24
-rw-r--r--compose.yml7
-rw-r--r--entrypoint.sh6
-rw-r--r--generate-status-object.php30
-rw-r--r--httpd-foreground7
-rw-r--r--httpd.conf97
-rw-r--r--public/index.php61
8 files changed, 204 insertions, 50 deletions
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..387023f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,22 @@
+FROM docker:27-dind AS apache
+USER root
+RUN apk update && \
+ apk add --no-cache \
+ bash \
+ coreutils \
+ su-exec \
+ apache2 \
+ php83-apache2 \
+ php83-session
+RUN adduser -D apache2 && \
+ addgroup apache2 docker
+RUN mkdir -p /root/.docker && \
+ chmod -R 0777 /root/.docker
+RUN chmod 4755 /sbin/su-exec
+COPY --chmod=777 httpd-foreground /usr/local/bin/
+COPY --chmod=777 entrypoint.sh /usr/local/bin/
+COPY --chmod=777 . /opt/application
+COPY httpd.conf /etc/apache2/httpd.conf
+ENV IS_IN_DOCKER=1
+EXPOSE 80
+CMD ["/usr/local/bin/entrypoint.sh"]
diff --git a/compile-and-run.sh b/compile-and-run.sh
index 64bacb1..423206e 100755
--- a/compile-and-run.sh
+++ b/compile-and-run.sh
@@ -2,6 +2,8 @@
source ./functions.sh
+unset DOCKER_HOST
+
if [ "$1" == "" ]; then
echo "Parameter 1 is empty"
exit 1
@@ -28,7 +30,8 @@ exec_path="$(realpath "$exec_path")"
results_path="$(realpath "$results_path")"
pushd containers/compiler > /dev/null
-compiler_image=$(docker build -q .) || exit 1
+compiler_image="ic$runner_id"
+docker build -q -t $compiler_image . || exit 1
catch compiler_stdout compiler_stderr docker run \
--rm \
--network none \
@@ -47,12 +50,13 @@ printf '%s' "$compiler_stdout" > $results_path/c.0
printf '%s' "$compiler_stderr" > $results_path/c.1
if [ $compiler_status -eq 0 ]; then
- runner_image=$(\
- docker build \
- --build-arg "EXEC_DIR_HOST=$exec_path_relative" \
- -q \
- -f "containers/runner/Dockerfile" .
- ) || exit 1
+ runner_image="ir$runner_id"
+ docker build \
+ --build-arg "EXEC_DIR_HOST=$exec_path_relative" \
+ -q \
+ -t "$runner_image" \
+ -f "containers/runner/Dockerfile" . \
+ || exit 1
catch runner_stdout runner_stderr timeout 60 docker run \
--rm \
-h "java-runner-$runner_id" \
@@ -60,7 +64,7 @@ if [ $compiler_status -eq 0 ]; then
--cpus=0.25 \
--network none \
-e "APPLICATION_NAME=$application_name" \
- $runner_image
+ "$runner_image"
runner_status=$?
docker image rm -f $runner_image > /dev/null || exit 1
@@ -68,7 +72,3 @@ if [ $compiler_status -eq 0 ]; then
printf '%s' "$runner_stdout" > $results_path/r.0
printf '%s' "$runner_stderr" > $results_path/r.1
fi
-
-php generate-status-object.php $runner_id
-
-rm -rf "$runner_dir"
diff --git a/compose.yml b/compose.yml
new file mode 100644
index 0000000..056bd4f
--- /dev/null
+++ b/compose.yml
@@ -0,0 +1,7 @@
+services:
+ main:
+ build: .
+ privileged: true
+ ports:
+ - 13821:80
+ environment: {}
diff --git a/entrypoint.sh b/entrypoint.sh
new file mode 100644
index 0000000..7914676
--- /dev/null
+++ b/entrypoint.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+cd /usr/local/bin/
+./dockerd-entrypoint.sh &
+./httpd-foreground &
+wait
diff --git a/generate-status-object.php b/generate-status-object.php
deleted file mode 100644
index 9d19070..0000000
--- a/generate-status-object.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-if (empty($argv[1])) {
- file_put_contents("php://stderr", "No runner ID specified");
- exit(1);
-}
-
-define("WORK_DIR", __DIR__ . "/_runners/" . $argv[1] . "/results");
-
-function get(string $name): ?string {
- $file = WORK_DIR . "/" . $name;
- if (!is_file($file))
- return null;
- return file_get_contents($file);
-}
-
-$data = [
- "compile" => [
- "status" => get("c.s"),
- "stdout" => get("c.0"),
- "stderr" => get("c.1"),
- ],
- "run" => [
- "status" => get("r.s"),
- "stdout" => get("r.0"),
- "stderr" => get("r.1"),
- ],
-];
-
-echo json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . PHP_EOL;
diff --git a/httpd-foreground b/httpd-foreground
new file mode 100644
index 0000000..e896168
--- /dev/null
+++ b/httpd-foreground
@@ -0,0 +1,7 @@
+#!/bin/sh
+set -e
+
+# Apache gets grumpy about PID files pre-existing
+rm -f /usr/local/apache2/logs/httpd.pid
+
+exec httpd -DFOREGROUND "$@"
diff --git a/httpd.conf b/httpd.conf
new file mode 100644
index 0000000..0ddc08d
--- /dev/null
+++ b/httpd.conf
@@ -0,0 +1,97 @@
+ServerTokens OS
+
+ServerRoot /var/www
+
+Listen 80
+
+LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
+LoadModule authn_file_module modules/mod_authn_file.so
+LoadModule authn_core_module modules/mod_authn_core.so
+LoadModule authz_host_module modules/mod_authz_host.so
+LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
+LoadModule authz_user_module modules/mod_authz_user.so
+LoadModule authz_core_module modules/mod_authz_core.so
+LoadModule access_compat_module modules/mod_access_compat.so
+LoadModule auth_basic_module modules/mod_auth_basic.so
+LoadModule reqtimeout_module modules/mod_reqtimeout.so
+LoadModule filter_module modules/mod_filter.so
+LoadModule mime_module modules/mod_mime.so
+LoadModule log_config_module modules/mod_log_config.so
+LoadModule env_module modules/mod_env.so
+LoadModule headers_module modules/mod_headers.so
+LoadModule setenvif_module modules/mod_setenvif.so
+LoadModule version_module modules/mod_version.so
+LoadModule unixd_module modules/mod_unixd.so
+LoadModule status_module modules/mod_status.so
+LoadModule autoindex_module modules/mod_autoindex.so
+LoadModule dir_module modules/mod_dir.so
+LoadModule alias_module modules/mod_alias.so
+
+LoadModule negotiation_module modules/mod_negotiation.so
+
+<IfModule unixd_module>
+User apache2
+Group apache2
+
+</IfModule>
+
+ServerAdmin you@example.com
+
+ServerSignature On
+
+ServerName localhost:80
+
+<Directory />
+ AllowOverride none
+ Require all denied
+</Directory>
+
+DocumentRoot "/opt/application/public"
+<Directory "/opt/application/public">
+ Options FollowSymLinks
+
+ AllowOverride All
+
+ Require all granted
+</Directory>
+
+<IfModule dir_module>
+ DirectoryIndex index.php index.html
+</IfModule>
+
+# <Files ".ht*">
+# Require all denied
+# </Files>
+
+#ErrorLog logs/error.log
+ErrorLog /proc/self/fd/2
+
+LogLevel warn
+
+<IfModule log_config_module>
+ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+ LogFormat "%h %l %u %t \"%r\" %>s %b" common
+
+ <IfModule logio_module>
+ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
+ </IfModule>
+
+ #CustomLog logs/access.log combined
+ CustomLog /proc/self/fd/1 combined
+</IfModule>
+
+<IfModule headers_module>
+ RequestHeader unset Proxy early
+</IfModule>
+
+<IfModule mime_module>
+ TypesConfig /etc/apache2/mime.types
+ AddType application/x-compress .Z
+ AddType application/x-gzip .gz .tgz
+</IfModule>
+
+<IfModule mime_magic_module>
+ MIMEMagicFile /etc/apache2/magic
+</IfModule>
+
+IncludeOptional /etc/apache2/conf.d/*.conf
diff --git a/public/index.php b/public/index.php
index 0b3cabc..5a77566 100644
--- a/public/index.php
+++ b/public/index.php
@@ -3,6 +3,13 @@
session_name("a3e0f0ee-9f5a-4be2-88cb-3b7ceb626d00");
session_start();
+function get(string $id, string $name): ?string {
+ $file = __DIR__ . "/../_runners/$id/results/" . $name;
+ if (!is_file($file))
+ return null;
+ return file_get_contents($file);
+}
+
function csrf_token(): string {
return $_SESSION["csrf-token"] = base64_encode(random_bytes(30));
}
@@ -53,24 +60,62 @@ if (isset($_POST["code"]) && strlen($_POST["code"]) <= 16383) {
exit;
}
- $srcDir = __DIR__ . "/../_runners/$id/src";
+ $runnerDir = __DIR__ . "/../_runners/$id";
+ $srcDir = $runnerDir . "/src";
mkdir($srcDir, recursive: true);
file_put_contents($srcDir . "/Program.java", $code);
+ $isInDocker = getenv("IS_IN_DOCKER") === "1";
+
+ if ($isInDocker)
+ file_put_contents("php://stderr", "[debug] In Docker\n");
chdir(__DIR__ . "/..");
- $resultStr = shell_exec("./compile-and-run.sh '$id' Program 2>/dev/null");
+
+ $stderrFile = sys_get_temp_dir() . "/tmp{$id}.2";
+ exec(
+ ($isInDocker ? "su-exec root " : "") .
+ "./compile-and-run.sh '$id' Program 2>'$stderrFile'", $resultStr, $code);
+ $resultStr = implode("\n", $resultStr);
+ if (is_file($stderrFile)) {
+ $stderrContents = file_get_contents($stderrFile);
+ unlink($stderrFile);
+ if (!empty($stderrContents)) {
+ file_put_contents("php://stderr", "compile-and-run.sh failed: $stderrContents\n");
+ if ($code != 0) {
+ echo json_encode([
+ "ok" => false,
+ "message" => "Execution failed:\n$stderrContents",
+ "csrf" => csrf_token(),
+ ]);
+ exit;
+ }
+ }
+ }
chdir(__DIR__);
+ file_put_contents("php://stderr", "result: $result\n");
$csrf = csrf_token();
- if (is_string($resultStr)) {
- $result = json_decode($resultStr, true);
- $result["runner"] = $id;
- $result["ok"] = true;
- $result["csrf"] = $csrf;
- }
+
+ $result = [
+ "compile" => [
+ "status" => get($id, "c.s"),
+ "stdout" => get($id, "c.0"),
+ "stderr" => get($id, "c.1"),
+ ],
+ "run" => [
+ "status" => get($id, "r.s"),
+ "stdout" => get($id, "r.0"),
+ "stderr" => get($id, "r.1"),
+ ],
+ "runner" => $id,
+ "ok" => true,
+ "csrf" => $csrf,
+ ];
+
+ delTree($runnerDir);
echo json_encode($result);
exit;