package distros import ( "errors" "fmt" "net/http" "regexp" "strconv" "github.com/rs/zerolog/log" "golang.org/x/net/html" "libguestfs.org/guestfs" "git.csclub.uwaterloo.ca/cloud/cloudbuild/pkg/config" ) // TODO: reduce code duplication with FedoraTemplateManager type AlmaLinuxTemplateManager struct { TemplateManager } // NewAlmaLinuxTemplateManager returns a AlmaLinuxTemplateManager with the given // config values. func NewAlmaLinuxTemplateManager(cfg *config.Config) *AlmaLinuxTemplateManager { logger := log.With().Str("distro", "almalinux").Logger() almaLinuxTemplateManager := AlmaLinuxTemplateManager{ TemplateManager{ cfg: cfg, logger: &logger, impl: nil, }, } almaLinuxTemplateManager.TemplateManager.impl = &almaLinuxTemplateManager return &almaLinuxTemplateManager } func (mgr *AlmaLinuxTemplateManager) GetLatestVersion() (version string, codename string, err error) { resp, err := http.Get("https://mirror.csclub.uwaterloo.ca/almalinux/") if err != nil { return } defer resp.Body.Close() node, err := html.Parse(resp.Body) if err != nil { return } var intVersion int64 getMaxVersionFromHtml(node, &intVersion) if intVersion == 0 { err = errors.New("Could not determine latest AlmaLinux version from HTML") } else { version = strconv.FormatInt(intVersion, 10) // AlmaLinux doesn't have codenames, only numbered versions codename = version } return } func (mgr *AlmaLinuxTemplateManager) DownloadTemplate(version, codename string) (path string, err error) { floatVersion, err := strconv.ParseFloat(version, 64) if err != nil { return } majorVersion := int(floatVersion) filename := fmt.Sprintf("AlmaLinux-%d-GenericCloud-latest.x86_64.qcow2", majorVersion) url := fmt.Sprintf("https://mirror.csclub.uwaterloo.ca/almalinux/%s/cloud/x86_64/images/%s", version, filename) return mgr.DownloadTemplateGeneric(filename, url) } func (mgr *AlmaLinuxTemplateManager) UsesNetworkManager() bool { return true } func (mgr *AlmaLinuxTemplateManager) addCloudInitSnippet(handle *guestfs.Guestfs) error { path := "/etc/cloud/cloud.cfg.d/99_csclub.cfg" mgr.logger.Debug().Msg("Writing to " + path) return handle.Write(path, getResource("fedora-cloud-init")) } func (mgr *AlmaLinuxTemplateManager) HasSELinuxEnabled() bool { return true } func (mgr *AlmaLinuxTemplateManager) CommandToUpdatePackageCache() []string { return fedoraCommandToUpdatePackageCache() } var almaLinuxYumRepoBaseUrlPattern *regexp.Regexp = regexp.MustCompile( "^(?Phttps?://)[A-Za-z0-9./-]+(?P/almalinux/\\$releasever/[A-Za-z0-9./$-]+)$", ) func (mgr *AlmaLinuxTemplateManager) transformAlmaLinuxYumRepoBaseUrl(url string) string { submatches := almaLinuxYumRepoBaseUrlPattern.FindStringSubmatch(url) if submatches != nil { scheme, path := submatches[1], submatches[2] url = scheme + mgr.cfg.MirrorHost + path } return url } func (mgr *AlmaLinuxTemplateManager) PerformDistroSpecificModifications(handle *guestfs.Guestfs) (err error) { if err = mgr.setChronyOptions(handle, "/etc/chrony.conf"); err != nil { return } if err = mgr.setNetworkManagerOptions(handle); err != nil { return } if err = mgr.addCloudInitSnippet(handle); err != nil { return } if err = mgr.replaceYumMirrorUrls(handle, mgr.transformAlmaLinuxYumRepoBaseUrl); err != nil { return } return }