package distros import ( "errors" "strings" "github.com/rs/zerolog/log" "libguestfs.org/guestfs" "git.csclub.uwaterloo.ca/cloud/cloudbuild/pkg/config" ) type OpensuseTumbleweedTemplateManager struct { TemplateManager } func NewOpensuseTumbleweedTemplateManager(cfg *config.Config) *OpensuseTumbleweedTemplateManager { logger := log.With().Str("distro", "opensuse-tumbleweed").Logger() opensuseTumbleweedTemplateManager := OpensuseTumbleweedTemplateManager{ TemplateManager{ cfg: cfg, logger: &logger, impl: nil, }, } opensuseTumbleweedTemplateManager.TemplateManager.impl = &opensuseTumbleweedTemplateManager return &opensuseTumbleweedTemplateManager } func (mgr *OpensuseTumbleweedTemplateManager) GetLatestVersion() (version string, codename string, err error) { err = errors.New("rolling release") return } func (mgr *OpensuseTumbleweedTemplateManager) DownloadTemplate(version, codename string) (path string, err error) { return mgr.DownloadTemplateGeneric( "openSUSE-Tumbleweed-Minimal-VM.x86_64-Cloud.qcow2", "https://download.opensuse.org/tumbleweed/appliances/openSUSE-Tumbleweed-Minimal-VM.x86_64-Cloud.qcow2", ) } func (mgr *OpensuseTumbleweedTemplateManager) setSysconfigNetworkParams(handle *guestfs.Guestfs) error { path := "/etc/sysconfig/network/config" // Make sure you don't override NETCONFIG_DNS_POLICY; the DNS server IP address // obtained from DHCP is needed for cloud-init to work. params := map[string]string{ "NETCONFIG_NTP_POLICY": "", "AUTO6_WAIT_AT_BOOT": "0", "AUTO6_UPDATE": "none", } // Unfortunately this causes Aug_save to fail later. I'm not sure why. // The error message just says "aug_save: No error". //for key, value := range params { // augPath := "/files" + path + "/ + key // if err := handle.Aug_set(augPath, value); err != nil { // return err // } //} content, err := handle.Cat(path) if err != nil { return err } lines := strings.Split(content, "\n") replacedLines := make([]string, len(lines)) for i, line := range lines { for key, value := range params { if strings.HasPrefix(line, key+"=") { mgr.logger.Debug(). Str("path", path). Msg("Setting " + key + "=" + value) replacedLines[i] = key + "=" + value } else { replacedLines[i] = line } } } replacedContent := strings.Join(replacedLines, "\n") return handle.Write(path, []byte(replacedContent)) } func (mgr *OpensuseTumbleweedTemplateManager) NeedsDynamicResolvConf() bool { // cloud-init won't work if we overwrite /etc/resolv.conf. // I'm not sure why it works on other distros but not on this one. return true } func (mgr *OpensuseTumbleweedTemplateManager) removeWelcomeMessage(handle *guestfs.Guestfs) error { // Says "Have a lot of fun..." mgr.logger.Debug().Msg("Removing /usr/lib/motd.d/welcome") return handle.Rm_f("/usr/lib/motd.d/welcome") } func (mgr *OpensuseTumbleweedTemplateManager) CommandToUpdatePackageCache() []string { return []string{"sudo", "zypper", "refresh"} } func (mgr *OpensuseTumbleweedTemplateManager) PerformDistroSpecificModifications(handle *guestfs.Guestfs) (err error) { if err = mgr.setChronyOptions(handle); err != nil { return } if err = mgr.maskSystemdUnit(handle, "wickedd-dhcp6.service"); err != nil { return } if err = mgr.setSysconfigNetworkParams(handle); err != nil { return } if err = mgr.removeWelcomeMessage(handle); err != nil { return } return }