Skip to content

Commit

Permalink
Fix volumes (#153)
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitjes authored May 19, 2024
1 parent a2291b3 commit 4ff5e16
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 24 deletions.
22 changes: 2 additions & 20 deletions src/commonMain/kotlin/me/devnatan/yoki/models/ExposedPort.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,12 @@ import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.JsonTransformingSerializer
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import me.devnatan.yoki.util.ListAsMapToEmptyObjectsSerializer

@Serializable
public data class ExposedPort internal constructor(
Expand Down Expand Up @@ -77,14 +69,4 @@ internal object ExposedPortSerializer : KSerializer<ExposedPort> {
}
}

internal object ExposedPortsSerializer :
JsonTransformingSerializer<List<ExposedPort>>(ListSerializer(ExposedPortSerializer)) {

override fun transformDeserialize(element: JsonElement): JsonElement {
return JsonArray(element.jsonObject.entries.map { JsonPrimitive(it.key) })
}

override fun transformSerialize(element: JsonElement): JsonElement {
return JsonObject(element.jsonArray.associate { it.jsonPrimitive.content to JsonObject(mapOf()) })
}
}
internal object ExposedPortsSerializer : ListAsMapToEmptyObjectsSerializer<ExposedPort>(ExposedPortSerializer)
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package me.devnatan.yoki.models.container

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.builtins.serializer
import me.devnatan.yoki.models.ExposedPort
import me.devnatan.yoki.models.ExposedPortsSerializer
import me.devnatan.yoki.models.HealthConfig
import me.devnatan.yoki.util.ListAsMapToEmptyObjectsSerializer

@Serializable
public data class ContainerConfig(
Expand All @@ -23,7 +25,7 @@ public data class ContainerConfig(
@SerialName("Healthcheck") public val healthcheck: HealthConfig? = null,
@SerialName("ArgsEscaped") public val argsEscaped: Boolean? = null,
@SerialName("Image") public val image: String? = null,
@SerialName("Volumes") public val volumes: Map<String, String>? = emptyMap(),
@SerialName("Volumes") public val volumes: @Serializable(with = VolumesSerializer::class) List<String>? = emptyList(),
@SerialName("WorkingDir") public val workingDir: String? = null,
@SerialName("Entrypoint") public val entrypoint: List<String>? = emptyList(),
@SerialName("NetworkDisabled") public val networkDisabled: Boolean? = null,
Expand All @@ -34,3 +36,5 @@ public data class ContainerConfig(
@SerialName("StopTimeout") public val stopTimeout: Int? = null,
@SerialName("Shell") public val shell: List<String> = emptyList(),
)

internal object VolumesSerializer : ListAsMapToEmptyObjectsSerializer<String>(String.serializer())
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package me.devnatan.yoki.models.container

import kotlinx.serialization.Contextual
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import me.devnatan.yoki.models.ExposedPort
Expand All @@ -25,7 +24,7 @@ public data class ContainerCreateOptions(
@SerialName("Healthcheck") public var healthcheck: HealthConfig? = null,
@SerialName("ArgsEscaped") public var escapedArgs: Boolean? = null,
@SerialName("Image") public var image: String? = null,
@SerialName("Volumes") public var volumes: Map<String, @Contextual Any>? = null,
@SerialName("Volumes") public var volumes: @Serializable(with = VolumesSerializer::class) List<String>? = null,
@SerialName("WorkingDir") public var workingDirectory: String? = null,
@SerialName("Entrypoint") public var entrypoint: List<String>? = null,
@SerialName("NetworkDisabled") public var disabledNetwork: Boolean? = null,
Expand Down Expand Up @@ -57,7 +56,7 @@ public fun ContainerCreateOptions.hostConfig(block: HostConfig.() -> Unit) {
}

public fun ContainerCreateOptions.volume(string: String) {
this.volumes = mapOf(string to emptyMap<String, Any>()) + volumes.orEmpty()
this.volumes = this.volumes.orEmpty() + string
}

public fun ContainerCreateOptions.networkingConfig(block: NetworkingConfig.() -> Unit) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package me.devnatan.yoki.util

import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.JsonTransformingSerializer
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive

internal open class ListAsMapToEmptyObjectsSerializer<T : Any>(
private val tSerializer: KSerializer<T>,
) : JsonTransformingSerializer<List<T>>(ListSerializer(tSerializer)) {

override fun transformDeserialize(element: JsonElement): JsonElement {
return JsonArray(element.jsonObject.entries.map { JsonPrimitive(it.key) })
}

override fun transformSerialize(element: JsonElement): JsonElement {
return JsonObject(element.jsonArray.associate { it.jsonPrimitive.content to JsonObject(mapOf()) })
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
@file:OptIn(ExperimentalCoroutinesApi::class)

package me.devnatan.yoki.resource.container

import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import me.devnatan.yoki.models.container.volume
import me.devnatan.yoki.resource.ResourceIT
import me.devnatan.yoki.withContainer
import kotlin.test.Test
import kotlin.test.assertEquals

class InspectContainerIT : ResourceIT() {

@Test
fun `inspects container with volumes`() = runTest {
testClient.withContainer(
"busybox:latest",
{
volume("/opt")
command = listOf("sleep", "infinity")
},
) { id ->
testClient.containers.start(id)
try {
val container = testClient.containers.inspect(id)
val volumes = container.config.volumes
assertEquals(volumes, listOf("/opt"))
} finally {
testClient.containers.stop(id)
}
}
}
}

0 comments on commit 4ff5e16

Please sign in to comment.