Skip to content

Commit 32b50d8

Browse files
committed
added global config yml validation
1 parent 012a518 commit 32b50d8

8 files changed

Lines changed: 191 additions & 3 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ require (
1010
github.com/spf13/cobra v1.9.1
1111
go.uber.org/zap v1.27.0
1212
gopkg.in/yaml.v3 v3.0.1
13+
sigs.k8s.io/yaml v1.4.0
1314
)
1415

1516
require (

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6N
88
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
99
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
1010
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11+
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
12+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1113
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
1214
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
1315
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
@@ -54,3 +56,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
5456
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5557
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
5658
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
59+
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
60+
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

internal/validate/validate.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,12 @@ func ValidateImageJSON(data []byte) error {
5050
data,
5151
)
5252
}
53+
54+
// ValidateConfigJSON runs the config schema against data
55+
func ValidateConfigJSON(data []byte) error {
56+
return ValidateAgainstSchema(
57+
"os-image-composer-config.schema.json",
58+
schema_pkg.ConfigSchema,
59+
data,
60+
)
61+
}

internal/validate/validate_test.go

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"path/filepath"
77
"testing"
88

9-
"gopkg.in/yaml.v3"
9+
"sigs.k8s.io/yaml"
1010
)
1111

1212
// loadFile reads a test JSON file from the project root testdata directory.
@@ -45,7 +45,7 @@ func TestValidImage(t *testing.T) {
4545
t.Errorf("yml parsing error: %v", err)
4646
}
4747

48-
// 3) Re‐marshal to JSON bytes
48+
// Re‐marshal to JSON bytes
4949
dataJSON, err := json.Marshal(raw)
5050
if err != nil {
5151
t.Errorf("json marshaling error: %v", err)
@@ -64,7 +64,7 @@ func TestInvalidImage(t *testing.T) {
6464
t.Errorf("yml parsing error: %v", err)
6565
}
6666

67-
// 3) Re‐marshal to JSON bytes
67+
// Re‐marshal to JSON bytes
6868
dataJSON, err := json.Marshal(raw)
6969
if err != nil {
7070
t.Errorf("json marshaling error: %v", err)
@@ -73,3 +73,42 @@ func TestInvalidImage(t *testing.T) {
7373
t.Errorf("expected testdata/invalid-image.yml to pass, but got: %v", err)
7474
}
7575
}
76+
77+
func TestValidConfig(t *testing.T) {
78+
v := loadFile(t, "testdata/valid-config.yml")
79+
80+
if v == nil {
81+
t.Fatal("failed to load testdata/valid-config.yml")
82+
}
83+
dataJSON, err := yaml.YAMLToJSON(v)
84+
85+
if err != nil {
86+
t.Fatalf("YAML→JSON conversion failed: %v", err)
87+
}
88+
if err := ValidateConfigJSON(dataJSON); err != nil {
89+
t.Errorf("validation failed: %v", err)
90+
}
91+
}
92+
93+
func TestInvalidConfig(t *testing.T) {
94+
v := loadFile(t, "testdata/invalid-config.yml")
95+
96+
// Parse to generic JSON interface
97+
var raw interface{}
98+
if err := yaml.Unmarshal(v, &raw); err != nil {
99+
t.Errorf("yml parsing error: %v", err)
100+
}
101+
102+
// Re‐marshal to JSON bytes
103+
dataJSON, err := yaml.YAMLToJSON(v)
104+
if err != nil {
105+
t.Errorf("json marshaling error: %v", err)
106+
}
107+
108+
if err := ValidateConfigJSON(dataJSON); err == nil {
109+
t.Errorf("expected invalid-config.json to fail validation: %v", err)
110+
} else {
111+
t.Logf("expected validation error: %v", err)
112+
}
113+
114+
}

schema/embed.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ var ComposerSchema []byte
77

88
//go:embed os-image-template.schema.json
99
var ImageSchema []byte
10+
11+
//go:embed os-image-composer-config.schema.json
12+
var ConfigSchema []byte
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"$schema": "https://json-schema.org/draft/2020-12/schema",
3+
"$id": "https://github.com/open-edge-platform/image-composer/schemas/os-image-composer-config.schema.json",
4+
"title": "OS Image Composer Config",
5+
"description": "Defines the global configuration file for the Image Composer",
6+
"type": "object",
7+
"properties": {
8+
"workers": {
9+
"type": "integer",
10+
"description": "Number of concurrent workers for tasks",
11+
"default": 8,
12+
"minimum": 1,
13+
"maximum": 64
14+
},
15+
"cache_dir": {
16+
"type": "string",
17+
"description": "Default root package cache directory",
18+
"default": ".cache",
19+
"pattern": "^[a-zA-Z0-9_./-]+$",
20+
"minLength": 0,
21+
"maxLength": 255
22+
},
23+
"work_dir": {
24+
"type": "string",
25+
"description": "Default root workspace directory",
26+
"default": ".workspace",
27+
"pattern": "^[a-zA-Z0-9_./-]+$",
28+
"minLength": 0,
29+
"maxLength": 255
30+
},
31+
"temp_dir": {
32+
"type": "string",
33+
"description": "Default temporary directory for short lived files",
34+
"default": ".temp",
35+
"pattern": "^[a-zA-Z0-9_./-]+$",
36+
"minLength": 0,
37+
"maxLength": 255
38+
},
39+
"logging": {
40+
"type": "object",
41+
"description": "Logging configuration",
42+
"properties": {
43+
"level": {
44+
"type": "string",
45+
"description": "Logging level",
46+
"enum": [
47+
"debug",
48+
"info",
49+
"warn",
50+
"error"
51+
],
52+
"default": "info"
53+
}
54+
},
55+
"required": [
56+
"level"
57+
],
58+
"additionalProperties": false
59+
}
60+
},
61+
"additionalProperties": false
62+
}

testdata/invalid-config.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Image Composer Tool - Global Configuration
2+
# This file contains tool-level settings that apply across all image builds.
3+
# Image-specific parameters should be defined in the image specification.
4+
5+
# Core tool settings
6+
workers: 67
7+
# Number of concurrent download workers (1-64, default: 8)
8+
# Higher values speed up package downloads but consume more network/CPU resources
9+
# Recommended: 8-16 for most systems, 20+ for high-bandwidth servers
10+
11+
cache_dir: "/var/cache/image-composer"
12+
# Package cache directory where downloaded RPMs/DEBs are stored (default: ./cache)
13+
# This directory persists between builds for package reuse
14+
# Should have sufficient space (typically 1-5GB depending on image size)
15+
16+
work_dir: "/tmp/image-composer"
17+
# Working directory for build operations and image assembly (default: ./workspace)
18+
# Contains temporary build artifacts, extracted packages, and final images
19+
# Cleaned up after successful builds
20+
# Requires substantial space during builds (2-10GB typical)
21+
22+
temp_dir: ""
23+
# Temporary directory for short-lived files like GPG keys and metadata parsing
24+
# Empty value uses system default (/tmp on Linux, %TEMP% on Windows)
25+
# Used for: GPG verification files, decompressed metadata, parsing operations
26+
# Files here are deleted within seconds/minutes of creation
27+
28+
# Logging configuration
29+
logging:
30+
level: "info"
31+
# Log verbosity level (default: info)
32+
# - debug: Most verbose, shows all operations and data structures
33+
# - info: Normal output, shows progress and important events
34+
# - warn: Only warnings and errors, minimal output
35+
# - error: Only errors, very quiet operation

testdata/valid-config.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Image Composer Tool - Global Configuration
2+
# This file contains tool-level settings that apply across all image builds.
3+
# Image-specific parameters should be defined in the image specification.
4+
5+
# Core tool settings
6+
workers: 12
7+
# Number of concurrent download workers (1-64, default: 8)
8+
# Higher values speed up package downloads but consume more network/CPU resources
9+
# Recommended: 8-16 for most systems, 20+ for high-bandwidth servers
10+
11+
cache_dir: "/var/cache/image-composer"
12+
# Package cache directory where downloaded RPMs/DEBs are stored (default: ./cache)
13+
# This directory persists between builds for package reuse
14+
# Should have sufficient space (typically 1-5GB depending on image size)
15+
16+
work_dir: "/tmp/image-composer"
17+
# Working directory for build operations and image assembly (default: ./workspace)
18+
# Contains temporary build artifacts, extracted packages, and final images
19+
# Cleaned up after successful builds
20+
# Requires substantial space during builds (2-10GB typical)
21+
22+
temp_dir: "/tmp"
23+
# Temporary directory for short-lived files like GPG keys and metadata parsing
24+
# Empty value uses system default (/tmp on Linux, %TEMP% on Windows)
25+
# Used for: GPG verification files, decompressed metadata, parsing operations
26+
# Files here are deleted within seconds/minutes of creation
27+
28+
# Logging configuration
29+
logging:
30+
level: "info"
31+
# Log verbosity level (default: info)
32+
# - debug: Most verbose, shows all operations and data structures
33+
# - info: Normal output, shows progress and important events
34+
# - warn: Only warnings and errors, minimal output
35+
# - error: Only errors, very quiet operation

0 commit comments

Comments
 (0)