2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-09-29 00:31:09 +00:00

Compare commits

..

848 Commits

Author SHA1 Message Date
Jarrod Johnson 7cb6b1ac35 Fix autoconsole error on SPCR-free EFI implementations 2025-05-13 16:46:18 -04:00
Jarrod Johnson 315d1d9b5e Change to common image from text for errors
This allows easier management of rendering of text.

Also add a black and white border to make tiling more delineated.
2025-05-13 15:39:40 -04:00
Jarrod Johnson d382bd5182 Provide cleaner recovery for image decode failure
When doing the kitty support with pillow installed,
recover from a condition, creating a stub 'screenshot' to
reflect the error.
2025-05-13 14:23:38 -04:00
Jarrod Johnson fca0119331 Amend URL shortening
302 works for iPXE, but not for more limited UEFI
http client.

If we are dealing with UefiHttpBoot, check for a header
from nginx config and use X-Accel-Redirect to induce proxy side
redirect transparent to client.

Otherwise, give an error indicating the issue with the profile
name length and incompatibility with Apache capabilities.
2025-05-13 11:41:11 -04:00
Jarrod Johnson a7c338786e Fix dotted field names in stub formatter
The stub formatter was chocking on dotted
key names.
2025-05-09 16:39:45 -04:00
Jarrod Johnson c892af5a1e Implement 8 character max for attribute formatting
When trying to set a node or group attribute, evaluate
length of any potential formatting specification to keep it under
8 characters.

This should prevent even temporary expansion over 10MB for an attribute
on the way to setting it.
2025-05-09 09:34:19 -04:00
Jarrod Johnson 870cee5ed8 Add public TLS certificates to identitiy images
Some profiles may want to have a fixed boot image,
and site specific content limited to the identity payload, or at
least the TLS so it could fetch the rest over https.
2025-05-09 09:11:58 -04:00
Jarrod Johnson 76a66a46e1 Restrict maximum attribute size from formatting
If an expression causes an inordinate amount of memory to be
used, then block it from continuing.

For now, we consider that an expression that expands beyond 16k.  I
am unable to conceive of a use case where someone would want to
use an expression to derive more than 16k as it stands, as we don't
carry any particularly large opaque payloads right now.
2025-05-08 17:01:35 -04:00
Jarrod Johnson df354c2f7d Add some network drivers to cloning/diskless
The r8169 enjoys some popularity.

Also, we'd like to be able to try out diskless/cloning with
VMs, so vmxnet3 and virtio_net are handy to round that out.
2025-05-08 11:21:27 -04:00
Jarrod Johnson 5b1492fed8 Restore error message on chassis without location information. 2025-05-06 15:31:03 -04:00
Jarrod Johnson ca3a53fde4 Provide specific guidance for bad ssh key permissions 2025-05-06 09:51:11 -04:00
Jarrod Johnson 5ab16851ec Treat '' as equivalent to unset for ipv{}_method
Since it's a really difficult distiction between blank
and unset, make sure this is treated the same.
2025-05-06 09:01:43 -04:00
Jarrod Johnson febccf4d5e Fix imgutil with el8 diskless 2025-05-06 08:39:53 -04:00
Jarrod Johnson d0ae7b46ae Disable the HTML API explorer
It may be the case that no one uses it.
2025-05-02 16:21:47 -04:00
Jarrod Johnson 57ada3728c Change default host to localhost only
Also, fix support for IPv4 addresses as bind_host
2025-05-02 16:18:28 -04:00
Jarrod Johnson 89437ee761 Fix Proxmox sample scripts for post/firstboot 2025-05-02 13:19:56 -04:00
Jarrod Johnson bfadc284b0 Expand documentation of graphical nodeconsole usage. 2025-05-02 08:57:29 -04:00
Jarrod Johnson fbea510fc1 Have nodeconsole respond to resize
When doing the screenshot tiling with interval,
sanely handle resizing the terminal.
2025-05-01 12:13:27 -04:00
Jarrod Johnson 5be99d995a Fix up VM power handling
For both proxmox and vmware, properly model the 'oldstate' feature.

For proxmox, further:
- Wait for power change to actually take effect
- Change reset to a cycle, to help nodesetboot actually work correctly.
2025-05-01 11:44:35 -04:00
Jarrod Johnson b3ffd632a5 Add proxmox ve example scripts to debian profile 2025-05-01 10:23:42 -04:00
Jarrod Johnson 62988117f1 Another iteration toward debian bookworm support 2025-05-01 09:39:18 -04:00
Jarrod Johnson 71f5ce2b29 Add deployment lock mechanism
This allows users to opt into disabling setting further profile changes.

Nodes may be 'unlocked' (normal), 'autolock' (will lock on next
completion), or 'locked' (unable to change the pending OS profile)
2025-05-01 09:25:05 -04:00
Jarrod Johnson 0c0cac140d Add debian profile material
Implement Debian 12 installation
2025-04-30 17:06:20 -04:00
Jarrod Johnson 5cc70846fd Fix asymmetric ipv4/ipv6 attribute PXE response
If a nic were aliased *and* the node had attributes
for ipv6 but used host resolution for ipv4 identity,
it was possible for PXE to pick the wrong way
to respond.

Instruct netutil to specifically consider only the matching family
for the PXE/HTTP boot context
2025-04-30 15:54:46 -04:00
Jarrod Johnson 71f75dbc31 Provide specific error on empty noderanges for expressions
For commands such as nodeshell and noderun,
provide a more useful message when a noderange is empty.
2025-04-29 16:13:33 -04:00
Jarrod Johnson f797ede15f Handle 503 from a stopped confluent member
If a confluent collective member is stopped, then the
HTTPS check passes.  If we end up with a 503 indicating
the other end has a missing confluent, fall back to the loop
to check for other living collective members.
2025-04-29 15:44:13 -04:00
Jarrod Johnson 9b3c8e185d Merge remote-tracking branch 'xcat' 2025-04-29 10:23:20 -04:00
Jarrod Johnson 9fa5278204 Merge pull request #191 from tkucherera-lenovo/nodeconsole
document nodeconsole sreenshot feature
2025-04-29 10:22:37 -04:00
Jarrod Johnson fd4c2686a4 Add telnets support to vmware console
This allows the console to be credibly secured,
provided the current host is a node to hold the known hosts...
2025-04-29 10:19:08 -04:00
Tinashe d4d9b015b8 document nodeconsole 2025-04-29 09:54:43 -04:00
Jarrod Johnson 0b5be68586 Give media bootstrap more of a chance in genesis
If the USB is slow to enumerate, keep trying during the network
scan to let the USB have a chance to interject if the network
is unwilling.
2025-04-29 09:53:58 -04:00
Jarrod Johnson 80bf0c9bfa Clean up a relatively common potential error in XC scan
Do not clutter logs with this condition.
2025-04-29 09:53:19 -04:00
Jarrod Johnson f89cc5863f Add text console support for Proxmox guests 2025-04-29 09:52:47 -04:00
Jarrod Johnson 6552c90e4d Clean up busy loop and other oddity with vcenter console
Fix it so that common conditions do not
trigger trace logs and busy loops.
2025-04-29 09:52:19 -04:00
Jarrod Johnson 0e8a6038dc Merge remote-tracking branch 'xcat' 2025-04-28 19:10:37 -04:00
Jarrod Johnson 797b5fc478 Fix proxmox power reporting while off 2025-04-28 19:09:56 -04:00
Jarrod Johnson 4c90d431b6 Add preliminary proxmox node support 2025-04-28 17:17:24 -04:00
Jarrod Johnson 5e87b3ff48 Merge pull request #190 from tkucherera-lenovo/nodeconsole
make nodeconsole kill more consistent
2025-04-28 11:00:01 -04:00
Jarrod Johnson 2370cb0b0a Merge pull request #188 from tkucherera-lenovo/console-redirect
remove-consoleredirect
2025-04-28 10:59:18 -04:00
Jarrod Johnson 20b4f46699 Add screenshot ikvm to vcenter plugin 2025-04-27 10:32:28 -04:00
Jarrod Johnson 74355e5220 Implement partial telnet for VMWare
The vmware serial support demands more proper
telnet support, provide some support for negotiating
do/don't, will/won't opcodes.
2025-04-25 18:41:01 -04:00
Tinashe 3b46ccb5b1 make nodeconsole kill more consistent 2025-04-25 16:55:25 -04:00
Jarrod Johnson 85249ae71b Basic VCenter plugin
This provides nodeinventory (mac and -s most interestingly),
nodepower, nodesetboot (and by extension, nodedeploy -n),
and nodeconsole (console.method=vcenter).
2025-04-25 13:19:38 -04:00
Jarrod Johnson 0bdcaecf82 Do not include localhost in syncfiles consideration
localhost was added to ssh principals, but should not be used
as a candidate in syncfiles.

The syncfileclient should already be filtering this possibility,
but best to filter it everywhere that makes sense.
2025-04-25 08:57:50 -04:00
Jarrod Johnson b4ef1b484a Amend syncfiles address selection.
A node with private, unroutable addresses relative to
the deployment server may cause the deployment server
to select an unroutable address.

Address this with two strategies.

First, if any of the addresses appear local to the deployment server
networks, prefer those and filter out unroutable.

Secondly, if a node is purely remote, and thus all addresses routable,
then make all the addresses a candidate. However, since the
client can't possibly be using fe80::, we can replace the principal list
with just the clientip, provided it appears in the principal list.
2025-04-25 08:55:10 -04:00
Jarrod Johnson 9f51e256ce Activate vinz on access if doing collective
If a node has not been asked to open any locally managed
video consoles before it was asked to open a peer managed console,
it would fail to start the needed vinz service.

Work around this by detecting that scenario and giving
the vinz subsystem a chance to fix itself.
2025-04-24 08:08:27 -04:00
Jarrod Johnson 1e1b7871cb Merge pull request #98 from weragrzeda/master
NTP servers fix for stateless images for RHEL 7-9
2025-04-24 08:05:55 -04:00
Wera Grzeda 1553af0f41 NTP servers fix for stateless images for RHEL 7-9
Node attribute ntp.servers in nodeattrib ca now be used in stateless images

	modified:   confluent_osdeploy/el7-diskless/profiles/default/scripts/onboot.sh
	modified:   confluent_osdeploy/el8-diskless/profiles/default/scripts/onboot.sh
	modified:   confluent_osdeploy/el9-diskless/profiles/default/scripts/onboot.sh
2025-04-24 10:47:38 +02:00
Jarrod Johnson 0c8799f4dd Favor more utilization of bottom screenshot row
When we have the grid size, cut off any extra columns
so long as it doesn't gain a row.
2025-04-23 12:50:44 -04:00
Jarrod Johnson 52b0ae179e Background console disconnect on node removal 2025-04-23 12:33:40 -04:00
Jarrod Johnson 690980c064 Always specify miimon=100 in networkmanager bonds
We already do this for SUSE, it makes sense as a default.
2025-04-23 10:28:42 -04:00
Jarrod Johnson 977d272c56 Fix untiled nodeconsole screenshot 2025-04-23 09:55:45 -04:00
Jarrod Johnson b5540dd395 Hide cursor during screenshot run 2025-04-23 09:48:54 -04:00
Jarrod Johnson af1659dafd Have nodeconsole exit below screenshots 2025-04-23 09:44:10 -04:00
Jarrod Johnson a69113222f Fix positioning errors in tiled console display
It turns out that specifying height and width explicitly
does not guarantee that the image protocols will actually fill
the specified space. Notably iterm will honor aspect ratio
(which is good), but leave the cursor where the image would
naturally leave it (which is difficult with relative positioning).

Previously, relative positioning was used as a workaround
for the fact that save/restore or any absolute positioning may
be fouled by incurring scroll.

To make cursor save/restore work, we determine the total rows and
print newlines enough to incur scroll and then move cursor back up.
This lets us use save/restore to ignore cursor movement by the image.
2025-04-23 09:34:44 -04:00
Jarrod Johnson 05ffc9da10 Constrain aspect ratio
When parceling out the screen real estate, avoid either the height
or the width from getting way out of proportion.

Better to let screen be unused than abuse it to distort the
aspect ratio too much.
2025-04-22 16:01:26 -04:00
Jarrod Johnson bfdd6a56f6 Add iterm tiling support
Also, block sixel attempts, since that is not implemented.
2025-04-22 10:58:25 -04:00
Jarrod Johnson 94af42031e Provide screenshot tiling with interval support
Only for kitty graphics protocol.

Also, attempt to use pillow to convert, if available.  Kitty itself
needs this, Konsole can work either way.

It currently does not preserve aspect ratio, to do that
we pretty much need to do some work with pillow.

If we specify just the height, then ratio is preserved, but it won't
honor the designed bounding box on wide screenshots. Also
Konsole won't even honor just one scaling factor.

So the better thing would be to determine the aspect ratio, which
needs pillow.
2025-04-22 10:35:14 -04:00
Jarrod Johnson 0cfdfbdfa4 Add tar.zstd capability
zstd is much faster and not too much bigger than xz
2025-04-18 11:19:12 -04:00
Tinashe 999a9c3acf remove-consoleredirect 2025-04-17 15:34:45 -04:00
Jarrod Johnson 082a20f776 Add mechanism to refresh screenshot in nodeconsole
For a single node, provide a way to cleanly
redraw a screen to keep an eye on it.
2025-04-17 10:34:11 -04:00
Jarrod Johnson 69240ef492 Add Fedora 42 scripted install support 2025-04-17 08:30:20 -04:00
Jarrod Johnson 656dea0929 Add error for failure to get screenshot
Usually this is due to the target not having a license key,
in the case of Lenovo equipment.
2025-04-16 15:34:06 -04:00
Jarrod Johnson e46b4ede6d Implement a CONFLUENT_IMAGE_PROTOCOL env variable
This directs CLI with image output to use a preferred protocol.

This is retroactively applied to stats.

Currently we prefer kitty, as it seems to be the most widely supported.

Though some things only support iterm, so that's an option.

And some only support sixel, but the user has to be the one to
figure out adding pysixel dependency.
2025-04-16 12:50:59 -04:00
Jarrod Johnson 9823ffc12d Fix collective serialization of screenshot messages 2025-04-16 09:46:48 -04:00
Jarrod Johnson e5da8c01a9 Do not attempt to print non-existent data. 2025-04-15 15:51:12 -04:00
Jarrod Johnson a138bef551 Do not worry about failure to reply to a SSDP confluent request 2025-04-15 15:40:17 -04:00
Jarrod Johnson e27f07ac36 Use IPv4 address for ikvm when fe80 is the local bmc
The fe80:: is hopeless, try to send ipv4 just in case.

Technically speaking, the user may be using a different address
or real ipv6 and the ipv4 guess might fail, but it probably won't.
2025-04-15 14:25:03 -04:00
Jarrod Johnson f11473c736 Numerous fixes for shell server
On exit, clear the terminal buffer and invalidate the session.  This
avoids the web ui being very attached to a closed, dead session, and
leaking stale buffer to a reused sessionid.

For confetty, treat starting a shell session more like starting a
console session.

If an attempt to resize a dead session is attempted,
ignore failures.
2025-04-14 10:25:25 -04:00
Jarrod Johnson 35e3ca1f1f Have screenshots become normal text
Base64 comes out as ASCII bytes, change to text for
json handling.
2025-04-14 07:53:40 -04:00
Jarrod Johnson 6d1da85991 Implement screenshot via nodeconsole -s
This will grab screenshots from Lenovo systems and
output them to the console, using the kitty image protocol.
2025-04-11 17:13:19 -04:00
Jarrod Johnson 507e6fa9ac Ensure bash runs the genesis_bootstrap from media 2025-04-11 16:05:08 -04:00
Jarrod Johnson e9372a4d34 Provide means for nodeping to use original name on -s 2025-04-11 15:10:28 -04:00
Jarrod Johnson 49ac3487c2 Fix bad indentation in add_local_repositories 2025-04-11 13:23:45 -04:00
Jarrod Johnson 1ec08336e6 Add notation on how to opt out of ubuntu install internet connect 2025-04-11 13:18:41 -04:00
Jarrod Johnson 90f4a2a062 Improve text console behaviors of Ubuntu and RedHat
RedHat makes grub redundantly handle serial output that firmware
already handles.  If we detect EFI firmware and SPCR ACPI table and
connected serial port, that suggests that firmware will handle.

Ubuntu hates serial console by default, amend it so it can actually
work for serial users.
2025-04-11 12:55:01 -04:00
Jarrod Johnson 1985525cc0 Add all gpgkeys to local repositories
gpgkey can take multiple, and better to specify them all instead
of just one.
2025-04-11 12:13:30 -04:00
Jarrod Johnson 9174ad651f Fallback to mac
Some systems do not have UUIDs. Which is unfortunate, but usually
a system mac address does well enough.
2025-04-11 08:38:51 -04:00
Jarrod Johnson ddf9244514 Correct typo in add_local_repositories 2025-04-09 17:00:56 -04:00
Jarrod Johnson 5e72a8b3c0 Handle reseat with '1a/1b' type bay description
This fixes ability to reseat newer chassis when
using the coordinate specification for bay location.
2025-04-09 16:29:57 -04:00
Jarrod Johnson 66265d170a Catch general reseat errors 2025-04-09 16:06:12 -04:00
Jarrod Johnson 2e60ca13b7 Try to add gpgkey to local repository
This is needed for things like followup imgutil
2025-04-09 13:27:29 -04:00
Jarrod Johnson 9744e0d1b0 Accept XCC and BMC for aliases of each other 2025-04-09 12:19:16 -04:00
Jarrod Johnson 7001f0d827 Add encoding for vfat usage in ubuntu genesis 2025-04-09 09:49:10 -04:00
Jarrod Johnson a6afbeebe0 Merge pull request #185 from Obihoernchen/validvalues_man
Show valid values from attributes.py in man pages
2025-04-09 09:13:10 -04:00
Markus Hilger 699efd2f4f Show valid values from attributes.py in man pages 2025-04-09 03:28:15 +02:00
Jarrod Johnson 5d60a6a427 Fix indentation in pdu module 2025-04-08 14:53:36 -04:00
Jarrod Johnson 672bc73756 Fix for potential hangs on race condition with task exit 2025-04-08 14:10:40 -04:00
Jarrod Johnson 0e3543c4aa Fix elif clause in module-setup 2025-04-08 10:51:29 -04:00
Jarrod Johnson 43d9fe09cf Merge remote-tracking branch 'xcat' 2025-04-08 10:44:05 -04:00
Jarrod Johnson 9cc3c96f6a Fetch fingerprint before credentials
Some implementations choose to close the certificate command after
granting user/password. Make sure we get the certificate first.
2025-04-08 10:40:07 -04:00
Jarrod Johnson b3b852a9e1 Add Ubuntu GUI considerations for genesis 2025-04-08 10:39:35 -04:00
Jarrod Johnson 71ddbb88fc If doing GUI in Genesis, defer until after udevd
udev is needed to run in some scenarios for seatd/sway to
function correctly.
2025-04-08 09:25:19 -04:00
Jarrod Johnson 5df6f9adbf Merge pull request #184 from tkucherera-lenovo/console-redirect
seperate console redirect scripts into oses
2025-04-07 15:19:03 -04:00
Jarrod Johnson 799fff10ff Handle different locale layouts 2025-04-03 14:58:09 -04:00
Jarrod Johnson bf03d8dc82 Pull locale file into genesis build 2025-04-03 14:51:58 -04:00
Jarrod Johnson 65760bb678 Break locale to a separate file 2025-04-03 14:49:24 -04:00
Jarrod Johnson 9980414160 Hook gui in genesis build if detected 2025-04-03 14:30:25 -04:00
Jarrod Johnson 5f7a5b18bf Add Sway to genesis install assets 2025-04-03 14:28:25 -04:00
Jarrod Johnson 53760ac576 More changes to support debian genesis host 2025-04-03 13:11:56 -04:00
Jarrod Johnson 1fa2baacb7 Support debian style lib layout 2025-04-03 13:06:37 -04:00
Jarrod Johnson b1ba1720b9 Suppress scary message from apiclient when asked to just do -f. 2025-04-02 11:10:33 -04:00
Jarrod Johnson b21d8b75e0 Incorporate block device into retry loop
Have block devices checked for identity information
in a loop with network source search.

Block devices may be delayed for various reasons. The previous method
could be bypassed by fast block device cutting off slow device
enumeration. It also incurred a delay for the network install
case.
2025-04-02 09:50:15 -04:00
Jarrod Johnson df6818a3cc Fix refactoring of detect_backend to lldp module 2025-04-01 15:59:02 -04:00
Jarrod Johnson 98add92a20 Correct the path to the api key during ubuntu installation 2025-04-01 15:26:37 -04:00
Jarrod Johnson 85b19acf5f Fix NXAPI neighbor table API backend 2025-04-01 15:22:36 -04:00
Jarrod Johnson e5f588d2b7 Fixup work to add nxapi for neighbor api backend 2025-04-01 14:24:59 -04:00
Jarrod Johnson c8ed877fda Make clearer api grant errors 2025-04-01 14:05:46 -04:00
Jarrod Johnson b665365178 Start with esxi7 contents as base for esxi9 2025-04-01 08:18:51 -04:00
Jarrod Johnson 48921c4ef0 Quick scanner to do ssdp scan 2025-03-31 15:12:29 -04:00
Jarrod Johnson df2c6a4e18 Fix states of absent PSU in NX-API 2025-03-28 17:30:49 -04:00
Jarrod Johnson 92ac49b561 Add NXAPI backend for mac table support. 2025-03-28 17:28:42 -04:00
Jarrod Johnson 2514507b87 Add node operations against Nexus switch
This enables the commands to work that one would expect.
2025-03-28 13:34:03 -04:00
Jarrod Johnson 7419dbcf71 Fix unpatched imports of webclient 2025-03-28 09:26:41 -04:00
Jarrod Johnson 659f87877d Rename the NX-API library 2025-03-28 08:29:18 -04:00
Jarrod Johnson 586261ddca Fix messed up PSU in nxos 2025-03-27 16:42:28 -04:00
Jarrod Johnson fc0cc41b90 Commence work on NXAPI support 2025-03-27 16:37:25 -04:00
Tinashe b596de93a0 seperate into oses 2025-03-27 11:09:25 -04:00
Jarrod Johnson ce5c1c925e Adapt to register XCC3
Handle XCC3 differences in the register scenario.
2025-03-27 10:00:44 -04:00
Jarrod Johnson 72c030995f Tolerate errors during register
If a condition breaks unicast query, keep going.
2025-03-27 09:50:19 -04:00
Jarrod Johnson 4677f2c806 Bump genesis version for next release 2025-03-25 11:20:58 -04:00
Jarrod Johnson 401ac50730 Merge remote-tracking branch 'xcat' 2025-03-25 11:20:40 -04:00
Jarrod Johnson 249ed5d9be Add script to try to sort out extra license material 2025-03-25 11:19:38 -04:00
Jarrod Johnson c29c9d5c47 Merge pull request #183 from stoderica/esxi7_fix
Modify apiclient utility, for esxi7 only, to check if the uplink of v…
2025-03-25 07:54:34 -04:00
Sorin Toderica 62e081cd72 Modify apiclient utility, for esxi7 only, to check if the uplink of vSwitch0 is up and if not, to try to replaces it with a different vmnic, that is up 2025-03-25 09:50:40 +02:00
Jarrod Johnson 1cf2a5339a Move sftp server to a more appropriate location 2025-03-24 16:34:51 -04:00
Jarrod Johnson 5ab02c31ee Add python 3.13 option for genesis 2025-03-24 16:34:15 -04:00
Jarrod Johnson 21f4d2e5c2 Remove opa from genesis 2025-03-24 16:29:51 -04:00
Jarrod Johnson fae266bf61 Refresh genesis for 3.13 release 2025-03-24 16:28:36 -04:00
Jarrod Johnson 84881cc6be Fix invoke to a file to not repeat the request 2025-03-21 09:12:57 -04:00
Jarrod Johnson 24e419568a Remove spurious output from stdout log 2025-03-21 09:12:41 -04:00
Jarrod Johnson e375c956ed Provide command line access to the updatestatus 2025-03-20 09:32:30 -04:00
Jarrod Johnson f6e9691b7f Amend arguments on IPv4 invocation
It turns out that when busybox invokes openssl for
IPv4, it does not pass a servername field.

In this case, start amending arguments after '-verify' instead, to catch
the verify_ip argument correctly.
2025-03-20 08:21:47 -04:00
Jarrod Johnson 5fb04126e6 Fix tracking of 'active' updates in update status 2025-03-19 16:43:19 -04:00
Jarrod Johnson 02bd26e7d2 Correct updatestatus to be resource, not collection 2025-03-19 16:17:31 -04:00
Jarrod Johnson 3a9b75839b Add another error code for XCC user rename refusal
Yet another error to reperesent rename refusal
2025-03-19 16:08:42 -04:00
Jarrod Johnson 29915acaeb Provide API to query update readyness 2025-03-19 15:31:51 -04:00
Jarrod Johnson ef68259745 Provide more full fixup of openssl invocation in wget
For IPv4 and IPv6, strip the ':443' for arguments where it doesn't make sense.

For IPv6, strip out [, ], and '%' from those arguments.
2025-03-19 12:41:50 -04:00
Jarrod Johnson e25b3acd98 Fix onboot.d in genesis profiles 2025-03-19 09:41:21 -04:00
Jarrod Johnson 1e463367fe Switch Ubunut initramfs to ssl
The busybox wget invocation of openssl is broken.

Override by stubbing it out to let openssl pick the verify
hostname instead of wget specified one, which is incorrect.
2025-03-18 15:52:37 -04:00
Jarrod Johnson 7d83a920a2 Add mechanism for configurable ikvm response
This allows for more flexible ikvm handling with newer pyghmi.
2025-03-13 15:59:10 -04:00
Jarrod Johnson 6402861f4c Provide custom node secret attributes
This allows for confluent to pass node secret data through.
2025-03-13 14:22:26 -04:00
Jarrod Johnson 0205f70d5a Merge pull request #182 from tkucherera-lenovo/eventlog
handle empty timestample
2025-03-13 10:22:39 -04:00
Jarrod Johnson 58608016c4 Add wait for disk bringup to allow media based co-opt of genesis 2025-03-12 13:23:00 -04:00
Tinashe 7d7baf0f77 handle empty timestample 2025-03-12 12:51:42 -04:00
Jarrod Johnson 9123d2f2e0 Add ability to post bodys to HTTP requests 2025-03-11 15:35:35 -04:00
Jarrod Johnson 9cecaab055 Fix confluent server identification using -s instead of file 2025-03-11 15:04:36 -04:00
Jarrod Johnson 9136341bda Tolerate different proxy pass configurations
The stock reverse proxy configuration strips the leading
'/confluent-api/' from the URL.

However, when doing a custom reverse proxy set up, one may preserve full
path without knowing which way to go.

Since '/confluent-api/' will never be used inside the api, just strip
it when detected to tolerate either of the likely proxy pass behaviors.
2025-03-11 11:38:05 -04:00
Jarrod Johnson d2011261ab Enable creation of bond and dependent tags in one iteration
Have a second pass to check interfaces that may
be created by the first pass.
2025-03-11 09:58:51 -04:00
Jarrod Johnson 060b81e205 Fix documentation error in attributes 2025-03-11 08:39:28 -04:00
Jarrod Johnson 1f97a5e67d Add a Makefile for building 2025-03-07 18:01:55 -05:00
Jarrod Johnson 13a6493100 Add a general utility for confluent in golang 2025-03-07 17:16:13 -05:00
Jarrod Johnson 28c929aec6 Have a draft apiclient in golang 2025-03-05 17:14:55 -05:00
Jarrod Johnson b4b011663e Handle more forms of confluent headers
Some frameworks won't allow headers through, normalize case
and normalize _ presence.
2025-03-05 17:14:28 -05:00
Jarrod Johnson defd41488e Merge remote-tracking branch 'xcat/master' 2025-03-05 13:13:55 -05:00
Jarrod Johnson 95952b5231 Detect active nic in multi-nic BMC discovery 2025-03-05 13:13:34 -05:00
Jarrod Johnson 857854a6e9 Merge pull request #179 from Obihoernchen/yaml
Implement YAML support for confluentdbutil (fixes #152)
2025-03-05 11:43:18 -05:00
Markus Hilger e5b1b5d3a0 Implement YAML support for confluentdbutil (fixes #152) 2025-03-05 17:42:31 +01:00
Jarrod Johnson c26936a2d7 Merge pull request #180 from Obihoernchen/fqdnfirst
Support FQDN first (Fix #167)
2025-03-05 11:35:36 -05:00
Jarrod Johnson 80ea0b3e91 Merge pull request #181 from tkucherera-lenovo/console-redirect
modify redirection code for rhel
2025-03-05 11:31:01 -05:00
Tinashe 1bfad11ee5 remove-mkconfig 2025-03-05 11:19:34 -05:00
Tinashe 7b4063a42f modify redirection code for rhel 2025-03-05 11:12:31 -05:00
Markus Hilger 2bc347fc2a Support FQDN first (Fix #167) 2025-03-05 04:17:45 +01:00
Jarrod Johnson f458c15677 Correct launching of GUI in genesis 2025-03-04 16:11:28 -05:00
Jarrod Johnson 02ec40092e Have genesis optionally GUI capable
Have Genesis work with newer distribution base, also support seatd/sway when
genesis contains it.
2025-03-04 15:12:59 -05:00
Jarrod Johnson cea87d012c Fix missing import from prepfish example. 2025-03-04 10:51:02 -05:00
Jarrod Johnson c73352a293 Add filter for bmc interface
People have been putting the BMC interface as
a net section, to aid in their information
and confluent2hosts.

Tolerate that by dropping net entries that match the
hardwaremanagement.manager attribute.
2025-03-04 10:50:48 -05:00
Jarrod Johnson f06d9a81e7 Have sshd only generate ed25519 during initramfs phase of diskless.
sshd-keygen service will come later with other keys, if desired.
2025-03-04 10:04:30 -05:00
Jarrod Johnson 0d4da78f05 Add certificate handling to prepfish.py 2025-03-03 10:51:10 -05:00
Jarrod Johnson 44a30686cb Add Fedora 41 scripted install support 2025-02-28 08:53:26 -05:00
Jarrod Johnson 596dca5d48 Merge pull request #178 from henglikuang/master
add a loop to find the accessible deployer when the method is not static
2025-02-28 06:36:07 -05:00
Hengli Kuang 75a0f44a36 add a loop to find the accessible deployer when the method is not static 2025-02-28 13:53:28 +08:00
Jarrod Johnson bde03f4595 Merge remote-tracking branch 'xcat' 2025-02-25 15:30:13 -05:00
Jarrod Johnson f62c0db678 Remove ssh_config directive not supported by EL7wq 2025-02-25 15:29:22 -05:00
Jarrod Johnson 132824ede5 Merge pull request #176 from tkucherera-lenovo/configbmc
Configbmc
2025-02-25 13:57:28 -05:00
Tinashe a595abe9e6 also allow users to just specify lom and we use the first port 2025-02-25 12:13:18 -05:00
Tinashe 11d63a4b5c allow users to choose which lom port to use for bmc shared mode 2025-02-25 11:00:16 -05:00
Jarrod Johnson 67bacc9934 Add sample script for bringing up a host interface 2025-02-21 15:25:41 -05:00
Jarrod Johnson 3a3f3a961d Add SMM3 to chained SMM logic 2025-02-20 15:42:49 -05:00
Jarrod Johnson 5fda02b9e0 Repeat NIC check loop on Ubuntu 18.04 deployments 2025-02-20 12:54:55 -05:00
Jarrod Johnson 825cacde0e Fix relay dhcp behavior
The refactor for multiple nics on same vlan omitted
a required parameter.
2025-02-12 09:52:23 -05:00
Jarrod Johnson e87d6652ca Fix type of height when pulled from attributes
location.height was left as string, which fouled
further processing.
2025-02-11 08:35:43 -05:00
Jarrod Johnson 76d4556501 Add a go version of genpasshmac 2025-02-07 10:19:54 -05:00
Jarrod Johnson 543a42edd6 Disable SELinux policy in EL diskless images
The SELinux policies do not currently work in a diskless
build, disable by default, though a user may try to enable
it manually after build.
2025-02-06 16:30:06 -05:00
Jarrod Johnson 82fe75e457 Add aliases to attrib clear
Support aliases when specified in clearing.
2025-02-06 15:59:29 -05:00
Jarrod Johnson 9b59c2fadb Have httpapi support multiple shell sessions 2025-02-06 13:25:39 -05:00
Jarrod Johnson 52497d7d95 Broaden except clause on automation check
For whatever reason, we can't seem to specifically catch
the CalledProcessError and have to resort to generic Exception.
2025-02-06 10:44:59 -05:00
Jarrod Johnson 2fcfbe9774 Fix multi-session access to shell
Shell sessions are now wired up to vtbufferd

The shellserver now correctly accounts for sessions being started.

The sockapi now correctly allows the client to specify/attach
to a specific session id.
2025-02-05 16:57:26 -05:00
Jarrod Johnson 564e136dc5 Always provide a badreadings output, even if empty 2025-02-04 09:11:53 -05:00
Jarrod Johnson b9f4051396 Export variables set in confluent functions 2025-02-03 16:40:57 -05:00
Jarrod Johnson e901559644 Add mechanism to explicitly ignore nics for netboot
A service.cfg configuration can be applied to ignore nics for netboot

# cat /etc/confluent/service.cfg
#[http]
#bindhost = /var/run/confluent/httpapi

[netboot]
ignorenics=enp65s0f1np1,enp65s0f3np3
2025-01-30 15:25:10 -05:00
Jarrod Johnson e536789c9d Mitigate send of duplicate replies
If an unrelated network interface shares a vlan with an otherwise
pertinent interface, defer and be silent to avoid confusion on the line.
2025-01-30 14:27:42 -05:00
Jarrod Johnson 7493cc5d48 Normalize enclosure handling 2025-01-30 09:37:10 -05:00
Jarrod Johnson 0fadb00acf Pass through slot geometry if provided 2025-01-30 08:03:36 -05:00
Jarrod Johnson b89ae4d74a Fix bytes being stored in db on identity image use 2025-01-27 12:58:42 -05:00
Jarrod Johnson 79d5a637a7 Correct syntax error in confignet 2025-01-24 11:12:25 -05:00
Jarrod Johnson 67aaee3b4e Adapt to the bond modes
When the team modes were defined in attributes, it was based on the
teamd names.  Since the ecosystem abandoned teamd, we went back to
bond.

However, we neglected to map all the names to the closest bond type equivalent.

Change confignet to do the mapping.
2025-01-24 07:58:31 -05:00
Jarrod Johnson e3d70f351d Provide internal URL shortening service
Permit users to have very long profile names, and provide
a URL shortening service to bridge the gap for fixed-width
field limitations in DHCP/PXE.
2025-01-22 15:44:49 -05:00
Jarrod Johnson 2f33aa5d83 Merge pull request #174 from tkucherera-lenovo/l2traceroute
l2traceroute
2025-01-22 15:30:14 -05:00
Tinashe d4fbd021ad l2traceroute 2025-01-22 09:49:46 -05:00
Jarrod Johnson 24f0ff5221 Add scripts to adopt a node to confluent SSH 2025-01-21 16:48:42 -05:00
Jarrod Johnson fb8675ddc5 Fix SMM3 discovery by switch 2025-01-21 10:10:40 -05:00
Jarrod Johnson cdfb76de57 Try alternate invocation for handshake
Newer versions of websocket change internal call, and we must follow.

This is a consequence of the library providing no means to customize the
TLS handling, so we have to dig in a little to get that customization.
2025-01-14 08:59:24 -05:00
Jarrod Johnson 32bc5afe03 Generate error on node/group misdeletion
If requesting to delete a group from a node when that node is
not a member of that group, generate an error.

Similarly to delete a node from a group.
2025-01-13 12:07:39 -05:00
Jarrod Johnson e2bb72cc14 Allow Unix socket for http socket
If service.cfg has:
[http]
bindhost = /var/run/confluent/httpapi

Then it will use the cited path to create a unix socket instead
of a network socket.
2025-01-08 15:59:48 -05:00
Jarrod Johnson 0cae0fe06e Add installtodisk support for el9 diskless images 2024-12-13 19:04:15 -05:00
Jarrod Johnson cd2509c485 Ignore unparseable net config files
If some pre-processing has rendered config files
unparseable, ignore the file as we can't intelligently rewrite
those.
2024-12-13 16:16:12 -05:00
Jarrod Johnson 8e0bc43008 Fix for SMMv3 onboarding 2024-12-13 16:15:23 -05:00
Jarrod Johnson ddd97388a6 Implement discovery for newer SMMv3 firmware 2024-12-11 10:22:10 -05:00
Jarrod Johnson 2c9b526de4 Repeat the interface loop for Ubuntu identity deploy
It may happen that the first pass at nics misses
a viable network interface due to slow link up
or slow spanning tree forwarding.

Repeat the loop through the interfaces to have follow
up chances at success.
2024-12-05 14:26:26 -05:00
Jarrod Johnson 5d6a935bec Bump genesis version 2024-12-05 10:21:12 -05:00
Jarrod Johnson 23cb1fa8ab Refresh genesis license handling 2024-12-05 10:18:16 -05:00
Jarrod Johnson 5f90aa4f69 Add SMMv3 handler for SMMv3 discovery 2024-12-03 15:00:10 -05:00
Jarrod Johnson 64895c9f95 Return empty hifurl list when non existent
For systems without a host interface,
properly show an empty list.
2024-12-03 14:55:50 -05:00
Jarrod Johnson 8bdabdc962 SMMv3 discovery support
The SMMv3 doesn't respond to the correct SSDP service, add the
odd service.

 Have SMMv3 use the standard redfish handler.

 Augment the standard redfish handler to deal with non-error
 password change required message.
2024-12-03 14:34:11 -05:00
Jarrod Johnson 3fa6b47995 Do not json dumps a string that is already json 2024-12-02 16:50:13 -05:00
Jarrod Johnson f1f433041c Restore underscore headers
Eventlet has "helpfully" stopped supporting headers with
underscores.  Restore them since we want to support
backwards compatibility and do not have the option to
just ignore existing clients.
2024-11-26 12:09:04 -05:00
Jarrod Johnson ebecc9c844 Merge pull request #170 from tkucherera-lenovo/webauth_update
use webauthn instead of webauthn-rp
2024-11-19 10:38:24 -05:00
Tinashe ff523a0d5c change the server spec file 2024-11-19 10:10:02 -05:00
Tinashe efda4b4ef7 remove LICENCE,VERSION and devel prints 2024-11-19 10:08:56 -05:00
Tinashe 8e89c8f622 use webauthn instead of webauthn-rp 2024-11-19 09:39:29 -05:00
Jarrod Johnson a0ffc11d6f Expand type for GUI usage 2024-11-15 09:24:04 -05:00
Jarrod Johnson 9c589e8352 Regenerate initrd after install
The drivers on target may differ from source, regenerate initramfs to allow for booting
2024-11-15 09:19:51 -05:00
Jarrod Johnson f88e9ecebf Support discovery through second XCC NIC 2024-11-14 08:03:34 -05:00
Jarrod Johnson 2f3a8619e8 Fix vinz VNC for non-root users
Relax permissions a tad to allow users to attempt
to connect if they otherwise know the socket name.
2024-11-12 16:16:47 -05:00
Jarrod Johnson 5df30881f8 Provide resource to check if http has been initialized
This allows clients to know if they need to direct user to do
early setup procedures.
2024-11-11 15:31:12 -05:00
Jarrod Johnson b1f8cf8f12 Avoid redrawing 'powered off' redundantly.
If the power state stays the same between queries, take no action to clear screen and
draw redundant data.

In the case of misreporting devices, it mitigates the impact of incorrect reporting,
while generally preserving the output behavior when accurate.
2024-11-11 13:51:10 -05:00
Jarrod Johnson d8c633a7d5 Add localhost to ssh principals/equiv
It shouldn't be possible to hijack localhost, so
allow such addresses to be principaled and be listed in equiv.
2024-11-11 08:03:57 -05:00
Jarrod Johnson 523d5920bc Add a sample script for grabbing XCC screenshots 2024-11-08 12:10:15 -05:00
Jarrod Johnson 9b6204db4f Switch to the type of the member interface
The 'team-slave/bond-slove' type is unneccesary, and
messes up with infiniband.

NetworkManager gets the idea if the 'ethernet' is a bond member without being told explicitly.
2024-10-28 13:21:54 -04:00
Jarrod Johnson a298ef8d74 Catch OpenBMC disconnects and handle them better 2024-10-28 09:41:38 -04:00
Jarrod Johnson 008c1308b4 Handle nvm subsystem without driver.
A variant of the M.2 RAID enablement kit does not manifest with nvme
driver.  Address this by allowing 'nvm' subsystype. to allow blank driver.

Also, to be on the safe side, have self.driver always be a string,
so it can be 'falsey' but still work as a string.
2024-10-26 08:16:56 -04:00
Jarrod Johnson b46a1e14a3 Fix video console when first run has multiple nodes
If client requested more than one on a fresh confluent run,
then only one of the video consoles would properly wait.

Fix by wrapping the assure in a startingup check.
2024-10-25 12:11:58 -04:00
Jarrod Johnson a46bcfa2b5 Add CentOS Stream 10 and Alma Kitten 10
Similar to 9, but now hooks must be in /var instead of /usr
2024-10-25 09:52:10 -04:00
Jarrod Johnson 773cab8189 Merge pull request #169 from tkucherera-lenovo/Staging
enable ability to clean up assets
2024-10-22 13:41:28 -04:00
tkucherera ab0f48f351 enable ability to clean up assets 2024-10-22 12:05:23 -04:00
Jarrod Johnson b99e4c94a0 Add Enlogic PDU support 2024-10-17 14:56:19 -04:00
Jarrod Johnson 3560415668 Update attribute inheritance on rename 2024-10-16 11:40:00 -04:00
Jarrod Johnson 81b57d5db6 Avoid potential endless recursion
If we are detaching, skip reattach in scenario
that leads to infinite recursion.
2024-10-10 16:22:58 -04:00
Jarrod Johnson b05b36484b Fix file staging in http api 2024-10-10 12:52:28 -04:00
Jarrod Johnson 3a0218c421 Simplify profile label outside of bootloader 2024-10-07 13:51:55 -04:00
Jarrod Johnson 84c119ce3d Reduce mandatory newlines between textgroup output 2024-10-04 09:19:19 -04:00
Jarrod Johnson 910af18a00 Fix http websockify 2024-09-30 13:57:09 -04:00
Jarrod Johnson 3ad53a3aac Fix client file staging
Skip read during httpapi, and inject sleep between file transfer chunks.
2024-09-27 15:30:59 -04:00
Jarrod Johnson 2fa56f4a38 Merge remote-tracking branch 'xcat/master' 2024-09-26 07:56:17 -04:00
Jarrod Johnson 7793de39b4 Merge pull request #165 from Obihoernchen/nodensensors-help
Fix nodesensors --skipnumberless help text
2024-09-26 07:54:24 -04:00
Markus Hilger a3212d7603 Fix nodesensors --skipnumberless help text 2024-09-26 13:19:21 +02:00
Jarrod Johnson ed2a8b6f9d Provide an example to name constrain a CA
It's imperfect, and abetter procedure should be written up
for the more security conscious.
2024-09-23 10:45:31 -04:00
Jarrod Johnson 71a83ac39c Try for more DNS lookups
Try to hit likely DNS names, or at least provide a means
of manipulating /etc/hosts to induce
a good domain for the default certificate SAN fields.

Note putting the FQDN first in /etc/hosts will get the FQDN in the
certificate.
2024-09-20 18:34:02 -04:00
Jarrod Johnson a8df3692b6 Persist passkeys as text
confluentdbutil and collective would choke
on the binary.  Have the binary bits be
safely converted to/from base64.
2024-09-20 17:26:02 -04:00
Jarrod Johnson 65ae52782e Merge pull request #164 from tkucherera-lenovo/webauth_update
remove hardcorded values
2024-09-19 16:29:33 -04:00
tkucherera 936153490a remove hardcorded values 2024-09-19 16:21:39 -04:00
Jarrod Johnson f19234419d Implement non-root ssh for SUSE diskless 2024-09-19 13:15:10 -04:00
Jarrod Johnson 787e8b95c0 Merge pull request #163 from tkucherera-lenovo/webauth_update
fix minor bugs and code clean up
2024-09-18 16:30:58 -04:00
tkucherera 9bce0de93d fix minor bugs and code clean up 2024-09-18 16:22:09 -04:00
Jarrod Johnson dbfb800c1b Fix regression in pyghmi dependency version 2024-09-12 13:26:15 -04:00
Jarrod Johnson 942bbd1c69 Merge pull request #154 from tkucherera-lenovo/webauthn
Webauthn
2024-09-12 13:25:15 -04:00
Jarrod Johnson bd37b1746d Merge pull request #136 from tkucherera-lenovo/firwareUpdateServer
Firware update server
2024-09-12 13:24:29 -04:00
Tinashe Kucherera 5609d4fe4b Merge branch 'master' into firwareUpdateServer 2024-09-12 11:44:22 -04:00
Tinashe Kucherera c2abe7c4cd Merge branch 'master' into webauthn 2024-09-12 11:40:20 -04:00
Jarrod Johnson 78dc6e31d7 Merge pull request #133 from tkucherera-lenovo/staging
Staging
2024-09-12 11:38:49 -04:00
Tinashe Kucherera bbc032056e Merge branch 'master' into firwareUpdateServer 2024-09-12 10:37:34 -04:00
Tinashe Kucherera 304d0b5dce Merge branch 'master' into staging 2024-09-12 10:29:52 -04:00
tkucherera d553ab864b resolve merge conflicts 2024-09-12 10:27:05 -04:00
tkucherera db381d377b account for timeout 2024-09-12 10:10:53 -04:00
Jarrod Johnson 7da3944b2b Allow blink for ipmi
OEM IPMI may now do blink
2024-09-11 09:13:30 -04:00
Jarrod Johnson 8704afcee5 Add glue to confluent api from vinzmanager 2024-09-10 11:28:00 -04:00
Jarrod Johnson 0fb19ce263 Wire up http sessions to vinzmanager 2024-09-06 13:41:50 -04:00
Jarrod Johnson c048439849 Reuse existing vinz unix session for a node 2024-09-05 11:44:29 -04:00
Jarrod Johnson f8715f4cb1 Implement logout on disconnect notification for vinz 2024-09-05 11:42:52 -04:00
Jarrod Johnson d17d5341f1 Imprement basic vinz management 2024-09-04 19:16:41 -04:00
Jarrod Johnson 2c76d94a6d Vary version for debian build process 2024-09-04 12:13:40 -04:00
Jarrod Johnson 7c8f85eb06 Handle python mangling of filename consistently for rpm build 2024-09-04 10:53:05 -04:00
Jarrod Johnson ee067fa3c0 Cleanup stray debian content in apt 2024-09-04 10:27:00 -04:00
Jarrod Johnson 4a2e943f84 Update osdeploy rpms to new version scheme for snapshots 2024-09-04 10:19:11 -04:00
Jarrod Johnson 97e29a5655 Change versioning to consistently produce prerelease consistent with rpm and deb 2024-09-04 10:11:47 -04:00
Jarrod Johnson cb67c83287 iAttempt to be consistent with ~ prerelease versioning
We may not know where we are going, but at least bump the minor number.

Ultimately we may not be building toward that number, or that number will be used in a different branch, but it
can at least handle more cases
2024-09-04 08:11:42 -04:00
Markus Hilger e11c3516e9 Create README.md (#162) 2024-09-03 12:25:15 -04:00
Jarrod Johnson 1f6987bafc Fix nodedeploy -c with profile
Remove vestigial statement near end, and put an up front
clarification to a user trying to use both '-c' and a
profile on the same command line.
2024-08-31 07:28:51 -04:00
Jarrod Johnson f4f5b4d1b6 Suppress bad gateway warning if the client ip is unknown
In a scenario where we are doing the 'next-server' next to a real dhcp server,
but through relay, the missing gateway would be expected.

Rely on the final message about 'no address' as the clue to users
that something went wrong on the node side.
2024-08-29 08:57:39 -04:00
Jarrod Johnson fd301c609f Add additional log data to relaydhcp 2024-08-29 08:51:22 -04:00
Jarrod Johnson 53b9a13a51 Fix different invocations of check_fish
Particularly nodediscover register can fail.

Those invocations are XCC specific, so the targtype should not matter
in those cases.
2024-08-28 19:19:39 -04:00
Jarrod Johnson cd91ed0b94 Fix escape warning on newer python 2024-08-27 15:55:54 -04:00
Jarrod Johnson 4dc54b92d5 Correct nodeconsole syntaxwarning 2024-08-27 11:35:39 -04:00
Jarrod Johnson 08a3a0ee76 Correct wrong pyghmi version in dependencies 2024-08-27 10:43:47 -04:00
Jarrod Johnson b601cd97c7 Bump pyghmi to a higher explicit version 2024-08-27 10:36:30 -04:00
Jarrod Johnson 1d80e2703c Add extended nodeconfig to confluent redfish 2024-08-27 09:59:16 -04:00
Jarrod Johnson 7304c8e3b7 Fix LLA request for deploycfg
If a client uses IPv6 LLA, the '%' location may slip in.
In such a case, disable client ip matching, since fe80::
is useless for that anyway.
2024-08-26 16:51:35 -04:00
Jarrod Johnson d84a76dbc6 Fix -a and -e nodeconfig 2024-08-26 10:01:24 -04:00
Jarrod Johnson 4f1b6b1fac Add extra_advanced to core resource tree. 2024-08-26 09:42:44 -04:00
Jarrod Johnson 77c5b70ad9 Wire up '-a -e' for nodeconfig 2024-08-26 09:34:58 -04:00
Jarrod Johnson c7d87b755a Add logic to get remote deployers locked into current nic 2024-08-23 18:02:15 -04:00
Jarrod Johnson f0c5ac557f Fix and extend Relay DHCP Support
Relay DHCP support needed better logging and behavior.

It had also broken non-relay clients.
2024-08-23 13:54:27 -04:00
Jarrod Johnson 5d4f0662d1 Fix add_local_repositories for routed IPv4
Routed IPv4 deployment is not guaranteed to have
an IPv6 server.  In this case the safer bet is
to try to just accept the IPv4 anyway.
2024-08-23 07:06:37 -04:00
Jarrod Johnson edc3a3e9f3 Have confignet fallback to unicast per deploycfg
In routed deployments, the scan mechanism
will not be available. Fall back to routed
access to the deploy server as indicated
by deploycfg from install time.
2024-08-22 16:39:52 -04:00
Jarrod Johnson 3d53b76317 Fix relay replies being broadcast instead of unicast 2024-08-22 14:54:48 -04:00
Jarrod Johnson 683a160c20 Amend mistake in parameter name 2024-08-22 10:25:15 -04:00
Jarrod Johnson 82be3c91d5 Add support for relay DHCP
Use the relay DHCP agent information as basis for
subnet comparison instead of self, when present.

Use the candidate prefix length verbatim since the
relay will offer no hint as to the 'proper' prefix
length for the target segment.
2024-08-22 10:20:04 -04:00
Jarrod Johnson 9cf199a53e Merge pull request #160 from Obihoernchen/typo
Fix small typo
2024-08-22 08:42:06 -04:00
Markus Hilger e735a12b3a Fix small typo 2024-08-22 12:38:52 +02:00
Jarrod Johnson cbd457b464 Cancel the recvr task on close
This avoids stail recvr from sending duplicate data.
2024-08-21 09:12:18 -04:00
Jarrod Johnson dd2119c6d9 Ignore very old ssh key file 2024-08-19 16:26:48 -04:00
Jarrod Johnson 4640cb194f Provide workaround for XCC refusal to rename the initial account 2024-08-19 13:28:49 -04:00
Jarrod Johnson fb10221e1b Amend affluent error handling
Be more consistent and informative
2024-08-16 11:26:52 -04:00
Jarrod Johnson d82a982857 Have affluent 'power' status actually at least reaching the service 2024-08-16 10:52:00 -04:00
Jarrod Johnson e6f6919ef4 Merge pull request #96 from weragrzeda/master
i reverted NTP and Eaton, Only Geist PDUs merging
2024-08-16 09:33:01 -04:00
Jarrod Johnson 1a40842f06 Fix osdeploy updateboot to find multiple grub.cfg 2024-08-15 10:54:52 -04:00
Jarrod Johnson 82e0d9c434 Rework ssh key init to reset key and use context management 2024-08-14 16:08:02 -04:00
Jarrod Johnson 83a4df49c7 Merge pull request #159 from adrianreber/2024-08-13-cat-keys
Do not overwrite the node SSH key with the last found public key
2024-08-14 16:04:36 -04:00
Jarrod Johnson c442c8704d Merge remote-tracking branch 'xcat/master' 2024-08-14 11:41:09 -04:00
Jarrod Johnson 28b88bdb12 Add reporting of skipped nodes in a 'skip' merge 2024-08-14 11:40:11 -04:00
Jarrod Johnson 29d0e90487 Implement confluentdbutil 'merge'
For now, implement 'skip', where conflicting nodes/groups are
ignored in new input.
2024-08-14 11:26:51 -04:00
Adrian Reber a6a1907611 Do not overwrite the node SSH key with the last found public key
Instead of overwriting the SSH public code for the node concatenate all
found SSH keys together in one file.

Signed-off-by: Adrian Reber <areber@redhat.com>
2024-08-13 17:30:43 +02:00
Jarrod Johnson ba7a0f7eab Merge pull request #158 from Obihoernchen/vlan
Add VLAN/PKEY support to confignet (fix #157)
2024-08-13 11:10:19 -04:00
Markus Hilger 0961174425 Remove redundant code 2024-08-09 19:55:42 +02:00
Markus Hilger 005adec437 Add error handling for interface_names 2024-08-09 19:45:19 +02:00
Markus Hilger 6943c2dc0f Make sure VLAN/PKEY connections are created last
Needed for VLANs on bond connections etc.
2024-08-09 19:38:45 +02:00
Markus Hilger 6833cd9c53 Add VLAN/PKEY support to confignet
Introduce new node attribute net.vlan_id to support VLAN/PKEY
configuration using confignet.
2024-08-09 17:59:34 +02:00
Jarrod Johnson 8fd39c36bb Fix some mistakes in confignet 2024-08-09 07:55:42 -04:00
Jarrod Johnson 2fc4483bba Backport SLP performance enhancement from async branch
Same concept that could bog down async variant
could be a slowdown for normal confluent.
2024-08-08 17:09:33 -04:00
Jarrod Johnson 4453ba3b64 Add cpio to confluent_server
In order to do osdeploy processing, we must have cpio
2024-08-07 09:20:34 -04:00
Jarrod Johnson ca4955101d Improve "realness" of imgutil exec context
Utilities that expected /dev/pts will now be satisfied,
as a new /dev/pts is mounted.

Further, systemd added a check in various utilities that
was fouled by the previous method of appearing to have a
root filesystem.

Before, after chroot, we would bind mount / to itself, and this
made things using /proc/mounts, /proc/self/mountinfo, df, mount,
etc happy that there is a real looking root filesystem.

However, by doing it after the chroot, systemd could statx on '..' and
get a different mnt id than /. So it had to be done prior to the
chroot.  However it also had to be done before other mounts as
bind mounting over it would block the submounts.

This more closely imitates the initramfs behavior, where '/' starts life
as a 'real' filesystem before being mounted up and switched into.

This behavior was made to imitate the 'start_root.c' behavior as that
seems to be more broadly successful.
2024-08-07 08:40:10 -04:00
Jarrod Johnson 187fda4bb8 Add debootstrap dependency for imgutil 2024-08-07 07:58:08 -04:00
Jarrod Johnson 7ab7600492 Add cpio dependency for imgutil 2024-08-07 07:56:11 -04:00
Jarrod Johnson f2b9a4fa5d Improve handling of ssh service being pre-hooked 2024-08-06 12:25:21 -04:00
Jarrod Johnson ef1f51ef98 Wire in bmc config clear to redfish 2024-08-06 10:05:39 -04:00
Jarrod Johnson 21b1ac7690 Remove asyncore for jammy
asyncore isn't needed before noble
2024-08-06 09:34:46 -04:00
Jarrod Johnson feaef79060 Successfully track credential currency across change 2024-08-06 09:30:13 -04:00
Jarrod Johnson 8c13816331 Fix fetch of model name for XCC3 systems 2024-08-05 15:03:00 -04:00
Jarrod Johnson e07e6ed152 Improve error handling in OpenBMC console 2024-08-05 14:56:23 -04:00
Jarrod Johnson 0afc3eb03a Port SSDP improvements to SLP
It may not apply, but better to be consistent.
2024-08-05 13:12:54 -04:00
Jarrod Johnson 0fd07e8427 Fix race condition in SSDP snoop
If an asynchronous handler is slow to
enroll a target while another target causes an iteration
of the snoop loop, the various modified structures
had been discarded in the interim.

Now persist the data structures iteration to iteration,
using 'clear()' to empty them rather than getting
brand new data structures each loop.
2024-08-05 13:09:50 -04:00
Jarrod Johnson fc5c1aa90f Fix SSDP error during merge 2024-08-05 11:32:57 -04:00
Jarrod Johnson 30c4d6b863 Add IPMI enablement to generic Redfish handler
If attributes indicate desire for IPMI, try to accomodate.
2024-08-05 11:07:50 -04:00
Jarrod Johnson cfb31a0d8d Implement XCC3 discovery
For XCC3, change to generic redfish onboarding mechanism.

Extend the generic mechanism to be more specific in some
ways that the XCC3 is pickier about. However, it's just reiteration
of what should have already have been the case.
2024-08-05 10:00:22 -04:00
Jarrod Johnson e9d4174ce5 Reapply "Add MegaRAC discovery support for recent MegaRAC"
This reverts commit 9d979256eb.
2024-08-05 08:35:10 -04:00
Jarrod Johnson ed33b4e93f Merge branch 'megaracdisco' into v4xcc 2024-08-05 08:31:47 -04:00
Jarrod Johnson 4b6d41d2f8 Begin work to support V4 Lenovo servers
V4 Lenovo servers will have XCC3, and will have differences
and mark an unambiguously redfish capable onboarding process.

For now identify XCC3 variants and mark them, stubbing them
to the xcc handler.

An XCC3 handler will be made basing on the generic redfishbmc handler
with accomodations for XCC specific data (e.g. DeviceDescription
attributes and the Lenovo default user/password choice).
2024-08-02 17:35:39 -04:00
Jarrod Johnson acce4de739 Add support for an OpenBMC modification
While stock OpenBmc does not care about subprotocols,
some implementations use it as a carrier for the XSRF-TOKEN.

Since base OpenBmc ignores it, we just offer it to any implementation
just in case.
2024-08-02 11:57:04 -04:00
Jarrod Johnson 89bd7c6053 Force load IB/OPA modules in case of IB boot
Ubuntu diskless was not working with boot over IB
2024-08-01 09:40:39 -04:00
Jarrod Johnson 71ca9ef76c Fix path to ntp servers in user-data mod for ubuntu 2024-07-29 15:57:34 -04:00
Jarrod Johnson 1c4f1ae817 Try to add ntp and timezones to Ubuntu scripted install 2024-07-29 15:21:10 -04:00
Jarrod Johnson e6dc383d25 Fix mistake in EL8/EL9 LUKS 2024-07-29 11:22:07 -04:00
Jarrod Johnson 329f2b4485 Amend cryptboot implementation for Ubuntu 22/24, EL8/EL9
Provide mechanism for administrator to place a custom
key for potential interactive recovery into
/var/lib/confluent/private/os/<profile>/pending/luks.key

If not provided, generate a unique one for each install.

Either way, persist the key in /etc/confluent/luks.key, to
facilitate later resealing if the user wants (clevis nor systemd
prior to 256 supports unlock via TPM2, so keyfile is required
for now).

Migrating to otherwise escrowed passphrases and/or sealing to
specific TPMs will be left to operators and/or third parties.
2024-07-29 10:17:14 -04:00
Jarrod Johnson bee9f18197 Tolerate / in the apikey for LUKS setup
The apikey is highly likely to have a /, and so we need to use something
not in the base64 alphabet as a delimiter.
2024-07-26 17:59:42 -04:00
Jarrod Johnson 1af898dcb8 Fix encryptboot on EL8/EL9 2024-07-26 17:43:51 -04:00
Jarrod Johnson 332068074d Extend systemdecrypt hook to support Ubuntu 24.04
Ubuntu 240.4 systemd-cryptsetup now has an external dependency.
2024-07-26 16:54:58 -04:00
Jarrod Johnson 2df902e80e Remove luks password from argv
Pass the luks password by environment variable instead.
2024-07-26 14:07:54 -04:00
Jarrod Johnson 7a602f58b2 Fixes for ubuntu profile tpm support 2024-07-26 13:47:13 -04:00
Jarrod Johnson c563f48c71 Fix assignment of lukspass variable. 2024-07-26 12:30:41 -04:00
Jarrod Johnson c1747ad24c Correct spelling of key for luks check 2024-07-26 11:54:10 -04:00
Jarrod Johnson 1ddf735590 Fix omitted argument to addcrypt 2024-07-26 11:50:53 -04:00
Jarrod Johnson f482d2ead9 Amend crypt hook check
The comment was changed, check for password instead.
2024-07-26 11:35:49 -04:00
Jarrod Johnson 58ee85f39e Rework Ubuntu addcrypt support
The comment based hook is destroyed during early install process.

Use python to manipulate the autoinstall file in a more sophisticated way.

Also refactor the initramfs hook material to be standalone files.
2024-07-26 11:33:01 -04:00
Jarrod Johnson 1d6009a2f2 Switch to using systemd-cryptenroll
The design more cleanly uses luks slot, but
requires providing initramfs hooks.

Those hooks are provided now.
2024-07-26 10:33:38 -04:00
Jarrod Johnson 6d15633a95 Merge branch 'master' into ubuntucryptboot 2024-07-25 15:57:00 -04:00
Jarrod Johnson dc7c9f4a3d Have SSDP fallback to unverified noderanges when looking at candidates 2024-07-25 15:26:23 -04:00
Jarrod Johnson 956e473fa6 Have SSDP fallback to unverified noderanges when looking at candidates 2024-07-25 15:25:09 -04:00
Jarrod Johnson 626f16cb6f Ignore duplicate specifications of same key
Particularly if traversing a lot of linked configuration, the same key/cert
path may come up multiple times, check for equality
and if equal, just keep going.
2024-07-25 14:55:06 -04:00
Jarrod Johnson 30aa6f382c Ignore duplicate specifications of same key
Particularly if traversing a lot of linked configuration, the same key/cert
path may come up multiple times, check for equality
and if equal, just keep going.
2024-07-25 14:54:15 -04:00
Jarrod Johnson fe6d44a4bb Merge pull request #153 from Obihoernchen/json-dump-sort
Use natural sort for lists in json dumps
2024-07-25 14:15:15 -04:00
tkucherera fa940579f1 adding webathn-rp dependency 2024-07-25 14:07:27 -04:00
Jarrod Johnson 298be3b30a Point to the C context object rather than python class
The OpenSSL variant of Context is a python class, but it does have
a C context in it.
2024-07-25 14:05:59 -04:00
Jarrod Johnson 80296b6cbc Point to the C context object rather than python class
The OpenSSL variant of Context is a python class, but it does have
a C context in it.
2024-07-25 14:05:10 -04:00
Markus Hilger 41b722c3f7 Use natural sort for lists in json dumps
Previously, items were randomly arranged in lists in the json dump. This meant that the JSON files were different after each export.
Now they are naturally sorted and identical.
This should make it easier to save and compare the JSON dumps in version control systems.
2024-07-25 18:38:23 +02:00
Jarrod Johnson 0f955cd068 Begin work on a cryptboot support for ubuntu
Start implementing a tpm2-initramfs-tool based approach.

This requires a bit of an odd transition as the PCR 7 is likely
to change between the install phase and the boot phase, so
we have to select different PCRs, but that requires
an argument to pass that crypttab does not support.
2024-07-25 11:24:41 -04:00
Jarrod Johnson c3e918fc5f Fix mistake in untethered support 2024-07-25 09:42:24 -04:00
Jarrod Johnson 8f1a1130a8 Add a selfcheck to check misdone collective manager 2024-07-24 15:55:04 -04:00
Jarrod Johnson 6e8d8dabd1 Fix whitespace issue 2024-07-24 15:28:03 -04:00
Jarrod Johnson a92edc7924 Apply ownership sanity check even for root
User could accidently run 'confluent' in a way that makes no sense,
block it the most accessible way.

The pid file should have blocked it, but systemd purges the directory
even on failure.
2024-07-24 15:20:02 -04:00
Jarrod Johnson 714fefe31b Fix unethered boot for ubuntu 2024-07-24 14:41:39 -04:00
Jarrod Johnson c91af840e5 Robust handling of relative link resolv.conf
resolv.conf may be a relative link, normal file, or absolute link.

Handle all cases.
2024-07-24 11:12:31 -04:00
Jarrod Johnson 2235faa76d Stop using private interface of PyCA
PyCA changes their minds about which bindings to include.

So make the binding ourselves since PyCA removed it in certain versions.

This is a backport of the implementation from the async port effort.
2024-07-24 08:33:20 -04:00
Jarrod Johnson 8f58567a70 Add ssh to default services of a built ubuntu image 2024-07-23 11:05:51 -04:00
Jarrod Johnson cf4475cfcc Escape the '\W' to avoid stepping on python processing 2024-07-23 10:23:05 -04:00
Jarrod Johnson a94b9235e8 Tighten umask on confignet to avoid ubuntu warnings 2024-07-23 10:14:32 -04:00
Jarrod Johnson bb04faed04 Explicitly request bash under ubuntu, which tends to use dash 2024-07-23 10:01:53 -04:00
Jarrod Johnson 33ed1a5e64 Add onboot for ubuntu diskless 2024-07-23 09:32:20 -04:00
Jarrod Johnson 1ade704daa Fix imgutil copy of ubuntu sources 2024-07-22 16:40:44 -04:00
Jarrod Johnson 34b03da494 Update for Ubuntu 24.04 diskless 2024-07-22 16:33:07 -04:00
Jarrod Johnson 4f18294d93 Fix path in debian build for imgutil 2024-07-22 13:57:38 -04:00
Jarrod Johnson 7154a1d60c Add control file for deb build of imgutil 2024-07-22 13:47:36 -04:00
Jarrod Johnson 69fa3f10c0 Add deb packaging of imgutil 2024-07-22 13:47:29 -04:00
Jarrod Johnson 36ca68f44d Add control file for deb build of imgutil 2024-07-22 13:46:45 -04:00
Jarrod Johnson ede941c0d9 Add deb packaging of imgutil 2024-07-22 13:46:27 -04:00
Jarrod Johnson 294ef8e88c Fix for IB diskless boot to install clone
The infiniband section must be defined for the OS
to use the IB link. If it is missing then networking
does not come up during firstboot.

Fix this by having an inifiniband section including explicitly
declaring use of datagram mode. This should suffice for all
install use cases, and may be changed after firstboot starts.
2024-07-19 09:28:29 -04:00
Jarrod Johnson b61e5fb1ff Merge pull request #151 from Obihoernchen/el-stateful-fix
Fix EL stateful install
2024-07-18 13:06:12 -04:00
Markus Hilger b4a33b8102 Fix EL stateful install
Sometimes stateful install can fail if vgchange -a n is run after dd.
Use wipefs instead and fix order of both commands.
Furthermore, use the $INSALLDISK variable.
2024-07-18 17:35:39 +02:00
Jarrod Johnson 9d5432f8cd Fix network configuration when middle name ends in 'net' 2024-07-18 08:40:40 -04:00
Jarrod Johnson abf12f2b96 Reinstate linuxefi/initrdefi for older GRUB
Technically, Grub never had 'linuxefi/initrdefi' commands
officially, so this is a bit weird.

However, if we see signs of GRUB older than 2.03, we will assume
that is requires the linuxefi/initrdefi commands from
the out of tree patch to support EFI the old way.

This corresponds with EL7.  Other variants seem ok with
the more proper linux/initrd command names.
2024-07-15 11:26:58 -04:00
Jarrod Johnson 5d08919769 Merge pull request #150 from tkucherera-lenovo/nodebmcpasswordUpdate
better error handling
2024-07-15 09:30:22 -04:00
tkucherera 8d726bced9 better error handling 2024-07-15 09:22:59 -04:00
Jarrod Johnson 945dff09f3 Change to generic linux/inird command in Grub
Modern grub has removed these variants, and should only be required for very old non-EFI stub kernels
2024-07-15 08:19:13 -04:00
Jarrod Johnson 7a3e1dfde3 Fix grub fallback path for more grub 2024-07-12 16:48:46 -04:00
Jarrod Johnson c0cc673c63 Make directory exist before creating file 2024-07-12 16:31:06 -04:00
Jarrod Johnson 3aea1ec7d6 Fix list syntax in grub cfg 2024-07-12 16:21:36 -04:00
Jarrod Johnson 08a5bffa90 Write multiple grub.cfg paths
Some have different requirements on how to find grub.cfg
2024-07-12 15:52:49 -04:00
Jarrod Johnson 8c193fe33f Fix issues with firstboot on Ubuntu 22+ 2024-07-12 15:30:47 -04:00
Jarrod Johnson bc624d9360 Fix Ubuntu 24.04 network bring up
Ubuntu 24.04 does not check conf files in /run before assuming dhcp anymore.

Influence its logic to skip dhcp if we have static for it
2024-07-12 15:15:56 -04:00
Jarrod Johnson 7bd41af2cc More properly error on bad requests
Avoid incurring an error code 500 issue in reaction to certain
bad request data.
2024-07-09 08:41:34 -04:00
Jarrod Johnson 4f21e62705 Fix typo in the auth code 2024-07-08 10:02:03 -04:00
Jarrod Johnson dde6ceadfb Allow local ISO to proceed if detected with Ubuntu 2024-07-03 14:36:54 -04:00
Jarrod Johnson 9d979256eb Revert "Add MegaRAC discovery support for recent MegaRAC"
This reverts commit 07005d83ca.

Premature addition to master branch
2024-06-27 11:36:41 -04:00
Jarrod Johnson 8ec836f492 Merge branch 'master' into megaracdisco 2024-06-27 11:36:08 -04:00
Jarrod Johnson 07005d83ca Add MegaRAC discovery support for recent MegaRAC
Create a generic redfish discovery and a MegaRAC specific
variant.

This should open the door for more generic common base redfish discovery
for vaguely compatible implementations.  For now, MegaRAC only
overrides the default username and password (which is undefined
in the redfish spec).

Also, have SSDP recognize the variant, and tolerate odd nonsense
like SSDP replies coming from all manner of odd port numbers (no
way to make a sane firewall rule to capture that odd behavior,
but at application level we have a chance).
2024-06-27 11:25:33 -04:00
Jarrod Johnson 411b2fae49 Merge remote-tracking branch 'lenovo/master' 2024-06-25 16:26:55 -04:00
Jarrod Johnson 762a8ee73f Correct proxyDHCP buffer use
It was possible for proxyDHCP to look past the network designated end of packet.
Fix this by consistently using the memoryview that was trimmed to size.
2024-06-25 16:25:19 -04:00
tkucherera c678510b02 working webauthn backend 2024-06-25 14:37:10 -04:00
Jarrod Johnson f2d9c3868b Draft work on MegaRAC out of band discovery 2024-06-24 15:56:26 -04:00
Jarrod Johnson 9715247cc6 Merge pull request #97 from sjtstg/dev-enos-plugin
Add ENOS management plugin
2024-06-21 13:07:00 -04:00
Simon Thompson 166e4599b9 add enos management plugin 2024-06-21 18:35:10 +02:00
Simon Thompson d231326dfb add class to run cmd by ssh 2024-06-21 18:34:47 +02:00
Jarrod Johnson 162e4d1d1e Add retry logic for the el8 identity image support
This allows slow linking interfaces to come up rather than being missed
2024-06-15 15:43:13 -04:00
Jarrod Johnson 8e407cb96e Correct mistake with confluent uuid copy-in in copernicus 2024-06-14 11:21:46 -04:00
Jarrod Johnson d06be55568 Add dependencies for Ubuntu Noble 2024-06-11 15:51:02 -04:00
Jarrod Johnson 8db6382629 Change autoversion scheme for dev builds
We need to be compliant with python versioning for the
tools to keep working
2024-06-11 09:25:57 -04:00
Jarrod Johnson 663b320868 Add more bounds checking in copernicus 2024-06-07 12:43:15 -04:00
Jarrod Johnson 517242df47 Avoid double run of driver disk content 2024-06-07 11:36:39 -04:00
Jarrod Johnson c6adf8175a Try processing driver disks before udevadm invocation 2024-06-07 11:03:00 -04:00
Jarrod Johnson 38a95131f9 Add more error handling in vtbufferd 2024-06-07 09:36:18 -04:00
Jarrod Johnson 5d416cb1b1 Remove disused dependency list 2024-06-06 11:23:28 -04:00
Jarrod Johnson 451e3ba224 Add nodeapply man page 2024-06-06 09:02:45 -04:00
Jarrod Johnson 6564f8de72 Update license material 2024-06-05 08:39:37 -04:00
Jarrod Johnson bb414524ad Add fallback if timedatectl can't run. 2024-05-30 08:14:58 -04:00
Jarrod Johnson bab0a77cb6 Refresh to CentOS stream 9 2024-05-23 15:15:37 -04:00
Jarrod Johnson 010c8a0a23 Amend EL network bringup
One issue is that there are multiple networkmanager connections,
clean this up, though this seems not to be a functional issue.

However, sometimes the lldpad usage screws up network configuration,
disable the facility by forcibly disabling fcoe sincec that is what triggers lldpad.
wq
2024-05-22 15:45:24 -04:00
Jarrod Johnson c0bcc3791d Fix handling some eatonpdu return values 2024-05-15 12:30:36 -04:00
Jarrod Johnson 172c57c6f1 Fix media location search for EL8
EL8 distributions marked the 'OS' as dracut, workaround by trying to use PRETTY_NAME
2024-05-15 12:29:32 -04:00
Jarrod Johnson 91dce25a8b Merge pull request #149 from tkucherera-lenovo/updateAttrib
check update args before setting anything
2024-05-09 08:52:22 -04:00
Jarrod Johnson 62be16442c Fix passive detection of SLP devices (e.g. SMM)
A mistake in the python3 port caused passive SLP
detection to break. Remedy that mistake.
2024-05-08 11:51:00 -04:00
Jarrod Johnson d0e73c887b Load firewall before esxi installation begins
Parts of esxi install depend on firewall running.  When
we are done with 'odd' networking, restore firewall
to meet that expectation.
2024-05-07 10:06:57 -04:00
Jarrod Johnson b7a5101a34 Provide extra warning about redoing SSH materials 2024-05-03 10:27:01 -04:00
tkucherera 930ff3e20d fix error message 2024-05-02 10:41:30 -04:00
tkucherera 39fb229ef1 check update args before setting anything 2024-05-02 10:29:20 -04:00
Jarrod Johnson 60f8f964f5 Merge pull request #144 from tkucherera-lenovo/nodebmcpassword
nodebmcpassword
2024-04-29 10:50:09 -04:00
tkucherera 8f01f22bb5 add password prompting and env var 2024-04-24 10:00:49 -04:00
Wera Grzeda d779f015d6 sed to use single quotes 2024-04-23 18:14:48 +02:00
Wera Grzeda bf004fb7b9 cleaned geist.py 2024-04-23 15:53:35 +02:00
Wera Grzeda 21b8534fef Revert "my changes to Eaton PDU sensors"
This reverts commit 6d87d11f5e.
2024-04-23 15:29:35 +02:00
Wera Grzeda 3b69c54203 Revert "new eaton pdu power readings"
This reverts commit ac68f1f22c.
2024-04-23 15:08:36 +02:00
Wera Grzeda 9954b227a9 Revert "nodeconfig ntp servers for smms"
This reverts commit 44405baaf3.
2024-04-23 15:06:28 +02:00
weragrzeda c0891faaeb Merge branch 'lenovo:master' into master 2024-04-23 14:59:57 +02:00
Jarrod Johnson 86e612b4bf Move anaconda netroot to not be specified in media sourced
When sourcing from media, do not trigger anaconda netroot
behavior.
2024-04-22 12:47:52 -04:00
Jarrod Johnson 6f2be355ef Source from "local" media if present
Some environments may want to load the bulk of the
media via USB rather than over the network. This prefers
that source if that scheme is detected.
2024-04-22 11:32:27 -04:00
Jarrod Johnson b606882327 Have collate preserve relative whitespace
The change to tolerate either a space or no space ended up
greedily consuming whitespace.  Do best possible in two cases:

For log, use the first line as a clue, and consistently pad or not pad
according to first line.  It won't catch different pad strategies, or
handle first line being indented but other lines not being indented.

For the textgroup variant, allow subsequent lines to revise the
pad downward, and accept any whitespace, not just space.
2024-04-19 08:22:32 -04:00
Jarrod Johnson 10f0fabb8c Fix nodegroup retrieval
nodegroup information was broken by clear warning support.
2024-04-17 15:18:45 -04:00
Jarrod Johnson 0d3e2cee6c Merge pull request #146 from tkucherera-lenovo/sample-postscrits
sample post scripts directory
2024-04-16 09:14:56 -04:00
tkucherera 3b55f500ce sample post scripts directory 2024-04-16 03:16:15 -04:00
Jarrod Johnson 3ba3394a54 Fix None return by exec_on_leader with warnings 2024-04-12 17:32:13 -04:00
Jarrod Johnson a6a2f2f2de Fixes for attribute clear warning behavior
Correct collective behavior for failing to clear on followers.

Also, connect the warnings from the leader to the member issuing the
RPC.
2024-04-12 11:46:17 -04:00
Jarrod Johnson 8e5ee6c9d8 Make orphaned sync runner retire on new sync request 2024-04-10 13:54:06 -04:00
Jarrod Johnson ceaf641c1a Keep reap loop going on error 2024-04-09 16:18:24 -04:00
Jarrod Johnson 01722c18c4 Fix location of idle sleep in syncfiles cleaner 2024-04-09 15:40:40 -04:00
Jarrod Johnson 8fb889ba73 Correct syntax error 2024-04-09 15:27:20 -04:00
Jarrod Johnson eaffb342b2 Reap stale sync runners after a minute dead
If the client never claims the result, delete the sync task.
2024-04-09 15:19:38 -04:00
Jarrod Johnson 1da27083cc Another cleanup of syncfileclient output 2024-04-09 15:08:56 -04:00
Jarrod Johnson 67b3c48dc9 Clean up error output on syncfileclient execution 2024-04-09 14:58:38 -04:00
Jarrod Johnson 8ca9a44476 Provide more interesting response body to syncfileclient 2024-04-09 14:27:00 -04:00
Jarrod Johnson 02f301b5d0 Fix mistakes in syncfileclient change 2024-04-09 13:41:27 -04:00
Jarrod Johnson 33271451d7 Support SHA384 if used as fingerprint 2024-04-09 13:17:19 -04:00
Jarrod Johnson f68f9f4693 Make syncfile step robust or pause
If syncfiles fails, keep it retrying.

Also, slow down sync checking to avoid hammering the system.

Further, randomized delay to spread highly synchronized requestors.

Block attempts to do multiple concurrent syncfile runs.
2024-04-09 11:07:11 -04:00
Jarrod Johnson a4e152c17d Defer disarm until after successful client notification
It is theoretically possible for a client to get disconnected
right in the middle. In such a scenario, err on the side of letting
the mechanism stay armed for the sake of a retry being possible.
2024-04-09 10:31:46 -04:00
tkucherera 272c456435 nodebmcpassword man page 2024-04-03 18:50:46 -04:00
tkucherera 894290f577 nodebmcpassword 2024-04-03 18:46:37 -04:00
Jarrod Johnson 34804b2d5f Provide components for cert management with modern XCC
Refresh getcsr and installcert to handle latest firmware.

Also add ability to have pre-existing CSR, and trust the SAN on the way through.

If this becomes more properly a feature, then would likely impose a SAN
on certs, similar to the SSH principals, rather than deferring to the CSR
to get it right.
2024-04-01 12:13:21 -04:00
Jarrod Johnson 77bb03e96c Merge tag '3.9.3'
Numerous bugfixes
2024-03-29 16:24:48 -04:00
Jarrod Johnson 12bb5d583a Correct the equality message in better messagesw 2024-03-27 08:40:01 -04:00
Jarrod Johnson 03bdbfc8ed Provide more useful error messages on mistakes within [] 2024-03-27 08:39:48 -04:00
Jarrod Johnson 661b2ae815 Filter out nvme 'c' devnames, that are used to refer to paths to nvme
Some versions start manifesting nvme devnames with 'c', which
are to be used to interact with multipath to have raw devices
backing a traditional nvme device.
2024-03-27 08:38:36 -04:00
Jarrod Johnson ddb8c4cce4 Fix a few noderange abbreviations
Also, add some test cases on abbreviation
to help sanity check things in the future.
2024-03-27 08:37:51 -04:00
Jarrod Johnson 17fff4997b Fix omission of info dir in plugins 2024-03-27 08:36:54 -04:00
Jarrod Johnson 7b3129a1a2 Fix FFDC preflight checks
The code was comparing two string constants, instead of
a variable to a constant.  Correct the problem to enable
the preflight checks to work as intended.
2024-03-27 08:36:11 -04:00
Jarrod Johnson d183a3f99c Fix problem where one multicast/broadcast attempt could tank other interfaces
Carrying over change from ssdp, ignore failures on transmit, particularly if
firewall
2024-03-27 08:35:52 -04:00
Jarrod Johnson b3b3627bf9 Remove disused bufferlock
We no longer use a lock on buffer communication, eliminate
the stale variable.
2024-03-27 08:34:36 -04:00
Jarrod Johnson c1afc144cb Change to unix domain for vtbuffer communication
The semaphore arbitrated single channel sharing
was proving to be too slow.  Make the communication
lockless by having dedicated sockets per request.
2024-03-27 08:34:31 -04:00
Jarrod Johnson ac1f7c57b6 Fix lldp when peername is null
Some neighbors result in a null name, handle that.
2024-03-27 08:33:50 -04:00
Jarrod Johnson 19e9c6910d Fix nodeapply redoing a single node multiple times 2024-03-27 08:33:35 -04:00
Jarrod Johnson e38cd5d3e5 Fallback to unverified noderange on candidate manager check in PXE
When doing pxe and the noderange of the candidate managers fails,
try again without validation in case the user omitted collective members
from nodelist, but still used ',' to enumerate them.
2024-03-27 08:31:44 -04:00
Jarrod Johnson f1d3e47439 Logout prior to renaming user
Some firmware cannot tolerate a web session being
active during a rename.  Make sure logout has been done, and
give a retry if needed to let the session close out after
logging out.
2024-03-27 08:31:06 -04:00
Jarrod Johnson f7a2e51f9c fstab fixup for hyphenated lvm vg names 2024-03-26 10:31:29 -04:00
Jarrod Johnson f3d0bd9079 Merge pull request #142 from tkucherera-lenovo/l2traceroute
L2traceroute
2024-03-25 08:06:52 -04:00
tkucherera 296a0e88b4 making the use cases more generic 2024-03-24 11:41:23 -04:00
Jarrod Johnson c60bf68cbc Logout prior to renaming user
Some firmware cannot tolerate a web session being
active during a rename.  Make sure logout has been done, and
give a retry if needed to let the session close out after
logging out.
2024-03-22 12:56:09 -04:00
tkucherera 466ed74961 l2traceroute 2024-03-22 11:37:51 -04:00
tkucherera 838c0920eb l2traceroute 2024-03-22 11:37:12 -04:00
Jarrod Johnson 6ad0e773de Actually have the vformat override return
Performing the super() is hardly helpful if it
doesn't actually copy the return behavior.
2024-03-21 16:28:49 -04:00
Jarrod Johnson 5a7d98c6b8 Enhance error reporting
For one, when using confluent expressions, induce {} to be an error to
trigger an error for someone trying to xargs something.

Another is to add warnings when clear does something deliberately, but
is something that might surprise a user, steering them toward
what they possibly might want to do instead.
2024-03-21 16:09:37 -04:00
Jarrod Johnson 13fc5d9f37 Capture better error data on failed syncfiles
syncfiles can often hang up in unexpected ways,
provide a catch-all.
2024-03-20 09:49:25 -04:00
Jarrod Johnson 559e88b144 Correct vgname for hyphenated node names 2024-03-19 09:41:20 -04:00
Jarrod Johnson 5f801e6683 Correct syntax error in ubuntu arm profile init 2024-03-18 12:45:25 -04:00
Jarrod Johnson 7a6b03097b Fixup Ubuntu 22 ARM support 2024-03-18 12:24:25 -04:00
Jarrod Johnson 6502573d90 Bring ubuntu 22 versions of firstboot and post to 20 2024-03-18 09:15:11 -04:00
Jarrod Johnson 3dd09b95e4 Fix Ubuntu 20 pre script to match 22 2024-03-18 09:13:53 -04:00
Jarrod Johnson a595d31e94 Explicitly invoke bash for ubuntu post
Ubuntu really tries to use non-bash, explicitly use bash when we need it.
2024-03-18 08:56:06 -04:00
Jarrod Johnson b157e55f00 Fallback to unverified noderange on candidate manager check in PXE
When doing pxe and the noderange of the candidate managers fails,
try again without validation in case the user omitted collective members
from nodelist, but still used ',' to enumerate them.
2024-03-15 15:50:58 -04:00
Jarrod Johnson 60fe306890 Numerous fixes
Normalize cloning by wipefs prior to image2disk

Have imgutil filter out zram mounts.

Fix syncfiles error handling.
2024-03-15 13:03:46 -04:00
Jarrod Johnson bd2288ccb7 Ensure preservation of " if rename fails
If ent would swallow a ", make sure to put it back.
2024-03-15 12:29:37 -04:00
Jarrod Johnson 789376029d Numerous fixes to the EL9 cloning
Fix various callbacks when using IPv6 based deployment.

Do not attempt to restore erroneously cloned zram partitions.

Convert LVM names to new LVM names consistent with source naming scheme.

Push new kernel command line into /boot/loader and /etc/kernel/cmdline.
2024-03-15 09:57:23 -04:00
Jarrod Johnson 1d4505ff3c SSH test by IP, to reflect actual usage and catch issues
One issue is modified ssh_known_hosts wildcard customization
failing to cover IP address.
2024-03-14 11:21:41 -04:00
Jarrod Johnson 876b59c1f0 Remove redundant kill on the agent pid
Extraneous kill on the agent pid is removed.
2024-03-14 10:52:52 -04:00
Jarrod Johnson 58d9bc1816 Updates to confluent_selfcheck
Reap ssh-agent to avoid stale agents lying around.

Remove nuisance warnings about virbr0 when present.

Do a full runthrough as the confluent user to ssh to a node when user
requests with '-a', marking known_hosts and automation key issues.
2024-03-14 10:50:26 -04:00
Jarrod Johnson 17af9c74b8 Fix nodeapply redoing a single node multiple times 2024-03-12 15:33:31 -04:00
Jarrod Johnson 0d720baf25 Fix lldp when peername is null
Some neighbors result in a null name, handle that.
2024-03-12 09:37:36 -04:00
Jarrod Johnson 49e614eb32 Have image2disk delay exit on error
Debugging cloning is difficult when system immediately reboots on error.
2024-03-11 17:11:44 -04:00
Jarrod Johnson cdefb400f9 Expose fingerprinting and better error handling to osdeploy
This allows custom name and pre-import checking.
2024-03-11 13:33:15 -04:00
Jarrod Johnson 3ffeef5cf3 Fix stray blank line at end of nodelist
Wrong indentation level for nodelist resulting in
spurious line.
2024-03-06 16:27:09 -05:00
Jarrod Johnson 5ae3f4c62a Properly address runansible error relay 2024-03-06 09:28:24 -05:00
Jarrod Johnson 2f8dfac9bc Dump stderr to client if ansible had an utterly disastrous condition 2024-03-06 09:27:31 -05:00
Jarrod Johnson 75db6da621 Opportunisticlly use sshd_config.d when detected 2024-03-04 08:16:18 -05:00
Jarrod Johnson fa5b1c671e Remove disused bufferlock
We no longer use a lock on buffer communication, eliminate
the stale variable.
2024-02-22 15:07:51 -05:00
Jarrod Johnson 72e26caf36 Change to unix domain for vtbuffer communication
The semaphore arbitrated single channel sharing
was proving to be too slow.  Make the communication
lockless by having dedicated sockets per request.
2024-02-22 15:07:42 -05:00
Jarrod Johnson 21f691cbd8 Correct the equality message in better messagesw 2024-02-13 16:00:50 -05:00
Jarrod Johnson d07e6f86c0 Provide more useful error messages on mistakes within [] 2024-02-13 15:58:08 -05:00
Jarrod Johnson 3a0172cccc Make indirect PDU operations concurrent
Similar to the enclosure reseat work, have indirect
PDU operations be made concurrent across PDUs, though
still serial within a PDU.
2024-02-02 10:35:47 -05:00
Jarrod Johnson 59a31d38a2 Make reseat concurrent
Spawn reseat activity concurrently between chassis.  This should
reduce time to nodes per chassis rather than total nodes.
2024-02-02 08:51:12 -05:00
Jarrod Johnson a17695ad06 Extend confluent PXE support
For relay agent options, preserve and echo back the option,
needed for certain environments.

Also, it turns out that for whatever reason on some platforms, iPXE's
proxyDHCP logic can't seem to get a reply.  In this scenario,
provide the filename in the DHCP offer without waiting for proxyDHCP.

This change may be worth evaluating more broadly, but may carry risk of not working
right with unmanaged DHCP servers.
2024-02-01 16:38:04 -05:00
Jarrod Johnson 7377c44e0f Fix problem where one multicast/broadcast attempt could tank other interfaces
Carrying over change from ssdp, ignore failures on transmit, particularly if
firewall
2024-02-01 08:50:44 -05:00
Jarrod Johnson fc82021f2b Add missing ubuntu24.04 to packaging 2024-01-30 15:04:04 -05:00
Jarrod Johnson 9ad9912ef1 Change to pre-made links for ubuntu24.04 2024-01-30 14:28:11 -05:00
Jarrod Johnson 7618fa8b63 Add diskless links 2024-01-30 14:21:25 -05:00
Jarrod Johnson 170e585e57 Add preliminary ubuntu 24.04 support 2024-01-30 13:53:59 -05:00
Jarrod Johnson 72cace5a50 More thoroughly wire up custom name
Have custom name go through to actual import and influence profile names
2024-01-30 11:11:27 -05:00
Jarrod Johnson d0373977b3 Fix FFDC preflight checks
The code was comparing two string constants, instead of
a variable to a constant.  Correct the problem to enable
the preflight checks to work as intended.
2024-01-30 09:08:28 -05:00
Jarrod Johnson f03525aac5 Merge pull request #141 from tkucherera-lenovo/defaultWebUI
opening web ui using default ip
2024-01-29 16:56:13 -05:00
tkucherera fcb3d917db use socket.getaddrinfo 2024-01-26 17:14:04 -05:00
tkucherera 16ad4e776f opening web ui using default ip 2024-01-26 12:39:25 -05:00
Jarrod Johnson 87454c1ab1 Start browserfs if not yet running 2024-01-26 09:31:59 -05:00
Jarrod Johnson fa3e1202c4 Relax systemd device policy to allow /dev/fuse access 2024-01-26 09:24:41 -05:00
Jarrod Johnson 41675e528f Amend dhcp license path 2024-01-24 15:31:27 -05:00
Jarrod Johnson a3d386dc39 Add NOTICE gathering for some genesis packages 2024-01-24 14:47:23 -05:00
Jarrod Johnson e5051408e5 More license handling 2024-01-23 15:02:08 -05:00
Jarrod Johnson fa7cd2940e More license updates for genesis 2024-01-23 14:39:32 -05:00
Jarrod Johnson e5736ecb51 Update license assets in genesis 2024-01-23 14:18:25 -05:00
Jarrod Johnson b90718982e Implement a number of OS deployment management enhancements.
Add capability to fingerprint media without doing a full import (/deployment/fingerprinting/)

Add fetching the profile info as json under the /deployment/ api.

Prepare to support custom distribution name on import
2024-01-22 17:22:47 -05:00
Jarrod Johnson 07a7357c87 Merge remote-tracking branch 'xcat/master' 2024-01-22 10:40:23 -05:00
Jarrod Johnson dec7454866 Merge branch 'browserfs' 2024-01-22 10:39:35 -05:00
Jarrod Johnson bcc631f88d Set static hostname in diskless boot 2024-01-22 10:39:17 -05:00
Jarrod Johnson 9203ac32e9 Start work on browserfs concept
This will allow WebUI reactivity even with large files for import.
2024-01-17 17:01:49 -05:00
Jarrod Johnson 141760ea19 Merge pull request #140 from henglikuang/boot_order_issue
Fix efivars handling of unexpected unmount
2024-01-17 08:20:17 -05:00
Jarrod Johnson c7628a3638 Merge pull request #139 from henglikuang/master
Add default time zone as UTC
2024-01-17 08:19:55 -05:00
Jarrod Johnson 5fdd6973f1 Update with more license content 2024-01-16 11:11:53 -05:00
Jarrod Johnson 07f91d792a Fix omission of info dir in plugins 2024-01-12 10:52:49 -05:00
Jarrod Johnson 56b644ead9 The 3rd party monotonic is no longer needed 2024-01-11 16:30:45 -05:00
henglikuang1 ea88ccb0ad Fix efivars handling of unexpected unmount 2024-01-11 14:31:45 +08:00
henglikuang1 382feea68d Add default time zone as UTC 2024-01-11 11:44:25 +08:00
Jarrod Johnson 0dfe66f1b2 Fix overzealous reaping of '-lib' folders 2024-01-09 16:08:49 -05:00
Jarrod Johnson cfccb046bc Correct syntax error in draft attempt 2024-01-09 13:36:55 -05:00
Jarrod Johnson 70f91d59b2 Update license material in gathering genesis 2024-01-09 13:32:54 -05:00
Tinashe Kucherera 0016d940e3 Merge branch 'xcat2:master' into firwareUpdateServer 2024-01-04 14:12:51 -05:00
Jarrod Johnson 4d63908164 Have a fallback height of 1 for any missing height 2024-01-04 11:17:02 -05:00
Jarrod Johnson 39c00323b3 Fix error where layout would bail if a partial error were encountered 2024-01-03 15:58:24 -05:00
Jarrod Johnson b0e23121a8 Add stub resize handler
For uninitialized console handlers, provide a stub
to do nothing on resize.

This avoids such a request crashing a shared websocket session.
2024-01-03 15:03:49 -05:00
Jarrod Johnson 85629dea64 Prevent unitiailized collective info
When doing proxyconsole, don't land in a useless retach
loop when managerinfo is None.
2023-12-07 14:45:19 -05:00
Jarrod Johnson 93269a05eb Fix cloning with ipv6 and EL9 2023-12-06 17:06:09 -05:00
Jarrod Johnson 7aef012a42 Correct string join syntax in confignet 2023-12-05 14:39:36 -05:00
Jarrod Johnson 7b89054b35 Fix a few noderange abbreviations
Also, add some test cases on abbreviation
to help sanity check things in the future.
2023-12-01 15:55:39 -05:00
Jarrod Johnson 3e7cdd1caa Merge pull request #138 from mslacken/suseInstall
disable online repos for openSUSE leap
2023-12-01 08:49:42 -05:00
Christian Goll 3aa91b61e5 disable online repos for openSUSE leap
online repositories may not be accesible for the cluster
nodes but were added from the content.xml. Editing this
files with initprofile.sh is impossible as they are executed
in parallel, so all repos starting with
https?://download.opensuse.org
are removed during post

Signed-off-by: Christian Goll <cgoll@suse.com>
2023-12-01 10:57:31 +01:00
Jarrod Johnson 6763c86387 Add DNS to NetworkManager
Similar to netplan, apply DNS to every interface.
2023-11-28 14:35:01 -05:00
Jarrod Johnson 63b737dc52 Correct bonding in confignet for NetworkManager 2023-11-28 14:09:59 -05:00
Jarrod Johnson 55e60d52fd Avoid potential multiple brackets in imageboot.sh 2023-11-28 13:33:21 -05:00
Jarrod Johnson 3730ba049f Fix potential doubling up of IPv6 brackets
There were scenarios where IPv6 URL brackets may double up.
2023-11-28 13:11:25 -05:00
Jarrod Johnson 4fb263e643 Merge pull request #137 from mslacken/python3-dbm
python3-dbm is required for SUSE
2023-11-27 09:53:27 -05:00
Christian Goll 0b28d64c83 python3-dbm is required for SUSE
the python module `anydbm` is part of this python package

Signed-off-by: Christian Goll <cgoll@suse.com>
2023-11-27 15:18:57 +01:00
Jarrod Johnson 68ce3d039d Filter out nvme 'c' devnames, that are used to refer to paths to nvme
Some versions start manifesting nvme devnames with 'c', which
are to be used to interact with multipath to have raw devices
backing a traditional nvme device.
2023-11-27 08:34:34 -05:00
Jarrod Johnson 9757cd1ae3 Check the profile *before* rebooting systems
This provides a much better experience when a typo or
other mistake has a profile that is not actionable.
2023-11-16 10:20:48 -05:00
Jarrod Johnson c9452e65e8 Fix some osdeploy ordering issues
osdeploy initialization dependencies have been
improved and marked if absolutely dependent.
2023-11-15 11:30:20 -05:00
Jarrod Johnson cd07e0e212 Add missing disclaimer from tmt license 2023-11-14 15:14:54 -05:00
Jarrod Johnson f475d58955 Various permission fixes for osdeploy initialize
Fix a few scenarios where certain ordering of
initialize creates unworkable permissions.
2023-11-13 15:43:11 -05:00
Jarrod Johnson ec023831a5 Fix syntax error in confignet 2023-11-09 17:28:38 -05:00
Jarrod Johnson 6e092934e7 Fix for ubuntu clone to nvme 2023-11-09 17:15:17 -05:00
Jarrod Johnson e03f010eac Fix Ubuntu confignet without IPv6
If confignet did not have ipv6 to work with, it
would fail to work at all.

Also handle when the configuration has a blank DNS server in it.
2023-11-09 09:03:59 -05:00
Jarrod Johnson 2cd75ef425 Fix diskless autocons message 2023-11-08 10:22:51 -05:00
Jarrod Johnson e90f2829ab Filter bind mounts from imgutil capture
If bind mounts are in use, it will foul the capture.

Notably, one example is if you install the firefox snap in
ubuntu, snapd creates a bind mount.

This will ignore bind mounts, and rely upon the system to
put it straight.
2023-11-08 09:37:44 -05:00
Jarrod Johnson 8f927d94e9 Switch to bond from team
Teaming is deprecated and EL went back to bond, follow
that guidance.
2023-11-01 11:17:04 -04:00
Jarrod Johnson 8a4ef0b1fe Make link type detection more specific
If the ip command shows altnames, do not
let the altnames interfere with locking
on to linktype.

Further, use show dev instead of grep to be more specific.
2023-11-01 10:42:33 -04:00
Jarrod Johnson 814f420852 Update genesis to deal with CS9 sshd 2023-10-31 11:47:28 -04:00
weragrzeda 80242e35b3 Merge branch 'lenovo:master' into master 2023-10-30 09:03:08 +01:00
Jarrod Johnson a1ac234b73 Enhance error message for authentication issue during syncfiles 2023-10-27 15:31:14 -04:00
Jarrod Johnson d082610678 Add more deep checking of node networking
Whether due to the management node or node IP addresses,
check if deployment can reasonably proceed using IPv4 or IPv6,
and give a warning with some suggestions to check.

Also, add nodeinventory <node> -s as an example resolution for missing
uuid.
2023-10-27 13:34:52 -04:00
Jarrod Johnson 0857716f64 Add support for normalized sensors
This opens the door for normalized common sensors
for clients that care about the semantics but
cannot keep track of inconsistent sensor names from
implementation to implementation.
2023-10-26 08:58:37 -04:00
Jarrod Johnson 49a504972f Fix syntax error in confignet 2023-10-25 14:21:55 -04:00
Wera Grzeda 62ab361ef8 nicer output for inventory 2023-10-23 08:16:27 +02:00
Wera Grzeda ac68f1f22c new eaton pdu power readings 2023-10-20 11:38:11 +02:00
weragrzeda 7972834a62 Merge branch 'lenovo:master' into master 2023-10-20 11:36:38 +02:00
Jarrod Johnson 9c9d71882c Disable keepalive
Unfortunately, apache can get a bit odd over how it
reports a non-viable open socket for keepalive, which
can happen in certain windows.

Disable the keepalive feature and take some performance penalty in
browsers for the sake of more consistent return behavior and
fewer idle greenthreads doing nothing.
2023-10-19 15:51:40 -04:00
Jarrod Johnson 913a26aec9 Change to consistent CWD for osdeploy arm build 2023-10-19 10:42:39 -04:00
Jarrod Johnson 063bfc17a5 Start using container for final build process
Makes supporting the base platform easier by largely ignoring the
base platform.
2023-10-19 10:40:57 -04:00
Jarrod Johnson 8b150a9047 Fix for post group failures
A node failure after group failure would
erase the group from range.

Further, correct an issue where an empty nodeset
would trigger
a bad behavior.
2023-10-19 09:25:57 -04:00
Jarrod Johnson b91a194184 Improve selfselfice performance with yaml
The yaml python default behavior is 'pure python' and is
tortuously slow.

As a test, yaml dump of a 17,000 element list took 70 seconds in default configuration.

Opting into the C functions, that time comes down to 10 seconds, a
nice and easy improvement for generic yaml.

For dumping a simple dumb list (e.g. the nodelist for ssh), a special
case yaml-looking result is done, which hits 0.4 seconds on that same
test. So this special case is added to nodelist, which can be very long
and very in demand at the same time.
2023-10-17 16:29:30 -04:00
Jarrod Johnson 06d18cec63 Fix abbreviation when pad decreases
This is a bizarre way to work, but it should be valid.
2023-10-16 08:29:45 -04:00
Jarrod Johnson 0434f38ea1 Add iterm and kitty image support to stats
This delivers improved graphics
speed and quality for selected terminals.
2023-10-13 15:25:08 -04:00
Jarrod Johnson bfbb7c2843 Handle mid-range pad changing, and identical names with only pad difference
This would be painful to operate, but if done at least
reverse noderange will
faithfully honor it now.
2023-10-12 16:09:40 -04:00
Jarrod Johnson 3a6932ea6d Start tracking padding during abbreviation
This will take care of padding when
padding is consistent across a range.

However, we still have a problem with a progression like:
01
02
...
98
099
100

Where numbers in the middle start getting padding unexpectedly without a leading digit.
2023-10-12 15:28:54 -04:00
Jarrod Johnson 6e4d9d9eb4 Address potential slowdowns by misbehaving DNS
For one, shorten the DNS timeout, if the DNS server is completely out, give up quickly.

For another, if a host has a large number of net.X.hostnames, the sequential nature
was intolerable.
Have each network be evaluated in a greenthread concurrently to serve
the DNS latency concurrently.
2023-10-12 14:46:09 -04:00
Jarrod Johnson 2d906e1886 Fix handling of pre-existing array 2023-10-11 10:15:24 -04:00
Jarrod Johnson e9a2f57ad8 Simplify the noderange abbreviation
Since the multi-iterator ambition is out,
ditch the expensive set wrangling step.

Now the procedure is:
-Suck nodes into groups, as possible
-Separately for groups and nodes:
     -Sort the elements
     -Chunk the elements based on 'non-numberical' situation matching
     -analyze the iterators to apply [] to shorten the name
     -Multi-iterator will cause a discontinuity, and a new ',' delimited name gets constructed
2023-10-10 16:56:32 -04:00
Jarrod Johnson c254564f02 Fully give up on multi-iterator abbreviation
There's too many cases that can go wrong.

Note that with this lower ambition, it would be possible to
significantly streamline the implementation.

Notably, the 'find discontinuities' approach
was selected to *try* to
support multiple iterators,
but since that didn't pan out,
a more straightforward
numerical strategy can
be used from the onset.
2023-10-10 12:47:19 -04:00
Jarrod Johnson fe27cdea4a Abbreviate harder, using brackets
Add a round that collapses as is
convenient to bracketed range.
2023-10-09 17:18:44 -04:00
Jarrod Johnson a4ea5e5c4b Abbreviate sequential nodes
When we have sequential nodes, collapse to ':' delimited range.
2023-10-07 09:51:32 -04:00
tkucherera b3f32eb805 "firmware update on the server side" 2023-10-06 08:32:47 -04:00
Jarrod Johnson 06ee48f702 Merge pull request #135 from tkucherera-lenovo/Nodeattrib
missing_shlex import in nodeattrib
2023-10-05 12:53:16 -04:00
tkucherera 77eec1a791 missing_shlex import in nodeattrib 2023-10-05 11:44:04 -04:00
Jarrod Johnson b60b78327f Merge pull request #134 from tkucherera-lenovo/Nodeattrib
Nodeattrib
2023-10-04 16:32:32 -04:00
tkucherera 2e84c73baa '' 2023-10-04 16:27:05 -04:00
tkucherera 67f607a8f1 fix to synopsis 2023-10-04 16:26:20 -04:00
tkucherera eca1854d56 fix to env doc 2023-10-04 10:37:41 -04:00
tkucherera ba90609f3b documentation for nodeattrib -s 2023-10-04 10:36:58 -04:00
tkucherera c8094276d0 typ0_fix 2023-10-04 10:34:07 -04:00
tkucherera d299db3442 doc 2023-10-04 10:31:24 -04:00
tkucherera 9f168aee73 docs- batch file systax 2023-10-04 10:28:16 -04:00
Jarrod Johnson ee19386d8c Export nodename in ubuntu pre 2023-10-04 09:49:09 -04:00
Jarrod Johnson ef9083062b Make multiple attempts to fetch networking configuration
Since confignet runs early in startup, the networking can be a bit fickle.

Tolerate outages during early use.
2023-10-03 10:13:53 -04:00
Tinashe Kucherera 901f633848 Merge branch 'xcat2:master' into staging 2023-10-02 12:58:14 -04:00
Jarrod Johnson cca0c57e90 Merge pull request #132 from tkucherera-lenovo/nodersync
node rsync -s switch
2023-10-02 12:57:19 -04:00
tkucherera 820d255a1a staging feature 2023-10-02 11:23:23 -04:00
Jarrod Johnson 79e3ad53f8 Add server side rack layout organization
The info is hard to put together client side, but
supremely easy server side.

Provide a nice call to
get the layout for a noderange, similar to (but better than) current
GUI code.

Now GUI can get a nice canned JSON
description of the layout.
2023-09-29 16:23:59 -04:00
tkucherera b63d75f2bb change to remove to many conditionals 2023-09-29 12:07:38 -04:00
tkucherera 378929579f Allow to be able to specify prefix as well 2023-09-28 08:56:52 -04:00
tkucherera eee8bbb498 node rsync -s switch 2023-09-27 17:52:15 -04:00
Jarrod Johnson a00fd325aa Export variables for ubuntu pre.d run 2023-09-27 13:09:23 -04:00
weragrzeda 02d2ce6bfd Merge branch 'lenovo:master' into master 2023-09-21 13:57:12 +02:00
weragrzeda 7b19e67bf0 amperage and outlet fix for geist.py 2023-09-21 06:27:12 +02:00
Jarrod Johnson 3624013889 Merge pull request #130 from tkucherera-lenovo/Nodeattrib
Nodeattrib
2023-09-20 15:07:02 -04:00
tkucherera bd0b16992d man page 2023-09-20 14:42:17 -04:00
tkucherera 4ecbbdfd9a nodeattrib -s use with batch file 2023-09-20 14:37:07 -04:00
tkucherera 5768514ba9 nodeattrib -s attrib.batch 2023-09-20 14:29:21 -04:00
Jarrod Johnson f88b44dee2 Fix issues with imgutil 2023-09-20 10:13:34 -04:00
Jarrod Johnson d0c97b7623 Add pieces of EL profiles 2023-09-19 13:14:07 -04:00
Jarrod Johnson 04505e1bbb Break out partitioning and pagkacelist for EL profiles 2023-09-19 13:01:10 -04:00
Jarrod Johnson d613d0f546 Add openbmc plugin for console 2023-09-18 16:03:48 -04:00
Jarrod Johnson 47fc233cce Fix debian packaging for confluent 2023-09-18 15:48:38 -04:00
Jarrod Johnson 8f80add0f1 Enhance debian packaging for confluent 2023-09-18 15:19:10 -04:00
Jarrod Johnson 0a527f5f39 Add environment to firstboot ubuntu 2023-09-18 11:38:41 -04:00
Jarrod Johnson 3e8c6d1ea6 Correct syntax issue in el7 image2disk 2023-09-18 11:04:50 -04:00
Jarrod Johnson a01b7c6503 Revamp and add missing bits to scripted ubuntu install 2023-09-18 10:30:52 -04:00
Jarrod Johnson 83e3627b47 Add pre.d to ubuntu 22 diskful 2023-09-18 10:19:50 -04:00
Jarrod Johnson 37b75ba777 Correct variable name on commit clear 2023-09-15 15:54:35 -04:00
Jarrod Johnson aa5de3c6a3 Suspend handling of new socket connections while configmanager down 2023-09-15 15:48:37 -04:00
Jarrod Johnson d4c535d038 Halt autonomous discovery handling while configmanager is down
This avoids triggering a potential large amount of churn on transiently
"unknown" systems
that are actually discovered.
2023-09-15 15:32:33 -04:00
Jarrod Johnson 94b8559777 Declare ready on becoming leader
Provide for leader scenario to correctly
flag configmanager as ready.
2023-09-15 15:28:16 -04:00
Jarrod Johnson f2f25fe912 Implement ready tracking
When going through the
dramatic scenario of initializing collective,
take _ready down
so that other code can
pause operation appropriately.
2023-09-15 15:25:26 -04:00
Jarrod Johnson c0629fcce5 Fix invocation of json restore change 2023-09-15 11:41:12 -04:00
Jarrod Johnson 4952e87309 Undo collective manager changes
Abort attempt to avoid duplicate startups, it was incorrect.
2023-09-15 10:52:13 -04:00
Jarrod Johnson 533244458d Do not count as 'initting' until collective starts. 2023-09-15 10:37:51 -04:00
Jarrod Johnson 20f02b5ef7 Avoid searching switches for foreign nodes
Consult collective.manager
to decide to skip
consideration of a node, if
that node shouldn't be managed anyway.

This should avoid "cross-island" behavior for such
environments.
2023-09-15 10:07:14 -04:00
Jarrod Johnson df47c6d0fd Disable attribute notify during json restore
This is guaranteed to be a lot of churn very quickly, disable it for
now.
2023-09-13 17:03:05 -04:00
Jarrod Johnson 97ee8e2372 Cerrect the logic of duplicate discovery protection 2023-09-13 10:50:21 -04:00
Jarrod Johnson 74c6848a0b Avoid redundant setting of known data
Setting attributes can be a touch expensive, since
there's a high risk
of this being old news,
check that discovery hasn't already set values
before trying to set them again.
2023-09-13 09:59:03 -04:00
Jarrod Johnson b75979f3ec Insulate confluent from fatal errors from discovery subscription errors 2023-09-12 16:59:53 -04:00
Jarrod Johnson 50d5cead06 Add prereq checks to EL cloning 2023-09-12 16:55:19 -04:00
Jarrod Johnson e6b0b235e9 Fix image2disk for nvme clone targets 2023-09-12 16:53:32 -04:00
Jarrod Johnson 00eb9e3c9d Fix full_net_config with missing address info 2023-09-12 16:49:15 -04:00
Jarrod Johnson b77d8b1f21 Make yaml import conditional
Only Ubuntu requires it, but tends to have it.

Other distributions do not tend to have it.
2023-09-12 10:45:15 -04:00
Jarrod Johnson d7190c893f Correct networkmanager entries for boot over infiniband
When booting and infiniband comes up as the 'get started' nic,
make the entry use correct type so as to avoid
confusion later, particularly when confignet comes along to fixup
the configuration.
2023-09-11 13:11:17 -04:00
Jarrod Johnson f82829aa0c Add dependency checking to imgutil capture
This will more quickly indicate problems in a profile trying to capture.

First iteration will address Ubuntu.
2023-09-08 17:10:27 -04:00
Jarrod Johnson 203dabfb0b Place nameservers on every NIC in netplan
netplan, like others, makes the questionable choice to designate DNS
as a NIC specific setting, despite not mapping well
to a NIC.

Since we model DNS like NTP, a global, just repeat the DNS config for
every interface.  This redundancy is fine in testing multiple
interfaces.
2023-09-08 16:56:58 -04:00
Jarrod Johnson 9441221150 Have cooltera plugin adapt
As new sensors appear, be more adaptive
to continue tracking existing sensors.
2023-09-08 11:30:57 -04:00
Jarrod Johnson 8de6f4356d Fix sense of new flag
Accidently made flag exactly opposite of intended
2023-09-07 15:12:43 -04:00
Jarrod Johnson fe78034eaa Add '-y' to imgutil build
Allow non-interactive imgutil build.
2023-09-07 14:56:07 -04:00
Jarrod Johnson 691d92f735 Avoid calling implicit nic config if nowhere to put it
If 'None' attributes are in use,
we'd have no where to
stick implicit configuration anyway.
2023-09-07 14:41:16 -04:00
Jarrod Johnson 8ca1f80ef6 Fix implicit nic in confignet
If the implicit IP
is not in any of the
attribute groups of net,
then auto-vivify from the normal place.
2023-09-07 14:36:56 -04:00
Jarrod Johnson 3cacbf283a Fix cloning to NVME boot
The partition device names
have a different scheme
for nvme v. other devices.
2023-09-07 10:09:19 -04:00
weragrzeda 0993ef0c11 Merge branch 'lenovo:master' into master 2023-09-07 13:13:05 +02:00
weragrzeda c950524386 geist.py outlet state fix 2023-09-07 13:08:33 +02:00
Jarrod Johnson 89e573207c Remove irrelevant command from ubuntu cloning firstboot 2023-09-01 16:55:01 -04:00
Jarrod Johnson f16cf4387f Further Ubuntu enhancements
Add confignet to Ubuntu 20 and 22
Add syncfile to the ubuntu diskless/cloning
2023-09-01 16:40:02 -04:00
Jarrod Johnson fa60a9dc9f Add IPv6 support to confignet 2023-09-01 16:34:30 -04:00
Jarrod Johnson 2268d7f65a Fix hotplug firmware in suse diskless 2023-09-01 13:51:17 -04:00
Jarrod Johnson abd5f4e9f2 Fix shebang in firstboot on ubuntu cloning 2023-09-01 13:51:02 -04:00
Jarrod Johnson f6e658c341 Add site CA to ubuntu profiles on install 2023-09-01 13:25:20 -04:00
Jarrod Johnson 44ec390f40 Add post.sh to ubuntu cloning 2023-09-01 12:29:27 -04:00
Jarrod Johnson 6ab91b50af Add missing bits of Ubuntu diskless 2023-09-01 10:55:18 -04:00
Jarrod Johnson 1f32ef2310 Implement basic netplan support
Start with single links, ipv4 only for ubuntu.
2023-09-01 10:07:51 -04:00
Jarrod Johnson 22cb2bdc40 Handle Ubuntu hardcoded grub cfg
Ubuntu hardcodes grub.cfg to
another location.

Make a stub file as a flag to guide osimage
to know where grub.cfg goes.
2023-08-29 10:57:25 -04:00
weragrzeda f633c93d0f Geit PDU nodeinvntory
Please enter the commit message for your changes. Lines starting
 with '' will be ignored, and an empty message aborts the commit.

 On branch master
 Your branch is up to date with 'origin/master'.

 Changes to be committed:
	modified:   geist.py
2023-08-25 08:27:27 +02:00
Jarrod Johnson 610bc793b7 Merge branch 'master' into ubuntucloning 2023-08-24 10:53:33 -04:00
Jarrod Johnson 85375cc733 Fix hotplug firmware to use rootfs after boot 2023-08-24 10:53:25 -04:00
Jarrod Johnson af4ca64da8 Fix hotplug firmware to use rootfs after boot 2023-08-24 10:53:00 -04:00
weragrzeda 6d87d11f5e my changes to Eaton PDU sensors 2023-08-23 14:28:33 +02:00
weragrzeda 9591ff4718 Merge branch 'master' of https://github.com/weragrzeda/confluent 2023-08-23 14:26:51 +02:00
Jarrod Johnson 439143115e Merge branch 'master' into ubuntucloning 2023-08-22 12:28:36 -04:00
Jarrod Johnson b14b34bdbd Add limited sensor support for Eaton PDUs 2023-08-22 12:28:07 -04:00
Jarrod Johnson 899ce7f055 Correct spelling of hooks directory in Ubuntu cloning 2023-08-17 16:27:45 -04:00
Jarrod Johnson 7e209e412a Make confluent hook executable in ubuntu diskless 2023-08-17 16:16:36 -04:00
Jarrod Johnson 7051f467bb Avoid a deprectationwarning in copytree handling
While trying to address one
deprecationwarning, we
hit another.  Check if the
new function exists and use it,
falling back to distutils if
everything fails.
2023-08-17 14:49:44 -04:00
Jarrod Johnson b88ccc292c Avoid deprecation on distutils with newer python
Unfortunately, python 3.6 needs the distutils version, but we should avoid it altogether
by python 3.10, but by 3.10 the shutil.copytree can do it.
2023-08-17 14:36:38 -04:00
Jarrod Johnson c47066d713 Include ubuntu material in packaging 2023-08-17 14:11:41 -04:00
Jarrod Johnson 8ddcf45e1d Create links for ubuntu20.04 and ubuntu22.04 2023-08-17 14:03:55 -04:00
Jarrod Johnson 53d2b873a2 Package ubuntu 22.04 diskless 2023-08-17 11:28:29 -04:00
Jarrod Johnson bc7dbeebea Add ubuntu 22.04 diskless 2023-08-17 11:16:32 -04:00
Jarrod Johnson 1b2d8a0596 Merge branch 'ubuntucloning' of github.com:lenovo/confluent into ubuntucloning 2023-08-17 11:16:01 -04:00
Jarrod Johnson f3e7d4ab67 Merge pull request #92 from sjtstg/nmcli-autoconnect
Confignet does not set autoconnect with network manager
2023-08-17 08:06:54 -04:00
Simon Thompson b27542ec00 Confignet does not set autoconnect with network manager so disk installed images do not bring up interface on reboot 2023-08-17 10:30:36 +02:00
Jarrod Johnson 58cc9840b3 Prune out any netplan configuration, if exists
To mitigate chance of network configuration
being tanked by image based
net config, mask it when capturing.
2023-08-16 14:28:10 -04:00
Jarrod Johnson 84d23bb1fd Begin work on Ubuntu cloning 2023-08-16 12:00:50 -04:00
weragrzeda 44405baaf3 nodeconfig ntp servers for smms 2023-08-16 14:30:05 +02:00
Jarrod Johnson ae915cd735 Merge pull request #126 from weragrzeda/master
nodelist delimiters
2023-08-15 11:03:48 -04:00
weragrzeda c7a323b370 nodelist delimiters fixed for py2 compatibility 2023-08-15 16:31:38 +02:00
root 9e070a14d4 nodelist delimiters 2023-08-15 15:58:10 +02:00
Jarrod Johnson 189ba525d3 Merge pull request #91 from sjtstg/ansible-play-fix
fix ansible support when multi stage plays are in playbook
2023-08-15 08:38:56 -04:00
Jarrod Johnson 5068cda2cf Catch another sort of exception for non-rpm distributions
subprocess may produce a different sort of exception if
rpm doesn't exist at all
2023-08-14 09:23:00 -04:00
Jarrod Johnson 95c5253944 Remove CIDR prefix length in ubuntu 20 deployment
This produces invalid configuration for subiquity otherwise.
2023-08-11 15:01:55 -04:00
Jarrod Johnson ca2dcd2dbe Reference identity network in ubuntu 20.04
When using identity image, also use identity image
for network configuration.
2023-08-11 14:34:12 -04:00
Jarrod Johnson dba6e7f378 Change Ubuntu 20.04 to be consistent to 22.04
This aims to bring
identity image deployment fully to ubuntu 20.0.4.
2023-08-11 13:44:37 -04:00
Jarrod Johnson 0b7247d386 Fix CentOS 7 routed deployment with identity image
Numerous issues prevented the identity image support from actually running,
correct them.
2023-08-10 16:27:42 -04:00
Jarrod Johnson 75add230b6 Skip API key init on checkonly runs
Checkonly does not require API key, and makes apiclient more dependent
on material that is unlikely to exist early in a deployment.
2023-08-09 11:13:09 -04:00
tkucherera 2c90227f63 "Firmware Update " 2023-08-09 10:48:09 -04:00
tkucherera 0cff70c607 firmware update 2023-08-09 10:37:35 -04:00
Jarrod Johnson 75082c4418 Move up creation of ca.pem 2023-08-03 14:03:36 -04:00
Jarrod Johnson 9a1c9eb43f Improve ssh concurrency on websocket
ssh module was pausing input for the
entire websocket while doing the simple 'write' operation.

Change to background the actual
logon processing,
rather than blocking what should be a fairly trivial write operation.
2023-08-03 09:56:36 -04:00
Jarrod Johnson 89bd798f8b Increasing time again, outlet count didn't factor 2023-08-02 15:20:29 -04:00
Jarrod Johnson bf10e58f00 Bump version
With recent collective changes, bump the version to block connection with
older collective members until upgraded.
2023-08-02 13:43:41 -04:00
Jarrod Johnson cbf2cdcdc5 Scale timeout with number of outlets
Delta PDUs seem to serialize outlet operation.
2023-08-01 16:08:51 -04:00
Jarrod Johnson 987587aaf8 Allow custom auth file to define valid roles 2023-07-26 16:37:55 -04:00
Jarrod Johnson ad25c31d3f Correct error in check_for_yaml function in auth 2023-07-26 16:15:36 -04:00
Jarrod Johnson b1018d648e Hook loading of /etc/confluent/authorization.yaml
This should permit custom roles to be defined.
2023-07-26 16:05:29 -04:00
Jarrod Johnson a18d0f10b7 Clean up stale lvm devices files
During cloning, stale lvm devices file may cause
ugly output.  Remove stale files before proceeding down steps
that trigger lvm warnings.
2023-07-26 07:54:41 -04:00
Jarrod Johnson 65ac3de21b Take EL9 version of image2disk for improvements with parted supervision 2023-07-26 07:26:49 -04:00
Jarrod Johnson c9d9a3cc54 Add EL9 cloning support
Main difference from EL8 is different grub strategy.  To cope, capture
the uuid of new /boot and manipulate the
stub grub.cfg with the right uuid.

In EL8, the efi has the main grub, EL9 changes to have /boot host the 'real' grub,
causing us to have to modify the stub grub.
2023-07-25 17:09:37 -04:00
Jarrod Johnson 957b979dde Reorder imports in configmanager to mitigate circular import 2023-07-24 13:38:44 -04:00
Jarrod Johnson 48c4a2e062 Have reconnects use new TCP connections
Current code was trying to reuse connections that would be useless,
explicitly go to new TCP connections for reconnection.
2023-07-24 12:31:32 -04:00
Jarrod Johnson 285a159ba5 Implement a number of improvements for collective
For one, remove 'non-voting' members from being leaders.
Large number of leader candidates create long delays for
converging on a valid organization.  Further, some treat 'non-voting'
more roughly, inducing the worst case convergence scenario of unclean
shutdown of leader.
Convergence now happens fairly quickly for collectives with large
number of non-voting members.

During initial DB transfer, the leader would be tied up unreasonably
long handling the jsonification of a large configuration.  Offload to a worker
process to allow the leader to continue operation while this intensive, rare
operation occurs.

Reliably run a reassimilation procedure for the lifetime of the leader.
This allows orphaned members to be prompted to join the correct leader.

Serialize the onboarding of a connecting member, and have redundancy more gracefully
paused. This avoids excessive waiting in lock and more deterministic timing
with respect to timeout expectations by the connecting system.
2023-07-24 11:11:39 -04:00
Jarrod Johnson 8ea2ba046e Sort the IP addresses in nodediscover for consistent UI 2023-07-19 16:16:27 -04:00
Jarrod Johnson f16daa44dd Handle older python with addrinfo
While newer python omits '%',
older python includes.  Change to handle
either form.
2023-07-19 16:04:25 -04:00
Jarrod Johnson 03fce4f762 Adjust sys.path logic in macmap and osimage
Ensure the sys.path logic
is before attempting
the relevant imports.
2023-07-19 12:15:01 -04:00
Jarrod Johnson 809099c8f8 Specifically wait for /dev/disk/by-label
When udev is populating the disk hierarchy, it can be a long time
before the 'by-label' is specifically ready.

Wait for that specific entry to come along before continuing to
check if there's an identity image.
2023-07-07 15:32:47 -04:00
Jarrod Johnson a875f0d3e1 Correct syntax error in selfservice 2023-07-06 14:04:49 -04:00
Simon Thompson 6ee9f96e08 fix ansible support when multi stage plays are in playbook 2023-07-06 09:34:38 +02:00
Jarrod Johnson fcc62b7cb7 Improve confluent scanning on newer python
Newer python changed the format of peer[0], adapt to the change
to use the socket info if not available in the peer[0] string.
2023-07-05 16:34:37 -04:00
Jarrod Johnson 11cb47c03e Use natural sort on some self service calls 2023-07-05 16:18:49 -04:00
Jarrod Johnson afc78513a1 Merge pull request #90 from sjtstg/ansible-fixes
Ansible fixes
2023-07-05 16:15:30 -04:00
Simon Thompson 45f22c3e31 when host is not in hosts file, group_vars is not loaded, change logic to emulate host being in hosts file with no groups to ensure group_vars is loaded which permits use of dynamic grouping in plays 2023-07-05 21:25:25 +02:00
Simon Thompson d0f978548e sort directory listing to make ansible plays and script order deterministic 2023-07-05 21:23:55 +02:00
Jarrod Johnson 052d16aa49 Avoid modifying PYTHONPATH
Since there's a possibility of cross-python invocation,
avoid modifying PYTHONPATH
2023-07-05 11:40:00 -04:00
Jarrod Johnson 7ddd2c2e6e Correct mistakes in shebang adaptive behavior 2023-07-05 11:14:32 -04:00
Jarrod Johnson 9186c8142c Fix incorrect reference in the smm validation by certificate 2023-06-28 13:13:26 -04:00
Jarrod Johnson c07248d58e Fix outlet control on Geist PDUs. 2023-06-27 08:04:16 -04:00
Jarrod Johnson 013de4f881 Adapt to ansible python runtime
Unfortunately, python being python, ansible may elect to install under a
different python runtime than confluent.

In such a case, hope that the ansible python can work.

Remove eventlet as a hard requirement, as
that is unlikely to be in ansible python.

This leaves msgpack, which is unavoidable, for now. But if it's in ansible python,
it's fine.
2023-06-26 15:41:44 -04:00
Jarrod Johnson 795b4c513d Rework for connected temperature sensors
PDUs behave differently when a sensor module is
connected. Handle
that difference and
provide the relevant data.
2023-06-26 12:32:45 -04:00
Jarrod Johnson 4056264991 Correct keyname from previous fix 2023-06-23 17:01:50 -04:00
Jarrod Johnson 77c8e93a8d Fix terminal actions on shared websocket
The full complement of functionality was not
interpreted in shared context
2023-06-23 16:33:30 -04:00
Jarrod Johnson 1695e222ec Rename command to nodeapply, by popular demand 2023-06-22 14:16:54 -04:00
Jarrod Johnson b2a793568a Merge pull request #125 from tkucherera-lenovo/master
change timestamp log option from -d to -T
2023-06-22 14:14:59 -04:00
Jarrod Johnson 3ebd43fe0c Bump genesis base version 2023-06-15 09:35:37 -04:00
Jarrod Johnson 2e20e0303f Fix libbpf link 2023-06-15 09:22:52 -04:00
Jarrod Johnson da2df63498 Update location of krb5 2023-06-15 09:20:37 -04:00
Jarrod Johnson 896a4ff1ff Fix spec format 2023-06-14 16:05:08 -04:00
Jarrod Johnson a14effa4f2 Undo change
Realized we need to install related rpm for efivar
2023-06-14 15:57:27 -04:00
Jarrod Johnson 66c79a5f42 Fixup handling of efivar license 2023-06-14 15:52:52 -04:00
Jarrod Johnson 389c37659e Refresh more licensing material in genesis rpm 2023-06-14 15:47:17 -04:00
tkucherera 89af8661da change timestamp log option from -d to -T 2023-06-12 10:51:29 -04:00
Jarrod Johnson 41437c511b Fix when networkmanager breaks one of our connections
This usually happens with ipv6 link local used
in initramfs stage, after networkmanager may
mutilate the ipv6 connectivity.
2023-06-12 08:49:13 -04:00
Jarrod Johnson 75f0aaeee9 Allow session id through header
This permits a client to exert finer grained control
over the session id
than provided by cookie.
2023-06-08 11:30:32 -04:00
Jarrod Johnson 68f9688292 Drop SLP packets with error
Some implementations send
error for services they do not provide.
2023-06-08 08:02:59 -04:00
Jarrod Johnson 67204f79a1 Fix bug where dispatching a request could block all other activity 2023-06-02 11:06:44 -04:00
Jarrod Johnson e9dd7da775 Fix syntax error in el7 identity image support 2023-06-02 08:55:27 -04:00
Jarrod Johnson 8f1be7c905 Fix Python2 compatibility issue with port forwarder 2023-06-01 16:50:06 -04:00
Jarrod Johnson bc684b82b4 Implement identity image based deployment for EL7
Though older, it is still popularly used.
2023-06-01 16:49:17 -04:00
Jarrod Johnson 5e72d40c03 Fix compatibility issue with python2 2023-06-01 13:31:32 -04:00
Jarrod Johnson 7ab2aff7f2 Restore syntax of EL7 deployment
Inadvertent incomplete checkin
broke syntax of EL7, fix to have it
work as-is for now.
2023-06-01 09:20:17 -04:00
Jarrod Johnson c3fc931ba4 Fix python2 compatibility issue for port forwarding
The measure for predictable port numbering
was done with python3 in mind, without consideration
of python2.
2023-06-01 09:18:36 -04:00
Jarrod Johnson 2c61cee72d Merge pull request #124 from Tkucherera/nodeconsole_timestamp
Nodeconsole timestamp
2023-06-01 09:08:33 -04:00
Tinashe 190ec2473b dump log to stfout with timestamps 2023-05-31 17:39:53 -04:00
Tkucherera 9ebb8f27ec Merge branch 'xcat2:master' into master 2023-05-31 17:34:52 -04:00
Jarrod Johnson 0db7d4f9d2 Stall readback of PDU after outlet control
There is some lag after requesting an outlet change and
the outlet state actually changing.
2023-05-26 10:43:04 -04:00
Jarrod Johnson 5d1315098f Enhance and extend check of node relations 2023-05-25 11:14:58 -04:00
Jarrod Johnson fc29ddb913 Improve routed EL8 deployment and add debug shell on tty2 2023-05-24 11:02:23 -04:00
Jarrod Johnson b06b77f5a5 Fix issues with confluent media deployment on multi-nics in routed env 2023-05-23 17:22:38 -04:00
Jarrod Johnson 97a5bf0806 Correct typo in suse 15 diskless boot 2023-05-19 14:50:04 -04:00
Jarrod Johnson 36e61f301a Add a nodefreshen command
This aims to provide the same shortcuts as 'updatenode'
2023-05-18 15:03:29 -04:00
Jarrod Johnson e476c7b9e6 Avoid deprecationwarning in python 3.10+
Newer python is not backwards compatible with
a constant.  Attempt to use new
constant and fallback to teh old one
if unavilable.
2023-05-18 09:20:52 -04:00
Jarrod Johnson a523df80e8 Handle newer SuSE
After SP4, suse drops mkinird requirement.

Switch to dracut -f in such a scenario.
2023-05-16 14:51:27 -04:00
Jarrod Johnson 8f4982e850 Fix build mistake in the cooltera plugin 2023-05-15 08:30:44 -04:00
Jarrod Johnson a167d19441 Add module for cooltera nodesensors 2023-05-10 13:24:20 -04:00
Jarrod Johnson 2237e0e173 Add a retry mechanism for connecting socket
Timing is sensitive during the handshake, catch and retry
if it should fail.
2023-05-10 11:12:29 -04:00
Jarrod Johnson b08b62614a Have proxydhcp recover from faults 2023-05-10 08:44:31 -04:00
Jarrod Johnson e93e4abd83 Add clear error when base profile doesn't exist
If the user specifies a wrong '-b',
indicate clearly that is the case,
and do so early.
2023-05-10 08:40:45 -04:00
Jarrod Johnson 430b24081c Have apiclient timeout if IO hangs up 2023-05-09 16:04:24 -04:00
Jarrod Johnson ec54ecc9cd Fix tiling with different gravity
In some environments, the coordinates may be reported in a
different format.  Handle the different context.
2023-04-28 09:20:31 -04:00
Jarrod Johnson f787461759 Merge pull request #123 from Tkucherera/tmux_reuse
Tmux reuse
2023-04-28 09:18:44 -04:00
Jarrod Johnson 7312d8e092 Provide commented hints for mdns integration
mdns protocol is not currently used, but
put in breadcrumbs for
bringing it alive if
we have an openbmc handler.
2023-04-27 15:51:28 -04:00
Tkucherera 884a6be68c Wkill like command (#1)
* wkill like command fix

* tmux session resuse

---------

Co-authored-by: Tinashe <tkucherera@lenovo.com>
2023-04-27 15:46:40 -04:00
Tinashe a35a7e74c3 tmux session resuse 2023-04-27 15:39:32 -04:00
Jarrod Johnson ffdf799713 Advance mdns support
At this point, the protocol handler
seems up to the task of describing openbmcs
2023-04-27 08:59:39 -04:00
Jarrod Johnson b9d0da0416 Correct mistake in the gathering of valid nodenames 2023-04-26 15:37:08 -04:00
Jarrod Johnson 3fd930137d Begin work on mdns protocol support 2023-04-21 16:14:25 -04:00
Tinashe 71a263366d wkill like command fix 2023-04-21 10:22:10 -04:00
Jarrod Johnson 7b150773df Extend multi-nic guessing to Ubuntu 20/22 2023-04-20 15:45:32 -04:00
Jarrod Johnson 53f4665358 Correct issues in Ubuntu 18 deployment 2023-04-20 14:48:39 -04:00
Jarrod Johnson e5fff430be Explicitly clear logonwaiters on discard of a session
When a session is being discarded, it
may inadvertently hold onto logonwaiters.

The IPMI session may be reused, but the context is new and those
dead contexts can consume memory unreasonably.
2023-04-19 10:22:33 -04:00
Jarrod Johnson 55da173b27 Correct missing parameter in Geist
Geist support was missing a variable in the refactor.
2023-04-19 10:20:34 -04:00
Jarrod Johnson 55a796af82 Correct some errors in the Ubuntu 18 support
An ommited end clause as well
as some bashisms.
2023-04-12 13:23:39 -04:00
Jarrod Johnson 123d190f12 Extend network and deployment server checking for Ubuntu 18.04
When doing network evaluation in ambiguous contexts,
spend some time checking each nic and each candidate target ip address.

This may take longer, but options are limited in a routed context.
2023-04-12 13:04:08 -04:00
Jarrod Johnson 305a3a06d2 Ensure $HOME is set during firstboot
systemd tends not to set environment variables.  However some firstboot
scripts generally expect $HOME to be correct.
2023-04-12 11:22:27 -04:00
Jarrod Johnson 024677d7de Try EL7 to build the old addons 2023-04-07 16:50:20 -04:00
Jarrod Johnson fb31a68818 Add profile.yaml to ubuntu18.04 stock profile 2023-04-07 16:26:32 -04:00
Jarrod Johnson 526a248963 Add ubuntu18.04 to build script in other location 2023-04-07 16:17:37 -04:00
Jarrod Johnson 86d9d6fc2f Add ubuntu18.04 to build 2023-04-07 15:46:29 -04:00
Jarrod Johnson 2bdc53722b Further advance ubuntu 18.04 support 2023-04-07 15:45:31 -04:00
Jarrod Johnson 25b0f45e6f Merge remote-tracking branch 'lenovo/master' 2023-04-07 13:53:44 -04:00
Jarrod Johnson f5b3682c08 Merge pull request #89 from erderial/patch-8
added functionality to check for net.*switch
2023-04-07 13:52:01 -04:00
Jarrod Johnson b7ea27b939 Advance draft Ubuntu 18 support
Get most things automated for the targeted use case.

Still need to handle partitioning and end of install question, add firstboot and add
staged and complete step.
2023-04-06 16:07:55 -04:00
Jarrod Johnson 1fff15677d Add el9bin correctly into build process 2023-04-04 11:55:23 -04:00
Jarrod Johnson 556d858d33 Address extraneous errors during build 2023-04-04 11:27:50 -04:00
Jarrod Johnson 0a02b010c9 Fix esxi build for new build strategy 2023-04-04 11:24:10 -04:00
Jarrod Johnson 08e19fbf6e Provide a sample for fuse3 urlmount
When the time comes to transition, this will be useful.

The challenge is that existing images will likely have a 'distribution'
with fuse2 libs, so this isn't a transition to make lightly.

Definitely should be done for new distributions at least, current
distributions pending further investigation
2023-04-04 10:39:12 -04:00
Jarrod Johnson 2d16d5558c Rework to build everything under el8 or el9 containers specifically
Make the build host less critical of an implementation detail
2023-04-04 10:19:13 -04:00
Jarrod Johnson 7f15e4af27 Change back to fedora
We need fuse-devel for now, since urlmount is written against older fuse
2023-04-04 09:44:04 -04:00
Jarrod Johnson 34313f4041 Change to EL9 for the new-wave util builds 2023-04-04 09:32:25 -04:00
erderial 9bb402a1b8 Update confluent_selfcheck 2023-04-03 10:27:07 +03:00
erderial 13d4c57ee2 changes done as per request 2023-03-31 19:32:43 +03:00
erderial 88c47c9254 added functionality to check for net.*switch
added functionality to check for net.*switch
2023-03-31 16:43:15 +03:00
Jarrod Johnson 181aa876a7 Draft initramfs addons for Ubuntu 18
For older Ubuntu 18, the automated installer is debian-installer.  Derive from the
prototype debian work, with same limitation about more limited network bringup that
we are stuck with from Debian limitations.
2023-03-30 16:36:40 -04:00
Jarrod Johnson a0dbb90c77 Handle mismatched alpha and numeric in hyphenated string
If 123abc-abc123 were attempted, it would produce
a strange error
when it encounters a string compare to number.

Detect the scenario and treat it like similar situations.
2023-03-30 14:21:22 -04:00
Jarrod Johnson cb129789b8 Properly recognize old ubuntu server install media
Older media designed around
debian installer requires
different handling.
2023-03-30 08:33:18 -04:00
Jarrod Johnson 7ac778106e Also skip over failure to broadcast SSDP 2023-03-29 16:55:12 -04:00
Jarrod Johnson f808c542e4 Ignore forbidden transmits on multicast 2023-03-29 16:53:40 -04:00
Jarrod Johnson 2a3bc61be3 Avoid overwriting groups on a redefine
When a node is being redefined, do
not populate groups.

That is only needed when truly defining for first time.
2023-03-29 09:28:52 -04:00
Jarrod Johnson 73fb54ccbc Add more manual licenses to the kernel 2023-03-28 17:02:53 -04:00
Jarrod Johnson 578bd9702a Sample script to install a cert into an XCC 2023-03-24 15:56:26 -04:00
Jarrod Johnson ca5f19a4f1 Sample script for getting a CSR from an XCC 2023-03-24 15:46:21 -04:00
Jarrod Johnson 717df579aa Add firmware to Geist support 2023-03-17 16:02:55 -04:00
Jarrod Johnson 70b973b1cf Refactor measurements in Geist
Use common code
for sensor translation.
2023-03-17 15:34:26 -04:00
Jarrod Johnson 48696ef63d Begin adding sensors to Geist PDUs 2023-03-17 14:37:03 -04:00
Jarrod Johnson ff025989c6 Restore spacing around float in nodesensors
The managed formatting needs
to be padded in the non-csv output.
2023-03-16 17:29:36 -04:00
Jarrod Johnson 872718c658 Add notation about alternate location of ansible plays
Make it known that plays may now be private.
2023-03-16 15:19:15 -04:00
Jarrod Johnson 47af869360 Allow ansible plays to be private
Since the node need not have access,
the ansible plays may be made private instead.

This enables potentially sensitive plays
to be protected.
2023-03-16 15:15:46 -04:00
Jarrod Johnson f256b1cd4e Handle more complex ansible configuration
Some plays expect the
inventory from /etc/ansible, detect
if that inventory *could* apply, use if it can.

ansible users generally anticipate leveraging the implicit '.' in the role
path,
chdir to meet that expectation.

'become' in the play without 'become_user' can upset ansible runtime.

Since we are already root, we will just ignore the implicit 'become', since we already
match that behavior.
2023-03-16 13:24:46 -04:00
Jarrod Johnson bfe03e6e01 Fix erronously dragging in CIDR to IPv4 configuration 2023-03-14 16:55:20 -04:00
Jarrod Johnson 8dc3dfd20c Limit TRYNIC to only one NIC in ubuntu deployment 2023-03-14 15:36:24 -04:00
Jarrod Johnson 0cc588f8e9 Carry nic detection through to bottom of Ubuntu 2023-03-14 15:24:37 -04:00
Jarrod Johnson e12578b6ac Use media net config when media deployed 2023-03-14 13:32:20 -04:00
Jarrod Johnson 0366bbd26f Place apikey where expected 2023-03-13 17:00:35 -04:00
Jarrod Johnson 5f4ab5ff80 Fix path to hmacfile
Since we are running
outside of chroot, need to adjust the $()
substitution.
2023-03-13 16:21:25 -04:00
Jarrod Johnson 88a6bccf12 Use b64 alphabet for b64
While POSIX hates +, b64 needs +
2023-03-13 16:20:17 -04:00
Jarrod Johnson 52c3e9d515 Do not care about port, let kernel decide 2023-03-13 11:19:11 -04:00
Jarrod Johnson 50a4ee2c6d Have a quick sample script to get LLA of USB nic peer 2023-03-13 11:15:31 -04:00
Jarrod Johnson 15ff24fccd Correct syntax errors in auth.py 2023-03-10 16:38:47 -05:00
Jarrod Johnson d9cc9112f4 Add identity image deployment to Ubuntu
Support the api arm token
and media network
config for Ubuntu.
2023-03-10 16:23:48 -05:00
Jarrod Johnson 5418d9ea97 Place a common script for setupssh 2023-03-10 16:05:29 -05:00
Jarrod Johnson 2aeade1e74 Merge pull request #88 from erderial/patch-6
updated with custom yaml file for auth
2023-03-09 15:48:12 -05:00
erderial 85f9dc12fb Update auth.py 2023-03-09 22:38:37 +02:00
erderial 56dea2422a Update auth.py 2023-03-07 21:08:01 +02:00
erderial cf2f5aac7b Merge branch 'lenovo:master' into patch-6 2023-02-27 18:27:39 +02:00
erderial 3b9f9abdd9 Merge pull request #2 from erderial/erderial-patch-1
updated auth.py with some changes
2023-02-27 17:36:20 +02:00
erderial b800aa032e updated auth.py with some changes
updated auth.py with some changes. Need to add the check_for_yaml() function to main.py as well
2023-02-27 17:10:17 +02:00
erderial 8940247164 updated with custom yaml file for auth
Added 2 new function to check if the custom yaml file exists - /etc/confluent/authorize.yaml - and one to update the _allowbyrole and _deniedbyrole vars accordingly.
2023-02-21 15:13:17 +02:00
330 changed files with 17766 additions and 1707 deletions
+30
View File
@@ -0,0 +1,30 @@
# Confluent
![Python 3](https://img.shields.io/badge/python-3-blue.svg) [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/xcat2/confluent/blob/master/LICENSE)
Confluent is a software package to handle essential bootstrap and operation of scale-out server configurations.
It supports stateful and stateless deployments for various operating systems.
Check [this page](https://hpc.lenovo.com/users/documentation/whatisconfluent.html
) for a more detailed list of features.
Confluent is the modern successor of [xCAT](https://github.com/xcat2/xcat-core).
If you're coming from xCAT, check out [this comparison](https://hpc.lenovo.com/users/documentation/confluentvxcat.html).
# Documentation
Confluent documentation is hosted on hpc.lenovo.com: https://hpc.lenovo.com/users/documentation/
# Download
Get the latest version from: https://hpc.lenovo.com/users/downloads/
Check release notes on: https://hpc.lenovo.com/users/news/
# Open Source License
Confluent is made available under the Apache 2.0 license: https://opensource.org/license/apache-2-0
# Developers
Want to help? Submit a [Pull Request](https://github.com/xcat2/confluent/pulls).
+58 -2
View File
@@ -1,6 +1,8 @@
Name: confluent-client
Project: https://hpc.lenovo.com/users/
Source: https://github.com/lenovo/confluent
Upstream-Name: confluent-client
All file of the Confluent-client software is distributed under the terms of an Apache-2.0 license as indicated below:
Files: *
Copyright: 2014-2019 Lenovo
@@ -11,7 +13,8 @@ Copyright: 2014 IBM Corporation
2015-2019 Lenovo
License: Apache-2.0
File: sortutil.py
File: sortutil.py,
tlvdata.py
Copyright: 2014 IBM Corporation
2015-2016 Lenovo
License: Apache-2.0
@@ -19,3 +22,56 @@ License: Apache-2.0
File: tlv.py
Copyright: 2014 IBM Corporation
License: Apache-2.0
License: Apache-2.0
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
+11 -6
View File
@@ -14,11 +14,16 @@ import shutil
shutil.copyfile('doc/man/nodeattrib.ronn.tmpl', 'doc/man/nodeattrib.ronn')
shutil.copyfile('doc/man/nodegroupattrib.ronn.tmpl', 'doc/man/nodegroupattrib.ronn')
with open('doc/man/nodeattrib.ronn', 'a') as outf:
for field in sorted(attr.node):
outf.write('\n* `{0}`:\n {1}\n'.format(field, attr.node[field]['description']))
with open('doc/man/nodegroupattrib.ronn', 'a') as outf:
for field in sorted(attr.node):
outf.write('\n* `{0}`:\n {1}\n'.format(field, attr.node[field]['description']))
def append_attributes(filename):
with open(filename, 'a') as outf:
for field in sorted(attr.node):
outf.write('\n* `{0}`:\n {1}\n'.format(field, attr.node[field]['description']))
# Optionally write valid values if they exist
for key, values in attr.node[field].items():
if key.startswith('valid'):
values_formatted = ', '.join("'{0}'".format(v) for v in values)
outf.write(f'\n Valid values: {values_formatted}\n')
append_attributes('doc/man/nodeattrib.ronn')
append_attributes('doc/man/nodegroupattrib.ronn')
+9 -2
View File
@@ -21,6 +21,7 @@
import optparse
import os
import re
import select
import sys
@@ -84,6 +85,7 @@ fullline = sys.stdin.readline()
printpending = True
clearpending = False
holdoff = 0
padded = None
while fullline:
for line in fullline.split('\n'):
if not line:
@@ -92,13 +94,18 @@ while fullline:
line = 'UNKNOWN: ' + line
if options.log:
node, output = line.split(':', 1)
output = output.lstrip()
if padded is None:
if output.startswith(' '):
padded = True
else:
padded = False
if padded:
output = re.sub(r'^ ', '', output)
currlog = options.log.format(node=node, nodename=node)
with open(currlog, mode='a') as log:
log.write(output + '\n')
continue
node, output = line.split(':', 1)
output = output.lstrip()
grouped.add_line(node, output)
if options.watch:
if not holdoff:
+12 -7
View File
@@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2014 IBM Corporation
@@ -654,13 +654,17 @@ def quitconfetty(code=0, fullexit=False, fixterm=True):
def get_session_node(shellargs):
# straight to node console
if len(shellargs) == 1 and ' ' not in shellargs[0]:
return shellargs[0]
targ = "/nodes/%s/console/session" % shellargs[0]
return targ, shellargs[0]
if len(shellargs) == 2 and shellargs[0] == 'start':
args = [s for s in shellargs[1].split('/') if s]
if len(args) == 4 and args[0] == 'nodes' and args[2] == 'console' and \
args[3] == 'session':
return args[1]
return None
return shellargs[1], args[1]
if len(args) == 5 and args[0] == 'nodes' and args[2] == 'shell' and \
args[3] == 'sessions':
return shellargs[1], args[1]
return None, None
def run_inline_command(path, arg, completion, **kwargs):
@@ -917,10 +921,10 @@ def main():
doexit = False
inconsole = False
pendingcommand = ""
session_node = get_session_node(shellargs)
targ, session_node = get_session_node(shellargs)
if session_node is not None:
consoleonly = True
do_command("start /nodes/%s/console/session" % session_node, netserver)
do_command("start %s" % targ, netserver)
doexit = True
elif shellargs:
do_command(shellargs, netserver)
@@ -948,8 +952,9 @@ def main():
except IOError:
pass
if powerstate is None or powertime < time.time() - 10: # Check powerstate every 10 seconds
if powerstate == None:
powerstate = True
powertime = time.time()
powerstate = True
check_power_state()
else:
currcommand = prompt()
+9 -2
View File
@@ -118,6 +118,7 @@ def main():
ap.add_argument('-a', '--attrib', help='Pull ip addresses and hostnames from attribute database', action='store_true')
ap.add_argument('-i', '--ip', help='Expression to generate addresses (e.g. 172.16.1.{n1} or fd2b:246f:8a50::{n1:x})')
ap.add_argument('-n', '--name', help='Expression for name to add ({node}-compute, etc). If unspecified, "{node} {node}.{dns.domain}" will be used', action='append')
ap.add_argument('-f', '--fqdn-first', help='Put the FQDN first in the hosts entries', action='store_true')
args = ap.parse_args()
c = client.Command()
if args.name:
@@ -157,7 +158,7 @@ def main():
elif attrib.endswith('.ipv6_address') and val:
ip6bynode[node][currnet] = val.split('/', 1)[0]
elif attrib.endswith('.hostname'):
namesbynode[node][currnet] = re.split('\s+|,', val)
namesbynode[node][currnet] = re.split(r'\s+|,', val)
for node in ip4bynode:
mydomain = domainsbynode.get(node, None)
for ipdb in (ip4bynode, ip6bynode):
@@ -173,7 +174,13 @@ def main():
break
else:
for name in list(names):
names.append('{0}.{1}'.format(name, mydomain))
fqdn = '{0}.{1}'.format(name, mydomain)
if args.fqdn_first:
# Insert FQDN at the beginning if --fqdn-first flag is set
names.insert(0, fqdn)
else:
# Otherwise, append FQDN at the end (original behavior)
names.append(fqdn)
names = ' '.join(names)
merger.add_entry(ipdb[node][currnet], names)
merger.write_out('/etc/whatnowhosts')
+39 -19
View File
@@ -8,30 +8,35 @@ import os
import subprocess
import sys
def create_image(directory, image, label=None):
ents = 0
datasz = 512
for dir in os.walk(sys.argv[1]):
ents += 1
for filen in dir[2]:
def create_image(directory, image, label=None, esize=0, totalsize=None):
if totalsize:
datasz = totalsize * 1048576
else:
ents = 0
datasz = 512 + (esize * 1048576)
for dir in os.walk(sys.argv[1]):
ents += 1
filename = os.path.join(dir[0], filen)
currsz = os.path.getsize(filename)
# assuming up to 65k cluster
currsz = (currsz // 512 +1) * 512
datasz += currsz
datasz += ents * 32768
datasz = datasz // 16384 + 1
for filen in dir[2]:
ents += 1
filename = os.path.join(dir[0], filen)
currsz = os.path.getsize(filename)
# assuming up to 65k cluster
currsz = (currsz // 512 + 1) * 512
datasz += currsz
datasz += ents * 32768
datasz = datasz // 65536 + 1
with open(image, 'wb') as imgfile:
imgfile.seek(datasz * 16384 - 1)
imgfile.seek(datasz * 65536 - 1)
imgfile.write(b'\x00')
if label:
# 4 heads, 32 sectors, means 65k per track
subprocess.check_call(['mformat', '-i', image, '-v', label,
'-r', '16', '-d', '1', '-t', str(datasz),
'-s', '16','-h', '2', '::'])
'-s', '32','-h', '4', '::'])
else:
subprocess.check_call(['mformat', '-i', image, '-r', '16', '-d', '1', '-t',
str(datasz), '-s', '16','-h', '2', '::'])
str(datasz), '-s', '32','-h', '4', '::'])
# Some clustered filesystems will have the lock from mformat
# linger after close (mformat doesn't unlock)
# do a blocking wait for shared lock and then explicitly
@@ -56,6 +61,21 @@ if __name__ == '__main__':
sys.argv[0]))
sys.exit(1)
label = None
if len(sys.argv) > 3:
label = sys.argv[3]
create_image(sys.argv[1], sys.argv[2], label)
args = sys.argv
esize = 0
try:
earg = args.index('-e')
esize = int(args[earg + 1])
args = args[:earg] + args[earg +2:]
except ValueError:
pass
totsize = None
try:
earg = args.index('-s')
totsize = int(args[earg + 1])
args = args[:earg] + args[earg +2:]
except ValueError:
pass
if len(args) > 3:
label = args[3]
create_image(args[1], args[2], label, esize, totsize)
+166
View File
@@ -0,0 +1,166 @@
#!/usr/bin/python3
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2016-2017 Lenovo
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from collections import deque
import optparse
import os
import select
import signal
import subprocess
import sys
try:
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
except AttributeError:
pass
path = os.path.dirname(os.path.realpath(__file__))
path = os.path.realpath(os.path.join(path, '..', 'lib', 'python'))
if path.startswith('/opt'):
sys.path.append(path)
import confluent.client as client
import confluent.sortutil as sortutil
devnull = None
def run():
global devnull
devnull = open(os.devnull, 'rb')
argparser = optparse.OptionParser(
usage="Usage: %prog [options] noderange commandexpression",
epilog="Expressions are the same as in attributes, e.g. "
"'ipmitool -H {hardwaremanagement.manager}' will be expanded.")
argparser.add_option('-f', '-c', '--count', type='int', default=168,
help='Number of commands to run at a time')
argparser.add_option('-k', '--security', action='store_true',
help='Update SSH setup')
argparser.add_option('-F', '--sync', action='store_true',
help='Run the syncfiles associated with the currently completed OS profile on the noderange')
argparser.add_option('-P', '--scripts',
help='Re-run specified scripts, with full path under scripts, e.g. post.d/first,firstboot.d/second')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to run remote ssh command to, '
'prompting if over the threshold')
# among other things, FD_SETSIZE limits. Besides, spawning too many
# processes can be unkind for the unaware on memory pressure and such...
#argparser.disable_interspersed_args()
(options, args) = argparser.parse_args()
if len(args) < 1:
argparser.print_help()
sys.exit(1)
client.check_globbing(args[0])
concurrentprocs = options.count
c = client.Command()
currprocs = 0
all = set([])
pipedesc = {}
pendingexecs = deque()
exitcode = 0
c.stop_if_noderange_over(args[0], options.maxnodes)
nodemap = {}
cmdparms = []
nodes = []
for res in c.read('/noderange/{0}/nodes/'.format(args[0])):
if 'error' in res:
sys.stderr.write(res['error'] + '\n')
exitcode |= res.get('errorcode', 1)
break
node = res['item']['href'][:-1]
nodes.append(node)
cmdstorun = []
if options.security:
cmdstorun.append(['run_remote', 'setupssh'])
if options.sync:
cmdstorun.append(['run_remote_python', 'syncfileclient'])
if options.scripts:
for script in options.scripts.split(','):
cmdstorun.append(['run_remote', script])
if not cmdstorun:
argparser.print_help()
sys.exit(1)
idxbynode = {}
cmdvbase = ['bash', '/etc/confluent/functions']
for sshnode in nodes:
idxbynode[sshnode] = 1
cmdv = ['ssh', sshnode] + cmdvbase + cmdstorun[0]
if currprocs < concurrentprocs:
currprocs += 1
run_cmdv(sshnode, cmdv, all, pipedesc)
else:
pendingexecs.append((sshnode, cmdv))
if not all or exitcode:
sys.exit(exitcode)
rdy, _, _ = select.select(all, [], [], 10)
while all:
pernodeout = {}
for r in rdy:
desc = pipedesc[r]
node = desc['node']
data = True
while data and select.select([r], [], [], 0)[0]:
data = r.readline()
if data:
if desc['type'] == 'stdout':
if node not in pernodeout:
pernodeout[node] = []
pernodeout[node].append(data)
else:
data = client.stringify(data)
sys.stderr.write('{0}: {1}'.format(node, data))
sys.stderr.flush()
else:
pop = desc['popen']
ret = pop.poll()
if ret is not None:
exitcode = exitcode | ret
all.discard(r)
r.close()
if desc['type'] == 'stdout':
if idxbynode[node] < len(cmdstorun):
cmdv = ['ssh', sshnode] + cmdvbase + cmdstorun[idxbynode[node]]
idxbynode[node] += 1
run_cmdv(node, cmdv, all, pipedesc)
elif pendingexecs:
node, cmdv = pendingexecs.popleft()
run_cmdv(node, cmdv, all, pipedesc)
for node in sortutil.natural_sort(pernodeout):
for line in pernodeout[node]:
line = client.stringify(line)
line = line.lstrip('\x08')
sys.stdout.write('{0}: {1}'.format(node, line))
sys.stdout.flush()
if all:
rdy, _, _ = select.select(all, [], [], 10)
sys.exit(exitcode)
def run_cmdv(node, cmdv, all, pipedesc):
nopen = subprocess.Popen(
cmdv, stdin=devnull, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
pipedesc[nopen.stdout] = {'node': node, 'popen': nopen,
'type': 'stdout'}
pipedesc[nopen.stderr] = {'node': node, 'popen': nopen,
'type': 'stderr'}
all.add(nopen.stdout)
all.add(nopen.stderr)
if __name__ == '__main__':
run()
+21
View File
@@ -22,6 +22,7 @@ import optparse
import os
import signal
import sys
import shlex
try:
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
@@ -53,6 +54,8 @@ argparser.add_option('-p', '--prompt', action='store_true',
argparser.add_option('-m', '--maxnodes', type='int',
help='Prompt if trying to set attributes on more '
'than specified number of nodes')
argparser.add_option('-s', '--set', dest='set', metavar='settings.batch',
default=False, help='set attributes using a batch file')
(options, args) = argparser.parse_args()
@@ -109,10 +112,28 @@ elif options.clear or options.environment or options.prompt:
sys.stderr.write('Attribute names required with specified options\n')
argparser.print_help()
exitcode = 400
elif options.set:
arglist = [noderange]
showtype='current'
argfile = open(options.set, 'r')
argset = argfile.readline()
while argset:
try:
argset = argset[:argset.index('#')]
except ValueError:
pass
argset = argset.strip()
if argset:
arglist += shlex.split(argset)
argset = argfile.readline()
session.stop_if_noderange_over(noderange, options.maxnodes)
exitcode=client.updateattrib(session,arglist,nodetype, noderange, options, None)
if exitcode != 0:
sys.exit(exitcode)
# Lists all attributes
if len(args) > 0:
# setting output to all so it can search since if we do have something to search, we want to show all outputs even if it is blank.
if requestargs is None:
+121
View File
@@ -0,0 +1,121 @@
#!/usr/libexec/platform-python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2015-2017 Lenovo
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
__author__ = 'tkucherera'
from getpass import getpass
import optparse
import os
import signal
import sys
try:
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
except AttributeError:
pass
path = os.path.dirname(os.path.realpath(__file__))
path = os.path.realpath(os.path.join(path, '..', 'lib', 'python'))
if path.startswith('/opt'):
sys.path.append(path)
import confluent.client as client
argparser = optparse.OptionParser(usage="Usage: %prog <noderange> <username> <new_password>")
argparser.add_option('-m', '--maxnodes', type='int',
help='Number of nodes to affect before prompting for confirmation')
argparser.add_option('-p', '--prompt', action='store_true',
help='Prompt for password values interactively')
argparser.add_option('-e', '--environment', action='store_true',
help='Set passwod, but from environment variable of '
'same name')
(options, args) = argparser.parse_args()
try:
noderange = args[0]
username = args[1]
except IndexError:
argparser.print_help()
sys.exit(1)
client.check_globbing(noderange)
session = client.Command()
exitcode = 0
if options.prompt:
oneval = 1
twoval = 2
while oneval != twoval:
oneval = getpass('Enter pass for {0}: '.format(username))
twoval = getpass('Confirm pass for {0}: '.format(username))
if oneval != twoval:
print('Values did not match.')
new_password = twoval
elif len(args) == 3:
if options.environment:
key = args[2]
new_password = os.environ.get(key, os.environ[key.upper()])
else:
new_password = args[2]
else:
argparser.print_help()
sys.exit(1)
errorNodes = set([])
uid_dict = {}
session.stop_if_noderange_over(noderange, options.maxnodes)
for rsp in session.read('/noderange/{0}/configuration/management_controller/users/all'.format(noderange)):
databynode = rsp["databynode"]
for node in databynode:
if 'error' in rsp['databynode'][node]:
print(node, ':', rsp['databynode'][node]['error'])
errorNodes.add(node)
continue
for user in rsp['databynode'][node]['users']:
if user['username'] == username:
if not user['uid'] in uid_dict:
uid_dict[user['uid']] = node
continue
uid_dict[user['uid']] = uid_dict[user['uid']] + ',{}'.format(node)
break
if not uid_dict:
print("Error: Could not reach target node's bmc user")
sys.exit(1)
for uid in uid_dict:
success = session.simple_noderange_command(uid_dict[uid], 'configuration/management_controller/users/{0}'.format(uid), new_password, key='password', errnodes=errorNodes) # = 0 if successful
allNodes = set([])
for node in session.read('/noderange/{0}/nodes/'.format(noderange)):
if 'error' in node and success != 0:
sys.exit(success)
allNodes.add(node['item']['href'].replace("/", ""))
goodNodes = allNodes - errorNodes
for node in goodNodes:
print(node + ": Password Change Successful")
sys.exit(success)
+8 -3
View File
@@ -303,9 +303,14 @@ else:
'/noderange/{0}/configuration/management_controller/extended/all'.format(noderange),
session, printbmc, options, attrprefix='bmc.')
if options.extra:
rcode |= client.print_attrib_path(
'/noderange/{0}/configuration/management_controller/extended/extra'.format(noderange),
session, printextbmc, options)
if options.advanced:
rcode |= client.print_attrib_path(
'/noderange/{0}/configuration/management_controller/extended/extra_advanced'.format(noderange),
session, printextbmc, options)
else:
rcode |= client.print_attrib_path(
'/noderange/{0}/configuration/management_controller/extended/extra'.format(noderange),
session, printextbmc, options)
if printsys or options.exclude:
if printsys == 'all':
printsys = []
+406 -14
View File
@@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/libexec/platform-python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2015 Lenovo
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import base64
import optparse
import os
import subprocess
@@ -23,12 +24,36 @@ path = os.path.dirname(os.path.realpath(__file__))
path = os.path.realpath(os.path.join(path, '..', 'lib', 'python'))
if path.startswith('/opt'):
sys.path.append(path)
import confluent.client as client
import confluent.sortutil as sortutil
import confluent.logreader as logreader
import time
import select
import signal
import socket
import re
import tty
import termios
import fcntl
import confluent.screensqueeze as sq
try:
from PIL import Image, ImageDraw
except ImportError:
Image = None
try:
# sixel is optional, attempt to import but stub out if unavailable
import io
import sixel
class DumbWriter(sixel.SixelWriter):
def restore_position(self, output):
return
except ImportError:
class DumbWriter():
def draw(self, imgfile):
sys.stderr.write("PySixel not detected, Sixel format display not supported\n")
confettypath = os.path.join(os.path.dirname(sys.argv[0]), 'confetty')
argparser = optparse.OptionParser(
@@ -41,6 +66,15 @@ argparser.add_option('-t', '--tile', action='store_true', default=False,
help='Tile console windows in the terminal')
argparser.add_option('-l', '--log', action='store_true', default=False,
help='Enter log replay mode instead of showing a live console')
argparser.add_option('-T', '--Timestamp', action='store_true', default=False,
help= 'Dump log in stdout with timestamps')
argparser.add_option('-s', '--screenshot', action='store_true', default=False,
help='Attempt to grab screenshot and render using kitty image protocol')
argparser.add_option('-i', '--interval', type='float',
help='Interval in seconds to redraw the screenshot. Currently only '
'works for one node')
argparser.add_option('-w','--windowed', action='store_true', default=False,
help='Open terminal windows for each node. The '
'environment variable NODECONSOLE_WINDOWED_COMMAND '
@@ -64,6 +98,209 @@ argparser.add_option('-w','--windowed', action='store_true', default=False,
(options, args) = argparser.parse_args()
oldtcattr = None
oldfl = None
def get_coords():
sys.stdout.write('\x1b[6n') #
sys.stdout.flush()
gotreply = select.select([sys.stdin,], [], [], 0.250)[0]
if gotreply:
response = ''
while select.select([sys.stdin,], [], [], 0.1)[0] and 'R' not in response:
response += sys.stdin.read()
coords = response.replace('R', '').split('[')[1].split(';')
#sys.stdout.write('\x1b[{}:{}H'.format(*coords))
def direct_console():
global oldtcattr
global oldfl
oldtcattr = termios.tcgetattr(sys.stdin.fileno())
oldfl = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL)
tty.setraw(sys.stdin.fileno())
fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, oldfl | os.O_NONBLOCK)
def indirect_console():
fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, oldfl & ~os.O_NONBLOCK)
termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, oldtcattr)
def determine_tile_size(numnodes):
# for now, smash everything to a common aspect ratio. 16:11
# is pretty much wrong for everything, making 4:3 a bit too wide
# and 16:9 significantly too narrow, but it is serviceable
# An improvement could come with us owning the scaling
# instead of delegating to Kitty, which says if we specify both,
# we get stretching. In theory we should be able to get aspect correct
# from kitty by omitting, but:
# then we don't know how much to move the cursor left after draw_image
# Konsole won't scale at all with only partial scaling specified
cheight, cwidth, pixwidth, pixheight = sq.get_screengeom()
# 16:12 is to roughly account for the 'titles' of the tiles
ratio = (pixwidth / 16) / (pixheight / 12)
bestdeviation = None
bestdims = []
for i in range(1, numnodes + 1):
number = numnodes
while number % i != 0:
number += 1
columns = i
rows = number // i
deviation = abs(ratio - (columns / rows))
if bestdeviation is None:
bestdeviation = deviation
bestdims = [columns, rows]
elif deviation < bestdeviation:
bestdeviation = deviation
bestdims = [columns, rows]
# ok, the above algorithm can still pick things like
# 1 2 3
# 4
# So we will let it pick the number of rows, and
# then see if we can chop columns and still fit
while (bestdims[0] - 1) * bestdims[1] >= numnodes:
bestdims[0] = bestdims[0] - 1
cellswide = cwidth // bestdims[0]
cellshigh = cheight // bestdims[1]
tilewidth = cellswide * pixwidth / cwidth
tileheight = cellshigh * pixheight / cheight
if tilewidth > (tileheight * 16 / 11):
tilewidth = tileheight * 16 / 11
cellswide = int(tilewidth // (pixwidth / cwidth))
if tileheight > (tilewidth * 11 /16):
tileheight = tilewidth * 11 / 16
cellshigh = int(tileheight // (pixheight / cheight))
bestdims = bestdims + [cellswide, cellshigh, cellshigh * bestdims[1]]
# incur any scrolling we might get. This allows us to accurately
# save/restore cursor or even get coordinates without scrolling fouling
# the desired target
sys.stdout.write('\n' * bestdims[4])
sys.stdout.flush()
cursor_up(bestdims[4])
return bestdims
cursor_saved = False
def sticky_cursor():
global cursor_saved
# get cursor restore_position
if sys.stdin.isatty() and not cursor_saved:
try:
direct_console()
sys.stdout.write('\x1b7')
cursor_saved = True
finally:
indirect_console()
elif cursor_saved:
try:
direct_console()
sys.stdout.write('\x1b8')
finally:
indirect_console()
def cursor_up(count=1):
sys.stdout.write(f'\x1b[{count}A')
def cursor_down(count=1):
sys.stdout.write(f'\x1b[{count}B')
def cursor_right(count=1):
sys.stdout.write(f'\x1b[{count}C')
def cursor_left(count=1):
sys.stdout.write(f'\x1b[{count}D')
def cursor_save():
sys.stdout.write('\x1b7')
def cursor_restore():
sys.stdout.write('\x1b8')
def cursor_hide():
sys.stdout.write('\x1b[?25l')
def cursor_show():
sys.stdout.write('\x1b[?25h')
def draw_text(text, width, height):
if Image:
maxfntsize = 256
nerr = Image.new(mode='RGB', size=(1024,768), color='green')
nd = ImageDraw.Draw(nerr)
for txtpiece in text.split('\n'):
fntsize = 8
while nd.textlength(txtpiece, font_size=fntsize) < 896:
fntsize += 1
fntsize -= 1
if fntsize < maxfntsize:
maxfntsize = fntsize
nd.text((64, 64), text, font_size=maxfntsize)
outfile = io.BytesIO()
nerr.save(outfile, format='PNG')
data = base64.b64encode(outfile.getbuffer())
draw_image(data, width, height)
else:
sys.stdout.write(text)
cursor_left(len(txt))
def draw_image(data, width, height):
imageformat = os.environ.get('CONFLUENT_IMAGE_PROTOCOL', 'kitty')
if imageformat == 'sixel':
sixel_draw(data)
elif imageformat == 'iterm':
iterm_draw(data, width, height)
else:
kitty_draw(data, width, height)
def sixel_draw(data):
bindata = base64.b64decode(data)
binfile = io.BytesIO()
binfile.write(bindata)
binfile.seek(0)
DumbWriter().draw(binfile)
def iterm_draw(data, width, height):
if not height:
height = 'auto'
if not width:
width = 'auto'
bindata = base64.b64decode(data)
datalen = len(bindata)
sys.stdout.write(
'\x1b]1337;File=inline=1;width={};height={};size={}:'.format(width,height,datalen))
sys.stdout.write(data.decode('utf8'))
sys.stdout.write('\a')
sys.stdout.flush()
def kitty_draw(data, width, height):
if Image:
bindata = base64.b64decode(data)
binfile = io.BytesIO()
binfile.write(bindata)
binfile.seek(0)
try:
img = Image.open(binfile)
except Exception as e:
errstr = 'Error rendering image:\n' + str(e)
return draw_text(errstr, width, height)
nimg = Image.new(mode='RGB', size=(img.width + 4, img.height + 4), color='black')
nd = ImageDraw.Draw(nimg)
nd.rectangle((0, 0, nimg.width - 1, nimg.height -1), outline='white', width=1)
nimg.paste(img, box=(2, 2))
outfile = io.BytesIO()
nimg.save(outfile, format='PNG')
data = base64.b64encode(outfile.getbuffer())
preamble = '\x1b_Ga=T,f=100'
if height:
preamble += f',r={height},c={width}'
#sys.stdout.write(repr(preamble))
#sys.stdout.write('\xb[{}D'.format(len(repr(preamble))))
#return
first = True
while data:
chunk, data = data[:4096], data[4096:]
m = 1 if data else 0
if first:
sys.stdout.write('{},m={};'.format(preamble, m))
else:
sys.stdout.write('\x1b_Gm={};'.format(m))
sys.stdout.write(chunk.decode('utf8'))
sys.stdout.write('\x1b\\')
sys.stdout.flush()
pass_through_args = []
killcon = False
try:
@@ -91,6 +328,153 @@ if options.log:
logreader.replay_to_console(logname)
sys.exit(0)
if options.Timestamp:
logname = args[0]
if not os.path.exists(logname) and logname[0] != '/':
logname = os.path.join('/var/log/confluent/consoles', logname)
if not os.path.exists(logname):
sys.stderr.write('Unable to locate {0} on local system\n'.format(logname))
sys.exit(1)
logreader.dump_to_console(logname)
sys.exit(0)
def prep_node_tile(node):
currcolcell, currrowcell = nodepositions[node]
if currcolcell:
cursor_right(currcolcell)
if currrowcell:
cursor_down(currrowcell)
sys.stdout.write('▏' + node)
cursor_left(len(node) + 1)
cursor_down()
def reset_cursor(node):
currcolcell, currrowcell = nodepositions[node]
if currcolcell:
cursor_left(currcolcell)
cursor_up(currrowcell + 1)
nodepositions = {}
numrows = 0
cwidth = 0
cheight = 0
imagedatabynode = {}
def redraw():
for node in imagedatabynode:
imgdata = imagedatabynode[node]
if node in nodepositions:
prep_node_tile(node)
cursor_save()
else:
if options.interval is not None:
if node != firstnodename:
sys.stderr.write('Multiple nodes not supported for interval')
sys.exit(1)
sticky_cursor()
sys.stdout.write('{}: '.format(node))
# one row is used by our own name, so cheight - 1 for that allowance
draw_image(imgdata.encode(), cwidth, cheight - 1 if cheight else cheight)
if node in nodepositions:
cursor_restore()
reset_cursor(node)
else:
sys.stdout.write('\n')
sys.stdout.flush()
def do_screenshot():
global numrows
sess = client.Command()
if options.tile:
imageformat = os.environ.get('CONFLUENT_IMAGE_PROTOCOL', 'kitty')
if imageformat not in ('kitty', 'iterm'):
sys.stderr.write('Tiled screenshots only supported with kitty or iterm protocol')
sys.exit(1)
allnodes = []
numnodes = 0
for res in sess.read('/noderange/{}/nodes/'.format(args[0])):
allnodes.append(res['item']['href'].replace('/', ''))
numnodes += 1
def do_resize(a=None, b=None):
if a:
# on a window resize, clear the old stuff
# ideally we'd retain the images and redraw them
sys.stdout.write('\x1bc')
global numrows
global cwidth
global cheight
cols, rows, cwidth, cheight, numrows = determine_tile_size(numnodes)
currcol = 1
currcolcell = 0
currrowcell = 0
for node in allnodes:
nodepositions[node] = currcolcell, currrowcell
if currcol < cols:
currcol += 1
currcolcell += cwidth
else:
currcol = 1
currcolcell = 0
currrowcell += cheight
if a:
redraw()
do_resize()
signal.signal(signal.SIGWINCH, do_resize)
elif options.interval is not None:
sys.stdout.write('\x1bc')
firstnodename = None
dorefresh = True
while dorefresh:
for res in sess.read('/noderange/{}/console/ikvm_screenshot'.format(args[0])):
for node in res.get('databynode', {}):
if not firstnodename:
firstnodename = node
imgdata = res['databynode'][node].get('image', {}).get('imgdata', None)
if imgdata:
errorstr = ''
if len(imgdata) < 32: # We were subjected to error
errorstr = f'Unable to get screenshot'
imagedatabynode[node] = imgdata
if node in nodepositions:
prep_node_tile(node)
cursor_save()
else:
if options.interval is not None:
if node != firstnodename:
sys.stderr.write('Multiple nodes not supported for interval')
sys.exit(1)
sticky_cursor()
sys.stdout.write('{}: '.format(node))
# one row is used by our own name, so cheight - 1 for that allowance
if errorstr:
draw_text(errorstr, cwidth, cheight -1 if cheight else cheight)
else:
draw_image(imgdata.encode(), cwidth, cheight - 1 if cheight else cheight)
if node in nodepositions:
cursor_restore()
reset_cursor(node)
else:
sys.stdout.write('\n')
sys.stdout.flush()
if options.interval is None:
dorefresh = False
else:
dorefresh = True
time.sleep(options.interval)
sys.exit(0)
if options.screenshot:
try:
cursor_hide()
do_screenshot()
except KeyboardInterrupt:
pass
finally:
cursor_show()
cursor_down(numrows)
sys.stdout.write('\n')
sys.exit(0)
def kill(noderange):
sess = client.Command()
envstring=os.environ.get('NODECONSOLE_WINDOWED_COMMAND')
@@ -98,21 +482,23 @@ def kill(noderange):
envstring = 'xterm'
nodes = []
for res in sess.read('/noderange/{0}/nodes/'.format(args[0])):
for res in sess.read('/noderange/{0}/nodes/'.format(noderange)):
node = res.get('item', {}).get('href', '/').replace('/', '')
if not node:
sys.stderr.write(res.get('error', repr(res)) + '\n')
sys.exit(1)
nodes.append(node)
for node in nodes:
ps_data=subprocess.Popen(['ps', '-auxww' ], stdout=subprocess.PIPE)
wintr=ps_data.communicate()[0]
for line in wintr.decode('utf-8').split('\n'):
if confettypath in line and envstring in line and node in line:
pid_line = [x for x in line.split(' ') if x != '']
ps_data=subprocess.Popen(['kill', '-9', pid_line[1] ], stdout=subprocess.PIPE)
for node in nodes:
command = "ps auxww | grep {0} | grep console | egrep '\\b{1}\\b' | grep -v grep | awk '{{print $2}}'".format(envstring, node)
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
try:
process_id = stdout.decode('utf-8').split()[0]
except IndexError:
sys.stderr.write(node + ": console window not found \n")
continue
subprocess.Popen(["kill", process_id], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sys.exit(0)
def handle_geometry(envlist, sizegeometry, side_pad=0, top_pad=0, first=False):
@@ -220,7 +606,7 @@ if options.windowed:
elif 'Height' in line:
window_height = int(line.split(':')[1])
elif '-geometry' in line:
l = re.split(' |x|\+', line)
l = re.split(' |x|-|\\+', line)
l_nosp = [ele for ele in l if ele.strip()]
wmxo = int(l_nosp[1])
wmyo = int(l_nosp[2])
@@ -259,7 +645,7 @@ if options.windowed:
else:
pass
with open(os.devnull, 'wb') as devnull:
xopen=subprocess.Popen(envlist + [confettypath, '-m', '5', 'start', '/nodes/{0}/console/session'.format(node)] , stdin=devnull)
xopen=subprocess.Popen(envlist + [confettypath, '-c', '/tmp/controlpath-{0}'.format(node), '-m', '5', 'start', '/nodes/{0}/console/session'.format(node)] , stdin=devnull)
sys.exit(0)
#end of wcons
if options.tile:
@@ -273,8 +659,13 @@ if options.tile:
sys.exit(1)
nodes.append(node)
initial = True
in_tmux = False
pane = 0
sessname = 'nodeconsole_{0}'.format(os.getpid())
if os.environ.get("TMUX"):
initial = False
in_tmux = True
subprocess.call(['tmux', 'rename-session', sessname])
for node in sortutil.natural_sort(nodes):
panename = '{0}:{1}'.format(sessname, pane)
if initial:
@@ -295,7 +686,8 @@ if options.tile:
pane += 1
subprocess.call(['tmux', 'select-pane', '-t', sessname])
subprocess.call(['tmux', 'set-option', '-t', panename, 'pane-border-status', 'top'], stderr=null)
os.execlp('tmux', 'tmux', 'attach', '-t', sessname)
if not in_tmux:
os.execlp('tmux', 'tmux', 'attach', '-t', sessname)
else:
os.execl(confettypath, confettypath, 'start',
'/nodes/{0}/console/session'.format(args[0]))
'/nodes/{0}/console/session'.format(args[0]))
+28 -14
View File
@@ -81,6 +81,12 @@ def main(args):
if not args.profile and args.network:
sys.stderr.write('Both noderange and a profile name are required arguments to request a network deployment\n')
return 1
if args.clear and args.profile:
sys.stderr.write(
'The -c/--clear option should not be used with a profile, '
'it is a request to not deploy any profile, and will clear '
'whatever the current profile is without being specified\n')
return 1
if extra:
sys.stderr.write('Unrecognized arguments: ' + repr(extra) + '\n')
c = client.Command()
@@ -90,17 +96,6 @@ def main(args):
if 'error' in rsp:
sys.stderr.write(rsp['error'] + '\n')
sys.exit(1)
if not args.clear and args.network and not args.prepareonly:
rc = c.simple_noderange_command(args.noderange, '/boot/nextdevice', 'network',
bootmode='uefi',
persistent=False,
errnodes=errnodes)
if errnodes:
sys.stderr.write(
'Unable to set boot device for following nodes: {0}\n'.format(
','.join(errnodes)))
return 1
rc |= c.simple_noderange_command(args.noderange, '/power/state', 'boot')
if args.clear:
cleararm(args.noderange, c)
clearpending(args.noderange, c)
@@ -120,7 +115,17 @@ def main(args):
for profname in profnames:
sys.stderr.write(' ' + profname + '\n')
else:
sys.stderr.write('No deployment profiles available, try osdeploy fiimport or imgutil capture\n')
sys.stderr.write('No deployment profiles available, try osdeploy import or imgutil capture\n')
sys.exit(1)
lockednodes = []
for lockinfo in c.read('/noderange/{0}/deployment/lock'.format(args.noderange)):
for node in lockinfo.get('databynode', {}):
lockstate = lockinfo['databynode'][node]['lock']['value']
if lockstate == 'locked':
lockednodes.append(node)
if lockednodes:
sys.stderr.write('Requested noderange has nodes with locked deployment: ' + ','.join(lockednodes))
sys.stderr.write('\n')
sys.exit(1)
armonce(args.noderange, c)
setpending(args.noderange, args.profile, c)
@@ -166,8 +171,17 @@ def main(args):
else:
print('{0}: {1}{2}'.format(node, profile, armed))
sys.exit(0)
if args.network and not args.prepareonly:
return rc
if not args.clear and args.network and not args.prepareonly:
rc = c.simple_noderange_command(args.noderange, '/boot/nextdevice', 'network',
bootmode='uefi',
persistent=False,
errnodes=errnodes)
if errnodes:
sys.stderr.write(
'Unable to set boot device for following nodes: {0}\n'.format(
','.join(errnodes)))
return 1
rc |= c.simple_noderange_command(args.noderange, '/power/state', 'boot')
return 0
if __name__ == '__main__':
+5 -2
View File
@@ -78,8 +78,11 @@ exitcode = 0
def format_event(evt):
retparts = []
if 'timestamp' in evt and evt['timestamp'] is not None:
display = dt.strptime(evt['timestamp'], '%Y-%m-%dT%H:%M:%S')
retparts.append(display.strftime('%m/%d/%Y %H:%M:%S'))
try:
display = dt.strptime(evt['timestamp'], '%Y-%m-%dT%H:%M:%S')
retparts.append(display.strftime('%m/%d/%Y %H:%M:%S'))
except ValueError:
display = ''
dscparts = []
if evt.get('log_id', None):
retparts.append(evt['log_id'] + ':')
+15 -2
View File
@@ -56,7 +56,7 @@ components = ['all']
argparser = optparse.OptionParser(
usage="Usage: "
"%prog <noderange> [list][update [--backup <file>]]|[<components>]")
"%prog <noderange> [list][updatestatus][update [--backup <file>]]|[<components>]")
argparser.add_option('-b', '--backup', action='store_true',
help='Target a backup bank rather than primary')
argparser.add_option('-m', '--maxnodes', type='int',
@@ -65,14 +65,18 @@ argparser.add_option('-m', '--maxnodes', type='int',
(options, args) = argparser.parse_args()
upfile = None
querystatus = False
try:
noderange = args[0]
if len(args) > 1:
if args[1] == 'update':
upfile = args[2]
else:
comps = []
if args[1] == 'list':
comps = args[2:]
elif args[1] == 'updatestatus':
querystatus = True
else:
comps = args[1:]
components = []
@@ -171,7 +175,16 @@ def show_firmware(session):
try:
session = client.Command()
if upfile is None:
if querystatus:
for res in session.read(
'/noderange/{0}/inventory/firmware/updatestatus'.format(noderange)):
for node in res.get('databynode', {}):
currstat = res['databynode'][node].get('status', None)
if currstat:
print('{}: {}'.format(node, currstat))
else:
print(repr(res))
elif upfile is None:
show_firmware(session)
else:
update_firmware(session, upfile)
+176
View File
@@ -0,0 +1,176 @@
#!/usr/libexec/platform-python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2017 Lenovo
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
__author__ = 'tkucherera'
import optparse
import os
import signal
import sys
import subprocess
try:
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
except AttributeError:
pass
path = os.path.dirname(os.path.realpath(__file__))
path = os.path.realpath(os.path.join(path, '..', 'lib', 'python'))
if path.startswith('/opt'):
sys.path.append(path)
import confluent.client as client
argparser = optparse.OptionParser(
usage="Usage: %prog <start_node> -i <interface> <end_node> -e <eface>",
)
argparser.add_option('-i', '--interface', type='str',
help='interface to check path against for the start node')
argparser.add_option('-e', '--eface', type='str',
help='interface to check path against for the end node')
argparser.add_option('-c', '--cumulus', action="store_true", dest="cumulus",
help='return layer 2 route through cumulus switches only')
(options, args) = argparser.parse_args()
try:
start_node = args[0]
end_node = args[1]
interface = options.interface
eface = options.eface
except IndexError:
argparser.print_help()
sys.exit(1)
session = client.Command()
def get_neighbors(switch):
switch_neigbors = []
url = '/networking/neighbors/by-switch/{0}/by-peername/'.format(switch)
for neighbor in session.read(url):
try:
switch = neighbor['item']['href'].strip('/')
except:
continue
if switch in all_switches:
switch_neigbors.append(switch)
return switch_neigbors
def find_path(start, end, path=[]):
path = path + [start]
if start == end:
return path # If start and end are the same, return the path
for node in get_neighbors(start):
if node not in path:
new_path = find_path(node, end, path)
if new_path:
return new_path # If a path is found, return it
return None # If no path is found, return None
def is_cumulus(switch):
try:
read_attrib = subprocess.check_output(['nodeattrib', switch, 'hardwaremanagement.method'])
except subprocess.CalledProcessError:
return False
for attribs in read_attrib.decode('utf-8').split('\n'):
if len(attribs.split(':')) > 1:
attrib = attribs.split(':')
if attrib[2].strip() == 'affluent':
return True
else:
return False
else:
return False
def host_to_switch(node, interface=None):
# first check the the node config to see what switches are connected
# if host is in rhel can use nmstate package
if node in all_switches:
return [node]
switches = []
netarg = 'net.*.switch'
if interface:
netarg = 'net.{0}.switch'.format(interface)
try:
read_attrib = subprocess.check_output(['nodeattrib', node, netarg])
except subprocess.CalledProcessError:
return False
for attribs in read_attrib.decode('utf-8').split('\n'):
attrib = attribs.split(':')
try:
if ' net.mgt.switch' in attrib or attrib[2] == '':
continue
except IndexError:
continue
switch = attrib[2].strip()
if is_cumulus(switch) and options.cumulus:
switches.append(switch)
else:
switches.append(switch)
return switches
def path_between_nodes(start_switches, end_switches):
for start_switch in start_switches:
for end_switch in end_switches:
if start_switch == end_switch:
return [start_switch]
else:
path = find_path(start_switch, end_switch)
if path:
return path
else:
return 'No path found'
all_switches = []
for res in session.read('/networking/neighbors/by-switch/'):
if 'error' in res:
sys.stderr.write(res['error'] + '\n')
exitcode = 1
else:
switch = (res['item']['href'].replace('/', ''))
all_switches.append(switch)
end_nodeslist = []
nodelist = '/noderange/{0}/nodes/'.format(end_node)
for res in session.read(nodelist):
if 'error' in res:
sys.stderr.write(res['error'] + '\n')
exitcode = 1
else:
elem=(res['item']['href'].replace('/', ''))
end_nodeslist.append(elem)
start_switches = host_to_switch(start_node, interface)
for end_node in end_nodeslist:
if end_node:
end_switches = host_to_switch(end_node, eface)
if not end_switches:
print('Error: net.{0}.switch attribute is not valid')
continue
path = path_between_nodes(start_switches, end_switches)
print(f'{start_node} to {end_node}: {path}')
# TODO dont put switches that are connected through management interfaces.
+10 -3
View File
@@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/libexec/platform-python
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2015-2017 Lenovo
@@ -15,13 +15,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
__author__ = 'jjohnson2,alin37'
__author__ = 'jjohnson2,alin37,wgrzeda'
import optparse
import os
import signal
import sys
try:
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
except AttributeError:
@@ -39,9 +41,12 @@ def main():
" or: %prog [options] noderange <nodeattribute>...")
argparser.add_option('-b', '--blame', action='store_true',
help='Show information about how attributes inherited')
argparser.add_option('-d', '--delim', metavar="STRING", default = "\n",
help='Delimiter separating the values')
(options, args) = argparser.parse_args()
noderange=""
nodelist=""
list = []
try:
noderange = args[0]
nodelist = '/noderange/{0}/nodes/'.format(noderange)
@@ -61,7 +66,9 @@ def main():
sys.stderr.write(res['error'] + '\n')
exitcode = 1
else:
print(res['item']['href'].replace('/', ''))
elem=(res['item']['href'].replace('/', ''))
list.append(elem)
print(options.delim.join(list))
sys.exit(exitcode)
+7 -2
View File
@@ -1,4 +1,4 @@
#!/usr/bin/python2
#!/usr/bin/python3
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2016-2017 Lenovo
@@ -42,6 +42,8 @@ def run():
usage="Usage: %prog [options] noderange")
argparser.add_option('-f', '-c', '--count', type='int', default=168,
help='Number of commands to run at a time')
argparser.add_option('-o', '--origname', action='store_true',
help='Use original nodename in print out even if substituted')
argparser.add_option('-s', '--substitutename',
help='Use a different name other than the nodename for ping, with {}, it is the entire name evaluated as an expression, otherwise it is used as a suffix')
# among other things, FD_SETSIZE limits. Besides, spawning too many
@@ -83,7 +85,10 @@ def run():
cmdv = ['ping', '-c', '1', '-W', '1', pingnode]
if currprocs < concurrentprocs:
currprocs += 1
run_cmdv(pingnode, cmdv, all, pipedesc)
if options.origname:
run_cmdv(node, cmdv, all, pipedesc)
else:
run_cmdv(pingnode, cmdv, all, pipedesc)
else:
pendingexecs.append((pingnode, cmdv))
if not all or exitcode:
+15 -3
View File
@@ -48,6 +48,8 @@ def run():
'prompting if over the threshold')
argparser.add_option('-l', '--loginname', type='str',
help='Username to use when connecting, defaults to current user.')
argparser.add_option('-s', '--substitutename',
help='Use a different name other than the nodename for rsync')
argparser.add_option('-f', '-c', '--count', type='int', default=168,
help='Number of nodes to concurrently rsync')
# among other things, FD_SETSIZE limits. Besides, spawning too many
@@ -63,10 +65,20 @@ def run():
c = client.Command()
cmdstr = ' '.join(args[:-1])
cmdstr = 'rsync -av --info=progress2 ' + cmdstr
if options.loginname:
cmdstr += ' {}@'.format(options.loginname) + '{node}:' + targpath
targname = options.substitutename
if targname and '{' in targname:
targname = targname + ':'
elif targname:
targname = '{node}' + targname + ':'
else:
cmdstr += ' {node}:' + targpath
targname = '{node}:'
if options.loginname:
cmdstr += ' {}@'.format(options.loginname) + targname + targpath
else:
cmdstr += ' {}'.format(targname) + targpath
currprocs = 0
all = set([])
+2 -2
View File
@@ -67,7 +67,7 @@ argparser.add_option('-n', '--numreadings', type='int',
argparser.add_option('-c', '--csv', action='store_true',
help='Output in CSV format')
argparser.add_option('-s', '--skipnumberless', action='store_true',
help='Output in CSV format')
help='Do not show non-numeric sensors')
(options, args) = argparser.parse_args()
repeatmode = False
if options.interval:
@@ -141,7 +141,7 @@ def sensorpass(showout=True, appendtime=False):
if sensedata['value'] is None:
showval = ''
elif isinstance(sensedata['value'], float):
showval = floatformat(sensedata['value'])
showval = u' {0} '.format(floatformat(sensedata['value']))
else:
showval = u' {0} '.format(sensedata['value'])
if sensedata['units'] not in (None, u''):
+38 -9
View File
@@ -16,13 +16,10 @@
# limitations under the License.
import argparse
import base64
import csv
import fcntl
import io
import numpy as np
import os
import subprocess
import sys
try:
@@ -35,7 +32,31 @@ except ImportError:
pass
def plot(gui, output, plotdata, bins):
def iterm_draw(data):
databuf = data.getbuffer()
datalen = len(databuf)
data = base64.b64encode(databuf).decode('utf8')
sys.stdout.write(
'\x1b]1337;File=inline=1;size={}:'.format(datalen))
sys.stdout.write(data)
sys.stdout.write('\a')
sys.stdout.write('\n')
sys.stdout.flush()
def kitty_draw(data):
data = base64.b64encode(data.getbuffer())
while data:
chunk, data = data[:4096], data[4096:]
m = 1 if data else 0
sys.stdout.write('\x1b_Ga=T,f=100,m={};'.format(m))
sys.stdout.write(chunk.decode('utf8'))
sys.stdout.write('\x1b\\')
sys.stdout.flush()
sys.stdout.write('\n')
def plot(gui, output, plotdata, bins, fmt):
import matplotlib as mpl
if gui and mpl.get_backend() == 'agg':
sys.stderr.write('Error: No GUI backend available and -g specified!\n')
@@ -51,8 +72,15 @@ def plot(gui, output, plotdata, bins):
tdata = io.BytesIO()
plt.savefig(tdata)
if not gui and not output:
writer = DumbWriter()
writer.draw(tdata)
if fmt == 'environment':
fmt = os.environ.get('CONFLUENT_IMAGE_PROTOCOL', 'kitty')
if fmt == 'sixel':
writer = DumbWriter()
writer.draw(tdata)
elif fmt == 'kitty':
kitty_draw(tdata)
elif fmt == 'iterm':
iterm_draw(tdata)
return n, bins
def textplot(plotdata, bins):
@@ -81,7 +109,8 @@ histogram = False
aparser = argparse.ArgumentParser(description='Quick access to common statistics')
aparser.add_argument('-c', type=int, default=0, help='Column number to analyze (default is last column)')
aparser.add_argument('-d', default=None, help='Value used to separate columns')
aparser.add_argument('-x', default=False, action='store_true', help='Output histogram in sixel format')
aparser.add_argument('-x', default=False, action='store_true', help='Output histogram in graphical format')
aparser.add_argument('-f', default='environment', help='Format for histogram output (sixel/iterm/kitty)')
aparser.add_argument('-s', default=0, help='Number of header lines to skip before processing')
aparser.add_argument('-g', default=False, action='store_true', help='Open histogram in separate graphical window')
aparser.add_argument('-o', default=None, help='Output histogram to the specified filename in PNG format')
@@ -138,7 +167,7 @@ while data:
data = list(csv.reader([data], delimiter=delimiter))[0]
n = None
if args.g or args.o or args.x:
n, bins = plot(args.g, args.o, plotdata, bins=args.b)
n, bins = plot(args.g, args.o, plotdata, bins=args.b, fmt=args.f)
if args.t:
n, bins = textplot(plotdata, bins=args.b)
print('Samples: {5} Min: {3} Median: {0} Mean: {1} Max: {4} StandardDeviation: {2} Sum: {6}'.format(np.median(plotdata), np.mean(plotdata), np.std(plotdata), np.min(plotdata), np.max(plotdata), len(plotdata), np.sum(plotdata)))
+12 -1
View File
@@ -595,7 +595,7 @@ def print_attrib_path(path, session, requestargs, options, rename=None, attrpref
else:
printmissing.add(attr)
for missing in printmissing:
sys.stderr.write('Error: {0} not a valid attribute\n'.format(attr))
sys.stderr.write('Error: {0} not a valid attribute\n'.format(missing))
return exitcode
@@ -668,6 +668,9 @@ def updateattrib(session, updateargs, nodetype, noderange, options, dictassign=N
for attrib in updateargs[1:]:
keydata[attrib] = None
for res in session.update(targpath, keydata):
for node in res.get('databynode', {}):
for warnmsg in res['databynode'][node].get('_warnings', []):
sys.stderr.write('Warning: ' + warnmsg + '\n')
if 'error' in res:
if 'errorcode' in res:
exitcode = res['errorcode']
@@ -702,6 +705,14 @@ def updateattrib(session, updateargs, nodetype, noderange, options, dictassign=N
noderange, 'attributes/all', dictassign[key], key)
else:
if "=" in updateargs[1]:
update_ready = True
for arg in updateargs[1:]:
if not '=' in arg:
update_ready = False
exitcode = 1
if not update_ready:
sys.stderr.write('Error: {0} Can not set and read at the same time!\n'.format(str(updateargs[1:])))
sys.exit(exitcode)
try:
for val in updateargs[1:]:
val = val.split('=', 1)
+42
View File
@@ -296,5 +296,47 @@ def replay_to_console(txtfile):
sys.exit(1)
_replay_to_console(txtfile, binfile)
def dump_to_console(txtfile):
if os.path.exists(txtfile + '.cbl'):
binfile = txtfile + '.cbl'
elif '.' not in txtfile:
if '/' not in txtfile:
txtfile = os.getcwd() + '/' + txtfile
sys.stderr.write('Unable to locate cbl file: "{0}"\n'.format(txtfile + '.cbl'))
sys.exit(1)
else:
fileparts = txtfile.split('.')
prefix = '.'.join(fileparts[:-1])
binfile = prefix + '.cbl.' + fileparts[-1]
if not os.path.exists(binfile):
sys.stderr.write('Unable to locate cbl file: "{0}"\n'.format(binfile))
sys.exit(1)
replay = LogReplay(txtfile, binfile)
quitit = False
writeout('\x1b[2J\x1b[;H')
prepend = ''
try:
while not quitit:
newdata, delay = replay.get_output(False)
if newdata:
if prepend:
newdata = prepend + newdata
prepend = b''
writeout(newdata.replace(b'\r\n', '\r\n[ {0} ] '.format(time.strftime('%m/%d %H:%M:%S', time.localtime(replay.laststamp))).encode('utf8')))
newdata = ''
try:
if hasattr(sys.stdout, 'buffer'):
sys.stdout.buffer.flush()
else:
sys.stdout.flush()
except IOError:
pass
else:
break
except Exception:
writeout('\x1b[m\x1b[?25h\n')
raise
writeout('\x1b[m\x1b[?25h\n')
if __name__ == '__main__':
replay_to_console(sys.argv[1])
+5 -3
View File
@@ -18,8 +18,9 @@ import struct
import termios
def get_screengeom():
return struct.unpack('hh', fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ,
b'....'))
# returns height in cells, width in cells, width in pixels, height in pixels
return struct.unpack('hhhh', fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ,
b'........'))
class ScreenPrinter(object):
def __init__(self, noderange, client, textlen=4):
@@ -58,7 +59,7 @@ class ScreenPrinter(object):
def drawscreen(self, node=None):
if self.squeeze:
currheight, currwidth = get_screengeom()
currheight, currwidth, _, _ = get_screengeom()
currheight -= 2
if currheight < 1:
currheight = 1
@@ -120,6 +121,7 @@ if __name__ == '__main__':
c = client.Command()
p = ScreenPrinter('d1-d12', c)
p.set_output('d3', 'Upload: 67%')
p.set_output('d7', 'Upload: 67%')
+15 -4
View File
@@ -98,17 +98,24 @@ class GroupedData(object):
self.byoutput = {}
self.header = {}
self.client = confluentconnection
self.detectedpad = None
def generate_byoutput(self):
self.byoutput = {}
thepad = self.detectedpad if self.detectedpad else ''
for n in self.bynode:
output = '\n'.join(self.bynode[n])
output = ''
for ln in self.bynode[n]:
output += ln.replace(thepad, '', 1) + '\n'
if output not in self.byoutput:
self.byoutput[output] = set([n])
else:
self.byoutput[output].add(n)
def add_line(self, node, line):
wspc = re.search(r'^\s*', line).group()
if self.detectedpad is None or len(wspc) < len(self.detectedpad):
self.detectedpad = wspc
if node not in self.bynode:
self.bynode[node] = [line]
else:
@@ -164,7 +171,9 @@ class GroupedData(object):
self.byoutput[outdata])))
currout += '\n====================================\n'
currout += outdata
currout += '\n\n'
if currout[-1] != '\n':
currout += '\n'
currout += '\n'
output.write(currout)
output.flush()
@@ -204,7 +213,9 @@ class GroupedData(object):
else:
currout += '\n'.join(colordiff(modaloutput.split('\n'),
outdata.split('\n')))
currout += '\n\n'
if currout[-1] != '\n':
currout += '\n'
currout += '\n'
if reverse:
revoutput.append(currout)
else:
@@ -219,4 +230,4 @@ if __name__ == '__main__':
if not line:
continue
groupoutput.add_line(*line.split(': ', 1))
groupoutput.print_deviants()
groupoutput.print_deviants()
+6 -2
View File
@@ -1,12 +1,16 @@
%define name confluent_client
%define version #VERSION#
%define fversion %{lua:
sv, _ = string.gsub("#VERSION#", "[~+]", "-")
print(sv)
}
%define release 1
Summary: Client libraries and utilities for confluent
Name: %{name}
Version: %{version}
Release: %{release}
Source0: %{name}-%{version}.tar.gz
Source0: %{name}-%{fversion}.tar.gz
License: Apache2
Group: Development/Libraries
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
@@ -21,7 +25,7 @@ This package enables python development and command line access to
a confluent server.
%prep
%setup -n %{name}-%{version} -n %{name}-%{version}
%setup -n %{name}-%{fversion}
%build
%if "%{dist}" == ".el7"
+2 -2
View File
@@ -153,11 +153,11 @@ _confluent_osimage_completion()
{
_confluent_get_args
if [ $NUMARGS == 2 ]; then
COMPREPLY=($(compgen -W "initialize import updateboot rebase" -- ${COMP_WORDS[COMP_CWORD]}))
COMPREPLY=($(compgen -W "initialize import importcheck updateboot rebase" -- ${COMP_WORDS[COMP_CWORD]}))
return
elif [ ${CMPARGS[1]} == 'initialize' ]; then
COMPREPLY=($(compgen -W "-h -u -s -t -i" -- ${COMP_WORDS[COMP_CWORD]}))
elif [ ${CMPARGS[1]} == 'import' ]; then
elif [ ${CMPARGS[1]} == 'import' ] || [ ${CMPARGS[1]} == 'importcheck' ]; then
compopt -o default
COMPREPLY=()
return
@@ -13,7 +13,7 @@ noderange. There are two general approaches.
It can be used ad-hoc, using -i and -n to specify the address and name portions respectively. This accepts the standard confluent expression syntax, allowing for things like 172.30.1.{n1} or {node}.{dns.domain} or {bmc}.
It can also read from the confluent db, using `-a`. In this mode, each net.<value>.<attribute> group is pulled together into hosts lines. ipv4_address and ipv6_address fields are associated with the corresponding hostname attributes.
It can also read from the confluent db, using `-a`. In this mode, each net.<value>.<attribute> group is pulled together into hosts lines. ipv4_address and ipv6_address fields are associated with the corresponding hostname attributes. You can use `-f` to put the FQDN first.
## EXAMPLES
@@ -38,5 +38,8 @@ the json files (password protected, removed from the files, or unprotected).
keys do not change and as such they do not require
incremental backup.
* `-y`, `--yaml
Use YAML instead of JSON as file format
* `-h`, `--help`:
Show help message and exit
+30
View File
@@ -0,0 +1,30 @@
nodeapply(8) -- Execute command on many nodes in a noderange through ssh
=========================================================================
## SYNOPSIS
`nodeapply [options] <noderange>`
## DESCRIPTION
Provides shortcut access to a number of common operations against deployed
nodes. These operations include refreshing ssh certificates and configuration,
rerunning syncflies, and executing specified postscripts.
## OPTIONS
* `-k`, `--security`
Refresh SSH configuration (hosts.equiv and node SSH certificates)
* `-F`, `--sync`
Rerun syncfiles from deployed profile
* `-P SCRIPTS`, `--scripts=SCRIPTS`
Re-run specified scripts, with full path under scripts specified, e.g. post.d/scriptname,firstboot.d/otherscriptname
* `-c COUNT`, `-f COUNT`, `--count=COUNT`
Specify the maximum number of instances to run concurrently
* `-m MAXNODES`, `--maxnodes=MAXNODES`
Specify a maximum number of nodes to run remote ssh command to, prompting
if over the threshold
+29 -3
View File
@@ -7,7 +7,8 @@ nodeattrib(8) -- List or change confluent nodes attributes
`nodeattrib <noderange> [<nodeattribute1=value1> <nodeattribute2=value2> ...]`
`nodeattrib -c <noderange> <nodeattribute1> <nodeattribute2> ...`
`nodeattrib -e <noderange> <nodeattribute1> <nodeattribute2> ...`
`nodeattrib -p <noderange> <nodeattribute1> <nodeattribute2> ...`
`nodeattrib -p <noderange> <nodeattribute1> <nodeattribute2> ...`
`nodeattrib <noderange> -s <attributes.batch> ...`
## DESCRIPTION
@@ -53,12 +54,18 @@ to a blank value will allow masking a group defined attribute with an empty valu
* `-e`, `--environment`:
Set specified attributes based on exported environment variable of matching name.
Environment variable names may be lower case or all upper case.
Replace . with _ as needed (e.g. info.note may be specified as either $info_note or $INFO_NOTE
Replace . with _ as needed (e.g. info.note may be specified as either $info_note or $INFO_NOTE)
* `-p`, `--prompt`:
Request interactive prompting to provide values rather than the command line
or environment variables.
* `-s`, `--set`:
Set attributes using a batch file rather than the command line. The attributes in the batch file
can be specified as one line of key=value pairs simmilar to command line or each attribute can
be in its own line. Lines that start with # sign will be read as a comment. See EXAMPLES for batch
file syntax.
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Prompt if trying to set attributes on more than
specified number of nodes.
@@ -116,6 +123,25 @@ to a blank value will allow masking a group defined attribute with an empty valu
`d1: net.pxe.switch: pxeswitch1`
`d1: net.switch:`
* Setting attributes using a batch file with syntax similar to command line:
`# cat nodeattributes.batch`
`# power`
`power.psu1.outlet=3 power.psu1.pdu=pdu2`
`# nodeattrib n41 -s nodeattributes.batch`
`n41: 3`
`n41: pdu2`
* Setting attributes using a batch file with syntax where each attribute is in its own line:
`# cat nodeattributes.batch`
`# management`
`custom.mgt.switch=switch_main`
`custom.mgt.switch.port=swp4`
`# nodeattrib n41 -s nodeattributes.batch`
`n41: switch_main`
`n41: swp4`
## SEE ALSO
nodegroupattrib(8), nodeattribexpressions(5)
@@ -0,0 +1,28 @@
nodebmcpassword(8) -- Change management controller password for a specified user
=========================================================
## SYNOPSIS
`nodebmcpassword <noderange> <username> <new_password>`
## DESCRIPTION
`nodebmcpassword` allows you to change the management controller password for a user on a specified noderange
## OPTIONS
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Number of nodes to affect before prompting for
confirmation
* `-h`, `--help`:
Show help message and exit
## EXAMPLES:
* Reset the management controller for nodes n1 through n4:
`# nodebmcreset n1-n4`
`n1: Password Change Successful`
`n2: Password Change Successful`
`n3: Password Change Successful`
`n4: Password Change Successful`
+21 -2
View File
@@ -21,14 +21,33 @@ console process which will result in the console window closing.
## OPTIONS
* `-i N`, `--interval`:
For screenshot mode, fetch new screenshots and overwrite old screenshots every N seconds.
For example, `nodeconsole r3u[21:24] -tsi 3` will tile screenshots of r3u21 through r3u24 and
refresh them every 3 seconds.
* `-t`, `--tile`:
Use tmux to arrange consoles of the given noderange into a tiled layout on
the terminal screen
For text consoles, use tmux to arrange consoles of the given noderange into a tiled layout on
the terminal screen. If using 'screenshot' mode, divide the terminal and display the images
in a grid.
* `-l`, `--log`:
Perform a log reply on the current, local log in /var/log/confluent/consoles.
If in collective mode, this only makes sense to use on the current collective
manager at this time.
* `-T`, `--Timestamp`:
Dump the log with Timpstamps on the current, local log in /var/log/confluent/consoles.
If in collective mode, this only makes sense to use on the current collective
manager at this time.
* `-s`, `--screenshot`:
Attempt to grab screenshot(s) and render using a terminal
image protocol. The image protocol defaults to kitty, and
can be selected by CONFLUENT_IMAGE_PROTOCOL environment variable.
Supported protocols are kitty, iterm, and, sixel (sixel only
if PySixel is installed). This only presents screenshots, there
is no input supported to graphical consoles from a terminal.
* `-w`, `--windowed`:
Open terminal windows for each node. The
+4 -1
View File
@@ -3,7 +3,7 @@ nodefirmware(8) -- Report firmware information on confluent nodes
## SYNOPSIS
`nodefirmware <noderange> [list][update [--backup <file>]]|[<components>]`
`nodefirmware <noderange> [list][updatestatus][update [--backup <file>]]|[<components>]`
## DESCRIPTION
@@ -17,6 +17,9 @@ not be relevant to redfish. Additionally, the Lenovo XCC makes certain
information available over IPMI that is not otherwise available (for example
the FPGA version where applicable).
The updatestatus argument will describe the state of firmware updates on the
nodes.
In the update form, it accepts a single file and attempts to update it using
the out of band facilities. Firmware updates can end in one of three states:
@@ -0,0 +1,42 @@
nodel2traceroute(8) -- returns the layer 2 route through an Ethernet network managed by confluent given 2 end points.
==============================
## SYNOPSIS
`nodel2traceroute [options] <start_node> <end_noderange>`
## DESCRIPTION
**nodel2traceroute** is a command that returns the layer 2 route for the configered interfaces in nodeattrib.
It can also be used with the -i and -e options to check against specific interfaces on the endpoints. If the
--interface or --eface option are not used then the command will check for routes against all the defined
interfaces in nodeattrib (net.*.switch) for the nodes.
## PREREQUISITES
**nodel2traceroute** the net.<interface>.switch attributes have to be set on the end points if endpoint is not a switch
## OPTIONS
* ` -e` EFACE, --eface=INTERFACE
interface to check against for the second end point or end points if using checking against multiple nodes
* ` -i` INTERFACE, --interface=INTERFACE
interface to check against for the first end point
* ` -c` CUMULUS, --cumulus=CUMULUS
return layer 2 route through cumulus switches only
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Checking route between two nodes:
`# nodel2traceroute n244 n1851`
`n244 to n1851: ['switch114']`
* Checking route from one node to multiple nodes:
`# nodel2traceroute n244 n1833,n1851`
`n244 to n1833: ['switch114', 'switch7', 'switch32', 'switch253', 'switch85', 'switch72', 'switch21', 'switch2', 'switch96', 'switch103', 'switch115']
n244 to n1851: ['switch114']`
+3 -2
View File
@@ -4,7 +4,7 @@ nodelist(8) -- List confluent nodes and their attributes
## SYNOPSIS
`nodelist <noderange>`
`nodelist <noderange> [-b] <nodeattribute>...`
`nodelist <noderange> [-b] [-d] {string} <nodeattribute>...`
## DESCRIPTION
@@ -24,7 +24,8 @@ all attributes that begin with `net.` and end with `switch`.
* `-b`, `--blame`:
Annotate inherited and expression based attributes to show their base value.
* `-d`, `--delim`:
Choose a delimiter to separat the values. Default - ENTER.
## EXAMPLES
* Listing matching nodes of a simple noderange:
`# nodelist n1-n4`
+3
View File
@@ -16,6 +16,9 @@ noderange. This will present progress as percentage for all nodes.
Specify how many rsync executions to do concurrently. If noderange
exceeds the count, then excess nodes will wait until one of the
active count completes.
* `-s`, `--substitutename`:
'Use a different name other than the nodename for rsync'
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to run rsync to, prompting if over the
+19 -4
View File
@@ -1,7 +1,11 @@
VERSION=`git describe|cut -d- -f 1`
NUMCOMMITS=`git describe|cut -d- -f 2`
if [ "$NUMCOMMITS" != "$VERSION" ]; then
VERSION=$VERSION.dev$NUMCOMMITS.g`git describe|cut -d- -f 3`
LASTNUM=$(echo $VERSION|rev|cut -d . -f 1|rev)
LASTNUM=$((LASTNUM+1))
FIRSTPART=$(echo $VERSION|rev|cut -d . -f 2- |rev)
VERSION=${FIRSTPART}.${LASTNUM}
VERSION=$VERSION~dev$NUMCOMMITS+`git describe|cut -d- -f 3`
fi
sed -e "s/#VERSION#/$VERSION/" confluent_osdeploy.spec.tmpl > confluent_osdeploy.spec
cd ..
@@ -11,13 +15,24 @@ mv confluent_osdeploy.tar.xz ~/rpmbuild/SOURCES/
cd -
mkdir -p el9bin/opt/confluent/bin
mkdir -p el9bin/stateless-bin
podman run --privileged --rm -v $(pwd)/utils:/buildutils -i -t fedorabuilder make -C /buildutils
podman run --privileged --rm -v $(pwd)/utils:/buildutils -i -t fedorabuild make -C /buildutils
cd utils
mv confluent_imginfo copernicus clortho autocons ../el9bin/opt/confluent/bin
mv start_root urlmount ../el9bin/stateless-bin/
cp confluent_imginfo copernicus clortho autocons ../el9bin/opt/confluent/bin
cp start_root urlmount ../el9bin/stateless-bin/
make clean
cd ..
mkdir -p el8bin/opt/confluent/bin
mkdir -p el8bin/stateless-bin
podman run --privileged --rm -v $(pwd)/utils:/buildutils -i -t el7build make -C /buildutils
cd utils
cp confluent_imginfo copernicus clortho autocons ../el8bin/opt/confluent/bin
cp start_root urlmount ../el8bin/stateless-bin/
make clean
cd ..
tar Jcvf confluent_el9bin.tar.xz el9bin/
tar Jcvf confluent_el8bin.tar.xz el8bin/
mv confluent_el8bin.tar.xz ~/rpmbuild/SOURCES/
mv confluent_el9bin.tar.xz ~/rpmbuild/SOURCES/
rm -rf el9bin
rm -rf el8bin
rpmbuild -ba confluent_osdeploy.spec
+8 -2
View File
@@ -1,7 +1,12 @@
cd $(dirname $0)
VERSION=`git describe|cut -d- -f 1`
NUMCOMMITS=`git describe|cut -d- -f 2`
if [ "$NUMCOMMITS" != "$VERSION" ]; then
VERSION=$VERSION.dev$NUMCOMMITS.g`git describe|cut -d- -f 3`
LASTNUM=$(echo $VERSION|rev|cut -d . -f 1|rev)
LASTNUM=$((LASTNUM+1))
FIRSTPART=$(echo $VERSION|rev|cut -d . -f 2- |rev)
VERSION=${FIRSTPART}.${LASTNUM}
VERSION=$VERSION~dev$NUMCOMMITS+`git describe|cut -d- -f 3`
fi
sed -e "s/#VERSION#/$VERSION/" confluent_osdeploy-aarch64.spec.tmpl > confluent_osdeploy-aarch64.spec
cd ..
@@ -29,4 +34,5 @@ mv confluent_el8bin.tar.xz ~/rpmbuild/SOURCES/
mv confluent_el9bin.tar.xz ~/rpmbuild/SOURCES/
rm -rf el9bin
rm -rf el8bin
rpmbuild -ba confluent_osdeploy-aarch64.spec
podman run --privileged --rm -v $HOME:/root el8builder rpmbuild -ba /root/confluent/confluent_osdeploy/confluent_osdeploy-aarch64.spec
@@ -14,6 +14,8 @@ import ssl
import sys
import struct
import time
import re
import json
class InvalidApiKey(Exception):
pass
@@ -21,6 +23,10 @@ class InvalidApiKey(Exception):
def msg_align(len):
return (len + 3) & ~3
try:
_protoparm = ssl.PROTOCOL_TLS_CLIENT
except AttributeError:
_protoparm = ssl.PROTOCOL_SSLv23
cryptname = ctypes.util.find_library('crypt')
if not cryptname:
if os.path.exists('/lib64/libcrypt.so.2') or os.path.exists('/usr/lib64/libcrypt.so.2'):
@@ -85,8 +91,11 @@ def scan_confluents():
confluentuuid = line.split(': ')[1]
msg += '/confluentuuid=' + confluentuuid
break
with open('/sys/devices/virtual/dmi/id/product_uuid') as uuidin:
msg += '/uuid=' + uuidin.read().strip()
try:
with open('/sys/devices/virtual/dmi/id/product_uuid') as uuidin:
msg += '/uuid=' + uuidin.read().strip()
except Exception:
pass
for addrf in glob.glob('/sys/class/net/*/address'):
with open(addrf) as addrin:
hwaddr = addrin.read().strip()
@@ -223,7 +232,8 @@ def get_apikey(nodename, hosts, errout=None):
return apikey
class HTTPSClient(client.HTTPConnection, object):
def __init__(self, usejson=False, port=443, host=None, errout=None, phmac=None):
def __init__(self, usejson=False, port=443, host=None, errout=None, phmac=None, checkonly=False):
self.ignorehosts = set([])
self.phmac = phmac
self.errout = None
if errout:
@@ -287,7 +297,7 @@ class HTTPSClient(client.HTTPConnection, object):
if self.phmac:
with open(phmac, 'r') as hmacin:
self.stdheaders['CONFLUENT_CRYPTHMAC'] = hmacin.read()
else:
elif not checkonly:
self.stdheaders['CONFLUENT_APIKEY'] = get_apikey(node, self.hosts, errout=self.errout)
if mgtiface:
self.stdheaders['CONFLUENT_MGTIFACE'] = mgtiface
@@ -305,12 +315,14 @@ class HTTPSClient(client.HTTPConnection, object):
def check_connections(self):
foundsrv = None
hosts = self.hosts
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ctx = ssl.SSLContext(_protoparm)
ctx.load_verify_locations('/etc/confluent/ca.pem')
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
for timeo in (0.1, 5):
for host in hosts:
if host in self.ignorehosts:
continue
try:
addrinf = socket.getaddrinfo(host, self.port)[0]
psock = socket.socket(addrinf[0])
@@ -321,7 +333,7 @@ class HTTPSClient(client.HTTPConnection, object):
foundsrv = host
psock.close()
break
except OSError:
except (OSError, socket.error):
continue
except ssl.SSLError:
continue
@@ -353,11 +365,12 @@ class HTTPSClient(client.HTTPConnection, object):
raise Exception('Unable to reach any hosts')
return foundsrv
def connect(self):
def connect(self, tries=3):
addrinf = socket.getaddrinfo(self.host, self.port)[0]
psock = socket.socket(addrinf[0])
psock.settimeout(15)
psock.connect(addrinf[4])
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ctx = ssl.SSLContext(_protoparm)
ctx.load_verify_locations('/etc/confluent/ca.pem')
host = self.host.split('%', 1)[0]
if '[' not in host and ':' in host:
@@ -375,6 +388,10 @@ class HTTPSClient(client.HTTPConnection, object):
self.errout.write(errmsg)
self.errout.flush()
sys.exit(1)
except socket.timeout:
if not tries:
raise
return self.connect(tries=tries-1)
def grab_url(self, url, data=None, returnrsp=False):
return self.grab_url_with_status(url, data, returnrsp)[1]
@@ -401,10 +418,100 @@ class HTTPSClient(client.HTTPConnection, object):
akfile.write('')
self.stdheaders['CONFLUENT_APIKEY'] = get_apikey(
self.node, [self.host], errout=self.errout)
if rsp.status == 503: # confluent is down, but the server running confluent is otherwise up
authed = False
self.ignorehosts.add(self.host)
host = self.check_connections()
client.HTTPConnection.__init__(self, host, self.port)
raise Exception(rsp.read())
def get_current_vmnic_vswitch():
uplinkmatch = re.compile(r'^\s*Uplinks:\s*(.*)')
switchmatch = re.compile(r'^\s*Name:\s*(.*)')
vswinfo = subprocess.check_output(['localcli', 'network', 'vswitch', 'standard', 'list']).decode()
vmnic = None
vswitch_name = None
for info in vswinfo.split('\n'):
name_match = switchmatch.match(info)
if name_match:
vswitch_name = name_match.group(1).strip()
upinfo = uplinkmatch.match(info)
if upinfo:
vmnic = upinfo.group(1).strip()
if vmnic and 'vusb0' not in vmnic:
return vswitch_name, vmnic
return vswitch_name, vmnic
def get_available_nics():
nicinfo = subprocess.check_output(['localcli', 'network', 'nic', 'list']).decode('utf8').split('\n')
available_nics = {}
# Skip headers and separators
parsing_started = False
for line in nicinfo:
if re.match(r'^-+', line):
parsing_started = True
continue
if not parsing_started or not line.strip():
continue
parts = re.split(r'\s{2,}', line.strip())
if len(parts) >= 5:
nic_name = parts[0]
nic_status = parts[4] # "Link Status" este al 5-lea câmp
available_nics[nic_name] = nic_status
return available_nics
def is_esxi():
return os.path.isdir("/etc/vmware")
def fix_vswitch():
if is_esxi():
start_time = time.time()
while True:
current_vswitch, current_vmnic = get_current_vmnic_vswitch()
if current_vswitch is None:
raise RuntimeError("Panic: current vswitch is None")
if current_vmnic is None:
raise RuntimeError("Panic: current vmnic is None")
available_nics = get_available_nics()
if current_vmnic and available_nics.get(current_vmnic) == 'Up':
break
new_vmnic = next((nic for nic, status in available_nics.items() if status == 'Up'), None)
if new_vmnic and new_vmnic != current_vmnic:
subprocess.check_call(['localcli', 'network', 'vswitch', 'standard', 'uplink', 'remove',
'--uplink-name', current_vmnic, '--vswitch-name', current_vswitch])
subprocess.check_call(['localcli', 'network', 'vswitch', 'standard', 'uplink', 'add',
'--uplink-name', new_vmnic, '--vswitch-name', current_vswitch])
elif not new_vmnic:
if time.time() - start_time > 300:
break
time.sleep(5)
time.sleep(5)
if __name__ == '__main__':
data = None
if '-f' in sys.argv:
try:
fix_vswitch()
except Exception as e:
print(f"fix_vswitch() error: {e}")
sys.argv.remove('-f')
sys.exit(0)
usejson = False
if '-j' in sys.argv:
usejson = True
@@ -459,13 +566,14 @@ if __name__ == '__main__':
outf.write(chunk)
chunk = reader.read(16384)
sys.exit(0)
client = HTTPSClient(usejson, errout=errout, phmac=phmac)
mclient = HTTPSClient(usejson, errout=errout, phmac=phmac, checkonly=checkonly)
if waitfor:
status = 201
while status != waitfor:
status, rsp = client.grab_url_with_status(sys.argv[1], data)
status, rsp = mclient.grab_url_with_status(sys.argv[1], data)
sys.stdout.write(rsp.decode())
elif checkonly:
sys.stdout.write(client.check_connections())
sys.stdout.write(mclient.check_connections())
else:
sys.stdout.write(client.grab_url(sys.argv[1], data).decode())
sys.stdout.write(mclient.grab_url(sys.argv[1], data).decode())
@@ -0,0 +1,119 @@
#!/usr/bin/python3
# This script evaluates whether firmware redirection is likely. It uses three cues:
# - Does the system offer up SPCR? This would indicate that the firmware is doing serial output.
# Otherwise, there's no indication that the firmware cares about serial console.
# - Is the system EFI? BIOS implementations may not intercept text draw calls after POST exit,
# thus even when BIOS tells us serial port is in use, it may not be doing anything when
# grub would be running
# - Is the serial port connected? In the event that firmware indicates serial port, but
# serial port is not reporting DCD, then it doesn't look like a comfortable enough scenario
import fcntl
import os
import os.path
import struct
import subprocess
import termios
addrtoname = {
0x3f8: '/dev/ttyS0',
0x2f8: '/dev/ttyS1',
0x3e8: '/dev/ttyS2',
0x2e8: '/dev/ttyS3',
}
speedmap = {
0: None,
3: 9600,
4: 19200,
6: 57600,
7: 115200,
}
termiobaud = {
9600: termios.B9600,
19200: termios.B19200,
57600: termios.B57600,
115200: termios.B115200,
}
def deserialize_grub_rh():
if 'console=ttyS' in open('/proc/cmdline').read():
return None # User manually indicated serial config
# they own the grub behavior too for now
grublines = []
with open('/etc/default/grub') as grubin:
grublines = grubin.read().split('\n')
with open('/etc/default/grub', 'w') as grubout:
for grubline in grublines:
if grubline.startswith('GRUB_TERMINAL'):
grubline = grubline.replace('serial ', '')
grubout.write(grubline + '\n')
subprocess.check_call(['grub2-mkconfig', '-o', '/boot/grub2/grub.cfg'])
def fixup_ubuntu_grub_serial():
# Ubuntu aggressively tries to graphics up
# grub. We will counter that for serial
# They also aggressively hide UI and
# block ability to interject. We will
# compromise and lean on nodeboot <node> setup
# as a means to give someone reasonable shot at
# the short timeout
with open('/etc/default/grub') as grubin:
grublines = grubin.read().split('\n')
with open('/etc/default/grub', 'w') as grubout:
for grubline in grublines:
if grubline.startswith('GRUB_TIMEOUT_STYLE=hidden'):
grubline = 'GRUB_TIMEOUT_STYLE=menu'
elif grubline.startswith('GRUB_TIMEOUT=0'):
grubline = 'GRUB_TIMEOUT=2'
elif grubline.startswith('#GRUB_TERMINAL=console'):
grubline = grubline.replace('#', '')
grubout.write(grubline + '\n')
subprocess.check_call(['update-grub'])
def get_serial_config():
if not os.path.exists('/sys/firmware/efi'):
return None
if not os.path.exists('/sys/firmware/acpi/tables/SPCR'):
return None
spcr = open("/sys/firmware/acpi/tables/SPCR", "rb")
spcr = bytearray(spcr.read())
if spcr[8] != 2 or spcr[36] != 0 or spcr[40] != 1:
return None
address = struct.unpack('<Q', spcr[44:52])[0]
tty = None
try:
tty = addrtoname[address]
except KeyError:
return None
retval = { 'tty': tty }
try:
retval['speed'] = speedmap[spcr[58]]
except KeyError:
return None
if retval['speed']:
ttyf = os.open(tty, os.O_RDWR | os.O_NOCTTY)
currattr = termios.tcgetattr(ttyf)
currattr[4:6] = [0, termiobaud[retval['speed']]]
termios.tcsetattr(ttyf, termios.TCSANOW, currattr)
retval['connected'] = bool(struct.unpack('<I', fcntl.ioctl(
ttyf, termios.TIOCMGET, '\x00\x00\x00\x00'))[0] & termios.TIOCM_CAR)
os.close(ttyf)
return retval
def main():
autoconscfg = get_serial_config()
if not autoconscfg or not autoconscfg['connected']:
return
if os.path.exists('/etc/redhat-release'): # redhat family
deserialize_grub_rh()
elif os.path.exists('/etc/os-release'):
with open('/etc/os-release') as osr:
if 'Ubuntu' in osr.read():
fixup_ubuntu_grub_serial()
if __name__ == '__main__':
main()
@@ -8,6 +8,10 @@ import sys
import time
import shlex
import subprocess
try:
import yaml
except ImportError:
pass
try:
from importlib.machinery import SourceFileLoader
def load_source(mod, path):
@@ -82,7 +86,7 @@ def map_idx_to_name():
for line in subprocess.check_output(['ip', 'l']).decode('utf8').splitlines():
if line.startswith(' ') and 'link/' in line:
typ = line.split()[0].split('/')[1]
devtype[prevdev] = typ if type != 'ether' else 'ethernet'
devtype[prevdev] = typ if typ != 'ether' else 'ethernet'
if line.startswith(' '):
continue
idx, iface, rst = line.split(':', 2)
@@ -107,6 +111,106 @@ def get_interface_name(iname, settings):
return iname
return None
class NetplanManager(object):
def __init__(self, deploycfg):
self.cfgbydev = {}
self.read_connections()
self.deploycfg = deploycfg
def read_connections(self):
for plan in glob.glob('/etc/netplan/*.y*ml'):
with open(plan) as planfile:
planinfo = yaml.safe_load(planfile)
if not planinfo:
continue
nicinfo = planinfo.get('network', {}).get('ethernets', {})
for devname in nicinfo:
if devname == 'lo':
continue
if 'gateway4' in nicinfo[devname]:
# normalize deprecated syntax on read in
gw4 = nicinfo[devname]['gateway4']
del nicinfo[devname]['gateway4']
routeinfo = nicinfo[devname].get('routes', [])
for ri in routeinfo:
if ri.get('via', None) == gw4 and ri.get('to', None) in ('default', '0.0.0.0/0', '0/0'):
break
else:
routeinfo.append({
'to': 'default',
'via': gw4
})
nicinfo[devname]['routes'] = routeinfo
self.cfgbydev[devname] = nicinfo[devname]
def apply_configuration(self, cfg):
devnames = cfg['interfaces']
if len(devnames) != 1:
raise Exception('Multi-nic team/bonds not yet supported')
stgs = cfg['settings']
needcfgapply = False
for devname in devnames:
needcfgwrite = False
# ipv6_method missing at uconn...
if stgs.get('ipv6_method', None) == 'static':
curraddr = stgs['ipv6_address']
currips = self.getcfgarrpath([devname, 'addresses'])
if curraddr not in currips:
needcfgwrite = True
currips.append(curraddr)
if stgs.get('ipv4_method', None) == 'static':
curraddr = stgs['ipv4_address']
currips = self.getcfgarrpath([devname, 'addresses'])
if curraddr not in currips:
needcfgwrite = True
currips.append(curraddr)
gws = []
gws.append(stgs.get('ipv4_gateway', None))
gws.append(stgs.get('ipv6_gateway', None))
for gwaddr in gws:
if gwaddr:
cfgroutes = self.getcfgarrpath([devname, 'routes'])
for rinfo in cfgroutes:
if rinfo.get('via', None) == gwaddr:
break
else:
needcfgwrite = True
cfgroutes.append({'via': gwaddr, 'to': 'default'})
dnsips = self.deploycfg.get('nameservers', [])
dnsdomain = self.deploycfg.get('dnsdomain', '')
if dnsips:
currdnsips = self.getcfgarrpath([devname, 'nameservers', 'addresses'])
for dnsip in dnsips:
if dnsip and dnsip not in currdnsips:
needcfgwrite = True
currdnsips.append(dnsip)
if dnsdomain:
currdnsdomain = self.getcfgarrpath([devname, 'nameservers', 'search'])
if dnsdomain not in currdnsdomain:
needcfgwrite = True
currdnsdomain.append(dnsdomain)
if needcfgwrite:
needcfgapply = True
newcfg = {'network': {'version': 2, 'ethernets': {devname: self.cfgbydev[devname]}}}
oumask = os.umask(0o77)
with open('/etc/netplan/{0}-confluentcfg.yaml'.format(devname), 'w') as planout:
planout.write(yaml.dump(newcfg))
os.umask(oumask)
if needcfgapply:
subprocess.call(['netplan', 'apply'])
def getcfgarrpath(self, devpath):
currptr = self.cfgbydev
for k in devpath[:-1]:
if k not in currptr:
currptr[k] = {}
currptr = currptr[k]
if devpath[-1] not in currptr:
currptr[devpath[-1]] = []
return currptr[devpath[-1]]
class WickedManager(object):
def __init__(self):
self.teamidx = 0
@@ -122,7 +226,11 @@ class WickedManager(object):
self.cfgbydev[devname] = currcfg
for cfg in open(ifcfg).read().splitlines():
cfg = cfg.split('#', 1)[0]
kv = ' '.join(shlex.split(cfg)).split('=', 1)
try:
kv = ' '.join(shlex.split(cfg)).split('=', 1)
except Exception:
# unparseable line, likely having something we can't handle
del self.cfgbydev[devname]
if len(kv) != 2:
continue
k, v = kv
@@ -193,7 +301,14 @@ class WickedManager(object):
class NetworkManager(object):
def __init__(self, devtypes):
bondtypes = {
'lacp': '802.3ad',
'loadbalance': 'balance-alb',
'roundrobin': 'balance-rr',
'activebackup': 'active-backup',
}
def __init__(self, devtypes, deploycfg):
self.deploycfg = deploycfg
self.connections = {}
self.uuidbyname = {}
self.uuidbydev = {}
@@ -243,7 +358,8 @@ class NetworkManager(object):
bondcfg[stg] = deats[stg]
if member in self.uuidbyname:
subprocess.check_call(['nmcli', 'c', 'del', self.uuidbyname[member]])
subprocess.check_call(['nmcli', 'c', 'add', 'type', 'team-slave', 'master', team, 'con-name', member, 'connection.interface-name', member])
devtype = self.devtypes.get(member, 'bond-slave')
subprocess.check_call(['nmcli', 'c', 'add', 'type', devtype, 'master', team, 'con-name', member, 'connection.interface-name', member])
if bondcfg:
args = []
for parm in bondcfg:
@@ -251,8 +367,9 @@ class NetworkManager(object):
args.append(bondcfg[parm])
subprocess.check_call(['nmcli', 'c', 'm', team] + args)
def apply_configuration(self, cfg):
def apply_configuration(self, cfg, lastchance=False):
cmdargs = {}
cmdargs['connection.autoconnect'] = 'yes'
stgs = cfg['settings']
cmdargs['ipv6.method'] = stgs.get('ipv6_method', 'link-local')
if stgs.get('ipv6_address', None):
@@ -264,6 +381,20 @@ class NetworkManager(object):
cmdargs['ipv4.gateway'] = stgs['ipv4_gateway']
if stgs.get('ipv6_gateway', None):
cmdargs['ipv6.gateway'] = stgs['ipv6_gateway']
dnsips = self.deploycfg.get('nameservers', [])
if not dnsips:
dnsips = []
dns4 = []
dns6 = []
for dnsip in dnsips:
if '.' in dnsip:
dns4.append(dnsip)
elif ':' in dnsip:
dns6.append(dnsip)
if dns4:
cmdargs['ipv4.dns'] = ','.join(dns4)
if dns6:
cmdargs['ipv6.dns'] = ','.join(dns6)
if len(cfg['interfaces']) > 1: # team time.. should be..
if not cfg['settings'].get('team_mode', None):
sys.stderr.write("Warning, multiple interfaces ({0}) without a team_mode, skipping setup\n".format(','.join(cfg['interfaces'])))
@@ -276,26 +407,46 @@ class NetworkManager(object):
for arg in cmdargs:
cargs.append(arg)
cargs.append(cmdargs[arg])
subprocess.check_call(['nmcli', 'c', 'add', 'type', 'team', 'con-name', cname, 'connection.interface-name', cname, 'team.runner', stgs['team_mode']] + cargs)
if stgs['team_mode'] in self.bondtypes:
stgs['team_mode'] = self.bondtypes[stgs['team_mode']]
subprocess.check_call(['nmcli', 'c', 'add', 'type', 'bond', 'con-name', cname, 'connection.interface-name', cname, 'bond.options', 'miimon=100,mode={}'.format(stgs['team_mode'])] + cargs)
for iface in cfg['interfaces']:
self.add_team_member(cname, iface)
subprocess.check_call(['nmcli', 'c', 'u', cname])
else:
cname = stgs.get('connection_name', None)
iname = list(cfg['interfaces'])[0]
if not cname:
cname = iname
ctype = self.devtypes.get(iname, None)
if not ctype:
if lastchance:
sys.stderr.write("Warning, no device found for interface_name ({0}), skipping setup\n".format(iname))
return 1
if stgs.get('vlan_id', None):
vlan = stgs['vlan_id']
if ctype == 'infiniband':
vlan = '0x{0}'.format(vlan) if not vlan.startswith('0x') else vlan
cmdargs['infiniband.parent'] = iname
cmdargs['infiniband.p-key'] = vlan
iname = '{0}.{1}'.format(iname, vlan[2:])
elif ctype == 'ethernet':
ctype = 'vlan'
cmdargs['vlan.parent'] = iname
cmdargs['vlan.id'] = vlan
iname = '{0}.{1}'.format(iname, vlan)
else:
sys.stderr.write("Warning, unknown interface_name ({0}) device type ({1}) for VLAN/PKEY, skipping setup\n".format(iname, ctype))
return
cname = iname if not cname else cname
u = self.uuidbyname.get(cname, None)
cargs = []
for arg in cmdargs:
cargs.append(arg)
cargs.append(cmdargs[arg])
if u:
cmdargs['connection.interface-name'] = iname
subprocess.check_call(['nmcli', 'c', 'm', u] + cargs)
subprocess.check_call(['nmcli', 'c', 'm', u, 'connection.interface-name', iname] + cargs)
subprocess.check_call(['nmcli', 'c', 'u', u])
else:
subprocess.check_call(['nmcli', 'c', 'add', 'type', self.devtypes[iname], 'con-name', cname, 'connection.interface-name', iname] + cargs)
subprocess.check_call(['nmcli', 'c', 'add', 'type', ctype, 'con-name', cname, 'connection.interface-name', iname] + cargs)
self.read_connections()
u = self.uuidbyname.get(cname, None)
if u:
@@ -315,8 +466,18 @@ if __name__ == '__main__':
myaddrs = apiclient.get_my_addresses()
srvs, _ = apiclient.scan_confluents()
doneidxs = set([])
dc = None
if not srvs: # the multicast scan failed, fallback to deploycfg cfg file
with open('/etc/confluent/confluent.deploycfg', 'r') as dci:
for cfgline in dci.read().split('\n'):
if cfgline.startswith('deploy_server:'):
srvs = [cfgline.split()[1]]
break
for srv in srvs:
s = socket.create_connection((srv, 443))
try:
s = socket.create_connection((srv, 443))
except socket.error:
continue
myname = s.getsockname()
s.close()
if len(myname) == 4:
@@ -329,8 +490,27 @@ if __name__ == '__main__':
curridx = addr[-1]
if curridx in doneidxs:
continue
status, nc = apiclient.HTTPSClient(usejson=True, host=srv).grab_url_with_status('/confluent-api/self/netcfg')
for tries in (1, 2, 3):
try:
status, nc = apiclient.HTTPSClient(usejson=True, host=srv).grab_url_with_status('/confluent-api/self/netcfg')
break
except Exception:
if tries == 3:
raise
time.sleep(1)
continue
nc = json.loads(nc)
if not dc:
for tries in (1, 2, 3):
try:
status, dc = apiclient.HTTPSClient(usejson=True, host=srv).grab_url_with_status('/confluent-api/self/deploycfg2')
break
except Exception:
if tries == 3:
raise
time.sleep(1)
continue
dc = json.loads(dc)
iname = get_interface_name(idxmap[curridx], nc.get('default', {}))
if iname:
for iname in iname.split(','):
@@ -355,13 +535,30 @@ if __name__ == '__main__':
netname_to_interfaces['default']['interfaces'] -= netname_to_interfaces[netn]['interfaces']
if not netname_to_interfaces['default']['interfaces']:
del netname_to_interfaces['default']
# Make sure VLAN/PKEY connections are created last
netname_to_interfaces = dict(sorted(netname_to_interfaces.items(), key=lambda item: 'vlan_id' in item[1]['settings']))
rm_tmp_llas(tmpllas)
if os.path.exists('/usr/sbin/netplan'):
nm = NetplanManager(dc)
if os.path.exists('/usr/bin/nmcli'):
nm = NetworkManager(devtypes)
nm = NetworkManager(devtypes, dc)
elif os.path.exists('/usr/sbin/wicked'):
nm = WickedManager()
retrynics = []
for netn in netname_to_interfaces:
nm.apply_configuration(netname_to_interfaces[netn])
redo = nm.apply_configuration(netname_to_interfaces[netn])
if redo == 1:
retrynics.append(netn)
if retrynics:
idxmap, devtypes = map_idx_to_name()
if os.path.exists('/usr/sbin/netplan'):
nm = NetplanManager(dc)
if os.path.exists('/usr/bin/nmcli'):
nm = NetworkManager(devtypes, dc)
elif os.path.exists('/usr/sbin/wicked'):
nm = WickedManager()
for netn in retrynics:
nm.apply_configuration(netname_to_interfaces[netn], lastchance=True)
if havefirewall:
subprocess.check_call(['systemctl', 'start', 'firewalld'])
await_tentative()
@@ -0,0 +1,43 @@
[ -f /lib/confluent/functions ] && . /lib/confluent/functions
[ -f /etc/confluent/functions ] && . /etc/confluent/functions
[ -f /opt/confluent/bin/apiclient ] && confapiclient=/opt/confluent/bin/apiclient
[ -f /etc/confluent/apiclient ] && confapiclient=/etc/confluent/apiclient
for pubkey in /etc/ssh/ssh_host*key.pub; do
if [ "$pubkey" = /etc/ssh/ssh_host_key.pub ]; then
continue
fi
certfile=${pubkey/.pub/-cert.pub}
rm $certfile
confluentpython $confapiclient /confluent-api/self/sshcert $pubkey -o $certfile
done
if [ -d /etc/ssh/sshd_config.d/ -a ! -e /etc/ssh/sshd_config.d/90-confluent.conf ]; then
for cert in /etc/ssh/ssh*-cert.pub; do
echo HostCertificate $cert >> /etc/ssh/sshd_config.d/90-confluent.conf
done
echo HostbasedAuthentication yes >> /etc/ssh/sshd_config.d/90-confluent.conf
echo HostbasedUsesNameFromPacketOnly yes >> /etc/ssh/sshd_config.d/90-confluent.conf
echo IgnoreRhosts no >> /etc/ssh/sshd_config.d/90-confluent.conf
fi
TMPDIR=$(mktemp -d)
cd $TMPDIR
confluentpython $confapiclient /confluent-public/site/initramfs.tgz -o initramfs.tgz
tar xf initramfs.tgz
for ca in ssh/*.ca; do
LINE=$(cat $ca)
cp -af /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts.new
grep -v "$LINE" /etc/ssh/ssh_known_hosts > /etc/ssh/ssh_known_hosts.new
echo '@cert-authority *' $LINE >> /etc/ssh/ssh_known_hosts.new
mv /etc/ssh/ssh_known_hosts.new /etc/ssh/ssh_known_hosts
done
for pubkey in ssh/*.*pubkey; do
LINE=$(cat $pubkey)
cp -af /root/.ssh/authorized_keys /root/.ssh/authorized_keys.new
grep -v "$LINE" /root/.ssh/authorized_keys > /root/.ssh/authorized_keys.new
echo "$LINE" >> /root/.ssh/authorized_keys.new
mv /root/.ssh/authorized_keys.new /root/.ssh/authorized_keys
done
confluentpython $confapiclient /confluent-api/self/nodelist | sed -e 's/^- //' > /etc/ssh/shosts.equiv
cat /etc/ssh/shosts.equiv > /root/.shosts
cd -
rm -rf $TMPDIR
@@ -26,7 +26,7 @@ mkdir -p opt/confluent/bin
mkdir -p stateless-bin
cp -a el8bin/* .
ln -s el8 el9
for os in rhvh4 el7 genesis el8 suse15 ubuntu20.04 ubuntu22.04 coreos el9; do
for os in rhvh4 el7 genesis el8 suse15 ubuntu20.04 ubuntu22.04 ubuntu24.04 coreos el9; do
mkdir ${os}out
cd ${os}out
if [ -d ../${os}bin ]; then
@@ -76,7 +76,7 @@ cp -a esxi7 esxi8
%install
mkdir -p %{buildroot}/opt/confluent/share/licenses/confluent_osdeploy/
#cp LICENSE %{buildroot}/opt/confluent/share/licenses/confluent_osdeploy/
for os in rhvh4 el7 el8 el9 genesis suse15 ubuntu20.04 ubuntu22.04 esxi6 esxi7 esxi8 coreos; do
for os in rhvh4 el7 el8 el9 genesis suse15 ubuntu20.04 ubuntu22.04 ubuntu24.04 esxi6 esxi7 esxi8 coreos; do
mkdir -p %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs/aarch64/
cp ${os}out/addons.* %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs/aarch64/
if [ -d ${os}disklessout ]; then
+20 -15
View File
@@ -7,6 +7,7 @@ License: Apache2
URL: https://hpc.lenovo.com/
Source0: confluent_osdeploy.tar.xz
Source1: confluent_el9bin.tar.xz
Source2: confluent_el8bin.tar.xz
BuildArch: noarch
Requires: confluent_ipxe mtools tar
BuildRoot: /tmp
@@ -18,24 +19,26 @@ This contains support utilities for enabling deployment of x86_64 architecture s
%define debug_package %{nil}
%prep
%setup -n confluent_osdeploy -a 1
%setup -n confluent_osdeploy -a 2 -a 1
%build
mkdir -p opt/confluent/bin
mkdir -p stateless-bin
cd utils
make all
cp confluent_imginfo copernicus clortho autocons ../opt/confluent/bin
cp start_root urlmount ../stateless-bin/
cd ..
#cd utils
#make all
#cp confluent_imginfo copernicus clortho autocons ../opt/confluent/bin
#cp start_root urlmount ../stateless-bin/
#cd ..
ln -s el8 el9
for os in rhvh4 el7 genesis el8 suse15 ubuntu20.04 ubuntu22.04 coreos el9; do
cp -a el8 el10
mv el10/initramfs/usr el10/initramfs/var
for os in rhvh4 el7 genesis el8 suse15 debian ubuntu18.04 ubuntu20.04 ubuntu22.04 ubuntu24.04 coreos el9 el10; do
mkdir ${os}out
cd ${os}out
if [ -d ../${os}bin ]; then
cp -a ../${os}bin/opt .
elif [ $os = el10 ]; then
cp -a ../el9bin/opt .
else
cp -a ../opt .
cp -a ../el8bin/opt .
fi
cp -a ../${os}/initramfs/* .
cp -a ../common/initramfs/* .
@@ -43,20 +46,20 @@ for os in rhvh4 el7 genesis el8 suse15 ubuntu20.04 ubuntu22.04 coreos el9; do
mv ../addons.cpio .
cd ..
done
for os in el7 el8 suse15 el9 ubuntu20.04; do
for os in el7 el8 suse15 el9 ubuntu20.04 ubuntu22.04 ubuntu24.04; do
mkdir ${os}disklessout
cd ${os}disklessout
if [ -d ../${os}bin ]; then
cp -a ../${os}bin/opt .
else
cp -a ../opt .
cp -a ../el8bin/opt .
fi
cp -a ../${os}-diskless/initramfs/* .
cp -a ../common/initramfs/* .
if [ -d ../${os}bin ]; then
cp -a ../${os}bin/stateless-bin/* opt/confluent/bin
else
cp -a ../stateless-bin/* opt/confluent/bin
cp -a ../el8bin/stateless-bin/* opt/confluent/bin
fi
find . | cpio -H newc -o > ../addons.cpio
mv ../addons.cpio .
@@ -64,7 +67,7 @@ for os in el7 el8 suse15 el9 ubuntu20.04; do
done
mkdir esxi7out
cd esxi7out
cp -a ../opt .
cp -a ../el8bin/opt .
cp -a ../esxi7/initramfs/* .
cp -a ../common/initramfs/* .
chmod +x bin/* opt/confluent/bin/*
@@ -74,12 +77,14 @@ cd ..
cp -a esxi7out esxi6out
cp -a esxi7 esxi6
cp -a esxi7out esxi8out
cp -a esxi7out esxi9out
cp -a esxi7 esxi8
cp -a esxi7 esxi9
%install
mkdir -p %{buildroot}/opt/confluent/share/licenses/confluent_osdeploy/
cp LICENSE %{buildroot}/opt/confluent/share/licenses/confluent_osdeploy/
for os in rhvh4 el7 el8 el9 genesis suse15 ubuntu20.04 ubuntu22.04 esxi6 esxi7 esxi8 coreos; do
for os in rhvh4 el7 el8 el9 el10 genesis suse15 ubuntu20.04 debian ubuntu18.04 ubuntu22.04 ubuntu24.04 esxi6 esxi7 esxi8 esxi9 coreos; do
mkdir -p %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs
mkdir -p %{buildroot}/opt/confluent/lib/osdeploy/$os/profiles
cp ${os}out/addons.* %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs
@@ -14,65 +14,127 @@ setdebopt() {
echo d-i $1 $3 $2 >> /preseed.cfg
}
dhuuid=$(reverse_uuid $(cat /sys/devices/virtual/dmi/id/product_uuid))
dhcpid=$(mktemp)
mkdir -p /etc/confluent
cp /tls/* /etc/ssl/certs/
for nic in $(ip link | grep mtu|grep -v LOOPBACK|cut -d: -f 2|sed -e 's/ //'); do
ip link set $nic up
for i in /sys/class/net/*; do
ip link set $(basename $i) up
done
for nic in $(ip link | grep mtu|grep -v LOOPBACK|grep LOWER_UP|cut -d: -f 2|sed -e 's/ //'); do
if udhcpc -i $nic -p $dhcpid -t 2 -T 2 -n -x 93:0007 -x 97:00$dhuuid -q; then
/opt/confluent/bin/copernicus > /etc/confluent/confluent.info
if grep ^MANAGER:.*\\. /etc/confluent/confluent.info ; then
break
fi
TRIES=5
while [ ! -e /dev/disk ] && [ $TRIES -gt 0 ]; do
sleep 2
TRIES=$((TRIES - 1))
done
for i in /sys/class/net/*; do
ip link set $(basename $i) down
udevadm info $i | grep ID_NET_DRIVER=cdc_ether > /dev/null && continue
ip link set $(basename $i) up
done
cp -a /tls/* /etc/ssl/certs/
mkdir -p /etc/confluent
if [ -e /dev/disk/by-label/CNFLNT_IDNT ]; then
tmnt=$(mktemp -d)
tcfg=$(mktemp)
mount /dev/disk/by-label/CNFLNT_IDNT $tmnt
cd $tmnt
deploysrvs=$(sed -n '/^deploy_servers:/,/^[^-]/p' cnflnt.yml |grep ^-|sed -e 's/^- //'|grep -v :)
nodename=$(grep ^nodename: cnflnt.yml|cut -f 2 -d ' ')
echo NODENAME: $nodename > /etc/confluent/confluent.info
sed -n '/^net_cfgs:/,/^[^- ]/{/^[^- ]/!p}' cnflnt.yml |sed -n '/^-/,/^-/{/^-/!p}'| sed -e 's/^[- ]*//'> $tcfg
autoconfigmethod=$(grep ^ipv4_method: $tcfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
if [ "$autoconfigmethod" = "static" ]; then
setdebopt netcfg/disable_dhcp true boolean
v4addr=$(grep ^ipv4_address: $tcfg|cut -d: -f 2|sed -e 's/ //')
v4gw=$(grep ^ipv4_gateway: $tcfg|cut -d: -f 2| sed -e 's/ //')
if [ "$v4gw" = "null" ]; then
v4gw=""
fi
v4nm=$(grep ^ipv4_netmask: $tcfg|cut -d: -f 2|sed -e 's/ //')
setdebopt netcfg/get_netmask $v4nm string
setdebopt netcfg/get_ipaddress ${v4addr%/*} string
setdebopt netcfg/confirm_static true boolean
if [ ! -z "$v4gw" ]; then
setdebopt netcfg/get_gateway $v4gw string
fi
NIC=""
while [ -z "$NIC" ]; do
for NICGUESS in $(ip link|grep LOWER_UP|grep -v LOOPBACK|cut -d ' ' -f 2 | sed -e 's/:$//'); do
ip addr add dev $NICGUESS $v4addr
if [ ! -z "$v4gw" ]; then
ip route add default via $v4gw
fi
for dsrv in $deploysrvs; do
if wget https://$dsrv/confluent-public/ --tries=1 --timeout=1 -O /dev/null > /dev/null 2>&1; then
deploysrvs=$dsrv
NIC=$NICGUESS
setdebopt netcfg/choose_interface $NIC select
break
fi
done
if [ -z "$NIC" ]; then
ip -4 a flush dev $NICGUESS
else
break
fi
done
done
#TODO: nameservers
elif [ "$v4cfgmeth" = "dhcp" ]; then
setdebopt netcfg/disable_dhcp false boolean
setdebopt netcfg/confirm_static false boolean
for NICGUESS in $(ip link|grep LOWER_UP|grep -v LOOPBACK|cut -d ' ' -f 2 | sed -e 's/:$//'); do
udhcpc $NICGUESS
done
for dsrv in $deploysrvs; do
if wget https://$dsrv/confluent-public/ --tries=1 --timeout=1 -O /dev/null > /dev/null 2>&1; then
deploysrvs=$dsrv
fi
done
fi
ip -4 flush dev $nic
done
mgr=$(grep ^MANAGER:.*\\. /etc/confluent/confluent.info|head -n 1|cut -d: -f 2|sed -e 's/ //')
nodename=$(grep ^NODENAME: /etc/confluent/confluent.info|head -n 1|cut -d: -f 2|sed -e 's/ //')
/opt/confluent/bin/clortho $nodename $mgr > /etc/confluent/confluent.apikey
mgr=$deploysrvs
ln -s /opt/confluent/bin/clortho /opt/confluent/bin/genpasshmac
hmackeyfile=/tmp/cnflnthmackeytmp
passfile=/tmp/cnflnttmppassfile
passcrypt=/tmp/cnflntcryptfile
hmacfile=/tmp/cnflnthmacfile
echo -n $(grep ^apitoken: cnflnt.yml|cut -d ' ' -f 2) > $hmackeyfile
/opt/confluent/bin/genpasshmac $passfile $passcrypt $hmacfile $hmackeyfile
wget --header="CONFLUENT_NODENAME: $nodename" --header="CONFLUENT_CRYPTHMAC: $(cat $hmacfile)" --post-file=$passcrypt https://$mgr/confluent-api/self/registerapikey -O - --quiet
cp $passfile /etc/confluent/confluent.apikey
nic=$NIC
else
dhuuid=$(reverse_uuid $(cat /sys/devices/virtual/dmi/id/product_uuid))
dhcpid=$(mktemp)
mkdir -p /etc/confluent
cp /tls/* /etc/ssl/certs/
cat /tls/*.pem >> /etc/confluent/ca.pem
for nic in $(ip link | grep mtu|grep -v LOOPBACK|cut -d: -f 2|sed -e 's/ //'); do
ip link set $nic up
done
for nic in $(ip link | grep mtu|grep -v LOOPBACK|grep LOWER_UP|cut -d: -f 2|sed -e 's/ //'); do
if udhcpc -i $nic -p $dhcpid -t 2 -T 2 -n -x 93:0007 -x 97:00$dhuuid -q; then
/opt/confluent/bin/copernicus > /etc/confluent/confluent.info
if grep ^MANAGER:.*\\. /etc/confluent/confluent.info ; then
break
fi
fi
ip -4 flush dev $nic
done
mgr=$(grep ^MANAGER:.*\\. /etc/confluent/confluent.info|head -n 1|cut -d: -f 2|sed -e 's/ //')
nodename=$(grep ^NODENAME: /etc/confluent/confluent.info|head -n 1|cut -d: -f 2|sed -e 's/ //')
/opt/confluent/bin/clortho $nodename $mgr > /etc/confluent/confluent.apikey
fi
apikey=$(cat /etc/confluent/confluent.apikey)
cd /etc/confluent
wget --header="CONFLUENT_NODENAME: $nodename" --header="CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/deploycfg
cd -
predir=$(mktemp -d)
cd $predir
cp /etc/confluent/deploycfg /etc/confluent/confluent.deploycfg
profile=$(grep ^profile: /etc/confluent/deploycfg|cut -d ' ' -f 2)
wget https://$mgr/confluent-public/os/$profile/scripts/pre.sh
chmod u+x pre.sh
wget https://$mgr/confluent-public/os/$profile/preseed.cfg
mv preseed.cfg /
setdebopt auto-install/enable true boolean
setdebopt partman/early_command $predir/pre.sh string
cd -
ip -4 a flush dev $nic
setdebopt netcfg/choose_interface $nic select
setdebopt netcfg/get_hostname $nodename string
v4cfgmeth=$(grep ipv4_method: /etc/confluent/deploycfg |cut -d: -f 2|sed -e 's/ //')
if [ "$v4cfgmeth" = "static" ]; then
setdebopt netcfg/disable_dhcp true boolean
v4addr=$(grep ^ipv4_address: /etc/confluent/deploycfg|cut -d: -f 2|sed -e 's/ //')
v4gw=$(grep ^ipv4_gateway: /etc/confluent/deploycfg|cut -d: -f 2| sed -e 's/ //')
if [ "$v4gw" = "null" ]; then
v4gw=""
fi
v4nm=$(grep ^ipv4_netmask: /etc/confluent/deploycfg|cut -d: -f 2|sed -e 's/ //')
setdebopt netcfg/get_netmask $v4nm string
setdebopt netcfg/get_ipaddress $v4addr string
setdebopt netcfg/confirm_static true boolean
if [ ! -z "$v4gw" ]; then
setdebopt netcfg/get_gateway $v4gw string
fi
namesrvs=$(sed -n '/^nameservers:/,/^[^-]/p' /etc/confluent/deploycfg|grep ^- | cut -d ' ' -f 2|sed -e 's/ //')
for namesrv in "$namesrvs"; do
setdebopt netcfg/get_nameservers $namesrv string
done
elif [ "$vpcfgmeth" = "dhcp" ]; then
setdebopt netcfg/disable_dhcp false boolean
setdebopt netcfg/confirm_static false boolean
fi
namesrvs=$(sed -n '/^nameservers:/,/^[^-]/p' /etc/confluent/deploycfg|grep ^- | cut -d ' ' -f 2|sed -e 's/ //')
for namesrv in "$namesrvs"; do
setdebopt netcfg/get_nameservers $namesrv string
done
rootpass=$(grep ^rootpassword: /etc/confluent/deploycfg|cut -d ' ' -f 2|sed -e 's/ //')
if [ "$rootpass" = null ] || [ -z "$rootpass" ]; then
setdebopt passwd/root-login false boolean
@@ -84,9 +146,8 @@ setdebopt time/zone $(grep ^timezone: /etc/confluent/deploycfg|cut -d ' ' -f 2|s
ntpsrvs=$(sed -n '/^ntpservers:/,/^[^-]/p' /etc/confluent/deploycfg|grep ^- | cut -d ' ' -f 2|sed -e 's/ //')
for ntpsrv in "$ntpsrvs"; do
setdebopt clock-setup/ntp true boolean
setdebopt clock-setup/ntep-server $ntpsrv string
setdebopt clock-setup/ntp-server $ntpsrv string
done
#setdebopt console-setup/layoutcode $(grep ^keymap: /etc/confluent/deploycfg|cut -d ' ' -f 2) string
setdebopt debian-installer/locale $(grep ^locale: /etc/confluent/deploycfg|cut -d ' ' -f 2) select
domainname=$(grep ^dnsdomain: /etc/confluent/deploycfg|cut -d ' ' -f 2)
if [ ! -z "$domainname" ] && [ "$domainname" != "null" ]; then
@@ -95,3 +156,54 @@ fi
wget https://$mgr/confluent-public/os/$profile/scripts/pre.sh
chmod u+x pre.sh
wget https://$mgr/confluent-public/os/$profile/scripts/prechroot.sh
chmod u+x prechroot.sh
wget https://$mgr/confluent-public/os/$profile/scripts/post.sh
chmod u+x post.sh
wget https://$mgr/confluent-public/os/$profile/preseed.cfg
cat preseed.cfg >> /preseed.cfg
echo $mgr > /etc/confluent/deployer
setdebopt auto-install/enable true boolean
setdebopt partman/early_command $predir/pre.sh string
setdebopt preseed/late_command $predir/prechroot.sh string
mv $predir/post.sh /tmp/
cd -
ip -4 a flush dev $nic
setdebopt netcfg/choose_interface $nic select
setdebopt netcfg/get_hostname $nodename string
setdebopt netcfg/hostname $nodename string
setdebopt mirror/protocol https string
setdebopt mirror/country manual string
setdebopt mirror/https/hostname deb.debian.org string
setdebopt mirror/https/directory /debian/ string
setdebopt mirror/protocol https string
setdebopt mirror/https/proxy "" string
#setdebopt apt-setup/security_host $mgr string
if [ ! -e /dev/disk/by-label/CNFLNT_IDNT ]; then
v4cfgmeth=$(grep ipv4_method: /etc/confluent/deploycfg |cut -d: -f 2|sed -e 's/ //')
if [ "$v4cfgmeth" = "static" ]; then
setdebopt netcfg/disable_dhcp true boolean
v4addr=$(grep ^ipv4_address: /etc/confluent/deploycfg|cut -d: -f 2|sed -e 's/ //')
v4gw=$(grep ^ipv4_gateway: /etc/confluent/deploycfg|cut -d: -f 2| sed -e 's/ //')
if [ "$v4gw" = "null" ]; then
v4gw=""
fi
v4nm=$(grep ^ipv4_netmask: /etc/confluent/deploycfg|cut -d: -f 2|sed -e 's/ //')
setdebopt netcfg/get_netmask $v4nm string
setdebopt netcfg/get_ipaddress $v4addr string
setdebopt netcfg/confirm_static true boolean
if [ ! -z "$v4gw" ]; then
setdebopt netcfg/get_gateway $v4gw string
fi
namesrvs=$(sed -n '/^nameservers:/,/^[^-]/p' /etc/confluent/deploycfg|grep ^- | cut -d ' ' -f 2|sed -e 's/ //')
for namesrv in "$namesrvs"; do
setdebopt netcfg/get_nameservers $namesrv string
done
elif [ "$vpcfgmeth" = "dhcp" ]; then
setdebopt netcfg/disable_dhcp false boolean
setdebopt netcfg/confirm_static false boolean
fi
fi
@@ -0,0 +1,8 @@
#!/bin/sh
sed -i 's/label: debian/label: Debian/' $2/profile.yaml && \
ln -s $1/linux $2/boot/kernel && \
ln -s $1/initrd.gz $2/boot/initramfs/distribution && \
mkdir -p $2/boot/efi/boot && \
rm $2/distribution && \
mcopy -i $1/boot/grub/efi.img ::/efi/boot/* $2/boot/efi/boot
@@ -0,0 +1,27 @@
d-i anna/choose_modules string openssh-server-udeb
d-i partman-auto/method string regular
d-i partman-lvm/device_remove_lvm boolean true
d-i partman-md/device_remove_md boolean true
d-i partman-auto/expert_recipe_file string /tmp/partitionfile
d-i partman/confirm_write_new_label boolean true
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i passwd/make-user boolean false
d-i clock-setup/utc boolean true
d-i apt-setup/multiverse boolean false
d-i apt-setup/universe boolean false
d-i apt-setup/backports boolean false
d-i apt-setup/updates boolean false
d-i grub-installer/only_debian boolean true
tasksel tasksel/first multiselect standard
d-i pkgsel/include string openssh-server curl
d-i pkgsel/update-policy select none
d-i pkgsel/updatedb boolean false
d-i finish-install/reboot_in_progress note
popularity-contest popularity-contest/participate boolean false
d-i partman-auto/method string lvm
d-i partman-auto/choose_recipe select atomic
d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-auto-lvm/guided_size string max
@@ -0,0 +1,3 @@
label: %%DISTRO%% %%VERSION%% %%ARCH%% (Default Profile)
kernelargs: quiet osprofile=%%PROFILE%%
#installedargs: example # These arguments would be added to the installed system
@@ -0,0 +1,565 @@
#!/usr/bin/python
import glob
import json
import os
import socket
import sys
import time
import shlex
import subprocess
try:
import yaml
except ImportError:
pass
try:
from importlib.machinery import SourceFileLoader
def load_source(mod, path):
return SourceFileLoader(mod, path).load_module()
except ImportError:
from imp import load_source
try:
apiclient = load_source('apiclient', '/opt/confluent/bin/apiclient')
except IOError:
apiclient = load_source('apiclient', '/etc/confluent/apiclient')
def add_lla(iface, mac):
pieces = mac.split(':')
initbyte = int(pieces[0], 16) ^ 2
lla = 'fe80::{0:x}{1}:{2}ff:fe{3}:{4}{5}/64'.format(initbyte, pieces[1], pieces[2], pieces[3], pieces[4], pieces[5])
try:
with open('/proc/sys/net/ipv6/conf/{0}/disable_ipv6'.format(iface), 'w') as setin:
setin.write('0')
subprocess.check_call(['ip', 'addr', 'add', 'dev', iface, lla, 'scope', 'link'])
except Exception:
return None
return lla
#cli = apiclient.HTTPSClient(json=True)
#c = cli.grab_url_with_status('/confluent-api/self/netcfg')
def add_missing_llas():
#NetworkManager goes out of its way to suppress ipv6 lla, so will just add some
added = {}
linkinfo = subprocess.check_output(['ip', '-br', 'l']).decode('utf8')
ifaces = {}
for line in linkinfo.split('\n'):
line = line.strip().split()
if not line or 'LOOPBACK' in line[-1] or 'NO-CARRIER' in line[-1]:
continue
if 'UP' not in line[-1]:
subprocess.call(['ip', 'link', 'set', line[0], 'up'])
ifaces[line[0]] = line[2]
ips = {}
ipinfo = subprocess.check_output(['ip', '-br', '-6', 'a']).decode('utf8')
for line in ipinfo.split('\n'):
line = line.strip().split(None, 2)
if not line:
continue
ips[line[0]] = line[2]
for iface in ifaces:
for addr in ips.get(iface, '').split():
if addr.startswith('fe80::'):
break
else:
newlla = add_lla(iface, ifaces[iface])
if newlla:
added[iface] = newlla
return added
def rm_tmp_llas(tmpllas):
for iface in tmpllas:
subprocess.check_call(['ip', 'addr', 'del', 'dev', iface, tmpllas[iface]])
def await_tentative():
maxwait = 10
while b'tentative' in subprocess.check_output(['ip', 'a']):
if maxwait == 0:
break
maxwait -= 1
time.sleep(1)
def map_idx_to_name():
map = {}
devtype = {}
prevdev = None
for line in subprocess.check_output(['ip', 'l']).decode('utf8').splitlines():
if line.startswith(' ') and 'link/' in line:
typ = line.split()[0].split('/')[1]
devtype[prevdev] = typ if typ != 'ether' else 'ethernet'
if line.startswith(' '):
continue
idx, iface, rst = line.split(':', 2)
prevdev = iface.strip()
rst = rst.split()
try:
midx = rst.index('master')
continue
except ValueError:
pass
idx = int(idx)
iface = iface.strip()
map[idx] = iface
return map, devtype
def get_interface_name(iname, settings):
explicitname = settings.get('interface_names', None)
if explicitname:
return explicitname
if settings.get('current_nic', False):
return iname
return None
class NetplanManager(object):
def __init__(self, deploycfg):
self.cfgbydev = {}
self.read_connections()
self.deploycfg = deploycfg
def read_connections(self):
for plan in glob.glob('/etc/netplan/*.y*ml'):
with open(plan) as planfile:
planinfo = yaml.safe_load(planfile)
if not planinfo:
continue
nicinfo = planinfo.get('network', {}).get('ethernets', {})
for devname in nicinfo:
if devname == 'lo':
continue
if 'gateway4' in nicinfo[devname]:
# normalize deprecated syntax on read in
gw4 = nicinfo[devname]['gateway4']
del nicinfo[devname]['gateway4']
routeinfo = nicinfo[devname].get('routes', [])
for ri in routeinfo:
if ri.get('via', None) == gw4 and ri.get('to', None) in ('default', '0.0.0.0/0', '0/0'):
break
else:
routeinfo.append({
'to': 'default',
'via': gw4
})
nicinfo[devname]['routes'] = routeinfo
self.cfgbydev[devname] = nicinfo[devname]
def apply_configuration(self, cfg):
devnames = cfg['interfaces']
if len(devnames) != 1:
raise Exception('Multi-nic team/bonds not yet supported')
stgs = cfg['settings']
needcfgapply = False
for devname in devnames:
needcfgwrite = False
# ipv6_method missing at uconn...
if stgs.get('ipv6_method', None) == 'static':
curraddr = stgs['ipv6_address']
currips = self.getcfgarrpath([devname, 'addresses'])
if curraddr not in currips:
needcfgwrite = True
currips.append(curraddr)
if stgs.get('ipv4_method', None) == 'static':
curraddr = stgs['ipv4_address']
currips = self.getcfgarrpath([devname, 'addresses'])
if curraddr not in currips:
needcfgwrite = True
currips.append(curraddr)
gws = []
gws.append(stgs.get('ipv4_gateway', None))
gws.append(stgs.get('ipv6_gateway', None))
for gwaddr in gws:
if gwaddr:
cfgroutes = self.getcfgarrpath([devname, 'routes'])
for rinfo in cfgroutes:
if rinfo.get('via', None) == gwaddr:
break
else:
needcfgwrite = True
cfgroutes.append({'via': gwaddr, 'to': 'default'})
dnsips = self.deploycfg.get('nameservers', [])
dnsdomain = self.deploycfg.get('dnsdomain', '')
if dnsips:
currdnsips = self.getcfgarrpath([devname, 'nameservers', 'addresses'])
for dnsip in dnsips:
if dnsip and dnsip not in currdnsips:
needcfgwrite = True
currdnsips.append(dnsip)
if dnsdomain:
currdnsdomain = self.getcfgarrpath([devname, 'nameservers', 'search'])
if dnsdomain not in currdnsdomain:
needcfgwrite = True
currdnsdomain.append(dnsdomain)
if needcfgwrite:
needcfgapply = True
newcfg = {'network': {'version': 2, 'ethernets': {devname: self.cfgbydev[devname]}}}
oumask = os.umask(0o77)
with open('/etc/netplan/{0}-confluentcfg.yaml'.format(devname), 'w') as planout:
planout.write(yaml.dump(newcfg))
os.umask(oumask)
if needcfgapply:
subprocess.call(['netplan', 'apply'])
def getcfgarrpath(self, devpath):
currptr = self.cfgbydev
for k in devpath[:-1]:
if k not in currptr:
currptr[k] = {}
currptr = currptr[k]
if devpath[-1] not in currptr:
currptr[devpath[-1]] = []
return currptr[devpath[-1]]
class WickedManager(object):
def __init__(self):
self.teamidx = 0
self.read_connections()
def read_connections(self):
self.cfgbydev = {}
for ifcfg in glob.glob('/etc/sysconfig/network/ifcfg-*'):
devname = ifcfg.replace('/etc/sysconfig/network/ifcfg-', '')
if devname == 'lo':
continue
currcfg = {}
self.cfgbydev[devname] = currcfg
for cfg in open(ifcfg).read().splitlines():
cfg = cfg.split('#', 1)[0]
try:
kv = ' '.join(shlex.split(cfg)).split('=', 1)
except Exception:
# unparseable line, likely having something we can't handle
del self.cfgbydev[devname]
if len(kv) != 2:
continue
k, v = kv
k = k.strip()
v = v.strip()
currcfg[k] = v
def apply_configuration(self, cfg):
stgs = cfg['settings']
ipcfg = 'STARTMODE=auto\n'
routecfg = ''
bootproto4 = stgs.get('ipv4_method', 'none')
bootproto6 = stgs.get('ipv6_method', 'none')
if bootproto4 == 'dhcp' and bootproto6 == 'dhcp':
ipcfg += 'BOOTPROTO=dhcp\n'
elif bootproto4 == 'dhcp':
ipcfg += 'BOOTPROTO=dhcp4\n'
elif bootproto6 == 'dhcp':
ipcfg += 'BOOTPROTO=dhcp6\n'
else:
ipcfg += 'BOOTPROTO=static\n'
if stgs.get('ipv4_address', None):
ipcfg += 'IPADDR=' + stgs['ipv4_address'] + '\n'
v4gw = stgs.get('ipv4_gateway', None)
if stgs.get('ipv6_address', None):
ipcfg += 'IPADDR_V6=' + stgs['ipv6_address'] + '\n'
v6gw = stgs.get('ipv6_gateway', None)
cname = None
if len(cfg['interfaces']) > 1: # creating new team
if not stgs.get('team_mode', None):
sys.stderr.write("Warning, multiple interfaces ({0}) without a team_mode, skipping setup\n".format(','.join(cfg['interfaces'])))
return
if not stgs.get('connection_name', None):
stgs['connection_name'] = 'bond{0}'.format(self.teamidx)
self.teamidx += 1
cname = stgs['connection_name']
with open('/etc/sysconfig/network/ifcfg-{0}'.format(cname), 'w') as teamout:
teamout.write(ipcfg)
if stgs['team_mode'] == 'lacp':
stgs['team_mode'] = '802.3ad'
teamout.write("BONDING_MODULE_OPTS='mode={0} miimon=100'\nBONDING_MASTER=yes\n".format(stgs['team_mode']))
idx = 1
for iface in cfg['interfaces']:
subprocess.call(['wicked', 'ifdown', iface])
try:
os.remove('/etc/sysconfig/network/ifcfg-{0}'.format(iface))
os.remove('/etc/sysconfig/network/ifroute-{0}'.format(iface))
except OSError:
pass
teamout.write('BONDING_SLAVE{0}={1}\n'.format(idx, iface))
idx += 1
else:
cname = list(cfg['interfaces'])[0]
priorcfg = self.cfgbydev.get(cname, {})
for cf in priorcfg:
if cf.startswith('TEAM_'):
ipcfg += '{0}={1}\n'.format(cf, priorcfg[cf])
with open('/etc/sysconfig/network/ifcfg-{0}'.format(cname), 'w') as iout:
iout.write(ipcfg)
if v4gw:
routecfg += 'default {0} - {1}\n'.format(v4gw, cname)
if v6gw:
routecfg += 'default {0} - {1}\n'.format(v6gw, cname)
if routecfg:
with open('/etc/sysconfig/network/ifroute-{0}'.format(cname), 'w') as routeout:
routeout.write(routecfg)
subprocess.call(['wicked', 'ifup', cname])
class NetworkManager(object):
bondtypes = {
'lacp': '802.3ad',
'loadbalance': 'balance-alb',
'roundrobin': 'balance-rr',
'activebackup': 'active-backup',
}
def __init__(self, devtypes, deploycfg):
self.deploycfg = deploycfg
self.connections = {}
self.uuidbyname = {}
self.uuidbydev = {}
self.connectiondetail = {}
self.read_connections()
self.teamidx = 0
self.devtypes = devtypes
def read_connections(self):
self.connections = {}
self.uuidbyname = {}
self.uuidbydev = {}
self.connectiondetail = {}
ci = subprocess.check_output(['nmcli', '-t', 'c']).decode('utf8')
for inf in ci.splitlines():
n, u, t, dev = inf.split(':')
if n == 'NAME':
continue
if dev == '--':
dev = None
self.uuidbyname[n] = u
if dev:
self.uuidbydev[dev] = u
self.connections[u] = {'name': n, 'uuid': u, 'type': t, 'dev': dev}
deats = {}
for deat in subprocess.check_output(['nmcli', 'c', 's', u]).decode('utf8').splitlines():
k, v = deat.split(':', 1)
v = v.strip()
if v == '--':
continue
if '(default)' in v:
continue
deats[k] = v
self.connectiondetail[u] = deats
def add_team_member(self, team, member):
bondcfg = {}
if member in self.uuidbydev:
myuuid = self.uuidbydev[member]
deats = self.connectiondetail[myuuid]
currteam = deats.get('connection.master', None)
if currteam == team:
return
for stg in ('ipv4.dhcp-hostname', 'ipv4.dns', 'ipv6.dns', 'ipv6.dhcp-hostname'):
if deats.get(stg, None):
bondcfg[stg] = deats[stg]
if member in self.uuidbyname:
subprocess.check_call(['nmcli', 'c', 'del', self.uuidbyname[member]])
devtype = self.devtypes.get(member, 'bond-slave')
subprocess.check_call(['nmcli', 'c', 'add', 'type', devtype, 'master', team, 'con-name', member, 'connection.interface-name', member])
if bondcfg:
args = []
for parm in bondcfg:
args.append(parm)
args.append(bondcfg[parm])
subprocess.check_call(['nmcli', 'c', 'm', team] + args)
def apply_configuration(self, cfg, lastchance=False):
cmdargs = {}
cmdargs['connection.autoconnect'] = 'yes'
stgs = cfg['settings']
cmdargs['ipv6.method'] = stgs.get('ipv6_method', 'link-local')
if stgs.get('ipv6_address', None):
cmdargs['ipv6.addresses'] = stgs['ipv6_address']
cmdargs['ipv4.method'] = stgs.get('ipv4_method', 'disabled')
if stgs.get('ipv4_address', None):
cmdargs['ipv4.addresses'] = stgs['ipv4_address']
if stgs.get('ipv4_gateway', None):
cmdargs['ipv4.gateway'] = stgs['ipv4_gateway']
if stgs.get('ipv6_gateway', None):
cmdargs['ipv6.gateway'] = stgs['ipv6_gateway']
dnsips = self.deploycfg.get('nameservers', [])
if not dnsips:
dnsips = []
dns4 = []
dns6 = []
for dnsip in dnsips:
if '.' in dnsip:
dns4.append(dnsip)
elif ':' in dnsip:
dns6.append(dnsip)
if dns4:
cmdargs['ipv4.dns'] = ','.join(dns4)
if dns6:
cmdargs['ipv6.dns'] = ','.join(dns6)
if len(cfg['interfaces']) > 1: # team time.. should be..
if not cfg['settings'].get('team_mode', None):
sys.stderr.write("Warning, multiple interfaces ({0}) without a team_mode, skipping setup\n".format(','.join(cfg['interfaces'])))
return
if not cfg['settings'].get('connection_name', None):
cfg['settings']['connection_name'] = 'team{0}'.format(self.teamidx)
self.teamidx += 1
cname = cfg['settings']['connection_name']
cargs = []
for arg in cmdargs:
cargs.append(arg)
cargs.append(cmdargs[arg])
if stgs['team_mode'] in self.bondtypes:
stgs['team_mode'] = self.bondtypes[stgs['team_mode']]
subprocess.check_call(['nmcli', 'c', 'add', 'type', 'bond', 'con-name', cname, 'connection.interface-name', cname, 'bond.options', 'mode={}'.format(stgs['team_mode'])] + cargs)
for iface in cfg['interfaces']:
self.add_team_member(cname, iface)
subprocess.check_call(['nmcli', 'c', 'u', cname])
else:
cname = stgs.get('connection_name', None)
iname = list(cfg['interfaces'])[0]
ctype = self.devtypes.get(iname, None)
if not ctype:
if lastchance:
sys.stderr.write("Warning, no device found for interface_name ({0}), skipping setup\n".format(iname))
return 1
if stgs.get('vlan_id', None):
vlan = stgs['vlan_id']
if ctype == 'infiniband':
vlan = '0x{0}'.format(vlan) if not vlan.startswith('0x') else vlan
cmdargs['infiniband.parent'] = iname
cmdargs['infiniband.p-key'] = vlan
iname = '{0}.{1}'.format(iname, vlan[2:])
elif ctype == 'ethernet':
ctype = 'vlan'
cmdargs['vlan.parent'] = iname
cmdargs['vlan.id'] = vlan
iname = '{0}.{1}'.format(iname, vlan)
else:
sys.stderr.write("Warning, unknown interface_name ({0}) device type ({1}) for VLAN/PKEY, skipping setup\n".format(iname, ctype))
return
cname = iname if not cname else cname
u = self.uuidbyname.get(cname, None)
cargs = []
for arg in cmdargs:
cargs.append(arg)
cargs.append(cmdargs[arg])
if u:
subprocess.check_call(['nmcli', 'c', 'm', u, 'connection.interface-name', iname] + cargs)
subprocess.check_call(['nmcli', 'c', 'u', u])
else:
subprocess.check_call(['nmcli', 'c', 'add', 'type', ctype, 'con-name', cname, 'connection.interface-name', iname] + cargs)
self.read_connections()
u = self.uuidbyname.get(cname, None)
if u:
subprocess.check_call(['nmcli', 'c', 'u', u])
if __name__ == '__main__':
havefirewall = subprocess.call(['systemctl', 'status', 'firewalld'])
havefirewall = havefirewall == 0
if havefirewall:
subprocess.check_call(['systemctl', 'stop', 'firewalld'])
tmpllas = add_missing_llas()
await_tentative()
idxmap, devtypes = map_idx_to_name()
netname_to_interfaces = {}
myaddrs = apiclient.get_my_addresses()
srvs, _ = apiclient.scan_confluents()
doneidxs = set([])
dc = None
if not srvs: # the multicast scan failed, fallback to deploycfg cfg file
with open('/etc/confluent/confluent.deploycfg', 'r') as dci:
for cfgline in dci.read().split('\n'):
if cfgline.startswith('deploy_server:'):
srvs = [cfgline.split()[1]]
break
for srv in srvs:
try:
s = socket.create_connection((srv, 443))
except socket.error:
continue
myname = s.getsockname()
s.close()
if len(myname) == 4:
curridx = myname[-1]
else:
myname = myname[0]
myname = socket.inet_pton(socket.AF_INET, myname)
for addr in myaddrs:
if myname == addr[1].tobytes():
curridx = addr[-1]
if curridx in doneidxs:
continue
for tries in (1, 2, 3):
try:
status, nc = apiclient.HTTPSClient(usejson=True, host=srv).grab_url_with_status('/confluent-api/self/netcfg')
break
except Exception:
if tries == 3:
raise
time.sleep(1)
continue
nc = json.loads(nc)
if not dc:
for tries in (1, 2, 3):
try:
status, dc = apiclient.HTTPSClient(usejson=True, host=srv).grab_url_with_status('/confluent-api/self/deploycfg2')
break
except Exception:
if tries == 3:
raise
time.sleep(1)
continue
dc = json.loads(dc)
iname = get_interface_name(idxmap[curridx], nc.get('default', {}))
if iname:
for iname in iname.split(','):
if 'default' in netname_to_interfaces:
netname_to_interfaces['default']['interfaces'].add(iname)
else:
netname_to_interfaces['default'] = {'interfaces': set([iname]), 'settings': nc['default']}
for netname in nc.get('extranets', {}):
uname = '_' + netname
iname = get_interface_name(idxmap[curridx], nc['extranets'][netname])
if iname:
for iname in iname.split(','):
if uname in netname_to_interfaces:
netname_to_interfaces[uname]['interfaces'].add(iname)
else:
netname_to_interfaces[uname] = {'interfaces': set([iname]), 'settings': nc['extranets'][netname]}
doneidxs.add(curridx)
if 'default' in netname_to_interfaces:
for netn in netname_to_interfaces:
if netn == 'default':
continue
netname_to_interfaces['default']['interfaces'] -= netname_to_interfaces[netn]['interfaces']
if not netname_to_interfaces['default']['interfaces']:
del netname_to_interfaces['default']
# Make sure VLAN/PKEY connections are created last
netname_to_interfaces = dict(sorted(netname_to_interfaces.items(), key=lambda item: 'vlan_id' in item[1]['settings']))
rm_tmp_llas(tmpllas)
if os.path.exists('/usr/sbin/netplan'):
nm = NetplanManager(dc)
if os.path.exists('/usr/bin/nmcli'):
nm = NetworkManager(devtypes, dc)
elif os.path.exists('/usr/sbin/wicked'):
nm = WickedManager()
retrynics = []
for netn in netname_to_interfaces:
redo = nm.apply_configuration(netname_to_interfaces[netn])
if redo == 1:
retrynics.append(netn)
if retrynics:
idxmap, devtypes = map_idx_to_name()
if os.path.exists('/usr/sbin/netplan'):
nm = NetplanManager(dc)
if os.path.exists('/usr/bin/nmcli'):
nm = NetworkManager(devtypes, dc)
elif os.path.exists('/usr/sbin/wicked'):
nm = WickedManager()
for netn in retrynics:
nm.apply_configuration(netname_to_interfaces[netn], lastchance=True)
if havefirewall:
subprocess.check_call(['systemctl', 'start', 'firewalld'])
await_tentative()
@@ -0,0 +1,11 @@
[Unit]
Description=First Boot Process
Requires=network-online.target
After=network-online.target
[Service]
ExecStart=/opt/confluent/bin/firstboot.sh
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,22 @@
#!/bin/bash
echo "Confluent first boot is running"
HOME=$(getent passwd $(whoami)|cut -d: -f 6)
export HOME
#cp -a /etc/confluent/ssh/* /etc/ssh/
#systemctl restart sshd
rootpw=$(grep ^rootpassword: /etc/confluent/confluent.deploycfg |awk '{print $2}')
if [ ! -z "$rootpw" -a "$rootpw" != "null" ]; then
echo root:$rootpw | chpasswd -e
fi
nodename=$(grep ^NODENAME: /etc/confluent/confluent.info | awk '{print $2}')
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg |awk '{print $2}')
while ! ping -c 1 $confluent_mgr >& /dev/null; do
sleep 1
done
source /etc/confluent/functions
run_remote_parts firstboot.d
run_remote_config firstboot.d
systemctl disable firstboot
curl -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" -X POST -d "status: complete" https://$confluent_mgr/confluent-api/self/updatestatus
@@ -0,0 +1,209 @@
#!/bin/bash
function test_mgr() {
whost=$1
if [[ "$whost" == *:* ]] && [[ "$whost" != *[* ]] ; then
whost="[$whost]"
fi
if curl -gs https://${whost}/confluent-api/ > /dev/null; then
return 0
fi
return 1
}
function confluentpython() {
if [ -x /usr/libexec/platform-python ]; then
/usr/libexec/platform-python $*
elif [ -x /usr/bin/python3 ]; then
/usr/bin/python3 $*
elif [ -x /usr/bin/python ]; then
/usr/bin/python $*
elif [ -x /usr/bin/python2 ]; then
/usr/bin/python2 $*
fi
}
function set_confluent_vars() {
if [ -z "$nodename" ]; then
nodename=$(grep ^NODENAME: /etc/confluent/confluent.info | awk '{print $2}')
fi
if [[ "$confluent_mgr" == *"%"* ]]; then
confluent_mgr=""
fi
if [ -z "$confluent_mgr" ]; then
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
if ! test_mgr $confluent_mgr; then
confluent_mgr=$(grep ^deploy_server_v6: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
if [[ "$confluent_mgr" = *":"* ]]; then
confluent_mgr="[$confluent_mgr]"
fi
fi
if ! test_mgr $confluent_mgr; then
BESTMGRS=$(grep ^EXTMGRINFO: /etc/confluent/confluent.info | grep '|1$' | sed -e 's/EXTMGRINFO: //' -e 's/|.*//')
OKMGRS=$(grep ^EXTMGRINFO: /etc/confluent/confluent.info | grep '|0$' | sed -e 's/EXTMGRINFO: //' -e 's/|.*//')
for confluent_mgr in $BESTMGRS $OKMGRS; do
if [[ $confluent_mgr == *":"* ]]; then
confluent_mgr="[$confluent_mgr]"
fi
if test_mgr $confluent_mgr; then
break
fi
done
fi
fi
if [ -z "$confluent_profile" ]; then
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
export confluent_profile confluent_mgr nodename
}
fetch_remote() {
curlargs=""
if [ -f /etc/confluent/ca.pem ]; then
curlargs=" --cacert /etc/confluent/ca.pem"
fi
set_confluent_vars
mkdir -p $(dirname $1)
whost=$confluent_mgr
if [[ "$whost" == *:* ]] && [[ "$whost" != *[* ]] ; then
whost="[$whost]"
fi
curl -gf -sS $curlargs https://$whost/confluent-public/os/$confluent_profile/scripts/$1 > $1
if [ $? != 0 ]; then echo $1 failed to download; return 1; fi
}
source_remote_parts() {
confluentscripttmpdir=$(mktemp -d /tmp/confluentscripts.XXXXXXXXX)
apiclient=/opt/confluent/bin/apiclient
if [ -f /etc/confluent/apiclient ]; then
apiclient=/etc/confluent/apiclient
fi
scriptlist=$(confluentpython $apiclient /confluent-api/self/scriptlist/$1|sed -e 's/^- //')
for script in $scriptlist; do
source_remote $1/$script
done
rm -rf $confluentscripttmpdir
unset confluentscripttmpdir
}
run_remote_parts() {
confluentscripttmpdir=$(mktemp -d /tmp/confluentscripts.XXXXXXXXX)
apiclient=/opt/confluent/bin/apiclient
if [ -f /etc/confluent/apiclient ]; then
apiclient=/etc/confluent/apiclient
fi
scriptlist=$(confluentpython $apiclient /confluent-api/self/scriptlist/$1|sed -e 's/^- //')
for script in $scriptlist; do
run_remote $1/$script
done
rm -rf $confluentscripttmpdir
unset confluentscripttmpdir
}
source_remote() {
set_confluent_vars
unsettmpdir=0
echo
echo '---------------------------------------------------------------------------'
echo Sourcing $1 from https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/
if [ -z "$confluentscripttmpdir" ]; then
confluentscripttmpdir=$(mktemp -d /tmp/confluentscripts.XXXXXXXXX)
unsettmpdir=1
fi
echo Sourcing from $confluentscripttmpdir
cd $confluentscripttmpdir
fetch_remote $1
if [ $? != 0 ]; then echo $1 failed to download; return 1; fi
chmod +x $1
cmd=$1
shift
source ./$cmd
cd - > /dev/null
if [ "$unsettmpdir" = 1 ]; then
rm -rf $confluentscripttmpdir
unset confluentscripttmpdir
unsettmpdir=0
fi
rm -rf $confluentscripttmpdir
return $retcode
}
run_remote() {
requestedcmd="'$*'"
unsettmpdir=0
set_confluent_vars
echo
echo '---------------------------------------------------------------------------'
echo Running $requestedcmd from https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/
if [ -z "$confluentscripttmpdir" ]; then
confluentscripttmpdir=$(mktemp -d /tmp/confluentscripts.XXXXXXXXX)
unsettmpdir=1
fi
echo Executing in $confluentscripttmpdir
cd $confluentscripttmpdir
fetch_remote $1
if [ $? != 0 ]; then echo $requestedcmd failed to download; return 1; fi
chmod +x $1
cmd=$1
if [ -x /usr/bin/chcon ]; then
chcon system_u:object_r:bin_t:s0 $cmd
fi
shift
./$cmd $*
retcode=$?
if [ $retcode -ne 0 ]; then
echo "$requestedcmd exited with code $retcode"
fi
cd - > /dev/null
if [ "$unsettmpdir" = 1 ]; then
rm -rf $confluentscripttmpdir
unset confluentscripttmpdir
unsettmpdir=0
fi
return $retcode
}
run_remote_python() {
echo
set_confluent_vars
if [ -f /etc/confluent/ca.pem ]; then
curlargs=" --cacert /etc/confluent/ca.pem"
fi
echo '---------------------------------------------------------------------------'
echo Running python script "'$*'" from https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/
confluentscripttmpdir=$(mktemp -d /tmp/confluentscripts.XXXXXXXXX)
echo Executing in $confluentscripttmpdir
cd $confluentscripttmpdir
mkdir -p $(dirname $1)
whost=$confluent_mgr
if [[ "$whost" == *:* ]] && [[ "$whost" != *[* ]] ; then
whost="[$whost]"
fi
curl -gf -sS $curlargs https://$whost/confluent-public/os/$confluent_profile/scripts/$1 > $1
if [ $? != 0 ]; then echo "'$*'" failed to download; return 1; fi
confluentpython $*
retcode=$?
echo "'$*' exited with code $retcode"
cd - > /dev/null
rm -rf $confluentscripttmpdir
unset confluentscripttmpdir
return $retcode
}
run_remote_config() {
echo
set_confluent_vars
apiclient=/opt/confluent/bin/apiclient
if [ -f /etc/confluent/apiclient ]; then
apiclient=/etc/confluent/apiclient
fi
echo '---------------------------------------------------------------------------'
echo Requesting to run remote configuration for "'$*'" from $confluent_mgr under profile $confluent_profile
confluentpython $apiclient /confluent-api/self/remoteconfig/"$*" -d {}
confluentpython $apiclient /confluent-api/self/remoteconfig/status -w 204
echo
echo 'Completed remote configuration'
echo '---------------------------------------------------------------------------'
return
}
#If invoked as a command, use the arguments to actually run a function
(return 0 2>/dev/null) || $1 "${@:2}"
+67
View File
@@ -0,0 +1,67 @@
#!/bin/bash
mkdir -p /run/sshd
mkdir -p /root/.ssh
cat /tmp/ssh/*pubkey >> /root/.ssh/authorized_keys
cat /tmp/ssh/*.ca | sed -e s/^/'@cert-authority * '/ >> /etc/ssh/ssh_known_hosts
chmod 700 /etc/confluent
chmod go-rwx /etc/confluent/*
sshconf=/etc/ssh/ssh_config
if [ -d /etc/ssh/ssh_config.d/ ]; then
sshconf=/etc/ssh/ssh_config.d/01-confluent.conf
fi
echo 'Host *' >> $sshconf
echo ' HostbasedAuthentication yes' >> $sshconf
echo ' EnableSSHKeysign yes' >> $sshconf
echo ' HostbasedKeyTypes *ed25519*' >> $sshconf
/usr/sbin/sshd
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | awk '{print $2}')
mkdir -p /opt/confluent/bin
python3 /opt/confluent/bin/apiclient /confluent-public/os/$confluent_profile/scripts/firstboot.sh > /opt/confluent/bin/firstboot.sh
chmod +x /opt/confluent/bin/firstboot.sh
python3 /opt/confluent/bin/apiclient /confluent-public/os/$confluent_profile/scripts/firstboot.service > /etc/systemd/system/firstboot.service
systemctl enable firstboot
python3 /opt/confluent/bin/apiclient /confluent-public/os/$confluent_profile/scripts/functions > /etc/confluent/functions
source /etc/confluent/functions
python3 /opt/confluent/bin/apiclient /confluent-api/self/nodelist | sed -e s/'^- //' > /tmp/allnodes
cp /tmp/allnodes /root/.shosts
cp /tmp/allnodes /etc/ssh/shosts.equiv
if grep ^ntpservers: /etc/confluent/confluent.deploycfg > /dev/null; then
ntps=$(sed -n '/^ntpservers:/,/^[^-]/p' /etc/confluent/confluent.deploycfg|sed 1d|sed '$d' | sed -e 's/^- //' | paste -sd ' ')
sed -i "s/#NTP=/NTP=$ntps/" /etc/systemd/timesyncd.conf
fi
textcons=$(grep ^textconsole: /etc/confluent/confluent.deploycfg |awk '{print $2}')
updategrub=0
if [ "$textcons" = "true" ] && ! grep console= /proc/cmdline > /dev/null; then
cons=""
if [ -f /tmp/autocons.info ]; then
cons=$(cat /tmp/autocons.info)
fi
if [ ! -z "$cons" ]; then
sed -i 's/GRUB_CMDLINE_LINUX="\([^"]*\)"/GRUB_CMDLINE_LINUX="\1 console='${cons#/dev/}'"/' /etc/default/grub
updategrub=1
fi
fi
kargs=$(python3 /opt/confluent/bin/apiclient /confluent-public/os/$confluent_profile/profile.yaml | grep ^installedargs: | sed -e 's/#.*//')
if [ ! -z "$kargs" ]; then
sed -i 's/GRUB_CMDLINE_LINUX="\([^"]*\)"/GRUB_CMDLINE_LINUX="\1 '"${kargs}"'"/' /etc/default/grub
fi
if [ 1 = $updategrub ]; then
update-grub
fi
if [ -e /sys/firmware/efi ]; then
bootnum=$(efibootmgr | grep ubuntu | sed -e 's/ .*//' -e 's/\*//' -e s/Boot//)
if [ ! -z "$bootnum" ]; then
currboot=$(efibootmgr | grep ^BootOrder: | awk '{print $2}')
nextboot=$(echo $currboot| awk -F, '{print $1}')
[ "$nextboot" = "$bootnum" ] || efibootmgr -o $bootnum,$currboot
efibootmgr -D
fi
fi
run_remote_python syncfileclient
run_remote_parts post.d
run_remote_config post
python3 /opt/confluent/bin/apiclient /confluent-api/self/updatestatus -d 'status: staged'
+81 -11
View File
@@ -1,18 +1,88 @@
anna-install openssh-server-udeb
mkdir -p ~/.ssh/
cat /ssh/*pubkey > ~/.ssh/authorized_keys
ssh-keygen -A
mgr=$(grep ^MANAGER:.*\\. /etc/confluent/confluent.info|head -n 1|cut -d: -f 2|sed -e 's/ //')
nodename=$(grep ^NODENAME: /etc/confluent/confluent.info|head -n 1|cut -d: -f 2|sed -e 's/ //')
#!/bin/sh
## Use the following option to add additional boot parameters for the
## installed system (if supported by the bootloader installer).
## Note: options passed to the installer will be added automatically.
#d-i debian-installer/add-kernel-opts string [from profile.yaml]
deploycfg=/etc/confluent/confluent.deploycfg
mgr=$(cat /etc/confluent/deployer)
cryptboot=$(grep encryptboot: $deploycfg|sed -e 's/^encryptboot: //')
if [ "$cryptboot" != "" ] && [ "$cryptboot" != "none" ] && [ "$cryptboot" != "null" ]; then
echo "****Encrypted boot requested, but not implemented for this OS, halting install" > /dev/console
[ -f '/tmp/autoconsdev' ] && (echo "****Encryptod boot requested, but not implemented for this OS,halting install" >> $(cat /tmp/autoconsdev))
while :; do sleep 86400; done
fi
cat > /usr/lib/live-installer.d/confluent-certs << EOF
#!/bin/sh
cp /tls/* /target/etc/ssl/certs/
cat /tls/*.pem >> /target/etc/ssl/certs/ca-certificates.crt
EOF
chmod a+x /usr/lib/live-installer.d/confluent-certs
mkdir -p /.ssh/
cat /ssh/*pubkey > /.ssh/authorized_keys
mkdir -p /etc/ssh
nodename=$(grep ^NODENAME: /etc/confluent/confluent.info|cut -d ' ' -f 2)
apikey=$(cat /etc/confluent/confluent.apikey)
ssh-keygen -A
for pubkey in /etc/ssh/ssh_host*key.pub; do
certfile=${pubkey%.pub}-cert.pub
certfile=$(echo $pubkey | sed -e s/.pub/-cert.pub/)
keyfile=${pubkey%.pub}
wget --post-file=$pubkey --header='CONFLUENT_NODENAME: '$nodename --header="CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/sshcert -O $certfile
wget --header="CONFLUENT_NODENAME: $nodename" --header="CONFLUENT_APIKEY: $apikey" --post-file=$pubkey https://$mgr/confluent-api/self/sshcert -O $certfile --quiet
echo HostKey $keyfile >> /etc/ssh/sshd_config
echo HostCertificate $certfile >> /etc/ssh/sshd_config
done
echo sshd:x:939:939::/: >> /etc/passwd
if [ -e /tmp/installdisk ]; then
instdisk=$(cat /tmp/installdisk)
else
for blockdev in $(ls /sys/class/block/); do
shortname=$(basename $blockdev)
if [ "$shortname" != "${shortname%loop*}" ]; then
continue
fi
udevadm info --query=property /dev/$shortname |grep DEVTYPE=disk > /dev/null || continue # ignore partitions
udevadm info --query=property /dev/$shortname |grep DM_NAME > /dev/null && continue # not a real disk
sz=$(cat /sys/block/$shortname/size 2> /dev/null)
[ -z "$sz" ] && continue
[ $sz -lt 1048576 ] && continue # Too small
[ -z "$firstdisk" ] && firstdisk=$shortname
if udevadm info --query=property /dev/$shortname|grep ID_MODEL=| sed -e s/' '/_/g | grep -iE '(thinksystem_m.2|m.2_nvme_2-bay_raid_kit)' > /dev/null; then
instdisk=$shortname
break
fi
if udevadm info --query=property /dev/$shortname|grep MD_CONTAINER=imsm; then
sraid=$sortname
else
drv=$(udevadm info -a /dev/sdb|grep DRIVERS==|grep -Ev '""|"sd"' | sed -e s/.*=// -e s/'"'//g)
if [ "ahci" = "$drv" -a -z "$onbdisk" ]; then
onbdisk=$shortname
elif [ "megaraid" = "$drv" -a -z "$rdisk" ]; then
rdisk=$shortname
fi
fi
done
fi
if [ -z "$instdisk" ]; then
if [ ! -z "$sraid"]; then
instdisk=$sraid
elif [ ! -z "$onbdisk" ]; then
instdisk=$onbdisk
elif [ ! -z "$rdisk" ]; then
instdisk=$rdisk
else
instdisk=$firstdisk
fi
fi
if [ ! -z "$instdisk" ]; then
debconf-set partman-auto/disk /dev/$instdisk
debconf-set grub-installer/bootdev /dev/$instdisk
fi
echo HostbasedAuthentication yes >> /etc/ssh/sshd_config
echo HostbasedUsesNameFromPacketOnly yes >> /etc/ssh/sshd_config
echo IgnoreRhosts no >> /etc/ssh/sshd_config
echo sshd:x:1:1::/run/sshd:/bin/false >> /etc/passwd
/usr/sbin/sshd
wget --header="CONFLUENT_NODENAME: $nodename" --header="CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/nodelist -O /tmp/allnodes --quiet
#kill -HUP $(ps | grep -v grep | grep /usr/sbin/sshd | sed -e 's/^ *//'|cut -d ' ' -f 1)
#curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/getinstalldisk > /tmp/getinstalldisk
#python3 /tmp/getinstalldisk
#sed -i s!%%INSTALLDISK%%!/dev/$(cat /tmp/installdisk)! /autoinstall.yaml
@@ -0,0 +1,19 @@
#!/bin/sh
mount -o bind /sys /target/sys
mount -o bind /dev /target/dev
mount -o bind /dev/pts /target/dev/pts
mount -o bind /proc /target/proc
mount -o bind /dev/pts /target/dev/pts
mount -o bind /run /target/run
cp -a /etc/confluent /target/etc/confluent
cp -a /opt/confluent /target/opt/confluent
mv /tmp/post.sh /target/tmp/
cp -a /ssh /tls /target/tmp
cat /tls/*.pem >> /target/etc/confluent/ca.pem
cp -a /etc/ssh/ssh_host_* /target/etc/ssh/
grep HostCertificate /etc/ssh/sshd_config >> /target/etc/ssh/sshd_config
echo Port 2222 >> /etc/ssh/sshd_config
kill -HUP $(ps |grep -v grep|grep sshd|grep /usr|sed -e s/' root.*//')
cp /tls/* /target/etc/ssl/certs/
cat /tls/*.pem >> /target/etc/ssl/certs/ca-certificates.crt
chroot /target bash /tmp/post.sh
@@ -0,0 +1,5 @@
#!/bin/bash
# Add this to firstboot.d
export DEBIAN_FRONTEND=noninteractive
apt-get -y install proxmox-ve postfix open-iscsi chrony < /dev/null
@@ -0,0 +1,20 @@
#!/bin/bash
# This script would run in post.d
#
export DEBIAN_FRONTEND=noninteractive
echo "deb [arch=amd64] http://download.proxmox.com/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-install-repo.list
wget https://enterprise.proxmox.com/debian/proxmox-release-bookworm.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg
sum=$(sha512sum /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg)
if [ "$sum" -ne "7da6fe34168adc6e479327ba517796d4702fa2f8b4f0a9833f5ea6e6b48f6507a6da403a274fe201595edc86a84463d50383d07f64bdde2e3658108db7d6dc87" ]; then
echo "Mismatch in fingerprint!"
rm /etc/apt/trusted.gpg.d/proxmox-release-bookworm.gpg
exit 1
fi
apt-get update && apt-get -y full-upgrade < /dev/null
apt-get -y install proxmox-default-kernel < /dev/null
apt-get -y remove linux-image-amd64 'linux-image-6.1*' < /dev/null
update-grub
apt-get -y remove os-prober < /dev/null
@@ -0,0 +1,43 @@
[ -f /lib/confluent/functions ] && . /lib/confluent/functions
[ -f /etc/confluent/functions ] && . /etc/confluent/functions
[ -f /opt/confluent/bin/apiclient ] && confapiclient=/opt/confluent/bin/apiclient
[ -f /etc/confluent/apiclient ] && confapiclient=/etc/confluent/apiclient
for pubkey in /etc/ssh/ssh_host*key.pub; do
if [ "$pubkey" = /etc/ssh/ssh_host_key.pub ]; then
continue
fi
certfile=${pubkey/.pub/-cert.pub}
rm $certfile
confluentpython $confapiclient /confluent-api/self/sshcert $pubkey -o $certfile
done
if [ -d /etc/ssh/sshd_config.d/ -a ! -e /etc/ssh/sshd_config.d/90-confluent.conf ]; then
for cert in /etc/ssh/ssh*-cert.pub; do
echo HostCertificate $cert >> /etc/ssh/sshd_config.d/90-confluent.conf
done
echo HostbasedAuthentication yes >> /etc/ssh/sshd_config.d/90-confluent.conf
echo HostbasedUsesNameFromPacketOnly yes >> /etc/ssh/sshd_config.d/90-confluent.conf
echo IgnoreRhosts no >> /etc/ssh/sshd_config.d/90-confluent.conf
fi
TMPDIR=$(mktemp -d)
cd $TMPDIR
confluentpython $confapiclient /confluent-public/site/initramfs.tgz -o initramfs.tgz
tar xf initramfs.tgz
for ca in ssh/*.ca; do
LINE=$(cat $ca)
cp -af /etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts.new
grep -v "$LINE" /etc/ssh/ssh_known_hosts > /etc/ssh/ssh_known_hosts.new
echo '@cert-authority *' $LINE >> /etc/ssh/ssh_known_hosts.new
mv /etc/ssh/ssh_known_hosts.new /etc/ssh/ssh_known_hosts
done
for pubkey in ssh/*.*pubkey; do
LINE=$(cat $pubkey)
cp -af /root/.ssh/authorized_keys /root/.ssh/authorized_keys.new
grep -v "$LINE" /root/.ssh/authorized_keys > /root/.ssh/authorized_keys.new
echo "$LINE" >> /root/.ssh/authorized_keys.new
mv /root/.ssh/authorized_keys.new /root/.ssh/authorized_keys
done
confluentpython $confapiclient /confluent-api/self/nodelist | sed -e 's/^- //' > /etc/ssh/shosts.equiv
cat /etc/ssh/shosts.equiv > /root/.shosts
cd -
rm -rf $TMPDIR
@@ -5,6 +5,8 @@
# noted below so custom commands are executed before
# the script notifies confluent that install is fully complete.
HOME=$(getent passwd $(whoami)|cut -d: -f 6)
export HOME
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg|awk '{print $2}')
@@ -53,6 +53,7 @@ function set_confluent_vars() {
if [ -z "$confluent_profile" ]; then
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
export confluent_profile confluent_mgr nodename
}
fetch_remote() {
@@ -1,15 +1,19 @@
#!/usr/bin/python3
import subprocess
import os
class DiskInfo(object):
def __init__(self, devname):
if devname.startswith('nvme') and 'c' in devname:
raise Exception("Skipping multipath devname")
self.name = devname
self.wwn = None
self.path = None
self.model = ''
self.size = 0
self.driver = None
self.driver = ''
self.mdcontainer = ''
self.subsystype = ''
devnode = '/dev/{0}'.format(devname)
qprop = subprocess.check_output(
['udevadm', 'info', '--query=property', devnode])
@@ -44,7 +48,9 @@ class DiskInfo(object):
elif (k == 'DRIVERS' and not self.driver
and v not in ('"sd"', '""')):
self.driver = v.replace('"', '')
if not self.driver and 'imsm' not in self.mdcontainer:
elif k == 'ATTRS{subsystype}':
self.subsystype = v.replace('"', '')
if not self.driver and 'imsm' not in self.mdcontainer and self.subsystype != 'nvm':
raise Exception("No driver detected")
if os.path.exists('/sys/block/{0}/size'.format(self.name)):
with open('/sys/block/{0}/size'.format(self.name), 'r') as sizesrc:
@@ -11,6 +11,13 @@ import struct
import sys
import subprocess
def get_partname(devname, idx):
if devname[-1] in '0123456789':
return '{}p{}'.format(devname, idx)
else:
return '{}{}'.format(devname, idx)
def get_next_part_meta(img, imgsize):
if img.tell() == imgsize:
return None
@@ -53,10 +60,13 @@ class PartedRunner():
def __init__(self, disk):
self.disk = disk
def run(self, command):
def run(self, command, check=True):
command = command.split()
command = ['parted', '-a', 'optimal', '-s', self.disk] + command
return subprocess.check_output(command).decode('utf8')
if check:
return subprocess.check_output(command).decode('utf8')
else:
return subprocess.run(command, stdout=subprocess.PIPE).stdout.decode('utf8')
def fixup(rootdir, vols):
devbymount = {}
@@ -166,6 +176,8 @@ def fixup(rootdir, vols):
partnum = re.search('(\d+)$', targdev).group(1)
targblock = re.search('(.*)\d+$', targdev).group(1)
if targblock:
if targblock.endswith('p') and 'nvme' in targblock:
targblock = targblock[:-1]
shimpath = subprocess.check_output(['find', os.path.join(rootdir, 'boot/efi'), '-name', 'shimx64.efi']).decode('utf8').strip()
shimpath = shimpath.replace(rootdir, '/').replace('/boot/efi', '').replace('//', '/').replace('/', '\\')
subprocess.check_call(['efibootmgr', '-c', '-d', targblock, '-l', shimpath, '--part', partnum])
@@ -224,7 +236,8 @@ def install_to_disk(imgpath):
instdisk = diskin.read()
instdisk = '/dev/' + instdisk
parted = PartedRunner(instdisk)
dinfo = parted.run('unit s print')
# do this safer, unit s print might bomb
dinfo = parted.run('unit s print', check=False)
dinfo = dinfo.split('\n')
sectors = 0
sectorsize = 0
@@ -258,7 +271,7 @@ def install_to_disk(imgpath):
if end > sectors:
end = sectors
parted.run('mkpart primary {}s {}s'.format(curroffset, end))
vol['targetdisk'] = instdisk + '{0}'.format(volidx)
vol['targetdisk'] = get_partname(instdisk , volidx)
curroffset += size + 1
if not lvmvols:
if swapsize:
@@ -268,10 +281,10 @@ def install_to_disk(imgpath):
if end > sectors:
end = sectors
parted.run('mkpart swap {}s {}s'.format(curroffset, end))
subprocess.check_call(['mkswap', instdisk + '{}'.format(volidx + 1)])
subprocess.check_call(['mkswap', get_partname(instdisk, volidx + 1)])
else:
parted.run('mkpart lvm {}s 100%'.format(curroffset))
lvmpart = instdisk + '{}'.format(volidx + 1)
lvmpart = get_partname(instdisk, volidx + 1)
subprocess.check_call(['pvcreate', '-ff', '-y', lvmpart])
subprocess.check_call(['vgcreate', 'localstorage', lvmpart])
vginfo = subprocess.check_output(['vgdisplay', 'localstorage', '--units', 'b']).decode('utf8')
@@ -125,4 +125,6 @@ if grep installtodisk /proc/cmdline > /dev/null; then
fi
mv /lib/modules/$(uname -r) /lib/modules/$(uname -r)-ramfs
ln -s /sysroot/lib/modules/$(uname -r) /lib/modules/
mv /lib/firmware /lib/firmware-ramfs
ln -s /sysroot/lib/firmware /lib/firmware
exec /opt/confluent/bin/start_root
@@ -5,11 +5,37 @@
# noted below so custom commands are executed before
# the script notifies confluent that install is fully complete.
ntpsrvs=""
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg|awk '{print $2}')
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg|awk '{print $2}')
timedatectl set-timezone $(grep ^timezone: /etc/confluent/confluent.deploycfg|awk '{print $2}')
if grep ^ntpservers: /etc/confluent/confluent.deploycfg > /dev/null; then
for ntpsrv in $(sed -n '/^ntpservers:/,/^[^-]/p' /etc/confluent/confluent.deploycfg|sed 1d|sed '$d' | sed -e 's/^- //'); do
echo "server ${ntpsrv} iburst " >> /tmp/timeservers
done
fi
if [ -f /tmp/timeservers ]; then
ntpsrvs=$(cat /tmp/timeservers)
sed -i "1,/^pool * /c\\
${ntpsrvs//$'\n'/\\$'\n'}" /etc/chrony.conf
systemctl restart chronyd
rm -f /tmp/timeservers
fi
export nodename confluent_mgr confluent_profile
. /etc/confluent/functions
mkdir -p /var/log/confluent
@@ -1,4 +1,5 @@
#!/usr/bin/python
import time
import importlib
import tempfile
import json
@@ -223,6 +224,7 @@ def synchronize():
if status == 202:
lastrsp = ''
while status != 204:
time.sleep(2)
status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles')
if not isinstance(rsp, str):
rsp = rsp.decode('utf8')
@@ -7,41 +7,127 @@ if [ -f /tmp/dd_disk ]; then
fi
done
fi
mkdir -p /etc/confluent
cat /tls/*.pem > /etc/confluent/ca.pem
TRIES=0
echo -n > /etc/confluent/confluent.info
cd /sys/class/net
while ! awk -F'|' '{print $3}' /etc/confluent/confluent.info |grep 1 >& /dev/null && [ "$TRIES" -lt 60 ]; do
TRIES=$((TRIES + 1))
for currif in *; do
ip link set $currif up
done
/opt/confluent/bin/copernicus -t > /etc/confluent/confluent.info
done
cd /
grep ^EXTMGRINFO: /etc/confluent/confluent.info || return 0 # Do absolutely nothing if no data at all yet
echo -n "" > /tmp/confluent.initq
# restart cmdline
echo -n "" > /etc/cmdline.d/01-confluent.conf
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
#TODO: blkid --label <whatever> to find mounted api
shutdownnic=""
oum=$(umask)
python /opt/confluent/bin/apiclient /confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg
ifidx=$(cat /tmp/confluent.ifidx)
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
echo $ifname > /tmp/net.ifaces
umask 0077
mkdir -p /etc/confluent
echo -n > /etc/confluent/confluent.info
cat /tls/*.pem > /etc/confluent/ca.pem
TRIES=5
while [ ! -e /dev/disk ] && [ $TRIES -gt 0 ]; do
sleep 2
TRIES=$((TRIES - 1))
done
if [ -e /dev/disk/by-label/CNFLNT_IDNT ]; then
tmnt=/tmp/idntmnt
mkdir -p $tmnt
tcfg=/tmp/idnttmp
mount /dev/disk/by-label/CNFLNT_IDNT $tmnt
cd $tmnt
deploysrvs=$(sed -n '/^deploy_servers:/, /^[^-]/p' cnflnt.yml |grep ^-|sed -e 's/^- //'|grep -v :)
nodename=$(grep ^nodename: cnflnt.yml|awk '{print $2}')
ln -s /opt/confluent/bin/clortho /opt/confluent/bin/genpasshmac
hmackeyfile=/tmp/hmackeyfile
passfile=/etc/confluent/confluent.apikey
passcrypt=/tmp/passcrypt
hmacfile=/tmp/hmacfile
echo -n $(grep ^apitoken: cnflnt.yml|awk '{print $2}') > $hmackeyfile;
/opt/confluent/bin/genpasshmac $passfile $passcrypt $hmacfile $hmackeyfile
echo "NODENAME: "$nodename > /etc/confluent/confluent.info
for dsrv in $deploysrvs; do
echo 'MANAGER: '$dsrv >> /etc/confluent/confluent.info
done
sed -n '/^net_cfgs:/, /^[^- ]/{/^[^- ]/!p}' cnflnt.yml |sed -n '/^-/, /^-/{/^-/!p}'| sed -e 's/^[- ]*//'> $tcfg
autoconfigmethod=$(grep ^ipv4_method: $tcfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
for i in /sys/class/net/*; do
ip link set $(basename $i) down
udevadm info $i | grep ID_NET_DRIVER=cdc_ether > /dev/null && continue
ip link set $(basename $i) up
done
sleep 10
usedhcp=0
for NICGUESS in $(ip link|grep LOWER_UP|grep -v LOOPBACK| awk '{print $2}' | sed -e 's/:$//'); do
if [ "$autoconfigmethod" = "dhcp" ]; then
usedhcp=1
else
v4addr=$(grep ^ipv4_address: $tcfg)
v4addr=${v4addr#ipv4_address: }
v4plen=${v4addr#*/}
v4addr=${v4addr%/*}
v4gw=$(grep ^ipv4_gateway: $tcfg)
v4gw=${v4gw#ipv4_gateway: }
ip addr add dev $NICGUESS $v4addr/$v4plen
if [ "$v4gw" = "null" ]; then
v4gw=""
fi
if [ ! -z "$v4gw" ]; then
ip route add default via $v4gw
fi
v4nm=$(grep ipv4_netmask: $tcfg)
v4nm=${v4nm#ipv4_netmask: }
TESTSRV=$(python /opt/confluent/bin/apiclient -c 2> /dev/null)
if [ ! -z "$TESTSRV" ]; then
python /opt/confluent/bin/apiclient -p $hmacfile /confluent-api/self/registerapikey $passcrypt
mgr=$TESTSRV
ifname=$NICGUESS
shutdownnic=$ifname
break
fi
if [ ! -z "$v4gw" ]; then
ip route del default via $v4gw
fi
ip -4 addr flush dev $NICGUESS
fi
done
fi
TRIES=0
if [ "$usedhcp" = 1 ]; then
echo ip=$ifname:dhcp >> /etc/cmdline.d/01-confluent.conf
elif [ -z "$ifname" ]; then
cd /sys/class/net
while ! awk -F'|' '{print $3}' /etc/confluent/confluent.info |grep 1 >& /dev/null && [ "$TRIES" -lt 60 ]; do
TRIES=$((TRIES + 1))
for currif in *; do
ip link set $currif up
done
/opt/confluent/bin/copernicus -t > /etc/confluent/confluent.info
done
cd /
grep ^EXTMGRINFO: /etc/confluent/confluent.info || return 0 # Do absolutely nothing if no data at all yet
echo -n "" > /etc/cmdline.d/01-confluent.conf
else
echo ip=$v4addr::$v4gw:$v4nm:$hostname:$ifname:none > /etc/cmdline.d/01-confluent.conf
fi
python /opt/confluent/bin/apiclient /confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg
if [ ! -z "$shutdownnic" ]; then
if [ ! -z "$v4gw" ]; then
ip route del default via $v4gw
fi
ip -4 addr flush dev $shutdownnic
fi
# restart cmdline
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
echo -n "" > /tmp/confluent.initq
if [ -z "$ifname" ]; then
ifidx=$(cat /tmp/confluent.ifidx)
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
fi
if [ ! -z "$ifname" ]; then
echo $ifname > /tmp/net.ifaces
fi
dnsdomain=$(grep ^dnsdomain: /etc/confluent/confluent.deploycfg)
dnsdomain=${dnsdomain#dnsdomain: }
hostname=$nodename
if [ ! -z "$dnsdomain" ] && [ "$dnsdomain" != "null" ]; then
hostname=$hostname.$dnsdomain
fi
mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg)
mgr=${mgr#deploy_server: }
if [ -z "$mgr" ]; then
mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg)
mgr=${mgr#deploy_server: }
fi
profilename=$(grep ^profile: /etc/confluent/confluent.deploycfg)
profilename=${profilename#profile: }
proto=$(grep ^protocol: /etc/confluent/confluent.deploycfg)
@@ -65,21 +151,23 @@ kickstart=$proto://$mgr/confluent-public/os/$profilename/kickstart
root=anaconda-net:$proto://$mgr/confluent-public/os/$profilename/distribution
export kickstart
export root
autoconfigmethod=$(grep ipv4_method /etc/confluent/confluent.deploycfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
if [ "$autoconfigmethod" = "dhcp" ]; then
echo ip=$ifname:dhcp >> /etc/cmdline.d/01-confluent.conf
else
v4addr=$(grep ^ipv4_address: /etc/confluent/confluent.deploycfg)
v4addr=${v4addr#ipv4_address: }
v4gw=$(grep ^ipv4_gateway: /etc/confluent/confluent.deploycfg)
v4gw=${v4gw#ipv4_gateway: }
if [ "$v4gw" = "null" ]; then
v4gw=""
if [ -z "$autoconfigmethod" ]; then
autoconfigmethod=$(grep ipv4_method /etc/confluent/confluent.deploycfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
if [ "$autoconfigmethod" = "dhcp" ]; then
echo ip=$ifname:dhcp >> /etc/cmdline.d/01-confluent.conf
else
v4addr=$(grep ^ipv4_address: /etc/confluent/confluent.deploycfg)
v4addr=${v4addr#ipv4_address: }
v4gw=$(grep ^ipv4_gateway: /etc/confluent/confluent.deploycfg)
v4gw=${v4gw#ipv4_gateway: }
if [ "$v4gw" = "null" ]; then
v4gw=""
fi
v4nm=$(grep ipv4_netmask: /etc/confluent/confluent.deploycfg)
v4nm=${v4nm#ipv4_netmask: }
echo ip=$v4addr::$v4gw:$v4nm:$hostname:$ifname:none >> /etc/cmdline.d/01-confluent.conf
fi
v4nm=$(grep ipv4_netmask: /etc/confluent/confluent.deploycfg)
v4nm=${v4nm#ipv4_netmask: }
echo ip=$v4addr::$v4gw:$v4nm:$hostname:$ifname:none >> /etc/cmdline.d/01-confluent.conf
fi
nameserversec=0
while read -r entry; do
@@ -1,6 +1,10 @@
Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the
appropriate phase of the install process.
Alternatively, plays may be placed in /var/lib/confluent/private/os/<profilename>/ansible/<directory>.
This prevents public clients from being able to read the plays, which is not necessary for them to function,
and may protect them from divulging material contained in the plays or associated roles.
The 'hosts' may be omitted, and if included will be ignored, replaced with the host that is specifically
requesting the playbooks be executed.
@@ -1,6 +1,10 @@
Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the
appropriate phase of the install process.
Alternatively, plays may be placed in /var/lib/confluent/private/os/<profilename>/ansible/<directory>.
This prevents public clients from being able to read the plays, which is not necessary for them to function,
and may protect them from divulging material contained in the plays or associated roles.
The 'hosts' may be omitted, and if included will be ignored, replaced with the host that is specifically
requesting the playbooks be executed.
@@ -1,4 +1,6 @@
#!/bin/sh
HOME=$(getent passwd $(whoami)|cut -d: -f 6)
export HOME
# This script is executed on the first boot after install has
# completed. It is best to edit the middle of the file as
@@ -53,6 +53,7 @@ function set_confluent_vars() {
if [ -z "$confluent_profile" ]; then
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
export confluent_profile confluent_mgr nodename
}
fetch_remote() {
@@ -1,15 +1,19 @@
#!/usr/bin/python3
import subprocess
import os
class DiskInfo(object):
def __init__(self, devname):
if devname.startswith('nvme') and 'c' in devname:
raise Exception("Skipping multipath devname")
self.name = devname
self.wwn = None
self.path = None
self.model = ''
self.size = 0
self.driver = None
self.driver = ''
self.mdcontainer = ''
self.subsystype = ''
devnode = '/dev/{0}'.format(devname)
qprop = subprocess.check_output(
['udevadm', 'info', '--query=property', devnode])
@@ -44,7 +48,9 @@ class DiskInfo(object):
elif (k == 'DRIVERS' and not self.driver
and v not in ('"sd"', '""')):
self.driver = v.replace('"', '')
if not self.driver and 'imsm' not in self.mdcontainer:
elif k == 'ATTRS{subsystype}':
self.subsystype = v.replace('"', '')
if not self.driver and 'imsm' not in self.mdcontainer and self.subsystype != 'nvm':
raise Exception("No driver detected")
if os.path.exists('/sys/block/{0}/size'.format(self.name)):
with open('/sys/block/{0}/size'.format(self.name), 'r') as sizesrc:
@@ -5,6 +5,7 @@ import json
import os
import shutil
import pwd
import time
import grp
try:
from importlib.machinery import SourceFileLoader
@@ -223,6 +224,7 @@ def synchronize():
if status == 202:
lastrsp = ''
while status != 204:
time.sleep(2)
status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles')
if not isinstance(rsp, str):
rsp = rsp.decode('utf8')
@@ -155,7 +155,7 @@ fi
ready=0
while [ $ready = "0" ]; do
get_remote_apikey
if [[ $confluent_mgr == *:* ]]; then
if [[ $confluent_mgr == *:* ]] && [[ $confluent_mgr != "["* ]]; then
confluent_mgr="[$confluent_mgr]"
fi
tmperr=$(mktemp)
@@ -189,8 +189,15 @@ cat > /run/NetworkManager/system-connections/$ifname.nmconnection << EOC
EOC
echo id=${ifname} >> /run/NetworkManager/system-connections/$ifname.nmconnection
echo uuid=$(uuidgen) >> /run/NetworkManager/system-connections/$ifname.nmconnection
linktype=$(ip link show dev ${ifname}|grep link/|awk '{print $1}')
if [ "$linktype" = link/infiniband ]; then
linktype="infiniband"
else
linktype="ethernet"
fi
echo type=$linktype >> /run/NetworkManager/system-connections/$ifname.nmconnection
cat >> /run/NetworkManager/system-connections/$ifname.nmconnection << EOC
type=ethernet
autoconnect-retries=1
EOC
echo interface-name=$ifname >> /run/NetworkManager/system-connections/$ifname.nmconnection
@@ -199,9 +206,6 @@ multi-connect=1
permissions=
wait-device-timeout=60000
[ethernet]
mac-address-blacklist=
EOC
autoconfigmethod=$(grep ^ipv4_method: /etc/confluent/confluent.deploycfg |awk '{print $2}')
auto6configmethod=$(grep ^ipv6_method: /etc/confluent/confluent.deploycfg |awk '{print $2}')
@@ -320,7 +324,7 @@ fi
echo '[proxy]' >> /run/NetworkManager/system-connections/$ifname.nmconnection
chmod 600 /run/NetworkManager/system-connections/*.nmconnection
confluent_websrv=$confluent_mgr
if [[ $confluent_websrv == *:* ]]; then
if [[ $confluent_websrv == *:* ]] && [[ $confluent_websrv != "["* ]]; then
confluent_websrv="[$confluent_websrv]"
fi
echo -n "Initializing ssh..."
@@ -5,6 +5,8 @@
# noted below so custom commands are executed before
# the script notifies confluent that install is fully complete.
HOME=$(getent passwd $(whoami)|cut -d: -f 6)
export HOME
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg|awk '{print $2}')
@@ -53,6 +53,7 @@ function set_confluent_vars() {
if [ -z "$confluent_profile" ]; then
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
export confluent_profile confluent_mgr nodename
}
fetch_remote() {
@@ -1,15 +1,19 @@
#!/usr/bin/python3
import subprocess
import os
class DiskInfo(object):
def __init__(self, devname):
if devname.startswith('nvme') and 'c' in devname:
raise Exception("Skipping multipath devname")
self.name = devname
self.wwn = None
self.path = None
self.model = ''
self.size = 0
self.driver = None
self.driver = ''
self.mdcontainer = ''
self.subsystype = ''
devnode = '/dev/{0}'.format(devname)
qprop = subprocess.check_output(
['udevadm', 'info', '--query=property', devnode])
@@ -44,7 +48,9 @@ class DiskInfo(object):
elif (k == 'DRIVERS' and not self.driver
and v not in ('"sd"', '""')):
self.driver = v.replace('"', '')
if not self.driver and 'imsm' not in self.mdcontainer:
elif k == 'ATTRS{subsystype}':
self.subsystype = v.replace('"', '')
if not self.driver and 'imsm' not in self.mdcontainer and self.subsystype != 'nvm':
raise Exception("No driver detected")
if os.path.exists('/sys/block/{0}/size'.format(self.name)):
with open('/sys/block/{0}/size'.format(self.name), 'r') as sizesrc:
@@ -10,6 +10,15 @@ import stat
import struct
import sys
import subprocess
import traceback
bootuuid = None
def get_partname(devname, idx):
if devname[-1] in '0123456789':
return '{}p{}'.format(devname, idx)
else:
return '{}{}'.format(devname, idx)
def get_next_part_meta(img, imgsize):
if img.tell() == imgsize:
@@ -53,10 +62,13 @@ class PartedRunner():
def __init__(self, disk):
self.disk = disk
def run(self, command):
def run(self, command, check=True):
command = command.split()
command = ['parted', '-a', 'optimal', '-s', self.disk] + command
return subprocess.check_output(command).decode('utf8')
if check:
return subprocess.check_output(command).decode('utf8')
else:
return subprocess.run(command, stdout=subprocess.PIPE).stdout.decode('utf8')
def fixup(rootdir, vols):
devbymount = {}
@@ -125,9 +137,14 @@ def fixup(rootdir, vols):
sys.stdout.flush()
for metafs in ('proc', 'sys', 'dev'):
subprocess.check_call(['mount', '-o', 'bind', '/{}'.format(metafs), os.path.join(rootdir, metafs)])
with open(os.path.join(rootdir, 'etc/sysconfig/grub')) as defgrubin:
if os.path.exists(os.path.join(rootdir, 'etc/lvm/devices/system.devices')):
os.remove(os.path.join(rootdir, 'etc/lvm/devices/system.devices'))
grubsyscfg = os.path.join(rootdir, 'etc/sysconfig/grub')
if not os.path.exists(grubsyscfg):
grubsyscfg = os.path.join(rootdir, 'etc/default/grub')
with open(grubsyscfg) as defgrubin:
defgrub = defgrubin.read().split('\n')
with open(os.path.join(rootdir, 'etc/sysconfig/grub'), 'w') as defgrubout:
with open(grubsyscfg, 'w') as defgrubout:
for gline in defgrub:
gline = gline.split()
newline = []
@@ -136,8 +153,34 @@ def fixup(rootdir, vols):
continue
newline.append(ent)
defgrubout.write(' '.join(newline) + '\n')
grubcfg = subprocess.check_output(['find', os.path.join(rootdir, 'boot'), '-name', 'grub.cfg']).decode('utf8').strip().replace(rootdir, '/')
subprocess.check_call(['chroot', rootdir, 'grub2-mkconfig', '-o', grubcfg])
grubcfg = subprocess.check_output(['find', os.path.join(rootdir, 'boot'), '-name', 'grub.cfg']).decode('utf8').strip().replace(rootdir, '/').replace('//', '/')
grubcfg = grubcfg.split('\n')
if not grubcfg[-1]:
grubcfg = grubcfg[:-1]
if len(grubcfg) == 1:
grubcfg = grubcfg[0]
else:
for gcfg in grubcfg:
rgcfg = os.path.join(rootdir, gcfg[1:]) # gcfg has a leading / to get rid of
if os.stat(rgcfg).st_size > 256:
grubcfg = gcfg
else:
with open(rgcfg, 'r') as gin:
tgrubcfg = gin.read()
tgrubcfg = tgrubcfg.split('\n')
if 'search --no-floppy --fs-uuid --set=dev' in tgrubcfg[0]:
tgrubcfg[0] = 'search --no-floppy --fs-uuid --set=dev ' + bootuuid
with open(rgcfg, 'w') as gout:
for gcline in tgrubcfg:
gout.write(gcline)
gout.write('\n')
try:
subprocess.check_call(['chroot', rootdir, 'grub2-mkconfig', '-o', grubcfg])
except Exception as e:
print(repr(e))
print(rootdir)
print(grubcfg)
time.sleep(86400)
newroot = None
with open('/etc/shadow') as shadowin:
shents = shadowin.read().split('\n')
@@ -166,6 +209,8 @@ def fixup(rootdir, vols):
partnum = re.search('(\d+)$', targdev).group(1)
targblock = re.search('(.*)\d+$', targdev).group(1)
if targblock:
if 'nvme' in targblock and targblock[-1] == 'p':
targblock = targblock[:-1]
shimpath = subprocess.check_output(['find', os.path.join(rootdir, 'boot/efi'), '-name', 'shimx64.efi']).decode('utf8').strip()
shimpath = shimpath.replace(rootdir, '/').replace('/boot/efi', '').replace('//', '/').replace('/', '\\')
subprocess.check_call(['efibootmgr', '-c', '-d', targblock, '-l', shimpath, '--part', partnum])
@@ -184,6 +229,7 @@ def had_swap():
return False
def install_to_disk(imgpath):
global bootuuid
lvmvols = {}
deftotsize = 0
mintotsize = 0
@@ -224,7 +270,7 @@ def install_to_disk(imgpath):
instdisk = diskin.read()
instdisk = '/dev/' + instdisk
parted = PartedRunner(instdisk)
dinfo = parted.run('unit s print')
dinfo = parted.run('unit s print', check=False)
dinfo = dinfo.split('\n')
sectors = 0
sectorsize = 0
@@ -258,7 +304,7 @@ def install_to_disk(imgpath):
if end > sectors:
end = sectors
parted.run('mkpart primary {}s {}s'.format(curroffset, end))
vol['targetdisk'] = instdisk + '{0}'.format(volidx)
vol['targetdisk'] = get_partname(instdisk, volidx)
curroffset += size + 1
if not lvmvols:
if swapsize:
@@ -268,10 +314,10 @@ def install_to_disk(imgpath):
if end > sectors:
end = sectors
parted.run('mkpart swap {}s {}s'.format(curroffset, end))
subprocess.check_call(['mkswap', instdisk + '{}'.format(volidx + 1)])
subprocess.check_call(['mkswap', get_partname(instdisk, volidx + 1)])
else:
parted.run('mkpart lvm {}s 100%'.format(curroffset))
lvmpart = instdisk + '{}'.format(volidx + 1)
lvmpart = get_partname(instdisk, volidx + 1)
subprocess.check_call(['pvcreate', '-ff', '-y', lvmpart])
subprocess.check_call(['vgcreate', 'localstorage', lvmpart])
vginfo = subprocess.check_output(['vgdisplay', 'localstorage', '--units', 'b']).decode('utf8')
@@ -366,6 +412,14 @@ def install_to_disk(imgpath):
sys.stdout.write('\x1b[1K\rDone writing {0}'.format(vol['mount']))
sys.stdout.write('\n')
sys.stdout.flush()
if vol['mount'] == '/boot':
tbootuuid = subprocess.check_output(['blkid', vol['targetdisk']])
if b'UUID="' in tbootuuid:
bootuuid = tbootuuid.split(b'UUID="', 1)[1].split(b'"')[0].decode('utf8')
subprocess.check_call(['umount', '/run/imginst/targ'])
for vol in allvols:
subprocess.check_call(['mount', vol['targetdisk'], '/run/imginst/targ/' + vol['mount']])
@@ -373,4 +427,9 @@ def install_to_disk(imgpath):
if __name__ == '__main__':
install_to_disk(os.environ['mountsrc'])
try:
install_to_disk(os.environ['mountsrc'])
except Exception:
traceback.print_exc()
time.sleep(86400)
raise
@@ -1,6 +1,6 @@
. /lib/dracut-lib.sh
confluent_whost=$confluent_mgr
if [[ "$confluent_whost" == *:* ]]; then
if [[ "$confluent_whost" == *:* ]] && [[ "$confluent_whost" != "["* ]]; then
confluent_whost="[$confluent_mgr]"
fi
mkdir -p /mnt/remoteimg /mnt/remote /mnt/overlay
@@ -127,5 +127,7 @@ if grep installtodisk /proc/cmdline > /dev/null; then
fi
mv /lib/modules/$(uname -r) /lib/modules/$(uname -r)-ramfs
ln -s /sysroot/lib/modules/$(uname -r) /lib/modules/
mv /lib/firmware /lib/firmware-ramfs
ln -s /sysroot/lib/firmware /lib/firmware
kill $(grep -l ^/usr/lib/systemd/systemd-udevd /proc/*/cmdline|cut -d/ -f 3)
exec /opt/confluent/bin/start_root
@@ -31,6 +31,9 @@ if [ ! -f /sysroot/tmp/installdisk ]; then
fi
lvm vgchange -a n
udevadm control -e
if [ -f /sysroot/etc/lvm/devices/system.devices ]; then
rm /sysroot/etc/lvm/devices/system.devices
fi
chroot /sysroot /usr/lib/systemd/systemd-udevd --daemon
chroot /sysroot bash -c "source /etc/confluent/functions; run_remote_python image2disk.py"
echo "Port 22" >> /etc/ssh/sshd_config
@@ -5,6 +5,7 @@
# noted below so custom commands are executed before
# the script notifies confluent that install is fully complete.
ntpsrvs=""
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
v4meth=$(grep ^ipv4_method: /etc/confluent/confluent.deploycfg|awk '{print $2}')
@@ -16,6 +17,34 @@ if [ -z "$confluent_mgr" ]; then
fi
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg|awk '{print $2}')
timedatectl set-timezone $(grep ^timezone: /etc/confluent/confluent.deploycfg|awk '{print $2}')
hostnamectl set-hostname $nodename
if grep ^ntpservers: /etc/confluent/confluent.deploycfg > /dev/null; then
for ntpsrv in $(sed -n '/^ntpservers:/,/^[^-]/p' /etc/confluent/confluent.deploycfg|sed 1d|sed '$d' | sed -e 's/^- //'); do
echo "server ${ntpsrv} iburst " >> /tmp/timeservers
done
fi
if [ -f /tmp/timeservers ]; then
ntpsrvs=$(cat /tmp/timeservers)
sed -i "1,/^pool * /c\\
${ntpsrvs//$'\n'/\\$'\n'}" /etc/chrony.conf
systemctl restart chronyd
rm -f /tmp/timeservers
fi
export nodename confluent_mgr confluent_profile
. /etc/confluent/functions
mkdir -p /var/log/confluent
@@ -1,4 +1,6 @@
#!/usr/bin/python3
import random
import time
import subprocess
import importlib
import tempfile
@@ -7,6 +9,7 @@ import os
import shutil
import pwd
import grp
import sys
from importlib.machinery import SourceFileLoader
try:
apiclient = SourceFileLoader('apiclient', '/opt/confluent/bin/apiclient').load_module()
@@ -227,9 +230,16 @@ def synchronize():
myips.append(addr)
data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir, 'myips': myips})
status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data)
if status >= 300:
sys.stderr.write("Error starting syncfiles - {}:\n".format(status))
sys.stderr.write(rsp.decode('utf8'))
sys.stderr.write('\n')
sys.stderr.flush()
return status
if status == 202:
lastrsp = ''
while status != 204:
time.sleep(1+(2*random.random()))
status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles')
if not isinstance(rsp, str):
rsp = rsp.decode('utf8')
@@ -277,10 +287,21 @@ def synchronize():
os.chmod(fname, int(opts[fname][opt], 8))
if uid != -1 or gid != -1:
os.chown(fname, uid, gid)
return status
finally:
shutil.rmtree(tmpdir)
shutil.rmtree(appendoncedir)
if __name__ == '__main__':
synchronize()
status = 202
while status not in (204, 200):
try:
status = synchronize()
except Exception as e:
sys.stderr.write(str(e))
sys.stderr.write('\n')
sys.stderr.flush()
status = 300
if status not in (204, 200):
time.sleep((random.random()*3)+2)
@@ -1,14 +1,20 @@
#!/bin/bash
echo -n "" >> /tmp/net.ifaces
echo -n "" > /tmp/01-autocons.devnode
cat /tls/*.0 >> /etc/pki/tls/certs/ca-bundle.crt
BUNDLENAME=/etc/pki/tls/certs/ca-bundle.crt
if [ ! -e "$BUNDLENAME" ]; then
BUNDLENAME=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
mkdir -p /etc/pki/tls/certs
ln -s $BUNDLENAME /etc/pki/tls/certs/ca-bundle.crt
fi
cat /tls/*.0 >> $BUNDLENAME
if ! grep console= /proc/cmdline >& /dev/null; then
autocons=$(/opt/confluent/bin/autocons)
if [ -n "$autocons" ]; then
echo console=$autocons |sed -e 's!/dev/!!' >> /tmp/01-autocons.conf
autocons=${autocons%,*}
echo $autocons > /tmp/01-autocons.devnode
echo "Detected firmware specified console at $(cat /tmp/01-autocons.conf)" > $autocons
echo $autocons > /tmp/01-autocons.devnode
echo "Detected firmware specified console at $(cat /tmp/01-autocons.conf)" > $autocons
echo "Initializing auto detected console when installer starts" > $autocons
fi
fi
@@ -16,4 +22,5 @@ if grep console=ttyS /proc/cmdline >& /dev/null; then
echo "Serial console has been requested in the kernel arguments, the local video may not show progress" > /dev/tty1
fi
. /lib/anaconda-lib.sh
echo rd.fcoe=0 > /etc/cmdline.d/nofcoe.conf
wait_for_kickstart
@@ -1,5 +1,8 @@
#!/bin/bash
BUNDLENAME=/sysroot/etc/pki/tls/certs/ca-bundle.crt
if [ ! -e "$BUNDLENAME" ]; then
BUNDLENAME=/sysroot/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
fi
while [ -h $BUNDLENAME ]; do
BUNDLENAME=/sysroot/$(readlink $BUNDLENAME)
done
@@ -1,6 +1,16 @@
#!/bin/sh
[ -e /tmp/confluent.initq ] && return 0
. /lib/dracut-lib.sh
setsid sh -c 'exec bash <> /dev/tty2 >&0 2>&1' &
if [ -f /tmp/dd_disk ]; then
for dd in $(cat /tmp/dd_disk); do
if [ -e $dd ]; then
driver-updates --disk $dd $dd
rm $dd
fi
done
rm /tmp/dd_disk
fi
udevadm trigger
udevadm trigger --type=devices --action=add
udevadm settle
@@ -19,13 +29,6 @@ function confluentpython() {
/usr/bin/python2 $*
fi
}
if [ -f /tmp/dd_disk ]; then
for dd in $(cat /tmp/dd_disk); do
if [ -e $dd ]; then
driver-updates --disk $dd $dd
fi
done
fi
vlaninfo=$(getarg vlan)
if [ ! -z "$vlaninfo" ]; then
vldev=${vlaninfo#*:}
@@ -40,7 +43,7 @@ mkdir -p /etc/confluent
echo -n > /etc/confluent/confluent.info
umask $oum
TRIES=5
while [ ! -e /dev/disk ] && [ $TRIES -gt 0 ]; do
while [ ! -e /dev/disk/by-label ] && [ $TRIES -gt 0 ]; do
sleep 2
TRIES=$((TRIES - 1))
done
@@ -55,21 +58,58 @@ if [ -e /dev/disk/by-label/CNFLNT_IDNT ]; then
sed -n '/^net_cfgs:/, /^[^- ]/{/^[^- ]/!p}' cnflnt.yml |sed -n '/^-/, /^-/{/^-/!p}'| sed -e 's/^[- ]*//'> $tcfg
autoconfigmethod=$(grep ^ipv4_method: $tcfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
if [ "$autoconfigmethod" = "dhcp" ]; then
/usr/libexec/nm-initrd-generator ip=:dhcp
else
v4addr=$(grep ^ipv4_address: $tcfg)
v4addr=${v4addr#ipv4_address: }
v4addr=${v4addr%/*}
v4gw=$(grep ^ipv4_gateway: $tcfg)
v4gw=${v4gw#ipv4_gateway: }
if [ "$v4gw" = "null" ]; then
v4gw=""
fi
v4nm=$(grep ipv4_netmask: $tcfg)
v4nm=${v4nm#ipv4_netmask: }
/usr/libexec/nm-initrd-generator ip=$v4addr::$v4gw:$v4nm:$hostname::none
fi
for i in /sys/class/net/*; do
ip link set $(basename $i) down
udevadm info $i | grep ID_NET_DRIVER=cdc_ether > /dev/null && continue
ip link set $(basename $i) up
done
TRIES=30
DETECTED=0
while [ "$DETECTED" = 0 ] && [ $TRIES -gt 0 ]; do
TRIES=$((TRIES - 1))
for NICGUESS in $(ip link|grep LOWER_UP|grep -v LOOPBACK| awk '{print $2}' | sed -e 's/:$//'); do
if [ "$autoconfigmethod" = "dhcp" ]; then
/usr/libexec/nm-initrd-generator ip=$NICGUESS:dhcp
else
v4addr=$(grep ^ipv4_address: $tcfg)
v4addr=${v4addr#ipv4_address: }
v4plen=${v4addr#*/}
v4addr=${v4addr%/*}
v4gw=$(grep ^ipv4_gateway: $tcfg)
v4gw=${v4gw#ipv4_gateway: }
ip addr add dev $NICGUESS $v4addr/$v4plen
if [ "$v4gw" = "null" ]; then
v4gw=""
fi
if [ ! -z "$v4gw" ]; then
ip route add default via $v4gw
fi
v4nm=$(grep ipv4_netmask: $tcfg)
v4nm=${v4nm#ipv4_netmask: }
DETECTED=0
for dsrv in $deploysrvs; do
if curl --capath /tls/ -s --connect-timeout 3 https://$dsrv/confluent-public/ > /dev/null; then
rm /run/NetworkManager/system-connections/*
/usr/libexec/nm-initrd-generator ip=$v4addr::$v4gw:$v4nm:$hostname:$NICGUESS:none
DETECTED=1
ifname=$NICGUESS
break
fi
done
if [ ! -z "$v4gw" ]; then
ip route del default via $v4gw
fi
ip addr flush dev $NICGUESS
if [ $DETECTED = 1 ]; then
break
fi
fi
done
done
for NICGUESS in $(ip link|grep LOWER_UP|grep -v LOOPBACK| awk '{print $2}' | sed -e 's/:$//'); do
ip addr flush dev $NICGUESS
ip link set $NICGUESS down
done
NetworkManager --configure-and-quit=initrd --no-daemon
hmackeyfile=/tmp/cnflnthmackeytmp
echo -n $(grep ^apitoken: cnflnt.yml|awk '{print $2}') > $hmackeyfile
@@ -85,10 +125,10 @@ if [ -e /dev/disk/by-label/CNFLNT_IDNT ]; then
echo 'MANAGER: '$deploysrv >> /etc/confluent/confluent.info
done
for deployer in $deploysrvs; do
if curl -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_CRYPTHMAC: $(cat $hmacfile)" -d@$passcrypt -k https://$deployer/confluent-api/self/registerapikey; then
if curl --capath /tls/ -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_CRYPTHMAC: $(cat $hmacfile)" -d@$passcrypt -k https://$deployer/confluent-api/self/registerapikey; then
cp $passfile /etc/confluent/confluent.apikey
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
curl -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$deployer/confluent-api/self/deploycfg2 > /etc/confluent/confluent.deploycfg
curl --capath /tls/ -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$deployer/confluent-api/self/deploycfg2 > /etc/confluent/confluent.deploycfg
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg)
confluent_profile=${confluent_profile#profile: }
mgr=$deployer
@@ -114,7 +154,7 @@ if ! grep MANAGER: /etc/confluent/confluent.info; then
for mac in $(ip -br link|grep -v LOOPBACK|awk '{print $3}'); do
myids=$myids"/mac="$mac
done
myname=$(curl -sH "CONFLUENT_IDS: $myids" https://$confluenthttpsrv/confluent-api/self/whoami)
myname=$(curl --capath /tls/ -sH "CONFLUENT_IDS: $myids" https://$confluenthttpsrv/confluent-api/self/whoami)
if [ ! -z "$myname" ]; then
echo NODENAME: $myname > /etc/confluent/confluent.info
echo MANAGER: $confluentsrv >> /etc/confluent/confluent.info
@@ -146,17 +186,19 @@ if [ ! -z "$autocons" ]; then
errout="-e $autocons"
fi
while ! confluentpython /opt/confluent/bin/apiclient $errout /confluent-api/self/deploycfg2 > /etc/confluent/confluent.deploycfg; do
sleep 10
sleep 10
done
ifidx=$(cat /tmp/confluent.ifidx 2> /dev/null)
if [ ! -z "$ifidx" ]; then
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
ifname=${ifname%@*}
echo $ifname > /tmp/net.ifaces
else
ip -br a|grep UP|awk '{print $1}' > /tmp/net.ifaces
ifname=$(cat /tmp/net.ifaces)
if [ -z "$ifname" ]; then
if [ ! -z "$ifidx" ]; then
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
ifname=${ifname%@*}
echo $ifname > /tmp/net.ifaces
else
ip -br a|grep UP|awk '{print $1}' > /tmp/net.ifaces
ifname=$(cat /tmp/net.ifaces)
fi
fi
dnsdomain=$(grep ^dnsdomain: /etc/confluent/confluent.deploycfg)
@@ -185,23 +227,38 @@ proto=${proto#protocol: }
textconsole=$(grep ^textconsole: /etc/confluent/confluent.deploycfg)
textconsole=${textconsole#textconsole: }
if [ "$textconsole" = "true" ] && ! grep console= /proc/cmdline > /dev/null; then
autocons=$(cat /tmp/01-autocons.devnode)
if [ ! -z "$autocons" ]; then
echo Auto-configuring installed system to use text console
echo Auto-configuring installed system to use text console > $autocons
autocons=$(cat /tmp/01-autocons.devnode)
if [ ! -z "$autocons" ]; then
echo Auto-configuring installed system to use text console
echo Auto-configuring installed system to use text console > $autocons
/opt/confluent/bin/autocons -c > /dev/null
cp /tmp/01-autocons.conf /etc/cmdline.d/
else
echo "Unable to automatically detect requested text console"
fi
cp /tmp/01-autocons.conf /etc/cmdline.d/
else
echo "Unable to automatically detect requested text console"
fi
fi
echo inst.repo=$proto://$mgr/confluent-public/os/$profilename/distribution >> /etc/cmdline.d/01-confluent.conf
. /etc/os-release
if [ "$ID" = "dracut" ]; then
ID=$(echo $PRETTY_NAME|awk '{print $1}')
VERSION_ID=$(echo $VERSION|awk '{print $1}')
if [ "$ID" = "Oracle" ]; then
ID=OL
elif [ "$ID" = "Red" ]; then
ID=RHEL
fi
fi
ISOSRC=$(blkid -t TYPE=iso9660|grep -Ei ' LABEL="'$ID-$VERSION_ID|sed -e s/:.*//)
if [ -z "$ISOSRC" ]; then
echo inst.repo=$proto://$mgr/confluent-public/os/$profilename/distribution >> /etc/cmdline.d/01-confluent.conf
root=anaconda-net:$proto://$mgr/confluent-public/os/$profilename/distribution
export root
else
echo inst.repo=cdrom:$ISOSRC >> /etc/cmdline.d/01-confluent.conf
fi
echo inst.ks=$proto://$mgr/confluent-public/os/$profilename/kickstart >> /etc/cmdline.d/01-confluent.conf
kickstart=$proto://$mgr/confluent-public/os/$profilename/kickstart
root=anaconda-net:$proto://$mgr/confluent-public/os/$profilename/distribution
export kickstart
export root
autoconfigmethod=$(grep ipv4_method /etc/confluent/confluent.deploycfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
if [ "$autoconfigmethod" = "dhcp" ]; then
@@ -281,4 +338,8 @@ if [ -e /lib/nm-lib.sh ]; then
fi
fi
fi
for NICGUESS in $(ip link|grep LOWER_UP|grep -v LOOPBACK| awk '{print $2}' | sed -e 's/:$//'); do
ip addr flush dev $NICGUESS
ip link set $NICGUESS down
done
@@ -1,6 +1,10 @@
Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the
appropriate phase of the install process.
Alternatively, plays may be placed in /var/lib/confluent/private/os/<profilename>/ansible/<directory>.
This prevents public clients from being able to read the plays, which is not necessary for them to function,
and may protect them from divulging material contained in the plays or associated roles.
The 'hosts' may be omitted, and if included will be ignored, replaced with the host that is specifically
requesting the playbooks be executed.
@@ -1,6 +1,10 @@
Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the
appropriate phase of the install process.
Alternatively, plays may be placed in /var/lib/confluent/private/os/<profilename>/ansible/<directory>.
This prevents public clients from being able to read the plays, which is not necessary for them to function,
and may protect them from divulging material contained in the plays or associated roles.
The 'hosts' may be omitted, and if included will be ignored, replaced with the host that is specifically
requesting the playbooks be executed.
@@ -1,5 +1,8 @@
#!/bin/sh
sed -i 's/centos/CentOS/; s/rhel/Red Hat Enterprise Linux/; s/oraclelinux/Oracle Linux/; s/alma/AlmaLinux/' $2/profile.yaml
sed -i 's/centos/CentOS/; s/rhel/Red Hat Enterprise Linux/; s/oraclelinux/Oracle Linux/; s/alma/AlmaLinux/;s/fedora/Fedora Linux/' $2/profile.yaml
if grep Fedora $2/profile.yaml > /dev/null; then
sed -i 's/@^minimal-environment/#/' $2/packagelist
fi
ln -s $1/images/pxeboot/vmlinuz $2/boot/kernel && \
ln -s $1/images/pxeboot/initrd.img $2/boot/initramfs/distribution
mkdir -p $2/boot/efi/boot
@@ -33,15 +33,7 @@
reboot
%packages
@^minimal-environment
#-kernel-uek # This can opt out of the UEK for the relevant distribution
bind-utils
chrony
pciutils
python3
rsync
tar
-iwl*-firmware
%include /tmp/pkglist
%include /tmp/addonpackages
%include /tmp/cryptpkglist
%end
@@ -0,0 +1,9 @@
@^minimal-environment
#-kernel-uek # This can opt out of the UEK for the relevant distribution
bind-utils
chrony
pciutils
python3
rsync
tar
-iwl*-firmware
@@ -0,0 +1,4 @@
clearpart --all --initlabel
ignoredisk --only-use %%INSTALLDISK%%
autopart --nohome %%LUKSHOOK%%
@@ -6,6 +6,7 @@ except ImportError:
import importlib.util
import importlib.machinery
import sys
import glob
modloader = importlib.machinery.SourceFileLoader('apiclient', '/opt/confluent/bin/apiclient')
modspec = importlib.util.spec_from_file_location('apiclient', '/opt/confluent/bin/apiclient', loader=modloader)
apiclient = importlib.util.module_from_spec(modspec)
@@ -27,7 +28,7 @@ with open('/etc/confluent/confluent.deploycfg') as dplcfgfile:
_, profile = line.split(' ', 1)
if line.startswith('ipv4_method: '):
_, v4cfg = line.split(' ', 1)
if v4cfg == 'static' or v4cfg =='dhcp':
if v4cfg == 'static' or v4cfg =='dhcp' or not server6:
server = server4
if not server:
server = '[{}]'.format(server6)
@@ -41,6 +42,7 @@ try:
except AttributeError:
f = cStringIO.StringIO(cfgdata)
c.readfp(f)
gpgkeys = glob.glob('/etc/pki/rpm-gpg/RPM-GPG-KEY-*')
for sec in c.sections():
if sec.startswith('variant-'):
try:
@@ -56,3 +58,6 @@ for sec in c.sections():
repopath = repopath[1:]
repout.write('baseurl=https://{}/confluent-public/os/{}/distribution/{}\n'.format(server, profile, repopath))
repout.write('enabled=1\n')
if gpgkeys:
gpgkeyvals = ['file://{}'.format(x) for x in gpgkeys]
repout.write('gpgkey=' + ' '.join(gpgkeyvals) + '\n')
@@ -1,4 +1,6 @@
#!/bin/sh
HOME=$(getent passwd $(whoami)|cut -d: -f 6)
export HOME
# This script is executed on the first boot after install has
# completed. It is best to edit the middle of the file as
@@ -53,6 +53,7 @@ function set_confluent_vars() {
if [ -z "$confluent_profile" ]; then
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
export confluent_profile confluent_mgr nodename
}
fetch_remote() {
@@ -1,15 +1,19 @@
#!/usr/bin/python3
import subprocess
import os
class DiskInfo(object):
def __init__(self, devname):
if devname.startswith('nvme') and 'c' in devname:
raise Exception("Skipping multipath devname")
self.name = devname
self.wwn = None
self.path = None
self.model = ''
self.size = 0
self.driver = None
self.driver = ''
self.mdcontainer = ''
self.subsystype = ''
devnode = '/dev/{0}'.format(devname)
qprop = subprocess.check_output(
['udevadm', 'info', '--query=property', devnode])
@@ -44,7 +48,9 @@ class DiskInfo(object):
elif (k == 'DRIVERS' and not self.driver
and v not in ('"sd"', '""')):
self.driver = v.replace('"', '')
if not self.driver and 'imsm' not in self.mdcontainer:
elif k == 'ATTRS{subsystype}':
self.subsystype = v.replace('"', '')
if not self.driver and 'imsm' not in self.mdcontainer and self.subsystype != 'nvm':
raise Exception("No driver detected")
if os.path.exists('/sys/block/{0}/size'.format(self.name)):
with open('/sys/block/{0}/size'.format(self.name), 'r') as sizesrc:
@@ -34,6 +34,11 @@ run_remote_python add_local_repositories
# run_remote_python will use the appropriate python interpreter path to run the specified script
# A post.custom is provided to more conveniently hold customizations, see the post.custom file.
# This will do some serial console fixup for bad grub configuration when serial is firmware
# managed. See script for details
run_remote_python autoconsole
# This will induce server side processing of the syncfile contents if
# present
run_remote_python syncfileclient
@@ -87,10 +87,17 @@ done
cryptboot=$(grep ^encryptboot: /etc/confluent/confluent.deploycfg | awk '{print $2}')
LUKSPARTY=''
touch /tmp/cryptpkglist
touch /tmp/pkglist
touch /tmp/addonpackages
if [ "$cryptboot" == "tpm2" ]; then
LUKSPARTY="--encrypted --passphrase=$(cat /etc/confluent/confluent.apikey)"
echo $cryptboot >> /tmp/cryptboot
lukspass=$(python3 /opt/confluent/bin/apiclient /confluent-api/self/profileprivate/pending/luks.key 2> /dev/null)
if [ -z "$lukspass" ]; then
lukspass=$(python3 -c 'import os;import base64;print(base64.b64encode(os.urandom(66)).decode())')
fi
echo $lukspass > /etc/confluent/luks.key
chmod 000 /etc/confluent/luks.key
LUKSPARTY="--encrypted --passphrase=$lukspass"
echo $cryptboot >> /tmp/cryptboot
echo clevis-dracut >> /tmp/cryptpkglist
fi
@@ -102,16 +109,19 @@ confluentpython /opt/confluent/bin/apiclient /confluent-public/os/$confluent_pro
run_remote pre.custom
run_remote_parts pre.d
confluentpython /etc/confluent/apiclient /confluent-public/os/$confluent_profile/kickstart -o /tmp/kickstart.base
if grep '^%include /tmp/pkglist' /tmp/kickstart.* > /dev/null; then
confluentpython /etc/confluent/apiclient /confluent-public/os/$confluent_profile/packagelist -o /tmp/pkglist
fi
grep '^%include /tmp/partitioning' /tmp/kickstart.* > /dev/null || touch /tmp/installdisk
if [ ! -e /tmp/installdisk ]; then
run_remote_python getinstalldisk
fi
confluentpython /etc/confluent/apiclient /confluent-public/os/$confluent_profile/partitioning -o /tmp/partitioning.template
grep '^%include /tmp/partitioning' /tmp/kickstart.* > /dev/null || rm /tmp/installdisk
if [ -e /tmp/installdisk -a ! -e /tmp/partitioning ]; then
echo clearpart --all --initlabel >> /tmp/partitioning
echo ignoredisk --only-use $(cat /tmp/installdisk) >> /tmp/partitioning
echo autopart --nohome $LUKSPARTY >> /tmp/partitioning
dd if=/dev/zero of=/dev/$(cat /tmp/installdisk) bs=1M count=1 >& /dev/null
INSTALLDISK=$(cat /tmp/installdisk)
sed -e s/%%INSTALLDISK%%/$INSTALLDISK/ -e "s!%%LUKSHOOK%%!$LUKSPARTY!" /tmp/partitioning.template > /tmp/partitioning
vgchange -a n >& /dev/null
wipefs -a -f /dev/$INSTALLDISK >& /dev/null
fi
kill $logshowpid
@@ -1,8 +1,12 @@
#!/bin/sh
grep HostCert /etc/ssh/sshd_config.anaconda >> /mnt/sysimage/etc/ssh/sshd_config
echo HostbasedAuthentication yes >> /mnt/sysimage/etc/ssh/sshd_config
echo HostbasedUsesNameFromPacketOnly yes >> /mnt/sysimage/etc/ssh/sshd_config
echo IgnoreRhosts no >> /mnt/sysimage/etc/ssh/sshd_config
targssh=/mnt/sysimage/etc/ssh/sshd_config
if [ -d /mnt/sysimage/etc/ssh/sshd_config.d/ ]; then
targssh=/mnt/sysimage/etc/ssh/sshd_config.d/90-confluent.conf
fi
grep HostCert /etc/ssh/sshd_config.anaconda >> $targssh
echo HostbasedAuthentication yes >> $targssh
echo HostbasedUsesNameFromPacketOnly yes >> $targssh
echo IgnoreRhosts no >> $targssh
sshconf=/mnt/sysimage/etc/ssh/ssh_config
if [ -d /mnt/sysimage/etc/ssh/ssh_config.d/ ]; then
sshconf=/mnt/sysimage/etc/ssh/ssh_config.d/01-confluent.conf

Some files were not shown because too many files have changed in this diff Show More