From 3fc32c0b6f02d245a544aaaa061094231830f661 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 14 Feb 2020 00:53:24 +0100 Subject: refactor: Remodel workloads and compute resource This change remodels our model for workloads and compute resources in order to support VM/container functionality where multiple workloads run on a single machine. In particular, we make the following changes: - Move the compute-related source code into the `opendc-compute` module. - Change from application-based model to image-based model, where the image has exclusive access over the machine, instead of applications that share the machine. We may model in the future again applications/operating system, but at the moment, we do not need this granularity, given that the workload traces can be simulated using VMs. --- .../com/atlarge/opendc/compute/core/Flavor.kt | 42 ++++++ .../atlarge/opendc/compute/core/ProcessingUnit.kt | 42 ++++++ .../com/atlarge/opendc/compute/core/Server.kt | 64 +++++++++ .../com/atlarge/opendc/compute/core/ServerState.kt | 55 ++++++++ .../opendc/compute/core/execution/Protocol.kt | 143 ++++++++++++++++++++ .../opendc/compute/core/execution/ServerContext.kt | 46 +++++++ .../core/execution/ServerManagementContext.kt | 40 ++++++ .../opendc/compute/core/image/EmptyImage.kt | 36 +++++ .../compute/core/image/FlopsApplicationImage.kt | 57 ++++++++ .../com/atlarge/opendc/compute/core/image/Image.kt | 51 +++++++ .../opendc/compute/core/monitor/Protocol.kt | 77 +++++++++++ .../opendc/compute/core/monitor/ServerMonitor.kt | 41 ++++++ .../com/atlarge/opendc/compute/metal/Node.kt | 63 +++++++++ .../com/atlarge/opendc/compute/metal/PowerState.kt | 40 ++++++ .../opendc/compute/metal/driver/BareMetalDriver.kt | 58 ++++++++ .../compute/metal/driver/FakeBareMetalDriver.kt | 138 +++++++++++++++++++ .../opendc/compute/metal/driver/Protocol.kt | 146 +++++++++++++++++++++ .../opendc/compute/metal/service/Allocation.kt | 37 ++++++ .../compute/metal/service/ProvisioningService.kt | 55 ++++++++ .../opendc/compute/virt/driver/VirtDriver.kt | 40 ++++++ .../metal/driver/FakeBareMetalDriverTest.kt | 70 ++++++++++ 21 files changed, 1341 insertions(+) create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Flavor.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingUnit.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ServerState.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/Protocol.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerContext.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerManagementContext.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/EmptyImage.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsApplicationImage.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/Image.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/monitor/Protocol.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/monitor/ServerMonitor.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/Node.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/PowerState.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/BareMetalDriver.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/Protocol.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/Allocation.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/VirtDriver.kt create mode 100644 opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt (limited to 'opendc/opendc-compute/src') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Flavor.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Flavor.kt new file mode 100644 index 00000000..0094704a --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Flavor.kt @@ -0,0 +1,42 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core + +/** + * (Virtual) hardware configuration of a server. + */ +public data class Flavor( + /** + * The processing units of this machine. + */ + public val cpus: List, + + /** + * Key and value pairs that can be used to describe the specification of the server which is more than just about + * CPU, disk and RAM. For example, it can be used to indicate that the server created by this flavor has PCI + * devices, etc. + */ + public val details: Map = emptyMap() +) diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingUnit.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingUnit.kt new file mode 100644 index 00000000..945b7061 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ProcessingUnit.kt @@ -0,0 +1,42 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core + +/** + * A processing unit of a compute resource, either virtual or physical. + * + * @property vendor The vendor string of the cpu. + * @property modelName The name of the cpu model. + * @property arch The architecture of the CPU. + * @property clockRate The clock speed of the cpu in MHz. + * @property cores The number of logical cores in the cpu. + */ +public data class ProcessingUnit( + public val vendor: String, + public val modelName: String, + public val arch: String, + public val clockRate: Double, + public val cores: Int +) diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt new file mode 100644 index 00000000..0dc1562c --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt @@ -0,0 +1,64 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core + +import com.atlarge.opendc.compute.core.image.Image +import com.atlarge.opendc.compute.metal.Node +import com.atlarge.opendc.core.Identity +import java.util.UUID + +/** + * A server instance that is running on some physical or virtual machine. + */ +public data class Server( + /** + * The unique identifier of the server. + */ + public override val uid: UUID, + + /** + * The optional name of the server. + */ + public override val name: String, + + /** + * The hardware configuration of the server. + */ + public val flavor: Flavor, + + /** + * The image running on the server. + */ + public val image: Image, + + /** + * The last known state of the server. + */ + public val state: ServerState + +) : Identity { + override fun hashCode(): Int = uid.hashCode() + override fun equals(other: Any?): Boolean = other is Node && uid == other.uid +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ServerState.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ServerState.kt new file mode 100644 index 00000000..27372a5e --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ServerState.kt @@ -0,0 +1,55 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core + +/** + * An enumeration describing the possible states of a server. + */ +public enum class ServerState { + /** + * The server has not yet finished the original build process. + */ + BUILD, + + /** + * The server was powered down by the user. + */ + SHUTOFF, + + /** + * The server is active and running. + */ + ACTIVE, + + /** + * The server is in error. + */ + ERROR, + + /** + * The state of the server is unknown. + */ + UNKNOWN, +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/Protocol.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/Protocol.kt new file mode 100644 index 00000000..1e4fa0fb --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/Protocol.kt @@ -0,0 +1,143 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core.execution + +import com.atlarge.odcsim.ReceivePort +import com.atlarge.odcsim.SendPort +import com.atlarge.odcsim.processContext +import com.atlarge.opendc.compute.core.Server +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch + +/** + * Request that are accepted by a [ServerContext] instance. + */ +public sealed class ServerRequest { + /** + * Request the context to be initialized. + */ + public object Initialize : ServerRequest() + + /** + * Request for each core the specified amount of cpu time to run from the server + */ + public data class Run(public val req: LongArray) : ServerRequest() + + /** + * Terminate the execution of the server. + */ + public data class Exit(public val cause: Throwable? = null) : ServerRequest() +} + +/** + * Messages sent in response to [ServerRequest] objects. + */ +public sealed class ServerResponse { + /** + * The server that sent this response. + */ + public abstract val server: Server + + /** + * Indicate that this request was processed successfully. + */ + public data class Ok(public override val server: Server) : ServerResponse() +} + +/** + * Serialize the specified [ServerManagementContext] instance in order to safely send this object across logical + * processes. + */ +public suspend fun ServerManagementContext.serialize(): ServerManagementContext { + val ctx = processContext + val input = ctx.open() + val output = ctx.open() + + ctx.launch { + val outlet = processContext.connect(output.send) + val inlet = processContext.listen(input.receive) + + while (isActive) { + when (val msg = inlet.receive()) { + is ServerRequest.Initialize -> { + init() + outlet.send(ServerResponse.Ok(server)) + } + is ServerRequest.Run -> { + run(msg.req) + outlet.send(ServerResponse.Ok(server)) + } + is ServerRequest.Exit -> { + exit(msg.cause) + outlet.send(ServerResponse.Ok(server)) + } + } + } + } + + return object : ServerManagementContext { + private lateinit var inlet: ReceivePort + private lateinit var outlet: SendPort + + override var server: Server = this@serialize.server + + override suspend fun run(req: LongArray) { + outlet.send(ServerRequest.Run(req)) + + when (val res = inlet.receive()) { + is ServerResponse.Ok -> { + server = res.server + } + } + } + + override suspend fun exit(cause: Throwable?) { + outlet.send(ServerRequest.Exit(cause)) + + when (val res = inlet.receive()) { + is ServerResponse.Ok -> { + server = res.server + } + } + } + + override suspend fun init() { + if (!this::outlet.isInitialized) { + outlet = processContext.connect(input.send) + } + + if (!this::inlet.isInitialized) { + inlet = processContext.listen(output.receive) + } + + outlet.send(ServerRequest.Initialize) + when (val res = inlet.receive()) { + is ServerResponse.Ok -> { + server = res.server + } + } + } + } +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerContext.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerContext.kt new file mode 100644 index 00000000..057ed118 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerContext.kt @@ -0,0 +1,46 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core.execution + +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.image.Image + +/** + * Represents the execution context in which an bootable [Image] runs on a [Server]. + */ +public interface ServerContext { + /** + * The server on which the image runs. + */ + public val server: Server + + /** + * Request for each core the specified amount of cpu time to run from the server and wait until all the threads have + * finished processing. If none of the cores are non-zero, the method will return immediately. + * + * @param req An array specifying for each core the amount of cpu time to request. + */ + public suspend fun run(req: LongArray) +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerManagementContext.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerManagementContext.kt new file mode 100644 index 00000000..5a9b725b --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/execution/ServerManagementContext.kt @@ -0,0 +1,40 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core.execution + +/** + * An extended [ServerContext] providing several methods for managing the execution context. + */ +public interface ServerManagementContext : ServerContext { + /** + * Initialize the management context. + */ + public suspend fun init() + + /** + * Terminate the execution of the server. + */ + public suspend fun exit(cause: Throwable? = null) +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/EmptyImage.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/EmptyImage.kt new file mode 100644 index 00000000..a51e55f9 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/EmptyImage.kt @@ -0,0 +1,36 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core.image + +import com.atlarge.opendc.compute.core.execution.ServerContext + +/** + * An empty boot disk [Image] that exits immediately on start. + */ +object EmptyImage : Image { + override val details: Map = emptyMap() + + override suspend fun invoke(ctx: ServerContext) {} +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsApplicationImage.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsApplicationImage.kt new file mode 100644 index 00000000..4519dc49 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/FlopsApplicationImage.kt @@ -0,0 +1,57 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core.image + +import com.atlarge.opendc.compute.core.execution.ServerContext +import kotlin.math.min + +/** + * An application [Image] that models applications performing a static number of floating point operations ([flops]) on + * a compute resource. + * + * @property flops The number of floating point operations to perform for this task. + * @property cores The number of cores that the image is able to utilize. + * @property utilization A model of the CPU utilization of the application. + * @property details The details of this image. + */ +class FlopsApplicationImage( + public val flops: Long, + public val cores: Int, + public val utilization: Double = 0.8, + public override val details: Map = emptyMap() +) : Image { + init { + require(flops >= 0) { "Negative number of flops" } + } + + /** + * Execute the runtime behavior based on a number of floating point operations to execute. + */ + override suspend fun invoke(ctx: ServerContext) { + val cores = min(this.cores, ctx.server.flavor.cpus.sumBy { it.cores }) + val req = (flops * (1 / utilization) / cores).toLong() + ctx.run(LongArray(cores) { req }) + } +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/Image.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/Image.kt new file mode 100644 index 00000000..bd4f5648 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/image/Image.kt @@ -0,0 +1,51 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core.image + +import com.atlarge.opendc.compute.core.execution.ServerContext + +/** + * An image containing a bootable operating system that can directly be executed by physical or virtual server. + * + * OpenStack: A collection of files used to create or rebuild a server. Operators provide a number of pre-built OS + * images by default. You may also create custom images from cloud servers you have launched. These custom images are + * useful for backup purposes or for producing “gold” server images if you plan to deploy a particular server + * configuration frequently. + + */ +public interface Image { + /** + * The details of the image in key/value pairs. + */ + public val details: Map + + /** + * Launch the machine image in the specified [ServerContext]. + * + * This method should encapsulate and characterize the runtime behavior of the instance resulting from launching + * the image on some machine, in terms of the resource consumption on the machine. + */ + public suspend operator fun invoke(ctx: ServerContext) +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/monitor/Protocol.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/monitor/Protocol.kt new file mode 100644 index 00000000..b16c0d59 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/monitor/Protocol.kt @@ -0,0 +1,77 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core.monitor + +import com.atlarge.odcsim.SendPort +import com.atlarge.odcsim.processContext +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerState +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch + +/** + * Events emitted by a [Server] instance. + */ +public sealed class ServerEvent { + /** + * The server that emitted this event. + */ + public abstract val server: Server + + /** + * A response sent when the bare metal driver has been initialized. + */ + public data class StateChanged(public override val server: Server, public val previousState: ServerState) : ServerEvent() +} + +/** + * Serialize the specified [ServerMonitor] instance in order to safely send this object across logical processes. + */ +public suspend fun ServerMonitor.serialize(): ServerMonitor { + val ctx = processContext + val input = ctx.open() + + ctx.launch { + val inlet = processContext.listen(input.receive) + + while (isActive) { + when (val msg = inlet.receive()) { + is ServerEvent.StateChanged -> onUpdate(msg.server, msg.previousState) + } + } + } + + return object : ServerMonitor { + private var outlet: SendPort? = null + + override suspend fun onUpdate(server: Server, previousState: ServerState) { + if (outlet == null) { + outlet = processContext.connect(input.send) + } + + outlet!!.send(ServerEvent.StateChanged(server, previousState)) + } + } +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/monitor/ServerMonitor.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/monitor/ServerMonitor.kt new file mode 100644 index 00000000..fbfd0ad6 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/monitor/ServerMonitor.kt @@ -0,0 +1,41 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core.monitor + +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerState + +/** + * An interface for monitoring the state of a machine. + */ +public interface ServerMonitor { + /** + * This method is invoked when the state of a machine updates. + * + * @param server The server which state was updated. + * @param previousState The previous state of the server. + */ + public suspend fun onUpdate(server: Server, previousState: ServerState) +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/Node.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/Node.kt new file mode 100644 index 00000000..a43abfe9 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/Node.kt @@ -0,0 +1,63 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal + +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.image.Image +import com.atlarge.opendc.core.Identity +import java.util.UUID + +/** + * A bare-metal compute node. + */ +data class Node( + /** + * The unique identifier of the node. + */ + public override val uid: UUID, + + /** + * The optional name of the node. + */ + public override val name: String, + + /** + * The power state of the node. + */ + public val powerState: PowerState, + + /** + * The boot image of the node. + */ + public val image: Image, + + /** + * The server instance that is running on the node or `null` if no server is running. + */ + public val server: Server? +) : Identity { + override fun hashCode(): Int = uid.hashCode() + override fun equals(other: Any?): Boolean = other is Node && uid == other.uid +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/PowerState.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/PowerState.kt new file mode 100644 index 00000000..5fce3f48 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/PowerState.kt @@ -0,0 +1,40 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal + +/** + * The power state of a compute node. + */ +public enum class PowerState { + /** + * Node is powered on. + */ + POWER_ON, + + /** + * Node is powered off. + */ + POWER_OFF, +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/BareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/BareMetalDriver.kt new file mode 100644 index 00000000..1330158e --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/BareMetalDriver.kt @@ -0,0 +1,58 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.driver + +import com.atlarge.opendc.compute.core.image.Image +import com.atlarge.opendc.compute.core.monitor.ServerMonitor +import com.atlarge.opendc.compute.metal.Node +import com.atlarge.opendc.compute.metal.PowerState + +/** + * A driver interface for the management interface of a bare-metal compute node. + */ +public interface BareMetalDriver { + /** + * Initialize the driver. + */ + public suspend fun init(monitor: ServerMonitor): Node + + /** + * Update the power state of the compute node. + */ + public suspend fun setPower(powerState: PowerState): Node + + /** + * Update the boot disk image of the compute node. + * + * Changing the boot disk image of node does not affect it while the node is running. In order to start the new boot + * disk image, the compute node must be restarted. + */ + public suspend fun setImage(image: Image): Node + + /** + * Obtain the state of the compute node. + */ + public suspend fun refresh(): Node +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt new file mode 100644 index 00000000..9d984017 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt @@ -0,0 +1,138 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.driver + +import com.atlarge.odcsim.processContext +import com.atlarge.opendc.compute.core.Flavor +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerState +import com.atlarge.opendc.compute.core.execution.ServerManagementContext +import com.atlarge.opendc.compute.core.execution.serialize +import com.atlarge.opendc.compute.core.image.EmptyImage +import com.atlarge.opendc.compute.core.image.Image +import com.atlarge.opendc.compute.core.monitor.ServerMonitor +import com.atlarge.opendc.compute.metal.Node +import com.atlarge.opendc.compute.metal.PowerState +import java.util.UUID +import kotlin.math.max +import kotlinx.coroutines.delay + +/** + * A implementation of the [BareMetalDriver] that simulates an [Image] running on a bare-metal machine, but performs + * not actual computation. + * + * @param uid The unique identifier of the machine. + * @param name An optional name of the machine. + * @param flavor The hardware configuration of the machine. + */ +public class FakeBareMetalDriver( + uid: UUID, + name: String, + private val flavor: Flavor +) : BareMetalDriver { + /** + * The monitor to use. + */ + private lateinit var monitor: ServerMonitor + + /** + * The machine state. + */ + private var node: Node = Node(uid, name, PowerState.POWER_OFF, EmptyImage, null) + + override suspend fun init(monitor: ServerMonitor): Node { + this.monitor = monitor + return node + } + + override suspend fun setPower(powerState: PowerState): Node { + val previousPowerState = node.powerState + val server = when (node.powerState to powerState) { + PowerState.POWER_OFF to PowerState.POWER_OFF -> null + PowerState.POWER_OFF to PowerState.POWER_ON -> Server(node.uid, node.name, flavor, node.image, ServerState.BUILD) + PowerState.POWER_ON to PowerState.POWER_OFF -> null // TODO Terminate existing image + PowerState.POWER_ON to PowerState.POWER_ON -> node.server + else -> throw IllegalStateException() + } + node = node.copy(powerState = powerState, server = server) + + if (powerState != previousPowerState && server != null) { + launch() + } + + return node + } + + override suspend fun setImage(image: Image): Node { + node = node.copy(image = image) + return node + } + + override suspend fun refresh(): Node = node + + /** + * Launch the server image on the machine. + */ + private suspend fun launch() { + val serverCtx = this.serverCtx.serialize() + + processContext.spawn { + serverCtx.init() + try { + node.server!!.image(serverCtx) + serverCtx.exit() + } catch (cause: Throwable) { + serverCtx.exit(cause) + } + } + } + + private val serverCtx = object : ServerManagementContext { + override var server: Server + get() = node.server!! + set(value) { + node = node.copy(server = value) + } + + override suspend fun init() { + val previousState = server.state + server = server.copy(state = ServerState.ACTIVE) + monitor.onUpdate(server, previousState) + } + + override suspend fun exit(cause: Throwable?) { + val previousState = server.state + val state = if (cause == null) ServerState.SHUTOFF else ServerState.ERROR + server = server.copy(state = state) + monitor.onUpdate(server, previousState) + } + + override suspend fun run(req: LongArray) { + // TODO Properly implement this for multiple CPUs + val time = max(0, req.max() ?: 0) * flavor.cpus[0].clockRate + delay(time.toLong()) + } + } +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/Protocol.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/Protocol.kt new file mode 100644 index 00000000..a8996f61 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/Protocol.kt @@ -0,0 +1,146 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.driver + +import com.atlarge.odcsim.ReceivePort +import com.atlarge.odcsim.SendPort +import com.atlarge.odcsim.processContext +import com.atlarge.opendc.compute.core.image.Image +import com.atlarge.opendc.compute.core.monitor.ServerMonitor +import com.atlarge.opendc.compute.metal.Node +import com.atlarge.opendc.compute.metal.PowerState +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch + +/** + * Messages that may be sent to the management interface of a bare-metal compute [Node], similar to the + * [BareMetalDriver] interface. + */ +public sealed class NodeRequest { + /** + * Initialize the compute node. + */ + public data class Initialize(public val monitor: ServerMonitor) : NodeRequest() + + /** + * Update the power state of the compute node. + */ + public data class SetPowerState(public val state: PowerState) : NodeRequest() + + /** + * Update the boot disk image of the compute node. + */ + public data class SetImage(public val image: Image) : NodeRequest() + + /** + * Obtain the state of the compute node. + */ + public object Refresh : NodeRequest() +} + +/** + * Responses emitted by a bare-metal compute [Node]. + */ +public sealed class NodeResponse { + /** + * The node that sent this response. + */ + public abstract val node: Node + + /** + * A response sent when the bare metal driver has been initialized. + */ + public data class Initialized(public override val node: Node) : NodeResponse() + + /** + * A response sent to indicate the power state of the node changed. + */ + public data class PowerStateChanged(public override val node: Node) : NodeResponse() + + /** + * A response sent to indicate the image of a node was changed. + */ + public data class ImageChanged(public override val node: Node) : NodeResponse() + + /** + * A response sent for obtaining the refreshed [Node] instance. + */ + public data class Refreshed(public override val node: Node) : NodeResponse() +} + +/** + * Serialize the specified [BareMetalDriver] instance in order to safely send this object across logical processes. + */ +public suspend fun BareMetalDriver.serialize(): BareMetalDriver { + val ctx = processContext + val input = ctx.open() + val output = ctx.open() + + ctx.launch { + val outlet = processContext.connect(output.send) + val inlet = processContext.listen(input.receive) + + while (isActive) { + when (val msg = inlet.receive()) { + is NodeRequest.Initialize -> + outlet.send(NodeResponse.Initialized(init(msg.monitor))) + is NodeRequest.SetPowerState -> + outlet.send(NodeResponse.PowerStateChanged(setPower(msg.state))) + is NodeRequest.SetImage -> + outlet.send(NodeResponse.ImageChanged(setImage(msg.image))) + is NodeRequest.Refresh -> + outlet.send(NodeResponse.Refreshed(refresh())) + } + } + } + + return object : BareMetalDriver { + private lateinit var inlet: ReceivePort + private lateinit var outlet: SendPort + + override suspend fun init(monitor: ServerMonitor): Node { + outlet = processContext.connect(input.send) + inlet = processContext.listen(output.receive) + + outlet.send(NodeRequest.Initialize(monitor)) + return (inlet.receive() as NodeResponse.Initialized).node + } + + override suspend fun setPower(powerState: PowerState): Node { + outlet.send(NodeRequest.SetPowerState(powerState)) + return (inlet.receive() as NodeResponse.PowerStateChanged).node + } + + override suspend fun setImage(image: Image): Node { + outlet.send(NodeRequest.SetImage(image)) + return (inlet.receive() as NodeResponse.ImageChanged).node + } + + override suspend fun refresh(): Node { + outlet.send(NodeRequest.Refresh) + return (inlet.receive() as NodeResponse.Refreshed).node + } + } +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/Allocation.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/Allocation.kt new file mode 100644 index 00000000..3f9ca71b --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/Allocation.kt @@ -0,0 +1,37 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.service + +import com.atlarge.opendc.compute.metal.Node + +/** + * Represents an allocation of bare-metal compute nodes. + */ +public interface Allocation { + /** + * The compute nodes that have been allocated. + */ + public val nodes: List +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt new file mode 100644 index 00000000..df96f47f --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt @@ -0,0 +1,55 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.service + +import com.atlarge.opendc.compute.core.image.Image +import com.atlarge.opendc.compute.core.monitor.ServerMonitor +import com.atlarge.opendc.compute.metal.Node +import com.atlarge.opendc.compute.metal.driver.BareMetalDriver + +/** + * A cloud platform service for provisioning bare-metal compute nodes on the platform. + */ +public interface ProvisioningService { + /** + * Create a new bare-metal compute node. + */ + public suspend fun create(driver: BareMetalDriver): Node + + /** + * Allocate the given number of nodes from the provisioner. + */ + public suspend fun allocate(num: Int): Allocation + + /** + * Refresh the state of a compute node. + */ + public suspend fun refresh(node: Node): Node + + /** + * Deploy the specified [Image] on a compute node. + */ + public suspend fun deploy(node: Node, allocation: Allocation, image: Image, monitor: ServerMonitor): Node +} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/VirtDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/VirtDriver.kt new file mode 100644 index 00000000..52aa6488 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/virt/driver/VirtDriver.kt @@ -0,0 +1,40 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.virt.driver + +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.image.Image +import com.atlarge.opendc.compute.core.monitor.ServerMonitor + +/** + * A driver interface for a hypervisor running on some host server and communicating with the central compute service to + * provide virtualization for that particular resource. + */ +public interface VirtDriver { + /** + * Spawn the given [Image] on the compute resource of this driver. + */ + public suspend fun spawn(image: Image, monitor: ServerMonitor): Server +} diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt new file mode 100644 index 00000000..bc8f677e --- /dev/null +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt @@ -0,0 +1,70 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.driver + +import com.atlarge.odcsim.SimulationEngineProvider +import com.atlarge.opendc.compute.core.Flavor +import com.atlarge.opendc.compute.core.ProcessingUnit +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerState +import com.atlarge.opendc.compute.core.image.FlopsApplicationImage +import com.atlarge.opendc.compute.core.monitor.ServerMonitor +import com.atlarge.opendc.compute.metal.PowerState +import java.util.ServiceLoader +import java.util.UUID +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Test + +internal class FakeBareMetalDriverTest { + /** + * A smoke test for the bare-metal driver. + */ + @Test + fun smoke() { + val provider = ServiceLoader.load(SimulationEngineProvider::class.java).first() + val system = provider({ ctx -> + val flavor = Flavor(listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4))) + val image = FlopsApplicationImage(1000, 2) + val monitor = object : ServerMonitor { + override suspend fun onUpdate(server: Server, previousState: ServerState) { + println(server) + } + } + val driver = FakeBareMetalDriver(UUID.randomUUID(), "test", flavor) + + driver.init(monitor) + driver.setImage(image) + driver.setPower(PowerState.POWER_ON) + delay(5) + println(driver.refresh()) + }, name = "sim") + + runBlocking { + system.run() + system.terminate() + } + } +} -- cgit v1.2.3 From 5095d42c0a1fe0a593c84bccfdd594712e12ca1a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 14 Feb 2020 10:54:53 +0100 Subject: feat: Implement basic provisioner service --- .../com/atlarge/opendc/compute/core/Server.kt | 2 +- .../compute/metal/driver/FakeBareMetalDriver.kt | 2 +- .../opendc/compute/metal/service/Allocation.kt | 37 ----------- .../compute/metal/service/ProvisioningService.kt | 6 +- .../metal/service/SimpleProvisioningService.kt | 73 +++++++++++++++++++++ .../metal/service/SimpleProvisioningServiceTest.kt | 76 ++++++++++++++++++++++ 6 files changed, 154 insertions(+), 42 deletions(-) delete mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/Allocation.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningService.kt create mode 100644 opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt (limited to 'opendc/opendc-compute/src') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt index 0dc1562c..dad24ebe 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt @@ -60,5 +60,5 @@ public data class Server( ) : Identity { override fun hashCode(): Int = uid.hashCode() - override fun equals(other: Any?): Boolean = other is Node && uid == other.uid + override fun equals(other: Any?): Boolean = other is Server && uid == other.uid } diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt index 9d984017..1b3782f6 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt @@ -96,7 +96,7 @@ public class FakeBareMetalDriver( * Launch the server image on the machine. */ private suspend fun launch() { - val serverCtx = this.serverCtx.serialize() + val serverCtx = this.serverCtx processContext.spawn { serverCtx.init() diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/Allocation.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/Allocation.kt deleted file mode 100644 index 3f9ca71b..00000000 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/Allocation.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.atlarge.opendc.compute.metal.service - -import com.atlarge.opendc.compute.metal.Node - -/** - * Represents an allocation of bare-metal compute nodes. - */ -public interface Allocation { - /** - * The compute nodes that have been allocated. - */ - public val nodes: List -} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt index df96f47f..ba2ebc80 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt @@ -39,9 +39,9 @@ public interface ProvisioningService { public suspend fun create(driver: BareMetalDriver): Node /** - * Allocate the given number of nodes from the provisioner. + * Obtain the available nodes. */ - public suspend fun allocate(num: Int): Allocation + public suspend fun nodes(): Set /** * Refresh the state of a compute node. @@ -51,5 +51,5 @@ public interface ProvisioningService { /** * Deploy the specified [Image] on a compute node. */ - public suspend fun deploy(node: Node, allocation: Allocation, image: Image, monitor: ServerMonitor): Node + public suspend fun deploy(node: Node, image: Image, monitor: ServerMonitor): Node } diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningService.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningService.kt new file mode 100644 index 00000000..dc860405 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningService.kt @@ -0,0 +1,73 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.service + +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerState +import com.atlarge.opendc.compute.core.image.Image +import com.atlarge.opendc.compute.core.monitor.ServerMonitor +import com.atlarge.opendc.compute.metal.Node +import com.atlarge.opendc.compute.metal.PowerState +import com.atlarge.opendc.compute.metal.driver.BareMetalDriver + +/** + * A very basic implementation of the [ProvisioningService]. + */ +public class SimpleProvisioningService : ProvisioningService, ServerMonitor { + /** + * The active nodes in this service. + */ + private val nodes: MutableMap = mutableMapOf() + + /** + * The installed monitors. + */ + private val monitors: MutableMap = mutableMapOf() + + override suspend fun create(driver: BareMetalDriver): Node { + val node = driver.init(this) + nodes[node] = driver + return node + } + + override suspend fun nodes(): Set = nodes.keys + + override suspend fun refresh(node: Node): Node { + return nodes[node]!!.refresh() + } + + override suspend fun deploy(node: Node, image: Image, monitor: ServerMonitor): Node { + val driver = nodes[node]!! + + driver.setImage(image) + val newNode = driver.setPower(PowerState.POWER_ON) + monitors[newNode.server!!] = monitor + return newNode + } + + override suspend fun onUpdate(server: Server, previousState: ServerState) { + monitors[server]?.onUpdate(server, previousState) + } +} diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt new file mode 100644 index 00000000..0bbd4b75 --- /dev/null +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt @@ -0,0 +1,76 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.service + +import com.atlarge.odcsim.SimulationEngineProvider +import com.atlarge.opendc.compute.core.Flavor +import com.atlarge.opendc.compute.core.ProcessingUnit +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerState +import com.atlarge.opendc.compute.core.image.FlopsApplicationImage +import com.atlarge.opendc.compute.core.monitor.ServerMonitor +import com.atlarge.opendc.compute.metal.PowerState +import com.atlarge.opendc.compute.metal.driver.FakeBareMetalDriver +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Test +import java.util.ServiceLoader +import java.util.UUID + + +/** + * Test suite for the [SimpleProvisioningService]. + */ +internal class SimpleProvisioningServiceTest { + /** + * A basic smoke test. + */ + @Test + fun smoke() { + val provider = ServiceLoader.load(SimulationEngineProvider::class.java).first() + val system = provider({ ctx -> + val flavor = Flavor(listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4))) + val image = FlopsApplicationImage(1000, 2) + val monitor = object : ServerMonitor { + override suspend fun onUpdate(server: Server, previousState: ServerState) { + println(server) + } + } + val driver = FakeBareMetalDriver(UUID.randomUUID(), "test", flavor) + + + val provisioner = SimpleProvisioningService() + provisioner.create(driver) + delay(5) + val nodes = provisioner.nodes() + provisioner.deploy(nodes.first(), image, monitor) + }, name = "sim") + + runBlocking { + system.run() + system.terminate() + } + } +} -- cgit v1.2.3 From 92e858e398bf69380dbacebc042dde2bfa8cfe9c Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 14 Feb 2020 12:43:29 +0100 Subject: refactor: Integrate opendc-compute in existing model This change refactors the existing model to use the new interfaces from the opendc-compute module. --- .../main/kotlin/com/atlarge/opendc/compute/core/Server.kt | 1 - .../opendc/compute/metal/driver/FakeBareMetalDriver.kt | 12 ++++++++++-- .../opendc/compute/metal/service/ProvisioningService.kt | 7 +++++++ .../compute/metal/service/SimpleProvisioningService.kt | 1 + .../compute/metal/service/SimpleProvisioningServiceTest.kt | 7 ++----- 5 files changed, 20 insertions(+), 8 deletions(-) (limited to 'opendc/opendc-compute/src') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt index dad24ebe..cb14835a 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt @@ -25,7 +25,6 @@ package com.atlarge.opendc.compute.core import com.atlarge.opendc.compute.core.image.Image -import com.atlarge.opendc.compute.metal.Node import com.atlarge.opendc.core.Identity import java.util.UUID diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt index 1b3782f6..7a6d9123 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt @@ -29,7 +29,6 @@ import com.atlarge.opendc.compute.core.Flavor import com.atlarge.opendc.compute.core.Server import com.atlarge.opendc.compute.core.ServerState import com.atlarge.opendc.compute.core.execution.ServerManagementContext -import com.atlarge.opendc.compute.core.execution.serialize import com.atlarge.opendc.compute.core.image.EmptyImage import com.atlarge.opendc.compute.core.image.Image import com.atlarge.opendc.compute.core.monitor.ServerMonitor @@ -71,7 +70,7 @@ public class FakeBareMetalDriver( val previousPowerState = node.powerState val server = when (node.powerState to powerState) { PowerState.POWER_OFF to PowerState.POWER_OFF -> null - PowerState.POWER_OFF to PowerState.POWER_ON -> Server(node.uid, node.name, flavor, node.image, ServerState.BUILD) + PowerState.POWER_OFF to PowerState.POWER_ON -> Server(UUID.randomUUID(), node.name, flavor, node.image, ServerState.BUILD) PowerState.POWER_ON to PowerState.POWER_OFF -> null // TODO Terminate existing image PowerState.POWER_ON to PowerState.POWER_ON -> node.server else -> throw IllegalStateException() @@ -110,6 +109,8 @@ public class FakeBareMetalDriver( } private val serverCtx = object : ServerManagementContext { + private var initialized: Boolean = false + override var server: Server get() = node.server!! set(value) { @@ -117,9 +118,15 @@ public class FakeBareMetalDriver( } override suspend fun init() { + if (initialized) { + throw IllegalStateException() + } + val previousState = server.state server = server.copy(state = ServerState.ACTIVE) monitor.onUpdate(server, previousState) + + initialized = true } override suspend fun exit(cause: Throwable?) { @@ -127,6 +134,7 @@ public class FakeBareMetalDriver( val state = if (cause == null) ServerState.SHUTOFF else ServerState.ERROR server = server.copy(state = state) monitor.onUpdate(server, previousState) + initialized = false } override suspend fun run(req: LongArray) { diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt index ba2ebc80..24ade799 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/ProvisioningService.kt @@ -28,6 +28,8 @@ import com.atlarge.opendc.compute.core.image.Image import com.atlarge.opendc.compute.core.monitor.ServerMonitor import com.atlarge.opendc.compute.metal.Node import com.atlarge.opendc.compute.metal.driver.BareMetalDriver +import com.atlarge.opendc.core.services.AbstractServiceKey +import java.util.UUID /** * A cloud platform service for provisioning bare-metal compute nodes on the platform. @@ -52,4 +54,9 @@ public interface ProvisioningService { * Deploy the specified [Image] on a compute node. */ public suspend fun deploy(node: Node, image: Image, monitor: ServerMonitor): Node + + /** + * The service key of this service. + */ + companion object Key : AbstractServiceKey(UUID.randomUUID(), "provisioner") } diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningService.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningService.kt index dc860405..6b5c0979 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningService.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningService.kt @@ -62,6 +62,7 @@ public class SimpleProvisioningService : ProvisioningService, ServerMonitor { val driver = nodes[node]!! driver.setImage(image) + driver.setPower(PowerState.POWER_OFF) val newNode = driver.setPower(PowerState.POWER_ON) monitors[newNode.server!!] = monitor return newNode diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt index 0bbd4b75..9c4a4e2a 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt @@ -31,14 +31,12 @@ import com.atlarge.opendc.compute.core.Server import com.atlarge.opendc.compute.core.ServerState import com.atlarge.opendc.compute.core.image.FlopsApplicationImage import com.atlarge.opendc.compute.core.monitor.ServerMonitor -import com.atlarge.opendc.compute.metal.PowerState import com.atlarge.opendc.compute.metal.driver.FakeBareMetalDriver +import java.util.ServiceLoader +import java.util.UUID import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Test -import java.util.ServiceLoader -import java.util.UUID - /** * Test suite for the [SimpleProvisioningService]. @@ -60,7 +58,6 @@ internal class SimpleProvisioningServiceTest { } val driver = FakeBareMetalDriver(UUID.randomUUID(), "test", flavor) - val provisioner = SimpleProvisioningService() provisioner.create(driver) delay(5) -- cgit v1.2.3 From 6ff2e43c55ffec98f444b9cd61b550fadd83633d Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 14 Feb 2020 12:52:29 +0100 Subject: refactor: Rename Flavor to ServerFlavor This change renames Flavor to ServerFlavor to be more indicative of its function. The Flavor name follows the naming of the OpenStack project. --- .../com/atlarge/opendc/compute/core/Flavor.kt | 42 ---------------------- .../com/atlarge/opendc/compute/core/Server.kt | 2 +- .../atlarge/opendc/compute/core/ServerFlavor.kt | 42 ++++++++++++++++++++++ .../compute/metal/driver/FakeBareMetalDriver.kt | 4 +-- .../metal/driver/FakeBareMetalDriverTest.kt | 4 +-- .../metal/service/SimpleProvisioningServiceTest.kt | 4 +-- 6 files changed, 49 insertions(+), 49 deletions(-) delete mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Flavor.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ServerFlavor.kt (limited to 'opendc/opendc-compute/src') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Flavor.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Flavor.kt deleted file mode 100644 index 0094704a..00000000 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Flavor.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.atlarge.opendc.compute.core - -/** - * (Virtual) hardware configuration of a server. - */ -public data class Flavor( - /** - * The processing units of this machine. - */ - public val cpus: List, - - /** - * Key and value pairs that can be used to describe the specification of the server which is more than just about - * CPU, disk and RAM. For example, it can be used to indicate that the server created by this flavor has PCI - * devices, etc. - */ - public val details: Map = emptyMap() -) diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt index cb14835a..d42b59b6 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/Server.kt @@ -45,7 +45,7 @@ public data class Server( /** * The hardware configuration of the server. */ - public val flavor: Flavor, + public val flavor: ServerFlavor, /** * The image running on the server. diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ServerFlavor.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ServerFlavor.kt new file mode 100644 index 00000000..d57dadf9 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/core/ServerFlavor.kt @@ -0,0 +1,42 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.core + +/** + * (Virtual) hardware configuration of a server. + */ +public data class ServerFlavor( + /** + * The processing units of this machine. + */ + public val cpus: List, + + /** + * Key and value pairs that can be used to describe the specification of the server which is more than just about + * CPU, disk and RAM. For example, it can be used to indicate that the server created by this flavor has PCI + * devices, etc. + */ + public val details: Map = emptyMap() +) diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt index 7a6d9123..cc4cc46c 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt @@ -25,7 +25,7 @@ package com.atlarge.opendc.compute.metal.driver import com.atlarge.odcsim.processContext -import com.atlarge.opendc.compute.core.Flavor +import com.atlarge.opendc.compute.core.ServerFlavor import com.atlarge.opendc.compute.core.Server import com.atlarge.opendc.compute.core.ServerState import com.atlarge.opendc.compute.core.execution.ServerManagementContext @@ -49,7 +49,7 @@ import kotlinx.coroutines.delay public class FakeBareMetalDriver( uid: UUID, name: String, - private val flavor: Flavor + private val flavor: ServerFlavor ) : BareMetalDriver { /** * The monitor to use. diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt index bc8f677e..39b170fb 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt @@ -25,7 +25,7 @@ package com.atlarge.opendc.compute.metal.driver import com.atlarge.odcsim.SimulationEngineProvider -import com.atlarge.opendc.compute.core.Flavor +import com.atlarge.opendc.compute.core.ServerFlavor import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.core.Server import com.atlarge.opendc.compute.core.ServerState @@ -46,7 +46,7 @@ internal class FakeBareMetalDriverTest { fun smoke() { val provider = ServiceLoader.load(SimulationEngineProvider::class.java).first() val system = provider({ ctx -> - val flavor = Flavor(listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4))) + val flavor = ServerFlavor(listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4))) val image = FlopsApplicationImage(1000, 2) val monitor = object : ServerMonitor { override suspend fun onUpdate(server: Server, previousState: ServerState) { diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt index 9c4a4e2a..f1abbaed 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt @@ -25,7 +25,7 @@ package com.atlarge.opendc.compute.metal.service import com.atlarge.odcsim.SimulationEngineProvider -import com.atlarge.opendc.compute.core.Flavor +import com.atlarge.opendc.compute.core.ServerFlavor import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.core.Server import com.atlarge.opendc.compute.core.ServerState @@ -49,7 +49,7 @@ internal class SimpleProvisioningServiceTest { fun smoke() { val provider = ServiceLoader.load(SimulationEngineProvider::class.java).first() val system = provider({ ctx -> - val flavor = Flavor(listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4))) + val flavor = ServerFlavor(listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4))) val image = FlopsApplicationImage(1000, 2) val monitor = object : ServerMonitor { override suspend fun onUpdate(server: Server, previousState: ServerState) { -- cgit v1.2.3 From cfb3a87edad5093b6f75e0bbde0cfdb58fdc9487 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 14 Feb 2020 12:54:06 +0100 Subject: refactor: Rename FakeBareMetalDriver to SimpleBareMetalDriver --- .../compute/metal/driver/FakeBareMetalDriver.kt | 146 --------------------- .../compute/metal/driver/SimpleBareMetalDriver.kt | 145 ++++++++++++++++++++ .../metal/driver/FakeBareMetalDriverTest.kt | 70 ---------- .../metal/driver/SimpleBareMetalDriverTest.kt | 70 ++++++++++ .../metal/service/SimpleProvisioningServiceTest.kt | 4 +- 5 files changed, 217 insertions(+), 218 deletions(-) delete mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt create mode 100644 opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt delete mode 100644 opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt create mode 100644 opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt (limited to 'opendc/opendc-compute/src') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt deleted file mode 100644 index cc4cc46c..00000000 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriver.kt +++ /dev/null @@ -1,146 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.atlarge.opendc.compute.metal.driver - -import com.atlarge.odcsim.processContext -import com.atlarge.opendc.compute.core.ServerFlavor -import com.atlarge.opendc.compute.core.Server -import com.atlarge.opendc.compute.core.ServerState -import com.atlarge.opendc.compute.core.execution.ServerManagementContext -import com.atlarge.opendc.compute.core.image.EmptyImage -import com.atlarge.opendc.compute.core.image.Image -import com.atlarge.opendc.compute.core.monitor.ServerMonitor -import com.atlarge.opendc.compute.metal.Node -import com.atlarge.opendc.compute.metal.PowerState -import java.util.UUID -import kotlin.math.max -import kotlinx.coroutines.delay - -/** - * A implementation of the [BareMetalDriver] that simulates an [Image] running on a bare-metal machine, but performs - * not actual computation. - * - * @param uid The unique identifier of the machine. - * @param name An optional name of the machine. - * @param flavor The hardware configuration of the machine. - */ -public class FakeBareMetalDriver( - uid: UUID, - name: String, - private val flavor: ServerFlavor -) : BareMetalDriver { - /** - * The monitor to use. - */ - private lateinit var monitor: ServerMonitor - - /** - * The machine state. - */ - private var node: Node = Node(uid, name, PowerState.POWER_OFF, EmptyImage, null) - - override suspend fun init(monitor: ServerMonitor): Node { - this.monitor = monitor - return node - } - - override suspend fun setPower(powerState: PowerState): Node { - val previousPowerState = node.powerState - val server = when (node.powerState to powerState) { - PowerState.POWER_OFF to PowerState.POWER_OFF -> null - PowerState.POWER_OFF to PowerState.POWER_ON -> Server(UUID.randomUUID(), node.name, flavor, node.image, ServerState.BUILD) - PowerState.POWER_ON to PowerState.POWER_OFF -> null // TODO Terminate existing image - PowerState.POWER_ON to PowerState.POWER_ON -> node.server - else -> throw IllegalStateException() - } - node = node.copy(powerState = powerState, server = server) - - if (powerState != previousPowerState && server != null) { - launch() - } - - return node - } - - override suspend fun setImage(image: Image): Node { - node = node.copy(image = image) - return node - } - - override suspend fun refresh(): Node = node - - /** - * Launch the server image on the machine. - */ - private suspend fun launch() { - val serverCtx = this.serverCtx - - processContext.spawn { - serverCtx.init() - try { - node.server!!.image(serverCtx) - serverCtx.exit() - } catch (cause: Throwable) { - serverCtx.exit(cause) - } - } - } - - private val serverCtx = object : ServerManagementContext { - private var initialized: Boolean = false - - override var server: Server - get() = node.server!! - set(value) { - node = node.copy(server = value) - } - - override suspend fun init() { - if (initialized) { - throw IllegalStateException() - } - - val previousState = server.state - server = server.copy(state = ServerState.ACTIVE) - monitor.onUpdate(server, previousState) - - initialized = true - } - - override suspend fun exit(cause: Throwable?) { - val previousState = server.state - val state = if (cause == null) ServerState.SHUTOFF else ServerState.ERROR - server = server.copy(state = state) - monitor.onUpdate(server, previousState) - initialized = false - } - - override suspend fun run(req: LongArray) { - // TODO Properly implement this for multiple CPUs - val time = max(0, req.max() ?: 0) * flavor.cpus[0].clockRate - delay(time.toLong()) - } - } -} diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt new file mode 100644 index 00000000..56fee524 --- /dev/null +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt @@ -0,0 +1,145 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.driver + +import com.atlarge.odcsim.processContext +import com.atlarge.opendc.compute.core.ServerFlavor +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerState +import com.atlarge.opendc.compute.core.execution.ServerManagementContext +import com.atlarge.opendc.compute.core.image.EmptyImage +import com.atlarge.opendc.compute.core.image.Image +import com.atlarge.opendc.compute.core.monitor.ServerMonitor +import com.atlarge.opendc.compute.metal.Node +import com.atlarge.opendc.compute.metal.PowerState +import java.util.UUID +import kotlin.math.max +import kotlinx.coroutines.delay + +/** + * A basic implementation of the [BareMetalDriver] that simulates an [Image] running on a bare-metal machine. + * + * @param uid The unique identifier of the machine. + * @param name An optional name of the machine. + * @param flavor The hardware configuration of the machine. + */ +public class SimpleBareMetalDriver( + uid: UUID, + name: String, + private val flavor: ServerFlavor +) : BareMetalDriver { + /** + * The monitor to use. + */ + private lateinit var monitor: ServerMonitor + + /** + * The machine state. + */ + private var node: Node = Node(uid, name, PowerState.POWER_OFF, EmptyImage, null) + + override suspend fun init(monitor: ServerMonitor): Node { + this.monitor = monitor + return node + } + + override suspend fun setPower(powerState: PowerState): Node { + val previousPowerState = node.powerState + val server = when (node.powerState to powerState) { + PowerState.POWER_OFF to PowerState.POWER_OFF -> null + PowerState.POWER_OFF to PowerState.POWER_ON -> Server(UUID.randomUUID(), node.name, flavor, node.image, ServerState.BUILD) + PowerState.POWER_ON to PowerState.POWER_OFF -> null // TODO Terminate existing image + PowerState.POWER_ON to PowerState.POWER_ON -> node.server + else -> throw IllegalStateException() + } + node = node.copy(powerState = powerState, server = server) + + if (powerState != previousPowerState && server != null) { + launch() + } + + return node + } + + override suspend fun setImage(image: Image): Node { + node = node.copy(image = image) + return node + } + + override suspend fun refresh(): Node = node + + /** + * Launch the server image on the machine. + */ + private suspend fun launch() { + val serverCtx = this.serverCtx + + processContext.spawn { + serverCtx.init() + try { + node.server!!.image(serverCtx) + serverCtx.exit() + } catch (cause: Throwable) { + serverCtx.exit(cause) + } + } + } + + private val serverCtx = object : ServerManagementContext { + private var initialized: Boolean = false + + override var server: Server + get() = node.server!! + set(value) { + node = node.copy(server = value) + } + + override suspend fun init() { + if (initialized) { + throw IllegalStateException() + } + + val previousState = server.state + server = server.copy(state = ServerState.ACTIVE) + monitor.onUpdate(server, previousState) + + initialized = true + } + + override suspend fun exit(cause: Throwable?) { + val previousState = server.state + val state = if (cause == null) ServerState.SHUTOFF else ServerState.ERROR + server = server.copy(state = state) + monitor.onUpdate(server, previousState) + initialized = false + } + + override suspend fun run(req: LongArray) { + // TODO Properly implement this for multiple CPUs + val time = max(0, req.max() ?: 0) * flavor.cpus[0].clockRate + delay(time.toLong()) + } + } +} diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt deleted file mode 100644 index 39b170fb..00000000 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/FakeBareMetalDriverTest.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 atlarge-research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package com.atlarge.opendc.compute.metal.driver - -import com.atlarge.odcsim.SimulationEngineProvider -import com.atlarge.opendc.compute.core.ServerFlavor -import com.atlarge.opendc.compute.core.ProcessingUnit -import com.atlarge.opendc.compute.core.Server -import com.atlarge.opendc.compute.core.ServerState -import com.atlarge.opendc.compute.core.image.FlopsApplicationImage -import com.atlarge.opendc.compute.core.monitor.ServerMonitor -import com.atlarge.opendc.compute.metal.PowerState -import java.util.ServiceLoader -import java.util.UUID -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Test - -internal class FakeBareMetalDriverTest { - /** - * A smoke test for the bare-metal driver. - */ - @Test - fun smoke() { - val provider = ServiceLoader.load(SimulationEngineProvider::class.java).first() - val system = provider({ ctx -> - val flavor = ServerFlavor(listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4))) - val image = FlopsApplicationImage(1000, 2) - val monitor = object : ServerMonitor { - override suspend fun onUpdate(server: Server, previousState: ServerState) { - println(server) - } - } - val driver = FakeBareMetalDriver(UUID.randomUUID(), "test", flavor) - - driver.init(monitor) - driver.setImage(image) - driver.setPower(PowerState.POWER_ON) - delay(5) - println(driver.refresh()) - }, name = "sim") - - runBlocking { - system.run() - system.terminate() - } - } -} diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt new file mode 100644 index 00000000..7835e305 --- /dev/null +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt @@ -0,0 +1,70 @@ +/* + * MIT License + * + * Copyright (c) 2020 atlarge-research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package com.atlarge.opendc.compute.metal.driver + +import com.atlarge.odcsim.SimulationEngineProvider +import com.atlarge.opendc.compute.core.ServerFlavor +import com.atlarge.opendc.compute.core.ProcessingUnit +import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerState +import com.atlarge.opendc.compute.core.image.FlopsApplicationImage +import com.atlarge.opendc.compute.core.monitor.ServerMonitor +import com.atlarge.opendc.compute.metal.PowerState +import java.util.ServiceLoader +import java.util.UUID +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Test + +internal class SimpleBareMetalDriverTest { + /** + * A smoke test for the bare-metal driver. + */ + @Test + fun smoke() { + val provider = ServiceLoader.load(SimulationEngineProvider::class.java).first() + val system = provider({ ctx -> + val flavor = ServerFlavor(listOf(ProcessingUnit("Intel", "Xeon", "amd64", 2300.0, 4))) + val image = FlopsApplicationImage(1000, 2) + val monitor = object : ServerMonitor { + override suspend fun onUpdate(server: Server, previousState: ServerState) { + println(server) + } + } + val driver = SimpleBareMetalDriver(UUID.randomUUID(), "test", flavor) + + driver.init(monitor) + driver.setImage(image) + driver.setPower(PowerState.POWER_ON) + delay(5) + println(driver.refresh()) + }, name = "sim") + + runBlocking { + system.run() + system.terminate() + } + } +} diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt index f1abbaed..34981b0a 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt @@ -31,7 +31,7 @@ import com.atlarge.opendc.compute.core.Server import com.atlarge.opendc.compute.core.ServerState import com.atlarge.opendc.compute.core.image.FlopsApplicationImage import com.atlarge.opendc.compute.core.monitor.ServerMonitor -import com.atlarge.opendc.compute.metal.driver.FakeBareMetalDriver +import com.atlarge.opendc.compute.metal.driver.SimpleBareMetalDriver import java.util.ServiceLoader import java.util.UUID import kotlinx.coroutines.delay @@ -56,7 +56,7 @@ internal class SimpleProvisioningServiceTest { println(server) } } - val driver = FakeBareMetalDriver(UUID.randomUUID(), "test", flavor) + val driver = SimpleBareMetalDriver(UUID.randomUUID(), "test", flavor) val provisioner = SimpleProvisioningService() provisioner.create(driver) -- cgit v1.2.3 From baeb118d68747e58f1c1beb8b2d27e1d640827f4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 14 Feb 2020 13:25:59 +0100 Subject: style: Fix Ktlint issues --- .../com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt | 2 +- .../atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt | 2 +- .../opendc/compute/metal/service/SimpleProvisioningServiceTest.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'opendc/opendc-compute/src') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt index 56fee524..4ccb6c57 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt @@ -25,8 +25,8 @@ package com.atlarge.opendc.compute.metal.driver import com.atlarge.odcsim.processContext -import com.atlarge.opendc.compute.core.ServerFlavor import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerFlavor import com.atlarge.opendc.compute.core.ServerState import com.atlarge.opendc.compute.core.execution.ServerManagementContext import com.atlarge.opendc.compute.core.image.EmptyImage diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt index 7835e305..c57d6eca 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriverTest.kt @@ -25,9 +25,9 @@ package com.atlarge.opendc.compute.metal.driver import com.atlarge.odcsim.SimulationEngineProvider -import com.atlarge.opendc.compute.core.ServerFlavor import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerFlavor import com.atlarge.opendc.compute.core.ServerState import com.atlarge.opendc.compute.core.image.FlopsApplicationImage import com.atlarge.opendc.compute.core.monitor.ServerMonitor diff --git a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt index 34981b0a..0f9cbd7f 100644 --- a/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt +++ b/opendc/opendc-compute/src/test/kotlin/com/atlarge/opendc/compute/metal/service/SimpleProvisioningServiceTest.kt @@ -25,9 +25,9 @@ package com.atlarge.opendc.compute.metal.service import com.atlarge.odcsim.SimulationEngineProvider -import com.atlarge.opendc.compute.core.ServerFlavor import com.atlarge.opendc.compute.core.ProcessingUnit import com.atlarge.opendc.compute.core.Server +import com.atlarge.opendc.compute.core.ServerFlavor import com.atlarge.opendc.compute.core.ServerState import com.atlarge.opendc.compute.core.image.FlopsApplicationImage import com.atlarge.opendc.compute.core.monitor.ServerMonitor -- cgit v1.2.3 From b13ba01e967e1a281d58b37cb57986b47ec99dd8 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Fri, 14 Feb 2020 13:26:20 +0100 Subject: bug: Apply requested cpu time correctly This change fixes an issue where the runtime of an image that requested cpu time was not properly computed. --- .../com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'opendc/opendc-compute/src') diff --git a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt index 4ccb6c57..4c702ffa 100644 --- a/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt +++ b/opendc/opendc-compute/src/main/kotlin/com/atlarge/opendc/compute/metal/driver/SimpleBareMetalDriver.kt @@ -138,7 +138,7 @@ public class SimpleBareMetalDriver( override suspend fun run(req: LongArray) { // TODO Properly implement this for multiple CPUs - val time = max(0, req.max() ?: 0) * flavor.cpus[0].clockRate + val time = max(0, req.max() ?: 0) / (flavor.cpus[0].clockRate * 1000) delay(time.toLong()) } } -- cgit v1.2.3