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

* Fixed a bug where, when DRBD->gather_data() calls 'drbdadm dump-xml…
This commit is contained in:
Digimer 2023-05-03 00:40:14 -04:00 committed by GitHub
commit dfc0c2c492
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 321 additions and 195 deletions

View File

@ -143,6 +143,9 @@ sub add_server
if (exists $anvil->data->{cib}{parsed}{cib}{resources}{primitive}{$server_name}{type})
{
# The server already exists
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"cib::parsed::cib::resources::primitive::${server_name}::type" => $anvil->data->{cib}{parsed}{cib}{resources}{primitive}{$server_name}{type},
}});
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", key => "error_0213", variables => { server_name => $server_name }});
return("!!error!!");
}

View File

@ -738,6 +738,24 @@ sub gather_data
local_short_host_name => $local_short_host_name,
}});
# Often, annoyingly, DRBD reports a message about usage before showing the XML. We need to detect and
# strip that off.
my $new_xml = "";
my $in_xml = 0;
foreach my $line (split/\n/, $xml)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line =~ /<config/)
{
$in_xml = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { in_xml => $in_xml }});
}
next if not $in_xml;
$new_xml .= $line."\n";
}
$xml = $new_xml;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { xml => $xml }});
local $@;
my $dom = eval { XML::LibXML->load_xml(string => $xml); };
if ($@)
@ -1903,6 +1921,75 @@ ORDER BY
}
else
{
# See if this minor is held by someone.
my $variable_name = "drbd::hold::minor::".$free_minor."::until";
my ($variable_value, $variable_uuid, undef) = $anvil->Database->read_variable({
debug => $debug,
variable_name => $variable_name,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:variable_name' => $variable_name,
's2:variable_value' => $variable_value,
's3:variable_uuid' => $variable_uuid,
}});
if (($variable_value) && ($variable_value !~ /^\d+$/))
{
# Bad value, clear it.
$variable_uuid = $anvil->Database->insert_or_update_variables({
debug => $debug,
variable_uuid => $variable_uuid,
variable_value => "0",
update_value_only => "",
});
$variable_value = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
variable_uuid => $variable_uuid,
variable_value => $variable_value
}});
}
if ($variable_uuid)
{
my $now_time = time;
my $age = $now_time - $variable_value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
age => $age,
now_time => $now_time,
}});
if (($variable_value) && ($now_time > $variable_value))
{
# This is being held, move on.
$free_minor++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { free_minor => $free_minor }});
next;
}
else
{
# Either the hold is stale or invalid, delete it.
$variable_uuid = $anvil->Database->insert_or_update_variables({
debug => $debug,
variable_uuid => $variable_uuid,
variable_value => "0",
update_value_only => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable_uuid => $variable_uuid }});
}
}
# To prevent race conditions, put a one minute hold on the minor number.
$variable_uuid = $anvil->Database->insert_or_update_variables({
debug => $debug,
variable_name => $variable_name,
variable_value => time+60,
variable_default => "0",
variable_description => "striker_0301",
variable_section => "hold",
variable_source_uuid => "NULL",
variable_source_table => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
$looking = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { looking => $looking }});
}
@ -1938,6 +2025,74 @@ ORDER BY
}
else
{
# See if this minor is held by someone.
my $variable_name = "drbd::hold::tcp_port::".$check_port."::until";
my ($variable_value, $variable_uuid, undef) = $anvil->Database->read_variable({
debug => $debug,
variable_name => $variable_name,
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:variable_name' => $variable_name,
's2:variable_value' => $variable_value,
's3:variable_uuid' => $variable_uuid,
}});
if (($variable_value) && ($variable_value !~ /^\d+$/))
{
# Bad value, clear it.
$variable_uuid = $anvil->Database->insert_or_update_variables({
debug => $debug,
variable_uuid => $variable_uuid,
variable_value => "0",
update_value_only => "",
});
$variable_value = 0;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
variable_uuid => $variable_uuid,
variable_value => $variable_value
}});
}
if ($variable_uuid)
{
my $now_time = time;
my $age = $now_time - $variable_value;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
age => $age,
now_time => $now_time }});
if (($variable_value) && ($now_time > $variable_value))
{
# This is being held, move on.
$check_port++;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { check_port => $check_port }});
next;
}
else
{
# Either the hold is stale or invalid, delete it.
$variable_uuid = $anvil->Database->insert_or_update_variables({
debug => $debug,
variable_uuid => $variable_uuid,
variable_value => "0",
update_value_only => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { variable_uuid => $variable_uuid }});
}
}
# To prevent a race condition, put a one minute hold on this port number.
$variable_uuid = $anvil->Database->insert_or_update_variables({
debug => $debug,
variable_name => $variable_name,
variable_value => time+60,
variable_default => "0",
variable_description => "striker_0301",
variable_section => "hold",
variable_source_uuid => "NULL",
variable_source_table => "",
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { variable_uuid => $variable_uuid }});
# This is a free port.
$free_ports .= $check_port.",";
$port_count++;
@ -1959,6 +2114,7 @@ ORDER BY
}
}
# Mark these ports as assigned.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
free_minor => $free_minor,
free_ports => $free_ports,

View File

@ -5900,7 +5900,6 @@ ORDER BY
my $storage_group_member_host_uuid = $row->[4];
my $storage_group_member_vg_uuid = $row->[5]; # This is the VG's internal UUID
my $storage_group_member_note = $row->[6]; # If this is 'DELETED', the link isn't used anymore
my $storage_group_member_host_name = $anvil->data->{hosts}{host_uuid}{$storage_group_member_host_uuid}{short_host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
storage_group_uuid => $storage_group_uuid,
storage_group_anvil_uuid => $storage_group_anvil_uuid,
@ -5909,6 +5908,14 @@ ORDER BY
storage_group_member_host_uuid => $storage_group_member_host_uuid,
storage_group_member_vg_uuid => $storage_group_member_vg_uuid,
storage_group_member_note => $storage_group_member_note,
}});
if (not exists $anvil->data->{hosts}{host_uuid}{$storage_group_member_host_uuid})
{
$anvil->Database->get_hosts({debug => $debug});
}
my $storage_group_member_host_name = $anvil->data->{hosts}{host_uuid}{$storage_group_member_host_uuid}{short_host_name};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
storage_group_member_host_name => $storage_group_member_host_name,
}});

View File

@ -514,23 +514,18 @@ sub available_resources
# Load hosts and network bridges. This loads Anvil! data as well
$anvil->Database->get_hosts({debug => $debug});
$anvil->Database->get_bridges({debug => $debug});
$anvil->Database->get_lvm_data({debug => $debug});
# Get the details.
my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
anvil_name => $anvil_name,
node1_host_uuid => $node1_host_uuid,
node2_host_uuid => $node2_host_uuid,
's1:anvil_name' => $anvil_name,
's2:node1_host_uuid' => $node1_host_uuid,
's3:node2_host_uuid' => $node2_host_uuid,
}});
# This both loads storage group data and assembles ungrouped VGs into storage groups, when possible.
$anvil->Cluster->assemble_storage_groups({
debug => $debug,
anvil_uuid => $anvil_uuid,
});
# This will store the available resources based on the least of the nodes.
$anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{cores} = 0;
$anvil->data->{anvil_resources}{$anvil_uuid}{cpu}{threads} = 0;
@ -601,7 +596,7 @@ WHERE
scan_hardware_cpu_cores => $scan_hardware_cpu_cores,
scan_hardware_cpu_threads => $scan_hardware_cpu_threads,
scan_hardware_cpu_model => $scan_hardware_cpu_model,
scan_hardware_ram_total => $scan_hardware_ram_total,
scan_hardware_ram_total => $scan_hardware_ram_total." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $scan_hardware_ram_total}).")",
}});
$anvil->data->{anvil_resources}{$anvil_uuid}{host_uuid}{$host_uuid}{cpu}{cores} = $scan_hardware_cpu_cores;
@ -663,7 +658,9 @@ SELECT
FROM
servers
WHERE
server_anvil_uuid = ".$anvil->Database->quote($anvil_uuid)."
server_anvil_uuid = ".$anvil->Database->quote($anvil_uuid)."
AND
server_state != 'DELETED'
ORDER BY
server_name ASC;";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { query => $query }});
@ -693,9 +690,13 @@ ORDER BY
if (not exists $anvil->data->{anvil_resources}{ram}{reserved})
{
$anvil->data->{anvil_resources}{ram}{reserved} = $default_reserved;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
default_reserved => $default_reserved,
"anvil_resources::ram::reserved" => $anvil->data->{anvil_resources}{ram}{reserved},
}});
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
"anvil_resources::ram::reserved" => $anvil->data->{anvil_resources}{ram}{reserved}." (".$anvil->Convert->bytes_to_human_readable({'bytes' => $anvil->data->{anvil_resources}{ram}{reserved}}).")",
"anvil_resources::ram::reserved" => $anvil->data->{anvil_resources}{ram}{reserved},
}});
$anvil->data->{anvil_resources}{ram}{reserved} =~ s/,//g;

124
notes
View File

@ -14,9 +14,19 @@ Create "Node status" which returns "degraded" if the peer is gone
Common queries;
* SELECT a.job_uuid, b.host_name, a.job_command, a.job_data, a.job_progress, a.job_status FROM jobs a, hosts b WHERE a.job_host_uuid = b.host_uuid AND a.job_progress != 100;
* SELECT a.host_name, b.file_name, c.file_location_active FROM hosts a, files b, file_locations c WHERE a.host_uuid = c.file_location_host_uuid AND b.file_uuid = c.file_location_file_uuid ORDER BY b.file_name ASC, a.host_name ASC;
* SELECT a.dr_link_uuid, b.host_name, c.anvil_name, a.dr_link_note FROM dr_links a, hosts b, anvils c WHERE a.dr_link_host_uuid = b.host_uuid AND a.dr_link_anvil_uuid = c.anvil_uuid ORDER BY c.anvil_name ASC, b.host_name ASC;
* SELECT a.storage_group_uuid, d.storage_group_member_uuid, b.anvil_name, a.storage_group_name, c.host_name, d.storage_group_member_vg_uuid, d.storage_group_member_note FROM storage_groups a, anvils b, hosts c, storage_group_members d WHERE a.storage_group_uuid = d.storage_group_member_storage_group_uuid AND a.storage_group_anvil_uuid = b.anvil_uuid AND c.host_uuid = d.storage_group_member_host_uuid ORDER BY a.storage_group_name ASC, c.host_name ASC;
* SELECT a.scan_hardware_uuid, b.host_name, a.scan_hardware_cpu_cores AS cores, a.scan_hardware_cpu_threads AS threads, pg_size_pretty(a.scan_hardware_ram_total) AS ram_total, pg_size_pretty(a.scan_hardware_memory_total) AS memory_total, pg_size_pretty(a.scan_hardware_memory_free) AS memory_free FROM scan_hardware a, hosts b WHERE a.scan_hardware_host_uuid = b.host_uuid ORDER BY b.host_name ASC;
* SELECT a.scan_apc_ups_name AS name, a.scan_apc_ups_serial_number AS sn, a.scan_apc_ups_health AS health, a.scan_apc_ups_nmc_serial_number AS nmc_sn, a.scan_apc_ups_nmc_mac_address AS mac, a.scan_apc_ups_ip AS ip, b._percentage_charge AS charge, d.scan_apc_ups_battery_temperature AS btemp FROM scan_apc_upses a, scan_apc_ups_input b, scan_apc_ups_output c, scan_apc_ups_batteries d WHERE a.scan_apc_ups_uuid = b.scan_apc_ups_input_scan_apc_ups_uuid AND a.scan_apc_ups_uuid = c.scan_apc_ups_output_scan_apc_ups_uuid AND a.scan_apc_ups_uuid = d.scan_apc_ups_battery_scan_apc_ups_uuid ORDER BY name ASC;
* SELECT b.host_name, a.network_interface_uuid, a.network_interface_mac_address AS mac, a.network_interface_name AS name, a.network_interface_speed AS speed, a.network_interface_link_state AS link, a.network_interface_operational AS op, a.network_interface_duplex AS duplex, a.network_interface_medium AS medium, a.network_interface_bond_uuid AS bond_uuid, a.network_interface_bridge_uuid AS bridge_uuid FROM network_interfaces a, hosts b WHERE a.network_interface_host_uuid = b.host_uuid AND b.host_name LIKE 'an-a02%' AND a.network_interface_operational != 'DELETED' ORDER BY b.host_name ASC, a.network_interface_name ASC;
* SELECT b.host_name, a.bond_uuid, a.bond_name, a.bond_mode, a.bond_mtu AS mtu, a.bond_primary_interface AS primary, a.bond_active_interface AS active, a.bond_mac_address AS mac, a.bond_operational AS op, c.bridge_name, a.modified_date FROM bonds a, hosts b, bridges c WHERE a.bond_host_uuid = b.host_uuid AND a.bond_bridge_uuid = c.bridge_uuid AND (b.host_uuid = 'b4e46faf-0ebe-e211-a0d6-00262d0ca874' OR b.host_uuid = '4ba42b4e-9bf7-e311-a889-899427029de4') ORDER BY b.host_name ASC, a.bond_name ASC;
* SELECT b.host_name, a.bridge_uuid, a.bridge_name, a.bridge_id, a.bridge_mtu FROM bridges a, hosts b WHERE a.bridge_host_uuid = b.host_uuid AND b.host_name LIKE 'an-a02%' ORDER BY b.host_name ASC, a.bridge_name ASC;
* SELECT a.host_name, b.file_name, c.file_location_active FROM hosts a, files b, file_locations c WHERE a.host_uuid = c.file_location_host_uuid AND b.file_uuid = c.file_location_file_uuid ORDER BY b.file_name ASC, a.host_name ASC;
* SELECT b.host_name, a.health_agent_name, a.health_source_name, a.health_source_weight FROM health a, hosts b WHERE b.host_uuid = a.health_host_uuid AND b.host_name LIKE 'an-a02%' order by b.host_name ASC, a.health_agent_name ASC, a.health_source_weight ASC;
for lv in $(lvscan | grep deploy| awk '{print $2}' | sed s/\'//g); do lvremove -y $lv; done; rm -f /etc/drbd.d/an-test-deploy*; lvscan; ls -lah /etc/drbd.d/
# Fail a resource for testing purposes.
@ -25,14 +35,11 @@ crm_resource --fail --resource srv02-b -N vm-a01n01
# Recover without reboot
crm_resource --resource srv01-a --refresh
uname -r; grubby --default-kernel; lsinitrd -m /boot/initramfs-4.18.0-448.el8.x86_64.img | grep lvm; systemctl is-enabled scancore.service;
dnf -y update; systemctl disable --now anvil-daemon; systemctl disable --now scancore
When pairing Striker, make sure new config goes to all known nodes!
dnf -y update && dnf -y install https://www.alteeve.com/an-repo/m3/anvil-release-latest.noarch.rpm && alteeve-repo-setup -y && dnf -y install anvil-striker --allowerasing
dnf -y update && dnf -y install https://www.alteeve.com/an-repo/m3/anvil-release-latest.noarch.rpm && alteeve-repo-setup -y && dnf -y install anvil-node --allowerasing
dnf -y update && dnf -y install https://www.alteeve.com/an-repo/m3/anvil-release-latest.noarch.rpm && alteeve-repo-setup -y && dnf -y install anvil-dr --allowerasing
@ -56,7 +63,6 @@ firewall-cmd --permanent --zone=IFN1 --add-port=22869/tcp
firewall-cmd --reload
# Configure APC PDUs and UPSes
tcpip -i 10.201.2.3 -s 255.255.0.0 -g 10.201.255.254
web -h enable
@ -71,7 +77,6 @@ snmp -S enable -c2 public -a2 writeplus
watch 'echo "striker 1"; ssh root@an-striker01 "grep ^database /etc/anvil/anvil.conf | grep host"; echo "striker 2"; ssh root@an-striker02 "grep ^database /etc/anvil/anvil.conf | grep host"; echo "node 1"; ssh root@an-a01n01 "grep ^database /etc/anvil/anvil.conf | grep host"; echo "node 2"; ssh root@an-a01n02 "grep ^database /etc/anvil/anvil.conf | grep host"; echo "dr 1"; ssh root@an-a01dr01 "grep ^database /etc/anvil/anvil.conf | grep host";'
Anvil! to Anvil! live migration;
1. Create LVs
2. Make sure /etc/hosts is populated
@ -91,13 +96,6 @@ Deleting Resource - srv01-cs8
10.
TODO:
- Remove this; (step 2) "This is the user name that you will log into Striker as and the name of the user that owns the database"
- Being set to the gateway, not the default DNS - "This is the domain name server(s) to use when resolving domain names. You can specify 2 or more, separated by commas."
- The web UI password isn't being set properly during Striker stage-2 setup
- Changing the password doesn't log out active webui sessions.
- host_health is a duplicate of 'health'
============
# Dump
@ -107,13 +105,9 @@ su - postgres -c "pg_dump --schema-only anvil > /var/lib/pgsql/anvil_schema.out"
su - postgres -c "dropdb anvil" && su - postgres -c "createdb --owner admin anvil" && su - postgres -c "psql anvil < /var/lib/pgsql/anvil.out"
su postgres -c "psql anvil"
SELECT a.scan_apc_ups_name AS name, a.scan_apc_ups_serial_number AS sn, a.scan_apc_ups_health AS health, a.scan_apc_ups_nmc_serial_number AS nmc_sn, a.scan_apc_ups_nmc_mac_address AS mac, a.scan_apc_ups_ip AS ip, b._percentage_charge AS charge, d.scan_apc_ups_battery_temperature AS btemp FROM scan_apc_upses a, scan_apc_ups_input b, scan_apc_ups_output c, scan_apc_ups_batteries d WHERE a.scan_apc_ups_uuid = b.scan_apc_ups_input_scan_apc_ups_uuid AND a.scan_apc_ups_uuid = c.scan_apc_ups_output_scan_apc_ups_uuid AND a.scan_apc_ups_uuid = d.scan_apc_ups_battery_scan_apc_ups_uuid ORDER BY name ASC;
============
dnf -y install augeas
Jenkins;
Initial setup:
@ -1072,8 +1066,8 @@ OS10# write memory
### Set hostname:
OS10# configure terminal
OS10(config)# hostname zo-switch02
zo-switch02(config)#
OS10(config)# hostname an-switch02
an-switch02(config)#
======] VLT Config [=======
@ -1107,7 +1101,7 @@ OS10# show vlt 1 mismatch
(If no issues, VLT is OK)
# See how I am and my role (* == switch you're on)
zo-switch02(config)# show vlt 1 role
an-switch02(config)# show vlt 1 role
VLT Unit ID Role
------------------------
* 1 secondary
@ -1122,31 +1116,31 @@ OS10(conf-if-ma-1/1/1)# ip address 10.201.1.2/16
OS10(conf-if-ma-1/1/1)# no shutdown
OS10(conf-if-ma-1/1/1)# exit
OS10(config)# write memory
OS10(config)# hostname zo-switch01
zo-switch01(config)# interface vlan 100
zo-switch01(conf-if-vl-100)# description BCN1
zo-switch01(config)# exit
zo-switch01(conf-if-vl-100)# interface range ethernet 1/1/1-1/1/14
zo-switch01(conf-range-eth1/1/1-1/1/10)# switchport access vlan 100
zo-switch01(conf-range-eth1/1/1-1/1/10)# no shutdown
zo-switch01(conf-range-eth1/1/1-1/1/10)# exit
OS10(config)# hostname an-switch01
an-switch01(config)# interface vlan 100
an-switch01(conf-if-vl-100)# description BCN1
an-switch01(config)# exit
an-switch01(conf-if-vl-100)# interface range ethernet 1/1/1-1/1/14
an-switch01(conf-range-eth1/1/1-1/1/10)# switchport access vlan 100
an-switch01(conf-range-eth1/1/1-1/1/10)# no shutdown
an-switch01(conf-range-eth1/1/1-1/1/10)# exit
zo-switch01(config)# interface vlan 200
zo-switch01(conf-if-vl-200)# description SN1
zo-switch01(conf-if-vl-200)# exit
zo-switch01(config)# interface range ethernet 1/1/11-1/1/14
zo-switch01(conf-range-eth1/1/11-1/1/14)# switchport access vlan 200
zo-switch01(conf-range-eth1/1/11-1/1/14)# no shutdown
zo-switch01(conf-range-eth1/1/11-1/1/14)# exit
an-switch01(config)# interface vlan 200
an-switch01(conf-if-vl-200)# description SN1
an-switch01(conf-if-vl-200)# exit
an-switch01(config)# interface range ethernet 1/1/11-1/1/14
an-switch01(conf-range-eth1/1/11-1/1/14)# switchport access vlan 200
an-switch01(conf-range-eth1/1/11-1/1/14)# no shutdown
an-switch01(conf-range-eth1/1/11-1/1/14)# exit
zo-switch01(config)# interface vlan 300
zo-switch01(conf-if-vl-300)# description IFN1
zo-switch01(conf-if-vl-300)# exit
zo-switch01(config)# interface range ethernet 1/1/15-1/1/24
zo-switch01(conf-range-eth1/1/15-1/1/24)# switchport access vlan 300
zo-switch01(conf-range-eth1/1/15-1/1/24)# no shutdown
zo-switch01(conf-range-eth1/1/15-1/1/24)# exit
zo-switch01(config)# show vlan
an-switch01(config)# interface vlan 300
an-switch01(conf-if-vl-300)# description IFN1
an-switch01(conf-if-vl-300)# exit
an-switch01(config)# interface range ethernet 1/1/15-1/1/24
an-switch01(conf-range-eth1/1/15-1/1/24)# switchport access vlan 300
an-switch01(conf-range-eth1/1/15-1/1/24)# no shutdown
an-switch01(conf-range-eth1/1/15-1/1/24)# exit
an-switch01(config)# show vlan
Codes: * - Default VLAN, M - Management VLAN, R - Remote Port Mirroring VLANs,
@ - Attached to Virtual Network, P - Primary, C - Community, I - Isolated
Q: A - Access (Untagged), T - Tagged
@ -1160,12 +1154,12 @@ Q: A - Access (Untagged), T - Tagged
300 Active IFN1 T Po1000
A Eth1/1/15-1/1/24
4094 Active T Po1000
zo-switch01(config)# write memory
an-switch01(config)# write memory
### Delete a VLAN:
zo-switch02(config)# no interface vlan 3400
zo-switch02(config)# show vlan
an-switch02(config)# no interface vlan 3400
an-switch02(config)# show vlan
=== Firmware Update ===
@ -1247,7 +1241,7 @@ reboot: machine restart
### NOTE: The login prompt will appear before the system is ready to log in. The default username and password revert to 'admin' / 'admin', but this won't work for the first couple of minutes.
## OLD
zo-switch02# show version
an-switch02# show version
Dell EMC Networking OS10 Enterprise
Copyright (c) 1999-2020 by Dell Inc. All Rights Reserved.
OS Version: 10.5.0.4
@ -1256,10 +1250,10 @@ Build Time: 2020-01-30T21:08:56+0000
System Type: S4128T-ON
Architecture: x86_64
Up Time: 22:49:57
zo-switch02#
an-switch02#
## New
zo-a01n01# show version
an-a01n01# show version
Dell EMC Networking OS10 Enterprise
Copyright (c) 1999-2021 by Dell Inc. All Rights Reserved.
OS Version: 10.5.2.3
@ -1535,13 +1529,13 @@ $body = $cgi->param('POSTDATA') # gives you the body of the request as a string,
ausearch -c 'drbdsetup' --raw | audit2allow -M my-drbdsetup && semodule -X 300 -i my-drbdsetup.pp
May 02 13:35:21 zo-a01n02.zennioptical.com setroubleshoot[5333]: SELinux is preventing /usr/sbin/drbdsetup from create access on the netlink_generic_socket labeled drbd_t. For complete SELinux messages run: sealert -l 4079c288-db4a-4f44-a588-94f1dbfff269
May 02 13:35:21 zo-a01n02.zennioptical.com setroubleshoot[5333]: SELinux is preventing /usr/sbin/drbdsetup from create access on the netlink_generic_socket labeled drbd_t.
May 02 13:35:21 an-a01n02.zennioptical.com setroubleshoot[5333]: SELinux is preventing /usr/sbin/drbdsetup from create access on the netlink_generic_socket labeled drbd_t. For complete SELinux messages run: sealert -l 4079c288-db4a-4f44-a588-94f1dbfff269
May 02 13:35:21 an-a01n02.zennioptical.com setroubleshoot[5333]: SELinux is preventing /usr/sbin/drbdsetup from create access on the netlink_generic_socket labeled drbd_t.
If you believe that drbdsetup should be allowed create access on netlink_generic_socket labeled drbd_t by default.
# ausearch -c 'drbdsetup' --raw | audit2allow -M my-drbdsetup
# semodule -X 300 -i my-drbdsetup.pp
If you believe that virsh should be allowed read access on the srv16-zo-psql-qa.xml file by default.
If you believe that virsh should be allowed read access on the srv16-an-psql-qa.xml file by default.
# ausearch -c 'virsh' --raw | audit2allow -M my-virsh
# semodule -X 300 -i my-virsh.pp
@ -1605,17 +1599,17 @@ Gi1/0/24 + Gi2/0/24
Dell LACP Config (OS10 - https://www.dell.com/support/kbdoc/en-us/000102901/dell-emc-networking-os10-how-to-set-up-virtual-link-trunking-vlt)
* On both switches;
zo-switch02# configure terminal
an-switch02# configure terminal
* IFN Port channel is 3
zo-switch02(config)# interface port-channel 3
zo-switch02(conf-if-po-3)# <165>1 2021-10-19T04:58:56.022086+00:00 zo-switch02 dn_alm 920 - - Node.1-Unit.1:PRI [event], Dell EMC (OS10) %IFM_ASTATE_UP: Interface admin state up :port-channel3
<165>1 2021-10-19T04:58:56.022722+00:00 zo-switch02 dn_alm 920 - - Node.1-Unit.1:PRI [event], Dell EMC (OS10) %IFM_OSTATE_DN: Interface operational state is down :port-channel3
zo-switch02(conf-if-po-3)# lacp fallback enable
zo-switch02(conf-if-po-3)# description IFN1
zo-switch02(conf-if-po-3)# exit
zo-switch02(config)# exit
zo-switch02# show port-channel summary
an-switch02(config)# interface port-channel 3
an-switch02(conf-if-po-3)# <165>1 2021-10-19T04:58:56.022086+00:00 an-switch02 dn_alm 920 - - Node.1-Unit.1:PRI [event], Dell EMC (OS10) %IFM_ASTATE_UP: Interface admin state up :port-channel3
<165>1 2021-10-19T04:58:56.022722+00:00 an-switch02 dn_alm 920 - - Node.1-Unit.1:PRI [event], Dell EMC (OS10) %IFM_OSTATE_DN: Interface operational state is down :port-channel3
an-switch02(conf-if-po-3)# lacp fallback enable
an-switch02(conf-if-po-3)# description IFN1
an-switch02(conf-if-po-3)# exit
an-switch02(config)# exit
an-switch02# show port-channel summary
Flags: D - Down I - member up but inactive P - member up and active
U - Up (port-channel) F - Fallback Activated
@ -1625,10 +1619,10 @@ Group Port-Channel Type Protocol Member Ports
3 port-channel3 (D) Eth STATIC
1000 port-channel1000 (U) Eth STATIC 1/1/25(P) 1/1/26(P)
zo-switch02# configure terminal
zo-switch02(config)# interface ethernet 1/1/24
zo-switch02(conf-if-eth1/1/24)# channel-group 3
zo-switch02(conf-if-eth1/1/24)# <165>1 2021-10-19T05:09:41.237808+00:00 zo-switch02 dn_alm 920 - - Node.1-Unit.1:PRI [event], Dell EMC (OS10) %IFM_OSTATE_UP: Interface operational state is up :port-channel3
an-switch02# configure terminal
an-switch02(config)# interface ethernet 1/1/24
an-switch02(conf-if-eth1/1/24)# channel-group 3
an-switch02(conf-if-eth1/1/24)# <165>1 2021-10-19T05:09:41.237808+00:00 an-switch02 dn_alm 920 - - Node.1-Unit.1:PRI [event], Dell EMC (OS10) %IFM_OSTATE_UP: Interface operational state is up :port-channel3
exit
exit

View File

@ -84,6 +84,9 @@ read_last_scan($anvil);
# Loog for changes
find_changes($anvil);
# Check storage for storage groups.
check_storage_groups($anvil);
# Shut down.
$anvil->ScanCore->agent_shutdown({agent => $THIS_FILE});
$anvil->nice_exit({exit_code => 0});
@ -93,6 +96,51 @@ $anvil->nice_exit({exit_code => 0});
# Functions #
#############################################################################################################
sub check_storage_groups
{
my ($anvil) = @_;
# Are we in an Anvil!? If so, are there any storage groups yet?
my $anvil_uuid = $anvil->Cluster->get_anvil_uuid();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { anvil_uuid => $anvil_uuid }});
if ($anvil_uuid)
{
# If we're node 1, we'll try to assemble the storage group. Onle node 1 does this to help avoid race
# conditions. This both loads storage group data and assembles ungrouped VGs into storage groups,
# when possible.
$anvil->Database->get_anvils();
my $host_uuid = $anvil->Get->host_uuid;
my $anvil_name = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_name};
my $node1_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node1_host_uuid};
my $node2_host_uuid = $anvil->data->{anvils}{anvil_uuid}{$anvil_uuid}{anvil_node2_host_uuid};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {
's1:anvil_name' => $anvil_name,
's2:node1_host_uuid' => $node1_host_uuid,
's3:node2_host_uuid' => $node2_host_uuid,
's4:host_uuid' => $host_uuid,
}});
if ($host_uuid eq $node1_host_uuid)
{
# Are there any storage groups yet? If not, try to assemble one.
my $query = "SELECT COUNT(*) FROM storage_groups WHERE storage_group_anvil_uuid = ".$anvil->Database->quote($anvil_uuid).";";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { query => $query }});
my $count = $anvil->Database->query({query => $query, source => $THIS_FILE, line => __LINE__})->[0]->[0];
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { count => $count }});
if (not $count)
{
$anvil->Cluster->assemble_storage_groups({
debug => 2,
anvil_uuid => $anvil_uuid,
});
}
}
}
return(0);
}
sub find_changes
{
my ($anvil) = @_;

View File

@ -2371,6 +2371,7 @@ The file: [#!variable!file!#] needs to be updated. The difference is:
<key name="log_0734">The DR host: [#!variable!host!#] as been linked to the Anvil! node: [#!variable!anvil!#].</key>
<key name="log_0735">The DR host: [#!variable!host!#] as been _unlinked_ to the Anvil! node: [#!variable!anvil!#].</key>
<key name="log_0736">The DR host: [#!variable!host!#] was not linked to the Anvil! node: [#!variable!anvil!#], nothing to do.</key>
<key name="log_0737">The job: [#!variable!command!#] (with job UUID: [#!variable!job_uuid!#]) is being skipped for now, already started a job (started job_uuid: [#!variable!started_job!#]) with this command on this loop.</key>
<!-- Messages for users (less technical than log entries), though sometimes used for logs, too. -->
<key name="message_0001">The host name: [#!variable!target!#] does not resolve to an IP address.</key>
@ -3213,6 +3214,7 @@ If you are comfortable that the target has changed for a known reason, you can s
<key name="striker_0298">TCP Port</key>
<key name="striker_0299">Migration Network link #!variable!number!#</key>
<key name="striker_0300">This is where you configure the optional network dedicated to RAM-copy during live migrations.</key>
<key name="striker_0301">This puts a temporary hold on a DRBD minor number or TCP port so that it isn't used again in the time between when it was queried as the next free number, and before it can be used.</key>
<!-- These are generally units and appended to numbers -->
<key name="suffix_0001">#!variable!number!#/sec</key>

View File

@ -43,14 +43,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
if ($anvil->data->{switches}{'job-uuid'})
{
# Load the job data.

View File

@ -1481,6 +1481,28 @@ sub run_jobs
updated_seconds_ago => $updated_seconds_ago,
}});
# To minimize the chance of race conditions, any given command will be called only once at a
# time. If two jobs of the same command exist, only one will be called.
if ($job_progress != 100)
{
my $short_command = $job_command;
$short_command =~ s/\s.*$//;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { short_command => $short_command }});
if (exists $anvil->data->{sys}{started}{$short_command})
{
# Skip it.
my $started_job = $anvil->data->{sys}{started}{$short_command};
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0737", variables => {
started_job => $started_job,
job_uuid => $job_uuid,
command => $short_command,
}});
next;
}
$anvil->data->{sys}{started}{$short_command} = $job_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "sys::started::${short_command}" => $anvil->data->{sys}{started}{$short_command} }});
}
# If this is a start-up call, only start jobs whose status is 'anvil_startup'.
if (($startup) && ($job_status ne "anvil_startup"))
{

View File

@ -54,14 +54,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->data->{sys}{anvil_uuid} = $anvil->Cluster->get_anvil_uuid();
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'sys::anvil_uuid' => $anvil->data->{sys}{anvil_uuid} }});
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({debug => 2, program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
# If we still don't have a job-uuit, go into interactive mode.
if ($anvil->data->{switches}{'job-uuid'})
{

View File

@ -105,19 +105,6 @@ sub get_job_details
{
my ($anvil) = @_;
# If I don't have a job-uuid, see if any jobs are pending
if (not $anvil->data->{switches}{'job-uuid'})
{
my $job_uuid = $anvil->Job->get_job_uuid({debug => 2, program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
if ($anvil->Validate->uuid({uuid => $job_uuid}))
{
# Got one!
$anvil->data->{switches}{'job-uuid'} = $job_uuid;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'switches::job-uuid' => $anvil->data->{switches}{'job-uuid'} }});
}
}
# If we've got a job-uuid, load the details.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { 'switches::job-uuid' => $anvil->data->{switches}{'job-uuid'} }});
if ($anvil->data->{switches}{'job-uuid'})

View File

@ -228,11 +228,6 @@ sub do_poweroff
$job_uuid = $anvil->data->{switches}{'job-uuid'};
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
}
else
{
$job_uuid = $anvil->Job->get_job_uuid({debug => 2, program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { job_uuid => $job_uuid }});
}
# Make sure the 'reboot needed' flag is set. When 'anvil-daemon' starts, it will use this to confirm
# that it is starting post-reboot and clear it.

View File

@ -52,14 +52,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
# If we still don't have a job-uuit, go into interactive mode.
if ($anvil->data->{switches}{'job-uuid'})
{

View File

@ -70,14 +70,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
$anvil->Database->get_hosts();
$anvil->Database->get_anvils();
$anvil->Database->get_servers();

View File

@ -32,6 +32,8 @@ if (($running_directory =~ /^\./) && ($ENV{PWD}))
$| = 1;
my $anvil = Anvil::Tools->new();
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
$anvil->Get->switches({list => [
"add",

View File

@ -59,14 +59,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
if ($anvil->data->{switches}{'job-uuid'})
{
# Load the job data.

View File

@ -31,6 +31,8 @@ if (($running_directory =~ /^\./) && ($ENV{PWD}))
$| = 1;
my $anvil = Anvil::Tools->new();
$anvil->Log->level({set => 2});
$anvil->Log->secure({set => 1});
# Read switches
$anvil->Get->switches({list => [
@ -66,14 +68,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
# If we still don't have a job-uuit, go into interactive mode.
if ($anvil->data->{switches}{'job-uuid'})
{
@ -354,7 +348,10 @@ sub add_server_to_cluster
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, key => "job_0207"});
# Is our peer in the cluster? For that matter, are we?
my $problem = $anvil->Cluster->add_server({server_name => $anvil->data->{job}{server_name}});
my $problem = $anvil->Cluster->add_server({
debug => 2,
server_name => $anvil->data->{job}{server_name},
});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { problem => $problem }});
if ($problem)
{

View File

@ -54,14 +54,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
# If we still don't have a job-uuit, go into interactive mode.
if ($anvil->data->{switches}{'job-uuid'})
{

View File

@ -74,14 +74,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
# If we still don't have a job-uuit, go into interactive mode.
if ($anvil->data->{switches}{'job-uuid'})
{

View File

@ -53,14 +53,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
if ($anvil->data->{switches}{'job-uuid'})
{
# Load the job data.

View File

@ -40,14 +40,6 @@ $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "
$anvil->Database->connect;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0132"});
# If we don't have a job-uuid, look for one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({debug => 2, program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
# If we have a job-uuid, process it.
if ($anvil->data->{switches}{'job-uuid'})
{

View File

@ -54,14 +54,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# Did we get called with a job UUID? If not, try to find a pending job and take it.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
if (not $anvil->data->{switches}{'job-uuid'})
{
# See if a job is waiting to run.
$anvil->data->{switches}{job_uuid} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
if ($anvil->data->{switches}{'job-uuid'})
{
# Load the job details. If anything is returned, there was a problem.

View File

@ -48,14 +48,6 @@ if (not $anvil->data->{sys}{database}{connections})
$anvil->nice_exit({exit_code => 1});
}
# If we don't have a job UUID, try to find one.
if (not $anvil->data->{switches}{'job-uuid'})
{
# Load the job data.
$anvil->data->{switches}{'job-uuid'} = $anvil->Job->get_job_uuid({program => $THIS_FILE});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { "switches::job-uuid" => $anvil->data->{switches}{'job-uuid'} }});
}
if ($anvil->data->{switches}{'job-uuid'})
{
# Load the job data.