diff --git a/internal/distro/rhel84/distro.go b/internal/distro/rhel84/distro.go index d4f175313..1a5877b1e 100644 --- a/internal/distro/rhel84/distro.go +++ b/internal/distro/rhel84/distro.go @@ -329,6 +329,18 @@ func (t *imageType) pipeline(c *blueprint.Customizations, options distro.ImageOp p.AddStage(osbuild.NewSELinuxStage(t.selinuxStageOptions())) + // These are the current defaults for the sysconfig stage. This can be changed to be image type exclusive if different configs are needed. + p.AddStage(osbuild.NewSysconfigStage(&osbuild.SysconfigStageOptions{ + Kernel: osbuild.SysconfigKernelOptions{ + UpdateDefault: true, + DefaultKernel: "kernel", + }, + Network: osbuild.SysconfigNetworkOptions{ + Networking: true, + NoZeroConf: true, + }, + })) + if t.rpmOstree { p.AddStage(osbuild.NewRPMOSTreeStage(&osbuild.RPMOSTreeStageOptions{ EtcGroupMembers: []string{ diff --git a/internal/osbuild/sysconfig_stage.go b/internal/osbuild/sysconfig_stage.go new file mode 100644 index 000000000..d083f7c45 --- /dev/null +++ b/internal/osbuild/sysconfig_stage.go @@ -0,0 +1,25 @@ +package osbuild + +type SysconfigStageOptions struct { + Kernel SysconfigKernelOptions `json:"kernel,omitempty"` + Network SysconfigNetworkOptions `json:"network,omitempty"` +} + +type SysconfigNetworkOptions struct { + Networking bool `json:"networking,omitempty"` + NoZeroConf bool `json:"no_zero_conf,omitempty"` +} + +type SysconfigKernelOptions struct { + UpdateDefault bool `json:"update_default,omitempty"` + DefaultKernel string `json:"default_kernel,omitempty"` +} + +func (SysconfigStageOptions) isStageOptions() {} + +func NewSysconfigStage(options *SysconfigStageOptions) *Stage { + return &Stage{ + Name: "org.osbuild.sysconfig", + Options: options, + } +} diff --git a/internal/osbuild/sysconfig_stage_test.go b/internal/osbuild/sysconfig_stage_test.go new file mode 100644 index 000000000..b1c30b024 --- /dev/null +++ b/internal/osbuild/sysconfig_stage_test.go @@ -0,0 +1,16 @@ +package osbuild + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewSysconfigStage(t *testing.T) { + expectedStage := &Stage{ + Name: "org.osbuild.sysconfig", + Options: &SysconfigStageOptions{}, + } + actualStage := NewSysconfigStage(&SysconfigStageOptions{}) + assert.Equal(t, expectedStage, actualStage) +} diff --git a/test/data/manifests/rhel_84-x86_64-ami-boot.json b/test/data/manifests/rhel_84-x86_64-ami-boot.json index f37ed5ef7..2b390e5a4 100644 --- a/test/data/manifests/rhel_84-x86_64-ami-boot.json +++ b/test/data/manifests/rhel_84-x86_64-ami-boot.json @@ -3285,6 +3285,19 @@ "options": { "file_contexts": "etc/selinux/targeted/contexts/files/file_contexts" } + }, + { + "name": "org.osbuild.sysconfig", + "options": { + "kernel": { + "update_default": true, + "default_kernel": "kernel" + }, + "network": { + "networking": true, + "no_zero_conf": true + } + } } ], "assembler": { @@ -9700,6 +9713,16 @@ "udisks2.service", "unbound-anchor.timer" ], + "sysconfig": { + "kernel": { + "DEFAULTKERNEL": "kernel", + "UPDATEDEFAULT": "yes" + }, + "network": { + "NETWORKING": "yes", + "NOZEROCONF": "yes" + } + }, "timezone": "New_York" } } \ No newline at end of file diff --git a/test/data/manifests/rhel_84-x86_64-openstack-boot.json b/test/data/manifests/rhel_84-x86_64-openstack-boot.json index 62ffc1c95..8a8aad0dc 100644 --- a/test/data/manifests/rhel_84-x86_64-openstack-boot.json +++ b/test/data/manifests/rhel_84-x86_64-openstack-boot.json @@ -3528,6 +3528,19 @@ "options": { "file_contexts": "etc/selinux/targeted/contexts/files/file_contexts" } + }, + { + "name": "org.osbuild.sysconfig", + "options": { + "kernel": { + "update_default": true, + "default_kernel": "kernel" + }, + "network": { + "networking": true, + "no_zero_conf": true + } + } } ], "assembler": { @@ -10321,6 +10334,16 @@ "udisks2.service", "unbound-anchor.timer" ], + "sysconfig": { + "kernel": { + "DEFAULTKERNEL": "kernel", + "UPDATEDEFAULT": "yes" + }, + "network": { + "NETWORKING": "yes", + "NOZEROCONF": "yes" + } + }, "timezone": "New_York" } } \ No newline at end of file diff --git a/test/data/manifests/rhel_84-x86_64-qcow2-boot.json b/test/data/manifests/rhel_84-x86_64-qcow2-boot.json index 94605512a..5478748d6 100644 --- a/test/data/manifests/rhel_84-x86_64-qcow2-boot.json +++ b/test/data/manifests/rhel_84-x86_64-qcow2-boot.json @@ -3468,6 +3468,19 @@ "options": { "file_contexts": "etc/selinux/targeted/contexts/files/file_contexts" } + }, + { + "name": "org.osbuild.sysconfig", + "options": { + "kernel": { + "update_default": true, + "default_kernel": "kernel" + }, + "network": { + "networking": true, + "no_zero_conf": true + } + } } ], "assembler": { @@ -10168,6 +10181,16 @@ "tuned.service", "unbound-anchor.timer" ], + "sysconfig": { + "kernel": { + "DEFAULTKERNEL": "kernel", + "UPDATEDEFAULT": "yes" + }, + "network": { + "NETWORKING": "yes", + "NOZEROCONF": "yes" + } + }, "timezone": "New_York" } } \ No newline at end of file diff --git a/test/data/manifests/rhel_84-x86_64-qcow2-customize.json b/test/data/manifests/rhel_84-x86_64-qcow2-customize.json index 63092a2fd..1d46d4f67 100644 --- a/test/data/manifests/rhel_84-x86_64-qcow2-customize.json +++ b/test/data/manifests/rhel_84-x86_64-qcow2-customize.json @@ -3573,6 +3573,19 @@ "options": { "file_contexts": "etc/selinux/targeted/contexts/files/file_contexts" } + }, + { + "name": "org.osbuild.sysconfig", + "options": { + "kernel": { + "update_default": true, + "default_kernel": "kernel" + }, + "network": { + "networking": true, + "no_zero_conf": true + } + } } ], "assembler": { @@ -10278,6 +10291,16 @@ "tuned.service", "unbound-anchor.timer" ], + "sysconfig": { + "kernel": { + "DEFAULTKERNEL": "kernel", + "UPDATEDEFAULT": "yes" + }, + "network": { + "NETWORKING": "yes", + "NOZEROCONF": "yes" + } + }, "timezone": "London" } } \ No newline at end of file diff --git a/test/data/manifests/rhel_84-x86_64-vhd-boot.json b/test/data/manifests/rhel_84-x86_64-vhd-boot.json index a46f6c34e..a3641f266 100644 --- a/test/data/manifests/rhel_84-x86_64-vhd-boot.json +++ b/test/data/manifests/rhel_84-x86_64-vhd-boot.json @@ -3499,6 +3499,19 @@ "options": { "file_contexts": "etc/selinux/targeted/contexts/files/file_contexts" } + }, + { + "name": "org.osbuild.sysconfig", + "options": { + "kernel": { + "update_default": true, + "default_kernel": "kernel" + }, + "network": { + "networking": true, + "no_zero_conf": true + } + } } ], "assembler": { @@ -10248,6 +10261,16 @@ "unbound-anchor.timer", "waagent.service" ], + "sysconfig": { + "kernel": { + "DEFAULTKERNEL": "kernel", + "UPDATEDEFAULT": "yes" + }, + "network": { + "NETWORKING": "yes", + "NOZEROCONF": "yes" + } + }, "timezone": "New_York" } } \ No newline at end of file diff --git a/test/data/manifests/rhel_84-x86_64-vmdk-boot.json b/test/data/manifests/rhel_84-x86_64-vmdk-boot.json index 5b52eb087..bf9e12ac9 100644 --- a/test/data/manifests/rhel_84-x86_64-vmdk-boot.json +++ b/test/data/manifests/rhel_84-x86_64-vmdk-boot.json @@ -3357,6 +3357,19 @@ "options": { "file_contexts": "etc/selinux/targeted/contexts/files/file_contexts" } + }, + { + "name": "org.osbuild.sysconfig", + "options": { + "kernel": { + "update_default": true, + "default_kernel": "kernel" + }, + "network": { + "networking": true, + "no_zero_conf": true + } + } } ], "assembler": { @@ -9873,6 +9886,16 @@ "vgauthd.service", "vmtoolsd.service" ], + "sysconfig": { + "kernel": { + "DEFAULTKERNEL": "kernel", + "UPDATEDEFAULT": "yes" + }, + "network": { + "NETWORKING": "yes", + "NOZEROCONF": "yes" + } + }, "timezone": "New_York" } } \ No newline at end of file diff --git a/tools/image-info b/tools/image-info index 61c84830e..cc874705f 100755 --- a/tools/image-info +++ b/tools/image-info @@ -358,6 +358,30 @@ def read_fstab(tree): result = sorted([line.split() for line in f if line and not line.startswith("#")]) return result +# Create a nested dictionary for all supported sysconfigs +def read_sysconfig(tree): + result = {} + sysconfig_paths = { + "kernel": f"{tree}/etc/sysconfig/kernel", + "network": f"{tree}/etc/sysconfig/network" + } + # iterate through supported configs + # based on https://github.com/osbuild/osbuild/blob/main/osbuild/util/osrelease.py#L17 + for name, path in sysconfig_paths.items(): + with contextlib.suppress(FileNotFoundError): + with open(path) as f: + # if file exists start with empty array of values + result[name] = {} + for line in f: + line = line.strip() + if not line: + continue + if line[0] == "#": + continue + key, value = line.split("=", 1) + result[name][key] = value.strip('"') + return result + def append_filesystem(report, tree, *, is_ostree=False): if os.path.exists(f"{tree}/etc/os-release"): @@ -389,6 +413,10 @@ def append_filesystem(report, tree, *, is_ostree=False): if fstab: report["fstab"] = fstab + sysconfig = read_sysconfig(tree) + if sysconfig: + report["sysconfig"] = sysconfig + with open(f"{tree}/etc/passwd") as f: report["passwd"] = sorted(f.read().strip().split("\n"))