Skip to content

Commit 624062c

Browse files
committed
Fix #35340: import ca certs in Docker container
1 parent f049d03 commit 624062c

3 files changed

Lines changed: 44 additions & 38 deletions

File tree

src/main/kotlin/eu/openanalytics/shinyproxyoperator/impl/docker/DockerOrchestrator.kt

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,16 @@ class DockerOrchestrator(channel: Channel<ShinyProxyEvent>,
246246
}
247247

248248
copyTemplates(shinyProxy, dir)
249+
val mountCaBundle = copyCaBundle(shinyProxy, inputDir, dir)
249250
fileManager.createDirectories(dir.resolve("logs"))
250251
val additioanlConfigFiles = copyAdditionalConfigFiles(shinyProxy, dir)
251-
252252
val envVars = arrayListOf("PROXY_VERSION=${version}", "PROXY_REALM_ID=${shinyProxy.realmId}", "SPRING_CONFIG_IMPORT_0=/opt/shinyproxy/generated.yml", "USE_SYSTEM_CA_CERTS=true")
253+
253254
val binds = mutableListOf(HostConfig.Bind.builder()
254-
.from(dockerSocket)
255-
.to("/var/run/docker.sock")
256-
.readOnly(true)
257-
.build(),
255+
.from(dockerSocket)
256+
.to("/var/run/docker.sock")
257+
.readOnly(true)
258+
.build(),
258259
HostConfig.Bind.builder()
259260
.from(dir.resolve("application.yml").toString())
260261
.to("/opt/shinyproxy/application.yml")
@@ -279,6 +280,14 @@ class DockerOrchestrator(channel: Channel<ShinyProxyEvent>,
279280
.to("/dev/termination-log")
280281
.build())
281282

283+
if (mountCaBundle) {
284+
binds.add(HostConfig.Bind.builder()
285+
.from(dir.resolve("ca-bundle.crt").toString())
286+
.to("/certificates/ca-bundle.crt")
287+
.readOnly(true)
288+
.build())
289+
}
290+
282291
for ((idx, file) in additioanlConfigFiles.withIndex()) {
283292
val destination = "/opt/shinyproxy/${file}"
284293
binds.add(HostConfig.Bind.builder()
@@ -291,36 +300,7 @@ class DockerOrchestrator(channel: Channel<ShinyProxyEvent>,
291300

292301
val hostConfigBuilder = HostConfig.builder()
293302
.networkMode(SHARED_NETWORK_NAME)
294-
.binds(
295-
HostConfig.Bind.builder()
296-
.from(dockerSocket)
297-
.to("/var/run/docker.sock")
298-
.readOnly(true)
299-
.build(),
300-
HostConfig.Bind.builder()
301-
.from(dir.resolve("application.yml").toString())
302-
.to("/opt/shinyproxy/application.yml")
303-
.readOnly(true)
304-
.build(),
305-
HostConfig.Bind.builder()
306-
.from(dir.resolve("generated.yml").toString())
307-
.to("/opt/shinyproxy/generated.yml")
308-
.readOnly(true)
309-
.build(),
310-
HostConfig.Bind.builder()
311-
.from(dir.resolve("templates").toString())
312-
.to("/opt/shinyproxy/templates")
313-
.readOnly(true)
314-
.build(),
315-
HostConfig.Bind.builder()
316-
.from(logsDir.toString())
317-
.to("/opt/shinyproxy/logs")
318-
.build(),
319-
HostConfig.Bind.builder()
320-
.from(dir.resolve("termination-log").toString())
321-
.to("/dev/termination-log")
322-
.build(),
323-
)
303+
.binds(*binds.toTypedArray())
324304
.groupAdd(dockerGID.toString())
325305
.restartPolicy(HostConfig.RestartPolicy.always())
326306
.memoryReservation(memoryToBytes(shinyProxy.memoryRequest))
@@ -412,6 +392,21 @@ class DockerOrchestrator(channel: Channel<ShinyProxyEvent>,
412392
return null
413393
}
414394

395+
private fun copyCaBundle(shinyProxy: ShinyProxy, inputDir: Path, dir: Path): Boolean {
396+
var source = shinyProxy.getCaBundleFile(inputDir)
397+
if (!source.isAbsolute) {
398+
logger.warn { "${logPrefix(shinyProxy)} CA bundle path must be absolute, ignoring." }
399+
return false
400+
}
401+
if (!source.exists() && !source.isRegularFile()) {
402+
logger.debug { "${logPrefix(shinyProxy)} CA bundle '${source.absolutePathString()}' not found" }
403+
return false
404+
}
405+
source.toFile().copyTo(dir.resolve("ca-bundle.crt").toFile(), true)
406+
logger.info { "${logPrefix(shinyProxy)} CA bundle '${source.absolutePathString()}' copied" }
407+
return true
408+
}
409+
415410
override suspend fun deleteInstance(shinyProxyInstance: ShinyProxyInstance) {
416411
val containers = dockerActions.getContainers(shinyProxyInstance)
417412
containers.forEach { container ->

src/main/kotlin/eu/openanalytics/shinyproxyoperator/impl/docker/FileSource.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class FileSource(
125125
channel.send(ShinyProxyEvent(ShinyProxyEventType.ADD, shinyProxy.realmId, name, NAMESPACE, null))
126126
} else {
127127
if (existingShinyProxy.hashOfCurrentSpec == shinyProxy.hashOfCurrentSpec) {
128-
val modified = shinyProxy.isReferencedFileMoreRecent(lastRun)
128+
val modified = shinyProxy.isReferencedFileMoreRecent(inputDir, lastRun)
129129
if (modified.first) {
130130
logger.info { "${logPrefix(shinyProxy.realmId)} [Update] Referenced file ${modified.second?.absolutePathString()} modified" }
131131
channel.send(ShinyProxyEvent(ShinyProxyEventType.UPDATE_SPEC, shinyProxy.realmId, name, NAMESPACE, shinyProxy.hashOfCurrentSpec))

src/main/kotlin/eu/openanalytics/shinyproxyoperator/impl/docker/ShinyProxy.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import com.fasterxml.jackson.module.kotlin.convertValue
2424
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
2525
import eu.openanalytics.shinyproxyoperator.model.ShinyProxy
2626
import java.nio.file.Path
27+
import kotlin.io.path.absolute
2728
import kotlin.io.path.exists
2829
import kotlin.io.path.getLastModifiedTime
2930
import kotlin.io.path.isRegularFile
@@ -59,8 +60,18 @@ fun ShinyProxy.getAdditionalConfigFiles(): List<Path> {
5960
return listOf()
6061
}
6162

62-
fun ShinyProxy.isReferencedFileMoreRecent(lastModified: Long): Pair<Boolean, Path?> {
63-
val files = listOf(getCaddyTlsCertFile(), getCaddyTlsKeyFile()) + getAdditionalConfigFiles()
63+
fun ShinyProxy.getCaBundleFile(inputDir: Path): Path {
64+
if (getSpec().get("caBundleFile")?.isTextual == true) {
65+
return Path.of(getSpec().get("caBundleFile").textValue())
66+
}
67+
if (getSpec().get("ca-bundle-file")?.isTextual == true) {
68+
return Path.of(getSpec().get("ca-bundle-file").textValue())
69+
}
70+
return inputDir.resolve("ca-bundle.crt").absolute()
71+
}
72+
73+
fun ShinyProxy.isReferencedFileMoreRecent(inputDir: Path, lastModified: Long): Pair<Boolean, Path?> {
74+
val files = listOf(getCaddyTlsCertFile(), getCaddyTlsKeyFile(), getCaBundleFile(inputDir)) + getAdditionalConfigFiles()
6475
for (file in files) {
6576
if (file == null || !file.exists() || !file.isRegularFile()) {
6677
continue

0 commit comments

Comments
 (0)