Files
ubicloud/prog/vm/vm_host_slice_nexus.rb
Jeremy Evans 59621ae323 Use create_with_id in progs and routes
Only changes to the specs in this commit are to fix mocking issues.
2025-08-07 02:13:08 +09:00

123 lines
3.3 KiB
Ruby

# frozen_string_literal: true
class Prog::Vm::VmHostSliceNexus < Prog::Base
subject_is :vm_host_slice
def self.assemble_with_host(name, vm_host, family:, allowed_cpus:, memory_gib:, is_shared: false)
DB.transaction do
vm_host_slice = VmHostSlice.create(
name: name,
is_shared: is_shared,
family: family,
cores: 0,
total_cpu_percent: 0,
used_cpu_percent: 0,
total_memory_gib: memory_gib,
used_memory_gib: 0,
vm_host_id: vm_host.id
)
# This will update the CPU allocation as well as total_cpu_percent and cores values
vm_host_slice.set_allowed_cpus(allowed_cpus)
Strand.create_with_id(vm_host_slice.id, prog: "Vm::VmHostSliceNexus", label: "prep")
end
end
def host
@host ||= vm_host_slice.vm_host
end
def before_run
when_destroy_set? do
hop_destroy if strand.label != "destroy"
end
end
label def prep
case host.sshable.cmd("common/bin/daemonizer --check prep_#{vm_host_slice.name}")
when "Succeeded"
host.sshable.cmd("common/bin/daemonizer --clean prep_#{vm_host_slice.name}")
hop_wait
when "NotStarted", "Failed"
host.sshable.cmd("common/bin/daemonizer 'sudo host/bin/setup-slice prep #{vm_host_slice.inhost_name} \"#{vm_host_slice.allowed_cpus_cgroup}\"' prep_#{vm_host_slice.name}")
end
nap 1
end
label def wait
when_start_after_host_reboot_set? do
register_deadline(:wait, 5 * 60)
hop_start_after_host_reboot
end
when_checkup_set? do
hop_unavailable if !available?
decr_checkup
rescue Sshable::SshError
# Host is likely to be down, which will be handled by HostNexus. We still
# go to the unavailable state for keeping track of the state.
hop_unavailable
end
nap 6 * 60 * 60
end
label def unavailable
# If the slice becomes unavailable due to host unavailability, it first needs to
# go through start_after_host_reboot state to be able to recover.
when_start_after_host_reboot_set? do
incr_checkup
hop_start_after_host_reboot
end
begin
if available?
decr_checkup
hop_wait
else
# Use deadlines to create a page instead of a custom page, so page
# resolution in different states can be handled properly.
register_deadline("wait", 0)
end
rescue *Sshable::SSH_CONNECTION_ERRORS
# Host is likely to be down, which will be handled by HostNexus. No need
# to create a page for this case.
end
nap 30
end
label def destroy
decr_destroy
host.sshable.cmd("sudo host/bin/setup-slice delete #{vm_host_slice.inhost_name}")
VmHost.dataset.where(id: host.id).update(
used_cores: Sequel[:used_cores] - vm_host_slice.cores,
used_hugepages_1g: Sequel[:used_hugepages_1g] - vm_host_slice.total_memory_gib
)
vm_host_slice.destroy
pop "vm_host_slice destroyed"
end
label def start_after_host_reboot
host.sshable.cmd("sudo host/bin/setup-slice recreate-unpersisted #{vm_host_slice.inhost_name}")
decr_start_after_host_reboot
hop_wait
end
def available?
available = false
host.sshable.start_fresh_session do |session|
available = vm_host_slice.up? session
end
available
end
end