ubicloud/prog/vnet/metal/nic_nexus.rb
Furkan Sahin 5c361d1212 Start using the newly added state and update it in NicNexus.rb
SubnetNexus/NicNexus relationship has been quite fragile. The dependency
on the semaphores + strand label proved to be quite useless. Especially
considering the label names may change, or new labels may be introduced.
Recently we had an issue of IpsecTunnels not being created for a VM that
was added to the subnet. When we add the new nic, or rekeying from
multiple different "connected" subnets, and no control over who does
what/when, this caused an issue. One of the nics were in the process of
getting added while the others were getting rekeyed. This caused the
label based filtering to completely fail. Instead, with this commit, we
are introducing the entity level state where we control every step and
filter using that state in a later commit.
2025-11-19 10:20:30 +01:00

100 lines
2 KiB
Ruby

# frozen_string_literal: true
class Prog::Vnet::Metal::NicNexus < Prog::Base
subject_is :nic
def before_run
when_destroy_set? do
hop_destroy if strand.label != "destroy"
end
end
label def start
when_vm_allocated_set? do
hop_wait_setup
end
nap 5
end
label def wait_setup
decr_vm_allocated
when_setup_nic_set? do
DB.transaction do
decr_setup_nic
nic.private_subnet.incr_add_new_nic
nic.update(state: "creating")
end
end
when_start_rekey_set? do
hop_start_rekey
end
nap 5
end
label def wait
when_repopulate_set? do
nic.private_subnet.incr_refresh_keys
decr_repopulate
end
when_start_rekey_set? do
hop_start_rekey
end
nap 6 * 60 * 60
end
label def start_rekey
decr_start_rekey
if retval&.dig("msg") == "inbound_setup is complete"
hop_wait_rekey_outbound_trigger
end
push Prog::Vnet::RekeyNicTunnel, {}, :setup_inbound
end
label def wait_rekey_outbound_trigger
if retval&.dig("msg") == "outbound_setup is complete"
hop_wait_rekey_old_state_drop_trigger
end
when_trigger_outbound_update_set? do
decr_trigger_outbound_update
push Prog::Vnet::RekeyNicTunnel, {}, :setup_outbound
end
nap 5
end
label def wait_rekey_old_state_drop_trigger
if retval&.dig("msg")&.include?("drop_old_state is complete")
unless nic.state == "active"
nic.update(state: "active")
nic.private_subnet.incr_refresh_keys
end
hop_wait
end
when_old_state_drop_trigger_set? do
decr_old_state_drop_trigger
push Prog::Vnet::RekeyNicTunnel, {}, :drop_old_state
end
nap 5
end
label def destroy
if nic.vm
Clog.emit("Cannot destroy nic with active vm, first clean up the attached resources") { nic }
nap 5
end
decr_destroy
nic.private_subnet.incr_refresh_keys
nic.destroy
pop "nic deleted"
end
end