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:
@@ -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
|
||||
|
||||
+281
@@ -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
|
||||
+5
-27
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user