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

Compare commits

...

495 Commits

Author SHA1 Message Date
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 4b7d042f2d Have a clause for redfish not yet ready
We need redfish, but redfish is slow to boot on TSM..
2020-09-23 08:24:18 -04:00
Jarrod Johnson 99f533b4cb 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-23 08:24:07 -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
Jarrod Johnson 9828ea5898 Fix chained smm discovery on cumulus 2020-09-14 11:02:00 -04:00
Jarrod Johnson 7bdf7afb80 Fix another mistake in chained SMM discovery 2020-09-14 08:04:41 -04:00
Jarrod Johnson cd20a69eb6 Fix typo in function name in chained smm discovery 2020-09-14 08:03:18 -04:00
Jarrod Johnson c3d14977f2 Update attributes documentation 2020-09-11 09:56:35 -04:00
Jarrod Johnson 31d19e9398 Fix deployment.useinsecureprotocols
If explicitly set to 'never', it would behave as 'firmware'.
2020-09-11 09:44:09 -04:00
Jarrod Johnson ea533e64c6 Fix more issues found in configbmc 2020-09-09 13:01:01 -04:00
Jarrod Johnson 4fe84ca6dc Fix various issues in 3.0.0 release
If the kernel is new enough to do SKU, but the firmware doesn't have it,
fallback to model.

Fix outright mistakes in the config_port_tsm code

Up mac count from 2 to 3. If querying cumulus switches using SNMP
the switch will add its own mac to the list bringing the
total for a shared port to 3.
2020-09-09 10:58:37 -04:00
Jarrod Johnson 6f55a4ffe0 Python 3.7 fix for ipv6 lla handling
Python 3.7 changes behavior of recfrom (because.. why not apparently...)
Use getnameinfo to normalize the printable version.
2020-09-02 12:12:10 -04:00
Jarrod Johnson 5e01d9c97b Handle unresolvable switches gracecfully
Rather than a trace log,
keep it to only the event log.
2020-09-02 11:50:50 -04:00
Jarrod Johnson 46396247bb Fix remote passphrase authentication
For python 3 platforms, the
db hosted hash
needed the str changed
to bytes explictly.
2020-09-02 08:54:29 -04:00
Jarrod Johnson b9fffad1f8 Fix post.sh comment documentation 2020-08-28 17:08:36 -04:00
Jarrod Johnson 37f60ea647 fix wrap on osdeploy man page 2020-08-28 16:38:28 -04:00
Jarrod Johnson a72ff7a0b0 Add osdeploy man page. 2020-08-28 12:52:42 -04:00
Jarrod Johnson c955b714a5 Add a nodedeploy man page 2020-08-28 12:48:05 -04:00
Jarrod Johnson a737ee7622 Correct incorrect quotes 2020-08-28 10:45:54 -04:00
Jarrod Johnson 971187b006 Handle 'unknown' health
Sometimes health may be 'unknown' and warrants more investigation.
2020-08-28 10:21:02 -04:00
Jarrod Johnson 616d0bd23e Amend language of attribute help 2020-08-28 09:49:25 -04:00
Jarrod Johnson b8ffdfbf74 Add more text to deployment.encryptboot 2020-08-28 09:45:55 -04:00
Jarrod Johnson f6c144ae16 Amend to work more cleanly installed after xCAT
xCAT intervenes on tftp a lot, so we need to stay away
and clearly indicate that we are.
2020-08-28 09:43:21 -04:00
Jarrod Johnson 6ab57b8669 Add a friendlier message if tftp service is running
The socket activation may fail due to tftp already running.
2020-08-28 09:38:10 -04:00
Jarrod Johnson ffe0144b2c Amend osdeploy missing tftp warning 2020-08-28 09:19:38 -04:00
Jarrod Johnson 2aa2402b73 Change to emprint from raise
The exception stack trace is offputting.
2020-08-28 07:18:07 -04:00
Jarrod Johnson 49eccaf68b Fix behavior on existing directory 2020-08-27 17:06:10 -04:00
Jarrod Johnson e8eaddf375 Fix for HTTP API browser
Python 3 had data coming in as bytes.
2020-08-27 13:11:21 -04:00
Jarrod Johnson bf1019c497 Have -p by itself not generate new site cpio
It is not needed for just -p
2020-08-27 11:43:55 -04:00
Jarrod Johnson aaff8d281c Add warning if someone tries to -n without a profile name. 2020-08-26 16:10:59 -04:00
Jarrod Johnson 24a3cbc133 Fix non-collective quorum check 2020-08-26 13:54:18 -04:00
Jarrod Johnson 46fc4d626d Fix quorum check in configmanager.py 2020-08-26 13:35:19 -04:00
Jarrod Johnson b12a5f6ec6 Fix osdeploy local on older system
Also add short name to principals if user has used FQDN as their name.
2020-08-26 13:04:12 -04:00
Jarrod Johnson c3403f339e Per request, change -p
The request was for -p to modify -n behavior rather than replace it. New
syntax always needs -n to
do deploymennt, with -p opting out of BMC interaction.
2020-08-26 12:04:00 -04:00
Jarrod Johnson 463584f301 Warn that -n and -p are exclusive 2020-08-26 11:05:27 -04:00
Jarrod Johnson 4348d9160b Provide ability for config file to specify cipher list
The default set of TLS 1.3 and TLS1.2 restricted ciphers are
generally considered strong today, but for future or special
circumstances, provide ability to override the defaults.
2020-08-26 09:43:55 -04:00
Jarrod Johnson 53f317fc09 Enhance nodedeploy status text 2020-08-25 16:01:50 -04:00
Jarrod Johnson 4b75f958ff Add function of nodedeploy to query current profile. 2020-08-25 15:47:44 -04:00
Jarrod Johnson 264b0be853 Use correct argument parsing 2020-08-25 14:29:23 -04:00
Jarrod Johnson ff0955d6be Final fix for nodedeploy without profile 2020-08-25 14:28:14 -04:00
Jarrod Johnson 14767e2909 Fix nodedeploy -c 2020-08-25 14:05:43 -04:00
Jarrod Johnson f5f7643734 Change -c to a store_true 2020-08-25 09:58:58 -04:00
Jarrod Johnson 3256899acf Add a nodedeploy clear
This will allow a pendingprofile to be cleared.
2020-08-24 16:05:58 -04:00
Jarrod Johnson e52556affb Fix certificate watch hang
If no certificate present, then once a day confluent could hang. Fix by
doing a non-blocking
read on the watcher.
2020-08-24 14:00:47 -04:00
Jarrod Johnson 59e739a143 Further tweaks to postscript library functions 2020-08-21 17:42:02 -04:00
Jarrod Johnson 2e2a34b470 Reduce curl verbosity
Hard to follow with so much extra output
2020-08-21 17:07:02 -04:00
Jarrod Johnson b8aa54fb8e Make output consistent for shell/python remote exec 2020-08-21 17:03:12 -04:00
Jarrod Johnson 67920980c8 Fix syntax error in functions library for pre/post/firstboot scripts 2020-08-21 16:39:37 -04:00
Jarrod Johnson d6158c9061 Add support for a future SMM to discovery 2020-08-21 16:09:05 -04:00
Jarrod Johnson e9dabdf51b Add clearer delineation between scripts in output 2020-08-21 10:35:28 -04:00
Jarrod Johnson 18f4c76730 Fix end code for run_remote
Output was missing due to shift. Save cmdline before
shifting and use it on way out.
2020-08-21 10:33:56 -04:00
Jarrod Johnson 13636097f5 Add more verbosity to remote functions 2020-08-20 16:20:02 -04:00
Jarrod Johnson 814857a706 Update client side aliases to match configmanager 2020-08-20 10:53:21 -04:00
Jarrod Johnson 5b0389000e Fix handling of password through TLS socket 2020-08-20 08:28:06 -04:00
Jarrod Johnson 77adcde52f Change version of confluent genesis. 2020-08-19 13:19:27 -04:00
Jarrod Johnson 22171828a7 Add nvme to genesis 2020-08-19 13:08:10 -04:00
Jarrod Johnson b847aacfc0 Add more documentation to deployment.apiarmed
Since nodedeploy is expected to be used to make
it less annoying, mention the expectation of nodedeploy
in its documentation.
2020-08-19 10:30:23 -04:00
Jarrod Johnson 1eb4b0f682 Copy all of scripts for genesis init 2020-08-18 17:25:15 -04:00
Jarrod Johnson 6c2cde7924 Give up on linking configbmc, just copy it for now 2020-08-18 15:53:04 -04:00
Jarrod Johnson 46ca9115a0 Fix configbmc in genesis 2020-08-18 15:43:23 -04:00
Jarrod Johnson 97b8beee76 Expound upon crypted.rootpassword documentation 2020-08-18 15:01:59 -04:00
Jarrod Johnson d956893104 Have EL8 ifup wait for tentative to go away 2020-08-17 15:06:38 -04:00
Jarrod Johnson 5bdd59bc67 Add configbmc to el8 and genesis script examples 2020-08-17 14:23:21 -04:00
Jarrod Johnson 584f6dc458 Handle no-argument invocation
apiclient is used to process confluent.info
2020-08-17 13:40:00 -04:00
Jarrod Johnson 53363905dd Add ability to call apiclient to configbmc
Next to put it into various profiles
and genesis.
2020-08-17 12:33:13 -04:00
Jarrod Johnson 1e445ad526 Have configbmc actually consume bmcconfig data
/usr/libexec/platform-python /opt/confluent/bin/apiclient /confluent-api/self/bmcconfig -j > /tmp/whatever.json
/usr/libexec/platform-python configbmc.py -i /tmp/whatever.json
2020-08-14 17:42:49 -04:00
Jarrod Johnson a126270570 Fix scope of hm attributes in bmcconfig 2020-08-14 16:05:46 -04:00
Jarrod Johnson dd4d7ded74 Fix syntax error in attributes.py 2020-08-14 15:48:52 -04:00
Jarrod Johnson 997b43045a Make preparations for a configbmc for inband config 2020-08-14 15:29:55 -04:00
Jarrod Johnson 1e59a710e7 Add json to genesis python 2020-08-14 14:55:22 -04:00
Jarrod Johnson e6b134419b Add argparse to genesis 2020-08-14 10:09:02 -04:00
Jarrod Johnson ece6903a04 Add fcntl to genesis python 2020-08-14 08:26:00 -04:00
Jarrod Johnson ec42a2aad8 Fix confluentdbrestore in non-root environments 2020-08-14 07:16:04 -04:00
Jarrod Johnson aab27ccc4b Fix typo in osdeploy code 2020-08-13 15:29:45 -04:00
Jarrod Johnson 5e33e45dbd Notes on a strategy to retrieve the appropriate src.rpms 2020-08-13 07:55:28 -04:00
Jarrod Johnson d0b0306eb2 Add floppy to man page synopsis for nodesetboot 2020-08-12 11:15:34 -04:00
Jarrod Johnson 64945662ac Add local CA to curl trust in genesis 2020-08-12 09:43:29 -04:00
Jarrod Johnson c02a482601 Add serial hint to console=ttyS users 2020-08-12 09:35:24 -04:00
Jarrod Johnson 823c9656ac Fix target path of osdeploy initialize -g 2020-08-12 09:26:04 -04:00
Jarrod Johnson d4b21ed5b9 Be sure to updateboot on g
If not generating a new site
archive, generate a new boot.img anyway for genesis.
2020-08-12 09:12:29 -04:00
Jarrod Johnson 6bbbf92613 Add genesis initialize to osdeploy 2020-08-12 08:59:25 -04:00
Jarrod Johnson 866cd85bd0 Add a profile description to genesis 2020-08-12 07:51:38 -04:00
Jarrod Johnson d88e33677e Fix typo in confluent in rungenesis 2020-08-11 18:40:57 -04:00
Jarrod Johnson 43ce1b17a7 Rework genesis with more output and an onboot.sh 2020-08-11 18:11:48 -04:00
Jarrod Johnson 1ceb588ad4 Just wait for ssh-keygen, just in case 2020-08-11 17:09:31 -04:00
Jarrod Johnson e2ff9163bc Remove the wait for ssh-keygen
By this point, it should be done and we accidentally wait on wrong
thing.
2020-08-11 17:08:00 -04:00
Jarrod Johnson 060d8093e6 Fix sshd_config generation 2020-08-11 16:51:42 -04:00
Jarrod Johnson 679f2cbf1c Extend timeout waiting for 'right' device
Some devices come up very slowly.
2020-08-11 16:29:30 -04:00
Jarrod Johnson 4cd7714099 Modify apiclient to rewrite ifidx if stale 2020-08-11 15:41:44 -04:00
Jarrod Johnson 32fe6b2fff Fix 'matchesnodename' behavior if ip manually specified 2020-08-11 15:34:55 -04:00
Jarrod Johnson bae4e448d9 Load umad driver 2020-08-11 15:19:09 -04:00
Jarrod Johnson 9d55d413fd Do not put fabric managers into genesis
It's getting too crowded...
2020-08-11 15:03:51 -04:00
Jarrod Johnson 3dd7611dc2 Try to enable high speed fabrics during genesis start 2020-08-11 15:00:41 -04:00
Jarrod Johnson 9291037e87 Add libibverbs dependencies 2020-08-11 14:51:11 -04:00
Jarrod Johnson 4404a1bed2 Put in more infiniband stack pieces 2020-08-11 14:44:58 -04:00
Jarrod Johnson 74e85289ac Add ib diag utilities 2020-08-11 14:28:05 -04:00
Jarrod Johnson 95f9854630 Fix missing data for apiclient 2020-08-11 13:40:55 -04:00
Jarrod Johnson f6343a1aa6 Fix the static ip configuration in genesis 2020-08-11 13:37:16 -04:00
Jarrod Johnson db8047318e Add missing dependencies for socket getaddrinfo 2020-08-11 13:23:31 -04:00
Jarrod Johnson 8b1193a6ff Setup authorized_keys in a useful way 2020-08-11 12:24:01 -04:00
Jarrod Johnson 8277679be4 Add spec file to git tracking 2020-08-11 12:11:48 -04:00
Jarrod Johnson 2132ae7003 Fixes for issues in genesis addons 2020-08-11 12:08:02 -04:00
Jarrod Johnson 9c758dafbf Add mlx5 drivers to genesis 2020-08-11 12:07:49 -04:00
Jarrod Johnson f8f1350403 Add ascii codec
A python without ascii could be of limited use
2020-08-11 12:06:28 -04:00
Jarrod Johnson 0960a23765 Change location of rungenesis
The bin as a directory conflicts with
bin as a symlink, keep to opt to avoid the whole mess
2020-08-11 11:17:46 -04:00
Jarrod Johnson 6aaeb9b910 Have a genesis profile to latch onto 2020-08-11 10:14:34 -04:00
Jarrod Johnson 644433fa5d Refactor genesis to have addons.cpio
This makes an easier division between pure CentOS
contributions and 'genesis-scripts' type output.
Do so in a manner consistent with how 'real'
operating systems get this added.
2020-08-11 09:54:53 -04:00
Jarrod Johnson 31dcea46af Fix permissions on dracut installkernel script 2020-08-10 14:49:30 -04:00
Jarrod Johnson 7fc2786ba5 Add TPM2 support to confluent genesis 2020-08-10 11:39:03 -04:00
Jarrod Johnson bd7d0ba42c Add updateboot to osdeploy command 2020-08-07 14:12:13 -04:00
Jarrod Johnson 468f9758e5 Fix update boot
update boot would leave
leftover content, truncate to
get rid of it.
2020-08-07 13:45:10 -04:00
Jarrod Johnson 022ba77298 Fix dhcp configuration
dhcp method was not accurately fed into os deployment
2020-08-07 11:42:13 -04:00
Jarrod Johnson 1d6a5fc329 Have add_local_repositories by python2/3 agnostic
RHEL7 is still python2
2020-08-07 09:55:37 -04:00
Jarrod Johnson d08ca5a114 Add local repositories to EL7 installs 2020-08-07 08:29:20 -04:00
Jarrod Johnson d12272eccc Support current directory in repo path 2020-08-07 08:26:42 -04:00
Jarrod Johnson 86c0d79d73 Fix RHEL 7 support
It was not correctly fingerprinting RHEL 7.
2020-08-06 20:40:31 -04:00
Jarrod Johnson 8aabdcc454 Fix name of rpm gpg keys 2020-08-06 19:32:47 -04:00
Jarrod Johnson 9c079a4203 Generate ifidx file
Use apiclient to generate ifidx for nmcli c u
2020-08-06 18:56:23 -04:00
Jarrod Johnson f55dc8104b Bring up the nic correctly during pre
nmcli can bring up the link with proper lla like confluent.info
indicates.
2020-08-06 18:15:27 -04:00
Jarrod Johnson 3812fc93ff Have EL8 family add repositories manually 2020-08-06 16:37:18 -04:00
Jarrod Johnson 972dc9780c Fix creation of distinfo.yaml 2020-08-06 09:07:41 -04:00
Jarrod Johnson 1d436d68ee Fix initprofile
initprofile was not being pointed to the specific
directory, which is required
for multi-disk sets like
older SUSE.
2020-08-06 08:43:11 -04:00
Jarrod Johnson 8d48fc3273 Fix osdeploy initialize in no-domain environment
If no domain is defined, then do not try to append
2020-08-05 16:31:08 -04:00
Jarrod Johnson 0a3936164e Fix role management for users and groups 2020-08-05 15:02:30 -04:00
Jarrod Johnson a9497b16e8 Fix handling of unset crypted attributes 2020-08-05 14:17:58 -04:00
Jarrod Johnson c8cda426be Fix crossed wires between user and usergroup
The requests were not being routed correctly
2020-08-05 12:57:35 -04:00
Jarrod Johnson 2b963ce854 Address typo in RHVH 4.3 support
This prevented 4.3 from deploying
2020-08-05 12:35:16 -04:00
Jarrod Johnson ae7ce2033b Handle more differences between 4.3 and 4.4 2020-08-05 12:14:29 -04:00
Jarrod Johnson aed96a2711 Add RHV4.4 support to RHV4
Again, we need to handle the drastic differences
in python between *minor* versions of RHVH
2020-08-05 09:45:38 -04:00
Jarrod Johnson b796d19a4c Add ifidx to bash path
The shell based apiclient alternative should write ifidx
as well.
2020-08-05 09:21:16 -04:00
Jarrod Johnson 55a6e3a1e2 Support RHV 4.4
Unfortunately, RHV considers rebasing from RHEL7 to RHEL8
to be a 'minor' change. So we have to have a sloppily
complicated iniqueue to serve either RHEL7 or RHEL8.
2020-08-05 09:15:02 -04:00
Jarrod Johnson bf706f82cf Fix a typo in httpapi 2020-08-05 08:28:30 -04:00
Jarrod Johnson b2731325f6 Refactor image copy
Break up image import into three phases, for breaking out the separate
phases to indpendent commands.
2020-08-04 13:09:34 -04:00
Jarrod Johnson 2e8d002876 Preserve distribution fingerprint
Useful for breaking out the
profile copy over stage.
2020-08-03 14:21:30 -04:00
Jarrod Johnson 8fca5d23c0 Correct scope of ipmethod
ipmethod was trying to be set outside the useful scope.
2020-08-03 12:01:40 -04:00
Jarrod Johnson 704e8379f0 Have firmwaredhcp become static to OS 2020-08-03 11:43:22 -04:00
Jarrod Johnson 585988b22a Add firmwaredhcp method
In a case where static is
desired for the OS, but
PXE or HTTP boot will
receive an IP address from
a DHCP server, offer firmwaredhcp.

This tells confluent to refrain from offering an IP during firmware, but still telling the OS to use static.
2020-08-03 11:42:27 -04:00
Jarrod Johnson c7b8d05930 Fik initialize -k without other actions 2020-08-03 11:06:45 -04:00
Jarrod Johnson 0758611481 Add '-l' to interactive initialize 2020-08-03 09:34:18 -04:00
Jarrod Johnson 755e97ca9a Fix SELinux context on local init
Files generated during osdeploy -l need to have correct context.
2020-07-30 15:41:27 -04:00
Jarrod Johnson 2ade557b3e Amend local osdeploy initialize behavior
Do not bother the site cpio and correctly avoid duplicate config lines.
2020-07-30 15:20:53 -04:00
Jarrod Johnson ac19f093fd Fixes to the previous draaft 2020-07-30 15:03:36 -04:00
Jarrod Johnson 2f4f9a39a6 Add osdeploy function to trust nodes
osdeploy initialize -l will
endeavor to do to the local
management node the same thing the deployment does to the nodes.
2020-07-30 14:44:02 -04:00
Jarrod Johnson d204eedb76 Have osdeploy -p enable tftp
This makes the procedure shorter.
2020-07-30 13:57:42 -04:00
Jarrod Johnson fa934ce334 Fix insertion of manager
The manager insertion failed
with the domain from nodes removed.
2020-07-29 13:52:28 -04:00
Jarrod Johnson dd91213969 Fix mistakes in the hostname support 2020-07-29 13:39:48 -04:00
Jarrod Johnson e93c3241ed Provide for more hostnames
This permits ssh infrastructure
to have multihomed nodes
handled more effeectively.
2020-07-29 13:08:03 -04:00
Jarrod Johnson b4d7812926 Add some likely customizations examples
RedHat family is likely to be customized with firewall and selinux,
use those as examples to get things going for users.
2020-07-29 12:19:44 -04:00
Jarrod Johnson c75a433ff8 Reduce trace activity around common connectivity issue
If the target has a resolution or other common socket issues,
do not make large trace logs.
2020-07-29 08:49:42 -04:00
Jarrod Johnson 56a6f24350 Merge branch '2.5' 2020-07-28 11:16:54 -04:00
Jarrod Johnson 908c566b73 Allow deletion of blank volume names 2020-07-28 11:16:38 -04:00
Jarrod Johnson 99f9e852da Allow deletion of blank volume names 2020-07-28 11:15:48 -04:00
Jarrod Johnson 6ab176218e Add '..' to range operators
The perl-style range operator exists in some tools, we
might as well support that alongside the usual '-'
operator and ':' python style operator.
2020-07-28 08:08:35 -04:00
Jarrod Johnson 8225a2297e Add '..' to range operators
The perl-style range operator exists in some tools, we
might as well support that alongside the usual '-'
operator and ':' python style operator.
2020-07-27 11:54:24 -04:00
Jarrod Johnson b09631fcbf Correct mistake in chcon path 2020-07-24 16:07:15 -04:00
Jarrod Johnson eb7791b884 Add missing example custom files 2020-07-24 16:00:16 -04:00
Jarrod Johnson cbc25c17c4 Revise customization across RH family 2020-07-24 15:45:19 -04:00
Jarrod Johnson 235c07063c Adjust SELinux context on remote exec
To facilitate firstboot, context must be changed
before execing remote content.
2020-07-24 15:32:13 -04:00
Jarrod Johnson 9304b41a12 Generic tab completion after generic noderange
Commands that go further than the noderange should
switch to generic completion for lack of a better
idea.
2020-07-24 14:35:54 -04:00
Jarrod Johnson d2f1ea6cec Tweak the customizations. 2020-07-24 11:10:01 -04:00
Jarrod Johnson d7c219f2a8 Add a new strategy for custom content
This allows a profile to more easily isolate customizations
from the base profile
2020-07-24 10:59:15 -04:00
Jarrod Johnson eabb212e58 Fix setupssh.sh without ssh_config.d
It was modifying the installer ssh_config
rather than the target ssh_config
2020-07-24 08:12:53 -04:00
Jarrod Johnson 33dd5e8315 Remove redundant call to nodectl 2020-07-23 15:10:30 -04:00
Jarrod Johnson 02ba6df421 Do not try to sign unsupported key 2020-07-23 14:41:59 -04:00
Jarrod Johnson e28f6b87fc Fix RHVH apikey location 2020-07-23 14:39:17 -04:00
Jarrod Johnson bbab1cb949 Adjust EL7 package list
Packages in EL8 do not apply to EL7
2020-07-23 13:05:24 -04:00
Jarrod Johnson 232e6c34c5 Add el7 to build 2020-07-23 12:42:34 -04:00
Jarrod Johnson ac622d84b2 Add EL7 support 2020-07-23 12:29:43 -04:00
Jarrod Johnson c81daba66f Merge branch '2.5' 2020-07-22 15:12:52 -04:00
Jarrod Johnson 2483f07c89 Add tar dependency for osdeploy 2020-07-22 15:11:58 -04:00
Jarrod Johnson 5f1ba49a12 Fix behavior with unspecified domain name
Ensure string is only checked if it is a string.
2020-07-22 13:56:55 -04:00
Jarrod Johnson 92018c725f Fix ssdp python3 issue
Attempt to use str to split bytes.
2020-07-17 13:58:00 -04:00
Jarrod Johnson fd46bae24f Fix for removing groups providing multiple values
I don't know how this was missed for so long,
but removing a group providing multiple values would produce an error and fail.
2020-07-17 11:48:49 -04:00
Jarrod Johnson 9f429f5af9 Adapt EL8 change to RHVH 2020-07-16 15:23:45 -04:00
Jarrod Johnson ded4762baf Go to internalizing driver disk load
Trying to let the dd happen naturally was evidently a mistake,
load the drivers manually.
2020-07-16 15:09:24 -04:00
Jarrod Johnson de7b83cbb4 Correct the spec file
It incorrectly omitted correct license.
2020-07-16 08:25:15 -04:00
Jarrod Johnson 767e65455f Apply reset of cmdline to RHVH 2020-07-15 17:24:19 -04:00
Jarrod Johnson 9661d4d6fb Clear cmdline between runs 2020-07-15 17:13:07 -04:00
Jarrod Johnson 8fc475a678 Fix mistakes in the initqueue hooks
Syntax errors were present.
2020-07-15 15:55:29 -04:00
Jarrod Johnson 99cb4748a7 Also amend the RHVH4 dracut hook
In addition to RHEL8, also have RHVH4 have the workaround.
2020-07-15 15:29:30 -04:00
Jarrod Johnson d49f018981 Correct functions in profiles
Use functions correectly.
2020-07-15 15:22:27 -04:00
Jarrod Johnson 6dadac498f Try another strategy for confluent initqueue
We want to have each iteration try not much.

But we also want to have a 'good' (primary network) match
supersede a less successful guess.

But we also want to keep guessing.

So the first 'vague' guess gets to run full hook.

If a future good guess happens, rerun the hook to update the data.
2020-07-15 15:20:17 -04:00
Jarrod Johnson ac308fbd9c Fix python3 issues in ssdp code
In the ssdp code, there were python3 specific issues.
2020-07-15 13:06:54 -04:00
Jarrod Johnson d792822f4b Go back to copy
tftp tends to chroot itself, making symlinks out of
the tftp data directory infeasible.
2020-07-15 12:53:41 -04:00
Jarrod Johnson dfc289b154 Allow osdeploy initialize -p by itself
It seems a rational thing to do.
2020-07-15 11:12:27 -04:00
Jarrod Johnson 77cfa7b45c Revise tftp initialization
For one, if the xCAT /tftpboot is present, roll with that.

For another, use a symlink to /opt instead of copy, to make upgrades
easier.
2020-07-15 10:59:30 -04:00
Jarrod Johnson 5ccfa36da6 Fix ssh disconnect handling in python 3
In python 3, '' will never match b''. Just
use the value as a boolean to catch either ''
or b''.
2020-07-15 10:34:23 -04:00
Jarrod Johnson 81835d66be Fix ssh disconnect handling in python 3
In python 3, '' will never match b''. Just
use the value as a boolean to catch either ''
or b''.
2020-07-15 10:33:28 -04:00
Jarrod Johnson 3b121cdb4b Have initqueue hook give up faster
Since the hook itself will get retried, we can be more aggressive
in giving up in each individual attempt.
2020-07-15 08:45:41 -04:00
Jarrod Johnson fba82f9379 Change el8 addons to retry confluent handler
If DD is in play, drivers may appear later, and
we have to wait for them in a future invocation.
2020-07-14 16:43:37 -04:00
Jarrod Johnson dad68bdf63 Conditionally include clevis-dracut
If not using LUKS, don't bother with clevis-dracut.

In 8.1, clevis-dracut will cause problems with network
in initrd time.
2020-07-14 14:40:05 -04:00
Jarrod Johnson 5b1e144d32 Fix python3 problem with backspace
In python3, a single element reference of a bytes
is an int, not equal to a b'' of the same length and
value. Change to use slices to have python2 and python3
act the same.
2020-07-14 09:13:37 -04:00
Jarrod Johnson 74af077651 Fix python3 problem with backspace
In python3, a single element reference of a bytes
is an int, not equal to a b'' of the same length and
value. Change to use slices to have python2 and python3
act the same.
2020-07-14 09:03:38 -04:00
Jarrod Johnson 910490cc74 Add arguments to the run_remote functions
This will help provide flexibility in invoking remote scripts
without hardcoding arguments into the scripts
2020-07-13 17:08:38 -04:00
Jarrod Johnson 2ec0c1366e Fix a couple of genesis issues 2020-07-10 10:06:35 -04:00
Jarrod Johnson 7f044c45de Revert "Have osdeploy require apache/ssl and provide config"
This reverts commit ea6155b2a1.

This rpm is built under centos7 for maximum C compatibility
of the addon utility. For now move the dependency back
to lenovo-confluent
2020-07-10 09:27:38 -04:00
Jarrod Johnson 1d596736f3 Tolerate : without a space
E.g. grep does not space delimit.
2020-07-10 08:53:57 -04:00
Jarrod Johnson 4a23ca3db1 Have blank values end with :
This is a bit more obvious for grep.
2020-07-10 08:28:28 -04:00
Jarrod Johnson b112cb0f16 Have unset and blank values look similar
This looks weird in collate otherwise
2020-07-09 17:00:44 -04:00
Jarrod Johnson eb8144214f Add NTP to RHVH profile 2020-07-09 16:02:53 -04:00
Jarrod Johnson 64f57dceaf Fix ubuntu NTP configuration 2020-07-09 15:51:19 -04:00
Jarrod Johnson 5051ab4bf5 Add NTP support to ubuntu profile 2020-07-09 15:21:48 -04:00
Jarrod Johnson 439859e4fc Implement suse ntp and correct redhat ntp 2020-07-09 15:05:20 -04:00
Jarrod Johnson b42e447e34 Fix NTPCFG replacement in suse pre.sh 2020-07-09 14:13:46 -04:00
Jarrod Johnson d2c999b01c Add NTP to suse15 profile 2020-07-09 13:37:50 -04:00
Jarrod Johnson 50661b7dee Fix multiple ntp servers in EL8 profile 2020-07-09 13:30:13 -04:00
Jarrod Johnson ea6155b2a1 Have osdeploy require apache/ssl and provide config
Have osdeploy pull in requirements itself
2020-07-09 13:18:42 -04:00
Jarrod Johnson f8affe99db Add ntp to EL8 profile prescript 2020-07-09 12:11:32 -04:00
Jarrod Johnson ca9655cd5e Cover the more common use case
With confluent running as non-root, it is now very much more
likely that it is a directory permission issue.

Since the root user is commonly asking a lesser privileged service to do the operation.
2020-07-09 11:46:06 -04:00
Jarrod Johnson 2bfbfeb4d3 Add ntp to deploycfg data 2020-07-09 11:35:11 -04:00
Jarrod Johnson 771c3a2984 Rework error message to look nicer 2020-07-09 11:12:00 -04:00
Jarrod Johnson 55ee203974 Improve error handling in pxe
If a name resolution error happens,
put an event in events for the
cleaner error.
2020-07-09 10:56:09 -04:00
Jarrod Johnson d5ff9b4cb5 Add missing traceback import to pxe
This concludes fixing the
susceptability to total
loss of pxe thread.
2020-07-09 10:44:05 -04:00
Jarrod Johnson 48804ed23f Initialize needed tracelog
pxe was trying to use tracelog
without actually initializing it
2020-07-09 10:25:28 -04:00
Jarrod Johnson d80a58304c Fix incorrect indentation
The exception was incorrectly
over indented.
2020-07-09 10:10:20 -04:00
Jarrod Johnson 994c53191c Improve resience of snoop threads
slp could crash in active_scan,
removing it's ability to passively scan.

pxe snoop could crash and go away persistently.
2020-07-09 09:53:25 -04:00
Jarrod Johnson 68c4652662 Fix per-collective globals
set_global is explicitly not
collective enabled, however
collective was causing partial
propagation.

Fix by removing the global carry over and having
commit_clear restore the non-key globals.
2020-07-09 09:10:24 -04:00
Jarrod Johnson 2c151caae7 Add a sample script for making uefi netboot entries
This may be handy for manually configuring uefi network
boot entries locally
2020-07-08 16:01:27 -04:00
Jarrod Johnson c9e1ecb616 Fix use of touch when touch is not present 2020-07-02 16:34:50 -04:00
Jarrod Johnson 4ecae144d9 Attempt to have both short and long names
In ssh, long or short name may matter and user may use short
or long names as node names.

Try to make ssh equipped to be apathetic about the choice.
2020-07-02 12:40:30 -04:00
Jarrod Johnson f70a3daf9a Clear both appropriate profile attributes
When setting a pending profile. clear any staged or established profile.
2020-07-01 15:39:12 -04:00
Jarrod Johnson fa6d42b1b3 Clear stagedprofile
staged profile should be cleared on completion.
2020-07-01 15:35:17 -04:00
Jarrod Johnson 2c30d4069c Correct syntax error in selfservice 2020-07-01 15:20:06 -04:00
Jarrod Johnson 2481759d44 Correct syntax error in nodedeploy 2020-07-01 15:16:39 -04:00
Jarrod Johnson f157ab1ef3 Use the 'staged' profile in some linux
The staged was added to control netboot mostly,
and is mostly optional but change some default
profiles to use it.
2020-07-01 14:20:40 -04:00
Jarrod Johnson 78e5d343e7 Implement a 'staged' phase of profile
This allows a limbo where remote deployment is blocked
but final deployment is not yet flagged.
2020-07-01 14:01:28 -04:00
Jarrod Johnson 22085e38f5 Change bound to 'tpm2'.
This is a bit more logical and flexible for the future.
2020-07-01 13:33:59 -04:00
Jarrod Johnson 8976ed9625 chmod is not available in rhvh initramfs 2020-07-01 12:26:02 -04:00
Jarrod Johnson c28578caf7 Fix variable name in RHV-H initramfs 2020-07-01 12:12:54 -04:00
Jarrod Johnson 649299fa82 Fix SUSE prechroot script 2020-07-01 11:38:33 -04:00
Jarrod Johnson 9d806010c8 Further fix issues with RHV-H deployment 2020-07-01 11:36:25 -04:00
Jarrod Johnson 004e609635 Fix apikey strip for python2
Strip after any conversions, whether it is bytes or str.
2020-07-01 11:29:31 -04:00
Jarrod Johnson 85241a488a Fix up RHVH support 2020-07-01 11:13:14 -04:00
Jarrod Johnson 3fdcecb8c6 Suppress spurious error output
Have the process start cleaner in EL8 deployments
2020-07-01 10:43:24 -04:00
Jarrod Johnson b372a15c33 Strip newline after decode
strip on bytes in python3 does not remove newlines.
Call after decode to have strip handle the newline.
2020-07-01 10:32:11 -04:00
Jarrod Johnson dfa636ac4c Coerce binary to text
In subprocess, since we get binary, need to
coerce to text.
2020-07-01 10:15:35 -04:00
Jarrod Johnson e863edfe3f Correct a number of mistakes 2020-07-01 09:52:17 -04:00
Jarrod Johnson 159d01b690 Update client for floppy
Update documentation and tab completion.
2020-07-01 09:00:33 -04:00
Jarrod Johnson b407fef988 Normalize path to confluent files
After going through tmp and etc, settle on /etc/confluent/
as the generally relevant directory when possible.

Additionally, move apikey and ifidx logic into apiclient where
possible
2020-07-01 08:57:08 -04:00
Jarrod Johnson 4cf34056e4 Correct mistakes in previous commit 2020-06-30 19:34:13 -04:00
Jarrod Johnson 32ba37a858 Extract default nic to the index in el8 2020-06-30 19:30:09 -04:00
Jarrod Johnson 0c3888441d Add the check for primary nic to suse 2020-06-30 18:48:10 -04:00
Jarrod Johnson 27a2a58ea1 Try more aggressively to get to 'default' network.
If a 'default' network is going to eventually link up,
wait for it.
2020-06-30 18:39:29 -04:00
Jarrod Johnson 8f9e4ea205 Build confluent CA cert for EL8 2020-06-30 17:02:21 -04:00
Jarrod Johnson 94f2b618bd Also copy api key to usable location. 2020-06-30 16:59:52 -04:00
Jarrod Johnson 8d3374b1e7 Move confluent.info to correct location 2020-06-30 16:55:01 -04:00
Jarrod Johnson 1e6f5c6da2 Update Ubuntu with the extendined info changes 2020-06-30 16:15:01 -04:00
Jarrod Johnson ea54007806 Have SuSE use extended info
SuSE does not have python this early, so use
shell utilities instead.
2020-06-30 16:00:47 -04:00
Jarrod Johnson 2f4dd240dd Change EL8 initramfs to use apiclient
This is a richer client that provides
the extended information required
for more accurate network autodetect.
2020-06-30 15:02:10 -04:00
Jarrod Johnson 1a664f669c Use client provided hint for net selection
More precise then trying to do by IP subnet
2020-06-30 14:58:04 -04:00
Jarrod Johnson 8ab9c14d45 Do not surpress if scope index is distinct
This allows vetting multiple peers when vlan tagging
is used with LLA.
2020-06-30 14:18:54 -04:00
Jarrod Johnson 03008f76e5 Remove stale copy of apiclient 2020-06-26 16:24:35 -04:00
Jarrod Johnson b4e8daaebe Incorporate common copy of apiclient into build 2020-06-26 16:23:51 -04:00
Jarrod Johnson 3733057852 Move apiclient to common location 2020-06-26 16:22:27 -04:00
Jarrod Johnson 7b21cc829f Incoporate extended info to apiclient 2020-06-26 16:21:48 -04:00
Jarrod Johnson 31aeb2552c Have copernicus outut extended info
This will help profiles select
the most appropriate interface.
2020-06-26 16:13:15 -04:00
Jarrod Johnson df503464d7 Tighten permissions on /etc/confluent on deployed target 2020-06-26 15:50:15 -04:00
Jarrod Johnson cadb222904 Add missing bit from last commit 2020-06-26 15:21:00 -04:00
Jarrod Johnson 3fed7ea075 Implement more context data in discovery
Let the client know the management
interface and whether that subnet has the nicest match
for a primary network.
2020-06-26 15:15:13 -04:00
Jarrod Johnson 86e944b3a4 Correct typo in function call 2020-06-26 14:11:50 -04:00
Jarrod Johnson 05fb763200 Try to auto-restart httpd on initialize
During setup process, restart
the service on behalf of user
if appropriate service file is found.
2020-06-26 12:49:28 -04:00
Jarrod Johnson 1896b51f82 Add emphasis to the HTTPS cert
This is a particularly significant
step that warrants highlighting.
2020-06-26 12:40:07 -04:00
Jarrod Johnson a704c0cdab Be more verbose in osdeploy initialize
Output was a tad terse.
2020-06-26 08:19:22 -04:00
Jarrod Johnson 283cd6318e Fix osdeploy -u
If running osdeploy -u by itself,
we did in fact do something.
2020-06-26 08:11:30 -04:00
Jarrod Johnson 7ec7dd4449 Add ssl module to python in confluent genesis concept 2020-06-25 12:50:45 -04:00
Jarrod Johnson 98008e409f Fix osdeploy tab completion 2020-06-25 10:41:58 -04:00
Jarrod Johnson 250a39bfef Change name of libarchive dependency
SLES12 builds without the '2', and other distros provide
both.
2020-06-25 10:29:27 -04:00
Jarrod Johnson 8fc3cc586d Begin work on a genesis for confluent
Have a genesis edition for confluent os deploy. While the need
for genesis is mitigated and many functions should be available
through pre script, provide a more assured environmennt as a
fallback, if the OS isn't going to be imported or using something
like ESXi.
2020-06-23 17:02:48 -04:00
Jarrod Johnson c7a8f524bd Add -s to nodesensors man page 2020-06-22 13:29:27 -04:00
Jarrod Johnson 32dff34f29 Add floppy to setboot options
'floppy' is used for small
hard disk boot in some scenarios.
2020-06-22 12:13:14 -04:00
Jarrod Johnson 6a272d17c5 Amend python2 dependencies for osdeploy
We use yaml and libarchive-c, have python2 rpms also pull them in.
2020-06-22 09:14:32 -04:00
Jarrod Johnson 785d8a7c1c Fix a couple of problems
In RHV, tmux was unable to attach because of TMUX variable.
Unset it to allow tmux to work normally.

Clortho didn't specify family, which worked in linux but not
in ESXi.
2020-06-19 10:24:51 -04:00
Jarrod Johnson fd82c584d3 Rename osimage in template to osdeploy 2020-06-19 09:24:26 -04:00
Jarrod Johnson 6c920206e7 Fixup image retrieval code for RHV-H 2020-06-19 09:13:19 -04:00
Jarrod Johnson e8d00bf229 Rename osimage command to osdeploy
Do not imply 'imaging' when it's a more generic deployment
facility, that might not even implement imaging.
2020-06-19 08:43:28 -04:00
Jarrod Johnson d86aaaf013 Add required nodectl init
Documentation states this is required.
2020-06-19 08:32:12 -04:00
Jarrod Johnson 03e3497d20 Use the image rpm for install
The image must be extracted from an rpm, for
some reason or another.
2020-06-19 08:28:25 -04:00
Jarrod Johnson 17ec74dcf8 Add binary output to apiclient
It is convenient to use apiclient as
a downloader, it's shorter and to the point
than curl.
2020-06-19 07:49:05 -04:00
Jarrod Johnson e7b93dba50 Have apiclient use first rather than last
apiclient was preferring the slowest rather than
the fastest respondant, inconsistent with intent
and everything else.
2020-06-19 07:29:14 -04:00
Jarrod Johnson 5bc9cb57d1 Amend RH initqueue
We may be called before drivers have manifested interfaces.
On each iteration make sure all nics are up before proceeding.
2020-06-18 16:45:24 -04:00
Jarrod Johnson 889b6a9930 Keep yum repo away from RHV
It must not think it has a yum repo to consider
2020-06-18 15:33:38 -04:00
Jarrod Johnson 5b605aa9d7 Further address EL7/RHV peculiarities
EL7 tends to skip the initqueue. Hook finished to
prevent that.
2020-06-18 15:26:35 -04:00
Jarrod Johnson ad5faf144e Fix more RHV4 issues with the profile 2020-06-18 14:28:44 -04:00
Jarrod Johnson b6c017ef1a Adjust some paths for compatibility
The profile expectations were not being met
2020-06-18 13:50:27 -04:00
Jarrod Johnson 095a831c0b Fix source of abnormal console exit
If using ctrl-e, c, then a delay while
there is console output to do,
console would crash.

Fix by catching the flush problem
and ignoring it.
2020-06-18 13:09:48 -04:00
Jarrod Johnson 9cc5b5f98c Add rhvh4 to profile list 2020-06-18 12:49:05 -04:00
Jarrod Johnson ac2e41bd78 First pass at RHV4 support
Derive from EL8 with some EL7 vintage accomodations
2020-06-18 12:36:00 -04:00
Jarrod Johnson d40426ff54 More cleanly error on unknown media
Rather than raise ugly unexpected
errors and pollute trace log,
cleanly handle the likelihood
of unknown media.
2020-06-18 11:11:53 -04:00
Jarrod Johnson 4722c3ec92 Check current SMM IP before pushing config
If the user requests the same ip address that
is already present, leave the network configuration
alone.
2020-06-18 09:23:30 -04:00
Jarrod Johnson 1c579723cc Check current SMM IP before pushing config
If the user requests the same ip address that
is already present, leave the network configuration
alone.
2020-06-18 09:02:09 -04:00
Jarrod Johnson e1270b2926 Do not seal to PCR 7
At least without secureboot, PCR 7 is not defined.

This would potentially be worth a conditional to
check on secureboot.
2020-06-17 16:23:13 -04:00
Jarrod Johnson d4736e0aad Do not respond to deployment calls without quorum 2020-06-17 11:09:05 -04:00
Jarrod Johnson 86de9ce276 Do not answer deploy solicit without quorum
If we are not in quorum, we cannot provide
credible answers to deployment.
2020-06-17 11:07:54 -04:00
Jarrod Johnson 231582dd0f Workaround mtools on cluster fs
When a lock is acquired by mtools,
it does not ensure it releases the
lock before exit.

Workaround this by doing a blocking
lock and unlock after any
invocation of mtools.
2020-06-16 16:36:02 -04:00
Jarrod Johnson 895430a89c Remove systemd management of /var/lib/confluent
systemd was too easily confused by the state
directory, remove it.
2020-06-16 09:16:01 -04:00
Jarrod Johnson e1de56f19b Correct typo in osimage.py
Wrong variable name...
2020-06-12 14:43:00 -04:00
Jarrod Johnson fc7ad4b028 Generate different boot.cfg for esxi
media boot and pxe boot need
two different strategies for module
location. Print the two cfg files
with the respectively useful
values.
2020-06-12 14:27:37 -04:00
Jarrod Johnson ab04ad85e8 Correct filename typo 2020-06-12 12:13:31 -04:00
Jarrod Johnson cb19425435 Import media world-readable
In the absence of extensions,
libarchive assumes ISO content
is private. Always make content
world readable for the sake of
confluent-public serving.
2020-06-12 11:54:37 -04:00
Jarrod Johnson b8dcfbae45 Move esxi customization back to include
This makes modding the template a bit safer and
more powerful.

It seems it was incorrect that the issue in esxi6
was not due to %include and is just a fact of life.
2020-06-12 11:36:56 -04:00
Jarrod Johnson 92913e1119 Fix path to kernel in boot.cfg
esxi was pointed to the wrong
location.
2020-06-12 11:12:57 -04:00
Jarrod Johnson 76f256a344 Fix missing quote that broke build 2020-06-12 10:36:06 -04:00
Jarrod Johnson 207065aab3 Fix more permission problems
Some ESXi contents that need to
be world readable are fixed.
2020-06-12 09:55:25 -04:00
Jarrod Johnson 5129b9fe9b Write more useful boot.cfg
ESXi should access using relative
path, rather than going to root
for everything.
2020-06-12 09:34:52 -04:00
Jarrod Johnson 458d6284d1 Dulpicate esxi7 to esxi6 2020-06-11 17:18:28 -04:00
Jarrod Johnson db7c5adf8d Add PXE to esxi os images
This will attempt to use
ipxe correctly when PXE
initiates the deployment.
2020-06-11 17:14:14 -04:00
Jarrod Johnson 68f000838e Relocate boot.ipxe
It looks a bit weird in the linux and outright bizarre
in the vmware case.
2020-06-11 15:28:45 -04:00
Jarrod Johnson 0849f20d60 Add stub initprofile.sh
While not needed, stub it out for code to
be extended if needed.
2020-06-11 13:58:01 -04:00
Jarrod Johnson 85b01ccec5 Switch to overwrite vmfs
esxi installs frequently fail unless overwritevmfs is
specified
2020-06-11 13:45:07 -04:00
Jarrod Johnson 198d6a795f Add runweasel to esxi
Early boot behavior is influenced by the
real kernel command line. Without /bootmodules things
fail.
2020-06-11 13:33:15 -04:00
Jarrod Johnson 09db9f5a25 Pull ks.cfg manipulation into scripts
This make it easier to customize rather than being
in addons.tgz
2020-06-11 10:29:22 -04:00
Jarrod Johnson 654932efb6 Modify the correct line for ks manipulation 2020-06-11 10:26:16 -04:00
Jarrod Johnson f78b358cd7 Try to adapt for esxi6.7
ESXi 6.7 had further restrictions
2020-06-11 09:26:40 -04:00
Jarrod Johnson 8e203723ef Further tweak esxi deployment support
Try removing the exec, as memory seems
constrained in exec case for some reason.

Specify behavior when dealing with existing
vmfs.
2020-06-10 14:01:07 -04:00
Jarrod Johnson 0a1409ffcf Amend esxi update
Some mistakes were made in the profile
2020-06-10 12:34:46 -04:00
Jarrod Johnson 873190cae9 Fix tgz generation
Previous attempt was duplicating files in the
archive, which caused vmware kernel to
fail to unpack them.
2020-06-10 12:17:51 -04:00
Jarrod Johnson 783c6ce7b6 Revise the esxi tar strategy
Finally, it has been ascertained
that ESXi rejecting the tar
was due to not having directories
explicitly listed, not because of
forbidding new paths or compression.
2020-06-10 10:37:14 -04:00
Jarrod Johnson facba645c5 Revert "Switch to tar"
This reverts commit c6d0c121d4.
2020-06-10 10:17:54 -04:00
Jarrod Johnson c6d0c121d4 Switch to tar
esxi seems to be inconsistent with working with
gz compressed tar, see if plain tar fares better
2020-06-10 09:44:44 -04:00
Jarrod Johnson d4f46a53e0 Fix tar generation of site
site content was nat being
correctly packed to tgz.
2020-06-10 09:42:44 -04:00
Jarrod Johnson 3b940b6194 Rename site contents in tgz
This moves location of site data for esxi
2020-06-09 16:40:29 -04:00
Jarrod Johnson ca91e10941 Numerous changes to esxi deployment 2020-06-09 16:12:22 -04:00
Jarrod Johnson 32ff75c86a Add profile to esxi 2020-06-09 10:28:16 -04:00
Jarrod Johnson 006db24591 Fix more mistakes in the esxi deploy 2020-06-09 09:51:48 -04:00
Jarrod Johnson 6bbe1a49e0 Fix typo in spec file 2020-06-09 08:50:54 -04:00
Jarrod Johnson 197f9950cb Add ESXi contents to OS deploy 2020-06-08 17:24:48 -04:00
Jarrod Johnson 0bd6aae76f Construct tgz for site
This is needed for vmware
deployment support.
2020-06-08 14:03:58 -04:00
Jarrod Johnson fa9f9c1d99 Tolerate certain HTTP clients
Some HTTP clients put the port
number into the host header.
We don't care about port number.
2020-06-08 11:29:31 -04:00
Jarrod Johnson 0a2ab341a8 Increase root directory size
ESXi demands a lot of files, increase
the root directory by a large amount
to fit esxi.
2020-06-04 15:16:45 -04:00
Jarrod Johnson 58e7a1f0b4 Recognize ESXi media
Fingerprint ESXi media, at
least tested with ESXi 7 media.
2020-06-04 14:58:52 -04:00
Jarrod Johnson 0016c31fef Fix encrypted boot on 8.1
8.1 requires -f or it will fail.
2020-06-04 13:41:00 -04:00
Jarrod Johnson f505b3ad16 Fix grub hash bytes
In python3, need to coerce the strings
to str or else end up with invalid grub password.
2020-06-04 10:27:55 -04:00
Jarrod Johnson d17a2054d4 Add warning about encryptboot to Ubuntu 2020-06-03 16:22:41 -04:00
Jarrod Johnson 97e7dbc936 Improve the SUSE encryption error 2020-06-03 16:18:24 -04:00
Jarrod Johnson 7da29c17e1 Try to add error on encryptboot for SUSE
We don't support under suse, so let the user know if they try.
2020-06-03 15:33:10 -04:00
Jarrod Johnson 942685b48d Amend confetty fix
shlex.join is not widely
available, switch to just
skipping the split if pre-split
by the calling process.
2020-06-03 14:58:30 -04:00
Jarrod Johnson 21e97689bc Fix handling of complex embedded args
If pulling from argv, it has already been
shell split. Use shlex to join to correctly
requote anything that needs quoting.
2020-06-03 13:52:14 -04:00
Jarrod Johnson 8ddcdf625b Fix SSDP issue in python3
A bytes was split by str, fix this.
2020-06-03 13:05:40 -04:00
Jarrod Johnson 427a518673 Fix Ubuntu prescript
Forgot a hyphen
2020-06-03 11:26:34 -04:00
Jarrod Johnson 8797189d5c Reduce sensing responses
Do not respond to a node
if we do not have any expectation
of deploying to that system.
Mitigates troubles of having multiple
confluent servers with the same
nodes.
2020-06-03 10:11:46 -04:00
Jarrod Johnson 762685459c Add confluent CA to installed EL8
Needed to continue boot process during install
2020-06-02 17:44:19 -04:00
Jarrod Johnson f86429c83c Fix credserver
The grubhash should only fill in if there is a value to fill in.
2020-06-02 16:47:50 -04:00
Jarrod Johnson 82ab56ebb4 Add boot encryption support to EL8
The stock profile should now encrypt if requested
2020-06-02 16:05:44 -04:00
Jarrod Johnson 9f4c02dc83 Fix grub hash storage of password 2020-06-02 12:47:47 -04:00
Jarrod Johnson 033903f712 Fix typo in configmanager 2020-06-02 11:38:03 -04:00
Jarrod Johnson cf9f4a9691 Add grub password to attributes
This permits opting into using
a password to block editing
of grub configuration.
2020-06-02 10:59:30 -04:00
Jarrod Johnson 77586c7f4d Add comment to SUSE 2020-06-01 16:03:53 -04:00
Jarrod Johnson 886aade5dc Refactor SUSE installs
Apply same comment principles to suse as was
applied to redhat.
2020-06-01 16:01:26 -04:00
Jarrod Johnson d8266ea6c9 Update firstboot to have some comments
Make it clearer how it would be edited.
2020-06-01 12:25:30 -04:00
Jarrod Johnson e326671057 Add python3-yaml to requires
Ensure yaml support installs in EL8.
2020-06-01 12:02:21 -04:00
179 changed files with 5972 additions and 770 deletions
+3
View File
@@ -1,4 +1,7 @@
*.pyc
.*.
confluent_client/man/man*
.vscode
.*.sw*
.sw*
.idea/*
+6 -3
View File
@@ -88,15 +88,18 @@ while fullline:
for line in fullline.split('\n'):
if not line:
continue
if ': ' not in line:
if ':' not in line:
line = 'UNKNOWN: ' + line
if options.log:
node, output = line.split(': ', 1)
node, output = line.split(':', 1)
output = output.lstrip()
currlog = options.log.format(node=node, nodename=node)
with open(currlog, mode='a') as log:
log.write(output + '\n')
continue
grouped.add_line(*line.split(': ', 1))
node, output = line.split(':', 1)
output = output.lstrip()
grouped.add_line(node, output)
if options.watch:
if not holdoff:
holdoff = os.times()[4] + 0.250
+20 -4
View File
@@ -292,6 +292,8 @@ def rcompleter(text, state):
def parse_command(command):
if isinstance(command, list):
return command
try:
args = shlex.split(command, posix=True)
except ValueError as ve:
@@ -371,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':
@@ -912,8 +914,7 @@ def main():
do_command("start /nodes/%s/console/session" % session_node, netserver)
doexit = True
elif shellargs:
command = " ".join(shellargs)
do_command(command, netserver)
do_command(shellargs, netserver)
quitconfetty(fullexit=True, fixterm=False)
powerstate = None
@@ -947,6 +948,8 @@ def main():
clearpowermessage = False
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:
@@ -957,7 +960,13 @@ def main():
# don't bother churning if minute does not change
laststate['showtime'] = now
updatestatus()
sys.stdout.flush()
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
@@ -1013,6 +1022,13 @@ if __name__ == '__main__':
main()
except BailOut as e:
errcode = e.errorcode
except Exception as e:
import traceback
try:
quitconfetty()
except Exception:
pass
traceback.print_exc()
finally:
if deadline and os.times()[4] < deadline:
sys.stderr.write('[Exited early, hit enter to continue]')
+25 -4
View File
@@ -2,12 +2,13 @@
# This will take a given directory and make a 'big floppy image'
# out of it, suitable for nodemedia upload.
import fcntl
import glob
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]):
@@ -24,12 +25,29 @@ 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, '-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
# unlock between calls to mtools
with open(image, 'rb') as imgfile:
fcntl.flock(imgfile.fileno(), fcntl.LOCK_SH)
fcntl.flock(imgfile.fileno(), fcntl.LOCK_UN)
cpycmd = ['mcopy', '-i', image, '-s']
cpycmd.extend(glob.glob('{0}/*'.format(directory)))
cpycmd.append('::')
subprocess.check_call(cpycmd)
# though not necessary for us, make sure dir2img doesn't have a lingering
# flock from mcopy for any subsequent commands
with open(image, 'rb') as imgfile:
fcntl.flock(imgfile.fileno(), fcntl.LOCK_SH)
fcntl.flock(imgfile.fileno(), fcntl.LOCK_UN)
if __name__ == '__main__':
@@ -37,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)
+10 -5
View File
@@ -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,7 +147,12 @@ 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:
@@ -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']
+95 -21
View File
@@ -1,5 +1,6 @@
#!/usr/bin/python3
import argparse
import os
import sys
@@ -9,6 +10,25 @@ if path.startswith('/opt'):
sys.path.append(path)
import confluent.client as client
import confluent.sortutil as sortutil
def cleararm(nr, cli):
nodes = set([])
for rsp in cli.read('/noderange/{0}/attributes/current'.format(nr)):
for node in rsp.get('databynode', {}):
nodeinfo = rsp['databynode'][node]
for attr in nodeinfo:
if attr == 'deployment.apiarmed':
curr = nodeinfo[attr].get('value', '')
if curr == 'continuous':
nodes.add(node)
noderange = nr
if nodes:
noderange += ',-({0})'.format(','.join(nodes))
for rsp in cli.update('/noderange/{0}/attributes/current'.format(noderange),
{'deployment.apiarmed': ''}):
pass
def armonce(nr, cli):
nodes = set([])
@@ -27,40 +47,94 @@ def armonce(nr, cli):
{'deployment.apiarmed': 'once'}):
pass
def setpending(nr, profile, cli):
args = {'deployment.pendingprofile': profile}
if not profile.startswith('genesis-'):
args['deployment.stagedprofile'] = ''
args['deployment.profile'] = ''
for rsp in cli.update('/noderange/{0}/attributes/current'.format(nr),
{'deployment.pendingprofile': profile}):
args):
pass
def clearpending(nr, cli):
for rsp in cli.update('/noderange/{0}/attributes/current'.format(nr),
{'deployment.pendingprofile': ''}):
pass
def main(args):
ap = argparse.ArgumentParser(description='Deploy OS to nodes')
ap.add_argument('-n', '--network', help='Initiate deployment over PXE', action='store_true')
ap.add_argument('-c', '--clear', help='Clear any pending deployment action', action='store_true')
ap.add_argument('-n', '--network', help='Initiate deployment over PXE/HTTP', action='store_true')
ap.add_argument('-p', '--prepareonly', help='Prepare only, skip any interaction with a BMC associated with this deployment action', action='store_true')
ap.add_argument('-m', '--maxnodes', help='Specifiy a maximum nodes to be deployed')
ap.add_argument('noderange', help='Set of nodes to deploy')
ap.add_argument('profile', help='Profile name to deploy')
args = ap.parse_args(args)
if not args.network:
sys.stderr.write('Currently only network (-n) deployment is supported\n')
ap.add_argument('profile', nargs='?', help='Profile name to deploy')
args, extra = ap.parse_known_args(args)
if args.profile is None and len(extra) == 1:
args.profile = extra[0]
extra = extra[1:]
if args.profile and not args.network:
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('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')
c = client.Command()
c.stop_if_noderange_over(args.noderange, args.maxnodes)
armonce(args.noderange, c)
setpending(args.noderange, args.profile, c)
if args.clear:
cleararm(args.noderange, c)
clearpending(args.noderange, c)
elif args.profile:
armonce(args.noderange, c)
setpending(args.noderange, args.profile, c)
else:
databynode = {}
for r in c.read('/noderange/{0}/attributes/current'.format(args.noderange)):
dbn = r.get('databynode', {})
for node in dbn:
if node not in databynode:
databynode[node] = {}
for attr in dbn[node]:
if attr in ('deployment.pendingprofile', 'deployment.apiarmed', 'deployment.stagedprofile', 'deployment.profile'):
databynode[node][attr] = dbn[node][attr].get('value', '')
for node in sortutil.natural_sort(databynode):
profile = databynode[node].get('deployment.pendingprofile', '')
if profile:
profile = 'pending: {}'.format(profile)
else:
profile = databynode[node].get('deployment.stagedprofile', '')
if profile:
profile = 'staged: {}'.format(profile)
else:
profile = databynode[node].get('deployment.profile', '')
if profile:
profile = 'completed: {}'.format(profile)
else:
profile= 'No profile pending or applied'
armed = databynode[node].get('deployment.apiarmed', '')
if armed in ('once', 'continuous'):
armed = ' (node authentication armed)'
else:
armed = ''
print('{0}: {1}{2}'.format(node, profile, armed))
sys.exit(0)
errnodes = set([])
rc = c.simple_noderange_command(args.noderange, '/boot/nextdevice', 'network',
bootmode='uefi',
persistent=False,
errnodes=errnodes)
if errnodes:
sys.stderr.write(
'Unable to set boot device for following nodes: {0}\n'.format(
','.join(errnodes)))
return 1
rc |= c.simple_noderange_command(args.noderange, '/power/state', 'boot')
return rc
if args.network and not args.prepareonly:
rc = c.simple_noderange_command(args.noderange, '/boot/nextdevice', 'network',
bootmode='uefi',
persistent=False,
errnodes=errnodes)
if errnodes:
sys.stderr.write(
'Unable to set boot device for following nodes: {0}\n'.format(
','.join(errnodes)))
return 1
rc |= c.simple_noderange_command(args.noderange, '/power/state', 'boot')
return rc
return 0
if __name__ == '__main__':
-1
View File
@@ -149,7 +149,6 @@ def show_firmware(session):
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']:
+1
View File
@@ -50,6 +50,7 @@ codemappings = {
'warning': 1,
'critical': 2,
'failed': 2,
'unknown': 2,
}
def main():
+2
View File
@@ -187,5 +187,7 @@ def main():
argparser.print_help()
sys.exit(1)
handler(noderange, media)
if __name__ == '__main__':
main()
sys.exit(exitcode)
+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]')
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)')
+8 -4
View File
@@ -22,13 +22,17 @@ 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):
+9 -1
View File
@@ -36,7 +36,9 @@ SO_PASSCRED = 16
_attraliases = {
'bmc': 'hardwaremanagement.manager',
'bmcuser': 'secret.hardwaremanagementuser',
'switchuser': 'secret.hardwaremanagementuser',
'bmcpass': 'secret.hardwaremanagementpassword',
'switchpass': 'secret.hardwaremanagementpassword',
}
try:
@@ -109,6 +111,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']))
@@ -465,7 +473,7 @@ def print_attrib_path(path, session, requestargs, options, rename=None, attrpref
if isinstance(val, list):
val = ','.join(val)
attrout = '{0}: {1}: {2}'.format(
node, printattr, val)
node, printattr, val).strip()
else:
attrout = '{0}: {1}:'.format(node, printattr)
elif 'isset' in currattr:
+1 -1
View File
@@ -7,7 +7,7 @@ Name: %{name}
Version: %{version}
Release: %{release}
Source0: %{name}-%{version}.tar.gz
License: UNKNOWN
License: Apache2
Group: Development/Libraries
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
Prefix: %{_prefix}
+8 -3
View File
@@ -91,7 +91,7 @@ _confluent_nodeidentify_completion()
_confluent_nodesetboot_completion()
{
COMP_CANDIDATES=("default,cd,network,setup,hd -h -b -p")
COMP_CANDIDATES=("default,cd,network,setup,hd,floppy,usb -h -b -p")
_confluent_generic_completion
}
@@ -142,7 +142,7 @@ _confluent_osimage_completion()
{
_confluent_get_args
if [ $NUMARGS == 2 ]; then
COMPREPLY=($(compgen -W "initialize import" -- ${COMP_WORDS[COMP_CWORD]}))
COMPREPLY=($(compgen -W "initialize import updateboot" -- ${COMP_WORDS[COMP_CWORD]}))
return
elif [ ${CMPARGS[1]} == 'initialize' ]; then
COMPREPLY=($(compgen -W "-h -u -s -t -i" -- ${COMP_WORDS[COMP_CWORD]}))
@@ -150,6 +150,9 @@ _confluent_osimage_completion()
compopt -o default
COMPREPLY=()
return
elif [ ${CMPARGS[1]} == 'updateboot' ]; then
COMPREPLY=($(compgen -W "-n $(confetty show /deployment/profiles|sed -e 's/\///')" -- "${COMP_WORDS[COMP_CWORD]}"))
return
fi
}
@@ -255,6 +258,8 @@ _confluent_nr_completion()
CMPARGS=($COMP_LINE)
_confluent_get_args
if [ $NUMARGS -gt 2 ]; then
compopt -o default
COMPREPLY=()
return;
fi
INPUT=${COMP_WORDS[COMP_CWORD]}
@@ -296,7 +301,7 @@ complete -F _confluent_nn_completion nodeconsole
complete -F _confluent_nr_completion nodeeventlog
complete -F _confluent_nodefirmware_completion nodefirmware
complete -F _confluent_nodedeploy_completion nodedeploy
complete -F _confluent_osimage_completion osimage
complete -F _confluent_osimage_completion osdeploy
complete -F _confluent_ng_completion nodegroupattrib
complete -F _confluent_ng_completion nodegroupremove
complete -F _confluent_nr_completion nodehealth
+42
View File
@@ -0,0 +1,42 @@
nodedeploy(8) -- Request preparation and/or initiating a node deployment
=========================================================================
## SYNOPSIS
`nodedeploy <noderange>`
`nodedeploy <noderange> -c`
`nodedeploy <noderange> [-n] [-p] <name of profile>`
## DESCRIPTION
**nodedeploy** configures attributes and interacts with BMC devices as appropriate
to change the operating system on the noderange to that indicated by `profile`. Tab completion
is supported under bash to help list and select a profile name. `-n` indicates that it
will be a network based deployment (either HTTP or PXE) and `-p` suppresses any activity
that requires the BMC (e.g. setting the next boot device and rebooting the system). Currently
**nodedeploy** only supports `-n` style deployment flows. Without options it shows the current
deployment status.
## OPTIONS
* '-c', '--clear`:
Remove any pending deployment action
* `-n`, `--network`:
Prepare for either an HTTP or PXE based deployment, setting boot device to network and rebooting unless `-p` is specified.
* `-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.
## EXAMPLES
* Begin the instalalation of a profile of CentOS 8.2:
`# nodedeploy d4 -n centos-8.2-x86_64-default`
`d4: network`
`d4: reset`
* Check current deployment state of nodes:
`# nodedeploy d4`
`d4: pending: centos-8.2-x86_64-default (node authentication armed)`
@@ -29,6 +29,10 @@ interval of 1 second is used.
Perform the specified number of readings, waiting `-i` indicated interval or 1 second if not
otherwise indicated.
* `-s`, `--skipnumberless`:
Return only sensors that provide numeric data (e.g. temperature, fanspeed),
ignoring sensors that do not provide numeric data.
## EXAMPLES
* Retrieving all temperature related sensors from one system
`# nodesensors n1 temperature`
+9 -1
View File
@@ -4,7 +4,7 @@ nodesetboot(8) -- Check or set next boot device for noderange
## SYNOPSIS
`nodesetboot <noderange>`
`nodesetboot [options] <noderange> [default|cd|network|setup|hd]`
`nodesetboot [options] <noderange> [default|cd|network|setup|hd|usb|floppy]`
## DESCRIPTION
@@ -42,6 +42,14 @@ control.
remote media mounted as CD/DVD, and detachable hard disks drives such as usb
key devices.
* `floppy`:
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
+17
View File
@@ -0,0 +1,17 @@
osdeploy(8) --- Configure general OS deployment facilities of confluent
==========================================================================
## SYNOPSIS
`osdeploy import <iso>`
`osdeploy updateboot <profile>`
`osdeploy initialize [-h] [-g] [-u] [-s] [-k] [-t] [-p] [-i] [-l]`
## DESCRIPTION
**osdeploy** manages the facilities and os deployment content of a confluent server. The
`import` subcommand will generate profiles from an iso image. `updateboot` will take any
changes in the specified update that need to be pushed into boot configuration and/or images
and ensure those needed changes are performed. `initialize` provides assistance in setting
up the most commonly required facilities. Run `osdeploy initialize -h` for more detail
on the options offered by `osdeploy initialize`
+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.
@@ -0,0 +1,135 @@
#!/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):
sealnew = True
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')
if apikey.startswith('SEALED:'):
sealnew = False
with open('/etc/confluent/confluent.sealedapikey', 'w+') as apiout:
apiout.write(apikey[7:])
with open('/etc/confluent/confluent.sealedapikey') as inp:
sp = subprocess.Popen(['/usr/bin/clevis-decrypt-tpm2'],
stdin=inp, stdout=subprocess.PIPE)
apikey = sp.communicate()[0]
if not isinstance(apikey, str):
apikey = apikey.decode('utf8')
with open('/etc/confluent/confluent.apikey', 'w+') as apiout:
apiout.write(apikey)
if sealnew and os.path.exists('/usr/bin/clevis-encrypt-tpm2'):
try:
with open('/etc/confluent/confluent.apikey') as apin:
sealed = subprocess.check_output(
['/usr/bin/clevis-encrypt-tpm2', '{}'], stdin=apin)
print(HTTPSClient().grab_url('/confluent-api/self/saveapikey', sealed).decode())
except Exception:
sys.stderr.write('Unable to persist API key through TPM2 sealing\n')
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'
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: '):
host = line.split(': ', 1)[1]
break
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()
sys.stdout.write(HTTPSClient(json=json).grab_url(sys.argv[1], data).decode())
@@ -7,7 +7,7 @@ License: Apache2
URL: http://hpc.lenovo.com/
Source0: confluent_osdeploy.tar.xz
BuildArch: noarch
Requires: confluent_ipxe mtools
Requires: confluent_ipxe mtools tar
BuildRoot: /tmp
%description
@@ -25,22 +25,35 @@ cd utils
make all
cp copernicus clortho autocons ../opt/confluent/bin
cd ..
for os in el8 suse15 ubuntu20.04; do
for os in rhvh4 el7 genesis el8 suse15 ubuntu20.04; do
mkdir ${os}out
cd ${os}out
cp -a ../opt .
cp -a ../${os}/initramfs/* .
cp -a ../common/* .
find . | cpio -H newc -o > ../addons.cpio
mv ../addons.cpio .
cd ..
done
mkdir esxi7out
cd esxi7out
cp -a ../opt .
cp -a ../esxi7/initramfs/* .
cp -a ../common/* .
chmod +x bin/* opt/confluent/bin/*
tar zcvf ../addons.tgz *
mv ../addons.tgz .
cd ..
cp -a esxi7out esxi6out
cp -a esxi7 esxi6
%install
for os in el8 suse15 ubuntu20.04; do
for os in rhvh4 el7 el8 genesis suse15 ubuntu20.04 esxi6 esxi7; do
mkdir -p %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs
mkdir -p %{buildroot}/opt/confluent/lib/osdeploy/$os/profiles
cp ${os}out/addons.cpio %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs
cp ${os}out/addons.* %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs
cp -a $os/profiles/* %{buildroot}/opt/confluent/lib/osdeploy/$os/profiles
find %{buildroot}/opt/confluent/lib/osdeploy/$os/profiles -name .gitignore -exec rm -f {} +
done
%files
@@ -0,0 +1,18 @@
#!/bin/bash
echo -n "" >> /tmp/net.ifaces
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
echo "Initializing auto detected console when installer starts" > $autocons
fi
fi
if grep console=ttyS /proc/cmdline >& /dev/null; then
echo "Serial console has been requested in the kernel arguments, the local video may not show progress" > /dev/tty1
fi
. /lib/anaconda-lib.sh
wait_for_kickstart
@@ -0,0 +1,98 @@
#!/bin/sh
[ -e /tmp/confluent.initq ] && return 0
if [ -f /tmp/dd_disk ]; then
for dd in $(cat /tmp/dd_disk); do
if [ -e $dd ]; then
driver-updates --disk $dd $dd
fi
done
fi
mkdir -p /etc/confluent
cat /tls/*.pem > /etc/confluent/ca.pem
TRIES=0
echo -n > /etc/confluent/confluent.info
cd /sys/class/net
while ! awk -F'|' '{print $3}' /etc/confluent/confluent.info |grep 1 >& /dev/null && [ "$TRIES" -lt 60 ]; do
TRIES=$((TRIES + 1))
for currif in *; do
ip link set $currif up
done
/opt/confluent/bin/copernicus -t > /etc/confluent/confluent.info
done
cd /
grep ^EXTMGRINFO: /etc/confluent/confluent.info || return 0 # Do absolutely nothing if no data at all yet
echo -n "" > /tmp/confluent.initq
# restart cmdline
echo -n "" > /etc/cmdline.d/01-confluent.conf
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
#TODO: blkid --label <whatever> to find mounted api
oum=$(umask)
python /opt/confluent/bin/apiclient /confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg
ifidx=$(cat /tmp/confluent.ifidx)
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
echo $ifname > /tmp/net.ifaces
dnsdomain=$(grep ^dnsdomain: /etc/confluent/confluent.deploycfg)
dnsdomain=${dnsdomain#dnsdomain: }
hostname=$nodename
if [ ! -z "$dnsdomain" ] && [ "$dnsdomain" != "null" ]; then
hostname=$hostname.$dnsdomain
fi
mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg)
mgr=${mgr#deploy_server: }
profilename=$(grep ^profile: /etc/confluent/confluent.deploycfg)
profilename=${profilename#profile: }
proto=$(grep ^protocol: /etc/confluent/confluent.deploycfg)
proto=${proto#protocol: }
textconsole=$(grep ^textconsole: /etc/confluent/confluent.deploycfg)
textconsole=${textconsole#textconsole: }
if [ "$textconsole" = "true" ] && ! grep console= /proc/cmdline > /dev/null; then
autocons=$(cat /tmp/01-autocons.devnode)
if [ ! -z "$autocons" ]; then
echo Auto-configuring installed system to use text console
echo Auto-configuring installed system to use text console > $autocons
cp /tmp/01-autocons.conf /etc/cmdline.d/
else
echo "Unable to automatically detect requested text console"
fi
fi
echo inst.repo=$proto://$mgr/confluent-public/os/$profilename/distribution >> /etc/cmdline.d/01-confluent.conf
echo inst.ks=$proto://$mgr/confluent-public/os/$profilename/kickstart >> /etc/cmdline.d/01-confluent.conf
kickstart=$proto://$mgr/confluent-public/os/$profilename/kickstart
root=anaconda-net:$proto://$mgr/confluent-public/os/$profilename/distribution
export kickstart
export root
autoconfigmethod=$(grep ipv4_method /etc/confluent/confluent.deploycfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
if [ "$autoconfigmethod" = "dhcp" ]; then
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
@@ -0,0 +1 @@
[ -e /tmp/confluent.initq ]
@@ -0,0 +1,21 @@
#!/bin/bash
BUNDLENAME=/sysroot/etc/pki/tls/certs/ca-bundle.crt
while [ -h $BUNDLENAME ]; do
BUNDLENAME=/sysroot/$(readlink $BUNDLENAME)
done
cat /etc/pki/tls/certs/ca-bundle.crt > $BUNDLENAME
mkdir -p /sysroot/etc/confluent/
cp -a /tls /sysroot/etc/confluent
cp -a /etc/confluent/* /sysroot/etc/confluent/
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
#chmod 600 /sysroot/root/.ssh/authorized_keys
mkdir -p /sysroot/etc/ssh/
for i in /ssh/*.ca; do
echo '@cert-authority *' $(cat $i) >> /sysroot/etc/ssh/ssh_known_hosts
done
cp /opt/confluent/bin/apiclient /sysroot/etc/confluent
@@ -0,0 +1,7 @@
#!/bin/sh
sed -i 's/centos/CentOS/; s/rhel/Red Hat Enterprise Linux/' $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 && \
ln -s $1/EFI/BOOT/BOOTX64.EFI $1/EFI/BOOT/grubx64.efi $2/boot/efi/boot/
@@ -0,0 +1,80 @@
# In this OS profile, data is largely filled in during the %pre
# phase, rather than the kickstart actually having the content.
# None of the files shall be replaced during an upgrade in
# /var/lib/confluent/public/os/<profile>, so customization should
# be done by modifying files in /var/lib/confluent/public/os/<profile>
# /tmp/rootpw will provide a 'rootpw' line, either locking password if not configured
# or the crypted form.
%include /tmp/rootpw
# timezone is fetched from confluent server, which provides the
# timezone that the management server itself is in by default.
%include /tmp/timezone
# similar to timezone, confluent is asked to provide the
# deployment servers language info and replicate that
# to the deployment target.
%include /tmp/langinfo
# bootloader may be specified if crypted.grubpassword is set on
# a node. This will become a bootloader line if a password
# was specified
%include /tmp/grubpw
# The default partition scheme is applied to a single drive, using
# the getinstalldisk script to make a best guess as to the most
# appropriate device. See pre.sh and getinstalldisk to customize
# the automatic behavior, or comment out/delete the
# following line and provide your own manual partition plan
# instead
%include /tmp/partitioning
reboot
%packages
chrony
rsync
python
pciutils
%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
# files may allow for more easily rebasing custom profiles to newer
# stock profiles
%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
. /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
. /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
%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
. /tmp/postinst.sh
%end
@@ -0,0 +1,7 @@
# Any custom kickstart additions may go here. It may be required to
# modify base kickstart file to change certain portions, but adding
# custom content to this file allows for most convenient way to
# refresh to a newer base profile if desired.
# Two common example customizations are provided:
#firewall --disabled
#selinux --disabled
@@ -0,0 +1,3 @@
label: %%DISTRO%% %%VERSION%% %%ARCH%% (Default Profile)
kernelargs: quiet
#installedargs: example # These arguments would be added to the installed system
@@ -0,0 +1,43 @@
try:
import configparser
except ImportError:
import ConfigParser as configparser
import cStringIO
import imp
import sys
apiclient = imp.load_source('apiclient', '/etc/confluent/apiclient')
repo = None
server = None
profile = None
with open('/etc/confluent/confluent.deploycfg') as dplcfgfile:
lines = dplcfgfile.read().split('\n')
for line in lines:
if line.startswith('deploy_server:'):
_, server = line.split(' ', 1)
if line.startswith('profile: '):
_, profile = line.split(' ', 1)
path = '/confluent-public/os/{0}/distribution/'.format(profile)
clnt = apiclient.HTTPSClient()
cfgdata = clnt.grab_url(path + '.treeinfo').decode()
c = configparser.ConfigParser()
try:
c.read_string(cfgdata)
except AttributeError:
f = cStringIO.StringIO(cfgdata)
c.readfp(f)
for sec in c.sections():
if sec.startswith('variant-'):
try:
repopath = c.get(sec, 'repository')
except Exception:
continue
_, varname = sec.split('-', 1)
reponame = '/etc/yum.repos.d/local-{0}.repo'.format(varname.lower())
with open(reponame, 'w') as repout:
repout.write('[local-{0}]\n'.format(varname.lower()))
repout.write('name=Local install repository for {0}\n'.format(varname))
if repopath[0] == '.':
repopath = repopath[1:]
repout.write('baseurl=https://{}/confluent-public/os/{}/distribution/{}\n'.format(server, profile, repopath))
repout.write('enabled=1\n')
@@ -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=/etc/confluent/firstboot.sh
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,22 @@
#!/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}')
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
. /etc/confluent/functions
run_remote firstboot.custom
curl -X POST -d 'status: complete' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/updatestatus
systemctl disable firstboot
rm /etc/systemd/system/firstboot.service
@@ -0,0 +1,72 @@
function set_confluent_vars() {
if [ -z "$mgr" ]; then
mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
if [ -z "$profile" ]; then
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
}
fetch_remote() {
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://$mgr/confluent-public/os/$profile/scripts/$1 > $1
if [ $? != 0 ]; then echo $1 failed to download; return 1; fi
}
run_remote() {
requestedcmd="'$*'"
curlargs=""
if [ -f /etc/confluent/ca.pem ]; then
curlargs=" --cacert /etc/confluent/ca.pem"
fi
set_confluent_vars
echo
echo '---------------------------------------------------------------------------'
echo Running $requestedcmd from https://$mgr/confluent-public/os/$profile/scripts/
tmpdir=$(mktemp -d)
echo Executing in $tmpdir
cd $tmpdir
mkdir -p $(dirname $1)
curl -f -sS $curlargs https://$mgr/confluent-public/os/$profile/scripts/$1 > $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=$?
echo "$requestedcmd exited with code $retcode"
cd - > /dev/null
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
mkdir -p $(dirname $1)
curl -f -sS $curlargs https://$mgr/confluent-public/os/$profile/scripts/$1 > $1
if [ $? != 0 ]; then echo "'$*'" failed to download; return 1; fi
if [ -x /usr/libexec/platform-python ]; then
/usr/libexec/platform-python $*
else
/usr/bin/python $*
fi
retcode=$?
echo "'$*' exited with code $retcode"
cd - > /dev/null
return $retcode
}
@@ -0,0 +1,88 @@
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")
@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,20 @@
# 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 ofed.iso MLNX_OFED
fetch_remote infiniband/mofed.tgz
tar xf infiniband/mofed.tgz
# The rest is common between tar and iso
cd MLNX_OFED*
mount -o loop 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
@@ -0,0 +1,7 @@
. /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.
# An example for installing OFED for infiniband follows (see the file for more detail):
#run_remote infiniband/mofed.post
@@ -0,0 +1,35 @@
#!/bin/sh
# need to copy over ssh key info
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
. /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
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-*
run_remote_python add_local_repositories
# This script will execute in the installed system, but using the installer kernel prior to reboot.
# This is an appropriate place to run post install activities that do not require the actual installed
# kernel to run. For example adding drivers that would be needed for first boot to run cleanly.
# If, for example, there is a post script that has a dependency on a driver or filesystem that
# cannot work until booting into the installer, use firstboot.sh instead
# run_remote will download and execute from /var/lib/confluent/public/os/<profile>/scripts/ directory
# 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.
# run_remote example.sh
# run_remote_python example.py
run_remote post.custom
@@ -0,0 +1,14 @@
. /tmp/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.
#
#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
@@ -0,0 +1,75 @@
#!/bin/sh
# This runs prior to the installer beginning. This is used to rewrite the
# scripted install file, merging data from confluent and identifying
# the most appropriate install source.
# 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
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
locale=$(grep ^locale: /etc/confluent/confluent.deploycfg)
locale=${locale#locale: }
keymap=$(grep ^keymap: /etc/confluent/confluent.deploycfg)
keymap=${keymap#keymap: }
echo lang $locale > /tmp/langinfo
echo keyboard --vckeymap=$keymap >> /tmp/langinfo
tz=$(grep ^timezone: /etc/confluent/confluent.deploycfg)
tz=${tz#timezone: }
ntpsrvs=""
if grep ^ntpservers: /etc/confluent/confluent.deploycfg > /dev/null; then
ntpsrvs="--ntpservers="$(sed -n '/^ntpservers:/,/^[^-]/p' /etc/confluent/confluent.deploycfg|sed 1d|sed '$d' | sed -e 's/^- //' | paste -sd,)
fi
echo timezone $ntpsrvs $tz --utc > /tmp/timezone
rootpw=$(grep ^rootpassword /etc/confluent/confluent.deploycfg | awk '{print $2}')
if [ "$rootpw" = null ]; then
echo "rootpw --lock" > /tmp/rootpw
else
echo "rootpw --iscrypted $rootpw" > /tmp/rootpw
fi
curl -f https://$mgr/confluent-public/os/$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
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
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
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
touch /tmp/addonpackages
cryptboot=$(grep ^encryptboot: /etc/confluent/confluent.deploycfg | awk '{print $2}')
LUKSPARTY=''
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
. /tmp/functions
run_remote_python getinstalldisk
if [ -e /tmp/installdisk ]; 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
@@ -0,0 +1,20 @@
#!/bin/sh
# This script runs after install is complete, but inside the installer
# environment. This is useful for carrying work done in pre/during the
# installer into the installed environment.
# It is almost certainly more useful to use post.sh or firstboot.sh
# for customization, which will run in a more normal mechanism
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
export mgr profile nodename
cp -a /etc/confluent /mnt/sysimage/etc
cp /tmp/functions /mnt/sysimage/etc/confluent/
. /tmp/functions
cp /tmp/cryptboot /mnt/sysimage/tmp/
# Preserve the ssh setup work done for the installer
# by copying into the target system and setting up
# host based authentication
run_remote setupssh.sh
@@ -0,0 +1,23 @@
#!/bin/sh
grep HostCert /etc/ssh/sshd_config.anaconda >> /mnt/sysimage/etc/ssh/sshd_config
echo HostbasedAuthentication yes >> /mnt/sysimage/etc/ssh/sshd_config
echo HostbasedUsesNameFromPacketOnly yes >> /mnt/sysimage/etc/ssh/sshd_config
echo IgnoreRhosts no >> /mnt/sysimage/etc/ssh/sshd_config
sshconf=/mnt/sysimage/etc/ssh/ssh_config
if [ -d /mnt/sysimage/etc/ssh/ssh_config.d/ ]; then
sshconf=/mnt/sysimage/etc/ssh/ssh_config.d/01-confluent.conf
fi
echo 'Host *' >> $sshconf
echo ' HostbasedAuthentication yes' >> $sshconf
echo ' EnableSSHKeysign yes' >> $sshconf
echo ' HostbasedKeyTypes *ed25519*' >> $sshconf
cp /etc/ssh/ssh_host_* /mnt/sysimage/etc/ssh/
mkdir /mnt/sysimage/root/.ssh/
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
cp /tmp/allnodes /mnt/sysimage/etc/ssh/shosts.equiv
cp /tmp/allnodes /mnt/sysimage/root/.shosts
@@ -0,0 +1,4 @@
#!/bin/sh
cryptdisk=$(blkid -t TYPE="crypto_LUKS"|sed -e s/:.*//)
clevis luks bind -f -d $cryptdisk -k - tpm2 '{}' < /etc/confluent/confluent.apikey
cryptsetup luksRemoveKey $cryptdisk < /etc/confluent/confluent.apikey
@@ -11,5 +11,8 @@ if ! grep console= /proc/cmdline >& /dev/null; then
echo "Initializing auto detected console when installer starts" > $autocons
fi
fi
if grep console=ttyS /proc/cmdline >& /dev/null; then
echo "Serial console has been requested in the kernel arguments, the local video may not show progress" > /dev/tty1
fi
. /lib/anaconda-lib.sh
wait_for_kickstart
@@ -1,52 +1,65 @@
#!/bin/sh
[ -e /tmp/confluent.initq ] && return 0
echo -n "" > /tmp/confluent.initq
cd /sys/class/net
for currif in *; do
ip link set $currif up
done
cd -
while ! grep MANAGER /tmp/confluent.info >& /dev/null; do
/opt/confluent/bin/copernicus -t > /tmp/confluent.info
done
read ifidx <<EOF
$(grep ^MANAGER /tmp/confluent.info|grep fe80|sed -e s/.*%//)
EOF
read mgr << EOF
$(grep ^MANAGER /tmp/confluent.info|grep fe80|awk '{print $2}')
EOF
mgridx=${mgr#*%}
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
echo $ifname > /tmp/net.ifaces
nodename=$(grep ^NODENAME /tmp/confluent.info|awk '{print $2}')
#TODO: blkid --label <whatever> to find mounted api
if [ -z "$apikey" ]; then
apikey=$(/opt/confluent/bin/clortho $nodename $mgr)
if [ -f /tmp/dd_disk ]; then
for dd in $(cat /tmp/dd_disk); do
if [ -e $dd ]; then
driver-updates --disk $dd $dd
fi
done
fi
vlaninfo=$(getarg vlan)
if [ ! -z "$vlaninfo" ]; then
vldev=${vlaninfo#*:}
vlid=${vlaninfo#*.}
vlid=${vlid%:*}
ip link add link $vldev name $vldev.$vlid type vlan id $vlid
fi
TRIES=0
oum=$(umask)
umask 0077
echo $apikey > /etc/confluent.apikey
mkdir -p /etc/confluent
echo -n > /etc/confluent/confluent.info
umask $oum
mgr="[$mgr]"
curl -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/deploycfg > /tmp/confluent.deploycfg
cd /sys/class/net
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
cd /
grep ^EXTMGRINFO: /etc/confluent/confluent.info || return 0 # Do absolutely nothing if no data at all yet
echo -n "" > /tmp/confluent.initq
# restart cmdline
echo -n "" > /etc/cmdline.d/01-confluent.conf
dnsdomain=$(grep ^dnsdomain: /tmp/confluent.deploycfg)
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
#TODO: blkid --label <whatever> to find mounted api
cat /tls/*.pem > /etc/confluent/ca.pem
/usr/libexec/platform-python /opt/confluent/bin/apiclient /confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg
ifidx=$(cat /tmp/confluent.ifidx)
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
ifname=${ifname%@*}
echo $ifname > /tmp/net.ifaces
dnsdomain=$(grep ^dnsdomain: /etc/confluent/confluent.deploycfg)
dnsdomain=${dnsdomain#dnsdomain: }
hostname=$nodename
if [ ! -z "$dnsdomain" ] && [ "$dnsdomain" != "null" ]; then
hostname=$hostname.$dnsdomain
fi
mgr=$(grep ^deploy_server: /tmp/confluent.deploycfg)
mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg)
mgr=${mgr#deploy_server: }
profilename=$(grep ^profile: /tmp/confluent.deploycfg)
profilename=$(grep ^profile: /etc/confluent/confluent.deploycfg)
profilename=${profilename#profile: }
proto=$(grep ^protocol: /tmp/confluent.deploycfg)
proto=$(grep ^protocol: /etc/confluent/confluent.deploycfg)
proto=${proto#protocol: }
textconsole=$(grep ^textconsole: /tmp/confluent.deploycfg)
textconsole=$(grep ^textconsole: /etc/confluent/confluent.deploycfg)
textconsole=${textconsole#textconsole: }
if [ $textconsole = "true" ] && ! grep console= /proc/cmdline > /dev/null; then
if [ "$textconsole" = "true" ] && ! grep console= /proc/cmdline > /dev/null; then
autocons=$(cat /tmp/01-autocons.devnode)
if [ ! -z "$autocons" ]; then
echo Auto-configuring installed system to use text console
@@ -63,19 +76,19 @@ kickstart=$proto://$mgr/confluent-public/os/$profilename/kickstart
root=anaconda-net:$proto://$mgr/confluent-public/os/$profilename/distribution
export kickstart
export root
autoconfigmethod=$(grep ipv4_method /tmp/confluent.deploycfg)
autoconfigmethod=$(grep ipv4_method /etc/confluent/confluent.deploycfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
if [ "$autoconfigmethod" = "dhcp" ]; then
echo ip=$ifname:dhcp >> /etc/cmdline.d/01-confluent.conf
else
v4addr=$(grep ^ipv4_address: /tmp/confluent.deploycfg)
v4addr=$(grep ^ipv4_address: /etc/confluent/confluent.deploycfg)
v4addr=${v4addr#ipv4_address: }
v4gw=$(grep ^ipv4_gateway: /tmp/confluent.deploycfg)
v4gw=$(grep ^ipv4_gateway: /etc/confluent/confluent.deploycfg)
v4gw=${v4gw#ipv4_gateway: }
if [ "$v4gw" = "null" ]; then
v4gw=""
fi
v4nm=$(grep ipv4_netmask: /tmp/confluent.deploycfg)
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
@@ -92,5 +105,17 @@ while read -r entry; do
nameserversec=1
continue
fi
done < /tmp/confluent.deploycfg
done < /etc/confluent/confluent.deploycfg
if [ -e /lib/nm-lib.sh ]; then
. /lib/nm-lib.sh
nm_generate_connections
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
@@ -6,7 +6,9 @@ done
cat /etc/pki/tls/certs/ca-bundle.crt > $BUNDLENAME
mkdir -p /sysroot/etc/confluent/
chmod 700 /sysroot/etc/confluent
cp -a /tls /sysroot/etc/confluent
cp /etc/confluent/* /sysroot/etc/confluent
sed -i 's/install::/install:*:/' /sysroot/etc/shadow
sed -i 's/root::/root:*:/' /sysroot/etc/shadow
mkdir -p /sysroot/root/.ssh
@@ -17,7 +19,4 @@ mkdir -p /sysroot/etc/ssh/
for i in /ssh/*.ca; do
echo '@cert-authority *' $(cat $i) >> /sysroot/etc/ssh/ssh_known_hosts
done
cp /etc/confluent.apikey /sysroot/etc/
cp /etc/confluent.apikey /sysroot/etc/confluent/
cp /tmp/confluent.deploycfg /tmp/confluent.info /sysroot/etc/
cp /tmp/confluent.deploycfg /tmp/confluent.info /sysroot/etc/confluent
cp /opt/confluent/bin/apiclient /sysroot/etc/confluent
@@ -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/' $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 && \
@@ -17,6 +17,11 @@
# to the deployment target.
%include /tmp/langinfo
# bootloader may be specified if crypted.grubpassword is set on
# a node. This will become a bootloader line if a password
# was specified
%include /tmp/grubpw
# The default partition scheme is applied to a single drive, using
# the getinstalldisk script to make a best guess as to the most
# appropriate device. See pre.sh and getinstalldisk to customize
@@ -29,35 +34,49 @@ reboot
%packages
@^minimal-environment
#-kernel-uek # This can opt out of the UEK for the relevant distribution
chrony
rsync
python3
tar
pciutils
%include /tmp/addonpackages
%include /tmp/cryptpkglist
%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
# files may allow for more easily rebasing custom profiles to newer
# stock profiles
%include /tmp/kickstart.custom
%pre
profile=$(grep ^profile: /etc/confluent.deploycfg |awk '{print $2}')
mgr=$(grep deploy_server /etc/confluent.deploycfg |awk '{print $2}')
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
. /tmp/preinst.sh
%end
%post --nochroot
mkdir -p /mnt/sysimage/etc/confluent
profile=$(grep ^profile: /etc/confluent.deploycfg |awk '{print $2}')
mgr=$(grep deploy_server /etc/confluent.deploycfg |awk '{print $2}')
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
. /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
mkdir -p /mnt/sysimage/opt/confluent/bin
curl -f https://$mgr/confluent-public/os/$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
restorecon /etc/ssh/ssh*key /root/.shosts /etc/ssh/shosts.equiv /etc/ssh/ssh_config.d/* /opt/confluent/bin/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
@@ -0,0 +1,7 @@
# Any custom kickstart additions may go here. It may be required to
# modify base kickstart file to change certain portions, but adding
# custom content to this file allows for most convenient way to
# refresh to a newer base profile if desired.
# Two common example customizations are provided:
#firewall --disabled
#selinux --disabled
@@ -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,43 @@
try:
import configparser
except ImportError:
import ConfigParser as configparser
import cStringIO
import imp
import sys
apiclient = imp.load_source('apiclient', '/etc/confluent/apiclient')
repo = None
server = None
profile = None
with open('/etc/confluent/confluent.deploycfg') as dplcfgfile:
lines = dplcfgfile.read().split('\n')
for line in lines:
if line.startswith('deploy_server:'):
_, server = line.split(' ', 1)
if line.startswith('profile: '):
_, profile = line.split(' ', 1)
path = '/confluent-public/os/{0}/distribution/'.format(profile)
clnt = apiclient.HTTPSClient()
cfgdata = clnt.grab_url(path + '.treeinfo').decode()
c = configparser.ConfigParser()
try:
c.read_string(cfgdata)
except AttributeError:
f = cStringIO.StringIO(cfgdata)
c.readfp(f)
for sec in c.sections():
if sec.startswith('variant-'):
try:
repopath = c.get(sec, 'repository')
except Exception:
continue
_, varname = sec.split('-', 1)
reponame = '/etc/yum.repos.d/local-{0}.repo'.format(varname.lower())
with open(reponame, 'w') as repout:
repout.write('[local-{0}]\n'.format(varname.lower()))
repout.write('name=Local install repository for {0}\n'.format(varname))
if repopath[0] == '.':
repopath = repopath[1:]
repout.write('baseurl=https://{}/confluent-public/os/{}/distribution/{}\n'.format(server, profile, repopath))
repout.write('enabled=1\n')
@@ -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()
@@ -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.
@@ -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
@@ -1,7 +1,24 @@
#!/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}')
apikey=$(cat /etc/confluent/confluent.apikey)
mgr=$(grep deploy_server /etc/confluent/confluent.deploycfg|awk '{print $2}')
curl --capath /etc/confluent/tls -X POST -d 'status: complete' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/updatestatus
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
. /etc/confluent/functions
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
curl -X POST -d 'status: complete' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/updatestatus
systemctl disable firstboot
rm /etc/systemd/system/firstboot.service
@@ -1,14 +1,75 @@
function set_confluent_vars() {
if [ -z "$mgr" ]; then
mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
if [ -z "$profile" ]; then
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
}
fetch_remote() {
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://$mgr/confluent-public/os/$profile/scripts/$1 > $1
if [ $? != 0 ]; then echo $1 failed to download; return 1; fi
}
run_remote_parts() {
scriptlist=$(/usr/libexec/platform-python /etc/confluent/apiclient /confluent-api/self/scriptlist/$1|sed -e 's/^- //')
for script in $scriptlist; do
run_remote $1.d/$script
done
}
run_remote() {
cd $(mktemp -d)
curl -f https://$mgr/confluent-public/os/$profile/scripts/$1 > $1
requestedcmd="'$*'"
curlargs=""
if [ -f /etc/confluent/ca.pem ]; then
curlargs=" --cacert /etc/confluent/ca.pem"
fi
set_confluent_vars
echo
echo '---------------------------------------------------------------------------'
echo Running $requestedcmd from https://$mgr/confluent-public/os/$profile/scripts/
tmpdir=$(mktemp -d)
echo Executing in $tmpdir
cd $tmpdir
mkdir -p $(dirname $1)
curl -f -sS $curlargs https://$mgr/confluent-public/os/$profile/scripts/$1 > $1
if [ $? != 0 ]; then echo $requestedcmd failed to download; return 1; fi
chmod +x $1
./$1
cd -
cmd=$1
if [ -x /usr/bin/chcon ]; then
chcon system_u:object_r:bin_t:s0 $cmd
fi
shift
./$cmd $*
retcode=$?
echo "$requestedcmd exited with code $retcode"
cd - > /dev/null
return $retcode
}
run_remote_python() {
cd $(mktemp -d)
curl -f https://$mgr/confluent-public/os/$profile/scripts/$1 > $1
/usr/libexec/platform-python $1
cd -
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
mkdir -p $(dirname $1)
curl -f -sS $curlargs https://$mgr/confluent-public/os/$profile/scripts/$1 > $1
if [ $? != 0 ]; then echo "'$*'" failed to download; return 1; fi
/usr/libexec/platform-python $*
retcode=$?
echo "'$*' exited with code $retcode"
cd - > /dev/null
return $retcode
}
@@ -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,20 @@
# 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 ofed.iso MLNX_OFED
fetch_remote infiniband/mofed.tgz
tar xf infiniband/mofed.tgz
# The rest is common between tar and iso
cd MLNX_OFED*
mount -o loop 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
@@ -0,0 +1,7 @@
. /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.
# An example for installing OFED for infiniband follows (see the file for more detail):
#run_remote infiniband/mofed.post
@@ -1,19 +1,38 @@
#!/bin/sh
# need to copy over ssh key info
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
. /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
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-*
run_remote_python add_local_repositories
# This script will execute in the installed system, but using the installer kernel prior to reboot.
# This is an appropriate place to run post install activities that do not require the actual installed
# kernel to run. For example adding drivers that would be needed for first boot to run cleanly.
# If, for example, there is a post script that has a dependency on a driver or filesystem that
# cannot work until booting into the installer, use firstboot.sh instead
# run_remote will download and execute from /var/lib/confluent/public/<os>/scripts/ directory
# run_remote will download and execute from /var/lib/confluent/public/os/<profile>/scripts/ directory
# run_remote_python will use the appropriate python interpreter path to run the specified script
# Add content as below:
# A post.custom is provided to more conveniently hold customizations, see the post.custom file.
# 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
@@ -0,0 +1,13 @@
. /tmp/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.
#
#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
@@ -1,32 +1,56 @@
#!/bin/sh
# This runs prior to the installer beginning. This is used to rewrite the
# scripted install file, merging data from confluennt and identifying
# scripted install file, merging data from confluent and identifying
# the most appropriate install source.
# 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
nodename=$(grep ^NODENAME /etc/confluent.info|awk '{print $2}')
locale=$(grep ^locale: /etc/confluent.deploycfg)
/usr/libexec/platform-python /etc/confluent/apiclient >& /dev/null
nicname=$(ip link|grep ^$(cat /tmp/confluent.ifidx): | awk '{print $2}' | awk -F: '{print $1}')
nmcli c u $nicname
while ip -6 addr | grep tentative > /dev/null; do
sleep 0.5
done
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
locale=$(grep ^locale: /etc/confluent/confluent.deploycfg)
locale=${locale#locale: }
keymap=$(grep ^keymap: /etc/confluent.deploycfg)
keymap=$(grep ^keymap: /etc/confluent/confluent.deploycfg)
keymap=${keymap#keymap: }
echo lang $locale > /tmp/langinfo
echo keyboard --vckeymap=$keymap >> /tmp/langinfo
tz=$(grep ^timezone: /etc/confluent.deploycfg)
tz=$(grep ^timezone: /etc/confluent/confluent.deploycfg)
tz=${tz#timezone: }
echo timezone $tz --utc > /tmp/timezone
rootpw=$(grep ^rootpassword /etc/confluent.deploycfg | awk '{print $2}')
ntpsrvs=""
if grep ^ntpservers: /etc/confluent/confluent.deploycfg > /dev/null; then
ntpsrvs="--ntpservers="$(sed -n '/^ntpservers:/,/^[^-]/p' /etc/confluent/confluent.deploycfg|sed 1d|sed '$d' | sed -e 's/^- //' | paste -sd,)
fi
echo timezone $ntpsrvs $tz --utc > /tmp/timezone
rootpw=$(grep ^rootpassword /etc/confluent/confluent.deploycfg | awk '{print $2}')
if [ "$rootpw" = null ]; then
echo "rootpw --lock" > /tmp/rootpw
else
echo "rootpw --iscrypted $rootpw" > /tmp/rootpw
fi
curl -f https://$mgr/confluent-public/os/$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
blargs=" --iscrypted --password=$grubpw $blargs"
fi
if [ ! -z "$blargs" ]; then
echo "bootloader $blargs" > /tmp/grubpw
fi
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.apikey)" -d @$pubkey https://$mgr/confluent-api/self/sshcert > $certfile
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
echo HostCertificate $certfile >> /etc/ssh/sshd_config.anaconda
done
/usr/sbin/sshd -f /etc/ssh/sshd_config.anaconda
@@ -34,6 +58,17 @@ 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 a <> $consoledev >&0 2>&1 &
fi
cryptboot=$(grep ^encryptboot: /etc/confluent/confluent.deploycfg | awk '{print $2}')
LUKSPARTY=''
touch /tmp/cryptpkglist
touch /tmp/addonpackages
if [ "$cryptboot" == "tpm2" ]; then
LUKSPARTY="--encrypted --passphrase=$(cat /etc/confluent/confluent.apikey)"
echo $cryptboot >> /tmp/cryptboot
echo clevis-dracut >> /tmp/cryptpkglist
fi
export mgr profile nodename
curl -f https://$mgr/confluent-public/os/$profile/scripts/functions > /tmp/functions
. /tmp/functions
@@ -41,5 +76,7 @@ run_remote_python getinstalldisk
if [ -e /tmp/installdisk ]; then
echo clearpart --all --initlabel >> /tmp/partitioning
echo ignoredisk --only-use $(cat /tmp/installdisk) >> /tmp/partitioning
echo autopart --nohome >> /tmp/partitioning
echo autopart --nohome $LUKSPARTY >> /tmp/partitioning
fi
curl -f https://$mgr/confluent-public/os/$profile/kickstart.custom > /tmp/kickstart.custom
run_remote pre.custom
@@ -7,11 +7,13 @@
# It is almost certainly more useful to use post.sh or firstboot.sh
# for customization, which will run in a more normal mechanism
nodename=$(grep ^NODENAME /etc/confluent.info|awk '{print $2}')
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
export mgr profile nodename
cp -a /etc/confluent /mnt/sysimage/etc
chmod -R og-rwx /mnt/sysimage/etc/confluent
cp /tmp/functions /mnt/sysimage/etc/confluent/
. /tmp/functions
cp /tmp/cryptboot /mnt/sysimage/tmp/
# Preserve the ssh setup work done for the installer
# by copying into the target system and setting up
@@ -3,7 +3,7 @@ grep HostCert /etc/ssh/sshd_config.anaconda >> /mnt/sysimage/etc/ssh/sshd_config
echo HostbasedAuthentication yes >> /mnt/sysimage/etc/ssh/sshd_config
echo HostbasedUsesNameFromPacketOnly yes >> /mnt/sysimage/etc/ssh/sshd_config
echo IgnoreRhosts no >> /mnt/sysimage/etc/ssh/sshd_config
sshconf=/etc/ssh/ssh_config
sshconf=/mnt/sysimage/etc/ssh/ssh_config
if [ -d /mnt/sysimage/etc/ssh/ssh_config.d/ ]; then
sshconf=/mnt/sysimage/etc/ssh/ssh_config.d/01-confluent.conf
fi
@@ -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.apikey)" https://$mgr/confluent-api/self/nodelist > /tmp/allnodes
curl -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" https://$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,4 @@
#!/bin/sh
cryptdisk=$(blkid -t TYPE="crypto_LUKS"|sed -e s/:.*//)
clevis luks bind -f -d $cryptdisk -k - tpm2 '{}' < /etc/confluent/confluent.apikey
cryptsetup luksRemoveKey $cryptdisk < /etc/confluent/confluent.apikey
@@ -0,0 +1,25 @@
#!/bin/sh
# copernicus is hard coded, easier to script a fake sysfs
uuid=$(vsish -e get /hardware/bios/dmiInfo|grep -A15 UUID|sed -e 's/.*://'|sed -e ':a;N;$!ba;s/\n//g' | sed -e 's/ *0x//g')
uuid=${uuid:0:8}-${uuid:8:4}-${uuid:12:4}-${uuid:16:4}-${uuid:20:12}
mkdir -p /sys/devices/virtual/dmi/id/
echo $uuid > /sys/devices/virtual/dmi/id/product_uuid
mkdir -p /etc/confluent
localcli network firewall unload
touch /etc/confluent/confluent.info
while ! grep NODENAME /etc/confluent/confluent.info; do
/opt/confluent/bin/copernicus > /etc/confluent/confluent.info
done
node=$(grep NODENAME: /etc/confluent/confluent.info|head -n 1|awk '{print $2}')
mgr=$(grep MANAGER: /etc/confluent/confluent.info|head -n 1|awk '{print $2}')
cp /opt/confluent/bin/clortho /clortho
/clortho $node $mgr > /etc/confluent/confluent.apikey
cat /tls/*.pem > /etc/confluent/ca.pem
/opt/confluent/bin/apiclient /confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg.new
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg.new | sed -e 's/^profile: //')
/opt/confluent/bin/apiclient /confluent-public/os/$profile/kickstart > /etc/confluent/ks.cfg
/opt/confluent/bin/apiclient /confluent-public/os/$profile/scripts/modinstall > /tmp/modinstall
mv /etc/confluent/confluent.deploycfg.new /etc/confluent/confluent.deploycfg
export node mgr profile
. /tmp/modinstall
exec /bin/install
@@ -0,0 +1 @@
#!/bin/sh
@@ -0,0 +1,11 @@
accepteula
clearpart --firstdisk --overwritevmfs
install --firstdisk --overwritevmfs
%include /tmp/ksnet
%include /tmp/rootpw
reboot
%post
localcli network firewall unload
STATUP=$(mktemp)
echo '{"status": "complete"}' > $STATUP
/opt/confluent/bin/apiclient /confluent-api/self/updatestatus $STATUP
@@ -0,0 +1,3 @@
label: Confluent installation of VMware ESXi %%VERSION%% Hypervisor
ostype: esxi
kernelargs: runweasel
@@ -0,0 +1,36 @@
#!/usr/bin/python
nodename = None
for inf in open('/etc/confluent/confluent.info', 'r').read().split('\n'):
if inf.startswith('NODENAME: '):
nodename = inf.replace('NODENAME: ', '')
break
deploycfg = open('/etc/confluent/confluent.deploycfg', 'r').read().split('\n')
cfg = {}
nslist = False
nameservers = []
for line in deploycfg:
kv = line.split(': ')
if not kv[0]:
continue
if len(kv) == 2:
cfg[kv[0]] = kv[1]
if kv[0] == 'nameservers:':
nslist = True
continue
if nslist and kv[0].startswith('- '):
nameservers.append(kv[0].split(' ', 1)[1])
else:
nslist=False
cfg['nameservers'] = ','.join(nameservers)
netline = 'network --hostname={0} --bootproto={1}'.format(nodename, cfg['ipv4_method'])
if cfg['ipv4_method'] == 'static':
netline += ' --ip={0} --netmask={1}'.format(cfg['ipv4_address'], cfg['ipv4_netmask'])
if cfg.get('ipv4_gateway', 'null') not in (None, '', 'null'):
netline += ' --gateway={0}'.format(cfg['ipv4_gateway'])
if cfg['nameservers']:
netline += ' --nameserver={0}'.format(cfg['nameservers'])
print(netline)
@@ -0,0 +1,9 @@
#!/bin/sh
mv /etc/confluent/confluent.deploycfg /etc/confluent/confluent.newdeploycfg
/opt/confluent/bin/apiclient /confluent-public/os/$profile/scripts/makeksnet >> /tmp/makeksnet
mv /etc/confluent/confluent.newdeploycfg /etc/confluent/confluent.deploycfg
chmod +x /tmp/makeksnet
/tmp/makeksnet > /tmp/ksnet
rootpw=$(grep ^rootpassword: /etc/confluent/confluent.deploycfg|sed -e 's/^rootpassword: //')
echo rootpw --iscrypted $rootpw > /tmp/rootpw
export BOOT_CMDLINE=ks=/etc/confluent/ks.cfg
@@ -0,0 +1,103 @@
#!/bin/bash
export LANG=en_US.utf8
mkdir -p /etc/confluent
if ! grep console= /proc/cmdline >& /dev/null; then
autocons=$(/opt/confluent/bin/autocons)
echo console=$autocons |sed -e 's!/dev/!!' >> /tmp/01-autocons.conf
autocons=${autocons%,*}
echo $autocons > /tmp/01-autocons.devnode
if [ ! -z "$autocons" ]; then
echo "Using $(cat /tmp/01-autocons.conf)"
(while :; do tmux a <> $autocons >&0 2>&1; done) &
(while :; do TERM=linux tmux a <> /dev/tty1 >&0 2>&1; done) &
else
(while :; do tmux a <> /dev/console >&0 2>&1; done) &
fi
else
(while :; do tmux a <> /dev/console >&0 2>&1; done) &
(while :; do TERM=linux tmux a <> /dev/tty1 >&0 2>&1; done) &
fi
(while :; do TERM=linux tmux <> /dev/tty2 >&0 2>&1; done) &
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 22
Port 3389
PermitRootLogin yes
AuthorizedKeysFile .ssh/authorized_keys
EOF
mkdir ~/.ssh
cat /ssh/*.rootpubkey > ~/.ssh/authorized_keys
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
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
/usr/libexec/platform-python /opt/confluent/bin/apiclient /confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg
ifidx=$(cat /tmp/confluent.ifidx)
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
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
fi
echo -n "Initialiing ssh..."
ssh-keygen -A
for pubkey in /etc/ssh/ssh_host*key.pub; do
certfile=${pubkey/.pub/-cert.pub}
privfile=${pubkey%.pub}
/usr/libexec/platform-python /opt/confluent/bin/apiclient /confluent-api/self/sshcert $pubkey > $certfile
if [ -s $certfile ]; then
echo HostCertificate $certfile >> /etc/ssh/sshd_config
fi
echo HostKey $privfile >> /etc/ssh/sshd_config
done
/usr/sbin/sshd
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | awk '{print $2}')
mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg | awk '{print $2}')
export profile mgr
echo "Running https://$mgr/confluent-public/os/$profile/scripts/onboot.sh"
/usr/libexec/platform-python /opt/confluent/bin/apiclient /confluent-public/os/$profile/scripts/functions > /tmp/functions
. /tmp/functions
run_remote onboot.sh
while :; do
bash
done
@@ -0,0 +1,16 @@
root=1
rootok=1
netroot=genesis
clear
echo PS1="'"'[genesis running on \H \w]$ '"'" >> ~/.bashrc
echo PS1="'"'[genesis running on \H \w]$ '"'" >> ~/.bash_profile
mkdir -p /etc/ssh
mkdir -p /var/tmp/
mkdir -p /var/empty/sshd
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
tmux new-session -d sh /opt/confluent/bin/rungenesis
while :; do
sleep 86400
done
@@ -0,0 +1,2 @@
label: Genesis
kernelargs: quiet
@@ -0,0 +1,431 @@
# 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 get_remote_config_mod(vendor, model):
if vendor in ('IBM', 'Lenovo'):
if _is_tsm(model):
return 'tsm'
else:
return 'xcc'
return None
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 awaitgw and not check_gateway(s, bmccfg['bmcgw'], channel):
dotwait()
sys.stdout.write('done\n')
sys.stdout.flush()
cfgmod = get_remote_config_mod(vendor, model)
if cfgmod:
with open('configbmc.configmod', 'w+') as cm:
cm.write('configmod: {0}\n'.format(cfgmod))
sys.stdout.write('Requesting remote configuration of authentication...')
sys.stdout.flush()
bmccfgsrc = subprocess.check_output(
[sys.executable, apiclient, '/confluent-api/self/remoteconfigbmc', 'configbmc.configmod'])
sys.stdout.write('done\n')
sys.stdout.flush()
if __name__ == '__main__':
main()
@@ -0,0 +1,65 @@
function set_confluent_vars() {
if [ -z "$mgr" ]; then
mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
if [ -z "$profile" ]; then
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | sed -e 's/[^ ]*: //')
fi
}
fetch_remote() {
if [ -f /etc/confluent/ca.pem ]; then
curlargs=" --cacert /etc/confluent/ca.pem"
fi
set_confluent_vars
curl -f -sS $curlargs https://$mgr/confluent-public/os/$profile/scripts/$1 > $1
if [ $? != 0 ]; then echo $1 failed to download; return 1; fi
}
run_remote() {
requestedcmd="'$*'"
curlargs=""
if [ -f /etc/confluent/ca.pem ]; then
curlargs=" --cacert /etc/confluent/ca.pem"
fi
set_confluent_vars
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 $curlargs https://$mgr/confluent-public/os/$profile/scripts/$1 > $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=$?
echo "$requestedcmd exited with code $retcode"
cd - > /dev/null
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 $curlargs https://$mgr/confluent-public/os/$profile/scripts/$1 > $1
if [ $? != 0 ]; then echo "'$*'" failed to download; return 1; fi
/usr/libexec/platform-python $*
retcode=$?
echo "'$*' exited with code $retcode"
cd - > /dev/null
return $retcode
}
@@ -0,0 +1,11 @@
#!/bin/sh
. /tmp/functions
# This runs whenever this genesis profile boots for customization
# purposes
# run_remote and run_remote_python are available to download scripts and
# execute them.
# This is an example to request the BMC be configured on the network
# according to how confluent has things configured:
# run_remote_python configbmc -c
@@ -0,0 +1,15 @@
#!/bin/bash
echo -n "" >> /tmp/net.ifaces
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
echo "Initializing auto detected console when installer starts" > $autocons
fi
fi
. /lib/anaconda-lib.sh
wait_for_kickstart
@@ -0,0 +1,120 @@
#!/bin/sh
[ -e /tmp/confluent.initq ] && return 0
if [ -f /tmp/dd_disk ]; then
for dd in $(cat /tmp/dd_disk); do
if [ -e $dd ]; then
driver-updates --disk $dd $dd
fi
done
fi
mkdir -p /etc/confluent
cat /tls/*.pem > /etc/confluent/ca.pem
TRIES=0
echo -n > /etc/confluent/confluent.info
cd /sys/class/net
while ! awk -F'|' '{print $3}' /etc/confluent/confluent.info |grep 1 >& /dev/null && [ "$TRIES" -lt 60 ]; do
TRIES=$((TRIES + 1))
for currif in *; do
ip link set $currif up
done
/opt/confluent/bin/copernicus -t > /etc/confluent/confluent.info
done
cd /
grep ^EXTMGRINFO: /etc/confluent/confluent.info || return 0 # Do absolutely nothing if no data at all yet
echo -n "" > /tmp/confluent.initq
# restart cmdline
echo -n "" > /etc/cmdline.d/01-confluent.conf
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
#TODO: blkid --label <whatever> to find mounted api
oum=$(umask)
# 4.3 is rhel7 with useless curl but has python, 4.4 has usable curl but no python..
if [ -x /usr/bin/python ]; then
python /opt/confluent/bin/apiclient /confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg
else
mgr=$(grep ^EXTMGRINFO: /etc/confluent/confluent.info| sed -e 's/^EXTMGRINFO: //' | awk -F'|' '{print $1 " " $2 " " $3}' |grep 1$ | awk 'NR < 2')
if [ -z "$mgr" ]; then
mgr=$(grep ^EXTMGRINFO: /etc/confluent/confluent.info| sed -e 's/^EXTMGRINFO: //' | awk -F'|' '{print $1 " " $2 " " $3}' | awk 'NR < 2')
fi
mgtiface=$(echo $mgr | awk '{print $2}')
mgr=$(echo $mgr | awk '{print $1}')
if [ ! -f /etc/confluent/confluent.apikey ]; then
/opt/confluent/bin/clortho $nodename $mgr > /etc/confluent/confluent.apikey
fi
if echo $mgr | grep '%' > /dev/null; then
echo $mgr | awk -F% '{print $2}' > /tmp/confluent.ifidx
fi
apikey=$(cat /etc/confluent/confluent.apikey)
if echo $mgr | grep ':' > /dev/null; then
mgr="[$mgr]"
fi
curl -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" -H "CONFLUENT_MGTIFACE: $mgtiface" https://$mgr/confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg
fi
ifidx=$(cat /tmp/confluent.ifidx)
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
echo $ifname > /tmp/net.ifaces
dnsdomain=$(grep ^dnsdomain: /etc/confluent/confluent.deploycfg)
dnsdomain=${dnsdomain#dnsdomain: }
hostname=$nodename
if [ ! -z "$dnsdomain" ] && [ "$dnsdomain" != "null" ]; then
hostname=$hostname.$dnsdomain
fi
mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg)
mgr=${mgr#deploy_server: }
profilename=$(grep ^profile: /etc/confluent/confluent.deploycfg)
profilename=${profilename#profile: }
proto=$(grep ^protocol: /etc/confluent/confluent.deploycfg)
proto=${proto#protocol: }
textconsole=$(grep ^textconsole: /etc/confluent/confluent.deploycfg)
textconsole=${textconsole#textconsole: }
if [ "$textconsole" = "true" ] && ! grep console= /proc/cmdline > /dev/null; then
autocons=$(cat /tmp/01-autocons.devnode)
if [ ! -z "$autocons" ]; then
echo Auto-configuring installed system to use text console
echo Auto-configuring installed system to use text console > $autocons
cp /tmp/01-autocons.conf /etc/cmdline.d/
else
echo "Unable to automatically detect requested text console"
fi
fi
# RHV must not have a repo
#echo inst.repo=$proto://$mgr/confluent-public/os/$profilename/distribution >> /etc/cmdline.d/01-confluent.conf
echo inst.ks=$proto://$mgr/confluent-public/os/$profilename/kickstart >> /etc/cmdline.d/01-confluent.conf
kickstart=$proto://$mgr/confluent-public/os/$profilename/kickstart
root=anaconda-net:$proto://$mgr/confluent-public/os/$profilename/distribution
export kickstart
export root
autoconfigmethod=$(grep ipv4_method /etc/confluent/confluent.deploycfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
if [ "$autoconfigmethod" = "dhcp" ]; then
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
@@ -0,0 +1 @@
[ -e /tmp/confluent.initq ]
@@ -0,0 +1,21 @@
#!/bin/bash
BUNDLENAME=/sysroot/etc/pki/tls/certs/ca-bundle.crt
while [ -h $BUNDLENAME ]; do
BUNDLENAME=/sysroot/$(readlink $BUNDLENAME)
done
cat /etc/pki/tls/certs/ca-bundle.crt > $BUNDLENAME
mkdir -p /sysroot/etc/confluent/
cp -a /tls /sysroot/etc/confluent
cp -a /etc/confluent/* /sysroot/etc/confluent/
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
#chmod 600 /sysroot/root/.ssh/authorized_keys
mkdir -p /sysroot/etc/ssh/
for i in /ssh/*.ca; do
echo '@cert-authority *' $(cat $i) >> /sysroot/etc/ssh/ssh_known_hosts
done
cp /opt/confluent/bin/apiclient /sysroot/etc/confluent
@@ -0,0 +1,8 @@
#!/bin/sh
sed -i 's/centos/CentOS/; s/rhel/Red Hat Enterprise Linux/' $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 && \
ln -s $1/EFI/BOOT/BOOTX64.EFI $1/EFI/BOOT/grubx64.efi $2/boot/efi/boot/
ln -s $(find $1 -name '*host-image*rpm') $2/image.rpm
@@ -0,0 +1,74 @@
# In this OS profile, data is largely filled in during the %pre
# phase, rather than the kickstart actually having the content.
# None of the files shall be replaced during an upgrade in
# /var/lib/confluent/public/os/<profile>, so customization should
# be done by modifying files in /var/lib/confluent/public/os/<profile>
# /tmp/rootpw will provide a 'rootpw' line, either locking password if not configured
# or the crypted form.
%include /tmp/rootpw
# timezone is fetched from confluent server, which provides the
# timezone that the management server itself is in by default.
%include /tmp/timezone
# similar to timezone, confluent is asked to provide the
# deployment servers language info and replicate that
# to the deployment target.
%include /tmp/langinfo
# bootloader may be specified if crypted.grubpassword is set on
# a node. This will become a bootloader line if a password
# was specified
%include /tmp/grubpw
# The default partition scheme is applied to a single drive, using
# the getinstalldisk script to make a best guess as to the most
# appropriate device. See pre.sh and getinstalldisk to customize
# the automatic behavior, or comment out/delete the
# following line and provide your own manual partition plan
# instead
%include /tmp/partitioning
liveimg --url=file:///tmp/install.img
reboot
# 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
# files may allow for more easily rebasing custom profiles to newer
# stock profiles
%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
. /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
. /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
%end
%post
cat /etc/confluent/tls/*.pem >> /etc/pki/tls/certs/ca-bundle.crt
nodectl init
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
. /tmp/postinst.sh
%end
@@ -0,0 +1,4 @@
# Any custom kickstart additions may go here. It may be required to
# modify base kickstart file to change certain portions, but adding
# custom content to this file allows for most convenient way to
# refresh to a newer base profile if desired.
@@ -0,0 +1,3 @@
label: %%DISTRO%% %%VERSION%% %%ARCH%% (Default Profile)
kernelargs: quiet
#installedargs: example # These arguments would be added to the installed system
@@ -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=/etc/confluent/firstboot.sh
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,22 @@
#!/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}')
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
. /etc/confluent/functions
run_remote firstboot.custom
curl -X POST -d 'status: complete' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/updatestatus
systemctl disable firstboot
rm /etc/systemd/system/firstboot.service
@@ -0,0 +1,38 @@
run_remote() {
requestedcmd="'$*'"
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
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=$?
echo "$requestedcmd exited with code $retcode"
cd - > /dev/null
return $retcode
}
run_remote_python() {
echo
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
if [ $? != 0 ]; then echo "'$*'" failed to download; return 1; fi
/usr/libexec/platform-python $*
retcode=$?
echo "'$*' exited with code $retcode"
cd - > /dev/null
return $retcode
}
@@ -0,0 +1,88 @@
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")
@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,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,30 @@
#!/bin/sh
# need to copy over ssh key info
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
. /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
# This script will execute in the installed system, but using the installer kernel prior to reboot.
# This is an appropriate place to run post install activities that do not require the actual installed
# kernel to run. For example adding drivers that would be needed for first boot to run cleanly.
# If, for example, there is a post script that has a dependency on a driver or filesystem that
# cannot work until booting into the installer, use firstboot.sh instead
# run_remote will download and execute from /var/lib/confluent/public/os/<profile>/scripts/ directory
# 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.
# run_remote example.sh
# run_remote_python example.py
run_remote post.custom
@@ -0,0 +1,4 @@
. /tmp/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,100 @@
#!/bin/sh
# This runs prior to the installer beginning. This is used to rewrite the
# scripted install file, merging data from confluent and identifying
# the most appropriate install source.
# 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
mgraw=$(grep ^EXTMGRINFO: /etc/confluent/confluent.info| sed -e 's/^EXTMGRINFO: //' | awk -F'|' '{print $1 " " $2 " " $3}' |grep 1$ | awk 'NR < 2')
if [ -z "$mgraw" ]; then
mgraw=$(grep ^EXTMGRINFO: /etc/confluent/confluent.info| sed -e 's/^EXTMGRINFO: //' | awk -F'|' '{print $1 " " $2 " " $3}' | awk 'NR < 2')
fi
mgraw=$(echo $mgraw | awk '{print $1}')
if echo $mgraw | grep '%' > /dev/null; then
echo $mgraw | awk -F% '{print $2}' > /tmp/confluent.ifidx
fi
iface=$(grep -H $(cat /tmp/confluent.ifidx) /sys/class/net/*/ifindex | awk -F/ '{print $5}')
nmcli c u $iface
while ip -6 addr | grep tentative > /dev/null; do
sleep 0.5
done
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
locale=$(grep ^locale: /etc/confluent/confluent.deploycfg)
locale=${locale#locale: }
keymap=$(grep ^keymap: /etc/confluent/confluent.deploycfg)
keymap=${keymap#keymap: }
echo lang $locale > /tmp/langinfo
echo keyboard --vckeymap=$keymap >> /tmp/langinfo
tz=$(grep ^timezone: /etc/confluent/confluent.deploycfg)
tz=${tz#timezone: }
ntpsrvs=""
if grep ^ntpservers: /etc/confluent/confluent.deploycfg > /dev/null; then
ntpsrvs="--ntpservers="$(sed -n '/^ntpservers:/,/^[^-]/p' /etc/confluent/confluent.deploycfg|sed 1d|sed '$d' | sed -e 's/^- //' | paste -sd,)
fi
echo timezone $ntpsrvs $tz --utc > /tmp/timezone
rootpw=$(grep ^rootpassword /etc/confluent/confluent.deploycfg | awk '{print $2}')
if [ "$rootpw" = null ]; then
echo "rootpw --lock" > /tmp/rootpw
else
echo "rootpw --iscrypted $rootpw" > /tmp/rootpw
fi
curl -f https://$mgr/confluent-public/os/$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
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
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
echo HostCertificate $certfile >> /etc/ssh/sshd_config.anaconda
done
cp /etc/ssh/sshd_config.anaconda /etc/ssh/sshd_config
/usr/sbin/sshd -f /etc/ssh/sshd_config.anaconda
systemctl start sshd
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=''
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
. /tmp/functions
run_remote_python getinstalldisk
if [ -e /tmp/installdisk ]; then
echo clearpart --all --initlabel >> /tmp/partitioning
echo ignoredisk --only-use $(cat /tmp/installdisk) >> /tmp/partitioning
echo autopart --type=thinp --nohome $LUKSPARTY >> /tmp/partitioning
fi
cd $(mktemp -d)
if [ -x /usr/bin/python ]; then
python=/usr/bin/python
elif [ -x /usr/libexec/platform-python ]; then
python=/usr/libexec/platform-python
fi
$python /etc/confluent/apiclient /confluent-public/os/$profile/image.rpm -o image.rpm
rpm2cpio image.rpm | cpio -dumi
ln -s $(find $(pwd) -name *img) /tmp/install.img
cd -
$python /etc/confluent/apiclient /confluent-public/os/$profile/kickstart.custom -o /tmp/kickstart.custom
run_remote pre.custom

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