Skip to content

Commit

Permalink
Merge branch 'main' of github.com:microsoft/azure-linux-image-tools i…
Browse files Browse the repository at this point in the history
…nto user/elaine/cosi
  • Loading branch information
elainezhao96 committed Dec 20, 2024
2 parents b7a02bb + 11ad05f commit 74f929d
Show file tree
Hide file tree
Showing 34 changed files with 516 additions and 127 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/github-pages-publishing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: update GitHub pages

on:
push:
branches: ["main"]
branches: ["stable"]
workflow_dispatch:

permissions:
Expand All @@ -22,6 +22,8 @@ jobs:
steps:
- name: checkout
uses: actions/checkout@v4
with:
ref: stable

- name: setup pages
uses: actions/configure-pages@v5
Expand Down
29 changes: 16 additions & 13 deletions docs/imagecustomizer/api/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,42 +43,44 @@ The top level type for the YAML file is the [config](./configuration/config.md)

10. Write the `/etc/image-customizer-release` file.

11. If the bootloader [resetType](./configuration/bootloader.md#resettype-string) is set
11. Write the image history file.

12. If the bootloader [resetType](./configuration/bootloader.md#resettype-string) is set
to `hard-reset`, then reset the boot-loader.

If the bootloader [resetType](./configuration/bootloader.md#resettype-string) is not
set, then append the
[extraCommandLine](./configuration/kernelcommandline.md#extracommandline-string)
value to the existing `grub.cfg` file.

12. Update the SELinux mode. [mode](./configuration/selinux.md#mode-string)
13. Update the SELinux mode. [mode](./configuration/selinux.md#mode-string)

13. If ([overlays](./configuration/os.md#overlays-overlay)) are specified, then add the
14. If ([overlays](./configuration/os.md#overlays-overlay)) are specified, then add the
overlay driver and update the fstab file with the overlay mount information.

14. If a ([verity](./configuration/storage.md#verity-verity)) device is specified, then
15. If a ([verity](./configuration/storage.md#verity-verity)) device is specified, then
add the dm-verity dracut driver and update the grub config.

15. Regenerate the initramfs file (if needed).
16. Regenerate the initramfs file (if needed).

16. Run ([postCustomization](./configuration/scripts.md#postcustomization-script)) scripts.
17. Run ([postCustomization](./configuration/scripts.md#postcustomization-script)) scripts.

17. Restore the `/etc/resolv.conf` file.
18. Restore the `/etc/resolv.conf` file.

18. If SELinux is enabled, call `setfiles`.
19. If SELinux is enabled, call `setfiles`.

19. Run finalize image scripts. ([finalizeCustomization](./configuration/scripts.md#finalizecustomization-script))
20. Run finalize image scripts. ([finalizeCustomization](./configuration/scripts.md#finalizecustomization-script))

20. If [--shrink-filesystems](./cli.md#shrink-filesystems) is specified, then shrink
21. If [--shrink-filesystems](./cli.md#shrink-filesystems) is specified, then shrink
the file systems.

21. If a ([verity](./configuration/storage.md#verity-verity)) device is specified, then
22. If a ([verity](./configuration/storage.md#verity-verity)) device is specified, then
create the hash tree and update the grub config.

22. If the output format is set to `iso`, copy additional iso media files.
23. If the output format is set to `iso`, copy additional iso media files.
([iso](./configuration/iso.md))

23. If [--output-pxe-artifacts-dir](./cli.md#output-pxe-artifacts-dir) is specified,
24. If [--output-pxe-artifacts-dir](./cli.md#output-pxe-artifacts-dir) is specified,
then export the ISO image contents to the specified folder.

## /etc/resolv.conf
Expand Down Expand Up @@ -206,6 +208,7 @@ os:
- [overlays](./configuration/os.md#overlays-overlay) ([overlay type](./configuration/overlay.md))
- [uki](./configuration/os.md#uki-uki) ([uki type](./configuration/uki.md))
- [kernels](./configuration/uki.md#kernels)
- [imageHistory](./configuration/imagehistory.md)
- [scripts](./configuration/config.md#scripts-scripts) ([scripts type](./configuration/scripts.md))
- [postCustomization](./configuration/scripts.md#postcustomization-script) ([script type](./configuration/script.md))
- [path](./configuration/script.md#script-path)
Expand Down
11 changes: 11 additions & 0 deletions docs/imagecustomizer/api/configuration/os.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,14 @@ os:
enable:
- sshd
```
## imageHistory [string]
Options for configuring image history.
Set value to `none` to disable.

```yaml
os:
imageHistory: none
```
12 changes: 3 additions & 9 deletions toolkit/tools/imagecustomizer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/microsoft/azurelinux/toolkit/tools/internal/logger"
"github.com/microsoft/azurelinux/toolkit/tools/internal/timestamp"
"github.com/microsoft/azurelinux/toolkit/tools/pkg/imagecustomizerlib"
"github.com/microsoft/azurelinux/toolkit/tools/pkg/profile"
"gopkg.in/alecthomas/kingpin.v2"
)

Expand All @@ -29,7 +28,6 @@ var (
enableShrinkFilesystems = app.Flag("shrink-filesystems", "Enable shrinking of filesystems to minimum size. Supports ext2, ext3, ext4 filesystem types.").Bool()
outputPXEArtifactsDir = app.Flag("output-pxe-artifacts-dir", "Create a directory with customized image PXE booting artifacts. '--output-image-format' must be set to 'iso'.").String()
logFlags = exe.SetupLogFlags(app)
profFlags = exe.SetupProfileFlags(app)
timestampFile = app.Flag("timestamp-file", "File that stores timestamps for this program.").String()
)

Expand All @@ -52,14 +50,10 @@ func main() {
logger.Log.Fatalf("--output-image-format cannot be used with --shrink-filesystems enabled.")
}

prof, err := profile.StartProfiling(profFlags)
if err != nil {
logger.Log.Warnf("Could not start profiling: %s", err)
if *timestampFile != "" {
timestamp.BeginTiming("imagecustomizer", *timestampFile)
defer timestamp.CompleteTiming()
}
defer prof.StopProfiler()

timestamp.BeginTiming("imagecustomizer", *timestampFile)
defer timestamp.CompleteTiming()

err = customizeImage()
if err != nil {
Expand Down
10 changes: 6 additions & 4 deletions toolkit/tools/imagecustomizerapi/additionalfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,20 @@ type AdditionalFileList []AdditionalFile

type AdditionalFile struct {
// The destination file path in the target OS that the file will be copied to.
Destination string `yaml:"destination"`
Destination string `yaml:"destination" json:"destination,omitempty"`

// The source file path of the file that will copied.
// Mutally exclusive with 'contents'.
Source string `yaml:"source"`
Source string `yaml:"source" json:"source,omitempty"`

// A string that will be used as the contents of the file.
// Mutally exclusive with 'source'.
Content *string `yaml:"content"`
Content *string `yaml:"content" json:"content,omitempty"`

// The file permissions to set on the file.
Permissions *FilePermissions `yaml:"permissions"`
Permissions *FilePermissions `yaml:"permissions" json:"permissions,omitempty"`

SHA256Hash string `json:"sha256hash,omitempty"`
}

func (l AdditionalFileList) IsValid() (err error) {
Expand Down
2 changes: 1 addition & 1 deletion toolkit/tools/imagecustomizerapi/bootloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

type BootLoader struct {
ResetType ResetBootLoaderType `yaml:"resetType"`
ResetType ResetBootLoaderType `yaml:"resetType" json:"resetType,omitempty"`
}

func (b *BootLoader) IsValid() error {
Expand Down
12 changes: 6 additions & 6 deletions toolkit/tools/imagecustomizerapi/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import (
)

type Config struct {
Storage Storage `yaml:"storage"`
Iso *Iso `yaml:"iso"`
Pxe *Pxe `yaml:"pxe"`
OS *OS `yaml:"os"`
Scripts Scripts `yaml:"scripts"`
PreviewFeatures []string `yaml:"previewFeatures"`
Storage Storage `yaml:"storage" json:"storage,omitempty"`
Iso *Iso `yaml:"iso" json:"iso,omitempty"`
Pxe *Pxe `yaml:"pxe" json:"pxe,omitempty"`
OS *OS `yaml:"os" json:"os,omitempty"`
Scripts Scripts `yaml:"scripts" json:"scripts,omitempty"`
PreviewFeatures []string `yaml:"previewFeatures" json:"previewFeatures,omitempty"`
}

func (c *Config) IsValid() (err error) {
Expand Down
12 changes: 7 additions & 5 deletions toolkit/tools/imagecustomizerapi/dirconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,24 @@ type DirConfigList []DirConfig

type DirConfig struct {
// The path to the source directory that will be copied (can be relative or absolute path).
Source string `yaml:"source"`
Source string `yaml:"source" json:"source,omitempty"`

// The absolute path in the target OS that the directory will be copied to.
Destination string `yaml:"destination"`
Destination string `yaml:"destination" json:"destination,omitempty"`

// The permissions to set on all of the new directories being created on the target OS (including the top-level directory).
// Note: If this value is not specified in the config, the permissions for these directories will be set to 0755.
NewDirPermissions *FilePermissions `yaml:"newDirPermissions"`
NewDirPermissions *FilePermissions `yaml:"newDirPermissions" json:"newDirPermissions,omitempty"`

// The permissions to set on the directories being copied that already do exist on the target OS (including the top-level directory).
// Note: If this value is not specified in the config, the permissions for this field will be the same as that of the pre-existing directory.
MergedDirPermissions *FilePermissions `yaml:"mergedDirPermissions"`
MergedDirPermissions *FilePermissions `yaml:"mergedDirPermissions" json:"mergedDirPermissions,omitempty"`

// The permissions to set on the children file of the directory.
// Note: If this value is not specified in the config, the permissions for these directories will be set to 0755.
ChildFilePermissions *FilePermissions `yaml:"childFilePermissions"`
ChildFilePermissions *FilePermissions `yaml:"childFilePermissions" json:"childFilePermissions,omitempty"`

SHA256HashMap map[string]string `json:"sha256hashmap,omitempty"`
}

func (l *DirConfigList) IsValid() (err error) {
Expand Down
6 changes: 3 additions & 3 deletions toolkit/tools/imagecustomizerapi/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ const (

type Disk struct {
// The type of partition table to use (e.g. mbr, gpt)
PartitionTableType PartitionTableType `yaml:"partitionTableType"`
PartitionTableType PartitionTableType `yaml:"partitionTableType" json:"partitionTableType,omitempty"`

// The virtual size of the disk.
// Note: This value is filled in by IsValid().
MaxSize *DiskSize `yaml:"maxSize"`
MaxSize *DiskSize `yaml:"maxSize" json:"maxSize,omitempty"`

// The partitions to allocate on the disk.
Partitions []Partition `yaml:"partitions"`
Partitions []Partition `yaml:"partitions" json:"partitions,omitempty"`
}

func (d *Disk) IsValid() error {
Expand Down
38 changes: 38 additions & 0 deletions toolkit/tools/imagecustomizerapi/disksize.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package imagecustomizerapi

import (
"encoding/json"
"fmt"
"regexp"
"strconv"
Expand Down Expand Up @@ -31,6 +32,26 @@ func (s *DiskSize) UnmarshalYAML(value *yaml.Node) error {
return fmt.Errorf("failed to parse disk size:\n%w", err)
}

return parseAndSetDiskSize(stringValue, s)
}

func (s DiskSize) MarshalJSON() ([]byte, error) {
return json.Marshal(s.String())
}

func (s *DiskSize) UnmarshalJSON(data []byte) error {
var err error

var stringValue string
err = json.Unmarshal(data, &stringValue)
if err != nil {
return fmt.Errorf("failed to parse disk size:\n%w", err)
}

return parseAndSetDiskSize(stringValue, s)
}

func parseAndSetDiskSize(stringValue string, s *DiskSize) error {
diskSize, err := parseDiskSize(stringValue)
if err != nil {
return fmt.Errorf("%w:\nexpected format: <NUM>(K|M|G|T) (e.g. 100M, 1G)", err)
Expand Down Expand Up @@ -98,3 +119,20 @@ func parseDiskSize(diskSizeString string) (DiskSize, error) {

return DiskSize(num), nil
}

// String returns the string representation of DiskSize in the most appropriate unit
// such that it matches the input format.
func (s DiskSize) String() string {
switch {
case s%diskutils.TiB == 0:
return fmt.Sprintf("%dT", s/diskutils.TiB)
case s%diskutils.GiB == 0:
return fmt.Sprintf("%dG", s/diskutils.GiB)
case s%diskutils.MiB == 0:
return fmt.Sprintf("%dM", s/diskutils.MiB)
case s%diskutils.KiB == 0:
return fmt.Sprintf("%dK", s/diskutils.KiB)
default:
return fmt.Sprintf("%d", s)
}
}
8 changes: 4 additions & 4 deletions toolkit/tools/imagecustomizerapi/filesystem.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import (
// FileSystem holds the file system information for a partition.
type FileSystem struct {
// DeviceId is the ID of the source partition.
DeviceId string `yaml:"deviceId"`
DeviceId string `yaml:"deviceId" json:"deviceId,omitempty"`
// FileSystemType is the type of file system to use on the partition.
Type FileSystemType `yaml:"type"`
Type FileSystemType `yaml:"type" json:"type,omitempty"`
// MountPoint contains the mount settings.
MountPoint *MountPoint `yaml:"mountPoint"`
MountPoint *MountPoint `yaml:"mountPoint" json:"mountPoint,omitempty"`

// If 'DeviceId' points at a verity device, this value is the 'Id' of the data partition.
// Otherwise, it is the same as 'DeviceId'.
// Value is filled in by Storage.IsValid().
PartitionId string
PartitionId string `json:"-"`
}

// IsValid returns an error if the MountPoint is not valid
Expand Down
26 changes: 26 additions & 0 deletions toolkit/tools/imagecustomizerapi/imagehistory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

package imagecustomizerapi

import (
"fmt"
)

type ImageHistory string

const (
ImageHistoryDefault ImageHistory = ""
ImageHistoryNone ImageHistory = "none"
)

func (t ImageHistory) IsValid() error {
switch t {
case ImageHistoryDefault, ImageHistoryNone:
// All good.
return nil

default:
return fmt.Errorf("invalid imageHistory value (%s)", t)
}
}
20 changes: 20 additions & 0 deletions toolkit/tools/imagecustomizerapi/imagehistory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

package imagecustomizerapi

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestImageHistoryIsValidValid(t *testing.T) {
err := ImageHistoryNone.IsValid()
assert.NoError(t, err)
}

func TestImageHistoryIsValidInvalid(t *testing.T) {
err := ImageHistory("aaa").IsValid()
assert.ErrorContains(t, err, "invalid imageHistory value (aaa)")
}
4 changes: 2 additions & 2 deletions toolkit/tools/imagecustomizerapi/iso.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import (

// Iso defines how the generated iso media should be configured.
type Iso struct {
KernelCommandLine KernelCommandLine `yaml:"kernelCommandLine"`
AdditionalFiles AdditionalFileList `yaml:"additionalFiles"`
KernelCommandLine KernelCommandLine `yaml:"kernelCommandLine" json:"kernelCommandLine,omitempty"`
AdditionalFiles AdditionalFileList `yaml:"additionalFiles" json:"additionalFiles,omitempty"`
}

func (i *Iso) IsValid() error {
Expand Down
2 changes: 1 addition & 1 deletion toolkit/tools/imagecustomizerapi/kernelcommandline.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

type KernelCommandLine struct {
// Extra kernel command line args.
ExtraCommandLine []string `yaml:"extraCommandLine"`
ExtraCommandLine []string `yaml:"extraCommandLine" json:"extraCommandLine,omitempty"`
}

func (k *KernelCommandLine) IsValid() error {
Expand Down
6 changes: 3 additions & 3 deletions toolkit/tools/imagecustomizerapi/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
)

type Module struct {
Name string `yaml:"name"`
LoadMode ModuleLoadMode `yaml:"loadMode"`
Options map[string]string `yaml:"options"`
Name string `yaml:"name" json:"name,omitempty"`
LoadMode ModuleLoadMode `yaml:"loadMode" json:"loadMode,omitempty"`
Options map[string]string `yaml:"options" json:"options,omitempty"`
}

type ModuleList []Module
Expand Down
Loading

0 comments on commit 74f929d

Please sign in to comment.