Skip to content

Commit

Permalink
nodectl, libnodectld: update SSH host keys/os-release on demand
Browse files Browse the repository at this point in the history
  • Loading branch information
aither64 committed Nov 26, 2024
1 parent 2bbd1c4 commit 9ea1b00
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 4 deletions.
3 changes: 2 additions & 1 deletion libnodectld/lib/nodectld/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ module NodeCtld
},

vps_os_release: {
enable: true
enable: true,
update_vps_delay: 1
},

dataset_expander: {
Expand Down
28 changes: 28 additions & 0 deletions libnodectld/lib/nodectld/remote_commands/update.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module NodeCtld::RemoteCommands
class Update < Base
handle :update

def exec
case @command
when 'ssh-host-keys'
if @vps_ids&.any?
NodeCtld::VpsSshHostKeys.update_vps_ids(@vps_ids)
else
NodeCtld::VpsSshHostKeys.update_all_vps
end

when 'os-release'
if @vps_ids&.any?
NodeCtld::VpsOsRelease.update_vps_ids(@vps_ids)
else
NodeCtld::VpsOsRelease.update_all_vps
end

else
raise NodeCtld::SystemCommandFailed.new(nil, nil, "Unknown command #{@command}")
end

ok
end
end
end
50 changes: 49 additions & 1 deletion libnodectld/lib/nodectld/vps_os_release.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ module NodeCtld
class VpsOsRelease
include Singleton
include OsCtl::Lib::Utils::Log
include OsCtl::Lib::Utils::System
include Utils::OsCtl

OPTIONS = %w[
# General
Expand All @@ -31,7 +33,7 @@ class VpsOsRelease
].freeze

class << self
%i[update_ct].each do |v|
%i[update_ct update_vps_ids update_all_vps].each do |v|
define_method(v) do |*args, **kwargs, &block|
instance.send(v, *args, **kwargs, &block)
end
Expand Down Expand Up @@ -80,6 +82,52 @@ def update_ct(ct)
content_type: 'application/json',
routing_key: 'vps_os_releases'
)

nil
end

# @param vps_ids [Array(Integer)]
def update_vps_ids(vps_ids)
return if !enable? || vps_ids.empty?

osctl_parse(%i[ct ls], vps_ids, { state: 'running' }).each do |ct|
osctl_ct = OsCtlContainer.new(ct)

# While ct ls returns only the selected containers, let's be sure
next unless vps_ids.include?(osctl_ct.vps_id)

update_ct(osctl_ct)
sleep($CFG.get(:vps_os_release, :update_vps_delay))
end

nil
end

def update_all_vps
return unless enable?

vps_ids = {}

RpcClient.run do |rpc|
rpc.list_running_vps_ids.each do |vps_id|
vps_ids[vps_id] = true
end
end

log(:info, "Updating os-release of #{vps_ids.length} VPS")

osctl_parse(%i[ct ls], vps_ids.keys, { state: 'running' }).each do |ct|
next unless /^\d+$/ =~ ct[:id]

osctl_ct = OsCtlContainer.new(ct)

next unless vps_ids.has_key?(osctl_ct.vps_id)

update_ct(osctl_ct)
sleep($CFG.get(:vps_os_release, :update_vps_delay))
end

nil
end

def enable?
Expand Down
29 changes: 27 additions & 2 deletions libnodectld/lib/nodectld/vps_ssh_host_keys.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class VpsSshHostKeys
include Utils::OsCtl

class << self
%i[update_ct].each do |v|
%i[update_ct update_vps_ids update_all_vps].each do |v|
define_method(v) do |*args, **kwargs, &block|
instance.send(v, *args, **kwargs, &block)
end
Expand All @@ -25,6 +25,7 @@ def initialize
@update_vps_queue = OsCtl::Lib::Queue.new
@update_vps_thread = Thread.new { update_vps_worker }

@update_all_queue = OsCtl::Lib::Queue.new
@update_all_thread = Thread.new { update_all_worker }
end

Expand All @@ -33,6 +34,30 @@ def update_ct(ct)
return unless enable?

@update_vps_queue.insert(ct)
nil
end

# @param vps_ids [Array(Integer)]
def update_vps_ids(vps_ids)
return if !enable? || vps_ids.empty?

osctl_parse(%i[ct ls], vps_ids, { state: 'running' }).each do |ct|
osctl_ct = OsCtlContainer.new(ct)

# While ct ls returns only the selected containers, let's be sure
next unless vps_ids.include?(osctl_ct.vps_id)

@update_vps_queue << osctl_ct
end

nil
end

def update_all_vps
return unless enable?

@update_all_queue << :update
nil
end

def enable?
Expand All @@ -57,7 +82,7 @@ def update_vps_worker

def update_all_worker
loop do
sleep($CFG.get(:vps_ssh_host_keys, :update_all_interval))
@update_all_queue.pop(timeout: $CFG.get(:vps_ssh_host_keys, :update_all_interval))

vps_ids = {}

Expand Down
33 changes: 33 additions & 0 deletions nodectl/lib/nodectl/commands/update.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module NodeCtl
class Commands::Update < Command::Remote
cmd :update
args '<command>'
description 'Update information about VPS'

def options(parser, _args)
parser.separator <<~END
Subcommands:
ssh-host-keys [vps...] Update SSH host keys
os-release [vps...] Update OS template info by reading /etc/os-release
END
end

def validate
if args.empty?
raise ValidationError, 'missing subcommand'
elsif !%w[ssh-host-keys os-release].include?(args[0])
raise ValidationError, "invalid subcommand '#{args[0]}'"
end

params.update(
command: args[0],
vps_ids: args[1..].map(&:to_i).select { |v| v > 0 }
)
end

def process
puts 'Update in progress'
end
end
end
7 changes: 7 additions & 0 deletions nodectl/man/man8/nodectl.8.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,13 @@ start it.

`nodectl` blocks until refresh is finished.

`update ssh-host-keys` [*vps...*]
Update SSH host keys from selected or all VPS and store them in vpsAdmin.

`update os-release` [*vps...*]
Read `/etc/os-release` in selected or all VPS and update OS template
in vpsAdmin if appropriate.

`incident-report pid` *pid...*
Report incident to VPS that the given PIDs belong to. `nodectl` identifies
the processes and opens `$EDITOR` with incident report content, which the user
Expand Down

0 comments on commit 9ea1b00

Please sign in to comment.