Skip to content

Commit d532226

Browse files
prestistyasminvalimjmarreroc4rt0
committed
base/v0_6_exp: add parent directory sugar
Add a field called 'Parent' which is used to specify a file's parent directory. When a parent is specified, all directories from the parent to the file will be created, with the 'mode' supplied in the parent directory. Co-authored-by: Yasmin Valim <[email protected]> Co-authored-by: Joseph Corchado <[email protected]> Co-authored-by: Adam Piasecki <[email protected]>
1 parent 4f1b414 commit d532226

File tree

4 files changed

+140
-4
lines changed

4 files changed

+140
-4
lines changed

base/v0_6_exp/schema.go

+6
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ type File struct {
6767
Append []Resource `yaml:"append"`
6868
Contents Resource `yaml:"contents"`
6969
Mode *int `yaml:"mode"`
70+
Parent Parent `yaml:"parent"`
71+
}
72+
73+
type Parent struct {
74+
Path *string `yaml:"path"`
75+
Mode *int `yaml:"mode"`
7076
}
7177

7278
type Filesystem struct {

base/v0_6_exp/translate.go

+68-4
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,7 @@ func (c Config) ToIgn3_5Unvalidated(options common.TranslateOptions) (types.Conf
8383

8484
tr := translate.NewTranslator("yaml", "json", options)
8585
tr.AddCustomTranslator(translateIgnition)
86-
tr.AddCustomTranslator(translateFile)
87-
tr.AddCustomTranslator(translateDirectory)
88-
tr.AddCustomTranslator(translateLink)
86+
tr.AddCustomTranslator(translateStorage)
8987
tr.AddCustomTranslator(translateResource)
9088
tr.AddCustomTranslator(translatePasswdUser)
9189
tr.AddCustomTranslator(translateUnit)
@@ -99,7 +97,6 @@ func (c Config) ToIgn3_5Unvalidated(options common.TranslateOptions) (types.Conf
9997
translate.MergeP(tr, tm, &r, "systemd", &c.Systemd, &ret.Systemd)
10098

10199
c.addMountUnits(&ret, &tm)
102-
103100
tm2, r2 := c.processTrees(&ret, options)
104101
tm.Merge(tm2)
105102
r.Merge(r2)
@@ -121,6 +118,64 @@ func translateIgnition(from Ignition, options common.TranslateOptions) (to types
121118
return
122119
}
123120

121+
func translateStorage(from Storage, options common.TranslateOptions) (to types.Storage, tm translate.TranslationSet, r report.Report) {
122+
tr := translate.NewTranslator("yaml", "json", options)
123+
tr.AddCustomTranslator(translateFile)
124+
tr.AddCustomTranslator(translateDirectory)
125+
tr.AddCustomTranslator(translateLink)
126+
tr.AddCustomTranslator(translateLuks)
127+
tm, r = translate.Prefixed(tr, "directories", &from.Directories, &to.Directories)
128+
translate.MergeP(tr, tm, &r, "disks", &from.Disks, &to.Disks)
129+
translate.MergeP(tr, tm, &r, "files", &from.Files, &to.Files)
130+
translate.MergeP(tr, tm, &r, "filesystems", &from.Filesystems, &to.Filesystems)
131+
translate.MergeP(tr, tm, &r, "links", &from.Links, &to.Links)
132+
translate.MergeP(tr, tm, &r, "luks", &from.Luks, &to.Luks)
133+
translate.MergeP(tr, tm, &r, "raid", &from.Raid, &to.Raid)
134+
for _, file := range from.Files {
135+
if util.NotEmpty(file.Parent.Path) {
136+
c := path.New("yaml", "parent")
137+
parentDirectory := types.Directory{
138+
Node: types.Node{
139+
Path: *file.Parent.Path,
140+
Group: types.NodeGroup{ID: file.Group.ID, Name: file.Group.Name},
141+
User: types.NodeUser{ID: file.User.ID, Name: file.User.Name},
142+
},
143+
DirectoryEmbedded1: types.DirectoryEmbedded1{
144+
Mode: file.Parent.Mode,
145+
},
146+
}
147+
to.Directories = append(to.Directories, parentDirectory)
148+
// find what is between parent and file path
149+
theInBetween := strings.Replace(file.Path, *file.Parent.Path, "", 1)
150+
151+
workingDirectory := *file.Parent.Path
152+
// render all directories between the filepath and the parent with the parent's mode
153+
arrayDirectory := strings.Split(theInBetween, "/")
154+
for i := 0; i < len(arrayDirectory)-1; i++ {
155+
dirTobeCreated := arrayDirectory[i]
156+
if dirTobeCreated == "" {
157+
continue
158+
}
159+
workingDirectory += "/" + dirTobeCreated
160+
directoryToBeRendered := types.Directory{
161+
Node: types.Node{
162+
Path: workingDirectory,
163+
Group: types.NodeGroup{ID: file.Group.ID, Name: file.Group.Name},
164+
User: types.NodeUser{ID: file.User.ID, Name: file.User.Name},
165+
},
166+
DirectoryEmbedded1: types.DirectoryEmbedded1{
167+
Mode: file.Parent.Mode,
168+
},
169+
}
170+
to.Directories = append(to.Directories, directoryToBeRendered)
171+
}
172+
tm.AddFromCommonSource(c, path.New("json", "directories"), to.Directories)
173+
}
174+
175+
}
176+
return
177+
}
178+
124179
func translateFile(from File, options common.TranslateOptions) (to types.File, tm translate.TranslationSet, r report.Report) {
125180
tr := translate.NewTranslator("yaml", "json", options)
126181
tr.AddCustomTranslator(translateResource)
@@ -134,6 +189,15 @@ func translateFile(from File, options common.TranslateOptions) (to types.File, t
134189
return
135190
}
136191

192+
func translateLuks(from Luks, options common.TranslateOptions) (to types.Luks, tm translate.TranslationSet, r report.Report) {
193+
tr := translate.NewTranslator("yaml", "json", options)
194+
tm, r = translate.Prefixed(tr, "clevis", &from.Clevis, &to.Clevis)
195+
translate.MergeP(tr, tm, &r, "device", &from.Device, &to.Device)
196+
translate.MergeP(tr, tm, &r, "name", &from.Name, &to.Name)
197+
translate.MergeP(tr, tm, &r, "wipe_volume", &from.WipeVolume, &to.WipeVolume)
198+
return
199+
}
200+
137201
func translateResource(from Resource, options common.TranslateOptions) (to types.Resource, tm translate.TranslationSet, r report.Report) {
138202
tr := translate.NewTranslator("yaml", "json", options)
139203
tm, r = translate.Prefixed(tr, "verification", &from.Verification, &to.Verification)

base/v0_6_exp/translate_test.go

+64
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,70 @@ func TestTranslateFile(t *testing.T) {
599599
})
600600
}
601601
}
602+
func TestTranslateStorage(t *testing.T) {
603+
tests := []struct {
604+
in Storage
605+
out types.Storage
606+
}{
607+
{
608+
Storage{
609+
Files: []File{
610+
{
611+
Path: "/foo/bar/txt.txt",
612+
Contents: Resource{},
613+
Mode: util.IntToPtr(420),
614+
Parent: Parent{
615+
Path: util.StrToPtr("/foo"),
616+
Mode: util.IntToPtr(420),
617+
},
618+
},
619+
},
620+
},
621+
types.Storage{
622+
Files: []types.File{
623+
{
624+
Node: types.Node{
625+
Path: "/foo/bar/txt.txt",
626+
},
627+
FileEmbedded1: types.FileEmbedded1{
628+
Mode: util.IntToPtr(420),
629+
Contents: types.Resource{},
630+
},
631+
},
632+
},
633+
Directories: []types.Directory{
634+
{
635+
Node: types.Node{
636+
Path: "/foo",
637+
},
638+
DirectoryEmbedded1: types.DirectoryEmbedded1{
639+
Mode: util.IntToPtr(420),
640+
},
641+
},
642+
{
643+
Node: types.Node{
644+
Path: "/foo/bar",
645+
},
646+
DirectoryEmbedded1: types.DirectoryEmbedded1{
647+
Mode: util.IntToPtr(420),
648+
},
649+
},
650+
},
651+
},
652+
},
653+
}
654+
655+
for i, test := range tests {
656+
t.Run(fmt.Sprintf("translate %d", i), func(t *testing.T) {
657+
actual, translations, r := translateStorage(test.in, common.TranslateOptions{})
658+
r = confutil.TranslateReportPaths(r, translations)
659+
baseutil.VerifyReport(t, test.in, r)
660+
assert.Equal(t, test.out, actual, "translation mismatch")
661+
assert.Equal(t, report.Report{}, r, "non-empty report")
662+
assert.NoError(t, translations.DebugVerifyCoverage(actual), "incomplete TranslationSet coverage")
663+
})
664+
}
665+
}
602666

603667
// TestTranslateDirectory tests translating the ct storage.directories.[i] entries to ignition storage.directories.[i] entires.
604668
func TestTranslateDirectory(t *testing.T) {

docs/release-notes.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ nav_order: 9
1313
### Features
1414

1515
- Support s390x layouts in `boot_device` section (fcos 1.6.0-exp, openshift 4.15.0-exp)
16+
- Add `parent` field to `files`, to reduce verbosity when configuring a deeply
17+
nested file. _(base 0.6.0-exp)_
1618

1719
### Bug fixes
1820

0 commit comments

Comments
 (0)