mirror of
https://github.com/xcat2/confluent.git
synced 2026-09-09 22:46:45 +00:00
Build SUSE 16 images with imgutil
SuseHandler refused anything but 15.x. What 16 needed beyond widening it:
- its repo urls are written in terms of ${releasever}, which zypper
resolves from the target root's os-release, a file that does not exist
yet when the first packages go in
- its repos name a zypper service backed by a package-provided directory
the target root does not have, so zypper discarded every one of them
as an orphan
- there is no mkinitrd to work out which kernel to build for, and bare
dracut would build for the build host's running kernel
- the efi payloads moved out of /usr/lib64/efi, arping out of /usr/sbin,
nsswitch.conf and protocols under /usr/etc, and the presets enable
sshd already
- the module list predated virtio, so an image built for a KVM guest had
no network at all, and dm-crypt could not allocate a transform for the
encrypted image without the aes-xts modules
- urlmount still links libpthread, an empty stub since glibc 2.34 that
nothing else in the initramfs pulls in
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
+55
-11
@@ -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,19 @@ 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/*'):
|
||||
with open(repofile) as repoin:
|
||||
cfg = [line for line in repoin.read().splitlines()
|
||||
if not line.startswith('service=')]
|
||||
with open(os.path.join(
|
||||
targrepos, os.path.basename(repofile)), 'w') as repoout:
|
||||
repoout.write('\n'.join(cfg) + '\n')
|
||||
idx = 1
|
||||
for source in self.sources:
|
||||
if not source:
|
||||
@@ -626,7 +647,7 @@ 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)])
|
||||
subprocess.check_call(self.zypper_cmd() + ['ar', source, 'source-{}'.format(idx)])
|
||||
idx += 1
|
||||
if gpgkeys:
|
||||
addkeycmd = ['rpm', '--root', self.targpath, '--import'] + gpgkeys
|
||||
@@ -638,7 +659,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,10 +673,15 @@ 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)
|
||||
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'
|
||||
@@ -675,7 +701,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 +1328,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 +1770,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 +1787,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 +1811,8 @@ 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):
|
||||
grubs = os.path.join(rootpath, 'boot/efi/EFI/*/grubx64.efi')
|
||||
grubs = glob.glob(grubs)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
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
|
||||
dracut_install efibootmgr uuidgen
|
||||
dracut_install du df ssh-keygen scp clear dhclient
|
||||
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,22 @@
|
||||
hostname
|
||||
curl
|
||||
irqbalance
|
||||
less
|
||||
sudo
|
||||
tuned
|
||||
xfsprogs
|
||||
e2fsprogs
|
||||
chrony net-tools rsync tar util-linux python3 tar dracut ethtool parted openssl bash rpm iputils lvm2 efibootmgr attr
|
||||
dhcp-client
|
||||
zypper
|
||||
grub2-x86_64-efi
|
||||
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
|
||||
Reference in New Issue
Block a user