Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to load consumer packaged binary resources #284

Merged
merged 5 commits into from
Mar 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions build-environment/src/main/kotlin/kmp/tor/env.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ object env {
// Must be either "-SNAPSHOT" || ""
private const val SNAPSHOT = "-SNAPSHOT"

private const val MANAGER_VERSION_NAME = "1.3.5"
private const val MANAGER_VERSION_NAME = "1.4.0"
// 1.0.0-alpha1 == 01_00_00_11
// 1.0.0-alpha2 == 01_00_00_12
// 1.0.0-beta1 == 01_00_00_21
Expand All @@ -29,13 +29,13 @@ object env {
// 1.0.1 == 01_00_01_99
// 1.1.1 == 01_01_01_99
// 1.15.1 == 01_15_01_99
private const val MANAGER_VERSION_CODE = /*0*/1_03_05_99
private const val MANAGER_VERSION_CODE = /*0*/1_04_00_99

private const val BINARY_VERSION_NAME = "4.7.13-0"
private const val BINARY_VERSION_NAME = "4.7.13-1"
// 4.6.9-0 == 00_04_06_09_00
// 4.6.9-1 == 00_04_06_09_01
// 4.6.9-2 == 00_04_06_09_02
private const val BINARY_VERSION_CODE = /*00_0*/4_07_13_00
private const val BINARY_VERSION_CODE = /*00_0*/4_07_13_01

/**
* Binaries exist in a different repo. Building against the staged
Expand Down
2 changes: 2 additions & 0 deletions library/kmp-tor/api/jvm/kmp-tor.api
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public final class io/matthewnelson/kmp/tor/PlatformInstaller {
public final field os Ljava/lang/String;
public final field sha256Sum Ljava/lang/String;
public synthetic fun <init> (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;Lio/matthewnelson/kmp/tor/binary/extract/TorResource$Binaries;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public static final fun custom (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;Lio/matthewnelson/kmp/tor/binary/extract/TorBinaryResource;)Lio/matthewnelson/kmp/tor/PlatformInstaller;
public final fun isLinux ()Z
public final fun isMacos ()Z
public final fun isMingw ()Z
Expand All @@ -22,6 +23,7 @@ public final class io/matthewnelson/kmp/tor/PlatformInstaller {
}

public final class io/matthewnelson/kmp/tor/PlatformInstaller$Companion {
public final fun custom (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;Lio/matthewnelson/kmp/tor/binary/extract/TorBinaryResource;)Lio/matthewnelson/kmp/tor/PlatformInstaller;
public final fun linuxX64 (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;)Lio/matthewnelson/kmp/tor/PlatformInstaller;
public final fun linuxX86 (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;)Lio/matthewnelson/kmp/tor/PlatformInstaller;
public final fun macosArm64 (Lio/matthewnelson/kmp/tor/PlatformInstaller$InstallOption;)Lio/matthewnelson/kmp/tor/PlatformInstaller;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,31 @@ class PlatformInstaller private constructor(
resource = TorResourceMingwX86,
)
}

/**
* In the event a platform and given architecture is not supported by kmp-tor, you
* can package your own, model the resources via [TorBinaryResource], and then have
* the files extracted and loaded at runtime.
*
* DISCLAIMER: Using this option does **not** guarantee kmp-tor compatibility with
* the version of Tor being loaded, as kmp-tor is only tested against binaries
* provided by the kmp-tor-binary project.
*
* Must:
* - Add dependency:
* - io.matthewnelson.kotlin-components:kmp-tor-binary-extract:(version)
* - package and model your binary resources in accordance with [TorBinaryResource]
* */
@JvmStatic
fun custom(
option: InstallOption,
resource: TorBinaryResource
): PlatformInstaller {
return PlatformInstaller(
installOption = option,
resource = resource,
)
}
}

@JvmField
Expand All @@ -139,6 +164,7 @@ class PlatformInstaller private constructor(
is TorResourceMacosArm64 -> MACOS
is TorResourceMingwX64,
is TorResourceMingwX86 -> MINGW
is TorBinaryResource -> resource.osName
}

@JvmField
Expand All @@ -149,6 +175,7 @@ class PlatformInstaller private constructor(
is TorResourceMacosArm64 -> ARM64
is TorResourceMingwX64 -> X64
is TorResourceMingwX86 -> X86
is TorBinaryResource -> resource.arch
}

@JvmField
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package io.matthewnelson.kmp.tor

import io.matthewnelson.kmp.tor.binary.extract.TorBinaryResource
import kotlinx.coroutines.runBlocking
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import java.io.File

class PlatformInstallerUnitTest {

@get:Rule
val testDir: TemporaryFolder = TemporaryFolder()
private lateinit var workDir: File

private val osName = System.getProperty("os.name")
private var resource: TorBinaryResource? = null

@Before
fun before() {
// Load static test resources for tor 0.4.7.12
resource = when {
osName.startsWith("Windows", true) -> {
TorBinaryResource.from(
os = TorBinaryResource.OS.Mingw,
arch = "testx64",
sha256sum = "f228252a094f3fed8d9d08d6b98f1925644cfbbf59fbd08c566bf184027068e4",
resourceManifest = listOf(
"tor.exe.gz",
"tor-gencert.exe.gz"
),
)
}

osName == "Mac OS X" -> {
TorBinaryResource.from(
os = TorBinaryResource.OS.Macos,
arch = "testx64",
sha256sum = "7c5687a3916483ee6c402ed77a99c6025c19b1bfdf54cb6e2e00601642451c82",
resourceManifest = listOf(
"libevent-2.1.7.dylib.gz",
"tor.gz"
),
)
}

osName.contains("Mac", true) -> {
TorBinaryResource.from(
os = TorBinaryResource.OS.Macos,
arch = "testarm64",
sha256sum = "0d9217a47af322d72e9213c1afdd53f4f571ff0483d8053726e56efeec850ff1",
resourceManifest = listOf(
"libevent-2.1.7.dylib.gz",
"tor.gz"
),
)
}

osName == "Linux" -> {
TorBinaryResource.from(
os = TorBinaryResource.OS.Linux,
arch = "testx64",
sha256sum = "7ea1e0a19f63d2542b34e1cfe8f8135b278a0eea5a7fd8d25e78e12972834ae2",
resourceManifest = listOf(
"libcrypto.so.1.1.gz",
"libevent-2.1.so.7.gz",
"libssl.so.1.1.gz",
"libstdc++.so.6.gz",
"tor.gz"
)
)
}
else -> null
}

workDir = resource?.let { r ->
testDir.newFolder(r.osName + r.arch)
} ?: testDir.newFolder()
}

@Test
fun givenPlatformInstaller_whenCustomBinaryResources_thenAreLoaded() = runBlocking {
val resource = resource
if (resource == null) {
println("osName($osName) not recognized. Skipping test")
} else {

val installer = PlatformInstaller.custom(
option = PlatformInstaller.InstallOption.CleanInstallOnEachStart,
resource = resource
)

val tor = installer.retrieveTor(workDir)
println("Tor Executable for osName($osName): $tor")
}

Unit
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
12 changes: 11 additions & 1 deletion samples/kotlin/javafx/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,14 @@ kotlin {
osName.contains("Windows", true) -> {
implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-mingwx64:${env.kmpTorBinaries.version.name}")
}
osName.contains("Mac", true) || osName.contains("Darwin", true) -> {
osName == "Mac OS X" -> {
implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-macosx64:${env.kmpTorBinaries.version.name}")
}
osName.contains("Mac", true) -> {
// Will be providing our own binary resources for arm64 Tor 0.4.7.12 as an example
// which are located in resources/kmptor/macos/arm64 of this sample.
// implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-macosx64:${env.kmpTorBinaries.version.name}")
}
osName.contains("linux", true) -> {
implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-linuxx64:${env.kmpTorBinaries.version.name}")
}
Expand All @@ -90,6 +95,11 @@ kotlin {
}
}

// In order to model our binary resources for macOS arm64, will need the extract
// dependency (which is not provided with the kmp-tor import) to be able to use
// the TorBinaryResource class
implementation("io.matthewnelson.kotlin-components:kmp-tor-binary-extract:${env.kmpTorBinaries.version.name}")

// Add support for Unix Domain Sockets (Only necessary for JDK 15 and below)
implementation(project(":library:extensions:kmp-tor-ext-unix-socket"))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@ import io.matthewnelson.kmp.tor.KmpTorLoaderJvm
import io.matthewnelson.kmp.tor.PlatformInstaller
import io.matthewnelson.kmp.tor.PlatformInstaller.InstallOption
import io.matthewnelson.kmp.tor.TorConfigProviderJvm
import io.matthewnelson.kmp.tor.binary.extract.TorBinaryResource
import io.matthewnelson.kmp.tor.common.address.*
import io.matthewnelson.kmp.tor.common.annotation.InternalTorApi
import io.matthewnelson.kmp.tor.controller.common.config.TorConfig
import io.matthewnelson.kmp.tor.controller.common.config.TorConfig.Setting.*
import io.matthewnelson.kmp.tor.controller.common.config.TorConfig.Option.*
import io.matthewnelson.kmp.tor.controller.common.control.usecase.TorControlInfoGet
import io.matthewnelson.kmp.tor.controller.common.events.TorEvent
import io.matthewnelson.kmp.tor.controller.common.file.Path
import io.matthewnelson.kmp.tor.controller.common.internal.PlatformUtil
import io.matthewnelson.kmp.tor.manager.TorManager
import io.matthewnelson.kmp.tor.manager.common.TorControlManager
import io.matthewnelson.kmp.tor.manager.common.TorOperationManager
Expand All @@ -49,15 +48,35 @@ class SampleApp: App(SampleView::class) {

private val platformInstaller: PlatformInstaller by lazy {

@OptIn(InternalTorApi::class)
val osName = System.getProperty("os.name")

val installer = when {
PlatformUtil.isMingw -> {
osName.contains("Windows", true) -> {
PlatformInstaller.mingwX64(InstallOption.CleanInstallIfMissing)
}
PlatformUtil.isDarwin -> {
osName == "Mac OS X" -> {
PlatformInstaller.macosX64(InstallOption.CleanInstallIfMissing)
}
PlatformUtil.isLinux -> {
osName.contains("Mac", true) -> {

// Example of providing your own packaged binary resources in the event a
// platform or architecture is not currently supported by kmp-tor-binary.
//
// Note that there IS a macOS arm64 binary dependency provided by
// kmp-tor-binary and that should be used instead; this is just an example.
//
// Files are located in this sample's resources/kmptor/macos/arm64 directory
PlatformInstaller.custom(
InstallOption.CleanInstallIfMissing,
TorBinaryResource.from(
os = TorBinaryResource.OS.Macos,
arch = "arm64",
sha256sum = "0d9217a47af322d72e9213c1afdd53f4f571ff0483d8053726e56efeec850ff1",
resourceManifest = listOf("libevent-2.1.7.dylib.gz", "tor.gz")
)
)
}
osName.contains("linux", true) -> {
PlatformInstaller.linuxX64(InstallOption.CleanInstallIfMissing)
}
else -> {
Expand Down
Binary file not shown.
Binary file not shown.