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

Compare commits

...

787 Commits

Author SHA1 Message Date
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
Jarrod Johnson 700afc6606 Fix function definition
Sourcing the functions was causing a hang.
2020-06-01 11:12:28 -04:00
Jarrod Johnson e7cb3f9a0c Add the refactored files
The refactoring put the files in new places,
add those to tracking.
2020-06-01 10:52:38 -04:00
Jarrod Johnson 0254963432 Add some commentary to help users
Embed comments to help users understand
how to customize a bit better.
2020-06-01 10:52:01 -04:00
Jarrod Johnson 110fb27b2a Refactor the kickstart for EL8 a bit
Based on early feedback, working towards a less
intimidating script set for the sake of not
needing a 'postscripts' facility.
2020-06-01 09:08:41 -04:00
Jarrod Johnson 116682082a Fix reply on nonfunctional nic
If a nic was up but without IPv4,
do not reply even if the kernel is
'helping' us to be in the ballpark.
2020-05-29 17:32:45 -04:00
Jarrod Johnson 2c1ca170e5 Fix python3 issues in ssdp
In python2, they are already bytes.

In python 3, we need to check and convert if not already bytes.
2020-05-29 16:12:23 -04:00
Jarrod Johnson e648c9c065 Fix typo in pxe handler 2020-05-29 12:58:14 -04:00
Jarrod Johnson c1576e9787 Handle blank lines without error
Do not trigger syntax error on a blank expression.
2020-05-29 12:23:57 -04:00
Jarrod Johnson 6ee9ccbc27 Fix python3 idxtoname
python3 needs it to be str, not
bytes as C would return.
Accomodate only for python3, leave
python2 the same.
2020-05-29 12:06:00 -04:00
Jarrod Johnson 2a9d4e8079 Avoid breaking net config with '' DNS server
The node is probably misconfigured, but tolerate it
and carry on so that networking will at least
come up.
2020-05-29 08:58:33 -04:00
Jarrod Johnson 335d06ea4c Default to US if management node is n/a
localectl can be n/a for some scenarios,
default to US for such cases.
2020-05-28 17:07:17 -04:00
Jarrod Johnson 17b8000c0f Fix ethernet support
In accomodating the 20 byte
IB hwaddr, it could no longer
accept the 6 byte.

Adapt to all destination addresses up to 20.
2020-05-28 16:49:59 -04:00
Jarrod Johnson 5f170585c5 Adjust SUSE logic to work
Finding the apache configured
TLS cert location now works in
an easy configuration.
2020-05-28 16:47:36 -04:00
Jarrod Johnson 356de251ee Boot over IB support
IB is a bit different in broadcast
and certainly address length. Be
adaptive for those values.

Further, OPA port addr can get
mangled in the middle of a
transaction, recognize both the
full and mangled variant.
2020-05-28 15:37:30 -04:00
Jarrod Johnson 405bd84ce2 OS import fixes for python 2
Python 2 does not have some
of the tricks we were using, replace with python 2 friendly tricks.
2020-05-28 11:09:24 -04:00
Jarrod Johnson e9a14bd180 Have PXE content adapt to OS
Detect the respective paths
of tftp servers in the three supported distributions.
2020-05-27 17:05:04 -04:00
Jarrod Johnson c3fedf7309 Fix missing import isn osimage 2020-05-27 12:16:24 -04:00
Jarrod Johnson da8baa2ccb Fix missing libarchive dep
confluent now requires
libarchive to run.
2020-05-27 11:46:54 -04:00
Jarrod Johnson 4480d0418e Fix permissions of SSH CA key
It was creating CA as root, which
blocked confluent functionality.
2020-05-27 08:58:10 -04:00
Jarrod Johnson 987ac22b4e Fix permission issues with sshutil
uid management was done incorrectly
2020-05-22 18:13:00 -04:00
Jarrod Johnson 6471599bb2 Fix public/os permissions
When using osimage import,
the permissions on os directory
were too strict. Relax permissions
on public/os
2020-05-22 17:55:22 -04:00
Jarrod Johnson 05983201ee Fix mistaken use of $proto variable
Always use https to fetch the script
2020-05-22 15:59:19 -04:00
Jarrod Johnson b20517bd82 Add missing mtools dependency 2020-05-22 15:47:57 -04:00
Jarrod Johnson 4e8e44605a Merge branch 'master' into osdeploy 2020-05-22 15:47:04 -04:00
Jarrod Johnson d75867050c Fallback when pyte contains unknown colors
This allows nodeconsole to connect to Ubuntu
installer, for example.
2020-05-22 15:46:16 -04:00
Jarrod Johnson b4374817f5 Move getinstalldisk into profiles 2020-05-22 15:27:25 -04:00
Jarrod Johnson 968400d72b Update ssh known hosts and tftp
This is also required to get install going.
2020-05-22 15:03:56 -04:00
Jarrod Johnson 88436ff129 Merge branch 'master' into osdeploy 2020-05-22 13:56:59 -04:00
Jarrod Johnson 213d440052 Fix certificate watch
In python3, it was not working.
If another file got added, it could go
with a busy loop.
2020-05-22 13:55:24 -04:00
Jarrod Johnson eabf2073c1 Fix construction of site cpio
It must include directory names in correct
order for it to unpack correctly
2020-05-22 12:49:33 -04:00
Jarrod Johnson 906855ecf7 Fix cpio generation
It needed to be relative path, and also
fix use of bytes fed into cpio.
2020-05-22 11:40:54 -04:00
Jarrod Johnson 59e9ef2215 Create initramfs.cpio
This actually enables the site for
booting with site addons.

Use of a temporary name mitigates
problem if multiple collective members
try to init at same time.
2020-05-22 11:05:35 -04:00
Jarrod Johnson 021591017c Fix osimagetab completion 2020-05-22 09:03:02 -04:00
Jarrod Johnson ba0d600bf7 Prepare osimage initialize
Provide a helper for the various
setup steps required for
getting ready for OS deployment.
2020-05-21 17:07:58 -04:00
Jarrod Johnson eda645b792 Freshen up ssh and tls helpers
TLS will now work from scratch

SSH user key management updated to final design
2020-05-21 16:26:01 -04:00
Jarrod Johnson 8ce8f18f56 Change certutil to be a module
This allows it to be used from within
osimage command.
2020-05-21 15:56:16 -04:00
Jarrod Johnson 0af9db5eb7 Autodetect TLS key/cert locations
This facilitates easier getting started when possible.
2020-05-21 15:55:22 -04:00
Jarrod Johnson 22d5da3ae9 Rename certs to pem
There are contexts where the .cert name is not
recognized, go for .pem name instead.
2020-05-21 14:37:17 -04:00
Jarrod Johnson 6246d9e0a4 Default to never allowing insecure protocol
It erroneously used http rather than https
without user intervention.
2020-05-21 14:29:58 -04:00
Jarrod Johnson 726cb198c1 Actually list partitions in the HPC template
Without listing, autoyast fails to honor the disk somehow.
This causes disk to be honored. Additionally, use xfs instead of
btrfs and get rid of /home.
2020-05-21 10:57:19 -04:00
Jarrod Johnson b34f308c8a Merge branch 'master' into osdeploy 2020-05-21 08:48:27 -04:00
Jarrod Johnson 0800290c8e Fix checking colleective status
In a few contexts, the result of list_collective
was used directly in a boolean context. As an iterator,
it is always true unless coerced into a potentially empty
list explicitly.
2020-05-21 08:47:07 -04:00
Jarrod Johnson 51bc7dc88f Add nodedeploy command
This is akin to rinstall, but with
better tab completion and such
2020-05-20 16:21:08 -04:00
Jarrod Johnson 76952e774b Add more verbose autoconsole text
Point users towards screendump for Ubuntu and
SuSE.
2020-05-20 14:46:26 -04:00
Jarrod Johnson 8bff5c272b Actually modify meaningful grub config 2020-05-20 14:26:22 -04:00
Jarrod Johnson c587cd34ac Check correct location for deploycfg
This should fix the autocons behavior in
ubuntu.
2020-05-20 14:10:06 -04:00
Jarrod Johnson f8b27f1f8d Add autoconsole to ubunntu install
Have the installed system use serial console.
2020-05-20 13:24:05 -04:00
Jarrod Johnson 60453973cb Actually use the domain name in rhel deploy 2020-05-20 12:48:05 -04:00
Jarrod Johnson c48b023236 Inject DNS domain to suse deploy 2020-05-20 12:20:58 -04:00
Jarrod Johnson c0bd9f8bfb Insert domain into EL deploy
This hopefully sets search path up well.
2020-05-20 12:08:05 -04:00
Jarrod Johnson c4379e3fd2 Null domain becomes blank for ubuntu 2020-05-20 09:40:16 -04:00
Jarrod Johnson b0be352134 Correct target for TLS certs in ubuntu 2020-05-20 09:33:38 -04:00
Jarrod Johnson 7d4ce55127 Fix firstboot on Ubuntu
Correctly update deployment attributes upon completion.
2020-05-19 17:38:25 -04:00
Jarrod Johnson 9506817a00 Add DNS to DOMAINSEARCH, as ubuntu igores domain.. 2020-05-19 17:09:26 -04:00
Jarrod Johnson 0a79307cc5 Fix scope of keymap 2020-05-19 17:05:43 -04:00
Jarrod Johnson 442902ecd8 Fix mistake in selfservice api 2020-05-19 16:49:07 -04:00
Jarrod Johnson 5540896ab1 Convert Ubuntu to netconf syntax
The ipconfig syntax can't take domain. See how
it works using the same hooks that dhcp would have.
2020-05-19 16:23:36 -04:00
Jarrod Johnson e696566b42 Add dns domain to deployment
This permits the deployment profiles
to pull in specified DNS domain.
2020-05-19 15:07:10 -04:00
Jarrod Johnson eec7236110 Rename dns server attribute 2020-05-19 14:45:06 -04:00
Jarrod Johnson ebd41d3e53 Merge branch 'master' into osdeploy 2020-05-19 14:19:26 -04:00
Jarrod Johnson c5c5b36536 Fix reverse noderange in python 3
python3 environments do not natively know the word 'unicode',
in such a case, make unicode an alias for 'str'.
2020-05-19 14:18:35 -04:00
Jarrod Johnson 26caffab76 Have Ubuntu report deployment completion 2020-05-19 13:36:49 -04:00
Jarrod Johnson 9093a6e80a Rework ubuntu profile to break scripts into profile
This makes the pre/post/firstboot scripts more accessible
and consistent with the other distributions.
2020-05-19 12:22:46 -04:00
Jarrod Johnson 66f0e8225e Tighten permissions on confluent config files
Prior to copying them, make sure only root can interact.
The directory should protect them as well, but best to
not have anything controversial.
2020-05-19 10:51:32 -04:00
Jarrod Johnson 5f63875cae Finally fix SuSE certificate handling
It was targeting a symlink that went out of chroot,
target the underlying directory instead.
2020-05-19 10:38:31 -04:00
Jarrod Johnson 92f8acab7a Fix target path of tls anchors 2020-05-18 22:07:03 -04:00
Jarrod Johnson 540d0e1795 Fix SUSE certificate handling
SUSE requires things go through update-ca-certificates,
update the generated certs and the post to do that.
2020-05-18 19:37:54 -04:00
Jarrod Johnson b9cdf0d941 Move TLS certs into correct locations for SuSE 2020-05-18 17:00:05 -04:00
Jarrod Johnson dcb9f60ade Modify suse autocons logic 2020-05-18 16:13:16 -04:00
Jarrod Johnson d12ac8a1ba Try to adjust suse autoconsole behavior 2020-05-18 16:07:38 -04:00
Jarrod Johnson 14ba48da1f Add keymap to EL install 2020-05-18 14:55:35 -04:00
Jarrod Johnson ceefb936c2 Add keymap from donor system
RHEL requires this to autoinstall graphically.
2020-05-18 14:17:57 -04:00
Jarrod Johnson 9caf8056ec Correct split
bytes need bytes to split
2020-05-18 13:50:48 -04:00
Jarrod Johnson 317a1c572b Fix startswith parameter
Needed to be bytes for subprocess
2020-05-18 13:30:22 -04:00
Jarrod Johnson 2b39b9b5a6 Correct string in locale defaulting 2020-05-18 13:02:50 -04:00
Jarrod Johnson 5dee338d50 Fix lang in EL8 install
While text mode does not care, if user goes down graphical
path, it pauses installer.
2020-05-18 12:52:31 -04:00
Jarrod Johnson c459990457 Change EL8 to use autoconsole less 2020-05-18 11:46:47 -04:00
Jarrod Johnson 485b5e0dce Add textconsole to deploycfg
It turns out that the SPCR is
not automatically populated.
Provide a hint via deploycfg
as to whether the user has
configured confluent for text
console access.
2020-05-18 10:41:04 -04:00
Jarrod Johnson 188467ccf0 Correct order of EL post script
Actually try to fetch the file before copying it.
2020-05-16 12:12:30 -04:00
Jarrod Johnson dcda6a1080 Fix EL host based authentication 2020-05-16 11:43:38 -04:00
Jarrod Johnson 0c575456e3 Fix SuSE host authentication
curl was failing to get allnodes
2020-05-16 11:42:19 -04:00
Jarrod Johnson 2211755bf7 Have SUSE profile work for LEAP and SLE
Add a directive to comment out the superfluous autoyast
content from SLE when dealing with the more
straightforward LEAP.
2020-05-16 10:14:23 -04:00
Jarrod Johnson bf5727cab1 Disable yast self-update in suse
It slows down installs and shouldn't be needed.
2020-05-16 10:04:44 -04:00
Jarrod Johnson a05bfcec80 Fix suse15 firstboot
It was not using correct CA path nor was it filling in
authentication headers.
2020-05-15 20:13:06 -04:00
Jarrod Johnson 5ebe127db2 Fix Suse deployment
It missed the rename of the deploy_server attribute.
2020-05-15 19:11:22 -04:00
Jarrod Johnson b67140248e Change ipv4_server to deploy_server
Use a more neutral name for the deployment server target.
It is still ipv4 only for the moment, but easier to pull in
ipv6 support when not having to change paths that don't care.
2020-05-15 16:06:57 -04:00
Jarrod Johnson a5adcbd496 Add firstboot to EL
Also add 'mgt_server' rather than 'ipv4_server'. Will move to this.
The server should be able to dictate the right address without the
deploymennt image having to keep track.
2020-05-15 16:03:25 -04:00
Jarrod Johnson cab2310f35 Fix SLES Full Media
SLES can have Full media set,
support that as well as the
Installer/Packages split.
2020-05-15 14:54:34 -04:00
Jarrod Johnson 4d5ec98525 Correct SELinux context for firstboot
This permits the script to actually run at firstboot, even
if SELinux is on.
2020-05-14 18:24:35 -04:00
Jarrod Johnson 008bf33be3 Fix el8 prescript retrieval
Mistakenly was using the deployer
ip as profile.
2020-05-14 17:16:26 -04:00
Jarrod Johnson b52568dc10 Refactor RedHat/CentOS class profile
Again, break things up for more approachable layout.
2020-05-14 15:47:08 -04:00
Jarrod Johnson 24288f988a Call updatestatus upon completion of suse install 2020-05-14 14:49:53 -04:00
Jarrod Johnson 408d0a8673 Refactor SUSE to have external scripts
Try to improve readability of portions of install by
refactoring.
2020-05-14 13:36:23 -04:00
Jarrod Johnson 579e05972f Rename 'default' to hpc for suse
Since the profile is oriented toward installing
HPC template, name it more appropriately.
2020-05-14 13:05:38 -04:00
Jarrod Johnson f85693b7e3 Fix Headers in new replies
Needs to be a nested tuple.
2020-05-13 16:53:36 -04:00
Jarrod Johnson 7dcad26002 Add hook for registering install completion
This will allow watching the
profile for changes to know
when install is utterly complete.
2020-05-13 16:29:10 -04:00
Jarrod Johnson 393c3ac38e Fix distribution link for SUSE
SUSE needs to be pointed at the
parent directory, not the media
specific path.
2020-05-12 15:51:08 -04:00
Jarrod Johnson b73c561ca9 Support relative path import
Have osimage import correct to absolute
path for import.
2020-05-12 15:02:18 -04:00
Jarrod Johnson 1ba2386b82 Provide keyname to importer
This allows client to reliably make association
between import request and tracking
the import activity.
2020-05-12 14:47:00 -04:00
Jarrod Johnson 8a48909ae3 Relax permissions on osimage
Public content has to be world
readable for the web server
to provide it. Mitigate by only
temporarily relaxing umask.

Note that the known sensitive
portions are already doing an
explicit specification of permissions, so umask
relaxing won't affect those.
2020-05-12 13:41:54 -04:00
Jarrod Johnson 0b01ca59d2 Add osimage script to package 2020-05-12 12:14:27 -04:00
Jarrod Johnson 69d14564b0 Stop trying to modify the confluent lib
The confluent lib may be shared and not modifiable. This is fine.
2020-05-12 11:58:18 -04:00
Jarrod Johnson ccd94fb0cf Actually fix centos profiles 2020-05-12 11:50:45 -04:00
Jarrod Johnson bd91c58768 Fix CentOS profile generation
CentOS checker did not provide
category for profile population.
2020-05-12 11:26:04 -04:00
Jarrod Johnson 72c22939ad Merge branch 'master' into osdeploy 2020-05-12 10:32:40 -04:00
Jarrod Johnson 87a7e65b42 Add missing dependencies to deb package
A number of python packages were missing.
2020-05-12 10:31:36 -04:00
Jarrod Johnson 1beed070fd Add help text to usage 2020-05-12 09:53:46 -04:00
Jarrod Johnson 5addc7519d Rename osdeploy to osimage 2020-05-12 09:48:57 -04:00
Jarrod Johnson 7a68d1444b Extend osdeploy to have a config 2020-05-12 09:48:27 -04:00
Jarrod Johnson b5ccf9446a Fix importing task on existing folder
Allow deletion of a failed task.
2020-05-11 16:37:21 -04:00
Jarrod Johnson 807c68890d Fix import error
Attempted to make the same
directory twice.
2020-05-08 14:43:54 -04:00
Jarrod Johnson ee2f80b5d2 Merge branch 'master' into osdeploy 2020-05-08 14:27:25 -04:00
Jarrod Johnson a017c5460f Have confluent server able to import OS media
This wires up osimage to the API
such that it can work.
2020-05-08 14:27:04 -04:00
Jarrod Johnson 51c09d844f Fix broken expressions
Fix mistake in the {} password fix.
2020-05-08 13:29:33 -04:00
Jarrod Johnson b7c830b041 Fix mistake in listing profiles
Additionally, remove redundant
function definition.
2020-05-07 17:06:23 -04:00
Jarrod Johnson 853318feba Merge branch 'master' into osdeploy 2020-05-07 16:27:12 -04:00
Jarrod Johnson 2c4f8dfceb Fix backup/restore with python3
backup/restore with password
was having problems with python3
2020-05-07 16:27:00 -04:00
Jarrod Johnson 6fa863e8f9 Begin wiring up osimage to core 2020-05-07 16:26:27 -04:00
Jarrod Johnson d90e87e153 Fix backup/restore with python3
backup/restore with password
was having problems with python3
2020-05-07 16:22:56 -04:00
Jarrod Johnson b80647a36e Move osimport and tidy up
Tidy up a few issues with
osimage as it gets moved into place.
2020-05-07 14:08:38 -04:00
Jarrod Johnson 2c74cb18b0 Fix stray letter in file 2020-05-07 13:42:10 -04:00
Jarrod Johnson 8fe1cea2ed Quote sed argument 2020-05-07 12:13:44 -04:00
Jarrod Johnson 471f3bd1cf Fix ubuntu profile name
It was erroneously changed by
initprofile.sh
2020-05-07 12:10:27 -04:00
Jarrod Johnson f10bbdc33d Fix ubuntu missing osprofile
osprofile argument needed to
find path to install image.
2020-05-07 11:57:52 -04:00
Jarrod Johnson d6df9db229 Change efi/boot to lowercase
Consitently use lowercase for
efi/boot for easier grub handling.
2020-05-07 11:12:24 -04:00
Jarrod Johnson d5cab22f41 Add boot configuration generation
On osimport prototype, generate
boot media and config file
2020-05-07 11:08:28 -04:00
Jarrod Johnson 72d52c56b7 Fix build problem for osdeploy
addons.cpio was erroneously
stepping on itself.
2020-05-07 09:35:32 -04:00
Jarrod Johnson 4f2d4a7709 Move media content out of subdirectory
This paves the way for a consistent organization of boot
media
and network based boot.
2020-05-07 09:32:11 -04:00
Jarrod Johnson dcdd453112 Delete trailing whitespace 2020-05-07 09:30:31 -04:00
Jarrod Johnson 5a22168657 Touch up profile label for SUSE 2020-05-07 08:57:15 -04:00
Jarrod Johnson e18ca3dd94 Merge branch 'master' into osdeploy 2020-05-07 08:31:50 -04:00
Jarrod Johnson 3f53c55a66 Add custom port to nodeshell
Permit use of an alternative
port in nodeshell.
2020-05-07 08:27:16 -04:00
Jarrod Johnson 3e02e8bf85 Fix LEAP media detection
LEAP was incorrectly detected as SLE.
2020-05-06 16:56:35 -04:00
Jarrod Johnson cda0f439d3 Fix name replacement of Red Hat distributions 2020-05-06 15:55:31 -04:00
Jarrod Johnson e4bea785c3 Fix RHEL osimport init script 2020-05-06 15:31:29 -04:00
Jarrod Johnson 404041e226 Bring over disk boot content
This allows construction of remote media and httpboot payloads.
2020-05-06 14:33:45 -04:00
Jarrod Johnson 9180bab761 Example for XCC cert scripting 2020-05-06 14:23:54 -04:00
Jarrod Johnson 6d2918ed45 Extend osimport
Prepare osimport for inclusion in confluent server,
by making it break off intense activity to a subprocess.

Additionally, get it ready to track long running
task in a way that can map to api.

Finally, have it combine osdeploy
stock profiles with image
into install profiles.
2020-05-06 14:22:25 -04:00
Jarrod Johnson dd2dca5837 Add more profile contents
More parts of OS image profiles.
2020-05-06 14:03:53 -04:00
Jarrod Johnson 16b3bc44a0 Fix filename in ubuntu osdeploy 2020-05-05 09:53:03 -04:00
Jarrod Johnson e1e34f9f31 Adjust ubuntu architecture name
x86_64 is the confluent  convention
for 64 bit x86.
2020-05-05 09:26:42 -04:00
Jarrod Johnson e4a4bdf317 Fix clortho mistake
In attempting to correct clortho,
a mistake was made in the printf
formats.
2020-05-04 17:27:22 -04:00
Jarrod Johnson a4f9fdec3d Correctly target profile content in osdeploy build 2020-05-04 15:57:11 -04:00
Jarrod Johnson c3b295a4a2 Fix omitted prefix on variable 2020-05-04 15:55:22 -04:00
Jarrod Johnson 5539a6a1e8 Fix mistakes in the rpm template file 2020-05-04 15:53:29 -04:00
Jarrod Johnson bdd982e2ed Correct incorrect rpm build in osdeploy 2020-05-04 15:51:05 -04:00
Jarrod Johnson 1db9282058 Fix buildrpm script 2020-05-04 15:49:46 -04:00
Jarrod Johnson f7dcabc1ab Add buildrpm script to confluent_osdeploy 2020-05-04 15:47:39 -04:00
Jarrod Johnson efe936a93d Further build process for confluent_osdeploy 2020-05-04 15:45:35 -04:00
Jarrod Johnson 4619c466e5 Further rearrange osdeploy content 2020-05-04 15:25:04 -04:00
Jarrod Johnson 65797abfbb Move ubuntu into the deploy directory
Also get started on a spec file
2020-05-04 13:49:48 -04:00
Jarrod Johnson 2929e18413 Organize SUSE15 content 2020-05-04 12:53:05 -04:00
Jarrod Johnson cae75dbccf Rearrange EL8 content
Sort the samples into appropriate
locations.
2020-05-04 11:15:44 -04:00
Jarrod Johnson de201c9a3b Add clean to makefile
Additionally correct a small mistake
in copernicus.c
2020-05-04 10:39:07 -04:00
Jarrod Johnson f619b5933c Add makefile for compilation
The C utilities are easy enough to build
with a Makefile.
2020-05-04 10:22:59 -04:00
Jarrod Johnson cb1d5ebd13 Move compiled utilities and fix clortho
clortho had a number of compiler
warnings, make it compile cleanly.
2020-05-04 10:22:04 -04:00
Jarrod Johnson bbb4f5a0ec Add Ubuntu media to osimport 2020-05-03 19:18:12 -04:00
Jarrod Johnson 14192a6c21 Disable cloud-init and remove double-console line 2020-05-02 11:55:37 -04:00
Jarrod Johnson 530be7a508 Setup host based authentication in ssh in ubuntu 2020-05-02 10:58:06 -04:00
Jarrod Johnson 00eb72a627 Have ssh_known_hosts ready post install for ubuntu 2020-05-01 22:17:27 -04:00
Jarrod Johnson fa40793dfa Add install disk detection to ubuntu 2020-05-01 22:04:32 -04:00
Jarrod Johnson 3f8d825540 Add hook for installing disk
This will be used by pre.sh and getinstalldisk
to direct the install.
2020-05-01 19:33:47 -04:00
Jarrod Johnson 924102fa32 Add the cloud-init script
Still needs storage section, but surprisingly
not going to use much of this and instead lean
in on the scripts.
2020-05-01 16:47:07 -04:00
Jarrod Johnson f3747025ff Further the ubuntu prototype
Switch to using firstboot mechanism as cloud-init
fights us too hard on ssh keys and root password.
2020-05-01 16:41:01 -04:00
Jarrod Johnson 2ac139934e Add console to ubuntu 2020-05-01 10:10:31 -04:00
Jarrod Johnson b3b68774ab Add prototype ubuntu initrd additions
This sets the stage for Ubuntu deployment
2020-04-30 17:28:40 -04:00
Jarrod Johnson f27e6dfdda Rearrange OS content in a more orderly fashion 2020-04-30 17:27:25 -04:00
Jarrod Johnson 45eba14b10 Add some content from exploring suse15/el8 install 2020-04-28 19:43:47 -04:00
Jarrod Johnson 598ec4a294 Change ubuntu package names 2020-04-28 11:29:41 -04:00
Jarrod Johnson 501ab64e18 Revert "Add a utility to select disks"
This reverts commit 2936c7e8fd.
2020-04-27 17:37:21 -04:00
Jarrod Johnson 3437b8b03c Actually write out dhcp conf in initquee
dhcp was not written out during initqueue phase
2020-04-27 16:08:05 -04:00
Jarrod Johnson 2936c7e8fd Add a utility to select disks
Use python to enable a bit
more flexibility and still be
readable.
2020-04-24 09:40:55 -04:00
Jarrod Johnson 68251ffbb8 Fix dhcp mistake in the rhel initqueue
This prevented dhcp from ever being attempted
2020-04-22 16:12:33 -04:00
Jarrod Johnson 051b8259fd Update certutil to update site tls
This puts the certificate in a location
to be picked up by installers,
complete with subject_hash
so that SuSE can easily pull
them in.
2020-04-22 13:33:31 -04:00
Jarrod Johnson d691bcd306 Merge branch 'master' into osdeploy 2020-04-22 09:47:32 -04:00
Jarrod Johnson 4f85ba2bff Fix nodeattrib set of password
This path happens in nodeattrib.
2020-04-22 09:46:38 -04:00
Jarrod Johnson 36911c0d2e Merge branch 'master' into osdeploy 2020-04-22 09:01:02 -04:00
Jarrod Johnson 5232b7c9c4 Fix passwords with {} in them
The input handler erroneously
tried to make an expression out
of values that did not support
expressions.
2020-04-22 08:58:38 -04:00
Jarrod Johnson 59aabb0e69 Fix apikey storage
Adapt to how crypted. values are handled.
2020-04-21 09:01:42 -04:00
Jarrod Johnson 931c7f25d1 Change apikey to crypted
Since it will be crypted, makes sense
for it to be presented same way as rootpassword.
2020-04-21 08:24:01 -04:00
Jarrod Johnson 149e41c33c Add DNS information
Enable setting DNS servers in
the deployment.
2020-04-20 14:27:14 -04:00
Jarrod Johnson 21327af140 Fix typo in the iniqueue script
gateway was not being honored.
2020-04-20 13:05:10 -04:00
Jarrod Johnson c21ae64f06 Fix PXE with static gateway
It was not working when gateway was set.
2020-04-20 12:45:13 -04:00
Jarrod Johnson eb2301b22e Add nodelist to selfservice
This permits a node to get list of nodes,
for example to build shosts.equiv
2020-04-20 11:11:29 -04:00
Jarrod Johnson 06d0e05dbb Set rootfs to have ssh ready
Get the CA and user key into the
right places to use in the target system.
2020-04-20 09:39:36 -04:00
Jarrod Johnson bfac51ba12 Prototype getinstalldisk
This script supersedes the bash script, hopefull
2020-04-17 16:37:04 -04:00
Jarrod Johnson 49a523ca5e Add timezone to deploycfg
This is generally needed to install
an operating system.
2020-04-17 13:21:15 -04:00
Jarrod Johnson 6798e4e848 Increase precision of copernicus time
While it is going to be off by some number of milliseconds,
it's better than being off by 250ms on average.
2020-04-17 12:07:48 -04:00
Jarrod Johnson 690c871d29 Merge branch 'master' into osdeploy 2020-04-17 10:01:55 -04:00
Jarrod Johnson f964fd8ce1 Add some information to man page
If the user consults the man page for help after a
HOSTUNREACH, give some text.
2020-04-17 10:00:56 -04:00
Jarrod Johnson 198b26245b Move hashing before collective
This results in consistent hash
using the initial random, rather
than equivalent, but odd looking
crypted hashes across collective.
2020-04-16 20:51:14 -04:00
Jarrod Johnson 4fb7924015 Fix invalid salts
base64 standard alphabet doesn't
quite map to salt alphabet.  Use
. and / instead.
2020-04-16 20:11:17 -04:00
Jarrod Johnson e4a9216683 Add root password to selfservice
This allows installers to set the
requested root password, or
not.
2020-04-16 17:07:31 -04:00
Jarrod Johnson dc2df09c4e Fix for crypted handling
Crypted attributes were not
handled well, fix the mistakes.
2020-04-16 16:54:59 -04:00
Jarrod Johnson 16667ed41c Add SSH cert to self api
This allows nodes to get a cert from
confluent.
2020-04-16 13:11:05 -04:00
Jarrod Johnson b37c034d6f Also carry in confluent.info
The installer needs this information to continue.
2020-04-16 12:40:35 -04:00
Jarrod Johnson 32038baa75 Carry deploycfg into installer 2020-04-16 12:23:45 -04:00
Jarrod Johnson dcdc8e4d5a Merge branch 'master' into osdeploy 2020-04-16 12:10:03 -04:00
Jarrod Johnson f97fd3105f Prevent GET from indicating a non-idempotent opreation
This could bypass CSRF protection in theory.
2020-04-16 12:08:47 -04:00
Jarrod Johnson 4e8cc3d801 Carry API key past initramfs
This enables api calls during
the installer.
2020-04-16 11:54:40 -04:00
Jarrod Johnson 86a68bf7f9 Rework CA layout to file-per-CA
Have the deployed system combine
into known_hosts.  This simplifies
potential contention.
2020-04-16 10:08:27 -04:00
Jarrod Johnson 84988031a2 Move sshutil to a more practical place
This makes the keysigning function available to the server.
2020-04-16 09:49:30 -04:00
Jarrod Johnson 211b8ab7e8 Actually print message to serial
When console detected, actually notify
the relevant console.
2020-04-15 18:25:16 -04:00
Jarrod Johnson 23e8642950 Improve autocons
Provide more feedback and have
a proper cmdline style argument
2020-04-15 17:27:52 -04:00
Jarrod Johnson 76f7c12ca5 Incorporate autocons
This should permit skipping
it on kernel command line.
2020-04-15 16:50:33 -04:00
Jarrod Johnson e2aaa2afb4 Support proper readback of crypted
crypted attributes should be
treated about the same as
passwords.
2020-04-15 16:34:54 -04:00
Jarrod Johnson 890793068c Have prepivot stage accounts
Carry forward the ssh key and
disable passwords so that ssh
may safely be enabled during
install.
2020-04-15 16:19:23 -04:00
Jarrod Johnson 09700626b5 Add attribute to store root password
We want a non-recoverable form,
so hard code it to force it that way.
2020-04-15 16:18:39 -04:00
Jarrod Johnson 709ace4c92 Fix CA bundle in install
Once transitioning to install,
the CA bundle was lost, because
the symlink lead out of sysroot.

Fix by prepending sysroot if symlink
2020-04-15 13:30:47 -04:00
Jarrod Johnson 2c1ddabf32 Rename api.* attributes
Gather them into the deployment
category.
2020-04-15 11:50:10 -04:00
Jarrod Johnson 24bc1210d0 Numerous fixes to the OS deploy
Most notably, change to safe_dump for yaml.

For the various initrd items, changes
to actually trigger the relevant bits
of the RH installer.
2020-04-14 16:34:50 -04:00
Jarrod Johnson 276e01434d Remove example output from script 2020-04-10 16:49:14 -04:00
Jarrod Johnson 58fd760698 Implement begins of self api
This paves the way to get deployment started
in earnest.
2020-04-10 16:46:41 -04:00
Jarrod Johnson c76a0cfa16 Merge branch 'master' into osdeploy 2020-04-10 12:12:31 -04:00
Jarrod Johnson bc03da47af Fix another python3 syntax problem
async can't even be a member of
a class, evidently.
2020-04-10 12:12:17 -04:00
Jarrod Johnson 2575e32209 Fix another python3 syntax problem
async can't even be a member of
a class, evidently.
2020-04-10 12:11:45 -04:00
Jarrod Johnson 989ae614c9 Merge branch 'master' into osdeploy 2020-04-10 12:09:41 -04:00
Jarrod Johnson bd39171611 Fix another use of async name
For better python 3 compatibility,
stop using async as a variable name.
2020-04-10 12:09:27 -04:00
Jarrod Johnson 814209385c Fix another use of async name
For better python 3 compatibility,
stop using async as a variable name.
2020-04-10 12:08:55 -04:00
Jarrod Johnson 3b3475e073 Merge branch 'master' into osdeploy 2020-04-10 11:59:04 -04:00
Jarrod Johnson ed050b37e1 Fix httpapi with python3
async is now particularly special,
rename variable to fix it
2020-04-10 11:58:45 -04:00
Jarrod Johnson 331d10140a Fix httpapi with python3
async is now particularly special,
rename variable to fix it
2020-04-10 11:57:59 -04:00
Jarrod Johnson 2bd2946e9f Add time sync option to copernicus
Since we are dealing in TLS certificates,
the easiest thing is to have copernicus sync
time.  It is not as robust as ntp,
but it'll do as a stopgap
until the real time utilities
kick in.
2020-04-10 11:23:12 -04:00
Jarrod Johnson a3f7fc12b5 Include fe80 in cert
fe80 is needed and a valid
thing to assert.
2020-04-10 09:59:53 -04:00
Jarrod Johnson 5fb4f2b36c Add CAs from site to install
Preserve the CA situation into the installer
2020-04-09 16:18:39 -04:00
Jarrod Johnson 3ddeb4bcd0 A basic hook to force network bringup
initqueue must be satisfied by a udev rule.  We don't
know which network until iniqueue phase, but the hook
needs to install earlier.  This change induces
udev rule generation.
2020-04-09 16:14:30 -04:00
Jarrod Johnson 1722ad941b Add a starting sample of initqueue dracut hook
For rhel8, this initqueu hook is useful
2020-04-09 16:13:33 -04:00
Jarrod Johnson d18c0a576d Fix ProxyDHCP reply
Use the memoryview instead
of the bytearray for correct
use.
2020-04-09 09:20:34 -04:00
Jarrod Johnson acda061710 Merge branch 'master' into osdeploy 2020-04-09 08:21:24 -04:00
Jarrod Johnson 8d1d19d9a8 Fix nodelicense save with expansion
Client side checking will not suffice.  Move it server side.

Additionally ,fix ownership of downloaded files.
2020-04-09 08:20:55 -04:00
Jarrod Johnson fdd9c0953c Fix numerous python2 issues
python2 needs tobytes rather
than bytes of a memoryview.
2020-04-08 17:28:29 -04:00
Jarrod Johnson 137e35217b Implement UDP checksum
Properly implement checksum
on ACK.
2020-04-07 17:36:51 -04:00
Jarrod Johnson fe3d9da5aa Have a workable static PXE behavior
All but the checksum is now
functioning.
2020-04-07 17:07:07 -04:00
Jarrod Johnson d76c576b4e Merge branch 'master' into osdeploy 2020-04-07 11:35:03 -04:00
Jarrod Johnson 017f3fb372 Switch CP storage to SSDP from SLP
The SLP behavior on CP storage BMC is problematic.
Switch to SSDP to see if that provides more robust
behavior.
2020-04-07 11:32:52 -04:00
Jarrod Johnson f58b943cfe Fix mistakes in pxe handler
stringify was passed a string, fix
that input.

Fix mispelling of isinstance.
2020-04-06 17:11:23 -04:00
Jarrod Johnson 86628929de Merge branch 'master' into osdeploy 2020-04-06 14:51:01 -04:00
Jarrod Johnson 46518f890b Fix nodediscover assign
The feature request for -n was
implemented in a way that broke
nodediscover assign.
2020-04-06 14:50:24 -04:00
Jarrod Johnson b0a0bad635 Merge branch 'master' into osdeploy 2020-04-03 12:34:05 -04:00
Jarrod Johnson 7e86a72872 Pass along unavailable info to client 2020-04-03 12:33:55 -04:00
Jarrod Johnson 1cfeed3f9d Merge branch 'master' into osdeploy 2020-04-03 11:02:14 -04:00
Jarrod Johnson 2567503662 Handle both types of CP reply
The CP storage may reply with
one of two distinct forms.  Recognize
either and treat them the same.
2020-04-03 11:01:55 -04:00
Jarrod Johnson 061e12beeb Merge branch 'master' into osdeploy 2020-04-02 11:43:32 -04:00
Jarrod Johnson 6b56181a52 Fix attrib add code
It was failing due to automatic pathing in python3
2020-04-02 11:42:54 -04:00
Jarrod Johnson 323be19f21 Fix typo in the legacy boot support 2020-04-02 11:34:42 -04:00
Jarrod Johnson 0983cacb20 Merge branch 'master' into osdeploy 2020-04-02 11:01:57 -04:00
Jarrod Johnson c18ce50138 Integrate attributes into man pages 2020-04-02 11:01:42 -04:00
Jarrod Johnson b3c878462f Integrate attributes into man pages 2020-04-02 11:00:45 -04:00
Jarrod Johnson 8e8e17a34e Merge branch 'master' into osdeploy 2020-04-02 10:26:28 -04:00
Jarrod Johnson a0684520d8 Add documentation for some parameter default 2020-04-02 10:25:57 -04:00
Jarrod Johnson e78b4e9f17 Merge branch 'master' into osdeploy 2020-04-02 10:18:11 -04:00
Jarrod Johnson 374aa49016 Add man page for nodersync 2020-04-02 10:17:44 -04:00
Jarrod Johnson ea537b1a1f Add branch to support legacy
Legacy boot gets into ipxe
through a kkpxe executable.
2020-04-02 09:41:17 -04:00
Jarrod Johnson bc7dc50388 Switch filename for iPXE
This offers the real iPXE script to
ipxe.
2020-04-01 17:19:23 -04:00
Jarrod Johnson 2da5bebf46 Fix iPXE recognition of our offer
iPXE requires that next-server
be set, unlike UEFI firmware
which did not care.
2020-04-01 16:59:43 -04:00
Jarrod Johnson 0fe136d4ee Extend a proxydhcpack
This is one stage of actually
providing download over
PXE.
2020-04-01 16:40:47 -04:00
Jarrod Johnson b573ffa897 Reduce log noise
Stop logging frequently occuring
events that are generally ignored.
2020-04-01 10:33:42 -04:00
Jarrod Johnson 0986853e6e Merge branch 'master' into osdeploy 2020-03-30 10:59:56 -04:00
Jarrod Johnson 0b95daa30d Add msgpack to explicit dependencies
This will pull in msgpack for debian derivatives.
2020-03-30 10:58:08 -04:00
Jarrod Johnson 96b5d3aa91 Actually populate the file field
Thankfully, it turns out that HTTPBoot carries the same flexibility
as PXE with respect to no-ip answer being merged with an IP answer.

As a bonus, it actually is simpler than PXE, allowing skipping of udp
port 4011.  Of course, we still want to support PXE boot, so that will
need to be implemented.
2020-03-27 16:17:51 -04:00
Jarrod Johnson 6cc0fd20a0 Merge branch 'master' into osdeploy 2020-03-27 12:14:56 -04:00
Jarrod Johnson d33365195b Have nodediscover list filter by -n
It is a reasonable expectation and useful feature to provide.
2020-03-27 12:14:41 -04:00
Jarrod Johnson 85c648925f Merge branch 'master' into osdeploy 2020-03-27 11:05:38 -04:00
Jarrod Johnson 3429173c27 nodeconsole changes to specifically target tmux
tmux needs more direction to avoid ambiguous results.
2020-03-27 10:57:14 -04:00
Jarrod Johnson 44836cabbe Prepare for http boot
HTTP boot does not seem to support proxy dhcp.
2020-03-27 10:56:38 -04:00
Jarrod Johnson 92e657b987 Fix UDP checksum of odd-length packets
Odd length packets were incorrectly handled, fix
the packet construction.
2020-03-26 16:59:58 -04:00
Jarrod Johnson 16209bc3d6 Merge branch 'master' into osdeploy 2020-03-26 14:11:03 -04:00
Jarrod Johnson f6c44922f8 Add support for forced password change
ThinkAgile CP storage BMC firmware now requires
a password change be navigated prior to operation.
2020-03-26 14:10:17 -04:00
Jarrod Johnson 41aa9e1cd2 Optimize chown
chown does not need to be called recursively every update/install.
2020-03-24 18:08:34 -04:00
Jarrod Johnson 0c96882fda Restore Python 3 compatibility for pxe
The changes accidentally broke python 3, make a
bytes explicit to fix.
2020-03-24 17:54:07 -04:00
Jarrod Johnson 00681489c7 Add python2 compatibility to pxe
Various facets of pxe.py were python3-only,
make it compatible with python2 for now.
2020-03-24 17:26:39 -04:00
Jarrod Johnson 8c2336b8fa Implemennt static when no DHCP
This permits an offer for a nominally static
node, unless it either doesn't map to an IP or
has dhcp method explicitly declared.
2020-03-24 15:09:28 -04:00
Jarrod Johnson a1bb603570 Fix multinet support and prefix 2020-03-24 10:31:19 -04:00
Jarrod Johnson 96cbfa5568 Prepare get_nic_config for servicing pxe
Ability to retrieve node network information according to context
of interface index that receives the packet.
2020-03-23 17:18:17 -04:00
Jarrod Johnson f0e5572b05 Remove filename from DHCP reply
filename is ignored if pxeclient anyway.  This will provide a
consistent approach for boot file for dhcp-elsewhere and
fixed ip clients alike.

Also add some TODO about how to enable DHCPREQUEST
processing when the time comes, as today the code skipping
option parsing for DISCOVER packets trips up the ability
to continue.  We must make sure we don't call discovery
handler again for REQUEST after doing so for DISCOVER.
2020-03-20 17:57:04 -04:00
Jarrod Johnson 895216d94f Setting PXEClient in option 60
This trigges the proxyDHCP sequence to follow up.
2020-03-20 17:40:29 -04:00
Jarrod Johnson 1c7c897267 Add option 97 (UUID) to OFFER
Per PXE specification, this is among the required fields.
2020-03-20 17:23:33 -04:00
Jarrod Johnson 20a26e6fdb Implement the UDP checksum
As long as we are doing UDP and IP in house, might as well do the
optional UDP checksum.
2020-03-20 16:55:20 -04:00
Jarrod Johnson 433f67730c Add RAW capability to the service
This is required for the new PXE support
2020-03-20 14:59:30 -04:00
Jarrod Johnson fcd73399fa Add IP and UDP header to OFFER attempt
It d oesn't quite work, but it looks convincing.  UDP checksum may
need to be added, and beyond that explore changes to the payload since
it is likely not enough DHCP was provided.
2020-03-19 18:39:32 -04:00
Jarrod Johnson b7d85b2166 Switch to ctypes for sendto
First, IP level sendto doesn't give the freedom to send 25.255.255.255
out of the interface desired.  So have to go link layer.

Second, while python can do sendto, we have the interface index number
from recvmsg (which was ctypes).  python expects the name instead
(wwhich it promptly turns... back into the index we start with).  I
could have added code to get the name using some syscalls which would
have been work and produced more system calls, or added the code to
directly use sendto, which would also be efficient at runtime.

So I chose to use ctypes for both recvmsg and sendto here.
2020-03-19 16:20:47 -04:00
Jarrod Johnson 22de1153c2 Continue draft of PXE support
It is able to vaguely construct a DHCPOFFER now, though it doesn't go
the right way for starters.
2020-03-18 17:12:26 -04:00
Jarrod Johnson e0223706b0 Add a sample CentOS/RH handler snippet
Begin work to prepare profiles for booting.
2020-03-16 18:03:07 -04:00
Jarrod Johnson 451ff6b5a3 Fix geometry in dir2img
The geometry was incorrect in dir2img, ensure the file is
a multiple of 512 bytes.
2020-03-16 14:47:21 -04:00
Jarrod Johnson b3c49c532c Rewrite dir2img in python
It is a good measure to prep for more heavy usage in
OS deployment.

While changes were being made anyway, also cut time to make
an image in half.
2020-03-16 12:52:18 -04:00
Jarrod Johnson 8fb206b1f7 Fix cert util on pythoen3
python 3 had bytes and not str and need to be
decoded before string operations.
2020-03-16 09:27:34 -04:00
Jarrod Johnson 1bf7c6970f Merge branch 'master' into osdeploy 2020-03-13 11:06:26 -04:00
Jarrod Johnson a86d962984 Fix missing pwd import
The pwd module was accidentally omitted, fix the mistake.
2020-03-13 11:04:16 -04:00
Jarrod Johnson 6ade0952c7 Workaround incorrect TLS clients
Standards compliant TLS clients require
that IP addresses be compared against
IP type SAN fields.

However, some firmware ignores IP fields and only checks DNS fields.

Workaround and provide compatibility
by duplicating the IP as DNS and IP fields.

Also, clean up the temporary config file when done.
2020-03-12 19:06:05 -04:00
Jarrod Johnson 517101f596 Reduce spurious logging
When ignoring DHCPREQUEST,
do not log, since DISCOVER
was enough logging.
2020-03-12 18:08:48 -04:00
Jarrod Johnson 1bfc949466 Add message when insecure is needed
Practically speaking, this will be only choice for most people, but we
must make sure that the user acknowledges the risk.
2020-03-12 17:42:56 -04:00
Jarrod Johnson e97214ca50 Merge branch 'master' into osdeploy 2020-03-12 16:05:08 -04:00
Jarrod Johnson 9ee29aabe1 Set certificate ownership properly
When creating certificate for collective, ensure that the certificate
is usable by confluent when running
as non-root.
2020-03-12 16:04:23 -04:00
Jarrod Johnson 57ff9808c4 Fix infinite loop in DHCP parsing
Accidentally failed to actually traverse
the data.
2020-03-11 15:43:34 -04:00
Jarrod Johnson 0f67f5c382 Draft attempt at refactoring PXE
The plan is to have 'discovery'
data only on DISCOVER, but
still parse and be able to react to
REQUEST packets.

Additionally add the attributes
to control deployment state and
permissible protocols.
2020-03-11 15:22:45 -04:00
Jarrod Johnson b789252c9c Merge branch 'master' into osdeploy 2020-03-11 14:00:52 -04:00
Jarrod Johnson a413f321fe Fix console loss on server exit
Catch the new exception that
was used to make other commands
exit cleaner.
2020-03-11 13:58:37 -04:00
Jarrod Johnson d38b06224c Merge branch 'master' into osdeploy 2020-03-11 09:30:18 -04:00
Jarrod Johnson f2bd796c2a Further clean up license error handling
Backup of nodelicense was not
consistently checked between
redfish and ipmi plugins.
2020-03-11 09:29:41 -04:00
Jarrod Johnson bf31c4872f Fix mistake in nodelicense save
It was incorrectly presenting unrecognized error infomation.
2020-03-11 09:22:16 -04:00
Jarrod Johnson 9ea9188fdf Get closer to replying to PXE
Monitor and maintain a uuid and
mac map to node in preparation for
efficient handling of
DISCOVERs/REQUESTS from
ONIE and/or PXE.
2020-03-10 11:16:59 -04:00
Jarrod Johnson 597393842a Add transaction ID to the carried information
The ability to extend an OFFER requires that we also keep track
of the transaction id.
2020-03-09 15:30:26 -04:00
Jarrod Johnson b9fc9b3c19 Put the recvmsg info into the handler payload
This allows the rest of the discovery infrastructure to operate
with this data.
2020-03-09 15:14:05 -04:00
Jarrod Johnson 49b8e12a01 Update TODO
We have now done IP_PKTINFO, but there is a potential TODO
if wanting to properly honor unicast request.

For now, will just do always-broadcast as the options to do unicast
are more complex to do (either construct the packets or inject neigh
entry manually)
2020-03-09 15:05:19 -04:00
Jarrod Johnson f20fb70336 Have the peer and target info on DHCP receive
This has the data that will be handy in formulating a reply.
2020-03-09 14:39:53 -04:00
Jarrod Johnson 934f8f0f20 Use recvmsg for PXE
Switch to recvmsg in preparation for getting more
data for forming replies.
2020-03-09 11:25:38 -04:00
Jarrod Johnson 945b8f2b4a Rename to reflect more function than CA 2020-03-09 08:52:29 -04:00
Jarrod Johnson 82921fb53d Add function to sign SSH key
This will enable the known_hosts
to work.

shosts.equiv and sshd and ssh client
config will be handled elsewhere.
shosts.equiv will just be everything.
2020-03-06 16:55:06 -05:00
Jarrod Johnson 59a0b00208 Flesh out the SSH code more
Notably add user key management
and start poking things in
/var/lib/confluent
2020-03-06 16:17:53 -05:00
Jarrod Johnson 34f2f6e359 Add a sample for doing SSH CA
This will explore the concept for the
backend of the get certificate api.
2020-03-06 13:43:54 -05:00
Jarrod Johnson 7fe47baab3 Fix another python 3 expectation
python3 needs this stringified from socket that
provides bytes.
2020-03-02 16:42:42 -05:00
Jarrod Johnson 3c1453c16b Actually use the de-lla address
After removing the %, actually use the trimmed address.
2020-03-02 16:23:18 -05:00
Jarrod Johnson 4529924cce Fix credserver python3 and LLA support
Both client and server had an issue with LLA, along with the
usual python3-isms.
2020-03-02 16:06:07 -05:00
Jarrod Johnson 97ddd59dbd Merge branch 'osdeploy' of github.com:jjohnson42/confluent into osdeploy 2020-03-02 14:55:11 -05:00
Jarrod Johnson b7b2522f6b Fix python3 compatibility of ssdp
The ssdp module in osdeploy was not reacting
adequately to copernicus.  fix the assumptions about bytes
versus str.
2020-03-02 14:54:23 -05:00
Jarrod Johnson bd0e187525 Merge branch 'master' into osdeploy 2020-03-02 13:15:22 -05:00
Jarrod Johnson 634e5a8944 Update gitignore 2020-03-02 13:15:09 -05:00
Jarrod Johnson 455b637c48 Merge branch 'master' into osdeploy 2020-03-02 11:30:30 -05:00
Jarrod Johnson 67e3530d16 Add group count to collate
Feature request to offer the
ability to count output groups
rather than actually show output
groups.
2020-03-02 11:29:28 -05:00
Jarrod Johnson e257d526c3 Have ip_on_same_subnet normalize ::ffff: addresses
This will cause the ips to count as equivalent rather than giving up
on them.
2020-02-27 17:03:12 -05:00
Jarrod Johnson a066f061c7 Remove IPv6 portion of IPv4 address
If it is presented as an IPv6 compatible IPv4 address,
make it a normal IP address.
2020-02-27 16:59:32 -05:00
Jarrod Johnson 29b4045817 Omit TRANS.TBL files from osimport
Avoid clutter of TRANS.TBL files while importing an ISO
2020-02-27 16:36:47 -05:00
Jarrod Johnson f798239f90 Switch to using the standard confluent port for credserver
Also add a check and only accept API arming
requests from local ips
2020-02-27 16:36:16 -05:00
Jarrod Johnson f955086cc3 Create an alternative api.armed behavior
Move from a clock based expiration to a simpler 'once' versus
'continous' model.  'once' is intended to be used generally, 'continuous'
for stateless without benefit of TPM.  The goal would be to use TPM
to seal a key to avoid continuous.
2020-02-27 13:33:05 -05:00
Jarrod Johnson cd20a23626 Merge branch 'master' into osdeploy 2020-02-27 07:20:20 -05:00
Jarrod Johnson 3c26beda1d Fix loss of web connectivity during XCC discovery
The password policy was incorrectly logging out in the
middle of the flow when a forced password change occurred.
Fix by externally managing the web session.
2020-02-26 10:00:10 -05:00
Jarrod Johnson 54be209f4e Merge branch 'nodesearch' into osdeploy 2020-02-24 16:26:07 -05:00
Jarrod Johnson 114324f513 Add CA to self signed cert constraints
Some applications require this be set for it to work
as an enrolled certificate.  Notably UEFI
requires this.
2020-02-24 15:34:55 -05:00
Jarrod Johnson d2de4ffa14 Fix single file OS image osimport 2020-02-21 14:25:18 -05:00
Jarrod Johnson d4483bb59f Polish up the osimport concept more 2020-02-21 14:18:15 -05:00
Jarrod Johnson 90bec92d1f Fix python3 for os import
Need to be explicit about binary data with python 3.
2020-02-21 09:34:49 -05:00
Jarrod Johnson 4b3541e21d Suppress libarchive logging
libarchive ffi goes crazy logging at *import* time.  Pre-empt
use of the logging with a null handler prior to import.
2020-02-21 08:46:42 -05:00
Jarrod Johnson 737e7a440f Add a prototype for imageimporter
This is a sample of fingerprinting, covering rhel/centos 7/8
and suse enterprise 12/15 and cumulus.

Mainly to run the gamut of detection schemes.

The schemes are for iso images, try to be very careful and adaptive.

Otherwise, go for a quick sum to see if we have a shot and a long checksum to confirm.
2020-02-20 23:24:42 -05:00
Jarrod Johnson 24874bb4be Merge branch 'master' into nodesearch 2020-02-20 20:37:23 -05:00
Jarrod Johnson e2d0e49fc7 Add HTTP boot architecture to pxe
This paves the way for future response to HTTP boot
2020-02-20 20:36:36 -05:00
Jarrod Johnson da5a34c2e4 Fix wheezy builds 2020-02-20 08:05:21 -05:00
Jarrod Johnson 3629cb8ee7 Fix spelling of cumulus 2020-02-19 16:53:35 -05:00
Jarrod Johnson 8233e0a5bd Merge branch 'master' of github.com:jjohnson42/confluent 2020-02-19 16:26:48 -05:00
Jarrod Johnson eae7b3bd80 Add discovery snoop for Cumulus ZTP
When a cumulus switch does ZTP, detect
in the discovery facility.
2020-02-19 16:26:33 -05:00
Jarrod Johnson 868367e052 Add sensing of ONIE switches
Have nodediscover show detected
ONIE install devices.
2020-02-19 15:20:45 -05:00
Jarrod Johnson 6289cfaac4 Fix nodeboot when used with -m
nodeboot was erroneously using sys.argv rather
than the processed args from optionparser.
2020-02-19 14:36:10 -05:00
Jarrod Johnson f6d4fef5e6 Improve error message for collective
When trying to not run as root, give a
better error message explaining the
situation more clearly.
2020-02-18 16:16:40 -05:00
Jarrod Johnson b1b7ec4d50 Add affluent plugin
Implementing Cumulus NOS
support through an agent called
'affluent'.
2020-02-18 14:23:57 -05:00
Jarrod Johnson c0cd6de4f7 Remove PrivateDevices from unit file
PrivateDevices breaks pam_unix, for some reason.  Remove this
protection.  We still have DevicePolicy closed and running as non-root,
so this should still be relatively safe.i
2020-02-13 11:42:21 -05:00
Jarrod Johnson 4437e81e04 Leverage unix_chkpwd
If doing PAM authentication, we
can setuid to the target user and then
pam_unix will use unix_chkpwd on
our behalf.

Problems with this working in the lab
was resolved by a yum reinstall pam,
so it was presumably due to messed up
setcap or similar experiments.
2020-02-13 10:37:15 -05:00
Jarrod Johnson 6a12af1242 Remove non-root for older distributions
Older systemd does not support capabilities.  For such a platform,
disable non-root mode.
2020-02-12 13:20:08 -05:00
Jarrod Johnson 9879a83a10 Fix mistake in the redfish access protection
It contained a syntax error.
2020-02-11 14:22:19 -05:00
Jarrod Johnson cce6b824de Merge branch 'master' of github.com:jjohnson42/confluent 2020-02-11 14:09:51 -05:00
Jarrod Johnson ce1cb952e8 Fix PAM authentication
It's tricky.  On Redhat platforms, we need the CAP_DAC_READ_SEARCH
capability.  Unfortunately this is one of the nicest capabilities to have.

For now add it to ambient set so that PAM can work on redhat platforms.
Mitigate this risk by safeguarding the license handling code, which
is the only known place that can read a file and send it to somewhere.

If we could drop the capability from effective set and add it back in when
needed, that would be nice, but that appears not to be possible.

Short of that, having a separate authentication process
running and dropping privilege would potentially work.
2020-02-11 14:09:22 -05:00
Jarrod Johnson c6812274e4 Fix media list through collective
The Media class was not
serializable by msgpack.  Fix this
and improve error messages in
future instances of this behavior.
2020-02-11 09:04:49 -05:00
Jarrod Johnson 7cd7068dd7 Remove stray developer output
Remove a developer repr from log
output.
2020-02-07 16:01:29 -05:00
Jarrod Johnson 48f0330568 Add affluent support to /networking
The /networking backend will now
check for affluent on the switches and
use it if possible for improved performance.
2020-02-07 15:57:33 -05:00
Jarrod Johnson 66e1d17d28 Have systemd manage confluent run dir
The run directory has to be created and owned by confluent,
or else things cannot start.
2020-02-06 13:45:46 -05:00
Jarrod Johnson 7480494432 Tighten up new PAM check
For one, remove the password cache cleaning, as it no longer is run.

For another, skip the fork if uid is already 0.

Finally, wrap the check in a try/finally to keep the privileged process
more certain in exiting.
2020-02-06 10:05:57 -05:00
Jarrod Johnson 49c00bfbb7 Become root to check a password
Running as non-root had broken PAM support.  Allow setuid so we
can assume root in one specific case.
2020-02-05 16:06:13 -05:00
Jarrod Johnson 201985dd0e Fix missing argument to rpc_set_user
Requests were unable to traverse
a collective.
2020-02-05 14:55:51 -05:00
Jarrod Johnson 1aee19997a Carry errors across msgpack
Messages that were formerly carried
as pickled exceptions are now sent
as generic strings over msgpack.
2020-02-04 10:16:48 -05:00
Jarrod Johnson 3bc366bef4 Fix mistake in the cert util 2020-02-03 15:37:20 -05:00
Jarrod Johnson 4c83a1a04e Fix typos
Previous commit had errors in
quotations.
2020-02-03 11:13:13 -05:00
Jarrod Johnson cfae28a869 Add error mesasges to help with non-root confluent
non-root confluent daemon will have a larger struggle
with permissions, try to help the user navigate that.
2020-02-03 10:13:26 -05:00
Jarrod Johnson 44e6a72847 Switch to using the defined service
For now, this makes no difference, but it is poor form,
probably.  Correct by referencing the variable
name.
2020-02-03 09:57:02 -05:00
Jarrod Johnson 006fdc8280 Merge branch 'master' of github.com:jjohnson42/confluent 2020-02-02 18:19:06 -05:00
Jarrod Johnson 895b5264f6 Fix incorrect pam service
pam was defaulting to use of 'login', but we want 'confluent' for the service.
2020-02-02 18:18:39 -05:00
Jarrod Johnson 0b577af1ca Fix ownership of confluent cache
It needs to be owned by the confluent user.
2020-01-31 11:48:34 -05:00
Jarrod Johnson ff0b1bba7f Fix rpm spec file
There was an ommision and a mistake.
2020-01-31 10:37:49 -05:00
Jarrod Johnson 0badd9e5b4 Migrate confluent installs to non-root
This will check for and repair uid 0 owned confluent directories.
2020-01-31 10:16:33 -05:00
Jarrod Johnson c02064f0a5 Add missing msgpack dependencies 2020-01-31 10:02:38 -05:00
Jarrod Johnson c1b82d8163 Protect confluent private data
This blocks use of private confluent data in commands like
nodelicense, nodefirmware, and nodemedia.
2020-01-31 10:00:35 -05:00
Jarrod Johnson 0d5fa7a98a Change confluent to run as non-root and harden systemd
This mitigates a great deal of risk compared to prior behavior.
2020-01-31 09:52:52 -05:00
Jarrod Johnson 968efe719a Add CAP_NET_BIND_SERVICE to unit file
This is preparing for running as non-root.

We need this capability to snoop SLP and PXE
2020-01-31 09:34:13 -05:00
Jarrod Johnson 7a63ca8759 Fix python3 problem with confetty
Under python3, there is no unicode.
2020-01-31 08:53:42 -05:00
Jarrod Johnson a24866c2df Fix exitcode for confetty noderange commands
The exitcode was not being set for noderange commands
where each node may independently raise errors.

Correct the oversight by catching each subelements errors.
2020-01-31 08:22:20 -05:00
Jarrod Johnson c666b11138 Add ability to foreground exec confluent
This allows easier debug and option for unit file
in systemd to run foreground if it makes sense.
2020-01-31 08:10:01 -05:00
Jarrod Johnson 22f6198f60 Fix nodebmcreset on bad noderange
This prevents confusing python stack when
a bad noderange is specified.
2020-01-30 14:35:58 -05:00
Jarrod Johnson c99d01dffc Fix indentation of date conversion
The conversion was not checking each element.
2020-01-29 17:08:00 -05:00
Jarrod Johnson 8d0028a1de Catch all for serialization errors
Rather than odd bool error, return something a
bit more precise.
2020-01-29 15:45:27 -05:00
Jarrod Johnson bb9c2297c9 Stringify firmware datetime
With the change to msgpack, datetime objects cannot be serialized.  Apply
tlvdata compliant transform before storing.
2020-01-29 15:41:13 -05:00
Jarrod Johnson 91fa5bd1eb Enhance nodeconfig treatment of IMM
This makes the IMM attributes usable, but not intrusive.
2020-01-29 14:20:56 -05:00
Jarrod Johnson ac9609c40d Adjust to pyghmi api change
Due to confusion of mixed settings, pyghmi api changes
to enable the confluent experience to be more
sane.
2020-01-29 10:56:31 -05:00
Jarrod Johnson 0c4cb49c20 Implement nodeconfig -e
This provides access to 'extra' settings.
Mainly intended to avoid slowing down nodeconfig
with IMM attributes that most people don't
want anyway.
2020-01-29 10:15:32 -05:00
Jarrod Johnson 4be4100014 Fix configmanager msgpack
msgpack method had some regressions.  For one, python2 strings
became bytes on mixed collective, fix by using raw=False on the
receiver.

Additionally, del_nodes tends to use sets, and that's not viable for
msgpack.  Guard against that.
2020-01-29 09:24:57 -05:00
Jarrod Johnson 9f7c8c69f2 Fix invalid credentials msgpack
The invalid credentials did not accept an argument like
the rest, fix the inconsistency for msgpack deserialization.
2020-01-28 15:41:50 -05:00
Jarrod Johnson c35f7d99f7 Update stripped exceptions to include node
While the exception had the node name, in some contexts the
exception was processed genericly.
2020-01-28 10:18:58 -05:00
Jarrod Johnson 445950d02a Roll back library level force of role
Doing collective and config restore breaks.  The API
will still prevent implicit role assumption.
2020-01-28 10:05:04 -05:00
Jarrod Johnson cf72cf2d8c Require role explicitly on user/group creation
Rather than default to administrator, require
the user to explicitly set the role to administrator.
2020-01-27 16:12:03 -05:00
Jarrod Johnson 0652a7321b Apply whitelist to rpc functions in configmanager 2020-01-27 15:59:22 -05:00
Jarrod Johnson 4c8ba92856 Change configuration sync to use msgpack
This removes use of pickle for config sync over network.
2020-01-27 15:53:29 -05:00
Jarrod Johnson 09582d7597 Move input handling to destination
It is tricky to serialize a configmanager object, and
probably was making the requests gigantic anyway.

Serialize the parameters to let the target use its local copy instead
of serializing an entire config manager.
2020-01-27 15:26:54 -05:00
Jarrod Johnson 8a9e9aa7b3 Always use string type in msgpack
To facilitate py2/py3 consistency, for these
messages just always use the native string.
With this, python 2 strings will be unpacked as
strings by python 3.  This means bytes cannot be
passed, but we will suffer that limitation for now.
2020-01-24 14:07:34 -05:00
Jarrod Johnson b766e7b0ee Opt into the msgpack 1.0 behavior
This fixes the dispatch to actually work.
2020-01-24 11:39:44 -05:00
Jarrod Johnson 92699e47f2 Merge tag '2.4.1'
2.4 bugfix release
2020-01-24 09:59:29 -05:00
Jarrod Johnson 2aa9910d83 Fix XCC discovery issues
A couple of issues could occur during discover that should be
stepped over.
2020-01-23 08:45:43 -05:00
Jarrod Johnson 18b6398c64 Fix XCC discovery issues
A couple of issues could occur during discover that should be
stepped over.
2020-01-23 08:44:17 -05:00
Jarrod Johnson 47b68e4258 Fix dispatch of redfish and tsmsol
redfish and tsmsol was not properly marked as
needing dispatch.
2020-01-22 15:04:43 -05:00
Jarrod Johnson 79b6d099ab Fix attribute sort with python 3
For attributes without a sortid, sort was failing with python3
2020-01-22 14:24:58 -05:00
Jarrod Johnson 604ebcde3b Merge branch 'master' of github.com:jjohnson42/confluent 2020-01-22 14:24:21 -05:00
Jarrod Johnson b4b733a573 Fix attribute sort with python 3
For attributes without a sortid, sort was failing with python3
2020-01-22 14:24:10 -05:00
Jarrod Johnson 3bf083deb3 Stage 3 of msgpack for dispatch
This may complete the dispatch portion of the msgpack migration.
2020-01-21 14:15:14 -05:00
Jarrod Johnson 9d770632ce Merge branch 'master' of github.com:jjohnson42/confluent 2020-01-21 13:44:04 -05:00
Jarrod Johnson 79afd174c9 Add serialization to ConfluentExceptions
In the same manner that messages
are handled, handle non-messages
content.
2020-01-21 11:28:08 -05:00
Jarrod Johnson 13a0bf4fbe Draft for message serialization
This adds msgpack based serialization to messages.

This would be used to superesed pickle in core.
2020-01-16 16:42:32 -05:00
Jarrod Johnson f1e1d9804a Use python3 for Debian and Ubuntu except for wheezy 2020-01-14 09:52:16 -05:00
Jarrod Johnson 546296ce71 Have the get_webclient always return two elements
Some scenario existed where the function could return
None and this could break code expectations that it
always returned a tuple and the first value needs
to be checked for None.
2020-01-08 10:17:06 -05:00
Jarrod Johnson 954b2dd15c Fix minor formatting issues in source 2020-01-07 09:38:40 -05:00
Jarrod Johnson a7b11d1e15 Fix closing ipmi session when not mapped
When not mapped, a noisy KeyError was occuring.  Handle
it to avoid cluttering log if the work is not needed.
2019-12-10 14:38:12 -05:00
Jarrod Johnson 3660cf18cc Fix a number of issues
For one, there were still bytes v. str for python3 issues in the
certificate exception and credential handling for smm and generic
credential lookup.

There was a python2-ism in lldp that needed to be made 2/3 agnostic
with ord() of a 'bytes' member, converting to bytearray for
normalized behavior.

The discovery core had an issue with chained smms where a set
was used which cannot take a dict, and so it is converted to a list.

If a temporary password is used but the user did not provide a permanent
password that is viable, make the error more explicit.
2019-12-10 11:54:24 -05:00
Jarrod Johnson 078afaf7d7 Make SLP more tolerant of malformed data
Unrelated devices may present invalid data
to SLP queries.  Have these conditions better tolerated.
2019-12-06 11:24:30 -05:00
Jarrod Johnson 3ab1eb7f01 Add words to nodefirmware man page
ipmi versus redfish produces some different behaviors, document
some examples in the man page.
2019-12-04 10:14:23 -05:00
Jarrod Johnson fbfdc9322b Raise errors during connection
This improves error behavior when login action
encounters an error.
2019-12-04 10:06:18 -05:00
Jarrod Johnson ef68656bde Fix nodestorage handling of error
Error messages were not properly handled if specific nodes had issues.
Properly provide the error messages.

Additionally, clarify a common uselessly vague error.
2019-12-03 10:04:34 -05:00
Jarrod Johnson 0e04b853f6 Fix common usage of noderange alerts
This fixes the usual circumstance of not having keyed input data.
2019-11-21 16:42:03 -05:00
Jarrod Johnson 63256e37b6 Remove some uses of xrange
Not friendly to python 3
2019-11-21 16:03:48 -05:00
Jarrod Johnson a1b81e978b Pull in websocket client dependency
This enables tsmsol plugin
2019-11-20 15:25:11 -05:00
Jarrod Johnson 06c53e9d89 Make the websocket module optional
Have tsmsol gracefully degrade for Wheezy, where
it is not relevant to that platform.
2019-11-20 13:53:16 -05:00
Jarrod Johnson ab0168b2ec Update man page for nodesupport
Correct typo and clarify that plugins may customize
filenames.
2019-11-20 10:48:08 -05:00
Jarrod Johnson 473bb39c54 Fix packaging omission of console plugins 2019-11-20 10:04:38 -05:00
Jarrod Johnson a48ecd8c78 Add hardware and firmware info to CNOS
CNOS devices now have nodefirmware and nodeinventory.
2019-11-15 16:08:28 -05:00
Jarrod Johnson 30398fc434 More explicit follower health checking
Be more careful about collective member health assessment,
explicitly closing a follower when it has failure and prefacing
collective commands with a check prior to performing the actual
changes.
2019-11-11 10:49:25 -05:00
Jarrod Johnson 0ed7e4eac3 Merge branch 'master' of github.com:jjohnson42/confluent 2019-11-07 11:26:04 -05:00
Jarrod Johnson 0d2999c7a8 Properly relay errors on console start
Rather than always saying console.method is not set, relay
the str of the exception to give a more accurate info.
2019-11-07 11:25:49 -05:00
Jarrod Johnson 75010ac6f0 Guard against accidental node duplication
If two nodes have same bmc, block one of them to prevent massive
fluctuation back and forth.
2019-11-07 11:10:26 -05:00
Jarrod Johnson a748cc3032 Remove incorrect check for HOSTUNREACH
This seems incorrect and further redundant with other portions
of the code.  This was causing a 'has no len()' error when encountered.
2019-11-05 13:28:12 -05:00
Jarrod Johnson 28bb143880 Recognize drive in rebuilding state
The rebuilding state was not recognized, add that state.
2019-11-04 14:16:02 -05:00
Jarrod Johnson 4b6899d4af Mark node as 'dirty' if it's group is removed
Group removal would end up with the on-disk copy not reflecting
the node membership, even though in-memory copy is fine.
Fix by adding the missing dirty mark to the entry.
2019-11-04 13:43:29 -05:00
Jarrod Johnson a175fd7345 Allow autosuffix to change passed filename
The resultant file may deviate and thus the chown
must have the updated name.
2019-10-29 16:06:51 -04:00
Jarrod Johnson 12bd473c0d Remove stray debug output 2019-10-29 15:50:48 -04:00
Jarrod Johnson a967c224fe Add TSMSOL plugin
This enables ipmi-free access to TSM SOL console
2019-10-29 15:20:40 -04:00
Jarrod Johnson 72a5f37232 Fix mid-line command completion
Use COMP_CWORD instead of -1 to dynamically decide where to
do completion and what candidates to offer
2019-10-24 15:27:17 -04:00
Jarrod Johnson 5c081a8e2c Remove SYSV init script from RPM packages
All supported RPM distros are systemd now...
2019-10-24 12:16:17 -04:00
Jarrod Johnson c0b69f64b8 Error when noderange tries to use secret
secret. cannot be used in expressions, provide
an error in such a case.
2019-10-24 12:04:47 -04:00
Jarrod Johnson f7fe38f498 Fix problem with reassign and TSM 2019-10-24 10:29:58 -04:00
Jarrod Johnson 5ae949b4eb Add UUID to TSM discovery
The UUID is now available in redfish,
use that to get the UUID.
2019-10-24 10:23:59 -04:00
Jarrod Johnson cec6918c1a Support unsupported bad disks 2019-10-23 17:02:37 -04:00
Jarrod Johnson 3df7a36c48 Fix a number of issues with maxnodes
Some commands did not function correctly
after modifications.
2019-10-23 16:47:42 -04:00
Jarrod Johnson 559e96f7ff Fix location of calling the noderange check 2019-10-23 16:27:18 -04:00
Jarrod Johnson 6f568919e1 Correct instance callout
The wrong value was called out
2019-10-23 15:57:16 -04:00
Jarrod Johnson c441739f68 Try a less jarring exit strategy
Have client not provide a developer looking trace on abort.
2019-10-23 14:41:57 -04:00
Jarrod Johnson a43361bb98 Amend the prompt for single node prompting
Remove the trailing slash
2019-10-23 14:38:45 -04:00
Jarrod Johnson 620263db3e Add maxnodes argument to potentially risky commands
This uses the client maxnodes check to double check.  Useful
for clients that want to sanity check unexpectedly large numbers of
nodes.
2019-10-23 14:20:40 -04:00
Jarrod Johnson dd096104cc Provide mechanism to prompt on large noderanges
Some commands can add options to prompt, and can have that option be
only activated on noderanges over a
certain size.
2019-10-22 15:49:09 -04:00
Jarrod Johnson 191ae762ab Use autosuffix feature of pyghmi
This produces output that is more consistent with support by vendors.
2019-10-22 15:17:31 -04:00
Jarrod Johnson f866b7379c Always relax minimum password interval on auto change
The preconfig could interfere with normal operations.
2019-10-22 10:51:41 -04:00
Jarrod Johnson aab6160d49 Fix compatibility between new and old TSM firmware 2019-10-21 16:20:54 -04:00
Jarrod Johnson e1dffe7c3a Fix compatibility with newer TSM firmware
TSM stopped accepting url encoded, switch to json.  This should work
for older and newer firmware.
2019-10-21 14:39:27 -04:00
Jarrod Johnson 97ca6dc48e Provide more detail on leader when leader is lost 2019-10-21 13:55:43 -04:00
Jarrod Johnson 1d59e1da8c Fix unicode issues in HTML api explorer 2019-10-17 15:36:51 -04:00
208 changed files with 8992 additions and 644 deletions
+4 -1
View File
@@ -1 +1,4 @@
.idea
*.pyc
.*.
confluent_client/man/man*
.*.sw*
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/python
import os
import sys
path = os.path.dirname(os.path.realpath(__file__))
try:
sys.path.remove(path)
except Exception:
pass
path = os.path.realpath(os.path.join(path, '..', 'confluent_server'))
sys.path.append(path)
import confluent.config.attributes as attr
import shutil
shutil.copyfile('doc/man/nodeattrib.ronn.tmpl', 'doc/man/nodeattrib.ronn')
shutil.copyfile('doc/man/nodegroupattrib.ronn.tmpl', 'doc/man/nodegroupattrib.ronn')
with open('doc/man/nodeattrib.ronn', 'a') as outf:
for field in sorted(attr.node):
outf.write('\n* `{0}`:\n {1}\n'.format(field, attr.node[field]['description']))
with open('doc/man/nodegroupattrib.ronn', 'a') as outf:
for field in sorted(attr.node):
outf.write('\n* `{0}`:\n {1}\n'.format(field, attr.node[field]['description']))
+11 -3
View File
@@ -43,6 +43,8 @@ argparser.add_option('-d', '--diff', action='store_true',
'output group and others')
argparser.add_option('-w', '--watch', action='store_true',
help='Show intermediate results while running')
argparser.add_option('-g', '--groupcount', action='store_true',
help='Show count of output groups rather than the actual output')
argparser.add_option('-s', '--skipcommon', action='store_true',
help='Do not print most common result, only non modal '
'groups, useful when combined with -d')
@@ -69,6 +71,9 @@ def print_current():
if options.diff:
grouped.print_deviants(skipmodal=options.skipcommon, count=options.count,
reverse=options.reverse, basenode=options.base)
elif options.groupcount:
grouped.generate_byoutput()
print(len(grouped.byoutput))
else:
grouped.print_all(skipmodal=options.skipcommon,
count=options.count,
@@ -83,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
+19 -4
View File
@@ -76,6 +76,11 @@ import confluent.termhandler as termhandler
import confluent.tlvdata as tlvdata
import confluent.client as client
try:
unicode
except NameError:
unicode = str
conserversequence = '\x05c' # ctrl-e, c
clearpowermessage = False
@@ -287,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:
@@ -299,8 +306,11 @@ currchildren = None
def print_result(res):
global exitcode
if 'errorcode' in res or 'error' in res:
print(res['error'])
if 'errorcode' in res:
exitcode |= res['errorcode']
return
if 'databynode' in res:
print_result(res['databynode'])
@@ -904,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
@@ -949,7 +958,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
@@ -957,7 +972,7 @@ def main():
try:
server_connect()
connected = True
except (socket.gaierror, socket.error):
except Exception:
pass
if not connected:
time.sleep(1)
+50 -16
View File
@@ -1,19 +1,53 @@
#!/bin/sh
#!/usr/bin/python
# This will take a given directory and make a 'big floppy image'
# out of it, suitable for nodemedia upload.
if [ -z "$1" -o -z "$2" ]; then
echo "Usage: $0 <directory> <imagefile>"
exit 1
fi
# Get the needed payload side
SIZE=$(du -sB 512 $1|awk '{print $1}')
ENTRIES=$(find $1 |wc -l)
# Also, each file and directory has overhead, pad size by 32kb per file,
# which should be overkill but other values proved to be inadequate
# A deeper understanding of VFAT would probably allow for more precise value
SIZE=$((SIZE + ENTRIES * 64))
dd if=/dev/zero of=$2 bs=512 count=$SIZE
# Make a big single sided floppy with many many tracks, saves on complex math
mformat -i $2 -d 1 -t $SIZE -s 1 -h 1 ::
mcopy -i $2 -s $1/* ::
import fcntl
import glob
import os
import subprocess
import sys
def create_image(directory, image):
ents = 0
datasz = 512
for dir in os.walk(sys.argv[1]):
ents += 1
for filen in dir[2]:
ents += 1
filename = os.path.join(dir[0], filen)
currsz = os.path.getsize(filename)
# assuming up to 65k cluster
currsz = (currsz // 512 +1) * 512
datasz += currsz
datasz += ents * 32768
datasz = datasz // 512 + 1
with open(image, 'wb') as imgfile:
imgfile.seek(datasz * 512 - 1)
imgfile.write(b'\x00')
subprocess.check_call(['mformat', '-i', image, '-r', '16', '-d', '1', '-t',
str(datasz), '-s', '1','-h', '1', '::'])
# 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__':
if len(sys.argv) < 3:
sys.stderr.write("Usage: {0} <directory> <imagefile>".format(
sys.argv[0]))
sys.exit(1)
create_image(sys.argv[1], sys.argv[2])
+4
View File
@@ -50,6 +50,9 @@ argparser.add_option('-c', '--clear', action='store_true',
help='Clear attributes')
argparser.add_option('-p', '--prompt', action='store_true',
help='Prompt for attribute values interactively')
argparser.add_option('-m', '--maxnodes', type='int',
help='Prompt if trying to set attributes on more '
'than specified number of nodes')
(options, args) = argparser.parse_args()
@@ -87,6 +90,7 @@ if len(args) > 1:
if oneval != twoval:
print('Values did not match.')
argassign[arg] = twoval
session.stop_if_noderange_over(noderange, options.maxnodes)
exitcode=client.updateattrib(session,args,nodetype, noderange, options, argassign)
try:
# setting user output to what the user inputs
+5 -1
View File
@@ -32,6 +32,8 @@ if path.startswith('/opt'):
import confluent.client as client
argparser = optparse.OptionParser(usage="Usage: %prog <noderange>")
argparser.add_option('-m', '--maxnodes', type='int',
help='Number of nodes to affect before prompting for confirmation')
(options, args) = argparser.parse_args()
try:
noderange = args[0]
@@ -43,8 +45,10 @@ session = client.Command()
exitcode = 0
errorNodes = set([])
session.stop_if_noderange_over(noderange, options.maxnodes)
success = session.simple_noderange_command(noderange, 'configuration/management_controller/reset', 'reset', key='state', errnodes=errorNodes) # = 0 if successful
if success != 0:
sys.exit(success)
# Determine which nodes were successful and print them
+7 -2
View File
@@ -42,6 +42,10 @@ argparser.add_option('-p', '--persist', dest='persist', action='store_true',
default=False,
help='Request the boot device be persistent rather than '
'one time')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to boot, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
@@ -54,8 +58,8 @@ except IndexError:
sys.exit(1)
client.check_globbing(noderange)
bootdev = None
if len(sys.argv) > 2:
bootdev = sys.argv[2]
if len(args) > 1:
bootdev = args[1]
if bootdev in ('net', 'pxe'):
bootdev = 'network'
session = client.Command()
@@ -66,6 +70,7 @@ else:
bootmode = 'uefi'
errnodes = set([])
session.stop_if_noderange_over(noderange, options.maxnodes)
rc = session.simple_noderange_command(noderange, '/boot/nextdevice', bootdev,
bootmode=bootmode,
persistent=options.persist,
+29 -6
View File
@@ -54,6 +54,12 @@ argparser.add_option('-d', '--detail', dest='detail',
action='store_true', default=False,
help='Provide verbose information as available, such as '
'help text and possible valid values')
argparser.add_option('-e', '--extra', dest='extra',
action='store_true', default=False,
help='Access extra configuration. Extra configuration is generally '
'reserved for unpopular or redundant options that may be slow to '
'read. Notably the IMM category on Lenovo settings is considered '
'to be extra configuration')
argparser.add_option('-x', '--exclude', dest='exclude',
action='store_true', default=False,
help='Treat positional arguments as items to not '
@@ -68,6 +74,10 @@ argparser.add_option('-r', '--restoredefault', default=False,
help='Restore the configuration of the node '
'to factory default for given component. '
'Currently only uefi is supported')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to configure, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
cfgpaths = {
@@ -99,6 +109,7 @@ assignment = {}
queryparms = {}
printsys = []
printbmc = []
printextbmc = []
printallbmc = False
setsys = {}
forceset = False
@@ -173,11 +184,17 @@ def parse_config_line(arguments):
del queryparms[path]
except KeyError:
pass
if not matchedparms:
if param.lower() == 'imm':
printextbmc.append(param)
options.extra = True
elif not matchedparms:
printsys.append(param)
elif param not in cfgpaths:
if param.startswith('bmc.'):
printbmc.append(param.replace('bmc.', ''))
elif param.lower().startswith('imm'):
options.extra = True
printextbmc.append(param)
else:
printsys.append(param)
else:
@@ -205,6 +222,7 @@ else:
session = client.Command()
rcode = 0
if options.restoredefault:
session.stop_if_noderange_over(noderange, options.maxnodes)
if options.restoredefault.lower() in (
'sys', 'system', 'uefi', 'bios'):
for fr in session.update(
@@ -225,6 +243,7 @@ if options.restoredefault:
options.restoredefault))
sys.exit(1)
if setmode:
session.stop_if_noderange_over(noderange, options.maxnodes)
if options.exclude:
sys.stderr.write('Cannot use exclude and assign at the same time\n')
sys.exit(1)
@@ -269,10 +288,15 @@ else:
NullOpt(), queryparms[path])
if rc:
sys.exit(rc)
if printbmc or printallbmc:
rcode = client.print_attrib_path(
'/noderange/{0}/configuration/management_controller/extended/all'.format(noderange),
session, printbmc, options, attrprefix='bmc.')
if printsys == 'all' or printextbmc or printbmc or printallbmc:
if printbmc or not printextbmc:
rcode = client.print_attrib_path(
'/noderange/{0}/configuration/management_controller/extended/all'.format(noderange),
session, printbmc, options, attrprefix='bmc.')
if options.extra:
rcode |= client.print_attrib_path(
'/noderange/{0}/configuration/management_controller/extended/extra'.format(noderange),
session, printextbmc, options)
if printsys or options.exclude:
if printsys == 'all':
printsys = []
@@ -281,7 +305,6 @@ else:
else:
path = '/noderange/{0}/configuration/system/advanced'.format(
noderange)
rcode = client.print_attrib_path(path, session, printsys,
options)
sys.exit(rcode)
+11 -10
View File
@@ -51,27 +51,28 @@ if options.tile:
nodes.append(node)
initial = True
pane = 0
sessname = 'nodeconsole_{0}'.format(os.getpid())
for node in sortutil.natural_sort(nodes):
panename = '{0}:{1}'.format(sessname, pane)
if initial:
initial = False
subprocess.call(
['tmux', 'new-session', '-d', '-s',
'nodeconsole_{0}'.format(os.getpid()), '-x', '800', '-y',
sessname, '-x', '800', '-y',
'800', '{0} -m 5 start /nodes/{1}/console/session'.format(
confettypath, node)])
else:
subprocess.call(['tmux', 'select-pane', '-t', str(pane)])
subprocess.call(['tmux', 'set-option', 'pane-border-status', 'top'], stderr=null)
pane += 1
subprocess.call(['tmux', 'select-pane', '-t', sessname])
subprocess.call(['tmux', 'set-option', '-t', panename, 'pane-border-status', 'top'], stderr=null)
subprocess.call(
['tmux', 'split', '-h',
['tmux', 'split', '-h', '-t', sessname,
'{0} -m 5 start /nodes/{1}/console/session'.format(
confettypath, node)])
subprocess.call(['tmux', 'select-layout', 'tiled'], stdout=null)
subprocess.call(['tmux', 'select-pane', '-t', '0'])
subprocess.call(['tmux', 'set-option', 'pane-border-status', 'top'], stderr=null)
os.execlp('tmux', 'tmux', 'attach', '-t', 'nodeconsole_{0}'.format(
os.getpid()))
subprocess.call(['tmux', 'select-layout', '-t', sessname, 'tiled'], stdout=null)
pane += 1
subprocess.call(['tmux', 'select-pane', '-t', sessname])
subprocess.call(['tmux', 'set-option', '-t', panename, 'pane-border-status', 'top'], stderr=null)
os.execlp('tmux', 'tmux', 'attach', '-t', sessname)
else:
os.execl(confettypath, confettypath, 'start',
'/nodes/{0}/console/session'.format(args[0]))
+141
View File
@@ -0,0 +1,141 @@
#!/usr/bin/python3
import argparse
import os
import sys
path = os.path.dirname(os.path.realpath(__file__))
path = os.path.realpath(os.path.join(path, '..', 'lib', 'python'))
if path.startswith('/opt'):
sys.path.append(path)
import confluent.client as client
import confluent.sortutil as sortutil
def 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([])
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': '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),
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('-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', 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('profile is a required argument 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)
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([])
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__':
sys.exit(main(sys.argv[1:]))
+5 -3
View File
@@ -237,10 +237,12 @@ def clear_discovery(options, session):
else:
print(repr(res))
def list_matching_macs(options, session, node=None):
def list_matching_macs(options, session, node=None, checknode=True):
path = '/discovery/'
if node:
path += 'by-node/{0}/'.format(node)
elif checknode and options.node:
path += 'by-node/{0}/'.format(options.node)
if options.model:
path += 'by-model/{0}/'.format(options.model)
if options.serial:
@@ -277,11 +279,11 @@ def assign_discovery(options, session, needid=True):
abort = True
if abort:
sys.exit(1)
matches = list_matching_macs(options, session, None if needid else options.node)
matches = list_matching_macs(options, session, None if needid else options.node, False)
if not matches:
# Do a rescan to catch missing requested data
blocking_scan(session)
matches = list_matching_macs(options, session, None if needid else options.node)
matches = list_matching_macs(options, session, None if needid else options.node, False)
if not matches:
sys.stderr.write("No matching discovery candidates found\n")
sys.exit(1)
+8 -3
View File
@@ -38,6 +38,10 @@ if sys.version_info[0] < 3:
argparser = optparse.OptionParser(
usage="Usage: %prog [options] noderange [clear]")
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to clear if clearing log, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
try:
noderange = args[0]
@@ -46,11 +50,11 @@ except IndexError:
sys.exit(1)
client.check_globbing(noderange)
deletemode = False
if len(sys.argv) > 3:
if len(args) > 2:
argparser.print_help()
sys.exit(1)
if len(sys.argv) == 3:
if sys.argv[2] == 'clear':
if len(args) == 2:
if args[1] == 'clear':
deletemode = True
else:
argparser.print_help()
@@ -88,6 +92,7 @@ def format_event(evt):
if deletemode:
func = session.delete
session.stop_if_noderange_over(noderange, options.maxnodes)
else:
func = session.read
for rsp in func('/noderange/{0}/events/hardware/log'.format(noderange)):
+5
View File
@@ -59,6 +59,10 @@ argparser = optparse.OptionParser(
"%prog <noderange> [list][update [--backup <file>]]|[<components>]")
argparser.add_option('-b', '--backup', action='store_true',
help='Target a backup bank rather than primary')
argparser.add_option('-m', '--maxnodes', type='int',
help='When updating, prompt if more than the specified '
'number of servers will be affected')
(options, args) = argparser.parse_args()
upfile = None
try:
@@ -95,6 +99,7 @@ def get_update_progress(session, url):
def update_firmware(session, filename):
global exitcode
session.stop_if_noderange_over(noderange, options.maxnodes)
output = sq.ScreenPrinter(noderange, session)
nodeurls = {}
filename = os.path.abspath(filename)
+1
View File
@@ -50,6 +50,7 @@ codemappings = {
'warning': 1,
'critical': 2,
'failed': 2,
'unknown': 2,
}
def main():
+9 -10
View File
@@ -37,6 +37,10 @@ exitcode = 0
argparser = optparse.OptionParser(
usage="Usage: "
"%prog <noderange> [list][install <file>|save <directory>|delete <name>]")
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to delete licenses from, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
upfile = None
downdir = None
@@ -52,7 +56,7 @@ try:
delete = args[2]
elif args[1] != 'list':
argparser.print_help()
sys.exit(1)
sys.exit(1)
except IndexError:
argparser.print_help()
sys.exit(1)
@@ -61,10 +65,6 @@ client.check_globbing(noderange)
def install_license(session, filename):
global exitcode
if not os.path.exists(filename):
sys.stderr.write('Unable to locate requested file {0}\n'.format(
filename))
sys.exit(404)
resource = '/noderange/{0}/configuration/' \
'management_controller/licenses/'.format(noderange)
filename = os.path.abspath(filename)
@@ -83,18 +83,16 @@ def save_licenses(session, dirname):
resource = '/noderange/{0}/configuration/' \
'management_controller/save_licenses'.format(noderange)
filename = os.path.abspath(dirname)
if not os.path.exists(filename):
sys.stderr.write('Unable to locate specified directory {0}\n'.format(
filename))
sys.exit(404)
instargs = {'dirname': filename}
for res in session.create(resource, instargs):
for node in res.get('databynode', {}):
fname = res['databynode'][node].get('filename', None)
if fname:
print('{0}: Saved license to {1}'.format(node, fname))
elif 'error' in res['databynode'][node]:
sys.stderr.write('{0}: {1}\n'.format(node, res['databynode'][node]['error']))
else:
sys.stderr.write('{0}: {1}', node, repr(res['databynode'][node]))
sys.stderr.write('{0}: {1}\n'.format(node, repr(res['databynode'][node])))
def show_licenses(session):
@@ -138,6 +136,7 @@ try:
elif downdir:
save_licenses(session, downdir)
elif delete:
session.stop_if_noderange_over(noderange, options.maxnodes)
delete_license(session, delete)
else:
show_licenses(session)
+6 -1
View File
@@ -37,6 +37,11 @@ argparser = optparse.OptionParser(
argparser.add_option('-p', '--showprevious', dest='previous',
action='store_true', default=False,
help='Show previous power state')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to change power state, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
try:
noderange = args[0]
@@ -72,4 +77,4 @@ if options.previous:
# add dictionary to session
session.add_precede_dict(prev)
sys.exit(session.simple_noderange_command(noderange, '/power/state', setstate))
sys.exit(session.simple_noderange_command(noderange, '/power/state', setstate, promptover=options.maxnodes))
+5
View File
@@ -35,6 +35,10 @@ import confluent.client as client
argparser = optparse.OptionParser(
usage='''\n %prog noderange
\n ''')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to delete, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
if len(args) != 1:
argparser.print_help()
@@ -43,6 +47,7 @@ noderange = args[0]
client.check_globbing(noderange)
session = client.Command()
exitcode = 0
session.stop_if_noderange_over(noderange, options.maxnodes)
for r in session.delete('/noderange/{0}'.format(noderange)):
if 'error' in r:
sys.stderr.write(r['error'] + '\n')
+5 -1
View File
@@ -32,6 +32,10 @@ if path.startswith('/opt'):
import confluent.client as client
argparser = optparse.OptionParser(usage="Usage: %prog <noderange>")
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to reseat, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
try:
noderange = args[0]
@@ -43,7 +47,7 @@ session = client.Command()
exitcode = 0
errorNodes = set([])
session.stop_if_noderange_over(noderange, options.maxnodes)
success = session.simple_noderange_command(noderange, 'power/reseat', 'reseat', key='reseat', errnodes=errorNodes) # = 0 if successful
# Determine which nodes were successful and print them
+6 -2
View File
@@ -42,6 +42,10 @@ def run():
argparser = optparse.OptionParser(
usage="Usage: %prog location noderange:location",
)
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to run rsync to, '
'prompting if over the threshold')
argparser.add_option('-f', '-c', '--count', type='int', default=168,
help='Number of nodes to concurrently rsync')
# among other things, FD_SETSIZE limits. Besides, spawning too many
@@ -64,7 +68,7 @@ def run():
pipedesc = {}
pendingexecs = deque()
exitcode = 0
c.stop_if_noderange_over(noderange, options.maxnodes)
for exp in c.create('/noderange/{0}/attributes/expression'.format(noderange),
{'expression': cmdstr}):
if 'error' in exp:
@@ -100,7 +104,7 @@ def run():
if desc['type'] == 'stdout':
if node not in pernodeout:
pernodeout[node] = ''
pernodeout[node] += stringify(data)
pernodeout[node] += client.stringify(data)
if '\n' in pernodeout[node]:
currout, pernodeout[node] = pernodeout[node].split('\n', 1)
if currout:
+5 -1
View File
@@ -46,6 +46,10 @@ def run():
help='Number of commands to run at a time')
argparser.add_option('-n', '--nonodeprefix', action='store_true',
help='Do not prefix output with node names')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to run the command with, '
'prompting if over the threshold')
# among other things, FD_SETSIZE limits. Besides, spawning too many
# processes can be unkind for the unaware on memory pressure and such...
argparser.disable_interspersed_args()
@@ -63,7 +67,7 @@ def run():
pipedesc = {}
pendingexecs = deque()
exitcode = 0
c.stop_if_noderange_over(args[0], options.maxnodes)
for exp in c.create('/noderange/{0}/attributes/expression'.format(args[0]),
{'expression': cmdstr}):
if 'error' in exp:
+6 -2
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|floppy]')
argparser.add_option('-b', '--bios', dest='biosmode',
action='store_true', default=False,
help='Request BIOS style boot (rather than UEFI)')
@@ -43,7 +43,10 @@ argparser.add_option('-p', '--persist', dest='persist', action='store_true',
argparser.add_option('-u', '--uefi', dest='uefi', action='store_true',
default=True,
help='Request UEFI style boot (rather than BIOS)')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to modify next boot device, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
try:
@@ -63,6 +66,7 @@ if options.biosmode:
bootmode = 'bios'
else:
bootmode = 'uefi'
session.stop_if_noderange_over(noderange, options.maxnodes)
sys.exit(session.simple_noderange_command(noderange, '/boot/nextdevice', bootdev,
bootmode=bootmode,
persistent=options.persist))
+11 -2
View File
@@ -46,6 +46,12 @@ def run():
help='Number of commands to run at a time')
argparser.add_option('-n', '--nonodeprefix', action='store_true',
help='Do not prefix output with node names')
argparser.add_option('-p', '--port', type='int', default=0,
help='Specify a custom port for ssh')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to run remote ssh command to, '
'prompting if over the threshold')
# among other things, FD_SETSIZE limits. Besides, spawning too many
# processes can be unkind for the unaware on memory pressure and such...
argparser.disable_interspersed_args()
@@ -64,7 +70,7 @@ def run():
pendingexecs = deque()
exitcode = 0
c.stop_if_noderange_over(args[0], options.maxnodes)
for exp in c.create('/noderange/{0}/attributes/expression'.format(args[0]),
{'expression': cmdstr}):
if 'error' in exp:
@@ -75,7 +81,10 @@ def run():
cmd = ex[node]['value']
if not isinstance(cmd, str) and not isinstance(cmd, bytes):
cmd = cmd.encode('utf-8')
cmdv = ['ssh', node, cmd]
if options.port:
cmdv = ['ssh', '-p', '{0}'.format(options.port), node, cmd]
else:
cmdv = ['ssh', node, cmd]
if currprocs < concurrentprocs:
currprocs += 1
run_cmdv(node, cmdv, all, pipedesc)
+14 -1
View File
@@ -63,10 +63,16 @@ def _print_cfg(scfg):
sys.stderr.write(e['error'] + '\n')
exitcode = e.get('errorcode', 1)
for node in e.get('databynode', {}):
curr = e['databynode'][node]
if 'error' in curr:
if 'no available drives' in curr['error']:
curr['error'] += ' (drives must be in unconfigured state to be available, they must not be in jbod or online state)'
sys.stderr.write('{0}: {1}\n'.format(node, curr['error']))
exitcode = curr.get('errorcode', 1)
continue
if node not in storagebynode:
storagebynode[node] = {'disks': [], 'arrays': [],
'volumes': []}
curr = e['databynode'][node]
storagebynode[node][curr['type'] + 's'].append(curr)
for node in storagebynode:
for disk in sorted(storagebynode[node]['disks'],
@@ -108,6 +114,7 @@ def createstorage(noderange, options, args):
sys.stderr.write('-r and -d are required arguments to create array\n')
sys.exit(1)
session = client.Command()
session.stop_if_noderange_over(noderange, options.maxnodes)
names = options.name
if names is None:
names = ''.join(args)
@@ -132,6 +139,7 @@ def deletestorage(noderange, options, args):
else:
names = options.name
session = client.Command()
session.stop_if_noderange_over(noderange, options.maxnodes)
for rsp in session.delete(
'/noderange/{0}/configuration/storage/volumes/{1}'.format(
noderange, names)):
@@ -162,6 +170,7 @@ def setdisk(noderange, options, args):
sys.stderr.write('diskset requires valid state as argument (hotspare, jbod, unconfigured)\n')
sys.exit(1)
session = client.Command()
session.stop_if_noderange_over(noderange, options.maxnodes)
scfg = session.update('/noderange/{0}/configuration/storage/disks/{1}'.format(noderange, names), {'state': args[0]})
_print_cfg(scfg)
@@ -202,6 +211,10 @@ def main():
help='Comma separated list of stripsizes to use when creating volumes. '
'This value is in kilobytes. The default behavior is to allow the '
'storage controller to decide.')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to configure storage on, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
if len(args) == 1:
args.append('show')
+7 -2
View File
@@ -64,7 +64,7 @@ def printerror(res, node=None):
def download_servicedata(noderange, media):
def download_servicedata(noderange, media, options):
global exitcode
session = client.Command()
output = sq.ScreenPrinter(noderange, session)
@@ -73,6 +73,7 @@ def download_servicedata(noderange, media):
upargs = {'filename': filename}
noderrs = {}
nodeurls = {}
session.stop_if_noderange_over(noderange, options.maxnodes)
for res in session.create(resource, upargs):
if 'created' not in res:
for nodename in res.get('databynode', ()):
@@ -121,6 +122,10 @@ def main():
'management server (the confluent server if running remote, '
'and the collective.manager if in collective)\n'
'\n\nSee `man %prog` for more info.\n')
argparser.add_option('-m', '--maxnodes', type='int',
help='Specify a maximum number of '
'nodes to download diagnostic data from, '
'prompting if over the threshold')
(options, args) = argparser.parse_args()
media = None
try:
@@ -142,6 +147,6 @@ def main():
except KeyError:
argparser.print_help()
sys.exit(1)
handler(noderange, media)
handler(noderange, media, options)
if __name__ == '__main__':
main()
+43 -11
View File
@@ -36,9 +36,15 @@ SO_PASSCRED = 16
_attraliases = {
'bmc': 'hardwaremanagement.manager',
'bmcuser': 'secret.hardwaremanagementuser',
'switchuser': 'secret.hardwaremanagementuser',
'bmcpass': 'secret.hardwaremanagementpassword',
'switchpass': 'secret.hardwaremanagementpassword',
}
try:
input = raw_input
except NameError:
pass
def stringify(instr):
# Normalize unicode and bytes to 'str', correcting for
@@ -219,7 +225,7 @@ class Command(object):
return rc
def simple_noderange_command(self, noderange, resource, input=None,
key=None, errnodes=None, **kwargs):
key=None, errnodes=None, promptover=None, **kwargs):
try:
self._currnoderange = noderange
rc = 0
@@ -235,6 +241,7 @@ class Command(object):
noderange, resource)):
rc = self.handle_results(ikey, rc, res, errnodes)
else:
self.stop_if_noderange_over(noderange, promptover)
kwargs[ikey] = input
for res in self.update('/noderange/{0}/{1}'.format(
noderange, resource), kwargs):
@@ -244,6 +251,33 @@ class Command(object):
except KeyboardInterrupt:
cprint('')
return 0
def stop_if_noderange_over(self, noderange, maxnodes):
if maxnodes is None:
return
nsize = self.get_noderange_size(noderange)
if nsize > maxnodes:
if nsize == 1:
nodename = list(self.read(
'/noderange/{0}/nodes/'.format(noderange)))[0].get('item', {}).get('href', None)
nodename = nodename[:-1]
p = input('Command is about to affect node {0}, continue (y/n)? '.format(nodename))
else:
p = input('Command is about to affect {0} nodes, continue (y/n)? '.format(nsize))
if p.lower() != 'y':
sys.stderr.write('Aborting at user request\n')
sys.exit(1)
raise Exception("Aborting at user request")
def get_noderange_size(self, noderange):
numnodes = 0
for node in self.read('/noderange/{0}/nodes/'.format(noderange)):
if node.get('item', {}).get('href', None):
numnodes += 1
else:
raise Exception("Error trying to size noderange {0}".format(noderange))
return numnodes
def simple_nodegroups_command(self, noderange, resource, input=None, key=None, **kwargs):
try:
@@ -344,12 +378,8 @@ class Command(object):
if fingerprint == khf[hostid]:
return
else:
try:
replace = raw_input(
"MISMATCHED CERTIFICATE DATA, ACCEPT NEW? (y/n):")
except NameError:
replace = input(
"MISMATCHED CERTIFICATE DATA, ACCEPT NEW? (y/n):")
replace = input(
"MISMATCHED CERTIFICATE DATA, ACCEPT NEW? (y/n):")
if replace not in ('y', 'Y'):
raise Exception("BAD CERTIFICATE")
cprint('Adding new key for %s:%s' % (server, port))
@@ -401,6 +431,10 @@ def printattributes(session, requestargs, showtype, nodetype, noderange, options
path = '/{0}/{1}/attributes/{2}'.format(nodetype, noderange, showtype)
return print_attrib_path(path, session, requestargs, options)
def _sort_attrib(k):
if isinstance(k[1], dict) and k[1].get('sortid', None) is not None:
return k[1]['sortid']
return k[0]
def print_attrib_path(path, session, requestargs, options, rename=None, attrprefix=None):
exitcode = 0
@@ -411,9 +445,7 @@ def print_attrib_path(path, session, requestargs, options, rename=None, attrpref
exitcode = 1
continue
for node in sorted(res['databynode']):
for attr, val in sorted(
res['databynode'][node].items(),
key=lambda k: k[1].get('sortid', k[0]) if isinstance(k[1], dict) else k[0]):
for attr, val in sorted(res['databynode'][node].items(), key=_sort_attrib):
if attr == 'error':
sys.stderr.write('{0}: Error: {1}\n'.format(node, val))
continue
@@ -435,7 +467,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}
+57 -27
View File
@@ -19,6 +19,7 @@ alias nodebmcreset='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export
alias nodeboot='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodeboot'
alias nodeconfig='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodeconfig'
alias nodeconsole='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodeconsole'
alias nodedeploy='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodedeploy'
alias nodedefine='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodedefine'
alias nodeeventlog='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodeeventlog'
alias nodefirmware='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export CURRENT_CMDLINE; nodefirmware'
@@ -46,9 +47,8 @@ alias nodelicense='CURRENT_CMDLINE=$(HISTTIMEFORMAT= builtin history 1); export
_confluent_get_args()
{
CMPARGS=($COMP_LINE)
NUMARGS=${#CMPARGS[@]}
if [ "${COMP_WORDS[-1]}" == '' ]; then
NUMARGS=$((NUMARGS+1))
NUMARGS=$((COMP_CWORD+1))
if [ "${COMP_WORDS[COMP_CWORD]}" == '' ]; then
CMPARGS+=("")
fi
GENNED=""
@@ -75,7 +75,7 @@ function _confluent_generic_completion()
{
_confluent_get_args
if [ $NUMARGS -ge 3 ] && [ ! -z "$GENNED" ]; then
COMPREPLY=($(compgen -W "$GENNED" -- ${COMP_WORDS[-1]}))
COMPREPLY=($(compgen -W "$GENNED" -- ${COMP_WORDS[COMP_CWORD]}))
fi
if [ $NUMARGS -lt 3 ]; then
_confluent_nr_completion
@@ -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 -h -b -p")
_confluent_generic_completion
}
@@ -111,7 +111,7 @@ _confluent_nodemedia_completion()
return
fi
if [ $NUMARGS -ge 3 ] && [ ! -z "$GENNED" ]; then
COMPREPLY=($(compgen -W "$GENNED" -- ${COMP_WORDS[-1]}))
COMPREPLY=($(compgen -W "$GENNED" -- ${COMP_WORDS[COMP_CWORD]}))
return;
fi
if [ $NUMARGS -lt 3 ]; then
@@ -124,7 +124,7 @@ _confluent_nodefirmware_completion()
{
_confluent_get_args
if [ $NUMARGS == 3 ]; then
COMPREPLY=($(compgen -W "list update" -- ${COMP_WORDS[-1]}))
COMPREPLY=($(compgen -W "list update" -- ${COMP_WORDS[COMP_CWORD]}))
return;
fi
if [ $NUMARGS -gt 3 ] && [ ${CMPARGS[2]} == 'update' ]; then
@@ -138,11 +138,42 @@ _confluent_nodefirmware_completion()
fi
}
_confluent_osimage_completion()
{
_confluent_get_args
if [ $NUMARGS == 2 ]; then
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]}))
elif [ ${CMPARGS[1]} == 'import' ]; then
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
}
_confluent_nodedeploy_completion()
{
_confluent_get_args
if [ $NUMARGS -gt 2 ]; then
COMPREPLY=($(compgen -W "-n $(confetty show /deployment/profiles|sed -e 's/\///')" -- "${COMP_WORDS[COMP_CWORD]}"))
return
fi
if [ $NUMARGS -lt 3 ]; then
_confluent_nr_completion
return;
fi
}
_confluent_nodeshell_completion()
{
_confluent_get_args
if [ $NUMARGS == 3 ]; then
COMPREPLY=($(compgen -c -- ${COMP_WORDS[-1]}))
COMPREPLY=($(compgen -c -- ${COMP_WORDS[COMP_CWORD]}))
return
fi
if [ $NUMARGS -gt 3 ]; then
@@ -160,7 +191,7 @@ _confluent_nodelicense_completion()
{
_confluent_get_args
if [ $NUMARGS == 3 ]; then
COMPREPLY=($(compgen -W "install list save delete" -- ${COMP_WORDS[-1]}))
COMPREPLY=($(compgen -W "install list save delete" -- ${COMP_WORDS[COMP_CWORD]}))
return;
fi
if [ $NUMARGS == 4 ] && [ ${CMPARGS[2]} == 'install' ]; then
@@ -183,7 +214,7 @@ _confluent_nodesupport_completion()
{
_confluent_get_args
if [ $NUMARGS == 3 ]; then
COMPREPLY=($(compgen -W "servicedata" -- ${COMP_WORDS[-1]}))
COMPREPLY=($(compgen -W "servicedata" -- ${COMP_WORDS[COMP_CWORD]}))
return;
fi
if [ $NUMARGS == 4 ] && [ ${CMPARGS[2]} == 'servicedata' ]; then
@@ -210,41 +241,38 @@ _confluent_nn_completion()
if [ $NUMARGS -gt 2 ]; then
return;
fi
INPUT=${COMP_WORDS[-1]}
INPUT=${COMP_WORDS[COMP_CWORD]}
INPUT=${INPUT##*,-}
INPUT=${INPUT##*,}
INPUT=${INPUT##*@}
PREFIX=""
if [ "$INPUT" != "${COMP_WORDS[-1]}" ]; then
PREFIX=${COMP_WORDS[-1]}
if [ "$INPUT" != "${COMP_WORDS[COMP_CWORD]}" ]; then
PREFIX=${COMP_WORDS[COMP_CWORD]}
PREFIX=$(echo $PREFIX | sed -e 's/,[^,@-]*$/,/' -e 's/,-[^,@]*$/,-/' -e 's/@[^,@]*/@/')
fi
COMPREPLY=($(compgen -W "$(nodelist | sed -e s/^/$PREFIX/)" -- "${COMP_WORDS[-1]}"))
COMPREPLY=($(compgen -W "$(nodelist | sed -e s/^/$PREFIX/)" -- "${COMP_WORDS[COMP_CWORD]}"))
}
_confluent_nr_completion()
{
CMPARGS=($COMP_LINE)
NUMARGS=${#CMPARGS[@]}
if [ "${COMP_WORDS[-1]}" == '' ]; then
NUMARGS=$((NUMARGS+1))
fi
_confluent_get_args
if [ $NUMARGS -gt 2 ]; then
compopt -o default
COMPREPLY=()
return;
fi
INPUT=${COMP_WORDS[-1]}
INPUT=${COMP_WORDS[COMP_CWORD]}
INPUT=${INPUT##*,-}
INPUT=${INPUT##*,}
INPUT=${INPUT##*@}
PREFIX=""
if [ "$INPUT" != "${COMP_WORDS[-1]}" ]; then
PREFIX=${COMP_WORDS[-1]}
if [ "$INPUT" != "${COMP_WORDS[COMP_CWORD]}" ]; then
PREFIX=${COMP_WORDS[COMP_CWORD]}
PREFIX=$(echo $PREFIX | sed -e 's/,[^,@-]*$/,/' -e 's/,-[^,@]*$/,-/' -e 's/@[^,@]*/@/')
fi
#COMPREPLY=($(compgen -W "$(confetty show /nodegroups|sed -e 's/\///' -e s/^/$PREFIX/;nodelist | sed -e s/^/$PREFIX/)" -- "${COMP_WORDS[-1]}"))
COMPREPLY=($(compgen -W "$(confetty show /nodegroups|sed -e 's/\///' -e s/^/$PREFIX/;nodelist | sed -e s/^/$PREFIX/)" -- "${COMP_WORDS[-1]}"))
COMPREPLY=($(compgen -W "$(confetty show /nodegroups|sed -e 's/\///' -e s/^/$PREFIX/;nodelist | sed -e s/^/$PREFIX/)" -- "${COMP_WORDS[COMP_CWORD]}"))
}
_confluent_ng_completion()
{
@@ -252,17 +280,17 @@ _confluent_ng_completion()
if [ $NUMARGS -gt 2 ]; then
return;
fi
INPUT=${COMP_WORDS[-1]}
INPUT=${COMP_WORDS[COMP_CWORD]}
INPUT=${INPUT##*,-}
INPUT=${INPUT##*,}
INPUT=${INPUT##*@}
PREFIX=""
if [ "$INPUT" != "${COMP_WORDS[-1]}" ]; then
PREFIX=${COMP_WORDS[-1]}
if [ "$INPUT" != "${COMP_WORDS[COMP_CWORD]}" ]; then
PREFIX=${COMP_WORDS[COMP_CWORD]}
PREFIX=$(echo $PREFIX | sed -e 's/,[^,@-]*$/,/' -e 's/,-[^,@]*$/,-/' -e 's/@[^,@]*/@/')
fi
COMPREPLY=($(compgen -W "$(confetty show /nodegroups|sed -e 's/\///' -e s/^/$PREFIX/)" -- "${COMP_WORDS[-1]}"))
COMPREPLY=($(compgen -W "$(confetty show /nodegroups|sed -e 's/\///' -e s/^/$PREFIX/)" -- "${COMP_WORDS[COMP_CWORD]}"))
}
complete -F _confluent_nodeattrib_completion nodeattrib
complete -F _confluent_nodeattrib_completion nodegroupattrib
@@ -272,6 +300,8 @@ complete -F _confluent_nr_completion nodeconfig
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 osdeploy
complete -F _confluent_ng_completion nodegroupattrib
complete -F _confluent_ng_completion nodegroupremove
complete -F _confluent_nr_completion nodehealth
@@ -100,3 +100,5 @@ See nodegroupattrib(8) command on how to manage attributes on a group level.
## SEE ALSO
nodegroupattrib(8), nodeattribexpressions(5)
## ATTRIBUTES
+5
View File
@@ -22,6 +22,11 @@ given as a node expression, as documented in the man page for nodeattribexpressi
If combined with `-x`, will show all differing values except those indicated
by `-x`
* `-e`, `--extra`:
Read settings that are generally not needed, but may be slow to retrieve.
Notably this includes the IMM category of Lenovo systems. The most popular
IMM settings are available through faster 'bmc' attributes.
* `-x`, `--exclude`:
Rather than listing only the specified configuration parameters, list all
attributes except for the specified ones
+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)`
@@ -23,6 +23,9 @@ data may be filtered by various parameters, as denoted in the options below.
**nodediscover assign** performs manual discovery, assigning an entry to a node
identity or, using `-i`, using a csv file to assign nodes all at once. For
example, a spreadsheet of serial numbers to desired node names could be used.
Note that if you see that the host is unreachable, it may be due to the IP
address on the endpoint having changed since last detected. In such a case, it
may help to **clear** and try **assign** again.
**nodediscover rescan** requests the server to do an active sweep for new
devices. Generally every effort is made to passively detect devices as they
+5 -1
View File
@@ -13,7 +13,11 @@ nodefirmware(8) -- Report firmware information on confluent nodes
will retrieve all firmware, but can be directed to fetch specific firmware by
calling out the name of the firmware (e.g. uefi or xcc) or request reading only
core firmware firmware by using the word 'core', which is generally a quicker
operation.
operation. Different hardwaremanagement.method indicated plugins may have
different capabilities available. For example, the 'core' distinction may
not be relevant to redfish. Additionally, the Lenovo XCC makes certain
information available over IPMI that is not otherwise available (for example
the FPGA version where applicable).
In the update form, it accepts a single file and attempts to update it using
the out of band facilities. Firmware updates can end in one of three states:
@@ -41,3 +41,5 @@ the attributes are set on the node versus a group to which a node belongs.
## SEE ALSO
nodeattrib(8), nodeattribexpressions(5)
## ATTRIBUTES
+21
View File
@@ -0,0 +1,21 @@
nodersync(8) -- Run rsync in parallel against a noderange
=========================================================================
## SYNOPSIS
`nodersync <file/directorylist> <noderange>:<destination>`
## DESCRIPTION
Supervises execution of rsync to push files or a directory tree to the specified
noderange. This will present progress as percentage for all nodes.
## OPTIONS
* `-m`:
Specify maximum number of nodes for noderange max.
* `-c`:
Specify how many rsync executions to do concurrently. If noderange
exceeds the count, then excess nodes will wait until one of the
active count completes.
@@ -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`
+5 -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|floppy]`
## DESCRIPTION
@@ -42,6 +42,10 @@ 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).
* `network`:
Request boot to network
+4 -1
View File
@@ -7,7 +7,7 @@ nodesupport(8) -- Utilities for interacting with vendor support
## DESCRIPTION
`nodesupport` provides capabilities associated with interactiong with support.
`nodesupport` provides capabilities associated with interacting with support.
Currently it only has the `servicedata` subcommand. `servicedata` takes
an argument that is either a directory name (that can be used for a single node
or multiple nodes) or a file name (only to be used with single node noderange).
@@ -16,6 +16,9 @@ connects to the managed system, so it will download to the remote system if runn
remotely and will download to the collective.manager indicated system if
running in collective mode.
Note that due to vendor filename requirements, any filename may have vendor
specific suffixes added to any file produced.
## EXAMPLES
* Download support data from a single node to a specific filename
+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`
+2
View File
@@ -1,4 +1,6 @@
#!/bin/sh
cd `dirname $0`
python3 addattribs.py || python2 addattribs.py
cd `dirname $0`/doc/man
mkdir -p ../../man/man1
mkdir -p ../../man/man5
+11
View File
@@ -0,0 +1,11 @@
VERSION=`git describe|cut -d- -f 1`
NUMCOMMITS=`git describe|cut -d- -f 2`
if [ "$NUMCOMMITS" != "$VERSION" ]; then
VERSION=$VERSION.dev$NUMCOMMITS.g`git describe|cut -d- -f 3`
fi
sed -e "s/#VERSION#/$VERSION/" confluent_osdeploy.spec.tmpl > confluent_osdeploy.spec
cd ..
tar Jcvf confluent_osdeploy.tar.xz confluent_osdeploy
mv confluent_osdeploy.tar.xz ~/rpmbuild/SOURCES/
cd -
rpmbuild -ba confluent_osdeploy.spec
@@ -0,0 +1,107 @@
#!/usr/bin/python
try:
import http.client as client
except ImportError:
import httplib as client
import os
import socket
import subprocess
import ssl
import sys
def get_apikey(nodename, mgr):
if os.path.exists('/etc/confluent/confluent.apikey'):
return open('/etc/confluent/confluent.apikey').read().strip()
apikey = subprocess.check_output(['/opt/confluent/bin/clortho', nodename, mgr])
if not isinstance(apikey, str):
apikey = apikey.decode('utf8')
with open('/etc/confluent/confluent.apikey', 'w+') as apiout:
apiout.write(apikey)
apikey = apikey.strip()
os.chmod('/etc/confluent/confluent.apikey', 0o600)
return apikey
class HTTPSClient(client.HTTPConnection, object):
def __init__(self, json=False, port=443):
self.stdheaders = {}
info = open('/etc/confluent/confluent.info').read().split('\n')
host = None
mgtiface = None
havedefault = '0'
for line in info:
if line.startswith('NODENAME:'):
node = line.split(' ')[1]
self.stdheaders['CONFLUENT_NODENAME'] = node
if line.startswith('MANAGER:') and not host:
host = line.split(' ')[1]
if line.startswith('EXTMGRINFO:'):
extinfo = line.split(' ')[1]
extinfo = extinfo.split('|')
if not mgtiface:
host, mgtiface, havedefault = extinfo[:3]
if havedefault == '0' and extinfo[2] == '1':
host, mgtiface, havedefault = extinfo[:3]
if '%' in host:
ifidx = host.split('%', 1)[1]
with open('/tmp/confluent.ifidx', 'w+') as ifout:
ifout.write(ifidx)
if json:
self.stdheaders['ACCEPT'] = 'application/json'
self.stdheaders['CONFLUENT_APIKEY'] = get_apikey(node, host)
if mgtiface:
self.stdheaders['CONFLUENT_MGTIFACE'] = mgtiface
client.HTTPConnection.__init__(self, host, port)
self.connect()
def set_header(self, key, val):
self.stdheaders[key] = val
def connect(self):
addrinf = socket.getaddrinfo(self.host, self.port)[0]
psock = socket.socket(addrinf[0])
psock.connect(addrinf[4])
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
ctx.load_verify_locations('/etc/confluent/ca.pem')
host = self.host.split('%', 1)[0]
if '[' not in host and ':' in host:
self.stdheaders['Host'] = '[{0}]'.format(host)
else:
self.stdheaders['Host'] = '{0}'.format(host)
ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
self.sock = ctx.wrap_socket(psock, server_hostname=host)
def grab_url(self, url, data=None, returnrsp=False):
if data:
method = 'POST'
else:
method = 'GET'
self.request(method, url, data, headers=self.stdheaders)
rsp = self.getresponse()
if rsp.status >= 200 and rsp.status < 300:
if returnrsp:
return rsp
else:
return rsp.read()
raise Exception(rsp.read())
if __name__ == '__main__':
data = None
json = False
if '-j' in sys.argv:
json = True
if len(sys.argv) == 1:
HTTPSClient()
sys.exit(0)
if sys.argv[-2] == '-o':
with open(sys.argv[3], 'wb') as outf:
reader = HTTPSClient(json=json).grab_url(
sys.argv[1], data, returnrsp=True)
chunk = reader.read(16384)
while chunk:
outf.write(chunk)
chunk = reader.read(16384)
sys.exit(0)
if os.path.exists(sys.argv[-1]):
data = open(sys.argv[-1]).read()
print(HTTPSClient(json=json).grab_url(sys.argv[1], data).decode())
@@ -0,0 +1,59 @@
Name: confluent_osdeploy-x86_64
Version: #VERSION#
Release: 1
Summary: OS Deployment support for confluent
License: Apache2
URL: http://hpc.lenovo.com/
Source0: confluent_osdeploy.tar.xz
BuildArch: noarch
Requires: confluent_ipxe mtools tar
BuildRoot: /tmp
%description
This contains support utilities for enabling deployment of x86_64 architecture systems
%define debug_package %{nil}
%prep
%setup -n confluent_osdeploy
%build
mkdir -p opt/confluent/bin
cd utils
make all
cp copernicus clortho autocons ../opt/confluent/bin
cd ..
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 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.* %{buildroot}/opt/confluent/lib/osdeploy/$os/initramfs
cp -a $os/profiles/* %{buildroot}/opt/confluent/lib/osdeploy/$os/profiles
done
%files
/opt/confluent/lib/osdeploy
@@ -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,78 @@
# 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
%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,2 @@
label: %%DISTRO%% %%VERSION%% %%ARCH%% (Default Profile)
kernelargs: quiet
@@ -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,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'):
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,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,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,66 @@
#!/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
grubpw=$(grep ^grubpassword /etc/confluent/confluent.deploycfg | awk '{print $2}')
if [ "$grubpw" = "null" ]; then
touch /tmp/grubpw
else
echo "bootloader --iscrypted --password=$grubpw" > /tmp/grubpw
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
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
@@ -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,101 @@
#!/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
TRIES=0
oum=$(umask)
umask 0077
mkdir -p /etc/confluent
echo -n > /etc/confluent/confluent.info
umask $oum
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
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%:}
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,22 @@
#!/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/
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
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,79 @@
# 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
@^minimal-environment
chrony
rsync
python3
%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/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,2 @@
label: %%DISTRO%% %%VERSION%% %%ARCH%% (Default Profile)
kernelargs: quiet
@@ -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,356 @@
# 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 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 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)
currvlan = bytes(s.raw_command(0xc, 2, bytearray([channel, 0x14 ,0, 0]))['data'][1:])
if bytearray(currvlan)[1] & 0b10000000 == 0:
currvlan = b'\x00\x00'
if currvlan == vlan:
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
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 set_ipv4(s, ipaddr, channel):
oipaddr = ipaddr
ipaddr = bytearray(socket.inet_aton(ipaddr))
rsp = s.raw_command(0xc, 2, bytearray([channel, 3, 0, 0]))['data'][-4:]
if rsp == ipaddr:
print('IP Address already set to {}'.format(oipaddr))
return
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)
def set_subnet(s, prefix, channel):
oprefix = prefix
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:]
if rsp == mask:
print('Subnet Mask already set to /{}'.format(oprefix))
return
print('Setting subnet mask to /{}'.format(oprefix))
s.raw_command(0xc, 1, bytearray([channel, 6]) + mask)
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 rsp == gw:
print('Gateway already set to {}'.format(ogw))
return
print('Setting gateway to {}'.format(ogw))
s.raw_command(0xc, 1, bytearray([channel, 12]) + gw)
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)
if bmccfg.get('bmcvlan', None):
set_vlan(s, bmccfg['bmcvlan'], channel)
if bmccfg.get('bmcipv4', None):
set_ipv4(s, bmccfg['bmcipv4'], channel)
if bmccfg.get('prefixv4', None):
set_subnet(s, bmccfg['prefixv4'], channel)
if bmccfg.get('bmcgw', None):
set_gateway(s, bmccfg['bmcgw'], channel)
#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.
@@ -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'):
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,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,9 @@
. /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
@@ -0,0 +1,73 @@
#!/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
/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/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
grubpw=$(grep ^grubpassword /etc/confluent/confluent.deploycfg | awk '{print $2}')
if [ "$grubpw" = "null" ]; then
touch /tmp/grubpw
else
echo "bootloader --iscrypted --password=$grubpw" > /tmp/grubpw
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/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 a <> $consoledev >&0 2>&1 &
fi
cryptboot=$(grep ^encryptboot: /etc/confluent/confluent.deploycfg | awk '{print $2}')
LUKSPARTY=''
touch /tmp/cryptpkglist
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
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
curl -f https://$mgr/confluent-public/os/$profile/kickstart.custom > /tmp/kickstart.custom
run_remote pre.custom
@@ -0,0 +1,21 @@
#!/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
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
# 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
@@ -0,0 +1,24 @@
#!/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
profile=$(grep ^profile: /etc/confluent/confluent.deploycfg | 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
export node mgr profile
. /tmp/modinstall
exec /bin/install
@@ -0,0 +1 @@
#!/bin/sh
@@ -0,0 +1,6 @@
accepteula
clearpart --firstdisk --overwritevmfs
install --firstdisk --overwritevmfs
%include /tmp/ksnet
%include /tmp/rootpw
reboot
@@ -0,0 +1,3 @@
label: 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,7 @@
#!/bin/sh
/opt/confluent/bin/apiclient /confluent-public/os/$profile/scripts/makeksnet >> /tmp/makeksnet
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,102 @@
#!/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)"
tmux a <> $autocons >&0 2>&1 &
fi
else
tmux a <> /dev/tty1 >&0 2>&1 &
fi
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
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
echo HostCertificate $certfile >> /etc/ssh/sshd_config
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
cd -
@@ -0,0 +1,13 @@
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 sh /opt/confluent/bin/rungenesis
@@ -0,0 +1,2 @@
label: Genesis
kernelarags: quiet
@@ -0,0 +1,356 @@
# 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 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 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)
currvlan = bytes(s.raw_command(0xc, 2, bytearray([channel, 0x14 ,0, 0]))['data'][1:])
if bytearray(currvlan)[1] & 0b10000000 == 0:
currvlan = b'\x00\x00'
if currvlan == vlan:
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
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 set_ipv4(s, ipaddr, channel):
oipaddr = ipaddr
ipaddr = bytearray(socket.inet_aton(ipaddr))
rsp = s.raw_command(0xc, 2, bytearray([channel, 3, 0, 0]))['data'][-4:]
if rsp == ipaddr:
print('IP Address already set to {}'.format(oipaddr))
return
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)
def set_subnet(s, prefix, channel):
oprefix = prefix
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:]
if rsp == mask:
print('Subnet Mask already set to /{}'.format(oprefix))
return
print('Setting subnet mask to /{}'.format(oprefix))
s.raw_command(0xc, 1, bytearray([channel, 6]) + mask)
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 rsp == gw:
print('Gateway already set to {}'.format(ogw))
return
print('Setting gateway to {}'.format(ogw))
s.raw_command(0xc, 1, bytearray([channel, 12]) + gw)
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)
if bmccfg.get('bmcvlan', None):
set_vlan(s, bmccfg['bmcvlan'], channel)
if bmccfg.get('bmcipv4', None):
set_ipv4(s, bmccfg['bmcipv4'], channel)
if bmccfg.get('prefixv4', None):
set_subnet(s, bmccfg['prefixv4'], channel)
if bmccfg.get('bmcgw', None):
set_gateway(s, bmccfg['bmcgw'], channel)
#await_config(s, bmccfg, channel)
if __name__ == '__main__':
main()
@@ -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,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

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