From 98c7f8157a31381ed43bf78bcddad3aeccb1abbb Mon Sep 17 00:00:00 2001 From: Michal Opala Date: Thu, 6 Jun 2024 10:43:59 +0200 Subject: [PATCH] F #110: VR: Add "ready" OpenRC function to Keepalived --- appliances/VRouter/Failover/execute.rb | 13 +++++++++ appliances/VRouter/Keepalived/main.rb | 40 +++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/appliances/VRouter/Failover/execute.rb b/appliances/VRouter/Failover/execute.rb index da73913b..a81781dd 100644 --- a/appliances/VRouter/Failover/execute.rb +++ b/appliances/VRouter/Failover/execute.rb @@ -131,6 +131,19 @@ def up load_env + # Give keepalived 30 seconds to setup VIPs.. + 6.times do + bash 'rc-service keepalived ready', terminate: false + break + rescue RuntimeError + sleep 5 + end.then do |result| + unless result.nil? + msg :error, 'Keepalived not ready!' + return + end + end + SERVICES.each do |service, settings| enabled = env settings[:_ENABLED], settings[:fallback] diff --git a/appliances/VRouter/Keepalived/main.rb b/appliances/VRouter/Keepalived/main.rb index 5956d55c..a9a4d18e 100644 --- a/appliances/VRouter/Keepalived/main.rb +++ b/appliances/VRouter/Keepalived/main.rb @@ -51,10 +51,29 @@ def parse_env(default_vrid = ONEAPP_VNF_KEEPALIVED_VRID) end end - def install + def install(initdir: '/etc/init.d') msg :info, 'Keepalived::install' puts bash 'apk --no-cache add keepalived' + + script = File.open("#{initdir}/keepalived").each_with_object([]) do |line, acc| + if line =~ /^extra_started_commands="(.*)"$/ + acc << %{extra_started_commands="#{$1} ready"\n} + else + acc << line + end + end.join + + file "#{initdir}/keepalived", <<~SCRIPT, mode: 'u=rwx,go=rx', overwrite: true + #{script} + + ready() { + ebegin "Checking readiness" + source /run/one-context/one_env + /usr/bin/ruby -r #{__FILE__} -e Service::Keepalived.ready + eend $? + } + SCRIPT end def configure(basedir: '/etc/keepalived') @@ -173,5 +192,24 @@ def toggle(operations) def bootstrap msg :info, 'Keepalived::bootstrap' end + + def ready + detect_vips.each do |nic, vips| + vips = vips.values.map do |vip| + vip.split(%[/])[0] # remove the CIDR "prefixlen" if present + end + + addrs = ip_addr_show(nic)['addr_info']&.each_with_object([]) do |item, acc| + acc << item['local'] unless item['local'].nil? + end + + if (vips & addrs) != vips + msg :debug, { nic => { vips: vips, addrs: addrs, ready: false } } + exit 1 + end + end + + exit 0 + end end end