David Galloway [Thu, 16 Jul 2026 14:06:26 +0000 (10:06 -0400)]
tools: Add blink-trial-sleds.sh for locating NVMe sleds
Blinks (or unblinks) the locator LED on Supermicro Microcloud NVMe
sleds via the BMC Redfish API using curl. Takes either a CSV of
hostname,serial[,serial...] pairs or a single hostname on the command
line. Given a hostname with no serials, it lists the drives it finds
so serial numbers can be discovered.
Also add trial-sleds.csv listing the sleds currently needing
replacement.
Signed-off-by: David Galloway <david.galloway@ibm.com>
David Galloway [Wed, 15 Jul 2026 22:56:27 +0000 (18:56 -0400)]
maas: Add relay_vlan support to networking reconciliation
MAAS relocates a subnet to whichever VLAN its DHCP/PXE traffic is
observed on. For VLANs whose boot traffic reaches the rack controller
relayed through another VLAN (e.g. pok vlan107 hosts PXE via the
rack's 1338 leg), this "fix-up" keeps moving the subnet off the VLAN
we configured. Setting relay_vlan on the VLAN tells MAAS the traffic
is relayed and stops the relocation.
A new optional per-VLAN `relay_vlan: <vid>` key in maas_networking is
resolved to the target VLAN's MAAS database id via _vlan_index (which
covers every VLAN MAAS knows on the fabric) and included in the VLAN
update PUT. `relay_vlan: ''` explicitly clears an existing relay;
omitting the key leaves MAAS untouched.
Pre-flight validation fails fast on configs MAAS would reject:
dhcp_on combined with relay_vlan, a VLAN relaying to itself, or a
relay target that is itself relayed (chained relays).
Signed-off-by: David Galloway <david.galloway@ibm.com>
David Galloway [Wed, 8 Jul 2026 18:13:40 +0000 (14:13 -0400)]
maas: Release discovered lease IP before STATIC link_subnet
MAAS keeps a DISCOVERED StaticIPAddress record for a machine's active
DHCP lease. link_subnet mode=STATIC does get_or_create(ip=...) and
raises StaticIPAddressUnavailable (HTTP 404 "IP address is already in
use.") while any record holds that IP, and unlink_subnet does not
remove the discovered record. This made both the initial link and the
unlink-then-relink paths fail for hosts that are deployed with the very
IP we want to assign statically (e.g. o03's 172.21.67.13).
When the desired STATIC IP is already seen on the same interface (its
links or discovered leases), POST /ipaddresses/?op=release with
force=true discovered=true first so the STATIC claim can succeed. If
another machine holds the IP we release nothing and still fail loudly.
Signed-off-by: David Galloway <david.galloway@ibm.com>
David Galloway [Thu, 2 Jul 2026 13:31:35 +0000 (09:31 -0400)]
maas: Skip bond members and no-native bonds in subnet pass
MAAS rejects link_subnet on a physical that's enslaved in a bond, and
bonded members share the bond's MAC so the inventory-MAC match was
pulling them into the loop anyway. Filter them out by name.
Also exclude bonds without a native VLAN: MAAS parks their untagged
interface on the parents' VLAN, so the CIDR match would hand that VLAN's
IP to the bare bond and collide with the interface that actually owns
it. Only the bond's tagged .NNNN children should get IPs.
Signed-off-by: David Galloway <david.galloway@ibm.com>
David Galloway [Thu, 2 Jul 2026 13:30:58 +0000 (09:30 -0400)]
maas: Assign STATIC IPs from inventory *_ip vars
When any inventory var ending in _ip falls inside the candidate subnet's
CIDR, link the interface STATIC on that exact address instead of relying
on DHCP or a dynamic range. Interfaces with no matching IP fall back to
iface.desired_mode or maas_iface_mode_default, which now defaults to
LINK_UP instead of DHCP.
Also relink when the mode matches but the assigned address doesn't, so a
changed inventory IP converges.
Signed-off-by: David Galloway <david.galloway@ibm.com>
David Galloway [Thu, 2 Jul 2026 13:30:31 +0000 (09:30 -0400)]
maas: Look up inventory MACs for the target host, not the play host
update.yml runs against hosts other than inventory_hostname (machines.yml
passes inv_host for exactly this reason), so the _inv_macs collection was
reading the wrong host's *_mac vars.
Signed-off-by: David Galloway <david.galloway@ibm.com>
PLAY [all] *********************************************************************************************************************************************************************************************
TASK [Make sure we have power_user and power_pass] *****************************************************************************************************************************************************
skipping: [trial001.front.sepia.ceph.com]
TASK [test factory ipmi creds] *************************************************************************************************************************************************************************
fatal: [trial001.front.sepia.ceph.com -> localhost]: FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
...ignoring
TASK [test power_user/power_pass creds] ****************************************************************************************************************************************************************
fatal: [trial001.front.sepia.ceph.com -> localhost]: FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
...ignoring
TASK [if both fail, halt now] **************************************************************************************************************************************************************************
fatal: [trial001.front.sepia.ceph.com]: FAILED! => {"changed": false, "msg": "Failed as requested from task"}
vim tools/set-bmc-static.yml
%
ansible-playbook tools/set-bmc-static.yml --limit 'trial001*' -e only_lan_access=true
PLAY [all] *********************************************************************************************************************************************************************************************
TASK [Make sure we have power_user and power_pass] *****************************************************************************************************************************************************
skipping: [trial001.front.sepia.ceph.com]
TASK [debug] *******************************************************************************************************************************************************************************************
fatal: [trial001.front.sepia.ceph.com]: FAILED! => {"msg": "The conditional check '(power_status_factory.rc != 0) or (power_status_power.rc != 0)' failed. The error was: error while evaluating conditional ((power_status_factory.rc != 0) or (power_status_power.rc != 0)): 'dict object' has no attribute 'rc'. 'dict object' has no attribute 'rc'\n\nThe error appears to be in '/Users/david/src/ceph-cm-ansible/tools/set-bmc-static.yml': line 70, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - debug:\n ^ here\n"}
PLAY [all] *********************************************************************************************************************************************************************************************
TASK [Make sure we have power_user and power_pass] *****************************************************************************************************************************************************
skipping: [trial001.front.sepia.ceph.com]
TASK [if both fail, halt now] **************************************************************************************************************************************************************************
fatal: [trial001.front.sepia.ceph.com]: FAILED! => {"msg": "The conditional check '(power_status_factory.rc != 0) and (power_status_power.rc != 0)' failed. The error was: error while evaluating conditional ((power_status_factory.rc != 0) and (power_status_power.rc != 0)): 'power_status_factory' is undefined. 'power_status_factory' is undefined\n\nThe error appears to be in '/Users/david/src/ceph-cm-ansible/tools/set-bmc-static.yml': line 81, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: if both fail, halt now\n ^ here\n"}
PLAY [all] *********************************************************************************************************************************************************************************************
TASK [Make sure we have power_user and power_pass] *****************************************************************************************************************************************************
skipping: [trial001.front.sepia.ceph.com]
TASK [Check if we have SSH access] *********************************************************************************************************************************************************************
skipping: [trial001.front.sepia.ceph.com]
TASK [Fake SSH failure if not desired] *****************************************************************************************************************************************************************
ok: [trial001.front.sepia.ceph.com]
TASK [Initial setup of username from localhost] ********************************************************************************************************************************************************
fatal: [trial001.front.sepia.ceph.com -> localhost]: FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
...ignoring
TASK [Initial setup of permissions from localhost] *****************************************************************************************************************************************************
fatal: [trial001.front.sepia.ceph.com -> localhost]: FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
...ignoring
TASK [Initial setup of password from localhost] ********************************************************************************************************************************************************
fatal: [trial001.front.sepia.ceph.com -> localhost]: FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
...ignoring
TASK [Enable user] *************************************************************************************************************************************************************************************
fatal: [trial001.front.sepia.ceph.com -> localhost]: FAILED! => {"changed": false, "module_stderr": "sudo: a password is required\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
...ignoring
Dan Mick [Mon, 1 Jun 2026 22:51:04 +0000 (15:51 -0700)]
roles/users/tasks/filter_users.yml: gut and replace
The old logic with jinja templates was just not robust anymore;
too easy to get a string value instead of an object floating around.
Modern ansible has filters to do this sort of thing better. I
expect this to be compatible with existing usage of the various user
variables, but there's a set of debug, enabled by --tags=debug (that's
what the tags: never is for, to make sure it doesn't run unless
explicitly requested).
David Galloway [Thu, 14 May 2026 22:08:10 +0000 (18:08 -0400)]
nameserver: Disable minimal-responses
Just upgraded vpn-pub to el9.
BIND 9.16 (EL9) changed the default behavior for minimal-responses,
causing authority and additional (glue) sections to be omitted from
responses. Set minimal-responses no explicitly to restore consistent
behavior across all nameservers regardless of BIND version.
Signed-off-by: David Galloway <david.galloway@ibm.com>
David Galloway [Thu, 14 May 2026 16:28:33 +0000 (12:28 -0400)]
users: Change home dir path for teuthology host
The home dirs live at the /tank/home mountpoint. This change will default to /home unless the host we're running the role against is in the teuthology ansible group.
Fixes: https://tracker.ceph.com/issues/63562 Signed-off-by: David Galloway <david.galloway@ibm.com>
Adam Kraitman [Wed, 16 Jul 2025 07:18:07 +0000 (10:18 +0300)]
Add cleanup tasks to resolve Grafana APT repository conflict
The new tasks remove the conflicting key file and duplicate repository entries before adding the standardized Grafana repository, ensuring a clean APT configuration
Signed-off-by: Adam Kraitman <akraitma@li-8b09b2cc-35b7-11b2-a85c-cd1dbade58f9.ibm.com>
David Galloway [Fri, 8 May 2026 20:59:38 +0000 (20:59 +0000)]
maas: quote variable usages to satisfy ansible-lint var-spacing
ansible-lint's var-spacing rule flags '{{ var }}temp' and 'prefix-{{ var }}'
because non-whitespace characters border the Jinja delimiters. Switch the
'temp' suffix to a Jinja string concatenation, and quote the YAML scalars
where a literal joins a variable so the boundaries are unambiguous.
Signed-off-by: David Galloway <david.galloway@ibm.com>
David Galloway [Fri, 20 Feb 2026 00:21:57 +0000 (19:21 -0500)]
nameserver: Match A records to reverse[] in named_domains
This will let multiple subnets/domains use the same ipvar
For example, bath and infra-compute can both have a if_25Gb_ip
```
bath14.front.sepia.ceph.com if_25Gb_ip=10.20.192.44
infra-compute-01.os.sepia.ceph.com if_25Gb_1_ip=172.16.53.11
- Using systemd instead of rc.local:
- Configure netplan on boot for Ubuntu
- Configure NetworkManager on boot for CentOS/Rocky
- Set hostname
- Update packages and reboot
Signed-off-by: David Galloway <david.galloway@ibm.com>