summaryrefslogtreecommitdiff
path: root/simulator/opendc-compute/opendc-compute-simulator/src
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-03-07 15:44:36 +0100
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-03-07 16:13:16 +0100
commit9bb91897404bbeac1d5f7a7f890abd3a9d5d9084 (patch)
tree9e492df044306b6230444b73f2c3db59ef45440e /simulator/opendc-compute/opendc-compute-simulator/src
parentdfbca195cbe1d6c4eebe7ccd4cc707c84ac43e79 (diff)
compute: Move ComputeService implementation in service module
This change introduces the ComputeService interface (previously VirtProvisioningService) and provides a central implementation in opendc-compute-service. Previously, the implementation of this interface was bound to the simulator package, which meant that independent business logic could not be re-used without importing the simulator code.
Diffstat (limited to 'simulator/opendc-compute/opendc-compute-simulator/src')
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ClientServer.kt86
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/HypervisorView.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt36
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHostProvisioner.kt69
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtProvisioningService.kt434
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AllocationPolicy.kt50
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AvailableCoreMemoryAllocationPolicy.kt38
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AvailableMemoryAllocationPolicy.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ComparableAllocationPolicyLogic.kt49
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/NumberOfActiveServersAllocationPolicy.kt37
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ProvisionedCoresAllocationPolicy.kt40
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/RandomAllocationPolicy.kt48
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ReplayAllocationPolicy.kt56
-rw-r--r--simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt12
14 files changed, 98 insertions, 931 deletions
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ClientServer.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ClientServer.kt
deleted file mode 100644
index 642587da..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/ClientServer.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2021 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 org.opendc.compute.simulator
-
-import org.opendc.compute.api.Flavor
-import org.opendc.compute.api.Image
-import org.opendc.compute.api.Server
-import org.opendc.compute.api.ServerState
-import org.opendc.compute.api.ServerWatcher
-import java.util.*
-
-/**
- * A [Server] implementation that is passed to clients but delegates its implementation to another class.
- */
-internal class ClientServer(private val delegate: Server) : Server, ServerWatcher {
- private val watchers = mutableListOf<ServerWatcher>()
-
- override val uid: UUID = delegate.uid
-
- override var name: String = delegate.name
- private set
-
- override var flavor: Flavor = delegate.flavor
- private set
-
- override var image: Image = delegate.image
- private set
-
- override var tags: Map<String, String> = delegate.tags.toMap()
- private set
-
- override var state: ServerState = delegate.state
- private set
-
- override fun watch(watcher: ServerWatcher) {
- if (watchers.isEmpty()) {
- delegate.watch(this)
- }
-
- watchers += watcher
- }
-
- override fun unwatch(watcher: ServerWatcher) {
- watchers += watcher
-
- if (watchers.isEmpty()) {
- delegate.unwatch(this)
- }
- }
-
- override suspend fun refresh() {
- name = delegate.name
- flavor = delegate.flavor
- image = delegate.image
- tags = delegate.tags
- state = delegate.state
- }
-
- override fun onStateChanged(server: Server, newState: ServerState) {
- val watchers = watchers
-
- for (watcher in watchers) {
- watcher.onStateChanged(this, newState)
- }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/HypervisorView.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/HypervisorView.kt
deleted file mode 100644
index a650144b..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/HypervisorView.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator
-
-import org.opendc.compute.core.metal.Node
-import org.opendc.compute.core.virt.Host
-import java.util.UUID
-
-public class HypervisorView(
- public val uid: UUID,
- public var node: Node,
- public var numberOfActiveServers: Int,
- public var availableMemory: Long,
- public var provisionedCores: Int
-) {
- public lateinit var driver: Host
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
index 9808cf50..801f73dd 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHost.kt
@@ -30,7 +30,7 @@ import org.opendc.compute.api.Server
import org.opendc.compute.api.ServerState
import org.opendc.compute.core.*
import org.opendc.compute.core.metal.Node
-import org.opendc.compute.core.virt.*
+import org.opendc.compute.service.driver.*
import org.opendc.simulator.compute.*
import org.opendc.simulator.compute.interference.IMAGE_PERF_INTERFERENCE_MODEL
import org.opendc.simulator.compute.interference.PerformanceInterferenceModel
@@ -45,7 +45,7 @@ import kotlin.coroutines.resume
* A [Host] that is simulates virtual machines on a physical machine using [SimHypervisor].
*/
public class SimHost(
- override val uid: UUID,
+ public val node: Node,
private val coroutineScope: CoroutineScope,
hypervisor: SimHypervisorProvider
) : Host, SimWorkload {
@@ -96,8 +96,7 @@ public class SimHost(
interferedWork,
cpuUsage,
cpuDemand,
- guests.size,
- node
+ guests.size
)
)
}
@@ -107,19 +106,22 @@ public class SimHost(
/**
* The virtual machines running on the hypervisor.
*/
- private val guests = HashMap<Server, SimGuest>()
+ private val guests = HashMap<Server, Guest>()
- /**
- * The node on which the hypervisor runs.
- */
- public val node: Node
- get() = ctx.meta["node"] as Node
+ override val uid: UUID
+ get() = node.uid
+
+ override val name: String
+ get() = node.name
+
+ override val model: HostModel
+ get() = HostModel(node.flavor.cpuCount, node.flavor.memorySize)
override val state: HostState
get() = _state
private var _state: HostState = HostState.UP
set(value) {
- listeners.forEach { it.onStateChange(this, value) }
+ listeners.forEach { it.onStateChanged(this, value) }
field = value
}
@@ -138,7 +140,7 @@ public class SimHost(
}
require(canFit(server)) { "Server does not fit" }
- val guest = SimGuest(server, hypervisor.createMachine(server.flavor.toMachineModel()))
+ val guest = Guest(server, hypervisor.createMachine(server.flavor.toMachineModel()))
guests[server] = guest
if (start) {
@@ -187,24 +189,24 @@ public class SimHost(
return SimMachineModel(processingUnits, memoryUnits)
}
- private fun onGuestStart(vm: SimGuest) {
+ private fun onGuestStart(vm: Guest) {
guests.forEach { _, guest ->
if (guest.state == ServerState.ACTIVE) {
vm.performanceInterferenceModel?.onStart(vm.server.image.name)
}
}
- listeners.forEach { it.onStateChange(this, vm.server, vm.state) }
+ listeners.forEach { it.onStateChanged(this, vm.server, vm.state) }
}
- private fun onGuestStop(vm: SimGuest) {
+ private fun onGuestStop(vm: Guest) {
guests.forEach { _, guest ->
if (guest.state == ServerState.ACTIVE) {
vm.performanceInterferenceModel?.onStop(vm.server.image.name)
}
}
- listeners.forEach { it.onStateChange(this, vm.server, vm.state) }
+ listeners.forEach { it.onStateChanged(this, vm.server, vm.state) }
_events.emit(HostEvent.VmsUpdated(this@SimHost, guests.count { it.value.state == ServerState.ACTIVE }, availableMemory))
}
@@ -212,7 +214,7 @@ public class SimHost(
/**
* A virtual machine instance that the driver manages.
*/
- private inner class SimGuest(val server: Server, val machine: SimMachine) {
+ private inner class Guest(val server: Server, val machine: SimMachine) {
val performanceInterferenceModel: PerformanceInterferenceModel? = server.image.tags[IMAGE_PERF_INTERFERENCE_MODEL] as? PerformanceInterferenceModel?
var state: ServerState = ServerState.SHUTOFF
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHostProvisioner.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHostProvisioner.kt
new file mode 100644
index 00000000..1c51162d
--- /dev/null
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimHostProvisioner.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2021 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 org.opendc.compute.simulator
+
+import kotlinx.coroutines.*
+import org.opendc.compute.api.Image
+import org.opendc.compute.core.metal.Node
+import org.opendc.compute.core.metal.service.ProvisioningService
+import org.opendc.compute.service.driver.Host
+import org.opendc.simulator.compute.SimHypervisorProvider
+import kotlin.coroutines.CoroutineContext
+
+/**
+ * A helper class to provision [SimHost]s on top of bare-metal machines using the [ProvisioningService].
+ *
+ * @param context The [CoroutineContext] to use.
+ * @param metal The [ProvisioningService] to use.
+ * @param hypervisor The type of hypervisor to use.
+ */
+public class SimHostProvisioner(
+ private val context: CoroutineContext,
+ private val metal: ProvisioningService,
+ private val hypervisor: SimHypervisorProvider
+) : AutoCloseable {
+ /**
+ * The [CoroutineScope] of the service bounded by the lifecycle of the service.
+ */
+ private val scope = CoroutineScope(context)
+
+ /**
+ * Provision all machines with a host.
+ */
+ public suspend fun provisionAll(): List<Host> = coroutineScope {
+ metal.nodes().map { node -> async { provision(node) } }.awaitAll()
+ }
+
+ /**
+ * Provision the specified [Node].
+ */
+ public suspend fun provision(node: Node): Host = coroutineScope {
+ val host = SimHost(node, scope, hypervisor)
+ metal.deploy(node, Image(node.uid, node.name, mapOf("workload" to host)))
+ host
+ }
+
+ override fun close() {
+ scope.cancel()
+ }
+}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtProvisioningService.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtProvisioningService.kt
deleted file mode 100644
index bdea93e3..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/SimVirtProvisioningService.kt
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator
-
-import kotlinx.coroutines.*
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import mu.KotlinLogging
-import org.opendc.compute.api.*
-import org.opendc.compute.core.*
-import org.opendc.compute.core.metal.Node
-import org.opendc.compute.core.metal.NodeEvent
-import org.opendc.compute.core.metal.NodeState
-import org.opendc.compute.core.metal.service.ProvisioningService
-import org.opendc.compute.core.virt.*
-import org.opendc.compute.core.virt.service.VirtProvisioningEvent
-import org.opendc.compute.core.virt.service.VirtProvisioningService
-import org.opendc.compute.core.virt.service.events.*
-import org.opendc.compute.simulator.allocation.AllocationPolicy
-import org.opendc.simulator.compute.SimHypervisorProvider
-import org.opendc.trace.core.EventTracer
-import org.opendc.utils.TimerScheduler
-import org.opendc.utils.flow.EventFlow
-import java.time.Clock
-import java.util.*
-import kotlin.coroutines.Continuation
-import kotlin.coroutines.resume
-import kotlin.math.max
-
-@OptIn(ExperimentalCoroutinesApi::class)
-public class SimVirtProvisioningService(
- private val coroutineScope: CoroutineScope,
- private val clock: Clock,
- private val provisioningService: ProvisioningService,
- public val allocationPolicy: AllocationPolicy,
- private val tracer: EventTracer,
- private val hypervisor: SimHypervisorProvider,
- private val schedulingQuantum: Long = 300000, // 5 minutes in milliseconds
-) : VirtProvisioningService, HostListener {
- /**
- * The logger instance to use.
- */
- private val logger = KotlinLogging.logger {}
-
- /**
- * A mapping from host to hypervisor view.
- */
- private val hostToHv = mutableMapOf<Host, HypervisorView>()
-
- /**
- * The hypervisors that have been launched by the service.
- */
- private val hypervisors: MutableMap<Node, HypervisorView> = mutableMapOf()
-
- /**
- * The available hypervisors.
- */
- private val availableHypervisors: MutableSet<HypervisorView> = mutableSetOf()
-
- /**
- * The servers that should be launched by the service.
- */
- private val queue: Deque<LaunchRequest> = ArrayDeque()
-
- /**
- * The active servers in the system.
- */
- private val activeServers: MutableSet<Server> = mutableSetOf()
-
- /**
- * The [Random] instance used to generate unique identifiers for the objects.
- */
- private val random = Random(0)
-
- public var submittedVms: Int = 0
- public var queuedVms: Int = 0
- public var runningVms: Int = 0
- public var finishedVms: Int = 0
- public var unscheduledVms: Int = 0
-
- private var maxCores = 0
- private var maxMemory = 0L
-
- /**
- * The allocation logic to use.
- */
- private val allocationLogic = allocationPolicy()
-
- override val events: Flow<VirtProvisioningEvent>
- get() = _events
- private val _events = EventFlow<VirtProvisioningEvent>()
-
- /**
- * The [TimerScheduler] to use for scheduling the scheduler cycles.
- */
- private var scheduler: TimerScheduler<Unit> = TimerScheduler(coroutineScope, clock)
-
- init {
- coroutineScope.launch {
- val provisionedNodes = provisioningService.nodes()
- provisionedNodes.forEach { node ->
- val workload = SimHost(UUID(random.nextLong(), random.nextLong()), coroutineScope, hypervisor)
- workload.addListener(this@SimVirtProvisioningService)
- val hypervisorImage = Image(UUID.randomUUID(), "vmm", mapOf("workload" to workload))
- launch {
- val deployedNode = provisioningService.deploy(node, hypervisorImage)
- deployedNode.events.onEach { event ->
- when (event) {
- is NodeEvent.StateChanged -> stateChanged(event.node, workload)
- }
- }.launchIn(this)
- }
- }
- }
- }
-
- override suspend fun drivers(): Set<Host> {
- return availableHypervisors.map { it.driver }.toSet()
- }
-
- override val hostCount: Int = hypervisors.size
-
- override fun newClient(): ComputeClient = object : ComputeClient {
- private var isClosed: Boolean = false
-
- override suspend fun newServer(name: String, image: Image, flavor: Flavor): Server {
- check(!isClosed) { "Client is closed" }
- tracer.commit(VmSubmissionEvent(name, image, flavor))
-
- _events.emit(
- VirtProvisioningEvent.MetricsAvailable(
- this@SimVirtProvisioningService,
- hypervisors.size,
- availableHypervisors.size,
- ++submittedVms,
- runningVms,
- finishedVms,
- ++queuedVms,
- unscheduledVms
- )
- )
-
- return suspendCancellableCoroutine { cont ->
- val request = LaunchRequest(createServer(name, image, flavor), cont)
- queue += request
- requestCycle()
- }
- }
-
- override fun close() {
- isClosed = true
- }
-
- override fun toString(): String = "ComputeClient"
- }
-
- override suspend fun terminate() {
- val provisionedNodes = provisioningService.nodes()
- provisionedNodes.forEach { node -> provisioningService.stop(node) }
- }
-
- private fun createServer(
- name: String,
- image: Image,
- flavor: Flavor
- ): Server {
- return ServerImpl(
- uid = UUID(random.nextLong(), random.nextLong()),
- name = name,
- flavor = flavor,
- image = image
- )
- }
-
- private fun requestCycle() {
- // Bail out in case we have already requested a new cycle.
- if (scheduler.isTimerActive(Unit)) {
- return
- }
-
- // We assume that the provisioner runs at a fixed slot every time quantum (e.g t=0, t=60, t=120).
- // This is important because the slices of the VMs need to be aligned.
- // We calculate here the delay until the next scheduling slot.
- val delay = schedulingQuantum - (clock.millis() % schedulingQuantum)
-
- scheduler.startSingleTimer(Unit, delay) {
- schedule()
- }
- }
-
- private fun schedule() {
- while (queue.isNotEmpty()) {
- val (server, cont) = queue.peekFirst()
- val requiredMemory = server.flavor.memorySize
- val selectedHv = allocationLogic.select(availableHypervisors, server)
-
- if (selectedHv == null || !selectedHv.driver.canFit(server)) {
- logger.trace { "Server $server selected for scheduling but no capacity available for it." }
-
- if (requiredMemory > maxMemory || server.flavor.cpuCount > maxCores) {
- tracer.commit(VmSubmissionInvalidEvent(server.name))
-
- _events.emit(
- VirtProvisioningEvent.MetricsAvailable(
- this@SimVirtProvisioningService,
- hypervisors.size,
- availableHypervisors.size,
- submittedVms,
- runningVms,
- finishedVms,
- --queuedVms,
- ++unscheduledVms
- )
- )
-
- // Remove the incoming image
- queue.poll()
-
- logger.warn("Failed to spawn $server: does not fit [${clock.millis()}]")
- continue
- } else {
- break
- }
- }
-
- try {
- logger.info { "[${clock.millis()}] Spawning $server on ${selectedHv.node.uid} ${selectedHv.node.name} ${selectedHv.node.flavor}" }
- queue.poll()
-
- // Speculatively update the hypervisor view information to prevent other images in the queue from
- // deciding on stale values.
- selectedHv.numberOfActiveServers++
- selectedHv.provisionedCores += server.flavor.cpuCount
- selectedHv.availableMemory -= requiredMemory // XXX Temporary hack
-
- coroutineScope.launch {
- try {
- cont.resume(ClientServer(server))
- selectedHv.driver.spawn(server)
- activeServers += server
-
- tracer.commit(VmScheduledEvent(server.name))
- _events.emit(
- VirtProvisioningEvent.MetricsAvailable(
- this@SimVirtProvisioningService,
- hypervisors.size,
- availableHypervisors.size,
- submittedVms,
- ++runningVms,
- finishedVms,
- --queuedVms,
- unscheduledVms
- )
- )
- } catch (e: InsufficientMemoryOnServerException) {
- logger.error("Failed to deploy VM", e)
-
- selectedHv.numberOfActiveServers--
- selectedHv.provisionedCores -= server.flavor.cpuCount
- selectedHv.availableMemory += requiredMemory
- }
- }
- } catch (e: Throwable) {
- logger.error("Failed to deploy VM", e)
- }
- }
- }
-
- private fun stateChanged(node: Node, hypervisor: SimHost) {
- when (node.state) {
- NodeState.ACTIVE -> {
- logger.debug { "[${clock.millis()}] Server ${node.uid} available: ${node.state}" }
-
- if (node in hypervisors) {
- // Corner case for when the hypervisor already exists
- availableHypervisors += hypervisors.getValue(node)
- } else {
- val hv = HypervisorView(
- node.uid,
- node,
- 0,
- node.flavor.memorySize,
- 0
- )
- hv.driver = hypervisor
- hv.driver.events
- .onEach { event ->
- if (event is HostEvent.VmsUpdated) {
- hv.numberOfActiveServers = event.numberOfActiveServers
- hv.availableMemory = event.availableMemory
- }
- }.launchIn(coroutineScope)
-
- maxCores = max(maxCores, node.flavor.cpuCount)
- maxMemory = max(maxMemory, node.flavor.memorySize)
- hypervisors[node] = hv
- hostToHv[hypervisor] = hv
- availableHypervisors += hv
- }
-
- tracer.commit(HypervisorAvailableEvent(node.uid))
-
- _events.emit(
- VirtProvisioningEvent.MetricsAvailable(
- this@SimVirtProvisioningService,
- hypervisors.size,
- availableHypervisors.size,
- submittedVms,
- runningVms,
- finishedVms,
- queuedVms,
- unscheduledVms
- )
- )
-
- // Re-schedule on the new machine
- if (queue.isNotEmpty()) {
- requestCycle()
- }
- }
- NodeState.SHUTOFF, NodeState.ERROR -> {
- logger.debug { "[${clock.millis()}] Server ${node.uid} unavailable: ${node.state}" }
- val hv = hypervisors[node] ?: return
- availableHypervisors -= hv
-
- tracer.commit(HypervisorUnavailableEvent(hv.uid))
-
- _events.emit(
- VirtProvisioningEvent.MetricsAvailable(
- this@SimVirtProvisioningService,
- hypervisors.size,
- availableHypervisors.size,
- submittedVms,
- runningVms,
- finishedVms,
- queuedVms,
- unscheduledVms
- )
- )
-
- if (queue.isNotEmpty()) {
- requestCycle()
- }
- }
- else -> throw IllegalStateException()
- }
- }
-
- override fun onStateChange(host: Host, server: Server, newState: ServerState) {
- val serverImpl = server as ServerImpl
- serverImpl.state = newState
- serverImpl.watchers.forEach { it.onStateChanged(server, newState) }
-
- if (newState == ServerState.SHUTOFF) {
- logger.info { "[${clock.millis()}] Server ${server.uid} ${server.name} ${server.flavor} finished." }
-
- tracer.commit(VmStoppedEvent(server.name))
-
- _events.emit(
- VirtProvisioningEvent.MetricsAvailable(
- this@SimVirtProvisioningService,
- hypervisors.size,
- availableHypervisors.size,
- submittedVms,
- --runningVms,
- ++finishedVms,
- queuedVms,
- unscheduledVms
- )
- )
-
- activeServers -= server
- val hv = hostToHv[host]
- if (hv != null) {
- hv.provisionedCores -= server.flavor.cpuCount
- } else {
- logger.error { "Unknown host $host" }
- }
-
- // Try to reschedule if needed
- if (queue.isNotEmpty()) {
- requestCycle()
- }
- }
- }
-
- public data class LaunchRequest(val server: Server, val cont: Continuation<Server>)
-
- private class ServerImpl(
- override val uid: UUID,
- override val name: String,
- override val flavor: Flavor,
- override val image: Image
- ) : Server {
- val watchers = mutableListOf<ServerWatcher>()
-
- override fun watch(watcher: ServerWatcher) {
- watchers += watcher
- }
-
- override fun unwatch(watcher: ServerWatcher) {
- watchers -= watcher
- }
-
- override suspend fun refresh() {
- // No-op: this object is the source-of-truth
- }
-
- override val tags: Map<String, String> = emptyMap()
-
- override var state: ServerState = ServerState.BUILD
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AllocationPolicy.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AllocationPolicy.kt
deleted file mode 100644
index f01e4064..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AllocationPolicy.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator.allocation
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.core.metal.Node
-import org.opendc.compute.simulator.HypervisorView
-
-/**
- * A policy for selecting the [Node] an image should be deployed to,
- */
-public interface AllocationPolicy {
- /**
- * The logic of the allocation policy.
- */
- public interface Logic {
- /**
- * Select the node on which the server should be scheduled.
- */
- public fun select(
- hypervisors: Set<HypervisorView>,
- server: Server
- ): HypervisorView?
- }
-
- /**
- * Builds the logic of the policy.
- */
- public operator fun invoke(): Logic
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AvailableCoreMemoryAllocationPolicy.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AvailableCoreMemoryAllocationPolicy.kt
deleted file mode 100644
index 5e044282..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AvailableCoreMemoryAllocationPolicy.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator.allocation
-
-import org.opendc.compute.simulator.HypervisorView
-
-/**
- * An [AllocationPolicy] that selects the machine with the highest/lowest amount of memory per core.
- *
- * @param reversed An option to reverse the order of the machines (lower amount of memory scores better).
- */
-public class AvailableCoreMemoryAllocationPolicy(private val reversed: Boolean = false) : AllocationPolicy {
- override fun invoke(): AllocationPolicy.Logic = object : ComparableAllocationPolicyLogic {
- override val comparator: Comparator<HypervisorView> =
- compareBy<HypervisorView> { -it.availableMemory / it.node.flavor.cpuCount }
- .run { if (reversed) reversed() else this }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AvailableMemoryAllocationPolicy.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AvailableMemoryAllocationPolicy.kt
deleted file mode 100644
index e87abd7b..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/AvailableMemoryAllocationPolicy.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator.allocation
-
-import org.opendc.compute.simulator.HypervisorView
-
-/**
- * Allocation policy that selects the node with the most available memory.
- *
- * @param reversed A flag to reverse the order (least amount of memory scores the best).
- */
-public class AvailableMemoryAllocationPolicy(public val reversed: Boolean = false) : AllocationPolicy {
- override fun invoke(): AllocationPolicy.Logic = object : ComparableAllocationPolicyLogic {
- override val comparator: Comparator<HypervisorView> = compareBy<HypervisorView> { -it.availableMemory }
- .run { if (reversed) reversed() else this }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ComparableAllocationPolicyLogic.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ComparableAllocationPolicyLogic.kt
deleted file mode 100644
index a1a1f984..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ComparableAllocationPolicyLogic.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator.allocation
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.simulator.HypervisorView
-
-/**
- * The logic for an [AllocationPolicy] that uses a [Comparator] to select the appropriate node.
- */
-public interface ComparableAllocationPolicyLogic : AllocationPolicy.Logic {
- /**
- * The comparator to use.
- */
- public val comparator: Comparator<HypervisorView>
-
- override fun select(
- hypervisors: Set<HypervisorView>,
- server: Server
- ): HypervisorView? {
- return hypervisors.asSequence()
- .filter { hv ->
- val fitsMemory = hv.availableMemory >= (server.flavor.memorySize)
- val fitsCpu = hv.node.flavor.cpuCount >= server.flavor.cpuCount
- fitsMemory && fitsCpu
- }
- .minWithOrNull(comparator.thenBy { it.node.uid })
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/NumberOfActiveServersAllocationPolicy.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/NumberOfActiveServersAllocationPolicy.kt
deleted file mode 100644
index 5e2b895c..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/NumberOfActiveServersAllocationPolicy.kt
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator.allocation
-
-import org.opendc.compute.simulator.HypervisorView
-
-/**
- * Allocation policy that selects the node with the least amount of active servers.
- *
- * @param reversed A flag to reverse the order, such that the node with the most active servers is selected.
- */
-public class NumberOfActiveServersAllocationPolicy(public val reversed: Boolean = false) : AllocationPolicy {
- override fun invoke(): AllocationPolicy.Logic = object : ComparableAllocationPolicyLogic {
- override val comparator: Comparator<HypervisorView> = compareBy<HypervisorView> { it.numberOfActiveServers }
- .run { if (reversed) reversed() else this }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ProvisionedCoresAllocationPolicy.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ProvisionedCoresAllocationPolicy.kt
deleted file mode 100644
index 91441ecd..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ProvisionedCoresAllocationPolicy.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator.allocation
-
-import org.opendc.compute.simulator.HypervisorView
-
-/**
- * An [AllocationPolicy] that takes into account the number of vCPUs that have been provisioned on this machine
- * relative to its core count.
- *
- * @param reversed A flag to reverse the order of the policy, such that the machine with the most provisioned cores
- * is selected.
- */
-public class ProvisionedCoresAllocationPolicy(private val reversed: Boolean = false) : AllocationPolicy {
- override fun invoke(): AllocationPolicy.Logic = object : ComparableAllocationPolicyLogic {
- override val comparator: Comparator<HypervisorView> =
- compareBy<HypervisorView> { it.provisionedCores / it.node.flavor.cpuCount }
- .run { if (reversed) reversed() else this }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/RandomAllocationPolicy.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/RandomAllocationPolicy.kt
deleted file mode 100644
index e6d9e1ce..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/RandomAllocationPolicy.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator.allocation
-
-import org.opendc.compute.api.Server
-import org.opendc.compute.simulator.HypervisorView
-import kotlin.random.Random
-
-/**
- * An [AllocationPolicy] that select a random node on which the server fits.
- */
-public class RandomAllocationPolicy(private val random: Random = Random(0)) : AllocationPolicy {
- @OptIn(ExperimentalStdlibApi::class)
- override fun invoke(): AllocationPolicy.Logic = object : AllocationPolicy.Logic {
- override fun select(
- hypervisors: Set<HypervisorView>,
- server: Server
- ): HypervisorView? {
- return hypervisors.asIterable()
- .filter { hv ->
- val fitsMemory = hv.availableMemory >= (server.image.tags["required-memory"] as Long)
- val fitsCpu = hv.node.flavor.cpuCount >= server.flavor.cpuCount
- fitsMemory && fitsCpu
- }
- .randomOrNull(random)
- }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ReplayAllocationPolicy.kt b/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ReplayAllocationPolicy.kt
deleted file mode 100644
index 9f8fa544..00000000
--- a/simulator/opendc-compute/opendc-compute-simulator/src/main/kotlin/org/opendc/compute/simulator/allocation/ReplayAllocationPolicy.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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 org.opendc.compute.simulator.allocation
-
-import mu.KotlinLogging
-import org.opendc.compute.api.Server
-import org.opendc.compute.simulator.HypervisorView
-
-private val logger = KotlinLogging.logger {}
-
-/**
- * Policy replaying VM-cluster assignment.
- *
- * Within each cluster, the active servers on each node determine which node gets
- * assigned the VM image.
- */
-public class ReplayAllocationPolicy(private val vmPlacements: Map<String, String>) : AllocationPolicy {
- override fun invoke(): AllocationPolicy.Logic = object : AllocationPolicy.Logic {
- override fun select(
- hypervisors: Set<HypervisorView>,
- server: Server
- ): HypervisorView? {
- val clusterName = vmPlacements[server.name]
- ?: throw IllegalStateException("Could not find placement data in VM placement file for VM ${server.name}")
- val machinesInCluster = hypervisors.filter { it.node.name.contains(clusterName) }
-
- if (machinesInCluster.isEmpty()) {
- logger.info { "Could not find any machines belonging to cluster $clusterName for image ${server.name}, assigning randomly." }
- return hypervisors.maxByOrNull { it.availableMemory }
- }
-
- return machinesInCluster.maxByOrNull { it.availableMemory }
- ?: throw IllegalStateException("Cloud not find any machine and could not randomly assign")
- }
- }
-}
diff --git a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
index 7b654473..d3b6c4bc 100644
--- a/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
+++ b/simulator/opendc-compute/opendc-compute-simulator/src/test/kotlin/org/opendc/compute/simulator/SimHostTest.kt
@@ -24,6 +24,7 @@ package org.opendc.compute.simulator
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
@@ -37,7 +38,9 @@ import org.opendc.compute.api.Image
import org.opendc.compute.api.Server
import org.opendc.compute.api.ServerState
import org.opendc.compute.api.ServerWatcher
-import org.opendc.compute.core.virt.HostEvent
+import org.opendc.compute.core.metal.Node
+import org.opendc.compute.core.metal.NodeState
+import org.opendc.compute.service.driver.HostEvent
import org.opendc.simulator.compute.SimFairShareHypervisorProvider
import org.opendc.simulator.compute.SimMachineModel
import org.opendc.simulator.compute.model.MemoryUnit
@@ -79,8 +82,13 @@ internal class SimHostTest {
var grantedWork = 0L
var overcommittedWork = 0L
+ val node = Node(
+ UUID.randomUUID(), "name", emptyMap(), NodeState.SHUTOFF,
+ Flavor(machineModel.cpus.size, machineModel.memory.map { it.size }.sum()), Image.EMPTY, emptyFlow()
+ )
+
scope.launch {
- val virtDriver = SimHost(UUID.randomUUID(), this, SimFairShareHypervisorProvider())
+ val virtDriver = SimHost(node, this, SimFairShareHypervisorProvider())
val vmm = Image(UUID.randomUUID(), "vmm", mapOf("workload" to virtDriver))
val duration = 5 * 60L
val vmImageA = Image(