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