dynamically determine network backend
This commit is contained in:
parent
dac1b10c5d
commit
3fa4541152
6
Makefile
6
Makefile
|
@ -4,10 +4,14 @@ LIBGUESTFS_PATH = guestfs/appliance
|
|||
LIBGUESTFS_HV = scripts/qemu.sh
|
||||
APPLIANCE_VERSION = 1.46.0
|
||||
|
||||
ifeq ($(shell test -e $(DEPS_DIR)/usr/lib/x86_64-linux-gnu/libvirt.so.0 && echo -n yes),yes)
|
||||
CGO_LDFLAGS = -lvirt -lyajl
|
||||
endif
|
||||
|
||||
# Export LIBGUESTFS_DEBUG=1 to debug
|
||||
|
||||
all:
|
||||
LIBRARY_PATH=$(LIBRARY_PATH) go build
|
||||
LIBRARY_PATH=$(LIBRARY_PATH) CGO_LDFLAGS="$(CGO_LDFLAGS)" go build
|
||||
|
||||
run:
|
||||
LD_LIBRARY_PATH=$(LIBRARY_PATH) LIBGUESTFS_PATH=$(LIBGUESTFS_PATH) LIBGUESTFS_HV=$(LIBGUESTFS_HV) LIBGUESTFS_BACKEND_SETTINGS=force_tcg ./cloudbuild
|
||||
|
|
|
@ -250,7 +250,7 @@ func (c *CloudBuilder) versionStringCompare(version1, version2 string) int {
|
|||
|
||||
func (c *CloudBuilder) Start() (err error) {
|
||||
distrosInfo := map[string]DistroInfo{
|
||||
"debian": DistroInfo{
|
||||
"debian": {
|
||||
name: "Debian",
|
||||
manager: distros.NewDebianTemplateManager(c.cfg),
|
||||
// This is the latest version available in CloudStack 4.16;
|
||||
|
@ -259,25 +259,25 @@ func (c *CloudBuilder) Start() (err error) {
|
|||
osDescription: "Debian GNU/Linux 11 (64-bit)",
|
||||
user: "debian",
|
||||
},
|
||||
"ubuntu": DistroInfo{
|
||||
"ubuntu": {
|
||||
name: "Ubuntu",
|
||||
manager: distros.NewUbuntuTemplateManager(c.cfg),
|
||||
osDescription: "Other Ubuntu (64-bit)",
|
||||
user: "ubuntu",
|
||||
},
|
||||
"fedora": DistroInfo{
|
||||
"fedora": {
|
||||
name: "Fedora",
|
||||
manager: distros.NewFedoraTemplateManager(c.cfg),
|
||||
osDescription: "Fedora Linux (64 bit)",
|
||||
user: "fedora",
|
||||
},
|
||||
"almalinux": DistroInfo{
|
||||
"almalinux": {
|
||||
name: "AlmaLinux",
|
||||
manager: distros.NewAlmaLinuxTemplateManager(c.cfg),
|
||||
osDescription: "Other CentOS (64-bit)",
|
||||
user: "almalinux",
|
||||
},
|
||||
"opensuse-tumbleweed": DistroInfo{
|
||||
"opensuse-tumbleweed": {
|
||||
name: "OpenSUSE Tumbleweed",
|
||||
manager: distros.NewOpensuseTumbleweedTemplateManager(c.cfg),
|
||||
osDescription: "OpenSUSE Linux (64 bit)",
|
||||
|
@ -285,7 +285,12 @@ func (c *CloudBuilder) Start() (err error) {
|
|||
isRollingRelease: true,
|
||||
},
|
||||
}
|
||||
existingTemplates := c.getExistingTemplateVersions()
|
||||
var existingTemplates map[string]TemplateVersionInfo
|
||||
if c.cfg.SkipFreshnessCheck {
|
||||
log.Debug().Msg("SKIP_FRESHNESS_CHECK was set, existing templates will not be checked")
|
||||
} else {
|
||||
existingTemplates = c.getExistingTemplateVersions()
|
||||
}
|
||||
for _, distroLower := range c.cfg.DistrosToCheck {
|
||||
distroInfo, ok := distrosInfo[distroLower]
|
||||
if !ok {
|
||||
|
|
|
@ -12,6 +12,11 @@ func isFalsy(s string) bool {
|
|||
return s == "false" || s == "no" || s == "0"
|
||||
}
|
||||
|
||||
func isTruthy(s string) bool {
|
||||
s = strings.ToLower(s)
|
||||
return s == "true" || s == "yes" || s == "1"
|
||||
}
|
||||
|
||||
// A Config holds all of the configuration values needed for the program.
|
||||
type Config struct {
|
||||
CloudstackApiKey string
|
||||
|
@ -21,17 +26,30 @@ type Config struct {
|
|||
CloudstackServiceOfferingName string
|
||||
CloudstackKeypairName string
|
||||
SSHKeyPath string
|
||||
DeleteOldTemplates bool
|
||||
// These must be keys of the distrosInfo map in cloudbuilder.go
|
||||
DistrosToCheck []string
|
||||
UploadDirectory string
|
||||
UploadBaseUrl string
|
||||
MirrorHost string
|
||||
EmailServer string
|
||||
EmailSender string
|
||||
EmailSenderName string
|
||||
EmailRecipient string
|
||||
EmailReplyTo string
|
||||
// DISTROS_TO_CHECK must be a comma-separated list of keys of the
|
||||
// distrosInfo map in cloudbuilder.go. Example: "debian,ubuntu".
|
||||
DistrosToCheck []string
|
||||
// If SKIP_FRESHNESS_CHECK is set to a truthy value, then existing
|
||||
// templates in CloudStack will not be checked to see if they are
|
||||
// outdated. This should only be used during development.
|
||||
// Default: false.
|
||||
SkipFreshnessCheck bool
|
||||
// If SKIP_DOWNLOAD is set to a truthy value, then QCOW2 images will
|
||||
// not be downloaded and are assumed to be already be present in the
|
||||
// current working directory. Default: false.
|
||||
SkipDownload bool
|
||||
// If DELETE_OLD_TEMPLATES is set to falsy value, then old templates
|
||||
// for a distro will not be deleted after a new one is uploaded.
|
||||
// Default: true.
|
||||
DeleteOldTemplates bool
|
||||
UploadDirectory string
|
||||
UploadBaseUrl string
|
||||
MirrorHost string
|
||||
EmailServer string
|
||||
EmailSender string
|
||||
EmailSenderName string
|
||||
EmailRecipient string
|
||||
EmailReplyTo string
|
||||
}
|
||||
|
||||
// New returns a Config filled with values read from environment variables.
|
||||
|
@ -46,9 +64,6 @@ func New() *Config {
|
|||
EmailRecipient: os.Getenv("EMAIL_RECIPIENT"),
|
||||
DeleteOldTemplates: true,
|
||||
}
|
||||
if isFalsy(os.Getenv("DELETE_OLD_TEMPLATES")) {
|
||||
cfg.DeleteOldTemplates = false
|
||||
}
|
||||
if cfg.CloudstackApiKey == "" {
|
||||
panic("CLOUDSTACK_API_KEY is empty or not set")
|
||||
}
|
||||
|
@ -73,6 +88,16 @@ func New() *Config {
|
|||
panic("EMAIL_RECIPIENT is empty or not set")
|
||||
}
|
||||
|
||||
if isTruthy(os.Getenv("SKIP_FRESHNESS_CHECK")) {
|
||||
cfg.SkipFreshnessCheck = true
|
||||
}
|
||||
if isTruthy(os.Getenv("SKIP_DOWNLOAD")) {
|
||||
cfg.SkipDownload = true
|
||||
}
|
||||
if isFalsy(os.Getenv("DELETE_OLD_TEMPLATES")) {
|
||||
cfg.DeleteOldTemplates = false
|
||||
}
|
||||
|
||||
// These should never change
|
||||
cfg.CloudstackApiBaseUrl = "https://cloud.csclub.uwaterloo.ca/client/api"
|
||||
cfg.CloudstackZoneName = "Zone1"
|
||||
|
|
|
@ -68,8 +68,8 @@ func (mgr *AlmaLinuxTemplateManager) DownloadTemplate(version, codename string)
|
|||
return mgr.DownloadTemplateGeneric(filename, url)
|
||||
}
|
||||
|
||||
func (mgr *AlmaLinuxTemplateManager) addCloudInitSnippet(handle *guestfs.Guestfs) error {
|
||||
path := "/etc/cloud/cloud.cfg.d/99_csclub.cfg"
|
||||
func (mgr *AlmaLinuxTemplateManager) addAlmaLinuxCloudInitSnippet(handle *guestfs.Guestfs) error {
|
||||
path := "/etc/cloud/cloud.cfg.d/99_csclub_misc.cfg"
|
||||
mgr.logger.Debug().Msg("Writing to " + path)
|
||||
return handle.Write(path, getResource("fedora-cloud-init"))
|
||||
}
|
||||
|
@ -92,13 +92,7 @@ func (mgr *AlmaLinuxTemplateManager) transformAlmaLinuxYumRepoBaseUrl(url string
|
|||
}
|
||||
|
||||
func (mgr *AlmaLinuxTemplateManager) PerformDistroSpecificModifications(handle *guestfs.Guestfs) (err error) {
|
||||
if err = mgr.setChronyOptions(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.setNetworkManagerOptions(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.addCloudInitSnippet(handle); err != nil {
|
||||
if err = mgr.addAlmaLinuxCloudInitSnippet(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.replaceYumMirrorUrls(handle, mgr.transformAlmaLinuxYumRepoBaseUrl); err != nil {
|
||||
|
|
|
@ -75,15 +75,6 @@ func (mgr *DebianTemplateManager) CommandToUpdatePackageCache() []string {
|
|||
return debianCommandToUpdatePackageCache()
|
||||
}
|
||||
|
||||
func (mgr *DebianTemplateManager) PerformDistroSpecificModifications(handle *guestfs.Guestfs) (err error) {
|
||||
if err = mgr.setChronyOptions(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.setDhclientOptions(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.replaceDebianMirrorUrls(handle); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
func (mgr *DebianTemplateManager) PerformDistroSpecificModifications(handle *guestfs.Guestfs) error {
|
||||
return mgr.replaceDebianMirrorUrls(handle)
|
||||
}
|
||||
|
|
|
@ -113,8 +113,8 @@ func (mgr *FedoraTemplateManager) DownloadTemplate(version, codename string) (pa
|
|||
return mgr.DownloadTemplateGeneric(filename, url)
|
||||
}
|
||||
|
||||
func (mgr *FedoraTemplateManager) addCloudInitSnippet(handle *guestfs.Guestfs) error {
|
||||
path := "/etc/cloud/cloud.cfg.d/99_csclub.cfg"
|
||||
func (mgr *FedoraTemplateManager) addFedoraCloudInitSnippet(handle *guestfs.Guestfs) error {
|
||||
path := "/etc/cloud/cloud.cfg.d/99_csclub_misc.cfg"
|
||||
mgr.logger.Debug().Msg("Writing to " + path)
|
||||
return handle.Write(path, getResource("fedora-cloud-init"))
|
||||
}
|
||||
|
@ -137,13 +137,7 @@ func (mgr *FedoraTemplateManager) transformFedoraYumRepoBaseUrl(url string) stri
|
|||
}
|
||||
|
||||
func (mgr *FedoraTemplateManager) PerformDistroSpecificModifications(handle *guestfs.Guestfs) (err error) {
|
||||
if err = mgr.setChronyOptions(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.setNetworkManagerOptions(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.addCloudInitSnippet(handle); err != nil {
|
||||
if err = mgr.addFedoraCloudInitSnippet(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.replaceYumMirrorUrls(handle, mgr.transformFedoraYumRepoBaseUrl); err != nil {
|
||||
|
|
|
@ -97,9 +97,6 @@ func (mgr *OpensuseTumbleweedTemplateManager) CommandToUpdatePackageCache() []st
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
id0:
|
||||
match:
|
||||
name: e*
|
||||
dhcp4: true
|
||||
accept-ra: false
|
|
@ -1,11 +1,2 @@
|
|||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
id0:
|
||||
match:
|
||||
name: e*
|
||||
dhcp4: true
|
||||
accept-ra: false
|
||||
|
||||
apt_preserve_sources_list: true
|
||||
manage_etc_hosts: true
|
||||
|
|
|
@ -80,6 +80,10 @@ func (mgr *TemplateManager) NeedsDynamicResolvConf() bool {
|
|||
}
|
||||
|
||||
func (mgr *TemplateManager) DownloadTemplateGeneric(filename, url string) (path string, err error) {
|
||||
if mgr.cfg.SkipDownload {
|
||||
mgr.logger.Debug().Str("url", url).Msg("SKIP_DOWNLOAD was set, skipping download")
|
||||
return filename, nil
|
||||
}
|
||||
mgr.logger.Debug().Str("url", url).Msg("Downloading template")
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
|
@ -106,12 +110,18 @@ func fedoraCommandToUpdatePackageCache() []string {
|
|||
}
|
||||
|
||||
func (mgr *TemplateManager) performDistroAgnosticModifications(handle *guestfs.Guestfs) (err error) {
|
||||
if err = mgr.setupCommonNetworkConfigs(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.setupIpv6Scripts(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.setResolvConf(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.setupCommonNTPConfigs(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.setMotd(handle); err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -242,6 +252,60 @@ func (mgr *TemplateManager) maskSystemdUnit(handle *guestfs.Guestfs, unit string
|
|||
return handle.Ln_sf("/dev/null", "/etc/systemd/system/"+unit)
|
||||
}
|
||||
|
||||
func systemdServiceIsEnabled(handle *guestfs.Guestfs, unit string) (bool, error) {
|
||||
dirPrefixes := []string{"/etc", "/lib"}
|
||||
unitPath := ""
|
||||
for _, dirPrefix := range dirPrefixes {
|
||||
possibleUnitPath := dirPrefix + "/systemd/system/" + unit
|
||||
exists, err := handle.Is_file(possibleUnitPath, nil)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("could not determine if %s is a file: %w", possibleUnitPath, err)
|
||||
}
|
||||
if exists {
|
||||
unitPath = possibleUnitPath
|
||||
break
|
||||
}
|
||||
}
|
||||
if unitPath == "" {
|
||||
return false, nil
|
||||
}
|
||||
content, err := handle.Cat(unitPath)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("could not read %s: %w", unitPath, err)
|
||||
}
|
||||
lines := strings.Split(content, "\n")
|
||||
wantedBy := ""
|
||||
for _, line := range lines {
|
||||
if strings.HasPrefix(line, "WantedBy=") {
|
||||
wantedBy = line[len("WantedBy="):]
|
||||
break
|
||||
}
|
||||
}
|
||||
if wantedBy == "" {
|
||||
return false, fmt.Errorf("could not find WantedBy property for %s", unitPath)
|
||||
}
|
||||
linkName := ""
|
||||
for _, dirPrefix := range dirPrefixes {
|
||||
possibleLinkName := dirPrefix + "/systemd/system/" + wantedBy + ".wants/" + unit
|
||||
isSymlink, err := handle.Is_symlink(possibleLinkName)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("could not determine if %s is a symlink: %w", possibleLinkName, err)
|
||||
}
|
||||
if isSymlink {
|
||||
linkName = possibleLinkName
|
||||
break
|
||||
}
|
||||
}
|
||||
if linkName == "" {
|
||||
return false, nil
|
||||
}
|
||||
target, err := handle.Readlink(linkName)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("could not read link at %s: %w", linkName, err)
|
||||
}
|
||||
return target == unitPath, nil
|
||||
}
|
||||
|
||||
// setChronyOptions sets custom NTP server URLs in a chrony config file.
|
||||
func (mgr *TemplateManager) setChronyOptions(handle *guestfs.Guestfs) (err error) {
|
||||
possiblePaths := []string{"/etc/chrony.conf", "/etc/chrony/chrony.conf"}
|
||||
|
@ -315,8 +379,7 @@ func (mgr *TemplateManager) setChronyOptions(handle *guestfs.Guestfs) (err error
|
|||
// Otherwise, assume we need to modify chrony.conf directly
|
||||
// e.g. Fedora
|
||||
if newLines == nil {
|
||||
mgr.logger.Warn().Msg("could not find chrony.conf, skipping")
|
||||
return
|
||||
return errors.New("could not find chrony.conf")
|
||||
}
|
||||
serverDirectiveExists := false
|
||||
for _, line := range newLines {
|
||||
|
@ -334,6 +397,45 @@ func (mgr *TemplateManager) setChronyOptions(handle *guestfs.Guestfs) (err error
|
|||
return handle.Write(path, []byte(newContent))
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) setTimesyncdConf(handle *guestfs.Guestfs) error {
|
||||
if err := handle.Mkdir_p("/etc/systemd/timesyncd.conf.d"); err != nil {
|
||||
return fmt.Errorf("could not create /etc/systemd/timesyncd.conf.d: %w", err)
|
||||
}
|
||||
mgr.logger.Debug().Msg("Writing to /etc/systemd/timesyncd.conf.d/csclub.conf")
|
||||
return handle.Write("/etc/systemd/timesyncd.conf.d/csclub.conf", getResource("timesyncd.conf"))
|
||||
}
|
||||
|
||||
func usesChrony(handle *guestfs.Guestfs) (bool, error) {
|
||||
// The systemd service for chrony is called on chrony.service on e.g. Debian,
|
||||
// but is called chronyd.service on e.g. Fedora
|
||||
chronyIsEnabled, err := systemdServiceIsEnabled(handle, "chrony.service")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if chronyIsEnabled {
|
||||
return true, nil
|
||||
}
|
||||
return systemdServiceIsEnabled(handle, "chronyd.service")
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) setupCommonNTPConfigs(handle *guestfs.Guestfs) error {
|
||||
usesChrony, err := usesChrony(handle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if usesChrony {
|
||||
return mgr.setChronyOptions(handle)
|
||||
}
|
||||
usesSystemdTimesyncd, err := systemdServiceIsEnabled(handle, "systemd-timesyncd.service")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if usesSystemdTimesyncd {
|
||||
return mgr.setTimesyncdConf(handle)
|
||||
}
|
||||
return errors.New("could not determine NTP backend")
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) setNetworkManagerOptions(handle *guestfs.Guestfs) (err error) {
|
||||
if err = handle.Mkdir_p("/etc/NetworkManager/conf.d"); err != nil {
|
||||
return
|
||||
|
@ -344,7 +446,54 @@ func (mgr *TemplateManager) setNetworkManagerOptions(handle *guestfs.Guestfs) (e
|
|||
}
|
||||
|
||||
func usesNetworkManager(handle *guestfs.Guestfs) (bool, error) {
|
||||
return handle.Is_file("/usr/sbin/NetworkManager", nil)
|
||||
return systemdServiceIsEnabled(handle, "NetworkManager.service")
|
||||
}
|
||||
|
||||
func usesEtcNetworkInterfaces(handle *guestfs.Guestfs) (bool, error) {
|
||||
configPath := "/etc/network/interfaces"
|
||||
configExists, err := handle.Is_file(configPath, nil)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("Could not determine if "+configPath+" is a file: %w", err)
|
||||
}
|
||||
if !configExists {
|
||||
return false, nil
|
||||
}
|
||||
return systemdServiceIsEnabled(handle, "networking.service")
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) addSystemdNetworkdCloudInitSnippet(handle *guestfs.Guestfs) error {
|
||||
// Use 98 so that each distro can use 99 for extra customization
|
||||
path := "/etc/cloud/cloud.cfg.d/98_csclub_network.cfg"
|
||||
mgr.logger.Debug().Msg("Writing to " + path)
|
||||
return handle.Write(path, getResource("systemd-networkd-cloud-init"))
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) setupCommonNetworkConfigs(handle *guestfs.Guestfs) error {
|
||||
usesNetworkManager, err := usesNetworkManager(handle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if usesNetworkManager {
|
||||
return mgr.setNetworkManagerOptions(handle)
|
||||
}
|
||||
usesSystemdNetworkd, err := systemdServiceIsEnabled(handle, "systemd-networkd.service")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if usesSystemdNetworkd {
|
||||
return mgr.addSystemdNetworkdCloudInitSnippet(handle)
|
||||
}
|
||||
usesEtcNetworkInterfaces, err := usesEtcNetworkInterfaces(handle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if usesEtcNetworkInterfaces {
|
||||
return mgr.setDhclientOptions(handle)
|
||||
}
|
||||
// The only other network backend used by one of our supported distros is
|
||||
// Sysconfig, which is currently only used by OpenSUSE Tumbleweed.
|
||||
// That case is handled separately in opensuse_tumbleweed.go.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) setupIpv6Scripts(handle *guestfs.Guestfs) (err error) {
|
||||
|
@ -703,14 +852,6 @@ func (mgr *TemplateManager) updateSshdConfig(handle *guestfs.Guestfs) error {
|
|||
return handle.Aug_set("/files/etc/ssh/sshd_config/PrintLastLog", "no")
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) setTimesyncdConf(handle *guestfs.Guestfs) (err error) {
|
||||
mgr.logger.Debug().Msg("Writing custom timesyncd.conf")
|
||||
if err = handle.Mkdir_p("/etc/systemd/timesyncd.conf.d"); err != nil {
|
||||
return
|
||||
}
|
||||
return handle.Write("/etc/systemd/timesyncd.conf.d/csclub.conf", getResource("timesyncd.conf"))
|
||||
}
|
||||
|
||||
func (mgr *TemplateManager) setJournaldConf(handle *guestfs.Guestfs) (err error) {
|
||||
mgr.logger.Debug().Msg("Writing custom journald.conf")
|
||||
if err = handle.Mkdir_p("/etc/systemd/journald.conf.d"); err != nil {
|
||||
|
|
|
@ -79,8 +79,8 @@ func (mgr *UbuntuTemplateManager) DownloadTemplate(version, codename string) (pa
|
|||
return mgr.DownloadTemplateGeneric(filename, url)
|
||||
}
|
||||
|
||||
func (mgr *UbuntuTemplateManager) addCloudInitSnippet(handle *guestfs.Guestfs) error {
|
||||
path := "/etc/cloud/cloud.cfg.d/99_csclub.cfg"
|
||||
func (mgr *UbuntuTemplateManager) addUbuntuCloudInitSnippet(handle *guestfs.Guestfs) error {
|
||||
path := "/etc/cloud/cloud.cfg.d/99_csclub_misc.cfg"
|
||||
mgr.logger.Debug().Msg("Writing to " + path)
|
||||
return handle.Write(path, getResource("ubuntu-cloud-init"))
|
||||
}
|
||||
|
@ -109,16 +109,10 @@ func (mgr *UbuntuTemplateManager) CommandToUpdatePackageCache() []string {
|
|||
}
|
||||
|
||||
func (mgr *UbuntuTemplateManager) PerformDistroSpecificModifications(handle *guestfs.Guestfs) (err error) {
|
||||
if err = mgr.setTimesyncdConf(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.setDhclientOptions(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.replaceDebianMirrorUrls(handle); err != nil {
|
||||
return
|
||||
}
|
||||
if err = mgr.addCloudInitSnippet(handle); err != nil {
|
||||
if err = mgr.addUbuntuCloudInitSnippet(handle); err != nil {
|
||||
return
|
||||
}
|
||||
mgr.disableNoisyMotdMessages(handle)
|
||||
|
|
|
@ -27,6 +27,7 @@ libvirt_dependencies=(
|
|||
libvdeplug2
|
||||
libvirglrenderer1
|
||||
libvirt0
|
||||
libvirt-dev
|
||||
libxencall1
|
||||
libxendevicemodel1
|
||||
libxenevtchn1
|
||||
|
@ -37,6 +38,7 @@ libvirt_dependencies=(
|
|||
libxentoolcore1
|
||||
libxentoollog1
|
||||
libyajl2
|
||||
libyajl-dev
|
||||
qemu-system-x86
|
||||
seabios
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue