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

Compare commits

..

1050 Commits

Author SHA1 Message Date
Jarrod Johnson a8132d87a7 Blacklist the tianocore default uuid
If a platform doesn't have a uuid, Tiano hardbakes
yet another invalid uuid to ignore.
2021-12-17 09:13:49 -05:00
Jarrod Johnson 65d6ff13fa Ignore and warn on bad gateway
If user specifies a bad gateway,
spare the firmware from seeing
it and log that the gateway is a problem.
2021-12-17 08:44:46 -05:00
Jarrod Johnson 9b178c0653 Provide nicer error message on existing name
Packing ontop of an existing profile is not presently supported,
provide a clearer indication of this.
2021-12-15 13:26:32 -05:00
Jarrod Johnson 016ee3ecb0 Fall back if timedatectl doesn't work 2021-12-15 12:34:28 -05:00
Jarrod Johnson 48ea6225aa Remove stderr from subprocess error
it is not a supported keyword
2021-12-15 12:28:09 -05:00
Jarrod Johnson c88f34d1e1 Merge tag '3.2.3'
Provide more reasonable hostname on install
2021-12-14 11:27:25 -05:00
Jarrod Johnson e488560090 Induce probe by randomized port
Replying to SLP caused some SLP
software to have a bug.

Since we aren't looking for a reply,
instead just throw a byte randomly at a high numbered
port.
2021-12-14 07:49:09 -05:00
Jarrod Johnson faa20660ed Assure confluent myname file is owned correctly
A lot of osdeploy initialize (which runs as root)
may induce creation of 'myname' file.  Fix by
becoming confluent user, if applicable.
2021-12-14 07:24:47 -05:00
Jarrod Johnson ee950ca8a2 Skip directories in initramfs symlink
If part of a debug effort leaves stray directories,
ignore them as they can't possibly be initramfs content.
2021-12-13 15:43:12 -05:00
Jarrod Johnson 743f984b3d Fix raw integer value support 2021-12-09 14:08:24 -05:00
Jarrod Johnson ad33572290 Add debug information to coreos init 2021-12-09 11:55:12 -05:00
Jarrod Johnson 773be640f8 Fix for long hostname on CA node 2021-12-09 11:19:16 -05:00
Jarrod Johnson 624984b1c9 Do not assume SPCR until confluent confirms text console
TIOCCONS was called for users that did not want to use serial.  This
makes the serial console delayeed when automatic, but avoids video
users from being confused.
2021-12-09 10:34:12 -05:00
Jarrod Johnson c2de127947 Bring el8 completely over to prefer ipv4 2021-12-09 08:31:07 -05:00
Jarrod Johnson cf686f8018 Prefer IPv4 deployment over IPv6 when both are available
Some older vintages of RHEL and clones do not support IPv4,
best to prefer ipv4 to avoid messing up on places that have ipv6
configured.
2021-12-08 17:04:04 -05:00
Jarrod Johnson d258a2ae0d Fix py2 compatibility of util 2021-12-08 12:12:39 -05:00
Jarrod Johnson 68bfb950f3 Correect which subprocess module is used by util 2021-12-08 11:26:08 -05:00
Jarrod Johnson 343e5eabe5 Utility function for running commands
Given the python2/3 differences, good to have a single run
that returns stdout and stderr.

This should trigger the same behavior as timeout did, but
in a manner consistent between 2 and 3.
2021-12-08 10:20:34 -05:00
Jarrod Johnson 02da50af8b Tighter permissions on /var/log/confluent 2021-12-08 07:42:19 -05:00
Jarrod Johnson 77de3ab25b Apply more restrictive permissions to /var/log/confluent/
While confluent shouldn't put anything sensitive in the log, custom
content may. To mitigate the risk, it will now lock down the
log permissions.
2021-12-07 07:21:04 -05:00
Jarrod Johnson dcca844e9b Refresh eventlet resolver on resolv.conf change
Eventlet holds on to stale resolv.conf. As a workaround,
monitor resolv.conf and explicitly reinitialize greendns
resolver.
2021-12-06 12:22:42 -05:00
Jarrod Johnson 1b21b9316c Correct variable typo in imageboot scripts 2021-12-06 09:00:44 -05:00
Jarrod Johnson 4260db20b7 Make confluent contennt from initramfs avalibale to normal root system 2021-12-03 16:06:47 -05:00
Jarrod Johnson 496be816ff Add exit 0 to avoid failed systemd unit 2021-12-03 12:50:03 -05:00
Jarrod Johnson 4e0a76d955 Fix typo in confluent name in coreos script 2021-12-03 12:47:05 -05:00
Jarrod Johnson f2b2d8519c Add onboot link to coreos relabel activity 2021-12-03 12:45:42 -05:00
Jarrod Johnson d829db4407 Add onboot hook to coreos 2021-12-03 12:37:03 -05:00
Jarrod Johnson 0e1da6ebd6 Explicitly check for TPM 2.0 before trying to use TPM 2.0 2021-12-03 11:05:11 -05:00
Jarrod Johnson d2435d315b Schedule fetch of private data before ignition cares 2021-12-03 10:39:47 -05:00
Jarrod Johnson 4388399f78 Fetch config.ign file during rootfs setup in CoreOS 2021-12-03 09:34:46 -05:00
Jarrod Johnson a146a54172 Move ignition to profile private data, extracted 2021-12-03 08:48:27 -05:00
Jarrod Johnson 4482b675b4 Wait for network to get ssh certificates 2021-12-03 08:32:25 -05:00
Jarrod Johnson 2b8c8e9af9 Add support for specifying login name in nodeshell 2021-12-03 08:03:09 -05:00
Jarrod Johnson 714a883d9c Purge the conflucting default nmconnection if we have better 2021-12-02 17:00:10 -05:00
Jarrod Johnson 77865ba71c Disable fakecmdline for now 2021-12-02 16:40:41 -05:00
Jarrod Johnson 3adb82370f Specify correct filename for fakecmdline 2021-12-02 16:27:55 -05:00
Jarrod Johnson 7a95c3e64c Set selinux context of fakecmdline 2021-12-02 16:17:04 -05:00
Jarrod Johnson e3d5a058d6 Change nodestorage to interactive and alias it to be interactive by default 2021-12-02 14:52:16 -05:00
Jarrod Johnson 25b68665e0 Provide a bit more elaboration on some attribute descriptions. 2021-12-02 11:42:32 -05:00
Jarrod Johnson 42f766d5f4 Fix osdeploy initialize when only ssh or tls is done
ssh is technically opt-in, though strongly recommended, so
osdeploy should cope with that.

TLS is pretty much required, but perhaps not done immediately,
so it gets similar treatmennt.
2021-12-02 11:38:18 -05:00
Jarrod Johnson 0092915cab Fix rerunning tls initialization 2021-12-02 10:19:47 -05:00
Jarrod Johnson 8ecbcb0f00 Fix coreos tendency to disable ipv6 2021-12-01 16:26:13 -05:00
Jarrod Johnson e5a748f0a2 Fix coreos pre-pivot to work better 2021-12-01 16:00:36 -05:00
Jarrod Johnson 7f476d64b5 Update style of nodesetboot usage message 2021-12-01 15:33:21 -05:00
Jarrod Johnson 90f3d5f323 Fix syntax error in coreos pre-pivot 2021-11-30 09:14:51 -05:00
Jarrod Johnson 00e853130f Fallback to other location for grub 2021-11-29 16:03:06 -05:00
Jarrod Johnson a4b1f1d30a Fix typo in fedora coreos signature 2021-11-29 15:54:38 -05:00
Jarrod Johnson 5718e07238 Treat empty attributes as unset
This fixes behavior when, for example, crypted.rootpassword
is explicitly blanked
2021-11-29 11:22:48 -05:00
Jarrod Johnson d049934626 Add a breadcrum to distinfo.yaml to indicate where an image came from 2021-11-29 09:55:38 -05:00
Jarrod Johnson 425f5276b3 Merge pull request #82 from PenghuiCui/master
Support getting message extention in plugin
2021-11-29 07:17:36 -05:00
Penghui Cui 079a04b28b Support getting message extention in plugin 2021-11-25 10:01:35 +08:00
Jarrod Johnson 2e10289807 Invoke mkinitrd after zypper runs 2021-11-22 10:46:23 -05:00
Jarrod Johnson e1c15cca8e Switch to secureboot signed grub for ubuntu
It was pulling an efi binary incompatible with secureboot before.
2021-11-19 11:34:06 -05:00
Jarrod Johnson 6e4c939cd9 Various ubuntu diskless fixes/improvements
Needed the real losetup to handle read-only file.

busybox wc is way too slow, use ls instead.

Explicitly make /sysroot and load xfs, as that doesn't happen implicitly.

Accept a dangling symlink as viable init, since this is the case in Ubuntu.

Update hostname and ca certificates consistent with
ubuntu standards
2021-11-19 11:00:50 -05:00
Jarrod Johnson 82a783fa55 Register CA certs in global location for ubuntu 2021-11-18 16:51:18 -05:00
Jarrod Johnson 6d623b046a Fixes for imageboot.sh with ubuntu 2021-11-18 16:34:27 -05:00
Jarrod Johnson 398563df55 Add dirname to the ubuntu diskless 2021-11-18 16:14:44 -05:00
Jarrod Johnson e653c5dff6 Switch to bash for running functions
functions is a bashified facility. Just use bash for it rather
than making it busybox friendly.
2021-11-18 14:56:38 -05:00
Jarrod Johnson 1b7d63da5d Fix wrong sense of apikey 2021-11-18 13:12:56 -05:00
Jarrod Johnson c02651b2de Switch from fork to source for premount 2021-11-18 12:56:53 -05:00
Jarrod Johnson 4316b8690e Make oscategory consistent for ubuntu 2021-11-18 12:38:11 -05:00
Jarrod Johnson 045caadff9 Add ubuntu scheme to boot assets in imgutil
This brings us to the redhat, suse, and ubuntu schemes being understood.
2021-11-18 12:12:55 -05:00
Jarrod Johnson 095339ed90 Have apt-get not prompt to install 2021-11-18 11:43:25 -05:00
Jarrod Johnson 5769cba3d1 Provide functions and update imageboot for ubuntu diskless 2021-11-18 11:25:51 -05:00
Jarrod Johnson 75c5151567 Add hook to hook the premount script 2021-11-18 10:42:22 -05:00
Jarrod Johnson 4a724f28bd Package imgutil ubuntu content 2021-11-18 10:12:34 -05:00
Jarrod Johnson ecb9a6633e Ignore common malformed dhcpv6 request 2021-11-18 09:16:57 -05:00
Jarrod Johnson bf4842baa9 Provide a starter profile for ubuntu diskless 2021-11-17 16:18:06 -05:00
Jarrod Johnson 172515a6e8 Add packaging of ubuntu20.04-diskless 2021-11-17 16:05:00 -05:00
Jarrod Johnson dde9eebf92 Further advance ubuntu diskless implementation 2021-11-17 15:57:21 -05:00
Jarrod Johnson 6b8dec7764 Fix license save through collective 2021-11-17 15:56:36 -05:00
Jarrod Johnson 9e47c1cfed Add mktemp to the confluent hook 2021-11-17 11:15:23 -05:00
Jarrod Johnson 4a13711972 Fix discovery of pre-nonce firmware 2021-11-17 09:39:34 -05:00
Jarrod Johnson 44cc580364 Correct handling of blank value in attribute 2021-11-17 09:24:26 -05:00
Jarrod Johnson cc1b887c31 Allow blanking to disable a crypted password 2021-11-17 09:00:58 -05:00
Jarrod Johnson ef324daf52 Advance ubuntu diskless
Add tpm2 and fuse dependecies that were missing.

Begin draft work on the init-premount script.
2021-11-16 17:03:48 -05:00
Jarrod Johnson cd1dff7c42 Add tpm2-tools to pkglist and switch to apt
The debootstrap was inadequate to
cover tpm2-tools, switch to apt.
2021-11-16 13:15:18 -05:00
Jarrod Johnson 10c019df2a Fix ordering of chmod arguments 2021-11-16 11:42:46 -05:00
Jarrod Johnson bd9c261534 Implement initramfs customization for debian build
The initramfstools are extended
to naturally create the materials needed to do diskless.
2021-11-16 11:33:58 -05:00
Jarrod Johnson c11da229b0 Amend draft ubuntu diskless
Have imgutil build work to call
debootstrap with a pkglist that appears to succeed.
2021-11-16 07:44:41 -05:00
Jarrod Johnson 2ef2e4d039 Fix gathered output with non-rectangular geometry
If we don't have a nice rectangular count of systems,
the last row must tolerate index error in column.
2021-11-16 06:37:59 -05:00
Jarrod Johnson 8ee3630aa1 Simplify get_nonce
Use the helper function, for example
to cope with the prospect of gzip response.
2021-11-15 16:09:17 -05:00
Jarrod Johnson 01a21ec248 Correct syntax error 2021-11-15 11:43:10 -05:00
Jarrod Johnson 218b914754 Fix relative pkglist includes 2021-11-15 11:42:15 -05:00
Jarrod Johnson d59ac74f3a Support relative path on < include
For pkglist and syncfile, detect
relative path and interpret relative
to the file that does the include.
2021-11-15 11:34:34 -05:00
Jarrod Johnson 7b23ee9c7c Organize squeeze vertically
The web gui and ls on cli use organize output this way,
so squeezed node output should be same.
2021-11-15 10:25:00 -05:00
Jarrod Johnson 55fc3bda51 Fix nodersync with output redirection
Variables were left unitialized, use them only
in the tty path.
2021-11-15 09:20:31 -05:00
Jarrod Johnson d5e4d1b90a Add navigating nonce login for xcc discovery
The nonce login from newer firmware is now required.
2021-11-12 11:27:58 -05:00
Jarrod Johnson cde45bb170 Commence draaft work on ubuntu diskless
Provide a initramfs hook (akin to dracut module) and
a potential pkglist to cover what debootstrap does not
provide by default.
2021-11-11 16:41:13 -05:00
Jarrod Johnson 524f0d460f Have imgutil exec manifest / mount
When execing, make the environment see
the '/' normally in mount/df contexts.
2021-11-11 12:05:53 -05:00
Jarrod Johnson 2b6418bc33 Script to walk identify light along a noderange 2021-11-10 15:19:37 -05:00
Jarrod Johnson 9a6d422fd8 Fix the python3 of rsp read 2021-11-09 16:01:45 -05:00
Jarrod Johnson ef10237cfe Update smm rules to relax 2021-11-09 15:58:17 -05:00
Jarrod Johnson 94761ba7c6 Refresh SMM fix expiration sample 2021-11-09 15:54:27 -05:00
Jarrod Johnson b59c88beed Explain more about need for -c versus =''
The concept of inherited and blank override is confusing
and warrants more documentation.
2021-11-09 08:26:35 -05:00
Jarrod Johnson cbed20bb7f Fix suse15 firstboot.sh
It was stripping the wrong value from the path.
2021-11-09 07:10:38 -05:00
Jarrod Johnson 61eecd672c Add confignet to default firstboot/onboot as appropriate for el8 and
suse15
2021-11-08 16:34:26 -05:00
Jarrod Johnson 8df1c5b8e4 Make confignet available as a 'common' script 2021-11-08 16:23:56 -05:00
Jarrod Johnson 766230bcd3 Fix loop extending pkgs
The attempt at include support modified incorrect
list.
2021-11-06 14:38:44 -04:00
Jarrod Johnson f1bc82cd08 Fix logic of websocket handling
Do not fall through to non-websocket path after handling the websocket
2021-11-05 14:15:39 -04:00
Jarrod Johnson b139f9cd2c Consistently return string from consume_termdata
If None is allowed to return, it can mess up caller.
2021-11-05 11:30:43 -04:00
Jarrod Johnson a23d5b9b55 Provide both v4 and v6 in deploycfg
When implicitly working by lookup, both v4 and v6
were provided, but first match only
on explicit specification.

Correct this discrepency.
2021-11-04 17:20:49 -04:00
Jarrod Johnson df7d34dc28 Add attribute support for confluent2hosts
Implement something akin to makehosts
from xCAT.
2021-11-04 14:44:06 -04:00
Jarrod Johnson e749f8f8d5 Prioritize columns over rows
Do not make columns when the noderange is too small
to warrant them
2021-11-04 12:44:47 -04:00
Jarrod Johnson 5ceaa0e4fe Change logreader to python3 2021-11-04 10:53:50 -04:00
Jarrod Johnson 5270f604eb Fix missing el9 from spec install section 2021-11-04 08:00:37 -04:00
Jarrod Johnson ce1d89c741 Set nodename as hostname prior to post for el class distros 2021-11-04 07:56:04 -04:00
Jarrod Johnson 4e9020c3a7 Add SUSE support for confignet 2021-11-02 14:04:11 -04:00
Jarrod Johnson 366a2feaaf Provide api for node to just fetch all it's attributes 2021-11-02 11:21:19 -04:00
Jarrod Johnson db7cb6450b Temporarily stop firewalld and add pause to try to wait for address assignment 2021-11-02 09:43:42 -04:00
Jarrod Johnson ea310e472a Improve preservation of existing connections/settings
When teaming up nics, salvage
things like dns settings from members.

When a connection already seems to exist, modify it rather than delete and replace,
for less disruption.

Running repeatedly should now be safer.
2021-11-01 12:34:37 -04:00
Jarrod Johnson a5f96ccc5d Correct whitespace mistake in previous commit 2021-11-01 11:09:45 -04:00
Jarrod Johnson 5e0aced2ea Merge branch 'master' of github.com:lenovo/confluent 2021-11-01 07:01:56 -04:00
Jarrod Johnson 28a13da118 Fix non-noderange alert specification.
The change in to accomodate nodarange without per-node
distinct input claimed the single input data exclusively
for multimode.

Correct by pulling the singleton code to be common if the
check breaks from the for loop.
2021-11-01 06:59:54 -04:00
Jarrod Johnson 6df8170401 Draft confignet implementation
This will team and set up additional interfaces,
but, for one, no dns.  Need to merge with deploycfg info, since
networkmanager is intent on making dns a
connection oriented thing.
2021-10-29 17:16:16 -04:00
Jarrod Johnson 224663d0c8 Fix execution of confluent functions after run_remote_python 2021-10-29 13:50:04 -04:00
Jarrod Johnson 729408a0cb Fix run_remote aafter the cleanup was added
The removal of the temp dir needed to be linked with
whether the script was dedicated or shared tmp with a run_remote_parts.
2021-10-29 13:01:59 -04:00
Jarrod Johnson b1ee751c7b Add newline to error output 2021-10-29 09:43:52 -04:00
Jarrod Johnson 9428c1fb8e Merge pull request #77 from vmaneagit/patch-80
Update nodelicense.ronn
2021-10-29 09:40:39 -04:00
Jarrod Johnson 391963e3f3 Merge pull request #78 from vmaneagit/patch-79
Update nodelicense
2021-10-29 09:40:25 -04:00
Jarrod Johnson 78163f1d09 Correct issue in parameter rename for apiclient 2021-10-29 07:23:26 -04:00
Jarrod Johnson 8ef70d463f Draft client for net configuration
Common code to struction networks into structure for configuration.

This organizes and autodetects
overlap, in prep for auto-teaming.
2021-10-28 17:09:09 -04:00
Jarrod Johnson aff0c82b0b Fix apiclient with explicit host 2021-10-28 16:15:21 -04:00
Jarrod Johnson 925ea3e95a Refactor apiclient and allow specific host
For getnetcfg, will need to select
spsecific interfaces.  While
tocuhing that anyway, simplify the
v4/v6 paths to be more agnostic.
2021-10-28 15:48:58 -04:00
Jarrod Johnson 5b128238e7 Fix netcfg self api call 2021-10-28 15:47:07 -04:00
Jarrod Johnson 6f967a3afa Bind apiclient search to make for viable firewall rule 2021-10-28 12:55:42 -04:00
Jarrod Johnson a2a9a38147 Fix mistaken sort 2021-10-28 12:30:06 -04:00
Jarrod Johnson 7eeba4e42a Rdeuce netlink traffic to get net config
Avoid superfluous calls to
get addresses and reuse
result through the lifetime
of a reply.
2021-10-27 17:25:54 -04:00
Jarrod Johnson 5a7f0db899 Fix use of autodetected plen 2021-10-27 17:19:22 -04:00
Jarrod Johnson 00b22bb18b Improve autosense of other nics 2021-10-27 17:12:03 -04:00
Jarrod Johnson 621ded7256 Prioritize 'none' and support names in _address fields 2021-10-27 17:03:26 -04:00
Jarrod Johnson ce8e671584 Have includes interpret section names
If <including> a syncfiles, then
be sure to honor MERGE/APPENDONCE in those files without perturbing flow
of the parent file.
2021-10-27 15:47:52 -04:00
Jarrod Johnson 41ba28e525 Connect network configuration to selfservice
This permits a client to ask via various nics for pertinent configuration .
2021-10-27 15:35:22 -04:00
Jarrod Johnson ce9b0bf556 Support terminating include with >
The previous thought of <base.pkglist is fine, but upon seing <base.pkglist>, that looks better.
2021-10-27 14:21:30 -04:00
Jarrod Johnson 74775fd2be Remove errant period in attributes 2021-10-27 13:11:24 -04:00
Jarrod Johnson feb12b95cb Add facility to enable confignet
Provide function to populate
a map of all networking, relative to the interface facing thte client.
2021-10-27 11:52:09 -04:00
Jarrod Johnson 154a328194 Merge pull request #81 from PenghuiCui/master
Add check for attribute value to avoid exception when attribute is None
2021-10-26 07:35:10 -04:00
Jarrod Johnson 8eb6ce0b69 Specify absolute path for mktemp
mktemp defaults to relative, to produce the correct
behavior, must be absolute template.
2021-10-25 12:03:26 -04:00
Jarrod Johnson 0d53612e9c Fix variable yielded when not including 2021-10-25 11:57:18 -04:00
Jarrod Johnson 81675faec1 Avoid clearing disk if autopartition is not to be used 2021-10-25 10:05:15 -04:00
Penghui Cui 6e10b3d2b1 Add check for attribute value to avoid exception when attribute is None 2021-10-25 16:11:38 +08:00
Jarrod Johnson a9bd31a9c4 Provide error when makedirs fails in genesis 2021-10-23 13:08:14 -04:00
Jarrod Johnson 219ad8f56b Fixes for confluent2hosts
python2 compatibility and various scenarios not handled.
2021-10-22 16:07:20 -04:00
Jarrod Johnson 9c0ec25b6e Merge branch 'master' of github.com:lenovo/confluent 2021-10-22 13:13:25 -04:00
Jarrod Johnson 412e2aaf76 Add '<' include syntax to syncfiles and pkglist
Provide means of combining
multiple pkglist and syncfiles
based on hierarchy.

This enables construction of
a more complex structure of
images for those that may want it.
2021-10-22 13:11:50 -04:00
Jarrod Johnson a48732923e Merge pull request #80 from PenghuiCui/master
Support resource register from plugin
2021-10-21 21:44:39 -04:00
Jarrod Johnson 40dea6a747 Support older python subprocess
Older python did not provide timeout.  Keep the timeout
for the modern python that skips select without a timeout,
but try again without timeout to retain compatibility.
2021-10-20 18:23:35 -04:00
Jarrod Johnson d441ff3d63 Fix pxe offers made in spite of managercandidate restriction 2021-10-20 16:45:40 -04:00
Jarrod Johnson 6550d584a2 Give scan callers a context for tracking local interface
When trying to leverage autodetect strategy for net config,
will need to keep track of receiving interface.  For now
only use ipv6 for this capability, as getting the incoming nic
for ipv4 would be more work.
2021-10-20 14:10:59 -04:00
Jarrod Johnson 8a01a0bbdc Use the scan_confluent for getting apikey, if relevant 2021-10-20 14:03:03 -04:00
Jarrod Johnson 484a3f8c64 Have apiclient priotize based on responsiveness 2021-10-19 17:09:52 -04:00
Jarrod Johnson 75557091ef Treat blank enclosure/bay as unset
If someone does the obvious approach to blank something,
treat that as equivalent.
2021-10-19 15:43:23 -04:00
Jarrod Johnson decee2ed93 Add fallback to apiclient
When apiclient fails using deploycfg, add
a multicast scan looking for replacements.
2021-10-19 15:39:47 -04:00
Jarrod Johnson 0725717359 Correct some issues in the ssdp snoop
We still need the node attributes even if
forcing reply.

Further,, sometimes eventlet returns None, tolerate
that better.
2021-10-19 13:12:35 -04:00
Jarrod Johnson f8f60052d0 Fix confluent uuid handling 2021-10-19 10:37:08 -04:00
Jarrod Johnson 3cd78500ce Make client adaptive to receive global data
When following, let the leader filter the
relevant global data rather than the follower.
2021-10-19 10:01:44 -04:00
Jarrod Johnson fd8dd03587 Implement a confluent instance uuid
This allows clients to indicate after install
whether they belong to the collective or
not, allowing ascertaining new deployment
server.
2021-10-19 09:57:49 -04:00
Penghui Cui 05a683698e Support resource register from plugin 2021-10-19 15:31:13 +08:00
Jarrod Johnson 6e7b6188dd Fix api client attempts and speed up checking connections 2021-10-18 16:31:59 -04:00
Jarrod Johnson ae7e69d73d Fix mistake in the apiclient 2021-10-18 15:52:22 -04:00
Jarrod Johnson 0f80b4a019 Change apiclient to embed apikey request
No longer require the clorthto utility
to request a token if we are already in
python.
2021-10-18 12:28:59 -04:00
Jarrod Johnson f93b8da1b7 Handle invalid vendor-class-identifier better
If the vci fails to decode, just ignore it and move on.
2021-10-15 16:49:45 -04:00
Jarrod Johnson 1d71cee61d Fix syncfiles not running with just APPENDONCE 2021-10-15 16:37:02 -04:00
Jarrod Johnson 957679db3c Update syncfile examples and el7 support 2021-10-15 16:24:22 -04:00
Jarrod Johnson 98a6ffd9b6 Update more profiles with the APPENDONCE support 2021-10-15 16:16:11 -04:00
Jarrod Johnson 2e7b315f29 Add 'APPENDONCE:' section to syncfiles
This will APPEND if the target file doesn't
already have the entire source contents in
a contiguous location already. This makes
it more safe to rerun without negative consequence.
2021-10-15 15:48:49 -04:00
Jarrod Johnson f33ed9b4d9 Cleanup after script execution
Leave cleaner tmp directories when functions are ran.
2021-10-15 12:16:48 -04:00
Jarrod Johnson 04dd374bfb Synchronize functions across the supported OSes 2021-10-15 12:10:24 -04:00
Jarrod Johnson 980c3dbcb3 Make functions common between redhat and suse 2021-10-15 12:07:00 -04:00
Jarrod Johnson 08f61e9391 Fix syntax mistake in the previous commit 2021-10-15 10:06:54 -04:00
Jarrod Johnson 653c0bd695 Bring up both IPv4 and IPv6 in EL8
If both are configured, then enable both as early as possible.
2021-10-15 09:30:08 -04:00
Jarrod Johnson 52549ec563 Fix module autoloading in diskless profiles
The initramfs has a reduced set of modules to boot and then
in diskless mode hands over to the 'real' OS for all userspace
to use the more substantial root filesystem with all of the modules.

However one exception is kernel module autoload, which induces modprobe
to run in the initial mount namespace unconditionally.

Thus, preserve the ramfs drivers (just in case) but have the autoloading
pivot
to the normal root filesystem to get the full complement of modules.
2021-10-13 11:37:48 -04:00
Jarrod Johnson 351d6a85ee Fix firstboot with ipv6 deployment in el8 2021-10-12 17:23:18 -04:00
Jarrod Johnson fda61bd354 Attempt to extend the v6 deployment support in el8 2021-10-12 16:58:42 -04:00
Jarrod Johnson d06e130af5 Fix ipv6 address specification in el8 scripted install 2021-10-12 16:42:07 -04:00
Jarrod Johnson 5ca3b68b8a Attempt to support ipv6 deployment in el8 2021-10-12 16:06:37 -04:00
Jarrod Johnson 4f40d9635a Fix nic config with mismatched gateway family
When a gateway exists on a family the node
does not exist for, handle the gateway better.
2021-10-12 15:32:30 -04:00
Jarrod Johnson b96e9f4f70 Provide better feedback on missing key and skip tpm when not present 2021-10-12 11:39:18 -04:00
Jarrod Johnson 58cf220203 Mask spurious output on disk cleanup 2021-10-11 13:30:31 -04:00
Jarrod Johnson a0dfd3f42d Move scripted install to pre-trigger
In Stream 9, initqueue is too late to pre-empt the auto dhcp,
move up to pre-trigger and manually trigger to get network
ready for pre-emption.
2021-10-11 13:28:55 -04:00
Jarrod Johnson 57f346fa4c Implement syncfiles parameters
chmod and chown as directed
by the syncfiles file if present
2021-10-08 10:27:57 -04:00
Jarrod Johnson deb5c2eed8 Fix potential delay in ssh-agent start
Be consistent with other check_output
calls to allow eventlet to properly
background the process.
2021-10-08 10:24:35 -04:00
Jarrod Johnson 7ccaa245b6 Provide both string and numeric for owner/group
To provide a fallback for unrecognized user/group,
provide an id for syncfileclient to resort for.
2021-10-08 10:02:13 -04:00
Jarrod Johnson 52a7921676 Correct mistakes in syncfile option passing 2021-10-07 18:23:57 -04:00
Jarrod Johnson 3f7a7d09dd Correct mistake in referencing option string 2021-10-07 18:02:56 -04:00
Jarrod Johnson c0287e93ed Roll back rsync ownership
Unfortunately, it will try to change parent directories on the way to
the files actually being written.
2021-10-07 16:34:37 -04:00
Jarrod Johnson a676eb0b83 Syncfile option passing to client
Provide a mechanism for a syncfiles to indicate options to the client.

This will be used for owner=, group=, and permissions=
options.
2021-10-07 15:54:53 -04:00
Jarrod Johnson a0ca3d3122 Extend snmp timeout
Default is 1 second, bump to 2 seconds for some
extraordinarily slow switches.  This changes
overall to about 10 seconds as there are, by default,
5 retries.
2021-10-07 13:03:05 -04:00
Jarrod Johnson e52a9ff70f Have syncfiles attempt to preserve more
We cannot preserve symlinks (since we need them intact),
but we can use other rsync features to make synchronization work
better by default.
2021-10-07 13:01:48 -04:00
Jarrod Johnson 3b7e7afc24 Fix inconsistent handling of marginal id in syncfileclient
Also, resynchronize syncfileclient across the distributions.
2021-10-07 12:36:52 -04:00
Jarrod Johnson 26c6f1407b Add syntax for noderange filtering
/etc/passwd -> compute,-n11:/etc/passwd

Will cause the line to be used only when the node matches the
compute,-n11 noderange.
2021-10-07 11:26:13 -04:00
Jarrod Johnson 6222883188 Syncronize syncfileclient for el8 diskless and diskful 2021-10-07 11:10:56 -04:00
Jarrod Johnson a4fc64ea56 Move el9bin build out of spec
Since the rpm itself is built in an el7 container, build
binary before spec driven build to be compatible.
2021-10-07 09:18:24 -04:00
Jarrod Johnson d23f9db6e0 Syncronize diskfull and diskless el8 and el9 functions 2021-10-07 08:38:29 -04:00
Jarrod Johnson d5bbda9e00 Extend el8 to el9 diskless 2021-10-07 08:22:38 -04:00
Jarrod Johnson 23ff788f09 Fix target for el9 binaries 2021-10-07 08:20:51 -04:00
Jarrod Johnson 172008f942 Attempt to cover centos stream 9 by el8
At first glance, there should be similarities,
apart from python differences and need for
different clortho build due to library mismatch.
2021-10-06 16:59:47 -04:00
Jarrod Johnson 2ef41fedf6 Add el9 compatible build
CentOS Stream 9 is not backwards compatible enough to run the
same confluent utilities that the other distributions use.

For now, use fedora to build.
2021-10-06 15:51:12 -04:00
Jarrod Johnson d666050ef7 Consolidate neigh wait time in slp
Rather than incurring it on each iteration (causing a scan to take
15 seconds in test), defer to
handle them all later (reducing to 5 seconds to scan).
2021-10-05 10:59:17 -04:00
Jarrod Johnson 3c72f9f18f Refactor slp neigh warm-up
Rather than pulling it out at active_scan level, intervene deeply.

This fixes the problem where an ip gets used as a key rather than mac.
2021-10-05 10:50:51 -04:00
Jarrod Johnson f50abd662a Provide analogus improvements to ssdp from slp
Recent changes to try to make neigh table fresh and viable in slp
can also apply to ssdp.

Bring those changes forward.
2021-10-05 10:03:28 -04:00
Jarrod Johnson 1fda0e50d8 Fix stub from refactor
foobar was a stand-in for continue to
allow refactor, and needed
to be changed to return.
2021-10-05 08:04:58 -04:00
Jarrod Johnson 1a80d9f31a Extend neigh table refresh to snoop
Improve reliability of 'snooping' slp.
2021-10-04 16:36:22 -04:00
Jarrod Johnson c569826ff1 Improve scan result with missing neigh entries
If no neigh table is present for
a given address, send a packet to
induce kernel activity.

Then wait for a bit over 2 seconds to allow for
2 retries (at default settings)
and then proceed assuming all findable neighbor table
entries will be found.
2021-10-04 16:22:12 -04:00
Jarrod Johnson 1c69700e1d Fix missing port 22
Either this was overlooked or the sshd_config stopped including
Port 22.  Fix by putting in port 22.  If port 22 already existed,
sshd is fine with the configuration being configured twice.
2021-10-01 08:34:51 -04:00
Jarrod Johnson 92949f012f Merge tag '3.2.2'
Fix collective mode
2021-10-01 08:03:50 -04:00
Jarrod Johnson 398c8b3a71 Improve syncfiles permission denied reporting
When a non-readable file was
encountered, confluent would
cryptically report rsync failure.

Check for the usual culprit, unreadable files if rsync fails.

Cause this error to manifest with clearer text.
2021-09-30 12:01:29 -04:00
Jarrod Johnson c93917e4a4 Add a failsafe for errors trying to connect to a new leader
Provide better experience in the face of the class of errors such
as the one fixed by previous commit.
2021-09-30 08:18:39 -04:00
Jarrod Johnson c1113430a2 Pass only the name rather than full sockaddr on retire
Followers of a server that is retiring to join the better leader
were being given incorrect format which would fail in the dns lookup.
2021-09-30 08:11:19 -04:00
Jarrod Johnson d899cfbf1a Clean disk to install in pre
Installers frequently fail if there's a derelict lvm on disk.

Explicitly remove the on-disk content and deactive lvm to let
anaconda work reliably.
2021-09-29 14:31:18 -04:00
Jarrod Johnson 99ba4e7765 Handle ip aliases in pxe
Use netutil assessment of the
best server ip for pxe responses.

Using 'recvip' is too simplistic for broadcast
packets.  recvip just gets the first ipv4 address on the interface,
when an alias may be better.

netutil assesses all the possible aliases, thus has better logic and pxe.py
now uses it.
2021-09-27 11:04:42 -04:00
Jarrod Johnson 929392c746 Fix hangs on check_output
Eventlet narrowly targets overriding
select in subprocess, to avoid rewriting adequate functions.

However, subprocess does an 'optimization' to skip
select if there's fewer than 3 pipes to juggle and no timeout specified.

Induce python to always use select
by specifying a very long timeout.

This causes confluent to be able to spawn multiple subprocesses and
not be hung waiting for input.
2021-09-23 10:42:47 -04:00
Jarrod Johnson 5d20ee6cca Serialize ssh agent interaction
Race conditions could occur when multiple
requests came in too close together.
2021-09-23 09:40:10 -04:00
Jarrod Johnson 42038048da Drop PC from the speed prefix 2021-09-22 10:52:29 -04:00
Jarrod Johnson d08d597818 Properly show DCPMM in nodeinventory 2021-09-22 10:50:32 -04:00
Jarrod Johnson 3869dd6918 Fix imgutil capture
Adding options for oshandler
broke fingerprinting for capture.

Fix by passing None and triggering the AttributeErrors.
2021-09-22 08:17:18 -04:00
Jarrod Johnson 4ab5cac3eb Generate random serial number for certificate
Hardcoding 0x123 serial number would cause strict clients to reject the
certificate.

While we are still not guaranteeing uniqueness, the chances of a
duplicate are impossibly small.
2021-09-22 07:48:44 -04:00
Jarrod Johnson 3a911acb81 Fix the efibootmgr override logic
Fully realize the chroot invocation of efibootmgr and also
bail out if no new boot number is detected.
2021-09-21 15:50:45 -04:00
Jarrod Johnson 1cb5efae75 Call efibootmgr in chroot for ubuntu 2021-09-21 11:21:13 -04:00
Jarrod Johnson 861c0230c7 Reorder ubuntu to first in post
Ubuntu tends to install itself as behind network
device.  Amend to match other OSes and avoid network
boot.
2021-09-21 10:03:29 -04:00
Jarrod Johnson 3b3fffb36b Note workaround for 'No data available'
In a diskless boot, sometimes the build system
might not label the scratch contents
correctly.  setfiles can be used to fix it.

Notably, this seems to cause the overlay+squashfs to
return 'no data available' on select
calls even with selinux disabled, so it may be another
gap with overlay and/or limitation of squashfs when
queried about modification without a label.
2021-09-21 08:13:06 -04:00
Jarrod Johnson dd89c48b9a Fix problem where syncfiles could fail on certan hosts
If the set of oldhosts and newhosts were just so,
targlines or sourcelines could be all
null and cause index errors.
2021-09-20 08:01:41 -04:00
Jarrod Johnson 6acd3c2b7d Add ability to execute functions as a command
This gives easier access over nodeshell and similar to run functions by executing the
functions as a script with arguments.
2021-09-20 08:00:35 -04:00
Jarrod Johnson fdc9b3c283 Add confluent2hosts utility
Add utility to help add/modify /etc/hosts for a noderange.

Also fix buggy code in syncfileclient noticed while
reusing it for confluent2hosts.
2021-09-17 12:57:18 -04:00
Jarrod Johnson 1b88e44c59 Ignore broken lldp results
Some switches may have broken incomplete records,
skip such records to focus on viable complete records.
2021-09-16 15:49:36 -04:00
Jarrod Johnson f881f955d4 Correct typo in ubunut initramfs scripts 2021-09-15 12:20:08 -04:00
Jarrod Johnson 9687ce89b8 Use fe80:: match to find index for getting addresses
This fixes a problem where fetching
from fe80:: fails to identify nic.
2021-09-13 17:54:18 -04:00
Jarrod Johnson 5276618b73 Actually remove group on split 2021-09-13 14:09:07 -04:00
Jarrod Johnson 38669ddbbc Have nodegroupremove accept comma delimited groups 2021-09-13 14:01:46 -04:00
Jarrod Johnson 2dcd0f769a Support defining multiple groups in one go 2021-09-13 13:48:56 -04:00
Jarrod Johnson d254cb08ac Default to None for second arg to get_apikey
In some context, we don't need to check both, we have a confirmed manager. Just take
one argument for that scenario.
2021-09-13 11:48:36 -04:00
Jarrod Johnson 66ddcfc194 Separate connection check from connection
Messing with connect corrupted
the http client too much,
have a separate helper function to evaluate
the candidate deployers,
then pass only the winner on.
2021-09-13 11:21:38 -04:00
Jarrod Johnson 95ea913108 Have genesis opt into ipv6 deploycfg 2021-09-13 10:26:50 -04:00
Jarrod Johnson 52bebe41d1 Provide ipv6 only for deploycfg2
Older profiles may trip over new network
lines, spare them 'v6' entries until
they opt into deploycfg2.
2021-09-13 10:26:17 -04:00
Jarrod Johnson 06e32c53cc Fix overly vague extraction of deploy_server
If deploy_server appears anywhere, it confuses
the scripts
2021-09-13 10:23:13 -04:00
Jarrod Johnson 7ba10e559e Correct ipv4/v6 handling in get_apikey 2021-09-13 10:03:32 -04:00
Jarrod Johnson cf097b153e Fix typo in genesis network bringup 2021-09-10 12:50:06 -04:00
Jarrod Johnson 269d9c79d1 Let functions set confluent_mgr
The better logic in functions is used instead of the simplistic logic.
2021-09-10 12:28:00 -04:00
Jarrod Johnson 1c3c54a35b Update functions to be more thorough
confluent_mgr could be ipv6 or
may need to be updated from a
link local or may need to go to copernicus data to work.
2021-09-10 11:40:17 -04:00
Jarrod Johnson 66d378a007 Simplify the ipv6 support and fix invocation before deploycfg 2021-09-10 09:16:08 -04:00
Jarrod Johnson 35b74764bf Amend apiclient to support v4/v6 2021-09-09 17:15:29 -04:00
Jarrod Johnson 11796cda81 Correct the ipv6 prefix name 2021-09-09 16:51:27 -04:00
Jarrod Johnson 8eb242cba0 Add ipv6 support to genesis 2021-09-09 16:27:59 -04:00
Jarrod Johnson a4de3b93ec Merge branch 'master' into ip6 2021-09-08 12:44:05 -04:00
Jarrod Johnson a3486c5e68 Skip calling localectl when possible
localectl can sometimes be unworkable,
prefer sourcing the relevant configuration files directly
when possible.
2021-09-08 12:43:56 -04:00
Jarrod Johnson 465b973f79 Add unencrypted option to pack and rework multi-repo support
Support skipping encryption if a user does not want it. Further support mulitple '-r'
arguments and fix builds when
no -r is specified.
2021-09-08 12:43:50 -04:00
Jarrod Johnson 20f607f49e Skip calling localectl when possible
localectl can sometimes be unworkable,
prefer sourcing the relevant configuration files directly
when possible.
2021-09-08 12:42:43 -04:00
Jarrod Johnson 3c7034edf2 Add unencrypted option to pack and rework multi-repo support
Support skipping encryption if a user does not want it. Further support mulitple '-r'
arguments and fix builds when
no -r is specified.
2021-09-08 12:17:30 -04:00
Jarrod Johnson 3762a37243 Provide advertise and reply
Since the packets are the same, just need to handle the
request type.
2021-09-07 16:50:55 -04:00
Jarrod Johnson f3d7a949e6 Fix ipv6 netboot support to get to request
A number of mistakes were in
netutil and the advertise needed
to be complete and transmitted.
2021-09-07 16:13:27 -04:00
Jarrod Johnson 10e408559b Merge branch 'master' into ip6 2021-09-07 11:10:25 -04:00
Jarrod Johnson 6465203918 Add ability to pack and combine with a previous baseprofile
For example, this is a good complement to unpack in a tethered environment:

unpack profile-v1 /root/scratch
#modify /root/scratch
pack /root/scratch profile-v2 -b profile-v1
2021-09-03 16:14:44 -04:00
Jarrod Johnson de5350ca6e Fix additional repository argument for suse build 2021-09-03 15:12:06 -04:00
Jarrod Johnson 5422f904f9 Add a breadcrumb for scripts to detect exec context 2021-09-03 12:11:10 -04:00
Jarrod Johnson 57a8149844 Fix adding repositories to rhel-style diskless 2021-09-03 09:16:22 -04:00
Jarrod Johnson 558139d654 Fix bug around pulling in img build info 2021-09-02 12:11:48 -04:00
Jarrod Johnson 63d9aea218 Support relative paths for build scratchdir and pkglist 2021-09-02 12:10:07 -04:00
Jarrod Johnson 5d1d527e09 If reasonable, provide a 'distribution' link for diskless
If the user uses '-s', then
preserve that in distribution like a diskful one would.
2021-09-02 11:58:22 -04:00
Jarrod Johnson 19685b7a4e Accept relative path for unpack 2021-09-02 11:38:09 -04:00
Jarrod Johnson adcc2f0aa9 Add some usage to the volume flag for now '-' 2021-09-02 11:30:51 -04:00
Jarrod Johnson fbef6442d5 Add a shorthand '-' to say 'mount to same path as outside' 2021-09-02 11:29:40 -04:00
Jarrod Johnson bf017b55e1 Have unpack more intuitively target the specific directory
This makes it symmetric witht pack/unpack.
2021-09-02 11:22:45 -04:00
Jarrod Johnson bcc278e4d8 Add losetup for new suse support 2021-09-02 10:30:30 -04:00
Jarrod Johnson 0d2ecd460d Merge changes from EL8 imageboot 2021-09-02 10:17:11 -04:00
Jarrod Johnson ac45d6e578 Support non-interactive request to exec command
Make outside scripting easier by accepting an optional command
to run in exec environment.
2021-09-02 09:06:57 -04:00
Jarrod Johnson 237670e9b1 Rework gpg key import for suse build
Only pull in host keys when not using a source.
When using source(s), pull in all normal gpg keys from local filesystem sources.
2021-09-02 08:39:45 -04:00
Jarrod Johnson f65056a047 Fix Suse image fingeprinting 2021-09-02 08:05:11 -04:00
Jarrod Johnson 6264dc1ed1 Add host pubkeys to build root 2021-09-01 16:17:34 -04:00
Jarrod Johnson a7d894007f Treat netgroup entries differently 2021-09-01 11:00:53 -04:00
Jarrod Johnson 27a1649d94 Add more in-context stateless documentation
Specify what default behavior is and reason to choose one over
the other.
2021-09-01 10:44:25 -04:00
Jarrod Johnson 96f50519d8 Fix typo in imgutil 2021-09-01 10:38:49 -04:00
Jarrod Johnson 925cca1733 Add some commentary 2021-09-01 10:28:49 -04:00
Jarrod Johnson 9afa33d0cc Assisted redfish bmc setup
This is a quick example script of using
confluent switch scanning in conjunction with
checking dhcp leases to handle some generic redfish
bmc.
2021-09-01 10:23:43 -04:00
Jarrod Johnson 6c32630bd9 Fix multi-server reply processing
The stateless code could get confused by multiple offers,
fix the mistake.
2021-08-30 11:24:57 -04:00
Jarrod Johnson aaea5bcaeb Make sure the netlink socket closes on the way out 2021-08-30 09:01:42 -04:00
Jarrod Johnson 3d4462d788 Fix support for newer XCC firmware
Newer XCC firmware requires more parameters for usermodify
2021-08-27 18:29:38 -04:00
Jarrod Johnson d69de62077 Amend setinitalpwd 2021-08-27 16:37:26 -04:00
Jarrod Johnson c48f3a8b59 Sample script to navigate first password change 2021-08-27 16:13:14 -04:00
Jarrod Johnson ce98ff6b3d Fix suse imgutil build function 2021-08-27 09:03:35 -04:00
Jarrod Johnson e35ce77bc7 Fix SUSE imgutil 2021-08-27 08:46:47 -04:00
Jarrod Johnson c2de5fa580 Fix SUSE imgutil 2021-08-27 08:46:23 -04:00
Jarrod Johnson a9044238ba Further the IPv6 support 2021-08-26 17:44:30 -04:00
Jarrod Johnson dd1615b4a7 Fixes for imgutil 2021-08-26 16:03:38 -04:00
Jarrod Johnson f2fcbc887d Fixes for imgutil 2021-08-26 16:03:17 -04:00
Jarrod Johnson d4a846e786 Merge branch 'master' into ip6 2021-08-26 12:23:29 -04:00
Jarrod Johnson 7c617a160b Close socket in relay_data
Closing the socket outside of relay_data causes relay_data
to stay alive, causing eventlet to think a filehandle is open that is not.

A reasonable question would be why eventlet fails to error that read
when the filehandle is closed, but for now, move the close activity
to the relay_data handler.

This resolves "Second simultaneous read on fileno" conditions introduced
by the fix for leaking filehandles.
2021-08-26 11:52:22 -04:00
Jarrod Johnson d0c23e490b Tolerate delays in crypt-dm completion for imgutil 2021-08-26 10:38:34 -04:00
Jarrod Johnson 6bf51a20b2 Set nodename as hostname prior to post for el class distros 2021-08-26 09:33:16 -04:00
Jarrod Johnson 3e21587f22 Update error text for redfish to cover completely unsupported redfish
systems
2021-08-26 08:58:02 -04:00
Jarrod Johnson 1b3231377c Draft work to update pxe and netutil for ipv6 support 2021-08-25 17:58:36 -04:00
Jarrod Johnson ba7ccaa7f2 Document the netlink data in neighutil 2021-08-25 17:57:52 -04:00
Jarrod Johnson 093e961613 Merge branch 'master' into ip6 2021-08-25 15:59:06 -04:00
Jarrod Johnson b4ee1ab6af Fix imgutil build 2021-08-25 15:58:48 -04:00
Jarrod Johnson 3eb9ef720b Fix imgutil build 2021-08-25 15:58:17 -04:00
Jarrod Johnson 597db2138f Begin work on ipv6 netboot support 2021-08-25 09:21:12 -04:00
Jarrod Johnson 6bb6b362ab Provide support for merging multiple sources to single destination 2021-08-24 17:39:06 -04:00
Jarrod Johnson 0cfd18d84e Add a little main to experiment with neighutil 2021-08-24 17:18:10 -04:00
Jarrod Johnson 51a73737a7 Fix new neigh behavior
It would sometimes miss a lookup.
2021-08-24 17:15:56 -04:00
Jarrod Johnson 4f4d02d68f Refactor neighutil
Stick to bytes in the expensive part, only convert to and from
presentation form on lookup need.

Convert all external calls to a unified lookup logic.
2021-08-24 16:19:41 -04:00
Jarrod Johnson 797465b3eb Handle some intra-collective errors better 2021-08-24 15:50:03 -04:00
Jarrod Johnson 69b58836f6 Change to built in neigh fetch
Rather than outsource, slowly,
to ip neigh for this frequent task,
call netlink directly.
2021-08-24 11:54:33 -04:00
Jarrod Johnson 06cfd408fc Fix handling of abrupt client close 2021-08-24 07:57:14 -04:00
Jarrod Johnson b367d8ea50 Fix ntpcfg handling in autoyast 2021-08-20 11:12:22 -04:00
Jarrod Johnson 30e901ef19 Attempt -p and -r arguments to add repos and speciy alternate pakagke list. 2021-08-18 17:34:27 -04:00
Jarrod Johnson b44ac19723 Provide some info on image progeny on pack 2021-08-18 15:50:03 -04:00
Jarrod Johnson f855dda70f Sort list of distributions and profiles
The default sort order of listdir
isn't particularly helpful to anyone.
2021-08-18 15:40:58 -04:00
Jarrod Johnson b07ca72a8b Close stray filehandles
Proxied terminals and dispsatched
requests would leak filehandles.
2021-08-17 17:18:10 -04:00
Jarrod Johnson d3b6326673 Fix incorrect variable name for starting tmux 2021-08-12 16:47:03 -04:00
Jarrod Johnson 216a390229 Further refine TERM for tmux 2021-08-12 16:33:46 -04:00
Jarrod Johnson 93c52c6981 Improve tmux draw behavior in genesis 2021-08-12 16:31:26 -04:00
Jarrod Johnson ef43d91164 Have diskless environment prefer 'primary' interface too 2021-08-12 15:20:43 -04:00
Jarrod Johnson 130e3adbc6 Add uuid fill-in for pxe when policy allows
If permissive or open, and xcc is known, but uuid missing,
fill it in.

If open or pxe, and can know node through XCC fingerprint,
then accetp that as a clue.

Also, do not search ethernet switches when xcc cert helps identity.
2021-08-12 14:17:57 -04:00
Jarrod Johnson 0f543c80e9 Add a more specific error if we have a guess about nodename
If a manual add procedure has not
specified a mac or uuid, but
the discovery framework has a guess about it,
have that guess appear
in events with suggestion on
how to proceed.
2021-08-12 13:07:57 -04:00
Jarrod Johnson e9bc7ebe8d Finish conversion of imgutil to argparse 2021-08-12 09:15:15 -04:00
Jarrod Johnson 8a8e9718f9 Begin migration of imgutil to argparse
We no longer support python 2.6, we can use argparse for better subcommand handling.
2021-08-11 17:01:32 -04:00
Jarrod Johnson 865021beff Unack to rootfs
This keeps things neutral and leaves the door open for multipart
support
2021-08-11 16:14:46 -04:00
Jarrod Johnson 034eca3bb0 Refine PXE/HTTP log
Add logs for ignored boot requests, suppress discovery warning for known uuids,
and generally throttle logging these to once per mac address per minute.
2021-08-11 08:14:32 -04:00
Jarrod Johnson 6b28877828 Add iputils to have ping in suse 2021-08-11 07:31:58 -04:00
Jarrod Johnson 71342272bf Add imgutil unpack
Provide capability to unpack previously packed diskless images.
2021-08-10 09:04:30 -04:00
Jarrod Johnson 1e418e1bcf Stub to drive unpack feature 2021-08-09 16:47:27 -04:00
Jarrod Johnson 225618ef75 Add stall in firstboot for deployer to be available 2021-08-09 15:19:36 -04:00
Jarrod Johnson 2a0491ef0c Add ability to specify custom increment in []
Often, it's desired to target odd or even, provide custom increment/step syntax,
but only in the [] context.

Perhaps one day can add n1-n12:2 support, but for now, this is easier to handle.
2021-08-09 11:19:07 -04:00
Jarrod Johnson db9df97fa0 Check and error if user request non-existant profile
This provides nice and immediate feedback for a common mistake.
2021-08-09 09:49:10 -04:00
Jarrod Johnson f9846cb564 Fix inability to delete a completed servicedata event 2021-08-05 08:31:13 -04:00
Jarrod Johnson 91caf76cae Fix ownership problems with build and capture
Some parent directories were never given to confluent user
2021-08-04 12:12:57 -04:00
Jarrod Johnson 9bfdd20919 Add sanity check to confluent start
Refuse to start if /etc/confluent is in bad shape that
may create issues later.
2021-08-04 10:54:21 -04:00
Jarrod Johnson c3e342a8c0 Fix ordering of python path discovery 2021-08-03 16:48:30 -04:00
Jarrod Johnson 54fde4af21 Fix pessimistic error on apikey
Actually make sure that the apikey retrieval failed before erroring.
2021-08-03 16:44:03 -04:00
Jarrod Johnson fc22c87ce9 Fix typo in informational message 2021-08-02 16:03:37 -04:00
Jarrod Johnson 48d84a5422 Fix get_json
Some handlers may work in bytes or str,
normalize to str on the way out.
2021-08-02 14:35:59 -04:00
Jarrod Johnson b604ec4773 Fix detection of missing sync source
Rather than just assume we want a directory when glob
finds no matches, just take the empty result.
2021-08-02 11:33:08 -04:00
Jarrod Johnson 2219297afc Fix simple password support
Simple password was broken during the MFA addition, restore
the most common authentication mechanism.
2021-07-29 13:16:33 -04:00
Jarrod Johnson 08f226a3bf Recognize Ubuntu 20.04.2 2021-07-28 14:31:04 -04:00
Jarrod Johnson a25a10cb86 Add firstboot/post directories to ubuntu 2021-07-28 08:52:05 -04:00
Jarrod Johnson af9676ee6f Improve appearance of imgutil capture
Provide more feedback with less worrisome normal output.
2021-07-27 08:36:48 -04:00
Jarrod Johnson 4c96735b6d Add ssh to post phase of cloning 2021-07-26 13:51:36 -04:00
Jarrod Johnson ac86961e24 Perform syncfiles on clone deployment post 2021-07-26 13:29:33 -04:00
Jarrod Johnson 6adc736450 Relocate syncfiles path to correct location 2021-07-26 13:22:31 -04:00
Jarrod Johnson 8ab6fef632 Fix kernel selection on pack
Make a specialized sort
for kernel versions to more reliably identify the latest version.
2021-07-26 13:03:26 -04:00
Jarrod Johnson 065d0585ea Make search for grub.cfg more specific
grub.cfg outside of /boot can easily exist, be more specific about where it can be.
2021-07-26 12:17:15 -04:00
Jarrod Johnson ca8f6fa52c Bash completion for imgutil capture 2021-07-26 11:59:04 -04:00
Jarrod Johnson a720ccdbc8 Set ownership/permissions of private section
Fix confluent being unable to read, and make the permissions more consistent.
2021-07-26 11:12:59 -04:00
Jarrod Johnson 0ad59436ec Mitigate scratch consumption
As an old file is copied in for future disposale, delete
it as we go by fallocate
to punch holes in it.
2021-07-26 09:19:33 -04:00
Jarrod Johnson 663f8fc085 Add nodename to set_confluent_vars
It is expected that nodename would also be set.
2021-07-23 19:08:06 -04:00
Jarrod Johnson a7b9e72589 Fixes and update umage2disk to new multipart format 2021-07-23 19:06:14 -04:00
Jarrod Johnson 9eb6f38bf1 Various fixes to imageboot.sh 2021-07-23 18:43:57 -04:00
Jarrod Johnson 4928f50332 Create private directiories and correct key format 2021-07-23 17:43:47 -04:00
Jarrod Johnson 7f468c3a91 Correct offset to be in sectors, not bytes 2021-07-23 17:32:42 -04:00
Jarrod Johnson 81b4da6a95 Add encrypted stateless pack 2021-07-23 17:11:33 -04:00
Jarrod Johnson 4bde1b963f Transfer encryption key on capture 2021-07-23 16:54:57 -04:00
Jarrod Johnson 1e44deecf6 Add support to retrieve private key and crypt mount diskless/cloning 2021-07-23 16:49:02 -04:00
Jarrod Johnson 1e653851fe Add syncfiles to el8 diskless 2021-07-23 16:23:15 -04:00
Jarrod Johnson 54667570bd Create encrypted image and private profile data
Prepare for securing os profile witht custom images
2021-07-23 16:13:24 -04:00
Jarrod Johnson 364085801a Fix apikey variable 2021-07-21 17:44:43 -04:00
Jarrod Johnson 8171d461ea Another selinux fixup
systemctl enable firstboot
produces invalid selinux context, fix aafter enabling.
2021-07-21 17:34:53 -04:00
Jarrod Johnson 3690dda177 Actually enable firstboot execution 2021-07-21 16:48:38 -04:00
Jarrod Johnson 365b81e7e1 Prune all .gitignore files, not just blessed profiles 2021-07-21 13:57:06 -04:00
Jarrod Johnson b3fee922f9 Try to speed up selinux labelling
There's only a couple of places
where the imaging should need fixup, be more selective in relabel.
2021-07-21 13:26:31 -04:00
Jarrod Johnson 29d0dd6678 Add missing profile content for cloning 2021-07-21 12:47:43 -04:00
Jarrod Johnson 7d31e22447 Add post/firstboot to os cloning 2021-07-21 12:28:03 -04:00
Jarrod Johnson 4ddfa192ba Remove sticky bit from profile directory 2021-07-21 12:16:22 -04:00
Jarrod Johnson fa45ea8ad3 Finalize a captured image 2021-07-21 11:56:15 -04:00
Jarrod Johnson f4281e115b Fix permissions on generated profile. 2021-07-21 11:53:51 -04:00
Jarrod Johnson 5dfbeef79c Advance state of cloning
Have imgutil complete the capture process, splitting work
between target and repository.

Provide hook through kcmdline to induce installtodisk.

Have installimage reboot system cleanly when done.

Have new /etc/confluent in cloned system.

Hook for post scripts to execute.
2021-07-21 11:15:42 -04:00
Jarrod Johnson cd8a1dfe5e Draft work to flesh out profile and pull back
Fingerprint the target and prepare for more effort.

Will have another imgutil primitive for post-capture prep to get the
initramfs, kernel, rootimg, and bootloader content ready for copy.
2021-07-20 17:02:08 -04:00
Jarrod Johnson 2257a67420 Begin wiring imgutil for remote capture
Will be having to run on remote
system and local system
and combining the results
as well as cleaning up after ourselves on target.
2021-07-20 15:56:47 -04:00
Jarrod Johnson 55302b74d9 Have prototype cloning implemented
Go ahead and relabel all selinux content, ssh keys, grub, and efiboot entry.
2021-07-20 14:07:55 -04:00
Jarrod Johnson 22008f9dc9 Image cloning changes
Refactor and try to mask ssh
keys for root user.

Try to preserve selinux context for masked files.

Add progress indicator for writing to disk.
2021-07-19 17:30:26 -04:00
Jarrod Johnson db735a654d Aggregate vt buffer feeds
If we start developing a backlog
of content to feed to the buffer manager,
aggregate updates to batch submit them more efficiently.
2021-07-19 11:16:12 -04:00
Jarrod Johnson cbee00d3bb Fix initial collective join
Initial collective join combined
with the orderly collective startup
hit a chicken and egg problem.

Disable initting on first enrollment
to let enrollment drive
that specific initialization to
restore behavior.
2021-07-19 10:26:05 -04:00
Jarrod Johnson a8b54ff434 Fix initial collective join
Initial collective join combined
with the orderly collective startup
hit a chicken and egg problem.

Disable initting on first enrollment
to let enrollment drive
that specific initialization to
restore behavior.
2021-07-19 10:25:35 -04:00
Jarrod Johnson fada9336ee Fix swapsize float in image install
If it undergoes float arithmetic, it must be made int again.
2021-07-16 17:23:21 -04:00
Jarrod Johnson bda51d2106 Start fixup, first up is the fstab
Provide an fstab consistent
with redhat strategy, but with
the new uuids from imaging.
2021-07-16 17:02:53 -04:00
Jarrod Johnson 88d49c9f40 Start image2disk
This marks having written out
the partitions verbatim.
2021-07-16 16:29:56 -04:00
Jarrod Johnson c92b2f4255 Stage for python application to actually execute the install 2021-07-16 12:03:11 -04:00
Jarrod Johnson ece525c2e2 Begin work on install and filter small devices from install candidacy 2021-07-16 11:11:13 -04:00
Jarrod Johnson 386dc2348c Mount multiple partitions in diskless mode 2021-07-16 10:39:11 -04:00
Jarrod Johnson da44738e00 Generalize more of an OS on capture
/etc/fstab, hostname, and networnk-scripts are masked
for the image.
2021-07-15 17:30:50 -04:00
Jarrod Johnson e43e5ac167 Add confluent_imgutil to addons 2021-07-15 14:42:26 -04:00
Jarrod Johnson 9458d33cc5 Add multipart image support to diskless 2021-07-15 14:39:17 -04:00
Jarrod Johnson 831b129899 Correct syntax error in confluent client 2021-07-15 12:39:38 -04:00
Jarrod Johnson 1570d3dbe3 Add c utility for reading confluent multipart images 2021-07-15 12:39:19 -04:00
Jarrod Johnson 46c0852b6f Add more non-json data to image format 2021-07-15 12:38:50 -04:00
Jarrod Johnson e3bd1d6cac Correct format of confluent multipart magic 2021-07-15 11:24:49 -04:00
Jarrod Johnson 597faecc04 Change error for nodefirmware with present, but empty noderange 2021-07-15 11:24:23 -04:00
Jarrod Johnson 85643d82e8 Add losetup to el8 stateless
For multipart support, need to manually
set up loop mount and dmsetup.
2021-07-15 10:45:38 -04:00
Jarrod Johnson 7e07ec96a2 Combine json and images into a single multi-part file
This will facilitate urlmount use for mounting without
downloading.
2021-07-15 09:12:17 -04:00
Jarrod Johnson eb3dd0f10a Begin work on imgutil capture
Provide mechanism to capture for cloning purposes.
2021-07-14 17:36:55 -04:00
Jarrod Johnson a953a6afba Provide clearer error when osdeploy initialize is not done
osdeploy import needs to have things prepared by
osdeploy initialize.  Check for it having run and error if needed.
2021-07-14 15:40:38 -04:00
Jarrod Johnson f7a80c6ac0 Fix nodeattrib when a list member is 'broken'
If 'broken' was used as a group name, it would behave incorrectly.
Only check 'broken' for dict types.
2021-07-14 08:06:52 -04:00
vmaneagit 5728e141a4 Update nodelicense.ronn
Man page clarification - file as license file, name as license feature name.
2021-07-14 13:46:08 +03:00
vmaneagit f531c1b856 Update nodelicense
Usage clarification - file as license file, name as license feature name.
2021-07-14 13:43:57 +03:00
Jarrod Johnson 101b5685d1 Move kickstart.custom fetch to before pre.d
Allow custom scripts to further customize kickstart.custom
by modifying /tmp/kickstart.custom
2021-07-12 09:23:01 -04:00
Jarrod Johnson 71d8b89a57 Fix profile name not being set in time 2021-07-09 16:22:57 -04:00
Jarrod Johnson ea26478714 Add needed dependency for OFED 2021-07-08 11:54:14 -04:00
Jarrod Johnson 175f9317ac Skip 32bit portion of mofed 2021-07-08 11:45:43 -04:00
Jarrod Johnson b291dee68c Add bind-utils, skip iwl*-firmware, and alphabatize packages 2021-07-08 11:38:50 -04:00
Jarrod Johnson 4f77615161 Provide a sample container build 2021-07-08 09:39:36 -04:00
Jarrod Johnson 430428eba2 Add missing dependencies to the confluent server package 2021-07-08 09:33:35 -04:00
Jarrod Johnson 4dee174bee Merge pull request #64 from vmaneagit/patch-64
Update nodeconfig.ronn
2021-07-08 09:25:11 -04:00
Jarrod Johnson 766a5e0fd2 Merge pull request #61 from vmaneagit/patch-62
Update confluentdbutil.ronn
2021-07-08 09:23:54 -04:00
Jarrod Johnson 90a3839353 Merge pull request #65 from vmaneagit/patch-65
Update nodeeventlog
2021-07-08 09:23:32 -04:00
Jarrod Johnson ce17015baf Merge pull request #68 from vmaneagit/patch-68
Update nodelicense.ronn
2021-07-08 09:22:41 -04:00
Jarrod Johnson 360ff0798c Merge pull request #69 from vmaneagit/patch-69
Update noderemove
2021-07-08 09:22:24 -04:00
Jarrod Johnson c2bd12234b Merge pull request #70 from vmaneagit/patch-70
Update nodersync.ronn
2021-07-08 09:22:03 -04:00
Jarrod Johnson 51f1c67a64 Merge pull request #63 from vmaneagit/patch-63
Update nodeconfig
2021-07-08 09:21:50 -04:00
Jarrod Johnson c3634fe75c Merge pull request #66 from vmaneagit/patch-66
Update nodelicense
2021-07-08 09:21:34 -04:00
Jarrod Johnson 8f394f230c Merge pull request #71 from vmaneagit/patch-71
Update nodersync
2021-07-08 09:21:20 -04:00
Jarrod Johnson b21d462acf Merge pull request #72 from vmaneagit/patch-73
Update noderun.ronn
2021-07-08 09:20:51 -04:00
Jarrod Johnson dc32813882 Merge pull request #73 from vmaneagit/patch-72
Update noderun
2021-07-08 09:20:38 -04:00
Jarrod Johnson c8ead7bb6d Merge pull request #74 from vmaneagit/patch-74
Update nodepower.ronn
2021-07-08 09:19:56 -04:00
Jarrod Johnson f352a10000 Merge pull request #75 from vmaneagit/patch-78
Update nodepower
2021-07-08 09:19:39 -04:00
Jarrod Johnson dd4f329139 Finish changes to builddeb script for vtbufferd 2021-07-01 16:45:20 -04:00
Jarrod Johnson 90bde09c82 Fix make clean without binary existing 2021-07-01 16:39:36 -04:00
Jarrod Johnson 2d2e8114b3 Add install section for Makefile in debian packaging 2021-07-01 16:34:06 -04:00
Jarrod Johnson b87580466e Add debian packaging for vtbuffered 2021-07-01 16:31:59 -04:00
Jarrod Johnson 08cf1bbf48 Fix the sed syntax for LEAP import 2021-07-01 14:07:43 -04:00
Jarrod Johnson e565a1752f Fix LEAP initprofile behavior 2021-07-01 13:43:31 -04:00
Jarrod Johnson ef1649208e Switch to using separate CA for TLS
This allows regenerating TLS cert
without updating boot images.

For example, if ip address changes need a new cert, no
longer should the nodes need new certs to trust
just due to that.
2021-06-30 14:25:46 -04:00
Jarrod Johnson 35b9635840 Clear armed API if current node token is used
If a node is armed, but instead unseals the prior key from TPM,
implicitly clear the armed state to avoid leaving it armed.
2021-06-28 13:30:09 -04:00
Jarrod Johnson 9c43dbff47 Rework MFA handling
Avoid calling PAM in the parent process, as
this seems to cause problems with some PAM
configurations.
2021-06-28 11:34:11 -04:00
Jarrod Johnson f830514d10 Implement support for additional pam prompts
For example, if PAM has OTP, then support it.
2021-06-25 17:26:32 -04:00
Jarrod Johnson f2eba22b9b Fix TLS certs for el8 diskless
Properly place and process
the TLS certs for a site.
2021-06-25 13:06:35 -04:00
Jarrod Johnson 1fcab688dd Fix connection name in networkmanager diskless 2021-06-25 10:56:35 -04:00
Jarrod Johnson abfa2c4f7c Switch back to default curl output
The terminal size on console is a challenge.
2021-06-24 17:01:35 -04:00
Jarrod Johnson 3be73af07e Change style of download progress in curl
Use a simpler progress bar.
2021-06-24 16:46:10 -04:00
Jarrod Johnson a2b2c8a995 Remove extraneous '/' output
Suppress output of cd -, as
it's a bit odd during boot.
2021-06-24 15:57:03 -04:00
Jarrod Johnson 42f8056d56 Fix apiclient with TPM managed token
The retry mechanism is amended
to clear out the useless key
and start trying to get a network grant again.
2021-06-24 14:53:54 -04:00
Jarrod Johnson 2ef695324a Migrate genesis to new TPM strategy
Have addons for genesis
implement the same TPM usage
model as the suse/redhat stateless.
2021-06-24 14:35:21 -04:00
Jarrod Johnson 4c6f0843f9 Remove microcode from genesis
Should not be needed for genesis level activity, and consumes a large
amount of storage.
2021-06-24 14:00:19 -04:00
Jarrod Johnson c19ae8a451 Add tpm2 tools to genesis
Follow the design of the stateless usage of TPM
2021-06-24 13:20:47 -04:00
Jarrod Johnson a8e152cc4a Switch TPM strategy on RedHat diskless
Switch to thte same approach as used in suse:
-Try to unseal any persistent handles
-If that works, try to use it on network
-If it didn't work, clear that handle
-When an api key is retrieved, then seal it to pcr 15
-When it's all done, extend pcr15 to prevent the OS from being able to
unseal
2021-06-24 12:04:10 -04:00
Jarrod Johnson c92b3aea9d Mitigate error output from extraneous handles
Unrelated handles in use will no longer result in misleading console
output.
2021-06-24 11:41:34 -04:00
Jarrod Johnson 5be4a5ab73 Add missing TPM utilities to suse boot 2021-06-24 11:22:41 -04:00
Jarrod Johnson 3c41c52d77 Rework TPM usage in SUSE diskless
For one, need to detect stale
TPM value and clear them.

For another, seal to PCR 15 and extend after unlock, so that the booted
system is unable to retrieve
the data from the TPM (e.g.
a plain user by default is allowed
to unseal data if there's no
policy, so use a policy and
extend the state away before boot)
2021-06-24 11:09:37 -04:00
Jarrod Johnson e24a3a7231 Change media_url
Have autoyast file pass validation and adapt
the processing to work with it.
2021-06-24 08:27:55 -04:00
Jarrod Johnson bffb7a8cac Correct typo in suse install autoconsole message 2021-06-23 17:52:21 -04:00
Jarrod Johnson feb418ac59 Store TPM unsealed apikey in usual location 2021-06-23 17:22:18 -04:00
Jarrod Johnson ee5ea4263f Add curl to suse15 pkglist 2021-06-23 17:16:13 -04:00
Jarrod Johnson b30fabd55d Enable TPM2 on SUSE diskless for apikey
Rather than remote sealed copy, store it in the TPM2

Will convert genesis and EL diskless for this to be the new preferred
mechanism.
2021-06-23 17:01:27 -04:00
Jarrod Johnson b8c9e9c535 Begin work to support complex PAM conversations
For example, TOTP setups need
more prompts, this will pass
the info to the client for the client to adjust.
2021-06-23 16:31:42 -04:00
Jarrod Johnson d86fc664e9 Handle space delimiting in nameservers
If multiple dns servers, then need to quote to preserve
the list.
2021-06-23 12:35:54 -04:00
Jarrod Johnson 6862d9e580 Correct formatting of nameserver list in suse 2021-06-23 12:26:49 -04:00
Jarrod Johnson dc8cb1b13f Correct syntax in imageboot for suse 2021-06-23 12:24:36 -04:00
Jarrod Johnson f10d2af59f Specify netconfig file location 2021-06-23 12:16:08 -04:00
Jarrod Johnson 172bb12885 Modify Suse diskless for suse networking
Suse doesn't use network manager, populate sysconfig
instead.
2021-06-23 12:07:13 -04:00
Jarrod Johnson 4445b8cc78 Fix name resolution for suse hosts/containers
Suse uses a strategy with symlinks, adapt
the resolv.conf target based on findings from
symlink chasing.
2021-06-23 11:49:16 -04:00
Jarrod Johnson b2fa2d92c5 Correct formatting mistake in os profile label in diskless 2021-06-23 11:32:43 -04:00
Jarrod Johnson fc19ca4e36 Change to pythton-dnspython for dependency
Multiple compatible packages exist that provide same name, accept
either.
2021-06-23 08:37:00 -04:00
Jarrod Johnson 23231e2b75 Have Suse15 diskless prep initrd and enable sshd 2021-06-22 16:59:12 -04:00
Jarrod Johnson 9ad5f52eed Package up suse diskless support 2021-06-22 16:37:04 -04:00
Jarrod Johnson 76f3537a79 Further advance SUSE15 diskless support 2021-06-22 16:18:32 -04:00
Jarrod Johnson b26b46dc41 Crate dracut module for suse15 2021-06-22 14:49:15 -04:00
Jarrod Johnson deec9b111a Initial phase of suse diskless support 2021-06-22 14:29:28 -04:00
Jarrod Johnson 59e6dc80b3 Remove commented, non-working concept code
The code was going to replace XInclude with something more manual
from sed and xml comments, but yast strips the comments.

So we instead manually make hooks for the replacement items.
2021-06-22 12:21:18 -04:00
Jarrod Johnson e34d76f7eb OpenSUSE 15.3 support
A number of changes in opensuse 15.3 require modifying our
strategy.

No more XInclude. This seems to be unintentional, but it released
and so we will work around it.

Some somewhat incorrect values, as pointed out by new validation.
2021-06-22 12:19:54 -04:00
vmaneagit 7f74476e5a Update nodepower
Updated line 35 to address the syntax mismatch between usage and man page SYNOPSIS
2021-06-16 18:25:10 +03:00
vmaneagit d201358c78 Update nodepower.ronn
Updated lines 6 and 30 to address the syntax mismatch between usage and man page SYNOPSIS
2021-06-16 18:19:49 +03:00
vmaneagit 902f9831cd Update noderun.ronn
Updated line 6 to address the syntax mismatches between usage output and man page SYNOPSIS
Line 18 has been updated to address the options listed differently between usage output and man page
2021-06-16 17:36:56 +03:00
vmaneagit 3723eadcfc Update noderun
Syntax mismatches between usage output and man page SYNOPSIS

Updated line 42:

        usage="Usage: %prog [options] <noderange> <command expression>",
2021-06-16 17:33:26 +03:00
vmaneagit 52d7bcbdb9 Update nodersync
Updated line 43:

        usage="Usage: %prog <file/directorylist> <noderange>:<destination>",

Syntax mismatch between usage output and man page SYNOPSIS
2021-06-16 17:23:18 +03:00
vmaneagit f33e35cebf Update nodersync.ronn
Updated line 15:

* `-f COUNT`, `-c COUNT`, `--count=COUNT`:

Options on SYNOPSIS page different than usage options
2021-06-16 17:23:03 +03:00
vmaneagit 2f00b31eb0 Update noderemove
Updated line 36:

    usage='''\n       %prog <noderange>

SYNOPSIS has < > around noderange whereas usage output does not
2021-06-16 17:11:11 +03:00
vmaneagit bbad704f43 Update nodelicense.ronn
Updated the syntax mismatch between usage output and man page SYNOPSIS

Line 6 was modified:

`nodelicense <noderange> [list][install <filename>|save <directory>|delete <license>]`
2021-06-16 16:58:21 +03:00
vmaneagit a05a95433d Update nodelicense
Fixing syntax mismatch between usage output and man page SYNOPSIS

Updated line 39

          "%prog <noderange> [list][install <filename>|save <directory>|delete <name>]")
2021-06-16 16:49:53 +03:00
vmaneagit 15d4247cf1 Update nodeeventlog
usage output doesn't have < > around noderange were as SYNOPSIS on man page does

Usage: nodeeventlog [options] noderange [clear]
SYNOPSIS: nodeeventlog [options] <noderange> [clear]

Line 40 has been updated:

    usage="Usage: %prog [options] <noderange> [clear]")
2021-06-16 16:17:08 +03:00
vmaneagit 4b45c148c8 Update nodeconfig.ronn
Updated the Syntax mismatch between usage output and man page SYNOPSIS

Options -b settings.batch, --batch=settings.batch and 
-r COMPONENT, --restoredefault=COMPONENT

were only shown as -b, --batch and -r, --restoredefault
2021-06-16 15:30:01 +03:00
vmaneagit 47a8da5ed0 Update nodeconfig
updated line 46:
argparser = optparse.OptionParser(usage="Usage: %prog [options] <noderange> [setting|setting=value]")
to match the man SYNOPSIS

nodeconfig [options] <noderange> [setting|setting=value]
2021-06-16 15:26:28 +03:00
Jarrod Johnson f0693f6ee5 Correct typo in imgutil 2021-06-15 13:45:27 -04:00
Jarrod Johnson 84634afc9c Improve imgutil brevity
Allow it to take only the basename and
default to likely /var/lib/confluent locations
Draft work on tab completion for imgutil.

Technically the tab completion should be in the imgutil package,
but for now bundle with server.
2021-06-15 13:30:30 -04:00
Jarrod Johnson 5621d48ffa Fix syntax error with new check 2021-06-15 12:23:45 -04:00
Jarrod Johnson 55a4211e71 Fix imgutil volume mounting 2021-06-15 12:12:27 -04:00
vmaneagit 03b644be7f Update confluentdbutil.ronn
Man page is missing part of the password option as shown under usage

from usage output:
-p PASSWORD, --password=PASSWORD
2021-06-15 17:28:30 +03:00
Jarrod Johnson 802ba9c708 Merge pull request #60 from vmaneagit/patch-61
Update collective.ronn
2021-06-15 09:42:48 -04:00
Jarrod Johnson 490827fe3a Allow memory reclamation through deletion
When going to zram, things were solid for space reduction as
data was written, however memory could no longer be reclaimed.

It turns out that zram supports TRIM, and by telling xfs discard,
we have it do trim-on-demand. It is by default off out of performance
concerns, but I don't think that applies to a zram backed filesystem.
2021-06-15 09:36:44 -04:00
vmaneagit 85568091fa Update collective.ronn
Added correction  for:

"collective gencert collective delete" should be on 2 separate lines.

correction should be:

collective gencert
collective delete
2021-06-15 16:25:26 +03:00
Jarrod Johnson 2ecab0432c Fix imageboot.sh issues for diskless boot 2021-06-15 08:58:21 -04:00
Jarrod Johnson dee03e1359 Attempt to updateboot at end of pack 2021-06-15 08:41:33 -04:00
Jarrod Johnson 3f87696978 Fix typo in imageboot.sh script 2021-06-15 08:38:27 -04:00
Jarrod Johnson 38a4e20b9a Fix issues around imageboot and source in functions 2021-06-15 08:31:45 -04:00
Jarrod Johnson 1d8d0699bc Fix ability to copy profiles during pack 2021-06-15 08:11:31 -04:00
Jarrod Johnson 62ac393721 Fix imgutil profile path and osdeploy diskless layout 2021-06-15 08:00:09 -04:00
Jarrod Johnson 1d148afd70 Add sourcing of functions to dracut hook 2021-06-14 18:46:36 -04:00
Jarrod Johnson e6550d8160 Fix use of label in profile.yaml 2021-06-14 16:55:32 -04:00
Jarrod Johnson 0079e5c437 Change imgutil packaging and pkglist path 2021-06-14 16:46:23 -04:00
Jarrod Johnson cce2c6d6db Add missing Release and remove stale binaries from git 2021-06-14 16:16:19 -04:00
Jarrod Johnson e32e40f451 Correct build script typo 2021-06-14 16:14:13 -04:00
Jarrod Johnson e50423881d Correct spec name in imgutil build script 2021-06-14 16:12:43 -04:00
Jarrod Johnson 82b94e3ff9 Add build script for imgutil 2021-06-14 16:12:01 -04:00
Jarrod Johnson 03cb065342 Fix inconsistency with naming of profiles 2021-06-14 16:09:48 -04:00
Jarrod Johnson cb4b8ab06f First pass at packaging imgutil 2021-06-14 16:02:52 -04:00
Jarrod Johnson ac2474f43e Attempt to fixup ownership, if applicable on the output 2021-06-14 15:17:54 -04:00
Jarrod Johnson e678ca24f9 Attempt to pull in osdeploy profile information 2021-06-14 14:59:59 -04:00
Jarrod Johnson 60aef0767c Pull in the diskless profile content for os deploy 2021-06-14 14:38:38 -04:00
Jarrod Johnson 15f5ec9362 Rename common to 'default' 2021-06-14 14:37:40 -04:00
Jarrod Johnson 870c8255f4 Move diskless to el8-diskless
The code so far is EL8 specific, properly
organize it.
2021-06-14 14:36:23 -04:00
Jarrod Johnson 795645f90a Extract boot logic from 'addons.cpio'
Make it easier to see and customize image boot script
behavior, leaving addons.cpio only to bring up network
and set up ssh.
2021-06-14 14:33:35 -04:00
Jarrod Johnson 99a42af907 Add zram module to stateless images 2021-06-14 14:31:57 -04:00
Jarrod Johnson 24d33256ca Fix typo in dracut configuration 2021-06-14 13:45:44 -04:00
Jarrod Johnson 334ec3a74f Refactor for multi-os support and improve initramfs experience
Organize el8 specific content to separate spaces for future
development of other OS support

Also, make the diskless initramfs a natural result of
dracut activity, so that normal rpm updates and oob driver
installs produce the expected initramfs without further
intervention.
2021-06-14 13:09:25 -04:00
Jarrod Johnson 261def8de2 Rename and refactor imgutil to separate rpm 2021-06-14 07:39:01 -04:00
Jarrod Johnson 25f65a278f Notation on untethered option 2021-06-11 16:18:59 -04:00
Jarrod Johnson f565030087 Switch to zram for overlay
Further mitigate unevictable memory penalty
for written files in stateless.
2021-06-11 16:16:17 -04:00
Jarrod Johnson 8edd2a28e4 Merge branch '3.2' 2021-06-10 18:51:56 -04:00
Jarrod Johnson 7122c17ce0 Remove pyte requirement
We no longer use pyte, remove the requirement.
2021-06-08 16:43:06 -04:00
Jarrod Johnson 14bb841b2d Fix nodebmcreset partial success
The error handling is improved, to
catch both noderange global issues as well
as partial completions.
2021-06-08 09:13:56 -04:00
Jarrod Johnson f5f16dac7a Fix nodebmcreset partial success
The error handling is improved, to
catch both noderange global issues as well
as partial completions.
2021-06-08 09:12:33 -04:00
Jarrod Johnson fa3220f3d1 Actually fix up the osdeploy build
For now, stub out the diskless profile dir, which doesn't quite
exist yet.
2021-06-04 17:45:52 -04:00
Jarrod Johnson 14bc4df92e Fix path mistake in osdeploy build script 2021-06-04 17:33:14 -04:00
Jarrod Johnson 1645d47b73 Fix clortho
The suggested correection for clortho was in fact
incorrect.  Revert back and cast it.
2021-06-04 17:19:19 -04:00
Jarrod Johnson bbe9bc3e06 Constrain plugin collections to flat by default
When asking for a path that exceeds the plugincollection,
thten provide generic 'not found' behavior.
2021-06-04 14:48:31 -04:00
Jarrod Johnson 03a75ec67d Error if noderange includes too many )
By default, pyparsing consumes only as much of the
input as matches the grammar. Tell it to consume all
of the noderange and error if there's more string than
matches our grammar.
2021-06-04 14:21:45 -04:00
Jarrod Johnson 58157b23d7 Error if noderange includes too many )
By default, pyparsing consumes only as much of the
input as matches the grammar. Tell it to consume all
of the noderange and error if there's more string than
matches our grammar.
2021-06-04 14:19:06 -04:00
Jarrod Johnson 269300119a Skip newer agent behaviors with incompatible old ssh
The previous attempt to support older ssh failed to completely
enact old behavior when needed.
2021-06-04 13:41:47 -04:00
Jarrod Johnson b8ddf149bd Skip newer agent behaviors with incompatible old ssh
The previous attempt to support older ssh failed to completely
enact old behavior when needed.
2021-06-04 13:40:39 -04:00
Jarrod Johnson bf158bc5aa Prep for diskless specific profile categories 2021-06-03 18:20:47 -04:00
Jarrod Johnson 8228c345bc Fix the build path of the stateless path 2021-06-03 18:12:18 -04:00
Jarrod Johnson 8eecd03d4b Correct path name in build process 2021-06-03 17:50:01 -04:00
Jarrod Johnson 044ae53ae3 Add symlink for site, and placeholder for addons
Will need to detect the proper 'category' for
the addons link.
2021-06-03 17:20:41 -04:00
Jarrod Johnson 1a30876a2d Begin work to package diskless support
First will work on the 'addons' portion of the needed
work.
2021-06-03 17:17:42 -04:00
Jarrod Johnson e0c59cc341 Fixup c utilities and add start_root
The diskless will use start_root to boot the 'main' OS as a container.
2021-06-03 17:06:10 -04:00
Jarrod Johnson 93c21d4148 Commit to python3 ofr imgutil
The imgutil will never be supported with python2,
so we will go ahead and commit to python.
2021-06-03 16:52:22 -04:00
Jarrod Johnson e23a88a4c3 Have resolv.conf more reliably work
Also, make sure it is read-only in the exec case
2021-06-03 15:47:17 -04:00
Jarrod Johnson 1289f95584 Merge branch '3.2' 2021-06-03 14:22:38 -04:00
Jarrod Johnson db965f133e Add a 'pack' and attempt to bind /etc/resolv.conf on exec
This facilitates custom manual image work
2021-06-02 17:26:46 -04:00
Jarrod Johnson a2edf46b8a Improve ctrl-c and other behaviors of osdeploy import
More reliably delete an import attempt to avoid odd behaviors.
2021-05-27 16:10:55 -04:00
Jarrod Johnson 2073926256 Improve ctrl-c and other behaviors of osdeploy import
More reliably delete an import attempt to avoid odd behaviors.
2021-05-27 16:10:06 -04:00
Jarrod Johnson 734e12f0f1 Amend long wait to only apply to shutdown
The previous 30 seconds was a good amount to
wait for everything but a graceful shutdown.

The new 5 minute wait is too long to wait to
find out a system can't turn on.

Apply the 5 minute wait only on clean shutdown
request.
2021-05-27 09:57:07 -04:00
Jarrod Johnson deb2b98e7f Merge pull request #59 from zhougj4/master
[merge-LXCA] pull request
2021-05-27 09:54:44 -04:00
Zhou Guangjun 32c84993b0 [merge-LXCA] fix problem in merge with upstream - htmlify the dict
Details:
Revision: d9cc888e68abe7794ade82a251c4dffe9108a014
Author: Michael Du <duxd2@LENOVO.COM>
Date: 2017/8/2 21:06:22
2021-05-27 09:58:05 +08:00
Jarrod Johnson 48ff1fd12c Fix background mode of urlmount
Need the recheck thread managed in the background process if using
urlmount the normal way.
2021-05-26 18:21:06 -04:00
Jarrod Johnson bca5d9497f Implement failback facility
Treat the url list as an ordered list of priority. Occasionally check
the more preferred paths for health if they had been detected as bad.
2021-05-26 17:54:33 -04:00
Jarrod Johnson 9be039b8e5 Continue advancing the img build and exec utility 2021-05-26 15:18:01 -04:00
Jarrod Johnson a3266ad01c Begin next draft of genimage
Write in python and support sourcing
only from local directories if desired.
2021-05-25 17:27:07 -04:00
Jarrod Johnson 74e011e964 Implement node name subtitution in nodeshell
If wanting to ssh to 'altenative interfaces', provide -s to facilitate that
behavior, with added flexibility
compared to previous incarnations.
2021-05-25 15:46:49 -04:00
Jarrod Johnson e1a4f370b2 Implement node name subtitution in nodeshell
If wanting to ssh to 'altenative interfaces', provide -s to facilitate that
behavior, with added flexibility
compared to previous incarnations.
2021-05-25 15:46:22 -04:00
Jarrod Johnson 66372bea0c Fix hang on ctrl-e,c,p,o
Leave the function to
consume termdata if data
is available.
2021-05-25 14:27:37 -04:00
Jarrod Johnson a7e7e647f3 Fix hang on ctrl-e,c,p,o
Leave the function to
consume termdata if data
is available.
2021-05-25 14:26:49 -04:00
Jarrod Johnson 9bdef5bbb9 Fix typo in confetty 2021-05-25 11:58:20 -04:00
Jarrod Johnson d250a3e850 Fix typo in confetty 2021-05-25 11:58:01 -04:00
Jarrod Johnson 49b69a2e19 Explicitly provide content-length 0 on 204
For some vintages of eventlet+apache, this is required
to avoid invalid responses from the server.
2021-05-25 10:19:11 -04:00
Jarrod Johnson af10e0ea91 Explicitly provide content-length 0 on 204
For some vintages of eventlet+apache, this is required
to avoid invalid responses from the server.
2021-05-25 10:18:13 -04:00
Jarrod Johnson 8455d30687 Disable selinux for now in a built image 2021-05-24 18:30:48 -04:00
Jarrod Johnson 903160f748 Fix the draft genimage script 2021-05-24 17:37:47 -04:00
Jarrod Johnson 52005dd6ae Further flesh out diskless profile 2021-05-24 16:20:54 -04:00
zhougj4 7363af866f Merge branch 'lenovo:master' into master 2021-05-24 10:46:50 +02:00
Jarrod Johnson 9ca42081de Try to add onboot service to diskless
It didn't quite work yet, but commit the progress so far.
2021-05-21 17:07:32 -04:00
Jarrod Johnson 6c6b766f37 Fix non-root node to node ssh in diskless 2021-05-21 13:18:29 -04:00
Jarrod Johnson a9b412fb81 Add node to node ssh to diskless 2021-05-21 12:41:58 -04:00
Jarrod Johnson 7c4b500e92 Add boot.img function to CoreOS 2021-05-21 11:11:01 -04:00
Jarrod Johnson 31ca787380 Register the service as needed for startup in CoreOS init 2021-05-21 07:50:50 -04:00
Jarrod Johnson 0ee67b8584 Mak the script executable for coreos bringup 2021-05-21 07:48:25 -04:00
Jarrod Johnson 19874d8032 Add coreos support to build 2021-05-21 07:32:47 -04:00
Jarrod Johnson 086def0bb8 Updates to the coreos support
Bring in and let ignition do the driving if the import had one.
2021-05-20 17:33:22 -04:00
Jarrod Johnson 9ac4cf0641 Rename generically to coreos
We should be able to support either RH or Fedora
flavors.
2021-05-19 17:28:05 -04:00
Jarrod Johnson 52b39e632d Draft CoreOS support
Preliminary work toward supporting CoreOS
2021-05-19 17:12:56 -04:00
Jarrod Johnson e167949db2 Fix comments and improve randomness
Since the granularity on time could cause a boot to
select the same 'random' entry, use better seed
for rand()
2021-05-19 11:05:58 -04:00
Jarrod Johnson 4ed9219704 Fix overruning the urls buffer
Technically, MAX_URL_PATHS would be one past the
buffer allocated, so it needs to stay under
that value.
2021-05-19 09:22:13 -04:00
Jarrod Johnson 5e1c366e0b Publish urlmount.c as 'misc'
It hasn't been packaged yet, but make it public while getting
ready to package.
2021-05-19 09:03:06 -04:00
Jarrod Johnson 85c3ca8c75 Pass root password onto diskless if set
This honors the administrator
setting the password in the
confluent database for the diskless node.
2021-05-18 15:25:26 -04:00
Jarrod Johnson a1ddb2323a Have networkmanager be content with diskless
Create an .nmconnection file
that sastisfies networkmanager
about the interface that confluent brought up.
2021-05-18 15:24:43 -04:00
Jarrod Johnson 93d4847763 Conditionally apply agent to sshutil
Older OSes (RHEL7/SLES12) cannot
do ssh-keygen with an agent.

Degrade to classic confluent behavior when that happens.
2021-05-18 12:28:42 -04:00
Jarrod Johnson efd7f1de63 Conditionally apply agent to sshutil
Older OSes (RHEL7/SLES12) cannot
do ssh-keygen with an agent.

Degrade to classic confluent behavior when that happens.
2021-05-18 12:28:22 -04:00
Jarrod Johnson b283b50cc6 Improve error on nodeconfig parse errors
The current error is vague and confusing, clarify with
more data showing what went wrong.
2021-05-18 10:34:09 -04:00
Jarrod Johnson b63565972b Improve error on nodeconfig parse errors
The current error is vague and confusing, clarify with
more data showing what went wrong.
2021-05-18 10:33:27 -04:00
Jarrod Johnson bb1559c8a2 Add support for Intel E810 (ice) to confluent genesis 2021-05-18 09:56:02 -04:00
Jarrod Johnson a93a8d5cd1 Add ice driver to default diskless images 2021-05-18 09:55:27 -04:00
Jarrod Johnson 1f320af8e5 Add error message for long profile names
If a profile name pushes the filename field of dhcp
beyond what it can support, log an event and
do not offer a corrupted
dhcp offer packet.
2021-05-18 09:44:27 -04:00
Jarrod Johnson af06c150b0 Add error message for long profile names
If a profile name pushes the filename field of dhcp
beyond what it can support, log an event and
do not offer a corrupted
dhcp offer packet.
2021-05-18 09:44:02 -04:00
Jarrod Johnson 7e14b41ef4 Fix typo in the genimage script 2021-05-14 16:40:48 -04:00
Jarrod Johnson 9c8529e9b4 Fix network interface names in confluent diskless 2021-05-14 16:36:43 -04:00
Jarrod Johnson 90daf5d5e3 Further advance the confluent diskless support 2021-05-14 15:58:57 -04:00
zhougj4 a28cd1055f Merge branch 'lenovo:master' into master 2021-05-14 08:07:23 +02:00
Jarrod Johnson 103b398629 Begin work to use urlmount 2021-05-13 18:58:37 -04:00
Jarrod Johnson 5fea265dc8 Change CSV to have unix style line endings
The excel dialog has nice minimal quoting, but DOS line endings.

Unix dialog has good line endings, but excessive quoting.

Create a hybrid dialect and use it for nodesensors output.
2021-05-13 10:39:03 -04:00
Jarrod Johnson cc9bb0533d Change CSV to have unix style line endings
The excel dialog has nice minimal quoting, but DOS line endings.

Unix dialog has good line endings, but excessive quoting.

Create a hybrid dialect and use it for nodesensors output.
2021-05-13 10:38:02 -04:00
Zhou Guangjun 32db72e38f [merge-LXCA] (138083) [ipmi] Restart Normally and Power off Normally job failed with the message Ensure that the endpoint is reachable on the network from LXCA
Details:
Revision: d02e5b653f764aeca44efd108acaabc8b173b482
Author: Zhou Guangjun <zhougj4@lenovo.com>
Date: 2018/10/17 17:26:39
2021-05-13 14:34:02 +08:00
Jarrod Johnson 51dece94ab Add draft for what will be genimage
Still very much prototype, but put it in github
to prepare to bring it together.
2021-05-12 18:13:55 -04:00
Jarrod Johnson 689418c8f1 Merge remote-tracking branch 'lenovo/master' 2021-05-12 17:32:51 -04:00
Jarrod Johnson b74d648e7f Fix refactored inline command run
This addresses the mistake in
refactoring the inline command
shortcut
2021-05-12 13:49:06 -04:00
Jarrod Johnson df2604291d Fix refactored inline command run
This addresses the mistake in
refactoring the inline command
shortcut
2021-05-12 13:48:44 -04:00
Jarrod Johnson 9b7a40a358 Merge pull request #58 from zhougj4/master
[merge-LXCA] Add support for graphical consoles
2021-05-12 07:31:50 -04:00
Zhou Guangjun 9648f1c8ac [merge-LXCA] Add support for graphical consoles
Details:
Revision: a0f0309ee0bc731463794da9d685fa56bc62bc6f
Author: Allan Vidal <avidal@lenovo.com>
Date: 2015/11/26 3:50:31
2021-05-12 10:49:13 +08:00
Jarrod Johnson 9f45b0ed56 Draft support for stateless images
Aim is to support a few modes of operation:
-tar.xz, extracted to memory (most inefficient, least dependency)
-nfs read-only (less secure, more efficient, depends on getting nfs
export just right)
-nfs image read-only (same as above, but using squashfs to make overlay
more easily happily)
-gocryptfs on nfs (this provides encryption and integrity check)
2021-05-11 17:05:12 -04:00
Jarrod Johnson 380f21853c Merge branch 'master' into 3.2 2021-05-11 08:10:41 -04:00
Jarrod Johnson 9900d76b0c Merge remote-tracking branch 'lenovo/master' 2021-05-11 08:09:57 -04:00
Jarrod Johnson aa7701ea3c More usefully indicate unfound interfaces
Rather than no data, provide
not found error when requesting a currently unsupported name.
2021-05-11 08:02:19 -04:00
Jarrod Johnson 3044c662ad Merge pull request #55 from vmaneagit/patch-45
Update nodesupport.ronn
2021-05-11 07:59:24 -04:00
Jarrod Johnson 7e02d1d008 Merge pull request #57 from vmaneagit/patch-43
Update collective.ronn
2021-05-11 07:56:55 -04:00
Jarrod Johnson f321e06e6e Merge pull request #51 from vmaneagit/patch-49
Update nodersync.ronn
2021-05-11 07:50:47 -04:00
Jarrod Johnson 5c0af9ebc7 Merge pull request #50 from vmaneagit/patch-50
Update nodersync.ronn
2021-05-11 07:50:18 -04:00
Jarrod Johnson c146b50b5b Merge pull request #49 from vmaneagit/patch-51
Update nodereseat.ronn
2021-05-11 07:49:37 -04:00
Jarrod Johnson cae8b2d0f8 Merge pull request #48 from vmaneagit/patch-52
Update noderemove.ronn
2021-05-11 07:49:24 -04:00
Jarrod Johnson 2664adefa4 Merge pull request #47 from vmaneagit/patch-53
Update nodepower.ronn
2021-05-11 07:49:10 -04:00
Jarrod Johnson c5f03ee62d Merge pull request #46 from vmaneagit/patch-54
Update nodelicense.ronn
2021-05-11 07:49:00 -04:00
Jarrod Johnson a932e91b17 Merge pull request #45 from vmaneagit/patch-56
Update nodegroupattrib.ronn.tmpl
2021-05-11 07:48:45 -04:00
Jarrod Johnson 1c00aa3c4e Merge pull request #44 from vmaneagit/patch-57
Update confetty.ronn
2021-05-11 07:48:35 -04:00
Jarrod Johnson bd889f4c78 Merge pull request #43 from vmaneagit/patch-58
Update collate.ronn
2021-05-11 07:48:17 -04:00
Jarrod Johnson 409a0796a1 Merge pull request #42 from vmaneagit/patch-59
Update nodesupport.ronn
2021-05-11 07:48:04 -04:00
Jarrod Johnson 70ffef6b06 Merge pull request #41 from vmaneagit/patch-55
Update nodelicense.ronn
2021-05-11 07:47:53 -04:00
Jarrod Johnson 77a043faa6 Change apiclient to append if outputting to existing file 2021-05-05 17:45:39 -04:00
Jarrod Johnson d69eb6ef12 Change apiclient to append if outputting to existing file 2021-05-05 17:45:04 -04:00
Jarrod Johnson 984c3044fe Invalidate sealed token on new token
If a new token grant occurs, do not
retain stale token sealed, as it can be misleading.
2021-05-05 09:18:28 -04:00
Jarrod Johnson 8543129fb9 Invalidate sealed token on new token
If a new token grant occurs, do not
retain stale token sealed, as it can be misleading.
2021-05-05 09:17:42 -04:00
Jarrod Johnson 257edff3a7 Redo ssh certs on firstboot for SUSE
For whatever reason, SUSE loses the certificate during firstboot.
2021-05-03 16:47:24 -04:00
Jarrod Johnson 763feda63b Fix missed references to old variable names 2021-05-03 15:54:39 -04:00
Jarrod Johnson 508e5b4a46 Fix suse run_remote_parts
Behave more consistently
2021-05-03 15:36:27 -04:00
Jarrod Johnson 7676c4fd26 Restore EL8 treatment
The changes caused EL8 to lose some required special treatment.
2021-05-03 15:18:33 -04:00
Jarrod Johnson c3b954a743 Move suse15 to log like rhel 2021-05-03 14:50:04 -04:00
Jarrod Johnson a94a341582 Fix ansible path compatibility. 2021-05-03 14:31:28 -04:00
Jarrod Johnson 08dfd55ea0 Rename variables in the ubuntu initramfs portion 2021-05-03 13:28:28 -04:00
Jarrod Johnson cf6975ded3 Fix python2/3 handling in el8 pre.sh 2021-05-03 13:11:52 -04:00
Jarrod Johnson d17b1d060c Prepend confluent_ to vars and switch to explicitly requesting directory
The 'profile' variable notably induces dracut to be excruciatingly slow,
mitigate chance by putting confluent before apikey, mgr, and profile.

Further, it has been requested to have the scripts use same name on
server for directory moving forward. Implement this request while
allowing existing OS profiles to keep working.
2021-05-03 12:48:08 -04:00
Jarrod Johnson fcb4b33e8e Include stderr in the script execution logs 2021-05-03 08:57:59 -04:00
Jarrod Johnson 121e0727cf Add Rocky linux recognition 2021-05-03 08:36:57 -04:00
Jarrod Johnson b5b9631b3f Correct typo in pre script 2021-04-30 16:27:16 -04:00
Jarrod Johnson c09f96b8c9 Remove pivot_root from genesis
It is not used (if we did use something, it would be switch_root).
2021-04-30 16:20:58 -04:00
Jarrod Johnson 196ed31bee Retry node api token retrieval, with message 2021-04-30 15:17:02 -04:00
Jarrod Johnson bb05f72583 Add source_remote_parts
This function will enable a script to invoke multiple
pieces in same variable/function context
2021-04-30 14:33:02 -04:00
Jarrod Johnson 68b4f83627 Have firstboot script be logged better
Also show on screen firstboot script execution.
2021-04-30 14:08:42 -04:00
Jarrod Johnson 672bc4f754 Amend postscript logging strategy
This adjusts to avoid hangs in
anaconda
2021-04-30 13:38:31 -04:00
Jarrod Johnson 4df3fda8ea Change logging/display for RH oses
The pre and post phases are
desirable to see both in logs and consoles.

Unfortunately, anaconda cheaps out by using communicate(), which means
the logs are unwritten until the end.

Change by using bash's redirectiors
to create a dynamically updated logfile
and tail -f that.
2021-04-30 09:39:00 -04:00
Jarrod Johnson f32619aa3e Allow firstboot to reboot in RH postscripts
Sometimes firstboot scripts want to reboot.

In such a case, start firstboot once, and if reboot prevents completion,
then next boot will updatestatus, but not run firstboot scripts and
deregister itself.
2021-04-29 09:20:24 -04:00
Jarrod Johnson dd7b9f0244 Bump genesis version 2021-04-28 16:44:24 -04:00
Jarrod Johnson def534e73f Fixes for boot by DHCP and by MAC 2021-04-28 16:43:11 -04:00
Jarrod Johnson 2cb641e734 Fix PXE based on mac
We normally use UUID, on a broken platform with bad UUID,
user may need to use hwaddr.  This was supposed to work, but
didn't. Fix it to work correctly.
2021-04-28 15:36:12 -04:00
Jarrod Johnson ca78b664c9 Get rid of minor warning about RSAAuthentication 2021-04-28 14:06:57 -04:00
Jarrod Johnson 0e55d390e3 Fix up post output to console 2021-04-28 13:46:26 -04:00
Jarrod Johnson 002146b2f7 Try to output pre/post content to console during install 2021-04-28 13:27:34 -04:00
Jarrod Johnson 917a51a406 Error if bind to privileged port fails 2021-04-28 08:37:23 -04:00
Jarrod Johnson d3fa08d78b Amend syncfiles to handle directory targets better
Rather than using symlinks for directories, recursively recreate tree
and symlink only the non-directory
entries.

This improves mixing and matching
files and directories to target a directory.
2021-04-27 12:48:27 -04:00
Jarrod Johnson 38eb88249e Permit wildcard in syncfiles
This was a supported and used feature in xCAT
syncfiles, carry it into confluent syncfiles.
2021-04-27 09:12:11 -04:00
Jarrod Johnson c333c3eb9c Fix missing data on XCC discovery
The XCC scan now calls the
imm scan to fill out the lost data.
2021-04-26 08:57:52 -04:00
Jarrod Johnson f32a9a2f08 Rework inline command handling
Previously, if hotkey entry
had text data come in, it
would corrupt the state of
the client.

Minimize the corruption and request the server to pause.
2021-04-23 14:22:24 -04:00
Jarrod Johnson f584b9bc11 Protect against binary sealed data
It was detected that binary sealed data
could happen. Ensure that it is str
before passing to configuration.
2021-04-23 14:17:54 -04:00
Jarrod Johnson affbbcc89b Fix syncfiles for el7 2021-04-23 12:27:42 -04:00
Jarrod Johnson 45cc4b7788 Add documentation syncfiles examples
Also, check to make sure a syncfiles has actual
work to do before triggering a greenthread and
the client to start polling.
2021-04-23 11:09:35 -04:00
Jarrod Johnson 945f108548 Fix inconsistencies between el7 and el8
While there are still differences, minimize
the ones that aren't for specific reasons
2021-04-23 09:08:50 -04:00
Jarrod Johnson 1f9c440525 Handle non-utf8 console data
Sometimes console uses non-utf8.

Fallback to cp437 when utf8 fails us.
2021-04-22 15:14:52 -04:00
Jarrod Johnson 8397c5defc Only close datfile if datfile is a file
If going by filename alone, there will be
no file handle to close. Correct by not
attempting a close in such a case.
2021-04-22 13:55:10 -04:00
Jarrod Johnson b7af6b5c27 Add model name to discovery info
Sometimes the model name is
useful criteria for evaluating systems,
and the model number isn't
quite that handy.

For XCC, we can provide this data too. Provide it in xcc scan
method and then offer it up to clients.
2021-04-22 13:38:51 -04:00
Jarrod Johnson c38aac88df Avoid overwriting customized installdisk or partitioning 2021-04-22 12:12:58 -04:00
Jarrod Johnson 6d1348f5fa Add pre.d to EL8 profiles 2021-04-22 12:08:25 -04:00
Jarrod Johnson c05f18d865 Remove abortive custom names for pre.sh.custom 2021-04-22 11:48:05 -04:00
Jarrod Johnson bf00c75f43 Specify supported protocols to be confluent.console
Eventlet will return no supported protocols if
none are specified. Firefox doesn't care, but
chrome rejects such a reply.
2021-04-22 07:44:18 -04:00
Jarrod Johnson 2e04647c95 Add xz to confluent genesis
xz provides better compression than gzip, handy
to have as an option.
2021-04-21 16:59:33 -04:00
Jarrod Johnson 479ddd582e Induce python2 to unicode
eventlet will treat str as binary,
correct by forcing unicode.

For python3, it is a no-op, but
python2 needs it to pass the 'text_type' check in eventlet.
2021-04-21 15:33:27 -04:00
Jarrod Johnson d82690f0d9 Fix python3-ism
python2 doesn't understand how to return
an iterator from within an iterator.
2021-04-21 13:31:11 -04:00
Jarrod Johnson 34cfd99fd8 Periodic reassimilation
Have leader periodically try to
assimilate offline members.

This will recover from some scenarios
where a rogue non-quorum collective
or a stray non-collective state
persists.
2021-04-21 10:30:54 -04:00
Jarrod Johnson 9009f63b2d Implement websocket based terminal access 2021-04-20 15:49:07 -04:00
Jarrod Johnson ab6bf82da6 Begin draft work to support websocket
First use case will be consoles.

Then we can consider the async case
for smoother async operation as well
though that is less critical.
2021-04-19 17:04:26 -04:00
Jarrod Johnson 0fae615756 Have nodediscover properly set exitcode
It was not propogating error to the caller in script context
2021-04-19 08:58:08 -04:00
Jarrod Johnson 37dca72579 Allow managercandidates to limit switch interrogation
If a switch is a node and has denoted allowed managers,
do not interrogate that switch if this member is not
permitted.
2021-04-16 14:19:51 -04:00
Jarrod Johnson 1aea406852 Restore error handling to SNMP
Properly carry and reconstitute exceptions
used to drive the specific errors.
2021-04-16 14:09:44 -04:00
Jarrod Johnson 374b87e2d7 Offload macmap SNMP activity to an auxillary process
This doesn't make the code more efficient, but it
keeps it from slowing down the main process
and allows it to leverage an additional core
to do the work.

Still needs work to restore the error reporting.
2021-04-15 17:22:15 -04:00
Jarrod Johnson 3469c8ab2b Fix affluent communication
Affluent would hang on error, particularly
certificate problem.  Fix by catching and being
explicit about the error, and generically
fixing the arguments for 'get' to have
the inntended timeout.
2021-04-14 15:51:18 -04:00
Jarrod Johnson e08ca5fb7e Have confetty show correct trace more easily
In some scenarios, the quitconfetty will overwrite the
stack trace.

Get the relevant trace before trying the quitconfetty, then print
the saved trace.
2021-04-14 10:10:44 -04:00
Jarrod Johnson 23dffe882e Do a keepalive to track idle, but alive collective
When relaying a command, use a keepalive to indicate that
the connection is alive, just not sending data.
2021-04-09 17:27:00 -04:00
Jarrod Johnson b6fb91b228 Have follower thread avoid killing self 2021-04-09 15:36:35 -04:00
Jarrod Johnson ac4d1fa8e1 More collective startup/recovery cleanup
If assimilated during startup, stop doing startup.
2021-04-09 13:32:32 -04:00
Jarrod Johnson 1d902c4d90 Backoff if trying to find a currently live server 2021-04-09 11:49:56 -04:00
Jarrod Johnson f11687998f Fix typo in cosmetic message 2021-04-08 20:48:46 -04:00
Jarrod Johnson 153956b2cd Further refine collective startup behavior 2021-04-08 18:26:59 -04:00
Jarrod Johnson 64d5081be3 Fix collective retry logic
It erroneously treated a thread as a bool, need
to check if None to know if it is scheduled.
2021-04-08 15:56:33 -04:00
Jarrod Johnson 8d16b412ae Further refine collective start process
Serialize assimilation, do not induce activity that may have been
aborted by an earlier chain.

Further, accelerate initial startup by making potential timeouts
occur concurrently, rather than sequentially.
2021-04-08 13:44:20 -04:00
Jarrod Johnson c5ec34d5a5 Actually hook in new assimilation behavior
Additionally, use collective member name as
tiebreaker if txcount and follower count is
identical.
2021-04-07 13:15:36 -04:00
Jarrod Johnson 6a4086679c Rework collective assimilation logic
Followers will only depart if their current leader
is assimilated.

Leaders with quorum will refuse assimilation and instruct
member trying to assimilate to join it.

Leaders without quorum will either follow the assimilation leader
or refuse, depending on who has highest transaction count, and if
a tie, which has the larger set of followers
2021-04-07 13:05:02 -04:00
Jarrod Johnson 3d2422ded3 Coerce iterator to list for length check 2021-04-07 08:40:18 -04:00
Jarrod Johnson 7d0f47bbcb Correct syntax for measuring collective size 2021-04-07 08:31:29 -04:00
Jarrod Johnson 9a779f2dd2 Improve collective startup behavior
Have confluent focus on establishing quorum before
initiating headless console and discovery activity.
2021-04-07 07:58:10 -04:00
Jarrod Johnson 4724d9e45b Eliminate one source of stale data leaking
If nodes are swapped, then clearing the attributes
did not clear some mappings.
2021-04-06 18:19:13 -04:00
Jarrod Johnson 8404ddf3a2 Fix import of sortutil 2021-04-06 10:43:37 -04:00
Jarrod Johnson 872a13589c Sort collective members
Improve consistency of output by sorting the output.
2021-04-06 09:35:34 -04:00
Jarrod Johnson 433a22e6e7 Finish rename of variable 2021-04-06 08:22:51 -04:00
Jarrod Johnson 1f238a3f8b Fix variable that was not declared after refactor 2021-04-06 08:20:10 -04:00
Jarrod Johnson 670fc87e1d Address several collective issues
When a stream has been deleted from cfgstreams, contiue exception
handling since the desired result.

For connections to a manager, institute a 15 second socket level timeout.
This avoids an abandoned server conversation from locking a colleective member startup.

When scheduling the failover check, first block any redundant attempts to schedule.

Wrap the collective startup in an exception
handler, so that a retry is
more well guaranteed.
2021-04-05 16:39:41 -04:00
Jarrod Johnson 3be3d4a588 Always send null byte out stdout
If the buffer doesn't exist or if it does,
either way make sure to write out a null
byte to let the caller know that it
is done.
2021-04-02 14:01:25 -04:00
Jarrod Johnson 14d13749ad Guarantee consoleserver init before use
During a restart, a client may aggressively trigger
console reconnect before the consoleserver starts.

Make sure that the daemon is running and globals
ready before API could possible ask for console.
2021-04-02 13:57:45 -04:00
Jarrod Johnson 92a10ede11 Pull in tmt fixes from Martin Hughes fork
Fix SGR being applied and fix default fg/bg color situation.
2021-04-02 13:13:19 -04:00
Jarrod Johnson d9051e80d3 Fix console buffer interaction
In some environments, the read method on the pipe object fails
to work, os.read should be the same, but seems to work better and
is happy to perform the opportunisticly large reads I want.
2021-04-02 12:29:41 -04:00
Jarrod Johnson 2d43fac1b5 Add a contingency for temporary read error 2021-04-02 11:54:38 -04:00
Jarrod Johnson 4a0d419f85 Improve behavior on python2 systems 2021-04-02 11:47:14 -04:00
Jarrod Johnson 7fb5f9756d Explictly request newer C version
C99 is needed for tmt, might as well go GNU11
2021-04-02 10:36:56 -04:00
Jarrod Johnson b482410072 Have server pull in vtbufferd 2021-04-01 17:31:52 -04:00
Jarrod Johnson 4d47f58e53 Make tar creation less verbose 2021-04-01 17:22:10 -04:00
Jarrod Johnson c5bb55e8f2 Fix name in the rpm spec 2021-04-01 17:21:33 -04:00
Jarrod Johnson 2320718618 Fix build issues with the vtbuffer daemon 2021-04-01 17:17:34 -04:00
Jarrod Johnson d64b3e6a4e Fix up build process for vtbufferd 2021-04-01 17:15:35 -04:00
Jarrod Johnson 637e0f0a81 Draft RPM spec for vtbufferd component 2021-04-01 16:44:40 -04:00
Jarrod Johnson e26218eb92 Implement SGR recreation and fix ECH
The tmt library had a bug with ECH with cursor position.

Flesh out the dump_vt to translate the attributes to VT codes
for the buffer to look the same as the attributes indicate.
2021-04-01 16:28:28 -04:00
Jarrod Johnson 03eb026b61 Improve VT dump behavior
Ensure the resultant dump has consistently long lines.  This
will matter when we start rendering attributes on blanks.

Additionally, simplify the code
significantly taking advantage
of first loop.
2021-04-01 12:51:32 -04:00
Jarrod Johnson beab6a3c02 Migrate VT buffering to c
C implementation to improve memory and cpu utilization.

Forked off to further move the work off the main process.

Still needs attribute rendition and packaging before merging to main
branch.
2021-03-31 17:28:26 -04:00
Jarrod Johnson 5e0ebce300 Add logs for offering boot
Make it easier to debug a failure
to boot due to misconfiguration.
2021-03-29 16:58:03 -04:00
Jarrod Johnson 85c4ec5654 Skip fqdn in cert generation
There are scenarios where getqfdn can induce a hang.
The certificate having FQDN isn't that useful anyway,
since confluent never uses it and external use of it
may need more carefully crafted certificate to have
a good chance of matching it anyway.

Also, the chances a user would import our cert as a
CA to something like a browser are low.
2021-03-29 14:29:42 -04:00
Jarrod Johnson 7957a6abd4 Add invoking syncfile activity to the default profiles 2021-03-29 14:03:11 -04:00
Jarrod Johnson 39a7d8d131 Move the syncfileclient into scripts
This does not need to be in initramfs,
so do not grow addons.cpio.
2021-03-29 13:55:44 -04:00
Jarrod Johnson 54c5bf128e Finish syncflieclient 2021-03-29 13:50:07 -04:00
Jarrod Johnson ca0c592044 Commence work on syncfileclient
This will be used to wait for deployer
to finish, then execute handlers
for 'MERGE' entries.
2021-03-25 16:55:56 -04:00
Jarrod Johnson 829d1316b2 Remove 'APPEND:'
If possible, we wannt to stick to 'MERGE', since the handlers
are designed to make that
idempotent for repeat.

APPEND: would not be idempotent...
2021-03-25 12:37:21 -04:00
Jarrod Johnson c2c1c85651 Increase verbosity of syncfiles 2021-03-25 08:59:16 -04:00
Jarrod Johnson c5833f1417 Reserve some characters for special syntax
May need to modify some behaviors in future, provide
a healthy supply of reserved characters toward that end.
2021-03-25 08:57:48 -04:00
Jarrod Johnson 07ae3593c3 Syncfiles fixes 2021-03-24 17:33:26 -04:00
Jarrod Johnson 8ab35b11cd Add -a notation about syncfiles relevance 2021-03-24 16:01:48 -04:00
Jarrod Johnson 35ef6170ba Implement syncfiles server side 2021-03-24 16:00:54 -04:00
Jarrod Johnson d650f11255 Begin work on syncfiles concept for confluent 2021-03-23 17:32:45 -04:00
Jarrod Johnson b4926b39fe Fix CA in installer env in ubuntu 2021-03-22 12:16:32 -04:00
Jarrod Johnson 53ccee734f Add more lvm dependencies 2021-03-22 11:00:21 -04:00
Jarrod Johnson fe9d0e84d3 Ubuntu firstboot ansible and scripts directory support 2021-03-22 10:36:14 -04:00
Jarrod Johnson 4e7e12f90f Add ansible to ubuntu post and scripts/post.d 2021-03-22 10:35:11 -04:00
Jarrod Johnson 8ae68cd34a Merge pull request #40 from vmaneagit/patch-60
Update nodesetboot.ronn
2021-03-22 08:05:59 -04:00
vmaneagit 607d69b1e1 Update nodesetboot.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command

Description chapter was updated
2021-03-22 13:47:04 +02:00
vmaneagit 75e13239c2 Update nodesupport.ronn 2021-03-22 13:40:49 +02:00
vmaneagit c88d8d047a Update collate.ronn
OPTIONS chapter has been updated to match the output from confetty -h
2021-03-22 13:38:13 +02:00
vmaneagit 304fbba2bb Update confetty.ronn
OPTIONS chapter has been updated to match the output from confetty -h
2021-03-22 13:31:54 +02:00
vmaneagit d2f35ccbde Update nodegroupattrib.ronn.tmpl
Changes made for Option chapter:
 - added -h command
2021-03-22 12:40:46 +02:00
vmaneagit 273c32d4a7 Update nodelicense.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command

Update typo in Description chapter: "Using delete will remove the specified license name from  th eBMC."
2021-03-22 12:38:55 +02:00
vmaneagit 1616999cb9 Update nodelicense.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command
2021-03-22 12:36:24 +02:00
vmaneagit 195db5c6e8 Update nodepower.ronn
Changes made for Option chapter:
 - added -m command
2021-03-22 12:34:23 +02:00
vmaneagit fa0e216c7e Update noderemove.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command
2021-03-22 12:29:35 +02:00
vmaneagit 1605169b92 Update nodereseat.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command
2021-03-22 12:28:17 +02:00
vmaneagit 7fa0016536 Update nodersync.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command
2021-03-22 12:26:51 +02:00
vmaneagit b4d26c3c4e Update nodersync.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command
2021-03-22 12:21:28 +02:00
vmaneagit 7470d9b55c Update nodesupport.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command
2021-03-22 12:06:57 +02:00
vmaneagit aaf1fb8c94 Update collective.ronn
Changes made for Option chapter:
 - added -h command
2021-03-22 12:01:24 +02:00
Jarrod Johnson 50e62c7b73 Bump release to pick up new lvm content 2021-03-19 19:24:31 -04:00
Jarrod Johnson 363eff831f Add devicemapper modules to genesis
This enables at least common lvm access for rescue purposes.
2021-03-19 18:52:18 -04:00
Jarrod Johnson 31820ddfd7 Fix ansible support of suse15
Must install python3 and we must have the python apiclient
intact with appropriate CA certs to proceed
2021-03-19 16:07:59 -04:00
Jarrod Johnson 153749aebe Change ssh duringe suse 15 post
Have port 22 be inside the target environment, and
2222 point to the installer. This improves ansible
experience.
2021-03-19 15:13:37 -04:00
Jarrod Johnson 7c5dd85e74 Copy in ansible to genesis profiles
Make it clearer that there could be ansible support in genesis
2021-03-19 13:09:21 -04:00
Jarrod Johnson 7a5bf8a06f Merge pull request #23 from vmaneagit/patch-25
Update noderun.ronn
2021-03-19 11:04:28 -04:00
Jarrod Johnson 9c05057deb Merge pull request #24 from vmaneagit/patch-26
Update nodemedia.ronn
2021-03-19 11:04:22 -04:00
Jarrod Johnson 8b1902601f Merge pull request #28 from vmaneagit/patch-30
Update nodepower.ronn
2021-03-19 11:04:17 -04:00
Jarrod Johnson d94d9d0a78 Merge pull request #32 from vmaneagit/patch-35
Update nodefirmware.ronn
2021-03-19 11:04:09 -04:00
Jarrod Johnson 457b0851c9 Merge pull request #33 from vmaneagit/patch-36
Update nodeeventlog.ronn
2021-03-19 11:04:05 -04:00
Jarrod Johnson d2cae9faca Merge pull request #34 from vmaneagit/patch-37
Update nodedeploy.ronn
2021-03-19 11:02:24 -04:00
Jarrod Johnson e27739eafd Merge pull request #37 from vmaneagit/patch-40
Update nodebmcreset.ronn
2021-03-19 11:02:16 -04:00
Jarrod Johnson 874302537d Merge pull request #36 from vmaneagit/patch-39
Update nodeboot.ronn
2021-03-19 11:01:56 -04:00
Jarrod Johnson cd3b67d4cc Merge pull request #38 from vmaneagit/patch-41
Update nodeattrib.ronn.tmpl
2021-03-19 11:01:41 -04:00
Jarrod Johnson 7aacac2fb7 Merge pull request #39 from vmaneagit/patch-42
Update confluentdbutil.ronn
2021-03-19 11:01:27 -04:00
Jarrod Johnson a69fb3fec3 Merge pull request #35 from vmaneagit/patch-38
Update nodeconfig.ronn
2021-03-19 11:01:13 -04:00
Jarrod Johnson 2d9cbe4f33 Merge pull request #22 from vmaneagit/patch-24
Update nodesupport
2021-03-19 11:00:57 -04:00
vmaneagit e33ed0afc8 Update confluentdbutil.ronn
Changes made for Option chapter:
 - added -h command
2021-03-19 16:55:09 +02:00
vmaneagit ace6544444 Update nodeattrib.ronn.tmpl
Changes made for Option chapter:
 - updated -m command
 - added -h command
2021-03-19 16:50:59 +02:00
vmaneagit 1468c56e1f Update nodebmcreset.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command
2021-03-19 16:48:40 +02:00
vmaneagit b36756ebbc Update nodeboot.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command

Synopsis chapter was reduced to single line
2021-03-19 15:28:33 +02:00
vmaneagit a8f378deb7 Update nodeconfig.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command

Synopsis chapter was reduced to single line
2021-03-19 15:22:14 +02:00
vmaneagit cb4e53c459 Update nodedeploy.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command

Synopsis chapter was reduced to single line
2021-03-19 15:20:08 +02:00
vmaneagit 3e0b283593 Update nodeeventlog.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command

Synopsis chapter was reduced to single line
2021-03-19 15:17:41 +02:00
vmaneagit 3b4e9fd2e4 Update nodefirmware.ronn
Changes made for Option chapter:
 - updated -m command
 - added -h command

Synopsis chapter was reduced to the same line as the usage:

nodefirmware <noderange> [list][update [--backup <file>]]|[<components>]
2021-03-19 15:06:14 +02:00
vmaneagit 6af6195798 Update nodepower.ronn
Changes made for Option chapter:

 - added -h command
2021-03-19 14:22:47 +02:00
vmaneagit a8d1f484b5 Update nodemedia.ronn
Changes made for Option chapter:
 - added -h command
- removed -c command
2021-03-19 13:17:30 +02:00
vmaneagit 619c60533d Update noderun.ronn
Changes made for Option chapter:
 - added -h command
 - updated -m command
2021-03-19 13:13:03 +02:00
vmaneagit c6fd760006 Update nodesupport
Updated line 119 with to show  "<filename or directory>"
2021-03-19 11:49:46 +02:00
Jarrod Johnson 03f88c6e3e Swap ssh during post phase to installed image
Preserve installer access on 2222

This enables easier ansible usage.
2021-03-18 15:53:30 -04:00
Jarrod Johnson 697b33ae80 Put a lower bound on autocons geometry
If some glitch happens during the read, do not end up with
absurdly low geometry.
2021-03-18 15:48:25 -04:00
Jarrod Johnson 79ef1c4811 Correct typo in functions update 2021-03-18 14:58:53 -04:00
Jarrod Johnson f442e949aa Add firstboot/post ansible play support to SUSE15 2021-03-18 14:37:54 -04:00
Jarrod Johnson 8050d3f69a Add playbook examples for default genesis 2021-03-18 14:30:18 -04:00
Jarrod Johnson 66efa1da5c Implement remote config for EL8 2021-03-18 14:12:19 -04:00
Jarrod Johnson df97e808c6 Wire up client retrieval of remoteconfig
remoteconfig can now watch for completion and return
data to client
2021-03-17 17:46:27 -04:00
Jarrod Johnson 98d14344ce Have runansible complete execution
It now completes runs and stores results for retrieval by deploying node.
2021-03-17 16:54:37 -04:00
Jarrod Johnson a149b0bcd0 Merge branch 'master' into ansibleplay 2021-03-17 10:25:57 -04:00
Jarrod Johnson 0be1e350e9 Merge pull request #21 from vmaneagit/patch-23
Update stats
2021-03-17 10:24:41 -04:00
Jarrod Johnson 4818bd57bb Advance state of runansible
Begin work to wire the results back to the supervisor and ultimately
back to the node affected.
2021-03-16 17:19:23 -04:00
Jarrod Johnson 7763327a63 Skip confluent import on exec
In main context, we don't need
sshutil, and python path is not
cooperative, so just skip it.
2021-03-16 16:23:27 -04:00
Jarrod Johnson dac957364f Merge branch 'master' into ansibleplay 2021-03-16 14:54:53 -04:00
Jarrod Johnson 528dd4c3e8 Merge branch '3.1' 2021-03-16 14:54:42 -04:00
Jarrod Johnson e40c362743 Fix network configuration changes through collective 2021-03-16 14:54:26 -04:00
Jarrod Johnson 7fdb4dccca Fix network configuration changes through collective 2021-03-16 14:53:55 -04:00
Jarrod Johnson a3c8c305c1 Add ansible supervisory code 2021-03-16 14:19:44 -04:00
Jarrod Johnson aeb1b704b3 Add mechanism to supply data from argv
Some POST calls may want body from CLI, make this
easier by no longer requiring a file to do so.
2021-03-16 11:18:46 -04:00
Jarrod Johnson f2cb6ea535 Merge branch 'master' into ansibleplay 2021-03-16 10:46:54 -04:00
Jarrod Johnson 5a81279b9d Fix servicedata fetch
In the new framework with
filehandle passing, the provided
callback must accept a data
argument.  get_diags can't
actually use it, but does have
to accept a token value.
2021-03-15 16:45:43 -04:00
vmaneagit 9954bf5b51 Update stats
Updated stats script with lines 40-41

Added:

if gui and mpl.get_backend() == 'agg':
        sys.stderr.write('Error: No GUI backend available and -g specified!\n')
2021-03-15 13:57:29 +02:00
Jarrod Johnson 309ea00f10 Merge branch 'master' into ansibleplay 2021-03-13 12:54:01 -05:00
Jarrod Johnson cafbc1d1c2 Have tty2 also run a shell
Some may find switching VTs to be more intuitive
than tmux session management. Provide one extra
on tty2 for such a scenario.
2021-03-13 12:50:44 -05:00
Jarrod Johnson 797e197bc7 Have tmux keep reattaching
If someone accidentally detaches, then intervene and
reattach.
2021-03-13 12:50:37 -05:00
Jarrod Johnson 19d4a3a83f Have autocons attempt sizing of serial console
If a terminal is open during autocons, that terminal
will be the size of the console.

Otherwise, fallback to 100x31.
2021-03-13 12:50:21 -05:00
Jarrod Johnson df328d6812 Have tty2 also run a shell
Some may find switching VTs to be more intuitive
than tmux session management. Provide one extra
on tty2 for such a scenario.
2021-03-13 12:49:26 -05:00
Jarrod Johnson 7da0dfa0bb Have tmux keep reattaching
If someone accidentally detaches, then intervene and
reattach.
2021-03-13 12:47:48 -05:00
Jarrod Johnson d3a699a8fb Have autocons attempt sizing of serial console
If a terminal is open during autocons, that terminal
will be the size of the console.

Otherwise, fallback to 100x31.
2021-03-13 12:33:53 -05:00
Jarrod Johnson 82598d02d8 Merge branch 'master' into ansibleplay 2021-03-12 13:56:02 -05:00
Jarrod Johnson 874947076d Fix local console behavior in genesis
This will have the vga console be less concerning.
2021-03-12 13:55:33 -05:00
Jarrod Johnson 8032ea36be Fix local console behavior in genesis
This will have the vga console be less concerning.
2021-03-12 13:55:14 -05:00
Jarrod Johnson 8ad130e14c Fix local console behavior in genesis
This will have the vga console be less concerning.
2021-03-12 13:54:36 -05:00
Jarrod Johnson ffe0754dd9 Fix typo in confluent profile.yaml
The quiet argument was missed due to typo in parameter name.
2021-03-12 12:44:19 -05:00
Jarrod Johnson 5aa6fbc019 Fix typo in confluent profile.yaml
The quiet argument was missed due to typo in parameter name.
2021-03-12 12:42:57 -05:00
Jarrod Johnson 7026fdfa3a WIP change to enhance selfservice api for ansible
Begin work on extending selfservice to allow nodes
to request the deployer run ansible plays.
2021-03-12 12:23:58 -05:00
Jarrod Johnson 9dbecd4c95 Merge branch 'master' into ansibleplay 2021-03-12 12:23:48 -05:00
Jarrod Johnson d85219d5fa Merge branch 'master' of github.com:lenovo/confluent 2021-03-12 12:22:20 -05:00
Jarrod Johnson bbb8e50c3e Fix configbmc gateway check
It erroneously linked to prefix to check gateway or not.
2021-03-11 16:28:01 -05:00
Jarrod Johnson 26782811d6 Fix configbmc gateway check
It erroneously linked to prefix to check gateway or not.
2021-03-11 16:27:17 -05:00
Jarrod Johnson e38dbc4470 Pull in the automation key into default profiles 2021-03-10 15:41:01 -05:00
Jarrod Johnson a26624a614 Use ssh-agent to store keys
Also add the 'automation' key for ansible to
take advantage of.
2021-03-10 15:41:01 -05:00
Jarrod Johnson 4f246e6a41 Fix compatibility with some switch configurations
While some implementations mess up portid and need portdescr instead, others are
just the opposite.

Tolerate match either by description or name.
2021-03-10 13:41:59 -05:00
Jarrod Johnson c53e758170 Workaround non-cisco switch crash
Querying Cisco MIB on certain
firmware levels of non-cisco switches
causes a crash.  Tolerate and
wait a bit to give SNMP a chance to restart.
2021-03-10 13:41:52 -05:00
Jarrod Johnson 1a7c238b54 Handle malformed json data more gracefully 2021-03-10 13:41:45 -05:00
Jarrod Johnson 6a88f35fc2 Fix compatibility with some switch configurations
While some implementations mess up portid and need portdescr instead, others are
just the opposite.

Tolerate match either by description or name.
2021-03-10 13:40:47 -05:00
Jarrod Johnson 7a27fba94b Workaround non-cisco switch crash
Querying Cisco MIB on certain
firmware levels of non-cisco switches
causes a crash.  Tolerate and
wait a bit to give SNMP a chance to restart.
2021-03-10 09:51:05 -05:00
Jarrod Johnson 94a4a7e20b Fix missing exit code in nomededia
nodemedia was not setting return code on exit properly.
2021-03-08 08:01:30 -05:00
Jarrod Johnson 2a87c32800 Handle malformed json data more gracefully 2021-03-08 02:55:58 -05:00
Jarrod Johnson d99bc37ed3 Fix missing exit code in nomededia
nodemedia was not setting return code on exit properly.
2021-03-08 08:01:19 -05:00
Jarrod Johnson 2c40d2fd0d Merge pull request #14 from vmaneagit/patch-22
Update nodesupport.ronn
2021-03-08 07:49:13 -05:00
Jarrod Johnson 611927d2ff Merge pull request #15 from vmaneagit/patch-16
Update nodelicense.ronn
2021-03-08 07:49:03 -05:00
Jarrod Johnson eb9ae61e75 Merge pull request #16 from vmaneagit/patch-17
Update noderemove.ronn
2021-03-08 07:48:51 -05:00
Jarrod Johnson 4ae102018a Merge pull request #17 from vmaneagit/patch-18
Update nodereseat.ronn
2021-03-08 07:48:42 -05:00
Jarrod Johnson 4f01545328 Merge pull request #18 from vmaneagit/patch-19
Update nodersync.ronn
2021-03-08 07:48:25 -05:00
Jarrod Johnson 762fb8259d Merge pull request #19 from vmaneagit/patch-20
Update noderun.ronn
2021-03-08 07:48:00 -05:00
Jarrod Johnson 2ca146c1aa Merge pull request #20 from vmaneagit/patch-21
Update nodesetboot.ronn
2021-03-08 07:47:38 -05:00
vmaneagit 16f40efb69 Update nodesupport.ronn
OPTIONS section has been added to match the output from nodesupport -h
2021-03-08 10:46:37 +02:00
vmaneagit a51a428761 Update nodesetboot.ronn
OPTIONS section has been updated to match the output from nodesetboot -h
2021-03-08 10:30:21 +02:00
vmaneagit a5261cc1da Update noderun.ronn
OPTIONS section has been added to match the output from noderun -h
2021-03-08 10:23:47 +02:00
vmaneagit c8166b7cce Update nodersync.ronn
OPTIONS section has updated to match the output from nodersync -h
2021-03-08 10:14:17 +02:00
vmaneagit a11317c994 Update nodereseat.ronn
OPTIONS section has been added to match the output from nodereseat -h
2021-03-08 10:06:08 +02:00
vmaneagit 279f622026 Update noderemove.ronn
OPTIONS section has been updated to match the output from noderemove -h
2021-03-08 09:58:33 +02:00
vmaneagit 32fa07d9ce Update nodelicense.ronn
OPTIONS section has been addeed to match the output from nodelicense -h
2021-03-08 09:51:42 +02:00
Jarrod Johnson c9157b90eb Close other places that may be false negative
Have checks for neightable be preceeded by an attempt to refresh,
to mitigate false negatives.
2021-03-05 13:15:37 -05:00
Jarrod Johnson 2e63ff3aca Close other places that may be false negative
Have checks for neightable be preceeded by an attempt to refresh,
to mitigate false negatives.
2021-03-05 13:14:41 -05:00
Jarrod Johnson 5d0423c38b Attempt refresh of neigh table on miss
When an address is new it may not be in the last
captured neighbor table. Induce refresh before deciding
that neighbor is unavailable.
2021-03-05 13:09:54 -05:00
Jarrod Johnson e3c17491e5 Attempt refresh of neigh table on miss
When an address is new it may not be in the last
captured neighbor table. Induce refresh before deciding
that neighbor is unavailable.
2021-03-05 13:08:25 -05:00
Jarrod Johnson da7b7c8923 Add a script to filter passwd/shadow/group for replication 2021-03-05 10:52:25 -05:00
Jarrod Johnson 5861af799c Merge pull request #13 from vmaneagit/patch-13
Update nodegroupattrib.ronn.tmpl
2021-03-05 09:21:33 -05:00
Jarrod Johnson 2b0353c771 Merge pull request #12 from vmaneagit/patch-12
Update nodefirmware.ronn
2021-03-05 09:21:16 -05:00
Jarrod Johnson bc6c3c5e68 Merge pull request #11 from vmaneagit/patch-11
Update nodeeventlog.ronn
2021-03-05 09:20:53 -05:00
Jarrod Johnson 37ec16058f Merge pull request #10 from vmaneagit/patch-10
Update nodedeploy.ronn
2021-03-05 09:20:32 -05:00
Jarrod Johnson b3efd2f31d Merge pull request #9 from vmaneagit/patch-9
Update nodeconfig.ronn
2021-03-05 09:20:16 -05:00
Jarrod Johnson 357ebfca3f Merge pull request #8 from vmaneagit/patch-8
Update nodeboot.ronn
2021-03-05 09:19:52 -05:00
vmaneagit 7e0cd9d709 Update nodegroupattrib.ronn.tmpl
OPTIONS section has been updated to match the output from nodegroupattrib -h
2021-03-05 15:56:27 +02:00
vmaneagit ba321551e4 Update nodefirmware.ronn
OPTIONS section has been added to match the output from nodefirmware -h
2021-03-05 15:51:52 +02:00
vmaneagit d96026ef5f Update nodeeventlog.ronn
OPTIONS section has been added to match the output from nodeeventlog -h
2021-03-05 15:46:11 +02:00
vmaneagit 08aa667b13 Update nodedeploy.ronn
OPTIONS chapter has been updated to match the output from nodedeploy -h
2021-03-05 11:49:24 +02:00
vmaneagit 0cb93c4bea Update nodeconfig.ronn
OPTIONS chapter has been updated to match the output from nodeconfig -h
2021-03-05 11:44:02 +02:00
vmaneagit 7b3ecc6e4f Update nodeboot.ronn
OPTIONS chapter has been updated to match the output from nodeboot -h
2021-03-05 11:37:42 +02:00
Jarrod Johnson 5a5b3f9927 Correct incorrect function call on image import 2021-03-04 16:55:26 -05:00
Jarrod Johnson 4455226ee0 Merge pull request #7 from vmaneagit/patch-7
Update nodebmcreset.ronn
2021-03-04 16:25:36 -05:00
Jarrod Johnson 0881d74731 Merge pull request #6 from vmaneagit/patch-6
Update nodeattrib.ronn.tmpl
2021-03-04 16:25:26 -05:00
Jarrod Johnson 55d7191573 Merge pull request #5 from vmaneagit/patch-5
Update confluentdbutil.ronn
2021-03-04 16:25:19 -05:00
Jarrod Johnson bc9d0a9d3b Merge remote-tracking branch 'lenovo/master' 2021-03-04 14:05:48 -05:00
Jarrod Johnson 866f138652 Fix mistakes in sample mofed post script 2021-03-04 13:30:00 -05:00
vmaneagit ee8ad66959 Update nodebmcreset.ronn
OPTIONS chapter has been added to match the output from nodebmcreset -h
2021-03-04 18:52:10 +02:00
vmaneagit be0e47142b Update nodeattrib.ronn.tmpl
OPTIONS chapter has been updated to match the output from nodeattrib -h
2021-03-04 18:45:29 +02:00
vmaneagit 4131f1ba4f Update confluentdbutil.ronn
OPTIONS chapter has been updated to match the output from confluentdbutil -h
2021-03-04 18:36:48 +02:00
Jarrod Johnson f2966bfeaf Merge pull request #4 from vmaneagit/patch-4
Update confetty.ronn
2021-03-04 11:16:38 -05:00
Jarrod Johnson eee6330aaf Merge pull request #3 from vmaneagit/patch-3
Update collective.ronn
2021-03-04 11:15:52 -05:00
Jarrod Johnson aa9ece529f Merge pull request #2 from vmaneagit/patch-2
Update collate.ronn
2021-03-04 11:15:36 -05:00
Jarrod Johnson 865d18d367 Back off progress update on file copy
The output was too frenzied, cool it down to fewer
updates.
2021-03-04 11:01:17 -05:00
Jarrod Johnson e583d34555 Fix nic index map with bonding
The assumption that /sys/class/net is interfaces is incorrect,
when encountering entries that are not interfaces, do not
mess up the call.
2021-03-04 10:49:23 -05:00
Jarrod Johnson b27d07f304 Fix nic index map with bonding
The assumption that /sys/class/net is interfaces is incorrect,
when encountering entries that are not interfaces, do not
mess up the call.
2021-03-04 10:47:28 -05:00
vmaneagit 50e60a5a17 Update confetty.ronn
OPTIONS chapter has been added to match the output from confetty -h
2021-03-04 17:33:59 +02:00
vmaneagit 8bf7e045d5 Update collective.ronn
SYNOPSIS chapter has been updated to match the output from collective -h
2021-03-04 17:05:50 +02:00
vmaneagit f0f4427dc3 Update collate.ronn
SYNOPSIS and OPTIONS chapters have been updated to match the output from collate -h
2021-03-04 16:52:30 +02:00
Jarrod Johnson b1f1f15ba8 Fix filecopy and enhnance
shutil was copying from wrong
index. Stop using shutil and
bring it in, and instrument the
percentage.
2021-03-04 09:29:31 -05:00
Jarrod Johnson 09ca449eab Fix iso import distinfo.yaml
If a copy method (e.g. ubuntu) is used, then distinfo.yaml is not
written. Fix by not overwriting the directory name.
2021-03-04 09:02:43 -05:00
Jarrod Johnson d08ce9e563 Correct fd used in libarchive
Actually use the cloned file descriptors
2021-03-04 08:43:17 -05:00
Jarrod Johnson ce92ea4084 Separate buffered and raw operation on filehandle
python and libarchive need different seek behaviors
with default file objects.
2021-03-04 08:30:05 -05:00
Jarrod Johnson 0695f8e827 Change seek method
The wrapper around seek would sometimes change offsets before
passing to lseek.  Directly call lseek since python appears
to be making some sort of mistake in some cases.
2021-03-04 07:55:18 -05:00
Jarrod Johnson 7609a46594 Merge remote-tracking branch 'lenovo/master' 2021-03-03 14:46:51 -05:00
Jarrod Johnson 247838f70c Redirect non-enclosure reseat to nodes
This allows new PSU AC cycle functionality to work.
2021-03-03 13:01:25 -05:00
Jarrod Johnson 594d419ca0 Merge pull request #1 from vmaneagit/patch-1
Update nodeshell.ronn
2021-03-02 15:57:09 -05:00
vmaneagit da0c83513a Update nodeshell.ronn
Updated SYNOPSIS and OPTIONS chapters
2021-03-02 22:51:48 +02:00
Jarrod Johnson 5ed0b50110 Fix non-client fallback
If client doesn't provide file,
then we need to open by name.
2021-03-02 15:15:54 -05:00
Jarrod Johnson e01a7cf4fb Merge branch 'master' into passfilehandle 2021-03-02 14:05:54 -05:00
Jarrod Johnson ad92ab13f3 Correct mistake in nodediscover correction 2021-03-02 14:05:28 -05:00
Jarrod Johnson 236e5466cb Merge branch 'master' into passfilehandle 2021-03-02 13:22:16 -05:00
Jarrod Johnson cc16e58c3a Merge branch '3.1' 2021-03-02 11:13:44 -05:00
Jarrod Johnson 0ff9d5dc7e Merge branch 'master' into passfilehandle 2021-03-01 10:32:39 -05:00
Jarrod Johnson 95466392f9 Fix typo in confluentdbutil
The restore function would fail
to chown directories due to typo
2021-03-01 10:32:13 -05:00
Jarrod Johnson b3857f8d33 Fix chained discovery of DWC SMMv2
SMMv2 for DWC has more ports. Make the code
not care about which port is which for checking
for matching smm fingerprints.
2021-03-01 10:32:05 -05:00
Jarrod Johnson f176ebe4c2 Fix typo in confluentdbutil
The restore function would fail
to chown directories due to typo
2021-03-01 10:31:28 -05:00
Jarrod Johnson e24852c480 Fix chained discovery of DWC SMMv2
SMMv2 for DWC has more ports. Make the code
not care about which port is which for checking
for matching smm fingerprints.
2021-02-27 20:53:33 -05:00
Jarrod Johnson 008089c4c0 license install through passed fd
Allow install of licenses that confluent cannot read.
2021-02-26 16:37:34 -05:00
Jarrod Johnson f34e184d31 Restore libc access to sockapi
Cleanup went too for in python2 port.
2021-02-26 16:25:51 -05:00
Jarrod Johnson 814257fbf8 Fix leaking file descriptors
When passing a filehandle for update, clean it up on end
of the update/upload.
2021-02-26 16:18:58 -05:00
Jarrod Johnson 83d92ecfcc Make file descriptor passing python2 friendly
python 2 did not have recvmsg/sendmsg,
so have to use ctypes to access
them through the c library.
2021-02-26 16:17:43 -05:00
Jarrod Johnson 7eb06f2722 Improve concurrency of SLP
During a scan, unicast TCP
interrogation of candidates
was done serially. Do this
concurrently so that poorly
behaving targets do not prolong
a scan.
2021-02-26 13:31:07 -05:00
Jarrod Johnson 0fbe39690e Improve concurrency of SLP
During a scan, unicast TCP
interrogation of candidates
was done serially. Do this
concurrently so that poorly
behaving targets do not prolong
a scan.
2021-02-26 13:30:36 -05:00
Jarrod Johnson ec2ad9861a Improve concurrency of SLP
During a scan, unicast TCP
interrogation of candidates
was done serially. Do this
concurrently so that poorly
behaving targets do not prolong
a scan.
2021-02-26 12:39:13 -05:00
Jarrod Johnson 16096ad745 FD passing for firmware and media upload
Extend use of client side file descriptors to
media and firmmware upload.
2021-02-25 12:55:38 -05:00
Jarrod Johnson 481a70c304 Fix traceback when multiple criteria have no matches
When a parent criteria has no match, then the api
returns a 404 as there is no parent.  Handle this
by only listing positively matched items.
2021-02-24 16:39:01 -05:00
Jarrod Johnson facd501100 Merge branch 'master' into passfilehandle 2021-02-19 15:44:55 -05:00
Jarrod Johnson 4c6f41ffb2 Have nodeconfig error on missing attributes per node 2021-02-19 14:36:51 -05:00
Jarrod Johnson 3e93ab1966 Have OS import work for unreadable input 2021-02-18 16:33:14 -05:00
Jarrod Johnson 0b5c4f6f0f Progress client managed filedescriptor 2021-02-18 14:58:45 -05:00
Jarrod Johnson e8778cb992 Merge branch 'master' into passfilehandle 2021-02-18 10:57:25 -05:00
Jarrod Johnson 2fae35b2c4 Be more consistent between man page and -h 2021-02-18 10:56:37 -05:00
Jarrod Johnson 08c7bd4e42 Merge branch 'master' into passfilehandle 2021-02-18 10:52:09 -05:00
Jarrod Johnson 1a17bf8fbb Further correct formatting discrepency 2021-02-18 10:51:30 -05:00
Jarrod Johnson f21b0570e8 Further amend formatting discrepencies 2021-02-18 10:50:21 -05:00
Jarrod Johnson 9cac77cac7 Correct minor formatting discrepency 2021-02-18 10:49:17 -05:00
Jarrod Johnson 3831d409f5 Merge branch 'master' into passfilehandle 2021-02-18 10:48:09 -05:00
Jarrod Johnson 10fcb5fa6d Add missing options to nodestorage man page 2021-02-18 10:35:37 -05:00
Jarrod Johnson ff00f48e58 Add missing [options] from -h on nodestorage 2021-02-18 10:31:54 -05:00
Jarrod Johnson 225a49f05e Merge branch 'master' into passfilehandle 2021-02-18 09:12:47 -05:00
Jarrod Johnson d3c9c90f35 Implement simple address scanning for SLP 2021-02-18 09:04:46 -05:00
Jarrod Johnson 78592bfe2a Merge branch 'master' into passfilehandle 2021-02-18 07:46:47 -05:00
Jarrod Johnson 1b2f5b6019 Add a misc slpscan.py 2021-02-18 07:35:11 -05:00
Jarrod Johnson 3c6511a0e7 Actually have a file handle pass
Rely upon python 3 for now. When the dust settles, either convert to
python 2 friendly use of ctypes, or alternatively just block using
the pass filehandle function in older python.
2021-02-17 17:04:16 -05:00
Jarrod Johnson c525a08c17 Correct a number of mistakes in the draft commit 2021-02-17 14:34:45 -05:00
Jarrod Johnson edaaafa059 Begin work on passing filehandles for local cli
This would enable files to be uploaded/downloaded
using the client filehandles, overcoming awkward
difference in file privilege between client and
server.
2021-02-17 13:54:18 -05:00
Jarrod Johnson f16e84de32 Fix group display of crypted attributes 2021-02-12 13:32:36 -05:00
Jarrod Johnson 4c99bc142b Bump genesis build number 2021-02-11 16:43:01 -05:00
Jarrod Johnson 8e4f5fcae6 Register sftp in genesis by default 2021-02-11 16:42:30 -05:00
Jarrod Johnson c4d3cb409d Also add sftp, to make ansible not complain 2021-02-11 16:41:24 -05:00
Jarrod Johnson 9eed1378f6 Enable ansible to target genesis 2021-02-11 16:39:17 -05:00
Jarrod Johnson 5f282dd40a Attempt removing needless cache from python
Try to shrink image by removing duplicate
cached modules.
2021-02-11 15:39:25 -05:00
Jarrod Johnson 6e88a44399 Update name of tpm2 utility
pcrlist became pcrread
2021-02-11 15:37:38 -05:00
Jarrod Johnson 94e731274a Add debug in case where ESXi has no network
Do away with appearance of mysterious hang
2021-02-11 11:44:53 -05:00
Jarrod Johnson 50c150f4b4 Fixup issues in esxi deployment
When installer boots, the autonic behavior it tries is discarded
by default. Explicitly preserve the autonic behavior into
the install phase and the installed system.
2021-02-11 11:06:02 -05:00
Jarrod Johnson a46810ca29 Merge branch '3.1' 2021-02-08 09:39:55 -05:00
Jarrod Johnson 76cdd958ec Add AlmaLinux recognition
This imports ALmaLinux
2021-02-08 09:24:46 -05:00
Jarrod Johnson e72292f989 Update status at end of esxi install 2021-02-05 14:03:41 -05:00
Jarrod Johnson 8cf264602d Update status at end of esxi install 2021-02-05 14:02:28 -05:00
Jarrod Johnson a2f5b11185 Add Usb to nodesetboot
Particularly for redfish, this is a more specific target
2021-02-01 08:43:47 -05:00
Jarrod Johnson ed4db91383 Add Usb to nodesetboot
Particularly for redfish, this is a more specific target
2021-02-01 08:42:35 -05:00
Jarrod Johnson a9e39eab96 Fix path mistake in mofed.post script
mofed.post had incorrect path to mofed.tgz after
fetch. Correct the path mistake.
2021-01-28 16:50:50 -05:00
Jarrod Johnson 209430ed35 Fix path mistake in mofed.post script
mofed.post had incorrect path to mofed.tgz after
fetch. Correct the path mistake.
2021-01-28 16:45:39 -05:00
Jarrod Johnson d29d2bf683 Implement workaround for install over infiniband
8.3 implemented networkmanager to manage the install time
networking, but didn't correctly generate infiniband
network manager configuration.

Workaround by checking for infiniband install, and
then checking if the configuration is wrong, and
adding an infiniband section if missing.
2021-01-28 13:49:10 -05:00
Jarrod Johnson 3d2b579f1a Implement workaround for install over infiniband
8.3 implemented networkmanager to manage the install time
networking, but didn't correctly generate infiniband
network manager configuration.

Workaround by checking for infiniband install, and
then checking if the configuration is wrong, and
adding an infiniband section if missing.
2021-01-28 13:47:28 -05:00
Jarrod Johnson c99ab2ac73 Improve nodestorage local documentation.
Include clearer information about the `diskset` facility
in particular in usage and man page.
2021-01-27 13:02:57 -05:00
Jarrod Johnson e4591eaf57 Update nodeconfig man page with more information 2021-01-27 09:04:24 -05:00
Jarrod Johnson 695bb3757b Merge pull request #111 from brianfinley/osdeploy-list
Add 'list' option to osdeploy command
2021-01-27 08:55:17 -05:00
Jarrod Johnson 4e2767ce9d Update osdeploy 2021-01-27 08:51:03 -05:00
Brian Elliott Finley 8cdc9c9479 Add 'list' option to osdeploy command 2021-01-26 16:17:56 -06:00
Jarrod Johnson 6458eac93b Tolerate multiple forms of 'stringy'
The fromstring needs to accept either, so
amend it to do so.
2021-01-22 12:43:15 -05:00
Jarrod Johnson 8df15b3a54 Tolerate different SR635/SR655 response
Some SR635/SR655 behave differently.  Adjust by adapting as possible,
but never making an assumption about data being present.
2021-01-22 10:30:19 -05:00
Jarrod Johnson b4f9bb78ae Address irrelavent call to yaml.load 2021-01-21 17:48:56 -05:00
Jarrod Johnson c8e1efecdb Mitigate XML parse risks
The intended xml never has !entity tags and
thus we can reject any such XML outright and
avoid billion laughs and similar abuses.
2021-01-21 17:46:21 -05:00
Jarrod Johnson 22dc852277 Remove now redundent errors
printerror now searches for deeper errors,
no longer need to call it as much.
2021-01-21 16:38:35 -05:00
Jarrod Johnson 784ac5ecba Fix gitignore to track ronn files 2021-01-21 11:52:22 -05:00
Jarrod Johnson 66c9777b3c Add man page for stats command 2021-01-21 11:36:08 -05:00
Jarrod Johnson dba4c40f0e Fix collective join with empty config
Collective join without a key set would fail on
first try.
2021-01-21 11:19:13 -05:00
Jarrod Johnson 6997508a0c Fallback to forced utf8 on unicodeerror
If LC_ALL is set to C, then unicode can be a problem.
2021-01-21 08:41:35 -05:00
Jarrod Johnson 203253e05f Fix mispelling of exception name in confetty 2021-01-20 11:19:24 -05:00
Jarrod Johnson edc4804146 Discover larger SMMv2 based chassis
SMMv2 can support 12 servers, so increase the limit.
2021-01-20 09:08:56 -05:00
Jarrod Johnson 7cfdf11bf2 Fix collective name return
It inadvertently would return None when
rereading from file.
2021-01-19 17:34:28 -05:00
Jarrod Johnson a3bd21d605 Cleanup confetty/nodeconsole exit
Unexpected exit from nodeconsole/confetty is now
handled better for feedback and terminal usefulness
2021-01-19 16:24:36 -05:00
Jarrod Johnson 6d8474a16a Fix node errors being swalled by print_error
Node specific errors were not processed, correct
that oversight.
2021-01-19 12:16:22 -05:00
Jarrod Johnson 5736c41daa Add more data to discovery
Some applications may
want to source more information
from systems to help
identify things, particularly with
partially preconfigured systems.
2021-01-15 10:34:43 -05:00
Jarrod Johnson a5c4b64c60 Have Genesis better work with BMC install
In a BMC install, the certificate may fail and we may
have ability to port forward 3389 but not 22.

Support normal and enhanced certificate behavior
when possible, but degrade to cert-less ssh and
also port 3389
2021-01-15 08:25:12 -05:00
Jarrod Johnson f7a940227d Move sixel under opportunistic import
Do not require sixel
to run stats.
2021-01-14 15:49:30 -05:00
Jarrod Johnson ebf50359f0 Fix file descriptor leak by web forwarder
It failed to close the two sockets when a socket was
done.
2021-01-13 16:50:17 -05:00
Jarrod Johnson 5160023cc4 Update nodedeploy error message
We can't tell which argument was omitted,
so warn that both are needed.
2021-01-13 16:43:41 -05:00
Jarrod Johnson a738b761b4 Fix XCC discovery with Whitley changes 2021-01-12 11:47:02 -05:00
Jarrod Johnson d27ef81e32 Fix PXE handling of candidate managers 2021-01-11 13:33:26 -05:00
Jarrod Johnson f5344fabaa Correct typo in new attribute text 2021-01-11 13:13:03 -05:00
Jarrod Johnson fa1c2f5c1e Only offer deployment if a candidate manager
If candidate managers are defined, and this node is not in
that set, ignore PXE and SSDP requests to opt out of
deployment.
2021-01-08 16:32:41 -05:00
Jarrod Johnson 25c3f40559 Cache manager name
Since the get_myname() may be called much much more
frequently now that it is in the deployment flow,
have it cache results to save a lot of disk I/O
2021-01-08 16:30:51 -05:00
Jarrod Johnson 5812a0eef6 Have a rebalance shortly after becoming leader
This will handle startup and takeover when the current leader dies.
2021-01-08 16:15:11 -05:00
Jarrod Johnson 086ce9823b First phase of collective manager candidate implementation
This implements recovery on loss of collective member to
the least loaded candidates for the node.
2021-01-08 16:00:24 -05:00
Jarrod Johnson 2d6bdffebe Finalize the ssh.trustnodes facility
This is the confluent approach to handling the same
problem that xCAT SSH Zones do.
2021-01-08 14:05:37 -05:00
Jarrod Johnson efdbeeae0d Fix SNMPv2 on non-cisco switches
The cisco change was causing problems elsewhere.
2021-01-08 09:16:40 -05:00
Jarrod Johnson a2a1142f18 Draft implementation of ssh trust segmentation
Have equiv optionally be restricted to a subset of nodes
so that node to node ssh may be enabled within subsets
without enabling across the board.

This is akin to 'zones' in xCAT, albeit a bit more flexible
and covering both users and administrative access.
2021-01-06 11:52:43 -05:00
Jarrod Johnson 8c89deaa95 Further defer use of deploycfg as normal
In ESXi flow, it is highly likely that IPv4 cannot
be ready yet, delay a bit more.
2021-01-05 15:32:46 -05:00
Jarrod Johnson 1ec5231ebe Do not reply to mismatched IP in confluent search
If an OS queries for confluent, but will not have a viable address,
avoid replying to let more usable network paths prevail.

For example, one OS was coming up with 169.254 with no dhcp server,
and being told it could do well to talk to 172.29, which obviously
would not work.
2021-01-05 15:17:23 -05:00
Jarrod Johnson 674e2887f3 Fix ESXi deployment without working DHCP
apiclient was instructing itself to use IPv4 prematurely. Change
the dcuiweasel hook to delay that change until after all data has been
fetched.
2021-01-05 11:55:30 -05:00
Jarrod Johnson 4768bc257a Handle API change for setting user name
The web api now requires the word Administrator instead of
the number 4.
2020-12-15 16:44:55 -05:00
Jarrod Johnson 7610f9b963 Clean out .gitignore files
Don't leave them laying around installed package.
2020-12-15 15:53:41 -05:00
Jarrod Johnson b29e7bc94a Add new requirement in newer ESXi versions
New ESXi versions use a new efi executable during
boot.
2020-12-15 14:39:15 -05:00
Jarrod Johnson 04d63a269d Fix detection of CentOS 8.3
They changed their package name to be consistent with
their focal shift.
2020-12-15 12:59:48 -05:00
Jarrod Johnson e1bf22911b Try to have example directories obvious
git can't do empty directories, try a .gitignore
to have directories appear in the profiles
2020-12-15 12:52:57 -05:00
Jarrod Johnson d6642f1bde Fix omitted directory for firstboot
firstboot being in /opt requires a mkdir
2020-12-15 12:51:16 -05:00
Jarrod Johnson 36f027ac71 Implement support for Cisco switches
Cisco bridge mib requires to be instanced by vlan.
Detect through proprietary mibs and use it to
guide bridge mib walking.
2020-12-15 10:46:14 -05:00
Jarrod Johnson c025f4d2fc Fix firstboot.sh with selinux enabled 2020-12-14 15:06:04 -05:00
Jarrod Johnson 1238babe60 Notate future development requirements 2020-12-14 13:09:02 -05:00
Jarrod Johnson f9a82bde00 Fix arch detection in CentOS stream 2020-12-14 10:42:52 -05:00
Jarrod Johnson 48c868e935 Detect architecture for CentOS stream
CentOS stream changed the release rpm to be noarch.
2020-12-14 10:23:05 -05:00
Jarrod Johnson caf9115439 Fix CentOS stream support 2020-12-14 10:04:31 -05:00
Jarrod Johnson 8b11acbcf2 Recognize CentOS Stream
Allow installation of CentOS stream as a profile.
2020-12-14 09:47:56 -05:00
Jarrod Johnson db0f91c160 Comment to show how to opt out of UEK
For users that use the distribution with UEK, but do
not want UEK at all.
2020-12-14 08:33:58 -05:00
Jarrod Johnson cbb46dec3a Allow firstboot to run with root access
Being it /etc is unusual, and restorecon treats it
as such. Manually use chcon to explicitly allow
it in /etc/
2020-12-12 14:57:02 -05:00
Jarrod Johnson 0afa4c217c Add directory based post/firstboot capability
el8 profiles gain post.d/firstboot.d capability
2020-12-11 16:29:12 -05:00
Jarrod Johnson 47f04c8462 Provide guidance if the user tries to use defaults
Default username/password is no longer a
viable long term credentiol for XCC, have user
clearly be told to change and that they
shouldn't have to worry about the default
user and password.
2020-12-11 10:37:00 -05:00
Jarrod Johnson 5b0e23b8d4 Provide better feedback on XCC security lockouts
Rather than 'NoneType' error about grab_json_response,
provide actual recognizable feedback
2020-12-11 10:21:21 -05:00
Jarrod Johnson 14d9284cc5 Fix older Oracle Linux 7
Older OL has another release file thtat
was tripping the fingerprinting code.
2020-12-10 13:48:51 -05:00
Jarrod Johnson cd251fa5d6 Add support for OL7 and older other EL7 flavors
Older EL7 didn't have platform-python in installer,
change to fallback to old /usr/bin/python if
needed.
2020-12-10 10:54:30 -05:00
Jarrod Johnson 8d47395e53 Add fetch of '<script>.d' scripts
This can be used by firstboot/post scripts to
get modularized scripts.
2020-12-09 16:46:58 -05:00
Jarrod Johnson d19b5e4376 Have apiclient preserve server response verbatim
Do not add extra \n to output that server would
have already terminated.
2020-12-09 16:37:12 -05:00
Jarrod Johnson 7a9276300a Have apiclient reach out to deploycfg server
If we already have deploycfg, use that to indicate the
target server rather than copernicus data.
2020-12-09 16:20:02 -05:00
Jarrod Johnson 87ef68e26a Add 'memory' console.logging
If console.logging is not desired, but reconstituting the screen is,
provide 'memory' as a method to do that.

On slow disks this can significantly improve performance.
2020-12-09 13:47:46 -05:00
Jarrod Johnson 55b97793fd Lower concurrency limit of ipmi actions
IPMI actions can be a bit sensitive. Introduce some serialization
for improved robustness in liue of better parallelism.

The ideal would be to have 128 per core/process in the end, but for now,
a pool for 128 concurrent operations in flight at a time.
2020-12-08 18:23:13 -05:00
Jarrod Johnson fa823510b6 Pretty-ify Oracle Linux name in profile.yaml
Give it a nicer looking automatic label when
Oracle Linux is detected.
2020-12-07 15:09:30 -05:00
Jarrod Johnson 99609aa669 Add Oracle Linux signature check to osimage
Oracle Linux was being misidenntified as RHEL,
fix so that oracle linux is treated differently.
2020-12-07 15:08:28 -05:00
Jarrod Johnson 906011a80b Support 8.3 install
In 8.3, they refactored how network configuration is
managed early in install. Fix by detecting the presence
of the nm-lib and calling it's function again to
re-read the new cmdline.
2020-12-07 12:35:33 -05:00
Jarrod Johnson ff7f5daac6 Parallelize and timeout ssdp queries
Badly behaving 'desc.tmpl' servers exist in the world,
do not get tripped up or slowed down too much by
having aggressive timeout and making it parallel.
2020-12-04 17:14:35 -05:00
Jarrod Johnson 2d58741f15 Fix PXE/HTTP boot UUID and Mac case sensitivity
Like the SSDP code, PXE too had case sensitivity issues
2020-12-04 12:42:14 -05:00
Jarrod Johnson 57b74d59af Force uuid to lowercase in uuid mapping
Most of the codebase presumes lower case uuid, but
the uuid mapping was preserving whatever case the
attribute was in, making it case sensitive.

In the normal discovery process, this was filled in
as lower case. However if id.uuid is filled in manually
with uppercase, this broke the node lookup by uuid.
2020-12-04 07:41:40 -05:00
Jarrod Johnson 191cd8192a Add example installedargs to new ubuntu profiles 2020-12-03 10:55:39 -05:00
Jarrod Johnson 475eaca56b Add installedargs support to ubuntu profiles 2020-12-03 10:44:14 -05:00
Jarrod Johnson f33ddf3ab9 Move fetch of profile.yaml
Need to use thte copernicus network setup,
as the 'final' setup will depend on subsequent autoyast
activity.

Therefore, move it up to when mgr is probably IPv6
2020-12-02 09:12:14 -05:00
Jarrod Johnson 3422f3cdc5 Add and comment use of the installedargs in SUSE
With the support in addons, hook it in the
profile.
2020-12-02 09:05:36 -05:00
Jarrod Johnson 4c74581f0c Try to add installedargs to suse profiles 2020-12-01 16:57:26 -05:00
Jarrod Johnson 674d32e9e5 Correct mistake in previous pre scripts 2020-12-01 12:55:41 -05:00
Jarrod Johnson 666059c8bf Ignore more extraneous material 2020-12-01 12:55:26 -05:00
Jarrod Johnson 0137f99636 Add installedargs to rhel family
Provide a profile.yaml line that can be used to add arguments to
installed kernel as well as install kernel.
2020-12-01 10:53:26 -05:00
Jarrod Johnson 0c66021d3e Add tagged vlan support to el8 deployment 2020-11-30 08:16:04 -05:00
Jarrod Johnson 014727d355 Label boot.img with profile name
This allows for easier
search should an image want it
2020-11-09 15:45:44 -05:00
Jarrod Johnson dc262c366c Fix false positive in affluent detection
Make sure we don't receive
a redirect or other
when asking for mac tables.
2020-11-09 11:23:54 -05:00
Jarrod Johnson 8f99d87fda Reduce calls to update_neigh
On a mostly stable system, update_neigh will
continue to drive a significant portion of
background activity. Mitigate to only call if
circumstances suggest a need, or once every
30 seconds.
2020-11-09 09:00:57 -05:00
Jarrod Johnson edaaa2393d Hook up apiclient to TPM2 persistence, when available 2020-11-06 16:38:05 -05:00
Jarrod Johnson 1ecef6f251 Be a bit paranoid about string boundary 2020-11-06 13:57:35 -05:00
Jarrod Johnson 31c2c5f6f7 Fix errors in the TPM2 support 2020-11-06 13:38:37 -05:00
Jarrod Johnson c8747ac369 Merge branch '3.0' 2020-11-06 12:51:15 -05:00
Jarrod Johnson f7e7d05729 Add TPM2 support to node api key handling
This is an optional capability that image payloads may use
to use the TPM2 to protect an apikey as an alternative to
arming a weak authentication invocation
2020-11-06 10:00:36 -05:00
Jarrod Johnson 40c74699f0 Check for some issues in a manual assign request
One is to provide clear feedback when a nodename is requested
that was not previously defined, to make it more clear that
it is a requirement and/or guard against going too far while
the config function will be missing data it needs to complete
onboarding.

Another is to break if the request is trying to assign a node
to a different definition when it already exists under a different
name.
2020-11-03 09:32:55 -05:00
Jarrod Johnson 3903cda789 Do not clear the entire nodes lookup on remap
remap may only amend part of the map,
do not cause that to clear out the good data.
2020-11-03 09:32:48 -05:00
Jarrod Johnson 72049657d7 Fix issues with leftover ssh sessions
Upon connection loss, even though confluent internally
decides it is done with it, it fails to close the session.

Catch a number of these scenarios and ensure the connection closes.
2020-11-02 13:20:55 -05:00
Jarrod Johnson 71cc0adadd Bump genesis to build more packages
Also notate src.rpm retrieval procedure
2020-10-30 12:34:42 -04:00
Jarrod Johnson b4e6e7caa8 Check for some issues in a manual assign request
One is to provide clear feedback when a nodename is requested
that was not previously defined, to make it more clear that
it is a requirement and/or guard against going too far while
the config function will be missing data it needs to complete
onboarding.

Another is to break if the request is trying to assign a node
to a different definition when it already exists under a different
name.
2020-10-30 08:18:27 -04:00
Jarrod Johnson 10ac1756f1 Do not clear the entire nodes lookup on remap
remap may only amend part of the map,
do not cause that to clear out the good data.
2020-10-29 15:49:31 -04:00
Jarrod Johnson 95659db00a Stop trying to use generic cookie parsing
Trying to do so while guarding against errors and sanitizing input was more code and slower
than targeting the one possible cookie we might care about.

So the code is simpler and
the performance is better, and the effect of stray cookies are mitigated.
2020-10-29 11:36:26 -04:00
Jarrod Johnson bddbc37e8e Fix incorrect length of random strings 2020-10-29 10:57:49 -04:00
Jarrod Johnson 7a2b295945 Change default label for ESXi to be more clear 2020-10-26 12:35:37 -04:00
Jarrod Johnson af8429ebf9 Fix esxi updateboot
Updateboot was confounded by a normal of 'file exists'
problems.
2020-10-26 12:22:56 -04:00
Jarrod Johnson 3ac6677d2d Sanitize cookies
If an invalid cookie from another site breaks the cookie jar,
then sanitize it.

https://bugs.python.org/issue31456

Performance enhancement through setting a header in javascript in
lieu of cookie parsing seems a wise move for the future.
2020-10-24 11:10:52 -04:00
Jarrod Johnson 8b5744b7eb Drop attempts to restore cursor key mode
It would corrupt F1 setup menu. This may cause problems for
ESXi TUI, but F1 in UEFI is more commonly on serial
2020-10-23 15:32:16 -04:00
Jarrod Johnson 7fcfc05205 Fix syntax problem in processing common nameserver 2020-10-22 12:48:01 -04:00
Jarrod Johnson 4b42bbda7e Fix spelling error
firmware is now spelled correctly
2020-10-22 12:11:10 -04:00
Jarrod Johnson ed41d93de5 Add remote authentication configuration
While our security guidelines preclude allowing host to know the password,
it is considered acceptable to do the out-of-band authentication configuration.

Have configbmc request a unicast remote configuration. This should handle authentication
as well as ensuring ongoing consistency between out of band and in-band configuration
methods.
2020-10-20 15:51:46 -04:00
Jarrod Johnson d36712d014 Refactor scripting to custom for suse
This makes it marginally easier to modify safely.

Further, it moves progress to after custom scripting
2020-10-16 11:34:43 -04:00
Jarrod Johnson 21cc9d66db Correct execution of post.sh
post.sh was not retrieved correctly, workaround
by prefecting it to the expected place rather than
letting yast do it.
2020-10-16 11:07:35 -04:00
Jarrod Johnson 4508cfa364 Update suse15 message with fixed autocons 2020-10-16 09:04:14 -04:00
Jarrod Johnson 05e84f2a7c Fix double-console out in genesis
With fixed autocons,
genesis was double outputting to serial console.

Let rungenesis pick
the console instead.
2020-10-14 16:49:10 -04:00
Jarrod Johnson 184727408a Have configbmc wait for settings to complete
There has been some confusion when configbmc changes
are deferred until later.

Reduce confusion by waiting for the settings to take effect,
but avoiding checking each parameter
to preserve most of the speedup.
2020-10-13 12:24:04 -04:00
Jarrod Johnson e7fbbe2737 Fix issues with leftover ssh sessions
Upon connection loss, even though confluent internally
decides it is done with it, it fails to close the session.

Catch a number of these scenarios and ensure the connection closes.
2020-10-12 09:47:24 -04:00
Jarrod Johnson 9a0c4ce4ce Fix function handling of subdirs of scripts 2020-10-09 14:07:58 -04:00
Jarrod Johnson 247a7f5d8a Fix problem when domain was not set
domain was checked even if domain not defined,
make sure domain is defined before trying
to use it.
2020-10-08 13:38:43 -04:00
Jarrod Johnson 745b82a603 Add examples for MOFED in EL7 distros 2020-10-08 13:37:19 -04:00
Jarrod Johnson 504bee2d2a Fix problem when domain was not set
domain was checked even if domain not defined,
make sure domain is defined before trying
to use it.
2020-10-08 10:39:29 -04:00
Jarrod Johnson 8285f2a3de Incorporate convenience for Mellanox OFED install 2020-10-07 15:27:06 -04:00
Jarrod Johnson cfa97f7a9a Cover Mellanox ethernet adapters for mofed
Some elect to use MOFED with ethernet as well
2020-10-07 14:27:11 -04:00
Jarrod Johnson cbf42469c3 Add a sample script to install mofed
This is an example install script to use in post.custom for mofed
2020-10-07 14:12:31 -04:00
Jarrod Johnson 61f793040e Avoid setting uuid and mac in pxe if already set
Notably the uuid change can end up recursing. Fix the behavior that will cause never ending
loops, which in some IO situations
can end in recursion limits.
2020-10-06 17:14:48 -04:00
Jarrod Johnson 8dd66211b7 Avoid setting uuid and mac in pxe if already set
Notably the uuid change can end up recursing. Fix the behavior that will cause never ending
loops, which in some IO situations
can end in recursion limits.
2020-10-06 17:14:20 -04:00
Jarrod Johnson 5a24619560 Recognize a different m.2 name 2020-10-06 10:37:20 -04:00
Jarrod Johnson d466595828 Recognize a different m.2 name 2020-10-06 09:36:12 -04:00
Jarrod Johnson b0b965db98 Use newer functions in genesis and el7 2020-10-05 16:57:46 -04:00
Jarrod Johnson 9e73979b5b Enhance the EL script enhancements
Make them easier to use ad-hoc and add some capability
2020-10-05 16:55:37 -04:00
Jarrod Johnson f4395abade Deprecate attempts to use default password with SMM
This is removed in some level of the product
2020-10-05 16:54:58 -04:00
Jarrod Johnson a194e2293e Fix syntax error on discovery core 2020-10-02 15:35:14 -04:00
Jarrod Johnson d27577d2b7 Fix missing close parenthesis 2020-10-02 14:57:59 -04:00
Jarrod Johnson 1113c2a849 Improve duplicate switch attribute errors 2020-10-02 13:36:45 -04:00
Jarrod Johnson 587197e934 Refresh chained SMM discovery for SMMv2
Additionally, amend overall
discovery to force chain validation
rather than theoretically
accepting a low mac count match.
2020-10-02 11:45:50 -04:00
Jarrod Johnson ef901f64af Merge branch '3.0' 2020-09-30 10:04:21 -04:00
Jarrod Johnson 2ba05fb7b1 Enable IPMI on SMMv2 2020-09-29 11:21:53 -04:00
Jarrod Johnson e186eb7319 Fix problem with autocons
autocons needed to open the devnode earlier
to have the correct name. Fixes TSM autocons
behavior
2020-09-24 08:31:20 -04:00
Jarrod Johnson a263851614 Fix problem with autocons
autocons needed to open the devnode earlier
to have the correct name. Fixes TSM autocons
behavior
2020-09-24 08:26:37 -04:00
Jarrod Johnson eeb3a3fa65 Have a clause for redfish not yet ready
We need redfish, but redfish is slow to boot on TSM..
2020-09-22 14:33:58 -04:00
Jarrod Johnson 56f8ca0982 Implement redfish resilient discovery for TSM
TSM redfish stack has an issue where it refuses to recognize any
non-redfish password change. Use redfish to change.

Regretably, it takes about 10 seconds for that change to propogate
to the practical API, so we have a discovery delay now.
2020-09-22 14:31:28 -04:00
Jarrod Johnson 8f94149627 Have batch files optionally not need quotes 2020-09-22 12:25:25 -04:00
Jarrod Johnson ed842fcc1a Add mods to adapt an xcat stateless image to a confluennt payload 2020-09-17 14:23:37 -04:00
295 changed files with 17022 additions and 1917 deletions
+3
View File
@@ -1,4 +1,7 @@
*.pyc
.*.
confluent_client/man/man*
.vscode
.*.sw*
.sw*
.idea/*
+106 -86
View File
@@ -373,7 +373,7 @@ def do_command(command, server):
if argv[0] == 'exit':
if os.environ.get('TERM', '') not in ('linux'):
sys.stdout.write('\x1b]0;\x07')
raise Bailout()
raise BailOut()
elif argv[0] in ('help', '?'):
return print_help()
elif argv[0] == 'cd':
@@ -663,6 +663,28 @@ def get_session_node(shellargs):
return None
def run_inline_command(path, arg, completion, **kwargs):
tlvdata.send(session.connection, {'operation': 'pause',
'path': currconsole})
buffdata = ''
while select.select((session.connection,), (), (), 0)[0]:
buffdata += consume_termdata(session.connection, bufferonly=True)
rc = session.simple_noderange_command(consolename, path, arg, **kwargs)
tlvdata.send(session.connection, {'operation': 'resume',
'path': currconsole})
sys.stdout.write(completion)
sys.stdout.flush()
if buffdata:
try:
sys.stdout.write(buffdata)
except UnicodeEncodeError:
sys.stdout.buffer.write(buffdata.encode('utf8'))
except IOError: # Some times circumstances are bad
# resort to byte at a time...
for d in buffdata:
sys.stdout.write(d)
return rc
def conserver_command(filehandle, localcommand):
# x - conserver has that as 'show baud', I am inclined to replace that with
# 'request exclusive'
@@ -698,13 +720,13 @@ def conserver_command(filehandle, localcommand):
localcommand = get_command_bytes(filehandle, localcommand, cmdlen)
if localcommand[1] == 'o': # off
print("powering off...")
session.simple_noderange_command(consolename, '/power/state', 'off')
print("complete]\r")
sys.stdout.write("powering off...")
sys.stdout.flush()
run_inline_command('/power/state', 'off', 'complete]')
elif localcommand[1] == 's': # shutdown
print("shutting down...")
session.simple_noderange_command(consolename, '/power/state', 'shutdown')
print("complete]\r")
sys.stdout.write("shutting down...")
sys.stdout.flush()
run_inline_command('/power/state', 'shutdown', 'complete]')
elif localcommand[1] == 'b': # boot
cmdlen += 1
localcommand = get_command_bytes(filehandle, localcommand, cmdlen)
@@ -715,59 +737,46 @@ def conserver_command(filehandle, localcommand):
bootmode = 'uefi'
bootdev = 'setup'
rc = session.simple_noderange_command(consolename, '/boot/nextdevice', bootdev, bootmode=bootmode)
rc = run_inline_command('/boot/nextdevice', bootdev, '', bootmode=bootmode)
if rc:
print("Error]\r")
else:
rc = session.simple_noderange_command(consolename, '/power/state', 'boot')
rc = run_inline_command('/power/state', 'boot', 'complete]')
if rc:
print("Error]\r")
else:
print("complete]\r")
print("Error]")
elif localcommand[2] == 'n': # boot to network
print("booting to network...")
sys.stdout.write("booting to network...")
sys.stdout.flush()
bootmode = 'uefi'
bootdev = 'network'
rc = session.simple_noderange_command(consolename, '/boot/nextdevice', bootdev, bootmode=bootmode)
rc = run_inline_command('/boot/nextdevice', bootdev, '', bootmode=bootmode)
if rc:
print("Error]\r")
else:
rc = session.simple_noderange_command(consolename, '/power/state', 'boot')
rc = run_inline_command('/power/state', 'boot', 'complete]')
if rc:
print("Error]\r")
else:
print("complete]\r")
elif localcommand[2] == '\x0d': # boot to default
print("booting to default...")
bootmode = 'uefi'
bootdev = 'default'
rc = session.simple_noderange_command(consolename, '/boot/nextdevice', bootdev, bootmode=bootmode)
rc = run_inline_command('/boot/nextdevice', bootdev, '', bootmode=bootmode)
if rc:
print("Error]\r")
else:
rc = session.simple_noderange_command(consolename, '/power/state', 'boot')
rc = run_inline_command('/power/state', 'boot', 'complete]')
if rc:
print("Error]\r")
else:
print("complete]\r")
else:
print("Unknown boot state.]\r")
else:
print("Unknown power state.]\r")
check_power_state()
elif localcommand[0] == 'r':
sys.stdout.write('\x1b7\x1b[999;999H\x1b[6n')
@@ -929,63 +938,7 @@ def main():
rdylist = ()
for fh in rdylist:
if fh == session.connection:
# this only should get called in the
# case of a console session
# each command should slurp up all relevant
# recv potential
#fh.read()
try:
data = tlvdata.recv(fh)
except Exception:
data = None
if type(data) == dict:
updatestatus(data)
continue
if data is not None:
data = client.stringify(data)
if clearpowermessage:
sys.stdout.write("\x1b[2J\x1b[;H")
clearpowermessage = False
try:
sys.stdout.write(data)
except IOError: # Some times circumstances are bad
# resort to byte at a time...
for d in data:
sys.stdout.write(d)
now = time.time()
if ('showtime' not in laststate or
(now // 60) != laststate['showtime'] // 60):
# don't bother churning if minute does not change
laststate['showtime'] = now
updatestatus()
try:
sys.stdout.flush()
except Exception:
# EWOULDBLOCK causes this to raise, ignore
# this scenario comfortable that it
# will come out soon enough
pass
else:
deadline = 5
connected = False
while not connected and deadline > 0:
try:
server_connect()
connected = True
except Exception:
pass
if not connected:
time.sleep(1)
deadline -=1
if connected:
do_command(
"start /nodes/%s/console/session skipreplay=True" % consolename,
netserver)
else:
doexit = True
inconsole = False
sys.stdout.write("\r\n[remote disconnected]\r\n")
break
consume_termdata(fh)
else:
try:
myinput = fh.read()
@@ -1011,6 +964,65 @@ def main():
sys.stdout.write('Lost connection to server')
quitconfetty(fullexit=True)
def consume_termdata(fh, bufferonly=False):
global clearpowermessage
try:
data = tlvdata.recv(fh)
except Exception:
data = None
if type(data) == dict:
updatestatus(data)
return ''
if data is not None:
data = client.stringify(data)
if clearpowermessage:
sys.stdout.write("\x1b[2J\x1b[;H")
clearpowermessage = False
if bufferonly:
return data
try:
sys.stdout.write(data)
except UnicodeEncodeError:
sys.stdout.buffer.write(data.encode('utf8'))
except IOError: # Some times circumstances are bad
# resort to byte at a time...
for d in data:
sys.stdout.write(d)
now = time.time()
if ('showtime' not in laststate or
(now // 60) != laststate['showtime'] // 60):
# don't bother churning if minute does not change
laststate['showtime'] = now
updatestatus()
try:
sys.stdout.flush()
except Exception:
# EWOULDBLOCK causes this to raise, ignore
# this scenario comfortable that it
# will come out soon enough
pass
else:
deadline = 5
connected = False
while not connected and deadline > 0:
try:
server_connect()
connected = True
except Exception:
pass
if not connected:
time.sleep(1)
deadline -=1
if connected:
do_command(
"start /nodes/%s/console/session skipreplay=True" % consolename,
netserver)
else:
doexit = True
inconsole = False
sys.stdout.write("\r\n[remote disconnected]\r\n")
return ''
if __name__ == '__main__':
errcode = 0
deadline = 0
@@ -1020,6 +1032,14 @@ if __name__ == '__main__':
main()
except BailOut as e:
errcode = e.errorcode
except Exception as e:
import traceback
excinfo = traceback.print_exc()
try:
quitconfetty()
except Exception:
pass
print(excinfo)
finally:
if deadline and os.times()[4] < deadline:
sys.stderr.write('[Exited early, hit enter to continue]')
+212
View File
@@ -0,0 +1,212 @@
#!/usr/bin/python2
import argparse
import os
import re
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
import confluent.sortutil as sortutil
def partitionhostsline(line):
comment = ''
if '#' in line:
cmdidx = line.index('#')
comment = line[cmdidx:]
line = line[:cmdidx].strip()
if not line.strip():
return '', [], comment
ipaddr, names = line.split(None, 1)
names = names.split()
return ipaddr, names, comment
class HostMerger(object):
def __init__(self):
self.byip = {}
self.byname = {}
self.byname6 = {}
self.sourcelines = []
self.targlines = []
def read_source(self, sourcefile):
with open(sourcefile, 'r') as hfile:
self.sourcelines = hfile.read().split('\n')
while not self.sourcelines[-1]:
self.sourcelines = self.sourcelines[:-1]
for x in range(len(self.sourcelines)):
line = self.sourcelines[x]
currip, names, comment = partitionhostsline(line)
if currip:
self.byip[currip] = x
byname = self.byname
if ':' in currip:
byname = self.byname6
for name in names:
byname[name] = x
def add_entry(self, ip, names):
targ = self.byname
if ':' in ip:
targ = self.byname6
line = '{:<39} {}'.format(ip, names)
x = len(self.sourcelines)
self.sourcelines.append(line)
for name in names.split():
if not name:
continue
targ[name] = x
self.byip[ip] = x
def read_target(self, targetfile):
if not os.path.exists(targetfile):
return
with open(targetfile, 'r') as hfile:
lines = hfile.read().split('\n')
while lines and not lines[-1]:
lines = lines[:-1]
for y in range(len(lines)):
line = lines[y]
currip, names, comment = partitionhostsline(line)
byname = self.byname
if ':' in currip:
byname = self.byname6
if currip in self.byip:
x = self.byip[currip]
if self.sourcelines[x] is None:
# have already consumed this entry
continue
self.targlines.append(self.sourcelines[x])
self.sourcelines[x] = None
continue
for name in names:
if name in byname:
x = byname[name]
if self.sourcelines[x] is None:
break
self.targlines.append(self.sourcelines[x])
self.sourcelines[x] = None
break
else:
self.targlines.append(line)
def write_out(self, targetfile):
while self.targlines and not self.targlines[-1]:
self.targlines = self.targlines[:-1]
while self.sourcelines and not self.sourcelines[-1]:
self.sourcelines = self.sourcelines[:-1]
if not self.sourcelines:
break
with open(targetfile, 'w') as hosts:
for line in self.targlines:
hosts.write(line + '\n')
for line in self.sourcelines:
if line is not None:
hosts.write(line + '\n')
def main():
ap = argparse.ArgumentParser(description="Create/amend /etc/hosts file for given noderange")
ap.add_argument('noderange', help='Noderange to generate/update /etc/hosts for')
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')
args = ap.parse_args()
c = client.Command()
if args.name:
names = ' '.join(args.name)
else:
names = '{node} {node}.{dns.domain}'
merger = HostMerger()
if not args.ip and not args.attrib:
sys.stderr.write('-a or -i is currently required\n')
sys.exit(1)
if args.attrib:
ip4bynode = {}
ip6bynode = {}
namesbynode = {}
domainsbynode = {}
for ent in c.read('/noderange/{0}/attributes/current'.format(args.noderange)):
ent = ent.get('databynode', {})
for node in ent:
for attrib in ent[node]:
val = ent[node][attrib]
if not isinstance(val, dict):
continue
val = val.get('value', None)
if attrib == 'dns.domain':
domainsbynode[node] = val
if attrib.startswith('net.'):
nameparts = attrib.split('.')
if len(nameparts) == 2:
currnet = None
else:
currnet = '.'.join(nameparts[1:-1])
for currdict in (ip4bynode, ip6bynode, namesbynode):
if node not in currdict:
currdict[node] = {}
if attrib.endswith('.ipv4_address') and val:
ip4bynode[node][currnet] = val.split('/', 1)[0]
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)
for node in ip4bynode:
mydomain = domainsbynode.get(node, None)
for ipdb in (ip4bynode, ip6bynode):
for currnet in ipdb[node]:
if args.name:
sys.stderr.write('Custom name and attribute addresses not currently supported together\n')
sys.exit(1)
else:
names = list(namesbynode.get(node, {}).get(currnet, [node]))
if mydomain:
for name in names:
if mydomain in names:
break
else:
for name in list(names):
names.append('{0}.{1}'.format(name, mydomain))
names = ' '.join(names)
merger.add_entry(ipdb[node][currnet], names)
merger.write_out('/etc/whatnowhosts')
else:
namesbynode = {}
ipbynode = {}
expurl = '/noderange/{0}/attributes/expression'.format(args.noderange)
expression = names
exitcode = 0
exitcode |= expand_expression(c, namesbynode, expurl, names)
exitcode |= expand_expression(c, ipbynode, expurl, args.ip)
if exitcode:
sys.exit(exitcode)
for node in ipbynode:
merger.add_entry(ipbynode[node], namesbynode[node])
if os.path.exists('/etc/hosts'):
merger.read_target('/etc/hosts')
os.rename('/etc/hosts', '/etc/hosts.confluentbkup')
merger.write_out('/etc/hosts')
def expand_expression(c, namesbynode, expurl, expression):
exitcode = 0
for exp in c.create(expurl, {'expression': expression}):
if 'error' in exp:
sys.stderr.write(exp['error'] + '\n')
exitcode |= exp.get('errorcode', 1)
ex = exp.get('databynode', ())
for node in ex:
namesbynode[node] = ex[node]['value']
return exitcode
if __name__ == '__main__':
main()
+12 -4
View File
@@ -8,7 +8,7 @@ import os
import subprocess
import sys
def create_image(directory, image):
def create_image(directory, image, label=None):
ents = 0
datasz = 512
for dir in os.walk(sys.argv[1]):
@@ -25,8 +25,13 @@ def create_image(directory, image):
with open(image, 'wb') as imgfile:
imgfile.seek(datasz * 512 - 1)
imgfile.write(b'\x00')
subprocess.check_call(['mformat', '-i', image, '-r', '16', '-d', '1', '-t',
str(datasz), '-s', '1','-h', '1', '::'])
if label:
subprocess.check_call(['mformat', '-i', image, '-v', label,
'-r', '16', '-d', '1', '-t', str(datasz),
'-s', '1','-h', '1', '::'])
else:
subprocess.check_call(['mformat', '-i', image, '-r', '16', '-d', '1', '-t',
str(datasz), '-s', '1','-h', '1', '::'])
# 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
@@ -50,4 +55,7 @@ if __name__ == '__main__':
sys.stderr.write("Usage: {0} <directory> <imagefile>".format(
sys.argv[0]))
sys.exit(1)
create_image(sys.argv[1], sys.argv[2])
label = None
if len(sys.argv) > 3:
label = sys.argv[3]
create_image(sys.argv[1], sys.argv[2], label)
+2 -2
View File
@@ -47,14 +47,14 @@ exitcode = 0
errorNodes = set([])
session.stop_if_noderange_over(noderange, options.maxnodes)
success = session.simple_noderange_command(noderange, 'configuration/management_controller/reset', 'reset', key='state', errnodes=errorNodes) # = 0 if successful
if success != 0:
sys.exit(success)
# Determine which nodes were successful and print them
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
+13 -8
View File
@@ -43,7 +43,7 @@ def bailout(msg, code=1):
sys.exit(code)
argparser = optparse.OptionParser(usage="Usage: %prog [options] noderange [option|option=value]")
argparser = optparse.OptionParser(usage="Usage: %prog [options] <noderange> [setting|setting=value]")
argparser.add_option('-c', '--comparedefault', dest='comparedefault',
action='store_true', default=False,
help='Compare given settings to default or list settings '
@@ -134,9 +134,10 @@ def _assign_value():
assignment[key] = value
def parse_config_line(arguments):
def parse_config_line(arguments, single=False):
global setmode, printallbmc, forceset, key, value, needval, candidate, path, attrib
for param in arguments:
for pidx in range(0, len(arguments)):
param = arguments[pidx]
if param == 'show':
continue # forgive muscle memory of pasu users
if param == 'set':
@@ -146,14 +147,19 @@ def parse_config_line(arguments):
if needval:
key = needval
needval = None
value = param
if single:
value = ' '.join(arguments[pidx:])
_assign_value()
break
else:
value = param
_assign_value()
continue
if '=' in param or param[-1] == ':' or forceset:
if setmode is None:
setmode = True
if setmode != True:
bailout('Cannot do set and query in same command')
bailout('Cannot do set and query in same command: Query detected but "{0}" appears to be set'.format(param))
if '=' in param:
key, _, value = param.partition('=')
_assign_value()
@@ -165,7 +171,7 @@ def parse_config_line(arguments):
if setmode is None:
setmode = False
if setmode != False:
bailout('Cannot do set and query in same command')
bailout('Cannot do set and query in same command: Set mode detected but "{0}" appears to be a query'.format(param))
if '.' not in param:
if param == 'bmc':
printallbmc = True
@@ -215,7 +221,7 @@ if options.batch:
pass
argset = argset.strip()
if argset:
parse_config_line(shlex.split(argset))
parse_config_line(shlex.split(argset), single=True)
argset = argfile.readline()
else:
parse_config_line(args[1:])
@@ -272,7 +278,6 @@ if setmode:
rcode |= client.printerror(fr)
for node in fr.get('databynode', []):
r = fr['databynode'][node]
rcode |= client.printerror(r, node)
if 'value' not in r:
continue
keyval = r['value']
+18 -1
View File
@@ -79,7 +79,7 @@ def main(args):
sys.stderr.write('-n is a required argument currently to perform an install, optionally with -p\n')
return 1
if not args.profile and args.network:
sys.stderr.write('profile is a required argument to request a network deployment\n')
sys.stderr.write('Both noderange and a profile name are required arguments to request a network deployment\n')
return 1
if extra:
sys.stderr.write('Unrecognized arguments: ' + repr(extra) + '\n')
@@ -89,6 +89,23 @@ def main(args):
cleararm(args.noderange, c)
clearpending(args.noderange, c)
elif args.profile:
profnames = []
for prof in c.read('/deployment/profiles/'):
profname = prof.get('item', {}).get('href', None)
if profname:
profname = profname.replace('/', '')
profnames.append(profname)
if profname == args.profile:
break
else:
sys.stderr.write('The specified profile "{}" is not an available profile\n'.format(args.profile))
if profnames:
sys.stderr.write('The following profiles are available:\n')
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.exit(1)
armonce(args.noderange, c)
setpending(args.noderange, args.profile, c)
else:
+17 -1
View File
@@ -34,6 +34,7 @@ defcolumns = ['Node', 'Model', 'Serial', 'UUID', 'Mac Address', 'Type',
columnmapping = {
'Node': 'nodename',
'Model': 'modelnumber',
'Model Name': 'modelname',
'Serial': 'serialnumber',
'UUID': 'uuid',
'Type': 'types',
@@ -148,6 +149,7 @@ unique_fields = frozenset(['serial', 'mac', 'uuid'])
def import_csv(options, session):
nodedata = []
unique_data = {}
exitcode = 0
with open(options.importfile, 'r') as datasrc:
records = csv.reader(datasrc)
fields = process_header(next(records))
@@ -188,6 +190,7 @@ def import_csv(options, session):
for res in session.create('/nodes/', datum):
if 'error' in res:
sys.stderr.write(res['error'] + '\n')
exitcode |= res.get('errorcode', 1)
continue
elif 'created' in res:
print('Defined ' + res['created'])
@@ -198,11 +201,14 @@ def import_csv(options, session):
{'node': nodename}):
if 'error' in res:
sys.stderr.write(res['error'] + '\n')
exitcode |= res.get('errorcode', 1)
continue
elif 'assigned' in res:
print('Discovered ' + res['assigned'])
else:
print(repr(res))
if exitcode:
sys.exit(exitcode)
def list_discovery(options, session):
@@ -263,7 +269,11 @@ def list_matching_macs(options, session, node=None, checknode=True):
return [options.mac.replace(':', '-')]
else:
path += 'by-mac/'
return [x['item']['href'] for x in session.read(path)]
ret = []
for x in session.read(path):
if 'item' in x and 'href' in x['item']:
ret.append(x['item']['href'])
return ret
def assign_discovery(options, session, needid=True):
abort = False
@@ -287,12 +297,18 @@ def assign_discovery(options, session, needid=True):
if not matches:
sys.stderr.write("No matching discovery candidates found\n")
sys.exit(1)
exitcode = 0
for res in session.update('/discovery/by-mac/{0}'.format(matches[0]),
{'node': options.node}):
if 'assigned' in res:
print('Assigned: {0}'.format(res['assigned']))
elif 'error' in res:
sys.stderr.write('Error: {0}\n'.format(res['error']))
exitcode |= res.get('errorcode', 1)
else:
print(repr(res))
if exitcode:
sys.exit(exitcode)
def blocking_scan(session):
list(session.update('/discovery/rescan', {'rescan': 'start'}))
+1 -1
View File
@@ -37,7 +37,7 @@ if sys.version_info[0] < 3:
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
argparser = optparse.OptionParser(
usage="Usage: %prog [options] noderange [clear]")
usage="Usage: %prog [options] <noderange> [clear]")
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to clear if clearing log, '
+11 -2
View File
@@ -109,6 +109,12 @@ def update_firmware(session, filename):
if options.backup:
upargs['bank'] = 'backup'
noderrs = {}
if session.unixdomain:
of = open(filename, 'rb')
try:
session.add_file(filename, of.fileno(), 'rb')
except Exception:
pass
for res in session.create(resource, upargs):
if 'created' not in res:
for nodename in res.get('databynode', ()):
@@ -141,22 +147,25 @@ def update_firmware(session, filename):
def show_firmware(session):
global exitcode
firmware_shown = False
nodes_matched = False
for component in components:
for res in session.read(
'/noderange/{0}/inventory/firmware/all/{1}'.format(
noderange, component)):
nodes_matched = True
exitcode |= client.printerror(res)
if 'databynode' not in res:
continue
for node in res['databynode']:
exitcode |= client.printerror(res['databynode'][node], node)
if 'firmware' not in res['databynode'][node]:
continue
for inv in res['databynode'][node]['firmware']:
for prefix in inv:
firmware_shown = True
printfirm(node, prefix, inv[prefix])
if not firmware_shown and not exitcode:
if not nodes_matched:
sys.stderr.write('No matching nodes for noderange "{0}"\n'.format(noderange))
elif not firmware_shown and not exitcode:
argparser.print_help()
+11 -10
View File
@@ -45,14 +45,15 @@ except IndexError:
client.check_globbing(noderange)
session = client.Command()
exitcode = 0
attribs = {'name': noderange}
for arg in args[1:]:
key, val = arg.split('=', 1)
attribs[key] = val
for r in session.create('/nodegroups/', attribs):
if 'error' in r:
sys.stderr.write(r['error'] + '\n')
exitcode |= 1
if 'created' in r:
print('{0}: created'.format(r['created']))
for group in noderange.split(','):
attribs = {'name': group}
for arg in args[1:]:
key, val = arg.split('=', 1)
attribs[key] = val
for r in session.create('/nodegroups/', attribs):
if 'error' in r:
sys.stderr.write(r['error'] + '\n')
exitcode |= 1
if 'created' in r:
print('{0}: created'.format(r['created']))
sys.exit(exitcode)
+7 -6
View File
@@ -43,10 +43,11 @@ noderange = args[0]
client.check_globbing(noderange)
session = client.Command()
exitcode = 0
for r in session.delete('/nodegroups/{0}'.format(noderange)):
if 'error' in r:
sys.stderr.write(r['error'] + '\n')
exitcode |= 1
if 'deleted' in r:
print('{0}: deleted'.format(r['deleted']))
for group in noderange.split(','):
for r in session.delete('/nodegroups/{0}'.format(group)):
if 'error' in r:
sys.stderr.write(r['error'] + '\n')
exitcode |= 1
if 'deleted' in r:
print('{0}: deleted'.format(r['deleted']))
sys.exit(exitcode)
+3
View File
@@ -53,6 +53,9 @@ def print_mem_info(node, prefix, meminfo):
memdescfmt += '3-{1} '
elif 'DDR4' in meminfo['memory_type']:
memdescfmt += '4-{1} '
elif 'DCPMM' in meminfo['memory_type']:
memdescfmt = '{0}GB {1} '
meminfo['module_type'] = 'DCPMM'
else:
print('{0}: {1}: Unrecognized Memory'.format(node, prefix))
return
+7 -1
View File
@@ -36,7 +36,7 @@ exitcode = 0
argparser = optparse.OptionParser(
usage="Usage: "
"%prog <noderange> [list][install <file>|save <directory>|delete <name>]")
"%prog <noderange> [list][install <license_filename>|save <directory>|delete <license_feature_name>]")
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to delete licenses from, '
@@ -69,6 +69,12 @@ def install_license(session, filename):
'management_controller/licenses/'.format(noderange)
filename = os.path.abspath(filename)
instargs = {'filename': filename}
if session.unixdomain:
of = open(filename, 'rb')
try:
session.add_file(filename, of.fileno(), 'rb')
except Exception:
pass
for res in session.create(resource, instargs):
for node in res.get('databynode', []):
if 'error' in res['databynode'][node]:
+8
View File
@@ -111,6 +111,12 @@ def upload_media(noderange, media):
resource = '/noderange/{0}/media/uploads/'.format(noderange)
upargs = {'filename': filename}
noderrs = {}
if session.unixdomain:
of = open(filename, 'rb')
try:
session.add_file(filename, of.fileno(), 'rb')
except Exception:
pass
nodeurls = {}
for res in session.create(resource, upargs):
if 'created' not in res:
@@ -187,5 +193,7 @@ def main():
argparser.print_help()
sys.exit(1)
handler(noderange, media)
if __name__ == '__main__':
main()
sys.exit(exitcode)
+2 -2
View File
@@ -32,7 +32,7 @@ if path.startswith('/opt'):
import confluent.client as client
argparser = optparse.OptionParser(
usage="Usage: %prog [options] noderange "
usage="Usage: %prog [options] <noderange> "
"([status|on|off|shutdown|boot|reset])")
argparser.add_option('-p', '--showprevious', dest='previous',
action='store_true', default=False,
@@ -77,4 +77,4 @@ if options.previous:
# add dictionary to session
session.add_precede_dict(prev)
sys.exit(session.simple_noderange_command(noderange, '/power/state', setstate, promptover=options.maxnodes))
sys.exit(session.simple_noderange_command(noderange, '/power/state', setstate, promptover=options.maxnodes))
+1 -1
View File
@@ -33,7 +33,7 @@ if path.startswith('/opt'):
import confluent.client as client
argparser = optparse.OptionParser(
usage='''\n %prog noderange
usage='''\n %prog <noderange>
\n ''')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
+1 -1
View File
@@ -40,7 +40,7 @@ import confluent.sortutil as sortutil
def run():
argparser = optparse.OptionParser(
usage="Usage: %prog location noderange:location",
usage="Usage: %prog <file/directorylist> <noderange>:<destination>",
)
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
+1 -1
View File
@@ -39,7 +39,7 @@ import confluent.sortutil as sortutil
def run():
argparser = optparse.OptionParser(
usage="Usage: %prog [options] noderange commandexpression",
usage="Usage: %prog [options] <noderange> <command expression>",
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,
+8 -1
View File
@@ -32,6 +32,13 @@ path = os.path.realpath(os.path.join(path, '..', 'lib', 'python'))
if path.startswith('/opt'):
sys.path.append(path)
class hybridcsv(csv.excel):
lineterminator = '\n'
csv.register_dialect('hybrid', hybridcsv)
import confluent.client as client
sensorcollections = {
@@ -209,7 +216,7 @@ def main():
headernames.append(headername)
if options.csv:
linebyline = False
csvwriter = csv.writer(sys.stdout)
csvwriter = csv.writer(sys.stdout, dialect='hybrid')
if options.interval:
csvwriter.writerow(['time', 'node'] + headernames)
else:
+1 -1
View File
@@ -32,7 +32,7 @@ if path.startswith('/opt'):
import confluent.client as client
argparser = optparse.OptionParser(
usage='Usage: %prog [options] noderange [default|cd|network|setup|hd|floppy]')
usage='Usage: %prog [options] <noderange> [default|cd|network|setup|hd|usb|floppy]')
argparser.add_option('-b', '--bios', dest='biosmode',
action='store_true', default=False,
help='Request BIOS style boot (rather than UEFI)')
+23 -3
View File
@@ -44,10 +44,14 @@ def run():
"'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('-l', '--loginname', type='str',
help='Username to use when connecting, defaults to current user.')
argparser.add_option('-n', '--nonodeprefix', action='store_true',
help='Do not prefix output with node names')
argparser.add_option('-p', '--port', type='int', default=0,
help='Specify a custom port for ssh')
argparser.add_option('-s', '--substitutename',
help='Use a different name other than the nodename for ssh')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to run remote ssh command to, '
@@ -71,6 +75,19 @@ def run():
exitcode = 0
c.stop_if_noderange_over(args[0], options.maxnodes)
nodemap = {}
if options.substitutename:
subname = options.substitutename
if '{' not in subname:
subname = '{node}' + subname
for exp in c.create('/noderange/{0}/attributes/expression'.format(args[0]),
{'expression': subname}):
if 'error' in exp:
sys.stderr.write(exp['error'] + '\n')
exitcode |= exp.get('errorcode', 1)
ex = exp.get('databynode', ())
for node in ex:
nodemap[node] = ex[node]['value']
for exp in c.create('/noderange/{0}/attributes/expression'.format(args[0]),
{'expression': cmdstr}):
if 'error' in exp:
@@ -79,12 +96,15 @@ def run():
ex = exp.get('databynode', ())
for node in ex:
cmd = ex[node]['value']
sshnode = nodemap.get(node, node)
if not isinstance(cmd, str) and not isinstance(cmd, bytes):
cmd = cmd.encode('utf-8')
cmdv = ['ssh']
if options.port:
cmdv = ['ssh', '-p', '{0}'.format(options.port), node, cmd]
else:
cmdv = ['ssh', node, cmd]
cmdv += ['-p', '{0}'.format(options.port)]
if options.loginname:
cmdv += ['-l', options.loginname]
cmdv += [sshnode, cmd]
if currprocs < concurrentprocs:
currprocs += 1
run_cmdv(node, cmdv, all, pipedesc)
+14 -1
View File
@@ -20,6 +20,10 @@ import os
import signal
import sys
try:
input = raw_input
except NameError:
pass
try:
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
except AttributeError:
@@ -186,7 +190,7 @@ funmap = {
def main():
argparser = OptParser(
usage='Usage: %prog <noderange> [show|create|delete|diskset]',
usage='Usage: %prog <noderange> [show|create|delete|diskset] [hotspare|jbod|unconfigured] [options]',
epilog='',
)
argparser.add_option('-r', '--raidlevel', type='int',
@@ -195,6 +199,8 @@ def main():
help='Comma separated list of disks to use, or the '
'word "rest" to indicate use of all available '
'disks')
argparser.add_option('-i', '--interactive', default=False, action='store_true',
help='Confirm any potentially destructive changes interactively')
argparser.add_option('-s', '--size', type='str',
help='Comma separated list of sizes to use when '
'creating volumes. The sizes may be absolute '
@@ -230,6 +236,13 @@ def main():
except KeyError:
argparser.print_help()
sys.exit(1)
if options.interactive and operation != 'show':
showstorage(noderange, None, None)
sys.stdout.write('The above configuration will be changed by this action, do you wish to continue (y/N): ')
confirm = input()
if confirm and confirm.lower()[0] != 'y':
sys.stdout.write('Aborting\n')
sys.exit(1)
handler(noderange, options, args[2:])
+1 -1
View File
@@ -116,7 +116,7 @@ class OptParser(optparse.OptionParser):
def main():
argparser = OptParser(
usage="Usage: %prog <noderange> servicedata "
"<filename>",
"<directory or filename>",
epilog='\nservicedata will save service data to the given '
'directory. It is saved to the location on the relevant '
'management server (the confluent server if running remote, '
+10 -4
View File
@@ -22,17 +22,23 @@ import io
import numpy as np
import os
import sixel
import subprocess
import sys
class DumbWriter(sixel.SixelWriter):
def restore_position(self, output):
return
try:
import sixel
class DumbWriter(sixel.SixelWriter):
def restore_position(self, output):
return
except ImportError:
pass
def plot(gui, output, plotdata, bins):
import matplotlib as mpl
if gui and mpl.get_backend() == 'agg':
sys.stderr.write('Error: No GUI backend available and -g specified!\n')
if not gui:
mpl.use('Agg')
import matplotlib.pyplot as plt
+62 -15
View File
@@ -46,6 +46,13 @@ try:
except NameError:
pass
class NestedDict(dict):
def __missing__(self, key):
value = self[key] = type(self)()
return value
def stringify(instr):
# Normalize unicode and bytes to 'str', correcting for
# current python version
@@ -111,6 +118,12 @@ def printerror(res, node=None):
exitcode = 0
if 'errorcode' in res:
exitcode = res['errorcode']
for node in res.get('databynode', {}):
exitcode = res['databynode'][node].get('errorcode', exitcode)
if 'error' in res['databynode'][node]:
sys.stderr.write('{0}: {1}\n'.format(node, res['databynode'][node]['error']))
if exitcode == 0:
exitcode = 1
if 'error' in res:
if node:
sys.stderr.write('{0}: {1}\n'.format(node, res['error']))
@@ -148,6 +161,7 @@ class Command(object):
self._prevkeyname = None
self.connection = None
self._currnoderange = None
self.unixdomain = False
if server is None:
if 'CONFLUENT_HOST' in os.environ:
self.serverloc = os.environ['CONFLUENT_HOST']
@@ -157,11 +171,13 @@ class Command(object):
self.serverloc = server
if os.path.isabs(self.serverloc) and os.path.exists(self.serverloc):
self._connect_unix()
self.unixdomain = True
elif self.serverloc == '/var/run/confluent/api.sock':
raise Exception('Confluent service is not available')
else:
self._connect_tls()
tlvdata.recv(self.connection)
self.protversion = int(tlvdata.recv(self.connection).split(
b'--')[1].strip()[1:])
authdata = tlvdata.recv(self.connection)
if authdata['authpassed'] == 1:
self.authenticated = True
@@ -172,6 +188,13 @@ class Command(object):
passphrase = os.environ['CONFLUENT_PASSPHRASE']
self.authenticate(username, passphrase)
def add_file(self, name, handle, mode):
if self.protversion < 3:
raise Exception('Not supported with connected confluent server')
if not self.unixdomain:
raise Exception('Can only add a file to a unix domain connection')
tlvdata.send(self.connection, {'filename': name, 'mode': mode}, handle)
def authenticate(self, username, password):
tlvdata.send(self.connection,
{'username': username, 'password': password})
@@ -411,7 +434,7 @@ def send_request(operation, path, server, parameters=None):
result = tlvdata.recv(server)
def attrrequested(attr, attrlist, seenattributes):
def attrrequested(attr, attrlist, seenattributes, node=None):
for candidate in attrlist:
truename = candidate
if candidate.startswith('hm'):
@@ -419,10 +442,16 @@ def attrrequested(attr, attrlist, seenattributes):
if candidate in _attraliases:
candidate = _attraliases[candidate]
if fnmatch.fnmatch(attr.lower(), candidate.lower()):
seenattributes.add(truename)
if node is None:
seenattributes.add(truename)
else:
seenattributes[node][truename] = True
return True
elif attr.lower().startswith(candidate.lower() + '.'):
seenattributes.add(truename)
if node is None:
seenattributes.add(truename)
else:
seenattributes[node][truename] = 1
return True
return False
@@ -438,13 +467,15 @@ def _sort_attrib(k):
def print_attrib_path(path, session, requestargs, options, rename=None, attrprefix=None):
exitcode = 0
seenattributes = set([])
seenattributes = NestedDict()
allnodes = set([])
for res in session.read(path):
if 'error' in res:
sys.stderr.write(res['error'] + '\n')
exitcode = 1
continue
for node in sorted(res['databynode']):
allnodes.add(node)
for attr, val in sorted(res['databynode'][node].items(), key=_sort_attrib):
if attr == 'error':
sys.stderr.write('{0}: Error: {1}\n'.format(node, val))
@@ -452,7 +483,7 @@ def print_attrib_path(path, session, requestargs, options, rename=None, attrpref
if attr == 'errorcode':
exitcode |= val
continue
seenattributes.add(attr)
seenattributes[node][attr] = True
if rename:
printattr = rename.get(attr, attr)
else:
@@ -460,7 +491,7 @@ def print_attrib_path(path, session, requestargs, options, rename=None, attrpref
if attrprefix:
printattr = attrprefix + printattr
currattr = res['databynode'][node][attr]
if show_attr(attr, requestargs, seenattributes, options):
if show_attr(attr, requestargs, seenattributes, options, node):
if 'value' in currattr:
if currattr['value'] is not None:
val = currattr['value']
@@ -476,7 +507,7 @@ def print_attrib_path(path, session, requestargs, options, rename=None, attrpref
printattr)
else:
attrout = '{0}: {1}:'.format(node, printattr)
elif 'broken' in currattr:
elif isinstance(currattr, dict) and 'broken' in currattr:
attrout = '{0}: {1}: *ERROR* BROKEN EXPRESSION: ' \
'{2}'.format(node, printattr,
currattr['broken'])
@@ -493,7 +524,7 @@ def print_attrib_path(path, session, requestargs, options, rename=None, attrpref
blame = options.blame
except AttributeError:
blame = False
if blame or 'broken' in currattr:
if blame or (isinstance(currattr, dict) and 'broken' in currattr):
blamedata = []
if 'inheritedfrom' in currattr:
blamedata.append('inherited from group {0}'.format(
@@ -541,23 +572,39 @@ def print_attrib_path(path, session, requestargs, options, rename=None, attrpref
except TypeError:
pass
cprint(attrout)
somematched = set([])
printmissing = set([])
badnodes = NestedDict()
if not exitcode:
if requestargs:
for attr in requestargs:
if attr not in seenattributes:
sys.stderr.write('Error: {0} not a valid attribute\n'.format(attr))
exitcode = 1
for node in allnodes:
if attr in seenattributes[node]:
somematched.add(attr)
else:
badnodes[node][attr] = True
exitcode = 1
for node in sortutil.natural_sort(badnodes):
for attr in badnodes[node]:
if attr in somematched:
sys.stderr.write(
'Error: {0} matches no valid value for {1}\n'.format(
attr, node))
else:
printmissing.add(attr)
for missing in printmissing:
sys.stderr.write('Error: {0} not a valid attribute\n'.format(attr))
return exitcode
def show_attr(attr, requestargs, seenattributes, options):
def show_attr(attr, requestargs, seenattributes, options, node):
try:
reverse = options.exclude
except AttributeError:
reverse = False
if requestargs is None or requestargs == []:
return True
processattr = attrrequested(attr, requestargs, seenattributes)
processattr = attrrequested(attr, requestargs, seenattributes, node)
if reverse:
processattr = not processattr
return processattr
@@ -586,7 +633,7 @@ def printgroupattributes(session, requestargs, showtype, nodetype, noderange, op
attrout = '{0}: {1}: ********'.format(noderange, attr)
else:
attrout = '{0}: {1}:'.format(noderange, attr)
elif 'broken' in currattr:
elif isinstance(currattr, dict) and 'broken' in currattr:
attrout = '{0}: {1}: *ERROR* BROKEN EXPRESSION: ' \
'{2}'.format(noderange, attr,
currattr['broken'])
+22 -14
View File
@@ -17,9 +17,9 @@ import sys
import struct
import termios
def get_screenwidth():
def get_screengeom():
return struct.unpack('hh', fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ,
b'....'))[1]
b'....'))
class ScreenPrinter(object):
def __init__(self, noderange, client, textlen=4):
@@ -44,7 +44,7 @@ class ScreenPrinter(object):
self.fieldwidth = maxlen + textlen + 1 # 1 for column
def set_output(self, node, text):
if self.nodeoutput[node] == text:
if self.nodeoutput.get(node, None) == text:
return
self.nodeoutput[node] = text
if len(text) >= self.textlen:
@@ -54,23 +54,31 @@ class ScreenPrinter(object):
def drawscreen(self):
if self.squeeze:
currwidth = get_screenwidth()
currheight, currwidth = get_screengeom()
currheight -= 1
numfields = currwidth // self.fieldwidth
fieldformat = '{{0:>{0}}}:{{1:{1}}}'.format(self.nodenamelen,
self.textlen)
sys.stdout.write('\x1b[2J\x1b[;H') # clear screen
if len(self.nodelist) < (numfields * currheight):
numfields = len(self.nodelist) // currheight + 1
else:
numfields = 1
fieldformat = '{0}: {1}'
currfields = 0
for node in self.nodelist:
if currfields >= numfields:
if self.squeeze:
columns = [self.nodelist[x:x+currheight] for x in range(0, len(self.nodelist), currheight)]
for currow in range(0, len(columns[0])):
for col in columns:
try:
node = col[currow]
sys.stdout.write(fieldformat.format(node, self.nodeoutput[node]))
except IndexError:
break
sys.stdout.write('\n')
else:
for node in self.nodelist:
sys.stdout.write(fieldformat.format(node, self.nodeoutput[node]))
sys.stdout.write('\n')
currfields = 1
else:
currfields += 1
sys.stdout.write(fieldformat.format(node, self.nodeoutput[node]))
sys.stdout.write('\n')
sys.stdout.flush()
@@ -80,8 +88,8 @@ class ScreenPrinter(object):
if __name__ == '__main__':
import confluent.client as client
c = client.Command()
p = ScreenPrinter('n1-n13', c)
p.set_output('n3', 'Upload: 67%')
p = ScreenPrinter('d1-d12', c)
p.set_output('d3', 'Upload: 67%')
+1 -1
View File
@@ -17,4 +17,4 @@
class Types(object):
text, json = range(2)
text, json, filehandle = range(3)
+130 -10
View File
@@ -15,9 +15,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import array
import ctypes
import ctypes.util
import confluent.tlv as tlv
import eventlet.green.socket as socket
import eventlet.green.select as select
from datetime import datetime
import json
import os
import struct
try:
@@ -30,6 +36,72 @@ try:
except NameError:
pass
class iovec(ctypes.Structure): # from uio.h
_fields_ = [('iov_base', ctypes.c_void_p),
('iov_len', ctypes.c_size_t)]
iovec_ptr = ctypes.POINTER(iovec)
class cmsghdr(ctypes.Structure): # also from bits/socket.h
_fields_ = [('cmsg_len', ctypes.c_size_t),
('cmsg_level', ctypes.c_int),
('cmsg_type', ctypes.c_int)]
@classmethod
def init_data(cls, cmsg_len, cmsg_level, cmsg_type, cmsg_data):
Data = ctypes.c_ubyte * ctypes.sizeof(cmsg_data)
class _flexhdr(ctypes.Structure):
_fields_ = cls._fields_ + [('cmsg_data', Data)]
datab = Data(*bytearray(cmsg_data))
return _flexhdr(cmsg_len=cmsg_len, cmsg_level=cmsg_level,
cmsg_type=cmsg_type, cmsg_data=datab)
def CMSG_LEN(length):
sizeof_cmshdr = ctypes.sizeof(cmsghdr)
return ctypes.c_size_t(CMSG_ALIGN(sizeof_cmshdr).value + length)
SCM_RIGHTS = 1
class msghdr(ctypes.Structure): # from bits/socket.h
_fields_ = [('msg_name', ctypes.c_void_p),
('msg_namelen', ctypes.c_uint),
('msg_iov', ctypes.POINTER(iovec)),
('msg_iovlen', ctypes.c_size_t),
('msg_control', ctypes.c_void_p),
('msg_controllen', ctypes.c_size_t),
('msg_flags', ctypes.c_int)]
def CMSG_ALIGN(length): # bits/socket.h
ret = (length + ctypes.sizeof(ctypes.c_size_t) - 1
& ~(ctypes.sizeof(ctypes.c_size_t) - 1))
return ctypes.c_size_t(ret)
def CMSG_SPACE(length): # bits/socket.h
ret = CMSG_ALIGN(length).value + CMSG_ALIGN(ctypes.sizeof(cmsghdr)).value
return ctypes.c_size_t(ret)
class ClientFile(object):
def __init__(self, name, mode, fd):
self.fileobject = os.fdopen(fd, mode)
self.filename = name
libc = ctypes.CDLL(ctypes.util.find_library('c'))
recvmsg = libc.recvmsg
recvmsg.argtypes = [ctypes.c_int, ctypes.POINTER(msghdr), ctypes.c_int]
recvmsg.restype = ctypes.c_int
sendmsg = libc.sendmsg
sendmsg.argtypes = [ctypes.c_int, ctypes.POINTER(msghdr), ctypes.c_int]
sendmsg.restype = ctypes.c_size_t
def decodestr(value):
ret = None
try:
@@ -65,7 +137,7 @@ def _unicode_list(currlist):
_unicode_list(currlist[i])
def send(handle, data):
def send(handle, data, filehandle=None):
if isinstance(data, unicode):
try:
data = data.encode('utf-8')
@@ -93,9 +165,27 @@ def send(handle, data):
if tl > 16777215:
raise Exception("JSON data exceeds protocol limits")
# xor in the type (0b1 << 24)
tl |= 16777216
handle.sendall(struct.pack("!I", tl))
handle.sendall(sdata)
if filehandle is None:
tl |= 16777216
handle.sendall(struct.pack("!I", tl))
handle.sendall(sdata)
else:
tl |= (2 << 24)
handle.sendall(struct.pack("!I", tl))
cdtype = ctypes.c_ubyte * len(sdata)
cdata = cdtype.from_buffer(bytearray(sdata))
ciov = iovec(iov_base=ctypes.addressof(cdata),
iov_len=ctypes.c_size_t(ctypes.sizeof(cdata)))
fd = ctypes.c_int(filehandle)
cmh = cmsghdr.init_data(
cmsg_len=CMSG_LEN(
ctypes.sizeof(fd)), cmsg_level=socket.SOL_SOCKET,
cmsg_type=SCM_RIGHTS, cmsg_data=fd)
mh = msghdr(msg_name=None, msg_len=0, msg_iov=iovec_ptr(ciov),
msg_iovlen=1, msg_control=ctypes.addressof(cmh),
msg_controllen=ctypes.c_size_t(ctypes.sizeof(cmh)))
sendmsg(handle.fileno(), mh, 0)
def recvall(handle, size):
rd = handle.recv(size)
@@ -125,12 +215,42 @@ def recv(handle):
datatype = (tl & 2130706432) >> 24 # grab 7 bits from near beginning
if dlen == 0:
return None
data = handle.recv(dlen)
while len(data) < dlen:
ndata = handle.recv(dlen - len(data))
if not ndata:
raise Exception("Error reading data")
data += ndata
if datatype == tlv.Types.filehandle:
filehandles = array.array('i')
rawbuffer = bytearray(2048)
pkttype = ctypes.c_ubyte * 2048
data = pkttype.from_buffer(rawbuffer)
cmsgsize = CMSG_SPACE(ctypes.sizeof(ctypes.c_int)).value
cmsgarr = bytearray(cmsgsize)
cmtype = ctypes.c_ubyte * cmsgsize
cmsg = cmtype.from_buffer(cmsgarr)
cmsg.cmsg_level = socket.SOL_SOCKET
cmsg.cmsg_type = SCM_RIGHTS
cmsg.cmsg_len = CMSG_LEN(ctypes.sizeof(ctypes.c_int))
iov = iovec()
iov.iov_base = ctypes.addressof(data)
iov.iov_len = 2048
msg = msghdr()
msg.msg_iov = ctypes.pointer(iov)
msg.msg_iovlen = 1
msg.msg_control = ctypes.addressof(cmsg)
msg.msg_controllen = ctypes.sizeof(cmsg)
select.select([handle], [], [])
i = recvmsg(handle.fileno(), ctypes.pointer(msg), 0)
cdata = cmsgarr[CMSG_LEN(0).value:]
data = rawbuffer[:i]
if cmsg.cmsg_level == socket.SOL_SOCKET and cmsg.cmsg_type == SCM_RIGHTS:
filehandles.fromstring(bytes(
cdata[:len(cdata) - len(cdata) % filehandles.itemsize]))
data = json.loads(bytes(data))
return ClientFile(data['filename'], data['mode'], filehandles[0])
else:
data = handle.recv(dlen)
while len(data) < dlen:
ndata = handle.recv(dlen - len(data))
if not ndata:
raise Exception("Error reading data")
data += ndata
if datatype == tlv.Types.text:
return data
elif datatype == tlv.Types.json:
+37 -5
View File
@@ -37,7 +37,7 @@ alias nodereseat='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export C
alias noderun='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; noderun'
alias nodesensors='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodesensors'
alias nodesetboot='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodesetboot'
alias nodestorage='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodestorage'
alias nodestorage='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodestorage -i'
alias nodeshell='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodeshell'
alias nodelicense='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodelicense'
# Do not continue for non-bash shells, the rest of this sets up bash completion functions
@@ -91,7 +91,7 @@ _confluent_nodeidentify_completion()
_confluent_nodesetboot_completion()
{
COMP_CANDIDATES=("default,cd,network,setup,hd,floppy -h -b -p")
COMP_CANDIDATES=("default,cd,network,setup,hd,floppy,usb -h -b -p")
_confluent_generic_completion
}
@@ -156,6 +156,40 @@ _confluent_osimage_completion()
fi
}
_confluent_imgutil_completion()
{
_confluent_get_args
if [ $NUMARGS == 2 ]; then
COMPREPLY=($(compgen -W "build exec unpack pack capture" -- ${COMP_WORDS[COMP_CWORD]}))
return
elif [ ${CMPARGS[1]} == 'build' ]; then
COMPREPLY=($(compgen -W "-s $(ls /var/lib/confluent/distributions)" -- ${COMP_WORDS[COMP_CWORD]}))
return
elif [ ${CMPARGS[1]} == 'unpack' ]; then
if [ $NUMARGS == 3 ]; then
COMPREPLY=($(compgen -W "-s $(ls /var/lib/confluent/public/os)" -- ${COMP_WORDS[COMP_CWORD]}))
return
fi
compopt -o dirnames
return
elif [ ${CMPARGS[1]} == 'pack' ]; then
if [ $NUMARGS == 3 ]; then
compopt -o dirnames
fi
COMPREPLY=()
return
elif [ ${CMPARGS[1]} == 'capture' ]; then
if [ $NUMARGS == 3 ]; then
_confluent_nn_completion
return
fi
return
elif [ ${CMPARGS[1]} == 'exec' ]; then
compopt -o dirnames
COMPREPLY=($(compgen -W "-v" -- ${COMP_WORDS[COMP_CWORD]}))
return
fi
}
_confluent_nodedeploy_completion()
{
_confluent_get_args
@@ -238,9 +272,6 @@ _confluent_nodeattrib_completion()
_confluent_nn_completion()
{
_confluent_get_args
if [ $NUMARGS -gt 2 ]; then
return;
fi
INPUT=${COMP_WORDS[COMP_CWORD]}
INPUT=${INPUT##*,-}
INPUT=${INPUT##*,}
@@ -302,6 +333,7 @@ complete -F _confluent_nr_completion nodeeventlog
complete -F _confluent_nodefirmware_completion nodefirmware
complete -F _confluent_nodedeploy_completion nodedeploy
complete -F _confluent_osimage_completion osdeploy
complete -F _confluent_imgutil_completion imgutil
complete -F _confluent_ng_completion nodegroupattrib
complete -F _confluent_ng_completion nodegroupremove
complete -F _confluent_nr_completion nodehealth
+22 -11
View File
@@ -3,7 +3,7 @@ collate(1) -- Organize text input by node
## SYNOPSIS
`<other command> | collate [-a] [-d] [-w] [-s] [-c] [-r] [-l lognametemplate]`
`<other command> | collate [-a] [-b] [-d] [-w] [-g] [-s] [-c] [-r] [-l lognametemplate]`
## DESCRIPTION
@@ -21,30 +21,41 @@ node and group names sorted alphanumerically.
when output differs along a telling group boundary. For example, if
output suggests a large number of nodes are unreachable, abbreviate
showing 'rack1' as being unreachable may make more obvious a possible cause.
* `-b BASE`, `--base=BASE`:
Use given node as reference for comparison when using
-d, instead of using the most common result
* `-d`, `--diff`:
Express all but the most common result group in terms of diff from
the most common result group
* `-l`, `--log`:
Save output per node to individual log files, replacing {node} in the name
with the nodename of each
* `-w`, `--watch`:
Update results dynamically as data becomes available, rather than
waiting for the command to fully complete.
* `-g`, `--groupcount`:
Show count of output groups rather than the actual
output
* `-s`, `--skipcommon`:
Suppress printing of the most common result text group. This is used to
focus on stray output against a well known and expected result.
* `-c`, `--count`:
Print a count of the number of nodes in an output group under the
noderange.
noderange.
* `-r`, `--reverse`:
Rather than starting with most common to least common, start with
the least common and print the most common last.
* `-r`, `--reverse`:
Rather than starting with most common to least common, start with
the least common and print the most common last.
* `-l LOG`, `--log=LOG`:
Save output per node to individual log files, replacing {node} in the name
with the nodename of each
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Organizing power state of multiple nodes:
+4
View File
@@ -7,6 +7,7 @@ collective(1) -- Check and manage a confluent collective
`collective join <server> [-i TOKEN]`
`collective show`
`collective gencert`
`collective delete`
## DESCRIPTION
@@ -36,6 +37,9 @@ on circumstances.
* `-i`:
Provide the token as an argument rather than interactively.
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Inviting a server called mgt2:
+15
View File
@@ -15,6 +15,21 @@ be mostly an aid for developing client software, with
day to day administration generally being easier with
the various function specific commands.
## OPTIONS
* `-s SERVER:PORT`, `--server=SERVER:PORT`:
Confluent instance to connect to
* `-c PATH`, `--control=PATH`:
Path to offer terminal control
* `-m MINTIME`, `--mintime=MINTIME`:
Minimum time to run or else pause for input (used to
keep a terminal from closing quickly on error)
* `-h`, `--help`:
Show help message and exit
## COMMANDS
The CLI may be navigated by shell commands and some other
+20 -4
View File
@@ -3,8 +3,7 @@ confluentdbutil(8) -- Backup or restore confluent database
## SYNOPSIS
`confluentdbutil [options] <dump|restore> <path>`
`confluentdbutil [options] [dump|restore] <path>`
## DESCRIPTION
@@ -16,11 +15,28 @@ the json files (password protected, removed from the files, or unprotected).
## OPTIONS
* `-p`, `--password`:
* `-p PASSWORD`, `--password=PASSWORD`:
If specified, information such as usernames and passwords will be encrypted
using the given password.
* `-i`, `--interactivepassword`:
Prompt for password.
* `-r`, `--redact`:
Indicates to replace usernames and passwords with a dummy string rather
than included.
* `-u`, `--unprotected`:
The keys.json file will include the encryption keys without any protection.
The keys.json file will include the encryption keys without any protection.
* `-s`, `--skipkeys`:
This specifies to dump the encrypted data without
dumping the keys needed to decrypt it. This is
suitable for an automated incremental backup, where an
earlier password protected dump has a protected
keys.json file, and only the protected data is needed.
keys do not change and as such they do not require
incremental backup.
* `-h`, `--help`:
Show help message and exit
+23 -4
View File
@@ -34,18 +34,37 @@ For the `groups` attribute, it is possible to add a group by doing
`groups,=<newgroup>` and to remove by doing `groups^=<oldgroup>`
Note that `nodeattrib <group>` will likely not provide the expected behavior.
See nodegroupattrib(8) command on how to manage attributes on a group level.
See nodegroupattrib(8) command on how to manage attributes on a group level. Running
nodeattrib on a group will simply set node-specific attributes on each individual
member of the group.
Additionally, if wanting to change from a node level attribute value to inherit from a
member group, it is required to use '-c' to clear the attribute. Conversely, assigning
to a blank value will allow masking a group defined attribute with an empty value.
## OPTIONS
* `-b`, `--blame`:
Annotate inherited and expression based attributes to show their base value.
* `-c`, `--clear`:
Clear specified nodeattributes
Clear specified nodeattributes.
* `-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
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
* `-p`, `--prompt`:
Request interactive prompting to provide values rather than the command line or environment variables.
Request interactive prompting to provide values rather than the command line
or environment variables.
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Prompt if trying to set attributes on more than
specified number of nodes.
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Listing matching nodes of a simple noderange:
@@ -9,6 +9,15 @@ nodebmcreset(8) -- Reset management controller
`nodebmcreset` allows you to reset the management controller of the 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:
+8 -2
View File
@@ -3,8 +3,7 @@ nodeboot(8) -- Reboot a confluent node to a specific device
## SYNOPSIS
`nodeboot <noderange>`
`nodeboot [options] <noderange>` [default|cd|network|setup|hd]
`nodeboot [options] <noderange> [default|cd|network|setup|hd]`
## DESCRIPTION
@@ -25,6 +24,13 @@ device without inducing a reboot, see the `nodesetboot` command.
* `-p`, `--persist`:
For a system that supports it, mark the boot override to persist rather than
be a one time change. Many systems do not support this functionality.
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to boot, prompting
if over the threshold
* `-h`, `--help`:
Show help message and exit
* `default`:
Request a normal default boot with no particular device override
+24 -9
View File
@@ -3,8 +3,7 @@ nodeconfig(8) -- Show or change node configuration
## SYNOPSIS
`nodeconfig <noderange> [options] [<configuration>..]`
`nodeconfig <noderange> [options] [<configuration=value>..]`
`nodeconfig [options] <noderange> [setting|setting=value]`
## DESCRIPTION
@@ -14,6 +13,12 @@ running configuration on the node firmware. Calling without '=' will show the
current value, and '=' will change the value. Network information can be
given as a node expression, as documented in the man page for nodeattribexpressions(5).
Note that when using nodeconfig to submit changes, it will exit when the change
is accepted, but the endpoint may not have fully processed it. Doing a show
immediately after doing a set may reflect older information. Also, if changing
BIOS/UEFI settings, the change may appear in output, but generally won't
actually be in effect until a reboot.
## OPTIONS
* `-c`, `--comparedefault`:
@@ -21,6 +26,13 @@ given as a node expression, as documented in the man page for nodeattribexpressi
no configuration values are specified, it will show only those that differ.
If combined with `-x`, will show all differing values except those indicated
by `-x`
* `-b settings.batch`, `--batch=settings.batch`:
Provide arguments as lines of a file, rather than the command line.
* `-d`, `--detail`:
Provide detailed data as available. This can include help text and valid
values for a setting.
* `-e`, `--extra`:
Read settings that are generally not needed, but may be slow to retrieve.
@@ -31,18 +43,21 @@ given as a node expression, as documented in the man page for nodeattribexpressi
Rather than listing only the specified configuration parameters, list all
attributes except for the specified ones
* `-d`, `--detail`:
Provide detailed data as available. This can include help text and valid
values for a setting.
* `-a`, `--advanced`:
Include advanced settings, which are normally not intended to be used
without direction from the relevant server vendor.
* `-r`, `--restoredefault`:
* `-r COMPONENT`, `--restoredefault=COMPONENT`:
Request that the specified component of the targeted nodes will have its
configuration reset to default. Currently the only component implemented
is uefi.
* `-b`, '--batch':
Provide arguments as lines of a file, rather than the command line.
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to configure, prompting if over
the threshold
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Showing the current IP configuration of noderange BMC/IMM/XCC:
+8 -4
View File
@@ -3,9 +3,7 @@ nodedeploy(8) -- Request preparation and/or initiating a node deployment
## SYNOPSIS
`nodedeploy <noderange>`
`nodedeploy <noderange> -c`
`nodedeploy <noderange> [-n] [-p] <name of profile>`
`nodedeploy [-h] [-c] [-n] [-p] [-m MAXNODES] <noderange> [profile]`
## DESCRIPTION
@@ -19,7 +17,7 @@ deployment status.
## OPTIONS
* '-c', '--clear`:
* `-c`, `--clear`:
Remove any pending deployment action
* `-n`, `--network`:
@@ -28,6 +26,12 @@ deployment status.
* `-p`, `--prepareonly`:
Prepare the network services for deployment, but do not interact with BMCs. This is intended for scenarios where
the boot device control and server restart will be handled outside of confluent.
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specifiy a maximum nodes to be deployed.
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Begin the instalalation of a profile of CentOS 8.2:
+10 -2
View File
@@ -3,14 +3,22 @@ nodeeventlog(8) -- Pull eventlog from confluent nodes
## SYNOPSIS
`nodeeventlog <noderange>`
`nodeeventlog <noderange> [clear]`
`nodeeventlog [options] <noderange> [clear]`
## DESCRIPTION
`nodeeventlog` pulls and optionally clears the event log from the requested
noderange.
## OPTIONS
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to clear if clearing log, prompting if
over the threshold
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Pull the event log from n2 and n3:
`# nodeeventlog n2,n3`
+13 -3
View File
@@ -3,9 +3,7 @@ nodefirmware(8) -- Report firmware information on confluent nodes
## SYNOPSIS
`nodefirmware <noderange>`
`nodefirmware <noderange> list|<components>|core`
`nodefirmware <noderange> update [--backup] <filename>`
`nodefirmware <noderange> [list][update [--backup <file>]]|[<components>]`
## DESCRIPTION
@@ -26,6 +24,18 @@ the out of band facilities. Firmware updates can end in one of three states:
* `pending`: The firmware update process has completed, but the firmware will not be active until the relevant component next resets. Generally speaking, for UEFI update the system will need a reboot, and for BMC updates, the `nodebmcreset` command will begin the process to activate the firmware.
* `complete`: The firmware update process has completed and activation has proceeded. Note that while the activation process has commenced, the component may still be in the process of rebooting when nodefirmware exits.
## OPTIONS
* `-b`, `--backup`:
Target a backup bank rather than primary
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
When updating, prompt if more than the specified number of servers will
be affected
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Pull firmware from a node:
@@ -25,8 +25,20 @@ the attributes are set on the node versus a group to which a node belongs.
## OPTIONS
* `-b`, `--blame`:
Show information about how attributes inherited
* `-e`, `--environment`:
Set attributes, but from environment variable of same name
* `-c`, `--clear`:
Clear specified nodeattributes.
* `-p`, `--prompt`:
Prompt for attribute values interactively
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
+9 -2
View File
@@ -3,15 +3,22 @@ nodelicense(8) -- Manage license keys on BMC
## SYNOPSIS
`nodelicense <noderange> [list|install <filename>|delete <license>|save <directory>]`
`nodelicense <noderange> [list][install <license_filename>|save <directory>|delete <license_feature_name>]`
## DESCRIPTION
`nodelicense` manages license keys on supported BMCs. Without an argument, the command
lists currently installed license. Using `delete` will remove the specified license name
from th eBMC. The `save` subcommand will take the passed directory (which may be in the form
from the BMC. The `save` subcommand will take the passed directory (which may be in the form
of /path/to/{node}/ to have the node name substituted for each node) and back up installed licenses
to that directory. The `install` command will take the specified filename and install. The filename
argument may be of the form xcc_fod_0034_7X21{id.serial}.key to have the serial number substituted
to allow unique licenses to be specified in a single command.
## OPTIONS
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to delete licenses from, prompting if over the threshold
* `-h`, `--help`:
Show help message and exit
+2 -2
View File
@@ -34,8 +34,8 @@ the host platform attempts.
## OPTIONS
* `-c`:
Specify the maximum number of instances to run concurrently.
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Listing currently mounted media:
+9 -3
View File
@@ -3,8 +3,7 @@ nodepower(8) -- Check or change power state of confluent nodes
## SYNOPSIS
`nodepower <noderange>`
`nodepower <noderange> [-p] [on|off|boot|shutdown|reset|status]`
`nodepower [options] <noderange> ([status|on|off|shutdown|boot|reset])`
## DESCRIPTION
@@ -28,8 +27,15 @@ off will not react to this request.
## OPTIONS
* `-p`, '--showprevious':
* `-p`, `--showprevious`:
Show previous power state for all directives that may change power state.
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to change power state, prompting if
over the threshold
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Get power state of nodes n1 through n4:
+8 -1
View File
@@ -9,6 +9,14 @@ noderemove(8) -- Remove nodes from the confluent management service
`noderemove` simply removes the given noderange from the confluent database.
## OPTIONS
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to delete, prompting if over the
threshold
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
@@ -22,4 +30,3 @@ noderemove(8) -- Remove nodes from the confluent management service
`r2u3: deleted`
`r2u2: deleted`
`r2u1: deleted`
+8 -1
View File
@@ -11,9 +11,16 @@ nodereseat(8) -- Request a reseat of a node
node's slot. This should be equivalent to removing the system entirely from
the chassis and putting it back in, but without actually having to do so.
## OPTIONS
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to reseat, prompting if over the threshold
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Reseating the node `s1`:
`# nodereseat s1`
`s1: Reseat successful`
+9 -5
View File
@@ -12,10 +12,14 @@ noderange. This will present progress as percentage for all nodes.
## OPTIONS
* `-m`:
Specify maximum number of nodes for noderange max.
* `-c`:
* `-f COUNT`, `-c COUNT`, `--count=COUNT`:
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.
active count completes.
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to run rsync to, prompting if over the
threshold
* `-h`, `--help`:
Show help message and exit
+16 -1
View File
@@ -3,7 +3,7 @@ noderun(8) -- Run arbitrary commands per node in a noderange
## SYNOPSIS
`noderun <noderange> <command string>`
`noderun [options] <noderange> <command expression>`
## DESCRIPTION
@@ -13,6 +13,21 @@ nodeattribexpressions(5) are expanded prior to execution of the command. For
noderun, the commands are locally executed. To execute commands on the nodes
themselves, see nodeshell(8).
## OPTIONS
* `-f COUNT`, `-c COUNT`, `--count=COUNT`:
Number of commands to run at a time
* `-n`, `--nonodeprefix`:
Do not prefix output with node names
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to run the command with, prompting if over
the threshold
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Run ping against nodes n1 through n4:
+15 -3
View File
@@ -2,9 +2,8 @@ nodesetboot(8) -- Check or set next boot device for noderange
====================================================
## SYNOPSIS
`nodesetboot <noderange>`
`nodesetboot [options] <noderange> [default|cd|network|setup|hd|floppy]`
`nodesetboot [options] <noderange> [default|cd|network|setup|hd|usb|floppy]`
## DESCRIPTION
@@ -21,6 +20,8 @@ to use `nodesetboot <noderange> setup` and then initiate a reboot from within
the operating system with ssh or similar rather than using the remote hardware
control.
Running the command with no target queries the current setting.
## OPTIONS
* `-b`, `--bios`:
@@ -33,6 +34,13 @@ control.
* `-u`, `--uefi`:
This flag does nothing, it is for command compatibility with xCAT's rsetboot
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to modify next boot device, prompting if
over the threshold
* `-h`, `--help`:
Show help message and exit
* `default`:
Request a normal default boot with no particular device override
@@ -46,6 +54,10 @@ control.
Request boot from floppy. Generally speaking firmware uses this to mean a USB
flash drive or similar (whether virtual or physical).
* `usb`:
Request boot from usb. Generally speaking firmware uses this to mean a USB
flash drive or similar (whether virtual or physical).
* `network`:
Request boot to network
+20 -3
View File
@@ -3,7 +3,7 @@ nodeshell(8) -- Execute command on many nodes in a noderange through ssh
## SYNOPSIS
`nodeshell <noderange> [options] <command to execute on each node>`
`nodeshell [options] <noderange> <command to execute on each node>`
## DESCRIPTION
@@ -13,9 +13,26 @@ nodeattribexpressions(5). `nodeshell` provides stdout as stdout and stderr
as stderr, unlike psh which combines all stdout and stderr into stdout.
## OPTIONS
* `-c COUNT`, `-f COUNT`, `--count=COUNT`
Specify the maximum number of instances to run concurrently
* `-c`:
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
* `-n`, `--nonodeprefix`
Do not prefix output with node names
* `-p PORT`, `--port=PORT`
Specify a custom port for ssh
* `-s SUBSTITUTION`, `--substitutename=SUBSTITITUTION`
Specify a substitution name instead of the nodename. If no {} are in the substitution,
it is considered to be an append. For example, '-s -ib' would produce 'node1-ib' from 'node1'.
Full expression syntax is supported, in which case the substitution is considered to be the entire
new name. {node}-ib would be equivalent to -ib. For example, nodeshell -s {bmc} node1
would ssh to the BMC instead of the node.
## EXAMPLES
+14 -2
View File
@@ -3,12 +3,15 @@ nodestorage(8) -- Examine/Modify storage configuration of a node
## SYNOPSIS
`nodestorage <noderange> [show|create|delete] [options]`
`nodestorage <noderange> [show|create|delete|diskset] [hotspare|jbod|unconfigured] [options]`
## DESCRIPTION
`nodestorage` provides access to the remote storage configuration of
the noderange.
the noderange. The `show` subcommand will show current storage configuration,
`create` can be used to create new arrays or volumes, `delete` can be used to
remove volumes and arrays, and `diskset` can modify the usage of disks
indicated by `-d` to either be `unconfigured`, `jbod`, or `hotspare`.
## OPTIONS
* `-r` **RAIDLEVEL**, `--raidlevel`=**RAIDLEVEL**:
@@ -29,6 +32,15 @@ the noderange.
volumes, or selecting a volume for delete. Default
behavior is to use implementation provided default
* `-z` **STRIPSIZES**, `--stripsizes`=**STRIPSIZES**:
Comma separated list of stripsizes to use when creating volumes.
This value is in kilobytes. The default behavior is to allow the
storage controller to decide
* `-m` **MAXNODES**, `--maxnodes`=**MAXNODES**:
Specify a maximum number of nodes to configure storage on, prompting
if over the threshold
## EXAMPLES
* Deleting the volume `somedata`:
@@ -19,6 +19,15 @@ running in collective mode.
Note that due to vendor filename requirements, any filename may have vendor
specific suffixes added to any file produced.
## OPTIONS
* `-m MAXNODES`, `--maxnodes=MAXNODES`:
Specify a maximum number of nodes to download diagnostic data from, prompting
if over the threshold
* `-h`, `--help`:
Show help message and exit
## EXAMPLES
* Download support data from a single node to a specific filename
+1 -1
View File
@@ -5,7 +5,7 @@ osdeploy(8) --- Configure general OS deployment facilities of confluent
`osdeploy import <iso>`
`osdeploy updateboot <profile>`
`osdeploy initialize [-h] [-g] [-u] [-s] [-k] [-t] [-p] [-i] [-l]`
`osdeploy initialize [-h] [-g] [-u] [-s] [-k] [-t] [-p] [-i] [-l] [-a]`
## DESCRIPTION
+49
View File
@@ -0,0 +1,49 @@
stats(8) -- Common basic statistics on typical numeric data in output
==============================
## SYNOPSIS
`<other command> | stats [-c N] [-d D] [-x|-g|-t|-o image.png] [-s N] [-v] [-b N]
## DESCRIPTION
The **stats** command helps analyze common numerical data such as performance numbers
or temperatures or any other numerical value.
By default it looks for the last numerical output on the first line to identify the numerical column
and analyze that number. This can be overriden by **-c COLUMN** to indicate a column. By default,
whitespace and commas are treated to delimit columns, and **-d DELIMITER** can be used to override.
By default it outputs basic statistics, but a histogram is available either text or through X11 output
or sixel or output to an image file depending on whether **-x**, **-g**, **-t*, or **-o image.png** is
used.
## OPTIONS
* `-c N`:
Select column number. Defaults to last column that appears numeric
* `-d D`:
Specify a custom column delimiter
* `-x`:
Output in Sixel format (supported by mlterm and PuTTY, among others)
* `-g`:
Try to open histogram as an X window
* `-t`:
Output histogram as bars rendered by =
* `-o image.png`:
Write graphical histogram to image.png.
* `-s N`:
Ignore specified number of lines as header content before processing numbers
* `-v`:
Treat value before : on each line as a label, and show which labels belong to which histogram buckets.
* `-b N`:
Specify a custom number of buckets for histogram. The default is 10.
+11
View File
@@ -8,4 +8,15 @@ cd ..
tar Jcvf confluent_osdeploy.tar.xz confluent_osdeploy
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
cd utils
mv confluent_imginfo copernicus clortho autocons ../el9bin/opt/confluent/bin
mv start_root urlmount ../el9bin/stateless-bin/
make clean
cd ..
tar Jcvf confluent_el9bin.tar.xz el9bin/
mv confluent_el9bin.tar.xz ~/rpmbuild/SOURCES/
rm -rf el9bin
rpmbuild -ba confluent_osdeploy.spec
@@ -0,0 +1,395 @@
#!/usr/bin/python
try:
import http.client as client
except ImportError:
import httplib as client
import ctypes
import ctypes.util
import glob
import os
import select
import socket
import subprocess
import ssl
import sys
import struct
import time
class InvalidApiKey(Exception):
pass
cryptname = ctypes.util.find_library('crypt')
if not cryptname:
if os.path.exists('/usr/lib64/libcrypt.so.1'):
cryptname = 'libcrypt.so.1'
elif os.path.exists('/usr/lib64/libcrypt.so.2'):
cryptname = 'libcrypt.so.2'
c_libcrypt = ctypes.CDLL(cryptname)
c_crypt = c_libcrypt.crypt
c_crypt.argtypes = (ctypes.c_char_p, ctypes.c_char_p)
c_crypt.restype = ctypes.c_char_p
def get_my_addresses():
nlhdrsz = struct.calcsize('IHHII')
ifaddrsz = struct.calcsize('BBBBI')
# RTM_GETADDR = 22
# nlmsghdr struct: u32 len, u16 type, u16 flags, u32 seq, u32 pid
nlhdr = struct.pack('IHHII', nlhdrsz + ifaddrsz, 22, 0x301, 0, 0)
# ifaddrmsg struct: u8 family, u8 prefixlen, u8 flags, u8 scope, u32 index
ifaddrmsg = struct.pack('BBBBI', 0, 0, 0, 0, 0)
s = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, socket.NETLINK_ROUTE)
s.bind((0, 0))
s.sendall(nlhdr + ifaddrmsg)
addrs = []
while True:
pdata = s.recv(65536)
v = memoryview(pdata)
if struct.unpack('H', v[4:6])[0] == 3: # netlink done message
break
while len(v):
length, typ = struct.unpack('IH', v[:6])
if typ == 20:
fam, plen, _, scope, ridx = struct.unpack('BBBBI', v[nlhdrsz:nlhdrsz+ifaddrsz])
if scope in (253, 0):
rta = v[nlhdrsz+ifaddrsz:length]
while len(rta):
rtalen, rtatyp = struct.unpack('HH', rta[:4])
if rtatyp == 1:
addrs.append((fam, rta[4:rtalen], plen, ridx))
if not rtalen:
break
rta = rta[rtalen:]
v = v[length:]
return addrs
def scan_confluents():
srvs = {}
s6 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
s6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
s6.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s6.bind(('::', 1900))
s4 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s4.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
s4.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
s4.bind(('0.0.0.0', 1900))
doneidxs = set([])
msg = 'M-SEARCH * HTTP/1.1\r\nST: urn:xcat.org:service:confluent:'
with open('/etc/confluent/confluent.deploycfg') as dcfg:
for line in dcfg.read().split('\n'):
if line.startswith('confluent_uuid:'):
confluentuuid = line.split(': ')[1]
msg += '/confluentuuid=' + confluentuuid
break
with open('/sys/devices/virtual/dmi/id/product_uuid') as uuidin:
msg += '/uuid=' + uuidin.read().strip()
for addrf in glob.glob('/sys/class/net/*/address'):
with open(addrf) as addrin:
hwaddr = addrin.read().strip()
msg += '/mac=' + hwaddr
msg = msg.encode('utf8')
for addr in get_my_addresses():
if addr[0] == socket.AF_INET6:
if addr[-1] in doneidxs:
continue
s6.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, addr[-1])
try:
s6.sendto(msg, ('ff02::c', 1900))
except OSError:
pass
doneidxs.add(addr[-1])
elif addr[0] == socket.AF_INET:
s4.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, addr[1])
try:
s4.sendto(msg, ('239.255.255.250', 1900))
except OSError:
pass
r = select.select((s4, s6), (), (), 4)
srvlist = []
if r:
r = r[0]
while r:
for s in r:
(rsp, peer) = s.recvfrom(9000)
rsp = rsp.split(b'\r\n')
current = None
for line in rsp:
if line.startswith(b'NODENAME: '):
current = {}
elif line.startswith(b'DEFAULTNET: 1'):
current['isdefault'] = True
elif line.startswith(b'MGTIFACE: '):
current['mgtiface'] = line.replace(b'MGTIFACE: ', b'').strip().decode('utf8')
if len(peer) > 2:
current['myidx'] = peer[-1]
srvs[peer[0]] = current
srvlist.append(peer[0])
r = select.select((s4, s6), (), (), 2)
if r:
r = r[0]
return srvlist, srvs
def get_net_apikey(nodename, mgr):
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./'
newpass = ''.join([alpha[x >> 2] for x in bytearray(os.urandom(32))])
salt = '$5$' + ''.join([alpha[x >> 2] for x in bytearray(os.urandom(8))])
newpass = newpass.encode('utf8')
salt = salt.encode('utf8')
crypted = c_crypt(newpass, salt)
for addrinfo in socket.getaddrinfo(mgr, 13001, type=socket.SOCK_STREAM):
try:
clisock = socket.socket(addrinfo[0], addrinfo[1])
clisock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if addrinfo[0] == socket.AF_INET:
cliaddr = ('0.0.0.0', 302)
else:
cliaddr = ('::', 302)
clisock.bind(cliaddr)
clisock.connect(addrinfo[-1])
rsp = clisock.recv(8)
if rsp != b'\xc2\xd1-\xa8\x80\xd8j\xba':
raise Exception('Unrecognized credential banner')
hellostr = bytearray([1, len(nodename)]) + bytearray(nodename.encode('utf8')) + bytearray(b'\x00\x00')
clisock.send(hellostr)
rsp = bytearray(clisock.recv(2))
if not rsp:
continue
if rsp[0] == 128:
continue
if rsp[0] == 2:
echotoken = clisock.recv(rsp[1])
clisock.recv(2) # drain \x00\x00
clisock.send(bytes(bytearray([3, rsp[1]])))
clisock.send(echotoken)
clisock.send(bytes(bytearray([4, len(crypted)])))
clisock.send(crypted)
clisock.send(b'\x00\x00')
rsp = bytearray(clisock.recv(2))
if rsp[0] == 5:
return newpass.decode('utf8')
finally:
clisock.close()
return ''
def get_apikey(nodename, hosts):
apikey = ""
if os.path.exists('/etc/confluent/confluent.apikey'):
apikey = open('/etc/confluent/confluent.apikey').read().strip()
if apikey:
return apikey
while not apikey:
for host in hosts:
try:
apikey = get_net_apikey(nodename, host)
except OSError:
apikey = None
if apikey:
break
else:
srvlist, _ = scan_confluents()
for host in srvlist:
try:
apikey = get_net_apikey(nodename, host)
except OSError:
apikey = None
if apikey:
break
if not apikey:
sys.stderr.write(
"Failed getting API token, check deployment.apiarmed attribute on {}\n".format(nodename))
time.sleep(10)
with open('/etc/confluent/confluent.apikey', 'w+') as apiout:
apiout.write(apikey)
apikey = apikey.strip()
os.chmod('/etc/confluent/confluent.apikey', 0o600)
return apikey
class HTTPSClient(client.HTTPConnection, object):
def __init__(self, usejson=False, port=443, host=None):
self.stdheaders = {}
mgtiface = None
if usejson:
self.stdheaders['ACCEPT'] = 'application/json'
if host:
self.hosts = [host]
with open('/etc/confluent/confluent.info') as cinfo:
info = cinfo.read().split('\n')
for line in info:
if line.startswith('NODENAME:'):
node = line.split(' ')[1]
self.stdheaders['CONFLUENT_NODENAME'] = node
else:
self.hosts = []
info = open('/etc/confluent/confluent.info').read().split('\n')
havedefault = '0'
for line in info:
if line.startswith('NODENAME:'):
node = line.split(' ')[1]
self.stdheaders['CONFLUENT_NODENAME'] = node
if line.startswith('MANAGER:') and not host:
host = line.split(' ')[1]
if line.startswith('EXTMGRINFO:'):
extinfo = line.split(' ')[1]
extinfo = extinfo.split('|')
if not mgtiface:
host, mgtiface, havedefault = extinfo[:3]
if havedefault == '0' and extinfo[2] == '1':
host, mgtiface, havedefault = extinfo[:3]
if '%' in host:
ifidx = host.split('%', 1)[1]
with open('/tmp/confluent.ifidx', 'w+') as ifout:
ifout.write(ifidx)
self.hosts.append(host)
try:
info = open('/etc/confluent/confluent.deploycfg').read().split('\n')
except Exception:
info = None
if info:
for line in info:
if line.startswith('deploy_server: ') or line.startswith('deploy_server_v6: '):
self.hosts.append(line.split(': ', 1)[1])
self.stdheaders['CONFLUENT_APIKEY'] = get_apikey(node, self.hosts)
if mgtiface:
self.stdheaders['CONFLUENT_MGTIFACE'] = mgtiface
self.port = port
self.host = None
self.node = node
host = self.check_connections()
client.HTTPConnection.__init__(self, host, port)
self.connect()
def set_header(self, key, val):
self.stdheaders[key] = val
def check_connections(self):
foundsrv = None
hosts = self.hosts
for timeo in (0.1, 5):
for host in hosts:
try:
addrinf = socket.getaddrinfo(host, self.port)[0]
psock = socket.socket(addrinf[0])
psock.settimeout(timeo)
psock.connect(addrinf[4])
foundsrv = host
psock.close()
break
except OSError:
continue
else:
continue
break
if not foundsrv:
srvlist, srvs = scan_confluents()
hosts = []
for srv in srvlist:
if srvs[srv].get('isdefault', False):
hosts = [srv] + hosts
else:
hosts = hosts + [srv]
for host in hosts:
try:
addrinf = socket.getaddrinfo(host, self.port)[0]
psock = socket.socket(addrinf[0])
psock.settimeout(timeo)
psock.connect(addrinf[4])
foundsrv = host
psock.close()
break
except OSError:
continue
else:
raise Exception('Unable to reach any hosts')
return foundsrv
def connect(self):
addrinf = socket.getaddrinfo(self.host, self.port)[0]
psock = socket.socket(addrinf[0])
psock.connect(addrinf[4])
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ctx.load_verify_locations('/etc/confluent/ca.pem')
host = self.host.split('%', 1)[0]
if '[' not in host and ':' in host:
self.stdheaders['Host'] = '[{0}]'.format(host)
else:
self.stdheaders['Host'] = '{0}'.format(host)
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
self.sock = ctx.wrap_socket(psock, server_hostname=host)
def grab_url(self, url, data=None, returnrsp=False):
return self.grab_url_with_status(url, data, returnrsp)[1]
def grab_url_with_status(self, url, data=None, returnrsp=False):
if data:
method = 'POST'
else:
method = 'GET'
authed = False
while not authed:
authed = True
self.request(method, url, data, headers=self.stdheaders)
rsp = self.getresponse()
if rsp.status >= 200 and rsp.status < 300:
if returnrsp:
return rsp.status, rsp
else:
return rsp.status, rsp.read()
if rsp.status == 401:
authed = False
rsp.read()
with open('/etc/confluent/confluent.apikey', 'w+') as akfile:
akfile.write('')
self.stdheaders['CONFLUENT_APIKEY'] = get_apikey(
self.node, [self.host])
raise Exception(rsp.read())
if __name__ == '__main__':
data = None
usejson = False
if '-j' in sys.argv:
usejson = True
if len(sys.argv) == 1:
HTTPSClient()
sys.exit(0)
try:
outbin = sys.argv.index('-o')
sys.argv.pop(outbin)
outbin = sys.argv.pop(outbin)
except ValueError:
outbin = None
try:
waitfor = sys.argv.index('-w')
sys.argv.pop(waitfor)
waitfor = int(sys.argv.pop(waitfor))
except ValueError:
waitfor = None
try:
data = sys.argv.index('-d')
sys.argv.pop(data)
data = sys.argv.pop(data)
except ValueError:
data = None
if outbin:
with open(outbin, 'ab+') as outf:
reader = HTTPSClient(usejson=usejson).grab_url(
sys.argv[1], data, returnrsp=True)
chunk = reader.read(16384)
while chunk:
outf.write(chunk)
chunk = reader.read(16384)
sys.exit(0)
if len(sys.argv) > 2 and os.path.exists(sys.argv[-1]):
data = open(sys.argv[-1]).read()
if waitfor:
client = HTTPSClient(usejson)
status = 201
while status != waitfor:
status, rsp = client.grab_url_with_status(sys.argv[1], data)
sys.stdout.write(rsp.decode())
else:
sys.stdout.write(HTTPSClient(usejson).grab_url(sys.argv[1], data).decode())
@@ -1,107 +0,0 @@
#!/usr/bin/python
try:
import http.client as client
except ImportError:
import httplib as client
import os
import socket
import subprocess
import ssl
import sys
def get_apikey(nodename, mgr):
if os.path.exists('/etc/confluent/confluent.apikey'):
return open('/etc/confluent/confluent.apikey').read().strip()
apikey = subprocess.check_output(['/opt/confluent/bin/clortho', nodename, mgr])
if not isinstance(apikey, str):
apikey = apikey.decode('utf8')
with open('/etc/confluent/confluent.apikey', 'w+') as apiout:
apiout.write(apikey)
apikey = apikey.strip()
os.chmod('/etc/confluent/confluent.apikey', 0o600)
return apikey
class HTTPSClient(client.HTTPConnection, object):
def __init__(self, json=False, port=443):
self.stdheaders = {}
info = open('/etc/confluent/confluent.info').read().split('\n')
host = None
mgtiface = None
havedefault = '0'
for line in info:
if line.startswith('NODENAME:'):
node = line.split(' ')[1]
self.stdheaders['CONFLUENT_NODENAME'] = node
if line.startswith('MANAGER:') and not host:
host = line.split(' ')[1]
if line.startswith('EXTMGRINFO:'):
extinfo = line.split(' ')[1]
extinfo = extinfo.split('|')
if not mgtiface:
host, mgtiface, havedefault = extinfo[:3]
if havedefault == '0' and extinfo[2] == '1':
host, mgtiface, havedefault = extinfo[:3]
if '%' in host:
ifidx = host.split('%', 1)[1]
with open('/tmp/confluent.ifidx', 'w+') as ifout:
ifout.write(ifidx)
if json:
self.stdheaders['ACCEPT'] = 'application/json'
self.stdheaders['CONFLUENT_APIKEY'] = get_apikey(node, host)
if mgtiface:
self.stdheaders['CONFLUENT_MGTIFACE'] = mgtiface
client.HTTPConnection.__init__(self, host, port)
self.connect()
def set_header(self, key, val):
self.stdheaders[key] = val
def connect(self):
addrinf = socket.getaddrinfo(self.host, self.port)[0]
psock = socket.socket(addrinf[0])
psock.connect(addrinf[4])
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ctx.load_verify_locations('/etc/confluent/ca.pem')
host = self.host.split('%', 1)[0]
if '[' not in host and ':' in host:
self.stdheaders['Host'] = '[{0}]'.format(host)
else:
self.stdheaders['Host'] = '{0}'.format(host)
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
self.sock = ctx.wrap_socket(psock, server_hostname=host)
def grab_url(self, url, data=None, returnrsp=False):
if data:
method = 'POST'
else:
method = 'GET'
self.request(method, url, data, headers=self.stdheaders)
rsp = self.getresponse()
if rsp.status >= 200 and rsp.status < 300:
if returnrsp:
return rsp
else:
return rsp.read()
raise Exception(rsp.read())
if __name__ == '__main__':
data = None
json = False
if '-j' in sys.argv:
json = True
if len(sys.argv) == 1:
HTTPSClient()
sys.exit(0)
if sys.argv[-2] == '-o':
with open(sys.argv[3], 'wb') as outf:
reader = HTTPSClient(json=json).grab_url(
sys.argv[1], data, returnrsp=True)
chunk = reader.read(16384)
while chunk:
outf.write(chunk)
chunk = reader.read(16384)
sys.exit(0)
if os.path.exists(sys.argv[-1]):
data = open(sys.argv[-1]).read()
print(HTTPSClient(json=json).grab_url(sys.argv[1], data).decode())
@@ -0,0 +1,345 @@
#!/usr/bin/python
import glob
import json
import os
import socket
import sys
import time
import shlex
import subprocess
from importlib.machinery import SourceFileLoader
try:
apiclient = SourceFileLoader('apiclient', '/opt/confluent/bin/apiclient').load_module()
except FileNotFoundError:
apiclient = SourceFileLoader('apiclient', '/etc/confluent/apiclient').load_module()
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:
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 type != '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 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]
kv = ' '.join(shlex.split(cfg)).split('=', 1)
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'] = 'team{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)
teamout.write('TEAM_RUNNER={0}\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('TEAM_PORT_DEVICE_{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):
def __init__(self, devtypes):
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]])
subprocess.check_call(['nmcli', 'c', 'add', 'type', 'team-slave', '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):
cmdargs = {}
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']
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])
subprocess.check_call(['nmcli', 'c', 'add', 'type', 'team', 'con-name', cname, 'connection.interface-name', cname, 'team.runner', 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
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', 'u', u])
else:
subprocess.check_call(['nmcli', 'c', 'add', 'type', self.devtypes[iname], 'con-name', cname, 'connection.interface-name', iname] + cargs)
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([])
for srv in srvs:
s = socket.create_connection((srv, 443))
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 == bytes(addr[1]):
curridx = addr[-1]
if curridx in doneidxs:
continue
status, nc = apiclient.HTTPSClient(usejson=True, host=srv).grab_url_with_status('/confluent-api/self/netcfg')
nc = json.loads(nc)
iname = get_interface_name(idxmap[curridx], nc.get('default', {}))
if iname:
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:
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)
rm_tmp_llas(tmpllas)
if os.path.exists('/usr/bin/nmcli'):
nm = NetworkManager(devtypes)
elif os.path.exists('/usr/sbin/wicked'):
nm = WickedManager()
for netn in netname_to_interfaces:
nm.apply_configuration(netname_to_interfaces[netn])
if havefirewall:
subprocess.check_call(['systemctl', 'start', 'firewalld'])
await_tentative()
@@ -4,8 +4,9 @@ Release: 1
Summary: OS Deployment support for confluent
License: Apache2
URL: http://hpc.lenovo.com/
URL: https://hpc.lenovo.com/
Source0: confluent_osdeploy.tar.xz
Source1: confluent_el9bin.tar.xz
BuildArch: noarch
Requires: confluent_ipxe mtools tar
BuildRoot: /tmp
@@ -17,20 +18,47 @@ This contains support utilities for enabling deployment of x86_64 architecture s
%define debug_package %{nil}
%prep
%setup -n confluent_osdeploy
%setup -n confluent_osdeploy -a 1
%build
mkdir -p opt/confluent/bin
mkdir -p stateless-bin
cd utils
make all
cp copernicus clortho autocons ../opt/confluent/bin
cp confluent_imginfo copernicus clortho autocons ../opt/confluent/bin
cp start_root urlmount ../stateless-bin/
cd ..
for os in rhvh4 el7 genesis el8 suse15 ubuntu20.04; do
ln -s el8 el9
ln -s el8-diskless el9-diskless
for os in rhvh4 el7 genesis el8 suse15 ubuntu20.04 coreos el9; do
mkdir ${os}out
cd ${os}out
cp -a ../opt .
if [ -d ../${os}bin ]; then
cp -a ../${os}bin/opt .
else
cp -a ../opt .
fi
cp -a ../${os}/initramfs/* .
cp -a ../common/* .
cp -a ../common/initramfs/* .
find . | cpio -H newc -o > ../addons.cpio
mv ../addons.cpio .
cd ..
done
for os in el8 suse15 el9 ubuntu20.04; do
mkdir ${os}disklessout
cd ${os}disklessout
if [ -d ../${os}bin ]; then
cp -a ../${os}bin/opt .
else
cp -a ../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
fi
find . | cpio -H newc -o > ../addons.cpio
mv ../addons.cpio .
cd ..
@@ -39,7 +67,7 @@ mkdir esxi7out
cd esxi7out
cp -a ../opt .
cp -a ../esxi7/initramfs/* .
cp -a ../common/* .
cp -a ../common/initramfs/* .
chmod +x bin/* opt/confluent/bin/*
tar zcvf ../addons.tgz *
mv ../addons.tgz .
@@ -48,12 +76,25 @@ cp -a esxi7out esxi6out
cp -a esxi7 esxi6
%install
for os in rhvh4 el7 el8 genesis suse15 ubuntu20.04 esxi6 esxi7; do
for os in rhvh4 el7 el8 el9 genesis suse15 ubuntu20.04 esxi6 esxi7 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
cp -a $os/profiles/* %{buildroot}/opt/confluent/lib/osdeploy/$os/profiles
for targ in %{buildroot}/opt/confluent/lib/osdeploy/$os/profiles/*; do
cp -a common/profile/* $targ
done
if [ -d ${os}disklessout ]; then
mkdir -p %{buildroot}/opt/confluent/lib/osdeploy/${os}-diskless/initramfs
mkdir -p %{buildroot}/opt/confluent/lib/osdeploy/${os}-diskless/profiles
cp ${os}disklessout/addons.* %{buildroot}/opt/confluent/lib/osdeploy/${os}-diskless/initramfs
cp -a ${os}-diskless/profiles/* %{buildroot}/opt/confluent/lib/osdeploy/$os-diskless/profiles
for targ in %{buildroot}/opt/confluent/lib/osdeploy/$os-diskless/profiles/*; do
cp -a common/profile/* $targ
done
fi
done
find %{buildroot}/opt/confluent/lib/osdeploy/ -name .gitignore -exec rm -f {} +
%files
/opt/confluent/lib/osdeploy
@@ -0,0 +1 @@
/usr/lib/systemd/system/confluent-rootfs.service
@@ -0,0 +1,122 @@
#!/bin/bash
TRIES=0
oum=$(umask)
umask 0077
mkdir -p /etc/confluent
echo -n > /etc/confluent/confluent.info
umask $oum
cd /sys/class/net
echo "Searching for confluent deployment server...." > /dev/console
while ! grep ^NODE /etc/confluent/confluent.info; do
while ! grep ^EXTMGRINFO: /etc/confluent/confluent.info | awk -F'|' '{print $3}' | 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
if ! grep ^NODE /etc/confluent/confluent.info; then
echo 'Current net config:' > /dev/console
ip -br a > /dev/console
fi
done
echo "Found confluent deployment services on local network" > /dev/console
cd /
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}')
cat /tls/*.pem > /etc/confluent/ca.pem
confluent_mgr=$(grep ^MANAGER: /etc/confluent/confluent.info|head -n 1 | awk '{print $2}')
echo "Connecting to confluent server: $confluent_mgr" > /dev/console
if [[ $confluent_mgr == *%* ]]; then
echo $confluent_mgr | awk -F% '{print $2}' > /tmp/confluent.ifidx
ifidx=$(cat /tmp/confluent.ifidx)
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
fi
needseal=1
oldumask=$(umask)
umask 0077
while [ -z "$confluent_apikey" ]; do
/opt/confluent/bin/clortho $nodename $confluent_mgr > /etc/confluent/confluent.apikey
if grep ^SEALED: /etc/confluent/confluent.apikey > /dev/null; then
needseal=0
sed -e s/^SEALED:// /etc/confluent/confluent.apikey | clevis-decrypt-tpm2 > /etc/confluent/confluent.apikey.decrypt
mv /etc/confluent/confluent.apikey.decrypt /etc/confluent/confluent.apikey
fi
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
if [ -z "$confluent_apikey" ]; then
echo "Unable to acquire node api key, no TPM2 sealed nor fresh token available, retrying..." > /dev/console
sleep 10
fi
done
if [[ $confluent_mgr == *:* ]]; then
confluent_mgr="[$confluent_mgr]"
fi
if [ $needseal == 1 ]; then
sealed=$(echo $confluent_apikey | clevis-encrypt-tpm2 {})
if [ ! -z "$sealed" ]; then
curl -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" -d $sealed https://$confluent_mgr/confluent-api/self/saveapikey
fi
fi
curl -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$confluent_mgr/confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg
curl -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$confluent_mgr/confluent-api/self/profileprivate/pending/config.ign > /config.ign
[ -s /config.ign ] || rm /config.ign
umask $oldumask
autoconfigmethod=$(grep ipv4_method /etc/confluent/confluent.deploycfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg)
confluent_profile=${confluent_profile#profile: }
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
nameserversec=0
while read -r entry; do
if [ $nameserversec = 1 ]; then
if [[ $entry == "-"* ]] && [[ $entry != "- ''" ]]; then
echo nameserver=${entry#- } >> /etc/cmdline.d/01-confluent.conf
continue
fi
fi
nameserversec=0
if [ "${entry%:*}" = "nameservers" ]; then
nameserversec=1
continue
fi
done < /etc/confluent/confluent.deploycfg
if [ -e /lib/nm-lib.sh ]; then
. /lib/nm-lib.sh
nm_generate_connections
sed -i 's/method=disabled/method=link-local/' /run/NetworkManager/system-connections/*.nmconnection
if [ -f /run/NetworkManager/system-connections/$ifname.nmconnection ]; then
rm /run/NetworkManager/system-connections/default_connection.nmconnection
fi
if [[ "$ifname" == ib* ]]; then
sed -i s/type=ethernet/type=infiniband/ /run/NetworkManager/system-connections/$ifname.nmconnection
if ! grep '\[infiniband\]' /run/NetworkManager/system-connections/$ifname.nmconnection > /dev/null; then
echo >> /run/NetworkManager/system-connections/$ifname.nmconnection
echo '[infiniband]' >> /run/NetworkManager/system-connections/$ifname.nmconnection
echo transport-mode=datagram >> /run/NetworkManager/system-connections/$ifname.nmconnection
fi
fi
fi
#cat /proc/cmdline /etc/cmdline.d/01-confluent.conf | tr '\n' ' ' > /run/fakecmdline
#chcon system_u:object_r:proc_t:s0 /run/fakecmdline
#mount -o bind /run/fakecmdline /proc/cmdline
curl -sf https://$confluent_mgr/confluent-public/os/$confluent_profile/rootfs.img | rdcore stream-hash /etc/coreos-live-want-rootfs | bsdtar -xf - -C /
@@ -0,0 +1,10 @@
cat /tls/*.0 >> /etc/pki/tls/certs/ca-bundle.crt
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
fi
fi
@@ -0,0 +1,93 @@
#!/bin/sh
nodename=$(grep ^NODENAME: /etc/confluent/confluent.info | awk '{print $2}')
confluent_mgr=$(grep ^MANAGER: /etc/confluent/confluent.info| head -n 1| awk '{print $2}' | sed -e s/%/%25/)
if [[ $confluent_mgr = *:* ]]; then
confluent_mgr=[$confluent_mgr]
fi
mkdir -p /sysroot/var/home/core/.ssh/
chmod 700 /sysroot/var/home/core/.ssh
cat /ssh/*.rootpubkey >> /sysroot/var/home/core/.ssh/authorized_keys
chmod 600 /sysroot/var/home/core/.ssh/authorized_keys
cp -a /etc/confluent /sysroot/etc/confluent
mkdir -p /sysroot/opt/confluent/bin/
cat > /sysroot/opt/confluent/bin/setssh.sh << 'EOF'
#!/bin/sh
nodename=$(grep ^NODENAME: /etc/confluent/confluent.info | awk '{print $2}')
confluent_mgr=$(grep ^MANAGER: /etc/confluent/confluent.info| head -n 1| awk '{print $2}' | sed -e s/%/%25/)
if [[ $confluent_mgr = *:* ]]; then
confluent_mgr=[$confluent_mgr]
fi
for i in /etc/ssh/ssh_host*key.pub; do
certname=${i/.pub/-cert.pub}
curl --cacert /etc/confluent/ca.pem -sf -X POST -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" -d @$i https://$confluent_mgr/confluent-api/self/sshcert > $certname
if ! grep HostKey ${i%.pub} /etc/ssh/sshd_config > /dev/null; then
echo HostKey ${i%.pub} >> /etc/ssh/sshd_config
fi
if ! grep HostCertificate $certname /etc/ssh/sshd_config > /dev/null; then
echo HostCertificate $certname >> /etc/ssh/sshd_config
fi
done
EOF
chmod 755 /sysroot/opt/confluent/bin/setssh.sh
chcon system_u:object_r:bin_t:s0 /sysroot/opt/confluent/bin/setssh.sh
cat > /sysroot/etc/systemd/system/confluent-ssh.service << EOF
[Service]
Type=oneshot
ExecStart=/opt/confluent/bin/setssh.sh
[Unit]
PartOf=sshd.service
Before=sshd.service
After=sshd-keygen.target
Wants=sshd-keygen.target
Requires=network-online.target
After=network-online.target
[Install]
WantedBy=sshd.service
EOF
mkdir -p /sysroot/etc/systemd/system/sshd.service.wants
ln -s /etc/systemd/system/confluent-ssh.service /sysroot/etc/systemd/system/sshd.service.wants/
ln -s /etc/systemd/system/confluent-onboot.service /sysroot/etc/systemd/system/multi-user.target.wants/
cat > /sysroot/opt/confluent/bin/onboot.sh << 'EOF'
#!/bin/sh
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg |awk '{print $2}')
nodename=$(grep ^NODENAME: /etc/confluent/confluent.info | awk '{print $2}')
confluent_mgr=$(grep ^MANAGER: /etc/confluent/confluent.info| head -n 1| awk '{print $2}' | sed -e s/%/%25/)
if [[ $confluent_mgr = *:* ]]; then
confluent_mgr=[$confluent_mgr]
fi
curl -sf https://$confluent_mgr/confluent-public/os/${confluent_profile}/scripts/onboot.sh > /tmp/onboot.sh
[ -s /tmp/onboot.sh ] && . /tmp/onboot.sh
exit 0
EOF
chmod 755 /sysroot/opt/confluent/bin/onboot.sh
chcon system_u:object_r:bin_t:s0 /sysroot/opt/confluent/bin/onboot.sh
cat > /sysroot/etc/systemd/system/confluent-onboot.service << EOF
[Service]
Type=oneshot
ExecStart=/opt/confluent/bin/onboot.sh
[Unit]
Requires=sshd.service
After=sshd.service
Requires=network-online.target
After=network-online.target
EOF
chcon -h system_u:object_r:systemd_unit_file_t:s0 /sysroot/etc/systemd/system/confluent-ssh.service /sysroot/etc/systemd/system/sshd.service.wants/confluent-ssh.service /sysroot/etc/systemd/system/confluent-onboot.service /sysroot/etc/systemd/system/multi-user.target.wants/confluent-onboot.service
cp -a /opt/confluent/bin/* /sysroot/opt/confluent/bin/
chcon system_u:object_r:bin_t:s0 /sysroot/opt/confluent/bin/*
@@ -0,0 +1,21 @@
[Unit]
Description=Confluent initialization
DefaultDependencies=false
After=basic.target
# Network is enabled here
After=dracut-initqueue.service
Before=ignition-setup-user.service
Before=coreos-livepxe-rootfs.service
# If we fail, the boot will fail. Be explicit about it.
OnFailure=emergency.target
OnFailureJobMode=isolate
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/opt/confluent/bin/initconfluent.sh
@@ -0,0 +1,14 @@
#!/bin/sh
profname=$(basename $2)
if file -L $1/images/ignition.img | grep gzip > /dev/null; then
mkdir -p /var/lib/confluent/private/os/${profname}/pending/
cd /var/lib/confluent/private/os/${profname}/pending/
zcat $1/images/ignition.img | cpio -dumiv
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/ && \
ln -s $1/images/pxeboot/rootfs.img $2/ && \
(mcopy -i $1/images/efiboot.img ::efi/redhat/grubx64.efi $2/boot/efi/boot/ || \
mcopy -i $1/images/efiboot.img ::efi/boot/grubx64.efi $2/boot/efi/boot/) && \
mcopy -i $1/images/efiboot.img ::efi/boot/bootx64.efi $2/boot/efi/boot/
@@ -0,0 +1,5 @@
label: RedHat CoreOS %%VERSION%% %%ARCH%% (Default Profile)
kernelargs: quiet random.trust_cpu=on ignition.firstboot ignition.platform.id=metal
#the above boots and will have ignition agent phone home and await instructions
#kernelargs: quiet random.trust_cpu=on ignition.firstboot ignition.platform.id=metal coreos.inst=yes coreos.inst.install_dev=sda
#the above runs the installer to write to disk
@@ -12,7 +12,7 @@ sed -i 's/install::/install:*:/' /sysroot/etc/shadow
sed -i 's/root::/root:*:/' /sysroot/etc/shadow
mkdir -p /sysroot/root/.ssh
#chmod 700 /sysroot/root/.ssh
cat /ssh/*.rootpubkey > /sysroot/root/.ssh/authorized_keys
cat /ssh/*pubkey > /sysroot/root/.ssh/authorized_keys
#chmod 600 /sysroot/root/.ssh/authorized_keys
mkdir -p /sysroot/etc/ssh/
for i in /ssh/*.ca; do
@@ -0,0 +1,25 @@
Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the
appropriate phase of the install process.
The 'hosts' may be omitted, and if included will be ignored, replaced with the host that is specifically
requesting the playbooks be executed.
Also, the playbooks will be executed on the deployment server. Hence it may be slower in aggregate than
running content under scripts/ which ask much less of the deployment server
Here is an example of what a playbook would look like broadly:
- name: Example
gather_facts: no
tasks:
- name: Example1
lineinfile:
path: /etc/hosts
line: 1.2.3.4 test1
create: yes
- name: Example2
lineinfile:
path: /etc/hosts
line: 1.2.3.5 test2
create: yes
@@ -0,0 +1,25 @@
Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the
appropriate phase of the install process.
The 'hosts' may be omitted, and if included will be ignored, replaced with the host that is specifically
requesting the playbooks be executed.
Also, the playbooks will be executed on the deployment server. Hence it may be slower in aggregate than
running content under scripts/ which ask much less of the deployment server
Here is an example of what a playbook would look like broadly:
- name: Example
gather_facts: no
tasks:
- name: Example1
lineinfile:
path: /etc/hosts
line: 1.2.3.4 test1
create: yes
- name: Example2
lineinfile:
path: /etc/hosts
line: 1.2.3.5 test2
create: yes
@@ -1,5 +1,5 @@
#!/bin/sh
sed -i 's/centos/CentOS/; s/rhel/Red Hat Enterprise Linux/' $2/profile.yaml
sed -i 's/centos/CentOS/; s/rhel/Red Hat Enterprise Linux/; s/oraclelinux/Oracle Linux/; s/alma/AlmaLinux/' $2/profile.yaml
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,12 +33,16 @@
reboot
%packages
#-kernel-uek # This can opt out of the UEK for the relevant distribution
chrony
rsync
pciutils
python
rsync
tar
-iwl*-firmware
%include /tmp/addonpackages
%end
# A kickstart.custom file is provided to enable easily adding
# kickstart content without modifying the stock file.
# While the stock file may be safely modified, using the .custom
@@ -47,32 +51,33 @@ python
%include /tmp/kickstart.custom
%pre
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg |awk '{print $2}')
mgr=$(grep deploy_server /etc/confluent/confluent.deploycfg |awk '{print $2}')
curl -f https://$mgr/confluent-public/os/$profile/scripts/pre.sh > /tmp/preinst.sh
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg |awk '{print $2}')
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg |awk '{print $2}')
curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/pre.sh > /tmp/preinst.sh
. /tmp/preinst.sh
%end
%post --nochroot
mkdir -p /mnt/sysimage/etc/confluent
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg |awk '{print $2}')
mgr=$(grep deploy_server /etc/confluent/confluent.deploycfg |awk '{print $2}')
curl -f https://$mgr/confluent-public/os/$profile/scripts/prechroot.sh > /tmp/postinst.sh
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg |awk '{print $2}')
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg |awk '{print $2}')
curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/prechroot.sh > /tmp/postinst.sh
. /tmp/postinst.sh
# Hook firstboot.sh
curl -f https://$mgr/confluent-public/os/$profile/scripts/firstboot.service > /mnt/sysimage/etc/systemd/system/firstboot.service
curl -f https://$mgr/confluent-public/os/$profile/scripts/firstboot.sh > /mnt/sysimage/etc/confluent/firstboot.sh
chmod +x /mnt/sysimage/etc/confluent/firstboot.sh
curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/firstboot.service > /mnt/sysimage/etc/systemd/system/firstboot.service
mkdir -p /mnt/sysimage/opt/confluent/bin
curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/firstboot.sh > /mnt/sysimage/opt/confluent/bin/firstboot.sh
chmod +x /mnt/sysimage/opt/confluent/bin/firstboot.sh
%end
%post
cat /etc/confluent/tls/*.pem >> /etc/pki/tls/certs/ca-bundle.crt
systemctl enable firstboot
chgrp ssh_keys /etc/ssh/ssh*key
restorecon /etc/ssh/ssh*key /root/.shosts /etc/ssh/shosts.equiv /etc/ssh/ssh_config.d/* /etc/confluent/firstboot.sh
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg |awk '{print $2}')
mgr=$(grep deploy_server /etc/confluent/confluent.deploycfg |awk '{print $2}')
curl -f https://$mgr/confluent-public/os/$profile/scripts/post.sh > /tmp/postinst.sh
restorecon /etc/ssh/ssh*key /root/.shosts /etc/ssh/shosts.equiv /etc/ssh/ssh_config.d/* /opt/confluent/bin/firstboot.sh
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg |awk '{print $2}')
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg |awk '{print $2}')
curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/post.sh > /tmp/postinst.sh
. /tmp/postinst.sh
%end
@@ -1,2 +1,3 @@
label: %%DISTRO%% %%VERSION%% %%ARCH%% (Default Profile)
kernelargs: quiet
kernelargs: quiet # These arguments are passed to the installer
#installedargs: example # These arguments would be added to the installed system
@@ -0,0 +1,414 @@
# 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.
import argparse
import ctypes
import fcntl
import json
from select import select
import socket
import struct
import os
import subprocess
import sys
import time
if os.path.exists('/opt/confluent/bin/apiclient'):
apiclient = '/opt/confluent/bin/apiclient'
elif os.path.exists('/etc/confluent/apiclient'):
apiclient = '/etc/confluent/apiclient'
class IpmiMsg(ctypes.Structure):
_fields_ = [('netfn', ctypes.c_ubyte),
('cmd', ctypes.c_ubyte),
('data_len', ctypes.c_short),
('data', ctypes.POINTER(ctypes.c_ubyte))]
class IpmiSystemInterfaceAddr(ctypes.Structure):
_fields_ = [('addr_type', ctypes.c_int),
('channel', ctypes.c_short),
('lun', ctypes.c_ubyte)]
class IpmiRecv(ctypes.Structure):
_fields_ = [('recv_type', ctypes.c_int),
('addr', ctypes.POINTER(IpmiSystemInterfaceAddr)),
('addr_len', ctypes.c_uint),
('msgid', ctypes.c_long),
('msg', IpmiMsg)]
class IpmiReq(ctypes.Structure):
_fields_ = [('addr', ctypes.POINTER(IpmiSystemInterfaceAddr)),
('addr_len', ctypes.c_uint),
('msgid', ctypes.c_long),
('msg', IpmiMsg)]
_IONONE = 0
_IOWRITE = 1
_IOREAD = 2
IPMICTL_SET_MY_ADDRESS_CMD = (
_IOREAD << 30 | ctypes.sizeof(ctypes.c_uint) << 16
| ord('i') << 8 | 17) # from ipmi.h
IPMICTL_SEND_COMMAND = (
_IOREAD << 30 | ctypes.sizeof(IpmiReq) << 16
| ord('i') << 8 | 13) # from ipmi.h
# next is really IPMICTL_RECEIVE_MSG_TRUNC, but will only use that
IPMICTL_RECV = (
(_IOWRITE | _IOREAD) << 30 | ctypes.sizeof(IpmiRecv) << 16
| ord('i') << 8 | 11) # from ipmi.h
BMC_SLAVE_ADDR = ctypes.c_uint(0x20)
CURRCHAN = 0xf
ADDRTYPE = 0xc
class Session(object):
def __init__(self, devnode='/dev/ipmi0'):
"""Create a local session inband
:param: devnode: The path to the ipmi device
"""
self.ipmidev = open(devnode, 'r+')
fcntl.ioctl(self.ipmidev, IPMICTL_SET_MY_ADDRESS_CMD, BMC_SLAVE_ADDR)
# the interface is initted, create some reusable memory for our session
self.databuffer = ctypes.create_string_buffer(4096)
self.req = IpmiReq()
self.rsp = IpmiRecv()
self.addr = IpmiSystemInterfaceAddr()
self.req.msg.data = ctypes.cast(
ctypes.addressof(self.databuffer),
ctypes.POINTER(ctypes.c_ubyte))
self.rsp.msg.data = self.req.msg.data
self.userid = None
self.password = None
def await_reply(self):
rd, _, _ = select((self.ipmidev,), (), (), 1)
while not rd:
rd, _, _ = select((self.ipmidev,), (), (), 1)
def pause(self, seconds):
time.sleep(seconds)
@property
def parsed_rsp(self):
response = {'netfn': self.rsp.msg.netfn, 'command': self.rsp.msg.cmd,
'code': bytearray(self.databuffer.raw)[0],
'data': bytearray(
self.databuffer.raw[1:self.rsp.msg.data_len])}
return response
def await_config(s, bmccfg, channel):
vlan = bmccfg.get('bmcvlan', None)
ipv4 = bmccfg.get('bmcipv4', None)
prefix = bmccfg.get('prefixv4', None)
gw = bmccfg.get('bmcgw', None)
def raw_command(self,
netfn,
command,
data=(),
bridge_request=None,
retry=True,
delay_xmit=None,
timeout=None,
waitall=False, rslun=0):
self.addr.channel = CURRCHAN
self.addr.addr_type = ADDRTYPE
self.addr.lun = rslun
self.req.addr_len = ctypes.sizeof(IpmiSystemInterfaceAddr)
self.req.addr = ctypes.pointer(self.addr)
self.req.msg.netfn = netfn
self.req.msg.cmd = command
if data:
data = memoryview(bytearray(data))
try:
self.databuffer[:len(data)] = data[:len(data)]
except ValueError:
self.databuffer[:len(data)] = data[:len(data)].tobytes()
self.req.msg.data_len = len(data)
fcntl.ioctl(self.ipmidev, IPMICTL_SEND_COMMAND, self.req)
self.await_reply()
self.rsp.msg.data_len = 4096
self.rsp.addr = ctypes.pointer(self.addr)
self.rsp.addr_len = ctypes.sizeof(IpmiSystemInterfaceAddr)
fcntl.ioctl(self.ipmidev, IPMICTL_RECV, self.rsp)
return self.parsed_rsp
def _is_tsm(model):
return model in ('7y00', '7z01', '7y98', '7y99')
def set_port(s, port, vendor, model):
oport = port
if vendor not in ('IBM', 'Lenovo'):
raise Exception('{0} not implemented'.format(vendor))
if _is_tsm(model):
return set_port_tsm(s, port, model)
else:
set_port_xcc(s, port, model)
return 1
def set_port_tsm(s, port, model):
oport = port
sys.stdout.write('Setting TSM port to "{}"...'.format(oport))
sys.stdout.flush()
if port == 'ocp':
s.raw_command(0x32, 0x71, b'\x00\x01\x00')
elif port == 'dedicated':
s.raw_command(0x32, 0x71, b'\x00\x00\x00')
else:
raise Exception("Unsupported port for TSM")
timer = 15
while timer:
timer = timer - 1
time.sleep(1.0)
sys.stdout.write('.')
sys.stdout.flush()
if port == 'ocp':
iface = 0
s.raw_command(0x32, 0x71, b'\x00\x00\x03')
elif port == 'dedicated':
iface = 1
s.raw_command(0x32, 0x71, b'\x00\x01\x03')
rsp = s.raw_command(0x32, 0x72, bytearray([4, iface, 0]))
print('Complete')
return int(rsp['data'][0])
def set_port_xcc(s, port, model):
oport = port
if port.lower() == 'dedicated':
port = b'\x01'
elif port.lower() in ('ml2', 'ocp'):
port = b'\x02\x00'
elif port.lower() == 'lom':
if model == '7x58':
port = b'\x00\x02'
else:
port = b'\x00\x00'
else:
port = port.split(' ')
port = bytes(bytearray([int(x) for x in port]))
currport = bytes(s.raw_command(0xc, 2, b'\x01\xc0\x00\x00')['data'][1:])
if port == currport:
sys.stdout.write('XCC port already set to "{}"\n'.format(oport))
return
sys.stdout.write('Setting XCC port to "{}"...'.format(oport))
sys.stdout.flush()
s.raw_command(0xc, 1, b'\x01\xc0' + port)
tries = 60
while currport != port and tries:
tries -= 1
time.sleep(0.5)
sys.stdout.write('.')
sys.stdout.flush()
currport = bytes(s.raw_command(0xc, 2, b'\x01\xc0\x00\x00')['data'][1:])
if not tries:
raise Exception('Timeout attempting to set port')
sys.stdout.write('Complete\n')
def check_vlan(s, vlan, channel):
if vlan == 'off':
vlan = b'\x00\x00'
else:
vlan = int(vlan)
if vlan:
vlan = vlan | 32768
vlan = struct.pack('<H', vlan)
currvlan = bytes(s.raw_command(0xc, 2, bytearray([channel, 0x14 ,0, 0]))['data'][1:])
if bytearray(currvlan)[1] & 0b10000000 == 0:
currvlan = b'\x00\x00'
return currvlan == vlan
def set_vlan(s, vlan, channel):
ovlan = vlan
if vlan == 'off':
vlan = b'\x00\x00'
else:
vlan = int(vlan)
if vlan:
vlan = vlan | 32768
vlan = struct.pack('<H', vlan)
if check_vlan(s, ovlan, channel):
sys.stdout.write('VLAN already configured to "{0}"\n'.format(ovlan))
return False
rsp = s.raw_command(0xc, 1, bytearray([channel, 0x14]) + vlan)
if rsp.get('code', 1) == 0:
print('VLAN configured to "{}"'.format(ovlan))
else:
print('Error setting vlan: ' + repr(rsp))
return True
def get_lan_channel(s):
for chan in range(1, 16):
rsp = s.raw_command(6, 0x42, bytearray([chan]))['data']
if not rsp:
continue
medtype = int(rsp[1]) & 0b1111111
if medtype not in (4, 6):
continue
rsp = s.raw_command(0xc, 2, bytearray([2, chan, 5, 0, 0]))
if rsp.get('code', 1) == 0:
return chan
return 1
def check_ipv4(s, ipaddr, channel):
ipaddr = bytearray(socket.inet_aton(ipaddr))
rsp = s.raw_command(0xc, 2, bytearray([channel, 3, 0, 0]))['data'][-4:]
return rsp == ipaddr
def set_ipv4(s, ipaddr, channel):
oipaddr = ipaddr
ipaddr = bytearray(socket.inet_aton(ipaddr))
if check_ipv4(s, oipaddr, channel):
print('IP Address already set to {}'.format(oipaddr))
return False
rsp = int(s.raw_command(0xc, 2, bytearray([channel, 4, 0, 0]))['data'][1]) & 0b1111
if rsp != 1:
sys.stdout.write("Changing configuration to static...")
sys.stdout.flush()
resp = s.raw_command(0xc, 1, bytearray([channel, 4, 1]))
tries = 0
while rsp != 1 and tries < 30:
sys.stdout.write('.')
sys.stdout.flush()
tries += 1
time.sleep(0.5)
rsp = int(s.raw_command(0xc, 2, bytearray([channel, 4, 0, 0]))['data'][1]) & 0b1111
sys.stdout.write('Complete\n')
sys.stdout.flush()
print('Setting IP to {}'.format(oipaddr))
s.raw_command(0xc, 1, bytearray([channel, 3]) + ipaddr)
return True
def check_subnet(s, prefix, channel):
prefix = int(prefix)
mask = bytearray(struct.pack('!I', (2**32 - 1) ^ (2**(32 - prefix) - 1)))
rsp = s.raw_command(0xc, 2, bytearray([channel, 6, 0, 0]))['data'][-4:]
return rsp == mask
def set_subnet(s, prefix, channel):
oprefix = prefix
prefix = int(prefix)
mask = bytearray(struct.pack('!I', (2**32 - 1) ^ (2**(32 - prefix) - 1)))
if check_subnet(s, prefix, channel):
print('Subnet Mask already set to /{}'.format(oprefix))
return False
print('Setting subnet mask to /{}'.format(oprefix))
s.raw_command(0xc, 1, bytearray([channel, 6]) + mask)
return True
def check_gateway(s, gw, channel):
gw = bytearray(socket.inet_aton(gw))
rsp = s.raw_command(0xc, 2, bytearray([channel, 12, 0, 0]))['data'][-4:]
return rsp == gw
def set_gateway(s, gw, channel):
ogw = gw
gw = bytearray(socket.inet_aton(gw))
rsp = s.raw_command(0xc, 2, bytearray([channel, 12, 0, 0]))['data'][-4:]
if check_gateway(s, ogw, channel):
print('Gateway already set to {}'.format(ogw))
return False
print('Setting gateway to {}'.format(ogw))
s.raw_command(0xc, 1, bytearray([channel, 12]) + gw)
return True
def dotwait():
sys.stdout.write('.')
sys.stdout.flush()
time.sleep(0.5)
def main():
a = argparse.ArgumentParser(description='Locally configure a BMC device')
a.add_argument('-v', help='vlan id or off to disable vlan tagging')
a.add_argument('-p', help='Which port to use (dedicated, lom, ocp, ml2)')
a.add_argument('-i', help='JSON configuration file to read for '
'configuration')
a.add_argument('-c', help='Use Confluent API to direct BMC configuration',
action='store_true')
args = a.parse_args()
if args.i:
bmccfg = json.load(open(args.i))
elif args.c:
bmccfgsrc = subprocess.check_output(
[sys.executable, apiclient, '/confluent-api/self/bmcconfig', '-j'])
bmccfg = json.loads(bmccfgsrc)
else:
bmccfg = {}
if args.p is not None:
bmccfg['bmcport'] = args.p
if args.v is not None:
bmccfg['bmcvlan'] = args.v
vendor = open('/sys/devices/virtual/dmi/id/sys_vendor').read()
vendor = vendor.strip()
try:
model = open('/sys/devices/virtual/dmi/id/product_sku').read().strip()
if model == 'none':
raise Exception('No SKU')
except Exception:
model = open('/sys/devices/virtual/dmi/id/product_name').read()
if vendor in ('Lenovo', 'IBM'):
if '[' in model and ']' in model:
model = model.split('[')[1].split(']')[0]
model = model[:4].lower()
s = Session('/dev/ipmi0')
if not bmccfg:
print("No BMC configuration specified, exiting.")
return
if bmccfg.get('bmcport', None):
channel = set_port(s, bmccfg['bmcport'], vendor, model)
else:
channel = get_lan_channel(s)
awaitvlan = False
awaitip = False
awaitprefix = False
awaitgw = False
if bmccfg.get('bmcvlan', None):
awaitvlan = set_vlan(s, bmccfg['bmcvlan'], channel)
if bmccfg.get('bmcipv4', None):
awaitip = set_ipv4(s, bmccfg['bmcipv4'], channel)
if bmccfg.get('prefixv4', None):
awaitprefix = set_subnet(s, bmccfg['prefixv4'], channel)
if bmccfg.get('bmcgw', None):
awaitgw = set_gateway(s, bmccfg['bmcgw'], channel)
sys.stdout.write('Waiting for changes to take effect...')
sys.stdout.flush()
while awaitvlan and not check_vlan(s, bmccfg['bmcvlan'], channel):
dotwait()
while awaitip and not check_ipv4(s, bmccfg['bmcipv4'], channel):
dotwait()
while awaitprefix and not check_subnet(s, bmccfg['prefixv4'], channel):
dotwait()
while awaitprefix and not check_gateway(s, bmccfg['bmcgw'], channel):
dotwait()
sys.stdout.write('done\n')
sys.stdout.flush()
#await_config(s, bmccfg, channel)
if __name__ == '__main__':
main()
@@ -4,7 +4,7 @@ Requires=network-online.target
After=network-online.target
[Service]
ExecStart=/etc/confluent/firstboot.sh
ExecStart=/opt/confluent/bin/firstboot.sh
[Install]
WantedBy=multi-user.target
@@ -6,17 +6,35 @@
# the script notifies confluent that install is fully complete.
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
apikey=$(cat /etc/confluent/confluent.apikey)
mgr=$(grep deploy_server /etc/confluent/confluent.deploycfg|awk '{print $2}')
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg|awk '{print $2}')
cat /etc/confluent/tls/*.pem >> /etc/pki/tls/certs/ca-bundle.crt
export nodename mgr profile
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}')
export nodename confluent_mgr confluent_profile
. /etc/confluent/functions
while ! ping -c 1 $confluent_mgr >& /dev/null; do
sleep 1
done
exec >> /var/log/confluent/confluent-firstboot.log
exec 2>> /var/log/confluent/confluent-firstboot.log
chmod 600 /var/log/confluent/confluent-firstboot.log
tail -f /var/log/confluent/confluent-firstboot.log > /dev/console &
logshowpid=$!
if [ ! -f /etc/confluent/firstboot.ran ]; then
touch /etc/confluent/firstboot.ran
run_remote firstboot.custom
cat /etc/confluent/tls/*.pem >> /etc/pki/tls/certs/ca-bundle.crt
run_remote firstboot.custom
# Firstboot scripts may be placed into firstboot.d, e.g. firstboot.d/01-firstaction.sh, firstboot.d/02-secondaction.sh
run_remote_parts firstboot.d
curl -X POST -d 'status: complete' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/updatestatus
# Induce execution of remote configuration, e.g. ansible plays in ansible/firstboot.d/
run_remote_config firstboot.d
fi
curl -X POST -d 'status: complete' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$confluent_mgr/confluent-api/self/updatestatus
systemctl disable firstboot
rm /etc/systemd/system/firstboot.service
rm /etc/confluent/firstboot.ran
kill $logshowpid
@@ -1,12 +1,137 @@
run_remote() {
requestedcmd="'$*'"
#!/bin/bash
function test_mgr() {
if curl -s https://${1}/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
}
fetch_remote() {
curlargs=""
if [ -f /etc/confluent/ca.pem ]; then
curlargs=" --cacert /etc/confluent/ca.pem"
fi
set_confluent_vars
mkdir -p $(dirname $1)
curl -f -sS $curlargs https://$confluent_mgr/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 Running $requestedcmd from https://$mgr/confluent-public/os/$profile/scripts/
tmpdir=$(mktemp -d)
echo Executing in $tmpdir
cd $tmpdir
curl -f -sS https://$mgr/confluent-public/os/$profile/scripts/$1 > $1
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
@@ -16,23 +141,56 @@ run_remote() {
shift
./$cmd $*
retcode=$?
echo "$requestedcmd exited with code $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://$mgr/confluent-public/os/$profile/scripts/
tmpdir=$(mktemp -d)
echo Executing in $tmpdir
cd $tmpdir
curl -f -sS https://$mgr/confluent-public/os/$profile/scripts/$1 > $1
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)
curl -f -sS $curlargs https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/$1 > $1
if [ $? != 0 ]; then echo "'$*'" failed to download; return 1; fi
/usr/libexec/platform-python $*
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}"
@@ -49,7 +49,7 @@ class DiskInfo(object):
@property
def priority(self):
if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2'):
if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2', 'thinksystem_m.2'):
return 0
if 'imsm' in self.mdcontainer:
return 1
@@ -0,0 +1,19 @@
# To use this script, rename or copy the mofed image to either ofed.tgz or ofed.iso
# and modify the script below if wanting to use the iso instead of tgz
# It checks for mellanox devices and opts not to install, so this script could be added
# to a general profile without causing mofed to install on non-mellanox systems
. /etc/confluent/functions
if lspci -d 15b3:: -n |grep 15b3 > /dev/null; then
# Uncomment the following three lines and comment out the next
# two lines to use the .iso instead of the tgz packaging
#fetch_remote infiniband/mofed.iso
#mkdir MLNX_OFED
#mount -o loop infiniband/mofed.iso MLNX_OFED
fetch_remote infiniband/mofed.tgz
tar xf infiniband/mofed.tgz
# The rest is common between tar and iso
cd MLNX_OFED*
./mlnxofedinstall --force
fi
@@ -0,0 +1,10 @@
# Add needed base packages to the install
cat << EOF >> /tmp/addonpackages
perl
pkgconf-pkg-config
tcsh
lsof
tk
gcc-gfortran
tcl
EOF
@@ -2,3 +2,6 @@
# This is a convenient place to keep customizations separate from modifying the stock scripts
# While modification of the stock scripts is fine, it may be easier to rebase to a newer
# stock profile if the '.custom' files are used.
# An example for installing OFED for infiniband follows (see the file for more detail):
#run_remote infiniband/mofed.post
@@ -1,20 +1,24 @@
#!/bin/sh
# need to copy over ssh key info
mkdir -p /var/log/confluent
chmod 700 /var/log/confluent
exec >> /var/log/confluent/confluent-post.log
exec 2>> /var/log/confluent/confluent-post.log
chmod 600 /var/log/confluent/confluent-post.log
tail -f /var/log/confluent/confluent-post.log > /dev/tty &
logshowpid=$!
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
apikey=$(cat /etc/confluent/confluent.apikey)
chmod 700 /etc/confluent
chmod og-rwx /etc/confluent/*
export mgr profile nodename
export confluent_mgr confluent_profile nodename
. /etc/confluent/functions
curl -X POST -d 'status: staged' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/updatestatus
if [ -f /tmp/cryptboot ]; then
run_remote tpm_luks.sh
fi
# By default, the install repository is ignored, change
# this by manually adding local repositories
@@ -30,6 +34,18 @@ 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 induce server side processing of the syncfile contents if
# present
run_remote_python syncfileclient
# run_remote example.sh
# run_remote_python example.py
run_remote post.custom
# Also, scripts may be placed into 'post.d', e.g. post.d/01-runfirst.sh, post.d/02-runsecond.sh
run_remote_parts post.d
# Induce execution of remote configuration, e.g. ansible plays in ansible/post.d/
run_remote_config post.d
curl -sf -X POST -d 'status: staged' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$confluent_mgr/confluent-api/self/updatestatus
kill $logshowpid
@@ -2,3 +2,12 @@
# This is a convenient place to keep customizations separate from modifying the stock scripts
# While modification of the stock scripts is fine, it may be easier to rebase to a newer
# stock profile if the '.custom' files are used.
#
#Here is an example to locally configure the platform BMC according
#to confluent configuration so that the BMC would be on the correct
#network:
#run_remote_python configbmc -c
#Some addons improve efficiency by adding dependencies during install
#here is an example for adding OFED install prereqs to the install
#run_remote infiniband/mofed.pre
@@ -7,7 +7,15 @@
# If you want to use a more custom partition plan, the easiest
# method is to edit the kicktstart file and comment out or
# delete %include /tmp/partitioning
if [ -f "/run/install/cmdline.d/01-autocons.conf" ]; then
consoledev=$(cat /run/install/cmdline.d/01-autocons.conf | sed -e 's!console=!/dev/!' -e 's/,.*//')
TMUX= tmux a <> $consoledev >&0 2>&1 &
fi
exec >> /tmp/confluent-pre.log
exec 2>> /tmp/confluent-pre.log
chmod 600 /tmp/confluent-pre.log
tail -f /tmp/confluent-pre.log > /dev/tty &
logshowpid=$!
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
locale=$(grep ^locale: /etc/confluent/confluent.deploycfg)
locale=${locale#locale: }
@@ -28,39 +36,48 @@ if [ "$rootpw" = null ]; then
else
echo "rootpw --iscrypted $rootpw" > /tmp/rootpw
fi
curl -sf https://$confluent_mgr/confluent-public/os/$confluent_profile/profile.yaml > /tmp/instprofile.yaml
blargs=$(grep ^installedargs: /tmp/instprofile.yaml | sed -e 's/#.*//' -e 's/^installedargs: //')
if [ ! -z "$blargs" ]; then
blargs=' --append="'$blargs'"'
fi
grubpw=$(grep ^grubpassword /etc/confluent/confluent.deploycfg | awk '{print $2}')
if [ "$grubpw" = "null" ]; then
touch /tmp/grubpw
else
echo "bootloader --iscrypted --password=$grubpw" > /tmp/grubpw
blargs=" --iscrypted --password=$grubpw $blargs"
fi
if [ ! -z "$blargs" ]; then
echo "bootloader $blargs" > /tmp/grubpw
fi
ssh-keygen -A
for pubkey in /etc/ssh/ssh_host_*_key.pub; do
for pubkey in /etc/ssh/ssh_host*key.pub; do
certfile=${pubkey/.pub/-cert.pub}
curl -f -X POST -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" -d @$pubkey https://$mgr/confluent-api/self/sshcert > $certfile
curl -sf -X POST -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" -d @$pubkey https://$confluent_mgr/confluent-api/self/sshcert > $certfile
echo HostCertificate $certfile >> /etc/ssh/sshd_config.anaconda
done
/usr/sbin/sshd -f /etc/ssh/sshd_config.anaconda
if [ -f "/run/install/cmdline.d/01-autocons.conf" ]; then
consoledev=$(cat /run/install/cmdline.d/01-autocons.conf | sed -e 's!console=!/dev/!' -e 's/,.*//')
TMUX= tmux a <> $consoledev >&0 2>&1 &
fi
cryptboot=$(grep ^encryptboot: /etc/confluent/confluent.deploycfg | awk '{print $2}')
LUKSPARTY=''
touch /tmp/addonpackages
if [ "$cryptboot" == "tpm2" ]; then
LUKSPARTY="--encrypted --passphrase=$(cat /etc/confluent/confluent.apikey)"
echo $cryptboot >> /tmp/cryptboot
fi
export mgr profile nodename
curl -f https://$mgr/confluent-public/os/$profile/scripts/functions > /tmp/functions
export confluent_mgr confluent_profile nodename
curl -sf https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/functions > /tmp/functions
. /tmp/functions
run_remote_python getinstalldisk
if [ -e /tmp/installdisk ]; then
run_remote pre.custom
run_remote_parts pre.d
if [ ! -e /tmp/installdisk ]; then
run_remote_python getinstalldisk
fi
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
fi
python /etc/confluent/apiclient /confluent-public/os/$profile/kickstart.custom -o /tmp/kickstart.custom
run_remote pre.custom
python /etc/confluent/apiclient /confluent-public/os/$confluent_profile/kickstart.custom -o /tmp/kickstart.custom
kill $logshowpid
@@ -8,11 +8,22 @@
# for customization, which will run in a more normal mechanism
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
export mgr profile nodename
export confluent_mgr confluent_profile nodename
cp -a /etc/confluent /mnt/sysimage/etc
chmod -R og-rwx /mnt/sysimage/etc/confluent
cp /tmp/functions /mnt/sysimage/etc/confluent/
hostnamectl set-hostname $nodename
cp /etc/hostname /mnt/sysimage/etc/hostname
. /tmp/functions
cp /tmp/cryptboot /mnt/sysimage/tmp/
if [ -f /tmp/cryptboot ]; then
cp /tmp/cryptboot /mnt/sysimage/tmp/
fi
mkdir -p /mnt/sysimage/var/log/confluent
mv /tmp/confluent-pre.log /mnt/sysimage/var/log/confluent
echo Port 2222 >> /etc/ssh/sshd_config.anaconda
echo Match LocalPort 22 >> /etc/ssh/sshd_config.anaconda
echo " ChrootDirectory /mnt/sysimage" >> /etc/ssh/sshd_config.anaconda
kill -HUP $(cat /run/sshd.pid)
# Preserve the ssh setup work done for the installer
# by copying into the target system and setting up
@@ -18,6 +18,6 @@ chmod 700 /mnt/sysimage/root/.ssh/
cp /root/.ssh/authorized_keys /mnt/sysimage/root/.ssh/
chmod 600 /mnt/sysimage/root/.ssh/authorized_keys
cp /etc/ssh/ssh_known_hosts /mnt/sysimage/etc/ssh/
curl -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" https://$mgr/confluent-api/self/nodelist > /tmp/allnodes
curl -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" https://$confluent_mgr/confluent-api/self/nodelist > /tmp/allnodes
cp /tmp/allnodes /mnt/sysimage/etc/ssh/shosts.equiv
cp /tmp/allnodes /mnt/sysimage/root/.shosts
@@ -0,0 +1,277 @@
#!/usr/bin/python
import importlib
import tempfile
import json
import os
import pwd
import grp
import shutil
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 partitionhostsline(line):
comment = ''
try:
cmdidx = line.index('#')
comment = line[cmdidx:]
line = line[:cmdidx].strip()
except ValueError:
pass
if not line:
return '', [], comment
ipaddr, names = line.split(maxsplit=1)
names = names.split()
return ipaddr, names, comment
class HostMerger(object):
def __init__(self):
self.byip = {}
self.byname = {}
self.sourcelines = []
self.targlines = []
def read_source(self, sourcefile):
with open(sourcefile, 'r') as hfile:
self.sourcelines = hfile.read().split('\n')
while not self.sourcelines[-1]:
self.sourcelines = self.sourcelines[:-1]
for x in range(len(self.sourcelines)):
line = self.sourcelines[x]
currip, names, comment = partitionhostsline(line)
if currip:
self.byip[currip] = x
for name in names:
self.byname[name] = x
def read_target(self, targetfile):
with open(targetfile, 'r') as hfile:
lines = hfile.read().split('\n')
if not lines[-1]:
lines = lines[:-1]
for y in range(len(lines)):
line = lines[y]
currip, names, comment = partitionhostsline(line)
if currip in self.byip:
x = self.byip[currip]
if self.sourcelines[x] is None:
# have already consumed this enntry
continue
self.targlines.append(self.sourcelines[x])
self.sourcelines[x] = None
continue
for name in names:
if name in self.byname:
x = self.byname[name]
if self.sourcelines[x] is None:
break
self.targlines.append(self.sourcelines[x])
self.sourcelines[x] = None
break
else:
self.targlines.append(line)
def write_out(self, targetfile):
while not self.targlines[-1]:
self.targlines = self.targlines[:-1]
if not self.targlines:
break
while not self.sourcelines[-1]:
self.sourcelines = self.sourcelines[:-1]
if not self.sourcelines:
break
with open(targetfile, 'w') as hosts:
for line in self.targlines:
hosts.write(line + '\n')
for line in self.sourcelines:
if line is not None:
hosts.write(line + '\n')
class CredMerger:
def __init__(self):
try:
with open('/etc/login.defs', 'r') as ldefs:
defs = ldefs.read().split('\n')
except FileNotFoundError:
defs = []
lkup = {}
self.discardnames = {}
self.shadowednames = {}
for line in defs:
try:
line = line[:line.index('#')]
except ValueError:
pass
keyval = line.split()
if len(keyval) < 2:
continue
lkup[keyval[0]] = keyval[1]
self.uidmin = int(lkup.get('UID_MIN', 1000))
self.uidmax = int(lkup.get('UID_MAX', 60000))
self.gidmin = int(lkup.get('GID_MIN', 1000))
self.gidmax = int(lkup.get('GID_MAX', 60000))
self.shadowlines = None
def read_passwd(self, source, targfile=False):
self.read_generic(source, self.uidmin, self.uidmax, targfile)
def read_group(self, source, targfile=False):
self.read_generic(source, self.gidmin, self.gidmax, targfile)
def read_generic(self, source, minid, maxid, targfile):
if targfile:
self.targdata = []
else:
self.sourcedata = []
with open(source, 'r') as inputfile:
for line in inputfile.read().split('\n'):
try:
name, _, uid, _ = line.split(':', 3)
uid = int(uid)
except ValueError:
continue
if targfile:
if uid < minid or uid > maxid:
self.targdata.append(line)
else:
self.discardnames[name] = 1
else:
if name[0] in ('+', '#', '@'):
self.sourcedata.append(line)
elif uid >= minid and uid <= maxid:
self.sourcedata.append(line)
def read_shadow(self, source):
self.shadowlines = []
try:
with open(source, 'r') as inshadow:
for line in inshadow.read().split('\n'):
try:
name, _ = line.split(':' , 1)
except ValueError:
continue
if name in self.discardnames:
continue
self.shadowednames[name] = 1
self.shadowlines.append(line)
except FileNotFoundError:
return
def write_out(self, outfile):
with open(outfile, 'w') as targ:
for line in self.targdata:
targ.write(line + '\n')
for line in self.sourcedata:
targ.write(line + '\n')
if outfile == '/etc/passwd':
if self.shadowlines is None:
self.read_shadow('/etc/shadow')
with open('/etc/shadow', 'w') as shadout:
for line in self.shadowlines:
shadout.write(line + '\n')
for line in self.sourcedata:
name, _ = line.split(':', 1)
if name[0] in ('+', '#', '@'):
continue
if name in self.shadowednames:
continue
shadout.write(name + ':!:::::::\n')
if outfile == '/etc/group':
if self.shadowlines is None:
self.read_shadow('/etc/gshadow')
with open('/etc/gshadow', 'w') as shadout:
for line in self.shadowlines:
shadout.write(line + '\n')
for line in self.sourcedata:
name, _ = line.split(':' , 1)
if name in self.shadowednames:
continue
shadout.write(name + ':!::\n')
def appendonce(basepath, filename):
with open(filename, 'rb') as filehdl:
thedata = filehdl.read()
targname = filename.replace(basepath, '')
try:
with open(targname, 'rb') as filehdl:
targdata = filehdl.read()
except IOError:
targdata = b''
if thedata in targdata:
return
with open(targname, 'ab') as targhdl:
targhdl.write(thedata)
def synchronize():
tmpdir = tempfile.mkdtemp()
appendoncedir = tempfile.mkdtemp()
try:
ac = apiclient.HTTPSClient()
data = json.dumps({'merge': tmpdir, 'appendonce': appendoncedir})
status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles', data)
if status == 202:
lastrsp = ''
while status != 204:
status, rsp = ac.grab_url_with_status('/confluent-api/self/remotesyncfiles')
if not isinstance(rsp, str):
rsp = rsp.decode('utf8')
if status == 200:
lastrsp = rsp
pendpasswd = os.path.join(tmpdir, 'etc/passwd')
if os.path.exists(pendpasswd):
cm = CredMerger()
cm.read_passwd(pendpasswd, targfile=False)
cm.read_passwd('/etc/passwd', targfile=True)
cm.write_out('/etc/passwd')
pendgroup = os.path.join(tmpdir, 'etc/group')
if os.path.exists(pendgroup):
cm = CredMerger()
cm.read_group(pendgroup, targfile=False)
cm.read_group('/etc/group', targfile=True)
cm.write_out('/etc/group')
pendhosts = os.path.join(tmpdir, 'etc/hosts')
if os.path.exists(pendhosts):
cm = HostMerger()
cm.read_source(pendhosts)
cm.read_target('/etc/hosts')
cm.write_out('/etc/hosts')
for dirn in os.walk(appendoncedir):
for filen in dirn[2]:
appendonce(appendoncedir, os.path.join(dirn[0], filen))
if lastrsp:
lastrsp = json.loads(lastrsp)
opts = lastrsp.get('options', {})
for fname in opts:
uid = -1
gid = -1
for opt in opts[fname]:
if opt == 'owner':
try:
uid = pwd.getpwnam(opts[fname][opt]['name']).pw_uid
except KeyError:
uid = opts[fname][opt]['id']
elif opt == 'group':
try:
gid = grp.getgrnam(opts[fname][opt]['name']).gr_gid
except KeyError:
gid = opts[fname][opt]['id']
elif opt == 'permissions':
os.chmod(fname, int(opts[fname][opt], 8))
if uid != -1 or gid != -1:
os.chown(fname, uid, gid)
finally:
shutil.rmtree(tmpdir)
if __name__ == '__main__':
synchronize()
@@ -0,0 +1,21 @@
# This file lists files to synchronize or merge to the deployed systems from the deployment server
# To specify taking /some/path/hosts on the deploymennt server and duplicating it to /etc/hosts:
# /some/path/hosts -> /etc/hosts
# If wanting to simply use the same path for source and destinaiton, the -> may be skipped:
# /etc/hosts
# More function is available, for example to limit the entry to run only on n1 through n8, and to set
# owner, group, and permissions in octal notation:
# /example/source -> n1-n8:/etc/target (owner=root,group=root,permissions=600)
# Entries under APPENDONCE: will be added to specified target, only if the target does not already
# contain the data in the source already in its entirety. This allows append in a fashion that
# is friendly to being run repeatedly
# Entries under MERGE: will attempt to be intelligently merged. This supports /etc/group and /etc/passwd
# Any supporting entries in /etc/shadow or /etc/gshadow are added automatically, with password disabled
# It also will not inject 'system' ids (under 1,000 usually) as those tend to be local and rpm managed.
MERGE:
# /etc/passwd
# /etc/group
@@ -0,0 +1,245 @@
get_remote_apikey() {
while [ -z "$confluent_apikey" ]; do
/opt/confluent/bin/clortho $nodename $confluent_mgr > /etc/confluent/confluent.apikey
if grep ^SEALED: /etc/confluent/confluent.apikey > /dev/null; then
# we don't support remote sealed api keys anymore
echo > /etc/confluent/confluent.apikey
fi
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
if [ -z "$confluent_apikey" ]; then
echo "Unable to acquire node api key, set deployment.apiarmed=once on node '$nodename', retrying..."
sleep 10
elif [ -c /dev/tpmrm0 ]; then
tmpdir=$(mktemp -d)
cd $tmpdir
tpm2_startauthsession --session=session.ctx
tpm2_policypcr -Q --session=session.ctx --pcr-list="sha256:15" --policy=pcr15.sha256.policy
tpm2_createprimary -G ecc -Q --key-context=prim.ctx
(echo -n "CONFLUENT_APIKEY:";cat /etc/confluent/confluent.apikey) | tpm2_create -Q --policy=pcr15.sha256.policy --public=data.pub --private=data.priv -i - -C prim.ctx
tpm2_load -Q --parent-context=prim.ctx --public=data.pub --private=data.priv --name=confluent.apikey --key-context=data.ctx
tpm2_evictcontrol -Q -c data.ctx
tpm2_flushcontext session.ctx
cd - > /dev/null
rm -rf $tmpdir
fi
done
}
root=1
rootok=1
netroot=confluent
clear
mkdir -p /etc/ssh
mkdir -p /var/tmp/
mkdir -p /var/empty/sshd
mkdir -p /etc/confluent
sed -i '/^root:x/d' /etc/passwd
echo root:x:0:0::/:/bin/bash >> /etc/passwd
echo sshd:x:30:30:SSH User:/var/empty/sshd:/sbin/nologin >> /etc/passwd
if ! grep console= /proc/cmdline >& /dev/null; then
autocons=$(/opt/confluent/bin/autocons)
autocons=${autocons##*/}
echo "Automatic console configured for $autocons"
fi
echo "Initializing confluent diskless environment"
echo -n "udevd: "
/usr/lib/systemd/systemd-udevd --daemon
echo -n "Loading drivers..."
udevadm trigger
udevadm trigger --type=devices --action=add
udevadm settle
modprobe ib_ipoib
modprobe ib_umad
modprobe hfi1
modprobe mlx5_ib
echo "done"
cat > /etc/ssh/sshd_config << EOF
Port 2222
Subsystem sftp /usr/libexec/openssh/sftp-server
PermitRootLogin yes
AuthorizedKeysFile .ssh/authorized_keys
EOF
mkdir /root/.ssh
mkdir /.ssh
cat /ssh/*pubkey > /root/.ssh/authorized_keys 2>/dev/null
cp /root/.ssh/authorized_keys /.ssh/
cat /tls/*.pem > /etc/confluent/ca.pem
mkdir -p /etc/pki/tls/certs
cat /tls/*.pem > /etc/pki/tls/certs/ca-bundle.crt
TRIES=0
oldumask=$(umask)
umask 0077
tpmdir=$(mktemp -d)
cd $tpmdir
lasthdl=""
if [ -c /dev/tpmrm0 ]; then
for hdl in $(tpm2_getcap handles-persistent|awk '{print $2}'); do
tpm2_startauthsession --policy-session --session=session.ctx
tpm2_policypcr -Q --session=session.ctx --pcr-list="sha256:15" --policy=pcr15.sha256.policy
unsealeddata=$(tpm2_unseal --auth=session:session.ctx -Q -c $hdl 2>/dev/null)
tpm2_flushcontext session.ctx
if [[ $unsealeddata == "CONFLUENT_APIKEY:"* ]]; then
confluent_apikey=${unsealeddata#CONFLUENT_APIKEY:}
echo $confluent_apikey > /etc/confluent/confluent.apikey
if [ -n "$lasthdl" ]; then
tpm2_evictcontrol -c $lasthdl
fi
lasthdl=$hdl
fi
done
fi
cd - > /dev/null
rm -rf $tpmdir
touch /etc/confluent/confluent.info
cd /sys/class/net
echo -n "Scanning for network configuration..."
while ! grep ^EXTMGRINFO: /etc/confluent/confluent.info | awk -F'|' '{print $3}' | grep 1 >& /dev/null && [ "$TRIES" -lt 30 ]; do
TRIES=$((TRIES + 1))
for i in *; do
ip link set $i up
done
/opt/confluent/bin/copernicus -t > /etc/confluent/confluent.info
done
cd /
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
hostname $nodename
confluent_mgr=$(grep '^EXTMGRINFO:.*1$' /etc/confluent/confluent.info | head -n 1 | awk -F': ' '{print $2}' | awk -F'|' '{print $1}')
if [ -z "$confluent_mgr" ]; then
confluent_mgr=$(grep ^MANAGER: /etc/confluent/confluent.info|head -n 1 | awk '{print $2}')
fi
if [[ $confluent_mgr == *%* ]]; then
echo $confluent_mgr | awk -F% '{print $2}' > /tmp/confluent.ifidx
ifidx=$(cat /tmp/confluent.ifidx)
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
fi
ready=0
while [ $ready = "0" ]; do
get_remote_apikey
if [[ $confluent_mgr == *:* ]]; then
confluent_mgr="[$confluent_mgr]"
fi
tmperr=$(mktemp)
curl -sSf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$confluent_mgr/confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg 2> $tmperr
if grep 401 $tmperr > /dev/null; then
confluent_apikey=""
if [ -n "$lasthdl" ]; then
tpm2_evictcontrol -c $lasthdl
fi
confluent_mgr=${confluent_mgr#[}
confluent_mgr=${confluent_mgr%]}
else
ready=1
fi
rm $tmperr
done
if [ ! -z "$autocons" ] && grep textconsole: true /etc/confluent/confluent.deploycfg > /dev/null; then /opt/confluent/bin/autocons -c > /dev/null; fi
if [ -c /dev/tpmrm0 ]; then
tpm2_pcrextend 15:sha256=2fbe96c50dde38ce9cd2764ddb79c216cfbcd3499568b1125450e60c45dd19f2
fi
umask $oldumask
autoconfigmethod=$(grep ^ipv4_method: /etc/confluent/confluent.deploycfg |awk '{print $2}')
if [ "$autoconfigmethod" = "dhcp" ]; then
echo -n "Attempting to use dhcp to bring up $ifname..."
dhclient $ifname
echo "Complete:"
ip addr show dev $ifname
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 ^prefix: /etc/confluent/confluent.deploycfg)
v4nm=${v4nm#prefix: }
echo "Setting up $ifname as static at $v4addr/$v4nm"
ip addr add dev $ifname $v4addr/$v4nm
if [ ! -z "$v4gw" ]; then
ip route add default via $v4gw
fi
mkdir -p /run/NetworkManager/system-connections
cat > /run/NetworkManager/system-connections/$ifname.nmconnection << EOC
[connection]
EOC
echo id=${ifname} >> /run/NetworkManager/system-connections/$ifname.nmconnection
echo uuid=$(uuidgen) >> /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
cat >> /run/NetworkManager/system-connections/$ifname.nmconnection << EOC
multi-connect=1
permissions=
wait-device-timeout=60000
[ethernet]
mac-address-blacklist=
[ipv4]
EOC
echo address1=$v4addr/$v4nm >> /run/NetworkManager/system-connections/$ifname.nmconnection
if [ ! -z "$v4gw" ]; then
echo gateway=$v4gw >> /run/NetworkManager/system-connections/$ifname.nmconnection
fi
nameserversec=0
nameservers=""
while read -r entry; do
if [ $nameserversec = 1 ]; then
if [[ $entry == "-"* ]]; then
nameservers="$nameservers"${entry#- }";"
continue
fi
fi
nameserversec=0
if [ "${entry%:*}" = "nameservers" ]; then
nameserversec=1
continue
fi
done < /etc/confluent/confluent.deploycfg
echo dns=$nameservers >> /run/NetworkManager/system-connections/$ifname.nmconnection
dnsdomain=$(grep ^dnsdomain: /etc/confluent/confluent.deploycfg)
dnsdomain=${dnsdomain#dnsdomain: }
echo dns-search=$dnsdomain >> /run/NetworkManager/system-connections/$ifname.nmconnection
cat >> /run/NetworkManager/system-connections/$ifname.nmconnection << EOC
may-fail=false
method=manual
[ipv6]
addr-gen-mode=eui64
method=auto
[proxy]
EOC
fi
chmod 600 /run/NetworkManager/system-connections/*.nmconnection
echo -n "Initializing ssh..."
ssh-keygen -A
for pubkey in /etc/ssh/ssh_host*key.pub; do
certfile=${pubkey/.pub/-cert.pub}
privfile=${pubkey%.pub}
curl -sf -X POST -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" -d @$pubkey https://$confluent_mgr/confluent-api/self/sshcert > $certfile
if [ -s $certfile ]; then
echo HostCertificate $certfile >> /etc/ssh/sshd_config
fi
echo HostKey $privfile >> /etc/ssh/sshd_config
done
/usr/sbin/sshd
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg| awk '{print $2}')
confluent_proto=$(grep ^protocol: /etc/confluent/confluent.deploycfg| awk '{print $2}')
confluent_urls=""
for addr in $(grep ^MANAGER: /etc/confluent/confluent.info|awk '{print $2}'|sed -e s/%/%25/); do
if [[ $addr == *:* ]]; then
confluent_urls="$confluent_urls $confluent_proto://[$addr]/confluent-public/os/$confluent_profile/rootimg.sfs"
else
confluent_urls="$confluent_urls $confluent_proto://$addr/confluent-public/os/$confluent_profile/rootimg.sfs"
fi
done
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg| awk '{print $2}')
mkdir -p /etc/confluent
curl -sf https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/functions > /etc/confluent/functions
. /etc/confluent/functions
source_remote imageboot.sh
@@ -0,0 +1,4 @@
. /etc/confluent/functions
# This is a convenient place to keep customizations separate from modifying the stock scripts
# While modification of the stock scripts is fine, it may be easier to rebase to a newer
# stock profile if the '.custom' files are used.
@@ -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,40 @@
#!/bin/sh
# This script is executed on the first boot after install has
# completed. It is best to edit the middle of the file as
# noted below so custom commands are executed before
# the script notifies confluent that install is fully complete.
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}')
export nodename confluent_mgr confluent_profile
. /etc/confluent/functions
exec >> /var/log/confluent/confluent-firstboot.log
exec 2>> /var/log/confluent/confluent-firstboot.log
chmod 600 /var/log/confluent/confluent-firstboot.log
tail -f /var/log/confluent/confluent-firstboot.log > /dev/console &
logshowpid=$!
while ! ping -c 1 $confluent_mgr >& /dev/null; do
sleep 1
done
if [ ! -f /etc/confluent/firstboot.ran ]; then
touch /etc/confluent/firstboot.ran
cat /etc/confluent/tls/*.pem >> /etc/pki/tls/certs/ca-bundle.crt
run_remote firstboot.custom
# Firstboot scripts may be placed into firstboot.d, e.g. firstboot.d/01-firstaction.sh, firstboot.d/02-secondaction.sh
run_remote_parts firstboot.d
# Induce execution of remote configuration, e.g. ansible plays in ansible/firstboot.d/
run_remote_config firstboot.d
fi
curl -X POST -d 'status: complete' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$confluent_mgr/confluent-api/self/updatestatus
systemctl disable firstboot
rm /etc/systemd/system/firstboot.service
rm /etc/confluent/firstboot.ran
kill $logshowpid
@@ -0,0 +1,196 @@
#!/bin/bash
function test_mgr() {
if curl -s https://${1}/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
}
fetch_remote() {
curlargs=""
if [ -f /etc/confluent/ca.pem ]; then
curlargs=" --cacert /etc/confluent/ca.pem"
fi
set_confluent_vars
mkdir -p $(dirname $1)
curl -f -sS $curlargs https://$confluent_mgr/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)
curl -f -sS $curlargs https://$confluent_mgr/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}"
@@ -0,0 +1,93 @@
import subprocess
import os
class DiskInfo(object):
def __init__(self, devname):
self.name = devname
self.wwn = None
self.path = None
self.model = ''
self.size = 0
self.driver = None
self.mdcontainer = ''
devnode = '/dev/{0}'.format(devname)
qprop = subprocess.check_output(
['udevadm', 'info', '--query=property', devnode])
if not isinstance(qprop, str):
qprop = qprop.decode('utf8')
for prop in qprop.split('\n'):
if '=' not in prop:
continue
k, v = prop.split('=', 1)
if k == 'DEVTYPE' and v != 'disk':
raise Exception('Not a disk')
elif k == 'DM_NAME':
raise Exception('Device Mapper')
elif k == 'ID_MODEL':
self.model = v
elif k == 'DEVPATH':
self.path = v
elif k == 'ID_WWN':
self.wwn = v
elif k == 'MD_CONTAINER':
self.mdcontainer = v
attrs = subprocess.check_output(['udevadm', 'info', '-a', devnode])
if not isinstance(attrs, str):
attrs = attrs.decode('utf8')
for attr in attrs.split('\n'):
if '==' not in attr:
continue
k, v = attr.split('==', 1)
k = k.strip()
if k == 'ATTRS{size}':
self.size = v.replace('"', '')
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:
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:
self.size = int(sizesrc.read()) * 512
if int(self.size) < 536870912:
raise Exception("Device too small for install")
@property
def priority(self):
if self.model.lower() in ('thinksystem_m.2_vd', 'thinksystem m.2', 'thinksystem_m.2'):
return 0
if 'imsm' in self.mdcontainer:
return 1
if self.driver == 'ahci':
return 2
if self.driver.startswith('megaraid'):
return 3
if self.driver.startswith('mpt'):
return 4
return 99
def __repr__(self):
return repr({
'name': self.name,
'path': self.path,
'wwn': self.wwn,
'driver': self.driver,
'size': self.size,
'model': self.model,
})
def main():
disks = []
for disk in sorted(os.listdir('/sys/class/block')):
try:
disk = DiskInfo(disk)
disks.append(disk)
except Exception as e:
print("Skipping {0}: {1}".format(disk, str(e)))
nd = [x.name for x in sorted(disks, key=lambda x: x.priority)]
if nd:
open('/tmp/installdisk', 'w').write(nd[0])
if __name__ == '__main__':
main()
@@ -0,0 +1,376 @@
#!/usr/bin/python3
import glob
import json
import os
import re
import time
import shutil
import socket
import stat
import struct
import sys
import subprocess
def get_next_part_meta(img, imgsize):
if img.tell() == imgsize:
return None
pathlen = struct.unpack('!H', img.read(2))[0]
mountpoint = img.read(pathlen).decode('utf8')
jsonlen = struct.unpack('!I', img.read(4))[0]
metadata = json.loads(img.read(jsonlen).decode('utf8'))
img.seek(16, 1) # skip the two 64-bit values we don't use, they are in json
nextlen = struct.unpack('!H', img.read(2))[0]
img.seek(nextlen, 1) # skip filesystem type
nextlen = struct.unpack('!H', img.read(2))[0]
img.seek(nextlen, 1) # skip orig devname (redundant with json)
nextlen = struct.unpack('!H', img.read(2))[0]
img.seek(nextlen, 1) # skip padding
nextlen = struct.unpack('!Q', img.read(8))[0]
img.seek(nextlen, 1) # go to next section
return metadata
def get_multipart_image_meta(img):
img.seek(0, 2)
imgsize = img.tell()
img.seek(16)
seekamt = img.read(1)
img.seek(struct.unpack('B', seekamt)[0], 1)
partinfo = get_next_part_meta(img, imgsize)
while partinfo:
yield partinfo
partinfo = get_next_part_meta(img, imgsize)
def get_image_metadata(imgpath):
with open(imgpath, 'rb') as img:
header = img.read(16)
if header == b'\x63\x7b\x9d\x26\xb7\xfd\x48\x30\x89\xf9\x11\xcf\x18\xfd\xff\xa1':
for md in get_multipart_image_meta(img):
yield md
else:
raise Exception('Installation from single part image not supported')
class PartedRunner():
def __init__(self, disk):
self.disk = disk
def run(self, command):
command = command.split()
command = ['parted', '-a', 'optimal', '-s', self.disk] + command
return subprocess.check_output(command).decode('utf8')
def fixup(rootdir, vols):
devbymount = {}
for vol in vols:
devbymount[vol['mount']] = vol['targetdisk']
fstabfile = os.path.join(rootdir, 'etc/fstab')
with open(fstabfile) as tfile:
fstab = tfile.read().split('\n')
while not fstab[0]:
fstab = fstab[1:]
if os.path.exists(os.path.join(rootdir, '.autorelabel')):
os.unlink(os.path.join(rootdir, '.autorelabel'))
with open(fstabfile, 'w') as tfile:
for tab in fstab:
entry = tab.split()
if tab.startswith('#ORIGFSTAB#'):
if entry[1] in devbymount:
targetdev = devbymount[entry[1]]
if targetdev.startswith('/dev/localstorage/'):
entry[0] = targetdev
else:
uuid = subprocess.check_output(['blkid', '-s', 'UUID', '-o', 'value', targetdev]).decode('utf8')
uuid = uuid.strip()
entry[0] = 'UUID={}'.format(uuid)
elif entry[2] == 'swap':
entry[0] = '/dev/mapper/localstorage-swap'
entry[0] = entry[0].ljust(42)
entry[1] = entry[1].ljust(16)
entry[3] = entry[3].ljust(28)
tab = '\t'.join(entry)
tfile.write(tab + '\n')
with open(os.path.join(rootdir, 'etc/hostname'), 'w') as nameout:
nameout.write(socket.gethostname() + '\n')
selinuxconfig = os.path.join(rootdir, 'etc/selinux/config')
policy = None
if os.path.exists(selinuxconfig):
with open(selinuxconfig) as cfgin:
sec = cfgin.read().split('\n')
for l in sec:
l = l.split('#', 1)[0]
if l.startswith('SELINUXTYPE='):
_, policy = l.split('=')
for sshkey in glob.glob(os.path.join(rootdir, 'etc/ssh/*_key*')):
os.unlink(sshkey)
for sshkey in glob.glob('/etc/ssh/*_key*'):
newkey = os.path.join(rootdir, sshkey[1:])
shutil.copy2(sshkey, newkey)
finfo = os.stat(sshkey)
os.chown(newkey, finfo[stat.ST_UID], finfo[stat.ST_GID])
for ifcfg in glob.glob(os.path.join(rootdir, 'etc/sysconfig/network-scripts/*')):
os.unlink(ifcfg)
for ifcfg in glob.glob(os.path.join(rootdir, 'etc/NetworkManager/system-connections/*')):
os.unlink(ifcfg)
for ifcfg in glob.glob('/run/NetworkManager/system-connections/*'):
newcfg = ifcfg.split('/')[-1]
newcfg = os.path.join(rootdir, 'etc/NetworkManager/system-connections/{0}'.format(newcfg))
shutil.copy2(ifcfg, newcfg)
shutil.rmtree(os.path.join(rootdir, 'etc/confluent/'))
shutil.copytree('/etc/confluent', os.path.join(rootdir, 'etc/confluent'))
if policy:
sys.stdout.write('Applying SELinux labeling...')
sys.stdout.flush()
subprocess.check_call(['setfiles', '-r', rootdir, os.path.join(rootdir, 'etc/selinux/{}/contexts/files/file_contexts'.format(policy)), os.path.join(rootdir, 'etc')])
subprocess.check_call(['setfiles', '-r', rootdir, os.path.join(rootdir, 'etc/selinux/{}/contexts/files/file_contexts'.format(policy)), os.path.join(rootdir, 'opt')])
sys.stdout.write('Done\n')
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:
defgrub = defgrubin.read().split('\n')
with open(os.path.join(rootdir, 'etc/sysconfig/grub'), 'w') as defgrubout:
for gline in defgrub:
gline = gline.split()
newline = []
for ent in gline:
if ent.startswith('resume=') or ent.startswith('rd.lvm.lv'):
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])
newroot = None
with open('/etc/shadow') as shadowin:
shents = shadowin.read().split('\n')
for shent in shents:
shent = shent.split(':')
if not shent:
continue
if shent[0] == 'root' and shent[1] not in ('*', '!!', ''):
newroot = shent[1]
if newroot:
shlines = None
with open(os.path.join(rootdir, 'etc/shadow')) as oshadow:
shlines = oshadow.read().split('\n')
with open(os.path.join(rootdir, 'etc/shadow'), 'w') as oshadow:
for line in shlines:
if line.startswith('root:'):
line = line.split(':')
line[1] = newroot
line = ':'.join(line)
oshadow.write(line + '\n')
partnum = None
targblock = None
for vol in vols:
if vol['mount'] == '/boot/efi':
targdev = vol['targetdisk']
partnum = re.search('(\d+)$', targdev).group(1)
targblock = re.search('(.*)\d+$', targdev).group(1)
if targblock:
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])
#other network interfaces
def had_swap():
with open('/etc/fstab') as tabfile:
tabs = tabfile.read().split('\n')
for tab in tabs:
tab = tab.split()
if len(tab) < 3:
continue
if tab[2] == 'swap':
return True
return False
def install_to_disk(imgpath):
lvmvols = {}
deftotsize = 0
mintotsize = 0
deflvmsize = 0
minlvmsize = 0
biggestsize = 0
biggestfs = None
plainvols = {}
allvols = []
swapsize = 0
if had_swap():
with open('/proc/meminfo') as meminfo:
swapsize = meminfo.read().split('\n')[0]
swapsize = int(swapsize.split()[1])
if swapsize < 2097152:
swapsize = swapsize * 2
elif swapsize > 8388608 and swapsize < 67108864:
swapsize = swapsize * 0.5
elif swapsize >= 67108864:
swapsize = 33554432
swapsize = int(swapsize * 1024)
deftotsize = swapsize
mintotsize = swapsize
for fs in get_image_metadata(imgpath):
allvols.append(fs)
deftotsize += fs['initsize']
mintotsize += fs['minsize']
if fs['initsize'] > biggestsize:
biggestfs = fs
biggestsize = fs['initsize']
if fs['device'].startswith('/dev/mapper'):
lvmvols[fs['device'].replace('/dev/mapper/', '')] = fs
deflvmsize += fs['initsize']
minlvmsize += fs['minsize']
else:
plainvols[int(re.search('(\d+)$', fs['device'])[0])] = fs
with open('/tmp/installdisk') as diskin:
instdisk = diskin.read()
instdisk = '/dev/' + instdisk
parted = PartedRunner(instdisk)
dinfo = parted.run('unit s print')
dinfo = dinfo.split('\n')
sectors = 0
sectorsize = 0
for inf in dinfo:
if inf.startswith('Disk {0}:'.format(instdisk)):
_, sectors = inf.split(': ')
sectors = int(sectors.replace('s', ''))
if inf.startswith('Sector size (logical/physical):'):
_, sectorsize = inf.split(':')
sectorsize = sectorsize.split('/')[0]
sectorsize = sectorsize.replace('B', '')
sectorsize = int(sectorsize)
# for now, only support resizing/growing the largest partition
minexcsize = deftotsize - biggestfs['initsize']
mintotsize = deftotsize - biggestfs['initsize'] + biggestfs['minsize']
minsectors = mintotsize // sectorsize
if sectors < (minsectors + 65536):
raise Exception('Disk too small to fit image')
biggestsectors = sectors - (minexcsize // sectorsize)
biggestsize = sectorsize * biggestsectors
parted.run('mklabel gpt')
curroffset = 2048
for volidx in sorted(plainvols):
vol = plainvols[volidx]
if vol is not biggestfs:
size = vol['initsize'] // sectorsize
else:
size = biggestsize // sectorsize
size += 2047 - (size % 2048)
end = curroffset + size
if end > sectors:
end = sectors
parted.run('mkpart primary {}s {}s'.format(curroffset, end))
vol['targetdisk'] = instdisk + '{0}'.format(volidx)
curroffset += size + 1
if not lvmvols:
if swapsize:
swapsize = swapsize // sectorsize
swapsize += 2047 - (size % 2048)
end = curroffset + swapsize
if end > sectors:
end = sectors
parted.run('mkpart swap {}s {}s'.format(curroffset, end))
subprocess.check_call(['mkswap', instdisk + '{}'.format(volidx + 1)])
else:
parted.run('mkpart lvm {}s 100%'.format(curroffset))
lvmpart = instdisk + '{}'.format(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')
vginfo = vginfo.split('\n')
pesize = 0
pes = 0
for infline in vginfo:
infline = infline.split()
if len(infline) >= 3 and infline[:2] == ['PE', 'Size']:
pesize = int(infline[2])
if len(infline) >= 5 and infline[:2] == ['Free', 'PE']:
pes = int(infline[4])
takeaway = swapsize // pesize
for volidx in lvmvols:
vol = lvmvols[volidx]
if vol is biggestfs:
continue
takeaway += vol['initsize'] // pesize
takeaway += 1
biggestextents = pes - takeaway
for volidx in lvmvols:
vol = lvmvols[volidx]
if vol is biggestfs:
extents = biggestextents
else:
extents = vol['initsize'] // pesize
extents += 1
if vol['mount'] == '/':
lvname = 'root'
else:
lvname = vol['mount'].replace('/', '_')
subprocess.check_call(['lvcreate', '-l', '{}'.format(extents), '-y', '-n', lvname, 'localstorage'])
vol['targetdisk'] = '/dev/localstorage/{}'.format(lvname)
if swapsize:
subprocess.check_call(['lvcreate', '-y', '-l', '{}'.format(swapsize // pesize), '-n', 'swap', 'localstorage'])
subprocess.check_call(['mkswap', '/dev/localstorage/swap'])
os.makedirs('/run/imginst/targ')
for vol in allvols:
with open(vol['targetdisk'], 'wb') as partition:
partition.write(b'\x00' * 1 * 1024 * 1024)
subprocess.check_call(['mkfs.{}'.format(vol['filesystem']), vol['targetdisk']])
subprocess.check_call(['mount', vol['targetdisk'], '/run/imginst/targ'])
source = vol['mount'].replace('/', '_')
source = '/run/imginst/sources/' + source
blankfsstat = os.statvfs('/run/imginst/targ')
blankused = (blankfsstat.f_blocks - blankfsstat.f_bfree) * blankfsstat.f_bsize
sys.stdout.write('\nWriting {0}: '.format(vol['mount']))
with subprocess.Popen(['cp', '-ax', source + '/.', '/run/imginst/targ']) as copier:
stillrunning = copier.poll()
lastprogress = 0.0
while stillrunning is None:
currfsstat = os.statvfs('/run/imginst/targ')
currused = (currfsstat.f_blocks - currfsstat.f_bfree) * currfsstat.f_bsize
currused -= blankused
with open('/proc/meminfo') as meminf:
for line in meminf.read().split('\n'):
if line.startswith('Dirty:'):
_, dirty, _ = line.split()
dirty = int(dirty) * 1024
progress = (currused - dirty) / vol['minsize']
if progress < lastprogress:
progress = lastprogress
if progress > 0.99:
progress = 0.99
lastprogress = progress
progress = progress * 100
sys.stdout.write('\x1b[1K\rWriting {0}: {1:3.2f}%'.format(vol['mount'], progress))
sys.stdout.flush()
time.sleep(0.5)
stillrunning = copier.poll()
if stillrunning != 0:
raise Exception("Error copying volume")
with subprocess.Popen(['sync']) as syncrun:
stillrunning = syncrun.poll()
while stillrunning is None:
with open('/proc/meminfo') as meminf:
for line in meminf.read().split('\n'):
if line.startswith('Dirty:'):
_, dirty, _ = line.split()
dirty = int(dirty) * 1024
progress = (vol['minsize'] - dirty) / vol['minsize']
if progress < lastprogress:
progress = lastprogress
if progress > 0.99:
progress = 0.99
lastprogress = progress
progress = progress * 100
sys.stdout.write('\x1b[1K\rWriting {0}: {1:3.2f}%'.format(vol['mount'], progress))
sys.stdout.flush()
time.sleep(0.5)
stillrunning = syncrun.poll()
sys.stdout.write('\x1b[1K\rDone writing {0}'.format(vol['mount']))
sys.stdout.write('\n')
sys.stdout.flush()
subprocess.check_call(['umount', '/run/imginst/targ'])
for vol in allvols:
subprocess.check_call(['mount', vol['targetdisk'], '/run/imginst/targ/' + vol['mount']])
fixup('/run/imginst/targ', allvols)
if __name__ == '__main__':
install_to_disk(os.environ['mountsrc'])
@@ -0,0 +1,126 @@
. /lib/dracut-lib.sh
mkdir -p /mnt/remoteimg /mnt/remote /mnt/overlay
if [ "untethered" = "$(getarg confluent_imagemethod)" ]; then
mount -t tmpfs untethered /mnt/remoteimg
curl https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs
else
confluent_urls="$confluent_urls https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs"
/opt/confluent/bin/urlmount $confluent_urls /mnt/remoteimg
fi
/opt/confluent/bin/confluent_imginfo /mnt/remoteimg/rootimg.sfs > /tmp/rootimg.info
loopdev=$(losetup -f)
export mountsrc=$loopdev
losetup -r $loopdev /mnt/remoteimg/rootimg.sfs
if grep '^Format: confluent_crypted' /tmp/rootimg.info > /dev/null; then
while ! curl -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" https://$confluent_mgr/confluent-api/self/profileprivate/pending/rootimg.key > /tmp/rootimg.key; do
echo "Unable to retrieve private key from $confluent_mgr (verify that confluent can access /var/lib/confluent/private/$confluent_profile/pending/rootimg.key)"
sleep 1
done
cipher=$(head -n 1 /tmp/rootimg.key)
key=$(tail -n 1 /tmp/rootimg.key)
len=$(wc -c /mnt/remoteimg/rootimg.sfs | awk '{print $1}')
len=$(((len-4096)/512))
dmsetup create cryptimg --table "0 $len crypt $cipher $key 0 $loopdev 8"
/opt/confluent/bin/confluent_imginfo /dev/mapper/cryptimg > /tmp/rootimg.info
mountsrc=/dev/mapper/cryptimg
fi
if grep '^Format: squashfs' /tmp/rootimg.info > /dev/null; then
mount -o ro $mountsrc /mnt/remote
elif grep '^Format: confluent_multisquash' /tmp/rootimg.info; then
tail -n +3 /tmp/rootimg.info | awk '{gsub("/", "_"); print "echo 0 " $4 " linear '$mountsrc' " $3 " | dmsetup create mproot" $7}' > /tmp/setupmount.sh
. /tmp/setupmount.sh
cat /tmp/setupmount.sh |awk '{printf "mount /dev/mapper/"$NF" "; sub("mproot", ""); gsub("_", "/"); print "/mnt/remote"$NF}' > /tmp/mountparts.sh
. /tmp/mountparts.sh
fi
#mount -t tmpfs overlay /mnt/overlay
modprobe zram
memtot=$(grep ^MemTotal: /proc/meminfo|awk '{print $2}')
memtot=$((memtot/2))$(grep ^MemTotal: /proc/meminfo | awk '{print $3'})
echo $memtot > /sys/block/zram0/disksize
mkfs.xfs /dev/zram0 > /dev/null
mount -o discard /dev/zram0 /mnt/overlay
if [ ! -f /tmp/mountparts.sh ]; then
mkdir -p /mnt/overlay/upper /mnt/overlay/work
mount -t overlay -o upperdir=/mnt/overlay/upper,workdir=/mnt/overlay/work,lowerdir=/mnt/remote disklessroot /sysroot
else
for srcmount in $(cat /tmp/mountparts.sh | awk '{print $3}'); do
mkdir -p /mnt/overlay${srcmount}/upper /mnt/overlay${srcmount}/work
mount -t overlay -o upperdir=/mnt/overlay${srcmount}/upper,workdir=/mnt/overlay${srcmount}/work,lowerdir=${srcmount} disklesspart /sysroot${srcmount#/mnt/remote}
done
fi
mkdir -p /sysroot/etc/ssh
mkdir -p /sysroot/etc/confluent
mkdir -p /sysroot/root/.ssh
cp /root/.ssh/* /sysroot/root/.ssh
chmod 700 /sysroot/root/.ssh
cp /etc/confluent/* /sysroot/etc/confluent/
cp /etc/ssh/*key* /sysroot/etc/ssh/
for pubkey in /etc/ssh/ssh_host*key.pub; do
certfile=${pubkey/.pub/-cert.pub}
privfile=${pubkey%.pub}
if [ -s $certfile ]; then
echo HostCertificate $certfile >> /sysroot/etc/ssh/sshd_config
fi
echo HostKey $privfile >> /sysroot/etc/ssh/sshd_config
done
mkdir -p /sysroot/dev /sysroot/sys /sysroot/proc /sysroot/run
if [ ! -z "$autocons" ]; then
autocons=${autocons%,*}
mkdir -p /run/systemd/generator/getty.target.wants
ln -s /usr/lib/systemd/system/serial-getty@.service /run/systemd/generator/getty.target.wants/serial-getty@${autocons}.service
fi
while [ ! -e /sysroot/sbin/init ]; do
echo "Failed to access root filesystem or it is missing /sbin/init"
echo "System should be accessible through ssh at port 2222 with the appropriate key"
while [ ! -e /sysroot/sbin/init ]; do
sleep 1
done
done
rootpassword=$(grep ^rootpassword: /etc/confluent/confluent.deploycfg)
rootpassword=${rootpassword#rootpassword: }
if [ "$rootpassword" = "null" ]; then
rootpassword=""
fi
if [ ! -z "$rootpassword" ]; then
sed -i "s@root:[^:]*:@root:$rootpassword:@" /sysroot/etc/shadow
fi
for i in /ssh/*.ca; do
echo '@cert-authority *' $(cat $i) >> /sysroot/etc/ssh/ssh_known_hosts
done
echo HostbasedAuthentication yes >> /sysroot/etc/ssh/sshd_config
echo HostbasedUsesNameFromPacketOnly yes >> /sysroot/etc/ssh/sshd_config
echo IgnoreRhosts no >> /sysroot/etc/ssh/sshd_config
sshconf=/sysroot/etc/ssh/ssh_config
if [ -d /sysroot/etc/ssh/ssh_config.d/ ]; then
sshconf=/sysroot/etc/ssh/ssh_config.d/01-confluent.conf
fi
echo 'Host *' >> $sshconf
echo ' HostbasedAuthentication yes' >> $sshconf
echo ' EnableSSHKeysign yes' >> $sshconf
echo ' HostbasedKeyTypes *ed25519*' >> $sshconf
curl -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" https://$confluent_mgr/confluent-api/self/nodelist > /sysroot/etc/ssh/shosts.equiv
cp /sysroot/etc/ssh/shosts.equiv /sysroot/root/.shosts
chmod 640 /sysroot/etc/ssh/*_key
chroot /sysroot chgrp ssh_keys /etc/ssh/*_key
cp /tls/*.pem /sysroot/etc/pki/ca-trust/source/anchors/
chroot /sysroot/ update-ca-trust
curl -sf https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/onboot.service > /sysroot/etc/systemd/system/onboot.service
mkdir -p /sysroot/opt/confluent/bin
curl -sf https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/onboot.sh > /sysroot/opt/confluent/bin/onboot.sh
chmod +x /sysroot/opt/confluent/bin/onboot.sh
cp /opt/confluent/bin/apiclient /sysroot/opt/confluent/bin
ln -s /etc/systemd/system/onboot.service /sysroot/etc/systemd/system/multi-user.target.wants/onboot.service
cp /etc/confluent/functions /sysroot/etc/confluent/functions
if grep installtodisk /proc/cmdline > /dev/null; then
. /etc/confluent/functions
run_remote installimage
exec reboot -f
fi
mv /lib/modules/$(uname -r) /lib/modules/$(uname -r)-ramfs
ln -s /sysroot/lib/modules/$(uname -r) /lib/modules/
exec /opt/confluent/bin/start_root

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