mirror of
				https://github.com/xcat2/confluent.git
				synced 2025-10-31 19:32:33 +00:00 
			
		
		
		
	Fix inconsistencies between el7 and el8
While there are still differences, minimize the ones that aren't for specific reasons
This commit is contained in:
		| @@ -0,0 +1,25 @@ | ||||
| Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the | ||||
| appropriate phase of the install process. | ||||
|  | ||||
| The 'hosts' may be omitted, and if included will be ignored, replaced with the host that is specifically | ||||
| requesting the playbooks be executed. | ||||
|  | ||||
| Also, the playbooks will be executed on the deployment server. Hence it may be slower in aggregate than | ||||
| running content under scripts/ which ask much less of the deployment server | ||||
|  | ||||
| Here is an example of what a playbook would look like broadly: | ||||
|  | ||||
| - name: Example | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
|        - name: Example1 | ||||
|          lineinfile: | ||||
|            path: /etc/hosts | ||||
|            line: 1.2.3.4 test1 | ||||
|            create: yes | ||||
|        - name: Example2 | ||||
|          lineinfile: | ||||
|            path: /etc/hosts | ||||
|            line: 1.2.3.5 test2 | ||||
|            create: yes | ||||
|  | ||||
| @@ -0,0 +1,25 @@ | ||||
| Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the | ||||
| appropriate phase of the install process. | ||||
|  | ||||
| The 'hosts' may be omitted, and if included will be ignored, replaced with the host that is specifically | ||||
| requesting the playbooks be executed. | ||||
|  | ||||
| Also, the playbooks will be executed on the deployment server. Hence it may be slower in aggregate than | ||||
| running content under scripts/ which ask much less of the deployment server | ||||
|  | ||||
| Here is an example of what a playbook would look like broadly: | ||||
|  | ||||
| - name: Example | ||||
|   gather_facts: no | ||||
|   tasks: | ||||
|        - name: Example1 | ||||
|          lineinfile: | ||||
|            path: /etc/hosts | ||||
|            line: 1.2.3.4 test1 | ||||
|            create: yes | ||||
|        - name: Example2 | ||||
|          lineinfile: | ||||
|            path: /etc/hosts | ||||
|            line: 1.2.3.5 test2 | ||||
|            create: yes | ||||
|  | ||||
| @@ -1,5 +1,5 @@ | ||||
| #!/bin/sh | ||||
| sed -i 's/centos/CentOS/; s/rhel/Red Hat Enterprise Linux/' $2/profile.yaml | ||||
| sed -i 's/centos/CentOS/; s/rhel/Red Hat Enterprise Linux/; s/oraclelinux/Oracle Linux/; s/alma/AlmaLinux/' $2/profile.yaml | ||||
| ln -s $1/images/pxeboot/vmlinuz $2/boot/kernel && \ | ||||
| ln -s $1/images/pxeboot/initrd.img $2/boot/initramfs/distribution | ||||
| mkdir -p $2/boot/efi/boot && \ | ||||
|   | ||||
| @@ -33,14 +33,15 @@ | ||||
| reboot | ||||
|  | ||||
| %packages | ||||
| #-kernel-uek # This can opt out of the UEK for the relevant distribution | ||||
| chrony | ||||
| rsync | ||||
| python | ||||
| tar | ||||
| pciutils | ||||
| %include /tmp/addonpackages | ||||
| %end | ||||
|  | ||||
|  | ||||
| # A kickstart.custom file is provided to enable easily adding | ||||
| # kickstart content without modifying the stock file. | ||||
| # While the stock file may be safely modified, using the .custom | ||||
| @@ -64,15 +65,16 @@ curl -f https://$mgr/confluent-public/os/$profile/scripts/prechroot.sh > /tmp/po | ||||
|  | ||||
| # Hook firstboot.sh | ||||
| curl -f https://$mgr/confluent-public/os/$profile/scripts/firstboot.service > /mnt/sysimage/etc/systemd/system/firstboot.service | ||||
| curl -f https://$mgr/confluent-public/os/$profile/scripts/firstboot.sh > /mnt/sysimage/etc/confluent/firstboot.sh | ||||
| chmod +x /mnt/sysimage/etc/confluent/firstboot.sh | ||||
| mkdir -p /mnt/sysimage/opt/confluent/bin | ||||
| curl -f https://$mgr/confluent-public/os/$profile/scripts/firstboot.sh > /mnt/sysimage/opt/confluent/bin/firstboot.sh | ||||
| chmod +x /mnt/sysimage/opt/confluent/bin/firstboot.sh | ||||
| %end | ||||
|  | ||||
| %post | ||||
| cat /etc/confluent/tls/*.pem >> /etc/pki/tls/certs/ca-bundle.crt | ||||
| systemctl enable firstboot | ||||
| chgrp ssh_keys /etc/ssh/ssh*key | ||||
| restorecon /etc/ssh/ssh*key /root/.shosts /etc/ssh/shosts.equiv /etc/ssh/ssh_config.d/* /etc/confluent/firstboot.sh | ||||
| restorecon /etc/ssh/ssh*key /root/.shosts /etc/ssh/shosts.equiv /etc/ssh/ssh_config.d/* /opt/confluent/bin/firstboot.sh | ||||
| profile=$(grep ^profile: /etc/confluent/confluent.deploycfg |awk '{print $2}') | ||||
| mgr=$(grep deploy_server /etc/confluent/confluent.deploycfg |awk '{print $2}') | ||||
| curl -f https://$mgr/confluent-public/os/$profile/scripts/post.sh > /tmp/postinst.sh | ||||
|   | ||||
| @@ -1,3 +1,3 @@ | ||||
| label: %%DISTRO%% %%VERSION%% %%ARCH%% (Default Profile) | ||||
| kernelargs: quiet | ||||
| kernelargs: quiet  # These arguments are passed to the installer | ||||
| #installedargs: example # These arguments would be added to the installed system | ||||
|   | ||||
							
								
								
									
										414
									
								
								confluent_osdeploy/el7/profiles/default/scripts/configbmc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										414
									
								
								confluent_osdeploy/el7/profiles/default/scripts/configbmc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,414 @@ | ||||
| # Copyright 2017 Lenovo | ||||
| # | ||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # you may not use this file except in compliance with the License. | ||||
| # You may obtain a copy of the License at | ||||
| # | ||||
| #     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| # Unless required by applicable law or agreed to in writing, software | ||||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | ||||
|  | ||||
| import argparse | ||||
| import ctypes | ||||
| import fcntl | ||||
| import json | ||||
| from select import select | ||||
| import socket | ||||
| import struct | ||||
| import os | ||||
| import subprocess | ||||
| import sys | ||||
| import time | ||||
|  | ||||
| if os.path.exists('/opt/confluent/bin/apiclient'): | ||||
|     apiclient = '/opt/confluent/bin/apiclient' | ||||
| elif os.path.exists('/etc/confluent/apiclient'): | ||||
|     apiclient = '/etc/confluent/apiclient' | ||||
|  | ||||
| class IpmiMsg(ctypes.Structure): | ||||
|     _fields_ = [('netfn', ctypes.c_ubyte), | ||||
|                 ('cmd', ctypes.c_ubyte), | ||||
|                 ('data_len', ctypes.c_short), | ||||
|                 ('data', ctypes.POINTER(ctypes.c_ubyte))] | ||||
|  | ||||
|  | ||||
| class IpmiSystemInterfaceAddr(ctypes.Structure): | ||||
|     _fields_ = [('addr_type', ctypes.c_int), | ||||
|                 ('channel', ctypes.c_short), | ||||
|                 ('lun', ctypes.c_ubyte)] | ||||
|  | ||||
|  | ||||
| class IpmiRecv(ctypes.Structure): | ||||
|     _fields_ = [('recv_type', ctypes.c_int), | ||||
|                 ('addr', ctypes.POINTER(IpmiSystemInterfaceAddr)), | ||||
|                 ('addr_len', ctypes.c_uint), | ||||
|                 ('msgid', ctypes.c_long), | ||||
|                 ('msg', IpmiMsg)] | ||||
|  | ||||
|  | ||||
| class IpmiReq(ctypes.Structure): | ||||
|     _fields_ = [('addr', ctypes.POINTER(IpmiSystemInterfaceAddr)), | ||||
|                 ('addr_len', ctypes.c_uint), | ||||
|                 ('msgid', ctypes.c_long), | ||||
|                 ('msg', IpmiMsg)] | ||||
|  | ||||
|  | ||||
| _IONONE = 0 | ||||
| _IOWRITE = 1 | ||||
| _IOREAD = 2 | ||||
| IPMICTL_SET_MY_ADDRESS_CMD = ( | ||||
|     _IOREAD << 30 | ctypes.sizeof(ctypes.c_uint) << 16 | ||||
|     | ord('i') << 8 | 17)  # from ipmi.h | ||||
| IPMICTL_SEND_COMMAND = ( | ||||
|     _IOREAD << 30 | ctypes.sizeof(IpmiReq) << 16 | ||||
|     | ord('i') << 8 | 13)  # from ipmi.h | ||||
| # next is really IPMICTL_RECEIVE_MSG_TRUNC, but will only use that | ||||
| IPMICTL_RECV = ( | ||||
|     (_IOWRITE | _IOREAD) << 30 | ctypes.sizeof(IpmiRecv) << 16 | ||||
|     | ord('i') << 8 | 11)  # from ipmi.h | ||||
| BMC_SLAVE_ADDR = ctypes.c_uint(0x20) | ||||
| CURRCHAN = 0xf | ||||
| ADDRTYPE = 0xc | ||||
|  | ||||
|  | ||||
| class Session(object): | ||||
|     def __init__(self, devnode='/dev/ipmi0'): | ||||
|         """Create a local session inband | ||||
|  | ||||
|         :param: devnode: The path to the ipmi device | ||||
|         """ | ||||
|         self.ipmidev = open(devnode, 'r+') | ||||
|         fcntl.ioctl(self.ipmidev, IPMICTL_SET_MY_ADDRESS_CMD, BMC_SLAVE_ADDR) | ||||
|         # the interface is initted, create some reusable memory for our session | ||||
|         self.databuffer = ctypes.create_string_buffer(4096) | ||||
|         self.req = IpmiReq() | ||||
|         self.rsp = IpmiRecv() | ||||
|         self.addr = IpmiSystemInterfaceAddr() | ||||
|         self.req.msg.data = ctypes.cast( | ||||
|             ctypes.addressof(self.databuffer), | ||||
|             ctypes.POINTER(ctypes.c_ubyte)) | ||||
|         self.rsp.msg.data = self.req.msg.data | ||||
|         self.userid = None | ||||
|         self.password = None | ||||
|  | ||||
|     def await_reply(self): | ||||
|         rd, _, _ = select((self.ipmidev,), (), (), 1) | ||||
|         while not rd: | ||||
|             rd, _, _ = select((self.ipmidev,), (), (), 1) | ||||
|  | ||||
|     def pause(self, seconds): | ||||
|         time.sleep(seconds) | ||||
|  | ||||
|     @property | ||||
|     def parsed_rsp(self): | ||||
|         response = {'netfn': self.rsp.msg.netfn, 'command': self.rsp.msg.cmd, | ||||
|                     'code': bytearray(self.databuffer.raw)[0], | ||||
|                     'data': bytearray( | ||||
|                         self.databuffer.raw[1:self.rsp.msg.data_len])} | ||||
|         return response | ||||
|  | ||||
|     def await_config(s, bmccfg, channel): | ||||
|         vlan = bmccfg.get('bmcvlan', None) | ||||
|         ipv4 = bmccfg.get('bmcipv4', None) | ||||
|         prefix = bmccfg.get('prefixv4', None) | ||||
|         gw = bmccfg.get('bmcgw', None) | ||||
|  | ||||
|  | ||||
|  | ||||
|     def raw_command(self, | ||||
|                     netfn, | ||||
|                     command, | ||||
|                     data=(), | ||||
|                     bridge_request=None, | ||||
|                     retry=True, | ||||
|                     delay_xmit=None, | ||||
|                     timeout=None, | ||||
|                     waitall=False, rslun=0): | ||||
|         self.addr.channel = CURRCHAN | ||||
|         self.addr.addr_type = ADDRTYPE | ||||
|         self.addr.lun = rslun | ||||
|         self.req.addr_len = ctypes.sizeof(IpmiSystemInterfaceAddr) | ||||
|         self.req.addr = ctypes.pointer(self.addr) | ||||
|         self.req.msg.netfn = netfn | ||||
|         self.req.msg.cmd = command | ||||
|         if data: | ||||
|             data = memoryview(bytearray(data)) | ||||
|             try: | ||||
|                 self.databuffer[:len(data)] = data[:len(data)] | ||||
|             except ValueError: | ||||
|                 self.databuffer[:len(data)] = data[:len(data)].tobytes() | ||||
|         self.req.msg.data_len = len(data) | ||||
|         fcntl.ioctl(self.ipmidev, IPMICTL_SEND_COMMAND, self.req) | ||||
|         self.await_reply() | ||||
|         self.rsp.msg.data_len = 4096 | ||||
|         self.rsp.addr = ctypes.pointer(self.addr) | ||||
|         self.rsp.addr_len = ctypes.sizeof(IpmiSystemInterfaceAddr) | ||||
|         fcntl.ioctl(self.ipmidev, IPMICTL_RECV, self.rsp) | ||||
|         return self.parsed_rsp | ||||
|  | ||||
|  | ||||
| def _is_tsm(model): | ||||
|     return model in ('7y00', '7z01', '7y98', '7y99') | ||||
|  | ||||
| def set_port(s, port, vendor, model): | ||||
|     oport = port | ||||
|     if vendor not in ('IBM', 'Lenovo'): | ||||
|         raise Exception('{0} not implemented'.format(vendor)) | ||||
|     if _is_tsm(model): | ||||
|         return set_port_tsm(s, port, model) | ||||
|     else: | ||||
|         set_port_xcc(s, port, model) | ||||
|         return 1 | ||||
|  | ||||
|  | ||||
| def set_port_tsm(s, port, model): | ||||
|     oport = port | ||||
|     sys.stdout.write('Setting TSM port to "{}"...'.format(oport)) | ||||
|     sys.stdout.flush() | ||||
|     if port == 'ocp': | ||||
|         s.raw_command(0x32, 0x71, b'\x00\x01\x00') | ||||
|     elif port == 'dedicated': | ||||
|         s.raw_command(0x32, 0x71, b'\x00\x00\x00') | ||||
|     else: | ||||
|         raise Exception("Unsupported port for TSM") | ||||
|     timer = 15 | ||||
|     while timer: | ||||
|         timer = timer - 1 | ||||
|         time.sleep(1.0) | ||||
|         sys.stdout.write('.') | ||||
|         sys.stdout.flush() | ||||
|     if port == 'ocp': | ||||
|         iface = 0 | ||||
|         s.raw_command(0x32, 0x71, b'\x00\x00\x03') | ||||
|     elif port == 'dedicated': | ||||
|         iface = 1 | ||||
|         s.raw_command(0x32, 0x71, b'\x00\x01\x03') | ||||
|     rsp = s.raw_command(0x32, 0x72, bytearray([4, iface, 0])) | ||||
|     print('Complete') | ||||
|     return int(rsp['data'][0]) | ||||
|  | ||||
|  | ||||
| def set_port_xcc(s, port, model): | ||||
|     oport = port | ||||
|     if port.lower() == 'dedicated': | ||||
|         port = b'\x01' | ||||
|     elif port.lower() in ('ml2', 'ocp'): | ||||
|         port = b'\x02\x00' | ||||
|     elif port.lower() == 'lom': | ||||
|         if model == '7x58': | ||||
|             port = b'\x00\x02' | ||||
|         else: | ||||
|             port = b'\x00\x00' | ||||
|     else: | ||||
|         port = port.split(' ') | ||||
|         port = bytes(bytearray([int(x) for x in port])) | ||||
|     currport = bytes(s.raw_command(0xc, 2, b'\x01\xc0\x00\x00')['data'][1:]) | ||||
|     if port == currport: | ||||
|         sys.stdout.write('XCC port already set to "{}"\n'.format(oport)) | ||||
|         return | ||||
|     sys.stdout.write('Setting XCC port to "{}"...'.format(oport)) | ||||
|     sys.stdout.flush() | ||||
|     s.raw_command(0xc, 1, b'\x01\xc0' + port) | ||||
|     tries = 60 | ||||
|     while currport != port and tries: | ||||
|         tries -= 1 | ||||
|         time.sleep(0.5) | ||||
|         sys.stdout.write('.') | ||||
|         sys.stdout.flush() | ||||
|         currport = bytes(s.raw_command(0xc, 2, b'\x01\xc0\x00\x00')['data'][1:]) | ||||
|     if not tries: | ||||
|         raise Exception('Timeout attempting to set port') | ||||
|     sys.stdout.write('Complete\n') | ||||
|  | ||||
|  | ||||
| def check_vlan(s, vlan, channel): | ||||
|     if vlan == 'off': | ||||
|         vlan = b'\x00\x00' | ||||
|     else: | ||||
|         vlan = int(vlan) | ||||
|         if vlan: | ||||
|             vlan = vlan | 32768 | ||||
|         vlan = struct.pack('<H', vlan) | ||||
|     currvlan = bytes(s.raw_command(0xc, 2, bytearray([channel, 0x14 ,0, 0]))['data'][1:]) | ||||
|     if bytearray(currvlan)[1] & 0b10000000 == 0: | ||||
|         currvlan = b'\x00\x00' | ||||
|     return currvlan == vlan | ||||
|  | ||||
|  | ||||
| def set_vlan(s, vlan, channel): | ||||
|     ovlan = vlan | ||||
|     if vlan == 'off': | ||||
|         vlan = b'\x00\x00' | ||||
|     else: | ||||
|         vlan = int(vlan) | ||||
|         if vlan: | ||||
|             vlan = vlan | 32768 | ||||
|         vlan = struct.pack('<H', vlan) | ||||
|     if check_vlan(s, ovlan, channel): | ||||
|         sys.stdout.write('VLAN already configured to "{0}"\n'.format(ovlan)) | ||||
|         return False | ||||
|     rsp = s.raw_command(0xc, 1, bytearray([channel, 0x14]) + vlan) | ||||
|     if rsp.get('code', 1) == 0: | ||||
|         print('VLAN configured to "{}"'.format(ovlan)) | ||||
|     else: | ||||
|         print('Error setting vlan: ' + repr(rsp)) | ||||
|     return True | ||||
|  | ||||
|  | ||||
| def get_lan_channel(s): | ||||
|     for chan in range(1, 16): | ||||
|         rsp = s.raw_command(6, 0x42, bytearray([chan]))['data'] | ||||
|         if not rsp: | ||||
|             continue | ||||
|         medtype = int(rsp[1]) & 0b1111111 | ||||
|         if medtype not in (4, 6): | ||||
|             continue | ||||
|         rsp = s.raw_command(0xc, 2, bytearray([2, chan, 5, 0, 0])) | ||||
|         if rsp.get('code', 1) == 0: | ||||
|             return chan | ||||
|     return 1 | ||||
|  | ||||
|  | ||||
| def check_ipv4(s, ipaddr, channel): | ||||
|     ipaddr = bytearray(socket.inet_aton(ipaddr)) | ||||
|     rsp = s.raw_command(0xc, 2, bytearray([channel, 3, 0, 0]))['data'][-4:] | ||||
|     return rsp == ipaddr | ||||
|  | ||||
| def set_ipv4(s, ipaddr, channel): | ||||
|     oipaddr = ipaddr | ||||
|     ipaddr = bytearray(socket.inet_aton(ipaddr)) | ||||
|     if check_ipv4(s, oipaddr, channel): | ||||
|         print('IP Address already set to {}'.format(oipaddr)) | ||||
|         return False | ||||
|     rsp = int(s.raw_command(0xc, 2, bytearray([channel, 4, 0, 0]))['data'][1]) & 0b1111 | ||||
|     if rsp != 1: | ||||
|         sys.stdout.write("Changing configuration to static...") | ||||
|         sys.stdout.flush() | ||||
|         resp = s.raw_command(0xc, 1, bytearray([channel, 4, 1])) | ||||
|         tries = 0 | ||||
|         while rsp != 1 and tries < 30: | ||||
|             sys.stdout.write('.') | ||||
|             sys.stdout.flush() | ||||
|             tries += 1 | ||||
|             time.sleep(0.5) | ||||
|             rsp = int(s.raw_command(0xc, 2, bytearray([channel, 4, 0, 0]))['data'][1]) & 0b1111 | ||||
|         sys.stdout.write('Complete\n') | ||||
|         sys.stdout.flush() | ||||
|     print('Setting IP to {}'.format(oipaddr)) | ||||
|     s.raw_command(0xc, 1, bytearray([channel, 3]) + ipaddr) | ||||
|     return True | ||||
|  | ||||
|  | ||||
| def check_subnet(s, prefix, channel): | ||||
|     prefix = int(prefix) | ||||
|     mask = bytearray(struct.pack('!I', (2**32 - 1) ^ (2**(32 - prefix) - 1))) | ||||
|     rsp = s.raw_command(0xc, 2, bytearray([channel, 6, 0, 0]))['data'][-4:] | ||||
|     return rsp == mask | ||||
|  | ||||
| def set_subnet(s, prefix, channel): | ||||
|     oprefix = prefix | ||||
|     prefix = int(prefix) | ||||
|     mask = bytearray(struct.pack('!I', (2**32 - 1) ^ (2**(32 - prefix) - 1))) | ||||
|     if check_subnet(s, prefix, channel): | ||||
|         print('Subnet Mask already set to /{}'.format(oprefix)) | ||||
|         return False | ||||
|     print('Setting subnet mask to /{}'.format(oprefix)) | ||||
|     s.raw_command(0xc, 1, bytearray([channel, 6]) + mask) | ||||
|     return True | ||||
|  | ||||
|  | ||||
| def check_gateway(s, gw, channel): | ||||
|     gw = bytearray(socket.inet_aton(gw)) | ||||
|     rsp = s.raw_command(0xc, 2, bytearray([channel, 12, 0, 0]))['data'][-4:] | ||||
|     return rsp == gw | ||||
|  | ||||
| def set_gateway(s, gw, channel): | ||||
|     ogw = gw | ||||
|     gw = bytearray(socket.inet_aton(gw)) | ||||
|     rsp = s.raw_command(0xc, 2, bytearray([channel, 12, 0, 0]))['data'][-4:] | ||||
|     if check_gateway(s, ogw, channel): | ||||
|         print('Gateway already set to {}'.format(ogw)) | ||||
|         return False | ||||
|     print('Setting gateway to {}'.format(ogw)) | ||||
|     s.raw_command(0xc, 1, bytearray([channel, 12]) + gw) | ||||
|     return True | ||||
|  | ||||
| def dotwait(): | ||||
|     sys.stdout.write('.') | ||||
|     sys.stdout.flush() | ||||
|     time.sleep(0.5) | ||||
|  | ||||
| def main(): | ||||
|     a = argparse.ArgumentParser(description='Locally configure a BMC device') | ||||
|     a.add_argument('-v', help='vlan id or off to disable vlan tagging') | ||||
|     a.add_argument('-p', help='Which port to use (dedicated, lom, ocp, ml2)') | ||||
|     a.add_argument('-i', help='JSON configuration file to read for ' | ||||
|                    'configuration') | ||||
|     a.add_argument('-c', help='Use Confluent API to direct BMC configuration', | ||||
|                    action='store_true') | ||||
|     args = a.parse_args() | ||||
|     if args.i: | ||||
|         bmccfg = json.load(open(args.i)) | ||||
|     elif args.c: | ||||
|         bmccfgsrc = subprocess.check_output( | ||||
|             [sys.executable, apiclient, '/confluent-api/self/bmcconfig', '-j']) | ||||
|         bmccfg = json.loads(bmccfgsrc) | ||||
|     else: | ||||
|         bmccfg = {} | ||||
|     if args.p is not None: | ||||
|         bmccfg['bmcport'] = args.p | ||||
|     if args.v is not None: | ||||
|         bmccfg['bmcvlan'] = args.v | ||||
|     vendor = open('/sys/devices/virtual/dmi/id/sys_vendor').read() | ||||
|     vendor = vendor.strip() | ||||
|     try: | ||||
|         model = open('/sys/devices/virtual/dmi/id/product_sku').read().strip() | ||||
|         if model == 'none': | ||||
|             raise Exception('No SKU') | ||||
|     except Exception: | ||||
|         model = open('/sys/devices/virtual/dmi/id/product_name').read() | ||||
|     if vendor in ('Lenovo', 'IBM'): | ||||
|         if '[' in model and ']' in model: | ||||
|             model = model.split('[')[1].split(']')[0] | ||||
|         model = model[:4].lower() | ||||
|     s = Session('/dev/ipmi0') | ||||
|     if not bmccfg: | ||||
|         print("No BMC configuration specified, exiting.") | ||||
|         return | ||||
|     if bmccfg.get('bmcport', None): | ||||
|         channel = set_port(s, bmccfg['bmcport'], vendor, model) | ||||
|     else: | ||||
|         channel = get_lan_channel(s) | ||||
|     awaitvlan = False | ||||
|     awaitip = False | ||||
|     awaitprefix = False | ||||
|     awaitgw = False | ||||
|     if bmccfg.get('bmcvlan', None): | ||||
|         awaitvlan = set_vlan(s, bmccfg['bmcvlan'], channel) | ||||
|     if bmccfg.get('bmcipv4', None): | ||||
|         awaitip = set_ipv4(s, bmccfg['bmcipv4'], channel) | ||||
|     if bmccfg.get('prefixv4', None): | ||||
|         awaitprefix = set_subnet(s, bmccfg['prefixv4'], channel) | ||||
|     if bmccfg.get('bmcgw', None): | ||||
|         awaitgw = set_gateway(s, bmccfg['bmcgw'], channel) | ||||
|     sys.stdout.write('Waiting for changes to take effect...') | ||||
|     sys.stdout.flush() | ||||
|     while awaitvlan and not check_vlan(s, bmccfg['bmcvlan'], channel): | ||||
|         dotwait() | ||||
|     while awaitip and not check_ipv4(s, bmccfg['bmcipv4'], channel): | ||||
|         dotwait() | ||||
|     while awaitprefix and not check_subnet(s, bmccfg['prefixv4'], channel): | ||||
|         dotwait() | ||||
|     while awaitprefix and not check_gateway(s, bmccfg['bmcgw'], channel): | ||||
|         dotwait() | ||||
|     sys.stdout.write('done\n') | ||||
|     sys.stdout.flush() | ||||
|     #await_config(s, bmccfg, channel) | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     main() | ||||
							
								
								
									
										0
									
								
								confluent_osdeploy/el7/profiles/default/scripts/firstboot.d/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								confluent_osdeploy/el7/profiles/default/scripts/firstboot.d/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -4,7 +4,7 @@ Requires=network-online.target | ||||
| After=network-online.target | ||||
|  | ||||
| [Service] | ||||
| ExecStart=/etc/confluent/firstboot.sh | ||||
| ExecStart=/opt/confluent/bin/firstboot.sh | ||||
|  | ||||
| [Install] | ||||
| WantedBy=multi-user.target | ||||
|   | ||||
| @@ -15,8 +15,13 @@ export nodename mgr profile | ||||
|  | ||||
|  | ||||
| run_remote firstboot.custom | ||||
| # Firstboot scripts may be placed into firstboot.d, e.g. firstboot.d/01-firstaction.sh, firstboot.d/02-secondaction.sh | ||||
| run_remote_parts firstboot | ||||
|  | ||||
|  | ||||
| # Induce execution of remote configuration, e.g. ansible plays in ansible/firstboot.d/ | ||||
| run_remote_config firstboot | ||||
|  | ||||
| curl -X POST -d 'status: complete' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/updatestatus | ||||
| systemctl disable firstboot | ||||
| rm /etc/systemd/system/firstboot.service | ||||
|   | ||||
| @@ -17,6 +17,13 @@ fetch_remote() { | ||||
|     if [ $? != 0 ]; then echo $1 failed to download; return 1; fi | ||||
| } | ||||
|  | ||||
| run_remote_parts() { | ||||
|     scriptlist=$(/usr/libexec/platform-python /etc/confluent/apiclient /confluent-api/self/scriptlist/$1|sed -e 's/^- //') | ||||
|     for script in $scriptlist; do | ||||
|         run_remote $1.d/$script | ||||
|     done | ||||
| } | ||||
|  | ||||
| run_remote() { | ||||
|     requestedcmd="'$*'" | ||||
|     curlargs="" | ||||
| @@ -70,3 +77,26 @@ run_remote_python() { | ||||
|     cd - > /dev/null | ||||
|     return $retcode | ||||
| } | ||||
|  | ||||
| run_remote_config() { | ||||
|     echo | ||||
|     set_confluent_vars | ||||
|     apiclient=/opt/confluent/bin/apiclient | ||||
|     if [ -f /etc/confluent/apiclient ]; then | ||||
|         apiclient=/etc/confluent/apiclient | ||||
|     fi | ||||
|     echo '---------------------------------------------------------------------------' | ||||
|     echo Requesting to run remote configuration for "'$*'" from $mgr under profile $profile | ||||
|     if [ -x /usr/libexec/platform-python ]; then | ||||
|         /usr/libexec/platform-python $apiclient /confluent-api/self/remoteconfig/"$*" -d {} | ||||
|         /usr/libexec/platform-python $apiclient /confluent-api/self/remoteconfig/status -w 204 | ||||
|     else | ||||
|         /usr/bin/python $apiclient /confluent-api/self/remoteconfig/"$*" -d {} | ||||
|         /usr/bin/python $apiclient /confluent-api/self/remoteconfig/status -w 204 | ||||
|     fi | ||||
|     echo | ||||
|     echo 'Completed remote configuration' | ||||
|     echo '---------------------------------------------------------------------------' | ||||
|     return | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2,6 +2,6 @@ | ||||
| # This is a convenient place to keep customizations separate from modifying the stock scripts | ||||
| # While modification of the stock scripts is fine, it may be easier to rebase to a newer | ||||
| # stock profile if the '.custom' files are used. | ||||
|  | ||||
| # An example for installing OFED for infiniband follows (see the file for more detail): | ||||
| #run_remote infiniband/mofed.post | ||||
|  | ||||
|   | ||||
							
								
								
									
										0
									
								
								confluent_osdeploy/el7/profiles/default/scripts/post.d/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								confluent_osdeploy/el7/profiles/default/scripts/post.d/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -5,16 +5,14 @@ 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 | ||||
|  | ||||
| @@ -37,3 +35,10 @@ run_remote_python syncfileclient | ||||
| # run_remote example.sh | ||||
| # run_remote_python example.py | ||||
| run_remote post.custom | ||||
|  | ||||
| # Also, scripts may be placed into 'post.d', e.g. post.d/01-runfirst.sh, post.d/02-runsecond.sh | ||||
| run_remote_parts post | ||||
|  | ||||
| # Induce execution of remote configuration, e.g. ansible plays in ansible/post.d/ | ||||
| run_remote_config post | ||||
| curl -X POST -d 'status: staged' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $apikey" https://$mgr/confluent-api/self/updatestatus | ||||
|   | ||||
| @@ -11,4 +11,3 @@ | ||||
| #Some addons improve efficiency by adding dependencies during install | ||||
| #here is an example for adding OFED install prereqs to the install | ||||
| #run_remote infiniband/mofed.pre | ||||
|  | ||||
|   | ||||
							
								
								
									
										0
									
								
								confluent_osdeploy/el7/profiles/default/scripts/pre.d/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								confluent_osdeploy/el7/profiles/default/scripts/pre.d/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -43,7 +43,7 @@ if [ ! -z "$blargs" ]; then | ||||
|     echo "bootloader $blargs" > /tmp/grubpw | ||||
| fi | ||||
| ssh-keygen -A | ||||
| for pubkey in /etc/ssh/ssh_host_*_key.pub; do | ||||
| for pubkey in /etc/ssh/ssh_host*key.pub; do | ||||
|     certfile=${pubkey/.pub/-cert.pub} | ||||
|     curl -f -X POST -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" -d @$pubkey https://$mgr/confluent-api/self/sshcert > $certfile | ||||
|     echo HostCertificate $certfile >> /etc/ssh/sshd_config.anaconda | ||||
| @@ -53,9 +53,9 @@ if [ -f "/run/install/cmdline.d/01-autocons.conf" ]; then | ||||
|     consoledev=$(cat /run/install/cmdline.d/01-autocons.conf | sed -e 's!console=!/dev/!' -e 's/,.*//') | ||||
|     TMUX= tmux a <> $consoledev >&0 2>&1 & | ||||
| fi | ||||
| touch /tmp/addonpackages | ||||
| cryptboot=$(grep ^encryptboot: /etc/confluent/confluent.deploycfg | awk '{print $2}') | ||||
| LUKSPARTY='' | ||||
| touch /tmp/addonpackages | ||||
| if [ "$cryptboot" == "tpm2" ]; then | ||||
| 	LUKSPARTY="--encrypted --passphrase=$(cat /etc/confluent/confluent.apikey)" | ||||
| 	echo $cryptboot >> /tmp/cryptboot | ||||
| @@ -65,11 +65,14 @@ 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 | ||||
| run_remote pre.custom | ||||
| run_remote_parts pre | ||||
| if [ ! -e /tmp/installdisk ]; then | ||||
|     run_remote_python getinstalldisk | ||||
| fi | ||||
| if [ -e /tmp/installdisk -a ! -e /tmp/partitioning ]; then | ||||
|     echo clearpart --all --initlabel >> /tmp/partitioning | ||||
|     echo ignoredisk --only-use $(cat /tmp/installdisk) >> /tmp/partitioning | ||||
|     echo autopart --nohome $LUKSPARTY >> /tmp/partitioning | ||||
| fi | ||||
| python /etc/confluent/apiclient /confluent-public/os/$profile/kickstart.custom -o /tmp/kickstart.custom | ||||
| run_remote pre.custom | ||||
|   | ||||
| @@ -10,9 +10,14 @@ | ||||
| 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/ | ||||
| echo Port 2222 >> /etc/ssh/sshd_config.anaconda | ||||
| echo Match LocalPort 22 >> /etc/ssh/sshd_config.anaconda | ||||
| echo "    ChrootDirectory /mnt/sysimage" >> /etc/ssh/sshd_config.anaconda | ||||
| kill -HUP $(cat /run/sshd.pid) | ||||
|  | ||||
| # Preserve the ssh setup work done for the installer | ||||
| # by copying into the target system and setting up | ||||
|   | ||||
| @@ -9,12 +9,11 @@ if lspci -d 15b3:: -n |grep 15b3 > /dev/null; then | ||||
|     # two lines to use the .iso instead of the tgz packaging | ||||
|     #fetch_remote infiniband/mofed.iso | ||||
|     #mkdir MLNX_OFED | ||||
|     #mount -o loop ofed.iso MLNX_OFED | ||||
|     #mount -o loop infiniband/mofed.iso MLNX_OFED | ||||
|     fetch_remote infiniband/mofed.tgz | ||||
|     tar xf infiniband/mofed.tgz | ||||
|     # The rest is common between tar and iso | ||||
|     cd MLNX_OFED* | ||||
|     mount -o loop ofed | ||||
|     ./mlnxofedinstall --force | ||||
| fi | ||||
|  | ||||
|   | ||||
| @@ -74,7 +74,7 @@ curl -f https://$mgr/confluent-public/os/$profile/scripts/functions > /tmp/funct | ||||
| . /tmp/functions | ||||
| run_remote pre.custom | ||||
| run_remote_parts pre | ||||
| if [ -e /tmp/installdisk ]; then | ||||
| if [ ! -e /tmp/installdisk ]; then | ||||
|     run_remote_python getinstalldisk | ||||
| fi | ||||
| if [ -e /tmp/installdisk -a ! -e /tmp/partitioning ]; then | ||||
|   | ||||
		Reference in New Issue
	
	Block a user