osbuild2: add support for org.osbuild.tmpfilesd stage
Add support for a new osbuild stage `org.osbuild.tmpfilesd`, for creating tmpfiles.d configuration files. Add unit tests for the new stage. Related to https://github.com/osbuild/osbuild/pull/801. Signed-off-by: Tomas Hozza <thozza@redhat.com>
This commit is contained in:
parent
fbb70c2d10
commit
3f52af2adb
4 changed files with 131 additions and 0 deletions
|
|
@ -91,6 +91,8 @@ func (stage *Stage) UnmarshalJSON(data []byte) error {
|
|||
options = new(ScriptStageOptions)
|
||||
case "org.osbuild.sysconfig":
|
||||
options = new(SysconfigStageOptions)
|
||||
case "org.osbuild.tmpfilesd":
|
||||
options = new(TmpfilesdStageOptions)
|
||||
case "org.osbuild.kernel-cmdline":
|
||||
options = new(KernelCmdlineStageOptions)
|
||||
case "org.osbuild.rpm":
|
||||
|
|
|
|||
|
|
@ -526,6 +526,24 @@ func TestStage_UnmarshalJSON(t *testing.T) {
|
|||
data: []byte(`{"type":"org.osbuild.timezone","options":{"zone":""}}`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "tmpfilesd",
|
||||
fields: fields{
|
||||
Type: "org.osbuild.tmpfilesd",
|
||||
Options: &TmpfilesdStageOptions{
|
||||
Filename: "example.conf",
|
||||
Config: []TmpfilesdConfigLine{
|
||||
{
|
||||
Type: "d",
|
||||
Path: "/tmp/my-example-path",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
args: args{
|
||||
data: []byte(`{"type":"org.osbuild.tmpfilesd","options":{"filename":"example.conf","config":[{"type":"d","path":"/tmp/my-example-path"}]}}`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "users",
|
||||
fields: fields{
|
||||
|
|
|
|||
61
internal/osbuild2/tmpfilesd_stage.go
Normal file
61
internal/osbuild2/tmpfilesd_stage.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package osbuild2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// TmpfilesdStageOptions represents a single tmpfiles.d configuration file.
|
||||
type TmpfilesdStageOptions struct {
|
||||
// Filename of the configuration file to be created. Must end with '.conf'.
|
||||
Filename string `json:"filename"`
|
||||
// List of configuration directives. The list must contain at least one item.
|
||||
Config []TmpfilesdConfigLine `json:"config"`
|
||||
}
|
||||
|
||||
func (TmpfilesdStageOptions) isStageOptions() {}
|
||||
|
||||
// NewTmpfilesdStageOptions creates a new Tmpfilesd Stage options object.
|
||||
func NewTmpfilesdStageOptions(filename string, config []TmpfilesdConfigLine) *TmpfilesdStageOptions {
|
||||
return &TmpfilesdStageOptions{
|
||||
Filename: filename,
|
||||
Config: config,
|
||||
}
|
||||
}
|
||||
|
||||
// Unexported alias for use in TmpfilesdStageOptions's MarshalJSON() to prevent recursion
|
||||
type tmpfilesdStageOptions TmpfilesdStageOptions
|
||||
|
||||
func (o TmpfilesdStageOptions) MarshalJSON() ([]byte, error) {
|
||||
if len(o.Config) == 0 {
|
||||
return nil, fmt.Errorf("the 'Config' list must contain at least one item")
|
||||
}
|
||||
options := tmpfilesdStageOptions(o)
|
||||
return json.Marshal(options)
|
||||
}
|
||||
|
||||
// NewTmpfilesdStage creates a new Tmpfilesd Stage object.
|
||||
func NewTmpfilesdStage(options *TmpfilesdStageOptions) *Stage {
|
||||
return &Stage{
|
||||
Type: "org.osbuild.tmpfilesd",
|
||||
Options: options,
|
||||
}
|
||||
}
|
||||
|
||||
// TmpfilesdConfigLine represents a single line in a tmpfiles.d configuration.
|
||||
type TmpfilesdConfigLine struct {
|
||||
// The file system path type
|
||||
Type string `json:"type"`
|
||||
// Absolute file system path
|
||||
Path string `json:"path"`
|
||||
// The file access mode when creating the file or directory
|
||||
Mode string `json:"mode,omitempty"`
|
||||
// The user to use for the file or directory
|
||||
User string `json:"user,omitempty"`
|
||||
// The group to use for the file or directory
|
||||
Group string `json:"group,omitempty"`
|
||||
// Date field used to decide what files to delete when cleaning
|
||||
Age string `json:"age,omitempty"`
|
||||
// Argument with its meaning being specific to the path type
|
||||
Argument string `json:"argument,omitempty"`
|
||||
}
|
||||
50
internal/osbuild2/tmpfilesd_stage_test.go
Normal file
50
internal/osbuild2/tmpfilesd_stage_test.go
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
package osbuild2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewTmpfilesdStageOptions(t *testing.T) {
|
||||
filename := "example.conf"
|
||||
config := []TmpfilesdConfigLine{{
|
||||
Type: "d",
|
||||
Path: "/tmp/my-example-path",
|
||||
}}
|
||||
|
||||
expectedOptions := &TmpfilesdStageOptions{
|
||||
Filename: filename,
|
||||
Config: config,
|
||||
}
|
||||
actualOptions := NewTmpfilesdStageOptions(filename, config)
|
||||
assert.Equal(t, expectedOptions, actualOptions)
|
||||
}
|
||||
|
||||
func TestNewTmpfilesdStage(t *testing.T) {
|
||||
expectedStage := &Stage{
|
||||
Type: "org.osbuild.tmpfilesd",
|
||||
Options: &TmpfilesdStageOptions{},
|
||||
}
|
||||
actualStage := NewTmpfilesdStage(&TmpfilesdStageOptions{})
|
||||
assert.Equal(t, expectedStage, actualStage)
|
||||
}
|
||||
|
||||
func TestTmpfilesdStageOptions_MarshalJSON_Invalid(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
options TmpfilesdStageOptions
|
||||
}{
|
||||
{
|
||||
name: "empty-options",
|
||||
options: TmpfilesdStageOptions{},
|
||||
},
|
||||
}
|
||||
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)
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue