Skip to content

Commit 645dd64

Browse files
authored
Persistent volumes param (#285)
- Support for persistent volume parameter - Some refactoring and cosmetics
1 parent 3e9cc88 commit 645dd64

File tree

8 files changed

+98
-64
lines changed

8 files changed

+98
-64
lines changed

.scalafmt.conf

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
version=3.5.9
22
continuationIndent.defnSite = 2
33
maxColumn = 140
4-
align = some
5-
newlines.alwaysBeforeTopLevelStatements = true
4+
align.preset = some
5+
runner.dialect = scala212

build.sbt

+23-26
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ lazy val `kubeyml` = (project in file("."))
1212
.settings(pluginSettings)
1313
.settings(
1414
name := "sbt-kubeyml"
15-
).settings(publishSettings)
15+
)
16+
.settings(publishSettings)
1617
.settings(releaseSettings)
1718
.settings(pluginSettings)
1819
.settings(compilerSettings)
@@ -23,7 +24,6 @@ lazy val site = (project in file("site"))
2324
.settings(noPublishSettings)
2425
.dependsOn(`kubeyml`)
2526

26-
2727
crossScalaVersions := Seq(scala212)
2828

2929
val circeVersion = "0.14.2"
@@ -38,7 +38,7 @@ libraryDependencies ++= Seq(
3838
"org.scalacheck" %% "scalacheck" % "1.16.0" % Test,
3939
"com.github.alexarchambault" %% "scalacheck-shapeless_1.15" % "1.3.0" % Test
4040
)
41-
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.11")
41+
addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.9")
4242

4343
lazy val pluginSettings = Seq(
4444
sbtPlugin := true
@@ -53,15 +53,13 @@ lazy val publishSettings = Seq(
5353
organizationName := "Vasilis Nicolaou",
5454
sonatypeProfileName := "org.vaslabs",
5555
sonatypeProjectHosting := Some(GitHubHosting("vaslabs", "sbt-kubeyml", "[email protected]")),
56-
scmInfo := Some(ScmInfo(
57-
url("https://github.com/vaslabs/sbt-kubeyml"),
58-
"scm:[email protected]:vaslabs/sbt-kubeyml.git")),
56+
scmInfo := Some(ScmInfo(url("https://github.com/vaslabs/sbt-kubeyml"), "scm:[email protected]:vaslabs/sbt-kubeyml.git")),
5957
developers := List(
6058
Developer(
61-
id = "vaslabs",
62-
name = "Vasilis Nicolaou",
59+
id = "vaslabs",
60+
name = "Vasilis Nicolaou",
6361
email = "[email protected]",
64-
url = url("http://vaslabs.org")
62+
url = url("http://vaslabs.org")
6563
)
6664
),
6765
publishConfiguration := publishConfiguration.value.withOverwrite(true),
@@ -99,24 +97,24 @@ lazy val compilerSettings = Seq(
9997
scalacOptions ++= Seq(
10098
"-deprecation",
10199
"-feature",
102-
"-language:postfixOps", //Allow postfix operator notation, such as `1 to 10 toList'
100+
"-language:postfixOps", // Allow postfix operator notation, such as `1 to 10 toList'
103101
"-language:implicitConversions",
104102
"-language:higherKinds",
105103
"-Ypartial-unification",
106-
"-Ywarn-dead-code", // Warn when dead code is identified.
107-
"-Ywarn-extra-implicit", // Warn when more than one implicit parameter section is defined.
108-
"-Ywarn-inaccessible", // Warn about inaccessible types in method signatures.
109-
"-Ywarn-infer-any", // Warn when a type argument is inferred to be `Any`.
110-
"-Ywarn-nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'.
111-
"-Ywarn-nullary-unit", // Warn when nullary methods return Unit.
112-
"-Ywarn-numeric-widen", // Warn when numerics are widened.
113-
"-Ywarn-unused:implicits", // Warn if an implicit parameter is unused.
114-
"-Ywarn-unused:imports", // Warn if an import selector is not referenced.
115-
"-Ywarn-unused:locals", // Warn if a local definition is unused.
116-
"-Ywarn-unused:params", // Warn if a value parameter is unused.
117-
"-Ywarn-unused:patvars", // Warn if a variable bound in a pattern is unused.
118-
"-Ywarn-unused:privates", // Warn if a private member is unused.
119-
"-Ywarn-value-discard", // Warn when non-Unit expression results are unused.
104+
"-Ywarn-dead-code", // Warn when dead code is identified.
105+
"-Ywarn-extra-implicit", // Warn when more than one implicit parameter section is defined.
106+
"-Ywarn-inaccessible", // Warn about inaccessible types in method signatures.
107+
"-Ywarn-infer-any", // Warn when a type argument is inferred to be `Any`.
108+
"-Ywarn-nullary-override", // Warn when non-nullary `def f()' overrides nullary `def f'.
109+
"-Ywarn-nullary-unit", // Warn when nullary methods return Unit.
110+
"-Ywarn-numeric-widen", // Warn when numerics are widened.
111+
"-Ywarn-unused:implicits", // Warn if an implicit parameter is unused.
112+
"-Ywarn-unused:imports", // Warn if an import selector is not referenced.
113+
"-Ywarn-unused:locals", // Warn if a local definition is unused.
114+
"-Ywarn-unused:params", // Warn if a value parameter is unused.
115+
"-Ywarn-unused:patvars", // Warn if a variable bound in a pattern is unused.
116+
"-Ywarn-unused:privates", // Warn if a private member is unused.
117+
"-Ywarn-value-discard", // Warn when non-Unit expression results are unused.
120118
"-Ywarn-unused:imports",
121119
"-Xfatal-warnings"
122120
)
@@ -141,7 +139,7 @@ lazy val docSettings = Seq(
141139
)
142140
),
143141
ghpagesCleanSite / excludeFilter :=
144-
new FileFilter{
142+
new FileFilter {
145143
def accept(f: File) = (ghpagesRepository.value / "CNAME").getCanonicalPath == f.getCanonicalPath
146144
} || "versions.html"
147145
)
@@ -153,4 +151,3 @@ lazy val noPublishSettings =
153151
publishArtifact := false,
154152
publishTo := None
155153
)
156-

src/main/scala/kubeyml/deployment/Protocol.scala

+29-5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ case class Deployment(
4242
private[kubeyml] def addEnv(envs: Map[EnvName, EnvValue]): Deployment =
4343
this.copy(spec = spec.addContainerEnvs(envs))
4444

45+
private[kubeyml] def addPersistentVolumes(volumes: Seq[VolumeWithClaim]): Deployment =
46+
this.copy(spec = spec.addPersistentVolumes(volumes))
47+
4548
private[kubeyml] def addCommand(cmd: Option[NonEmptyString], args: Seq[String]): Deployment = {
4649
this.copy(spec = spec.addContainerCmd(cmd, args))
4750
}
@@ -61,7 +64,6 @@ case class Deployment(
6164
private[kubeyml] def withDeploymentStrategy(deploymentStrategy: DeploymentStrategy): Deployment =
6265
this.copy(spec = spec.withDeploymentStrategy(deploymentStrategy))
6366

64-
6567
}
6668

6769
case class DeploymentMetadata(
@@ -87,6 +89,9 @@ case class Spec(
8789
private[deployment] def addContainerEnvs(envs: Map[EnvName, EnvValue]): Spec =
8890
this.copy(template = template.addContainerEnvs(envs))
8991

92+
private[deployment] def addPersistentVolumes(volumes: Seq[VolumeWithClaim]): Spec =
93+
this.copy(template = template.addPersistentVolumes(volumes))
94+
9095
private[deployment] def addContainerCmd(command: Option[NonEmptyString], args: Seq[String]): Spec =
9196
this.copy(template = template.addContainerCmd(command, args))
9297

@@ -105,7 +110,6 @@ case class Spec(
105110
private[deployment] def withDeploymentStrategy(deploymentStrategy: DeploymentStrategy): Spec =
106111
this.copy(strategy = deploymentStrategy)
107112

108-
109113
}
110114

111115
case class Selector(
@@ -129,8 +133,8 @@ case class Template(metadata: TemplateMetadata, spec: TemplateSpec) {
129133
this.copy(spec = spec.addContainerPorts(ports))
130134

131135
private[deployment] def annotate(annotations: Map[String, String]): Template = {
132-
require(annotations.forall {
133-
case (key, value) => key.nonEmpty && value.nonEmpty
136+
require(annotations.forall { case (key, value) =>
137+
key.nonEmpty && value.nonEmpty
134138
})
135139
this.copy(metadata = metadata.copy(annotations = annotations))
136140
}
@@ -141,6 +145,9 @@ case class Template(metadata: TemplateMetadata, spec: TemplateSpec) {
141145
private[deployment] def addContainerEnvs(envs: Map[EnvName, EnvValue]): Template =
142146
this.copy(spec = spec.addContainerEnvs(envs))
143147

148+
private[deployment] def addPersistentVolumes(volumes: Seq[VolumeWithClaim]): Template =
149+
this.copy(spec = spec.addPersistentVolumes(volumes))
150+
144151
private[deployment] def requestResource(resource: Resource): Template =
145152
this.copy(spec = spec.requestResource(resource))
146153

@@ -159,7 +166,7 @@ case class TemplateMetadata(labels: Labels, annotations: Map[String, String])
159166

160167
case class HostAlias(ip: IPv4, hostnames: List[Host])
161168

162-
case class TemplateSpec(containers: List[Container], hostAliases: List[HostAlias]) {
169+
case class TemplateSpec(containers: List[Container], volumes: List[Volume], hostAliases: List[HostAlias]) {
163170

164171
private[deployment] def addContainerPorts(ports: List[Port]): TemplateSpec =
165172
this.copy(containers = containers.map { container =>
@@ -172,6 +179,12 @@ case class TemplateSpec(containers: List[Container], hostAliases: List[HostAlias
172179
private[deployment] def addContainerEnvs(envs: Map[EnvName, EnvValue]): TemplateSpec =
173180
this.copy(containers = containers.map(_.addEnvs(envs)))
174181

182+
private[deployment] def addPersistentVolumes(volumesWithClaim: Seq[VolumeWithClaim]): TemplateSpec =
183+
this.copy(
184+
containers = containers.map(_.withVolumeMounts(volumesWithClaim.map(vwc => VolumeMount(vwc.mountPath, vwc.name)))),
185+
volumes = volumesWithClaim.map(vwc => Volume(vwc.name, PersistentVolumeClaim(vwc.claimName))).toList
186+
)
187+
175188
private[deployment] def requestResource(resource: Resource): TemplateSpec =
176189
this.copy(containers = containers.map(_.requestResource(resource)))
177190

@@ -196,6 +209,7 @@ case class Container(
196209
livenessProbe: Probe,
197210
readinessProbe: Probe,
198211
env: Map[EnvName, EnvValue],
212+
volumeMounts: Seq[VolumeMount],
199213
resources: Resources = Resources()
200214
) {
201215

@@ -219,6 +233,9 @@ case class Container(
219233
private[deployment] def withResources(limits: Resource, requests: Resource): Container =
220234
this.copy(resources = resources.copy(limits = limits, requests = requests))
221235

236+
private[deployment] def withVolumeMounts(volumeMounts: Seq[VolumeMount]): Container =
237+
this.copy(volumeMounts = volumeMounts)
238+
222239
}
223240

224241
case class Resources(
@@ -247,6 +264,13 @@ case class Memory(value: Int) {
247264
require(value > 0)
248265
}
249266

267+
case class VolumeWithClaim(name: String, claimName: String, mountPath: String)
268+
269+
case class VolumeMount(mountPath: String, name: String)
270+
271+
case class PersistentVolumeClaim(claimName: String)
272+
case class Volume(name: String, persistentVolumeClaim: PersistentVolumeClaim)
273+
250274
case class EnvName(value: NonEmptyString)
251275
sealed trait EnvValue
252276
case class EnvRawValue(value: String) extends EnvValue

src/main/scala/kubeyml/deployment/api/package.scala

+6-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ package object api {
2929
EmptyDeployment
3030

3131
implicit def toNonEmptyString(value: String): NonEmptyString = {
32-
require(!value.isEmpty)
32+
require(value.nonEmpty)
3333
NonEmptyString(value)
3434
}
3535

@@ -53,7 +53,7 @@ package object api {
5353
}
5454

5555
implicit final class DockerisedAppDeploymentOps(val dockerisedAppDeployment: DockerisedAppDeployment) extends AnyVal {
56-
import dockerisedAppDeployment._
56+
import dockerisedAppDeployment.*
5757

5858
def withProbes(livenessProbe: Probe, readinessProbe: Probe): Deployment = Deployment(
5959
metadata = DeploymentMetadata(name = dockerisedAppDeployment.service, namespace = namespace),
@@ -76,9 +76,11 @@ package object api {
7676
IfNotPresent,
7777
livenessProbe,
7878
readinessProbe,
79-
Map.empty
79+
Map.empty,
80+
Seq.empty
8081
)
8182
),
83+
List.empty,
8284
List.empty
8385
)
8486
),
@@ -93,7 +95,7 @@ package object api {
9395

9496
def replicas(number: Int): Deployment = deployment.copy(spec = deployment.spec.copy(replicas = number))
9597

96-
def annotateTemplate(annotations: Map[String, String]) = deployment.annotateSpecTemplate(annotations)
98+
def annotateTemplate(annotations: Map[String, String]): Deployment = deployment.annotateSpecTemplate(annotations)
9799

98100
def envFromSecret(variableName: String, name: String, key: String): Deployment =
99101
deployment.addEnv(Map(EnvName(variableName) -> EnvSecretValue(name, key)))

src/main/scala/kubeyml/deployment/json_support.scala

+12-13
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ object json_support {
4242

4343
implicit val deploymentStrategyEncoder: Encoder[DeploymentStrategy] = Encoder.instance {
4444
case r: RollingUpdate => rollingUpdateEncoder.apply(r)
45-
case Recreate => Json.obj("type" -> "Recreate".asJson)
45+
case Recreate => Json.obj("type" -> "Recreate".asJson)
4646
}
4747

48-
implicit val containerCmdEncoder: Encoder[Command] = Encoder.instance {
49-
case Command(cmd) => Seq(cmd).asJson
48+
implicit val containerCmdEncoder: Encoder[Command] = Encoder.instance { case Command(cmd) =>
49+
Seq(cmd).asJson
5050
}
5151

5252
implicit val imagePullPolicyEncoder: Encoder[ImagePullPolicy] = Encoder.instance {
@@ -127,20 +127,19 @@ object json_support {
127127

128128
implicit val environmentVariablesEncoder: Encoder[Map[EnvName, EnvValue]] = Encoder
129129
.encodeList[EnvVarDefinition]
130-
.contramap(_.toList.map {
131-
case (name, value) => EnvVarDefinition(name.value, value)
130+
.contramap(_.toList.map { case (name, value) =>
131+
EnvVarDefinition(name.value, value)
132132
})
133133

134-
implicit val templateSpecEncoder: Encoder[TemplateSpec] = Encoder.instance(
135-
ts =>
136-
Json.obj(
137-
Seq(
138-
"containers" -> ts.containers.asJson
139-
) ++ addIfNonEmpty(ts.hostAliases, "hostAliases"): _*
140-
)
134+
implicit val templateSpecEncoder: Encoder[TemplateSpec] = Encoder.instance(ts =>
135+
Json.obj(
136+
Seq(
137+
"containers" -> ts.containers.asJson
138+
) ++ (addIfNonEmpty(ts.hostAliases, "hostAliases") ++ addIfNonEmpty(ts.volumes, "volumes")): _*
139+
)
141140
)
142141

143-
private def addIfNonEmpty(aliases: List[HostAlias], key: String): Seq[(String, Json)] =
142+
private def addIfNonEmpty[A](aliases: List[A], key: String)(implicit encoder: Encoder[A]): Seq[(String, Json)] =
144143
if (aliases.isEmpty)
145144
Seq.empty
146145
else

src/main/scala/kubeyml/deployment/plugin/Keys.scala

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ trait Keys {
4747
val command = settingKey[Option[NonEmptyString]]("Command for the container")
4848
val args = settingKey[Seq[String]]("arguments for the container")
4949

50+
val persistentVolumes = settingKey[Seq[VolumeWithClaim]]("Persistent volume for the container")
51+
5052
val imagePullPolicy = settingKey[ImagePullPolicy]("Pull policy of docker image")
5153
val deployment = settingKey[Deployment]("The kubernetes deployment description")
5254

@@ -76,6 +78,7 @@ object Keys extends Keys {
7678
annotations := Map.empty,
7779
replicas := 2,
7880
envs := Map.empty,
81+
persistentVolumes := Seq.empty,
7982
resourceRequests := Resources().requests,
8083
resourceLimits := Resources().limits,
8184
command := None,
@@ -95,6 +98,7 @@ object Keys extends Keys {
9598
.addCommand(kubeSetting(command).value, kubeSetting(args).value)
9699
.replicas(kubeSetting(replicas).value)
97100
.addEnv(kubeSetting(envs).value)
101+
.addPersistentVolumes(kubeSetting(persistentVolumes).value)
98102
.resources(kubeSetting(resourceLimits).value, kubeSetting(resourceRequests).value)
99103
.pullPolicy(kubeSetting(imagePullPolicy).value)
100104
)

src/main/scala/kubeyml/plugin/package.scala

+5-4
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ import io.circe.yaml.syntax._
2929

3030
package object plugin {
3131

32-
private[kubeyml] def writePlan[A](a: A, buildTarget: File, kind: String)(implicit encoder: Encoder[A]) = {
32+
private[kubeyml] def writePlan[A](a: A, buildTarget: File, kind: String)(implicit encoder: Encoder[A]): Unit = {
3333
buildTarget.mkdirs()
34-
val file = new File(buildTarget, s"${kind}.yml")
34+
val file = new File(buildTarget, s"$kind.yml")
3535
val printWriter = new PrintWriter(file)
3636
try {
3737
printWriter.println(a.asJson.asYaml.spaces4)
@@ -41,8 +41,9 @@ package object plugin {
4141
}
4242

4343
private[kubeyml] def writePlansInSingle[A, B](a: A, b: B, buildTarget: File, kind: String)(implicit
44-
encoderA: Encoder[A], encoder: Encoder[B]
45-
) = {
44+
encoderA: Encoder[A],
45+
encoder: Encoder[B]
46+
): Unit = {
4647
buildTarget.mkdirs()
4748
val file = new File(buildTarget, s"${kind}.yml")
4849
val printWriter = new PrintWriter(file)

0 commit comments

Comments
 (0)