329 lines
7.4 KiB
Go
329 lines
7.4 KiB
Go
package opensuse
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"code.dumpstack.io/tools/out-of-tree/cache"
|
|
"code.dumpstack.io/tools/out-of-tree/container"
|
|
"code.dumpstack.io/tools/out-of-tree/distro"
|
|
)
|
|
|
|
func init() {
|
|
releases := []string{
|
|
"12.1", "12.2", "12.3",
|
|
"13.1", "13.2",
|
|
"42.1", "42.2", "42.3",
|
|
"15.0", "15.1", "15.2", "15.3", "15.4", "15.5",
|
|
}
|
|
|
|
for _, release := range releases {
|
|
distro.Register(OpenSUSE{release: release})
|
|
}
|
|
}
|
|
|
|
type OpenSUSE struct {
|
|
release string
|
|
}
|
|
|
|
func (suse OpenSUSE) Equal(d distro.Distro) bool {
|
|
return suse.release == d.Release && distro.OpenSUSE == d.ID
|
|
}
|
|
|
|
func (suse OpenSUSE) Distro() distro.Distro {
|
|
return distro.Distro{ID: distro.OpenSUSE, Release: suse.release}
|
|
}
|
|
|
|
func (suse OpenSUSE) Packages() (pkgs []string, err error) {
|
|
c, err := container.New(suse.Distro())
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var name string
|
|
if strings.HasPrefix(suse.release, "12") {
|
|
var cnt string
|
|
switch suse.release {
|
|
case "12.1", "12.2":
|
|
name = "opensuse:12.1"
|
|
cnt = "openSUSE-12.1"
|
|
case "12.3":
|
|
name = "opensuse:12.3"
|
|
cnt = "openSUSE-12.3"
|
|
}
|
|
|
|
cnturl := cache.ContainerURL(cnt)
|
|
err = container.Import(cnturl, name)
|
|
if err != nil {
|
|
return
|
|
}
|
|
c.LocalBase = true
|
|
|
|
} else if strings.HasPrefix(suse.release, "13") {
|
|
name = "opensuse:13"
|
|
cnturl := cache.ContainerURL("openSUSE-13.2")
|
|
err = container.Import(cnturl, name)
|
|
if err != nil {
|
|
return
|
|
}
|
|
c.LocalBase = true
|
|
|
|
} else if strings.HasPrefix(suse.release, "42") {
|
|
name = "opensuse/leap:42"
|
|
} else if strings.HasPrefix(suse.release, "15") {
|
|
name = "opensuse/leap:" + suse.release
|
|
}
|
|
|
|
err = c.Build(name, suse.envs(), suse.runs())
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
cmd := "zypper search -s --match-exact kernel-default | grep x86_64 " +
|
|
"| cut -d '|' -f 4 | sed 's/ //g'"
|
|
|
|
output, err := c.Run("", []string{cmd})
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
// TODO Find a way for non-interactive installation of
|
|
// retracted kernels
|
|
retracted := []string{
|
|
"5.14.21-150400.24.49.3",
|
|
"5.14.21-150400.24.84.1",
|
|
"5.14.21-150500.55.22.1",
|
|
"5.3.18-150300.59.81.1",
|
|
"5.3.18-59.30.1",
|
|
"5.3.18-lp152.98.1",
|
|
}
|
|
|
|
for _, k := range strings.Fields(output) {
|
|
skip := false
|
|
for _, rk := range retracted {
|
|
if rk == k {
|
|
skip = true
|
|
break
|
|
}
|
|
}
|
|
if skip {
|
|
continue
|
|
}
|
|
|
|
pkgs = append(pkgs, k)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (suse OpenSUSE) Kernels() (kernels []distro.KernelInfo, err error) {
|
|
c, err := container.New(suse.Distro())
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
kernels, err = c.Kernels()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for i := range kernels {
|
|
kernels[i].KernelRelease = strings.Replace(
|
|
kernels[i].KernelRelease, "-default", "", -1)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (suse OpenSUSE) envs() (envs []string) {
|
|
return
|
|
}
|
|
|
|
func (suse OpenSUSE) runs() (commands []string) {
|
|
cmdf := func(f string, s ...interface{}) {
|
|
commands = append(commands, fmt.Sprintf(f, s...))
|
|
}
|
|
|
|
main := "http://download.opensuse.org/"
|
|
discontinued := "http://ftp.gwdg.de/pub/opensuse/discontinued/"
|
|
|
|
var repourls []string
|
|
|
|
if strings.HasPrefix(suse.release, "12") ||
|
|
strings.HasPrefix(suse.release, "13") {
|
|
|
|
dist := discontinued + "distribution/%s/repo/oss/"
|
|
update := discontinued + "update/%s/"
|
|
repourls = append(repourls,
|
|
fmt.Sprintf(dist, suse.release),
|
|
fmt.Sprintf(update, suse.release),
|
|
)
|
|
} else if strings.HasPrefix(suse.release, "42") {
|
|
dist := discontinued + "distribution/leap/%s/repo/oss/suse/"
|
|
update := discontinued + "update/leap/%s/oss/"
|
|
repourls = append(repourls,
|
|
fmt.Sprintf(dist, suse.release),
|
|
fmt.Sprintf(update, suse.release),
|
|
)
|
|
} else if strings.HasPrefix(suse.release, "15") {
|
|
dist := main + "distribution/leap/%s/repo/oss/"
|
|
update := main + "update/leap/%s/oss/"
|
|
repourls = append(repourls,
|
|
fmt.Sprintf(dist, suse.release),
|
|
fmt.Sprintf(update, suse.release),
|
|
)
|
|
|
|
switch suse.release {
|
|
case "15.3", "15.4", "15.5":
|
|
sle := main + "update/leap/%s/sle/"
|
|
repourls = append(repourls,
|
|
fmt.Sprintf(sle, suse.release),
|
|
)
|
|
}
|
|
}
|
|
|
|
cmdf("rm /etc/zypp/repos.d/*")
|
|
|
|
switch suse.release {
|
|
case "12.1", "12.2":
|
|
repourl := discontinued + "distribution/12.3/repo/oss/"
|
|
cmdf(`echo -e `+
|
|
`"[dracut]\n`+
|
|
`name=dracut\n`+
|
|
`enabled=1\n`+
|
|
`autorefresh=0\n`+
|
|
`gpgcheck=0\n`+
|
|
// higher number is lower priority
|
|
// default is 99
|
|
`priority=100\n`+
|
|
`baseurl=%s" > /etc/zypp/repos.d/dracut.repo`,
|
|
repourl,
|
|
)
|
|
}
|
|
|
|
for i, repourl := range repourls {
|
|
cmdf(`echo -e `+
|
|
`"[%d]\n`+
|
|
`name=%d\n`+
|
|
`enabled=1\n`+
|
|
`autorefresh=0\n`+
|
|
`gpgcheck=0\n`+
|
|
`baseurl=%s" > /etc/zypp/repos.d/%d.repo`,
|
|
i, i, repourl, i,
|
|
)
|
|
}
|
|
|
|
cmdf("zypper -n refresh")
|
|
|
|
params := "--no-recommends --force-resolution"
|
|
if !strings.HasPrefix(suse.release, "12") {
|
|
params += " --replacefiles"
|
|
}
|
|
|
|
cmdf("zypper -n update %s", params)
|
|
|
|
cmdf("zypper --no-refresh -n install %s -t pattern devel_kernel", params)
|
|
|
|
// Cache dependencies
|
|
cmdf("zypper -n install %s kernel-default kernel-default-devel "+
|
|
"&& zypper -n remove -U kernel-default kernel-default-devel",
|
|
params)
|
|
|
|
switch suse.release {
|
|
case "12.1", "12.2":
|
|
cmdf("zypper -n install %s -r dracut dracut", params)
|
|
cmdf("rm /etc/zypp/repos.d/dracut.repo")
|
|
case "12.3":
|
|
cmdf("zypper -n install %s dracut", params)
|
|
}
|
|
|
|
if !strings.HasPrefix(suse.release, "12") {
|
|
cmdf("zypper --no-refresh -n install %s kmod which", params)
|
|
}
|
|
|
|
if strings.HasPrefix(suse.release, "13") {
|
|
cmdf("zypper --no-refresh -n install %s kernel-firmware", params)
|
|
}
|
|
|
|
cmdf("rm -rf /boot/*")
|
|
cmdf("rm -rf /lib/modules/*")
|
|
return
|
|
}
|
|
|
|
func (suse OpenSUSE) Install(version string, headers bool) (err error) {
|
|
var commands []string
|
|
cmdf := func(f string, s ...interface{}) {
|
|
commands = append(commands, fmt.Sprintf(f, s...))
|
|
}
|
|
|
|
installcmd := "zypper --no-refresh -n install "
|
|
if !strings.HasPrefix(suse.release, "12") {
|
|
installcmd += " --replacefiles"
|
|
}
|
|
installcmd += " --no-recommends --force-resolution --capability"
|
|
cmdf("%s kernel-default=%s", installcmd, version)
|
|
if headers {
|
|
cmdf("%s kernel-default-devel=%s", installcmd, version)
|
|
}
|
|
|
|
cmdf("mkdir /usr/lib/dracut/modules.d/42workaround")
|
|
wsetuppath := "/usr/lib/dracut/modules.d/42workaround/module-setup.sh"
|
|
|
|
cmdf("echo 'check() { return 0; }' >> %s", wsetuppath)
|
|
cmdf("echo 'depends() { return 0; }' >> %s", wsetuppath)
|
|
cmdf(`echo 'install() { `+
|
|
`inst_hook pre-mount 91 "$moddir/workaround.sh"; `+
|
|
`}' >> %s`, wsetuppath)
|
|
cmdf("echo 'installkernel() { "+
|
|
"instmods af_packet e1000; "+
|
|
"}' >> %s", wsetuppath)
|
|
|
|
wpath := "/usr/lib/dracut/modules.d/42workaround/workaround.sh"
|
|
|
|
cmdf("echo '#!/bin/sh' >> %s", wpath)
|
|
cmdf("echo 'modprobe af_packet' >> %s", wpath)
|
|
cmdf("echo 'modprobe e1000' >> %s", wpath)
|
|
|
|
modules := "ata_piix e1000 rfkill af_packet"
|
|
if suse.release != "15.2" {
|
|
modules += " libata ext4 sd_mod"
|
|
}
|
|
|
|
format := "dracut "
|
|
format += "-a workaround "
|
|
|
|
if strings.HasPrefix(suse.release, "12") {
|
|
format += "--no-hostonly --add-drivers '%s' "
|
|
} else {
|
|
format += "--force-drivers '%s' "
|
|
}
|
|
format += "-f /boot/initrd-$(ls /lib/modules) $(ls /lib/modules)"
|
|
|
|
cmdf(format, modules)
|
|
|
|
cmdf("cp -r /boot /target/")
|
|
cmdf("cp -r /lib/modules /target/lib/")
|
|
cmdf("cp -r /usr/src /target/usr/")
|
|
|
|
c, err := container.New(suse.Distro())
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
for i := range c.Volumes {
|
|
c.Volumes[i].Dest = "/target" + c.Volumes[i].Dest
|
|
}
|
|
|
|
_, err = c.Run("", commands)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (suse OpenSUSE) RootFS() string {
|
|
return fmt.Sprintf("out_of_tree_opensuse_%s.img",
|
|
strings.Split(suse.release, ".")[0])
|
|
}
|