Skip to content

Commit 0774c50

Browse files
committed
chore
1 parent f273767 commit 0774c50

File tree

2 files changed

+147
-129
lines changed

2 files changed

+147
-129
lines changed

src/main/kotlin/de/gesellix/docker/compose/ComposeFileReader.kt

Lines changed: 144 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -25,103 +25,110 @@ private val log = KotlinLogging.logger {}
2525

2626
class ComposeFileReader {
2727

28-
// UnsupportedProperties not yet supported by this implementation of the compose file
29-
private val unsupportedProperties = listOf(
30-
"build",
31-
"cap_add",
32-
"cap_drop",
33-
"cgroup_parent",
34-
"devices",
35-
"dns",
36-
"dns_search",
37-
"domainname",
38-
"external_links",
39-
"ipc",
40-
"links",
41-
"mac_address",
42-
"network_mode",
43-
"privileged",
44-
"read_only",
45-
"restart",
46-
"security_opt",
47-
"shm_size",
48-
"sysctls",
49-
"tmpfs",
50-
"userns_mode")
51-
52-
// DeprecatedProperties that were removed from the v3 format, but their use should not impact the behaviour of the application.
53-
private val deprecatedProperties = hashMapOf<String, String>().let {
54-
it["container_name"] = "Setting the container name is not supported."
55-
it["expose"] = "Exposing ports is unnecessary - services on the same network can access each other's containers on any port."
56-
it
28+
// UnsupportedProperties not yet supported by this implementation of the compose file
29+
private val unsupportedProperties = listOf(
30+
"build",
31+
"cap_add",
32+
"cap_drop",
33+
"cgroup_parent",
34+
"devices",
35+
"dns",
36+
"dns_search",
37+
"domainname",
38+
"external_links",
39+
"ipc",
40+
"links",
41+
"mac_address",
42+
"network_mode",
43+
"privileged",
44+
"read_only",
45+
"restart",
46+
"security_opt",
47+
"shm_size",
48+
"sysctls",
49+
"tmpfs",
50+
"userns_mode"
51+
)
52+
53+
// DeprecatedProperties that were removed from the v3 format, but their use should not impact the behaviour of the application.
54+
private val deprecatedProperties = hashMapOf<String, String>().let {
55+
it["container_name"] = "Setting the container name is not supported."
56+
it["expose"] = "Exposing ports is unnecessary - services on the same network can access each other's containers on any port."
57+
it
58+
}
59+
60+
// ForbiddenProperties that are not supported in this implementation of the compose file.
61+
private val forbiddenProperties = hashMapOf<String, String>().let {
62+
it["extends"] = "Support for `extends` is not implemented yet."
63+
it["volume_driver"] = "Instead of setting the volume driver on the service, define a volume using the top-level `volumes` option and specify the driver there."
64+
it["volumes_from"] = "To share a volume between services, define it using the top-level `volumes` option and reference it from each service that shares it using the service-level `volumes` option."
65+
it["cpu_quota"] = "Set resource limits using deploy.resources"
66+
it["cpu_shares"] = "Set resource limits using deploy.resources"
67+
it["cpuset"] = "Set resource limits using deploy.resources"
68+
it["mem_limit"] = "Set resource limits using deploy.resources"
69+
it["memswap_limit"] = "Set resource limits using deploy.resources"
70+
it
71+
}
72+
73+
private val interpolator = ComposeInterpolator()
74+
75+
fun loadYaml(composeFile: InputStream): HashMap<String, Map<String, Map<String, Any?>?>> {
76+
// val loadSettings = LoadSettings.builder().build()
77+
// val composeContent = Load(loadSettings).loadFromInputStream(composeFile) as Map<String, Map<String, Map<String, Any?>?>>
78+
val composeContent = Yaml().loadAs(composeFile, Map::class.java) as Map<String, Map<String, Map<String, Any?>?>>
79+
log.info("composeContent: $composeContent}")
80+
81+
return hashMapOf<String, Map<String, Map<String, Any?>?>>().apply {
82+
putAll(composeContent)
5783
}
58-
59-
// ForbiddenProperties that are not supported in this implementation of the compose file.
60-
private val forbiddenProperties = hashMapOf<String, String>().let {
61-
it["extends"] = "Support for `extends` is not implemented yet."
62-
it["volume_driver"] = "Instead of setting the volume driver on the service, define a volume using the top-level `volumes` option and specify the driver there."
63-
it["volumes_from"] = "To share a volume between services, define it using the top-level `volumes` option and reference it from each service that shares it using the service-level `volumes` option."
64-
it["cpu_quota"] = "Set resource limits using deploy.resources"
65-
it["cpu_shares"] = "Set resource limits using deploy.resources"
66-
it["cpuset"] = "Set resource limits using deploy.resources"
67-
it["mem_limit"] = "Set resource limits using deploy.resources"
68-
it["memswap_limit"] = "Set resource limits using deploy.resources"
69-
it
84+
}
85+
86+
fun load(
87+
composeFile: InputStream,
88+
workingDir: String,
89+
environment: Map<String, String> = System.getenv()
90+
): ComposeConfig? {
91+
val composeContent = loadYaml(composeFile)
92+
93+
val forbiddenProperties = collectForbiddenServiceProperties(composeContent["services"], forbiddenProperties)
94+
if (forbiddenProperties.isNotEmpty()) {
95+
log.error("Configuration contains forbidden properties: $forbiddenProperties")
96+
throw IllegalStateException("Configuration contains forbidden properties")
7097
}
7198

72-
private val interpolator = ComposeInterpolator()
73-
74-
fun loadYaml(composeFile: InputStream): HashMap<String, Map<String, Map<String, Any?>?>> {
75-
val composeContent = Yaml().loadAs(composeFile, Map::class.java) as Map<String, Map<String, Map<String, Any?>?>>
76-
log.info("composeContent: $composeContent}")
77-
78-
return hashMapOf<String, Map<String, Map<String, Any?>?>>().apply {
79-
putAll(composeContent)
80-
}
81-
}
82-
83-
fun load(composeFile: InputStream, workingDir: String, environment: Map<String, String> = System.getenv()): ComposeConfig? {
84-
val composeContent = loadYaml(composeFile)
85-
86-
val forbiddenProperties = collectForbiddenServiceProperties(composeContent["services"], forbiddenProperties)
87-
if (forbiddenProperties.isNotEmpty()) {
88-
log.error("Configuration contains forbidden properties: $forbiddenProperties")
89-
throw IllegalStateException("Configuration contains forbidden properties")
90-
}
91-
92-
// overrides interpolated sections, but keeps non-interpolated ones.
93-
composeContent.putAll(interpolator.interpolate(composeContent, environment))
94-
95-
val cfg = Moshi.Builder()
96-
.add(KotlinJsonAdapterFactory())
97-
.add(ListToExposeAdapter())
98-
.add(ListToPortConfigsAdapter())
99-
.add(ListToServiceSecretsAdapter())
100-
.add(ListToServiceVolumesAdapter())
101-
.add(ListToServiceConfigsAdapter())
102-
.add(MapOrListToEnvironmentAdapter())
103-
.add(MapOrListToExtraHosts())
104-
.add(MapOrListToLabelAdapter())
105-
.add(MapToDriverOptsAdapter())
106-
.add(MapToExternalAdapter())
107-
.add(StringOrListToEntrypointAdapter())
108-
.add(StringOrListToCommandAdapter())
109-
.add(StringToServiceNetworksAdapter())
110-
.build()
111-
.adapter(ComposeConfig::class.java)
112-
.fromJsonValue(composeContent)
99+
// overrides interpolated sections, but keeps non-interpolated ones.
100+
composeContent.putAll(interpolator.interpolate(composeContent, environment))
101+
102+
val cfg = Moshi.Builder()
103+
.add(KotlinJsonAdapterFactory())
104+
.add(ListToExposeAdapter())
105+
.add(ListToPortConfigsAdapter())
106+
.add(ListToServiceSecretsAdapter())
107+
.add(ListToServiceVolumesAdapter())
108+
.add(ListToServiceConfigsAdapter())
109+
.add(MapOrListToEnvironmentAdapter())
110+
.add(MapOrListToExtraHosts())
111+
.add(MapOrListToLabelAdapter())
112+
.add(MapToDriverOptsAdapter())
113+
.add(MapToExternalAdapter())
114+
.add(StringOrListToEntrypointAdapter())
115+
.add(StringOrListToCommandAdapter())
116+
.add(StringToServiceNetworksAdapter())
117+
.build()
118+
.adapter(ComposeConfig::class.java)
119+
.fromJsonValue(composeContent)
113120

114121
// def valid = new SchemaValidator().validate(composeContent)
115122

116-
val unsupportedProperties = collectUnsupportedServiceProperties(composeContent["services"], unsupportedProperties)
117-
if (unsupportedProperties.isNotEmpty()) {
118-
log.warn("Ignoring unsupported options: ${unsupportedProperties.joinToString(", ")}")
119-
}
123+
val unsupportedProperties = collectUnsupportedServiceProperties(composeContent["services"], unsupportedProperties)
124+
if (unsupportedProperties.isNotEmpty()) {
125+
log.warn("Ignoring unsupported options: ${unsupportedProperties.joinToString(", ")}")
126+
}
120127

121-
val deprecatedProperties = collectDeprecatedServiceProperties(composeContent["services"], deprecatedProperties)
122-
if (deprecatedProperties.isNotEmpty()) {
123-
log.warn("Ignoring deprecated options: $deprecatedProperties")
124-
}
128+
val deprecatedProperties = collectDeprecatedServiceProperties(composeContent["services"], deprecatedProperties)
129+
if (deprecatedProperties.isNotEmpty()) {
130+
log.warn("Ignoring deprecated options: $deprecatedProperties")
131+
}
125132

126133
// if volume.External.Name == "" {
127134
// volume.External.Name = name
@@ -134,48 +141,57 @@ class ComposeFileReader {
134141
// }
135142
// }
136143

137-
return cfg
138-
}
139-
140-
private fun collectForbiddenServiceProperties(services: Map<String, Map<String, Any?>?>?, forbiddenProperties: Map<String, String>): Map<String, String> {
141-
val hits = hashMapOf<String, String>()
142-
services?.forEach { service, serviceConfig ->
143-
if (serviceConfig != null) {
144-
forbiddenProperties.forEach { (property, description) ->
145-
if (serviceConfig.containsKey(property)) {
146-
hits["$service.$property"] = description
147-
}
148-
}
149-
}
144+
return cfg
145+
}
146+
147+
private fun collectForbiddenServiceProperties(
148+
services: Map<String, Map<String, Any?>?>?,
149+
forbiddenProperties: Map<String, String>
150+
): Map<String, String> {
151+
val hits = hashMapOf<String, String>()
152+
services?.forEach { service, serviceConfig ->
153+
if (serviceConfig != null) {
154+
forbiddenProperties.forEach { (property, description) ->
155+
if (serviceConfig.containsKey(property)) {
156+
hits["$service.$property"] = description
157+
}
150158
}
151-
return hits
159+
}
152160
}
153-
154-
private fun collectUnsupportedServiceProperties(services: Map<String, Map<String, Any?>?>?, unsupportedProperties: List<String>): List<String> {
155-
val hits = arrayListOf<String>()
156-
services?.forEach { service, serviceConfig ->
157-
if (serviceConfig != null) {
158-
unsupportedProperties.forEach { property ->
159-
if (serviceConfig.containsKey(property)) {
160-
hits.add("$service.$property")
161-
}
162-
}
163-
}
161+
return hits
162+
}
163+
164+
private fun collectUnsupportedServiceProperties(
165+
services: Map<String, Map<String, Any?>?>?,
166+
unsupportedProperties: List<String>
167+
): List<String> {
168+
val hits = arrayListOf<String>()
169+
services?.forEach { service, serviceConfig ->
170+
if (serviceConfig != null) {
171+
unsupportedProperties.forEach { property ->
172+
if (serviceConfig.containsKey(property)) {
173+
hits.add("$service.$property")
174+
}
164175
}
165-
return hits
176+
}
166177
}
167-
168-
private fun collectDeprecatedServiceProperties(services: Map<String, Map<String, Any?>?>?, deprecatedProperties: Map<String, String>): Map<String, String> {
169-
val hits = hashMapOf<String, String>()
170-
services?.forEach { service, serviceConfig ->
171-
if (serviceConfig != null) {
172-
deprecatedProperties.forEach { (property, description) ->
173-
if (serviceConfig.containsKey(property)) {
174-
hits["$service.$property"] = description
175-
}
176-
}
177-
}
178+
return hits
179+
}
180+
181+
private fun collectDeprecatedServiceProperties(
182+
services: Map<String, Map<String, Any?>?>?,
183+
deprecatedProperties: Map<String, String>
184+
): Map<String, String> {
185+
val hits = hashMapOf<String, String>()
186+
services?.forEach { service, serviceConfig ->
187+
if (serviceConfig != null) {
188+
deprecatedProperties.forEach { (property, description) ->
189+
if (serviceConfig.containsKey(property)) {
190+
hits["$service.$property"] = description
191+
}
178192
}
179-
return hits
193+
}
180194
}
195+
return hits
196+
}
181197
}

src/test/resources/de/gesellix/docker/compose/version_3_1/sample.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ services:
55
secrets:
66
- super
77
- source: duper
8-
mode: 0444
8+
mode: 0444 # YAML 1.1
9+
# mode: 0o444 # YAML 1.2
10+
# mode: 292 # decimal
911
secrets:
1012
super:
1113
external: true

0 commit comments

Comments
 (0)