config to start docker and runner at startup
All checks were successful
Build, test and publish / verify (push) Successful in 1m15s

This commit is contained in:
2026-10-29 21:16:31 +01:00
parent b0c2f28e13
commit 8ae2c16fee
5 changed files with 72 additions and 4 deletions

View File

@@ -108,10 +108,20 @@ class Setup {
Pipeline.check(actual.contains("v0.2.13"), "Expected runner v0.2.13");
privateWrite(runnerDir.resolve("config.yaml"),Files.readString(root.resolve("ci/runner/config.yaml")));
Files.copy(root.resolve("ci/runner/agiledancers-runner.service"),units.resolve("agiledancers-runner.service"),StandardCopyOption.REPLACE_EXISTING);
Files.copy(root.resolve("ci/runner/WaitForDocker.java"),runnerDir.resolve("WaitForDocker.java"),StandardCopyOption.REPLACE_EXISTING);
String dockerHost = env.get("DOCKER_HOST");
if (dockerHost == null || dockerHost.isBlank()) dockerHost = commands.execute(List.of("docker","context","inspect","--format","{{.Endpoints.docker.Host}}"),root,env,null,false).checked();
String path = javaHome + "/bin:" + executable(env,"node").getParent() + ":" + executable(env,"mvn").getParent() + ":/usr/local/bin:/usr/bin:/bin";
privateWrite(configDir.resolve("environment"),"JAVA_HOME=" + quoted(javaHome) + "\nPATH=" + quoted(path) + "\nDOCKER_HOST=" + quoted(dockerHost) + "\n");
boolean desktop = dockerHost.endsWith("/.docker/desktop/docker.sock");
Path overrides = units.resolve("agiledancers-runner.service.d");
Path desktopOverride = overrides.resolve("10-agiledancers-docker-desktop.conf");
if (desktop) {
Files.createDirectories(overrides);
Files.copy(root.resolve("ci/runner/docker-desktop.conf"),desktopOverride,StandardCopyOption.REPLACE_EXISTING);
} else {
Files.deleteIfExists(desktopOverride);
}
commands.execute(List.of("systemctl","--user","daemon-reload"),root,env,null,true).checked();
if (prepareOnly) { System.out.println("Runner installed; registration and startup still required."); return; }
commands.execute(List.of("docker","info"),root,env,null,false).checked();
@@ -123,6 +133,11 @@ class Setup {
"--name","agiledancers-mini-pc","--labels","agiledancers-mini-pc:host","--token",token),runnerDir,env,null,true).checked();
Files.setPosixFilePermissions(runnerDir.resolve(".runner"),PosixFilePermissions.fromString("rw-------"));
}
if (desktop) {
commands.execute(List.of("systemctl","--user","enable","--now","docker-desktop.service"),root,env,null,true).checked();
// Replace any previous default.target link with the desktop-login target.
commands.execute(List.of("systemctl","--user","disable","agiledancers-runner.service"),root,env,null,true).checked();
}
commands.execute(List.of("systemctl","--user","enable","--now","agiledancers-runner.service"),root,env,null,true).checked();
System.out.println("Runner registered and started; keep the mini-PC and Docker available.");
}

View File

@@ -0,0 +1,35 @@
import java.time.Duration;
import java.util.concurrent.TimeUnit;
/** Source-launcher startup probe; uses the service's configured DOCKER_HOST. */
class WaitForDocker {
public static void main(String[] args) throws Exception {
long seconds = args.length == 0 ? 120 : Long.parseLong(args[0]);
if (seconds < 1 || seconds > 300) throw new IllegalArgumentException("Timeout must be 1–300 seconds");
long deadline = System.nanoTime() + Duration.ofSeconds(seconds).toNanos();
System.out.println("Waiting for the configured Docker engine...");
while (System.nanoTime() < deadline) {
Process process = new ProcessBuilder("docker", "info", "--format", "{{.ServerVersion}}")
.redirectOutput(ProcessBuilder.Redirect.DISCARD)
.redirectError(ProcessBuilder.Redirect.DISCARD)
.start();
try {
long remaining = Math.max(1, deadline - System.nanoTime());
if (process.waitFor(Math.min(remaining, TimeUnit.SECONDS.toNanos(5)), TimeUnit.NANOSECONDS)
&& process.exitValue() == 0) {
System.out.println("Docker is available; starting the Gitea runner.");
return;
}
} finally {
if (process.isAlive()) {
process.destroyForcibly();
process.waitFor();
}
}
long remaining = deadline - System.nanoTime();
if (remaining > 0) TimeUnit.NANOSECONDS.sleep(Math.min(remaining, TimeUnit.SECONDS.toNanos(2)));
}
System.err.println("Docker did not become available within " + seconds + " seconds; runner not started.");
System.exit(1);
}
}

View File

@@ -7,6 +7,8 @@ Wants=network-online.target
Type=simple
WorkingDirectory=%h/.local/share/agiledancers-runner
EnvironmentFile=%h/.config/agiledancers-runner/environment
ExecStartPre=/usr/bin/env java %h/.local/share/agiledancers-runner/WaitForDocker.java 120
TimeoutStartSec=150
ExecStart=%h/.local/bin/act_runner daemon --config %h/.local/share/agiledancers-runner/config.yaml
Restart=on-failure
RestartSec=10

View File

@@ -0,0 +1,9 @@
# Desktop-specific override: start after graphical login, alongside Docker Desktop.
[Unit]
Requires=docker-desktop.service
After=graphical-session.target docker-desktop.service
PartOf=graphical-session.target docker-desktop.service
[Install]
WantedBy=
WantedBy=graphical-session.target