Skip to content
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
3 changes: 2 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ ij_kotlin_keep_blank_lines_before_right_brace = 0
ij_kotlin_align_multiline_parameters = false
ij_continuation_indent_size = 4
ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma = true
ktlint_property_naming_constant_naming = pascal_case
6 changes: 6 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jmailen.gradle.kotlinter.support.ReporterType

plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlinx.serialization)
Expand Down Expand Up @@ -124,3 +126,7 @@ publishing {
}
}
}

kotlinter {
reporters = arrayOf(ReporterType.html.name)
}
99 changes: 19 additions & 80 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,92 +4,31 @@ ktx-coroutines = "1.10.2"
ktx-serialization = "1.9.0"
ktor = "3.3.2"
junixsocket = "2.6.1"
junit = "5.12.2"
slf4j = "2.0.13"
apache-compress = "1.26.2"
kotlinx-io = "0.8.0"
plugin-kotlinter = "5.3.0"
plugin-publish = "0.35.0"

[libraries.ktx-coroutines-core]
module = "org.jetbrains.kotlinx:kotlinx-coroutines-core"
version.ref = "ktx-coroutines"

[libraries.ktx-coroutines-test]
module = "org.jetbrains.kotlinx:kotlinx-coroutines-test"
version.ref = "ktx-coroutines"

[libraries.ktx-serialization-core]
module = "org.jetbrains.kotlinx:kotlinx-serialization-core"
version.ref = "ktx-serialization"

[libraries.ktx-serialization-json]
module = "org.jetbrains.kotlinx:kotlinx-serialization-json"
version.ref = "ktx-serialization"

[libraries.ktor-client-core]
module = "io.ktor:ktor-client-core"
version.ref = "ktor"

[libraries.ktor-client-engine-okhttp]
module = "io.ktor:ktor-client-okhttp"
version.ref = "ktor"

[libraries.ktor-client-engine-cio]
module = "io.ktor:ktor-client-cio"
version.ref = "ktor"

[libraries.ktor-client-serialization]
module = "io.ktor:ktor-client-serialization"
version.ref = "ktor"

[libraries.ktor-client-json]
module = "io.ktor:ktor-client-json"
version.ref = "ktor"

[libraries.ktor-client-logging]
module = "io.ktor:ktor-client-logging"
version.ref = "ktor"

[libraries.ktor-client-mock]
module = "io.ktor:ktor-client-mock"
version.ref = "ktor"

[libraries.ktor-client-content-negotiation]
module = "io.ktor:ktor-client-content-negotiation"
version.ref = "ktor"

[libraries.ktor-serialization-kotlinx-json]
module = "io.ktor:ktor-serialization-kotlinx-json"
version.ref = "ktor"

[libraries.ktor-network]
module = "io.ktor:ktor-network"
version.ref = "ktor"

[libraries.junixsocket-common]
module = "com.kohlschutter.junixsocket:junixsocket-common"
version.ref = "junixsocket"

[libraries.junixsocket-native]
module = "com.kohlschutter.junixsocket:junixsocket-native-common"
version.ref = "junixsocket"

[libraries.junit]
module = "org.junit.jupiter:junit-jupiter-engine"
version.ref = "junit"

[libraries.slf4j-api]
module = "org.slf4j:slf4j-api"
version.ref = "slf4j"

[libraries.apache-compress]
module = "org.apache.commons:commons-compress"
version.ref = "apache-compress"

[libraries.kotlinx-io-core]
module = "org.jetbrains.kotlinx:kotlinx-io-core"
version.ref = "kotlinx-io"
[libraries]
ktx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "ktx-coroutines" }
ktx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "ktx-coroutines" }
ktx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "ktx-serialization" }
ktx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "ktx-serialization" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-engine-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
ktor-client-engine-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-client-serialization = { module = "io.ktor:ktor-client-serialization", version.ref = "ktor" }
ktor-client-json = { module = "io.ktor:ktor-client-json", version.ref = "ktor" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-network = { module = "io.ktor:ktor-network", version.ref = "ktor" }
junixsocket-common = { module = "com.kohlschutter.junixsocket:junixsocket-common", version.ref = "junixsocket" }
junixsocket-native = { module = "com.kohlschutter.junixsocket:junixsocket-native-common", version.ref = "junixsocket" }
slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" }
apache-compress = { module = "org.apache.commons:commons-compress", version.ref = "apache-compress" }
kotlinx-io-core = { module = "org.jetbrains.kotlinx:kotlinx-io-core", version.ref = "kotlinx-io" }

[bundles]
ktor = ["ktor-client-core", "ktor-client-serialization", "ktor-client-json", "ktor-client-logging", "ktor-client-content-negotiation", "ktor-serialization-kotlinx-json", "ktor-network"]
Expand Down
72 changes: 35 additions & 37 deletions src/commonMain/kotlin/me/devnatan/dockerkt/DockerClientConfig.kt
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
package me.devnatan.dockerkt

import me.devnatan.dockerkt.io.DEFAULT_DOCKER_HTTP_SOCKET
import me.devnatan.dockerkt.io.DEFAULT_DOCKER_UNIX_SOCKET
import me.devnatan.dockerkt.io.HTTP_SOCKET_PREFIX
import me.devnatan.dockerkt.io.UNIX_SOCKET_PREFIX
import me.devnatan.dockerkt.io.DefaultDockerHttpSocket
import me.devnatan.dockerkt.io.DefaultDockerUnixSocket
import me.devnatan.dockerkt.io.HttpSocketPrefix
import me.devnatan.dockerkt.io.UnixSocketPrefix
import kotlin.jvm.JvmStatic

internal val DefaultDocketClientConfig = DocketClientConfig.builder().forCurrentPlatform().build()

/**
* Daemon socket to connect to.
*/
private const val DockerHostEnvKey = "DOCKER_HOST"

/**
* Override the negotiated Docker Remote API version.
*/
private const val DockerApiVersionEnvKey = "DOCKER_API_VERSION"

/**
* Minimum Docker Remote API version supported by docker-kotlin.
*/
public const val DefaultDockerApiVersion: String = "1.41"

/**
* Class to store all Docker client configurations.
*
* @param socketPath Docker socket file used to communicate with the main Docker daemon.
* If not set, it will try to get from [DOCKER_HOST_ENV_KEY] environment variable, if it's found,
* If not set, it will try to get from [DockerHostEnvKey] environment variable, if it's found,
* will try to select the socket path based on current operating system.
* @param apiVersion The version of the Docker API that will be used during communication.
* See more: [Versioned API and SDK](https://docs.docker.com/engine/api/#versioned-api-and-sdk).
Expand Down Expand Up @@ -47,8 +62,8 @@ public class DockerClientConfigBuilder {
*/
private var apiVersion: String =
envOrFallback(
key = DOCKER_API_VERSION_ENV_KEY,
fallback = DEFAULT_DOCKER_API_VERSION,
key = DockerApiVersionEnvKey,
fallback = DefaultDockerApiVersion,
prefix = null,
)

Expand Down Expand Up @@ -90,31 +105,31 @@ public class DockerClientConfigBuilder {
/**
* Configures to use a Unix socket defaults common to the standard Docker configuration.
*
* The socket path is defined to [DEFAULT_DOCKER_UNIX_SOCKET] if `DOCKER_HOST` env var is not set, or it doesn't
* have the [UNIX_SOCKET_PREFIX] on its prefix.
* The socket path is defined to [DefaultDockerUnixSocket] if `DOCKER_HOST` env var is not set, or it doesn't
* have the [UnixSocketPrefix] on its prefix.
*/
public fun useUnixDefaults(): DockerClientConfigBuilder {
socketPath =
envOrFallback(
key = DOCKER_HOST_ENV_KEY,
fallback = DEFAULT_DOCKER_UNIX_SOCKET,
prefix = UNIX_SOCKET_PREFIX,
key = DockerHostEnvKey,
fallback = DefaultDockerUnixSocket,
prefix = UnixSocketPrefix,
)
return this
}

/**
* Configures to use an HTTP socket defaults common to the standard Docker configuration.
*
* The socket path is defined to [DEFAULT_DOCKER_HTTP_SOCKET] if `DOCKER_HOST` env var is not set, or it doesn't
* have the [HTTP_SOCKET_PREFIX] on its prefix.
* The socket path is defined to [DefaultDockerHttpSocket] if `DOCKER_HOST` env var is not set, or it doesn't
* have the [HttpSocketPrefix] on its prefix.
*/
public fun useHttpDefaults(): DockerClientConfigBuilder {
socketPath =
envOrFallback(
key = DOCKER_HOST_ENV_KEY,
fallback = DEFAULT_DOCKER_HTTP_SOCKET,
prefix = HTTP_SOCKET_PREFIX,
key = DockerHostEnvKey,
fallback = DefaultDockerHttpSocket,
prefix = HttpSocketPrefix,
)
return this
}
Expand All @@ -126,7 +141,7 @@ public class DockerClientConfigBuilder {
public fun forCurrentPlatform(): DockerClientConfigBuilder {
socketPath =
envOrFallback(
key = DOCKER_HOST_ENV_KEY,
key = DockerHostEnvKey,
fallback = selectDockerSocketPath(),
prefix = null,
)
Expand Down Expand Up @@ -163,25 +178,8 @@ public class DockerClientConfigBuilder {
*/
private fun selectDockerSocketPath(): String =
if (isUnixPlatform()) {
DEFAULT_DOCKER_UNIX_SOCKET
DefaultDockerUnixSocket
} else {
DEFAULT_DOCKER_HTTP_SOCKET
DefaultDockerHttpSocket
}

public companion object {
/**
* Daemon socket to connect to.
*/
private const val DOCKER_HOST_ENV_KEY = "DOCKER_HOST"

/**
* Override the negotiated Docker Remote API version.
*/
private const val DOCKER_API_VERSION_ENV_KEY = "DOCKER_API_VERSION"

/**
* Minimum Docker Remote API version supported by docker-kotlin.
*/
public const val DEFAULT_DOCKER_API_VERSION: String = "1.41"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

package me.devnatan.dockerkt

import me.devnatan.dockerkt.DockerClientConfigBuilder.Companion.DEFAULT_DOCKER_API_VERSION
import kotlin.jvm.JvmSynthetic

/**
* Creates a new Docker client instance with platform default socket path and [DEFAULT_DOCKER_API_VERSION]
* Creates a new Docker client instance with platform default socket path and [DefaultDockerApiVersion]
* Docker API version that'll be merged with specified configuration.
*
* @param configure The client configuration.
Expand Down
10 changes: 7 additions & 3 deletions src/commonMain/kotlin/me/devnatan/dockerkt/io/Http.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import io.ktor.client.plugins.ResponseException
import io.ktor.client.plugins.UserAgent
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.plugins.logging.*
import io.ktor.client.plugins.logging.LogLevel
import io.ktor.client.plugins.logging.Logger
import io.ktor.client.plugins.logging.Logging
import io.ktor.client.plugins.logging.SIMPLE
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.http.URLBuilder
Expand All @@ -30,6 +33,7 @@ internal fun createHttpClient(client: DockerClient): HttpClient {
check(client.config.socketPath.isNotBlank()) { "Socket path cannot be blank" }
return HttpClient {
expectSuccess = true

install(ContentNegotiation) {
json(
Json {
Expand Down Expand Up @@ -86,8 +90,8 @@ private fun createUrlBuilder(socketPath: String): URLBuilder =
if (isUnixSocket(socketPath)) {
URLBuilder(
protocol = URLProtocol.HTTP,
port = DOCKER_SOCKET_PORT,
host = socketPath.substringAfter(UNIX_SOCKET_PREFIX).encodeToByteArray().toHexString() + ENCODED_HOSTNAME_SUFFIX,
port = DockerSocketPort,
host = socketPath.substringAfter(UnixSocketPrefix).encodeToByteArray().toHexString() + EncodedHostnameSuffix,
)
} else {
val url = Url(socketPath)
Expand Down
14 changes: 7 additions & 7 deletions src/commonMain/kotlin/me/devnatan/dockerkt/io/Sockets.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ package me.devnatan.dockerkt.io

import kotlin.jvm.JvmName

internal const val ENCODED_HOSTNAME_SUFFIX = ".socket"
internal const val EncodedHostnameSuffix = ".socket"

internal const val DOCKER_SOCKET_PORT = 2375
internal const val UNIX_SOCKET_PREFIX = "unix://"
internal const val HTTP_SOCKET_PREFIX = "tcp://"
internal const val DockerSocketPort = 2375
internal const val UnixSocketPrefix = "unix://"
internal const val HttpSocketPrefix = "tcp://"

// unix:///var/run/docker.sock
public const val DEFAULT_DOCKER_UNIX_SOCKET: String = "$UNIX_SOCKET_PREFIX/var/run/docker.sock"
public const val DefaultDockerUnixSocket: String = "$UnixSocketPrefix/var/run/docker.sock"

// tcp://localhost:2375
public const val DEFAULT_DOCKER_HTTP_SOCKET: String = "${HTTP_SOCKET_PREFIX}localhost:$DOCKER_SOCKET_PORT"
public const val DefaultDockerHttpSocket: String = "${HttpSocketPrefix}localhost:$DockerSocketPort"

internal fun isUnixSocket(input: String): Boolean = input.startsWith(UNIX_SOCKET_PREFIX)
internal fun isUnixSocket(input: String): Boolean = input.startsWith(UnixSocketPrefix)
8 changes: 0 additions & 8 deletions src/commonMain/kotlin/me/devnatan/dockerkt/models/Resource.kt

This file was deleted.

Loading
Loading