osbuild2: add support for org.osbuild.modprobe stage
Add support for the `org.osbuild.modprobe` osbuild stage [1], which allows one to configure modprobe by creating configuration files. Add unit test cases for the newly added stage. [1] https://github.com/osbuild/osbuild/pull/670 Signed-off-by: Tomas Hozza <thozza@redhat.com>
This commit is contained in:
parent
9386a02984
commit
c0e8d4bdc4
4 changed files with 171 additions and 0 deletions
91
internal/osbuild2/modprobe_stage.go
Normal file
91
internal/osbuild2/modprobe_stage.go
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
package osbuild2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type ModprobeStageOptions struct {
|
||||
ConfigFiles map[string]ModprobeConfigCmdList `json:"configuration_files,omitempty"`
|
||||
}
|
||||
|
||||
func (ModprobeStageOptions) isStageOptions() {}
|
||||
|
||||
func NewModprobeStage(options *ModprobeStageOptions) *Stage {
|
||||
return &Stage{
|
||||
Type: "org.osbuild.modprobe",
|
||||
Options: options,
|
||||
}
|
||||
}
|
||||
|
||||
type ModprobeConfigCmd interface {
|
||||
isModprobeConfigCmd()
|
||||
}
|
||||
|
||||
// ModprobeConfigCmdList represents a modprobe configuration file, which contains
|
||||
// a list of commands.
|
||||
type ModprobeConfigCmdList []ModprobeConfigCmd
|
||||
|
||||
func (configFile *ModprobeConfigCmdList) UnmarshalJSON(data []byte) error {
|
||||
var rawConfigFile []interface{}
|
||||
|
||||
if err := json.Unmarshal(data, &rawConfigFile); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, rawConfigCmd := range rawConfigFile {
|
||||
var modprobeCmd ModprobeConfigCmd
|
||||
|
||||
// The command object structure depends on the value of "command"
|
||||
// item, therefore make no assumptions on the structure.
|
||||
configCmdMap, ok := rawConfigCmd.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected modprobe configuration file format")
|
||||
}
|
||||
command, ok := configCmdMap["command"].(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("'command' item should be string, not %T", configCmdMap["command"])
|
||||
}
|
||||
|
||||
switch command {
|
||||
case "blacklist":
|
||||
modulename, ok := configCmdMap["modulename"].(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("'modulename' item should be string, not %T", configCmdMap["modulename"])
|
||||
}
|
||||
modprobeCmd = NewModprobeConfigCmdBlacklist(modulename)
|
||||
default:
|
||||
return fmt.Errorf("unexpected modprobe command: %s", command)
|
||||
}
|
||||
|
||||
*configFile = append(*configFile, modprobeCmd)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o ModprobeConfigCmdList) MarshalJSON() ([]byte, error) {
|
||||
if len(o) == 0 {
|
||||
return nil, fmt.Errorf("at least one modprobe command must be specified for a configuration file")
|
||||
}
|
||||
var configList []ModprobeConfigCmd = o
|
||||
return json.Marshal(configList)
|
||||
}
|
||||
|
||||
// ModprobeConfigCmdBlacklist represents the 'blacklist' command in the
|
||||
// modprobe configuration.
|
||||
type ModprobeConfigCmdBlacklist struct {
|
||||
Command string `json:"command"`
|
||||
Modulename string `json:"modulename"`
|
||||
}
|
||||
|
||||
func (ModprobeConfigCmdBlacklist) isModprobeConfigCmd() {}
|
||||
|
||||
// NewModprobeConfigCmdBlacklist creates a new instance of ModprobeConfigCmdBlacklist
|
||||
// for the provided modulename.
|
||||
func NewModprobeConfigCmdBlacklist(modulename string) *ModprobeConfigCmdBlacklist {
|
||||
return &ModprobeConfigCmdBlacklist{
|
||||
Command: "blacklist",
|
||||
Modulename: modulename,
|
||||
}
|
||||
}
|
||||
39
internal/osbuild2/modprobe_stage_test.go
Normal file
39
internal/osbuild2/modprobe_stage_test.go
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
package osbuild2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewModprobeStage(t *testing.T) {
|
||||
expectedStage := &Stage{
|
||||
Type: "org.osbuild.modprobe",
|
||||
Options: &ModprobeStageOptions{},
|
||||
}
|
||||
actualStage := NewModprobeStage(&ModprobeStageOptions{})
|
||||
assert.Equal(t, expectedStage, actualStage)
|
||||
}
|
||||
|
||||
func TestModprobeStage_MarshalJSON_Invalid(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
options ModprobeStageOptions
|
||||
}{
|
||||
{
|
||||
name: "no-commands",
|
||||
options: ModprobeStageOptions{
|
||||
ConfigFiles: map[string]ModprobeConfigCmdList{
|
||||
"disallow-modules.conf": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for idx, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotBytes, err := json.Marshal(tt.options)
|
||||
assert.NotNilf(t, err, "json.Marshal() didn't return an error, but: %s [idx: %d]", string(gotBytes), idx)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -89,6 +89,8 @@ func (stage *Stage) UnmarshalJSON(data []byte) error {
|
|||
options = new(ChronyStageOptions)
|
||||
case "org.osbuild.keymap":
|
||||
options = new(KeymapStageOptions)
|
||||
case "org.osbuild.modprobe":
|
||||
options = new(ModprobeStageOptions)
|
||||
case "org.osbuild.firewall":
|
||||
options = new(FirewallStageOptions)
|
||||
case "org.osbuild.rhsm":
|
||||
|
|
|
|||
|
|
@ -162,6 +162,45 @@ func TestStage_UnmarshalJSON(t *testing.T) {
|
|||
data: []byte(`{"type":"org.osbuild.keymap","options":{"keymap":""}}`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "modprobe",
|
||||
fields: fields{
|
||||
Type: "org.osbuild.modprobe",
|
||||
Options: &ModprobeStageOptions{},
|
||||
},
|
||||
args: args{
|
||||
data: []byte(`{"type":"org.osbuild.modprobe","options":{}}`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "modprobe-data",
|
||||
fields: fields{
|
||||
Type: "org.osbuild.modprobe",
|
||||
Options: &ModprobeStageOptions{
|
||||
ConfigFiles: map[string]ModprobeConfigCmdList{
|
||||
"disallow-modules.conf": {
|
||||
&ModprobeConfigCmdBlacklist{
|
||||
Command: "blacklist",
|
||||
Modulename: "nouveau",
|
||||
},
|
||||
&ModprobeConfigCmdBlacklist{
|
||||
Command: "blacklist",
|
||||
Modulename: "floppy",
|
||||
},
|
||||
},
|
||||
"disallow-additional-modules.conf": {
|
||||
&ModprobeConfigCmdBlacklist{
|
||||
Command: "blacklist",
|
||||
Modulename: "my-module",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
data: []byte(`{"type":"org.osbuild.modprobe","options":{"configuration_files":{"disallow-additional-modules.conf":[{"command":"blacklist","modulename":"my-module"}],"disallow-modules.conf":[{"command":"blacklist","modulename":"nouveau"},{"command":"blacklist","modulename":"floppy"}]}}}`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "locale",
|
||||
fields: fields{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue