Skip to content

Commit

Permalink
WIP: AASM approach sketch
Browse files Browse the repository at this point in the history
  • Loading branch information
dbackeus committed Jun 20, 2024
1 parent 1b9eccd commit 0058a05
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 8 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ source "https://rubygems.org"

ruby "3.2.0"

gem "aasm"
gem "bootsnap", require: false
gem "importmap-rails"
gem "net-ssh"
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
GEM
remote: https://rubygems.org/
specs:
aasm (5.5.0)
concurrent-ruby (~> 1.0)
actioncable (7.1.3.2)
actionpack (= 7.1.3.2)
activesupport (= 7.1.3.2)
Expand Down Expand Up @@ -239,6 +241,7 @@ PLATFORMS
x86_64-linux

DEPENDENCIES
aasm
bootsnap
cloudflare-rails
debug
Expand Down
5 changes: 2 additions & 3 deletions app/controllers/configs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ def show
server = Server.find_by_ip!(ip)

if server.machine_config
# Using 1.second.ago seems silly but is required to show the correct status in the UI at the moment
server.update!(last_request_for_configuration_at: 1.second.ago, last_configured_at: Time.now)
server.configure!
headers["Content-Type"] = "text/yaml"
render plain: server.machine_config.generate_config
else
server.update!(last_configured_at: nil, last_request_for_configuration_at: Time.now)
server.request_configuration!
render plain: "No configuration found for server with IP #{server.ip}", status: 420
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/servers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def bootstrap
def rescue
server = Server.find(params[:id])

server.rescue
server.rescue!

redirect_to servers_path, notice: "Server #{server.name} is rebooting in rescue mode"
end
Expand Down
59 changes: 57 additions & 2 deletions app/models/server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,61 @@ class Server < ApplicationRecord
has_one :machine_config, dependent: :destroy
has_one :config, through: :machine_config

include AASM

aasm timestamps: true do
state :pending, initial: true
state :rescuing
state :failed_rescue
state :rescued
state :installing_talos
state :awaiting_configuration
state :configuring
state :configured
state :ready
state :inaccessible

event :rescue, before: :before_rescue do
transitions to: :rescuing
end

event :await_rescued do
transitions from: %i[rescuing failed_rescue], to: :rescued, guard: :bootstrappable?
transitions from: :rescuing, to: :failed_rescue, guard: :rescue_timeout?
end

event :install_talos, before: :bootstrap! do
transitions from: :rescued, to: :installing_talos
end

event :request_configuration do
before do
assign_attributes(last_configured_at: nil, last_request_for_configuration_at: Time.now)
end

transitions to: :awaiting_configuration
end

event :configure do
before do
# 1.second.ago seems silly but is required to show the correct status in the UI at the moment
assign_attributes(last_configured_at: Time.now, last_request_for_configuration_at: 1.second.ago)
end

transitions to: :configuring
end

event :await_configured do
transitions from: %i[configuring failed_configure], to: :configured, guard: :talos_accessible?
transitions from: :configuring, to: :failed_configure, guard: :configure_timeout?
end

event :await_ready do
transitions from: %i[configured failed_ready], to: :ready, guard: :ready?
transitions from: :configured, to: :failed_ready, guard: :ready_timeout?
end
end

attr_accessor :sync # set to true to sync changed attributes to hetzner

validates_uniqueness_of :name, allow_nil: true
Expand Down Expand Up @@ -85,8 +140,8 @@ def bootstrap!
update!(accessible: false)
end

def rescue
raise "#rescue is not implemented for #{self.class.name}"
def before_rescue
raise "#before_rescue is not implemented for #{self.class.name}"
end

def reset
Expand Down
2 changes: 1 addition & 1 deletion app/models/server/hetzner_cloud.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def bootstrappable?
session&.shutdown!
end

def rescue
def before_rescue
::HetznerCloud.active_rescue_system(id)

# Hetzner appears to temporarily lock the server immediately after enabling rescue mode.
Expand Down
2 changes: 1 addition & 1 deletion app/models/server/hetzner_dedicated.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def bootstrappable?
session&.shutdown!
end

def rescue
def before_rescue
Hetzner.active_rescue_system(id)

if Hetzner.reset_state(id).fetch("operating_status") == "shut off"
Expand Down

0 comments on commit 0058a05

Please sign in to comment.