2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-09-09 14:36:44 +00:00

Merge pull request #297 from Obihoernchen/sles16-support

Sles16 support
This commit is contained in:
Jarrod Johnson
2026-09-09 08:30:38 -04:00
committed by GitHub
32 changed files with 854 additions and 54 deletions
@@ -47,7 +47,7 @@ for os in rhvh4 el7 genesis el8 suse15 suse16 debian debian13 ubuntu20.04 ubuntu
mv ../addons.cpio .
cd ..
done
for os in el7 el8 suse15 el9 el10 ubuntu20.04 ubuntu22.04 ubuntu24.04 ubuntu26.04; do
for os in el7 el8 suse15 suse16 el9 el10 ubuntu20.04 ubuntu22.04 ubuntu24.04 ubuntu26.04; do
mkdir ${os}disklessout
cd ${os}disklessout
if [ -d ../${os}bin ]; then
@@ -49,7 +49,7 @@ for os in rhvh4 el7 genesis el8 suse15 suse16 debian debian13 ubuntu18.04 ubuntu
mv ../addons.cpio .
cd ..
done
for os in el7 el8 suse15 el9 el10 ubuntu20.04 ubuntu22.04 ubuntu24.04 ubuntu26.04; do
for os in el7 el8 suse15 suse16 el9 el10 ubuntu20.04 ubuntu22.04 ubuntu24.04 ubuntu26.04; do
mkdir ${os}disklessout
cd ${os}disklessout
if [ -d ../${os}bin ]; then
@@ -0,0 +1,281 @@
pcrextendvalue=2fbe96c50dde38ce9cd2764ddb79c216cfbcd3499568b1125450e60c45dd19f2
pcrhashalgo=sha256
set_tpm_hashalgo() {
if [ -n "$confluent_tpm_hashalgo" ]; then
pcrhashalgo="$confluent_tpm_hashalgo"
return 0
fi
tpm_pcrbanks=$(tpm2_getcap pcrs 2>/dev/null)
for algo in sha256 sha512 sha384; do
# Match only banks that actually have PCRs allocated (a digit in [ ... ]).
if echo "$tpm_pcrbanks" | grep -Eq "$algo:[[:space:]]*\[[^]]*[0-9]"; then
confluent_tpm_hashalgo="$algo"
pcrhashalgo="$algo"
if [[ "$algo" == "sha256" ]]; then
pcrextendvalue=2fbe96c50dde38ce9cd2764ddb79c216cfbcd3499568b1125450e60c45dd19f2
elif [[ "$algo" == "sha384" ]]; then
pcrextendvalue=20aaa1073c215c8bc97ff8dc509dd63ff09eef9d2dfa4d8ef224ce372d80e5417e53840ef2fb72924c195f69396a27b9
elif [[ "$algo" == "sha512" ]]; then
pcrextendvalue=77113aa32ac249789c0cdcf24e78efdb81d5be0d878e9a9a750446ecf9b9b3b1c084194eb6187cfd890b8f61a7f2e79eb4d33f6f27827b862367897c8123bceb
fi
return 0
fi
done
return 1
}
get_remote_apikey() {
while [ -z "$confluent_apikey" ]; do
/opt/confluent/bin/clortho $nodename $confluent_mgr > /etc/confluent/confluent.apikey
if grep ^SEALED: /etc/confluent/confluent.apikey > /dev/null; then
# we don't support remote sealed api keys
echo > /etc/confluent/confluent.apikey
fi
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
if [ -z "$confluent_apikey" ]; then
echo "Unable to acquire node api key, set deployment.apiarmed=once on node '$nodename', retrying..."
sleep 10
else
tmpdir=$(mktemp -d)
cd $tmpdir
set_tpm_hashalgo
tpm2_startauthsession --session=session.ctx
tpm2_policypcr -Q --session=session.ctx --pcr-list="${pcrhashalgo}:15" --policy=pcr15.${pcrhashalgo}.policy
tpm2_createprimary -G ecc -Q --key-context=prim.ctx
(echo -n "CONFLUENT_APIKEY:";cat /etc/confluent/confluent.apikey) | tpm2_create -Q --policy=pcr15.${pcrhashalgo}.policy --public=data.pub --private=data.priv -i - -C prim.ctx
tpm2_load -Q --parent-context=prim.ctx --public=data.pub --private=data.priv --name=confluent.apikey --key-context=data.ctx
tpm2_evictcontrol -Q -c data.ctx
tpm2_flushcontext session.ctx
cd - > /dev/null
rm -rf $tmpdir
fi
done
}
root=1
rootok=1
netroot=confluent
clear
mkdir -p /etc/ssh
mkdir -p /var/tmp/
mkdir -p /var/lib/empty
mkdir -p /var/empty/sshd
mkdir -p /etc/confluent
sed -i '/^root:x/d' /etc/passwd
echo root:x:0:0::/:/bin/bash >> /etc/passwd
echo sshd:x:30:30:SSH User:/var/empty/sshd:/sbin/nologin >> /etc/passwd
if ! grep console= /proc/cmdline >& /dev/null; then
autocons=$(/opt/confluent/bin/autocons)
autocons=${autocons##*/}
if [ ! -z "$autocons" ]; then
echo "Automatic console configured for $autocons"
fi
fi
echo "Initializing confluent diskless environment"
echo -n "udevd: "
/usr/lib/systemd/systemd-udevd --daemon
echo -n "Loading drivers..."
udevadm trigger
udevadm trigger --type=devices --action=add
udevadm settle
modprobe ib_ipoib
modprobe ib_umad
modprobe hfi1
modprobe mlx5_ib
echo "done"
cat > /etc/ssh/sshd_config << EOF
Port 2222
Subsystem sftp /usr/libexec/openssh/sftp-server
PermitRootLogin yes
AuthorizedKeysFile .ssh/authorized_keys
EOF
mkdir /root/.ssh
mkdir /.ssh
cat /ssh/*pubkey > /root/.ssh/authorized_keys 2>/dev/null
cp /root/.ssh/authorized_keys /.ssh/
cat /tls/*.pem > /etc/confluent/ca.pem
mkdir -p /var/lib/ca-certificates/
cat /tls/*.pem > /var/lib/ca-certificates/ca-bundle.pem
TRIES=0
oldumask=$(umask)
umask 0077
tpmdir=$(mktemp -d)
cd $tpmdir
lasthdl=""
for hdl in $(tpm2_getcap handles-persistent|awk '{print $2}'); do
tpm2_startauthsession --policy-session --session=session.ctx
set_tpm_hashalgo
tpm2_policypcr -Q --session=session.ctx --pcr-list="${pcrhashalgo}:15" --policy=pcr15.${pcrhashalgo}.policy
unsealeddata=$(tpm2_unseal --auth=session:session.ctx -Q -c $hdl 2>/dev/null)
tpm2_flushcontext session.ctx
if [[ $unsealeddata == "CONFLUENT_APIKEY:"* ]]; then
confluent_apikey=${unsealeddata#CONFLUENT_APIKEY:}
echo $confluent_apikey > /etc/confluent/confluent.apikey
if [ -n "$lasthdl" ]; then
tpm2_evictcontrol -c $lasthdl
fi
lasthdl=$hdl
fi
done
cd - > /dev/null
rm -rf $tpmdir
touch /etc/confluent/confluent.info
cd /sys/class/net
echo -n "Scanning for network configuration..."
while ! grep ^EXTMGRINFO: /etc/confluent/confluent.info | awk -F'|' '{print $3}' | grep 1 >& /dev/null && [ "$TRIES" -lt 30 ]; do
TRIES=$((TRIES + 1))
for i in *; do
ip link set $i up
done
/opt/confluent/bin/copernicus -t > /etc/confluent/confluent.info
echo -n .
done
# The loop above has no delay, so on a link that takes a moment to come up it
# can burn all 30 tries before the first packet can go anywhere. Keep asking.
TRIES=0
while ! grep ^NODENAME: /etc/confluent/confluent.info >& /dev/null && [ "$TRIES" -lt 300 ]; do
sleep 0.5
echo -n .
/opt/confluent/bin/copernicus -t > /etc/confluent/confluent.info
TRIES=$((TRIES + 1))
done
cd /
nodename=$(grep ^NODENAME /etc/confluent/confluent.info|awk '{print $2}')
hostname $nodename
confluent_mgr=$(grep '^EXTMGRINFO:.*1$' /etc/confluent/confluent.info | head -n 1|awk -F': ' '{print $2}' | awk -F'|' '{print $1}')
if [ -z "$confluent_mgr" ]; then
confluent_mgr=$(grep ^MANAGER: /etc/confluent/confluent.info|head -n 1 | awk '{print $2}')
fi
if [[ $confluent_mgr == *%* ]]; then
echo $confluent_mgr | awk -F% '{print $2}' > /tmp/confluent.ifidx
ifidx=$(cat /tmp/confluent.ifidx)
ifname=$(ip link |grep ^$ifidx:|awk '{print $2}')
ifname=${ifname%:}
fi
ready=0
while [ $ready = "0" ]; do
get_remote_apikey
if [[ $confluent_mgr == *:* ]] && [[ $confluent_mgr != "["* ]]; then
confluent_mgr="[$confluent_mgr]"
fi
tmperr=$(mktemp)
curl -sSf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$confluent_mgr/confluent-api/self/deploycfg > /etc/confluent/confluent.deploycfg 2> $tmperr
if grep 401 $tmperr > /dev/null; then
confluent_apikey=""
if [ -n "$lasthdl" ]; then
tpm2_evictcontrol -c $lasthdl
fi
confluent_mgr=${confluent_mgr#[}
confluent_mgr=${confluent_mgr%]}
else
ready=1
fi
rm $tmperr
done
if [ ! -z "$autocons" ] && grep textconsole: true /etc/confluent/confluent.deploycfg > /dev/null; then /opt/confluent/bin/autocons -c > /dev/null; fi
set_tpm_hashalgo
tpm2_pcrextend 15:${pcrhashalgo}=${pcrextendvalue}
umask $oldumask
# The root filesystem is served over this interface, so NetworkManager must
# adopt the address the initramfs set rather than reconfigure the link out from
# under it. Leave a keyfile for imageboot.sh to place in the image. 15 handed
# wicked an ifcfg file for the same reason.
nameservers=""
nameserversec=0
while read -r entry; do
if [ $nameserversec = 1 ]; then
if [[ $entry == "-"* ]] && [[ $entry != "- ''" ]]; then
nameservers="$nameservers"${entry#- }";"
continue
fi
fi
nameserversec=0
if [ "${entry%:*}" = "nameservers" ]; then
nameserversec=1
continue
fi
done < /etc/confluent/confluent.deploycfg
dnsdomain=$(grep ^dnsdomain: /etc/confluent/confluent.deploycfg)
dnsdomain=${dnsdomain#dnsdomain: }
if [ "$dnsdomain" = "null" ]; then
dnsdomain=""
fi
mkdir -p /run/confluent
nmcfg=/run/confluent/$ifname.nmconnection
linktype=$(ip link show dev "$ifname" | grep link/ | awk '{print $1}')
if [ "$linktype" = link/infiniband ]; then
linktype=infiniband
else
linktype=ethernet
fi
printf '[connection]\nid=%s\ntype=%s\ninterface-name=%s\nautoconnect=true\n' "$ifname" "$linktype" "$ifname" > $nmcfg
if [ "$linktype" = infiniband ]; then
printf '\n[infiniband]\ntransport-mode=datagram\n' >> $nmcfg
fi
autoconfigmethod=$(grep ipv4_method /etc/confluent/confluent.deploycfg |awk '{print $2}')
if [ "$autoconfigmethod" = "dhcp" ]; then
echo -n "Attempting to use dhcp to bring up $ifname..."
dhcpcd $ifname
echo "Complete:"
ip addr show dev $ifname
printf '\n[ipv4]\nmethod=auto\n' >> $nmcfg
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
printf '\n[ipv4]\nmethod=manual\naddress1=%s/%s' "$v4addr" "$v4nm" >> $nmcfg
if [ ! -z "$v4gw" ]; then
printf ',%s' "$v4gw" >> $nmcfg
fi
printf '\n' >> $nmcfg
if [ ! -z "$nameservers" ]; then
printf 'dns=%s\n' "$nameservers" >> $nmcfg
fi
if [ ! -z "$dnsdomain" ]; then
printf 'dns-search=%s\n' "$dnsdomain" >> $nmcfg
fi
fi
printf '\n[ipv6]\nmethod=link-local\n' >> $nmcfg
chmod 600 $nmcfg
echo -n "Initializing ssh..."
ssh-keygen -A
for pubkey in /etc/ssh/ssh_host*key.pub; do
certfile=${pubkey/.pub/-cert.pub}
privfile=${pubkey%.pub}
curl -sf -X POST -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" -d @$pubkey https://$confluent_mgr/confluent-api/self/sshcert > $certfile
if [ -s $certfile ]; then
echo HostCertificate $certfile >> /etc/ssh/sshd_config
fi
echo HostKey $privfile >> /etc/ssh/sshd_config
done
/usr/sbin/sshd
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg| awk '{print $2}')
confluent_proto=$(grep ^protocol: /etc/confluent/confluent.deploycfg| awk '{print $2}')
confluent_urls=""
for addr in $(grep ^MANAGER: /etc/confluent/confluent.info|awk '{print $2}'|sed -e s/%/%25/); do
if [[ $addr == *:* ]]; then
confluent_urls="$confluent_urls $confluent_proto://[$addr]/confluent-public/os/$confluent_profile/rootimg.sfs"
else
confluent_urls="$confluent_urls $confluent_proto://$addr/confluent-public/os/$confluent_profile/rootimg.sfs"
fi
done
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg| awk '{print $2}')
mkdir -p /etc/confluent
curl -sf https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/functions > /etc/confluent/functions
. /etc/confluent/functions
source_remote imageboot.sh
@@ -0,0 +1,134 @@
. /lib/dracut-lib.sh
mkdir -p /mnt/remoteimg /mnt/remote /mnt/overlay
if [ "untethered" = "$(getarg confluent_imagemethod)" ]; then
mount -t tmpfs untethered /mnt/remoteimg
curl https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs
else
confluent_urls="$confluent_urls https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs"
/opt/confluent/bin/urlmount $confluent_urls /mnt/remoteimg
fi
/opt/confluent/bin/confluent_imginfo /mnt/remoteimg/rootimg.sfs > /tmp/rootimg.info
loopdev=$(losetup -f)
export mountsrc=$loopdev
losetup -r $loopdev /mnt/remoteimg/rootimg.sfs
if grep '^Format: confluent_crypted' /tmp/rootimg.info > /dev/null; then
curl -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" https://$confluent_mgr/confluent-api/self/profileprivate/pending/rootimg.key > /tmp/rootimg.key
cipher=$(head -n 1 /tmp/rootimg.key)
key=$(tail -n 1 /tmp/rootimg.key)
len=$(wc -c /mnt/remoteimg/rootimg.sfs | awk '{print $1}')
len=$(((len-4096)/512))
dmsetup create cryptimg --table "0 $len crypt $cipher $key 0 $loopdev 8"
/opt/confluent/bin/confluent_imginfo /dev/mapper/cryptimg > /tmp/rootimg.info
mountsrc=/dev/mapper/cryptimg
fi
if grep '^Format: squashfs' /tmp/rootimg.info > /dev/null; then
mount -o ro $mountsrc /mnt/remote
elif grep '^Format: confluent_multisquash' /tmp/rootimg.info; then
tail -n +3 /tmp/rootimg.info | awk '{gsub("/", "_"); print "echo 0 " $4 " linear '$mountsrc' " $3 " | dmsetup create mproot" $7}' > /tmp/setupmount.sh
. /tmp/setupmount.sh
cat /tmp/setupmount.sh |awk '{printf "mount /dev/mapper/"$NF" "; sub("mproot", ""); gsub("_", "/"); print "/mnt/remote"$NF}' > /tmp/mountparts.sh
. /tmp/mountparts.sh
fi
#mount -t tmpfs overlay /mnt/overlay
modprobe zram
memtot=$(grep ^MemTotal: /proc/meminfo|awk '{print $2}')
memtot=$((memtot/2))$(grep ^MemTotal: /proc/meminfo | awk '{print $3'})
echo $memtot > /sys/block/zram0/disksize
mkfs.xfs /dev/zram0 > /dev/null
mount -o discard /dev/zram0 /mnt/overlay
if [ ! -f /tmp/mountparts.sh ]; then
mkdir -p /mnt/overlay/upper /mnt/overlay/work
mount -t overlay -o upperdir=/mnt/overlay/upper,workdir=/mnt/overlay/work,lowerdir=/mnt/remote disklessroot /sysroot
else
for srcmount in $(cat /tmp/mountparts.sh | awk '{print $3}'); do
mkdir -p /mnt/overlay${srcmount}/upper /mnt/overlay${srcmount}/work
mount -t overlay -o upperdir=/mnt/overlay${srcmount}/upper,workdir=/mnt/overlay${srcmount}/work,lowerdir=${srcmount} disklesspart /sysroot${srcmount#/mnt/remote}
done
fi
mkdir -p /sysroot/etc/ssh
mkdir -p /sysroot/etc/confluent
mkdir -p /sysroot/root/.ssh
cp /root/.ssh/* /sysroot/root/.ssh
chmod 700 /sysroot/root/.ssh
cp /etc/confluent/* /sysroot/etc/confluent/
cp /etc/ssh/*key* /sysroot/etc/ssh/
for pubkey in /etc/ssh/ssh_host*key.pub; do
certfile=${pubkey/.pub/-cert.pub}
privfile=${pubkey%.pub}
if [ -s $certfile ]; then
echo HostCertificate $certfile >> /sysroot/etc/ssh/sshd_config
fi
echo HostKey $privfile >> /sysroot/etc/ssh/sshd_config
done
mkdir -p /sysroot/dev /sysroot/sys /sysroot/proc /sysroot/run
if [ ! -z "$autocons" ]; then
autocons=${autocons%,*}
mkdir -p /run/systemd/generator/getty.target.wants
ln -s /usr/lib/systemd/system/serial-getty@.service /run/systemd/generator/getty.target.wants/serial-getty@${autocons}.service
fi
while [ ! -e /sysroot/sbin/init ]; do
echo "Failed to access root filesystem or it is missing /sbin/init"
echo "System should be accessible through ssh at port 2222 with the appropriate key"
while [ ! -e /sysroot/sbin/init ]; do
sleep 1
done
done
rootpassword=$(grep ^rootpassword: /etc/confluent/confluent.deploycfg)
rootpassword=${rootpassword#rootpassword: }
if [ "$rootpassword" = "null" ]; then
rootpassword=""
fi
if [ ! -z "$rootpassword" ]; then
sed -i "s@root:[^:]*:@root:$rootpassword:@" /sysroot/etc/shadow
fi
for i in /ssh/*.ca; do
echo '@cert-authority *' $(cat $i) >> /sysroot/etc/ssh/ssh_known_hosts
done
echo HostbasedAuthentication yes >> /sysroot/etc/ssh/sshd_config
echo HostbasedUsesNameFromPacketOnly yes >> /sysroot/etc/ssh/sshd_config
echo IgnoreRhosts no >> /sysroot/etc/ssh/sshd_config
sshconf=/sysroot/etc/ssh/ssh_config
if [ -d /sysroot/etc/ssh/ssh_config.d/ ]; then
sshconf=/sysroot/etc/ssh/ssh_config.d/01-confluent.conf
fi
echo 'Host *' >> $sshconf
echo ' HostbasedAuthentication yes' >> $sshconf
echo ' EnableSSHKeysign yes' >> $sshconf
echo ' HostbasedKeyTypes *ed25519*' >> $sshconf
curl -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $(cat /etc/confluent/confluent.apikey)" https://$confluent_mgr/confluent-api/self/nodelist > /sysroot/etc/ssh/shosts.equiv
cp /sysroot/etc/ssh/shosts.equiv /sysroot/root/.shosts
chmod 600 /sysroot/etc/ssh/*_key
chroot /sysroot cat /etc/confluent/ca.pem >> /sysroot/var/lib/ca-certificates/ca-bundle.pem
curl -sf https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/onboot.service > /sysroot/etc/systemd/system/onboot.service
mkdir -p /sysroot/opt/confluent/bin
curl -sf https://$confluent_mgr/confluent-public/os/$confluent_profile/scripts/onboot.sh > /sysroot/opt/confluent/bin/onboot.sh
chmod +x /sysroot/opt/confluent/bin/onboot.sh
cp /opt/confluent/bin/apiclient /sysroot/opt/confluent/bin
ln -s /etc/systemd/system/onboot.service /sysroot/etc/systemd/system/multi-user.target.wants/onboot.service
cp /etc/confluent/functions /sysroot/etc/confluent/functions
# Hand NetworkManager the connection the initramfs is already using. Without
# this it claims the interface on its own terms and the tethered root
# filesystem goes away with the old address. confignet refines it at onboot.
mkdir -p /sysroot/etc/NetworkManager/system-connections
for nmcfg in /run/confluent/*.nmconnection; do
[ -e "$nmcfg" ] || continue
cp $nmcfg /sysroot/etc/NetworkManager/system-connections/
chmod 600 /sysroot/etc/NetworkManager/system-connections/$(basename $nmcfg)
done
if grep installtodisk /proc/cmdline > /dev/null; then
. /etc/confluent/functions
run_remote installimage
exec reboot -f
fi
mv /lib/modules/$(uname -r) /lib/modules/$(uname -r)-ramfs
ln -s /sysroot/lib/modules/$(uname -r) /lib/modules/
if [ -d /lib/firmware ]; then
mv /lib/firmware /lib/firmware-ramfs
fi
ln -s /sysroot/lib/firmware /lib/firmware
chroot /sysroot chkstat --system --set --noheader > /dev/null
exec /opt/confluent/bin/start_root
@@ -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
@@ -0,0 +1,33 @@
#!/bin/sh
# 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)
confluent_mgr=$(grep ^deploy_server: /etc/confluent/confluent.deploycfg|awk '{print $2}')
confluent_profile=$(grep ^profile: /etc/confluent/confluent.deploycfg|awk '{print $2}')
timedatectl set-timezone $(grep ^timezone: /etc/confluent/confluent.deploycfg|awk '{print $2}')
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
run_remote onboot.custom
# 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
printf 'state: booted\nstatus: booted' | curl -X POST --data-binary @- -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$confluent_mgr/confluent-api/self/updatestatus
kill $logshowpid
@@ -0,0 +1,29 @@
# It is advised to avoid /var/lib/confluent/public as a source for syncing. /var/lib/confluent/public
# is served without authentication and thus any sensitive content would be a risk. If wanting to host
# syncfiles on a common share, it is suggested to have /var/lib/confluent be the share and use some other
# subdirectory other than public.
#
# Syncing is performed as the 'confluent' user, so all source files must be accessible by the confluent user.
#
# This file lists files to synchronize or merge to the deployed systems from the deployment server
# To specify taking /some/path/hosts on the deployment server and duplicating it to /etc/hosts:
# Note particularly the use of '->' to delineate source from target.
# /some/path/hosts -> /etc/hosts
# If wanting to simply use the same path for source and destinaiton, the -> may be skipped:
# /etc/hosts
# More function is available, for example to limit the entry to run only on n1 through n8, and to set
# owner, group, and permissions in octal notation:
# /example/source -> n1-n8:/etc/target (owner=root,group=root,permissions=600)
# Entries under APPENDONCE: will be added to specified target, only if the target does not already
# contain the data in the source already in its entirety. This allows append in a fashion that
# is friendly to being run repeatedly
# Entries under MERGE: will attempt to be intelligently merged. This supports /etc/group and /etc/passwd
# Any supporting entries in /etc/shadow or /etc/gshadow are added automatically, with password disabled
# It also will not inject 'system' ids (under 1,000 usually) as those tend to be local and rpm managed.
# MERGE:
# /etc/passwd
# /etc/group
@@ -128,7 +128,7 @@ if [ -e /dev/disk/by-label/CNFLNT_IDNT ]; then
echo 'MANAGER: '$deploysrv >> /etc/confluent/confluent.info
done
for deployer in $deploysrvs; do
if curl --capath /tls/ -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_CRYPTHMAC: $(cat $hmacfile)" -d@$passcrypt -k https://$deployer/confluent-api/self/registerapikey; then
if curl --capath /tls/ -f -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_CRYPTHMAC: $(cat $hmacfile)" -d@$passcrypt https://$deployer/confluent-api/self/registerapikey; then
cp $passfile /etc/confluent/confluent.apikey
confluent_apikey=$(cat /etc/confluent/confluent.apikey)
curl --capath /tls/ -sf -H "CONFLUENT_NODENAME: $nodename" -H "CONFLUENT_APIKEY: $confluent_apikey" https://$deployer/confluent-api/self/deploycfg2 > /etc/confluent/confluent.deploycfg
@@ -268,32 +268,10 @@ if [ "$textconsole" = "true" ] && ! grep console= /proc/cmdline > /dev/null; the
fi
fi
. /etc/os-release
if [ "$ID" = "dracut" ]; then
ID=$(echo $PRETTY_NAME|awk '{print $1}')
VERSION_ID=$(echo $VERSION|awk '{print $1}')
if [ "$ID" = "Oracle" ]; then
ID=OL
elif [ "$ID" = "Red" ]; then
ID=RHEL
fi
fi
ISOSRC=$(blkid -t TYPE=iso9660|grep -Ei ' LABEL="'$ID-$VERSION_ID|sed -e s/:.*//)
if [ -z "$ISOSRC" ]; then
echo root=live:$proto://$mgr/confluent-public/os/$profilename/distribution/1/LiveOS/squashfs.img >> /etc/cmdline.d/01-confluent.conf
echo -n " "inst.install_url=$proto://$mgr/confluent-public/os/$profilename/distribution/1/install >> /run/agama/cmdline.d/agama.conf
echo -n " "inst.script=$proto://$mgr/confluent-public/os/$profilename/autoinstall.sh" " >> /run/agama/cmdline.d/agama.conf
#echo inst.=$proto://$mgr/confluent-public/os/$profilename/distribution >> /etc/cmdline.d/01-confluent.conf
#root=anaconda-net:$proto://$mgr/confluent-public/os/$profilename/distribution
#export root
netroot=livenet:$proto://$mgr/confluent-public/os/$profilename/distribution/1/LiveOS/squashfs.img
else
echo inst.repo=cdrom:$ISOSRC >> /etc/cmdline.d/01-confluent.conf
fi
#echo inst.ks=$proto://$mgr/confluent-public/os/$profilename/kickstart >> /etc/cmdline.d/01-confluent.conf
#kickstart=$proto://$mgr/confluent-public/os/$profilename/kickstart
#export kickstart
echo root=live:$proto://$mgr/confluent-public/os/$profilename/distribution/1/LiveOS/squashfs.img >> /etc/cmdline.d/01-confluent.conf
echo -n " "inst.install_url=$proto://$mgr/confluent-public/os/$profilename/distribution/1/install >> /run/agama/cmdline.d/agama.conf
echo -n " "inst.script=$proto://$mgr/confluent-public/os/$profilename/autoinstall.sh" " >> /run/agama/cmdline.d/agama.conf
netroot=livenet:$proto://$mgr/confluent-public/os/$profilename/distribution/1/LiveOS/squashfs.img
autoconfigmethod=$(grep ipv4_method /etc/confluent/confluent.deploycfg)
autoconfigmethod=${autoconfigmethod#ipv4_method: }
if [ "$autoconfigmethod" = "dhcp" ]; then
@@ -0,0 +1,29 @@
Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the
appropriate phase of the install process.
Alternatively, plays may be placed in /var/lib/confluent/private/os/<profilename>/ansible/<directory>.
This prevents public clients from being able to read the plays, which is not necessary for them to function,
and may protect them from divulging material contained in the plays or associated roles.
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,29 @@
Ansible playbooks ending in .yml or .yaml that are placed into this directory will be executed at the
appropriate phase of the install process.
Alternatively, plays may be placed in /var/lib/confluent/private/os/<profilename>/ansible/<directory>.
This prevents public clients from being able to read the plays, which is not necessary for them to function,
and may protect them from divulging material contained in the plays or associated roles.
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
@@ -16,6 +16,9 @@
"product": {
"id": "%%PRODUCT%%"
},
"bootloader": {
"extraKernelParams": "%%INSTALLEDARGS%%"
},
"storage": {
"drives": [
{
@@ -24,6 +24,9 @@ python3 /opt/confluent/bin/apiclient /confluent-public/os/$profile/scripts/pre.s
chmod +x /tmp/pre.sh
/tmp/pre.sh > $serialcons 2>&1
kill $tailpid
agama config load /tmp/autoinstall.json <> $serialcons > $serialcons 2>&1
if ! agama config load /tmp/autoinstall.json <> $serialcons > $serialcons 2>&1; then
echo "****Failed to load the install configuration, halting install" > $serialcons
while :; do sleep 86400; done
fi
agama install <> $serialcons > $serialcons 2>&1
agama finish <> $serialcons > $serialcons 2>&1
@@ -7,7 +7,7 @@ if [ "$discnum" != 1 ]; then exit 0; fi
if [ -e $2/boot/kernel ]; then exit 0; fi
profile=$(basename $2)
sed -i 's/sle 15/SUSE Linux Enterprise 15/; s/opensuse_leap/openSUSE Leap/' $2/profile.yaml
sed -i 's/sle 16/SUSE Linux Enterprise 16/; s/opensuse_leap/openSUSE Leap/' $2/profile.yaml
ln -s $1/boot/x86_64/loader/linux $2/boot/kernel && \
ln -s $1/boot/x86_64/loader/initrd $2/boot/initramfs/distribution && \
mkdir -p $2/boot/efi/boot && \
@@ -0,0 +1,3 @@
label: %%DISTRO%% %%VERSION%% %%ARCH%% (Server Profile)
kernelargs: quiet # These arguments are passed to the installer
#installedargs: example # These arguments would be added to the installed system
@@ -0,0 +1,9 @@
#!/bin/sh
# This script runs at the end of the final boot
. /etc/confluent/functions
# Custom scripts may go here
# run_remote example.sh
# run_remote_python example.py
@@ -29,6 +29,8 @@ done
export confluent_mgr
run_remote_python confignet
run_remote firstboot.custom
# Firstboot scripts may be placed into firstboot.d, e.g. firstboot.d/01-firstaction.sh, firstboot.d/02-secondaction.sh
run_remote_parts firstboot.d
@@ -36,3 +38,6 @@ run_remote_parts firstboot.d
run_remote_config firstboot.d
python3 /opt/confluent/bin/apiclient /confluent-api/self/updatestatus -d 'status: complete'
systemctl disable confluent-firstboot
rm /etc/systemd/system/confluent-firstboot.service
@@ -0,0 +1,16 @@
#!/bin/sh
# This script runs at the end of install in the installed system
# but still under the installer kernel.
# This is a good place to run most customizations that do not have any
# dependency upon the install target kernel being active.
# If there are dependencies on the kernel (drivers or special filesystems)
# then firstboot.sh would be the script to customize.
. /etc/confluent/functions
# Examples:
# run_remote script.sh
# run_remote_python script.py
@@ -1,7 +1,7 @@
#!/bin/bash
# This script runs before the installer executes, and sets up ssh during install as well
# as rewriting the autoyast file with any substitutions prior to it being evaluated for real
# as rewriting the autoinstall file with any substitutions prior to it being evaluated for real
exec >> /tmp/confluent-pre.log
exec 2>> /tmp/confluent-pre.log
@@ -36,8 +36,16 @@ hostname $(grep ^NODENAME: /etc/confluent/confluent.info|awk '{print $2}')
run_remote_parts pre.d
sed -i s!%%DEPLOYER%%!$deployserver!g /tmp/autoinstall.json
sed -i s!%%PROFILE%%!$(grep ^profile: /etc/confluent/confluent.deploycfg|awk '{print $2}')!g /tmp/autoinstall.json
sed -i s!%%ROOTPASSWORD%%!$(grep ^rootpassword: /etc/confluent/confluent.deploycfg|awk '{print $2}')!g /tmp/autoinstall.json
rootpw=$(grep ^rootpassword: /etc/confluent/confluent.deploycfg|awk '{print $2}')
if [ "$rootpw" = "null" ]; then
# lock the account, as 15 does. ! is a marker, not a hash anything matches
rootpw='!'
fi
sed -i 's@%%ROOTPASSWORD%%@'"$rootpw"'@g' /tmp/autoinstall.json
sed -i s!%%NODENAME%%!$(hostname)!g /tmp/autoinstall.json
python3 /opt/confluent/bin/apiclient /confluent-public/os/$profile/profile.yaml > /tmp/instprofile.yaml
blargs=$(grep ^installedargs: /tmp/instprofile.yaml | sed -e 's/#.*//' -e 's/^installedargs: //')
sed -i 's!%%INSTALLEDARGS%%!'"$blargs"'!g' /tmp/autoinstall.json
python3 /opt/confluent/bin/apiclient /confluent-public/os/$profile/scripts/getinstalldisk > /tmp/getinstalldisk
locale=$(grep ^locale: /etc/confluent/confluent.deploycfg)
locale=${locale#locale: }
@@ -45,6 +53,10 @@ keymap=$(grep ^keymap: /etc/confluent/confluent.deploycfg)
keymap=${keymap#keymap: }
tz=$(grep ^timezone: /etc/confluent/confluent.deploycfg)
tz=${tz#timezone: }
# agama checks against the tzdata list, which carries UTC but no Etc/ zones
if [ "$tz" = "Etc/UTC" ]; then
tz=UTC
fi
sed -i 's!%%TIMEZONE%%!'$tz'!g' /tmp/autoinstall.json
sed -i 's!%%LOCALE%%!'$locale'!g' /tmp/autoinstall.json
sed -i 's!%%KEYMAP%%!'$keymap'!g' /tmp/autoinstall.json
@@ -26,12 +26,7 @@ if [ -e "$instnmcfg" ]; then
cp $instnmcfg /mnt/etc/NetworkManager/system-connections/
fi
#run_remote setupssh.sh
cp /etc/ssh/ssh*key* /mnt/etc/ssh/
mkdir -p /mnt/etc/ssh/sshd_config.d/
cp /etc/ssh/sshd_config.d/20_hostkeys.conf /mnt/etc/ssh/sshd_config.d/
mkdir -p /mnt/root/.ssh/
cp /root/.ssh/authorized_keys /mnt/root/.ssh/
run_remote setupssh.sh
echo Port 22 >> /etc/ssh/sshd_config.d/00-chroot.conf
echo Port 2222 >> /etc/ssh/sshd_config.d/00-chroot.conf
@@ -0,0 +1,44 @@
#!/bin/bash
# Carry over install-time ssh material into installed system
mkdir -p /mnt/root/.ssh/
chmod 700 /mnt/root/.ssh/
cp /root/.ssh/authorized_keys /mnt/root/.ssh/
chmod 600 /mnt/root/.ssh/authorized_keys
cp /etc/ssh/ssh*key* /mnt/etc/ssh/
mkdir -p /mnt/etc/ssh/sshd_config.d/
# pre.sh put the host certificates confluent signed into this drop-in
cp /etc/ssh/sshd_config.d/20_hostkeys.conf /mnt/etc/ssh/sshd_config.d/
# the initramfs wrote the confluent CA into the installer's known hosts
cp /etc/ssh/ssh_known_hosts /mnt/etc/ssh/
# Enable ~/.shosts, for the sake of root user, who is forbidden from using shosts.equiv
cat >> /mnt/etc/ssh/sshd_config.d/90-confluent.conf << EOF
IgnoreRhosts no
HostbasedAuthentication yes
HostbasedUsesNameFromPacketOnly yes
EOF
sshconf=/mnt/etc/ssh/ssh_config
if [ -d /mnt/etc/ssh/ssh_config.d/ ]; then
sshconf=/mnt/etc/ssh/ssh_config.d/01-confluent.conf
fi
echo Host '*' >> $sshconf
echo " HostbasedAuthentication yes" >> $sshconf
echo " EnableSSHKeysign yes" >> $sshconf
# Limit the attempts of using host key. This prevents client from using 3 or 4
# authentication attempts through host based attempts
echo " HostbasedKeyTypes *ed25519*" >> $sshconf
# In SUSE platform, setuid for ssh-keysign is required for host based,
# and also must be opted into. 16 moved the helper to libexec.
keysign=/usr/libexec/ssh/ssh-keysign
if [ ! -e /mnt$keysign ]; then
keysign=/usr/lib/ssh/ssh-keysign
fi
echo $keysign root:root 4711 >> /mnt/etc/permissions.local
chmod 4711 /mnt$keysign
# Download list of nodes from confluent, and put it into shosts.equiv (for most users) and .shosts (for root)
python3 /opt/confluent/bin/apiclient /confluent-api/self/nodelist | sed -e 's/^- //' > /mnt/etc/ssh/shosts.equiv
cp /mnt/etc/ssh/shosts.equiv /mnt/root/.shosts
@@ -0,0 +1,29 @@
# It is advised to avoid /var/lib/confluent/public as a source for syncing. /var/lib/confluent/public
# is served without authentication and thus any sensitive content would be a risk. If wanting to host
# syncfiles on a common share, it is suggested to have /var/lib/confluent be the share and use some other
# subdirectory other than public.
#
# Syncing is performed as the 'confluent' user, so all source files must be accessible by the confluent user.
#
# This file lists files to synchronize or merge to the deployed systems from the deployment server
# To specify taking /some/path/hosts on the deployment server and duplicating it to /etc/hosts:
# Note particularly the use of '->' to delineate source from target.
# /some/path/hosts -> /etc/hosts
# If wanting to simply use the same path for source and destinaiton, the -> may be skipped:
# /etc/hosts
# More function is available, for example to limit the entry to run only on n1 through n8, and to set
# owner, group, and permissions in octal notation:
# /example/source -> n1-n8:/etc/target (owner=root,group=root,permissions=600)
# Entries under APPENDONCE: will be added to specified target, only if the target does not already
# contain the data in the source already in its entirety. This allows append in a fashion that
# is friendly to being run repeatedly
# Entries under MERGE: will attempt to be intelligently merged. This supports /etc/group and /etc/passwd
# Any supporting entries in /etc/shadow or /etc/gshadow are added automatically, with password disabled
# It also will not inject 'system' ids (under 1,000 usually) as those tend to be local and rpm managed.
# MERGE:
# /etc/passwd
# /etc/group
+1 -1
View File
@@ -13,7 +13,7 @@ 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/
mv ubuntu* suse15 suse16 el7 el9 el10 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
+1 -1
View File
@@ -34,7 +34,7 @@ mkdir -p opt/confluent/lib/imgutil
mkdir -p opt/confluent/bin
mv imgutil opt/confluent/bin/
chmod a+x opt/confluent/bin/imgutil
mv ubuntu* suse15 el7 el9 el10 el8 opt/confluent/lib/imgutil/
mv ubuntu* suse15 suse16 el7 el9 el10 el8 opt/confluent/lib/imgutil/
mkdir -p opt/confluent/share/licenses/confluent_imgutil
cp LICENSE opt/confluent/share/licenses/confluent_imgutil
+79 -13
View File
@@ -588,9 +588,10 @@ class SuseHandler(OsHandler):
def __init__(self, name, version, arch, args):
if not isinstance(version, str):
version = version.decode('utf8')
if not version.startswith('15.'):
major = version.split('.', 1)[0]
if major not in ('15', '16'):
raise Exception('Unsupported Suse version {}'.format(version))
self.oscategory = 'suse15'
self.oscategory = 'suse{0}'.format(major)
super().__init__(name, version, arch, args)
self.zyppargs = []
self.sources = []
@@ -610,6 +611,15 @@ class SuseHandler(OsHandler):
if enterprise:
self.sources.append('file://' + os.path.join(sourcepath, 'Product-HPC'))
def zypper_cmd(self):
# 16's stock repo urls are written in terms of ${releasever}, which
# zypper resolves from the target root's os-release. That file does not
# exist yet when the first packages are installed, so say it outright.
cmd = ['zypper', '-R', self.targpath]
if self.version:
cmd.extend(['--releasever', self.version])
return cmd
def prep_root(self, args):
gpgkeys = []
mkdirp(self.targpath)
@@ -617,8 +627,29 @@ class SuseHandler(OsHandler):
gpgkeys = glob.glob('/usr/lib/rpm/gnupg/keys/*.asc')
targzypp = os.path.join(self.targpath, 'etc/zypp')
mkdirp(targzypp)
shutil.copytree(
'/etc/zypp/repos.d/', os.path.join(targzypp, 'repos.d'))
# 16 declares its repositories through a zypper service backed by
# a package-provided directory the target root does not have. Drop
# the service line so each definition stands on its own, otherwise
# zypper discards every one of them as an orphan.
targrepos = os.path.join(targzypp, 'repos.d')
mkdirp(targrepos)
for repofile in glob.glob('/etc/zypp/repos.d/*'):
targrepo = os.path.join(targrepos, os.path.basename(repofile))
# Anything that is not a plain text repo definition is passed
# through as-is rather than rewritten
if os.path.isdir(repofile):
shutil.copytree(repofile, targrepo)
continue
try:
with open(repofile) as repoin:
cfg = [line for line in repoin.read().splitlines()
if not line.startswith('service=')]
except (IsADirectoryError, UnicodeDecodeError):
shutil.copy2(repofile, targrepo)
continue
with open(targrepo, 'w') as repoout:
repoout.write('\n'.join(cfg) + '\n')
shutil.copystat(repofile, targrepo)
idx = 1
for source in self.sources:
if not source:
@@ -626,7 +657,9 @@ class SuseHandler(OsHandler):
if source.startswith('file://'):
gpgpath = source.replace('file://', '')
gpgkeys.extend(glob.glob(os.path.join(gpgpath, '*/gpg-pubkey*.asc')))
subprocess.check_call(['zypper', '-R', self.targpath, 'ar', source, 'source-{}'.format(idx)])
# SLE media publishes the signing key only as the repo key
gpgkeys.extend(glob.glob(os.path.join(gpgpath, '*/repodata/repomd.xml.key')))
subprocess.check_call(self.zypper_cmd() + ['ar', source, 'source-{}'.format(idx)])
idx += 1
if gpgkeys:
addkeycmd = ['rpm', '--root', self.targpath, '--import'] + gpgkeys
@@ -638,7 +671,7 @@ class SuseHandler(OsHandler):
if not source.startswith('/') and os.path.exists(os.path.abspath(source)):
source = os.path.abspath(source)
source = 'file://' + source
subprocess.check_call(['zypper', '-R', self.targpath, 'ar', source, 'source-{}'.format(idx)])
subprocess.check_call(self.zypper_cmd() + ['ar', source, 'source-{}'.format(idx)])
idx += 1
mydir = get_mydir(self.oscategory)
mkdirp(os.path.join(self.targpath, 'usr/lib/dracut/modules.d'))
@@ -652,17 +685,26 @@ class SuseHandler(OsHandler):
cmd.extend(glob.glob(os.path.join(targdir, '*')))
subprocess.check_call(cmd)
if self._interactive:
subprocess.check_call(['zypper', '-R', self.targpath, 'install'] + self.zyppargs)
subprocess.check_call(self.zypper_cmd() + ['install'] + self.zyppargs)
else:
subprocess.check_call(['zypper', '-n', '-R', self.targpath, 'install'] + self.zyppargs)
os.symlink('/usr/lib/systemd/system/sshd.service', os.path.join(self.targpath, 'etc/systemd/system/multi-user.target.wants/sshd.service'))
subprocess.check_call(self.zypper_cmd() + ['-n', 'install'] + self.zyppargs)
# 16's presets enable sshd already, so the link is often there
sshdwant = os.path.join(
self.targpath, 'etc/systemd/system/multi-user.target.wants/sshd.service')
mkdirp(os.path.dirname(sshdwant))
if not os.path.lexists(sshdwant):
os.symlink('/usr/lib/systemd/system/sshd.service', sshdwant)
# 16 moved ssh-keysign to libexec
keysign = 'usr/libexec/ssh/ssh-keysign'
if not os.path.exists(os.path.join(self.targpath, keysign)):
keysign = 'usr/lib/ssh/ssh-keysign'
with open(os.path.join(self.targpath, 'etc/permissions.local'), 'a') as permout:
permout.write(
'/usr/lib/ssh/ssh-keysign root:ssh_keys 2711\n'
'/{0} root:ssh_keys 2711\n'
'/etc/ssh/ssh_host_dsa_key root:ssh_keys 640\n'
'/etc/ssh/ssh_host_ecdsa_key root:ssh_keys 640\n'
'/etc/ssh/ssh_host_ed25519_key root:ssh_keys 640\n'
'/etc/ssh/ssh_host_rsa_key root:ssh_keys 640\n'
'/etc/ssh/ssh_host_rsa_key root:ssh_keys 640\n'.format(keysign)
)
args.cmd = ['groupadd', 'ssh_keys']
run_constrainedx(fancy_chroot, (args,
@@ -675,7 +717,12 @@ class SuseHandler(OsHandler):
if os.path.exists(os.path.join(self.targpath, 'sbin/mkinitrd')):
args.cmd = ['mkinitrd']
else:
args.cmd = ['dracut', '-f']
# dracut alone would build for the running kernel, which is the
# build host's, not the one just installed into the image. 16 has
# no mkinitrd to work that out, so name the kernel and the output.
kver = sorted(os.listdir(os.path.join(self.targpath, 'lib/modules')),
key=versionize_string)[-1]
args.cmd = ['dracut', '-f', '/boot/initrd-{0}'.format(kver), kver]
run_constrainedx(fancy_chroot, (args, self.targpath))
@@ -1297,7 +1344,7 @@ def fingerprint_source_suse(files, sourcepath, args):
if ': ' not in line:
continue
key, val = line.split(': ')
if key == 'category' and val == 'suse15':
if key == 'category' and val in ('suse15', 'suse16'):
issuse = True
if key == 'name':
osname, ver, arch = val.split('-')
@@ -1739,6 +1786,15 @@ def gather_bootloader(outdir, rootpath='/'):
shimlocation = os.path.join(rootpath, 'usr/lib/shim/shimx64.efi.signed')
if not os.path.exists(shimlocation):
shimlocation = os.path.join(rootpath, 'usr/lib/shim/shimaa64.efi.signed.latest')
if not os.path.exists(shimlocation):
# SUSE 16 moved the efi payloads out of /usr/lib64/efi
shimlocation = os.path.join(rootpath, 'usr/share/efi/x86_64/shim.efi')
shimdestfilename = 'BOOTX64.EFI'
if not os.path.exists(shimlocation):
aa64shim = os.path.join(rootpath, 'usr/share/efi/aarch64/shim.efi')
if os.path.exists(aa64shim):
shimlocation = aa64shim
shimdestfilename = 'BOOTAA64.EFI'
mkdirp(os.path.join(outdir, 'boot/efi/boot'))
shutil.copyfile(shimlocation, os.path.join(outdir, 'boot/efi/boot/{0}'.format(shimdestfilename)))
for maybemokmanager in glob.glob(os.path.join(rootpath, 'boot/efi/EFI/*/mmx64.efi')):
@@ -1747,6 +1803,8 @@ def gather_bootloader(outdir, rootpath='/'):
else:
if os.path.exists(os.path.join(rootpath, 'usr/lib/shim/mmx64.efi')):
shutil.copyfile(os.path.join(rootpath, 'usr/lib/shim/mmx64.efi'), os.path.join(outdir, 'boot/efi/boot/mmx64.efi'))
elif os.path.exists(os.path.join(rootpath, 'usr/share/efi/x86_64/MokManager.efi')):
shutil.copyfile(os.path.join(rootpath, 'usr/share/efi/x86_64/MokManager.efi'), os.path.join(outdir, 'boot/efi/boot/mmx64.efi'))
for maybemokmanager in glob.glob(os.path.join(rootpath, 'boot/efi/EFI/*/mmaa64.efi')):
shutil.copyfile(maybemokmanager, os.path.join(outdir, 'boot/efi/boot/mmaa64.efi'))
break
@@ -1769,6 +1827,14 @@ def gather_bootloader(outdir, rootpath='/'):
grubbin = os.path.join(rootpath, 'usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed')
if not os.path.exists(grubbin):
grubbin = os.path.join(rootpath, 'usr/lib/grub/arm64-efi/monolithic/grubaa64.efi')
if not os.path.exists(grubbin):
grubbin = os.path.join(rootpath, 'usr/share/efi/x86_64/grub.efi')
if not os.path.exists(grubbin):
# same relocation as the shim above, on the other architecture
aa64grub = os.path.join(rootpath, 'usr/share/efi/aarch64/grub.efi')
if os.path.exists(aa64grub):
grubbin = aa64grub
grubdestfilename = 'grubaa64.efi'
if not os.path.exists(grubbin):
grubs = os.path.join(rootpath, 'boot/efi/EFI/*/grubx64.efi')
grubs = glob.glob(grubs)
+46
View File
@@ -0,0 +1,46 @@
dracut_install mktemp
dracut_install /usr/lib64/libtss2-tcti-device.so.*
dracut_install tpm2_create tpm2_pcrread tpm2_createpolicy tpm2_createprimary
dracut_install tpm2_load tpm2_unseal tpm2_getcap tpm2_evictcontrol
dracut_install tpm2_pcrextend tpm2_policypcr tpm2_flushcontext tpm2_startauthsession
dracut_install curl openssl tar cpio gzip lsmod ethtool xz lsmod ethtool
dracut_install modprobe touch echo cut wc bash uniq grep ip hostname
dracut_install awk egrep dirname expr sort
dracut_install ssh sshd reboot parted mkfs mkfs.ext4 mkfs.xfs xfs_db mkswap
# 10 execs a helper per connection, and that helper execs another to
# authenticate. Without both, the initramfs sshd accepts nothing.
dracut_install /usr/libexec/ssh/sshd-session /usr/libexec/ssh/sshd-auth
dracut_install efibootmgr uuidgen
dracut_install du df ssh-keygen scp clear dhcpcd
# udev's kmod builtin dlopens this. The dracut on SLE 16 media declares it
# only in 00systemd, which the diskless module set never loads, so without
# this line udev autoloads nothing at all
dracut_install /usr/lib64/libkmod.so.2
dracut_install /lib64/libnss_dns.so.2 # glibc dropped the versioned name
dracut_install /lib64/libnss_compat*
dracut_install /usr/lib64/libnl-3.so.200
# 16 ships the stock config defaults under /usr/etc; only services stayed put
dracut_install /usr/etc/nsswitch.conf /etc/services /usr/etc/protocols
dracut_install chmod whoami head tail basename tr
dracut_install arping logger hostnamectl # 16 moved arping to /usr/bin
inst /bin/bash /bin/sh
dracut_install /lib64/libfuse.so.2 # symlink, dracut brings the target along
# urlmount still links libpthread, which since glibc 2.34 is an empty stub that
# nothing else in the initramfs pulls in
dracut_install /lib64/libpthread.so.0
dracut_install chown chroot dd expr kill parted rsync sort blockdev findfs insmod lvm
dracut_install /usr/lib/udev/rules.d/10-dm.rules /usr/sbin/dmsetup /usr/lib/udev/rules.d/95-dm-notify.rules
dracut_install /usr/lib/systemd/network/99-default.link
dracut_install losetup # multipart support
#this would be nfs with lock, but not needed, go nolock
#dracut_install mount.nfs rpcbind rpc.statd /etc/netconfig sm-notify
#dracut_install mount.nfs /etc/netconfig
inst /usr/lib/dracut/modules.d/40network/net-lib.sh /lib/net-lib.sh
# network mount, and disk imaging helpers can come from a second stage
# this is narrowly focused on getting network up and fetching images
# and those images may opt to do something with cloning or whatever
+18
View File
@@ -0,0 +1,18 @@
#!/bin/bash
instmods nfsv3 nfs_acl nfsv4 dns_resolver lockd fscache sunrpc
instmods e1000 e1000e igb sfc mlx5_ib mlx5_core mlx4_en cxgb3 cxgb4 tg3 bnx2 bnx2x bna ixgb ixgbe qlge mptsas mpt2sas mpt3sas megaraid_sas ahci xhci-hcd sd_mod pmcraid be2net vfat ext3 ext4 usb_storage scsi_wait_scan ipmi_si ipmi_devintf qlcnic xfs
instmods nvme
instmods cdc_ether r8152
instmods r8169
instmods vmxnet3 virtio_net
instmods virtio_scsi vmw_pvscsi
instmods xen-netfront xen-blkfront xen-pcifront
instmods mptctl
instmods mlx4_ib mlx5_ub ib_umad ib_ipoib
instmods ice i40e hfi1 bnxt_en qed qede
instmods dm-mod dm-log raid0 raid1 raid10 raid456 dm-raid dm-thin-pool dm-crypt dm-snapshot linear dm-era
# imgutil packs encrypted by default and dm-crypt cannot allocate the transform
# without these; the stock dracut crypt module is not in the diskless image
instmods aes_generic aesni_intel xts crypto_simd
# nfs root and optionally gocryptfs
instmods fuse overlay squashfs loop zram
+27
View File
@@ -0,0 +1,27 @@
hostname
curl
irqbalance
less
sudo
tuned
xfsprogs
e2fsprogs
chrony timezone net-tools rsync tar util-linux python3 tar dracut ethtool parted openssl bash rpm iputils lvm2 efibootmgr attr
dhcpcd
# dhcp-client used to pull this in; the diskless hook needs ip regardless
iproute2
zypper
libfuse2
openssh
shim
kernel-default
tpm2.0-tools
# tpm2.0-tools only requires tctildr, and the diskless dracut module
# installs the device tcti explicitly
libtss2-tcti-device0
NetworkManager # 16 dropped wicked; confignet writes nmconnections
vim
%onlyarch x86_64
grub2-x86_64-efi
%onlyarch aarch64
grub2-arm64-efi