Skip to content

Commit 7ee1ea0

Browse files
author
Steve Ramage
committed
feat: Add support for IOWeight=,BlockIOWeight=,SocketBindAllow=,SocketBindDeny=,BlockIOReadBandwidth= (Resolves #321)
1 parent ed4d3e6 commit 7ee1ea0

File tree

12 files changed

+824
-5
lines changed

12 files changed

+824
-5
lines changed

src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/SemanticDataRepository.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,14 @@ class SemanticDataRepository private constructor() {
115115
validatorMap.putAll(AllowedCpuSetOptionValue.validators)
116116
validatorMap.putAll(TtySizeOptionValue.validators)
117117
validatorMap.putAll(ExecDirectoriesOptionValue.validators)
118-
119118
validatorMap.putAll(IOLimitOptionValue.validators)
119+
validatorMap.putAll(CGWeightOptionValue.validators)
120+
validatorMap.putAll(BlockIOWeightOptionValue.validators)
121+
validatorMap.putAll(BlockIOBandwidthOptionValue.validators)
120122
validatorMap.putAll(ImagePolicyOptionValue.validators)
121123
validatorMap.putAll(CPUWeightOptionValue.validators)
122124
validatorMap.putAll(CPUSharesOptionValue.validators)
123-
125+
validatorMap.putAll(CgroupSocketBindOptionValue.validators)
124126
validatorMap.putAll(RlimitOptionValue.validators)
125127
// Scopes are not supported since they aren't standard unit files.
126128
fileClassToSectionNameToKeyValuesFromDoc["unit"]?.remove(SCOPE_KEYWORD)
@@ -543,8 +545,6 @@ unit types. These options are documented in <a href="http://man7.org/linux/man-p
543545
else -> FileClass.UNIT_FILE
544546
}
545547
}
546-
547-
548548
}
549549
}
550550

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
5+
6+
7+
8+
class BlockIOBandwidthOptionValue() : GrammarOptionValue("config_parse_blockio_bandwidth", GRAMMAR) {
9+
10+
companion object {
11+
val GRAMMAR = SequenceCombinator(OneOrMore(SequenceCombinator(DEVICE, BYTES)), EOF())
12+
13+
val validators = mapOf(
14+
Validator("config_parse_blockio_bandwidth", "0") to BlockIOBandwidthOptionValue()
15+
)
16+
}
17+
}
18+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
5+
6+
7+
8+
class BlockIOWeightOptionValue() : GrammarOptionValue("config_parse_blockio_weight", GRAMMAR) {
9+
10+
companion object {
11+
val GRAMMAR =
12+
SequenceCombinator(
13+
IntegerTerminal(10, 1001),
14+
EOF()
15+
)
16+
17+
val validators = mapOf(
18+
Validator("config_parse_blockio_weight", "0") to BlockIOWeightOptionValue()
19+
)
20+
}
21+
}
22+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues
2+
3+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
5+
6+
7+
8+
class CGWeightOptionValue() : GrammarOptionValue("config_parse_cg_weight", GRAMMAR) {
9+
10+
companion object {
11+
val GRAMMAR =
12+
SequenceCombinator(
13+
IntegerTerminal(1, 10001),
14+
EOF()
15+
)
16+
17+
val validators = mapOf(
18+
Validator("config_parse_cg_weight", "0") to CGWeightOptionValue()
19+
)
20+
}
21+
}
22+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues
2+
3+
import kotlinx.html.ADDRESS
4+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator
5+
import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.*
6+
7+
8+
9+
class CgroupSocketBindOptionValue() : GrammarOptionValue("config_parse_cgroup_socket_bind", GRAMMAR) {
10+
11+
companion object {
12+
// https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html
13+
val ADDRESS_FAMILY = LiteralChoiceTerminal("ipv4", "ipv6")
14+
val TRANSPORT_PROTOCOL = LiteralChoiceTerminal("tcp", "udp")
15+
val IP_PORT = IntegerTerminal(1, 65536)
16+
val DASH = LiteralChoiceTerminal("-")
17+
val COLON = LiteralChoiceTerminal(":")
18+
val IP_PORT_RANGE = SequenceCombinator(IP_PORT, DASH, IP_PORT)
19+
val IP_PORTS = AlternativeCombinator(IP_PORT_RANGE, IP_PORT)
20+
21+
val GRAMMAR = SequenceCombinator(
22+
AlternativeCombinator(
23+
LiteralChoiceTerminal("any"),
24+
// The grammar has three blocks address-family, transport-protocol, and ip-ports, if there is more than one, there is a colon.
25+
// We break this up into a few cases
26+
// All specified
27+
SequenceCombinator(ADDRESS_FAMILY, COLON, TRANSPORT_PROTOCOL,COLON, IP_PORTS),
28+
// No ports
29+
SequenceCombinator(ADDRESS_FAMILY, COLON, TRANSPORT_PROTOCOL),
30+
// No transport
31+
SequenceCombinator(ADDRESS_FAMILY, COLON, IP_PORTS),
32+
// No Address family
33+
SequenceCombinator(TRANSPORT_PROTOCOL,COLON, IP_PORTS),
34+
ADDRESS_FAMILY,
35+
TRANSPORT_PROTOCOL,
36+
IP_PORTS
37+
),
38+
EOF())
39+
40+
val validators = mapOf(
41+
Validator("config_parse_cgroup_socket_bind", "0") to CgroupSocketBindOptionValue()
42+
)
43+
}
44+
}
45+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar
2+
3+
import kotlin.math.max
4+
5+
/**
6+
* Zero Or More Combinator
7+
*/
8+
class ZeroOrOne(val combinator : Combinator) : Combinator {
9+
10+
private fun match(value: String, offset: Int, f: (String, Int) -> MatchResult): MatchResult {
11+
var index = offset
12+
val tokens = mutableListOf<String>()
13+
val terminals = mutableListOf<TerminalCombinator>()
14+
15+
var match = f(value, index)
16+
17+
18+
if (match.matchResult == -1) {
19+
return MatchResult(tokens, offset, terminals, match.longestMatch)
20+
}
21+
22+
var maxLength = match.longestMatch
23+
24+
25+
index = match.matchResult
26+
tokens.addAll(match.tokens)
27+
terminals.addAll(match.terminals)
28+
29+
match = f(value, index)
30+
maxLength = max(maxLength, match.longestMatch)
31+
32+
return MatchResult(tokens, index, terminals, maxLength)
33+
}
34+
35+
override fun SyntacticMatch(value: String, offset: Int): MatchResult {
36+
return match(value, offset, combinator::SyntacticMatch)
37+
}
38+
39+
override fun SemanticMatch(value: String, offset: Int): MatchResult {
40+
return match(value, offset, combinator::SemanticMatch)
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package net.sjrx.intellij.plugins.systemdunitfiles.inspections
2+
3+
import junit.framework.TestCase
4+
import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest
5+
6+
class InvalidValueInspectionForBlockIOBandwidthOptionValue : AbstractUnitFileTest() {
7+
8+
fun testNoWarningWhenNumberSpecifiedWithoutUnit() {
9+
// Fixture Setup
10+
// language="unit file (systemd)"
11+
val file = """
12+
[Service]
13+
BlockIOReadBandwidth=/home 2
14+
""".trimIndent()
15+
16+
17+
// Execute SUT
18+
setupFileInEditor("file.service", file)
19+
enableInspection(InvalidValueInspection::class.java)
20+
val highlights = myFixture.doHighlighting()
21+
22+
// Verification
23+
assertSize(0, highlights)
24+
25+
}
26+
27+
fun testNoWarningWhenNumberSpecifiedWithUnit() {
28+
// Fixture Setup
29+
// language="unit file (systemd)"
30+
val file = """
31+
[Service]
32+
BlockIOReadBandwidth=/home 2M
33+
""".trimIndent()
34+
35+
36+
// Execute SUT
37+
setupFileInEditor("file.service", file)
38+
enableInspection(InvalidValueInspection::class.java)
39+
val highlights = myFixture.doHighlighting()
40+
41+
// Verification
42+
assertSize(0, highlights)
43+
44+
}
45+
46+
fun testWeakWarningWhenNegativeIntegerSpecified() {
47+
// Fixture Setup
48+
// language="unit file (systemd)"
49+
val file = """
50+
[Service]
51+
BlockIOReadBandwidth=-5
52+
""".trimIndent()
53+
54+
55+
// Execute SUT
56+
setupFileInEditor("file.service", file)
57+
enableInspection(InvalidValueInspection::class.java)
58+
val highlights = myFixture.doHighlighting()
59+
60+
// Verification
61+
assertSize(1, highlights)
62+
val info = highlights[0]
63+
assertStringContains("BlockIOReadBandwidth's value does not match the expected format. Possible reasons include unrecognized characters or premature end of input.", info!!.description)
64+
TestCase.assertEquals("-5", info.text)
65+
}
66+
67+
fun testWeakWarningWhenDeviceSpecifiedWithNoValue() {
68+
// Fixture Setup
69+
// language="unit file (systemd)"
70+
val file = """
71+
[Service]
72+
BlockIOReadBandwidth=/home
73+
""".trimIndent()
74+
75+
76+
// Execute SUT
77+
setupFileInEditor("file.service", file)
78+
enableInspection(InvalidValueInspection::class.java)
79+
val highlights = myFixture.doHighlighting()
80+
81+
// Verification
82+
assertSize(1, highlights)
83+
val info = highlights[0]
84+
assertStringContains("BlockIOReadBandwidth's value does not match the expected format. Possible reasons include unrecognized characters or premature end of input.", info!!.description)
85+
TestCase.assertEquals("/home", info.text)
86+
}
87+
88+
89+
fun testWeakWarningWhenPositiveIntegerSpecified() {
90+
// Fixture Setup
91+
// language="unit file (systemd)"
92+
val file = """
93+
[Service]
94+
BlockIOReadBandwidth=5
95+
""".trimIndent()
96+
97+
98+
// Execute SUT
99+
setupFileInEditor("file.service", file)
100+
enableInspection(InvalidValueInspection::class.java)
101+
val highlights = myFixture.doHighlighting()
102+
103+
// Verification
104+
assertSize(1, highlights)
105+
val info = highlights[0]
106+
assertStringContains("BlockIOReadBandwidth's value does not match the expected format. Possible reasons include unrecognized characters or premature end of input.", info!!.description)
107+
TestCase.assertEquals("5", info.text)
108+
}
109+
110+
}

0 commit comments

Comments
 (0)