config to start docker and runner at startup #3

Merged
wanjakrah merged 1 commits from feature/s4-gitea-ci into main 2026-10-29 21:17:42 +01:00
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

View File

@@ -158,10 +158,17 @@ Een bestaande registratie wordt hergebruikt. Er worden geen secrets in de
repository geschreven. Bewaar het tokenbestand alleen zolang registratie/herstel
dat nodig heeft en behandel `.runner` als credential.
De gebruikersservice start bij een gebruikerssessie. Automatisch doorlopen zonder
inloggen vereist daarnaast een bewuste keuze voor user lingering en een Docker-
daemon die zonder desktopsessie beschikbaar is. S4 belooft geen beschikbaarheid
wanneer de mini-pc uitstaat. Herstarten/stoppen:
Op de mini-pc starten Docker Desktop en de runner automatisch na grafisch
aanmelden. Bij een Docker Desktop-socket installeert de installer hiervoor
`~/.config/systemd/user/agiledancers-runner.service.d/10-agiledancers-docker-desktop.conf`
en schakelt beide services in voor `graphical-session.target`. De runner wacht
via `~/.local/share/agiledancers-runner/WaitForDocker.java` maximaal 120 seconden
tot de ingestelde Docker-engine bereikbaar is. Bij een mislukte start probeert
systemd het na tien seconden opnieuw. De runner volgt stoppen en herstarten van
Docker Desktop en stopt bij afmelden.
User lingering staat op deze pc uit: vóór aanmelden starten deze services niet.
S4 belooft geen beschikbaarheid wanneer de mini-pc uitstaat. Herstarten/stoppen:
```sh
systemctl --user restart agiledancers-runner