From 567524152bc245293668b3044aaad337f2760f1e Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Thu, 24 Aug 2023 13:11:06 +0000 Subject: [PATCH 01/16] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@758c2197a9c194cd0067f1f200a6ac4d8015de9f. --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index 0b00413c..9799e735 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -14,7 +14,7 @@ kramdown: ndash: "--" mdash: "---" -remote_theme: just-the-docs/just-the-docs@v0.5.3 +remote_theme: just-the-docs/just-the-docs@v0.6.0 plugins: - jekyll-remote-theme From 0f43b1b6a149840e159cdf85276ae2410d24183d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Thu, 14 Sep 2023 11:54:18 +0200 Subject: [PATCH 02/16] openshift/v4_15_exp: Copy from 4.14_exp --- config/openshift/v4_15_exp/result/schema.go | 48 ++ config/openshift/v4_15_exp/schema.go | 39 ++ config/openshift/v4_15_exp/translate.go | 327 ++++++++++ config/openshift/v4_15_exp/translate_test.go | 598 +++++++++++++++++++ config/openshift/v4_15_exp/validate.go | 43 ++ config/openshift/v4_15_exp/validate_test.go | 254 ++++++++ 6 files changed, 1309 insertions(+) create mode 100644 config/openshift/v4_15_exp/result/schema.go create mode 100644 config/openshift/v4_15_exp/schema.go create mode 100644 config/openshift/v4_15_exp/translate.go create mode 100644 config/openshift/v4_15_exp/translate_test.go create mode 100644 config/openshift/v4_15_exp/validate.go create mode 100644 config/openshift/v4_15_exp/validate_test.go diff --git a/config/openshift/v4_15_exp/result/schema.go b/config/openshift/v4_15_exp/result/schema.go new file mode 100644 index 00000000..c8d45b79 --- /dev/null +++ b/config/openshift/v4_15_exp/result/schema.go @@ -0,0 +1,48 @@ +// Copyright 2021 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package result + +import ( + "github.com/coreos/ignition/v2/config/v3_5_experimental/types" +) + +const ( + MC_API_VERSION = "machineconfiguration.openshift.io/v1" + MC_KIND = "MachineConfig" +) + +// We round-trip through JSON because Ignition uses `json` struct tags, +// so all struct tags need to be `json` even though we're ultimately +// writing YAML. + +type MachineConfig struct { + ApiVersion string `json:"apiVersion"` + Kind string `json:"kind"` + Metadata Metadata `json:"metadata"` + Spec Spec `json:"spec"` +} + +type Metadata struct { + Name string `json:"name"` + Labels map[string]string `json:"labels,omitempty"` +} + +type Spec struct { + Config types.Config `json:"config"` + KernelArguments []string `json:"kernelArguments,omitempty"` + Extensions []string `json:"extensions,omitempty"` + FIPS *bool `json:"fips,omitempty"` + KernelType *string `json:"kernelType,omitempty"` +} diff --git a/config/openshift/v4_15_exp/schema.go b/config/openshift/v4_15_exp/schema.go new file mode 100644 index 00000000..16d45ab4 --- /dev/null +++ b/config/openshift/v4_15_exp/schema.go @@ -0,0 +1,39 @@ +// Copyright 2020 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v4_14_exp + +import ( + fcos "github.com/coreos/butane/config/fcos/v1_6_exp" +) + +const ROLE_LABEL_KEY = "machineconfiguration.openshift.io/role" + +type Config struct { + fcos.Config `yaml:",inline"` + Metadata Metadata `yaml:"metadata"` + OpenShift OpenShift `yaml:"openshift"` +} + +type Metadata struct { + Name string `yaml:"name"` + Labels map[string]string `yaml:"labels,omitempty"` +} + +type OpenShift struct { + KernelArguments []string `yaml:"kernel_arguments"` + Extensions []string `yaml:"extensions"` + FIPS *bool `yaml:"fips"` + KernelType *string `yaml:"kernel_type"` +} diff --git a/config/openshift/v4_15_exp/translate.go b/config/openshift/v4_15_exp/translate.go new file mode 100644 index 00000000..bbd05f23 --- /dev/null +++ b/config/openshift/v4_15_exp/translate.go @@ -0,0 +1,327 @@ +// Copyright 2020 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v4_14_exp + +import ( + "net/url" + "strings" + + "github.com/coreos/butane/config/common" + "github.com/coreos/butane/config/openshift/v4_14_exp/result" + cutil "github.com/coreos/butane/config/util" + "github.com/coreos/butane/translate" + + "github.com/coreos/ignition/v2/config/util" + "github.com/coreos/ignition/v2/config/v3_5_experimental/types" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +// Error classes: +// +// UNPARSABLE - Cannot be rendered into a config by the MCC. If present in +// MC, MCC will mark the pool degraded. We reject these. +// +// FORBIDDEN - Not supported by the MCD. If present in MC, MCD will mark +// the node degraded. We reject these. +// +// REDUNDANT - Feature is also provided by a MachineConfig-specific field +// with different semantics. To reduce confusion, disable this +// implementation. +// +// IMMUTABLE - Permitted in MC, passed through to Ignition, but not +// supported by the MCD. MCD will mark the node degraded if the field +// changes after the node is provisioned. We reject these outright to +// discourage their use. +// +// TRIPWIRE - A subset of fields in the containing struct are supported by +// the MCD. If the struct contents change after the node is provisioned, +// and the struct contains unsupported fields, MCD will mark the node +// degraded, even if the change only affects supported fields. We reject +// these. + +const ( + // FIPS 140-2 doesn't allow the default XTS mode + fipsCipherOption = types.LuksOption("--cipher") + fipsCipherShortOption = types.LuksOption("-c") + fipsCipherArgument = types.LuksOption("aes-cbc-essiv:sha256") +) + +var ( + // See also validateRHCOSSupport() and validateMCOSupport() + fieldFilters = cutil.NewFilters(result.MachineConfig{}, cutil.FilterMap{ + // UNPARSABLE, REDUNDANT + "spec.config.kernelArguments": common.ErrKernelArgumentSupport, + // IMMUTABLE + "spec.config.passwd.groups": common.ErrGroupSupport, + // TRIPWIRE + "spec.config.passwd.users.gecos": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.groups": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.homeDir": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.noCreateHome": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.noLogInit": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.noUserGroup": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.primaryGroup": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.shell": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.shouldExist": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.system": common.ErrUserFieldSupport, + // TRIPWIRE + "spec.config.passwd.users.uid": common.ErrUserFieldSupport, + // IMMUTABLE + "spec.config.storage.directories": common.ErrDirectorySupport, + // FORBIDDEN + "spec.config.storage.files.append": common.ErrFileAppendSupport, + // redundant with a check from Ignition validation, but ensures we + // exclude the section from docs + "spec.config.storage.files.contents.httpHeaders": common.ErrFileHeaderSupport, + // IMMUTABLE + // If you change this to be less restrictive without adding + // link support in the MCO, consider what should happen if + // the user specifies a storage.tree that includes symlinks. + "spec.config.storage.links": common.ErrLinkSupport, + }) +) + +// Return FieldFilters for this spec. +func (c Config) FieldFilters() *cutil.FieldFilters { + return &fieldFilters +} + +// ToMachineConfig4_14Unvalidated translates the config to a MachineConfig. It also +// returns the set of translations it did so paths in the resultant config +// can be tracked back to their source in the source config. No config +// validation is performed on input or output. +func (c Config) ToMachineConfig4_14Unvalidated(options common.TranslateOptions) (result.MachineConfig, translate.TranslationSet, report.Report) { + cfg, ts, r := c.Config.ToIgn3_5Unvalidated(options) + if r.IsFatal() { + return result.MachineConfig{}, ts, r + } + ts = translateUserGrubCfg(&cfg, &ts) + + // wrap + ts = ts.PrefixPaths(path.New("yaml"), path.New("json", "spec", "config")) + mc := result.MachineConfig{ + ApiVersion: result.MC_API_VERSION, + Kind: result.MC_KIND, + Metadata: result.Metadata{ + Name: c.Metadata.Name, + Labels: make(map[string]string), + }, + Spec: result.Spec{ + Config: cfg, + }, + } + ts.AddTranslation(path.New("yaml", "version"), path.New("json", "apiVersion")) + ts.AddTranslation(path.New("yaml", "version"), path.New("json", "kind")) + ts.AddTranslation(path.New("yaml", "metadata"), path.New("json", "metadata")) + ts.AddTranslation(path.New("yaml", "metadata", "name"), path.New("json", "metadata", "name")) + ts.AddTranslation(path.New("yaml", "metadata", "labels"), path.New("json", "metadata", "labels")) + ts.AddTranslation(path.New("yaml", "version"), path.New("json", "spec")) + ts.AddTranslation(path.New("yaml"), path.New("json", "spec", "config")) + for k, v := range c.Metadata.Labels { + mc.Metadata.Labels[k] = v + ts.AddTranslation(path.New("yaml", "metadata", "labels", k), path.New("json", "metadata", "labels", k)) + } + + // translate OpenShift fields + tr := translate.NewTranslator("yaml", "json", options) + from := &c.OpenShift + to := &mc.Spec + ts2, r2 := translate.Prefixed(tr, "extensions", &from.Extensions, &to.Extensions) + translate.MergeP(tr, ts2, &r2, "fips", &from.FIPS, &to.FIPS) + translate.MergeP2(tr, ts2, &r2, "kernel_arguments", &from.KernelArguments, "kernelArguments", &to.KernelArguments) + translate.MergeP2(tr, ts2, &r2, "kernel_type", &from.KernelType, "kernelType", &to.KernelType) + ts.MergeP2("openshift", "spec", ts2) + r.Merge(r2) + + // apply FIPS options to LUKS volumes + ts.Merge(addLuksFipsOptions(&mc)) + + // finally, check the fully desugared config for RHCOS and MCO support + r.Merge(validateRHCOSSupport(mc)) + r.Merge(validateMCOSupport(mc)) + + return mc, ts, r +} + +// ToMachineConfig4_14 translates the config to a MachineConfig. It returns a +// report of any errors or warnings in the source and resultant config. If +// the report has fatal errors or it encounters other problems translating, +// an error is returned. +func (c Config) ToMachineConfig4_14(options common.TranslateOptions) (result.MachineConfig, report.Report, error) { + cfg, r, err := cutil.Translate(c, "ToMachineConfig4_14Unvalidated", options) + return cfg.(result.MachineConfig), r, err +} + +// ToIgn3_5Unvalidated translates the config to an Ignition config. It also +// returns the set of translations it did so paths in the resultant config +// can be tracked back to their source in the source config. No config +// validation is performed on input or output. +func (c Config) ToIgn3_5Unvalidated(options common.TranslateOptions) (types.Config, translate.TranslationSet, report.Report) { + mc, ts, r := c.ToMachineConfig4_14Unvalidated(options) + cfg := mc.Spec.Config + + // report warnings if there are any non-empty fields in Spec (other + // than the Ignition config itself) that we're ignoring + mc.Spec.Config = types.Config{} + warnings := translate.PrefixReport(cutil.CheckForElidedFields(mc.Spec), "spec") + // translate from json space into yaml space, since the caller won't + // have enough info to do it + r.Merge(cutil.TranslateReportPaths(warnings, ts)) + + ts = ts.Descend(path.New("json", "spec", "config")) + return cfg, ts, r +} + +// ToIgn3_5 translates the config to an Ignition config. It returns a +// report of any errors or warnings in the source and resultant config. If +// the report has fatal errors or it encounters other problems translating, +// an error is returned. +func (c Config) ToIgn3_5(options common.TranslateOptions) (types.Config, report.Report, error) { + cfg, r, err := cutil.Translate(c, "ToIgn3_5Unvalidated", options) + return cfg.(types.Config), r, err +} + +// ToConfigBytes translates from a v4.14 Butane config to a v4.14 MachineConfig or a v3.4.0 Ignition config. It returns a report of any errors or +// warnings in the source and resultant config. If the report has fatal errors or it encounters other problems +// translating, an error is returned. +func ToConfigBytes(input []byte, options common.TranslateBytesOptions) ([]byte, report.Report, error) { + if options.Raw { + return cutil.TranslateBytes(input, &Config{}, "ToIgn3_5", options) + } else { + return cutil.TranslateBytesYAML(input, &Config{}, "ToMachineConfig4_14", options) + } +} + +func addLuksFipsOptions(mc *result.MachineConfig) translate.TranslationSet { + ts := translate.NewTranslationSet("yaml", "json") + if !util.IsTrue(mc.Spec.FIPS) { + return ts + } + +OUTER: + for i := range mc.Spec.Config.Storage.Luks { + luks := &mc.Spec.Config.Storage.Luks[i] + // Only add options if the user hasn't already specified + // a cipher option. Do this in-place, since config merging + // doesn't support conditional logic. + for _, option := range luks.Options { + if option == fipsCipherOption || + strings.HasPrefix(string(option), string(fipsCipherOption)+"=") || + option == fipsCipherShortOption { + continue OUTER + } + } + for j := 0; j < 2; j++ { + ts.AddTranslation(path.New("yaml", "openshift", "fips"), path.New("json", "spec", "config", "storage", "luks", i, "options", len(luks.Options)+j)) + } + if len(luks.Options) == 0 { + ts.AddTranslation(path.New("yaml", "openshift", "fips"), path.New("json", "spec", "config", "storage", "luks", i, "options")) + } + luks.Options = append(luks.Options, fipsCipherOption, fipsCipherArgument) + } + return ts +} + +// Error on fields that are rejected by RHCOS. +// +// Some of these fields may have been generated by sugar (e.g. +// boot_device.luks), so we work in JSON (output) space and then translate +// paths back to YAML (input) space. That's also the reason we do these +// checks after translation, rather than during validation. +func validateRHCOSSupport(mc result.MachineConfig) report.Report { + var r report.Report + for i, fs := range mc.Spec.Config.Storage.Filesystems { + if fs.Format != nil && *fs.Format == "btrfs" { + // we don't ship mkfs.btrfs + r.AddOnError(path.New("json", "spec", "config", "storage", "filesystems", i, "format"), common.ErrBtrfsSupport) + } + } + return r +} + +// Error on fields that are rejected outright by the MCO, or that are +// unsupported by the MCO and we want to discourage. +// +// https://github.com/openshift/machine-config-operator/blob/d6dabadeca05/MachineConfigDaemon.md#supported-vs-unsupported-ignition-config-changes +// +// Some of these fields may have been generated by sugar (e.g. storage.trees), +// so we work in JSON (output) space and then translate paths back to YAML +// (input) space. That's also the reason we do these checks after +// translation, rather than during validation. +func validateMCOSupport(mc result.MachineConfig) report.Report { + // See also fieldFilters at the top of this file. + + var r report.Report + for i, fs := range mc.Spec.Config.Storage.Filesystems { + if fs.Format != nil && *fs.Format == "none" { + // UNPARSABLE + r.AddOnError(path.New("json", "spec", "config", "storage", "filesystems", i, "format"), common.ErrFilesystemNoneSupport) + } + } + for i, file := range mc.Spec.Config.Storage.Files { + if file.Contents.Source != nil { + fileSource, err := url.Parse(*file.Contents.Source) + // parse errors will be caught by normal config validation + if err == nil && fileSource.Scheme != "data" { + // FORBIDDEN + r.AddOnError(path.New("json", "spec", "config", "storage", "files", i, "contents", "source"), common.ErrFileSchemeSupport) + } + } + if file.Mode != nil && *file.Mode & ^0777 != 0 { + // UNPARSABLE + r.AddOnError(path.New("json", "spec", "config", "storage", "files", i, "mode"), common.ErrFileSpecialModeSupport) + } + } + for i, user := range mc.Spec.Config.Passwd.Users { + if user.Name != "core" { + // TRIPWIRE + r.AddOnError(path.New("json", "spec", "config", "passwd", "users", i, "name"), common.ErrUserNameSupport) + } + } + return r +} + +// fcos config generates a user.cfg file using append; however, OpenShift config +// does not support append (since MCO does not support it). Let change the file to use contents +func translateUserGrubCfg(config *types.Config, ts *translate.TranslationSet) translate.TranslationSet { + newMappings := translate.NewTranslationSet("json", "json") + for i, file := range config.Storage.Files { + if file.Path == "/boot/grub2/user.cfg" { + if len(file.Append) != 1 { + // The number of append objects was different from expected, this file + // was created by the user and not via butane GRUB sugar + return *ts + } + fromPath := path.New("json", "storage", "files", i, "append", 0) + translatedPath := path.New("json", "storage", "files", i, "contents") + config.Storage.Files[i].FileEmbedded1.Contents = file.Append[0] + config.Storage.Files[i].FileEmbedded1.Append = nil + newMappings.AddFromCommonObject(fromPath, translatedPath, config.Storage.Files[i].FileEmbedded1.Contents) + + return ts.Map(newMappings) + } + } + return *ts +} diff --git a/config/openshift/v4_15_exp/translate_test.go b/config/openshift/v4_15_exp/translate_test.go new file mode 100644 index 00000000..edda5b2c --- /dev/null +++ b/config/openshift/v4_15_exp/translate_test.go @@ -0,0 +1,598 @@ +// Copyright 2021 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v4_14_exp + +import ( + "fmt" + "testing" + + baseutil "github.com/coreos/butane/base/util" + base "github.com/coreos/butane/base/v0_6_exp" + "github.com/coreos/butane/config/common" + fcos "github.com/coreos/butane/config/fcos/v1_6_exp" + "github.com/coreos/butane/config/openshift/v4_14_exp/result" + confutil "github.com/coreos/butane/config/util" + "github.com/coreos/butane/translate" + + "github.com/coreos/ignition/v2/config/util" + "github.com/coreos/ignition/v2/config/v3_5_experimental/types" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + "github.com/stretchr/testify/assert" +) + +// TestElidedFieldWarning tests that we warn when transpiling fields to an +// Ignition config that can't be represented in an Ignition config. +func TestElidedFieldWarning(t *testing.T) { + in := Config{ + Metadata: Metadata{ + Name: "z", + }, + OpenShift: OpenShift{ + KernelArguments: []string{"a", "b"}, + FIPS: util.BoolToPtr(true), + KernelType: util.StrToPtr("realtime"), + }, + } + + var expected report.Report + expected.AddOnWarn(path.New("yaml", "openshift", "kernel_arguments"), common.ErrFieldElided) + expected.AddOnWarn(path.New("yaml", "openshift", "fips"), common.ErrFieldElided) + expected.AddOnWarn(path.New("yaml", "openshift", "kernel_type"), common.ErrFieldElided) + + _, _, r := in.ToIgn3_5Unvalidated(common.TranslateOptions{}) + assert.Equal(t, expected, r, "report mismatch") +} + +func TestTranslateConfig(t *testing.T) { + tests := []struct { + in Config + out result.MachineConfig + exceptions []translate.Translation + }{ + // empty-ish config + { + Config{ + Metadata: Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + }, + result.MachineConfig{ + ApiVersion: result.MC_API_VERSION, + Kind: result.MC_KIND, + Metadata: result.Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + Spec: result.Spec{ + Config: types.Config{ + Ignition: types.Ignition{ + Version: "3.5.0-experimental", + }, + }, + }, + }, + []translate.Translation{ + {From: path.New("yaml", "version"), To: path.New("json", "apiVersion")}, + {From: path.New("yaml", "version"), To: path.New("json", "kind")}, + {From: path.New("yaml", "version"), To: path.New("json", "spec")}, + {From: path.New("yaml"), To: path.New("json", "spec", "config")}, + {From: path.New("yaml", "ignition"), To: path.New("json", "spec", "config", "ignition")}, + {From: path.New("yaml", "version"), To: path.New("json", "spec", "config", "ignition", "version")}, + }, + }, + // FIPS + { + Config{ + Metadata: Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + OpenShift: OpenShift{ + FIPS: util.BoolToPtr(true), + }, + Config: fcos.Config{ + Config: base.Config{ + Storage: base.Storage{ + Luks: []base.Luks{ + { + Name: "a", + }, + { + Name: "b", + Options: []string{"b", "b"}, + }, + { + Name: "c", + Options: []string{"c", "--cipher", "c"}, + }, + { + Name: "d", + Options: []string{"--cipher=z"}, + }, + { + Name: "e", + Options: []string{"-c", "z"}, + }, + { + Name: "f", + Options: []string{"--ciphertext"}, + }, + }, + }, + }, + BootDevice: fcos.BootDevice{ + Luks: fcos.BootDeviceLuks{ + Tpm2: util.BoolToPtr(true), + }, + }, + }, + }, + result.MachineConfig{ + ApiVersion: result.MC_API_VERSION, + Kind: result.MC_KIND, + Metadata: result.Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + Spec: result.Spec{ + Config: types.Config{ + Ignition: types.Ignition{ + Version: "3.5.0-experimental", + }, + Storage: types.Storage{ + Filesystems: []types.Filesystem{ + { + Device: "/dev/mapper/root", + Format: util.StrToPtr("xfs"), + Label: util.StrToPtr("root"), + WipeFilesystem: util.BoolToPtr(true), + }, + }, + Luks: []types.Luks{ + { + Name: "root", + Device: util.StrToPtr("/dev/disk/by-partlabel/root"), + Label: util.StrToPtr("luks-root"), + WipeVolume: util.BoolToPtr(true), + Options: []types.LuksOption{fipsCipherOption, fipsCipherArgument}, + Clevis: types.Clevis{ + Tpm2: util.BoolToPtr(true), + }, + }, + { + Name: "a", + Options: []types.LuksOption{fipsCipherOption, fipsCipherArgument}, + }, + { + Name: "b", + Options: []types.LuksOption{"b", "b", fipsCipherOption, fipsCipherArgument}, + }, + { + Name: "c", + Options: []types.LuksOption{"c", "--cipher", "c"}, + }, + { + Name: "d", + Options: []types.LuksOption{"--cipher=z"}, + }, + { + Name: "e", + Options: []types.LuksOption{"-c", "z"}, + }, + { + Name: "f", + Options: []types.LuksOption{"--ciphertext", fipsCipherOption, fipsCipherArgument}, + }, + }, + }, + }, + FIPS: util.BoolToPtr(true), + }, + }, + []translate.Translation{ + {From: path.New("yaml", "version"), To: path.New("json", "apiVersion")}, + {From: path.New("yaml", "version"), To: path.New("json", "kind")}, + {From: path.New("yaml", "version"), To: path.New("json", "spec")}, + {From: path.New("yaml"), To: path.New("json", "spec", "config")}, + {From: path.New("yaml", "ignition"), To: path.New("json", "spec", "config", "ignition")}, + {From: path.New("yaml", "version"), To: path.New("json", "spec", "config", "ignition", "version")}, + {From: path.New("yaml", "boot_device", "luks", "tpm2"), To: path.New("json", "spec", "config", "storage", "luks", 0, "clevis", "tpm2")}, + {From: path.New("yaml", "boot_device", "luks"), To: path.New("json", "spec", "config", "storage", "luks", 0, "clevis")}, + {From: path.New("yaml", "boot_device", "luks"), To: path.New("json", "spec", "config", "storage", "luks", 0, "device")}, + {From: path.New("yaml", "boot_device", "luks"), To: path.New("json", "spec", "config", "storage", "luks", 0, "label")}, + {From: path.New("yaml", "boot_device", "luks"), To: path.New("json", "spec", "config", "storage", "luks", 0, "name")}, + {From: path.New("yaml", "boot_device", "luks"), To: path.New("json", "spec", "config", "storage", "luks", 0, "wipeVolume")}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 0, "options", 0)}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 0, "options", 1)}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 0, "options")}, + {From: path.New("yaml", "boot_device", "luks"), To: path.New("json", "spec", "config", "storage", "luks", 0)}, + {From: path.New("yaml", "storage", "luks", 0, "name"), To: path.New("json", "spec", "config", "storage", "luks", 1, "name")}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 1, "options", 0)}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 1, "options", 1)}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 1, "options")}, + {From: path.New("yaml", "storage", "luks", 0), To: path.New("json", "spec", "config", "storage", "luks", 1)}, + {From: path.New("yaml", "storage", "luks", 1, "name"), To: path.New("json", "spec", "config", "storage", "luks", 2, "name")}, + {From: path.New("yaml", "storage", "luks", 1, "options", 0), To: path.New("json", "spec", "config", "storage", "luks", 2, "options", 0)}, + {From: path.New("yaml", "storage", "luks", 1, "options", 1), To: path.New("json", "spec", "config", "storage", "luks", 2, "options", 1)}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 2, "options", 2)}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 2, "options", 3)}, + {From: path.New("yaml", "storage", "luks", 1, "options"), To: path.New("json", "spec", "config", "storage", "luks", 2, "options")}, + {From: path.New("yaml", "storage", "luks", 1), To: path.New("json", "spec", "config", "storage", "luks", 2)}, + {From: path.New("yaml", "storage", "luks", 2, "name"), To: path.New("json", "spec", "config", "storage", "luks", 3, "name")}, + {From: path.New("yaml", "storage", "luks", 2, "options", 0), To: path.New("json", "spec", "config", "storage", "luks", 3, "options", 0)}, + {From: path.New("yaml", "storage", "luks", 2, "options", 1), To: path.New("json", "spec", "config", "storage", "luks", 3, "options", 1)}, + {From: path.New("yaml", "storage", "luks", 2, "options", 2), To: path.New("json", "spec", "config", "storage", "luks", 3, "options", 2)}, + {From: path.New("yaml", "storage", "luks", 2, "options"), To: path.New("json", "spec", "config", "storage", "luks", 3, "options")}, + {From: path.New("yaml", "storage", "luks", 2), To: path.New("json", "spec", "config", "storage", "luks", 3)}, + {From: path.New("yaml", "storage", "luks", 3, "name"), To: path.New("json", "spec", "config", "storage", "luks", 4, "name")}, + {From: path.New("yaml", "storage", "luks", 3, "options", 0), To: path.New("json", "spec", "config", "storage", "luks", 4, "options", 0)}, + {From: path.New("yaml", "storage", "luks", 3, "options"), To: path.New("json", "spec", "config", "storage", "luks", 4, "options")}, + {From: path.New("yaml", "storage", "luks", 3), To: path.New("json", "spec", "config", "storage", "luks", 4)}, + {From: path.New("yaml", "storage", "luks", 4, "name"), To: path.New("json", "spec", "config", "storage", "luks", 5, "name")}, + {From: path.New("yaml", "storage", "luks", 4, "options", 0), To: path.New("json", "spec", "config", "storage", "luks", 5, "options", 0)}, + {From: path.New("yaml", "storage", "luks", 4, "options", 1), To: path.New("json", "spec", "config", "storage", "luks", 5, "options", 1)}, + {From: path.New("yaml", "storage", "luks", 4, "options"), To: path.New("json", "spec", "config", "storage", "luks", 5, "options")}, + {From: path.New("yaml", "storage", "luks", 4), To: path.New("json", "spec", "config", "storage", "luks", 5)}, + {From: path.New("yaml", "storage", "luks", 5, "name"), To: path.New("json", "spec", "config", "storage", "luks", 6, "name")}, + {From: path.New("yaml", "storage", "luks", 5, "options", 0), To: path.New("json", "spec", "config", "storage", "luks", 6, "options", 0)}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 6, "options", 1)}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "config", "storage", "luks", 6, "options", 2)}, + {From: path.New("yaml", "storage", "luks", 5, "options"), To: path.New("json", "spec", "config", "storage", "luks", 6, "options")}, + {From: path.New("yaml", "storage", "luks", 5), To: path.New("json", "spec", "config", "storage", "luks", 6)}, + {From: path.New("yaml", "storage", "luks"), To: path.New("json", "spec", "config", "storage", "luks")}, + {From: path.New("yaml", "boot_device"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "device")}, + {From: path.New("yaml", "boot_device"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "format")}, + {From: path.New("yaml", "boot_device"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "label")}, + {From: path.New("yaml", "boot_device"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "wipeFilesystem")}, + {From: path.New("yaml", "boot_device"), To: path.New("json", "spec", "config", "storage", "filesystems", 0)}, + {From: path.New("yaml", "boot_device"), To: path.New("json", "spec", "config", "storage", "filesystems")}, + {From: path.New("yaml", "storage"), To: path.New("json", "spec", "config", "storage")}, + {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "fips")}, + }, + }, + // Test Grub config + { + Config{ + Metadata: Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + Config: fcos.Config{ + Grub: fcos.Grub{ + Users: []fcos.GrubUser{ + { + Name: "root", + PasswordHash: util.StrToPtr("grub.pbkdf2.sha512.10000.874A958E526409..."), + }, + }, + }, + }, + }, + result.MachineConfig{ + ApiVersion: result.MC_API_VERSION, + Kind: result.MC_KIND, + Metadata: result.Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + Spec: result.Spec{ + Config: types.Config{ + Ignition: types.Ignition{ + Version: "3.5.0-experimental", + }, + Storage: types.Storage{ + Filesystems: []types.Filesystem{ + { + Device: "/dev/disk/by-label/boot", + Format: util.StrToPtr("ext4"), + Path: util.StrToPtr("/boot"), + }, + }, + Files: []types.File{ + { + Node: types.Node{ + Path: "/boot/grub2/user.cfg", + }, + FileEmbedded1: types.FileEmbedded1{ + Contents: types.Resource{ + Source: util.StrToPtr("data:,%23%20Generated%20by%20Butane%0A%0Aset%20superusers%3D%22root%22%0Apassword_pbkdf2%20root%20grub.pbkdf2.sha512.10000.874A958E526409...%0A"), + Compression: util.StrToPtr(""), + }, + }, + }, + }, + }, + }, + }, + }, + []translate.Translation{ + {From: path.New("yaml", "version"), To: path.New("json", "apiVersion")}, + {From: path.New("yaml", "version"), To: path.New("json", "kind")}, + {From: path.New("yaml", "version"), To: path.New("json", "spec")}, + {From: path.New("yaml"), To: path.New("json", "spec", "config")}, + {From: path.New("yaml", "ignition"), To: path.New("json", "spec", "config", "ignition")}, + {From: path.New("yaml", "version"), To: path.New("json", "spec", "config", "ignition", "version")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems", 0)}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "path")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "device")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "format")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0)}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "path")}, + // "append" field is a remnant of translations performed in fcos config + // TODO: add a delete function to translation.TranslationSet and delete "append" translation + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "append")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "contents")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "contents", "source")}, + {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "contents", "compression")}, + }, + }, + } + + for i, test := range tests { + t.Run(fmt.Sprintf("translate %d", i), func(t *testing.T) { + actual, translations, r := test.in.ToMachineConfig4_14Unvalidated(common.TranslateOptions{}) + r = confutil.TranslateReportPaths(r, translations) + baseutil.VerifyReport(t, test.in, r) + assert.Equal(t, test.out, actual, "translation mismatch") + assert.Equal(t, report.Report{}, r, "non-empty report") + baseutil.VerifyTranslations(t, translations, test.exceptions) + assert.NoError(t, translations.DebugVerifyCoverage(actual), "incomplete TranslationSet coverage") + }) + } +} + +// Test post-translation validation of RHCOS/MCO support for Ignition config fields. +func TestValidateSupport(t *testing.T) { + type entry struct { + kind report.EntryKind + err error + path path.ContextPath + } + tests := []struct { + in Config + entries []entry + }{ + // empty-ish config + { + Config{ + Metadata: Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + }, + []entry{}, + }, + // core user with only accepted fields + { + Config{ + Metadata: Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + Config: fcos.Config{ + Config: base.Config{ + Passwd: base.Passwd{ + Users: []base.PasswdUser{ + { + Name: "core", + PasswordHash: util.StrToPtr("corned beef"), + SSHAuthorizedKeys: []base.SSHAuthorizedKey{"value"}, + }, + }, + }, + }, + }, + }, + []entry{}, + }, + // valid data URL + { + Config{ + Metadata: Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + Config: fcos.Config{ + Config: base.Config{ + Storage: base.Storage{ + Files: []base.File{ + { + Path: "/f", + Contents: base.Resource{ + Source: util.StrToPtr("data:,foo"), + }, + }, + }, + }, + }, + }, + }, + []entry{}, + }, + // all the warnings/errors + { + Config{ + Metadata: Metadata{ + Name: "z", + Labels: map[string]string{ + ROLE_LABEL_KEY: "z", + }, + }, + Config: fcos.Config{ + Config: base.Config{ + Storage: base.Storage{ + Files: []base.File{ + { + Path: "/f", + }, + { + Path: "/g", + Append: []base.Resource{ + { + Inline: util.StrToPtr("z"), + }, + }, + }, + { + Path: "/h", + Contents: base.Resource{ + Source: util.StrToPtr("https://example.com/"), + }, + Mode: util.IntToPtr(04755), + }, + { + Path: "/i", + Contents: base.Resource{ + Source: util.StrToPtr("data:,z"), + HTTPHeaders: base.HTTPHeaders{ + { + Name: "foo", + Value: util.StrToPtr("bar"), + }, + }, + }, + }, + }, + Filesystems: []base.Filesystem{ + { + Device: "/dev/vda4", + Format: util.StrToPtr("btrfs"), + }, + { + Device: "/dev/vda5", + Format: util.StrToPtr("none"), + }, + }, + Directories: []base.Directory{ + { + Path: "/d", + }, + }, + Links: []base.Link{ + { + Path: "/l", + Target: util.StrToPtr("/t"), + }, + }, + }, + Passwd: base.Passwd{ + Users: []base.PasswdUser{ + { + Name: "core", + Gecos: util.StrToPtr("mercury delay line"), + Groups: []base.Group{ + "z", + }, + HomeDir: util.StrToPtr("/home/drum"), + NoCreateHome: util.BoolToPtr(true), + NoLogInit: util.BoolToPtr(true), + NoUserGroup: util.BoolToPtr(true), + PasswordHash: util.StrToPtr("corned beef"), + PrimaryGroup: util.StrToPtr("wheel"), + SSHAuthorizedKeys: []base.SSHAuthorizedKey{"value"}, + SSHAuthorizedKeysLocal: []string{}, + Shell: util.StrToPtr("/bin/tcsh"), + ShouldExist: util.BoolToPtr(false), + System: util.BoolToPtr(true), + UID: util.IntToPtr(42), + }, + { + Name: "bovik", + }, + }, + Groups: []base.PasswdGroup{ + { + Name: "mock", + }, + }, + }, + KernelArguments: base.KernelArguments{ + ShouldExist: []base.KernelArgument{ + "foo", + }, + ShouldNotExist: []base.KernelArgument{ + "bar", + }, + }, + }, + }, + }, + []entry{ + // code + {report.Error, common.ErrBtrfsSupport, path.New("yaml", "storage", "filesystems", 0, "format")}, + {report.Error, common.ErrFilesystemNoneSupport, path.New("yaml", "storage", "filesystems", 1, "format")}, + {report.Error, common.ErrFileSchemeSupport, path.New("yaml", "storage", "files", 2, "contents", "source")}, + {report.Error, common.ErrFileSpecialModeSupport, path.New("yaml", "storage", "files", 2, "mode")}, + {report.Error, common.ErrUserNameSupport, path.New("yaml", "passwd", "users", 1, "name")}, + // filters + {report.Error, common.ErrKernelArgumentSupport, path.New("yaml", "kernel_arguments")}, + {report.Error, common.ErrGroupSupport, path.New("yaml", "passwd", "groups")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "gecos")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "groups")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "home_dir")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "no_create_home")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "no_log_init")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "no_user_group")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "primary_group")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "shell")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "should_exist")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "system")}, + {report.Error, common.ErrUserFieldSupport, path.New("yaml", "passwd", "users", 0, "uid")}, + {report.Error, common.ErrDirectorySupport, path.New("yaml", "storage", "directories")}, + {report.Error, common.ErrFileAppendSupport, path.New("yaml", "storage", "files", 1, "append")}, + {report.Error, common.ErrFileHeaderSupport, path.New("yaml", "storage", "files", 3, "contents", "http_headers")}, + {report.Error, common.ErrLinkSupport, path.New("yaml", "storage", "links")}, + }, + }, + } + + for i, test := range tests { + t.Run(fmt.Sprintf("translate %d", i), func(t *testing.T) { + var expectedReport report.Report + for _, entry := range test.entries { + expectedReport.AddOn(entry.path, entry.err, entry.kind) + } + actual, translations, r := test.in.ToMachineConfig4_14Unvalidated(common.TranslateOptions{}) + r.Merge(fieldFilters.Verify(actual)) + r = confutil.TranslateReportPaths(r, translations) + baseutil.VerifyReport(t, test.in, r) + assert.Equal(t, expectedReport, r, "report mismatch") + assert.NoError(t, translations.DebugVerifyCoverage(actual), "incomplete TranslationSet coverage") + }) + } +} diff --git a/config/openshift/v4_15_exp/validate.go b/config/openshift/v4_15_exp/validate.go new file mode 100644 index 00000000..35b41f00 --- /dev/null +++ b/config/openshift/v4_15_exp/validate.go @@ -0,0 +1,43 @@ +// Copyright 2021 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v4_14_exp + +import ( + "github.com/coreos/butane/config/common" + + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" +) + +func (m Metadata) Validate(c path.ContextPath) (r report.Report) { + if m.Name == "" { + r.AddOnError(c.Append("name"), common.ErrNameRequired) + } + if m.Labels[ROLE_LABEL_KEY] == "" { + r.AddOnError(c.Append("labels"), common.ErrRoleRequired) + } + return +} + +func (os OpenShift) Validate(c path.ContextPath) (r report.Report) { + if os.KernelType != nil { + switch *os.KernelType { + case "", "default", "realtime": + default: + r.AddOnError(c.Append("kernel_type"), common.ErrInvalidKernelType) + } + } + return +} diff --git a/config/openshift/v4_15_exp/validate_test.go b/config/openshift/v4_15_exp/validate_test.go new file mode 100644 index 00000000..66966bbd --- /dev/null +++ b/config/openshift/v4_15_exp/validate_test.go @@ -0,0 +1,254 @@ +// Copyright 2021 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v4_14_exp + +import ( + "fmt" + "testing" + + baseutil "github.com/coreos/butane/base/util" + "github.com/coreos/butane/config/common" + + "github.com/coreos/ignition/v2/config/shared/errors" + "github.com/coreos/ignition/v2/config/util" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + "github.com/stretchr/testify/assert" +) + +func TestValidateMetadata(t *testing.T) { + tests := []struct { + in Metadata + out error + errPath path.ContextPath + }{ + // missing name + { + Metadata{ + Labels: map[string]string{ + ROLE_LABEL_KEY: "r", + }, + }, + common.ErrNameRequired, + path.New("yaml", "name"), + }, + // missing role + { + Metadata{ + Name: "n", + }, + common.ErrRoleRequired, + path.New("yaml", "labels"), + }, + // empty role + { + Metadata{ + Name: "n", + Labels: map[string]string{ + ROLE_LABEL_KEY: "", + }, + }, + common.ErrRoleRequired, + path.New("yaml", "labels"), + }, + } + + for i, test := range tests { + t.Run(fmt.Sprintf("validate %d", i), func(t *testing.T) { + actual := test.in.Validate(path.New("yaml")) + baseutil.VerifyReport(t, test.in, actual) + expected := report.Report{} + expected.AddOnError(test.errPath, test.out) + assert.Equal(t, expected, actual, "bad report") + }) + } +} + +func TestValidateOpenShift(t *testing.T) { + tests := []struct { + in OpenShift + out error + errPath path.ContextPath + }{ + // empty struct + { + OpenShift{}, + nil, + path.New("yaml"), + }, + // bad kernel type + { + OpenShift{ + KernelType: util.StrToPtr("hurd"), + }, + common.ErrInvalidKernelType, + path.New("yaml", "kernel_type"), + }, + } + + for i, test := range tests { + t.Run(fmt.Sprintf("validate %d", i), func(t *testing.T) { + actual := test.in.Validate(path.New("yaml")) + baseutil.VerifyReport(t, test.in, actual) + expected := report.Report{} + expected.AddOnError(test.errPath, test.out) + assert.Equal(t, expected, actual, "bad report") + }) + } +} + +// TestReportCorrelation tests that errors are correctly correlated to their source lines +func TestReportCorrelation(t *testing.T) { + tests := []struct { + in string + message string + line int64 + }{ + // Butane unused key check + { + ` + metadata: + name: something + labels: + machineconfiguration.openshift.io/role: r + storage: + files: + - path: /z + q: z`, + "Unused key q", + 9, + }, + // Butane YAML validation error + { + ` + metadata: + name: something + labels: + machineconfiguration.openshift.io/role: r + storage: + files: + - path: /z + contents: + source: https://example.com + inline: z`, + common.ErrTooManyResourceSources.Error(), + 10, + }, + // Butane YAML validation warning + { + ` + metadata: + name: something + labels: + machineconfiguration.openshift.io/role: r + storage: + files: + - path: /z + mode: 444`, + common.ErrDecimalMode.Error(), + 9, + }, + // Butane translation error + { + ` + metadata: + name: something + labels: + machineconfiguration.openshift.io/role: r + storage: + files: + - path: /z + contents: + local: z`, + common.ErrNoFilesDir.Error(), + 10, + }, + // Ignition validation error, leaf node + { + ` + metadata: + name: something + labels: + machineconfiguration.openshift.io/role: r + storage: + files: + - path: z`, + errors.ErrPathRelative.Error(), + 8, + }, + // Ignition validation error, partition + { + ` + metadata: + name: something + labels: + machineconfiguration.openshift.io/role: r + storage: + disks: + - device: /dev/z + wipe_table: true + partitions: + - start_mib: 5`, + errors.ErrNeedLabelOrNumber.Error(), + 11, + }, + // Ignition validation error, partition list + { + ` + metadata: + name: something + labels: + machineconfiguration.openshift.io/role: r + storage: + disks: + - device: /dev/z + wipe_table: true + partitions: + - number: 1 + should_exist: false + - label: z`, + errors.ErrZeroesWithShouldNotExist.Error(), + 11, + }, + // Ignition duplicate key check, paths + { + ` + metadata: + name: something + labels: + machineconfiguration.openshift.io/role: r + storage: + files: + - path: /z + - path: /z`, + errors.ErrDuplicate.Error(), + 9, + }, + } + + for i, test := range tests { + t.Run(fmt.Sprintf("validate %d", i), func(t *testing.T) { + for _, raw := range []bool{false, true} { + _, r, _ := ToConfigBytes([]byte(test.in), common.TranslateBytesOptions{ + Raw: raw, + }) + assert.Len(t, r.Entries, 1, "unexpected report length, raw %v", raw) + assert.Equal(t, test.message, r.Entries[0].Message, "bad error, raw %v", raw) + assert.NotNil(t, r.Entries[0].Marker.StartP, "marker start is nil, raw %v", raw) + assert.Equal(t, test.line, r.Entries[0].Marker.StartP.Line, "incorrect error line, raw %v", raw) + } + }) + } +} From a7b25508e84d921c0228738491feb4dcbffb948e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Thu, 14 Sep 2023 11:59:38 +0200 Subject: [PATCH 03/16] openshift/v4_15_exp: Update spec to 4.15.0-experimental --- config/config.go | 2 + config/openshift/v4_15_exp/schema.go | 2 +- config/openshift/v4_15_exp/translate.go | 20 +-- config/openshift/v4_15_exp/translate_test.go | 8 +- config/openshift/v4_15_exp/validate.go | 2 +- config/openshift/v4_15_exp/validate_test.go | 2 +- docs/config-openshift-v4_15-exp.md | 180 +++++++++++++++++++ docs/specs.md | 3 +- internal/doc/main.go | 2 + 9 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 docs/config-openshift-v4_15-exp.md diff --git a/config/config.go b/config/config.go index 7d1c02a8..d9ddc0d9 100644 --- a/config/config.go +++ b/config/config.go @@ -33,6 +33,7 @@ import ( openshift4_12 "github.com/coreos/butane/config/openshift/v4_12" openshift4_13 "github.com/coreos/butane/config/openshift/v4_13" openshift4_14_exp "github.com/coreos/butane/config/openshift/v4_14_exp" + openshift4_15_exp "github.com/coreos/butane/config/openshift/v4_15_exp" openshift4_8 "github.com/coreos/butane/config/openshift/v4_8" openshift4_9 "github.com/coreos/butane/config/openshift/v4_9" r4e1_0 "github.com/coreos/butane/config/r4e/v1_0" @@ -72,6 +73,7 @@ func init() { RegisterTranslator("openshift", "4.12.0", openshift4_12.ToConfigBytes) RegisterTranslator("openshift", "4.13.0", openshift4_13.ToConfigBytes) RegisterTranslator("openshift", "4.14.0-experimental", openshift4_14_exp.ToConfigBytes) + RegisterTranslator("openshift", "4.15.0-experimental", openshift4_15_exp.ToConfigBytes) RegisterTranslator("r4e", "1.0.0", r4e1_0.ToIgn3_3Bytes) RegisterTranslator("r4e", "1.1.0", r4e1_1.ToIgn3_4Bytes) RegisterTranslator("r4e", "1.2.0-experimental", r4e1_2_exp.ToIgn3_5Bytes) diff --git a/config/openshift/v4_15_exp/schema.go b/config/openshift/v4_15_exp/schema.go index 16d45ab4..5ed101e3 100644 --- a/config/openshift/v4_15_exp/schema.go +++ b/config/openshift/v4_15_exp/schema.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_15_exp import ( fcos "github.com/coreos/butane/config/fcos/v1_6_exp" diff --git a/config/openshift/v4_15_exp/translate.go b/config/openshift/v4_15_exp/translate.go index bbd05f23..8ba7be9d 100644 --- a/config/openshift/v4_15_exp/translate.go +++ b/config/openshift/v4_15_exp/translate.go @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_15_exp import ( "net/url" "strings" "github.com/coreos/butane/config/common" - "github.com/coreos/butane/config/openshift/v4_14_exp/result" + "github.com/coreos/butane/config/openshift/v4_15_exp/result" cutil "github.com/coreos/butane/config/util" "github.com/coreos/butane/translate" @@ -108,11 +108,11 @@ func (c Config) FieldFilters() *cutil.FieldFilters { return &fieldFilters } -// ToMachineConfig4_14Unvalidated translates the config to a MachineConfig. It also +// ToMachineConfig4_15Unvalidated translates the config to a MachineConfig. It also // returns the set of translations it did so paths in the resultant config // can be tracked back to their source in the source config. No config // validation is performed on input or output. -func (c Config) ToMachineConfig4_14Unvalidated(options common.TranslateOptions) (result.MachineConfig, translate.TranslationSet, report.Report) { +func (c Config) ToMachineConfig4_15Unvalidated(options common.TranslateOptions) (result.MachineConfig, translate.TranslationSet, report.Report) { cfg, ts, r := c.Config.ToIgn3_5Unvalidated(options) if r.IsFatal() { return result.MachineConfig{}, ts, r @@ -165,12 +165,12 @@ func (c Config) ToMachineConfig4_14Unvalidated(options common.TranslateOptions) return mc, ts, r } -// ToMachineConfig4_14 translates the config to a MachineConfig. It returns a +// ToMachineConfig4_15 translates the config to a MachineConfig. It returns a // report of any errors or warnings in the source and resultant config. If // the report has fatal errors or it encounters other problems translating, // an error is returned. -func (c Config) ToMachineConfig4_14(options common.TranslateOptions) (result.MachineConfig, report.Report, error) { - cfg, r, err := cutil.Translate(c, "ToMachineConfig4_14Unvalidated", options) +func (c Config) ToMachineConfig4_15(options common.TranslateOptions) (result.MachineConfig, report.Report, error) { + cfg, r, err := cutil.Translate(c, "ToMachineConfig4_15Unvalidated", options) return cfg.(result.MachineConfig), r, err } @@ -179,7 +179,7 @@ func (c Config) ToMachineConfig4_14(options common.TranslateOptions) (result.Mac // can be tracked back to their source in the source config. No config // validation is performed on input or output. func (c Config) ToIgn3_5Unvalidated(options common.TranslateOptions) (types.Config, translate.TranslationSet, report.Report) { - mc, ts, r := c.ToMachineConfig4_14Unvalidated(options) + mc, ts, r := c.ToMachineConfig4_15Unvalidated(options) cfg := mc.Spec.Config // report warnings if there are any non-empty fields in Spec (other @@ -203,14 +203,14 @@ func (c Config) ToIgn3_5(options common.TranslateOptions) (types.Config, report. return cfg.(types.Config), r, err } -// ToConfigBytes translates from a v4.14 Butane config to a v4.14 MachineConfig or a v3.4.0 Ignition config. It returns a report of any errors or +// ToConfigBytes translates from a v4.15 Butane config to a v4.15 MachineConfig or a v3.5.0 Ignition config. It returns a report of any errors or // warnings in the source and resultant config. If the report has fatal errors or it encounters other problems // translating, an error is returned. func ToConfigBytes(input []byte, options common.TranslateBytesOptions) ([]byte, report.Report, error) { if options.Raw { return cutil.TranslateBytes(input, &Config{}, "ToIgn3_5", options) } else { - return cutil.TranslateBytesYAML(input, &Config{}, "ToMachineConfig4_14", options) + return cutil.TranslateBytesYAML(input, &Config{}, "ToMachineConfig4_15", options) } } diff --git a/config/openshift/v4_15_exp/translate_test.go b/config/openshift/v4_15_exp/translate_test.go index edda5b2c..f9a10754 100644 --- a/config/openshift/v4_15_exp/translate_test.go +++ b/config/openshift/v4_15_exp/translate_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_15_exp import ( "fmt" @@ -22,7 +22,7 @@ import ( base "github.com/coreos/butane/base/v0_6_exp" "github.com/coreos/butane/config/common" fcos "github.com/coreos/butane/config/fcos/v1_6_exp" - "github.com/coreos/butane/config/openshift/v4_14_exp/result" + "github.com/coreos/butane/config/openshift/v4_15_exp/result" confutil "github.com/coreos/butane/config/util" "github.com/coreos/butane/translate" @@ -359,7 +359,7 @@ func TestTranslateConfig(t *testing.T) { for i, test := range tests { t.Run(fmt.Sprintf("translate %d", i), func(t *testing.T) { - actual, translations, r := test.in.ToMachineConfig4_14Unvalidated(common.TranslateOptions{}) + actual, translations, r := test.in.ToMachineConfig4_15Unvalidated(common.TranslateOptions{}) r = confutil.TranslateReportPaths(r, translations) baseutil.VerifyReport(t, test.in, r) assert.Equal(t, test.out, actual, "translation mismatch") @@ -587,7 +587,7 @@ func TestValidateSupport(t *testing.T) { for _, entry := range test.entries { expectedReport.AddOn(entry.path, entry.err, entry.kind) } - actual, translations, r := test.in.ToMachineConfig4_14Unvalidated(common.TranslateOptions{}) + actual, translations, r := test.in.ToMachineConfig4_15Unvalidated(common.TranslateOptions{}) r.Merge(fieldFilters.Verify(actual)) r = confutil.TranslateReportPaths(r, translations) baseutil.VerifyReport(t, test.in, r) diff --git a/config/openshift/v4_15_exp/validate.go b/config/openshift/v4_15_exp/validate.go index 35b41f00..715797d3 100644 --- a/config/openshift/v4_15_exp/validate.go +++ b/config/openshift/v4_15_exp/validate.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_15_exp import ( "github.com/coreos/butane/config/common" diff --git a/config/openshift/v4_15_exp/validate_test.go b/config/openshift/v4_15_exp/validate_test.go index 66966bbd..ce9db95f 100644 --- a/config/openshift/v4_15_exp/validate_test.go +++ b/config/openshift/v4_15_exp/validate_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_15_exp import ( "fmt" diff --git a/docs/config-openshift-v4_15-exp.md b/docs/config-openshift-v4_15-exp.md new file mode 100644 index 00000000..c6fa8f64 --- /dev/null +++ b/docs/config-openshift-v4_15-exp.md @@ -0,0 +1,180 @@ +--- +# This file is automatically generated from internal/doc and Ignition's +# config/doc. Do not edit. +title: OpenShift v4.15.0-experimental +parent: Configuration specifications +nav_order: 150 +--- + +# OpenShift Specification v4.15.0-experimental + +**Note: This configuration is experimental and has not been stabilized. It is subject to change without warning or announcement.** + +The OpenShift configuration is a YAML document conforming to the following specification, with **_italicized_** entries being optional: + +
+ +* **variant** (string): used to differentiate configs for different operating systems. Must be `openshift` for this specification. +* **version** (string): the semantic version of the spec for this document. This document is for version `4.15.0-experimental` and generates Ignition configs with version `3.5.0-experimental`. +* **metadata** (object): metadata about the generated MachineConfig resource. Respected when rendering to a MachineConfig, ignored when rendering directly to an Ignition config. + * **name** (string): a unique [name](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names) for this MachineConfig resource. + * **labels** (object): string key/value pairs to apply as [Kubernetes labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) to this MachineConfig resource. `machineconfiguration.openshift.io/role` is required. +* **_ignition_** (object): metadata about the configuration itself. + * **_config_** (object): options related to the configuration. + * **_merge_** (list of objects): a list of the configs to be merged to the current config. + * **_source_** (string): the URL of the config. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the config. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the config, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the config (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the config. + * **_hash_** (string): the hash of the config, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed config. + * **_replace_** (object): the config that will replace the current. + * **_source_** (string): the URL of the config. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the config. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the config, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the config (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the config. + * **_hash_** (string): the hash of the config, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed config. + * **_timeouts_** (object): options relating to `http` timeouts when fetching files over `http` or `https`. + * **_http_response_headers_** (integer): the time to wait (in seconds) for the server's response headers (but not the body) after making a request. 0 indicates no timeout. Default is 10 seconds. + * **_http_total_** (integer): the time limit (in seconds) for the operation (connection, request, and response), including retries. 0 indicates no timeout. Default is 0. + * **_security_** (object): options relating to network security. + * **_tls_** (object): options relating to TLS when fetching resources over `https`. + * **_certificate_authorities_** (list of objects): the list of additional certificate authorities (in addition to the system authorities) to be used for TLS verification when fetching over `https`. All certificate authorities must have a unique `source`, `inline`, or `local`. + * **_source_** (string): the URL of the certificate bundle (in PEM format). The bundle can contain multiple concatenated certificates. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the certificate bundle (in PEM format). The bundle can contain multiple concatenated certificates. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the certificate bundle (in PEM format), relative to the directory specified by the `--files-dir` command-line argument. The bundle can contain multiple concatenated certificates. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the certificate bundle (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the certificate bundle. + * **_hash_** (string): the hash of the certificate bundle, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed certificate bundle. + * **_proxy_** (object): options relating to setting an `HTTP(S)` proxy when fetching resources. + * **_http_proxy_** (string): will be used as the proxy URL for HTTP requests and HTTPS requests unless overridden by `https_proxy` or `no_proxy`. + * **_https_proxy_** (string): will be used as the proxy URL for HTTPS requests unless overridden by `no_proxy`. + * **_no_proxy_** (list of strings): specifies a list of strings to hosts that should be excluded from proxying. Each value is represented by an `IP address prefix (1.2.3.4)`, `an IP address prefix in CIDR notation (1.2.3.4/8)`, `a domain name`, or `a special DNS label (*)`. An IP address prefix and domain name can also include a literal port number `(1.2.3.4:80)`. A domain name matches that name and all subdomains. A domain name with a leading `.` matches subdomains only. For example `foo.com` matches `foo.com` and `bar.foo.com`; `.y.com` matches `x.y.com` but not `y.com`. A single asterisk `(*)` indicates that no proxying should be done. +* **_storage_** (object): describes the desired state of the system's storage devices. + * **_disks_** (list of objects): the list of disks to be configured and their options. Every entry must have a unique `device`. + * **device** (string): the absolute path to the device. Devices are typically referenced by the `/dev/disk/by-*` symlinks. The boot disk can be referenced as `/dev/disk/by-id/coreos-boot-disk`. + * **_wipe_table_** (boolean): whether or not the partition tables shall be wiped. When true, the partition tables are erased before any further manipulation. Otherwise, the existing entries are left intact. + * **_partitions_** (list of objects): the list of partitions and their configuration for this particular disk. Every partition must have a unique `number`, or if 0 is specified, a unique `label`. + * **_label_** (string): the PARTLABEL for the partition. + * **_number_** (integer): the partition number, which dictates its position in the partition table (one-indexed). If zero, use the next available partition slot. + * **_size_mib_** (integer): the size of the partition (in mebibytes). If zero, the partition will be made as large as possible. + * **_start_mib_** (integer): the start of the partition (in mebibytes). If zero, the partition will be positioned at the start of the largest block available. + * **_type_guid_** (string): the GPT [partition type GUID](https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_type_GUIDs). If omitted, the default will be 0FC63DAF-8483-4772-8E79-3D69D8477DE4 (Linux filesystem data). + * **_guid_** (string): the GPT unique partition GUID. + * **_wipe_partition_entry_** (boolean): if true, Ignition will clobber an existing partition if it does not match the config. If false (default), Ignition will fail instead. + * **_should_exist_** (boolean): whether or not the partition with the specified `number` should exist. If omitted, it defaults to true. If false Ignition will either delete the specified partition or fail, depending on `wipePartitionEntry`. If false `number` must be specified and non-zero and `label`, `start`, `size`, `guid`, and `typeGuid` must all be omitted. + * **_resize_** (boolean): whether or not the existing partition should be resized. If omitted, it defaults to false. If true, Ignition will resize an existing partition if it matches the config in all respects except the partition size. + * **_raid_** (list of objects): the list of RAID arrays to be configured. Every RAID array must have a unique `name`. + * **name** (string): the name to use for the resulting md device. + * **level** (string): the redundancy level of the array (e.g. linear, raid1, raid5, etc.). + * **devices** (list of strings): the list of devices (referenced by their absolute path) in the array. + * **_spares_** (integer): the number of spares (if applicable) in the array. + * **_options_** (list of strings): any additional options to be passed to mdadm. + * **_filesystems_** (list of objects): the list of filesystems to be configured. `device` and `format` need to be specified. Every filesystem must have a unique `device`. + * **device** (string): the absolute path to the device. Devices are typically referenced by the `/dev/disk/by-*` symlinks. + * **format** (string): the filesystem format (ext4, xfs, vfat, or swap). + * **_path_** (string): the mount-point of the filesystem while Ignition is running relative to where the root filesystem will be mounted. This is not necessarily the same as where it should be mounted in the real root, but it is encouraged to make it the same. + * **_wipe_filesystem_** (boolean): whether or not to wipe the device before filesystem creation, see [Ignition's documentation on filesystems](https://coreos.github.io/ignition/operator-notes/#filesystem-reuse-semantics) for more information. Defaults to false. + * **_label_** (string): the label of the filesystem. + * **_uuid_** (string): the uuid of the filesystem. + * **_options_** (list of strings): any additional options to be passed to the format-specific mkfs utility. + * **_mount_options_** (list of strings): any special options to be passed to the mount command. + * **_with_mount_unit_** (boolean): whether to additionally generate a generic mount unit for this filesystem or a swap unit for this swap area. If a more specific unit is needed, a custom one can be specified in the `systemd.units` section. The unit will be named with the [escaped](https://www.freedesktop.org/software/systemd/man/systemd-escape.html) version of the `path` or `device`, depending on the unit type. If your filesystem is located on a Tang-backed LUKS device, the unit will automatically require network access if you specify the device as `/dev/mapper/` or `/dev/disk/by-id/dm-name-`. + * **_files_** (list of objects): the list of files to be written. Every file, directory and link must have a unique `path`. + * **path** (string): the absolute path to the file. + * **_overwrite_** (boolean): whether to delete preexisting nodes at the path. `contents` must be specified if `overwrite` is true. Defaults to false. + * **_contents_** (object): options related to the contents of the file. + * **_source_** (string): the URL of the file. Only the [`data`](https://tools.ietf.org/html/rfc2397) scheme is supported. If source is omitted and a regular file already exists at the path, Ignition will do nothing. If source is omitted and no file exists, an empty file will be created. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the file. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the file, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the file (null or gzip). Compression cannot be used with S3. + * **_verification_** (object): options related to the verification of the file. + * **_hash_** (string): the hash of the file, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed file. + * **_mode_** (integer): the file's permission mode. Setuid/setgid/sticky bits are not supported. If not specified, the permission mode for files defaults to 0644 or the existing file's permissions if `overwrite` is false, `contents` is unspecified, and a file already exists at the path. + * **_user_** (object): specifies the file's owner. + * **_id_** (integer): the user ID of the owner. + * **_name_** (string): the user name of the owner. + * **_group_** (object): specifies the file's group. + * **_id_** (integer): the group ID of the group. + * **_name_** (string): the group name of the group. + * **_luks_** (list of objects): the list of luks devices to be created. Every device must have a unique `name`. + * **name** (string): the name of the luks device. + * **device** (string): the absolute path to the device. Devices are typically referenced by the `/dev/disk/by-*` symlinks. + * **_key_file_** (object): options related to the contents of the key file. + * **_source_** (string): the URL of the key file. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the key file. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the key file, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the key file (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the key file. + * **_hash_** (string): the hash of the key file, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed key file. + * **_label_** (string): the label of the luks device. + * **_uuid_** (string): the uuid of the luks device. + * **_options_** (list of strings): any additional options to be passed to `cryptsetup luksFormat`. + * **_discard_** (boolean): whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. + * **_open_options_** (list of strings): any additional options to be passed to `cryptsetup luksOpen`. Supported options will be persistently written to the luks volume. + * **_wipe_volume_** (boolean): whether or not to wipe the device before volume creation, see [Ignition's documentation on filesystems](https://coreos.github.io/ignition/operator-notes/#filesystem-reuse-semantics) for more information. + * **_clevis_** (object): describes the clevis configuration for the luks device. + * **_tang_** (list of objects): describes a tang server. Every server must have a unique `url`. + * **url** (string): url of the tang server. + * **thumbprint** (string): thumbprint of a trusted signing key. + * **_advertisement_** (string): the advertisement JSON. If not specified, the advertisement is fetched from the tang server during provisioning. + * **_tpm2_** (boolean): whether or not to use a tpm2 device. + * **_threshold_** (integer): sets the minimum number of pieces required to decrypt the device. Default is 1. + * **_custom_** (object): overrides the clevis configuration. The `pin` & `config` will be passed directly to `clevis luks bind`. If specified, all other clevis options must be omitted. + * **pin** (string): the clevis pin. + * **config** (string): the clevis configuration JSON. + * **_needs_network_** (boolean): whether or not the device requires networking. + * **_trees_** (list of objects): a list of local directory trees to be embedded in the config. Symlinks must not be present. Ownership is not preserved. File modes are set to 0755 if the local file is executable or 0644 otherwise. File attributes can be overridden by creating a corresponding entry in the `files` section; such entries must omit `contents`. + * **local** (string): the base of the local directory tree, relative to the directory specified by the `--files-dir` command-line argument. + * **_path_** (string): the path of the tree within the target system. Defaults to `/`. +* **_systemd_** (object): describes the desired state of the systemd units. + * **_units_** (list of objects): the list of systemd units. Every unit must have a unique `name`. + * **name** (string): the name of the unit. This must be suffixed with a valid unit type (e.g. "thing.service"). + * **_enabled_** (boolean): whether or not the service shall be enabled. When true, the service is enabled. When false, the service is disabled. When omitted, the service is unmodified. In order for this to have any effect, the unit must have an install section. + * **_mask_** (boolean): whether or not the service shall be masked. When true, the service is masked by symlinking it to `/dev/null`. When false, the service is unmasked by deleting the symlink to `/dev/null` if it exists. + * **_contents_** (string): the contents of the unit. Mutually exclusive with `contents_local`. + * **_contents_local_** (string): a local path to the contents of the unit, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `contents`. + * **_dropins_** (list of objects): the list of drop-ins for the unit. Every drop-in must have a unique `name`. + * **name** (string): the name of the drop-in. This must be suffixed with ".conf". + * **_contents_** (string): the contents of the drop-in. Mutually exclusive with `contents_local`. + * **_contents_local_** (string): a local path to the contents of the drop-in, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `contents`. +* **_passwd_** (object): describes the desired additions to the passwd database. + * **_users_** (list of objects): the list of accounts that shall exist. All users must have a unique `name`. + * **name** (string): the username for the account. Must be `core`. + * **_password_hash_** (string): the hashed password for the account. + * **_ssh_authorized_keys_** (list of strings): a list of SSH keys to be added as an SSH key fragment at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. + * **_ssh_authorized_keys_local_** (list of strings): a list of local paths to SSH key files, relative to the directory specified by the `--files-dir` command-line argument, to be added as SSH key fragments at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. Each file may contain multiple SSH keys, one per line. +* **_boot_device_** (object): describes the desired boot device configuration. At least one of `luks` or `mirror` must be specified. + * **_layout_** (string): the disk layout of the target OS image. Supported values are `aarch64`, `ppc64le`, and `x86_64`. Defaults to `x86_64`. + * **_luks_** (object): describes the clevis configuration for encrypting the root filesystem. + * **_tang_** (list of objects): describes a tang server. Every server must have a unique `url`. + * **url** (string): url of the tang server. + * **thumbprint** (string): thumbprint of a trusted signing key. + * **_advertisement_** (string): the advertisement JSON. If not specified, the advertisement is fetched from the tang server during provisioning. + * **_tpm2_** (boolean): whether or not to use a tpm2 device. + * **_threshold_** (integer): sets the minimum number of pieces required to decrypt the device. Default is 1. + * **_discard_** (boolean): whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. + * **_mirror_** (object): describes mirroring of the boot disk for fault tolerance. + * **_devices_** (list of strings): the list of whole-disk devices (not partitions) to include in the disk array, referenced by their absolute path. At least two devices must be specified. +* **_grub_** (object): describes the desired GRUB bootloader configuration. + * **_users_** (list of objects): the list of GRUB superusers. + * **name** (string): the user name. + * **password_hash** (string): the PBKDF2 password hash, generated with `grub2-mkpasswd-pbkdf2`. +* **_openshift_** (object): describes miscellaneous OpenShift configuration. Respected when rendering to a MachineConfig, ignored when rendering directly to an Ignition config. + * **_kernel_type_** (string): which kernel to use on the node. Must be `default` or `realtime`. + * **_kernel_arguments_** (list of strings): arguments to be added to the kernel command line. + * **_extensions_** (list of strings): RHCOS extensions to be installed on the node. + * **_fips_** (boolean): whether or not to enable FIPS 140-2 compatibility. If omitted, defaults to false. diff --git a/docs/specs.md b/docs/specs.md index 57450037..62024934 100644 --- a/docs/specs.md +++ b/docs/specs.md @@ -44,7 +44,7 @@ Do not use **experimental** specifications for anything beyond **development and - Flatcar (`flatcar`) - [v1.2.0-experimental](config-flatcar-v1_2-exp.md) - OpenShift (`openshift`) - - [v4.14.0-experimental](config-openshift-v4_14-exp.md) + - [v4.15.0-experimental](config-openshift-v4_15-exp.md) - RHEL for Edge (`r4e`) - [v1.2.0-experimental](config-r4e-v1_2-exp.md) @@ -71,6 +71,7 @@ Each version of the Butane specification corresponds to a version of the Ignitio | `openshift` | 4.12.0 | 3.2.0 | | `openshift` | 4.13.0 | 3.2.0 | | `openshift` | 4.14.0-experimental | 3.5.0-experimental | +| `openshift` | 4.15.0-experimental | 3.5.0-experimental | | `r4e` | 1.0.0 | 3.3.0 | | `r4e` | 1.1.0 | 3.4.0 | | `r4e` | 1.2.0-experimental | 3.5.0-experimental | diff --git a/internal/doc/main.go b/internal/doc/main.go index 31d8f5de..623f95e6 100644 --- a/internal/doc/main.go +++ b/internal/doc/main.go @@ -50,6 +50,7 @@ import ( openshift4_12 "github.com/coreos/butane/config/openshift/v4_12" openshift4_13 "github.com/coreos/butane/config/openshift/v4_13" openshift4_14_exp "github.com/coreos/butane/config/openshift/v4_14_exp" + openshift4_15_exp "github.com/coreos/butane/config/openshift/v4_15_exp" openshift4_8 "github.com/coreos/butane/config/openshift/v4_8" openshift4_9 "github.com/coreos/butane/config/openshift/v4_9" r4e1_0 "github.com/coreos/butane/config/r4e/v1_0" @@ -120,6 +121,7 @@ func generate(dir string) error { "openshift", []version{ // inverse order of website navbar + {"4.15.0-experimental", openshift4_15_exp.Config{}}, {"4.14.0-experimental", openshift4_14_exp.Config{}}, {"4.8.0", openshift4_8.Config{}}, {"4.9.0", openshift4_9.Config{}}, From 186b8e8a7e2183b470f3edee967ca3da12761153 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Thu, 14 Sep 2023 15:00:26 +0200 Subject: [PATCH 04/16] openshift/v4.14: Stabilize 4.14.0 spec --- config/config.go | 4 ++-- .../{v4_14_exp => v4_14}/result/schema.go | 0 .../openshift/{v4_14_exp => v4_14}/schema.go | 2 +- .../{v4_14_exp => v4_14}/translate.go | 4 ++-- .../{v4_14_exp => v4_14}/translate_test.go | 4 ++-- .../{v4_14_exp => v4_14}/validate.go | 2 +- .../{v4_14_exp => v4_14}/validate_test.go | 2 +- ...v4_14-exp.md => config-openshift-v4_14.md} | 22 ++++--------------- docs/specs.md | 3 ++- docs/upgrading-openshift.md | 10 ++++++--- internal/doc/butane.yaml | 4 ++-- internal/doc/main.go | 4 ++-- 12 files changed, 26 insertions(+), 35 deletions(-) rename config/openshift/{v4_14_exp => v4_14}/result/schema.go (100%) rename config/openshift/{v4_14_exp => v4_14}/schema.go (98%) rename config/openshift/{v4_14_exp => v4_14}/translate.go (99%) rename config/openshift/{v4_14_exp => v4_14}/translate_test.go (99%) rename config/openshift/{v4_14_exp => v4_14}/validate.go (98%) rename config/openshift/{v4_14_exp => v4_14}/validate_test.go (99%) rename docs/{config-openshift-v4_14-exp.md => config-openshift-v4_14.md} (89%) diff --git a/config/config.go b/config/config.go index d9ddc0d9..06867585 100644 --- a/config/config.go +++ b/config/config.go @@ -32,7 +32,7 @@ import ( openshift4_11 "github.com/coreos/butane/config/openshift/v4_11" openshift4_12 "github.com/coreos/butane/config/openshift/v4_12" openshift4_13 "github.com/coreos/butane/config/openshift/v4_13" - openshift4_14_exp "github.com/coreos/butane/config/openshift/v4_14_exp" + openshift4_14 "github.com/coreos/butane/config/openshift/v4_14" openshift4_15_exp "github.com/coreos/butane/config/openshift/v4_15_exp" openshift4_8 "github.com/coreos/butane/config/openshift/v4_8" openshift4_9 "github.com/coreos/butane/config/openshift/v4_9" @@ -72,7 +72,7 @@ func init() { RegisterTranslator("openshift", "4.11.0", openshift4_11.ToConfigBytes) RegisterTranslator("openshift", "4.12.0", openshift4_12.ToConfigBytes) RegisterTranslator("openshift", "4.13.0", openshift4_13.ToConfigBytes) - RegisterTranslator("openshift", "4.14.0-experimental", openshift4_14_exp.ToConfigBytes) + RegisterTranslator("openshift", "4.14.0", openshift4_14.ToConfigBytes) RegisterTranslator("openshift", "4.15.0-experimental", openshift4_15_exp.ToConfigBytes) RegisterTranslator("r4e", "1.0.0", r4e1_0.ToIgn3_3Bytes) RegisterTranslator("r4e", "1.1.0", r4e1_1.ToIgn3_4Bytes) diff --git a/config/openshift/v4_14_exp/result/schema.go b/config/openshift/v4_14/result/schema.go similarity index 100% rename from config/openshift/v4_14_exp/result/schema.go rename to config/openshift/v4_14/result/schema.go diff --git a/config/openshift/v4_14_exp/schema.go b/config/openshift/v4_14/schema.go similarity index 98% rename from config/openshift/v4_14_exp/schema.go rename to config/openshift/v4_14/schema.go index 16d45ab4..a78c3d5a 100644 --- a/config/openshift/v4_14_exp/schema.go +++ b/config/openshift/v4_14/schema.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_14 import ( fcos "github.com/coreos/butane/config/fcos/v1_6_exp" diff --git a/config/openshift/v4_14_exp/translate.go b/config/openshift/v4_14/translate.go similarity index 99% rename from config/openshift/v4_14_exp/translate.go rename to config/openshift/v4_14/translate.go index bbd05f23..199c9e90 100644 --- a/config/openshift/v4_14_exp/translate.go +++ b/config/openshift/v4_14/translate.go @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_14 import ( "net/url" "strings" "github.com/coreos/butane/config/common" - "github.com/coreos/butane/config/openshift/v4_14_exp/result" + "github.com/coreos/butane/config/openshift/v4_14/result" cutil "github.com/coreos/butane/config/util" "github.com/coreos/butane/translate" diff --git a/config/openshift/v4_14_exp/translate_test.go b/config/openshift/v4_14/translate_test.go similarity index 99% rename from config/openshift/v4_14_exp/translate_test.go rename to config/openshift/v4_14/translate_test.go index edda5b2c..02745a53 100644 --- a/config/openshift/v4_14_exp/translate_test.go +++ b/config/openshift/v4_14/translate_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_14 import ( "fmt" @@ -22,7 +22,7 @@ import ( base "github.com/coreos/butane/base/v0_6_exp" "github.com/coreos/butane/config/common" fcos "github.com/coreos/butane/config/fcos/v1_6_exp" - "github.com/coreos/butane/config/openshift/v4_14_exp/result" + "github.com/coreos/butane/config/openshift/v4_14/result" confutil "github.com/coreos/butane/config/util" "github.com/coreos/butane/translate" diff --git a/config/openshift/v4_14_exp/validate.go b/config/openshift/v4_14/validate.go similarity index 98% rename from config/openshift/v4_14_exp/validate.go rename to config/openshift/v4_14/validate.go index 35b41f00..d1becc02 100644 --- a/config/openshift/v4_14_exp/validate.go +++ b/config/openshift/v4_14/validate.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_14 import ( "github.com/coreos/butane/config/common" diff --git a/config/openshift/v4_14_exp/validate_test.go b/config/openshift/v4_14/validate_test.go similarity index 99% rename from config/openshift/v4_14_exp/validate_test.go rename to config/openshift/v4_14/validate_test.go index 66966bbd..bf46c654 100644 --- a/config/openshift/v4_14_exp/validate_test.go +++ b/config/openshift/v4_14/validate_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License.) -package v4_14_exp +package v4_14 import ( "fmt" diff --git a/docs/config-openshift-v4_14-exp.md b/docs/config-openshift-v4_14.md similarity index 89% rename from docs/config-openshift-v4_14-exp.md rename to docs/config-openshift-v4_14.md index a3eb9c6b..6cb3a7e7 100644 --- a/docs/config-openshift-v4_14-exp.md +++ b/docs/config-openshift-v4_14.md @@ -1,21 +1,19 @@ --- # This file is automatically generated from internal/doc and Ignition's # config/doc. Do not edit. -title: OpenShift v4.14.0-experimental +title: OpenShift v4.14.0 parent: Configuration specifications -nav_order: 150 +nav_order: 143 --- -# OpenShift Specification v4.14.0-experimental - -**Note: This configuration is experimental and has not been stabilized. It is subject to change without warning or announcement.** +# OpenShift Specification v4.14.0 The OpenShift configuration is a YAML document conforming to the following specification, with **_italicized_** entries being optional:
* **variant** (string): used to differentiate configs for different operating systems. Must be `openshift` for this specification. -* **version** (string): the semantic version of the spec for this document. This document is for version `4.14.0-experimental` and generates Ignition configs with version `3.5.0-experimental`. +* **version** (string): the semantic version of the spec for this document. This document is for version `4.14.0` and generates Ignition configs with version `3.5.0-experimental`. * **metadata** (object): metadata about the generated MachineConfig resource. Respected when rendering to a MachineConfig, ignored when rendering directly to an Ignition config. * **name** (string): a unique [name](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names) for this MachineConfig resource. * **labels** (object): string key/value pairs to apply as [Kubernetes labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) to this MachineConfig resource. `machineconfiguration.openshift.io/role` is required. @@ -123,14 +121,11 @@ The OpenShift configuration is a YAML document conforming to the following speci * **_label_** (string): the label of the luks device. * **_uuid_** (string): the uuid of the luks device. * **_options_** (list of strings): any additional options to be passed to `cryptsetup luksFormat`. - * **_discard_** (boolean): whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. - * **_open_options_** (list of strings): any additional options to be passed to `cryptsetup luksOpen`. Supported options will be persistently written to the luks volume. * **_wipe_volume_** (boolean): whether or not to wipe the device before volume creation, see [Ignition's documentation on filesystems](https://coreos.github.io/ignition/operator-notes/#filesystem-reuse-semantics) for more information. * **_clevis_** (object): describes the clevis configuration for the luks device. * **_tang_** (list of objects): describes a tang server. Every server must have a unique `url`. * **url** (string): url of the tang server. * **thumbprint** (string): thumbprint of a trusted signing key. - * **_advertisement_** (string): the advertisement JSON. If not specified, the advertisement is fetched from the tang server during provisioning. * **_tpm2_** (boolean): whether or not to use a tpm2 device. * **_threshold_** (integer): sets the minimum number of pieces required to decrypt the device. Default is 1. * **_custom_** (object): overrides the clevis configuration. The `pin` & `config` will be passed directly to `clevis luks bind`. If specified, all other clevis options must be omitted. @@ -146,33 +141,24 @@ The OpenShift configuration is a YAML document conforming to the following speci * **_enabled_** (boolean): whether or not the service shall be enabled. When true, the service is enabled. When false, the service is disabled. When omitted, the service is unmodified. In order for this to have any effect, the unit must have an install section. * **_mask_** (boolean): whether or not the service shall be masked. When true, the service is masked by symlinking it to `/dev/null`. When false, the service is unmasked by deleting the symlink to `/dev/null` if it exists. * **_contents_** (string): the contents of the unit. Mutually exclusive with `contents_local`. - * **_contents_local_** (string): a local path to the contents of the unit, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `contents`. * **_dropins_** (list of objects): the list of drop-ins for the unit. Every drop-in must have a unique `name`. * **name** (string): the name of the drop-in. This must be suffixed with ".conf". * **_contents_** (string): the contents of the drop-in. Mutually exclusive with `contents_local`. - * **_contents_local_** (string): a local path to the contents of the drop-in, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `contents`. * **_passwd_** (object): describes the desired additions to the passwd database. * **_users_** (list of objects): the list of accounts that shall exist. All users must have a unique `name`. * **name** (string): the username for the account. Must be `core`. * **_password_hash_** (string): the hashed password for the account. * **_ssh_authorized_keys_** (list of strings): a list of SSH keys to be added as an SSH key fragment at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. - * **_ssh_authorized_keys_local_** (list of strings): a list of local paths to SSH key files, relative to the directory specified by the `--files-dir` command-line argument, to be added as SSH key fragments at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. Each file may contain multiple SSH keys, one per line. * **_boot_device_** (object): describes the desired boot device configuration. At least one of `luks` or `mirror` must be specified. * **_layout_** (string): the disk layout of the target OS image. Supported values are `aarch64`, `ppc64le`, and `x86_64`. Defaults to `x86_64`. * **_luks_** (object): describes the clevis configuration for encrypting the root filesystem. * **_tang_** (list of objects): describes a tang server. Every server must have a unique `url`. * **url** (string): url of the tang server. * **thumbprint** (string): thumbprint of a trusted signing key. - * **_advertisement_** (string): the advertisement JSON. If not specified, the advertisement is fetched from the tang server during provisioning. * **_tpm2_** (boolean): whether or not to use a tpm2 device. * **_threshold_** (integer): sets the minimum number of pieces required to decrypt the device. Default is 1. - * **_discard_** (boolean): whether to issue discard commands to the underlying block device when blocks are freed. Enabling this improves performance and device longevity on SSDs and space utilization on thinly provisioned SAN devices, but leaks information about which disk blocks contain data. If omitted, it defaults to false. * **_mirror_** (object): describes mirroring of the boot disk for fault tolerance. * **_devices_** (list of strings): the list of whole-disk devices (not partitions) to include in the disk array, referenced by their absolute path. At least two devices must be specified. -* **_grub_** (object): describes the desired GRUB bootloader configuration. - * **_users_** (list of objects): the list of GRUB superusers. - * **name** (string): the user name. - * **password_hash** (string): the PBKDF2 password hash, generated with `grub2-mkpasswd-pbkdf2`. * **_openshift_** (object): describes miscellaneous OpenShift configuration. Respected when rendering to a MachineConfig, ignored when rendering directly to an Ignition config. * **_kernel_type_** (string): which kernel to use on the node. Must be `default` or `realtime`. * **_kernel_arguments_** (list of strings): arguments to be added to the kernel command line. diff --git a/docs/specs.md b/docs/specs.md index 62024934..27e29861 100644 --- a/docs/specs.md +++ b/docs/specs.md @@ -25,6 +25,7 @@ We recommend that you always use the latest **stable** specification for your op - [v1.1.0](config-flatcar-v1_1.md) - [v1.0.0](config-flatcar-v1_0.md) - OpenShift (`openshift`) + - [v4.14.0](config-openshift-v4_14.md) - [v4.13.0](config-openshift-v4_13.md) - [v4.12.0](config-openshift-v4_12.md) - [v4.11.0](config-openshift-v4_11.md) @@ -70,7 +71,7 @@ Each version of the Butane specification corresponds to a version of the Ignitio | `openshift` | 4.11.0 | 3.2.0 | | `openshift` | 4.12.0 | 3.2.0 | | `openshift` | 4.13.0 | 3.2.0 | -| `openshift` | 4.14.0-experimental | 3.5.0-experimental | +| `openshift` | 4.14.0 | 3.4.0 | | `openshift` | 4.15.0-experimental | 3.5.0-experimental | | `r4e` | 1.0.0 | 3.3.0 | | `r4e` | 1.1.0 | 3.4.0 | diff --git a/docs/upgrading-openshift.md b/docs/upgrading-openshift.md index 5632a7e4..9ffbdad5 100644 --- a/docs/upgrading-openshift.md +++ b/docs/upgrading-openshift.md @@ -15,6 +15,12 @@ Occasionally, changes are made to OpenShift Butane configs (those that specify ` {% comment %} +## From Version 4.14.0 to 4.15.0 + +There are no breaking changes between versions 4.14.0 and 4.15.0 of the `openshift` configuration specification. Any valid 4.14.0 configuration can be updated to a 4.15.0 configuration by changing the version string in the config. + +{% endcomment %} + ## From Version 4.13.0 to 4.14.0 There are no breaking changes between versions 4.13.0 and 4.14.0 of the `openshift` configuration specification. Any valid 4.13.0 configuration can be updated to a 4.14.0 configuration by changing the version string in the config. @@ -26,7 +32,7 @@ SSH keys and systemd units are now embeddable via file references to local files ```yaml variant: openshift -version: 4.14.0-experimental +version: 4.14.0 metadata: name: minimal-config labels: @@ -46,8 +52,6 @@ passwd: - id_rsa.pub ``` -{% endcomment %} - ## From Version 4.12.0 to 4.13.0 There are no breaking changes between versions 4.12.0 and 4.13.0 of the `openshift` configuration specification. Any valid 4.12.0 configuration can be updated to a 4.13.0 configuration by changing the version string in the config. diff --git a/internal/doc/butane.yaml b/internal/doc/butane.yaml index 482dc677..13ef285f 100644 --- a/internal/doc/butane.yaml +++ b/internal/doc/butane.yaml @@ -39,7 +39,7 @@ mode: replacement: are not supported if: - variant: openshift - min: 4.14.0-experimental + min: 4.14.0 append-contents-local: # Mention contents_local on specs that support it. @@ -212,7 +212,7 @@ root: replacement: "or swap" if: - variant: openshift - min: 4.14.0-experimental + min: 4.14.0 - name: with_mount_unit after: $ desc: whether to additionally generate a generic mount unit for this filesystem or a swap unit for this swap area. If a more specific unit is needed, a custom one can be specified in the `systemd.units` section. The unit will be named with the [escaped](https://www.freedesktop.org/software/systemd/man/systemd-escape.html) version of the `path` or `device`, depending on the unit type. If your filesystem is located on a Tang-backed LUKS device, the unit will automatically require network access if you specify the device as `/dev/mapper/` or `/dev/disk/by-id/dm-name-`. diff --git a/internal/doc/main.go b/internal/doc/main.go index 623f95e6..d3b25064 100644 --- a/internal/doc/main.go +++ b/internal/doc/main.go @@ -49,7 +49,7 @@ import ( openshift4_11 "github.com/coreos/butane/config/openshift/v4_11" openshift4_12 "github.com/coreos/butane/config/openshift/v4_12" openshift4_13 "github.com/coreos/butane/config/openshift/v4_13" - openshift4_14_exp "github.com/coreos/butane/config/openshift/v4_14_exp" + openshift4_14 "github.com/coreos/butane/config/openshift/v4_13" openshift4_15_exp "github.com/coreos/butane/config/openshift/v4_15_exp" openshift4_8 "github.com/coreos/butane/config/openshift/v4_8" openshift4_9 "github.com/coreos/butane/config/openshift/v4_9" @@ -122,13 +122,13 @@ func generate(dir string) error { []version{ // inverse order of website navbar {"4.15.0-experimental", openshift4_15_exp.Config{}}, - {"4.14.0-experimental", openshift4_14_exp.Config{}}, {"4.8.0", openshift4_8.Config{}}, {"4.9.0", openshift4_9.Config{}}, {"4.10.0", openshift4_10.Config{}}, {"4.11.0", openshift4_11.Config{}}, {"4.12.0", openshift4_12.Config{}}, {"4.13.0", openshift4_13.Config{}}, + {"4.14.0", openshift4_14.Config{}}, }, }, { From 3d0e3d3f71c6c5b3b22e20437d2ac8ab6fae7cfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Thu, 14 Sep 2023 16:23:01 +0200 Subject: [PATCH 05/16] openshift/v4.14: Use fcos 1.5 & ignition 3.4 specs Stabilise openshift 4.14.0 spec on fcos 1.5 and ignition 3.4 stable specs. The MCO is now capable of understanding Ignition 3.4.0 specs and uses that by default. See: https://github.com/openshift/machine-config-operator/pull/3576 See: https://github.com/openshift/machine-config-operator/pull/3814 --- config/openshift/v4_14/result/schema.go | 2 +- config/openshift/v4_14/schema.go | 2 +- config/openshift/v4_14/translate.go | 16 ++++++++-------- config/openshift/v4_14/translate_test.go | 14 +++++++------- docs/config-openshift-v4_14.md | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/config/openshift/v4_14/result/schema.go b/config/openshift/v4_14/result/schema.go index c8d45b79..ad5abd8e 100644 --- a/config/openshift/v4_14/result/schema.go +++ b/config/openshift/v4_14/result/schema.go @@ -15,7 +15,7 @@ package result import ( - "github.com/coreos/ignition/v2/config/v3_5_experimental/types" + "github.com/coreos/ignition/v2/config/v3_4/types" ) const ( diff --git a/config/openshift/v4_14/schema.go b/config/openshift/v4_14/schema.go index a78c3d5a..4ef6cf20 100644 --- a/config/openshift/v4_14/schema.go +++ b/config/openshift/v4_14/schema.go @@ -15,7 +15,7 @@ package v4_14 import ( - fcos "github.com/coreos/butane/config/fcos/v1_6_exp" + fcos "github.com/coreos/butane/config/fcos/v1_5" ) const ROLE_LABEL_KEY = "machineconfiguration.openshift.io/role" diff --git a/config/openshift/v4_14/translate.go b/config/openshift/v4_14/translate.go index 199c9e90..5e4d91c1 100644 --- a/config/openshift/v4_14/translate.go +++ b/config/openshift/v4_14/translate.go @@ -24,7 +24,7 @@ import ( "github.com/coreos/butane/translate" "github.com/coreos/ignition/v2/config/util" - "github.com/coreos/ignition/v2/config/v3_5_experimental/types" + "github.com/coreos/ignition/v2/config/v3_4/types" "github.com/coreos/vcontext/path" "github.com/coreos/vcontext/report" ) @@ -113,7 +113,7 @@ func (c Config) FieldFilters() *cutil.FieldFilters { // can be tracked back to their source in the source config. No config // validation is performed on input or output. func (c Config) ToMachineConfig4_14Unvalidated(options common.TranslateOptions) (result.MachineConfig, translate.TranslationSet, report.Report) { - cfg, ts, r := c.Config.ToIgn3_5Unvalidated(options) + cfg, ts, r := c.Config.ToIgn3_4Unvalidated(options) if r.IsFatal() { return result.MachineConfig{}, ts, r } @@ -174,11 +174,11 @@ func (c Config) ToMachineConfig4_14(options common.TranslateOptions) (result.Mac return cfg.(result.MachineConfig), r, err } -// ToIgn3_5Unvalidated translates the config to an Ignition config. It also +// ToIgn3_4Unvalidated translates the config to an Ignition config. It also // returns the set of translations it did so paths in the resultant config // can be tracked back to their source in the source config. No config // validation is performed on input or output. -func (c Config) ToIgn3_5Unvalidated(options common.TranslateOptions) (types.Config, translate.TranslationSet, report.Report) { +func (c Config) ToIgn3_4Unvalidated(options common.TranslateOptions) (types.Config, translate.TranslationSet, report.Report) { mc, ts, r := c.ToMachineConfig4_14Unvalidated(options) cfg := mc.Spec.Config @@ -194,12 +194,12 @@ func (c Config) ToIgn3_5Unvalidated(options common.TranslateOptions) (types.Conf return cfg, ts, r } -// ToIgn3_5 translates the config to an Ignition config. It returns a +// ToIgn3_4 translates the config to an Ignition config. It returns a // report of any errors or warnings in the source and resultant config. If // the report has fatal errors or it encounters other problems translating, // an error is returned. -func (c Config) ToIgn3_5(options common.TranslateOptions) (types.Config, report.Report, error) { - cfg, r, err := cutil.Translate(c, "ToIgn3_5Unvalidated", options) +func (c Config) ToIgn3_4(options common.TranslateOptions) (types.Config, report.Report, error) { + cfg, r, err := cutil.Translate(c, "ToIgn3_4Unvalidated", options) return cfg.(types.Config), r, err } @@ -208,7 +208,7 @@ func (c Config) ToIgn3_5(options common.TranslateOptions) (types.Config, report. // translating, an error is returned. func ToConfigBytes(input []byte, options common.TranslateBytesOptions) ([]byte, report.Report, error) { if options.Raw { - return cutil.TranslateBytes(input, &Config{}, "ToIgn3_5", options) + return cutil.TranslateBytes(input, &Config{}, "ToIgn3_4", options) } else { return cutil.TranslateBytesYAML(input, &Config{}, "ToMachineConfig4_14", options) } diff --git a/config/openshift/v4_14/translate_test.go b/config/openshift/v4_14/translate_test.go index 02745a53..fcf797b0 100644 --- a/config/openshift/v4_14/translate_test.go +++ b/config/openshift/v4_14/translate_test.go @@ -19,15 +19,15 @@ import ( "testing" baseutil "github.com/coreos/butane/base/util" - base "github.com/coreos/butane/base/v0_6_exp" + base "github.com/coreos/butane/base/v0_5" "github.com/coreos/butane/config/common" - fcos "github.com/coreos/butane/config/fcos/v1_6_exp" + fcos "github.com/coreos/butane/config/fcos/v1_5" "github.com/coreos/butane/config/openshift/v4_14/result" confutil "github.com/coreos/butane/config/util" "github.com/coreos/butane/translate" "github.com/coreos/ignition/v2/config/util" - "github.com/coreos/ignition/v2/config/v3_5_experimental/types" + "github.com/coreos/ignition/v2/config/v3_4/types" "github.com/coreos/vcontext/path" "github.com/coreos/vcontext/report" "github.com/stretchr/testify/assert" @@ -52,7 +52,7 @@ func TestElidedFieldWarning(t *testing.T) { expected.AddOnWarn(path.New("yaml", "openshift", "fips"), common.ErrFieldElided) expected.AddOnWarn(path.New("yaml", "openshift", "kernel_type"), common.ErrFieldElided) - _, _, r := in.ToIgn3_5Unvalidated(common.TranslateOptions{}) + _, _, r := in.ToIgn3_4Unvalidated(common.TranslateOptions{}) assert.Equal(t, expected, r, "report mismatch") } @@ -84,7 +84,7 @@ func TestTranslateConfig(t *testing.T) { Spec: result.Spec{ Config: types.Config{ Ignition: types.Ignition{ - Version: "3.5.0-experimental", + Version: "3.4.0", }, }, }, @@ -159,7 +159,7 @@ func TestTranslateConfig(t *testing.T) { Spec: result.Spec{ Config: types.Config{ Ignition: types.Ignition{ - Version: "3.5.0-experimental", + Version: "3.4.0", }, Storage: types.Storage{ Filesystems: []types.Filesystem{ @@ -304,7 +304,7 @@ func TestTranslateConfig(t *testing.T) { Spec: result.Spec{ Config: types.Config{ Ignition: types.Ignition{ - Version: "3.5.0-experimental", + Version: "3.4.0", }, Storage: types.Storage{ Filesystems: []types.Filesystem{ diff --git a/docs/config-openshift-v4_14.md b/docs/config-openshift-v4_14.md index 6cb3a7e7..efe72cc6 100644 --- a/docs/config-openshift-v4_14.md +++ b/docs/config-openshift-v4_14.md @@ -13,7 +13,7 @@ The OpenShift configuration is a YAML document conforming to the following speci
* **variant** (string): used to differentiate configs for different operating systems. Must be `openshift` for this specification. -* **version** (string): the semantic version of the spec for this document. This document is for version `4.14.0` and generates Ignition configs with version `3.5.0-experimental`. +* **version** (string): the semantic version of the spec for this document. This document is for version `4.14.0` and generates Ignition configs with version `3.4.0`. * **metadata** (object): metadata about the generated MachineConfig resource. Respected when rendering to a MachineConfig, ignored when rendering directly to an Ignition config. * **name** (string): a unique [name](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names) for this MachineConfig resource. * **labels** (object): string key/value pairs to apply as [Kubernetes labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) to this MachineConfig resource. `machineconfiguration.openshift.io/role` is required. From 1f65fb659af34fe3d56f13462703ed87ba2f0b17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Mon, 18 Sep 2023 16:27:27 +0200 Subject: [PATCH 06/16] openshift/v4.14: Remove GRUB password support Remove all GRUB bootloader configuration sugar for openshift/v4.14 configs as the MCO does not know how to manage files in the read only /boot partition yet. While we could use Ignition to write the initial file, any update would fail which makes for a bad user experience. This is revert of [1] for openshift/v4.14 only. [1] https://github.com/coreos/butane/commit/4bd006e3f00eae89f9555e986b331fce8fdc2882 See: https://issues.redhat.com/browse/OCPSTRAT-831 See: https://issues.redhat.com/browse/OCPSTRAT-113 --- config/openshift/v4_14/translate.go | 24 ------- config/openshift/v4_14/translate_test.go | 83 ------------------------ docs/release-notes.md | 2 +- 3 files changed, 1 insertion(+), 108 deletions(-) diff --git a/config/openshift/v4_14/translate.go b/config/openshift/v4_14/translate.go index 5e4d91c1..ae7e36f4 100644 --- a/config/openshift/v4_14/translate.go +++ b/config/openshift/v4_14/translate.go @@ -117,7 +117,6 @@ func (c Config) ToMachineConfig4_14Unvalidated(options common.TranslateOptions) if r.IsFatal() { return result.MachineConfig{}, ts, r } - ts = translateUserGrubCfg(&cfg, &ts) // wrap ts = ts.PrefixPaths(path.New("yaml"), path.New("json", "spec", "config")) @@ -302,26 +301,3 @@ func validateMCOSupport(mc result.MachineConfig) report.Report { } return r } - -// fcos config generates a user.cfg file using append; however, OpenShift config -// does not support append (since MCO does not support it). Let change the file to use contents -func translateUserGrubCfg(config *types.Config, ts *translate.TranslationSet) translate.TranslationSet { - newMappings := translate.NewTranslationSet("json", "json") - for i, file := range config.Storage.Files { - if file.Path == "/boot/grub2/user.cfg" { - if len(file.Append) != 1 { - // The number of append objects was different from expected, this file - // was created by the user and not via butane GRUB sugar - return *ts - } - fromPath := path.New("json", "storage", "files", i, "append", 0) - translatedPath := path.New("json", "storage", "files", i, "contents") - config.Storage.Files[i].FileEmbedded1.Contents = file.Append[0] - config.Storage.Files[i].FileEmbedded1.Append = nil - newMappings.AddFromCommonObject(fromPath, translatedPath, config.Storage.Files[i].FileEmbedded1.Contents) - - return ts.Map(newMappings) - } - } - return *ts -} diff --git a/config/openshift/v4_14/translate_test.go b/config/openshift/v4_14/translate_test.go index fcf797b0..4d163de2 100644 --- a/config/openshift/v4_14/translate_test.go +++ b/config/openshift/v4_14/translate_test.go @@ -272,89 +272,6 @@ func TestTranslateConfig(t *testing.T) { {From: path.New("yaml", "openshift", "fips"), To: path.New("json", "spec", "fips")}, }, }, - // Test Grub config - { - Config{ - Metadata: Metadata{ - Name: "z", - Labels: map[string]string{ - ROLE_LABEL_KEY: "z", - }, - }, - Config: fcos.Config{ - Grub: fcos.Grub{ - Users: []fcos.GrubUser{ - { - Name: "root", - PasswordHash: util.StrToPtr("grub.pbkdf2.sha512.10000.874A958E526409..."), - }, - }, - }, - }, - }, - result.MachineConfig{ - ApiVersion: result.MC_API_VERSION, - Kind: result.MC_KIND, - Metadata: result.Metadata{ - Name: "z", - Labels: map[string]string{ - ROLE_LABEL_KEY: "z", - }, - }, - Spec: result.Spec{ - Config: types.Config{ - Ignition: types.Ignition{ - Version: "3.4.0", - }, - Storage: types.Storage{ - Filesystems: []types.Filesystem{ - { - Device: "/dev/disk/by-label/boot", - Format: util.StrToPtr("ext4"), - Path: util.StrToPtr("/boot"), - }, - }, - Files: []types.File{ - { - Node: types.Node{ - Path: "/boot/grub2/user.cfg", - }, - FileEmbedded1: types.FileEmbedded1{ - Contents: types.Resource{ - Source: util.StrToPtr("data:,%23%20Generated%20by%20Butane%0A%0Aset%20superusers%3D%22root%22%0Apassword_pbkdf2%20root%20grub.pbkdf2.sha512.10000.874A958E526409...%0A"), - Compression: util.StrToPtr(""), - }, - }, - }, - }, - }, - }, - }, - }, - []translate.Translation{ - {From: path.New("yaml", "version"), To: path.New("json", "apiVersion")}, - {From: path.New("yaml", "version"), To: path.New("json", "kind")}, - {From: path.New("yaml", "version"), To: path.New("json", "spec")}, - {From: path.New("yaml"), To: path.New("json", "spec", "config")}, - {From: path.New("yaml", "ignition"), To: path.New("json", "spec", "config", "ignition")}, - {From: path.New("yaml", "version"), To: path.New("json", "spec", "config", "ignition", "version")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems", 0)}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "path")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "device")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "filesystems", 0, "format")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0)}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "path")}, - // "append" field is a remnant of translations performed in fcos config - // TODO: add a delete function to translation.TranslationSet and delete "append" translation - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "append")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "contents")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "contents", "source")}, - {From: path.New("yaml", "grub", "users"), To: path.New("json", "spec", "config", "storage", "files", 0, "contents", "compression")}, - }, - }, } for i, test := range tests { diff --git a/docs/release-notes.md b/docs/release-notes.md index f7596971..ebbd52e4 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -34,7 +34,7 @@ key](https://getfedora.org/security/). ### Docs changes - Document consequence of setting `systemd.units.mask` to false -- Document `grub` section _(openshift 4.14.0-exp)_ +- Document `grub` section _(openshift 4.15.0-exp)_ - Document `/dev/disk/by-id/coreos-boot-disk` _(fcos, openshift 4.11.0+)_ - Don't claim to support generating swap units _(openshift 4.8.0 - 4.13.0)_ - Document `key_file` `compression` field _(openshift 4.8.0 - 4.9.0)_ From e9d13a80c5a13d41e62cec5726a7e6f78f6b4079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Ravier?= Date: Thu, 21 Sep 2023 15:45:36 +0200 Subject: [PATCH 07/16] NEWS: Update for 4.14 stabilization Fixes: https://github.com/coreos/butane/issues/488 --- docs/release-notes.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index ebbd52e4..a97bf735 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -18,9 +18,12 @@ key](https://getfedora.org/security/). - Add `-c`/`--check` option to check config without producing output - Warn if config attempts to reuse partition by label _(fcos 1.6.0-exp, - openshift 4.14.0-exp)_ + openshift 4.14.0)_ - Require `storage.filesystems.path` to start with `/etc` or `/var` if - `with_mount_unit` is true _(fcos 1.6.0-exp, openshift 4.14.0-exp)_ + `with_mount_unit` is true _(fcos 1.6.0-exp, openshift 4.14.0)_ +- Stabilize OpenShift spec 4.14.0, targeting Ignition spec 3.4.0 +- Add OpenShift spec 4.15.0-experimental, targeting Ignition spec + 3.5.0-experimental ### Bug fixes @@ -30,6 +33,7 @@ key](https://getfedora.org/security/). ### Misc. changes - Add error structs for YAML unmarshal errors, unknown config versions (Go API) +- Roll back to Ignition spec 3.4.0 _(openshift 4.14.0)_ ### Docs changes From d3929c681003351fcdd76e7b2f82ddc722783e74 Mon Sep 17 00:00:00 2001 From: Steven Presti Date: Tue, 3 Oct 2023 11:57:34 -0400 Subject: [PATCH 08/16] docs/release-notes: update for release --- docs/release-notes.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index a97bf735..f56a2573 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -4,7 +4,26 @@ nav_order: 9 # Release notes -## Upcoming Butane 0.19.0 (unreleased) +## Upcoming Butane 0.20.0 (unreleased) + + +### Breaking changes + + +### Features + + +### Bug fixes + + +### Misc. changes + + +### Docs changes + + + +## Butane 0.19.0 (2023-10-03) Starting with this release, Butane binaries are signed with the [Fedora 38 key](https://getfedora.org/security/). From f57e987cc52931b4a62376a41775f70dcc316304 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Wed, 1 Nov 2023 19:40:52 +0000 Subject: [PATCH 09/16] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@90904e8f378272f690d458e5496d61a56488bd49. --- .github/workflows/go.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 5559f20a..0a4dc053 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -20,12 +20,12 @@ jobs: name: Test strategy: matrix: - go-version: [1.18.x, 1.19.x, 1.20.x] + go-version: [1.20.x, 1.21.x] os: [ubuntu-latest] include: - - go-version: 1.20.x + - go-version: 1.21.x os: macos-latest - - go-version: 1.20.x + - go-version: 1.21.x os: windows-latest runs-on: ${{ matrix.os }} steps: @@ -59,7 +59,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v4 with: - go-version: 1.20.x + go-version: 1.21.x - name: Regenerate run: ./generate - name: Check whether generated output is current From 0d2fa0fb99bf81a95c6f3c73379bfd8af36d9cba Mon Sep 17 00:00:00 2001 From: madhu-pillai Date: Tue, 3 Oct 2023 11:10:59 +0530 Subject: [PATCH 10/16] spec/v1.6: Add support for boot_device sugar on s390x Co-authored-by: Nikita Dubrovski Co-authored-by: Jonathan Lebon --- config/common/errors.go | 5 +++- config/fcos/v1_6_exp/schema.go | 1 + config/fcos/v1_6_exp/translate.go | 13 +++++++-- config/fcos/v1_6_exp/validate.go | 21 ++++++++++++++ docs/config-fcos-v1_6-exp.md | 3 +- docs/config-openshift-v4_15-exp.md | 3 +- docs/examples.md | 44 ++++++++++++++++++++++++++++++ docs/release-notes.md | 1 + internal/doc/butane.yaml | 10 +++++++ 9 files changed, 96 insertions(+), 5 deletions(-) diff --git a/config/common/errors.go b/config/common/errors.go index a5f8d5b2..922111ab 100644 --- a/config/common/errors.go +++ b/config/common/errors.go @@ -54,8 +54,11 @@ var ( ErrMountPointForbidden = errors.New("path must be under /etc or /var if with_mount_unit is true") // boot device - ErrUnknownBootDeviceLayout = errors.New("layout must be one of: aarch64, ppc64le, x86_64") + ErrUnknownBootDeviceLayout = errors.New("layout must be one of: aarch64, ppc64le, s390x-eckd, s390x-virt, s390x-zfcp, x86_64") ErrTooFewMirrorDevices = errors.New("mirroring requires at least two devices") + ErrNoLuksBootDevice = errors.New("device is required for layouts: s390x-eckd, s390x-zfcp") + ErrMirrorNotSupport = errors.New("mirroring not supported on layouts: s390x-eckd, s390x-zfcp, s390x-virt") + ErrLuksBootDeviceBadName = errors.New("device name must start with /dev/dasd on s390x-eckd layout or /dev/sd on s390x-zfcp layout") // partition ErrReuseByLabel = errors.New("partitions cannot be reused by label; number must be specified except on boot disk (/dev/disk/by-id/coreos-boot-disk) or when wipe_table is true") diff --git a/config/fcos/v1_6_exp/schema.go b/config/fcos/v1_6_exp/schema.go index 140cd31a..52cdfb43 100644 --- a/config/fcos/v1_6_exp/schema.go +++ b/config/fcos/v1_6_exp/schema.go @@ -32,6 +32,7 @@ type BootDevice struct { type BootDeviceLuks struct { Discard *bool `yaml:"discard"` + Device *string `yaml:"device"` Tang []base.Tang `yaml:"tang"` Threshold *int `yaml:"threshold"` Tpm2 *bool `yaml:"tpm2"` diff --git a/config/fcos/v1_6_exp/translate.go b/config/fcos/v1_6_exp/translate.go index 2a45287b..a7c0a679 100644 --- a/config/fcos/v1_6_exp/translate.go +++ b/config/fcos/v1_6_exp/translate.go @@ -133,6 +133,7 @@ func (c Config) processBootDevice(config *types.Config, ts *translate.Translatio wantEFIPart = true case *layout == "ppc64le": wantPRePPart = true + case *layout == "s390x-eckd" || *layout == "s390x-virt" || *layout == "s390x-zfcp": default: // should have failed validation panic("unknown layout") @@ -239,9 +240,17 @@ func (c Config) processBootDevice(config *types.Config, ts *translate.Translatio // encrypted root partition if wantLuks { - luksDevice := "/dev/disk/by-partlabel/root" - if wantMirror { + var luksDevice string + switch { + //Luks Device for dasd and zFCP-scsi + case layout != nil && *layout == "s390x-eckd": + luksDevice = *c.BootDevice.Luks.Device + "2" + case layout != nil && *layout == "s390x-zfcp": + luksDevice = *c.BootDevice.Luks.Device + "4" + case wantMirror: luksDevice = "/dev/md/md-root" + default: + luksDevice = "/dev/disk/by-partlabel/root" } clevis, ts2, r2 := translateBootDeviceLuks(c.BootDevice.Luks, options) rendered.Storage.Luks = []types.Luks{{ diff --git a/config/fcos/v1_6_exp/validate.go b/config/fcos/v1_6_exp/validate.go index 4c3ae9de..481e3d84 100644 --- a/config/fcos/v1_6_exp/validate.go +++ b/config/fcos/v1_6_exp/validate.go @@ -27,6 +27,8 @@ import ( const rootDevice = "/dev/disk/by-id/coreos-boot-disk" var allowedMountpoints = regexp.MustCompile(`^/(etc|var)(/|$)`) +var dasdRe = regexp.MustCompile("(/dev/dasd[a-z]$)") +var sdRe = regexp.MustCompile("(/dev/sd[a-z]$)") // We can't define a Validate function directly on Disk because that's defined in base, // so we use a Validate function on the top-level Config instead. @@ -52,9 +54,28 @@ func (d BootDevice) Validate(c path.ContextPath) (r report.Report) { if d.Layout != nil { switch *d.Layout { case "aarch64", "ppc64le", "x86_64": + case "s390x-eckd": + if util.NilOrEmpty(d.Luks.Device) { + r.AddOnError(c.Append(*d.Layout), common.ErrNoLuksBootDevice) + } else if !dasdRe.MatchString(*d.Luks.Device) { + r.AddOnError(c.Append(*d.Layout), common.ErrLuksBootDeviceBadName) + } + case "s390x-zfcp": + if util.NilOrEmpty(d.Luks.Device) { + r.AddOnError(c.Append(*d.Layout), common.ErrNoLuksBootDevice) + } else if !sdRe.MatchString(*d.Luks.Device) { + r.AddOnError(c.Append(*d.Layout), common.ErrLuksBootDeviceBadName) + } + case "s390x-virt": default: r.AddOnError(c.Append("layout"), common.ErrUnknownBootDeviceLayout) } + + if *d.Layout == "s390x-eckd" || *d.Layout == "s390x-zfcp" || *d.Layout == "s390x-virt" { + if len(d.Mirror.Devices) > 0 { + r.AddOnError(c.Append(*d.Layout), common.ErrMirrorNotSupport) + } + } } r.Merge(d.Mirror.Validate(c.Append("mirror"))) return diff --git a/docs/config-fcos-v1_6-exp.md b/docs/config-fcos-v1_6-exp.md index ebc21a5a..6f8a4d1c 100644 --- a/docs/config-fcos-v1_6-exp.md +++ b/docs/config-fcos-v1_6-exp.md @@ -209,8 +209,9 @@ The Fedora CoreOS configuration is a YAML document conforming to the following s * **_should_exist_** (list of strings): the list of kernel arguments that should exist. * **_should_not_exist_** (list of strings): the list of kernel arguments that should not exist. * **_boot_device_** (object): describes the desired boot device configuration. At least one of `luks` or `mirror` must be specified. - * **_layout_** (string): the disk layout of the target OS image. Supported values are `aarch64`, `ppc64le`, and `x86_64`. Defaults to `x86_64`. + * **_layout_** (string): the disk layout of the target OS image. Supported values are `aarch64`, `ppc64le`, `s390x-eckd`, `s390x-virt`, `s390x-zfcp`, and `x86_64`. Defaults to `x86_64`. * **_luks_** (object): describes the clevis configuration for encrypting the root filesystem. + * **_device_** (string): the whole-disk device (not partitions), referenced by their absolute path. Must start with `/dev/dasd` for `s390x-eckd` layout or `/dev/sd` for `s390x-zfcp` layouts. * **_tang_** (list of objects): describes a tang server. Every server must have a unique `url`. * **url** (string): url of the tang server. * **thumbprint** (string): thumbprint of a trusted signing key. diff --git a/docs/config-openshift-v4_15-exp.md b/docs/config-openshift-v4_15-exp.md index c6fa8f64..23938dca 100644 --- a/docs/config-openshift-v4_15-exp.md +++ b/docs/config-openshift-v4_15-exp.md @@ -158,8 +158,9 @@ The OpenShift configuration is a YAML document conforming to the following speci * **_ssh_authorized_keys_** (list of strings): a list of SSH keys to be added as an SSH key fragment at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. * **_ssh_authorized_keys_local_** (list of strings): a list of local paths to SSH key files, relative to the directory specified by the `--files-dir` command-line argument, to be added as SSH key fragments at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. Each file may contain multiple SSH keys, one per line. * **_boot_device_** (object): describes the desired boot device configuration. At least one of `luks` or `mirror` must be specified. - * **_layout_** (string): the disk layout of the target OS image. Supported values are `aarch64`, `ppc64le`, and `x86_64`. Defaults to `x86_64`. + * **_layout_** (string): the disk layout of the target OS image. Supported values are `aarch64`, `ppc64le`, `s390x-eckd`, `s390x-virt`, `s390x-zfcp`, and `x86_64`. Defaults to `x86_64`. * **_luks_** (object): describes the clevis configuration for encrypting the root filesystem. + * **_device_** (string): the whole-disk device (not partitions), referenced by their absolute path. Must start with `/dev/dasd` for `s390x-eckd` layout or `/dev/sd` for `s390x-zfcp` layouts. * **_tang_** (list of objects): describes a tang server. Every server must have a unique `url`. * **url** (string): url of the tang server. * **thumbprint** (string): thumbprint of a trusted signing key. diff --git a/docs/examples.md b/docs/examples.md index 6fb1c3e4..3609bb19 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -296,6 +296,50 @@ storage: format: ext4 ``` +This example uses the shortcut `boot_device` syntax to configure an encrypted root filesystem in s390x on the `dasda` DASD device unlocked with a network Tang server. + + +```yaml +variant: fcos +version: 1.6.0-experimental +boot_device: + layout: s390x-eckd + luks: + device: /dev/dasda + tang: + - url: https://tang.example.com + thumbprint: REPLACE-THIS-WITH-YOUR-TANG-THUMBPRINT +``` + +This example uses the shortcut `boot_device` syntax to configure an encrypted root filesystem in s390x on the `sdb` zFCP device unlocked with a network Tang server. + + +```yaml +variant: fcos +version: 1.6.0-experimental +boot_device: + layout: s390x-zfcp + luks: + device: /dev/sdb + tang: + - url: https://tang.example.com + thumbprint: REPLACE-THIS-WITH-YOUR-TANG-THUMBPRINT +``` + +This example uses the shortcut `boot_device` syntax to configure an encrypted root filesystem in s390x KVM unlocked with a network Tang server. + + +```yaml +variant: fcos +version: 1.6.0-experimental +boot_device: + layout: s390x-virt + luks: + tang: + - url: https://tang.example.com + thumbprint: REPLACE-THIS-WITH-YOUR-TANG-THUMBPRINT +``` + ### Mirrored boot disk This example replicates all default partitions on the boot disk across multiple disks, allowing the system to survive disk failure. diff --git a/docs/release-notes.md b/docs/release-notes.md index f56a2573..ad8e136c 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -12,6 +12,7 @@ nav_order: 9 ### Features +- Support s390x layouts in `boot_device` section (fcos 1.6.0-exp, openshift 4.15.0-exp) ### Bug fixes diff --git a/internal/doc/butane.yaml b/internal/doc/butane.yaml index 13ef285f..d39a8baf 100644 --- a/internal/doc/butane.yaml +++ b/internal/doc/butane.yaml @@ -323,9 +323,19 @@ root: children: - name: layout desc: the disk layout of the target OS image. Supported values are `aarch64`, `ppc64le`, and `x86_64`. Defaults to `x86_64`. + transforms: + - regex: "Supported values are (.*), and `x86_64`." + replacement: "Supported values are $1, `s390x-eckd`, `s390x-virt`, `s390x-zfcp`, and `x86_64`." + if: + - variant: fcos + min: 1.6.0-experimental + - variant: openshift + min: 4.15.0-experimental - name: luks desc: describes the clevis configuration for encrypting the root filesystem. children: + - name: device + desc: the whole-disk device (not partitions), referenced by their absolute path. Must start with `/dev/dasd` for `s390x-eckd` layout or `/dev/sd` for `s390x-zfcp` layouts. - name: tang use: tang - name: tpm2 From 7cb151bd53eb24a3c9844c4d0a51445a3f7a1ea7 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Thu, 23 Nov 2023 11:13:41 +0000 Subject: [PATCH 11/16] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@d4f0da854ab1f971fc67619e37aeca8379ae1255. --- docs/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/_config.yml b/docs/_config.yml index 9799e735..43ad687f 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -14,7 +14,7 @@ kramdown: ndash: "--" mdash: "---" -remote_theme: just-the-docs/just-the-docs@v0.6.0 +remote_theme: just-the-docs/just-the-docs@v0.7.0 plugins: - jekyll-remote-theme From 6a0e763c3885bd6d5660e412417ca1c35abe351a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 04:34:19 +0000 Subject: [PATCH 12/16] build(deps): bump github.com/coreos/ignition/v2 from 2.16.2 to 2.17.0 Bumps [github.com/coreos/ignition/v2](https://github.com/coreos/ignition) from 2.16.2 to 2.17.0. - [Release notes](https://github.com/coreos/ignition/releases) - [Changelog](https://github.com/coreos/ignition/blob/main/docs/release-notes.md) - [Commits](https://github.com/coreos/ignition/compare/v2.16.2...v2.17.0) --- updated-dependencies: - dependency-name: github.com/coreos/ignition/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 41 ++++------------------------------------- vendor/modules.txt | 8 ++++---- 3 files changed, 10 insertions(+), 43 deletions(-) diff --git a/go.mod b/go.mod index 32174105..6a2757c2 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/clarketm/json v1.17.1 github.com/coreos/go-semver v0.3.1 github.com/coreos/go-systemd/v22 v22.5.0 - github.com/coreos/ignition/v2 v2.16.2 + github.com/coreos/ignition/v2 v2.17.0 github.com/coreos/vcontext v0.0.0-20230201181013-d72178a18687 github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace github.com/stretchr/testify v1.8.4 @@ -15,7 +15,7 @@ require ( ) require ( - github.com/aws/aws-sdk-go v1.44.298 // indirect + github.com/aws/aws-sdk-go v1.47.9 // indirect github.com/coreos/go-json v0.0.0-20230131223807-18775e0fb4fb // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/kr/pretty v0.3.1 // indirect diff --git a/go.sum b/go.sum index caa968a1..e326aabf 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g= -github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.47.9 h1:rarTsos0mA16q+huicGx0e560aYRtOucV5z2Mw23JRY= +github.com/aws/aws-sdk-go v1.47.9/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/clarketm/json v1.17.1 h1:U1IxjqJkJ7bRK4L6dyphmoO840P6bdhPdbbLySourqI= github.com/clarketm/json v1.17.1/go.mod h1:ynr2LRfb0fQU34l07csRNBTcivjySLLiY1YzQqKVfdo= github.com/coreos/go-json v0.0.0-20230131223807-18775e0fb4fb h1:rmqyI19j3Z/74bIRhuC59RB442rXUazKNueVpfJPxg4= @@ -8,17 +8,14 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/ignition/v2 v2.16.2 h1:wPpxTovdzCLJISYmNiM5Cpw4qCPc3/P2ibruPyS46eA= -github.com/coreos/ignition/v2 v2.16.2/go.mod h1:Y1BKC60VSNgA5oWNoLIHXigpFX1FFn4CVeimmsI+Bhg= +github.com/coreos/ignition/v2 v2.17.0 h1:bBqoZ9HYuIq20hbkb1ucypA7tMi9k/iouPnLNFZQXGM= +github.com/coreos/ignition/v2 v2.17.0/go.mod h1:BFL205qhVgftPJ1nej+C/VPrK6Hl3LlZUhqmhV/HUuA= github.com/coreos/vcontext v0.0.0-20230201181013-d72178a18687 h1:uSmlDgJGbUB0bwQBcZomBTottKwEDF5fF8UjSwKSzWM= github.com/coreos/vcontext v0.0.0-20230201181013-d72178a18687/go.mod h1:Salmysdw7DAVuobBW/LwsKKgpyCPHUhjyJoMJD+ZJiI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -28,48 +25,18 @@ github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HK github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace h1:9PNP1jnUjRhfmGMlkXHjYPishpcw4jpSt/V/xYY3FMA= github.com/spf13/pflag v1.0.6-0.20210604193023-d5e0c0615ace/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI= github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/modules.txt b/vendor/modules.txt index d4ea6695..8543e27b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,5 +1,5 @@ -# github.com/aws/aws-sdk-go v1.44.298 -## explicit; go 1.11 +# github.com/aws/aws-sdk-go v1.47.9 +## explicit; go 1.19 github.com/aws/aws-sdk-go/aws/arn # github.com/clarketm/json v1.17.1 ## explicit @@ -13,8 +13,8 @@ github.com/coreos/go-semver/semver # github.com/coreos/go-systemd/v22 v22.5.0 ## explicit; go 1.12 github.com/coreos/go-systemd/v22/unit -# github.com/coreos/ignition/v2 v2.16.2 -## explicit; go 1.18 +# github.com/coreos/ignition/v2 v2.17.0 +## explicit; go 1.19 github.com/coreos/ignition/v2/config/doc github.com/coreos/ignition/v2/config/merge github.com/coreos/ignition/v2/config/shared/errors From fed77f6c873ff0b60ae99b05941eca5690a8ea48 Mon Sep 17 00:00:00 2001 From: Sayan Paul Date: Mon, 11 Sep 2023 16:12:18 +0530 Subject: [PATCH 13/16] Add new fiot variant for fedora-iot v1_0 is compatible with ignition 3.4.0 v1_1_exp is experimental version compatible with ignition 3.5.0 docs added for fiot Signed-off-by: Sayan Paul --- config/config.go | 4 + config/fiot/v1_0/schema.go | 23 ++++ config/fiot/v1_0/translate.go | 54 ++++++++ config/fiot/v1_0/translate_test.go | 180 +++++++++++++++++++++++++ config/fiot/v1_1_exp/schema.go | 23 ++++ config/fiot/v1_1_exp/translate.go | 54 ++++++++ config/fiot/v1_1_exp/translate_test.go | 180 +++++++++++++++++++++++++ docs/config-fiot-v1_0.md | 146 ++++++++++++++++++++ docs/config-fiot-v1_1-exp.md | 148 ++++++++++++++++++++ docs/release-notes.md | 1 + docs/specs.md | 6 + internal/doc/main.go | 11 ++ 12 files changed, 830 insertions(+) create mode 100644 config/fiot/v1_0/schema.go create mode 100644 config/fiot/v1_0/translate.go create mode 100644 config/fiot/v1_0/translate_test.go create mode 100644 config/fiot/v1_1_exp/schema.go create mode 100644 config/fiot/v1_1_exp/translate.go create mode 100644 config/fiot/v1_1_exp/translate_test.go create mode 100644 docs/config-fiot-v1_0.md create mode 100644 docs/config-fiot-v1_1-exp.md diff --git a/config/config.go b/config/config.go index 06867585..c4da31e7 100644 --- a/config/config.go +++ b/config/config.go @@ -25,6 +25,8 @@ import ( fcos1_4 "github.com/coreos/butane/config/fcos/v1_4" fcos1_5 "github.com/coreos/butane/config/fcos/v1_5" fcos1_6_exp "github.com/coreos/butane/config/fcos/v1_6_exp" + fiot1_0 "github.com/coreos/butane/config/fiot/v1_0" + fiot1_1_exp "github.com/coreos/butane/config/fiot/v1_1_exp" flatcar1_0 "github.com/coreos/butane/config/flatcar/v1_0" flatcar1_1 "github.com/coreos/butane/config/flatcar/v1_1" flatcar1_2_exp "github.com/coreos/butane/config/flatcar/v1_2_exp" @@ -77,6 +79,8 @@ func init() { RegisterTranslator("r4e", "1.0.0", r4e1_0.ToIgn3_3Bytes) RegisterTranslator("r4e", "1.1.0", r4e1_1.ToIgn3_4Bytes) RegisterTranslator("r4e", "1.2.0-experimental", r4e1_2_exp.ToIgn3_5Bytes) + RegisterTranslator("fiot", "1.0.0", fiot1_0.ToIgn3_4Bytes) + RegisterTranslator("fiot", "1.1.0-experimental", fiot1_1_exp.ToIgn3_5Bytes) RegisterTranslator("rhcos", "0.1.0", unsupportedRhcosVariant) } diff --git a/config/fiot/v1_0/schema.go b/config/fiot/v1_0/schema.go new file mode 100644 index 00000000..d9c6f0dc --- /dev/null +++ b/config/fiot/v1_0/schema.go @@ -0,0 +1,23 @@ +// Copyright 2022 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v1_0 + +import ( + base "github.com/coreos/butane/base/v0_5" +) + +type Config struct { + base.Config `yaml:",inline"` +} diff --git a/config/fiot/v1_0/translate.go b/config/fiot/v1_0/translate.go new file mode 100644 index 00000000..529629ed --- /dev/null +++ b/config/fiot/v1_0/translate.go @@ -0,0 +1,54 @@ +// Copyright 2022 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v1_0 + +import ( + "github.com/coreos/butane/config/common" + cutil "github.com/coreos/butane/config/util" + + "github.com/coreos/ignition/v2/config/v3_4/types" + "github.com/coreos/vcontext/report" +) + +var ( + fieldFilters = cutil.NewFilters(types.Config{}, cutil.FilterMap{ + "kernelArguments": common.ErrGeneralKernelArgumentSupport, + "storage.disks": common.ErrDiskSupport, + "storage.filesystems": common.ErrFilesystemSupport, + "storage.luks": common.ErrLuksSupport, + "storage.raid": common.ErrRaidSupport, + }) +) + +// Return FieldFilters for this spec. +func (c Config) FieldFilters() *cutil.FieldFilters { + return &fieldFilters +} + +// ToIgn3_4 translates the config to an Ignition config. It returns a +// report of any errors or warnings in the source and resultant config. If +// the report has fatal errors or it encounters other problems translating, +// an error is returned. +func (c Config) ToIgn3_4(options common.TranslateOptions) (types.Config, report.Report, error) { + cfg, r, err := cutil.Translate(c, "ToIgn3_4Unvalidated", options) + return cfg.(types.Config), r, err +} + +// ToIgn3_4Bytes translates from a v1.1 Butane config to a v3.4.0 Ignition config. It returns a report of any errors or +// warnings in the source and resultant config. If the report has fatal errors or it encounters other problems +// translating, an error is returned. +func ToIgn3_4Bytes(input []byte, options common.TranslateBytesOptions) ([]byte, report.Report, error) { + return cutil.TranslateBytes(input, &Config{}, "ToIgn3_4", options) +} diff --git a/config/fiot/v1_0/translate_test.go b/config/fiot/v1_0/translate_test.go new file mode 100644 index 00000000..77215d9a --- /dev/null +++ b/config/fiot/v1_0/translate_test.go @@ -0,0 +1,180 @@ +// Copyright 2022 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v1_0 + +import ( + "fmt" + "testing" + + baseutil "github.com/coreos/butane/base/util" + base "github.com/coreos/butane/base/v0_5" + "github.com/coreos/butane/config/common" + confutil "github.com/coreos/butane/config/util" + "github.com/coreos/ignition/v2/config/util" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + "github.com/stretchr/testify/assert" +) + +// Test that we error on unsupported fields for fiot +func TestTranslateInvalid(t *testing.T) { + type InvalidEntry struct { + Kind report.EntryKind + Err error + Path path.ContextPath + } + tests := []struct { + In Config + Entries []InvalidEntry + }{ + // we don't support setting kernel arguments + { + Config{ + Config: base.Config{ + KernelArguments: base.KernelArguments{ + ShouldExist: []base.KernelArgument{ + "test", + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrGeneralKernelArgumentSupport, + path.New("yaml", "kernel_arguments"), + }, + }, + }, + // we don't support unsetting kernel arguments either + { + Config{ + Config: base.Config{ + KernelArguments: base.KernelArguments{ + ShouldNotExist: []base.KernelArgument{ + "another-test", + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrGeneralKernelArgumentSupport, + path.New("yaml", "kernel_arguments"), + }, + }, + }, + // disk customizations are made in Image Builder, fiot doesn't support this via ignition + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Disks: []base.Disk{ + { + Device: "some-device", + }, + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrDiskSupport, + path.New("yaml", "storage", "disks"), + }, + }, + }, + // filesystem customizations are made in Image Builder, fiot doesn't support this via ignition + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Filesystems: []base.Filesystem{ + { + Device: "/dev/disk/by-label/TEST", + Path: util.StrToPtr("/var"), + }, + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrFilesystemSupport, + path.New("yaml", "storage", "filesystems"), + }, + }, + }, + // default luks configuration is made in Image Builder for fiot, we don't support this via ignition + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Luks: []base.Luks{ + { + Label: util.StrToPtr("some-label"), + }, + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrLuksSupport, + path.New("yaml", "storage", "luks"), + }, + }, + }, + // we don't support configuring raid via ignition + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Raid: []base.Raid{ + { + Name: "some-name", + }, + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrRaidSupport, + path.New("yaml", "storage", "raid"), + }, + }, + }, + } + for i, test := range tests { + t.Run(fmt.Sprintf("translate %d", i), func(t *testing.T) { + var expectedReport report.Report + for _, entry := range test.Entries { + expectedReport.AddOnError(entry.Path, entry.Err) + } + actual, translations, r := test.In.ToIgn3_4Unvalidated(common.TranslateOptions{}) + r.Merge(fieldFilters.Verify(actual)) + r = confutil.TranslateReportPaths(r, translations) + baseutil.VerifyReport(t, test.In, r) + assert.Equal(t, expectedReport, r, "report mismatch") + assert.NoError(t, translations.DebugVerifyCoverage(actual), "incomplete TranslationSet coverage") + }) + } +} diff --git a/config/fiot/v1_1_exp/schema.go b/config/fiot/v1_1_exp/schema.go new file mode 100644 index 00000000..e8e5c415 --- /dev/null +++ b/config/fiot/v1_1_exp/schema.go @@ -0,0 +1,23 @@ +// Copyright 2022 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v1_1_exp + +import ( + base "github.com/coreos/butane/base/v0_6_exp" +) + +type Config struct { + base.Config `yaml:",inline"` +} diff --git a/config/fiot/v1_1_exp/translate.go b/config/fiot/v1_1_exp/translate.go new file mode 100644 index 00000000..9ecac218 --- /dev/null +++ b/config/fiot/v1_1_exp/translate.go @@ -0,0 +1,54 @@ +// Copyright 2022 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v1_1_exp + +import ( + "github.com/coreos/butane/config/common" + cutil "github.com/coreos/butane/config/util" + + "github.com/coreos/ignition/v2/config/v3_5_experimental/types" + "github.com/coreos/vcontext/report" +) + +var ( + fieldFilters = cutil.NewFilters(types.Config{}, cutil.FilterMap{ + "kernelArguments": common.ErrGeneralKernelArgumentSupport, + "storage.disks": common.ErrDiskSupport, + "storage.filesystems": common.ErrFilesystemSupport, + "storage.luks": common.ErrLuksSupport, + "storage.raid": common.ErrRaidSupport, + }) +) + +// Return FieldFilters for this spec. +func (c Config) FieldFilters() *cutil.FieldFilters { + return &fieldFilters +} + +// ToIgn3_5 translates the config to an Ignition config. It returns a +// report of any errors or warnings in the source and resultant config. If +// the report has fatal errors or it encounters other problems translating, +// an error is returned. +func (c Config) ToIgn3_5(options common.TranslateOptions) (types.Config, report.Report, error) { + cfg, r, err := cutil.Translate(c, "ToIgn3_5Unvalidated", options) + return cfg.(types.Config), r, err +} + +// ToIgn3_5Bytes translates from a v1.2 Butane config to a v3.5.0 Ignition config. It returns a report of any errors or +// warnings in the source and resultant config. If the report has fatal errors or it encounters other problems +// translating, an error is returned. +func ToIgn3_5Bytes(input []byte, options common.TranslateBytesOptions) ([]byte, report.Report, error) { + return cutil.TranslateBytes(input, &Config{}, "ToIgn3_5", options) +} diff --git a/config/fiot/v1_1_exp/translate_test.go b/config/fiot/v1_1_exp/translate_test.go new file mode 100644 index 00000000..cd664f63 --- /dev/null +++ b/config/fiot/v1_1_exp/translate_test.go @@ -0,0 +1,180 @@ +// Copyright 2022 Red Hat, Inc +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License.) + +package v1_1_exp + +import ( + "fmt" + "testing" + + baseutil "github.com/coreos/butane/base/util" + base "github.com/coreos/butane/base/v0_6_exp" + "github.com/coreos/butane/config/common" + confutil "github.com/coreos/butane/config/util" + "github.com/coreos/ignition/v2/config/util" + "github.com/coreos/vcontext/path" + "github.com/coreos/vcontext/report" + "github.com/stretchr/testify/assert" +) + +// Test that we error on unsupported fields for fiot +func TestTranslateInvalid(t *testing.T) { + type InvalidEntry struct { + Kind report.EntryKind + Err error + Path path.ContextPath + } + tests := []struct { + In Config + Entries []InvalidEntry + }{ + // we don't support setting kernel arguments + { + Config{ + Config: base.Config{ + KernelArguments: base.KernelArguments{ + ShouldExist: []base.KernelArgument{ + "test", + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrGeneralKernelArgumentSupport, + path.New("yaml", "kernel_arguments"), + }, + }, + }, + // we don't support unsetting kernel arguments either + { + Config{ + Config: base.Config{ + KernelArguments: base.KernelArguments{ + ShouldNotExist: []base.KernelArgument{ + "another-test", + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrGeneralKernelArgumentSupport, + path.New("yaml", "kernel_arguments"), + }, + }, + }, + // disk customizations are made in Image Builder, fiot doesn't support this via ignition + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Disks: []base.Disk{ + { + Device: "some-device", + }, + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrDiskSupport, + path.New("yaml", "storage", "disks"), + }, + }, + }, + // filesystem customizations are made in Image Builder, fiot doesn't support this via ignition + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Filesystems: []base.Filesystem{ + { + Device: "/dev/disk/by-label/TEST", + Path: util.StrToPtr("/var"), + }, + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrFilesystemSupport, + path.New("yaml", "storage", "filesystems"), + }, + }, + }, + // default luks configuration is made in Image Builder for fiot, we don't support this via ignition + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Luks: []base.Luks{ + { + Label: util.StrToPtr("some-label"), + }, + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrLuksSupport, + path.New("yaml", "storage", "luks"), + }, + }, + }, + // we don't support configuring raid via ignition + { + Config{ + Config: base.Config{ + Storage: base.Storage{ + Raid: []base.Raid{ + { + Name: "some-name", + }, + }, + }, + }, + }, + []InvalidEntry{ + { + report.Error, + common.ErrRaidSupport, + path.New("yaml", "storage", "raid"), + }, + }, + }, + } + for i, test := range tests { + t.Run(fmt.Sprintf("translate %d", i), func(t *testing.T) { + var expectedReport report.Report + for _, entry := range test.Entries { + expectedReport.AddOnError(entry.Path, entry.Err) + } + actual, translations, r := test.In.ToIgn3_5Unvalidated(common.TranslateOptions{}) + r.Merge(fieldFilters.Verify(actual)) + r = confutil.TranslateReportPaths(r, translations) + baseutil.VerifyReport(t, test.In, r) + assert.Equal(t, expectedReport, r, "report mismatch") + assert.NoError(t, translations.DebugVerifyCoverage(actual), "incomplete TranslationSet coverage") + }) + } +} diff --git a/docs/config-fiot-v1_0.md b/docs/config-fiot-v1_0.md new file mode 100644 index 00000000..907ff41e --- /dev/null +++ b/docs/config-fiot-v1_0.md @@ -0,0 +1,146 @@ +--- +# This file is automatically generated from internal/doc and Ignition's +# config/doc. Do not edit. +title: Fedora IoT v1.0.0 +parent: Configuration specifications +nav_order: 249 +--- + +# Fedora IoT Specification v1.0.0 + +The Fedora IoT configuration is a YAML document conforming to the following specification, with **_italicized_** entries being optional: + +
+ +* **variant** (string): used to differentiate configs for different operating systems. Must be `%VARIANT%` for this specification. +* **version** (string): the semantic version of the spec for this document. This document is for version `%VERSION%` and generates Ignition configs with version `3.4.0`. +* **_ignition_** (object): metadata about the configuration itself. + * **_config_** (object): options related to the configuration. + * **_merge_** (list of objects): a list of the configs to be merged to the current config. + * **_source_** (string): the URL of the config. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the config. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the config, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the config (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the config. + * **_hash_** (string): the hash of the config, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed config. + * **_replace_** (object): the config that will replace the current. + * **_source_** (string): the URL of the config. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the config. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the config, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the config (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the config. + * **_hash_** (string): the hash of the config, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed config. + * **_timeouts_** (object): options relating to `http` timeouts when fetching files over `http` or `https`. + * **_http_response_headers_** (integer): the time to wait (in seconds) for the server's response headers (but not the body) after making a request. 0 indicates no timeout. Default is 10 seconds. + * **_http_total_** (integer): the time limit (in seconds) for the operation (connection, request, and response), including retries. 0 indicates no timeout. Default is 0. + * **_security_** (object): options relating to network security. + * **_tls_** (object): options relating to TLS when fetching resources over `https`. + * **_certificate_authorities_** (list of objects): the list of additional certificate authorities (in addition to the system authorities) to be used for TLS verification when fetching over `https`. All certificate authorities must have a unique `source`, `inline`, or `local`. + * **_source_** (string): the URL of the certificate bundle (in PEM format). The bundle can contain multiple concatenated certificates. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the certificate bundle (in PEM format). The bundle can contain multiple concatenated certificates. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the certificate bundle (in PEM format), relative to the directory specified by the `--files-dir` command-line argument. The bundle can contain multiple concatenated certificates. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the certificate bundle (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the certificate bundle. + * **_hash_** (string): the hash of the certificate bundle, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed certificate bundle. + * **_proxy_** (object): options relating to setting an `HTTP(S)` proxy when fetching resources. + * **_http_proxy_** (string): will be used as the proxy URL for HTTP requests and HTTPS requests unless overridden by `https_proxy` or `no_proxy`. + * **_https_proxy_** (string): will be used as the proxy URL for HTTPS requests unless overridden by `no_proxy`. + * **_no_proxy_** (list of strings): specifies a list of strings to hosts that should be excluded from proxying. Each value is represented by an `IP address prefix (1.2.3.4)`, `an IP address prefix in CIDR notation (1.2.3.4/8)`, `a domain name`, or `a special DNS label (*)`. An IP address prefix and domain name can also include a literal port number `(1.2.3.4:80)`. A domain name matches that name and all subdomains. A domain name with a leading `.` matches subdomains only. For example `foo.com` matches `foo.com` and `bar.foo.com`; `.y.com` matches `x.y.com` but not `y.com`. A single asterisk `(*)` indicates that no proxying should be done. +* **_storage_** (object): describes the desired state of the system's storage devices. + * **_files_** (list of objects): the list of files to be written. Every file, directory and link must have a unique `path`. + * **path** (string): the absolute path to the file. + * **_overwrite_** (boolean): whether to delete preexisting nodes at the path. `contents` must be specified if `overwrite` is true. Defaults to false. + * **_contents_** (object): options related to the contents of the file. + * **_source_** (string): the URL of the file. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. If source is omitted and a regular file already exists at the path, Ignition will do nothing. If source is omitted and no file exists, an empty file will be created. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the file. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the file, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the file (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the file. + * **_hash_** (string): the hash of the file, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed file. + * **_append_** (list of objects): list of fragments to be appended to the file. Follows the same structure as `contents`. + * **_source_** (string): the URL of the fragment. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the fragment. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the fragment, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the fragment (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the fragment. + * **_hash_** (string): the hash of the fragment, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed fragment. + * **_mode_** (integer): the file's permission mode. Setuid/setgid/sticky bits are supported. If not specified, the permission mode for files defaults to 0644 or the existing file's permissions if `overwrite` is false, `contents` is unspecified, and a file already exists at the path. + * **_user_** (object): specifies the file's owner. + * **_id_** (integer): the user ID of the owner. + * **_name_** (string): the user name of the owner. + * **_group_** (object): specifies the file's group. + * **_id_** (integer): the group ID of the group. + * **_name_** (string): the group name of the group. + * **_directories_** (list of objects): the list of directories to be created. Every file, directory, and link must have a unique `path`. + * **path** (string): the absolute path to the directory. + * **_overwrite_** (boolean): whether to delete preexisting nodes at the path. If false and a directory already exists at the path, Ignition will only set its permissions. If false and a non-directory exists at that path, Ignition will fail. Defaults to false. + * **_mode_** (integer): the directory's permission mode. Setuid/setgid/sticky bits are supported. If not specified, the permission mode for directories defaults to 0755 or the mode of an existing directory if `overwrite` is false and a directory already exists at the path. + * **_user_** (object): specifies the directory's owner. + * **_id_** (integer): the user ID of the owner. + * **_name_** (string): the user name of the owner. + * **_group_** (object): specifies the directory's group. + * **_id_** (integer): the group ID of the group. + * **_name_** (string): the group name of the group. + * **_links_** (list of objects): the list of links to be created. Every file, directory, and link must have a unique `path`. + * **path** (string): the absolute path to the link + * **_overwrite_** (boolean): whether to delete preexisting nodes at the path. If overwrite is false and a matching link exists at the path, Ignition will only set the owner and group. Defaults to false. + * **_user_** (object): specifies the owner for a symbolic link. Ignored for hard links. + * **_id_** (integer): the user ID of the owner. + * **_name_** (string): the user name of the owner. + * **_group_** (object): specifies the group for a symbolic link. Ignored for hard links. + * **_id_** (integer): the group ID of the group. + * **_name_** (string): the group name of the group. + * **target** (string): the target path of the link + * **_hard_** (boolean): a symbolic link is created if this is false, a hard one if this is true. + * **_trees_** (list of objects): a list of local directory trees to be embedded in the config. Ownership is not preserved. File modes are set to 0755 if the local file is executable or 0644 otherwise. Attributes of files, directories, and symlinks can be overridden by creating a corresponding entry in the `files`, `directories`, or `links` section; such `files` entries must omit `contents` and such `links` entries must omit `target`. + * **local** (string): the base of the local directory tree, relative to the directory specified by the `--files-dir` command-line argument. + * **_path_** (string): the path of the tree within the target system. Defaults to `/`. +* **_systemd_** (object): describes the desired state of the systemd units. + * **_units_** (list of objects): the list of systemd units. Every unit must have a unique `name`. + * **name** (string): the name of the unit. This must be suffixed with a valid unit type (e.g. "thing.service"). + * **_enabled_** (boolean): whether or not the service shall be enabled. When true, the service is enabled. When false, the service is disabled. When omitted, the service is unmodified. In order for this to have any effect, the unit must have an install section. + * **_mask_** (boolean): whether or not the service shall be masked. When true, the service is masked by symlinking it to `/dev/null`. When false, the service is unmasked by deleting the symlink to `/dev/null` if it exists. + * **_contents_** (string): the contents of the unit. Mutually exclusive with `contents_local`. + * **_contents_local_** (string): a local path to the contents of the unit, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `contents`. + * **_dropins_** (list of objects): the list of drop-ins for the unit. Every drop-in must have a unique `name`. + * **name** (string): the name of the drop-in. This must be suffixed with ".conf". + * **_contents_** (string): the contents of the drop-in. Mutually exclusive with `contents_local`. + * **_contents_local_** (string): a local path to the contents of the drop-in, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `contents`. +* **_passwd_** (object): describes the desired additions to the passwd database. + * **_users_** (list of objects): the list of accounts that shall exist. All users must have a unique `name`. + * **name** (string): the username for the account. + * **_password_hash_** (string): the hashed password for the account. + * **_ssh_authorized_keys_** (list of strings): a list of SSH keys to be added as an SSH key fragment at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. + * **_ssh_authorized_keys_local_** (list of strings): a list of local paths to SSH key files, relative to the directory specified by the `--files-dir` command-line argument, to be added as SSH key fragments at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. Each file may contain multiple SSH keys, one per line. + * **_uid_** (integer): the user ID of the account. + * **_gecos_** (string): the GECOS field of the account. + * **_home_dir_** (string): the home directory of the account. + * **_no_create_home_** (boolean): whether or not to create the user's home directory. This only has an effect if the account doesn't exist yet. + * **_primary_group_** (string): the name of the primary group of the account. + * **_groups_** (list of strings): the list of supplementary groups of the account. + * **_no_user_group_** (boolean): whether or not to create a group with the same name as the user. This only has an effect if the account doesn't exist yet. + * **_no_log_init_** (boolean): whether or not to add the user to the lastlog and faillog databases. This only has an effect if the account doesn't exist yet. + * **_shell_** (string): the login shell of the new account. + * **_should_exist_** (boolean): whether or not the user with the specified `name` should exist. If omitted, it defaults to true. If false, then Ignition will delete the specified user. + * **_system_** (boolean): whether or not this account should be a system account. This only has an effect if the account doesn't exist yet. + * **_groups_** (list of objects): the list of groups to be added. All groups must have a unique `name`. + * **name** (string): the name of the group. + * **_gid_** (integer): the group ID of the new group. + * **_password_hash_** (string): the hashed password of the new group. + * **_should_exist_** (boolean): whether or not the group with the specified `name` should exist. If omitted, it defaults to true. If false, then Ignition will delete the specified group. + * **_system_** (boolean): whether or not the group should be a system group. This only has an effect if the group doesn't exist yet. diff --git a/docs/config-fiot-v1_1-exp.md b/docs/config-fiot-v1_1-exp.md new file mode 100644 index 00000000..8749b1e5 --- /dev/null +++ b/docs/config-fiot-v1_1-exp.md @@ -0,0 +1,148 @@ +--- +# This file is automatically generated from internal/doc and Ignition's +# config/doc. Do not edit. +title: Fedora IoT v1.1.0-experimental +parent: Configuration specifications +nav_order: 250 +--- + +# Fedora IoT Specification v1.1.0-experimental + +**Note: This configuration is experimental and has not been stabilized. It is subject to change without warning or announcement.** + +The Fedora IoT configuration is a YAML document conforming to the following specification, with **_italicized_** entries being optional: + +
+ +* **variant** (string): used to differentiate configs for different operating systems. Must be `%VARIANT%` for this specification. +* **version** (string): the semantic version of the spec for this document. This document is for version `%VERSION%` and generates Ignition configs with version `3.5.0-experimental`. +* **_ignition_** (object): metadata about the configuration itself. + * **_config_** (object): options related to the configuration. + * **_merge_** (list of objects): a list of the configs to be merged to the current config. + * **_source_** (string): the URL of the config. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the config. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the config, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the config (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the config. + * **_hash_** (string): the hash of the config, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed config. + * **_replace_** (object): the config that will replace the current. + * **_source_** (string): the URL of the config. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the config. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the config, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the config (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the config. + * **_hash_** (string): the hash of the config, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed config. + * **_timeouts_** (object): options relating to `http` timeouts when fetching files over `http` or `https`. + * **_http_response_headers_** (integer): the time to wait (in seconds) for the server's response headers (but not the body) after making a request. 0 indicates no timeout. Default is 10 seconds. + * **_http_total_** (integer): the time limit (in seconds) for the operation (connection, request, and response), including retries. 0 indicates no timeout. Default is 0. + * **_security_** (object): options relating to network security. + * **_tls_** (object): options relating to TLS when fetching resources over `https`. + * **_certificate_authorities_** (list of objects): the list of additional certificate authorities (in addition to the system authorities) to be used for TLS verification when fetching over `https`. All certificate authorities must have a unique `source`, `inline`, or `local`. + * **_source_** (string): the URL of the certificate bundle (in PEM format). The bundle can contain multiple concatenated certificates. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the certificate bundle (in PEM format). The bundle can contain multiple concatenated certificates. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the certificate bundle (in PEM format), relative to the directory specified by the `--files-dir` command-line argument. The bundle can contain multiple concatenated certificates. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the certificate bundle (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the certificate bundle. + * **_hash_** (string): the hash of the certificate bundle, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed certificate bundle. + * **_proxy_** (object): options relating to setting an `HTTP(S)` proxy when fetching resources. + * **_http_proxy_** (string): will be used as the proxy URL for HTTP requests and HTTPS requests unless overridden by `https_proxy` or `no_proxy`. + * **_https_proxy_** (string): will be used as the proxy URL for HTTPS requests unless overridden by `no_proxy`. + * **_no_proxy_** (list of strings): specifies a list of strings to hosts that should be excluded from proxying. Each value is represented by an `IP address prefix (1.2.3.4)`, `an IP address prefix in CIDR notation (1.2.3.4/8)`, `a domain name`, or `a special DNS label (*)`. An IP address prefix and domain name can also include a literal port number `(1.2.3.4:80)`. A domain name matches that name and all subdomains. A domain name with a leading `.` matches subdomains only. For example `foo.com` matches `foo.com` and `bar.foo.com`; `.y.com` matches `x.y.com` but not `y.com`. A single asterisk `(*)` indicates that no proxying should be done. +* **_storage_** (object): describes the desired state of the system's storage devices. + * **_files_** (list of objects): the list of files to be written. Every file, directory and link must have a unique `path`. + * **path** (string): the absolute path to the file. + * **_overwrite_** (boolean): whether to delete preexisting nodes at the path. `contents` must be specified if `overwrite` is true. Defaults to false. + * **_contents_** (object): options related to the contents of the file. + * **_source_** (string): the URL of the file. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. If source is omitted and a regular file already exists at the path, Ignition will do nothing. If source is omitted and no file exists, an empty file will be created. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the file. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the file, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the file (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the file. + * **_hash_** (string): the hash of the file, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed file. + * **_append_** (list of objects): list of fragments to be appended to the file. Follows the same structure as `contents`. + * **_source_** (string): the URL of the fragment. Supported schemes are `http`, `https`, `tftp`, `s3`, `arn`, `gs`, and [`data`](https://tools.ietf.org/html/rfc2397). When using `http`, it is advisable to use the verification option to ensure the contents haven't been modified. Mutually exclusive with `inline` and `local`. + * **_inline_** (string): the contents of the fragment. Mutually exclusive with `source` and `local`. + * **_local_** (string): a local path to the contents of the fragment, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `source` and `inline`. + * **_compression_** (string): the type of compression used on the fragment (null or gzip). Compression cannot be used with S3. + * **_http_headers_** (list of objects): a list of HTTP headers to be added to the request. Available for `http` and `https` source schemes only. + * **name** (string): the header name. + * **_value_** (string): the header contents. + * **_verification_** (object): options related to the verification of the fragment. + * **_hash_** (string): the hash of the fragment, in the form `-` where type is either `sha512` or `sha256`. If `compression` is specified, the hash describes the decompressed fragment. + * **_mode_** (integer): the file's permission mode. Setuid/setgid/sticky bits are supported. If not specified, the permission mode for files defaults to 0644 or the existing file's permissions if `overwrite` is false, `contents` is unspecified, and a file already exists at the path. + * **_user_** (object): specifies the file's owner. + * **_id_** (integer): the user ID of the owner. + * **_name_** (string): the user name of the owner. + * **_group_** (object): specifies the file's group. + * **_id_** (integer): the group ID of the group. + * **_name_** (string): the group name of the group. + * **_directories_** (list of objects): the list of directories to be created. Every file, directory, and link must have a unique `path`. + * **path** (string): the absolute path to the directory. + * **_overwrite_** (boolean): whether to delete preexisting nodes at the path. If false and a directory already exists at the path, Ignition will only set its permissions. If false and a non-directory exists at that path, Ignition will fail. Defaults to false. + * **_mode_** (integer): the directory's permission mode. Setuid/setgid/sticky bits are supported. If not specified, the permission mode for directories defaults to 0755 or the mode of an existing directory if `overwrite` is false and a directory already exists at the path. + * **_user_** (object): specifies the directory's owner. + * **_id_** (integer): the user ID of the owner. + * **_name_** (string): the user name of the owner. + * **_group_** (object): specifies the directory's group. + * **_id_** (integer): the group ID of the group. + * **_name_** (string): the group name of the group. + * **_links_** (list of objects): the list of links to be created. Every file, directory, and link must have a unique `path`. + * **path** (string): the absolute path to the link + * **_overwrite_** (boolean): whether to delete preexisting nodes at the path. If overwrite is false and a matching link exists at the path, Ignition will only set the owner and group. Defaults to false. + * **_user_** (object): specifies the owner for a symbolic link. Ignored for hard links. + * **_id_** (integer): the user ID of the owner. + * **_name_** (string): the user name of the owner. + * **_group_** (object): specifies the group for a symbolic link. Ignored for hard links. + * **_id_** (integer): the group ID of the group. + * **_name_** (string): the group name of the group. + * **target** (string): the target path of the link + * **_hard_** (boolean): a symbolic link is created if this is false, a hard one if this is true. + * **_trees_** (list of objects): a list of local directory trees to be embedded in the config. Ownership is not preserved. File modes are set to 0755 if the local file is executable or 0644 otherwise. Attributes of files, directories, and symlinks can be overridden by creating a corresponding entry in the `files`, `directories`, or `links` section; such `files` entries must omit `contents` and such `links` entries must omit `target`. + * **local** (string): the base of the local directory tree, relative to the directory specified by the `--files-dir` command-line argument. + * **_path_** (string): the path of the tree within the target system. Defaults to `/`. +* **_systemd_** (object): describes the desired state of the systemd units. + * **_units_** (list of objects): the list of systemd units. Every unit must have a unique `name`. + * **name** (string): the name of the unit. This must be suffixed with a valid unit type (e.g. "thing.service"). + * **_enabled_** (boolean): whether or not the service shall be enabled. When true, the service is enabled. When false, the service is disabled. When omitted, the service is unmodified. In order for this to have any effect, the unit must have an install section. + * **_mask_** (boolean): whether or not the service shall be masked. When true, the service is masked by symlinking it to `/dev/null`. When false, the service is unmasked by deleting the symlink to `/dev/null` if it exists. + * **_contents_** (string): the contents of the unit. Mutually exclusive with `contents_local`. + * **_contents_local_** (string): a local path to the contents of the unit, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `contents`. + * **_dropins_** (list of objects): the list of drop-ins for the unit. Every drop-in must have a unique `name`. + * **name** (string): the name of the drop-in. This must be suffixed with ".conf". + * **_contents_** (string): the contents of the drop-in. Mutually exclusive with `contents_local`. + * **_contents_local_** (string): a local path to the contents of the drop-in, relative to the directory specified by the `--files-dir` command-line argument. Mutually exclusive with `contents`. +* **_passwd_** (object): describes the desired additions to the passwd database. + * **_users_** (list of objects): the list of accounts that shall exist. All users must have a unique `name`. + * **name** (string): the username for the account. + * **_password_hash_** (string): the hashed password for the account. + * **_ssh_authorized_keys_** (list of strings): a list of SSH keys to be added as an SSH key fragment at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. + * **_ssh_authorized_keys_local_** (list of strings): a list of local paths to SSH key files, relative to the directory specified by the `--files-dir` command-line argument, to be added as SSH key fragments at `.ssh/authorized_keys.d/ignition` in the user's home directory. All SSH keys must be unique. Each file may contain multiple SSH keys, one per line. + * **_uid_** (integer): the user ID of the account. + * **_gecos_** (string): the GECOS field of the account. + * **_home_dir_** (string): the home directory of the account. + * **_no_create_home_** (boolean): whether or not to create the user's home directory. This only has an effect if the account doesn't exist yet. + * **_primary_group_** (string): the name of the primary group of the account. + * **_groups_** (list of strings): the list of supplementary groups of the account. + * **_no_user_group_** (boolean): whether or not to create a group with the same name as the user. This only has an effect if the account doesn't exist yet. + * **_no_log_init_** (boolean): whether or not to add the user to the lastlog and faillog databases. This only has an effect if the account doesn't exist yet. + * **_shell_** (string): the login shell of the new account. + * **_should_exist_** (boolean): whether or not the user with the specified `name` should exist. If omitted, it defaults to true. If false, then Ignition will delete the specified user. + * **_system_** (boolean): whether or not this account should be a system account. This only has an effect if the account doesn't exist yet. + * **_groups_** (list of objects): the list of groups to be added. All groups must have a unique `name`. + * **name** (string): the name of the group. + * **_gid_** (integer): the group ID of the new group. + * **_password_hash_** (string): the hashed password of the new group. + * **_should_exist_** (boolean): whether or not the group with the specified `name` should exist. If omitted, it defaults to true. If false, then Ignition will delete the specified group. + * **_system_** (boolean): whether or not the group should be a system group. This only has an effect if the group doesn't exist yet. diff --git a/docs/release-notes.md b/docs/release-notes.md index ad8e136c..e5274bbc 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -44,6 +44,7 @@ key](https://getfedora.org/security/). - Stabilize OpenShift spec 4.14.0, targeting Ignition spec 3.4.0 - Add OpenShift spec 4.15.0-experimental, targeting Ignition spec 3.5.0-experimental +- Add new variant `fiot` for fedora-iot ### Bug fixes diff --git a/docs/specs.md b/docs/specs.md index 27e29861..dbe7e8b5 100644 --- a/docs/specs.md +++ b/docs/specs.md @@ -35,6 +35,8 @@ We recommend that you always use the latest **stable** specification for your op - RHEL for Edge (`r4e`) - [v1.1.0](config-r4e-v1_1.md) - [v1.0.0](config-r4e-v1_0.md) +- Fedora IoT (`fiot`) + - [v1.0.0](config-fiot-v1_0.md) ## Experimental specification versions @@ -48,6 +50,8 @@ Do not use **experimental** specifications for anything beyond **development and - [v4.15.0-experimental](config-openshift-v4_15-exp.md) - RHEL for Edge (`r4e`) - [v1.2.0-experimental](config-r4e-v1_2-exp.md) +- Fedora IoT (`fiot`) + - [v1.1.0-experimental](config-fiot-v1_1-exp.md) ## Butane specifications and Ignition specifications @@ -76,3 +80,5 @@ Each version of the Butane specification corresponds to a version of the Ignitio | `r4e` | 1.0.0 | 3.3.0 | | `r4e` | 1.1.0 | 3.4.0 | | `r4e` | 1.2.0-experimental | 3.5.0-experimental | +| `fiot` | 1.0.0 | 3.4.0 | +| `fiot` | 1.1.0-experimental | 3.5.0-experimental | \ No newline at end of file diff --git a/internal/doc/main.go b/internal/doc/main.go index d3b25064..f9c3134b 100644 --- a/internal/doc/main.go +++ b/internal/doc/main.go @@ -42,6 +42,8 @@ import ( fcos1_4 "github.com/coreos/butane/config/fcos/v1_4" fcos1_5 "github.com/coreos/butane/config/fcos/v1_5" fcos1_6_exp "github.com/coreos/butane/config/fcos/v1_6_exp" + fiot1_0 "github.com/coreos/butane/config/fiot/v1_0" + fiot1_1_exp "github.com/coreos/butane/config/fiot/v1_1_exp" flatcar1_0 "github.com/coreos/butane/config/flatcar/v1_0" flatcar1_1 "github.com/coreos/butane/config/flatcar/v1_1" flatcar1_2_exp "github.com/coreos/butane/config/flatcar/v1_2_exp" @@ -141,6 +143,15 @@ func generate(dir string) error { {"1.1.0", r4e1_1.Config{}}, }, }, + { + "Fedora IoT", + "fiot", + []version{ + // inverse order of website navbar + {"1.1.0-experimental", fiot1_1_exp.Config{}}, + {"1.0.0", fiot1_0.Config{}}, + }, + }, } // parse and snakify Ignition components From 447f94f5d5dcd63ef6cfa0ebe3d9861a1366b47f Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Mon, 11 Dec 2023 16:28:06 +0000 Subject: [PATCH 14/16] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@d9f6038654f04a3a271566217e6dc5fbb52ba57e. --- .github/ISSUE_TEMPLATE/release-checklist.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/release-checklist.md b/.github/ISSUE_TEMPLATE/release-checklist.md index bcecb7ba..5ec6f11b 100644 --- a/.github/ISSUE_TEMPLATE/release-checklist.md +++ b/.github/ISSUE_TEMPLATE/release-checklist.md @@ -74,6 +74,7 @@ RHCOS packaging for the current RHCOS development release: - [ ] Get the PR reviewed and merge it - [ ] Update your local repo and run `rhpkg build` - [ ] File ticket similar to [this one](https://issues.redhat.com/browse/ART-3711) to sync the new version to mirror.openshift.com + - [ ] Wait until mirror.openshift.com is updated and confirm the new version is correct CentOS Stream 9 packaging: - [ ] Create a `rebase-c9s-butane` issue in the internal team-operations repo and follow the steps there From 8af9923b78db3c1b3d7ac87dd5b9c0ac4555ced9 Mon Sep 17 00:00:00 2001 From: CoreOS Bot Date: Wed, 3 Jan 2024 21:10:14 +0000 Subject: [PATCH 15/16] =?UTF-8?q?Sync=20repo=20templates=20=E2=9A=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sync with coreos/repo-templates@7e30893b8860c6a7733bca2e56a2b86545bab5b8. --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 0a4dc053..d632d994 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -48,7 +48,7 @@ jobs: uses: golangci/golangci-lint-action@v3 if: runner.os == 'Linux' with: - version: v1.52.2 + version: v1.55.1 args: -E=gofmt --timeout=30m0s regenerate: name: Regenerate From 0b7aae93e8d5d95ed4282a7ecfcf6a65b7ddd117 Mon Sep 17 00:00:00 2001 From: Steven Presti Date: Wed, 3 Jan 2024 14:44:33 -0500 Subject: [PATCH 16/16] Bump minimum Go version to 1.20 Go 1.18 is EOL --- docs/release-notes.md | 1 + go.mod | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/release-notes.md b/docs/release-notes.md index e5274bbc..25eda216 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -19,6 +19,7 @@ nav_order: 9 ### Misc. changes +- Require Go 1.20+ ### Docs changes diff --git a/go.mod b/go.mod index 6a2757c2..0aabea8d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/coreos/butane -go 1.18 +go 1.20 require ( github.com/clarketm/json v1.17.1