From 022f0f34e6554b7209b1019692acf279208a928f Mon Sep 17 00:00:00 2001 From: Sohan Kunkerkar Date: Thu, 15 Oct 2020 17:47:27 -0400 Subject: [PATCH] providers/system: support .d directory for base config fragments Fixes https://github.com/coreos/ignition/issues/1101 This change allows the two distrosi (i.e. FCOS and RHCOS) to carry different base.ign files with common elements. Also,this will support an additional .d directory for each platform ID. --- dracut/30ignition/ignition-setup-base.service | 18 ------- dracut/30ignition/ignition-setup-base.sh | 19 -------- dracut/30ignition/module-setup.sh | 3 -- internal/exec/engine.go | 2 +- internal/providers/system/system.go | 48 +++++++++++++++++-- 5 files changed, 46 insertions(+), 44 deletions(-) delete mode 100644 dracut/30ignition/ignition-setup-base.service delete mode 100755 dracut/30ignition/ignition-setup-base.sh diff --git a/dracut/30ignition/ignition-setup-base.service b/dracut/30ignition/ignition-setup-base.service deleted file mode 100644 index aec6207bb8..0000000000 --- a/dracut/30ignition/ignition-setup-base.service +++ /dev/null @@ -1,18 +0,0 @@ -[Unit] -Description=Ignition (setup base config) -Documentation=https://github.com/coreos/ignition -ConditionPathExists=/etc/initrd-release -DefaultDependencies=false -Before=ignition-complete.target - -OnFailure=emergency.target -OnFailureJobMode=isolate - -# Stage order: setup -> fetch-offline [-> fetch] -> disks -> mount -> files. -Before=ignition-fetch-offline.service - -[Service] -Type=oneshot -RemainAfterExit=yes -EnvironmentFile=/run/ignition.env -ExecStart=/usr/sbin/ignition-setup-base diff --git a/dracut/30ignition/ignition-setup-base.sh b/dracut/30ignition/ignition-setup-base.sh deleted file mode 100755 index bc7c189504..0000000000 --- a/dracut/30ignition/ignition-setup-base.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -set -euo pipefail - -copy_file_if_exists() { - src="${1}"; dst="${2}" - if [ -f "${src}" ]; then - echo "Copying ${src} to ${dst}" - cp "${src}" "${dst}" - else - echo "File ${src} does not exist.. Skipping copy" - fi -} - -destination=/usr/lib/ignition -mkdir -p $destination - -# We will support grabbing a platform specific base.ign config -# from the initrd at /usr/lib/ignition/platform/${PLATFORM_ID}/base.ign -copy_file_if_exists "/usr/lib/ignition/platform/${PLATFORM_ID}/base.ign" "${destination}/base.ign" diff --git a/dracut/30ignition/module-setup.sh b/dracut/30ignition/module-setup.sh index d8c9d514bf..73c23054fe 100755 --- a/dracut/30ignition/module-setup.sh +++ b/dracut/30ignition/module-setup.sh @@ -56,8 +56,6 @@ install() { # Required on system using SELinux inst_multiple -o setfiles - inst_script "$moddir/ignition-setup-base.sh" \ - "/usr/sbin/ignition-setup-base" inst_script "$moddir/ignition-setup-user.sh" \ "/usr/sbin/ignition-setup-user" @@ -82,7 +80,6 @@ install() { "$systemdsystemunitdir/ignition-$x.target" done - install_ignition_unit ignition-setup-base.service install_ignition_unit ignition-setup-user.service install_ignition_unit ignition-fetch.service install_ignition_unit ignition-fetch-offline.service diff --git a/internal/exec/engine.go b/internal/exec/engine.go index f5445837e5..bdd4e78e8f 100644 --- a/internal/exec/engine.go +++ b/internal/exec/engine.go @@ -88,7 +88,7 @@ func (e Engine) Run(stageName string) error { } baseConfig := emptyConfig - systemBaseConfig, r, err := system.FetchBaseConfig(e.Logger) + systemBaseConfig, r, err := system.FetchBaseConfig(e.Logger, e.PlatformConfig.Name()) e.logReport(r) if err != nil && err != providers.ErrNoProvider { e.Logger.Crit("failed to acquire system base config: %v", err) diff --git a/internal/providers/system/system.go b/internal/providers/system/system.go index ec9f831ec4..49d13abf57 100644 --- a/internal/providers/system/system.go +++ b/internal/providers/system/system.go @@ -15,10 +15,12 @@ package system import ( + "fmt" "io/ioutil" "os" "path/filepath" + latest "github.com/coreos/ignition/v2/config/v3_3_experimental" "github.com/coreos/ignition/v2/config/v3_3_experimental/types" "github.com/coreos/ignition/v2/internal/distro" "github.com/coreos/ignition/v2/internal/log" @@ -30,12 +32,24 @@ import ( ) const ( - baseFilename = "base.ign" userFilename = "user.ign" ) -func FetchBaseConfig(logger *log.Logger) (types.Config, report.Report, error) { - return fetchConfig(logger, baseFilename) +func FetchBaseConfig(logger *log.Logger, platformName string) (types.Config, report.Report, error) { + var fullBaseConfig types.Config + baseDConfig, baseDReport, err := fetchBaseDirectoryConfig(logger, "base.d") + if err != nil { + return types.Config{}, baseDReport, err + } + + platformDir := fmt.Sprintf("base.%s.d", platformName) + basePlatformDConfig, basePlatformDReport, err := fetchBaseDirectoryConfig(logger, platformDir) + if err != nil { + logger.Info("no config at %q: %v", platformDir, err) + } + fullBaseConfig = latest.Merge(baseDConfig, basePlatformDConfig) + baseDReport.Merge(basePlatformDReport) + return fullBaseConfig, baseDReport, nil } func FetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) { @@ -56,3 +70,31 @@ func fetchConfig(logger *log.Logger, filename string) (types.Config, report.Repo } return util.ParseConfig(logger, rawConfig) } + +// fetchBaseDirectoryConfig is a helper function to merge all the base config fragments inside of a particular directory. +func fetchBaseDirectoryConfig(logger *log.Logger, dir string) (types.Config, report.Report, error) { + var baseConfig types.Config + var report report.Report + path := filepath.Join(distro.SystemConfigDir(), dir) + configs, err := ioutil.ReadDir(path) + if os.IsNotExist(err) { + logger.Info("no config dir at %q", path) + return types.Config{}, report, nil + } else if err != nil { + logger.Err("couldn't read config dir %q: %v", path, err) + return types.Config{}, report, err + } + if len(configs) == 0 { + logger.Info("no configs at %q", path) + return types.Config{}, report, nil + } + for _, config := range configs { + intermediateConfig, intermediateReport, err := fetchConfig(logger, filepath.Join(dir, config.Name())) + if err != nil { + return types.Config{}, intermediateReport, err + } + baseConfig = latest.Merge(baseConfig, intermediateConfig) + report.Merge(intermediateReport) + } + return baseConfig, report, nil +}