Merge pull request #113 from ClusterLabs/anvil-tools-dev

Anvil tools dev
main
digimer-bot 4 years ago committed by GitHub
commit 0aac9ead8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      Anvil/Tools.pm
  2. 10
      Anvil/Tools/Cluster.pm
  3. 47
      Anvil/Tools/Database.pm
  4. 22
      Anvil/Tools/Server.pm
  5. 53
      cgi-bin/striker
  6. 267
      ocf/alteeve/server
  7. 66
      scancore-agents/scan-server/scan-server
  8. 36
      tools/anvil-daemon
  9. 20
      tools/anvil-manage-keys
  10. 37
      tools/scancore

@ -1355,7 +1355,9 @@ sub catch_sig
$anvil->System->call({shell_call => $anvil->data->{path}{exe}{stty}." ".$anvil->data->{sys}{terminal}{stty}});
}
}
$anvil->nice_exit({exit_code => 255});
# Exit with '0' so shutdowns from systemd doesn't think we failed.
$anvil->nice_exit({exit_code => 0});
}

@ -3001,10 +3001,11 @@ sub parse_cib
}
else
{
# It's our peer.
# It's our peer. Note that we only get the peer's host UUID if we have a DB
# connection. This method is called by ocf:alteeve:anvil which skips the DB.
$anvil->data->{cib}{parsed}{peer}{ready} = $ready;
$anvil->data->{cib}{parsed}{peer}{name} = $node_name;
$anvil->data->{cib}{parsed}{peer}{host_uuid} = $anvil->Get->host_uuid_from_name({debug => $debug, host_name => $node_name});
$anvil->data->{cib}{parsed}{peer}{host_uuid} = $anvil->data->{sys}{database}{connections} ? $anvil->Get->host_uuid_from_name({debug => $debug, host_name => $node_name}) : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"cib::parsed::peer::ready" => $anvil->data->{cib}{parsed}{peer}{ready},
"cib::parsed::peer::name" => $anvil->data->{cib}{parsed}{peer}{name},
@ -3183,8 +3184,9 @@ sub parse_cib
# Stopping
$status = $active ? "running" : "off";
# If the role is NOT 'migating', check to see if it's marked as such in the database.
if ($role ne "migrating")
# If the role is NOT 'migrating', and we have a database connection, check to see if
# it's marked as such in the database.
if (($role ne "migrating") && ($anvil->data->{sys}{database}{connections}))
{
$anvil->Database->get_servers({debug => $debug});
my $anvil_uuid = $anvil->Cluster->get_anvil_uuid({debug => $debug});

@ -1732,15 +1732,6 @@ sub connect
# }
}
if ($sensitive)
{
# Return here.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"sys::database::connections" => $anvil->data->{sys}{database}{connections},
}});
return($anvil->data->{sys}{database}{connections});
}
# Make sure my host UUID is valod
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { "sys::host_uuid" => $anvil->data->{sys}{host_uuid} }});
if ($anvil->data->{sys}{host_uuid} !~ /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/)
@ -1752,23 +1743,33 @@ sub connect
$anvil->Database->disconnect({debug => $debug});
}
# If this is a time sensitive call, end here.
if ($sensitive)
{
# Return here.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::database::connections" => $anvil->data->{sys}{database}{connections},
}});
return($anvil->data->{sys}{database}{connections});
}
# If we have a previous count and the new count is higher, resync.
if (exists $anvil->data->{sys}{database}{last_db_count})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::database::last_db_count" => $anvil->data->{sys}{database}{last_db_count},
"sys::database::connections" => $anvil->data->{sys}{database}{connections},
}});
if ($anvil->data->{sys}{database}{connections} > $anvil->data->{sys}{database}{last_db_count})
{
$check_for_resync = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { check_for_resync => $check_for_resync }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { check_for_resync => $check_for_resync }});
}
}
# If we have a "last_db_count" and it's the lower than the current number of connections, check for a
# resync.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::database::connections" => $anvil->data->{sys}{database}{connections},
check_for_resync => $check_for_resync,
}});
@ -1787,11 +1788,11 @@ sub connect
# Hold if a lock has been requested.
$anvil->Database->locking({debug => $debug});
# Mark that we're not active.
# Mark that we're now active.
$anvil->Database->mark_active({debug => $debug, set => 1});
# Sync the database, if needed.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"sys::database::resync_needed" => $anvil->data->{sys}{database}{resync_needed},
check_for_resync => $check_for_resync,
}});
@ -1832,8 +1833,8 @@ sub disconnect
# Clear locks and mark that we're done running.
if (not $marked_inactive)
{
$anvil->Database->mark_active({set => 0});
$anvil->Database->locking({release => 1});
$anvil->Database->mark_active({debug => $debug, set => 0});
$anvil->Database->locking({debug => $debug, release => 1});
$marked_inactive = 1;
}
@ -1846,7 +1847,7 @@ sub disconnect
delete $anvil->data->{sys}{database}{timestamp};
delete $anvil->data->{sys}{database}{read_uuid};
delete $anvil->data->{sys}{database}{identifier};
$anvil->Database->read({set => "delete"});
$anvil->Database->read({debug => $debug, set => "delete"});
# Delete any database information (reconnects should re-read anvil.conf anyway).
delete $anvil->data->{database};
@ -15161,7 +15162,7 @@ sub resync_databases
# Add the host column.
$query = "INSERT INTO public.$table ($host_column, $uuid_column, ".$columns."modified_date) VALUES (".$anvil->Database->quote($anvil->data->{sys}{host_uuid}).", ".$anvil->Database->quote($row_uuid).", ".$values.$anvil->Database->quote($modified_date)."::timestamp AT TIME ZONE 'UTC');";
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0460", variables => { uuid => $anvil->data->{database}{$uuid}{host}, query => $query }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0460", variables => { uuid => $anvil->data->{database}{$uuid}{host}, query => $query }});
### NOTE: After an archive operationg, a record can
### end up in the public schema while nothing
@ -15185,14 +15186,14 @@ sub resync_databases
query => $query,
}});
$query =~ s/INSERT INTO public./INSERT INTO history./;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
push @{$anvil->data->{db_resync}{$uuid}{history}{sql}}, $query;
}
else
{
# No problem, record the query in the array
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
push @{$anvil->data->{db_resync}{$uuid}{public}{sql}}, $query;
}
} # if not exists
@ -15240,7 +15241,7 @@ sub resync_databases
# Add the host column.
$query = "INSERT INTO history.$table ($host_column, $uuid_column, ".$columns."modified_date) VALUES (".$anvil->Database->quote($anvil->data->{sys}{host_uuid}).", ".$anvil->Database->quote($row_uuid).", ".$values.$anvil->Database->quote($modified_date)."::timestamp AT TIME ZONE 'UTC');";
}
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0460", variables => { uuid => $anvil->data->{database}{$uuid}{host}, query => $query }});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0460", variables => { uuid => $anvil->data->{database}{$uuid}{host}, query => $query }});
# Now record the query in the array
push @{$anvil->data->{db_resync}{$uuid}{history}{sql}}, $query;
@ -16519,7 +16520,7 @@ ORDER BY
# {
# # Resync needed.
# my $difference = $anvil->data->{sys}{database}{table}{$table}{last_updated} - $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{last_updated};
# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
# $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
# "s1:difference" => $anvil->Convert->add_commas({number => $difference }),
# "s2:sys::database::table::${table}::last_updated" => $anvil->data->{sys}{database}{table}{$table}{last_updated},
# "s3:sys::database::table::${table}::uuid::${uuid}::last_updated" => $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{last_updated},
@ -16540,7 +16541,7 @@ ORDER BY
{
# Resync needed.
my $difference = ($anvil->data->{sys}{database}{table}{$table}{row_count} - $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{row_count});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"s1:difference" => $anvil->Convert->add_commas({number => $difference }),
"s2:sys::database::table::${table}::row_count" => $anvil->data->{sys}{database}{table}{$table}{row_count},
"s3:sys::database::table::${table}::uuid::${uuid}::row_count" => $anvil->data->{sys}{database}{table}{$table}{uuid}{$uuid}{row_count},

@ -983,8 +983,8 @@ sub migrate_virsh
});
}
### NOTE: This method is called by ocf:alteeve:server, which is allowed to operate without database
### access. As such, queries need to be run only if we've got one or more DB connections.
### NOTE: This method is called by ocf:alteeve:server, which operates without database access. As
### such, queries need to be run only if we've got one or more DB connections.
# Mark this server as being in a migration state.
if ($anvil->data->{sys}{database}{connections})
{
@ -1113,6 +1113,9 @@ WHERE
$success = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { success => $success }});
# Update the server state, if we have a database connection.
if ($anvil->data->{sys}{database}{connections})
{
# Revert the server state and update the server host.
my $server_host_uuid = $anvil->Get->host_uuid_from_name({debug => $debug, host_name => $target});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { server_host_uuid => $server_host_uuid }});
@ -1123,7 +1126,7 @@ WHERE
$server_host_uuid = $anvil->data->{servers}{server_uuid}{$server_uuid}{server_host_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { server_host_uuid => $server_host_uuid }});
}
if (($server_uuid) && ($anvil->data->{sys}{database}{connections}))
if ($server_uuid)
{
my $query = "
UPDATE
@ -1172,6 +1175,19 @@ WHERE
});
}
}
else
{
# There's no database, so write the migration time to a temp file.
my $body = "server_name=".$server.",migration_took=".$migration_took."\n";
my $file = "/tmp/anvil/migration-duration.".$server.".".time;
my ($failed) = $anvil->Storage->write_file({
file => $file,
body => $body,
mode => "0666",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { failed => $failed }});
}
}
# Switch off dual-primary.
foreach my $resource (sort {$a cmp $b} keys %{$anvil->data->{server}{$target}{$server}{resource}})

@ -1282,13 +1282,13 @@ sub process_keys
{
my ($anvil) = @_;
### NOTE: This doesn't update Striker (the Alteeve) stack yet, just the base OK.
### NOTE: This doesn't update Striker (the Alteeve) stack yet, just the base OS.
my $show_list = 1;
$anvil->data->{cgi}{'delete'}{value} = "" if not defined $anvil->data->{cgi}{'delete'}{value};
if ($anvil->data->{cgi}{'delete'}{value})
{
# Record the job!
my $job_data = "";
my $job_data = {};
foreach my $key (sort {$a cmp $b} keys %{$anvil->data->{cgi}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { key => $key }});
@ -1296,34 +1296,63 @@ sub process_keys
{
my $state_uuid = $1;
$show_list = 0;
$job_data .= $state_uuid.",";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
state_uuid => $state_uuid,
show_list => $show_list,
job_data => $job_data,
}});
my $query = "SELECT state_host_uuid FROM states WHERE state_uuid = ".$anvil->Database->quote($state_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $host_uuid = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$host_uuid = "" if not defined $host_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_uuid => $host_uuid }});
next if not $host_uuid;
if (not exists $job_data->{$host_uuid})
{
$job_data->{$host_uuid} = "";
}
$job_data->{$host_uuid} .= $state_uuid.",";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"job_data->{$host_uuid}" => $job_data->{$host_uuid},
}});
}
}
$job_data =~ s/,$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_data => $job_data }});
if ($job_data)
my $show_template = 0;
foreach my $host_uuid (keys %{$job_data})
{
$job_data->{$host_uuid} =~ s/,$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"job_data->{$host_uuid}" => $job_data->{$host_uuid},
}});
if ($job_data->{$host_uuid})
{
$show_template = 1;
my ($job_uuid) = $anvil->Database->insert_or_update_jobs({
file => $THIS_FILE,
line => __LINE__,
job_command => $anvil->data->{path}{exe}{'anvil-manage-keys'}.$anvil->Log->switches,
job_data => $job_data,
job_data => $job_data->{$host_uuid},
job_name => "manage::broken_keys",
job_title => "job_0056",
job_description => "job_0057",
job_progress => 0,
job_host_uuid => $anvil->data->{sys}{host_uuid},
job_host_uuid => $host_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
show_template => $show_template,
job_uuid => $job_uuid,
}});
}
}
# We don't need to store anything as hidden variables, we'll read it back from the database
# later.
if ($show_template)
{
# We don't need to store anything as hidden variables, we'll read it back from the
# database later.
$anvil->data->{form}{body} = $anvil->Template->get({file => "striker.html", name => "job recorded", variables => {
title_id => "",
message_id => "",

@ -9,6 +9,10 @@
# cluster or on any configuration outside how the Anvil! m3 uses it. If you plan to adapt it to
# another purpose, let us know and we'll try to help.
#
# NOTE: This method, for the sake of speed and reliability, does not connect to the Anvil! database. If you
# do work on this RA, be sure that a check is made for database connections before SQL calls are made
# in module methods.
#
# Based on: https://github.com/ClusterLabs/resource-agents/blob/master/doc/dev-guides/ra-dev-guide.asc
#
# Error types from pacemaker's perspective;
@ -144,12 +148,22 @@ $anvil->data->{environment}{OCF_RESKEY_CRM_meta_stop_drbd_resources} = 0;
# use switches. Pick those up, if passed.
$anvil->data->{switches}{migrate_to} = ""; # Sets 'meta_migrate_target'
$anvil->data->{switches}{'migrate-to'} = "";
$anvil->data->{switches}{migrate_from} = ""; # Sets 'meta_migrate_source' When set without 'migrate_to', does a status check after migration
$anvil->data->{switches}{'migrate-from'} = "";
$anvil->data->{switches}{server} = ""; # Sets 'name'.
$anvil->data->{switches}{start} = "";
$anvil->data->{switches}{stop} = "";
$anvil->data->{switches}{monitor} = "";
$anvil->Get->switches();
if (($anvil->data->{switches}{'migrate-to'}) && not ($anvil->data->{switches}{migrate_to}))
{
$anvil->data->{switches}{migrate_to} = $anvil->data->{switches}{'migrate-to'};
}
if (($anvil->data->{switches}{'migrate-from'}) && not ($anvil->data->{switches}{migrate_from}))
{
$anvil->data->{switches}{migrate_from} = $anvil->data->{switches}{'migrate-from'};
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"switches::migrate_to" => $anvil->data->{switches}{migrate_to},
"switches::migrate_from" => $anvil->data->{switches}{migrate_from},
@ -159,16 +173,6 @@ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list
"switches::monitor" => $anvil->data->{switches}{monitor},
}});
# If we can connect to a database, we'll set/clear the 'migrating' flag during migrations. For timing reasons
# we don't let the RA do resyncs.
$anvil->Database->connect({sensitive => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
# No databases,
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, secure => 0, key => "warning_0073"});
}
if ($anvil->data->{switches}{stop_drbd_resources})
{
$anvil->data->{environment}{OCF_RESKEY_CRM_meta_migrate_source} = 1;
@ -177,190 +181,43 @@ if ($anvil->data->{switches}{stop_drbd_resources})
# Something for the logs
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 0, level => 2, key => "log_0298"});
=cut
Start:
environment::OCF_RESKEY_CRM_meta_migrate_source: []
environment::OCF_RESKEY_CRM_meta_migrate_target: []
environment::OCF_RESKEY_CRM_meta_name: [start]
environment::OCF_RESKEY_CRM_meta_on_fail: [block]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n01]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [1]
environment::OCF_RESKEY_CRM_meta_record_pending: []
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [300000]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::OCF_ROOT: [/usr/lib/ocf]
Monitor after start:
environment::OCF_RESKEY_CRM_meta_interval: [60000]
environment::OCF_RESKEY_CRM_meta_migrate_source: []
environment::OCF_RESKEY_CRM_meta_migrate_target: []
environment::OCF_RESKEY_CRM_meta_name: [monitor]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n01]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [1]
environment::OCF_RESKEY_CRM_meta_record_pending: []
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [20000]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::OCF_ROOT: [/usr/lib/ocf]
Monitor one minute later:
environment::OCF_RESKEY_CRM_meta_interval: [60000]
environment::OCF_RESKEY_CRM_meta_migrate_source: []
environment::OCF_RESKEY_CRM_meta_migrate_target: []
environment::OCF_RESKEY_CRM_meta_name: [monitor]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n01]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [1]
environment::OCF_RESKEY_CRM_meta_record_pending: []
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [20000]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::OCF_ROOT: [/usr/lib/ocf]
Migrate from an-a02n01 to an-a02n02
environment::OCF_RESKEY_CRM_meta_interval: [60000]
environment::OCF_RESKEY_CRM_meta_migrate_source: []
environment::OCF_RESKEY_CRM_meta_migrate_target: []
environment::OCF_RESKEY_CRM_meta_name: [monitor]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n01]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [1]
environment::OCF_RESKEY_CRM_meta_record_pending: []
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [20000]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::OCF_ROOT: [/usr/lib/ocf]
<2 seconds later>
environment::OCF_RESKEY_CRM_meta_migrate_source: [an-a02n01]
environment::OCF_RESKEY_CRM_meta_migrate_target: [an-a02n02]
environment::OCF_RESKEY_CRM_meta_name: [migrate_to]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n01]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [1]
environment::OCF_RESKEY_CRM_meta_record_pending: [true]
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [86400000]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::OCF_ROOT: [/usr/lib/ocf]
Post migration on an-a02n01
environment::OCF_RESKEY_CRM_meta_migrate_source: []
environment::OCF_RESKEY_CRM_meta_migrate_target: []
environment::OCF_RESKEY_CRM_meta_name: [stop]
environment::OCF_RESKEY_CRM_meta_on_fail: [block]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n01]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [1]
environment::OCF_RESKEY_CRM_meta_record_pending: []
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [86400000]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::PCMK_debug: [0]
Post migration on an-a02n02
environment::OCF_RESKEY_CRM_meta_migrate_source: [an-a02n01]
environment::OCF_RESKEY_CRM_meta_migrate_target: [an-a02n02]
environment::OCF_RESKEY_CRM_meta_name: [migrate_from]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n02]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [2]
environment::OCF_RESKEY_CRM_meta_record_pending: []
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [600000]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_PROVIDER: [alteeve]
environment::OCF_RESOURCE_TYPE: [server]
environment::OCF_ROOT: [/usr/lib/ocf]
environment::PCMK_debug: [0]
Checking server state after: [srv02-c8s-fujitsu] was migrated to this host.
environment::OCF_EXIT_REASON_PREFIX: [ocf-exit-reason:]
environment::OCF_RA_VERSION_MAJOR: [1]
environment::OCF_RA_VERSION_MINOR: [0]
environment::OCF_RESKEY_CRM_meta_interval: [60000]
environment::OCF_RESKEY_CRM_meta_migrate_source: []
environment::OCF_RESKEY_CRM_meta_migrate_target: []
environment::OCF_RESKEY_CRM_meta_name: [monitor]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n02]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [2]
environment::OCF_RESKEY_CRM_meta_record_pending: []
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [20000]
environment::OCF_RESKEY_crm_feature_set: [3.7.1]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_PROVIDER: [alteeve]
environment::OCF_RESOURCE_TYPE: [server]
environment::OCF_ROOT: [/usr/lib/ocf]
environment::PCMK_debug: [0]
Monitor on an-a02n02 after a minute
environment::OCF_EXIT_REASON_PREFIX: [ocf-exit-reason:]
environment::OCF_RA_VERSION_MAJOR: [1]
environment::OCF_RA_VERSION_MINOR: [0]
environment::OCF_RESKEY_CRM_meta_interval: [60000]
environment::OCF_RESKEY_CRM_meta_migrate_source: []
environment::OCF_RESKEY_CRM_meta_migrate_target: []
environment::OCF_RESKEY_CRM_meta_name: [monitor]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n02]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [2]
environment::OCF_RESKEY_CRM_meta_record_pending: []
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [20000]
environment::OCF_RESKEY_crm_feature_set: [3.7.1]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_PROVIDER: [alteeve]
environment::OCF_RESOURCE_TYPE: [server]
environment::OCF_ROOT: [/usr/lib/ocf]
environment::PCMK_debug: [0]
Stop server:
environment::OCF_EXIT_REASON_PREFIX: [ocf-exit-reason:]
environment::OCF_RA_VERSION_MAJOR: [1]
environment::OCF_RA_VERSION_MINOR: [0]
environment::OCF_RESKEY_CRM_meta_migrate_source: []
environment::OCF_RESKEY_CRM_meta_migrate_target: []
environment::OCF_RESKEY_CRM_meta_name: [stop]
environment::OCF_RESKEY_CRM_meta_on_fail: [block]
environment::OCF_RESKEY_CRM_meta_on_node: [an-a02n02]
environment::OCF_RESKEY_CRM_meta_on_node_uuid: [2]
environment::OCF_RESKEY_CRM_meta_record_pending: []
environment::OCF_RESKEY_CRM_meta_stop_drbd_resources: [0]
environment::OCF_RESKEY_CRM_meta_timeout: [86400000]
environment::OCF_RESKEY_crm_feature_set: [3.7.1]
environment::OCF_RESKEY_name: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_INSTANCE: [srv02-c8s-fujitsu]
environment::OCF_RESOURCE_PROVIDER: [alteeve]
environment::OCF_RESOURCE_TYPE: [server]
environment::OCF_ROOT: [/usr/lib/ocf]
environment::PCMK_debug: [0]
=cut Manual calls;
# Start a server;
/usr/lib/ocf/resource.d/alteeve/server -vv --log-secure --server <server_name> --start
# Stop a server
/usr/lib/ocf/resource.d/alteeve/server -vv --log-secure --server <server_name> --stop
# Monitor a server
/usr/lib/ocf/resource.d/alteeve/server -vv --log-secure --server <server_name> --monitor
# Migrate (run on current host)
/usr/lib/ocf/resource.d/alteeve/server -vv --log-secure --server <server_name> --migrate-to <target_node_name> --migrate-from <current_node_name>
=cut
foreach my $key (sort {$a cmp $b} keys %{$anvil->data->{environment}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
"environment::${key}" => $anvil->data->{environment}{$key},
}});
}
foreach my $key (sort {$a cmp $b} keys %{$anvil->data->{switches}})
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 1, list => {
"switches::${key}" => $anvil->data->{switches}{$key},
}});
}
# Set environment variables from switches, if otherwise not set.
if (($anvil->data->{switches}{server}) && (not $anvil->data->{environment}{OCF_RESKEY_name}))
{
$anvil->data->{environment}{OCF_RESKEY_name} = $anvil->data->{switches}{server};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"environment::OCF_RESKEY_name" => $anvil->data->{environment}{OCF_RESKEY_name},
}});
}
if (($anvil->data->{switches}{migrate_to}) && (not $anvil->data->{environment}{OCF_RESKEY_CRM_meta_migrate_target}))
{
$anvil->data->{environment}{OCF_RESKEY_CRM_meta_migrate_target} = $anvil->data->{switches}{migrate_to};
@ -376,13 +233,6 @@ if (($anvil->data->{switches}{migrate_from}) && (not $anvil->data->{environment}
"environment::OCF_RESKEY_CRM_meta_migrate_source" => $anvil->data->{environment}{OCF_RESKEY_CRM_meta_migrate_source},
}});
}
if (($anvil->data->{switches}{server}) && (not $anvil->data->{environment}{OCF_RESKEY_name}))
{
$anvil->data->{environment}{OCF_RESKEY_name} = $anvil->data->{switches}{server};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"environment::OCF_RESKEY_name" => $anvil->data->{environment}{OCF_RESKEY_name},
}});
}
# This is for debugging.
if (not $anvil->data->{switches}{monitor})
@ -486,7 +336,8 @@ sub check_daemons
{
my ($anvil, $task) = @_;
my $problem = $anvil->Cluster->parse_cib();
my $problem = $anvil->Cluster->parse_cib({debug => 3});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { problem => $problem }});
if ($problem)
{
# Pacemaker isn't running, or some other problem. Someone must have called this script
@ -498,7 +349,7 @@ sub check_daemons
# Is the peer running? We'll use this to know whether to try and start daemons on the peer.
my $peer_name = $anvil->data->{cib}{parsed}{peer}{name};
my $peer_ready = $anvil->data->{cib}{parsed}{peer}{ready};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
peer_name => $peer_name,
peer_ready => $peer_ready,
}});
@ -513,7 +364,7 @@ sub check_daemons
my $running_peer = 0;
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{systemctl}." status ".$daemon});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
output => $output,
return_code => $return_code,
}});
@ -522,7 +373,7 @@ sub check_daemons
# It is stopped, start it..
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0482", variables => { daemon => $daemon }});
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{systemctl}." start ".$daemon});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
output => $output,
return_code => $return_code,
}});
@ -532,7 +383,7 @@ sub check_daemons
until ($running)
{
my ($output, $return_code) = $anvil->System->call({shell_call => $anvil->data->{path}{exe}{systemctl}." status ".$daemon});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
output => $output,
return_code => $return_code,
}});
@ -588,7 +439,7 @@ sub check_daemons
target => $peer_name,
shell_call => $anvil->data->{path}{exe}{systemctl}." start ".$daemon,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
output => $output,
error => $error,
return_code => $return_code,
@ -602,7 +453,7 @@ sub check_daemons
target => $peer_name,
shell_call => $anvil->data->{path}{exe}{systemctl}." status ".$daemon,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
output => $output,
error => $error,
return_code => $return_code,
@ -847,6 +698,14 @@ sub start_server
my $server = $anvil->data->{environment}{OCF_RESKEY_name};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0303", variables => { server => $server }});
if ((not $anvil->data->{environment}{OCF_RESKEY_CRM_meta_on_node}) && ($anvil->data->{switches}{target}))
{
$anvil->data->{environment}{OCF_RESKEY_CRM_meta_on_node} = $anvil->data->{switches}{target};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
"environment::OCF_RESKEY_CRM_meta_on_node" => $anvil->data->{environment}{OCF_RESKEY_CRM_meta_on_node},
}});
}
# Make sure things are sane.
validate_all($anvil);
@ -1362,23 +1221,11 @@ pmsuspended - The domain has been suspended by guest power management, e.g. ente
$anvil->nice_exit({exit_code => 1});
}
### TODO: Write the migration duration to /tmp/anvil.migration.<server>.data and have 'anvil-migrate-server' read that in to update the DB.
# Migrate the server
sub migrate_server
{
my ($anvil) = @_;
### This requires a database
# If we can connect to a database, we'll set/clear the 'migrating' flag during migrations. For timing
# reasons we don't let the RA do resyncs.
# $anvil->Database->connect({sensitive => 1});
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
# if (not $anvil->data->{sys}{database}{connections})
# {
# # No databases, exit.
# $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, secure => 0, key => "error_0003"});
# return(1);
# }
### NOTE: For now, we're not going to block if the target is not UpToDate. There are times when a
### user might want to do this (ie: sync will be done soon and the need to evacuate the node

@ -85,6 +85,9 @@ if ($host_type eq "striker")
# This is more than data collection in most agents, as it actually handles the changes on the fly
collect_data($anvil);
# Look for migration times written out by ocf:alteeve:server.
record_migration_times($anvil);
# Mark that we ran.
$anvil->Database->insert_or_update_updated({updated_by => $THIS_FILE});
@ -94,6 +97,69 @@ $anvil->nice_exit({exit_code => 0});
# Functions #
#############################################################################################################
# Look for migration times written out by ocf:alteeve:server.
sub record_migration_times
{
my ($anvil) = @_;
my $directory = "/tmp/anvil";
if (-d $directory)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { directory => $directory }});
local(*DIRECTORY);
opendir(DIRECTORY, $directory);
while(my $file = readdir(DIRECTORY))
{
next if $file eq ".";
next if $file eq "..";
next if $file !~ /^migration-duration\./;
my $full_path = $directory."/".$file;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
file => $file,
full_path => $full_path,
}});
my $body = $anvil->Storage->read_file({file => $full_path});
$body =~ s/\n//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { body => $body }});
if ($body =~ /server_name=(.*?),migration_took=(.*?)$/)
{
my $server_name = $1;
my $migration_took = $2;
my $anvil_uuid = $anvil->Cluster->get_anvil_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
server_name => $server_name,
migration_took => $migration_took,
anvil_uuid => $anvil_uuid,
}});
my $server_uuid = $anvil->Get->server_uuid_from_name({
server_name => $server_name,
anvil_uuid => $anvil_uuid,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { server_uuid => $server_uuid }});
if (($server_uuid) && ($migration_took))
{
my ($variable_uuid) = $anvil->Database->insert_or_update_variables({
file => $THIS_FILE,
line => __LINE__,
variable_name => "server::migration_duration",
variable_value => $migration_took,
variable_default => "",
variable_description => "message_0236",
variable_section => "servers",
variable_source_uuid => $server_uuid,
variable_source_table => "servers",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
}
}
unlink $full_path;
}
}
return(0);
}
# This reads in all the data we can find about servers running locally. This is more than data collection in
# most agents, as it actually handles the changes on the fly.
sub collect_data

@ -946,6 +946,9 @@ AND
# Make sure /etc/hosts is updated.
$anvil->System->update_hosts();
# This handles weird bits for things like bug work-arounds.
handle_special_cases($anvil);
# Now look for jobs that have a job status of 'scancore_startup'
run_jobs($anvil, 1);
@ -963,6 +966,37 @@ AND
return(0);
}
# This handles weird bits for things like bug work-arounds.
sub handle_special_cases
{
my ($anvil) = @_;
# RHBZ #1961562 - https://bugzilla.redhat.com/show_bug.cgi?id=1961562#c16
my $host_type = $anvil->Get->host_type();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { host_type => $host_type }});
if ($host_type ne "striker")
{
# We're a node or DR host. We need to touch this file.
my $work_around_file = "/etc/qemu/firmware/50-edk2-ovmf-cc.json";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { work_around_file => $work_around_file }});
if (not -e $work_around_file)
{
$anvil->Storage->write_file({
debug => 2,
file => $work_around_file,
body => "",
overwrite => 0,
backup => 0,
mode => "0644",
user => "root",
group => "root",
});
}
}
return(0);
}
# Configure the local database, if needed.
sub prep_database
{
@ -1274,7 +1308,7 @@ sub run_jobs
backup => 0,
mode => "0644",
user => "apache",
group => "apache"
group => "apache",
});
return(0);

@ -41,8 +41,8 @@ $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list
'switches::job-uuid' => $anvil->data->{switches}{'job-uuid'},
}});
$anvil->Database->connect();
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 3, secure => 0, key => "log_0132"});
$anvil->Database->connect({check_for_resync => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, secure => 0, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
# No databases, update the job, sleep for a bit and then exit. The daemon will pick it up and try
@ -85,13 +85,25 @@ WHERE
state_uuid = ".$anvil->Database->quote($state_uuid)."
;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $results = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__});
# States aren't sync'ed, so we may need to check both/all DBs to find our data.
my $state_found = 0;
my $results = [];
foreach my $uuid (keys %{$anvil->data->{cache}{database_handle}})
{
$results = $anvil->Database->query({uuid => $uuid, query => $query, source => $THIS_FILE, line => __LINE__});
my $count = @{$results};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
results => $results,
count => $count,
}});
if (not $count)
if ($count)
{
$state_found = 1;
last;
}
}
if (not $state_found)
{
# No bad keys found on this host.
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 0, priority => "err", key => "error_0078"});

@ -229,7 +229,7 @@ sub prepare_for_run
$anvil->Storage->read_config();
$anvil->Get->switches();
$anvil->Words->read();
$anvil->Database->connect();
$anvil->Database->connect({check_for_resync => 1});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0132"});
# See if the mail server needs to be updated.
@ -243,7 +243,9 @@ sub wait_for_database
{
my ($anvil) = @_;
$anvil->Database->connect({check_for_resync => 1});
# Don't check for resync here as we may need to load agent schemas. We'll check for resync in the
# main loop.
$anvil->Database->connect({check_for_resync => 0});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0132"});
if (not $anvil->data->{sys}{database}{connections})
{
@ -259,7 +261,7 @@ sub wait_for_database
$anvil->_set_paths();
$anvil->_set_defaults();
$anvil->Storage->read_config();
$anvil->Database->connect({check_for_resync => 1});
$anvil->Database->connect({check_for_resync => 0});
if ($anvil->data->{sys}{database}{connections})
{
# We're good
@ -323,6 +325,35 @@ sub startup_tasks
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "log_0572"});
# Make sure all agents schemas are loaded so that resyncs where a table on one DB doesn't exist on
# another, causing a fault.
$anvil->ScanCore->_scan_directory({directory => $anvil->data->{path}{directories}{scan_agents}});
foreach my $scan_agent (sort {$a cmp $b} keys %{$anvil->data->{scancore}{agent}})
{
my $schema_file = $anvil->data->{path}{directories}{scan_agents}."/".$scan_agent."/".$scan_agent.".sql";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
scan_agent => $scan_agent,
schema_file => $schema_file,
}});
if (-e $schema_file)
{
my $tables = $anvil->Database->get_tables_from_schema({debug => 3, schema_file => $schema_file});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { tables => $tables }});
my $table_count = @{$tables};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { table_count => $table_count }});
# It's possible that some agents don't have a database (or use core database tables only)
if (@{$tables} > 0)
{
$anvil->Database->check_agent_data({
agent => $scan_agent,
tables => $tables,
});
}
}
}
# Update our status
$anvil->Database->get_hosts({debug => 3});
my $host_uuid = $anvil->Get->host_uuid();

Loading…
Cancel
Save