Skip to content

Commit

Permalink
Merge pull request #1604 from guardian/pm-support-xlarge-builders
Browse files Browse the repository at this point in the history
Add 'requiresXLargeBuilder' field to base image
  • Loading branch information
philmcmahon authored Jan 22, 2025
2 parents 86cd00f + 2366d26 commit 5439aa8
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 66 deletions.
118 changes: 74 additions & 44 deletions app/controllers/BaseImageController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class BaseImageController(
image.description,
image.amiId,
image.linuxDist.getOrElse(Ubuntu),
image.eolDate.getOrElse(DateTime.now).toLocalDate.toDate
image.eolDate.getOrElse(DateTime.now).toLocalDate.toDate,
image.requiresXLargeBuilder
)
)
Ok(views.html.editBaseImage(image, form, Roles.listIds))
Expand All @@ -73,24 +74,32 @@ class BaseImageController(
views.html.editBaseImage(image, formWithErrors, Roles.listIds)
)
},
{ case (description, amiId, linuxDist, eolDate) =>
val customisedRoles = parseEnabledRoles(request.body)
customisedRoles.fold(
error => BadRequest(s"Problem parsing roles: $error"),
roles => {
BaseImages.update(
image,
{
case (
description,
amiId,
linuxDist,
roles,
modifiedBy = request.user.fullName,
new DateTime(eolDate)
)
Redirect(routes.BaseImageController.showBaseImage(id))
.flashing("info" -> "Successfully updated base image")
}
)
eolDate,
requiresXLargeBuilder
) =>
val customisedRoles = parseEnabledRoles(request.body)
customisedRoles.fold(
error => BadRequest(s"Problem parsing roles: $error"),
roles => {
BaseImages.update(
image,
description,
amiId,
linuxDist,
roles,
modifiedBy = request.user.fullName,
new DateTime(eolDate),
requiresXLargeBuilder
)
Redirect(routes.BaseImageController.showBaseImage(id))
.flashing("info" -> "Successfully updated base image")
}
)
}
)
}
Expand All @@ -107,32 +116,50 @@ class BaseImageController(
{ formWithErrors =>
BadRequest(views.html.newBaseImage(formWithErrors, Roles.listIds))
},
{ case (id, description, amiId, linuxDist, eolDate) =>
BaseImages.findById(id) match {
case Some(existingImage) =>
val formWithError = Forms.createBaseImage
.fill((id, description, amiId, linuxDist, eolDate))
.withError("id", "This base image ID is already in use")
Conflict(views.html.newBaseImage(formWithError, Roles.listIds))
case None =>
val customisedRoles = parseEnabledRoles(request.body)
customisedRoles.fold(
error => BadRequest(s"Problem parsing roles: $error"),
roles => {
BaseImages.create(
id,
description,
amiId,
roles,
createdBy = request.user.fullName,
linuxDist,
Some(new DateTime(eolDate))
{
case (
id,
description,
amiId,
linuxDist,
eolDate,
requiresXLargeBuilder
) =>
BaseImages.findById(id) match {
case Some(existingImage) =>
val formWithError = Forms.createBaseImage
.fill(
(
id,
description,
amiId,
linuxDist,
eolDate,
requiresXLargeBuilder
)
)
Redirect(routes.BaseImageController.showBaseImage(id))
.flashing("info" -> "Successfully created base image")
}
)
}
.withError("id", "This base image ID is already in use")
Conflict(views.html.newBaseImage(formWithError, Roles.listIds))
case None =>
val customisedRoles = parseEnabledRoles(request.body)
customisedRoles.fold(
error => BadRequest(s"Problem parsing roles: $error"),
roles => {
BaseImages.create(
id,
description,
amiId,
roles,
createdBy = request.user.fullName,
linuxDist,
Some(new DateTime(eolDate)),
requiresXLargeBuilder
)
Redirect(routes.BaseImageController.showBaseImage(id))
.flashing("info" -> "Successfully created base image")
}
)
}
}
)
}
Expand Down Expand Up @@ -160,7 +187,8 @@ class BaseImageController(
builtinRoles = baseImage.builtinRoles,
createdBy = request.user.fullName,
linuxDist = linuxDist,
eolDate = baseImage.eolDate
eolDate = baseImage.eolDate,
requiresXLargeBuilder = baseImage.requiresXLargeBuilder
)
Redirect(routes.BaseImageController.showBaseImage(newId))
.flashing("info" -> "Successfully cloned base image")
Expand Down Expand Up @@ -219,7 +247,8 @@ object BaseImageController {
"description" -> text(maxLength = 10000),
"amiId" -> amiId,
"linuxDist" -> linuxDist,
"eolDate" -> date("yyyy-MM-dd")
"eolDate" -> date("yyyy-MM-dd"),
"requiresXLargeBuilder" -> boolean
)
)

Expand All @@ -230,7 +259,8 @@ object BaseImageController {
"description" -> text(maxLength = 10000),
"amiId" -> amiId,
"linuxDist" -> linuxDist,
"eolDate" -> date("yyyy-MM-dd")
"eolDate" -> date("yyyy-MM-dd"),
"requiresXLargeBuilder" -> boolean
)
)

Expand Down
12 changes: 8 additions & 4 deletions app/data/BaseImages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ object BaseImages {
builtinRoles: List[CustomisedRole],
createdBy: String,
linuxDist: LinuxDist,
eolDate: Option[DateTime]
eolDate: Option[DateTime],
requiresXLargeBuilder: Boolean
)(implicit dynamo: Dynamo): BaseImage = {
val now = DateTime.now()
val baseImage = BaseImage(
Expand All @@ -27,7 +28,8 @@ object BaseImages {
modifiedBy = createdBy,
modifiedAt = now,
Some(linuxDist),
eolDate
eolDate,
requiresXLargeBuilder
)

table.put(baseImage).exec()
Expand All @@ -41,7 +43,8 @@ object BaseImages {
linuxDist: LinuxDist,
builtinRoles: List[CustomisedRole],
modifiedBy: String,
eolDate: DateTime
eolDate: DateTime,
requiresXLargeBuilder: Boolean
)(implicit dynamo: Dynamo): Unit = {
val updated = baseImage.copy(
description = description,
Expand All @@ -50,7 +53,8 @@ object BaseImages {
builtinRoles = builtinRoles,
modifiedBy = modifiedBy,
modifiedAt = DateTime.now(),
eolDate = Some(eolDate)
eolDate = Some(eolDate),
requiresXLargeBuilder = requiresXLargeBuilder
)
table.put(updated).exec()
}
Expand Down
3 changes: 2 additions & 1 deletion app/models/BaseImage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ case class BaseImage(
modifiedBy: String,
modifiedAt: DateTime,
linuxDist: Option[LinuxDist] = None,
eolDate: Option[DateTime] = None
eolDate: Option[DateTime] = None,
requiresXLargeBuilder: Boolean = false
)

sealed trait EolStatus
Expand Down
9 changes: 6 additions & 3 deletions app/packer/PackerBuildConfigGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ object PackerBuildConfigGenerator {
variables: PackerVariablesConfig,
awsAccountNumbers: Seq[String],
sourceAmiMetadata: AmiMetadata,
amigoDataBucket: Option[String]
amigoDataBucket: Option[String],
requresXlargeBukder: Boolean
)(implicit packerConfig: PackerConfig): PackerBuildConfig = {
val awsAccounts = awsAccountNumbers.mkString(",")
val imageDetails = ImageDetails.apply(variables, packerConfig.stage)
Expand All @@ -33,9 +34,11 @@ object PackerBuildConfigGenerator {
List(BlockDeviceMapping(volume_size = size))
)

val instanceSize = if (requresXlargeBukder) "xlarge" else "small"

val instanceType = sourceAmiMetadata.architecture match {
case "x86_64" => "t3.small"
case "arm64" => "t4g.small"
case "x86_64" => s"t3.${instanceSize}"
case "arm64" => s"t4g.${instanceSize}"
case other =>
throw new IllegalArgumentException(
s"Don't know what instance type to use to bake an AMI for $other"
Expand Down
3 changes: 2 additions & 1 deletion app/packer/PackerRunner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ class PackerRunner(maxInstances: Int) extends Loggable {
packerVars,
awsAccountNumbers,
amiMetadata,
amigoDataBucket
amigoDataBucket,
bake.recipe.baseImage.requiresXLargeBuilder
)
val packerJson = Json.prettyPrint(Json.toJson(packerBuildConfig))
val packerConfigFile =
Expand Down
11 changes: 2 additions & 9 deletions app/views/editBaseImage.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,8 @@
@b3.text( form("amiId"), Symbol("_label") -> "AMI ID", Symbol("placeholder") -> "ami-a1b2c3d4" )
@b3.select( form("linuxDist"), models.LinuxDist.all.toList.map{ case (k,v) => k -> v.name }, Symbol("_label") -> "Linux Distribution" )
@b3.textarea( form("description"), Symbol("_label") -> "Description" )
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-6">
@b3.date(form("eolDate"), Symbol("_label")-> "End of Life Date")
</div>
<div class="col-md-3">
<p>(Find Ubuntu support info <a href="https://wiki.ubuntu.com/Releases" target="_blank">here</a>)</p>
</div>
</div>
@b3.date(form("eolDate"), Symbol("_label")-> "End of Life Date", Symbol("_help") -> Html("""Find Ubuntu support info <a href="https://wiki.ubuntu.com/Releases" target="_blank">here</a>"""))
@b3.checkbox(form("requiresXLargeBuilder"), Symbol("_label") -> "Requires XLarge builder instance", Symbol("_help") -> "XLarge instances are 8x more expensive than normal AMIgo builders. Avoid where possible.")
<div class="form-group">
<label class="control-label col-md-2" for="builtin-roles">Builtin roles</label>
<div class="col-md-10" id="builtin-roles">
Expand Down
5 changes: 2 additions & 3 deletions app/views/newBaseImage.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@
@b3.text( form("amiId"), Symbol("_label") -> "AMI ID", Symbol("placeholder") -> "ami-a1b2c3d4" )
@b3.select( form("linuxDist"), models.LinuxDist.all.toList.map{ case (k,v) => k -> v.name }, Symbol("_label") -> "Linux Distribution" )
@b3.textarea( form("description"), Symbol("_label") -> "Description" )
@b3.date(form("eolDate"), Symbol("_label")-> "End of Life Date")
<p>(Find Ubuntu support info <a href="https://wiki.ubuntu.com/Releases">here</a></p>

@b3.date(form("eolDate"), Symbol("_label")-> "End of Life Date", Symbol("_help") -> Html("""Find Ubuntu support info <a href="https://wiki.ubuntu.com/Releases" target="_blank">here</a>"""))
@b3.checkbox(form("requiresXLargeBuilder"), Symbol("_label") -> "Requires XLarge builder instance", Symbol("_help") -> "XLarge instances are 8x more expensive than normal AMIgo builders. Avoid where possible.")
<div class="form-group">
<label class="control-label col-md-2" for="builtin-roles">Builtin roles</label>
<div class="col-md-10" id="builtin-roles">
Expand Down
3 changes: 2 additions & 1 deletion app/views/showBaseImage.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ <h1>@image.id.value</h1>
<p>Created @fragments.timestamp(image.createdAt, image.createdBy)</p>
<p>Modified @fragments.timestamp(image.modifiedAt, image.modifiedBy)</p>
@image.eolDate.map{eolDate => <p class="@BaseImage.eolStatusClass(image)">End of Life @eolDate.toString("dd/MM/yyyy")</p>}
@if(image.requiresXLargeBuilder){<p>Requires XLarge builder instance</p>}
<p>@image.description</p>
</div>
</div>
Expand Down Expand Up @@ -64,4 +65,4 @@ <h1>@image.id.value</h1>
</div>
</div>

}
}

0 comments on commit 5439aa8

Please sign in to comment.