mirror of
https://github.com/usatiuk/dhfs.git
synced 2025-10-28 20:47:49 +01:00
Compare commits
11 Commits
686cc550db
...
fac2feb598
| Author | SHA1 | Date | |
|---|---|---|---|
| fac2feb598 | |||
| 3e8be87ad1 | |||
| 1a2f7fc32b | |||
| 49b16cda2f | |||
| 2bad240a21 | |||
| 5d88401775 | |||
| f3a6650cb7 | |||
| 53ba9dc12e | |||
| 3f6d66330a | |||
| 60ffc12c61 | |||
| e3e62467e4 |
@@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="Main 2" type="QsApplicationConfigurationType" factoryName="QuarkusApplication">
|
<configuration default="false" name="Main 2" type="QsApplicationConfigurationType" factoryName="QuarkusApplication">
|
||||||
<option name="MAIN_CLASS_NAME" value="com.usatiuk.dhfsfuse.Main" />
|
<option name="MAIN_CLASS_NAME" value="com.usatiuk.dhfsfuse.Main" />
|
||||||
<module name="dhfs-fuse" />
|
<module name="dhfs-fuse" />
|
||||||
<option name="VM_PARAMETERS" value="-XX:+UnlockDiagnosticVMOptions -XX:+UseParallelGC -XX:+DebugNonSafepoints --enable-preview --add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-exports java.base/jdk.internal.access=ALL-UNNAMED -ea -Xmx512M -Ddhfs.webui.root=$ProjectFileDir$/../webui/dist -Ddhfs.fuse.root=${HOME}/dhfs_test/2/fuse -Ddhfs.objects.persistence.files.root=${HOME}/dhfs_test/2/data -Ddhfs.objects.persistence.stuff.root=${HOME}/dhfs_test/2/data/stuff -Ddhfs.objects.peerdiscovery.broadcast=false -Dquarkus.http.port=9020 -Dquarkus.http.ssl-port=9021 -Ddhfs.peerdiscovery.preset-uuid=22000000-0000-0000-0000-000000000000 -Ddhfs.peerdiscovery.static-peers=11000000-0000-0000-0000-000000000000:127.0.0.1:9010:9011" />
|
<option name="VM_PARAMETERS" value="-XX:+UnlockDiagnosticVMOptions -XX:+UseParallelGC -XX:+DebugNonSafepoints --enable-preview --add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-exports java.base/jdk.internal.access=ALL-UNNAMED -ea -Xmx512M -Ddhfs.webui.root=$ProjectFileDir$/../webui/dist -Ddhfs.fuse.root=${HOME}/dhfs_test/2/fuse -Ddhfs.objects.persistence.root=${HOME}/dhfs_test/2/data -Ddhfs.objects.peerdiscovery.broadcast=false -Dquarkus.http.port=9020 -Dquarkus.http.ssl-port=9021 -Ddhfs.peerdiscovery.preset-uuid=22000000-0000-0000-0000-000000000000 -Ddhfs.peerdiscovery.static-peers=11000000-0000-0000-0000-000000000000:127.0.0.1:9010:9011" />
|
||||||
<extension name="coverage">
|
<extension name="coverage">
|
||||||
<pattern>
|
<pattern>
|
||||||
<option name="PATTERN" value="com.usatiuk.dhfs.remoteobj.*" />
|
<option name="PATTERN" value="com.usatiuk.dhfs.remoteobj.*" />
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<configuration default="false" name="Main" type="QsApplicationConfigurationType" factoryName="QuarkusApplication" nameIsGenerated="true">
|
<configuration default="false" name="Main" type="QsApplicationConfigurationType" factoryName="QuarkusApplication" nameIsGenerated="true">
|
||||||
<option name="MAIN_CLASS_NAME" value="com.usatiuk.dhfsfuse.Main" />
|
<option name="MAIN_CLASS_NAME" value="com.usatiuk.dhfsfuse.Main" />
|
||||||
<module name="dhfs-fuse" />
|
<module name="dhfs-fuse" />
|
||||||
<option name="VM_PARAMETERS" value="-XX:+UnlockDiagnosticVMOptions -XX:+UseZGC -XX:+ZGenerational --enable-preview -XX:+DebugNonSafepoints --add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-exports java.base/jdk.internal.access=ALL-UNNAMED -ea -Xmx1G -Ddhfs.webui.root=$ProjectFileDir$/../webui/dist -Ddhfs.fuse.root=${HOME}/dhfs_test/1/fuse -Ddhfs.objects.persistence.files.root=${HOME}/dhfs_test/1/data -Ddhfs.objects.persistence.stuff.root=${HOME}/dhfs_test/1/data/stuff -Ddhfs.objects.peerdiscovery.broadcast=true -Dquarkus.http.port=9010 -Dquarkus.http.ssl-port=9011 -Ddhfs.peerdiscovery.preset-uuid=11000000-0000-0000-0000-000000000000 -Ddhfs.peerdiscovery.static-peers=22000000-0000-0000-0000-000000000000:127.0.0.1:9020:9021 -Dquarkus.http.host=0.0.0.0" />
|
<option name="VM_PARAMETERS" value="-XX:+UnlockDiagnosticVMOptions -XX:+UseZGC -XX:+ZGenerational --enable-preview -XX:+DebugNonSafepoints --add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.nio=ALL-UNNAMED --add-exports java.base/jdk.internal.access=ALL-UNNAMED -ea -Xmx1G -Ddhfs.webui.root=$ProjectFileDir$/../webui/dist -Ddhfs.fuse.root=${HOME}/dhfs_test/1/fuse -Ddhfs.objects.persistence.root=${HOME}/dhfs_test/1/data -Ddhfs.objects.peerdiscovery.broadcast=true -Dquarkus.http.port=9010 -Dquarkus.http.ssl-port=9011 -Ddhfs.peerdiscovery.preset-uuid=11000000-0000-0000-0000-000000000000 -Ddhfs.peerdiscovery.static-peers=22000000-0000-0000-0000-000000000000:127.0.0.1:9020:9021 -Dquarkus.http.host=0.0.0.0" />
|
||||||
<extension name="coverage">
|
<extension name="coverage">
|
||||||
<pattern>
|
<pattern>
|
||||||
<option name="PATTERN" value="com.usatiuk.dhfs.remoteobj.*" />
|
<option name="PATTERN" value="com.usatiuk.dhfs.remoteobj.*" />
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
version: "3.2"
|
|
||||||
|
|
||||||
services:
|
|
||||||
dhfs1:
|
|
||||||
build: .
|
|
||||||
privileged: true
|
|
||||||
devices:
|
|
||||||
- /dev/fuse
|
|
||||||
volumes:
|
|
||||||
- $HOME/dhfs/dhfs1:/dhfs_root
|
|
||||||
- $HOME/dhfs/dhfs1_f:/dhfs_root/fuse:rshared
|
|
||||||
- ./target/quarkus-app:/app
|
|
||||||
command: "java --add-exports java.base/sun.nio.ch=ALL-UNNAMED
|
|
||||||
-Ddhfs.objects.persistence.files.root=/dhfs_root/p
|
|
||||||
-Ddhfs.objects.root=/dhfs_root/d
|
|
||||||
-Ddhfs.fuse.root=/dhfs_root/fuse -Dquarkus.http.host=0.0.0.0
|
|
||||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
|
|
||||||
-jar /app/quarkus-run.jar"
|
|
||||||
ports:
|
|
||||||
- 8080:8080
|
|
||||||
- 8081:8443
|
|
||||||
- 5005:5005
|
|
||||||
dhfs2:
|
|
||||||
build: .
|
|
||||||
privileged: true
|
|
||||||
devices:
|
|
||||||
- /dev/fuse
|
|
||||||
volumes:
|
|
||||||
- $HOME/dhfs/dhfs2:/dhfs_root
|
|
||||||
- $HOME/dhfs/dhfs2_f:/dhfs_root/fuse:rshared
|
|
||||||
- ./target/quarkus-app:/app
|
|
||||||
command: "java --add-exports java.base/sun.nio.ch=ALL-UNNAMED
|
|
||||||
--add-exports java.base/jdk.internal.access=ALL-UNNAMED
|
|
||||||
--add-opens=java.base/java.nio=ALL-UNNAMED
|
|
||||||
-Ddhfs.objects.persistence.files.root=/dhfs_root/p
|
|
||||||
-Ddhfs.objects.root=/dhfs_root/d
|
|
||||||
-Ddhfs.fuse.root=/dhfs_root/fuse -Dquarkus.http.host=0.0.0.0
|
|
||||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5010
|
|
||||||
-jar /app/quarkus-run.jar"
|
|
||||||
ports:
|
|
||||||
- 8090:8080
|
|
||||||
- 8091:8443
|
|
||||||
- 5010:5010
|
|
||||||
@@ -21,7 +21,7 @@ abstract public class TempDataProfile implements QuarkusTestProfile {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
var ret = new HashMap<String, String>();
|
var ret = new HashMap<String, String>();
|
||||||
ret.put("dhfs.objects.persistence.files.root", tempDirWithPrefix.resolve("dhfs_root_test").toString());
|
ret.put("dhfs.objects.persistence.root", tempDirWithPrefix.resolve("dhfs_root_test").toString());
|
||||||
ret.put("dhfs.fuse.root", tempDirWithPrefix.resolve("dhfs_fuse_root_test").toString());
|
ret.put("dhfs.fuse.root", tempDirWithPrefix.resolve("dhfs_fuse_root_test").toString());
|
||||||
getConfigOverrides(ret);
|
getConfigOverrides(ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class TestDataCleaner {
|
public class TestDataCleaner {
|
||||||
@ConfigProperty(name = "dhfs.objects.persistence.files.root")
|
@ConfigProperty(name = "dhfs.objects.persistence.root")
|
||||||
String tempDirectory;
|
String tempDirectory;
|
||||||
|
|
||||||
void init(@Observes @Priority(1) StartupEvent event) throws IOException {
|
void init(@Observes @Priority(1) StartupEvent event) throws IOException {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
dhfs.objects.persistence.files.root=${HOME}/dhfs_data/dhfs_root_test
|
dhfs.objects.persistence.root=${HOME}/dhfs_data/dhfs_root_test
|
||||||
dhfs.objects.root=${HOME}/dhfs_data/dhfs_root_d_test
|
|
||||||
dhfs.fuse.root=${HOME}/dhfs_data/dhfs_fuse_root_test
|
dhfs.fuse.root=${HOME}/dhfs_data/dhfs_fuse_root_test
|
||||||
dhfs.objects.ref_verification=true
|
dhfs.objects.ref_verification=true
|
||||||
dhfs.objects.deletion.delay=0
|
dhfs.objects.deletion.delay=0
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ services:
|
|||||||
- $HOME/dhfs/dhfs1_f:/dhfs_root/fuse:rshared
|
- $HOME/dhfs/dhfs1_f:/dhfs_root/fuse:rshared
|
||||||
- ./target/quarkus-app:/app
|
- ./target/quarkus-app:/app
|
||||||
command: "java --add-exports java.base/sun.nio.ch=ALL-UNNAMED
|
command: "java --add-exports java.base/sun.nio.ch=ALL-UNNAMED
|
||||||
-Ddhfs.objects.persistence.files.root=/dhfs_root/p
|
-Ddhfs.objects.persistence.root=/dhfs_root/p
|
||||||
-Ddhfs.objects.root=/dhfs_root/d
|
|
||||||
-Ddhfs.fuse.root=/dhfs_root/fuse -Dquarkus.http.host=0.0.0.0
|
-Ddhfs.fuse.root=/dhfs_root/fuse -Dquarkus.http.host=0.0.0.0
|
||||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
|
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
|
||||||
-jar /app/quarkus-run.jar"
|
-jar /app/quarkus-run.jar"
|
||||||
@@ -32,8 +31,7 @@ services:
|
|||||||
command: "java --add-exports java.base/sun.nio.ch=ALL-UNNAMED
|
command: "java --add-exports java.base/sun.nio.ch=ALL-UNNAMED
|
||||||
--add-exports java.base/jdk.internal.access=ALL-UNNAMED
|
--add-exports java.base/jdk.internal.access=ALL-UNNAMED
|
||||||
--add-opens=java.base/java.nio=ALL-UNNAMED
|
--add-opens=java.base/java.nio=ALL-UNNAMED
|
||||||
-Ddhfs.objects.persistence.files.root=/dhfs_root/p
|
-Ddhfs.objects.persistence.root=/dhfs_root/p
|
||||||
-Ddhfs.objects.root=/dhfs_root/d
|
|
||||||
-Ddhfs.fuse.root=/dhfs_root/fuse -Dquarkus.http.host=0.0.0.0
|
-Ddhfs.fuse.root=/dhfs_root/fuse -Dquarkus.http.host=0.0.0.0
|
||||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5010
|
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5010
|
||||||
-jar /app/quarkus-run.jar"
|
-jar /app/quarkus-run.jar"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ abstract public class TempDataProfile implements QuarkusTestProfile {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
var ret = new HashMap<String, String>();
|
var ret = new HashMap<String, String>();
|
||||||
ret.put("dhfs.objects.persistence.files.root", tempDirWithPrefix.resolve("dhfs_root_test").toString());
|
ret.put("dhfs.objects.persistence.root", tempDirWithPrefix.resolve("dhfs_root_test").toString());
|
||||||
ret.put("dhfs.fuse.root", tempDirWithPrefix.resolve("dhfs_fuse_root_test").toString());
|
ret.put("dhfs.fuse.root", tempDirWithPrefix.resolve("dhfs_fuse_root_test").toString());
|
||||||
getConfigOverrides(ret);
|
getConfigOverrides(ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class TestDataCleaner {
|
public class TestDataCleaner {
|
||||||
@ConfigProperty(name = "dhfs.objects.persistence.files.root")
|
@ConfigProperty(name = "dhfs.objects.persistence.root")
|
||||||
String tempDirectory;
|
String tempDirectory;
|
||||||
|
|
||||||
void init(@Observes @Priority(1) StartupEvent event) throws IOException {
|
void init(@Observes @Priority(1) StartupEvent event) throws IOException {
|
||||||
|
|||||||
@@ -56,8 +56,8 @@ public class DhfsFuseIT {
|
|||||||
waitingConsumer2.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
waitingConsumer2.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
||||||
waitingConsumer1.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
waitingConsumer1.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
||||||
|
|
||||||
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
|
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
||||||
|
|||||||
@@ -72,9 +72,9 @@ public class DhfsFusex3IT {
|
|||||||
waitingConsumer2.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
waitingConsumer2.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
||||||
waitingConsumer1.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
waitingConsumer1.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
||||||
|
|
||||||
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
c3uuid = container3.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c3uuid = container3.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
|
|
||||||
Log.info(container1.getContainerId() + "=" + c1uuid + " = 1");
|
Log.info(container1.getContainerId() + "=" + c1uuid + " = 1");
|
||||||
Log.info(container2.getContainerId() + "=" + c2uuid + " = 2");
|
Log.info(container2.getContainerId() + "=" + c2uuid + " = 2");
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class DhfsImage implements Future<String> {
|
|||||||
"-Dquarkus.log.category.\"com.usatiuk.objects.transaction\".level=INFO",
|
"-Dquarkus.log.category.\"com.usatiuk.objects.transaction\".level=INFO",
|
||||||
"-Ddhfs.objects.periodic-push-op-interval=5s",
|
"-Ddhfs.objects.periodic-push-op-interval=5s",
|
||||||
"-Ddhfs.fuse.root=/dhfs_test/fuse",
|
"-Ddhfs.fuse.root=/dhfs_test/fuse",
|
||||||
"-Ddhfs.objects.persistence.files.root=/dhfs_test/data",
|
"-Ddhfs.objects.persistence.root=/dhfs_test/data",
|
||||||
"-Ddhfs.objects.persistence.stuff.root=/dhfs_test/data/stuff",
|
"-Ddhfs.objects.persistence.stuff.root=/dhfs_test/data/stuff",
|
||||||
"-jar", "/app/quarkus-run.jar")
|
"-jar", "/app/quarkus-run.jar")
|
||||||
.run("mkdir /dhfs_test && chmod 777 /dhfs_test")
|
.run("mkdir /dhfs_test && chmod 777 /dhfs_test")
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ public class KillIT {
|
|||||||
waitingConsumer2.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
waitingConsumer2.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
||||||
waitingConsumer1.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
waitingConsumer1.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
||||||
|
|
||||||
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
|
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
import static org.awaitility.Awaitility.await;
|
import static org.awaitility.Awaitility.await;
|
||||||
|
|
||||||
|
@Disabled
|
||||||
public class LazyFsIT {
|
public class LazyFsIT {
|
||||||
GenericContainer<?> container1;
|
GenericContainer<?> container1;
|
||||||
GenericContainer<?> container2;
|
GenericContainer<?> container2;
|
||||||
@@ -82,8 +83,8 @@ public class LazyFsIT {
|
|||||||
waitingConsumer2.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
waitingConsumer2.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
||||||
waitingConsumer1.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
waitingConsumer1.waitUntil(frame -> frame.getUtf8String().contains("Listening"), 60, TimeUnit.SECONDS);
|
||||||
|
|
||||||
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
|
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
||||||
|
|||||||
@@ -66,8 +66,8 @@ public class ResyncIT {
|
|||||||
@Test
|
@Test
|
||||||
void readWriteFileTest() throws IOException, InterruptedException, TimeoutException {
|
void readWriteFileTest() throws IOException, InterruptedException, TimeoutException {
|
||||||
await().atMost(45, TimeUnit.SECONDS).until(() -> 0 == container1.execInContainer("/bin/sh", "-c", "echo tesempty > /dhfs_test/fuse/testf1").getExitCode());
|
await().atMost(45, TimeUnit.SECONDS).until(() -> 0 == container1.execInContainer("/bin/sh", "-c", "echo tesempty > /dhfs_test/fuse/testf1").getExitCode());
|
||||||
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
|
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
||||||
@@ -106,8 +106,8 @@ public class ResyncIT {
|
|||||||
foundWc = container2.execInContainer("/bin/sh", "-c", "find /dhfs_test/fuse -type f | wc -l");
|
foundWc = container2.execInContainer("/bin/sh", "-c", "find /dhfs_test/fuse -type f | wc -l");
|
||||||
Assertions.assertEquals(200, Integer.valueOf(foundWc.getStdout().strip()));
|
Assertions.assertEquals(200, Integer.valueOf(foundWc.getStdout().strip()));
|
||||||
|
|
||||||
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
|
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
||||||
@@ -146,8 +146,8 @@ public class ResyncIT {
|
|||||||
await().atMost(45, TimeUnit.SECONDS).until(() -> 0 == container1.execInContainer("/bin/sh", "-c", "mv /dhfs_test/fuse/testd1 /dhfs_test/fuse/testd2").getExitCode());
|
await().atMost(45, TimeUnit.SECONDS).until(() -> 0 == container1.execInContainer("/bin/sh", "-c", "mv /dhfs_test/fuse/testd1 /dhfs_test/fuse/testd2").getExitCode());
|
||||||
await().atMost(45, TimeUnit.SECONDS).until(() -> 0 == container1.execInContainer("/bin/sh", "-c", "echo tesempty2 > /dhfs_test/fuse/testd2/testf2").getExitCode());
|
await().atMost(45, TimeUnit.SECONDS).until(() -> 0 == container1.execInContainer("/bin/sh", "-c", "echo tesempty2 > /dhfs_test/fuse/testd2/testf2").getExitCode());
|
||||||
|
|
||||||
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c1uuid = container1.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/stuff/self_uuid").getStdout();
|
c2uuid = container2.execInContainer("/bin/sh", "-c", "cat /dhfs_test/data/self_uuid").getStdout();
|
||||||
|
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c1uuid));
|
||||||
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
Assertions.assertDoesNotThrow(() -> UUID.fromString(c2uuid));
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
dhfs.objects.persistence.files.root=${HOME}/dhfs_data/dhfs_root_test
|
dhfs.objects.persistence.root=${HOME}/dhfs_data/dhfs_root_test
|
||||||
dhfs.objects.root=${HOME}/dhfs_data/dhfs_root_d_test
|
|
||||||
dhfs.fuse.root=${HOME}/dhfs_data/dhfs_fuse_root_test
|
dhfs.fuse.root=${HOME}/dhfs_data/dhfs_fuse_root_test
|
||||||
dhfs.objects.ref_verification=true
|
dhfs.objects.ref_verification=true
|
||||||
dhfs.objects.deletion.delay=0
|
dhfs.objects.deletion.delay=0
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public class LmdbObjectPersistentStore implements ObjectPersistentStore {
|
|||||||
private Dbi<ByteBuffer> _db;
|
private Dbi<ByteBuffer> _db;
|
||||||
private boolean _ready = false;
|
private boolean _ready = false;
|
||||||
|
|
||||||
public LmdbObjectPersistentStore(@ConfigProperty(name = "dhfs.objects.persistence.files.root") String root) {
|
public LmdbObjectPersistentStore(@ConfigProperty(name = "dhfs.objects.persistence.root") String root) {
|
||||||
_root = Path.of(root).resolve("objects");
|
_root = Path.of(root).resolve("objects");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ dhfs.objects.writeback.limit=16777216
|
|||||||
dhfs.objects.lru.limit=67108864
|
dhfs.objects.lru.limit=67108864
|
||||||
dhfs.objects.lru.print-stats=false
|
dhfs.objects.lru.print-stats=false
|
||||||
dhfs.objects.lock_timeout_secs=15
|
dhfs.objects.lock_timeout_secs=15
|
||||||
dhfs.objects.persistence.files.root=${HOME}/dhfs_default/data/objs
|
dhfs.objects.persistence.root=${HOME}/dhfs_default/data/objs
|
||||||
dhfs.objects.persistence.snapshot-extra-checks=false
|
dhfs.objects.persistence.snapshot-extra-checks=false
|
||||||
dhfs.objects.last-seen.update=60
|
dhfs.objects.last-seen.update=60
|
||||||
dhfs.objects.last-seen.timeout=43200
|
dhfs.objects.last-seen.timeout=43200
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class TempDataProfile implements QuarkusTestProfile {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
var ret = new HashMap<String, String>();
|
var ret = new HashMap<String, String>();
|
||||||
ret.put("dhfs.objects.persistence.files.root", tempDirWithPrefix.resolve("dhfs_root_test").toString());
|
ret.put("dhfs.objects.persistence.root", tempDirWithPrefix.resolve("dhfs_root_test").toString());
|
||||||
ret.put("dhfs.fuse.root", tempDirWithPrefix.resolve("dhfs_fuse_root_test").toString());
|
ret.put("dhfs.fuse.root", tempDirWithPrefix.resolve("dhfs_fuse_root_test").toString());
|
||||||
ret.put("dhfs.objects.persistence", "lmdb");
|
ret.put("dhfs.objects.persistence", "lmdb");
|
||||||
getConfigOverrides(ret);
|
getConfigOverrides(ret);
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class TestDataCleaner {
|
public class TestDataCleaner {
|
||||||
@ConfigProperty(name = "dhfs.objects.persistence.files.root")
|
@ConfigProperty(name = "dhfs.objects.persistence.root")
|
||||||
String tempDirectory;
|
String tempDirectory;
|
||||||
|
|
||||||
void init(@Observes @Priority(1) StartupEvent event) throws IOException {
|
void init(@Observes @Priority(1) StartupEvent event) throws IOException {
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
version: "3.2"
|
|
||||||
|
|
||||||
services:
|
|
||||||
dhfs1:
|
|
||||||
build: .
|
|
||||||
privileged: true
|
|
||||||
devices:
|
|
||||||
- /dev/fuse
|
|
||||||
volumes:
|
|
||||||
- $HOME/dhfs/dhfs1:/dhfs_root
|
|
||||||
- $HOME/dhfs/dhfs1_f:/dhfs_root/fuse:rshared
|
|
||||||
- ./target/quarkus-app:/app
|
|
||||||
command: "java --add-exports java.base/sun.nio.ch=ALL-UNNAMED
|
|
||||||
-Ddhfs.objects.persistence.files.root=/dhfs_root/p
|
|
||||||
-Ddhfs.objects.root=/dhfs_root/d
|
|
||||||
-Ddhfs.fuse.root=/dhfs_root/fuse -Dquarkus.http.host=0.0.0.0
|
|
||||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
|
|
||||||
-jar /app/quarkus-run.jar"
|
|
||||||
ports:
|
|
||||||
- 8080:8080
|
|
||||||
- 8081:8443
|
|
||||||
- 5005:5005
|
|
||||||
dhfs2:
|
|
||||||
build: .
|
|
||||||
privileged: true
|
|
||||||
devices:
|
|
||||||
- /dev/fuse
|
|
||||||
volumes:
|
|
||||||
- $HOME/dhfs/dhfs2:/dhfs_root
|
|
||||||
- $HOME/dhfs/dhfs2_f:/dhfs_root/fuse:rshared
|
|
||||||
- ./target/quarkus-app:/app
|
|
||||||
command: "java --add-exports java.base/sun.nio.ch=ALL-UNNAMED
|
|
||||||
--add-exports java.base/jdk.internal.access=ALL-UNNAMED
|
|
||||||
--add-opens=java.base/java.nio=ALL-UNNAMED
|
|
||||||
-Ddhfs.objects.persistence.files.root=/dhfs_root/p
|
|
||||||
-Ddhfs.objects.root=/dhfs_root/d
|
|
||||||
-Ddhfs.fuse.root=/dhfs_root/fuse -Dquarkus.http.host=0.0.0.0
|
|
||||||
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5010
|
|
||||||
-jar /app/quarkus-run.jar"
|
|
||||||
ports:
|
|
||||||
- 8090:8080
|
|
||||||
- 8091:8443
|
|
||||||
- 5010:5010
|
|
||||||
@@ -19,7 +19,7 @@ import java.nio.file.Paths;
|
|||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class ShutdownChecker {
|
public class ShutdownChecker {
|
||||||
private static final String dataFileName = "running";
|
private static final String dataFileName = "running";
|
||||||
@ConfigProperty(name = "dhfs.objects.persistence.files.root")
|
@ConfigProperty(name = "dhfs.objects.persistence.root")
|
||||||
String dataRoot;
|
String dataRoot;
|
||||||
boolean _cleanShutdown = true;
|
boolean _cleanShutdown = true;
|
||||||
boolean _initialized = false;
|
boolean _initialized = false;
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class DeferredInvalidationQueueService implements PeerConnectedEventListe
|
|||||||
ReachablePeerManager reachablePeerManager;
|
ReachablePeerManager reachablePeerManager;
|
||||||
@Inject
|
@Inject
|
||||||
InvalidationQueueService invalidationQueueService;
|
InvalidationQueueService invalidationQueueService;
|
||||||
@ConfigProperty(name = "dhfs.objects.persistence.files.root")
|
@ConfigProperty(name = "dhfs.objects.persistence.root")
|
||||||
String dataRoot;
|
String dataRoot;
|
||||||
private DeferredInvalidationQueueData _persistentData = new DeferredInvalidationQueueData();
|
private DeferredInvalidationQueueData _persistentData = new DeferredInvalidationQueueData();
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class PersistentPeerDataService {
|
|||||||
|
|
||||||
@ConfigProperty(name = "dhfs.peerdiscovery.preset-uuid")
|
@ConfigProperty(name = "dhfs.peerdiscovery.preset-uuid")
|
||||||
Optional<String> presetUuid;
|
Optional<String> presetUuid;
|
||||||
@ConfigProperty(name = "dhfs.objects.persistence.stuff.root")
|
@ConfigProperty(name = "dhfs.objects.persistence.root")
|
||||||
String stuffRoot;
|
String stuffRoot;
|
||||||
|
|
||||||
private PeerId _selfUuid;
|
private PeerId _selfUuid;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ dhfs.objects.reconnect_interval=5s
|
|||||||
dhfs.objects.write_log=false
|
dhfs.objects.write_log=false
|
||||||
dhfs.objects.periodic-push-op-interval=5m
|
dhfs.objects.periodic-push-op-interval=5m
|
||||||
dhfs.fuse.root=${HOME}/dhfs_default/fuse
|
dhfs.fuse.root=${HOME}/dhfs_default/fuse
|
||||||
dhfs.objects.persistence.stuff.root=${HOME}/dhfs_default/data/stuff
|
|
||||||
dhfs.fuse.debug=false
|
dhfs.fuse.debug=false
|
||||||
dhfs.fuse.enabled=true
|
dhfs.fuse.enabled=true
|
||||||
dhfs.files.allow_recursive_delete=false
|
dhfs.files.allow_recursive_delete=false
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ abstract public class TempDataProfile implements QuarkusTestProfile {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
var ret = new HashMap<String, String>();
|
var ret = new HashMap<String, String>();
|
||||||
ret.put("dhfs.objects.persistence.files.root", tempDirWithPrefix.resolve("dhfs_root_test").toString());
|
ret.put("dhfs.objects.persistence.root", tempDirWithPrefix.resolve("dhfs_root_test").toString());
|
||||||
ret.put("dhfs.fuse.root", tempDirWithPrefix.resolve("dhfs_fuse_root_test").toString());
|
ret.put("dhfs.fuse.root", tempDirWithPrefix.resolve("dhfs_fuse_root_test").toString());
|
||||||
getConfigOverrides(ret);
|
getConfigOverrides(ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.util.Objects;
|
|||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class TestDataCleaner {
|
public class TestDataCleaner {
|
||||||
@ConfigProperty(name = "dhfs.objects.persistence.files.root")
|
@ConfigProperty(name = "dhfs.objects.persistence.root")
|
||||||
String tempDirectory;
|
String tempDirectory;
|
||||||
|
|
||||||
void init(@Observes @Priority(1) StartupEvent event) throws IOException {
|
void init(@Observes @Priority(1) StartupEvent event) throws IOException {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
dhfs.objects.persistence.files.root=${HOME}/dhfs_data/dhfs_root_test
|
dhfs.objects.persistence.root=${HOME}/dhfs_data/dhfs_root_test
|
||||||
dhfs.objects.root=${HOME}/dhfs_data/dhfs_root_d_test
|
|
||||||
dhfs.fuse.root=${HOME}/dhfs_data/dhfs_fuse_root_test
|
dhfs.fuse.root=${HOME}/dhfs_data/dhfs_fuse_root_test
|
||||||
dhfs.objects.ref_verification=true
|
dhfs.objects.ref_verification=true
|
||||||
dhfs.objects.deletion.delay=0
|
dhfs.objects.deletion.delay=0
|
||||||
|
|||||||
80
launcher/.gitignore
vendored
Normal file
80
launcher/.gitignore
vendored
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
Testing
|
||||||
33
launcher/CMakeLists.txt
Normal file
33
launcher/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
project(launcher)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
# if (NOT DEFINED SANITIZE)
|
||||||
|
# set(SANITIZE YES)
|
||||||
|
# endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (SANITIZE STREQUAL "YES")
|
||||||
|
message(STATUS "Enabling sanitizers!")
|
||||||
|
add_compile_options(-Werror -O0 -Wall -Wextra -pedantic -Wno-unused-parameter -Wno-unused-variable
|
||||||
|
-Wno-error=unused-function
|
||||||
|
-Wshadow -Wformat=2 -Wfloat-equal -D_GLIBCXX_DEBUG -Wconversion)
|
||||||
|
add_compile_options(-fsanitize=address -fno-sanitize-recover)
|
||||||
|
add_link_options(-fsanitize=address -fno-sanitize-recover)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
add_compile_options(-O3)
|
||||||
|
add_link_options(-O3)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_subdirectory(utils)
|
||||||
|
add_subdirectory(backend)
|
||||||
|
add_subdirectory(gui)
|
||||||
19
launcher/backend/CMakeLists.txt
Normal file
19
launcher/backend/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
find_package(wxWidgets REQUIRED COMPONENTS base)
|
||||||
|
if (wxWidgets_USE_FILE) # not defined in CONFIG mode
|
||||||
|
include(${wxWidgets_USE_FILE})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_library(backend
|
||||||
|
src/DhfsInstance.cpp
|
||||||
|
include_public/DhfsInstance.hpp
|
||||||
|
src/DhfsStartOptions.cpp
|
||||||
|
include_public/DhfsStartOptions.hpp
|
||||||
|
src/DhfsWxProcess.cpp
|
||||||
|
include_public/DhfsWxProcess.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(backend PRIVATE include)
|
||||||
|
target_include_directories(backend PUBLIC include_public)
|
||||||
|
|
||||||
|
target_link_libraries(backend PRIVATE ${wxWidgets_LIBRARIES})
|
||||||
|
target_link_libraries(backend PUBLIC utils)
|
||||||
49
launcher/backend/include_public/DhfsInstance.hpp
Normal file
49
launcher/backend/include_public/DhfsInstance.hpp
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// Created by stepus53 on 24.6.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef DHFSINSTANCE_HPP
|
||||||
|
#define DHFSINSTANCE_HPP
|
||||||
|
|
||||||
|
#include <wx/process.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <thread>
|
||||||
|
#include<mutex>
|
||||||
|
|
||||||
|
#include "DhfsStartOptions.hpp"
|
||||||
|
#include "DhfsWxProcess.hpp"
|
||||||
|
|
||||||
|
enum class DhfsInstanceState {
|
||||||
|
RUNNING,
|
||||||
|
STOPPED,
|
||||||
|
};
|
||||||
|
|
||||||
|
class DhfsInstance {
|
||||||
|
public:
|
||||||
|
DhfsInstance();
|
||||||
|
|
||||||
|
virtual ~DhfsInstance();
|
||||||
|
|
||||||
|
DhfsInstanceState state();
|
||||||
|
|
||||||
|
void start(DhfsStartOptions start_options);
|
||||||
|
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
virtual void OnTerminate(int pid, int status) = 0;
|
||||||
|
|
||||||
|
virtual void OnRead(std::string s) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<DhfsWxProcess> process = std::make_unique<DhfsWxProcess>(*this);
|
||||||
|
|
||||||
|
private:
|
||||||
|
DhfsInstanceState _state = DhfsInstanceState::STOPPED;
|
||||||
|
std::thread _readThread;
|
||||||
|
std::thread _readThreadErr;
|
||||||
|
std::mutex _mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DHFSINSTANCE_HPP
|
||||||
25
launcher/backend/include_public/DhfsStartOptions.hpp
Normal file
25
launcher/backend/include_public/DhfsStartOptions.hpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 25.06.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef DHFSSTARTOPTIONS_HPP
|
||||||
|
#define DHFSSTARTOPTIONS_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class DhfsStartOptions {
|
||||||
|
public:
|
||||||
|
std::string java_home;
|
||||||
|
std::string xmx;
|
||||||
|
std::string mount_path;
|
||||||
|
std::string data_path;
|
||||||
|
std::string jar_path;
|
||||||
|
std::string webui_path;
|
||||||
|
std::vector<std::string> extra_options;
|
||||||
|
|
||||||
|
std::vector<std::string> getOptions();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DHFSSTARTOPTIONS_HPP
|
||||||
24
launcher/backend/include_public/DhfsWxProcess.hpp
Normal file
24
launcher/backend/include_public/DhfsWxProcess.hpp
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 25.06.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef DHFSWXPROCESS_HPP
|
||||||
|
#define DHFSWXPROCESS_HPP
|
||||||
|
#include <wx/process.h>
|
||||||
|
|
||||||
|
|
||||||
|
class DhfsInstance;
|
||||||
|
|
||||||
|
class DhfsWxProcess : public wxProcess {
|
||||||
|
public:
|
||||||
|
DhfsWxProcess(DhfsInstance& parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnTerminate(int pid, int status) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DhfsInstance& _instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DHFSWXPROCESS_HPP
|
||||||
100
launcher/backend/src/DhfsInstance.cpp
Normal file
100
launcher/backend/src/DhfsInstance.cpp
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
//
|
||||||
|
// Created by stepus53 on 24.6.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DhfsInstance.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Exception.h"
|
||||||
|
|
||||||
|
DhfsInstance::DhfsInstance() {
|
||||||
|
}
|
||||||
|
|
||||||
|
DhfsInstance::~DhfsInstance() {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
DhfsInstanceState DhfsInstance::state() {
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
return _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DhfsInstance::start(DhfsStartOptions options) {
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
switch (_state) {
|
||||||
|
case DhfsInstanceState::RUNNING:
|
||||||
|
return;
|
||||||
|
case DhfsInstanceState::STOPPED:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unknown DhfsInstanceState");
|
||||||
|
}
|
||||||
|
_state = DhfsInstanceState::RUNNING;
|
||||||
|
|
||||||
|
std::vector<char*> args;
|
||||||
|
auto readyOptions = options.getOptions();
|
||||||
|
for (const auto& option: readyOptions) {
|
||||||
|
args.push_back(const_cast<char*>(option.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
long ret = wxExecute(args.data(), wxEXEC_ASYNC | wxEXEC_HIDE_CONSOLE | wxEXEC_MAKE_GROUP_LEADER, process.get(),
|
||||||
|
nullptr);
|
||||||
|
if (ret == 0) {
|
||||||
|
_state = DhfsInstanceState::STOPPED;
|
||||||
|
throw Exception("Failed to start DHFS");
|
||||||
|
}
|
||||||
|
|
||||||
|
OnRead("Started! " + std::to_string(ret) + " PID: " + std::to_string(process->GetPid()) + "\n");
|
||||||
|
|
||||||
|
_readThread = std::thread([&]() {
|
||||||
|
auto stream = process->GetInputStream();
|
||||||
|
while (!stream->Eof() || stream->CanRead()) {
|
||||||
|
char buffer[1024];
|
||||||
|
size_t bytesRead = stream->Read(buffer, sizeof(buffer) - 1).LastRead();
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
buffer[bytesRead] = '\0'; // Null-terminate the string
|
||||||
|
OnRead(std::string(buffer));
|
||||||
|
} else if (bytesRead == 0) {
|
||||||
|
break; // EOF reached
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_readThreadErr = std::thread([&]() {
|
||||||
|
auto stream = process->GetErrorStream();
|
||||||
|
while (!stream->Eof() || stream->CanRead()) {
|
||||||
|
char buffer[1024];
|
||||||
|
size_t bytesRead = stream->Read(buffer, sizeof(buffer) - 1).LastRead();
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
buffer[bytesRead] = '\0'; // Null-terminate the string
|
||||||
|
OnRead(std::string(buffer));
|
||||||
|
} else if (bytesRead == 0) {
|
||||||
|
break; // EOF reached
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void DhfsInstance::stop() {
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
switch (_state) {
|
||||||
|
case DhfsInstanceState::RUNNING:
|
||||||
|
break;
|
||||||
|
case DhfsInstanceState::STOPPED:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("Unknown DhfsInstanceState");
|
||||||
|
}
|
||||||
|
|
||||||
|
_state = DhfsInstanceState::STOPPED;
|
||||||
|
|
||||||
|
int err = wxProcess::Kill(process->GetPid(), wxSIGTERM, wxKILL_CHILDREN);
|
||||||
|
_readThread.join();
|
||||||
|
_readThreadErr.join();
|
||||||
|
OnRead("Stopped!\n");
|
||||||
|
if (err != wxKILL_OK) {
|
||||||
|
OnRead("Failed to stop DHFS: " + std::to_string(err) + "\n");
|
||||||
|
}
|
||||||
|
OnTerminate(0, 0);
|
||||||
|
}
|
||||||
31
launcher/backend/src/DhfsStartOptions.cpp
Normal file
31
launcher/backend/src/DhfsStartOptions.cpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 25.06.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DhfsStartOptions.hpp"
|
||||||
|
|
||||||
|
std::vector<std::string> DhfsStartOptions::getOptions() {
|
||||||
|
std::vector<std::string> out;
|
||||||
|
out.emplace_back(java_home + "/bin/java");
|
||||||
|
out.emplace_back("--enable-preview");
|
||||||
|
out.emplace_back("-Xmx" + xmx);
|
||||||
|
out.emplace_back("-Ddhfs.objects.writeback.limit=16777216");
|
||||||
|
out.emplace_back("-Ddhfs.objects.lru.limit=67108864");
|
||||||
|
out.emplace_back("--add-exports");
|
||||||
|
out.emplace_back("java.base/sun.nio.ch=ALL-UNNAMED");
|
||||||
|
out.emplace_back("--add-exports");
|
||||||
|
out.emplace_back("java.base/jdk.internal.access=ALL-UNNAMED");
|
||||||
|
out.emplace_back("--add-opens=java.base/java.nio=ALL-UNNAMED");
|
||||||
|
out.emplace_back("-Dquarkus.http.host=0.0.0.0");
|
||||||
|
out.emplace_back("-Dquarkus.log.category.\"com.usatiuk\".level=INFO");
|
||||||
|
out.emplace_back("-Dquarkus.log.category.\"com.usatiuk.dhfs\".level=INFO");
|
||||||
|
out.emplace_back("-Ddhfs.fuse.root=" + mount_path);
|
||||||
|
out.emplace_back("-Ddhfs.objects.persistence.root=" + data_path);
|
||||||
|
out.emplace_back("-Ddhfs.webui.root=" + webui_path);
|
||||||
|
for (auto option: extra_options) {
|
||||||
|
out.emplace_back(option);
|
||||||
|
}
|
||||||
|
out.emplace_back("-jar");
|
||||||
|
out.emplace_back(jar_path);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
14
launcher/backend/src/DhfsWxProcess.cpp
Normal file
14
launcher/backend/src/DhfsWxProcess.cpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 25.06.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DhfsWxProcess.hpp"
|
||||||
|
|
||||||
|
#include "DhfsInstance.hpp"
|
||||||
|
|
||||||
|
DhfsWxProcess::DhfsWxProcess(DhfsInstance& parent): wxProcess(wxPROCESS_REDIRECT), _instance(parent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DhfsWxProcess::OnTerminate(int pid, int status) {
|
||||||
|
_instance.stop();
|
||||||
|
}
|
||||||
16
launcher/gui/CMakeLists.txt
Normal file
16
launcher/gui/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
find_package(wxWidgets REQUIRED COMPONENTS net core base webview)
|
||||||
|
if (wxWidgets_USE_FILE) # not defined in CONFIG mode
|
||||||
|
include(${wxWidgets_USE_FILE})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_executable(launcher
|
||||||
|
src/LauncherApp.cpp
|
||||||
|
src/GLauncherApp.cpp
|
||||||
|
src/LauncherAppMainFrame.cpp
|
||||||
|
src/DhfsGuiInstance.cpp
|
||||||
|
src/DhfsGuiInstance.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(launcher ${wxWidgets_LIBRARIES})
|
||||||
|
target_link_libraries(launcher backend utils)
|
||||||
23
launcher/gui/src/DhfsGuiInstance.cpp
Normal file
23
launcher/gui/src/DhfsGuiInstance.cpp
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 25.06.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "DhfsGuiInstance.hpp"
|
||||||
|
|
||||||
|
#include "LauncherAppMainFrame.h"
|
||||||
|
|
||||||
|
DhfsGuiInstance::DhfsGuiInstance(LauncherAppMainFrame& parent): _parent(parent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void DhfsGuiInstance::OnTerminate(int pid, int status) {
|
||||||
|
wxCommandEvent* event = new wxCommandEvent(SHUTDOWN_EVENT, _parent.GetId());
|
||||||
|
event->SetEventObject(&_parent);
|
||||||
|
_parent.GetEventHandler()->QueueEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DhfsGuiInstance::OnRead(std::string s) {
|
||||||
|
wxCommandEvent* event = new wxCommandEvent(NEW_LINE_OUTPUT_EVENT, _parent.GetId());
|
||||||
|
event->SetEventObject(&_parent);
|
||||||
|
event->SetString(std::move(s));
|
||||||
|
_parent.GetEventHandler()->QueueEvent(event);
|
||||||
|
}
|
||||||
25
launcher/gui/src/DhfsGuiInstance.hpp
Normal file
25
launcher/gui/src/DhfsGuiInstance.hpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 25.06.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef DHFSGUIINSTANCE_HPP
|
||||||
|
#define DHFSGUIINSTANCE_HPP
|
||||||
|
#include "DhfsInstance.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
class LauncherAppMainFrame;
|
||||||
|
|
||||||
|
class DhfsGuiInstance : public DhfsInstance {
|
||||||
|
public:
|
||||||
|
DhfsGuiInstance(LauncherAppMainFrame& parent);
|
||||||
|
|
||||||
|
void OnTerminate(int pid, int status) override;
|
||||||
|
|
||||||
|
void OnRead(std::string s) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LauncherAppMainFrame& _parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //DHFSGUIINSTANCE_HPP
|
||||||
161
launcher/gui/src/GLauncherApp.cpp
Normal file
161
launcher/gui/src/GLauncherApp.cpp
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "GLauncherApp.h"
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxFrame( parent, id, title, pos, size, style, name )
|
||||||
|
{
|
||||||
|
this->SetSizeHints( wxSize( 600,400 ), wxDefaultSize );
|
||||||
|
|
||||||
|
m_statusBar1 = this->CreateStatusBar( 1, wxSTB_SIZEGRIP, wxID_ANY );
|
||||||
|
wxBoxSizer* bSizer3;
|
||||||
|
bSizer3 = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
m_notebook1 = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0|wxBORDER_NONE );
|
||||||
|
m_panel1 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
|
wxBoxSizer* bSizer2;
|
||||||
|
bSizer2 = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
wxStaticBoxSizer* sbSizer4;
|
||||||
|
sbSizer4 = new wxStaticBoxSizer( new wxStaticBox( m_panel1, wxID_ANY, _("Status") ), wxVERTICAL );
|
||||||
|
|
||||||
|
wxGridBagSizer* gbSizer1;
|
||||||
|
gbSizer1 = new wxGridBagSizer( 0, 0 );
|
||||||
|
gbSizer1->SetFlexibleDirection( wxBOTH );
|
||||||
|
gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||||
|
|
||||||
|
m_statusText = new wxStaticText( sbSizer4->GetStaticBox(), wxID_ANY, _("Running"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_statusText->Wrap( -1 );
|
||||||
|
gbSizer1->Add( m_statusText, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
m_startStopButton = new wxButton( sbSizer4->GetStaticBox(), wxID_ANY, _("Start"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
gbSizer1->Add( m_startStopButton, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
sbSizer4->Add( gbSizer1, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
bSizer2->Add( sbSizer4, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
wxStaticBoxSizer* sbSizer6;
|
||||||
|
sbSizer6 = new wxStaticBoxSizer( new wxStaticBox( m_panel1, wxID_ANY, _("Statistics") ), wxVERTICAL );
|
||||||
|
|
||||||
|
|
||||||
|
bSizer2->Add( sbSizer6, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
m_panel1->SetSizer( bSizer2 );
|
||||||
|
m_panel1->Layout();
|
||||||
|
bSizer2->Fit( m_panel1 );
|
||||||
|
m_notebook1->AddPage( m_panel1, _("Info"), false );
|
||||||
|
m_panel3 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
|
wxGridSizer* gSizer1;
|
||||||
|
gSizer1 = new wxGridSizer( 1, 1, 0, 0 );
|
||||||
|
|
||||||
|
m_logOutputTextCtrl = new wxTextCtrl( m_panel3, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxBORDER_NONE );
|
||||||
|
gSizer1->Add( m_logOutputTextCtrl, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
m_panel3->SetSizer( gSizer1 );
|
||||||
|
m_panel3->Layout();
|
||||||
|
gSizer1->Fit( m_panel3 );
|
||||||
|
m_notebook1->AddPage( m_panel3, _("Logs"), true );
|
||||||
|
m_panel2 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
|
wxBoxSizer* bSizer5;
|
||||||
|
bSizer5 = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
wxStaticBoxSizer* sbSizer3;
|
||||||
|
sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_panel2, wxID_ANY, _("JVM") ), wxVERTICAL );
|
||||||
|
|
||||||
|
wxGridBagSizer* gbSizer2;
|
||||||
|
gbSizer2 = new wxGridBagSizer( 0, 0 );
|
||||||
|
gbSizer2->SetFlexibleDirection( wxBOTH );
|
||||||
|
gbSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||||
|
|
||||||
|
m_button2 = new wxButton( sbSizer3->GetStaticBox(), wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
gbSizer2->Add( m_button2, wxGBPosition( 0, 3 ), wxGBSpan( 1, 1 ), wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
gbSizer2->Add( 50, 0, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_javaHomeDirPicker = new wxDirPickerCtrl( sbSizer3->GetStaticBox(), wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, wxDIRP_DEFAULT_STYLE|wxDIRP_USE_TEXTCTRL );
|
||||||
|
gbSizer2->Add( m_javaHomeDirPicker, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_staticText2 = new wxStaticText( sbSizer3->GetStaticBox(), wxID_ANY, _("Java Home"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText2->Wrap( -1 );
|
||||||
|
gbSizer2->Add( m_staticText2, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
gbSizer2->AddGrowableCol( 1 );
|
||||||
|
|
||||||
|
sbSizer3->Add( gbSizer2, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
bSizer5->Add( sbSizer3, 1, wxALL|wxEXPAND|wxFIXED_MINSIZE, 5 );
|
||||||
|
|
||||||
|
wxStaticBoxSizer* sbSizer41;
|
||||||
|
sbSizer41 = new wxStaticBoxSizer( new wxStaticBox( m_panel2, wxID_ANY, _("Paths") ), wxVERTICAL );
|
||||||
|
|
||||||
|
wxGridBagSizer* gbSizer3;
|
||||||
|
gbSizer3 = new wxGridBagSizer( 0, 0 );
|
||||||
|
gbSizer3->SetFlexibleDirection( wxBOTH );
|
||||||
|
gbSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||||
|
|
||||||
|
m_staticText6 = new wxStaticText( sbSizer41->GetStaticBox(), wxID_ANY, _("Mount path"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText6->Wrap( -1 );
|
||||||
|
gbSizer3->Add( m_staticText6, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
m_staticText61 = new wxStaticText( sbSizer41->GetStaticBox(), wxID_ANY, _("Data path"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
m_staticText61->Wrap( -1 );
|
||||||
|
gbSizer3->Add( m_staticText61, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||||
|
|
||||||
|
m_mountPathDirPicker = new wxDirPickerCtrl( sbSizer41->GetStaticBox(), wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL );
|
||||||
|
gbSizer3->Add( m_mountPathDirPicker, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
m_dataPathDirPicker = new wxDirPickerCtrl( sbSizer41->GetStaticBox(), wxID_ANY, wxEmptyString, _("Select a folder"), wxDefaultPosition, wxDefaultSize, wxDIRP_USE_TEXTCTRL );
|
||||||
|
gbSizer3->Add( m_dataPathDirPicker, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
gbSizer3->AddGrowableCol( 1 );
|
||||||
|
|
||||||
|
sbSizer41->Add( gbSizer3, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
bSizer5->Add( sbSizer41, 1, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
m_panel2->SetSizer( bSizer5 );
|
||||||
|
m_panel2->Layout();
|
||||||
|
bSizer5->Fit( m_panel2 );
|
||||||
|
m_notebook1->AddPage( m_panel2, _("Settings"), false );
|
||||||
|
m_panel4 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
|
m_notebook1->AddPage( m_panel4, _("Advanced Settings"), false );
|
||||||
|
m_panel5 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
|
m_notebook1->AddPage( m_panel5, _("a page"), false );
|
||||||
|
|
||||||
|
bSizer3->Add( m_notebook1, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
this->SetSizer( bSizer3 );
|
||||||
|
this->Layout();
|
||||||
|
|
||||||
|
this->Centre( wxBOTH );
|
||||||
|
|
||||||
|
// Connect Events
|
||||||
|
m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler( MainFrame::OnNotebookPageChanged ), NULL, this );
|
||||||
|
m_notebook1->Connect( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, wxNotebookEventHandler( MainFrame::OnNotebookPageChanging ), NULL, this );
|
||||||
|
m_startStopButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( MainFrame::OnStartStopButtonClick ), NULL, this );
|
||||||
|
m_javaHomeDirPicker->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainFrame::OnJavaHomeChanged ), NULL, this );
|
||||||
|
m_mountPathDirPicker->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainFrame::OnMountPathChanged ), NULL, this );
|
||||||
|
m_dataPathDirPicker->Connect( wxEVT_COMMAND_DIRPICKER_CHANGED, wxFileDirPickerEventHandler( MainFrame::OnDataPathChanged ), NULL, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
MainFrame::~MainFrame()
|
||||||
|
{
|
||||||
|
}
|
||||||
77
launcher/gui/src/GLauncherApp.h
Normal file
77
launcher/gui/src/GLauncherApp.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
|
||||||
|
// http://www.wxformbuilder.org/
|
||||||
|
//
|
||||||
|
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <wx/artprov.h>
|
||||||
|
#include <wx/xrc/xmlres.h>
|
||||||
|
#include <wx/intl.h>
|
||||||
|
#include <wx/statusbr.h>
|
||||||
|
#include <wx/gdicmn.h>
|
||||||
|
#include <wx/font.h>
|
||||||
|
#include <wx/colour.h>
|
||||||
|
#include <wx/settings.h>
|
||||||
|
#include <wx/string.h>
|
||||||
|
#include <wx/stattext.h>
|
||||||
|
#include <wx/button.h>
|
||||||
|
#include <wx/bitmap.h>
|
||||||
|
#include <wx/image.h>
|
||||||
|
#include <wx/icon.h>
|
||||||
|
#include <wx/gbsizer.h>
|
||||||
|
#include <wx/sizer.h>
|
||||||
|
#include <wx/statbox.h>
|
||||||
|
#include <wx/panel.h>
|
||||||
|
#include <wx/textctrl.h>
|
||||||
|
#include <wx/filepicker.h>
|
||||||
|
#include <wx/notebook.h>
|
||||||
|
#include <wx/frame.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// Class MainFrame
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
class MainFrame : public wxFrame
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxStatusBar* m_statusBar1;
|
||||||
|
wxNotebook* m_notebook1;
|
||||||
|
wxPanel* m_panel1;
|
||||||
|
wxStaticText* m_statusText;
|
||||||
|
wxButton* m_startStopButton;
|
||||||
|
wxPanel* m_panel3;
|
||||||
|
wxTextCtrl* m_logOutputTextCtrl;
|
||||||
|
wxPanel* m_panel2;
|
||||||
|
wxButton* m_button2;
|
||||||
|
wxDirPickerCtrl* m_javaHomeDirPicker;
|
||||||
|
wxStaticText* m_staticText2;
|
||||||
|
wxStaticText* m_staticText6;
|
||||||
|
wxStaticText* m_staticText61;
|
||||||
|
wxDirPickerCtrl* m_mountPathDirPicker;
|
||||||
|
wxDirPickerCtrl* m_dataPathDirPicker;
|
||||||
|
wxPanel* m_panel4;
|
||||||
|
wxPanel* m_panel5;
|
||||||
|
|
||||||
|
// Virtual event handlers, override them in your derived class
|
||||||
|
virtual void OnNotebookPageChanged( wxNotebookEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnNotebookPageChanging( wxNotebookEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnStartStopButtonClick( wxCommandEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnJavaHomeChanged( wxFileDirPickerEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnMountPathChanged( wxFileDirPickerEvent& event ) { event.Skip(); }
|
||||||
|
virtual void OnDataPathChanged( wxFileDirPickerEvent& event ) { event.Skip(); }
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MainFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("DHFS"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 600,400 ), long style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL, const wxString& name = wxT("DHFS") );
|
||||||
|
|
||||||
|
~MainFrame();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
44
launcher/gui/src/LauncherApp.cpp
Normal file
44
launcher/gui/src/LauncherApp.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 11.07.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
// For compilers that don't support precompilation, include "wx/wx.h"
|
||||||
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
|
#ifndef WX_PRECOMP
|
||||||
|
# include "wx/wx.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/notebook.h"
|
||||||
|
|
||||||
|
#include "LauncherApp.h"
|
||||||
|
|
||||||
|
#include "LauncherAppMainFrame.h"
|
||||||
|
#include "wx/taskbar.h"
|
||||||
|
#include <wx/fileconf.h>
|
||||||
|
IMPLEMENT_APP(LauncherApp)
|
||||||
|
|
||||||
|
// This is executed upon startup, like 'main()' in non-wxWidgets programs.
|
||||||
|
bool LauncherApp::OnInit() {
|
||||||
|
wxFileConfig::Get()->SetAppName("DHFS");
|
||||||
|
|
||||||
|
wxFrame* frame = new LauncherAppMainFrame(NULL);
|
||||||
|
frame->Show(true);
|
||||||
|
SetTopWindow(frame);
|
||||||
|
|
||||||
|
// wxTaskBarIcon* tb = new wxTaskBarIcon();
|
||||||
|
// auto img = new wxImage(32, 32, false);
|
||||||
|
// img->Clear(128);
|
||||||
|
// tb->SetIcon(*(new wxBitmapBundle(*(new wxBitmap(*img)))), "e");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LauncherApp::OnExceptionInMainLoop() {
|
||||||
|
try {
|
||||||
|
std::rethrow_exception(std::current_exception());
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
wxMessageBox(e.what(), "Error", wxOK | wxICON_ERROR | wxCENTRE, GetTopWindow());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
19
launcher/gui/src/LauncherApp.h
Normal file
19
launcher/gui/src/LauncherApp.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 11.07.2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HELLOWORLDAPP_H
|
||||||
|
#define HELLOWORLDAPP_H
|
||||||
|
|
||||||
|
// The HelloWorldApp class. This class shows a window
|
||||||
|
// containing a statusbar with the text "Hello World"
|
||||||
|
class LauncherApp : public wxApp {
|
||||||
|
public:
|
||||||
|
virtual bool OnInit() override;
|
||||||
|
|
||||||
|
virtual bool OnExceptionInMainLoop() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_APP(LauncherApp)
|
||||||
|
|
||||||
|
#endif //HELLOWORLDAPP_H
|
||||||
115
launcher/gui/src/LauncherAppMainFrame.cpp
Normal file
115
launcher/gui/src/LauncherAppMainFrame.cpp
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
#include "LauncherAppMainFrame.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <wx/fileconf.h>
|
||||||
|
|
||||||
|
#include "Exception.h"
|
||||||
|
|
||||||
|
wxDEFINE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
|
||||||
|
wxDEFINE_EVENT(SHUTDOWN_EVENT, wxCommandEvent);
|
||||||
|
|
||||||
|
LauncherAppMainFrame::LauncherAppMainFrame(wxWindow* parent)
|
||||||
|
: MainFrame(parent) {
|
||||||
|
m_javaHomeDirPicker->SetPath(wxFileConfig::Get()->Read(kJavaHomeSettingsKey));
|
||||||
|
m_mountPathDirPicker->SetPath(wxFileConfig::Get()->Read(kMountPointSettingsKey));
|
||||||
|
m_dataPathDirPicker->SetPath(wxFileConfig::Get()->Read(kDataDirSettingsKey));
|
||||||
|
|
||||||
|
m_webViewSizer = new wxGridSizer(1, 0, 0);
|
||||||
|
m_panel5->SetSizer(m_webViewSizer);
|
||||||
|
m_panel5->Layout();
|
||||||
|
m_webViewSizer->Fit(m_panel5);
|
||||||
|
|
||||||
|
Bind(NEW_LINE_OUTPUT_EVENT, &LauncherAppMainFrame::onNewLineOutput, this);
|
||||||
|
Bind(SHUTDOWN_EVENT, &LauncherAppMainFrame::onShutdown, this);
|
||||||
|
wxFont font = wxFont(wxSize(16, 16),
|
||||||
|
wxFontFamily::wxFONTFAMILY_TELETYPE,
|
||||||
|
wxFontStyle::wxFONTSTYLE_NORMAL,
|
||||||
|
wxFontWeight::wxFONTWEIGHT_NORMAL);
|
||||||
|
m_logOutputTextCtrl->SetFont(font);
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::updateState() {
|
||||||
|
switch (_dhfsInstance.state()) {
|
||||||
|
case DhfsInstanceState::RUNNING:
|
||||||
|
m_statusText->SetLabel("Running");
|
||||||
|
m_startStopButton->SetLabel("Stop");
|
||||||
|
m_statusBar1->SetStatusText("Running", 0);
|
||||||
|
break;
|
||||||
|
case DhfsInstanceState::STOPPED: {
|
||||||
|
m_statusText->SetLabel("Stopped");
|
||||||
|
m_startStopButton->SetLabel("Start");
|
||||||
|
m_statusBar1->SetStatusText("Stopped", 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw Exception("Unhandled switch case");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::OnStartStopButtonClick(wxCommandEvent& event) {
|
||||||
|
switch (_dhfsInstance.state()) {
|
||||||
|
case DhfsInstanceState::RUNNING:
|
||||||
|
_dhfsInstance.stop();
|
||||||
|
break;
|
||||||
|
case DhfsInstanceState::STOPPED: {
|
||||||
|
DhfsStartOptions options;
|
||||||
|
options.java_home = wxFileConfig::Get()->Read(kJavaHomeSettingsKey);
|
||||||
|
options.xmx = "512m";
|
||||||
|
options.mount_path = wxFileConfig::Get()->Read(kMountPointSettingsKey);
|
||||||
|
options.data_path = wxFileConfig::Get()->Read(kDataDirSettingsKey);
|
||||||
|
std::string bundlePath = wxGetenv("DHFS_BUNDLE_PATH");
|
||||||
|
options.jar_path = bundlePath + "/app/Server/quarkus-run.jar";
|
||||||
|
options.webui_path = bundlePath + "/app/Webui";
|
||||||
|
|
||||||
|
_dhfsInstance.start(options);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw Exception("Unhandled switch case");
|
||||||
|
}
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::OnJavaHomeChanged(wxFileDirPickerEvent& event) {
|
||||||
|
wxFileConfig::Get()->Write(kJavaHomeSettingsKey, event.GetPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::OnMountPathChanged(wxFileDirPickerEvent& event) {
|
||||||
|
wxFileConfig::Get()->Write(kMountPointSettingsKey, event.GetPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::OnDataPathChanged(wxFileDirPickerEvent& event) {
|
||||||
|
wxFileConfig::Get()->Write(kDataDirSettingsKey, event.GetPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::onNewLineOutput(wxCommandEvent& event) {
|
||||||
|
m_logOutputTextCtrl->AppendText(event.GetString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::OnNotebookPageChanged(wxBookCtrlEvent& event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::OnNotebookPageChanging(wxBookCtrlEvent& event) {
|
||||||
|
if (event.GetSelection() == 4) prepareWebview();
|
||||||
|
else unloadWebview();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::onShutdown(wxCommandEvent& event) {
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::unloadWebview() {
|
||||||
|
if (m_webView != nullptr) {
|
||||||
|
m_webViewSizer->Detach(m_webView);
|
||||||
|
m_webView->Destroy();
|
||||||
|
m_webView = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::prepareWebview() {
|
||||||
|
m_webView = wxWebView::New(m_panel5, wxID_ANY);
|
||||||
|
m_webViewSizer->Add(m_webView, 0, wxALL | wxEXPAND);
|
||||||
|
m_webView->LoadURL("http://localhost:8080");
|
||||||
|
m_panel5->Layout();
|
||||||
|
}
|
||||||
62
launcher/gui/src/LauncherAppMainFrame.h
Normal file
62
launcher/gui/src/LauncherAppMainFrame.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef __LauncherAppMainFrame__
|
||||||
|
#define __LauncherAppMainFrame__
|
||||||
|
|
||||||
|
/**
|
||||||
|
@file
|
||||||
|
Subclass of MainFrame, which is generated by wxFormBuilder.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GLauncherApp.h"
|
||||||
|
|
||||||
|
//// end generated include
|
||||||
|
|
||||||
|
#include <wx/webview.h>
|
||||||
|
|
||||||
|
#include "DhfsGuiInstance.hpp"
|
||||||
|
|
||||||
|
static constexpr auto kJavaHomeSettingsKey = "DHFS/JavaHome";
|
||||||
|
static constexpr auto kMountPointSettingsKey = "DHFS/MountDir";
|
||||||
|
static constexpr auto kDataDirSettingsKey = "DHFS/DataDir";
|
||||||
|
|
||||||
|
wxDECLARE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
|
||||||
|
wxDECLARE_EVENT(SHUTDOWN_EVENT, wxCommandEvent);
|
||||||
|
|
||||||
|
/** Implementing MainFrame */
|
||||||
|
class LauncherAppMainFrame : public MainFrame {
|
||||||
|
protected:
|
||||||
|
// Handlers for MainFrame events.
|
||||||
|
void OnStartStopButtonClick(wxCommandEvent& event) override;
|
||||||
|
|
||||||
|
void OnJavaHomeChanged(wxFileDirPickerEvent& event) override;
|
||||||
|
|
||||||
|
void OnMountPathChanged(wxFileDirPickerEvent& event) override;
|
||||||
|
|
||||||
|
void OnDataPathChanged(wxFileDirPickerEvent& event) override;
|
||||||
|
|
||||||
|
void OnNotebookPageChanged(wxNotebookEvent& event) override;
|
||||||
|
|
||||||
|
void OnNotebookPageChanging(wxNotebookEvent& event) override;
|
||||||
|
|
||||||
|
void onNewLineOutput(wxCommandEvent& event);
|
||||||
|
|
||||||
|
void onShutdown(wxCommandEvent& event);
|
||||||
|
|
||||||
|
void updateState();
|
||||||
|
|
||||||
|
void unloadWebview();
|
||||||
|
void prepareWebview();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructor */
|
||||||
|
LauncherAppMainFrame(wxWindow* parent);
|
||||||
|
|
||||||
|
//// end generated class members
|
||||||
|
|
||||||
|
private:
|
||||||
|
wxWebView* m_webView = nullptr;
|
||||||
|
wxGridSizer* m_webViewSizer;
|
||||||
|
|
||||||
|
DhfsGuiInstance _dhfsInstance{*this};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __LauncherAppMainFrame__
|
||||||
1275
launcher/gui/src/launcher.fbp
Normal file
1275
launcher/gui/src/launcher.fbp
Normal file
File diff suppressed because it is too large
Load Diff
7
launcher/utils/CMakeLists.txt
Normal file
7
launcher/utils/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
add_library(utils
|
||||||
|
src/Exception.cpp
|
||||||
|
include_public/Exception.h
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(utils PRIVATE include)
|
||||||
|
target_include_directories(utils PUBLIC include_public)
|
||||||
30
launcher/utils/include_public/Exception.h
Normal file
30
launcher/utils/include_public/Exception.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 01.05.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SEMBACKUP_EXCEPTION_H
|
||||||
|
#define SEMBACKUP_EXCEPTION_H
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/// Custom exception class that uses execinfo to append a stacktrace to the exception message
|
||||||
|
class Exception : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
Exception(const std::string& text);
|
||||||
|
Exception(const char* text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Static function to get the current stacktrace
|
||||||
|
static std::string getStacktrace();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ErrnoException : public Exception {
|
||||||
|
public:
|
||||||
|
ErrnoException(const std::string& text) : Exception(text + " " + std::strerror(errno)) {}
|
||||||
|
ErrnoException(const char* text) : Exception(std::string(text) + " " + std::strerror(errno)) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SEMBACKUP_EXCEPTION_H
|
||||||
35
launcher/utils/src/Exception.cpp
Normal file
35
launcher/utils/src/Exception.cpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// Created by Stepan Usatiuk on 01.05.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Exception.h"
|
||||||
|
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
Exception::Exception(const std::string& text) : runtime_error(text + "\n" + getStacktrace()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception::Exception(const char* text) : runtime_error(std::string(text) + "\n" + getStacktrace()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on: https://www.gnu.org/software/libc/manual/html_node/Backtraces.html
|
||||||
|
std::string Exception::getStacktrace() {
|
||||||
|
std::vector<void*> functions(50);
|
||||||
|
char** strings;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = backtrace(functions.data(), 50);
|
||||||
|
strings = backtrace_symbols(functions.data(), n);
|
||||||
|
|
||||||
|
std::stringstream out;
|
||||||
|
|
||||||
|
if (strings != nullptr) {
|
||||||
|
out << "Stacktrace:" << std::endl;
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
out << strings[i] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(strings);
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
@@ -42,8 +42,7 @@ fi
|
|||||||
--add-exports java.base/sun.nio.ch=ALL-UNNAMED \
|
--add-exports java.base/sun.nio.ch=ALL-UNNAMED \
|
||||||
--add-exports java.base/jdk.internal.access=ALL-UNNAMED \
|
--add-exports java.base/jdk.internal.access=ALL-UNNAMED \
|
||||||
--add-opens=java.base/java.nio=ALL-UNNAMED \
|
--add-opens=java.base/java.nio=ALL-UNNAMED \
|
||||||
-Ddhfs.objects.persistence.files.root="$SCRIPT_DIR"/../data/objects \
|
-Ddhfs.objects.persistence.root="$SCRIPT_DIR"/../data \
|
||||||
-Ddhfs.objects.persistence.stuff.root="$SCRIPT_DIR"/../data/stuff \
|
|
||||||
-Ddhfs.fuse.root="$SCRIPT_DIR"/../fuse \
|
-Ddhfs.fuse.root="$SCRIPT_DIR"/../fuse \
|
||||||
-Dquarkus.http.host=0.0.0.0 \
|
-Dquarkus.http.host=0.0.0.0 \
|
||||||
-Dquarkus.log.category.\"com.usatiuk\".level=INFO \
|
-Dquarkus.log.category.\"com.usatiuk\".level=INFO \
|
||||||
|
|||||||
Reference in New Issue
Block a user