Compare commits
3 Commits
ca586aaa36
...
d7193b6a5f
Author | SHA1 | Date | |
---|---|---|---|
d7193b6a5f | |||
f369e5f6c5 | |||
d3da1c57f8 |
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,14 +1,12 @@
|
||||
.gradle
|
||||
gradlew.bat
|
||||
build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
/.idea/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
@ -43,5 +41,3 @@ bin/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
/app/src/test/resources/debian-images/
|
||||
/app/src/test/resources/squashfs-root/
|
||||
|
8
.idea/artifacts/api_jvm.xml
generated
8
.idea/artifacts/api_jvm.xml
generated
@ -1,8 +0,0 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="api-jvm">
|
||||
<output-path>$PROJECT_DIR$/api/build/libs</output-path>
|
||||
<root id="archive" name="api-jvm.jar">
|
||||
<element id="module-output" name="planterette.api.jvmMain" />
|
||||
</root>
|
||||
</artifact>
|
||||
</component>
|
12
.idea/kotlinc.xml
generated
12
.idea/kotlinc.xml
generated
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Kotlin2JsCompilerArguments">
|
||||
<option name="moduleKind" value="plain" />
|
||||
</component>
|
||||
<component name="Kotlin2JvmCompilerArguments">
|
||||
<option name="jvmTarget" value="1.8" />
|
||||
</component>
|
||||
<component name="KotlinJpsPluginSettings">
|
||||
<option name="version" value="2.2.0" />
|
||||
</component>
|
||||
</project>
|
@ -3,7 +3,7 @@ plugins {
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(21)
|
||||
jvmToolchain(24)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
#Tue Aug 26 23:15:20 CDT 2025
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
@ -1,47 +1,48 @@
|
||||
package app.hakurei.planterette.api
|
||||
|
||||
@Suppress("unused")
|
||||
object Paths {
|
||||
const val FHSRoot = "/"
|
||||
const val FHSEtc = "/etc/"
|
||||
const val FHSTmp = "/tmp/"
|
||||
const val FHS_ROOT = "/"
|
||||
const val FHS_ETC = "/etc/"
|
||||
const val FHS_TMP = "/tmp/"
|
||||
|
||||
const val FHSRun = "/run/"
|
||||
const val FHSRunUser = FHSRun + "user/"
|
||||
const val FHS_RUN = "/run/"
|
||||
const val FHS_RUN_USER = FHS_RUN + "user/"
|
||||
|
||||
const val FHSUsr = "/usr/"
|
||||
const val FHSUsrBin = FHSUsr + "bin/"
|
||||
const val FHS_USR = "/usr/"
|
||||
const val FHS_USR_BIN = FHS_USR + "bin/"
|
||||
|
||||
const val FHSVar = "/var/"
|
||||
const val FHSVarLib = FHSVar + "lib/"
|
||||
const val FHSVarEmpty = FHSVar + "empty/"
|
||||
const val FHS_VAR = "/var/"
|
||||
const val FHS_VAR_LIB = FHS_VAR + "lib/"
|
||||
const val FHS_VAR_EMPTY = FHS_VAR + "empty/"
|
||||
|
||||
const val FHSDev = "/dev/"
|
||||
const val FHSProc = "/proc/"
|
||||
const val FHSProcSys = FHSProc + "sys/"
|
||||
const val FHSSys = "/sys/"
|
||||
const val FHS_DEV = "/dev/"
|
||||
const val FHS_PROC = "/proc/"
|
||||
const val FHS_PROC_SYS = FHS_PROC + "sys/"
|
||||
const val FHS_SYS = "/sys/"
|
||||
|
||||
const val Nonexistent = FHSProc + "nonexistent"
|
||||
const val sysrootDir = "sysroot"
|
||||
const val hostDir = "host"
|
||||
const val hostPath = FHSRoot + hostDir
|
||||
const val sysrootPath = FHSRoot + sysrootDir
|
||||
const val NONEXISTENT = FHS_PROC + "nonexistent"
|
||||
const val SYSROOT_DIR = "sysroot"
|
||||
const val HOST_DIR = "host"
|
||||
const val HOST_PATH = FHS_ROOT + HOST_DIR
|
||||
const val SYSROOT_PATH = FHS_ROOT + SYSROOT_DIR
|
||||
|
||||
val AbsFHSRoot = AbsolutePath(FHSRoot)
|
||||
val AbsFHSEtc = AbsolutePath(FHSEtc)
|
||||
val AbsFHSTmp = AbsolutePath(FHSTmp)
|
||||
val AbsFHSRoot = AbsolutePath(FHS_ROOT)
|
||||
val AbsFHSEtc = AbsolutePath(FHS_ETC)
|
||||
val AbsFHSTmp = AbsolutePath(FHS_TMP)
|
||||
|
||||
val AbsFHSRun = AbsolutePath(FHSRun)
|
||||
val AbsFHSRunUser = AbsolutePath(FHSRunUser)
|
||||
val AbsFHSRun = AbsolutePath(FHS_RUN)
|
||||
val AbsFHSRunUser = AbsolutePath(FHS_RUN_USER)
|
||||
|
||||
val AbsFHSUsrBin = AbsolutePath(FHSUsrBin)
|
||||
val AbsFHSUsrBin = AbsolutePath(FHS_USR_BIN)
|
||||
|
||||
val AbsFHSVar = AbsolutePath(FHSVar)
|
||||
val AbsFHSVarLib = AbsolutePath(FHSVarLib)
|
||||
val AbsFHSVar = AbsolutePath(FHS_VAR)
|
||||
val AbsFHSVarLib = AbsolutePath(FHS_VAR_LIB)
|
||||
|
||||
val AbsFHSDev = AbsolutePath(FHSDev)
|
||||
val AbsFHSProc = AbsolutePath(FHSProc)
|
||||
val AbsFHSSys = AbsolutePath(FHSSys)
|
||||
val AbsFHSDev = AbsolutePath(FHS_DEV)
|
||||
val AbsFHSProc = AbsolutePath(FHS_PROC)
|
||||
val AbsFHSSys = AbsolutePath(FHS_SYS)
|
||||
|
||||
val AbsNonexistent = AbsolutePath(Nonexistent)
|
||||
val AbsNonexistent = AbsolutePath(NONEXISTENT)
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,5 @@
|
||||
package app.hakurei.planterette.api
|
||||
|
||||
import kotlinx.io.Buffer
|
||||
import kotlinx.io.buffered
|
||||
import kotlinx.io.files.Path
|
||||
import kotlinx.io.files.SystemFileSystem
|
||||
import kotlinx.io.readString
|
||||
|
||||
object Util {
|
||||
fun readFileToString(path: String): String {
|
||||
val buffer = Buffer()
|
||||
val source = SystemFileSystem.source(Path(path))
|
||||
source.buffered().transferTo(buffer)
|
||||
return buffer.readString()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T> Array<out T>.orOf(selector: (T) -> Int): Int {
|
||||
var sum = 0
|
||||
for (element in this) {
|
||||
|
@ -0,0 +1,26 @@
|
||||
package app.hakurei.planterette.api
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertIs
|
||||
|
||||
class AbsolutePathTest {
|
||||
@Test
|
||||
fun testAbsolutePath() {
|
||||
val path = AbsolutePath("/dev/null")
|
||||
assertIs<AbsolutePath>(path)
|
||||
}
|
||||
@Test
|
||||
fun testRelativePath() {
|
||||
assertFailsWith(AbsolutePathException::class) {
|
||||
AbsolutePath("./test")
|
||||
}
|
||||
}
|
||||
@Test
|
||||
fun testPathJoin() {
|
||||
val want = AbsolutePath("/dev/null")
|
||||
val base = AbsolutePath("/dev/")
|
||||
assertEquals(want, base + "null")
|
||||
}
|
||||
}
|
@ -1,11 +1,13 @@
|
||||
package app.hakurei.planterette.api
|
||||
|
||||
import app.hakurei.planterette.api.HakureiConfig.Enablement.*
|
||||
import app.hakurei.planterette.api.HakureiConfig.RootFlag
|
||||
import app.hakurei.planterette.api.HakureiConfig.SeccompFilterPreset.*
|
||||
import app.hakurei.planterette.api.HakureiConfig.HakureiExportFlag.*
|
||||
import app.hakurei.planterette.api.HakureiConfig.RootFlag.*
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.serializer
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -146,8 +148,6 @@ class HakureiConfigTest {
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
@Test
|
||||
fun testHakureiConfigSerialization() {
|
||||
val testConfig = HakureiConfig(
|
||||
id = "org.chromium.Chromium",
|
||||
path = Paths.AbsFHSRun + "current-system/sw/bin/chromium",
|
||||
@ -160,21 +160,27 @@ class HakureiConfigTest {
|
||||
),
|
||||
enablements = HakureiConfig.Enablement.enablements(Wayland, DBus, Pulse),
|
||||
sessionBus = HakureiConfig.DbusConfig(
|
||||
see = null,
|
||||
talk = listOf("org.freedesktop.Notifications", "org.freedesktop.FileManager1", "org.freedesktop.ScreenSaver"),
|
||||
own = listOf("org.chromium.Chromium.*", "org.mpris.MediaPlayer2.org.chromium.Chromium.*",
|
||||
"org.mpris.MediaPlayer2.chromium.*"),
|
||||
talk = listOf(
|
||||
"org.freedesktop.Notifications",
|
||||
"org.freedesktop.FileManager1",
|
||||
"org.freedesktop.ScreenSaver",
|
||||
"org.freedesktop.secrets",
|
||||
"org.kde.kwalletd5",
|
||||
"org.kde.kwalletd6",
|
||||
"org.gnome.SessionManager"
|
||||
),
|
||||
own = listOf(
|
||||
"org.chromium.Chromium.*",
|
||||
"org.mpris.MediaPlayer2.org.chromium.Chromium.*",
|
||||
"org.mpris.MediaPlayer2.chromium.*"
|
||||
),
|
||||
call = mapOf("org.freedesktop.portal.*" to "*"),
|
||||
broadcast = mapOf("org.freedesktop.portal.*" to "@/org/freedesktop/portal/*"),
|
||||
log = false,
|
||||
filter = true,
|
||||
),
|
||||
systemBus = HakureiConfig.DbusConfig(
|
||||
see = null,
|
||||
talk = listOf("org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"),
|
||||
own = null,
|
||||
call = null,
|
||||
broadcast = null,
|
||||
log = false,
|
||||
filter = true,
|
||||
),
|
||||
@ -197,8 +203,8 @@ class HakureiConfigTest {
|
||||
net = true,
|
||||
device = true,
|
||||
waitDelay = -1,
|
||||
seccompFlags = HakureiConfig.HakureiExportFlag.exportFlags(HakureiConfig.HakureiExportFlag.Multiarch),
|
||||
seccompPresets = HakureiConfig.SeccompFilterPreset.filterPresets(HakureiConfig.SeccompFilterPreset.Ext),
|
||||
seccompFlags = HakureiConfig.HakureiExportFlag.exportFlags(Multiarch),
|
||||
seccompPresets = HakureiConfig.SeccompFilterPreset.filterPresets(Ext),
|
||||
seccompCompat = true,
|
||||
tty = true,
|
||||
multiarch = true,
|
||||
@ -217,14 +223,111 @@ class HakureiConfigTest {
|
||||
HakureiConfig.FilesystemConfig(src = Paths.AbsFHSVarLib + "hakurei/u0/org.chromium.Chromium", dst = AbsolutePath("/data/data/org.chromium.Chromium"), write = true, must = true),
|
||||
HakureiConfig.FilesystemConfig(src = Paths.AbsFHSDev + "dri", device = true)
|
||||
),
|
||||
link = listOf(HakureiConfig.LinkConfig(Paths.AbsFHSRunUser + "65534", Paths.FHSRunUser + "150")),
|
||||
link = listOf(HakureiConfig.LinkConfig(Paths.AbsFHSRunUser + "65534", Paths.FHS_RUN_USER + "150")),
|
||||
autoRoot = Paths.AbsFHSVarLib + "hakurei/base/org.debian",
|
||||
rootFlags = RootFlag.rootFlags(RootFlag.Writable),
|
||||
rootFlags = HakureiConfig.RootFlag.rootFlags(Writable),
|
||||
etc = Paths.AbsFHSEtc,
|
||||
autoEtc = true
|
||||
)
|
||||
)
|
||||
println("printing for now until a more proper test can be written")
|
||||
println(format.encodeToString(testConfig))
|
||||
|
||||
internal fun compare(want: HakureiConfig, test: HakureiConfig) {
|
||||
assertEquals(want.id, test.id, "id")
|
||||
|
||||
assertEquals(want.path, test.path, "path")
|
||||
assertEquals(want.args, test.args, "args")
|
||||
|
||||
assertEquals(want.enablements, test.enablements, "enablements")
|
||||
|
||||
assertEquals(want.sessionBus?.see, test.sessionBus?.see, "sessionBus.see")
|
||||
assertEquals(want.sessionBus?.talk, test.sessionBus?.talk, "sessionBus.talk")
|
||||
assertEquals(want.sessionBus?.own, test.sessionBus?.own, "sessionBus.own")
|
||||
assertEquals(want.sessionBus?.broadcast, test.sessionBus?.broadcast, "sessionBus.broadcast")
|
||||
assertEquals(want.sessionBus?.log ?: false, test.sessionBus?.log, "sessionBus.log")
|
||||
assertEquals(want.sessionBus?.filter, test.sessionBus?.filter, "sessionBus.filter")
|
||||
|
||||
assertEquals(want.systemBus?.see, test.systemBus?.see, "systemBus.see")
|
||||
assertEquals(want.systemBus?.talk, test.systemBus?.talk, "systemBus.talk")
|
||||
assertEquals(want.systemBus?.own, test.systemBus?.own, "systemBus.own")
|
||||
assertEquals(want.systemBus?.broadcast, test.systemBus?.broadcast, "systemBus.broadcast")
|
||||
assertEquals(want.systemBus?.log ?: false, test.systemBus?.log, "systemBus.log")
|
||||
assertEquals(want.systemBus?.filter, test.systemBus?.filter, "systemBus.filter")
|
||||
|
||||
assertEquals(want.directWayland ?: false, test.directWayland, "directWayland")
|
||||
assertEquals(want.username, test.username, "username")
|
||||
assertEquals(want.shell, test.shell, "shell")
|
||||
assertEquals(want.data, test.data, "data")
|
||||
assertEquals(want.dir, test.dir, "dir")
|
||||
assertEquals(want.extraPerms, test.extraPerms, "extraPerms")
|
||||
|
||||
assertEquals(want.identity, test.identity, "identity")
|
||||
assertEquals(want.groups, test.groups, "groups")
|
||||
|
||||
assertEquals(want.container.waitDelay, test.container.waitDelay, "waitDelay")
|
||||
assertEquals(want.container.seccompFlags, test.container.seccompFlags, "seccompFlags")
|
||||
assertEquals(want.container.seccompPresets, test.container.seccompPresets, "seccompPresets")
|
||||
assertEquals(want.container.seccompCompat, test.container.seccompCompat, "seccompCompat")
|
||||
|
||||
assertEquals(want.container.devel, test.container.devel, "devel")
|
||||
assertEquals(want.container.userns, test.container.userns, "userns")
|
||||
assertEquals(want.container.net, test.container.net, "net")
|
||||
assertEquals(want.container.tty, test.container.tty, "tty")
|
||||
assertEquals(want.container.multiarch, test.container.multiarch, "multiarch")
|
||||
|
||||
assertEquals(want.container.env, test.container.env, "env")
|
||||
assertEquals(want.container.mapRealUid, test.container.mapRealUid, "mapRealUid")
|
||||
|
||||
assertEquals(want.container.device, test.container.device, "device")
|
||||
assertEquals(want.container.filesystem.size, test.container.filesystem.size, "filesystem.size")
|
||||
for(i in 0 until want.container.filesystem.size) {
|
||||
val w = want.container.filesystem[i]
|
||||
val t = test.container.filesystem[i]
|
||||
|
||||
assertEquals(w.src, t.src, "filesystem[$i].src")
|
||||
assertEquals(w.dst, t.dst, "filesystem[$i].dst")
|
||||
assertEquals(w.write, t.write, "filesystem[$i].write")
|
||||
assertEquals(w.device, t.device, "filesystem[$i].device")
|
||||
assertEquals(w.must, t.must, "filesystem[$i].must")
|
||||
}
|
||||
assertEquals(want.container.link, test.container.link, "link")
|
||||
assertEquals(want.container.autoRoot, test.container.autoRoot, "autoroot")
|
||||
|
||||
assertEquals(want.container.etc, test.container.etc, "etc")
|
||||
|
||||
assertEquals(want.container.autoEtc, test.container.autoEtc, "autoEtc")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHakureiConfigSerialization() {
|
||||
val json = format.encodeToString(testConfig)
|
||||
val test = format.decodeFromString<HakureiConfig>(json)
|
||||
assertEquals(testConfig, test)
|
||||
val want = format.decodeFromString<HakureiConfig>(want)
|
||||
|
||||
compare(want, test)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEnablements() {
|
||||
val enablement = HakureiConfig.Enablement.enablements(Wayland, X11, DBus, Pulse)
|
||||
assertEquals(enablement, 0b1111)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSeccompFilterPresets() {
|
||||
val presets = HakureiConfig.SeccompFilterPreset.filterPresets(Ext, DenyNS, DenyTTY, DenyDevel, Linux32)
|
||||
assertEquals(presets, 0b11111)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExportFlags() {
|
||||
val flags = HakureiConfig.HakureiExportFlag.exportFlags(Multiarch, CAN, Bluetooth)
|
||||
assertEquals(flags, 0b111)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testRootFlags() {
|
||||
val flags = HakureiConfig.RootFlag.rootFlags(Optional, Writable, Device)
|
||||
assertEquals(flags, 0b111)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user