Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions cmd/image/qcow2ova/prep/loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,19 @@ func partprobe(device string) error {
return nil
}

// get partition number of the image
// get partition number of the image - returns the largest partition (typically root)
func getPartition(device string) (string, error) {
args := fmt.Sprintf("fdisk -l %s | grep ^/dev | wc -l", device)
// Use fdisk to get partition info and find the largest one
args := fmt.Sprintf("fdisk -l %s | grep '^%s' | awk '{print $1, $4}' | sort -k2 -n | tail -1 | awk '{print $1}' | sed 's/.*p//'", device, device)
exitcode, out, err := utils.RunCMD("bash", "-c", args)
if exitcode != 0 {
return "", fmt.Errorf("failed to get partition for device: %s, exitcode: %d, stdout: %s, err: %s", device, exitcode, out, err)
}
return strings.TrimSpace(out), nil
partition := strings.TrimSpace(out)
if partition == "" {
return "", fmt.Errorf("no partition found for device: %s", device)
}
return partition, nil
}

// growpart resizes the partition
Expand Down
26 changes: 18 additions & 8 deletions cmd/image/qcow2ova/prep/prepare.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,27 @@ func prepare(mnt, volume, dist, rhnuser, rhnpasswd, rootpasswd string) error {
}

partDev := lo + "p" + partition

err = mount("nouuid", partDev, mnt)
err = growpart(lo, partition)
if err != nil {
return err
klog.Warningf("growpart failed (non-fatal): %v", err)
}
defer Umount(mnt)

err = growpart(lo, partition)
fsType, err := getFSType(partDev)
if err != nil {
return err
}

fsType, err := getFSType(partDev)
mountOpts := "defaults"
if fsType == "xfs" {
mountOpts = "nouuid"
}

err = mount(mountOpts, partDev, mnt)
if err != nil {
return err
}
defer Umount(mnt)


switch fsType {
case "xfs":
Expand Down Expand Up @@ -105,7 +110,12 @@ func prepare(mnt, volume, dist, rhnuser, rhnpasswd, rootpasswd string) error {
}

// Verify /boot is mounted properly and files are present.
bootDirFiles := []string{"config-*.ppc64le", "efi", "grub2", "initramfs-*.ppc64le.img", "loader", "symvers-*.ppc64le.*", "System.map-*.ppc64le", "vmlinuz-*.ppc64le"}
var bootDirFiles []string
if dist == "ubuntu" {
bootDirFiles = []string{"config-*-generic", "grub", "initrd.img-*-generic", "System.map-*-generic", "vmlinux-*-generic"}
} else {
bootDirFiles = []string{"config-*.ppc64le", "efi", "grub2", "initramfs-*.ppc64le.img", "loader", "symvers-*.ppc64le.*", "System.map-*.ppc64le", "vmlinuz-*.ppc64le"}
}
for _, file := range bootDirFiles {
exist, err := checkFileExists(filepath.Join(mnt, "boot", file))
if err != nil {
Expand Down Expand Up @@ -176,7 +186,7 @@ func Prepare4capture(mnt, volume, dist, rhnuser, rhnpasswd, rootpasswd string) e
//}
//defer os.Chdir(cwd)
switch dist := strings.ToLower(dist); dist {
case "rhel", "centos":
case "rhel", "centos", "ubuntu":
return prepare(mnt, volume, dist, rhnuser, rhnpasswd, rootpasswd)
case "coreos":
klog.Info("No image preparation required for the coreos.")
Expand Down
101 changes: 95 additions & 6 deletions cmd/image/qcow2ova/prep/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,74 @@ set -o pipefail

mv /etc/resolv.conf /etc/resolv.conf.orig || true
echo "nameserver 9.9.9.9" | tee /etc/resolv.conf

{{if eq .Dist "rhel"}}
subscription-manager register --force --auto-attach --username={{ .RHNUser }} --password={{ .RHNPassword }}
{{end}}
{{if .RootPasswd }}
echo {{ .RootPasswd }} | passwd root --stdin
{{end}}
yum update -y && yum install -y yum-utils
yum install -y cloud-init
{{end}}

{{ if eq .Dist "ubuntu" }}
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get -y upgrade
apt-get -y install cloud-init multipath-tools
{{ end }}

{{ if .RootPasswd }}
echo "DEBUG: Setting password for dist={{ .Dist }}"
{{ if or (eq .Dist "rhel") (eq .Dist "centos") }}
echo {{ .RootPasswd }} | passwd root --stdin
{{ else if eq .Dist "ubuntu" }}
echo "root:{{ .RootPasswd }}" | chpasswd
{{ else }}
echo "ERROR: Unknown distribution {{ .Dist }}"
exit 1
{{ end }}
{{ end }}

{{if or (eq .Dist "rhel") (eq .Dist "centos")}}
yum reinstall grub2-common -y
rm -rf /etc/systemd/system/multi-user.target.wants/firewalld.service
{{end}}

{{if eq .Dist "ubuntu"}}
apt install --reinstall grub-common
{{end}}

{{if or (eq .Dist "rhel") (eq .Dist "centos")}}
rpm -vih --nodeps https://public.dhe.ibm.com/software/server/POWER/Linux/yum/download/ibm-power-repo-latest.noarch.rpm
sed -i 's/^more \/opt\/ibm\/lop\/notice/#more \/opt\/ibm\/lop\/notice/g' /opt/ibm/lop/configure
echo 'y' | /opt/ibm/lop/configure
{{end}}

{{if eq .Dist "ubuntu"}}
# For Ubuntu, install IBM Power tools from Ubuntu repositories or skip if not available
if [ -f /opt/ibm/lop/configure ]; then
sed -i 's/^more \/opt\/ibm\/lop\/notice/#more \/opt\/ibm\/lop\/notice/g' /opt/ibm/lop/configure
echo 'y' | /opt/ibm/lop/configure
fi
{{end}}

{{if eq .Dist "rhel"}}
# Disable the AT repository due to slowness in nature
yum-config-manager --disable Advance_Toolchain
{{end}}

{{if eq .Dist "centos"}}
yum-config-manager --add-repo=https://public.dhe.ibm.com/software/server/POWER/Linux/yum/IBM/RHEL/$(rpm -E %{rhel})/ppc64le/
rpm --import https://public.dhe.ibm.com/software/server/POWER/Linux/yum/IBM/RHEL/$(rpm -E %{rhel})/ppc64le/repodata/repomd.xml.key
{{end}}

{{if or (eq .Dist "rhel") (eq .Dist "centos")}}
yum install powerpc-utils librtas DynamicRM devices.chrp.base.ServiceRM rsct.opt.storagerm rsct.core rsct.basic rsct.core src -y
yum install -y device-mapper-multipath
{{end}}

{{if eq .Dist "ubuntu"}}
apt install -y powerpc-utils
{{end}}

cat <<EOF > /etc/multipath.conf
defaults {
user_friendly_names yes
Expand All @@ -65,27 +110,58 @@ defaults {
find_multipaths smart
}
EOF

sed -i 's/GRUB_TIMEOUT=.*$/GRUB_TIMEOUT=60/g' /etc/default/grub
sed -i 's/GRUB_CMDLINE_LINUX=.*$/GRUB_CMDLINE_LINUX="console=tty0 console=hvc0,115200n8 biosdevname=0 crashkernel=auto rd.shell rd.debug rd.driver.pre=dm_multipath log_buf_len=1M "/g' /etc/default/grub
{{if or (eq .Dist "rhel") (eq .Dist "centos")}}
echo 'force_drivers+=" dm-multipath "' >/etc/dracut.conf.d/10-mp.conf
dracut --regenerate-all --force
for kernel in $(rpm -q kernel | sort -V | sed 's/kernel-//')
do
echo "Generating initramfs for kernel version: ${kernel}"
dracut --kver ${kernel} --force --add multipath --include /etc/multipath /etc/multipath --include /etc/multipath.conf /etc/multipath.conf
done
{{end}}

{{if eq .Dist "ubuntu"}}
# Check if Ubuntu is using dracut or initramfs-tools
if command -v dracut >/dev/null 2>&1; then
# Ubuntu with dracut (24.04+)
echo 'force_drivers+=" dm-multipath "' >/etc/dracut.conf.d/10-mp.conf
dracut --regenerate-all --force
for kernel in $(ls /boot/vmlinuz-* | sed 's/\/boot\/vmlinuz-//'); do
echo "Generating initramfs for kernel version: ${kernel}"
dracut --kver ${kernel} --force --add multipath --include /etc/multipath /etc/multipath --include /etc/multipath.conf /etc/multipath.conf
done
else
# Ubuntu with initramfs-tools (older versions)
update-initramfs -u
fi
{{end}}

{{if or (eq .Dist "rhel") (eq .Dist "centos")}}
grub2-mkconfig -o /boot/grub2/grub.cfg
rm -rf /etc/sysconfig/network-scripts/ifcfg-eth0
{{end}}

{{if eq .Dist "ubuntu"}}
update-grub
{{end}}

{{if eq .Dist "rhel"}}
subscription-manager unregister
subscription-manager clean
{{end}}

{{if or (eq .Dist "rhel") (eq .Dist "centos")}}
# Remove the ibm repositories used for the rsct installation
rpm -e ibm-power-repo-*.noarch
{{end}}

mv /etc/resolv.conf.orig /etc/resolv.conf || true
{{if or (eq .Dist "rhel") (eq .Dist "centos")}}
touch /.autorelabel
{{end}}
`

var CloudConfig = `# latest file from cloud-init-22.1-1.el8.noarch
Expand Down Expand Up @@ -176,13 +252,13 @@ runcmd:

system_info:
default_user:
name: cloud-user
name: {{if eq .Dist "ubuntu"}}ubuntu{{else}}cloud-user{{end}}
lock_passwd: true
gecos: Cloud User
groups: [adm, systemd-journal]
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
shell: /bin/bash
distro: rhel
distro: {{.Dist}}
paths:
cloud_dir: /var/lib/cloud
templates_dir: /etc/cloud/templates
Expand Down Expand Up @@ -218,3 +294,16 @@ func Render(dist, rhnuser, rhnpasswd, rootpasswd string) (string, error) {
}
return wr.String(), nil
}

func RenderCloudConfig(dist string) (string, error) {
s := Setup{
Dist: dist,
}
var wr bytes.Buffer
t := template.Must(template.New("cloud").Parse(CloudConfig))
err := t.Execute(&wr, s)
if err != nil {
return "", fmt.Errorf("error while rendering the cloud config template: %v", err)
}
return wr.String(), nil
}
4 changes: 2 additions & 2 deletions cmd/image/qcow2ova/qcow2ova.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ Qcow2 images location:
prep.CloudConfig = string(content)

}
if !utils.Contains([]string{"rhel", "centos", "coreos"}, strings.ToLower(opt.ImageDist)) {
klog.Errorln("--image-dist is a mandatory flag and one of these [rhel, centos, coreos]")
if !utils.Contains([]string{"rhel", "centos", "coreos", "ubuntu"}, strings.ToLower(opt.ImageDist)) {
klog.Errorln("--image-dist is a mandatory flag and one of these [rhel, centos, coreos, ubuntu]")
os.Exit(1)
}

Expand Down
13 changes: 4 additions & 9 deletions cmd/image/sync/mock/sync_client_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions pkg/audit/audit.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,15 @@ func (a *Audit) Log(name, op, value string) {
func Delete(file string) {
check_file, err := os.Stat(file)
if err != nil {
klog.Errorf("cannot retrieve file stats, err: %v", err)
if os.IsNotExist(err) {
return
}
klog.V(2).Infof("cannot retrieve file stats, err: %v", err)
return
}
if check_file.Size() == 0 {
os.Remove(file)
if err := os.Remove(file); err != nil {
klog.V(2).Infof("failed to remove empty audit file: %v", err)
}
}
}