Improve FREEd PID1
[gpl/argeo-freed.git] / sjbin / src / freed-pid1.java
diff --git a/sjbin/src/freed-pid1.java b/sjbin/src/freed-pid1.java
new file mode 100644 (file)
index 0000000..0239cb7
--- /dev/null
@@ -0,0 +1,116 @@
+//#! /usr/bin/java --source 17 @/usr/local/etc/freed/pid1/jvm.args
+
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.TreeMap;
+
+import org.argeo.init.Service;
+
+import jdk.jshell.tool.JavaShellToolBuilder;
+import sun.misc.Signal;
+
+class FreedPid1 {
+       public static void main(String... args) {
+               final long pid = ProcessHandle.current().pid();
+               System.out.println("FREEd Init daemon starting with pid " + pid + "...");
+//             System.out.println(System.getProperty("user.dir"));
+//             System.out.println(System.getProperty("user.name"));
+//             System.out.println(System.getProperty("user.home"));
+
+               // System.setProperty("user.dir", "/tmp");
+               for (Object key : new TreeMap<>(System.getProperties()).keySet()) {
+                       System.out.println(key + "=" + System.getProperty(key.toString()));
+               }
+
+               System.out.flush();
+
+               Signal.handle(new Signal("TERM"), (signal) -> {
+                       System.out.println("SIGTERM caught");
+                       System.exit(0);
+               });
+               Signal.handle(new Signal("INT"), (signal) -> {
+                       System.out.println("SIGINT caught");
+                       System.exit(0);
+               });
+               Signal.handle(new Signal("HUP"), (signal) -> {
+                       System.out.println("SIGHUP caught");
+                       System.exit(0);
+               });
+
+               if (args.length > 0 && ("1".equals(args[0]) //
+                               || "single".equals(args[0]) //
+                               || "emergency".equals(args[0]))) {
+                       // TODO check if we can remove dependency to management
+                       String classpath = ManagementFactory.getRuntimeMXBean().getClassPath();
+                       String feedbackMode = "concise";
+                       // TODO --startup script
+                       JavaShellToolBuilder builder = JavaShellToolBuilder.builder();
+                       try {
+                               builder.start("--execution", "direct", "--class-path", classpath, "--feedback", feedbackMode);
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                               System.err.flush();
+                               System.exit(1);
+                               return;
+                       }
+
+               } else {
+                       // init Linux services
+                       initSysctl();
+                       startInitDService("networking");
+                       startInitDService("nslcd");
+
+                       waitForNetwork();
+
+                       // init Argeo CMS
+                       Service.main(args);
+               }
+       }
+
+       static void initSysctl() {
+               try {
+                       Path sysctlD = Paths.get("/etc/sysctl.d/");
+                       for (Path conf : Files.newDirectoryStream(sysctlD, "*.conf")) {
+                               try {
+                                       new ProcessBuilder("/usr/sbin/sysctl", "-p", conf.toString()).start();
+                               } catch (IOException e) {
+                                       e.printStackTrace();
+                               }
+                       }
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       static void startInitDService(String serviceName) {
+               Path serviceInit = Paths.get("/etc/init.d/", serviceName);
+               if (Files.exists(serviceInit))
+                       try {
+                               new ProcessBuilder(serviceInit.toString(), "start").start().waitFor();
+                               System.out.println("Service " + serviceName + " started");
+                               Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+                                       try {
+                                               new ProcessBuilder(serviceInit.toString(), "stop").start().waitFor();
+                                       } catch (IOException | InterruptedException e) {
+                                               e.printStackTrace();
+                                       }
+                               }, "Stop service " + serviceName));
+                       } catch (IOException | InterruptedException e) {
+                               e.printStackTrace();
+                       }
+               else
+                       System.out.println("Service " + serviceName + " not found and therefore not started");
+       }
+
+       static void waitForNetwork() {
+               // TODO Do it properly
+               try {
+                       Thread.sleep(1000);
+               } catch (InterruptedException e) {
+                       e.printStackTrace();
+               }
+       }
+}