diff --git a/confluent_client/bin/nodebmcpassword b/confluent_client/bin/nodebmcpassword index f76b076c..135abb96 100755 --- a/confluent_client/bin/nodebmcpassword +++ b/confluent_client/bin/nodebmcpassword @@ -88,6 +88,7 @@ for rsp in session.read('/noderange/{0}/configuration/management_controller/user for node in databynode: if 'error' in rsp['databynode'][node]: print(node, ':', rsp['databynode'][node]['error']) + errorNodes.add(node) continue for user in rsp['databynode'][node]['users']: if user['username'] == username: @@ -97,6 +98,10 @@ for rsp in session.read('/noderange/{0}/configuration/management_controller/user uid_dict[user['uid']] = uid_dict[user['uid']] + ',{}'.format(node) break +if not uid_dict: + print("Error: Could not reach target node's bmc user") + sys.exit(1) + for uid in uid_dict: success = session.simple_noderange_command(uid_dict[uid], 'configuration/management_controller/users/{0}'.format(uid), new_password, key='password', errnodes=errorNodes) # = 0 if successful diff --git a/confluent_osdeploy/common/profile/scripts/confignet b/confluent_osdeploy/common/profile/scripts/confignet index 8cda6c83..72462834 100644 --- a/confluent_osdeploy/common/profile/scripts/confignet +++ b/confluent_osdeploy/common/profile/scripts/confignet @@ -192,8 +192,10 @@ class NetplanManager(object): if needcfgwrite: needcfgapply = True newcfg = {'network': {'version': 2, 'ethernets': {devname: self.cfgbydev[devname]}}} + oumask = os.umask(0o77) with open('/etc/netplan/{0}-confluentcfg.yaml'.format(devname), 'w') as planout: planout.write(yaml.dump(newcfg)) + os.umask(oumask) if needcfgapply: subprocess.call(['netplan', 'apply']) diff --git a/confluent_osdeploy/el8/profiles/default/scripts/pre.sh b/confluent_osdeploy/el8/profiles/default/scripts/pre.sh index 4d76aaa3..cd831360 100644 --- a/confluent_osdeploy/el8/profiles/default/scripts/pre.sh +++ b/confluent_osdeploy/el8/profiles/default/scripts/pre.sh @@ -115,7 +115,7 @@ grep '^%include /tmp/partitioning' /tmp/kickstart.* > /dev/null || rm /tmp/insta if [ -e /tmp/installdisk -a ! -e /tmp/partitioning ]; then INSTALLDISK=$(cat /tmp/installdisk) sed -e s/%%INSTALLDISK%%/$INSTALLDISK/ -e s/%%LUKSHOOK%%/$LUKSPARTY/ /tmp/partitioning.template > /tmp/partitioning - dd if=/dev/zero of=/dev/$(cat /tmp/installdisk) bs=1M count=1 >& /dev/null vgchange -a n >& /dev/null + wipefs -a -f /dev/$INSTALLDISK >& /dev/null fi kill $logshowpid diff --git a/confluent_osdeploy/el9-diskless/initramfs/usr/lib/dracut/hooks/cmdline/10-confluentdiskless.sh b/confluent_osdeploy/el9-diskless/initramfs/usr/lib/dracut/hooks/cmdline/10-confluentdiskless.sh index a4f10ee2..9b885e82 100644 --- a/confluent_osdeploy/el9-diskless/initramfs/usr/lib/dracut/hooks/cmdline/10-confluentdiskless.sh +++ b/confluent_osdeploy/el9-diskless/initramfs/usr/lib/dracut/hooks/cmdline/10-confluentdiskless.sh @@ -171,6 +171,13 @@ permissions= wait-device-timeout=60000 EOC +if [ "$linktype" = infiniband ]; then +cat >> /run/NetworkManager/system-connections/$ifname.nmconnection << EOC +[infiniband] +transport-mode=datagram + +EOC +fi autoconfigmethod=$(grep ^ipv4_method: /etc/confluent/confluent.deploycfg |awk '{print $2}') auto6configmethod=$(grep ^ipv6_method: /etc/confluent/confluent.deploycfg |awk '{print $2}') if [ "$autoconfigmethod" = "dhcp" ]; then diff --git a/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/onboot.service b/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/onboot.service new file mode 100644 index 00000000..f9235033 --- /dev/null +++ b/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/onboot.service @@ -0,0 +1,11 @@ +[Unit] +Description=Confluent onboot hook +Requires=network-online.target +After=network-online.target + +[Service] +ExecStart=/opt/confluent/bin/onboot.sh + +[Install] +WantedBy=multi-user.target + diff --git a/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/onboot.sh b/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/onboot.sh new file mode 100644 index 00000000..cc470d6f --- /dev/null +++ b/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/onboot.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +# This script is executed on each boot as it is +# completed. It is best to edit the middle of the file as +# noted below so custom commands are executed before +# the script notifies confluent that install is fully complete. + +nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}') +confluent_apikey=$(cat /etc/confluent/confluent.apikey) +v4meth=$(grep ^ipv4_method: /etc/confluent/confluent.deploycfg|awk '{print $2}') +if [ "$v4meth" = "null" -o -z "$v4meth" ]; then + confluent_mgr=$(grep ^deploy_server_v6: /etc/confluent/confluent.deploycfg|awk '{print $2}') +fi +if [ -z "$confluent_mgr" ]; then + confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg|awk '{print $2}') +fi +confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg|awk '{print $2}') +timedatectl set-timezone $(grep ^timezone: /etc/confluent/confluent.deploycfg|awk '{print $2}') +hostnamectl set-hostname $nodename +export nodename confluent_mgr confluent_profile +. /etc/confluent/functions +mkdir -p /var/log/confluent +chmod 700 /var/log/confluent +exec >> /var/log/confluent/confluent-onboot.log +exec 2>> /var/log/confluent/confluent-onboot.log +chmod 600 /var/log/confluent/confluent-onboot.log +tail -f /var/log/confluent/confluent-onboot.log > /dev/console & +logshowpid=$! + +run_remote_python syncfileclient +run_remote_python confignet + +# onboot scripts may be placed into onboot.d, e.g. onboot.d/01-firstaction.sh, onboot.d/02-secondaction.sh +run_remote_parts onboot.d + +# Induce execution of remote configuration, e.g. ansible plays in ansible/onboot.d/ +run_remote_config onboot.d + +#curl -X POST -d 'status: booted' -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$confluent_mgr/confluent-api/self/updatestatus +kill $logshowpid diff --git a/confluent_osdeploy/ubuntu22.04/initramfs/scripts/casper-bottom/99confluent b/confluent_osdeploy/ubuntu22.04/initramfs/scripts/casper-bottom/99confluent index e066714e..d629cf32 100755 --- a/confluent_osdeploy/ubuntu22.04/initramfs/scripts/casper-bottom/99confluent +++ b/confluent_osdeploy/ubuntu22.04/initramfs/scripts/casper-bottom/99confluent @@ -26,12 +26,14 @@ if [ -e /tmp/cnflnthmackeytmp ]; then chroot . curl -f -H "CONFLUENT_NODENAME: $NODENAME" -H "CONFLUENT_CRYPTHMAC: $(cat /root/$hmacfile)" -d @/tmp/cnflntcryptfile https://$MGR/confluent-api/self/registerapikey cp /root/$passfile /root/custom-installation/confluent/confluent.apikey DEVICE=$(cat /tmp/autodetectnic) + IP=done else chroot . custom-installation/confluent/bin/clortho $NODENAME $MGR > /root/custom-installation/confluent/confluent.apikey MGR=[$MGR] nic=$(grep ^MANAGER /custom-installation/confluent/confluent.info|grep fe80::|sed -e s/.*%//|head -n 1) nic=$(ip link |grep ^$nic:|awk '{print $2}') DEVICE=${nic%:} + IP=done fi if [ -z "$MGTIFACE" ]; then chroot . usr/bin/curl -f -H "CONFLUENT_NODENAME: $NODENAME" -H "CONFLUENT_APIKEY: $(cat /root//custom-installation/confluent/confluent.apikey)" https://${MGR}/confluent-api/self/deploycfg > $deploycfg diff --git a/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/firstboot.sh b/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/firstboot.sh index c0ba44ab..996bfffe 100755 --- a/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/firstboot.sh +++ b/confluent_osdeploy/ubuntu22.04/profiles/default/scripts/firstboot.sh @@ -3,11 +3,11 @@ echo "Confluent first boot is running" HOME=$(getent passwd $(whoami)|cut -d: -f 6) export HOME ( -exec >> /target/var/log/confluent/confluent-firstboot.log -exec 2>> /target/var/log/confluent/confluent-firstboot.log -chmod 600 /target/var/log/confluent/confluent-firstboot.log +exec >> /var/log/confluent/confluent-firstboot.log +exec 2>> /var/log/confluent/confluent-firstboot.log +chmod 600 /var/log/confluent/confluent-firstboot.log cp -a /etc/confluent/ssh/* /etc/ssh/ -systemctl restart sshd +systemctl restart ssh rootpw=$(grep ^rootpassword: /etc/confluent/confluent.deploycfg |awk '{print $2}') if [ ! -z "$rootpw" -a "$rootpw" != "null" ]; then echo root:$rootpw | chpasswd -e @@ -27,4 +27,4 @@ run_remote_parts firstboot.d run_remote_config firstboot.d curl --capath /etc/confluent/tls -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" -X POST -d "status: complete" https://$confluent_mgr/confluent-api/self/updatestatus ) & -tail --pid $! -n 0 -F /target/var/log/confluent/confluent-post.log > /dev/console +tail --pid $! -n 0 -F /var/log/confluent/confluent-post.log > /dev/console diff --git a/confluent_server/confluent/netutil.py b/confluent_server/confluent/netutil.py index 9e9fd597..9bac92c2 100644 --- a/confluent_server/confluent/netutil.py +++ b/confluent_server/confluent/netutil.py @@ -320,7 +320,7 @@ def get_full_net_config(configmanager, node, serverip=None): if val is None: continue if attrib.startswith('net.'): - attrib = attrib.replace('net.', '').rsplit('.', 1) + attrib = attrib.replace('net.', '', 1).rsplit('.', 1) if len(attrib) == 1: iface = None attrib = attrib[0] diff --git a/confluent_server/confluent/osimage.py b/confluent_server/confluent/osimage.py index 02363408..57296663 100644 --- a/confluent_server/confluent/osimage.py +++ b/confluent_server/confluent/osimage.py @@ -158,16 +158,34 @@ def find_glob(loc, fileglob): for cdir, _, fs in os.walk(loc): for f in fs: if fnmatch(f, fileglob): - return os.path.join(cdir, f) + return [os.path.join(cdir, f)] return None async def update_boot_linux(profiledir, profile, label): profname = os.path.basename(profiledir) kernelargs = profile.get('kernelargs', '') + needefi = False + for grubexe in glob.glob(profiledir + '/boot/efi/boot/grubx64.efi'): + with open(grubexe, 'rb') as grubin: + grubcontent = grubin.read() + uaidx = grubcontent.find(b'User-Agent: GRUB 2.0') + if uaidx > 0: + grubcontent = grubcontent[uaidx:] + cridx = grubcontent.find(b'\r') + if cridx > 1: + grubcontent = grubcontent[:cridx] + grubver = grubcontent.split(b'~', 1)[0] + grubver = grubver.rsplit(b' ', 1)[-1] + grubver = grubver.split(b'.') + if len(grubver) > 1: + if int(grubver[0]) < 3 and int(grubver[1]) < 3: + needefi = True + lincmd = 'linuxefi' if needefi else 'linux' + initrdcmd = 'initrdefi' if needefi else 'initrd' grubcfg = "set timeout=5\nmenuentry '" grubcfg += label - grubcfg += "' {\n linuxefi /kernel " + kernelargs + "\n" + grubcfg += "' {\n " + lincmd + " /kernel " + kernelargs + "\n" initrds = [] for initramfs in glob.glob(profiledir + '/boot/initramfs/*.cpio'): initramfs = os.path.basename(initramfs) @@ -175,16 +193,21 @@ async def update_boot_linux(profiledir, profile, label): for initramfs in os.listdir(profiledir + '/boot/initramfs'): if initramfs not in initrds: initrds.append(initramfs) - grubcfg += " initrdefi " + grubcfg += " " + initrdcmd + " " for initramfs in initrds: grubcfg += " /initramfs/{0}".format(initramfs) grubcfg += "\n}\n" # well need to honor grubprefix path if different grubcfgpath = find_glob(profiledir + '/boot', 'grub.cfg') if not grubcfgpath: - grubcfgpath = profiledir + '/boot/efi/boot/grub.cfg' - with open(grubcfgpath, 'w') as grubout: - grubout.write(grubcfg) + grubcfgpath = [ + profiledir + '/boot/efi/boot/grub.cfg', + profiledir + '/boot/boot/grub/grub.cfg' + ] + for grubcfgpth in grubcfgpath: + os.makedirs(os.path.dirname(grubcfgpth), 0o755, exist_ok=True) + with open(grubcfgpth, 'w') as grubout: + grubout.write(grubcfg) ipxeargs = kernelargs for initramfs in initrds: ipxeargs += " initrd=" + initramfs diff --git a/imgutil/builddeb b/imgutil/builddeb new file mode 100755 index 00000000..7e12a6e6 --- /dev/null +++ b/imgutil/builddeb @@ -0,0 +1,24 @@ +#!/bin/bash +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 +mkdir -p /tmp/confluent-imgutil +cp -a * /tmp/confluent-imgutil +cp ../LICENSE /tmp/confluent-imgutil +cd /tmp/confluent-imgutil +rm -rf deb/confluent_imgutil_$VERSION/ +mkdir -p deb/confluent_imgutil_$VERSION/DEBIAN/ +mkdir -p deb/confluent_imgutil_$VERSION/opt/confluent/lib/imgutil +mkdir -p deb/confluent_imgutil_$VERSION/opt/confluent/bin +mv imgutil deb/confluent_imgutil_$VERSION/opt/confluent/bin/ +chmod a+x deb/confluent_imgutil_$VERSION/opt/confluent/bin/imgutil +mv ubuntu* suse15 el7 el9 el8 deb/confluent_imgutil_$VERSION/opt/confluent/lib/imgutil/ +mkdir -p deb/confluent_imgutil_$VERSION/opt/confluent/share/licenses/confluent_imgutil +cp LICENSE deb/confluent_imgutil_$VERSION/opt/confluent/share/licenses/confluent_imgutil +sed -e 's/#VERSION#/'$VERSION/ control.tmpl > deb/confluent_imgutil_$VERSION/DEBIAN/control +dpkg-deb --build deb/confluent_imgutil_$VERSION +if [ ! -z "$1" ]; then + mv deb/confluent_imgutil_$VERSION.deb $1 +fi diff --git a/imgutil/control.tmpl b/imgutil/control.tmpl new file mode 100644 index 00000000..a0fe21af --- /dev/null +++ b/imgutil/control.tmpl @@ -0,0 +1,8 @@ +Package: confluent-imgutil +Version: #VERSION# +Section: base +Priority: optional +Maintainer: Jarrod Johnson +Description: Web frontend for confluent server +Architecture: all + diff --git a/imgutil/imgutil b/imgutil/imgutil index 022279cc..907a3b64 100644 --- a/imgutil/imgutil +++ b/imgutil/imgutil @@ -655,10 +655,18 @@ class DebHandler(OsHandler): def prep_root(self, args): shutil.copy('/etc/apt/sources.list', os.path.join(self.targpath, 'etc/apt/sources.list')) + for listfile in glob.glob('/etc/apt/sources.list.d/*'): + shutil.copy(listfile, os.path.join(self.targpath, listfile[1:])) args.cmd = ['apt-get', 'update'] run_constrainedx(fancy_chroot, (args, self.targpath)) args.cmd = ['apt-get', '-y', 'install'] + self.includepkgs run_constrainedx(fancy_chroot, (args, self.targpath)) + servicefile = os.path.join(self.targpath, 'usr/lib/systemd/system/ssh.service') + if os.path.exists(servicefile): + os.symlink('/usr/lib/systemd/system/ssh.service', os.path.join(self.targpath, 'etc/systemd/system/multi-user.target.wants/ssh.service')) + else: + os.symlink('/usr/lib/systemd/system/sshd.service', os.path.join(self.targpath, 'etc/systemd/system/multi-user.target.wants/sshd.service')) + class ElHandler(OsHandler): @@ -945,7 +953,7 @@ def fancy_chroot(args, installroot): os.chroot(installroot) os.chdir('/') _mount('/', '/', flags=MS_BIND) # Make / manifest as a mounted filesystem in exec - os.environ['PS1'] = '[\x1b[1m\x1b[4mIMGUTIL EXEC {0}\x1b[0m \W]$ '.format(imgname) + os.environ['PS1'] = '[\x1b[1m\x1b[4mIMGUTIL EXEC {0}\x1b[0m \\W]$ '.format(imgname) os.environ['CONFLUENT_IMGUTIL_MODE'] = 'exec' if oshandler: oshandler.set_source('/run/confluentdistro') diff --git a/imgutil/ubuntu24.04 b/imgutil/ubuntu24.04 new file mode 120000 index 00000000..7d13753d --- /dev/null +++ b/imgutil/ubuntu24.04 @@ -0,0 +1 @@ +ubuntu \ No newline at end of file