@@ -5,7 +5,6 @@ package imagecustomizerlib
5
5
6
6
import (
7
7
"fmt"
8
- "io/fs"
9
8
"os"
10
9
"path/filepath"
11
10
"regexp"
@@ -29,13 +28,22 @@ const (
29
28
savedConfigsFileNamePath = "/" + savedConfigsDir + "/" + savedConfigsFileName
30
29
)
31
30
31
+ var (
32
+ kernelVersionRegEx = regexp .MustCompile (`\b(\d+\.\d+\.\d+\.\d+-\d+\.(azl|cm)\d)\b` )
33
+ )
34
+
32
35
type IsoInfoStore struct {
33
- kernelVersion string
34
36
seLinuxMode imagecustomizerapi.SELinuxMode
35
37
dracutPackageInfo * PackageVersionInformation
36
38
selinuxPolicyPackageInfo * PackageVersionInformation
37
39
}
38
40
41
+ type KernelBootFiles struct {
42
+ vmlinuzPath string
43
+ initrdImagePath string
44
+ otherFiles []string
45
+ }
46
+
39
47
type IsoFilesStore struct {
40
48
artifactsDir string
41
49
bootEfiPath string
@@ -44,8 +52,8 @@ type IsoFilesStore struct {
44
52
isoGrubCfgPath string
45
53
pxeGrubCfgPath string
46
54
savedConfigsFilePath string
47
- vmlinuzPath string
48
- initrdImagePath string
55
+ kernelBootFiles map [ string ] * KernelBootFiles // kernel-version -> KernelBootFiles
56
+ initrdImagePath string // non-kernel specific
49
57
squashfsImagePath string
50
58
additionalFiles map [string ]string // local-build-path -> iso-media-path
51
59
}
@@ -82,53 +90,60 @@ func containsGrubNoPrefix(filePaths []string) (bool, error) {
82
90
return false , nil
83
91
}
84
92
85
- func findKernelVersion (imageRootDir string ) (kernelVersion string , err error ) {
86
- const kernelModulesDir = "/usr/lib/modules"
93
+ func getSELinuxMode (imageChroot * safechroot.Chroot ) (imagecustomizerapi.SELinuxMode , error ) {
94
+ bootCustomizer , err := NewBootCustomizer (imageChroot )
95
+ if err != nil {
96
+ return imagecustomizerapi .SELinuxModeDefault , err
97
+ }
87
98
88
- kernelParentPath := filepath .Join (imageRootDir , kernelModulesDir )
89
- kernelDirs , err := os .ReadDir (kernelParentPath )
99
+ imageSELinuxMode , err := bootCustomizer .GetSELinuxMode (imageChroot )
90
100
if err != nil {
91
- return "" , fmt .Errorf ("failed to enumerate kernels under (%s) :\n %w" , kernelParentPath , err )
101
+ return imagecustomizerapi . SELinuxModeDefault , fmt .Errorf ("failed to get current SELinux mode :\n %w" , err )
92
102
}
93
103
94
- // Filter out directories that are empty.
95
- // Some versions of Azure Linux 2.0 don't cleanup properly when the kernel package is uninstalled.
96
- filteredKernelDirs := []fs.DirEntry (nil )
97
- for _ , kernelDir := range kernelDirs {
98
- kernelPath := filepath .Join (kernelParentPath , kernelDir .Name ())
99
- empty , err := file .IsDirEmpty (kernelPath )
100
- if err != nil {
101
- return "" , err
102
- }
104
+ return imageSELinuxMode , nil
105
+ }
103
106
104
- if ! empty {
105
- filteredKernelDirs = append (filteredKernelDirs , kernelDir )
106
- }
107
+ func getKernelVersions (filesStore * IsoFilesStore ) []string {
108
+ var kernelVersions []string
109
+ for k := range filesStore .kernelBootFiles {
110
+ kernelVersions = append (kernelVersions , k )
107
111
}
108
112
109
- if len (filteredKernelDirs ) == 0 {
110
- return "" , fmt .Errorf ("did not find any kernels installed under (%s)" , kernelModulesDir )
111
- }
112
- if len (filteredKernelDirs ) > 1 {
113
- return "" , fmt .Errorf ("unsupported scenario: found more than one kernel under (%s)" , kernelModulesDir )
114
- }
115
- kernelVersion = filteredKernelDirs [0 ].Name ()
116
- logger .Log .Debugf ("Found installed kernel version (%s)" , kernelVersion )
117
- return kernelVersion , nil
113
+ return kernelVersions
118
114
}
119
115
120
- func getSELinuxMode (imageChroot * safechroot.Chroot ) (imagecustomizerapi.SELinuxMode , error ) {
121
- bootCustomizer , err := NewBootCustomizer (imageChroot )
122
- if err != nil {
123
- return imagecustomizerapi .SELinuxModeDefault , err
116
+ func storeIfKernelSpecificFile (filesStore * IsoFilesStore , targetPath string ) bool {
117
+ scheduleAdditionalFile := true
118
+
119
+ baseFileName := filepath .Base (targetPath )
120
+
121
+ matches := kernelVersionRegEx .FindStringSubmatch (baseFileName )
122
+ if len (matches ) <= 1 {
123
+ return scheduleAdditionalFile
124
124
}
125
125
126
- imageSELinuxMode , err := bootCustomizer .GetSELinuxMode (imageChroot )
127
- if err != nil {
128
- return imagecustomizerapi .SELinuxModeDefault , fmt .Errorf ("failed to get current SELinux mode:\n %w" , err )
126
+ kernelVersion := matches [1 ]
127
+
128
+ // Ensure we have an entry in the map for it
129
+ kernelBootFiles , exists := filesStore .kernelBootFiles [kernelVersion ]
130
+ if ! exists {
131
+ kernelBootFiles = & KernelBootFiles {}
132
+ filesStore .kernelBootFiles [kernelVersion ] = kernelBootFiles
129
133
}
130
134
131
- return imageSELinuxMode , nil
135
+ if strings .HasPrefix (baseFileName , vmLinuzPrefix ) {
136
+ kernelBootFiles .vmlinuzPath = targetPath
137
+ scheduleAdditionalFile = false
138
+ } else if strings .HasPrefix (baseFileName , initramfsPrefix ) || strings .HasPrefix (baseFileName , initrdPrefix ) {
139
+ kernelBootFiles .initrdImagePath = targetPath
140
+ scheduleAdditionalFile = false
141
+ } else {
142
+ kernelBootFiles .otherFiles = append (kernelBootFiles .otherFiles , targetPath )
143
+ scheduleAdditionalFile = false
144
+ }
145
+
146
+ return scheduleAdditionalFile
132
147
}
133
148
134
149
func createIsoFilesStoreFromMountedImage (inputArtifactsStore * IsoArtifactsStore , imageRootDir string , storeDir string ) (filesStore * IsoFilesStore , err error ) {
@@ -138,18 +153,13 @@ func createIsoFilesStoreFromMountedImage(inputArtifactsStore *IsoArtifactsStore,
138
153
artifactsDir : artifactsDir ,
139
154
savedConfigsFilePath : filepath .Join (artifactsDir , savedConfigsDir , savedConfigsFileName ),
140
155
additionalFiles : make (map [string ]string ),
156
+ kernelBootFiles : make (map [string ]* KernelBootFiles ),
141
157
}
142
158
143
159
// the following files will be re-created - no need to copy them only to
144
160
// have them overwritten.
145
161
var exclusions []* regexp.Regexp
146
162
//
147
- // We will generate a new initrd later. So, we do not copy the initrd.img
148
- // that comes in the input full disk image.
149
- //
150
- exclusions = append (exclusions , regexp .MustCompile (`/boot/initrd\.img.*` ))
151
- exclusions = append (exclusions , regexp .MustCompile (`/boot/initramfs-.*\.img.*` ))
152
- //
153
163
// On full disk images (generated by Mariner toolkit), there are two
154
164
// grub.cfg files:
155
165
// - <boot partition>/boot/grub2/grub.cfg:
@@ -195,6 +205,13 @@ func createIsoFilesStoreFromMountedImage(inputArtifactsStore *IsoArtifactsStore,
195
205
relativeFilePath := strings .TrimPrefix (sourcePath , imageRootDir )
196
206
targetPath := strings .Replace (sourcePath , imageRootDir , filesStore .artifactsDir , - 1 )
197
207
208
+ // `scheduleAdditionalFile` indicates whether the file being processed
209
+ // now should be captured in the general 'additional' files collection
210
+ // or it has been captured in a data structure specific field
211
+ // (like filesStore.isoGrubCfgPath) and it will be handled from there.
212
+ // 'additional files' is a collection of all the files that need to be
213
+ // included in the final output, but we do not have particular interest
214
+ // in them (i.e. user files that we do not manipulate - but copy as-is).
198
215
scheduleAdditionalFile := true
199
216
200
217
_ , bootFilesConfig , err := getBootArchConfig ()
@@ -237,12 +254,11 @@ func createIsoFilesStoreFromMountedImage(inputArtifactsStore *IsoArtifactsStore,
237
254
// We will place the pxe grub config next to the iso grub config.
238
255
filesStore .pxeGrubCfgPath = filepath .Join (filepath .Dir (filesStore .isoGrubCfgPath ), pxeGrubCfg )
239
256
scheduleAdditionalFile = false
240
- }
241
-
242
- if strings .HasPrefix (filepath .Base (targetPath ), vmLinuzPrefix ) {
243
- targetPath = filepath .Join (filepath .Dir (targetPath ), "vmlinuz" )
244
- filesStore .vmlinuzPath = targetPath
257
+ case isoInitrdPath :
258
+ filesStore .initrdImagePath = targetPath
245
259
scheduleAdditionalFile = false
260
+ default :
261
+ scheduleAdditionalFile = storeIfKernelSpecificFile (filesStore , targetPath )
246
262
}
247
263
248
264
err = file .NewFileCopyBuilder (sourcePath , targetPath ).
@@ -280,7 +296,7 @@ func createIsoFilesStoreFromMountedImage(inputArtifactsStore *IsoArtifactsStore,
280
296
// already. This also ensures that no file from the input iso overwrites
281
297
// a newer version that has just been created.
282
298
283
- // Copy the addition files from the input iso store
299
+ // Copy the additional files from the input iso store
284
300
for inputSourceFile , inputTargetFile := range inputArtifactsStore .files .additionalFiles {
285
301
found := false
286
302
for _ , targetFile := range filesStore .additionalFiles {
@@ -327,15 +343,9 @@ func createIsoFilesStoreFromMountedImage(inputArtifactsStore *IsoArtifactsStore,
327
343
func createIsoInfoStoreFromMountedImage (imageRootDir string ) (infoStore * IsoInfoStore , err error ) {
328
344
infoStore = & IsoInfoStore {}
329
345
330
- kernelVersion , err := findKernelVersion (imageRootDir )
331
- if err != nil {
332
- return nil , fmt .Errorf ("failed to determine kernel version from (%s):\n %w" , imageRootDir , err )
333
- }
334
- infoStore .kernelVersion = kernelVersion
335
-
336
346
chroot := safechroot .NewChroot (imageRootDir , true /*isExistingDir*/ )
337
347
if chroot == nil {
338
- return nil , fmt .Errorf ("failed to create a new chroot object for (%s). " , imageRootDir )
348
+ return nil , fmt .Errorf ("failed to create a new chroot object for (%s)" , imageRootDir )
339
349
}
340
350
defer chroot .Close (true /*leaveOnDisk*/ )
341
351
@@ -387,6 +397,7 @@ func createIsoFilesStoreFromIsoImage(isoImageFile, storeDir string) (filesStore
387
397
}
388
398
389
399
filesStore .additionalFiles = make (map [string ]string )
400
+ filesStore .kernelBootFiles = make (map [string ]* KernelBootFiles )
390
401
391
402
_ , bootFilesConfig , err := getBootArchConfig ()
392
403
if err != nil {
@@ -429,12 +440,11 @@ func createIsoFilesStoreFromIsoImage(isoImageFile, storeDir string) (filesStore
429
440
case savedConfigsFileNamePath :
430
441
filesStore .savedConfigsFilePath = isoFile
431
442
scheduleAdditionalFile = false
432
- case isoKernelPath :
433
- filesStore .vmlinuzPath = isoFile
434
- scheduleAdditionalFile = false
435
443
case isoBootImagePath :
436
444
filesStore .isoBootImagePath = isoFile
437
445
scheduleAdditionalFile = false
446
+ default :
447
+ scheduleAdditionalFile = storeIfKernelSpecificFile (filesStore , isoFile )
438
448
}
439
449
440
450
if scheduleAdditionalFile {
@@ -457,7 +467,6 @@ func createIsoInfoStoreFromIsoImage(savedConfigFile string) (infoStore *IsoInfoS
457
467
// since we will not expand the rootfs and inspect its contents to get
458
468
// such information.
459
469
infoStore = & IsoInfoStore {
460
- kernelVersion : savedConfigs .OS .KernelVersion ,
461
470
dracutPackageInfo : savedConfigs .OS .DracutPackageInfo ,
462
471
selinuxPolicyPackageInfo : savedConfigs .OS .SELinuxPolicyPackageInfo ,
463
472
}
@@ -524,6 +533,19 @@ func fileExistsToString(filePath string) string {
524
533
return "!e " + filePath
525
534
}
526
535
536
+ func dumpKernelFiles (kernelBootFiles * KernelBootFiles ) {
537
+ if kernelBootFiles == nil {
538
+ logger .Log .Debugf ("-- -- not defined" )
539
+ return
540
+ }
541
+
542
+ logger .Log .Debugf ("-- -- vmlinuzPath = %s" , fileExistsToString (kernelBootFiles .vmlinuzPath ))
543
+ logger .Log .Debugf ("-- -- initrdImagePath = %s" , fileExistsToString (kernelBootFiles .initrdImagePath ))
544
+ for _ , otherFile := range kernelBootFiles .otherFiles {
545
+ logger .Log .Debugf ("-- -- otherFile = %s" , fileExistsToString (otherFile ))
546
+ }
547
+ }
548
+
527
549
func dumpFilesStore (filesStore * IsoFilesStore ) {
528
550
logger .Log .Debugf ("Files Store" )
529
551
if filesStore == nil {
@@ -537,7 +559,12 @@ func dumpFilesStore(filesStore *IsoFilesStore) {
537
559
logger .Log .Debugf ("-- isoGrubCfgPath = %s" , fileExistsToString (filesStore .isoGrubCfgPath ))
538
560
logger .Log .Debugf ("-- pxeGrubCfgPath = %s" , fileExistsToString (filesStore .pxeGrubCfgPath ))
539
561
logger .Log .Debugf ("-- savedConfigsFilePath = %s" , fileExistsToString (filesStore .savedConfigsFilePath ))
540
- logger .Log .Debugf ("-- vmlinuzPath = %s" , fileExistsToString (filesStore .vmlinuzPath ))
562
+ logger .Log .Debugf ("-- kernel file groups" )
563
+ for key , value := range filesStore .kernelBootFiles {
564
+ logger .Log .Debugf ("-- -- version = %s" , key )
565
+ dumpKernelFiles (value )
566
+ }
567
+
541
568
logger .Log .Debugf ("-- initrdImagePath = %s" , fileExistsToString (filesStore .initrdImagePath ))
542
569
logger .Log .Debugf ("-- squashfsImagePath = %s" , fileExistsToString (filesStore .squashfsImagePath ))
543
570
logger .Log .Debugf ("-- additionalFiles =" )
@@ -552,7 +579,6 @@ func dumpInfoStore(infoStore *IsoInfoStore) {
552
579
logger .Log .Debugf ("-- not defined" )
553
580
return
554
581
}
555
- logger .Log .Debugf ("-- kernelVersion = %s" , infoStore .kernelVersion )
556
582
logger .Log .Debugf ("-- seLinuxMode = %s" , infoStore .seLinuxMode )
557
583
if infoStore .dracutPackageInfo != nil {
558
584
logger .Log .Debugf ("-- dracut package info = %s" , infoStore .dracutPackageInfo .getFullVersionString ())
0 commit comments