Skip to content

Commit

Permalink
Add option to notify systemd on startup
Browse files Browse the repository at this point in the history
Because this loads a native library, it requires Java 21 with preview features enables.
  • Loading branch information
gartens committed Jun 7, 2024
1 parent 554226d commit 01c756f
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 19 deletions.
12 changes: 8 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ sourceSets {
}
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
}

tasks.withType(JavaCompile).configureEach {
options.encoding = "UTF-8"
sourceCompatibility = "11"
targetCompatibility = "11"
options.compilerArgs += "--enable-preview"
}


configurations {
webjars
}
Expand Down Expand Up @@ -175,7 +179,7 @@ artifacts {


task extractWebjars(type: Copy) {
configurations.webjars.each {jar ->
configurations.webjars.each { jar ->
from zipTree(jar)
into "$buildDir/webjars"
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,6 @@ String getStatus() {
}


public int checkForAnyRunningPolyphenyInstances() {
return Integer.parseInt( executeGet( "/control/checkAnyRunningPolyphenyInstances" ) );
}


private String executeGet( String command ) {
HttpResponse<String> httpResponse;
try {
Expand All @@ -191,15 +186,6 @@ private String executeGet( String command ) {
}


private void executePost( String command, String data ) {
try {
Unirest.post( controlUrl + command ).body( data ).asString();
} catch ( UnirestException e ) {
log.error( "Exception while sending request", e );
}
}


private class WebSocket extends WebSocketClient {

private final Gson gson = new Gson();
Expand Down
48 changes: 47 additions & 1 deletion src/main/java/org/polypheny/control/main/ControlCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
import com.github.rvesse.airline.annotations.Command;
import com.github.rvesse.airline.annotations.Option;
import com.typesafe.config.Config;
import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.Linker;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SymbolLookup;
import java.lang.foreign.ValueLayout;
import java.lang.invoke.MethodHandle;
import java.util.HashMap;
import org.polypheny.control.authentication.AuthenticationFileManager;
import org.polypheny.control.control.ConfigManager;
Expand All @@ -31,7 +38,10 @@
public class ControlCommand extends AbstractCommand {

@Option(name = { "-p", "--port" }, description = "Overwrite port of the Polypheny Control dashboard and API.")
private final int port = -1;
private int port = -1;

@Option(name = { "--notify" }, description = "Notify systemd when server is listening.")
private boolean notify = false;

@Option(name = { "-x", "--suppress-warning" }, description = "Suppress the auth warnings on startup.")
protected boolean suppressWarning = false;
Expand Down Expand Up @@ -63,6 +73,16 @@ public int _run_() {
server = new Server( control, ConfigManager.getConfig().getInt( "pcrtl.control.port" ) );
}

if ( notify ) {
try {
notifySystemd();
} catch ( Throwable t ) {
server.shutdown();
System.err.println( "Failed to notify systemd: " + t.getMessage() );
return 1;
}
}

Runtime.getRuntime().addShutdownHook( new Thread( () -> running = false ) );

while ( running ) {
Expand All @@ -80,6 +100,32 @@ public int _run_() {
}


@SuppressWarnings("preview")
private static void notifySystemd() {
// When adding another architecture, ensure that the sizes of the types below are correct.
if ( !System.getProperty( "os.arch" ).equals( "amd64" ) ) {
throw new RuntimeException( "Unexpected OS architecture" );
}
try ( Arena a = Arena.ofConfined() ) {
Linker l = Linker.nativeLinker();
SymbolLookup systemd = SymbolLookup.libraryLookup( "libsystemd.so.0", a );
MethodHandle sd_notify = l.downcallHandle(
systemd.find( "sd_notify" ).orElseThrow(),
FunctionDescriptor.ofVoid( ValueLayout.JAVA_INT, ValueLayout.ADDRESS )
);
MemorySegment m = a.allocateUtf8String( "READY=1" );
sd_notify.invokeExact( 0, m );
} catch ( IllegalArgumentException e ) {
if ( e.getMessage().contains( "Cannot open library" ) ) {
throw new RuntimeException( "libsystemd is required for --notify" );
}
throw e;
} catch ( Throwable e ) {
throw new RuntimeException( e );
}
}


private static void warnNoUserAccounts() {
System.out.println( "WARNING: No Users Exist. Polypheny-Control executes and manages Polypheny-DB." );
System.out.println( "WARNING: For security reasons it is advisable to create at least one user." );
Expand Down

0 comments on commit 01c756f

Please sign in to comment.