restructure, begin implementing libplt
This commit is contained in:
		
							parent
							
								
									ae166bc45c
								
							
						
					
					
						commit
						ca586aaa36
					
				
							
								
								
									
										9
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										9
									
								
								.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							| @ -20,11 +20,12 @@ | ||||
|         <option name="modules"> | ||||
|           <set> | ||||
|             <option value="$PROJECT_DIR$" /> | ||||
|             <option value="$PROJECT_DIR$/api" /> | ||||
|             <option value="$PROJECT_DIR$/buildSrc" /> | ||||
|             <option value="$PROJECT_DIR$/cli" /> | ||||
|             <option value="$PROJECT_DIR$/daemon" /> | ||||
|             <option value="$PROJECT_DIR$/gui" /> | ||||
|             <option value="$PROJECT_DIR$/libplt" /> | ||||
|             <option value="$PROJECT_DIR$/plt" /> | ||||
|             <option value="$PROJECT_DIR$/plt-build" /> | ||||
|             <option value="$PROJECT_DIR$/plt-fetch" /> | ||||
|             <option value="$PROJECT_DIR$/plt-pkg" /> | ||||
|           </set> | ||||
|         </option> | ||||
|       </GradleProjectSettings> | ||||
|  | ||||
| @ -1,126 +0,0 @@ | ||||
| package app.hakurei.planterette.api | ||||
| 
 | ||||
| import kotlinx.serialization.SerialName | ||||
| import kotlinx.serialization.Serializable | ||||
| 
 | ||||
| @Serializable | ||||
| data class HakureiConfig( | ||||
|     val id: String, | ||||
| 
 | ||||
|     val path: String? = null, | ||||
|     val args: List<String>, | ||||
| 
 | ||||
|     val enablements: Byte, | ||||
| 
 | ||||
|     @SerialName("session_bus") val sessionBus: DbusConfig? = null, | ||||
|     @SerialName("system_bus") val systemBus: DbusConfig? = null, | ||||
|     @SerialName("direct_wayland") val directWayland: Boolean? = null, | ||||
| 
 | ||||
|     val username: String? = null, | ||||
|     val shell: String? = null, | ||||
|     val data: String, | ||||
|     val dir: String, | ||||
|     @SerialName("extra_perms") val extraPerms: List<ExtraPermConfig>?, | ||||
| 
 | ||||
|     val identity: Int, | ||||
|     val groups: List<String>, | ||||
| 
 | ||||
|     val container: ContainerConfig | ||||
| ) { | ||||
|     @Serializable | ||||
|     data class DbusConfig( | ||||
|         val see: List<String>? = null, | ||||
|         val talk: List<String>? = null, | ||||
|         val own: List<String>? = null, | ||||
|         val call: Map<String, String>? = null, | ||||
|         val broadcast: Map<String, String>? = null, | ||||
|         val log: Boolean? = null, | ||||
|         val filter: Boolean? = null | ||||
|     ) { | ||||
|     } | ||||
| 
 | ||||
|     @Serializable | ||||
|     data class ExtraPermConfig( | ||||
|         val ensure: Boolean? = null, | ||||
|         val path: String, | ||||
|         @SerialName("r") val read: Boolean? = null, | ||||
|         @SerialName("w") val write: Boolean? = null, | ||||
|         @SerialName("x") val execute: Boolean? = null | ||||
|     ) | ||||
|     @Serializable | ||||
|     data class ContainerConfig( | ||||
|         val hostname: String? = null, | ||||
|         @SerialName("wait_delay") val delay: Int = -1, | ||||
|         @SerialName("seccomp_flags") val seccompFlags: Int, | ||||
|         @SerialName("seccomp_presets") val seccompPresets: Int, | ||||
|         @SerialName("seccomp_compat") val seccompCompat: Boolean? = null, | ||||
| 
 | ||||
|         val devel: Boolean? = null, | ||||
|         val userns: Boolean? = null, | ||||
|         val net: Boolean? = null, | ||||
|         val tty: Boolean? = null, | ||||
|         val multiarch: Boolean? = null, | ||||
| 
 | ||||
|         val env: Map<String, String>, | ||||
|         @SerialName("map_real_uid") val mapRealUid: Boolean, | ||||
| 
 | ||||
|         val device: Boolean? = null, | ||||
|         val filesystem: List<FilesystemConfig>, | ||||
|         @SerialName("symlink") val link: List<String>, | ||||
| 
 | ||||
|         val etc: String? = null, | ||||
|         @SerialName("auto_etc") val autoEtc: Boolean, | ||||
|         val cover: List<String> | ||||
|     ) | ||||
| 
 | ||||
|     @Serializable | ||||
|     data class FilesystemConfig( | ||||
|         val dst: String? = null, | ||||
|         val src: String, | ||||
|         val write: Boolean? = null, | ||||
|         @SerialName("dev") val device: Boolean? = null, | ||||
|         @SerialName("require") val must: Boolean? = null | ||||
|     ) | ||||
| 
 | ||||
|     @Serializable | ||||
|     enum class Enablement(val value: Int) { | ||||
|         Wayland(1 shl 0), | ||||
|         X11(1 shl 1), | ||||
|         DBus(1 shl 2), | ||||
|         Pulse(1 shl 3); | ||||
| 
 | ||||
|         companion object { | ||||
|             fun enablements(vararg enablements: Enablement): Byte { | ||||
|                 return enablements.sumOf(Enablement::value).toByte() | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Serializable | ||||
|     enum class SeccompFilterPreset(val value: Int) { | ||||
|         Ext(1 shl 0), | ||||
|         DenyNS(1 shl 1), | ||||
|         DenyTTY(1 shl 2), | ||||
|         DenyDevel(1 shl 3), | ||||
|         Linux32(1 shl 4); | ||||
| 
 | ||||
|         companion object { | ||||
|             fun filterPresets(vararg filterPresets: SeccompFilterPreset): Int { | ||||
|                 return filterPresets.sumOf(SeccompFilterPreset::value) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Serializable | ||||
|     enum class HakureiExportFlag(val value: Int) { | ||||
|         Multiarch(1 shl 0), | ||||
|         CAN(1 shl 1), | ||||
|         Bluetooth(1 shl 2); | ||||
| 
 | ||||
|         companion object { | ||||
|             fun exportFlags(vararg exportFlags: HakureiExportFlag): Int { | ||||
|                 return exportFlags.sumOf(HakureiExportFlag::value) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -1,97 +0,0 @@ | ||||
| package app.hakurei.planterette.api | ||||
| 
 | ||||
| import kotlinx.serialization.ExperimentalSerializationApi | ||||
| import kotlinx.serialization.json.Json | ||||
| import kotlinx.serialization.serializer | ||||
| import kotlin.test.Test | ||||
| import kotlin.test.assertEquals | ||||
| 
 | ||||
| class HakureiConfigTest { | ||||
|     @OptIn(ExperimentalSerializationApi::class) | ||||
|     val format = Json { | ||||
|         explicitNulls = false | ||||
|         prettyPrint = true | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     fun testHakureiConfigSerialization() { | ||||
|         val testConfig = HakureiConfig( | ||||
|             id = "org.chromium.Chromium", | ||||
|             path = "/run/current-system/sw/bin/chromium", | ||||
|             args = listOf( | ||||
|                 "chromium", | ||||
|                 "--ignore-gpu-blocklist", | ||||
|                 "--disable-smooth-scrolling", | ||||
|                 "--enable-features=UseOzonePlatform", | ||||
|                 "--ozone-platform=wayland" | ||||
|                 ), | ||||
|             enablements = HakureiConfig.Enablement.enablements(HakureiConfig.Enablement.Wayland, HakureiConfig.Enablement.DBus, | ||||
|                 HakureiConfig.Enablement.Pulse), | ||||
|             sessionBus = HakureiConfig.DbusConfig( | ||||
|                 see = null, | ||||
|                 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/*"), | ||||
|                 filter = true | ||||
|             ), | ||||
|             systemBus = HakureiConfig.DbusConfig( | ||||
|                 talk = listOf("org.bluez", "org.freedesktop.Avahi", "org.freedesktop.UPower"), | ||||
|                 filter = true | ||||
|             ), | ||||
| 
 | ||||
|             username = "chronos", | ||||
|             shell = "/run/current-system/sw/bin/zsh", | ||||
|             data = "/var/lib/hakurei/u0/org.chromium.Chromium", | ||||
|             dir = "/data/data/org.chromium.Chromium", | ||||
|             extraPerms = listOf( | ||||
|                 HakureiConfig.ExtraPermConfig(path = "/var/lib/hakurei/u0", ensure = true, execute = true), | ||||
|                 HakureiConfig.ExtraPermConfig(path = "/var/lib/hakurei/u0/org.chromium.Chromium", read = true, write = true, execute = true) | ||||
|             ), | ||||
|             identity = 9, | ||||
|             groups = listOf("video", "dialout", "plugdev"), | ||||
|             container = HakureiConfig.ContainerConfig( | ||||
|                 hostname = "localhost", | ||||
|                 devel = true, | ||||
|                 userns = true, | ||||
|                 net = true, | ||||
|                 device = true, | ||||
|                 seccompFlags = HakureiConfig.HakureiExportFlag.Multiarch.value, | ||||
|                 seccompPresets = HakureiConfig.SeccompFilterPreset.Ext.value, | ||||
|                 tty = true, | ||||
|                 multiarch = true, | ||||
|                 mapRealUid = true, | ||||
|                 env = mapOf( | ||||
|                     "GOOGLE_API_KEY" to "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY", | ||||
|                     "GOOGLE_DEFAULT_CLIENT_ID" to "77185425430.apps.googleusercontent.com", | ||||
|                     "GOOGLE_DEFAULT_CLIENT_SECRET" to "OTJgUOQcT7lO7GsGZq2G4IlT", | ||||
|                 ), | ||||
|                 filesystem = listOf( | ||||
|                     HakureiConfig.FilesystemConfig(src = "/nix/store"), | ||||
|                     HakureiConfig.FilesystemConfig(src = "/run/current-system"), | ||||
|                     HakureiConfig.FilesystemConfig(src = "/run/opengl-driver"), | ||||
|                     HakureiConfig.FilesystemConfig(src = "/var/db/nix-channels"), | ||||
|                     HakureiConfig.FilesystemConfig( | ||||
|                         src = "/var/lib/hakurei/u0/org.chromium.Chromium", | ||||
|                         dst = "/data/data/org.chromium.Chromium", | ||||
|                         write = true, | ||||
|                         must = true | ||||
|                     ), | ||||
|                     HakureiConfig.FilesystemConfig(src = "/dev/dri", device = true) | ||||
|                 ), | ||||
|                 link = listOf("/run/user/65534", "/run/user/150"), | ||||
|                 etc = "/etc", | ||||
|                 autoEtc = true, | ||||
|                 cover = listOf("/var/run/nscd"), | ||||
|                 delay = -1, | ||||
|                 seccompCompat = true | ||||
|             ) | ||||
|         ) | ||||
|         val json = format.encodeToString(serializer(), testConfig) | ||||
|         val deserializeJson: HakureiConfig = format.decodeFromString(json) | ||||
|         val templateJson: HakureiConfig = format.decodeFromString(Util.readFileToString("/home/lilly/Documents/Projects/Rosa/planterette/api/src/commonTest/resources/template.json")) | ||||
|         assertEquals(templateJson, deserializeJson, "") | ||||
|     } | ||||
| } | ||||
| @ -1,123 +0,0 @@ | ||||
| { | ||||
|   "id": "org.chromium.Chromium", | ||||
|   "path": "/run/current-system/sw/bin/chromium", | ||||
|   "args": [ | ||||
|     "chromium", | ||||
|     "--ignore-gpu-blocklist", | ||||
|     "--disable-smooth-scrolling", | ||||
|     "--enable-features=UseOzonePlatform", | ||||
|     "--ozone-platform=wayland" | ||||
|   ], | ||||
|   "enablements": 13, | ||||
|   "session_bus": { | ||||
|     "see": null, | ||||
|     "talk": [ | ||||
|       "org.freedesktop.Notifications", | ||||
|       "org.freedesktop.FileManager1", | ||||
|       "org.freedesktop.ScreenSaver", | ||||
|       "org.freedesktop.secrets", | ||||
|       "org.kde.kwalletd5", | ||||
|       "org.kde.kwalletd6", | ||||
|       "org.gnome.SessionManager" | ||||
|     ], | ||||
|     "own": [ | ||||
|       "org.chromium.Chromium.*", | ||||
|       "org.mpris.MediaPlayer2.org.chromium.Chromium.*", | ||||
|       "org.mpris.MediaPlayer2.chromium.*" | ||||
|     ], | ||||
|     "call": { | ||||
|       "org.freedesktop.portal.*": "*" | ||||
|     }, | ||||
|     "broadcast": { | ||||
|       "org.freedesktop.portal.*": "@/org/freedesktop/portal/*" | ||||
|     }, | ||||
|     "filter": true | ||||
|   }, | ||||
|   "system_bus": { | ||||
|     "see": null, | ||||
|     "talk": [ | ||||
|       "org.bluez", | ||||
|       "org.freedesktop.Avahi", | ||||
|       "org.freedesktop.UPower" | ||||
|     ], | ||||
|     "own": null, | ||||
|     "call": null, | ||||
|     "broadcast": null, | ||||
|     "filter": true | ||||
|   }, | ||||
|   "username": "chronos", | ||||
|   "shell": "/run/current-system/sw/bin/zsh", | ||||
|   "data": "/var/lib/hakurei/u0/org.chromium.Chromium", | ||||
|   "dir": "/data/data/org.chromium.Chromium", | ||||
|   "extra_perms": [ | ||||
|     { | ||||
|       "ensure": true, | ||||
|       "path": "/var/lib/hakurei/u0", | ||||
|       "x": true | ||||
|     }, | ||||
|     { | ||||
|       "path": "/var/lib/hakurei/u0/org.chromium.Chromium", | ||||
|       "r": true, | ||||
|       "w": true, | ||||
|       "x": true | ||||
|     } | ||||
|   ], | ||||
|   "identity": 9, | ||||
|   "groups": [ | ||||
|     "video", | ||||
|     "dialout", | ||||
|     "plugdev" | ||||
|   ], | ||||
|   "container": { | ||||
|     "hostname": "localhost", | ||||
|     "wait_delay": -1, | ||||
|     "seccomp_flags": 1, | ||||
|     "seccomp_presets": 1, | ||||
|     "seccomp_compat": true, | ||||
|     "devel": true, | ||||
|     "userns": true, | ||||
|     "net": true, | ||||
|     "tty": true, | ||||
|     "multiarch": true, | ||||
|     "env": { | ||||
|       "GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY", | ||||
|       "GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com", | ||||
|       "GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT" | ||||
|     }, | ||||
|     "map_real_uid": true, | ||||
|     "device": true, | ||||
|     "filesystem": [ | ||||
|       { | ||||
|         "src": "/nix/store" | ||||
|       }, | ||||
|       { | ||||
|         "src": "/run/current-system" | ||||
|       }, | ||||
|       { | ||||
|         "src": "/run/opengl-driver" | ||||
|       }, | ||||
|       { | ||||
|         "src": "/var/db/nix-channels" | ||||
|       }, | ||||
|       { | ||||
|         "dst": "/data/data/org.chromium.Chromium", | ||||
|         "src": "/var/lib/hakurei/u0/org.chromium.Chromium", | ||||
|         "write": true, | ||||
|         "require": true | ||||
|       }, | ||||
|       { | ||||
|         "src": "/dev/dri", | ||||
|         "dev": true | ||||
|       } | ||||
|     ], | ||||
|     "symlink": [ | ||||
|       "/run/user/65534", | ||||
|       "/run/user/150" | ||||
|     ], | ||||
|     "etc": "/etc", | ||||
|     "auto_etc": true, | ||||
|     "cover": [ | ||||
|       "/var/run/nscd" | ||||
|     ] | ||||
|   } | ||||
| } | ||||
| @ -1,2 +0,0 @@ | ||||
| package app.hakurei.planterette.api.dsl | ||||
| 
 | ||||
| @ -1,19 +0,0 @@ | ||||
| plugins { | ||||
|     kotlin("jvm") | ||||
| } | ||||
| 
 | ||||
| repositories { | ||||
|     mavenCentral() | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation(project(":api")) | ||||
|     testImplementation(kotlin("test")) | ||||
| } | ||||
| 
 | ||||
| tasks.test { | ||||
|     useJUnitPlatform() | ||||
| } | ||||
| kotlin { | ||||
|     jvmToolchain(21) | ||||
| } | ||||
| @ -1,13 +0,0 @@ | ||||
| plugins { | ||||
|     id("buildsrc.convention.kotlin-jvm") | ||||
|     kotlin("jvm") | ||||
|     application | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation(project(":api")) | ||||
| } | ||||
| 
 | ||||
| application { | ||||
|     mainClass = "app.hakurei.planterette.PlanteretteKt" | ||||
| } | ||||
| @ -1,5 +0,0 @@ | ||||
| package app.hakurei.planterette | ||||
| 
 | ||||
| fun main() { | ||||
| 
 | ||||
| } | ||||
| @ -1,124 +0,0 @@ | ||||
| { | ||||
|   "id": "org.debian", | ||||
|   "path": "/bin/bash", | ||||
|   "args": [ | ||||
|     "bash" | ||||
|   ], | ||||
|   "enablements": 13, | ||||
|   "session_bus": { | ||||
|     "see": null, | ||||
|     "talk": [ | ||||
|       "org.freedesktop.Notifications", | ||||
|       "org.freedesktop.FileManager1", | ||||
|       "org.freedesktop.ScreenSaver" | ||||
|     ], | ||||
|     "own": null, | ||||
|     "call": null, | ||||
|     "broadcast": null, | ||||
|     "filter": true | ||||
|   }, | ||||
|   "system_bus": { | ||||
|     "see": null, | ||||
|     "talk": null, | ||||
|     "own": null, | ||||
|     "call": null, | ||||
|     "broadcast": null, | ||||
|     "filter": true | ||||
|   }, | ||||
|   "username": "chronos", | ||||
|   "shell": "/bin/bash", | ||||
|   "data": "/tmp/chronos", | ||||
|   "dir": "/.hakurei/home", | ||||
|   "identity": 9, | ||||
|   "groups": null, | ||||
|   "container": { | ||||
|     "hostname": "debian", | ||||
|     "seccomp_flags": 0, | ||||
|     "seccomp_presets": 0, | ||||
|     "devel": true, | ||||
|     "userns": true, | ||||
|     "net": true, | ||||
|     "tty": true, | ||||
|     "multiarch": true, | ||||
|     "env": null, | ||||
|     "map_real_uid": true, | ||||
|     "filesystem": [ | ||||
|       { | ||||
|         "dst": "/boot", | ||||
|         "src": "/mnt/debian/boot" | ||||
|       }, | ||||
|       { | ||||
|         "dst": "/home", | ||||
|         "src": "/mnt/debian/home" | ||||
|       }, | ||||
|       { | ||||
|         "dst": "/media", | ||||
|         "src": "/mnt/debian/media" | ||||
|       }, | ||||
|       { | ||||
|         "dst": "/mnt", | ||||
|         "src": "/mnt/debian/mnt" | ||||
|       }, | ||||
|       { | ||||
|         "dst": "/opt", | ||||
|         "src": "/mnt/debian/opt" | ||||
|       }, | ||||
|       { | ||||
|         "dst": "/root", | ||||
|         "src": "/mnt/debian/root" | ||||
|       }, | ||||
|       { | ||||
|         "dst": "/srv", | ||||
|         "src": "/mnt/debian/srv" | ||||
|       }, | ||||
|       { | ||||
|         "dst": "/usr", | ||||
|         "src": "/mnt/debian/usr" | ||||
|       }, | ||||
|       { | ||||
|         "dst": "/var", | ||||
|         "src": "/mnt/debian/var" | ||||
|       }, | ||||
|       { | ||||
|         "src": "/sys/block" | ||||
|       }, | ||||
|       { | ||||
|         "src": "/sys/bus" | ||||
|       }, | ||||
|       { | ||||
|         "src": "/sys/class" | ||||
|       }, | ||||
|       { | ||||
|         "src": "/sys/dev" | ||||
|       }, | ||||
|       { | ||||
|         "src": "/sys/devices" | ||||
|       }, | ||||
|       { | ||||
|         "src": "/dev/dri", | ||||
|         "dev": true | ||||
|       } | ||||
|     ], | ||||
|     "symlink": [ | ||||
|       [ | ||||
|         "usr/bin", | ||||
|         "/bin" | ||||
|       ], | ||||
|       [ | ||||
|         "usr/lib", | ||||
|         "/lib" | ||||
|       ], | ||||
|       [ | ||||
|         "usr/lib64", | ||||
|         "/lib64" | ||||
|       ], | ||||
|       [ | ||||
|         "usr/sbin", | ||||
|         "/sbin" | ||||
|       ] | ||||
|     ], | ||||
|     "etc": "/mnt/debian/etc", | ||||
|     "auto_etc": false, | ||||
|     "cover": null | ||||
|   } | ||||
| } | ||||
| @ -1,20 +0,0 @@ | ||||
| plugins { | ||||
|     kotlin("jvm") | ||||
| } | ||||
| 
 | ||||
| repositories { | ||||
|     mavenCentral() | ||||
| } | ||||
| 
 | ||||
| dependencies { | ||||
|     implementation(project(":api")) | ||||
|     implementation(project(":cli")) | ||||
|     testImplementation(kotlin("test")) | ||||
| } | ||||
| 
 | ||||
| tasks.test { | ||||
|     useJUnitPlatform() | ||||
| } | ||||
| kotlin { | ||||
|     jvmToolchain(21) | ||||
| } | ||||
| @ -11,7 +11,7 @@ kotlin { | ||||
|     } | ||||
|     nativeTarget.binaries { | ||||
|         sharedLib { | ||||
|             baseName = "planterette" | ||||
|             baseName = "libplt" | ||||
|         } | ||||
|     } | ||||
|     sourceSets { | ||||
| @ -22,11 +22,5 @@ kotlin { | ||||
|             implementation(libs.bundles.kotlinxEcosystem) | ||||
|             implementation(kotlin("test")) | ||||
|         } | ||||
|         jvmMain.dependencies { | ||||
| 
 | ||||
|         } | ||||
|         jvmTest.dependencies { | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,51 @@ | ||||
| package app.hakurei.planterette.api | ||||
| 
 | ||||
| import app.hakurei.planterette.api.AbsolutePath.Companion.isAbsolute | ||||
| import kotlinx.io.files.Path | ||||
| import kotlinx.serialization.KSerializer | ||||
| import kotlinx.serialization.Serializable | ||||
| import kotlinx.serialization.Serializer | ||||
| import kotlinx.serialization.Transient | ||||
| import kotlinx.serialization.descriptors.PrimitiveKind | ||||
| import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor | ||||
| import kotlinx.serialization.descriptors.SerialDescriptor | ||||
| import kotlinx.serialization.encoding.Decoder | ||||
| import kotlinx.serialization.encoding.Encoder | ||||
| 
 | ||||
| /** | ||||
|  * AbsolutePath holds a pathname checked to be absolute. | ||||
|  * @constructor checks pathname and returns a new AbsolutePath if pathname is absolute. | ||||
|  */ | ||||
| @Serializable(with = AbsolutePathSerializer::class) | ||||
| data class AbsolutePath(val pathname: String, @Transient val path: Path = Path(pathname)) { | ||||
|     init { | ||||
|         if(!isAbsolute(pathname)) { | ||||
|             throw AbsolutePathException(pathname) | ||||
|         } | ||||
|     } | ||||
|     operator fun plus(other: String): AbsolutePath { | ||||
|         return AbsolutePath(pathname + other) | ||||
|     } | ||||
|     companion object { | ||||
|         fun isAbsolute(pathname: String): Boolean { | ||||
|             return Path(pathname).isAbsolute | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| object AbsolutePathSerializer : KSerializer<AbsolutePath> { | ||||
|     override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(this::class.qualifiedName!!, PrimitiveKind.STRING) | ||||
|     override fun serialize(encoder: Encoder, value: AbsolutePath) { | ||||
|         encoder.encodeString(value.pathname) | ||||
|     } | ||||
| 
 | ||||
|     override fun deserialize(decoder: Decoder): AbsolutePath { | ||||
|         val path = decoder.decodeString() | ||||
|         return AbsolutePath(path) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * AbsolutePathException is returned by @see AbsolutePath() and holds the invalid pathname. | ||||
|  */ | ||||
| data class AbsolutePathException(val pathname: String) : IllegalArgumentException("Path $pathname is not absolute") | ||||
| @ -0,0 +1,209 @@ | ||||
| package app.hakurei.planterette.api | ||||
| 
 | ||||
| import kotlinx.serialization.SerialName | ||||
| import kotlinx.serialization.Serializable | ||||
| 
 | ||||
| /** | ||||
|  * HakureiConfig is used to seal an app implementation. | ||||
|  * @param id reverse-DNS style arbitrary identifier string from config; Passed to wayland security-context-v1 as application ID and used as part of defaults in dbus session proxy | ||||
|  * | ||||
|  * @param path absolute path to executable file | ||||
|  * @param args final args passed to container init | ||||
|  * | ||||
|  * @param enablements system services to make available in the container | ||||
|  * | ||||
|  * @param sessionBus session D-Bus proxy configuration; null makes session bus proxy assume built-in defaults | ||||
|  * @param systemBus system D-Bus proxy configuration; null disables system bus proxy | ||||
|  * @param directWayland direct access to the wayland socket; when this gets set no attempt is made to attach security-context-v1 and the bare socket is mounted to the sandbox | ||||
|  * | ||||
|  * @param username passwd username in container, defaults to passwd name of target uid or chronos | ||||
|  * @param shell absolute path to shell | ||||
|  * @param data absolute path to home directory in the init mount namespace | ||||
|  * @param dir directory to ender and use as home in the container mount namespace, null for Data | ||||
|  * @param extraPerms extra ACL ops, dispatches before container init | ||||
|  * | ||||
|  * @param identity numerical application id, used for init user namespace credentials | ||||
|  * @param groups list of supplementary groups inherited by container processes | ||||
|  * | ||||
|  * @param container abstract container configuration baseline | ||||
|  */ | ||||
| @Serializable | ||||
| data class HakureiConfig( | ||||
|     val id: String, | ||||
| 
 | ||||
|     val path: AbsolutePath? = null, | ||||
|     val args: List<String>, | ||||
| 
 | ||||
|     val enablements: Byte, | ||||
| 
 | ||||
|     @SerialName("session_bus") val sessionBus: DbusConfig? = null, | ||||
|     @SerialName("system_bus") val systemBus: DbusConfig? = null, | ||||
|     @SerialName("direct_wayland") val directWayland: Boolean? = null, | ||||
| 
 | ||||
|     val username: String? = null, | ||||
|     val shell: AbsolutePath, | ||||
|     val data: AbsolutePath, | ||||
|     val dir: AbsolutePath, | ||||
|     @SerialName("extra_perms") val extraPerms: List<ExtraPermConfig>? = null, | ||||
| 
 | ||||
|     val identity: Int, | ||||
|     val groups: List<String>, | ||||
| 
 | ||||
|     val container: ContainerConfig | ||||
| ) { | ||||
|     @Serializable | ||||
|     data class DbusConfig( | ||||
|         val see: List<String>? = null, | ||||
|         val talk: List<String>? = null, | ||||
|         val own: List<String>? = null, | ||||
|         val call: Map<String, String>? = null, | ||||
|         val broadcast: Map<String, String>? = null, | ||||
| 
 | ||||
|         val log: Boolean? = null, | ||||
|         val filter: Boolean | ||||
|     ) | ||||
| 
 | ||||
|     /** | ||||
|      * ExtraPermConfig describes an ACL update op. | ||||
|      */ | ||||
|     @Serializable | ||||
|     data class ExtraPermConfig( | ||||
|         val ensure: Boolean? = null, | ||||
|         val path: AbsolutePath, | ||||
|         @SerialName("r") val read: Boolean? = null, | ||||
|         @SerialName("w") val write: Boolean? = null, | ||||
|         @SerialName("x") val execute: Boolean? = null | ||||
|     ) | ||||
| 
 | ||||
|     /** | ||||
|      * ContainerConfig describes the container configuration baseline to which the app implementation adds upon. | ||||
|      * @param hostname container hostname | ||||
|      * @param waitDelay duration to wait for after interrupting a container's initial process in nanoseconds; a negative value causes the container to be terminated immediately on cancellation | ||||
|      * @param seccompFlags extra seccomp flags | ||||
|      * @param seccompPresets extra seccomp presets | ||||
|      * @param seccompCompat disable project-specific filter extensions | ||||
|      * @param devel allow ptrace and friends | ||||
|      * @param userns allow userns creation in container | ||||
|      * @param net share host net namespace | ||||
|      * @param tty allow dangerous terminal I/O | ||||
|      * @param multiarch allow multiarch | ||||
|      * | ||||
|      * @param env initial process environment variables | ||||
|      * @param mapRealUid map target user uid to privileged user uid in the user namespace | ||||
|      * | ||||
|      * @param device pass through all devices | ||||
|      * @param filesystem container host filesystem bind mounts | ||||
|      * @param link create symlinks inside container filesystem | ||||
|      * | ||||
|      * @param autoRoot automatically bind mount top-level directories to container root; the zero value disables this behaviour | ||||
|      * @param rootFlags extra flags for AutoRoot | ||||
|      * | ||||
|      * @param etc read-only /etc directory | ||||
|      * @param autoEtc automatically set up /etc symlinks | ||||
|      */ | ||||
|     @Serializable | ||||
|     data class ContainerConfig( | ||||
|         val hostname: String?, | ||||
|         @SerialName("wait_delay") val waitDelay: Int? = null, | ||||
|         @SerialName("seccomp_flags") val seccompFlags: Int, | ||||
|         @SerialName("seccomp_presets") val seccompPresets: Int, | ||||
|         @SerialName("seccomp_compat") val seccompCompat: Boolean? = null, | ||||
| 
 | ||||
|         val devel: Boolean? = null, | ||||
|         val userns: Boolean? = null, | ||||
|         val net: Boolean? = null, | ||||
|         val tty: Boolean? = null, | ||||
|         val multiarch: Boolean? = null, | ||||
| 
 | ||||
|         val env: Map<String, String>, | ||||
|         @SerialName("map_real_uid") val mapRealUid: Boolean, | ||||
| 
 | ||||
|         val device: Boolean?, | ||||
|         val filesystem: List<FilesystemConfig>, | ||||
|         @SerialName("symlink") val link: List<LinkConfig>, | ||||
| 
 | ||||
|         @SerialName("auto_root") val autoRoot: AbsolutePath, | ||||
|         @SerialName("root_flags") val rootFlags: Int, | ||||
| 
 | ||||
|         val etc: AbsolutePath?, | ||||
| 
 | ||||
|         @SerialName("auto_etc") val autoEtc: Boolean, | ||||
|     ) | ||||
| 
 | ||||
|     /** | ||||
|      * FilesystemConfig is an abstract representation of a bind mount. | ||||
|      * @param dst mount point in container, same as src if empty | ||||
|      * @param src host filesystem path to make available to the container | ||||
|      * @param write do not mount filesystem read-only | ||||
|      * @param device do not disable device files | ||||
|      * @param must fail if the bind mount cannot be established for any reason | ||||
|      */ | ||||
|     @Serializable | ||||
|     data class FilesystemConfig( | ||||
|         val dst: AbsolutePath? = null, | ||||
|         val src: AbsolutePath, | ||||
|         val write: Boolean? = null, | ||||
|         @SerialName("dev") val device: Boolean? = null, | ||||
|         @SerialName("require") val must: Boolean? = null | ||||
|     ) | ||||
| 
 | ||||
|     /** | ||||
|      * @param target symlink target in container | ||||
|      * @param linkname linkname the symlink points to; prepend '*' to dereference an absolute pathname on host | ||||
|      */ | ||||
|     @Serializable | ||||
|     data class LinkConfig( | ||||
|         val target: AbsolutePath, | ||||
|         val linkname: String | ||||
|     ) | ||||
|     enum class Enablement(val value: Int) { | ||||
|         Wayland(1 shl 0), | ||||
|         X11(1 shl 1), | ||||
|         DBus(1 shl 2), | ||||
|         Pulse(1 shl 3); | ||||
| 
 | ||||
|         companion object { | ||||
|             fun enablements(vararg enablements: Enablement): Byte { | ||||
|                 return enablements.orOf(Enablement::value).toByte() | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     enum class SeccompFilterPreset(val value: Int) { | ||||
|         Ext(1 shl 0), | ||||
|         DenyNS(1 shl 1), | ||||
|         DenyTTY(1 shl 2), | ||||
|         DenyDevel(1 shl 3), | ||||
|         Linux32(1 shl 4); | ||||
| 
 | ||||
|         companion object { | ||||
|             fun filterPresets(vararg filterPresets: SeccompFilterPreset): Int { | ||||
|                 return filterPresets.orOf(SeccompFilterPreset::value) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     enum class HakureiExportFlag(val value: Int) { | ||||
|         Multiarch(1 shl 0), | ||||
|         CAN(1 shl 1), | ||||
|         Bluetooth(1 shl 2); | ||||
| 
 | ||||
|         companion object { | ||||
|             fun exportFlags(vararg exportFlags: HakureiExportFlag): Int { | ||||
|                 return exportFlags.orOf(HakureiExportFlag::value) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     enum class RootFlag(val value: Int) { | ||||
|         Optional(1 shl 0), | ||||
|         Writable(1 shl 1), | ||||
|         Device(1 shl 2); | ||||
| 
 | ||||
|         companion object { | ||||
|             fun rootFlags(vararg rootFlags: RootFlag): Int { | ||||
|                 return rootFlags.orOf(RootFlag::value) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -4,13 +4,13 @@ import kotlinx.serialization.Serializable | ||||
| 
 | ||||
| @Serializable | ||||
| data class PackageManifest( | ||||
|     val hakureiConfig: HakureiConfig, | ||||
|     val id: String, | ||||
|     val version: Version, | ||||
|     val name: String, | ||||
|     val description: String, | ||||
|     val architecture: List<Architecture>, | ||||
|     val baseImage: BaseImage | ||||
|     var hakureiConfig: HakureiConfig, | ||||
|     var id: String, | ||||
|     var version: Version, | ||||
|     var name: String, | ||||
|     var description: String, | ||||
|     var architecture: MutableList<Architecture>, | ||||
|     var baseImage: BaseImage | ||||
| ) { | ||||
|     @Serializable | ||||
|     data class Version(val version: String, val canonicalVersion: UInt) | ||||
| @ -21,10 +21,12 @@ data class PackageManifest( | ||||
|         ARM64, | ||||
|     } | ||||
|     @Serializable | ||||
|     enum class BaseImage { | ||||
|         DEBIAN, | ||||
|         CHIMERA, | ||||
| 
 | ||||
|     data class BaseImage(val type: Type) { | ||||
|         @Serializable | ||||
|         enum class Type { | ||||
|             DEBIAN, | ||||
|             CHIMERA, | ||||
|         } | ||||
|     } | ||||
|     companion object { | ||||
|         val fileList = listOf("planterette.json", "icon.png", "image.tar") | ||||
| @ -0,0 +1,47 @@ | ||||
| package app.hakurei.planterette.api | ||||
| 
 | ||||
| object Paths { | ||||
|     const val FHSRoot = "/" | ||||
|     const val FHSEtc = "/etc/" | ||||
|     const val FHSTmp = "/tmp/" | ||||
| 
 | ||||
|     const val FHSRun = "/run/" | ||||
|     const val FHSRunUser = FHSRun + "user/" | ||||
| 
 | ||||
|     const val FHSUsr = "/usr/" | ||||
|     const val FHSUsrBin = FHSUsr + "bin/" | ||||
| 
 | ||||
|     const val FHSVar = "/var/" | ||||
|     const val FHSVarLib = FHSVar + "lib/" | ||||
|     const val FHSVarEmpty = FHSVar + "empty/" | ||||
| 
 | ||||
|     const val FHSDev = "/dev/" | ||||
|     const val FHSProc = "/proc/" | ||||
|     const val FHSProcSys = FHSProc + "sys/" | ||||
|     const val FHSSys = "/sys/" | ||||
| 
 | ||||
|     const val Nonexistent = FHSProc + "nonexistent" | ||||
|     const val sysrootDir = "sysroot" | ||||
|     const val hostDir = "host" | ||||
|     const val hostPath = FHSRoot + hostDir | ||||
|     const val sysrootPath = FHSRoot + sysrootDir | ||||
| 
 | ||||
|     val AbsFHSRoot = AbsolutePath(FHSRoot) | ||||
|     val AbsFHSEtc = AbsolutePath(FHSEtc) | ||||
|     val AbsFHSTmp = AbsolutePath(FHSTmp) | ||||
| 
 | ||||
|     val AbsFHSRun = AbsolutePath(FHSRun) | ||||
|     val AbsFHSRunUser = AbsolutePath(FHSRunUser) | ||||
| 
 | ||||
|     val AbsFHSUsrBin = AbsolutePath(FHSUsrBin) | ||||
| 
 | ||||
|     val AbsFHSVar = AbsolutePath(FHSVar) | ||||
|     val AbsFHSVarLib = AbsolutePath(FHSVarLib) | ||||
| 
 | ||||
|     val AbsFHSDev = AbsolutePath(FHSDev) | ||||
|     val AbsFHSProc = AbsolutePath(FHSProc) | ||||
|     val AbsFHSSys = AbsolutePath(FHSSys) | ||||
| 
 | ||||
|     val AbsNonexistent = AbsolutePath(Nonexistent) | ||||
| } | ||||
| 
 | ||||
| @ -14,3 +14,11 @@ object Util { | ||||
|         return buffer.readString() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| inline fun <T> Array<out T>.orOf(selector: (T) -> Int): Int { | ||||
|     var sum = 0 | ||||
|     for (element in this) { | ||||
|         sum = sum or selector(element) | ||||
|     } | ||||
|     return sum | ||||
| } | ||||
| @ -0,0 +1,230 @@ | ||||
| package app.hakurei.planterette.api | ||||
| 
 | ||||
| import app.hakurei.planterette.api.HakureiConfig.Enablement.* | ||||
| 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 | ||||
| 
 | ||||
| class HakureiConfigTest { | ||||
|     @OptIn(ExperimentalSerializationApi::class) | ||||
|     val format = Json { | ||||
|         explicitNulls = false | ||||
|         prettyPrint = true | ||||
|     } | ||||
|     val want: String = """ | ||||
|         { | ||||
|         	"id": "org.chromium.Chromium", | ||||
|         	"path": "/run/current-system/sw/bin/chromium", | ||||
|         	"args": [ | ||||
|         		"chromium", | ||||
|         		"--ignore-gpu-blocklist", | ||||
|         		"--disable-smooth-scrolling", | ||||
|         		"--enable-features=UseOzonePlatform", | ||||
|         		"--ozone-platform=wayland" | ||||
|         	], | ||||
|         	"enablements": 13, | ||||
|         	"session_bus": { | ||||
|         		"see": null, | ||||
|         		"talk": [ | ||||
|         			"org.freedesktop.Notifications", | ||||
|         			"org.freedesktop.FileManager1", | ||||
|         			"org.freedesktop.ScreenSaver", | ||||
|         			"org.freedesktop.secrets", | ||||
|         			"org.kde.kwalletd5", | ||||
|         			"org.kde.kwalletd6", | ||||
|         			"org.gnome.SessionManager" | ||||
|         		], | ||||
|         		"own": [ | ||||
|         			"org.chromium.Chromium.*", | ||||
|         			"org.mpris.MediaPlayer2.org.chromium.Chromium.*", | ||||
|         			"org.mpris.MediaPlayer2.chromium.*" | ||||
|         		], | ||||
|         		"call": { | ||||
|         			"org.freedesktop.portal.*": "*" | ||||
|         		}, | ||||
|         		"broadcast": { | ||||
|         			"org.freedesktop.portal.*": "@/org/freedesktop/portal/*" | ||||
|         		}, | ||||
|         		"filter": true | ||||
|         	}, | ||||
|         	"system_bus": { | ||||
|         		"see": null, | ||||
|         		"talk": [ | ||||
|         			"org.bluez", | ||||
|         			"org.freedesktop.Avahi", | ||||
|         			"org.freedesktop.UPower" | ||||
|         		], | ||||
|         		"own": null, | ||||
|         		"call": null, | ||||
|         		"broadcast": null, | ||||
|         		"filter": true | ||||
|         	}, | ||||
|         	"username": "chronos", | ||||
|         	"shell": "/run/current-system/sw/bin/zsh", | ||||
|         	"data": "/var/lib/hakurei/u0/org.chromium.Chromium", | ||||
|         	"dir": "/data/data/org.chromium.Chromium", | ||||
|         	"extra_perms": [ | ||||
|         		{ | ||||
|         			"ensure": true, | ||||
|         			"path": "/var/lib/hakurei/u0", | ||||
|         			"x": true | ||||
|         		}, | ||||
|         		{ | ||||
|         			"path": "/var/lib/hakurei/u0/org.chromium.Chromium", | ||||
|         			"r": true, | ||||
|         			"w": true, | ||||
|         			"x": true | ||||
|         		} | ||||
|         	], | ||||
|         	"identity": 9, | ||||
|         	"groups": [ | ||||
|         		"video", | ||||
|         		"dialout", | ||||
|         		"plugdev" | ||||
|         	], | ||||
|         	"container": { | ||||
|         		"hostname": "localhost", | ||||
|         		"wait_delay": -1, | ||||
|         		"seccomp_flags": 1, | ||||
|         		"seccomp_presets": 1, | ||||
|         		"seccomp_compat": true, | ||||
|         		"devel": true, | ||||
|         		"userns": true, | ||||
|         		"net": true, | ||||
|         		"tty": true, | ||||
|         		"multiarch": true, | ||||
|         		"env": { | ||||
|         			"GOOGLE_API_KEY": "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY", | ||||
|         			"GOOGLE_DEFAULT_CLIENT_ID": "77185425430.apps.googleusercontent.com", | ||||
|         			"GOOGLE_DEFAULT_CLIENT_SECRET": "OTJgUOQcT7lO7GsGZq2G4IlT" | ||||
|         		}, | ||||
|         		"map_real_uid": true, | ||||
|         		"device": true, | ||||
|         		"filesystem": [ | ||||
|         			{ | ||||
|         				"dst": "/tmp/", | ||||
|         				"src": "/proc/nonexistent", | ||||
|         				"write": true | ||||
|         			}, | ||||
|         			{ | ||||
|         				"src": "/nix/store" | ||||
|         			}, | ||||
|         			{ | ||||
|         				"src": "/run/current-system" | ||||
|         			}, | ||||
|         			{ | ||||
|         				"src": "/run/opengl-driver" | ||||
|         			}, | ||||
|         			{ | ||||
|         				"src": "/var/db/nix-channels" | ||||
|         			}, | ||||
|         			{ | ||||
|         				"dst": "/data/data/org.chromium.Chromium", | ||||
|         				"src": "/var/lib/hakurei/u0/org.chromium.Chromium", | ||||
|         				"write": true, | ||||
|         				"require": true | ||||
|         			}, | ||||
|         			{ | ||||
|         				"src": "/dev/dri", | ||||
|         				"dev": true | ||||
|         			} | ||||
|         		], | ||||
|         		"symlink": [ | ||||
|         			{ | ||||
|         				"target": "/run/user/65534", | ||||
|         				"linkname": "/run/user/150" | ||||
|         			} | ||||
|         		], | ||||
|         		"auto_root": "/var/lib/hakurei/base/org.debian", | ||||
|         		"root_flags": 2, | ||||
|         		"etc": "/etc/", | ||||
|         		"auto_etc": true | ||||
|         	} | ||||
|         } | ||||
|     """.trimIndent() | ||||
|     @Test | ||||
|     fun testHakureiConfigSerialization() { | ||||
|         val testConfig = HakureiConfig( | ||||
|             id = "org.chromium.Chromium", | ||||
|             path = Paths.AbsFHSRun + "current-system/sw/bin/chromium", | ||||
|             args = listOf( | ||||
|                     "chromium", | ||||
|                     "--ignore-gpu-blocklist", | ||||
|                     "--disable-smooth-scrolling", | ||||
|                     "--enable-features=UseOzonePlatform", | ||||
|                     "--ozone-platform=wayland", | ||||
|                 ), | ||||
|             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.*"), | ||||
|                 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, | ||||
|             ), | ||||
|             directWayland = false, | ||||
| 
 | ||||
|             username = "chronos", | ||||
|             shell = Paths.AbsFHSRun + "current-system/sw/bin/zsh", | ||||
|             data = Paths.AbsFHSVarLib + "hakurei/u0/org.chromium.Chromium", | ||||
|             dir = AbsolutePath("/data/data/org.chromium.Chromium"), | ||||
|             extraPerms = listOf( | ||||
|                 HakureiConfig.ExtraPermConfig(path = Paths.AbsFHSVarLib + "hakurei/u0", ensure = true, execute = true), | ||||
|                 HakureiConfig.ExtraPermConfig(path = Paths.AbsFHSVarLib + "hakurei/u0/org.chromium.Chromium", read = true, write = true, execute = true) | ||||
|             ), | ||||
|             identity = 9, | ||||
|             groups = listOf("video", "dialout", "plugdev"), | ||||
|             container = HakureiConfig.ContainerConfig( | ||||
|                 hostname = "localhost", | ||||
|                 devel = true, | ||||
|                 userns = true, | ||||
|                 net = true, | ||||
|                 device = true, | ||||
|                 waitDelay = -1, | ||||
|                 seccompFlags = HakureiConfig.HakureiExportFlag.exportFlags(HakureiConfig.HakureiExportFlag.Multiarch), | ||||
|                 seccompPresets = HakureiConfig.SeccompFilterPreset.filterPresets(HakureiConfig.SeccompFilterPreset.Ext), | ||||
|                 seccompCompat = true, | ||||
|                 tty = true, | ||||
|                 multiarch = true, | ||||
|                 mapRealUid = true, | ||||
|                 env = mapOf( | ||||
|                     "GOOGLE_API_KEY" to "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY", | ||||
|                     "GOOGLE_DEFAULT_CLIENT_ID" to "77185425430.apps.googleusercontent.com", | ||||
|                     "GOOGLE_DEFAULT_CLIENT_SECRET" to "OTJgUOQcT7lO7GsGZq2G4IlT" | ||||
|                 ), | ||||
|                 filesystem = listOf( | ||||
|                     HakureiConfig.FilesystemConfig(dst = Paths.AbsFHSTmp, src = Paths.AbsNonexistent, write = true), | ||||
|                     HakureiConfig.FilesystemConfig(src = AbsolutePath("/nix/store")), | ||||
|                     HakureiConfig.FilesystemConfig(src = Paths.AbsFHSRun + "current-system"), | ||||
|                     HakureiConfig.FilesystemConfig(src = Paths.AbsFHSRun + "opengl-driver"), | ||||
|                     HakureiConfig.FilesystemConfig(src = Paths.AbsFHSVar + "db/nix-channels"), | ||||
|                     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")), | ||||
|                 autoRoot = Paths.AbsFHSVarLib + "hakurei/base/org.debian", | ||||
|                 rootFlags = RootFlag.rootFlags(RootFlag.Writable), | ||||
|                 etc = Paths.AbsFHSEtc, | ||||
|                 autoEtc = true | ||||
|             ) | ||||
|         ) | ||||
|         println("printing for now until a more proper test can be written") | ||||
|         println(format.encodeToString(testConfig)) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										30
									
								
								plt-build/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								plt-build/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| plugins { | ||||
|     kotlin("multiplatform") | ||||
| } | ||||
| kotlin { | ||||
|     jvm() | ||||
|     val nativeTarget = if(System.getProperty("os.arch") == "aarch64") { | ||||
|         linuxArm64("native") | ||||
|     } else { | ||||
|         linuxX64("native") | ||||
|     } | ||||
|     nativeTarget.binaries { | ||||
|         executable() | ||||
|     } | ||||
|     sourceSets { | ||||
|         nativeMain.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|         } | ||||
|         nativeTest.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|             implementation(kotlin("test")) | ||||
|         } | ||||
|         jvmMain.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|         } | ||||
|         jvmTest.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|             implementation(kotlin("test")) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,16 @@ | ||||
| package app.hakurei.planterette.api | ||||
| 
 | ||||
| interface Task { | ||||
|     val execute: String | ||||
| } | ||||
| class AptInstallTask(val packages: List<String>) : Task { | ||||
|     private fun getPackageList(): String { | ||||
|         var string = "" | ||||
|         packages.forEach { p -> | ||||
|             string += "$p " | ||||
|         } | ||||
|         return string | ||||
|     } | ||||
|     override val execute: String | ||||
|         get() = "sudo apt install ${getPackageList()}" | ||||
| } | ||||
							
								
								
									
										22
									
								
								plt-fetch/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								plt-fetch/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| plugins { | ||||
|     kotlin("multiplatform") | ||||
| } | ||||
| kotlin { | ||||
|     val nativeTarget = if(System.getProperty("os.arch") == "aarch64") { | ||||
|         linuxArm64("native") | ||||
|     } else { | ||||
|         linuxX64("native") | ||||
|     } | ||||
|     nativeTarget.binaries { | ||||
|         executable() | ||||
|     } | ||||
|     sourceSets { | ||||
|         nativeMain.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|         } | ||||
|         nativeTest.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|             implementation(kotlin("test")) | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										22
									
								
								plt-pkg/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								plt-pkg/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| plugins { | ||||
|     kotlin("multiplatform") | ||||
| } | ||||
| kotlin { | ||||
|     val nativeTarget = if(System.getProperty("os.arch") == "aarch64") { | ||||
|         linuxArm64("native") | ||||
|     } else { | ||||
|         linuxX64("native") | ||||
|     } | ||||
|     nativeTarget.binaries { | ||||
|         executable() | ||||
|     } | ||||
|     sourceSets { | ||||
|         nativeMain.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|         } | ||||
|         nativeTest.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|             implementation(kotlin("test")) | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										22
									
								
								plt/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								plt/build.gradle.kts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| plugins { | ||||
|     kotlin("multiplatform") | ||||
| } | ||||
| kotlin { | ||||
|     val nativeTarget = if(System.getProperty("os.arch") == "aarch64") { | ||||
|         linuxArm64("native") | ||||
|     } else { | ||||
|         linuxX64("native") | ||||
|     } | ||||
|     nativeTarget.binaries { | ||||
|             executable() | ||||
|     } | ||||
|     sourceSets { | ||||
|         nativeMain.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|         } | ||||
|         nativeTest.dependencies { | ||||
|             implementation(project(":libplt")) | ||||
|             implementation(kotlin("test")) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -9,9 +9,10 @@ plugins { | ||||
|     id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" | ||||
| } | ||||
| 
 | ||||
| include(":daemon") | ||||
| include(":api") | ||||
| include(":cli") | ||||
| include(":gui") | ||||
| 
 | ||||
| rootProject.name = "planterette" | ||||
| 
 | ||||
| include("plt") | ||||
| include("libplt") | ||||
| include("plt-build") | ||||
| include("plt-fetch") | ||||
| include("plt-pkg") | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user