Skip to content

Commit b3962e8

Browse files
committed
Change Butane Configs conversion to compatible Ignition version
* Parse Ignition bytes to the compatible Ignition version (determined by current Ignition module's `ParseCompatibleVersion`) * Parse v1.3 Butane Configs to Ignition v3.3 * Parse v1.2 Butane Configs to Ignition v3.3 * Parse v1.1 Butane Configs to Ignition v3.3 * Parse v1.0 Butane Configs to Ignition v3.3 * Relies on Ignition v3.x spec's future compatibility, where lesser Ignition can be converted forward to the current Ignition (e.g. any new fields will be empty or equivalently zero effect) * Add support for version skew among Butane Config snippets * Butane Config and snippets will always convert to the Ignition version set by this provider Docs: https://github.com/poseidon/terraform-provider-ct#versions
1 parent 2e011c1 commit b3962e8

File tree

4 files changed

+137
-316
lines changed

4 files changed

+137
-316
lines changed

CHANGES.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ Notable changes between releases.
44

55
## Latest
66

7+
## v0.10.0
8+
9+
* Change how older (< 1.4) Butane Configs are parsed to Ignition ([#116](https://github.com/poseidon/terraform-provider-ct/pull/116))
10+
* Parse Ignition bytes to the forward compatible Ignition version ([docs](https://github.com/poseidon/terraform-provider-ct#versions))
11+
* Parse v1.3 Butane Configs to Ignition v3.3
12+
* Parse v1.2 Butane Configs to Ignition v3.3
13+
* Parse v1.1 Butane Configs to Ignition v3.3
14+
* Parse v1.0 Butane Configs to Ignition v3.3
15+
* Add support for verison skew among Butane Config snippets
16+
* Butane Config and snippets will always convert to the current Ignition version
17+
718
## v0.9.2
819

920
* Update butane, ignition, and Terraform SDK modules

README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ terraform {
1313
required_providers {
1414
ct = {
1515
source = "poseidon/ct"
16-
version = "0.9.2"
16+
version = "0.10.0"
1717
}
1818
}
1919
}
@@ -75,12 +75,15 @@ $ terraform init
7575
7676
## Versions
7777
78-
Butane configs contain a `version` that is associated with an Ignition format version. For example, a Butane config with `version: 1.0.0` would produce an Ignition config with version `3.0.0`, across future releases.
78+
Butane configs are converted to the current (according to this provider) stable Ignition config and merged together. For example, a Butane Config with `version: 1.2.0` would produce an Ignition config with version `v3.3.0`. This relies on Ignition's [forward compatibility](https://github.com/coreos/ignition/blob/main/config/v3_3/config.go#L61).
7979
8080
Container Linux Configs render a fixed Ignition version, depending on the `terraform-provider-ct` release, so updating alters the rendered Ignition version.
8181
82+
Before `terraform-provider-ct` v0.10.0, Butane configs contained a `version` that was associated with an Ignition format version. For example, a Butane config with `version: 1.0.0` would produce an Ignition config with version `3.0.0`.
83+
8284
| terraform-provider-ct | CLC to Ignition | Butane to Ignition |
8385
|-----------------------|---------------------|--------------------|
86+
| 0.10.x | Renders 2.3.0 | Butane (1.0, 1.1, 1.2, 1.3, 1.4) -> Ignition 3.3 |
8487
| 0.9.x | Renders 2.3.0 | Butane (1.0, 1.1, 1.2, 1.3, 1.4) -> Ignition (3.0, 3.1, 3.2, 3.2, 3.3)
8588
| 0.8.x | Renders 2.3.0 | Butane (1.0, 1.1, 1.2, 1.3) -> Ignition (3.0, 3.1, 3.2, 3.2)
8689
| 0.7.x | Renders 2.3.0 | Butane (1.0, 1.1, 1.2) -> Ignition (3.0, 3.1, 3.2) |
@@ -90,10 +93,6 @@ Container Linux Configs render a fixed Ignition version, depending on the `terra
9093
| 0.3.x | Renders 2.2.0 | NA |
9194
| 0.2.x | Renders 2.0.0 | NA |
9295
93-
Notes:
94-
95-
* Butane config `snippets` must match the version set in the content. Version skew among snippets is **not** supported.
96-
9796
## Development
9897
9998
### Binary

ct/datasource_ct_config.go

Lines changed: 12 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,7 @@ import (
1616

1717
ignition "github.com/coreos/ignition/config/v2_3"
1818
ignitionTypes "github.com/coreos/ignition/config/v2_3/types"
19-
ignition30 "github.com/coreos/ignition/v2/config/v3_0"
20-
ignition30Types "github.com/coreos/ignition/v2/config/v3_0/types"
21-
ignition31 "github.com/coreos/ignition/v2/config/v3_1"
22-
ignition31Types "github.com/coreos/ignition/v2/config/v3_1/types"
23-
ignition32 "github.com/coreos/ignition/v2/config/v3_2"
24-
ignition32Types "github.com/coreos/ignition/v2/config/v3_2/types"
2519
ignition33 "github.com/coreos/ignition/v2/config/v3_3"
26-
ignition33Types "github.com/coreos/ignition/v2/config/v3_3/types"
2720
)
2821

2922
func dataSourceCTConfig() *schema.Resource {
@@ -97,8 +90,8 @@ func renderConfig(d *schema.ResourceData) (string, error) {
9790
}
9891
}
9992

100-
// Fedora CoreOS Config
101-
ign, err := fccToIgnition([]byte(content), pretty, strict, snippets)
93+
// Butane Config
94+
ign, err := butaneToIgnition([]byte(content), pretty, strict, snippets)
10295
if err == common.ErrNoVariant {
10396
// consider as Container Linux Config
10497
ign, err = renderCLC([]byte(content), platform, pretty, strict, snippets)
@@ -107,7 +100,7 @@ func renderConfig(d *schema.ResourceData) (string, error) {
107100
}
108101

109102
// Translate Fedora CoreOS config to Ignition v3.X.Y
110-
func fccToIgnition(data []byte, pretty, strict bool, snippets []string) ([]byte, error) {
103+
func butaneToIgnition(data []byte, pretty, strict bool, snippets []string) ([]byte, error) {
111104
ignBytes, report, err := butane.TranslateBytes(data, common.TranslateBytesOptions{
112105
Pretty: pretty,
113106
})
@@ -119,166 +112,40 @@ func fccToIgnition(data []byte, pretty, strict bool, snippets []string) ([]byte,
119112
return nil, fmt.Errorf("strict parsing error: %v", report.String())
120113
}
121114

122-
if len(snippets) == 0 {
123-
return ignBytes, nil
124-
}
125-
126115
// merge FCC snippets into main Ignition config
127116
return mergeFCCSnippets(ignBytes, pretty, strict, snippets)
128117
}
129118

130-
// Manually parse main Fedora CoreOS Config's Ignition using fallback Ignition
131-
// versions. Then translate and parse FCC snippets as the chosen Ignition
132-
// version to merge.
133-
// version
134-
// Upstream might later handle: https://github.com/coreos/butane/issues/118
135-
// Note: This means snippets version must match the main config version.
119+
// Parse Fedora CoreOS Ignition and Butane snippets into Ignition Config.
136120
func mergeFCCSnippets(ignBytes []byte, pretty, strict bool, snippets []string) ([]byte, error) {
137-
ign33, _, err := ignition33.Parse(ignBytes)
138-
if err == nil {
139-
// FCC config v1.4.0
140-
ign33, err = mergeFCC14(ign33, snippets, pretty, strict)
141-
if err != nil {
142-
return nil, fmt.Errorf("FCC v1.4.0 merge error: %v", err)
143-
}
144-
return marshalJSON(ign33, pretty)
145-
}
146-
147-
ign32, _, err := ignition32.Parse(ignBytes)
148-
if err == nil {
149-
// FCC config v1.2.0
150-
ign32, err = mergeFCC12(ign32, snippets, pretty, strict)
151-
if err != nil {
152-
return nil, fmt.Errorf("FCC v1.2.0 merge error: %v", err)
153-
}
154-
return marshalJSON(ign32, pretty)
155-
}
156-
157-
ign31, _, err := ignition31.Parse(ignBytes)
158-
if err == nil {
159-
// FCC config v1.1.0
160-
ign31, err = mergeFCC11(ign31, snippets, pretty, strict)
161-
if err != nil {
162-
return nil, fmt.Errorf("FCC v1.1.0 merge error: %v", err)
163-
}
164-
return marshalJSON(ign31, pretty)
165-
}
166-
167-
var ign30 ignition30Types.Config
168-
ign30, _, err = ignition30.Parse(ignBytes)
121+
ign, _, err := ignition33.ParseCompatibleVersion(ignBytes)
169122
if err != nil {
170-
return nil, fmt.Errorf("FCC v1.0.0 parse error: %v", err)
123+
return nil, fmt.Errorf("%v", err)
171124
}
172-
// FCC config v1.0.0
173-
ign30, err = mergeFCCV10(ign30, snippets, pretty, strict)
174-
if err != nil {
175-
return nil, fmt.Errorf("FCC v1.0.0 merge error: %v", err)
176-
}
177-
return marshalJSON(ign30, pretty)
178-
}
179125

180-
// merge FCC v1.4.0 snippets
181-
func mergeFCC14(ign ignition33Types.Config, snippets []string, pretty, strict bool) (ignition33Types.Config, error) {
182126
for _, snippet := range snippets {
183127
ignextBytes, report, err := butane.TranslateBytes([]byte(snippet), common.TranslateBytesOptions{
184128
Pretty: pretty,
185129
})
186130
if err != nil {
187131
// For FCC, require snippets be FCCs (don't fall-through to CLC)
188132
if err == common.ErrNoVariant {
189-
return ign, fmt.Errorf("Fedora CoreOS snippets require `variant`: %v", err)
133+
return nil, fmt.Errorf("Butane snippets require `variant`: %v", err)
190134
}
191-
return ign, fmt.Errorf("snippet v1.4.0 translate error: %v", err)
135+
return nil, fmt.Errorf("Butane translate error: %v", err)
192136
}
193137
if strict && len(report.Entries) > 0 {
194-
return ign, fmt.Errorf("strict parsing error: %v", report.String())
138+
return nil, fmt.Errorf("strict parsing error: %v", report.String())
195139
}
196140

197-
ignext, _, err := ignition33.Parse(ignextBytes)
141+
ignext, _, err := ignition33.ParseCompatibleVersion(ignextBytes)
198142
if err != nil {
199-
return ign, fmt.Errorf("snippet parse error: %v, expect v1.4.0", err)
143+
return nil, fmt.Errorf("snippet parse error: %v, expect v1.4.0", err)
200144
}
201145
ign = ignition33.Merge(ign, ignext)
202146
}
203-
return ign, nil
204-
}
205-
206-
// merge FCC v1.2.0 snippets
207-
func mergeFCC12(ign ignition32Types.Config, snippets []string, pretty, strict bool) (ignition32Types.Config, error) {
208-
for _, snippet := range snippets {
209-
ignextBytes, report, err := butane.TranslateBytes([]byte(snippet), common.TranslateBytesOptions{
210-
Pretty: pretty,
211-
})
212-
if err != nil {
213-
// For FCC, require snippets be FCCs (don't fall-through to CLC)
214-
if err == common.ErrNoVariant {
215-
return ign, fmt.Errorf("Fedora CoreOS snippets require `variant`: %v", err)
216-
}
217-
return ign, fmt.Errorf("snippet v1.2.0 translate error: %v", err)
218-
}
219-
if strict && len(report.Entries) > 0 {
220-
return ign, fmt.Errorf("strict parsing error: %v", report.String())
221-
}
222-
223-
ignext, _, err := ignition32.Parse(ignextBytes)
224-
if err != nil {
225-
return ign, fmt.Errorf("snippet parse error: %v, expect v1.2.0", err)
226-
}
227-
ign = ignition32.Merge(ign, ignext)
228-
}
229-
return ign, nil
230-
}
231-
232-
// merge FCC v1.1.0 snippets
233-
func mergeFCC11(ign ignition31Types.Config, snippets []string, pretty, strict bool) (ignition31Types.Config, error) {
234-
for _, snippet := range snippets {
235-
ignextBytes, report, err := butane.TranslateBytes([]byte(snippet), common.TranslateBytesOptions{
236-
Pretty: pretty,
237-
})
238-
if err != nil {
239-
// For FCC, require snippets be FCCs (don't fall-through to CLC)
240-
if err == common.ErrNoVariant {
241-
return ign, fmt.Errorf("Fedora CoreOS snippets require `variant`: %v", err)
242-
}
243-
return ign, fmt.Errorf("snippet v1.1.0 translate error: %v", err)
244-
}
245-
if strict && len(report.Entries) > 0 {
246-
return ign, fmt.Errorf("strict parsing error: %v", report.String())
247-
}
248-
249-
ignext, _, err := ignition31.Parse(ignextBytes)
250-
if err != nil {
251-
return ign, fmt.Errorf("snippet parse error: %v, expect v1.1.0", err)
252-
}
253-
ign = ignition31.Merge(ign, ignext)
254-
}
255-
return ign, nil
256-
}
257-
258-
// merge FCC v1.0.0 snippets
259-
func mergeFCCV10(ign ignition30Types.Config, snippets []string, pretty, strict bool) (ignition30Types.Config, error) {
260-
for _, snippet := range snippets {
261-
ignextBytes, report, err := butane.TranslateBytes([]byte(snippet), common.TranslateBytesOptions{
262-
Pretty: pretty,
263-
})
264-
if err != nil {
265-
// For FCC, require snippets be FCCs (don't fall-through to CLC)
266-
if err == common.ErrNoVariant {
267-
return ign, fmt.Errorf("Fedora CoreOS snippets require `variant`: %v", err)
268-
}
269-
return ign, fmt.Errorf("snippet v1.0.0 translate error: %v", err)
270-
}
271-
if strict && len(report.Entries) > 0 {
272-
return ign, fmt.Errorf("strict parsing error: %v", report.String())
273-
}
274147

275-
ignext, _, err := ignition30.Parse(ignextBytes)
276-
if err != nil {
277-
return ign, fmt.Errorf("snippet parse error: %v, expect v1.0.0", err)
278-
}
279-
ign = ignition30.Merge(ign, ignext)
280-
}
281-
return ign, nil
148+
return marshalJSON(ign, pretty)
282149
}
283150

284151
// Translate Container Linux Config as Ignition JSON.

0 commit comments

Comments
 (0)