[MIC ISO generation] Allow adding kernel parameters to the LiveOS iso grub.cfg. (#7744)
This commit is contained in:
Родитель
8474fd4bb1
Коммит
9346d073c8
|
@ -240,6 +240,10 @@ The partitions to provision on the disk.
|
|||
|
||||
Specifies the configuration for the generated ISO media.
|
||||
|
||||
### KernelExtraCommandLine [string]
|
||||
|
||||
- See [ExtraCommandLine](#extracommandline-string).
|
||||
|
||||
### AdditionalFiles
|
||||
|
||||
- See [AdditionalFiles](#additionalfiles-mapstring-fileconfig).
|
||||
|
|
|
@ -35,8 +35,64 @@ The current implementation for the LiveOS ISO does not support the following:
|
|||
- disk layout.
|
||||
- There is always one disk generated when an `iso` output format is
|
||||
specified.
|
||||
- SELinux
|
||||
- No SELinux configuration is supported for the generated ISO image.
|
||||
|
||||
## ISO Specific Customizations
|
||||
## ISO Specific Customizations
|
||||
|
||||
- The user can specify one or more files to be copied to the iso media.
|
||||
See MIC's iso configuration [Config.ISO](./configuration.md#iso-type).
|
||||
- The user can specify one or more files to be copied to the iso media.
|
||||
- The user can add kernel parameters.
|
||||
|
||||
For a full list of capabilities, see Mariner Image Customizer's iso
|
||||
configuration section: [Config.ISO](./configuration.md#iso-type).
|
||||
|
||||
## cloud-init Support
|
||||
|
||||
In some user scenarios, it desired to embed the cloud-init data files into the
|
||||
iso media. The easiest way is to include the data files on the media, and then
|
||||
the cloud-init `ds` kernel parameter to where the files are.
|
||||
|
||||
The files can be placed directly within the iso file system or they can be
|
||||
placed within the LiveOS root file system.
|
||||
|
||||
Placing those files directly on the iso file system will allow a more efficient
|
||||
replacement flow in the future (i.e. when it is desired to only replace the
|
||||
cloud-init data files).
|
||||
|
||||
#### Example 1
|
||||
|
||||
If cloud-init data is to be placed directly within the iso file system:
|
||||
|
||||
```yaml
|
||||
Iso:
|
||||
AdditionalFiles:
|
||||
cloud-init-data/user-data: /cloud-init-data/user-data
|
||||
cloud-init-data/network-config: /cloud-init-data/network-config
|
||||
cloud-init-data/meta-data: /cloud-init-data/meta-data
|
||||
KernelCommandLine:
|
||||
ExtraCommandLine: "'ds=nocloud;s=file://run/initramfs/live/cloud-init-data'"
|
||||
SystemConfig:
|
||||
Users:
|
||||
- Name: test
|
||||
Password: testpassword
|
||||
PrimaryGroup: sudo
|
||||
```
|
||||
|
||||
#### Example 2
|
||||
|
||||
If cloud-init data is to be placed within the LiveOS root file system:
|
||||
|
||||
```yaml
|
||||
Iso:
|
||||
KernelCommandLine:
|
||||
ExtraCommandLine: "'ds=nocloud;s=file://cloud-init-data'"
|
||||
SystemConfig:
|
||||
Users:
|
||||
- Name: test
|
||||
Password: testpassword
|
||||
PrimaryGroup: sudo
|
||||
AdditionalFiles:
|
||||
cloud-init-data/user-data: /cloud-init-data/user-data
|
||||
cloud-init-data/network-config: /cloud-init-data/network-config
|
||||
cloud-init-data/meta-data: /cloud-init-data/meta-data
|
||||
```
|
|
@ -9,13 +9,24 @@ import (
|
|||
|
||||
// Iso defines how the generated iso media should be configured.
|
||||
type Iso struct {
|
||||
AdditionalFiles AdditionalFilesMap `yaml:"AdditionalFiles"`
|
||||
KernelCommandLine KernelCommandLine `yaml:"KernelCommandLine"`
|
||||
AdditionalFiles AdditionalFilesMap `yaml:"AdditionalFiles"`
|
||||
}
|
||||
|
||||
func (i *Iso) IsValid() error {
|
||||
err := i.AdditionalFiles.IsValid()
|
||||
var err error
|
||||
|
||||
err = i.KernelCommandLine.IsValid()
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid AdditionalFiles: %w", err)
|
||||
return fmt.Errorf("invalid KernelCommandLine: %w", err)
|
||||
}
|
||||
|
||||
if i.AdditionalFiles != nil {
|
||||
err := i.AdditionalFiles.IsValid()
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid AdditionalFiles: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,16 +3,11 @@
|
|||
|
||||
package imagecustomizerapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type KernelCommandLine struct {
|
||||
// SELinux specifies whether or not to enable SELinux on the image (and what mode SELinux should be in).
|
||||
SELinux SELinux `yaml:"SELinux"`
|
||||
// Extra kernel command line args.
|
||||
ExtraCommandLine string `yaml:"ExtraCommandLine"`
|
||||
ExtraCommandLine KernelExtraArguments `yaml:"ExtraCommandLine"`
|
||||
}
|
||||
|
||||
func (s *KernelCommandLine) IsValid() error {
|
||||
|
@ -21,21 +16,10 @@ func (s *KernelCommandLine) IsValid() error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = commandLineIsValid(s.ExtraCommandLine, "ExtraCommandLine")
|
||||
err = s.ExtraCommandLine.IsValid()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func commandLineIsValid(commandLine string, fieldName string) error {
|
||||
// Disallow special characters to avoid breaking the grub.cfg file.
|
||||
// In addition, disallow the "`" character, since it is used as the sed escape character by
|
||||
// `installutils.setGrubCfgAdditionalCmdLine()`.
|
||||
if strings.ContainsAny(commandLine, "\n'\"\\$`") {
|
||||
return fmt.Errorf("the %s value contains invalid characters", fieldName)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
package imagecustomizerapi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// KernelExtraArguments defines one or more extra kernel arguments.
|
||||
type KernelExtraArguments string
|
||||
|
||||
func (e KernelExtraArguments) IsValid() error {
|
||||
err := validateKernelArgumentsFormat(string(e))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
The following code is based on the 'quoting' section in grub
|
||||
documentation: https://www.gnu.org/software/grub/manual/grub/grub.html#Quoting
|
||||
|
||||
Here is a copy for convenience:
|
||||
|
||||
There are three quoting mechanisms: the escape character, single quotes, and
|
||||
double quotes.
|
||||
|
||||
(1)
|
||||
A non-quoted backslash (\) is the escape character. It preserves the literal
|
||||
value of the next character that follows, with the exception of newline.
|
||||
|
||||
(2)
|
||||
Enclosing characters in single quotes preserves the literal value of each
|
||||
character within the quotes.
|
||||
|
||||
(3)
|
||||
A single quote may not occur between single
|
||||
quotes, even when preceded by a backslash.
|
||||
|
||||
(4)
|
||||
Enclosing characters in double quotes preserves the literal value of all
|
||||
characters within the quotes, with the exception of ‘$’ and ‘\’.
|
||||
|
||||
(5)
|
||||
The ‘$’ character retains its special meaning within double quotes.
|
||||
|
||||
(6)
|
||||
The backslash retains its special meaning only when followed by one of the
|
||||
following characters: ‘$’, ‘"’, ‘\’, or newline. A backslash-newline pair is
|
||||
treated as a line continuation (that is, it is removed from the input stream
|
||||
and effectively ignored.
|
||||
|
||||
(7)
|
||||
A double quote may be quoted within double quotes by preceding it with a
|
||||
backslash.
|
||||
*/
|
||||
|
||||
// if escapedCharacters is empty, it means always escape the next character.
|
||||
// if escapedCharacters is not empty, it means escape only if the next
|
||||
// character is one of escapedCharacters.
|
||||
func processEscapedCharacter(text string, start int, count int, escapedCharacters string) (lastProcessed int, err error) {
|
||||
i := start + 1
|
||||
if i < count {
|
||||
if len(escapedCharacters) == 0 || bytes.IndexByte([]byte(escapedCharacters), text[i]) != -1 {
|
||||
// character is meant to be escaped
|
||||
return i, nil
|
||||
} else {
|
||||
// character is not meant to be escaped
|
||||
// In some cases (see (6) above), the escape charater is not meant
|
||||
// escape the next character - so, we should not remove the next
|
||||
// character from the stream.
|
||||
return start, nil
|
||||
}
|
||||
}
|
||||
return i, fmt.Errorf("missing escaped character. '\\' must be followed by a character.")
|
||||
}
|
||||
|
||||
func processDoubleQuotedString(text string, start int, count int) (lastProcessed int, err error) {
|
||||
i := start + 1
|
||||
for i < count {
|
||||
switch {
|
||||
case text[i] == '\\':
|
||||
i, err = processEscapedCharacter(text, i, count, "$\"\\n")
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
default:
|
||||
if text[i] == '"' {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
i++
|
||||
}
|
||||
return i, fmt.Errorf("invalid double-quoted string. Missing closing double-quotes.")
|
||||
}
|
||||
|
||||
func processSingleQuotedString(text string, start int, count int) (lastProcessed int, err error) {
|
||||
i := start + 1
|
||||
for i < count {
|
||||
if text[i] == '\'' {
|
||||
return i, nil
|
||||
}
|
||||
i++
|
||||
}
|
||||
return i, fmt.Errorf("invalid single-quoted string. Missing closing single-quote.")
|
||||
}
|
||||
|
||||
func validateQuotedSubstrings(kernelArguments string) (err error) {
|
||||
count := len(kernelArguments)
|
||||
for i := 0; i < count; i++ {
|
||||
switch {
|
||||
case kernelArguments[i] == '"':
|
||||
i, err = processDoubleQuotedString(kernelArguments, i, count)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case kernelArguments[i] == '\'':
|
||||
i, err = processSingleQuotedString(kernelArguments, i, count)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case kernelArguments[i] == '\\':
|
||||
i, err = processEscapedCharacter(kernelArguments, i, count, "" /*skip all*/)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateKernelArgumentsFormat(kernelArguments string) (err error) {
|
||||
// Disallow special characters to avoid breaking the grub.cfg file.
|
||||
// In addition, disallow the "`" character, since it is used as the sed
|
||||
// escape character by `installutils.setGrubCfgAdditionalCmdLine()`.
|
||||
if strings.ContainsAny(kernelArguments, "$`") {
|
||||
return fmt.Errorf("the ExtraCommandLine value contains invalid characters")
|
||||
}
|
||||
|
||||
err = validateQuotedSubstrings(kernelArguments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
package imagecustomizerapi
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestKernelExtraArgumentsIsValid(t *testing.T) {
|
||||
/*
|
||||
The following test cases are based on the 'quoting' section in grub
|
||||
documentation: https://www.gnu.org/software/grub/manual/grub/grub.html#Quoting
|
||||
|
||||
Here is a copy for convenience along with section numbers to be associated
|
||||
with test cases:
|
||||
|
||||
There are three quoting mechanisms: the escape character, single quotes, and
|
||||
double quotes.
|
||||
|
||||
(1)
|
||||
A non-quoted backslash (\) is the escape character. It preserves the literal
|
||||
value of the next character that follows, with the exception of newline.
|
||||
|
||||
(2)
|
||||
Enclosing characters in single quotes preserves the literal value of each
|
||||
character within the quotes.
|
||||
|
||||
(3)
|
||||
A single quote may not occur between single
|
||||
quotes, even when preceded by a backslash.
|
||||
|
||||
(4)
|
||||
Enclosing characters in double quotes preserves the literal value of all
|
||||
characters within the quotes, with the exception of ‘$’ and ‘\’.
|
||||
|
||||
(5)
|
||||
The ‘$’ character retains its special meaning within double quotes.
|
||||
|
||||
(6)
|
||||
The backslash retains its special meaning only when followed by one of the
|
||||
following characters: ‘$’, ‘"’, ‘\’, or newline. A backslash-newline pair is
|
||||
treated as a line continuation (that is, it is removed from the input stream
|
||||
and effectively ignored.
|
||||
|
||||
(7)
|
||||
A double quote may be quoted within double quotes by preceding it with a
|
||||
backslash.
|
||||
*/
|
||||
|
||||
missingClosingDoubleQuotes := "invalid double-quoted string. Missing closing double-quotes."
|
||||
missingClosingSingleQuote := "invalid single-quoted string. Missing closing single-quote."
|
||||
|
||||
configsToTest := map[KernelExtraArguments]*string{
|
||||
// very simple cases (no quoting)
|
||||
"": nil,
|
||||
"a": nil,
|
||||
"a=b": nil,
|
||||
"a=b x=y": nil,
|
||||
// enlosed in double quotes (4)
|
||||
"\"a=b\"": nil,
|
||||
// enclosed in single quotes (2)
|
||||
"'a=b'": nil,
|
||||
// single quote embedded within double quotes and vice versa (2)
|
||||
"\"a='b\" 'x=\"y'": nil,
|
||||
// single-quoted string embedded within a double quoted value (4)
|
||||
"\"'a=b' x=y\"": nil,
|
||||
// double-quoted string embedded within a double quoted value (4)(6)(7)
|
||||
"\"a=b \\\"x=y\\\"\"": nil,
|
||||
// \n embedded within a double quoted value (4)(6)
|
||||
"\"a=b x=y\\n\"": nil,
|
||||
// \ embedded within a double quoted value (4)(6)
|
||||
"\"a=b x=y\\\\\"": nil,
|
||||
// unmatched open double-quote - beginning of string (4)
|
||||
"\"a=b x=y": &missingClosingDoubleQuotes,
|
||||
// unmatched open double-quote - middle of string (4)
|
||||
"a=b \"x=y": &missingClosingDoubleQuotes,
|
||||
// unmatched open double-quote - end of string (4)
|
||||
"a=b x=y\"": &missingClosingDoubleQuotes,
|
||||
// unmatched open single-quote - beginning of string (2)
|
||||
"'a=b x=y": &missingClosingSingleQuote,
|
||||
// unmatched open single-quote - middle of string (2)
|
||||
"a=b 'x=y": &missingClosingSingleQuote,
|
||||
// unmatched open single-quote - end of string (2)
|
||||
"a=b x='y": &missingClosingSingleQuote,
|
||||
// attempt to use \ to escape single quotes (3)
|
||||
"'a=\\'b'": &missingClosingSingleQuote,
|
||||
}
|
||||
|
||||
// testsOk := true
|
||||
for config, expectedErr := range configsToTest {
|
||||
err := config.IsValid()
|
||||
if expectedErr == nil {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.Error(t, err)
|
||||
assert.ErrorContains(t, err, *expectedErr)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -42,18 +42,6 @@ func TestSystemConfigIsValidDuplicatePartitionID(t *testing.T) {
|
|||
assert.ErrorContains(t, err, "duplicate PartitionSettings ID")
|
||||
}
|
||||
|
||||
func TestSystemConfigIsValidKernelCommandLineInvalidChars(t *testing.T) {
|
||||
value := SystemConfig{
|
||||
KernelCommandLine: KernelCommandLine{
|
||||
ExtraCommandLine: "example=\"example\"",
|
||||
},
|
||||
}
|
||||
|
||||
err := value.IsValid()
|
||||
assert.Error(t, err)
|
||||
assert.ErrorContains(t, err, "ExtraCommandLine")
|
||||
}
|
||||
|
||||
func TestSystemConfigIsValidVerityInValidPartUuid(t *testing.T) {
|
||||
invalidVerity := SystemConfig{
|
||||
Verity: &Verity{
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/microsoft/CBL-Mariner/toolkit/tools/imagecustomizerapi"
|
||||
"github.com/microsoft/CBL-Mariner/toolkit/tools/imagegen/installutils"
|
||||
|
@ -47,7 +48,7 @@ const (
|
|||
selinuxConfigModeRegexSELinuxMode = 1
|
||||
)
|
||||
|
||||
func handleKernelCommandLine(extraCommandLine string, imageChroot *safechroot.Chroot, partitionsCustomized bool) error {
|
||||
func handleKernelCommandLine(kernelExtraArguments imagecustomizerapi.KernelExtraArguments, imageChroot *safechroot.Chroot, partitionsCustomized bool) error {
|
||||
var err error
|
||||
|
||||
if partitionsCustomized {
|
||||
|
@ -56,6 +57,7 @@ func handleKernelCommandLine(extraCommandLine string, imageChroot *safechroot.Ch
|
|||
return nil
|
||||
}
|
||||
|
||||
extraCommandLine := strings.TrimSpace(string(kernelExtraArguments))
|
||||
if extraCommandLine == "" {
|
||||
// Nothing to do.
|
||||
return nil
|
||||
|
|
|
@ -250,11 +250,23 @@ func validateIsoConfig(baseConfigPath string, config *imagecustomizerapi.Iso) er
|
|||
return nil
|
||||
}
|
||||
|
||||
err := validateAdditionalFiles(baseConfigPath, config.AdditionalFiles)
|
||||
err := validateIsoKernelCommandline(config.KernelCommandLine)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = validateAdditionalFiles(baseConfigPath, config.AdditionalFiles)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateIsoKernelCommandline(kernelCommandLine imagecustomizerapi.KernelCommandLine) error {
|
||||
if kernelCommandLine.SELinux != imagecustomizerapi.SELinuxDefault {
|
||||
return fmt.Errorf("unsupported SELinux configuration for the output ISO image.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/microsoft/CBL-Mariner/toolkit/tools/imagecustomizerapi"
|
||||
"github.com/microsoft/CBL-Mariner/toolkit/tools/imagegen/configuration"
|
||||
|
@ -26,6 +27,7 @@ menuentry "Mariner Baremetal Iso" {
|
|||
|
||||
search --label CDROM --set root
|
||||
linux /isolinux/vmlinuz \
|
||||
%s \
|
||||
overlay-size=70%% \
|
||||
selinux=0 \
|
||||
console=tty0 \
|
||||
|
@ -41,6 +43,7 @@ menuentry "Mariner Baremetal Iso" {
|
|||
initrd /isolinux/initrd.img
|
||||
}
|
||||
`
|
||||
|
||||
liveOSDir = "liveos"
|
||||
liveOSImage = "rootfs.img"
|
||||
|
||||
|
@ -261,11 +264,13 @@ func (b *LiveOSIsoBuilder) prepareRootfsForDracut(writeableRootfsDir string) err
|
|||
// The folder where the artifacts needed by isoMaker will be staged before
|
||||
// 'dracut' is run. 'dracut' will include this folder as-is and place it in
|
||||
// the initrd image.
|
||||
// - 'extraCommandLine':
|
||||
// extra kernel command line arguments to add to grub.
|
||||
//
|
||||
// outputs
|
||||
// - customized writeableRootfsDir (new files, deleted files, etc)
|
||||
// - extracted artifacts
|
||||
func (b *LiveOSIsoBuilder) prepareLiveOSDir(writeableRootfsDir, isoMakerArtifactsStagingDir string) error {
|
||||
func (b *LiveOSIsoBuilder) prepareLiveOSDir(writeableRootfsDir string, isoMakerArtifactsStagingDir string, extraCommandLine string) error {
|
||||
|
||||
logger.Log.Debugf("Creating LiveOS squashfs image")
|
||||
|
||||
|
@ -296,7 +301,7 @@ func (b *LiveOSIsoBuilder) prepareLiveOSDir(writeableRootfsDir, isoMakerArtifact
|
|||
b.artifacts.vmlinuzPath = targetVmLinuzPath
|
||||
|
||||
// create grub.cfg
|
||||
targetGrubCfgContent := fmt.Sprintf(grubCfgTemplate, liveOSDir, liveOSImage)
|
||||
targetGrubCfgContent := fmt.Sprintf(grubCfgTemplate, extraCommandLine, liveOSDir, liveOSImage)
|
||||
targetGrubCfgPath := filepath.Join(b.workingDirs.isoArtifactsDir, "grub.cfg")
|
||||
|
||||
err = os.WriteFile(targetGrubCfgPath, []byte(targetGrubCfgContent), 0o644)
|
||||
|
@ -422,13 +427,15 @@ func (b *LiveOSIsoBuilder) generateInitrdImage(rootfsSourceDir, artifactsSourceD
|
|||
// - 'rawImageFile':
|
||||
// path to an existing raw full disk image (i.e. image with boot
|
||||
// partition and a rootfs partition).
|
||||
// - 'extraCommandLine':
|
||||
// extra kernel command line arguments to add to grub.
|
||||
//
|
||||
// outputs:
|
||||
// - all the extracted/generated artifacts will be placed in the
|
||||
// `LiveOSIsoBuilder.workingDirs.isoArtifactsDir` folder.
|
||||
// - the paths to individual artifaces are found in the
|
||||
// `LiveOSIsoBuilder.artifacts` data structure.
|
||||
func (b *LiveOSIsoBuilder) prepareArtifactsFromFullImage(rawImageFile string) error {
|
||||
func (b *LiveOSIsoBuilder) prepareArtifactsFromFullImage(rawImageFile string, extraCommandLine string) error {
|
||||
|
||||
logger.Log.Infof("Preparing iso artifacts")
|
||||
|
||||
|
@ -451,7 +458,7 @@ func (b *LiveOSIsoBuilder) prepareArtifactsFromFullImage(rawImageFile string) er
|
|||
}
|
||||
|
||||
isoMakerArtifactsStagingDir := "/boot-staging"
|
||||
err = b.prepareLiveOSDir(writeableRootfsDir, isoMakerArtifactsStagingDir)
|
||||
err = b.prepareLiveOSDir(writeableRootfsDir, isoMakerArtifactsStagingDir, extraCommandLine)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert rootfs folder to a LiveOS folder:\n%w", err)
|
||||
}
|
||||
|
@ -572,7 +579,9 @@ func (b *LiveOSIsoBuilder) createIsoImage(additionalIsoFiles []safechroot.FileTo
|
|||
// outputs:
|
||||
// - 'additionalIsoFiles'
|
||||
// list of files to copy from the build machine to the iso media.
|
||||
func micIsoConfigToIsoMakerConfig(baseConfigPath string, isoConfig *imagecustomizerapi.Iso) (additionalIsoFiles []safechroot.FileToCopy, err error) {
|
||||
func micIsoConfigToIsoMakerConfig(baseConfigPath string, isoConfig *imagecustomizerapi.Iso) (additionalIsoFiles []safechroot.FileToCopy, extraCommandLine string, err error) {
|
||||
|
||||
extraCommandLine = strings.TrimSpace(string(isoConfig.KernelCommandLine.ExtraCommandLine))
|
||||
|
||||
additionalIsoFiles = []safechroot.FileToCopy{}
|
||||
|
||||
|
@ -588,7 +597,7 @@ func micIsoConfigToIsoMakerConfig(baseConfigPath string, isoConfig *imagecustomi
|
|||
}
|
||||
}
|
||||
|
||||
return additionalIsoFiles, nil
|
||||
return additionalIsoFiles, extraCommandLine, nil
|
||||
}
|
||||
|
||||
// createLiveOSIsoImage
|
||||
|
@ -618,7 +627,7 @@ func micIsoConfigToIsoMakerConfig(baseConfigPath string, isoConfig *imagecustomi
|
|||
// creates a LiveOS ISO image.
|
||||
func createLiveOSIsoImage(buildDir, baseConfigPath string, isoConfig *imagecustomizerapi.Iso, rawImageFile, outputImageDir, outputImageBase string) (err error) {
|
||||
|
||||
additionalIsoFiles, err := micIsoConfigToIsoMakerConfig(baseConfigPath, isoConfig)
|
||||
additionalIsoFiles, extraCommandLine, err := micIsoConfigToIsoMakerConfig(baseConfigPath, isoConfig)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to convert iso configuration to isomaker format:\n%w", err)
|
||||
}
|
||||
|
@ -651,7 +660,7 @@ func createLiveOSIsoImage(buildDir, baseConfigPath string, isoConfig *imagecusto
|
|||
}
|
||||
}()
|
||||
|
||||
err = isoBuilder.prepareArtifactsFromFullImage(rawImageFile)
|
||||
err = isoBuilder.prepareArtifactsFromFullImage(rawImageFile, extraCommandLine)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ func kernelCommandLineToImager(kernelCommandLine imagecustomizerapi.KernelComman
|
|||
}
|
||||
|
||||
imagerKernelCommandLine := configuration.KernelCommandLine{
|
||||
ExtraCommandLine: kernelCommandLine.ExtraCommandLine,
|
||||
ExtraCommandLine: string(kernelCommandLine.ExtraCommandLine),
|
||||
SELinux: imagerSELinux,
|
||||
SELinuxPolicy: "",
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче