Skip to content

Commit 075ee91

Browse files
committed
feat: extend image metadata
Extend config file so images can self-report capabilities as well as publishing channels.
1 parent 344e4e9 commit 075ee91

File tree

7 files changed

+287
-49
lines changed

7 files changed

+287
-49
lines changed

docs/user/reference/config/images.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ The `[images]` section defines system images (VMs, containers, etc.) that azldev
88
|-------|----------|------|----------|-------------|
99
| Description | `description` | string | No | Human-readable description of the image |
1010
| Definition | `definition` | [ImageDefinition](#image-definition) | No | Specifies the image definition format, file path, and optional profile |
11+
| Publish | `publish` | [ImagePublishConfig](#image-publish-config) | No | Publishing settings for this image |
12+
| Capabilities | `capabilities` | [ImageCapabilities](#image-capabilities) | No | Self-reported runtime capabilities of this image |
1113

1214
## Image Definition
1315

@@ -19,6 +21,31 @@ The `definition` field tells azldev where to find the image definition file and
1921
| Path | `path` | string | No | Path to the image definition file, relative to the config file |
2022
| Profile | `profile` | string | No | Build profile to use when building the image (format-specific) |
2123

24+
## Image Publish Config
25+
26+
The `publish` field controls which channels the image is published to.
27+
28+
| Field | TOML Key | Type | Required | Description |
29+
|-------|----------|------|----------|-------------|
30+
| Channels | `channels` | array of string | No | List of publish channels for this image. An empty list means the image is not published. |
31+
32+
## Image Capabilities
33+
34+
The `capabilities` field lets an image self-report its runtime capabilities. This informs consumers about supported deployment and runtime scenarios.
35+
36+
| Field | TOML Key | Type | Required | Description |
37+
|-------|----------|------|----------|-------------|
38+
| SupportedHosts | `supported-hosts` | array of [SupportedHost](#supported-host-values) | No | Host types on which this image can be deployed or run |
39+
| RuntimePackageManagement | `runtime-package-management` | bool | No | Image supports runtime package management (e.g., `tdnf install` after first boot) |
40+
41+
### Supported Host Values
42+
43+
| Value | Description |
44+
|-------|-------------|
45+
| `azure-vm-gen1` | Image can be booted in a Generation 1 Azure VM |
46+
| `azure-vm-gen2` | Image can be booted in a Generation 2 Azure VM |
47+
| `oci-container` | Image can be run in an OCI-compliant container host |
48+
2249
> **Note:** Each image name must be unique across all config files. Defining the same image name in two files produces an error.
2350
2451
## Examples
@@ -47,6 +74,32 @@ description = "Azure-optimized VM image"
4774
definition = { type = "kiwi", path = "vm-azure/vm-azure.kiwi", profile = "azure" }
4875
```
4976

77+
### Azure VM image with publish channels and capabilities
78+
79+
```toml
80+
[images.vm-azure-gen2]
81+
description = "Azure Gen2 VM image"
82+
definition = { type = "kiwi", path = "vm-azure/vm-azure.kiwi", profile = "azure-gen2" }
83+
84+
[images.vm-azure-gen2.publish]
85+
channels = ["vm-release", "vm-preview"]
86+
87+
[images.vm-azure-gen2.capabilities]
88+
supported-hosts = ["azure-vm-gen2"]
89+
runtime-package-management = true
90+
```
91+
92+
### Container image with OCI capability
93+
94+
```toml
95+
[images.container-base]
96+
description = "Container base image"
97+
definition = { type = "kiwi", path = "container/container.kiwi" }
98+
99+
[images.container-base.capabilities]
100+
supported-hosts = ["oci-container"]
101+
```
102+
50103
## Related Resources
51104

52105
- [Config File Structure](config-file.md) — top-level config file layout

internal/projectconfig/configfile.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,15 @@ type ConfigFile struct {
3434
// Definitions of distros.
3535
Distros map[string]DistroDefinition `toml:"distros,omitempty" jsonschema:"title=Distros,description=Definitions of distros to build for or consume from"`
3636

37+
// Definitions of components.
38+
Components map[string]ComponentConfig `toml:"components,omitempty" validate:"dive" jsonschema:"title=Components,description=Definitions of components for this project"`
39+
3740
// Definitions of component groups.
3841
ComponentGroups map[string]ComponentGroupConfig `toml:"component-groups,omitempty" validate:"dive" jsonschema:"title=Component groups,description=Definitions of component groups for this project"`
3942

40-
// Definitions of components.
41-
Components map[string]ComponentConfig `toml:"components,omitempty" validate:"dive" jsonschema:"title=Components,description=Definitions of components for this project"`
43+
// Definitions of package groups. Groups allow shared configuration
44+
// to be applied to sets of binary packages.
45+
PackageGroups map[string]PackageGroupConfig `toml:"package-groups,omitempty" validate:"dive" jsonschema:"title=Package groups,description=Definitions of package groups for shared binary package configuration"`
4246

4347
// Definitions of images.
4448
Images map[string]ImageConfig `toml:"images,omitempty" validate:"dive" jsonschema:"title=Images,description=Definitions of images for this project"`
@@ -50,10 +54,6 @@ type ConfigFile struct {
5054
// package-group or component-level config is considered.
5155
DefaultPackageConfig *PackageConfig `toml:"default-package-config,omitempty" jsonschema:"title=Default package config,description=Project-wide default applied to all binary packages before group and component overrides"`
5256

53-
// Definitions of package groups. Groups allow shared configuration
54-
// to be applied to sets of binary packages.
55-
PackageGroups map[string]PackageGroupConfig `toml:"package-groups,omitempty" validate:"dive" jsonschema:"title=Package groups,description=Definitions of package groups for shared binary package configuration"`
56-
5757
// Internal fields used to track the origin of the config file; `dir` is the directory
5858
// that the config file's relative paths are based from.
5959
sourcePath string `toml:"-"`

internal/projectconfig/image.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,46 @@ type ImageConfig struct {
2424

2525
// Where to find its definition.
2626
Definition ImageDefinition `toml:"definition,omitempty" json:"definition,omitempty" jsonschema:"title=Definition,description=Identifies where to find the definition for this image"`
27+
28+
// Publish holds publishing settings for this image.
29+
Publish ImagePublishConfig `toml:"publish,omitempty" json:"publish,omitempty" jsonschema:"title=Publish settings,description=Publishing settings for this image"`
30+
31+
// Capabilities describes the runtime capabilities of this image.
32+
Capabilities ImageCapabilities `toml:"capabilities,omitempty" json:"capabilities,omitempty" jsonschema:"title=Capabilities,description=Runtime capabilities of this image"`
33+
34+
}
35+
36+
// ImagePublishConfig holds publishing settings for an image.
37+
// Unlike binary packages (which publish to a single channel), images may be
38+
// published to multiple channels simultaneously.
39+
type ImagePublishConfig struct {
40+
// Channels is the list of publish channels for this image.
41+
// An empty list means the image is not published to any channel.
42+
Channels []string `toml:"channels,omitempty" json:"channels,omitempty" jsonschema:"title=Channels,description=List of publish channels for this image"`
43+
}
44+
45+
// SupportedHost identifies a type of host on which an image can be deployed or run.
46+
type SupportedHost string
47+
48+
const (
49+
// SupportedHostAzureVMGen1 indicates the image can be booted in a Generation 1 Azure VM.
50+
SupportedHostAzureVMGen1 SupportedHost = "azure-vm-gen1"
51+
// SupportedHostAzureVMGen2 indicates the image can be booted in a Generation 2 Azure VM.
52+
SupportedHostAzureVMGen2 SupportedHost = "azure-vm-gen2"
53+
// SupportedHostOCIContainer indicates the image can be run in an OCI-compliant container host.
54+
SupportedHostOCIContainer SupportedHost = "oci-container"
55+
)
56+
57+
// ImageCapabilities describes the runtime capabilities of an image.
58+
// Capabilities are self-reported by the image definition and inform consumers
59+
// about supported deployment and runtime scenarios.
60+
type ImageCapabilities struct {
61+
// SupportedHosts lists the host types on which this image can be deployed or run.
62+
SupportedHosts []SupportedHost `toml:"supported-hosts,omitempty" json:"supportedHosts,omitempty" jsonschema:"title=Supported hosts,description=Host types on which this image can be deployed or run,enum=azure-vm-gen1,enum=azure-vm-gen2,enum=oci-container"`
63+
64+
// RuntimePackageManagement indicates the image supports runtime package management
65+
// (e.g., installing or removing packages after first boot).
66+
RuntimePackageManagement bool `toml:"runtime-package-management,omitempty" json:"runtimePackageManagement,omitempty" jsonschema:"title=Runtime package management,description=Image supports runtime package management (e.g. tdnf install at runtime)"`
2767
}
2868

2969
// Defines where to find an image definition.
@@ -69,6 +109,8 @@ func (i *ImageConfig) WithAbsolutePaths(referenceDir string) *ImageConfig {
69109
Description: i.Description,
70110
SourceConfigFile: i.SourceConfigFile,
71111
Definition: deep.MustCopy(i.Definition),
112+
Publish: deep.MustCopy(i.Publish),
113+
Capabilities: deep.MustCopy(i.Capabilities),
72114
}
73115

74116
// Fix up paths.

internal/projectconfig/project.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ import (
1515
type ProjectConfig struct {
1616
// Basic project info.
1717
Project ProjectInfo `toml:"project,omitempty" json:"project,omitempty" jsonschema:"title=Project Info,description=Basic project information"`
18-
// Definitions of component groups.
19-
ComponentGroups map[string]ComponentGroupConfig `toml:"component-groups,omitempty" json:"componentGroups,omitempty" jsonschema:"title=Component Groups,description=Mapping of component group names to configurations"`
18+
// Definitions of distros.
19+
Distros map[string]DistroDefinition `toml:"distros,omitempty" json:"distros,omitempty" jsonschema:"title=Distros,description=Mapping of distro names to their definitions"`
2020
// Definitions of components.
2121
Components map[string]ComponentConfig `toml:"components,omitempty" json:"components,omitempty" jsonschema:"title=Components,description=Mapping of component names to configurations"`
2222
// Definitions of images.
2323
Images map[string]ImageConfig `toml:"images,omitempty" json:"images,omitempty" jsonschema:"title=Images,description=Mapping of image names to configurations"`
24-
// Definitions of distros.
25-
Distros map[string]DistroDefinition `toml:"distros,omitempty" json:"distros,omitempty" jsonschema:"title=Distros,description=Mapping of distro names to their definitions"`
24+
// Definitions of component groups.
25+
ComponentGroups map[string]ComponentGroupConfig `toml:"component-groups,omitempty" json:"componentGroups,omitempty" jsonschema:"title=Component Groups,description=Mapping of component group names to configurations"`
26+
// Definitions of package groups with shared configuration.
27+
PackageGroups map[string]PackageGroupConfig `toml:"package-groups,omitempty" json:"packageGroups,omitempty" jsonschema:"title=Package groups,description=Mapping of package group names to configurations for publish-time routing"`
2628
// Configuration for tools used by azldev.
2729
Tools ToolsConfig `toml:"tools,omitempty" json:"tools,omitempty" jsonschema:"title=Tools configuration,description=Configuration for tools used by azldev"`
2830

@@ -31,9 +33,6 @@ type ProjectConfig struct {
3133
// package config resolution order.
3234
DefaultPackageConfig PackageConfig `toml:"default-package-config,omitempty" json:"defaultPackageConfig,omitempty" jsonschema:"title=Default package config,description=Project-wide default applied to all binary packages before group and component overrides"`
3335

34-
// Definitions of package groups with shared configuration.
35-
PackageGroups map[string]PackageGroupConfig `toml:"package-groups,omitempty" json:"packageGroups,omitempty" jsonschema:"title=Package groups,description=Mapping of package group names to configurations for publish-time routing"`
36-
3736
// Root config file path; not serialized.
3837
RootConfigFilePath string `toml:"-" json:"-"`
3938
// Map from component names to groups they belong to; not serialized.

scenario/__snapshots__/TestSnapshotsContainer_config_generate-schema_stdout_1.snap

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@
301301
"title": "Distros",
302302
"description": "Definitions of distros to build for or consume from"
303303
},
304+
"components": {
305+
"additionalProperties": {
306+
"$ref": "#/$defs/ComponentConfig"
307+
},
308+
"type": "object",
309+
"title": "Components",
310+
"description": "Definitions of components for this project"
311+
},
304312
"component-groups": {
305313
"additionalProperties": {
306314
"$ref": "#/$defs/ComponentGroupConfig"
@@ -309,13 +317,13 @@
309317
"title": "Component groups",
310318
"description": "Definitions of component groups for this project"
311319
},
312-
"components": {
320+
"package-groups": {
313321
"additionalProperties": {
314-
"$ref": "#/$defs/ComponentConfig"
322+
"$ref": "#/$defs/PackageGroupConfig"
315323
},
316324
"type": "object",
317-
"title": "Components",
318-
"description": "Definitions of components for this project"
325+
"title": "Package groups",
326+
"description": "Definitions of package groups for shared binary package configuration"
319327
},
320328
"images": {
321329
"additionalProperties": {
@@ -334,14 +342,6 @@
334342
"$ref": "#/$defs/PackageConfig",
335343
"title": "Default package config",
336344
"description": "Project-wide default applied to all binary packages before group and component overrides"
337-
},
338-
"package-groups": {
339-
"additionalProperties": {
340-
"$ref": "#/$defs/PackageGroupConfig"
341-
},
342-
"type": "object",
343-
"title": "Package groups",
344-
"description": "Definitions of package groups for shared binary package configuration"
345345
}
346346
},
347347
"additionalProperties": false,
@@ -465,6 +465,30 @@
465465
"release-ver"
466466
]
467467
},
468+
"ImageCapabilities": {
469+
"properties": {
470+
"supported-hosts": {
471+
"items": {
472+
"type": "string",
473+
"enum": [
474+
"azure-vm-gen1",
475+
"azure-vm-gen2",
476+
"oci-container"
477+
]
478+
},
479+
"type": "array",
480+
"title": "Supported hosts",
481+
"description": "Host types on which this image can be deployed or run"
482+
},
483+
"runtime-package-management": {
484+
"type": "boolean",
485+
"title": "Runtime package management",
486+
"description": "Image supports runtime package management (e.g. tdnf install at runtime)"
487+
}
488+
},
489+
"additionalProperties": false,
490+
"type": "object"
491+
},
468492
"ImageConfig": {
469493
"properties": {
470494
"description": {
@@ -476,6 +500,16 @@
476500
"$ref": "#/$defs/ImageDefinition",
477501
"title": "Definition",
478502
"description": "Identifies where to find the definition for this image"
503+
},
504+
"publish": {
505+
"$ref": "#/$defs/ImagePublishConfig",
506+
"title": "Publish settings",
507+
"description": "Publishing settings for this image"
508+
},
509+
"capabilities": {
510+
"$ref": "#/$defs/ImageCapabilities",
511+
"title": "Capabilities",
512+
"description": "Runtime capabilities of this image"
479513
}
480514
},
481515
"additionalProperties": false,
@@ -513,6 +547,20 @@
513547
"additionalProperties": false,
514548
"type": "object"
515549
},
550+
"ImagePublishConfig": {
551+
"properties": {
552+
"channels": {
553+
"items": {
554+
"type": "string"
555+
},
556+
"type": "array",
557+
"title": "Channels",
558+
"description": "List of publish channels for this image"
559+
}
560+
},
561+
"additionalProperties": false,
562+
"type": "object"
563+
},
516564
"Origin": {
517565
"properties": {
518566
"type": {

0 commit comments

Comments
 (0)